2 * This file is part of the coreboot project.
4 * Copyright (C) 2009 One Laptop per Child, Association, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "pci_rawops.h"
22 typedef struct __UMA_RAM_tag {
46 #define VGA_PORT_512M 0x00
47 #define VGA_PORT_256M 0x80
48 #define VGA_PORT_128M 0xC0
49 #define VGA_PORT_64M 0xE0
50 #define VGA_PORT_32M 0xF0
51 #define VGA_PORT_16M 0xF8
53 #define VIACONFIG_VGA_PCI_10 0xf8000008
54 #define VIACONFIG_VGA_PCI_14 0xfc000000
56 static const UMARAM UMARamArr[] = {
57 {0, UMARAM_0M, FB_4M, 0xFE},
58 {8, UMARAM_8M, FB_8M, 0xFC},
59 {16, UMARAM_16M, FB_16M, VGA_PORT_16M},
60 {32, UMARAM_32M, FB_32M, VGA_PORT_32M},
61 {64, UMARAM_64M, FB_64M, VGA_PORT_64M},
62 {128, UMARAM_128M, FB_128M, VGA_PORT_128M},
63 {256, UMARAM_256M, FB_256M, VGA_PORT_256M},
64 {512, UMARAM_512M, FB_512M, VGA_PORT_512M},
65 {0xffff, 0xff, 0xff, 0xFF}
71 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
72 device_t vga_dev = PCI_DEV(0, 1, 0), d0f0_dev = PCI_DEV(0, 0, 0);
74 const UMARAM *pUMARamTable;
76 u8 SLD0F3Val, SLD1F0Val, VgaPortVal;
77 u32 RamSize, SLBase, Tmp;
79 PRINT_DEBUG_MEM("Entering vx800 SetUMARam.\n");
84 ByteVal = pci_read_config8(MEMCTRL, 0xa1);
86 pci_write_config8(MEMCTRL, 0xa1, ByteVal);
89 pci_write_config8(MEMCTRL, 0xa2, 0xee);
92 //GFX Data Delay to Sync with Clock
93 pci_write_config8(MEMCTRL, 0xa4, 0x01);
95 //page register life timer
96 pci_write_config8(MEMCTRL, 0xa6, 0x76);
98 //GMINT and GFX relatate
99 //note Bit 3 VGA Enable
100 pci_write_config8(MEMCTRL, 0xa7, 0x8c);
104 //pci_write_config8(MEMCTRL, 0xb0, 0x80);
106 //pci_write_config8(MEMCTRL, 0xb1, 0xaa);
109 //pci_write_config8(MEMCTRL, 0xb2, 0x82);
113 //disable read pass write
114 pci_write_config8(MEMCTRL, 0xb3, 0x9A);
117 //pci_write_config8(MEMCTRL, 0xb4, 0x04);
119 //enable CHA and CHB merge mode
120 pci_write_config8(MEMCTRL, 0xde, 0x06);
122 //if can get the value from setup interface, so get the value
123 //else use the default value
124 UmaSize = CONFIG_VIDEO_MB;
126 for (pUMARamTable = UMARamArr; pUMARamTable->DramSize != 0xffff;
128 if (UmaSize == pUMARamTable->DramSize) {
129 SLD0F3Val = pUMARamTable->D0F3Val;
130 SLD1F0Val = pUMARamTable->D1F0Val;
131 VgaPortVal = pUMARamTable->VgaPortVal;
135 //Fill in Fun3_RXA1[6:4] with the Frame Buffer size for the Integrated Graphic Device.
136 ByteVal = pci_read_config8(MEMCTRL, 0xa1);
137 ByteVal = (ByteVal & 0x8f) | (SLD0F3Val << 4);
138 pci_write_config8(MEMCTRL, 0xa1, ByteVal);
140 // vga_dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_VGA, 0);
142 //RxB2 may be for S.L. and RxB1 may be for L. L.
143 // It is different from Spec.
145 pci_write_config8(vga_dev, 0xb2, ByteVal);
148 //ByteVal=pci_read_config8(MEMCTRL, 0xa3);
150 //pci_write_config8(MEMCTRL, 0xa3, ByteVal);
152 PRINT_DEBUG_MEM("UMA setting - 3\n");
156 pci_write_config8(vga_dev, 0x04, ByteVal);
158 //must set SL and MMIO base, or else when enable GFX memory space, system will hang
160 Tmp = pci_read_config32(vga_dev, 0x10);
162 pci_write_config32(vga_dev, 0x10, Tmp);
163 Tmp = pci_read_config32(vga_dev, 0x10);
164 Tmp = VIACONFIG_VGA_PCI_10;
165 pci_write_config32(vga_dev, 0x10, Tmp);
168 Tmp = pci_read_config32(vga_dev, 0x14);
170 pci_write_config32(vga_dev, 0x14, Tmp);
171 Tmp = pci_read_config32(vga_dev, 0x14);
172 Tmp = VIACONFIG_VGA_PCI_14;
173 pci_write_config32(vga_dev, 0x14, Tmp);
175 //enable direct cpu frame buffer access
176 i = pci_rawread_config8(PCI_RAWDEV(0, 0, 3), 0xa1);
177 i = (i & 0xf0) | (VIACONFIG_VGA_PCI_10 >> 28);
178 pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa1, i);
179 pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa0, 0x01);
181 //enable GFx memory space access control for S.L and mmio
182 ByteVal = pci_read_config8(d0f0_dev, 0xD4);
185 pci_write_config8(d0f0_dev, 0xD4, ByteVal);
187 //enable Base VGA 16 Bits Decode
188 ByteVal = pci_read_config8(d0f0_dev, 0xfe);
190 pci_write_config8(d0f0_dev, 0xfe, ByteVal);
193 //set VGA memory selection
194 ByteVal = pci_read_config8(vga_dev, 0xb0);
198 pci_write_config8(vga_dev, 0xb0, ByteVal);
202 //enable memory access to SL,MMIO,LL and IO to 3B0~3BB,3C0 ~3DF
204 //pci_write_config8(d0f0_dev, 0xc0, ByteVal);
206 //Turn on Graphic chip IO port port access
207 ByteVal = inb(0x03C3);
209 outb(ByteVal, 0x03C3);
211 //Turn off Graphic chip Register protection
214 ByteVal = inb(0x03C5);
216 outb(ByteVal, 0x03C5);
218 //set VGA memory Frequence
219 //direct IO port 0x3DX to vga io space 0x3C2[0]
220 ByteVal = inb(0x03CC);
222 outb(ByteVal, 0x03C2);
223 // ByteVal=inb(0x03C2);
225 // outb(ByteVal,0x03C2);
227 #if 1 //bios porting guide has no this two defination: 3d on 3d4/3d5 and 39 on 3c4/3c5
228 //set frequence 0x3D5.3d[7:4]
231 temp = pci_read_config8(MEMCTRL, 0x90);
232 temp = (u8) (temp & 0x07);
233 ByteVal = inb(0x03d5);
235 case 0: //DIMMFREQ_200:
236 ByteVal = (u8) ((ByteVal & 0x0F) | 0x30);
238 case 1: //DIMMFREQ_266:
239 ByteVal = (u8) ((ByteVal & 0x0F) | 0x40);
241 case 3: //DIMMFREQ_400:
242 ByteVal = (u8) ((ByteVal & 0x0F) | 0x60);
244 case 4: //DIMMFREQ_533:
245 ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
247 case 5: //DIMMFREQ_667:
248 ByteVal = (u8) ((ByteVal & 0x0F) | 0x80);
250 case 6: //DIMMFREQ_800:
251 ByteVal = (u8) ((ByteVal & 0x0F) | 0x90);
254 ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
257 outb(ByteVal, 0x03d5);
259 // Set frame buffer size
261 outb(1 << SLD0F3Val, 0x03c5);
264 // Set S.L. size in GFX's register
266 outb(VgaPortVal, 0x03c5);
268 // ECLK Selection (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
269 // set 3C5.5A[0]=1, address maps to secondary resgiters
271 ByteVal = inb(0x03c5);
273 outb(ByteVal, 0x03c5);
275 // Set 3D5.4C[7:6] (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
277 ByteVal = inb(0x03d5);
278 ByteVal = (ByteVal & 0x3F) | 0x80;
279 outb(ByteVal, 0x03d5);
281 // set 3C5.5A[0]=0, address maps to first resgiters
283 ByteVal = inb(0x03c5);
285 outb(ByteVal, 0x03c5);
287 // Set S.L. Address in System Memory
288 //calculate dram size
289 for (RamSize = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
290 RamSize = pci_read_config8(MEMCTRL, ramregs[i]);
294 //calculate SL Base Address
295 SLBase = (RamSize << 26) - (UmaSize << 20);
299 outb((u8) ((SLBase >> 21) & 0xFF), 0x03c5);
303 outb((u8) ((SLBase >> 29) & 0xFF), 0x03c5);
308 // Set SVID high byte
324 //start : For enable snapshot mode control
325 // program 3C5 for SNAPSHOT Mode control, set RxF3h=1Ah
327 ByteVal = inb(0x03c5);
328 ByteVal = (ByteVal & 0xE5) | 0x1A;
329 outb(ByteVal, 0x03c5);
332 ByteVal = inb(0x03d5);
333 ByteVal = (ByteVal & 0xE5) | 0x1A;
334 outb(ByteVal, 0x03d5);
337 u8 table3c43c5[0x70] = {
338 0x03, 0x01, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x01, 0x78, 0x00, 0x00, 0x00, 0xBE, 0x20, 0x7F,
341 0x60, 0x7F, 0x08, 0x31, 0xCC, 0x00, 0x01, 0x00,
342 0x00, 0x18, 0x10, 0x00, 0x00, 0x00, 0x3D, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x04, 0xF3, 0xFF, 0xFC,
344 0xF8, 0x0C, 0x00, 0x00, 0x40, 0x06, 0x11, 0x22,
345 0x51, 0x10, 0x00, 0x01, 0x19, 0x0C, 0x00, 0xFF,
346 0x38, 0x40, 0x30, 0xFF, 0x70, 0x8C, 0x85, 0x9D,
347 0x80, 0x05, 0x54, 0x90, 0x03, 0x30, 0x00, 0x5F,
348 0x1F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
349 0x06, 0xDF, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x20, 0x20,
351 0xE0, 0x20, 0xD0, 0x3F, 0x00, 0xE0, 0x00, 0x00
353 u8 table3d43d5[0x88] = {
354 0x7F, 0x63, 0x63, 0x83, 0x69, 0x19, 0x72, 0xE0,
355 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x58, 0x9C, 0x57, 0x90, 0x00, 0x57, 0x73, 0xE3,
357 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x0C, 0x00, 0x11, 0x06, 0x00, 0x20, 0x01, 0x34,
361 0xEE, 0x74, 0x01, 0x01, 0x08, 0x84, 0x00, 0x00,
362 0x00, 0xF3, 0x40, 0x90, 0x00, 0x00, 0x00, 0x01,
363 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00,
364 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
365 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x10,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x9D,
368 0x9D, 0x9D, 0x9D, 0x9D, 0x00, 0x9D, 0x1D, 0x00,
369 0x00, 0x00, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
370 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
373 u8 table3c0space[0xc0] = {
374 0x11, 0x00, 0x10, 0x01, 0x26, 0x3D, 0xFF, 0x00,
375 0x10, 0x3F, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
379 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
380 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0xFF,
381 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
382 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
383 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
384 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
385 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
386 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
387 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
388 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
389 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
390 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
391 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
392 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
393 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
394 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
395 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
396 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
397 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
400 //for(i=0;i<0xc0;i++)
401 for (i = 0; i < 0x40; i++)
403 outb(table3c0space[i], 0x03c0 + i);
406 for (i = 0; i < 0x70; i++) {
408 outb(table3c43c5[i], 0x03c5);
410 for (i = 0; i < 0x88; i++) {
412 outb(table3d43d5[i], 0x03d5);
426 // IO Port / Index: 3X5.3D
427 // Scratch Pad Register 4
428 // outb(0x39,0x03c4);
429 // outb(1 << SLD0F3Val ,0x03c5);