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 typedef struct __UMA_RAM_tag {
45 #define VGA_PORT_512M 0x00
46 #define VGA_PORT_256M 0x80
47 #define VGA_PORT_128M 0xC0
48 #define VGA_PORT_64M 0xE0
49 #define VGA_PORT_32M 0xF0
50 #define VGA_PORT_16M 0xF8
52 static const UMARAM UMARamArr[] = {
53 {0, UMARAM_0M, FB_4M, 0xFE},
54 {8, UMARAM_8M, FB_8M, 0xFC},
55 {16, UMARAM_16M, FB_16M, VGA_PORT_16M},
56 {32, UMARAM_32M, FB_32M, VGA_PORT_32M},
57 {64, UMARAM_64M, FB_64M, VGA_PORT_64M},
58 {128, UMARAM_128M, FB_128M, VGA_PORT_128M},
59 {256, UMARAM_256M, FB_256M, VGA_PORT_256M},
60 {512, UMARAM_512M, FB_512M, VGA_PORT_512M},
61 {0xffff, 0xff, 0xff, 0xFF}
67 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
68 device_t vga_dev = PCI_DEV(0, 1, 0), d0f0_dev = PCI_DEV(0, 0, 0);
72 u8 SLD0F3Val, SLD1F0Val, VgaPortVal;
73 u32 RamSize, SLBase, Tmp;
75 PRINT_DEBUG_MEM("Entering vx800 SetUMARam.\n");
81 ByteVal = pci_read_config8(MEMCTRL, 0xa1);
83 pci_write_config8(MEMCTRL, 0xa1, ByteVal);
86 pci_write_config8(MEMCTRL, 0xa2, 0xee);
89 //GFX Data Delay to Sync with Clock
90 pci_write_config8(MEMCTRL, 0xa4, 0x01);
92 //page register life timer
93 pci_write_config8(MEMCTRL, 0xa6, 0x76);
95 //GMINT and GFX relatate
96 //note Bit 3 VGA Enable
97 pci_write_config8(MEMCTRL, 0xa7, 0x8c);
101 //pci_write_config8(MEMCTRL, 0xb0, 0x80);
103 //pci_write_config8(MEMCTRL, 0xb1, 0xaa);
106 //pci_write_config8(MEMCTRL, 0xb2, 0x82);
110 //disable read pass write
111 pci_write_config8(MEMCTRL, 0xb3, 0x9A);
114 //pci_write_config8(MEMCTRL, 0xb4, 0x04);
116 //enable CHA and CHB merge mode
117 pci_write_config8(MEMCTRL, 0xde, 0x06);
119 //if can get the value from setup interface, so get the value
120 //else use the default value
121 UmaSize = CONFIG_VIDEO_MB;
123 for (pUMARamTable = UMARamArr; pUMARamTable->DramSize != 0xffff;
125 if (UmaSize == pUMARamTable->DramSize) {
126 SLD0F3Val = pUMARamTable->D0F3Val;
127 SLD1F0Val = pUMARamTable->D1F0Val;
128 VgaPortVal = pUMARamTable->VgaPortVal;
132 //Fill in Fun3_RXA1[6:4] with the Frame Buffer size for the Integrated Graphic Device.
133 ByteVal = pci_read_config8(MEMCTRL, 0xa1);
134 ByteVal = (ByteVal & 0x8f) | (SLD0F3Val << 4);
135 pci_write_config8(MEMCTRL, 0xa1, ByteVal);
138 // vga_dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_VGA, 0);
140 //RxB2 may be for S.L. and RxB1 may be for L. L.
141 // It is different from Spec.
143 pci_write_config8(vga_dev, 0xb2, ByteVal);
147 //ByteVal=pci_read_config8(MEMCTRL, 0xa3);
149 //pci_write_config8(MEMCTRL, 0xa3, ByteVal);
151 PRINT_DEBUG_MEM("UMA setting - 3\n");
158 pci_write_config8(vga_dev, 0x04, ByteVal);
163 //must set SL and MMIO base, or else when enable GFX memory space, system will hang
165 Tmp = pci_read_config32(vga_dev, 0x10);
167 pci_write_config32(vga_dev, 0x10, Tmp);
168 Tmp = pci_read_config32(vga_dev, 0x10);
169 Tmp = VIACONFIG_VGA_PCI_10;
170 pci_write_config32(vga_dev, 0x10, Tmp);
173 Tmp = pci_read_config32(vga_dev, 0x14);
175 pci_write_config32(vga_dev, 0x14, Tmp);
176 Tmp = pci_read_config32(vga_dev, 0x14);
177 Tmp = VIACONFIG_VGA_PCI_14;
178 pci_write_config32(vga_dev, 0x14, Tmp);
181 //enable direct cpu frame buffer access
182 i = pci_rawread_config8(PCI_RAWDEV(0, 0, 3), 0xa1);
183 i = (i & 0xf0) | (VIACONFIG_VGA_PCI_10 >> 28);
184 pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa1, i);
185 pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa0, 0x01);
188 //enable GFx memory space access control for S.L and mmio
189 ByteVal = pci_read_config8(d0f0_dev, 0xD4);
192 pci_write_config8(d0f0_dev, 0xD4, ByteVal);
195 //enable Base VGA 16 Bits Decode
196 ByteVal = pci_read_config8(d0f0_dev, 0xfe);
198 pci_write_config8(d0f0_dev, 0xfe, ByteVal);
202 //set VGA memory selection
203 ByteVal = pci_read_config8(vga_dev, 0xb0);
207 pci_write_config8(vga_dev, 0xb0, ByteVal);
211 //enable memory access to SL,MMIO,LL and IO to 3B0~3BB,3C0 ~3DF
213 //pci_write_config8(d0f0_dev, 0xc0, ByteVal);
215 //Turn on Graphic chip IO port port access
216 ByteVal = inb(0x03C3);
218 outb(ByteVal, 0x03C3);
220 //Turn off Graphic chip Register protection
223 ByteVal = inb(0x03C5);
225 outb(ByteVal, 0x03C5);
227 //set VGA memory Frequence
228 //direct IO port 0x3DX to vga io space 0x3C2[0]
229 ByteVal = inb(0x03CC);
231 outb(ByteVal, 0x03C2);
232 // ByteVal=inb(0x03C2);
234 // outb(ByteVal,0x03C2);
237 #if 1 //bios porting guide has no this two defination: 3d on 3d4/3d5 and 39 on 3c4/3c5
238 //set frequence 0x3D5.3d[7:4]
241 temp = pci_read_config8(MEMCTRL, 0x90);
242 temp = (u8) (temp & 0x07);
243 ByteVal = inb(0x03d5);
245 case 0: //DIMMFREQ_200:
246 ByteVal = (u8) ((ByteVal & 0x0F) | 0x30);
248 case 1: //DIMMFREQ_266:
249 ByteVal = (u8) ((ByteVal & 0x0F) | 0x40);
251 case 3: //DIMMFREQ_400:
252 ByteVal = (u8) ((ByteVal & 0x0F) | 0x60);
254 case 4: //DIMMFREQ_533:
255 ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
257 case 5: //DIMMFREQ_667:
258 ByteVal = (u8) ((ByteVal & 0x0F) | 0x80);
260 case 6: //DIMMFREQ_800:
261 ByteVal = (u8) ((ByteVal & 0x0F) | 0x90);
264 ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
267 outb(ByteVal, 0x03d5);
269 // Set frame buffer size
271 outb(1 << SLD0F3Val, 0x03c5);
274 // Set S.L. size in GFX's register
276 outb(VgaPortVal, 0x03c5);
278 // ECLK Selection (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
279 // set 3C5.5A[0]=1, address maps to secondary resgiters
281 ByteVal = inb(0x03c5);
283 outb(ByteVal, 0x03c5);
285 // Set 3D5.4C[7:6] (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
287 ByteVal = inb(0x03d5);
288 ByteVal = (ByteVal & 0x3F) | 0x80;
289 outb(ByteVal, 0x03d5);
291 // set 3C5.5A[0]=0, address maps to first resgiters
293 ByteVal = inb(0x03c5);
295 outb(ByteVal, 0x03c5);
297 // Set S.L. Address in System Memory
298 //calculate dram size
299 for (RamSize = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
300 RamSize = pci_read_config8(MEMCTRL, ramregs[i]);
304 //calculate SL Base Address
305 SLBase = (RamSize << 26) - (UmaSize << 20);
310 outb((u8) ((SLBase >> 21) & 0xFF), 0x03c5);
314 outb((u8) ((SLBase >> 29) & 0xFF), 0x03c5);
319 // Set SVID high byte
335 //start : For enable snapshot mode control
336 // program 3C5 for SNAPSHOT Mode control, set RxF3h=1Ah
338 ByteVal = inb(0x03c5);
339 ByteVal = (ByteVal & 0xE5) | 0x1A;
340 outb(ByteVal, 0x03c5);
344 ByteVal = inb(0x03d5);
345 ByteVal = (ByteVal & 0xE5) | 0x1A;
346 outb(ByteVal, 0x03d5);
348 u8 table3c43c5[0x70] = {
349 0x03, 0x01, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x01, 0x78, 0x00, 0x00, 0x00, 0xBE, 0x20, 0x7F,
352 0x60, 0x7F, 0x08, 0x31, 0xCC, 0x00, 0x01, 0x00,
353 0x00, 0x18, 0x10, 0x00, 0x00, 0x00, 0x3D, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x04, 0xF3, 0xFF, 0xFC,
355 0xF8, 0x0C, 0x00, 0x00, 0x40, 0x06, 0x11, 0x22,
356 0x51, 0x10, 0x00, 0x01, 0x19, 0x0C, 0x00, 0xFF,
357 0x38, 0x40, 0x30, 0xFF, 0x70, 0x8C, 0x85, 0x9D,
358 0x80, 0x05, 0x54, 0x90, 0x03, 0x30, 0x00, 0x5F,
359 0x1F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
360 0x06, 0xDF, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x20, 0x20,
362 0xE0, 0x20, 0xD0, 0x3F, 0x00, 0xE0, 0x00, 0x00
364 u8 table3d43d5[0x88] = {
365 0x7F, 0x63, 0x63, 0x83, 0x69, 0x19, 0x72, 0xE0,
366 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x58, 0x9C, 0x57, 0x90, 0x00, 0x57, 0x73, 0xE3,
368 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x0C, 0x00, 0x11, 0x06, 0x00, 0x20, 0x01, 0x34,
372 0xEE, 0x74, 0x01, 0x01, 0x08, 0x84, 0x00, 0x00,
373 0x00, 0xF3, 0x40, 0x90, 0x00, 0x00, 0x00, 0x01,
374 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00,
375 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
376 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x10,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x9D,
379 0x9D, 0x9D, 0x9D, 0x9D, 0x00, 0x9D, 0x1D, 0x00,
380 0x00, 0x00, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
381 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
385 u8 table3c0space[0xc0] = {
386 0x11, 0x00, 0x10, 0x01, 0x26, 0x3D, 0xFF, 0x00,
387 0x10, 0x3F, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x50, 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, 0x00, 0x00, 0x00, 0x00,
397 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
398 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
399 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
400 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
401 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
402 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
403 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
404 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
405 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
406 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
407 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
408 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
409 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
412 //for(i=0;i<0xc0;i++)
413 for (i = 0; i < 0x40; i++) //
415 outb(table3c0space[i], 0x03c0 + i);
419 for (i = 0; i < 0x70; i++) {
421 outb(table3c43c5[i], 0x03c5);
423 for (i = 0; i < 0x88; i++) {
425 outb(table3d43d5[i], 0x03d5);
437 //IO Port / Index: 3X5.3D
438 //Scratch Pad Register 4
440 // outb(0x39,0x03c4);//
441 //outb(1 << SLD0F3Val ,0x03c5);