Here's the VIA vx800 patch from OLPC.
[coreboot.git] / src / northbridge / via / vx800 / ddr2init / vx800 / UMARamSetting.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2009 One Laptop per Child, Association, Inc.
5  *
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.
9  *
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.
14  *
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
18  */
19
20 typedef struct __UMA_RAM_tag {
21         u16 DramSize;
22         u8 D0F3Val;
23         u8 D1F0Val;
24         u8 VgaPortVal;
25 } UMARAM;
26 #define UMARAM_512M     7
27 #define UMARAM_256M     6
28 #define UMARAM_128M     5
29 #define UMARAM_64M      4
30 #define UMARAM_32M      3
31 #define UMARAM_16M      2
32 #define UMARAM_8M       1
33 #define UMARAM_0M       0
34
35
36 #define FB_512M         0
37 #define FB_256M         0x40
38 #define FB_128M         0x60
39 #define FB_64M          0x70
40 #define FB_32M          0x78
41 #define FB_16M          0x7c
42 #define FB_8M           0x7E
43 #define FB_4M           0x7F
44
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
51
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}
62 };
63
64 void SetUMARam(void)
65 {
66 #if 1
67         u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
68         device_t vga_dev = PCI_DEV(0, 1, 0), d0f0_dev = PCI_DEV(0, 0, 0);
69         u8 ByteVal, temp;
70         UMARAM *pUMARamTable;
71         u16 UmaSize;
72         u8 SLD0F3Val, SLD1F0Val, VgaPortVal;
73         u32 RamSize, SLBase, Tmp;
74         u8 i;
75         PRINT_DEBUG_MEM("Entering vx800 SetUMARam.\n");
76         SLD0F3Val = 0;
77         SLD1F0Val = 0;
78         VgaPortVal = 0;
79
80
81         ByteVal = pci_read_config8(MEMCTRL, 0xa1);
82         ByteVal |= 0x80;
83         pci_write_config8(MEMCTRL, 0xa1, ByteVal);
84
85         //set VGA Timer
86         pci_write_config8(MEMCTRL, 0xa2, 0xee);
87
88         //set agp misc
89         //GFX Data Delay to Sync with Clock
90         pci_write_config8(MEMCTRL, 0xa4, 0x01);
91
92         //page register life timer
93         pci_write_config8(MEMCTRL, 0xa6, 0x76);
94
95         //GMINT and GFX relatate
96         //note Bit 3 VGA Enable
97         pci_write_config8(MEMCTRL, 0xa7, 0x8c);
98         // ByteVal = 0x4c;
99
100         //GMINT Misc.1
101         //pci_write_config8(MEMCTRL, 0xb0, 0x80);
102
103         //pci_write_config8(MEMCTRL, 0xb1, 0xaa);
104
105         //AGPCINT MISC
106         //pci_write_config8(MEMCTRL, 0xb2, 0x82);
107         //ByteVal = 0x8A;
108
109         //GMINT MISC.2
110         //disable read pass write
111         pci_write_config8(MEMCTRL, 0xb3, 0x9A);
112
113         //EPLL Register
114         //pci_write_config8(MEMCTRL, 0xb4, 0x04);
115
116         //enable CHA and CHB merge mode
117         pci_write_config8(MEMCTRL, 0xde, 0x06);
118
119         //if can get the value from setup interface, so get the value
120         //else use the default value
121         UmaSize = CONFIG_VIDEO_MB;
122
123         for (pUMARamTable = UMARamArr; pUMARamTable->DramSize != 0xffff;
124              pUMARamTable++) {
125                 if (UmaSize == pUMARamTable->DramSize) {
126                         SLD0F3Val = pUMARamTable->D0F3Val;
127                         SLD1F0Val = pUMARamTable->D1F0Val;
128                         VgaPortVal = pUMARamTable->VgaPortVal;
129                 }
130         }
131         //set SL size
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);
136
137
138 //      vga_dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_VGA, 0);
139
140         //RxB2 may be for S.L. and RxB1 may be for L. L. 
141         // It is different from Spec.
142         ByteVal = SLD1F0Val;
143         pci_write_config8(vga_dev, 0xb2, ByteVal);
144
145
146         //set M1 size
147         //ByteVal=pci_read_config8(MEMCTRL, 0xa3);
148         //ByteVal = 0x02;
149         //pci_write_config8(MEMCTRL, 0xa3, ByteVal);
150
151         PRINT_DEBUG_MEM("UMA setting - 3\n");
152
153
154
155
156         //Enable p2p  IO/mem
157         ByteVal = 0x07;
158         pci_write_config8(vga_dev, 0x04, ByteVal);
159
160
161
162
163         //must set SL and MMIO base, or else when enable GFX memory space, system will hang
164         //set S.L base
165         Tmp = pci_read_config32(vga_dev, 0x10);
166         Tmp = 0xfffffff8;
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);
171
172         //set MMIO base
173         Tmp = pci_read_config32(vga_dev, 0x14);
174         Tmp = 0xfffffffC;
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);
179
180
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);
186
187
188         //enable GFx memory space access control for S.L and mmio
189         ByteVal = pci_read_config8(d0f0_dev, 0xD4);
190         ByteVal |= 0x03;
191         //ByteVal |= 0x01;
192         pci_write_config8(d0f0_dev, 0xD4, ByteVal);
193
194
195         //enable Base VGA 16 Bits Decode
196         ByteVal = pci_read_config8(d0f0_dev, 0xfe);
197         ByteVal |= 0x10;
198         pci_write_config8(d0f0_dev, 0xfe, ByteVal);
199
200
201         //disable CHB L.L
202         //set VGA memory selection
203         ByteVal = pci_read_config8(vga_dev, 0xb0);
204         ByteVal &= 0xF8;
205         //ByteVal |= 0x01;
206         ByteVal |= 0x03;
207         pci_write_config8(vga_dev, 0xb0, ByteVal);
208
209         //set LL size
210
211         //enable memory access to SL,MMIO,LL and IO to 3B0~3BB,3C0 ~3DF
212         //ByteVal = 0x03;
213         //pci_write_config8(d0f0_dev, 0xc0, ByteVal);
214
215         //Turn on Graphic chip IO port port access
216         ByteVal = inb(0x03C3);
217         ByteVal |= 0x01;
218         outb(ByteVal, 0x03C3);
219
220         //Turn off Graphic chip Register protection
221         outb(0x10, 0x03C4);
222
223         ByteVal = inb(0x03C5);
224         ByteVal |= 0x01;
225         outb(ByteVal, 0x03C5);
226
227         //set VGA memory Frequence
228         //direct IO port 0x3DX to vga io space 0x3C2[0]
229         ByteVal = inb(0x03CC);
230         ByteVal |= 0x03;
231         outb(ByteVal, 0x03C2);
232         //  ByteVal=inb(0x03C2);
233         //   ByteVal |= 0x01;
234         //   outb(ByteVal,0x03C2);
235
236
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]
239         outb(0x3d, 0x03d4);
240
241         temp = pci_read_config8(MEMCTRL, 0x90);
242         temp = (u8) (temp & 0x07);
243         ByteVal = inb(0x03d5);
244         switch (temp) {
245         case 0:         //DIMMFREQ_200:
246                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x30);
247                 break;
248         case 1:         //DIMMFREQ_266:
249                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x40);
250                 break;
251         case 3:         //DIMMFREQ_400:
252                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x60);
253                 break;
254         case 4:         //DIMMFREQ_533:
255                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
256                 break;
257         case 5:         //DIMMFREQ_667:
258                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x80);
259                 break;
260         case 6:         //DIMMFREQ_800:
261                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x90);
262                 break;
263         default:
264                 ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
265                 break;
266         }
267         outb(ByteVal, 0x03d5);
268
269         // Set frame buffer size 
270         outb(0x39, 0x03c4);
271         outb(1 << SLD0F3Val, 0x03c5);
272
273 #endif
274         // Set S.L. size in GFX's register
275         outb(0x68, 0x03c4);
276         outb(VgaPortVal, 0x03c5);
277
278         //  ECLK Selection (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
279         // set 3C5.5A[0]=1, address maps to secondary resgiters
280         outb(0x5a, 0x03c4);
281         ByteVal = inb(0x03c5);
282         ByteVal |= 0x01;
283         outb(ByteVal, 0x03c5);
284
285         // Set 3D5.4C[7:6] (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
286         outb(0x4c, 0x03d4);
287         ByteVal = inb(0x03d5);
288         ByteVal = (ByteVal & 0x3F) | 0x80;
289         outb(ByteVal, 0x03d5);
290
291         // set 3C5.5A[0]=0, address maps to first resgiters
292         outb(0x5a, 0x03c4);
293         ByteVal = inb(0x03c5);
294         ByteVal &= 0xFE;
295         outb(ByteVal, 0x03c5);
296
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]);
301                 if (RamSize != 0)
302                         break;
303         }
304         //calculate SL Base Address
305         SLBase = (RamSize << 26) - (UmaSize << 20);
306
307
308         outb(0x6D, 0x03c4);
309         //SL Base[28:21] 
310         outb((u8) ((SLBase >> 21) & 0xFF), 0x03c5);
311
312         outb(0x6e, 0x03c4);
313         //SL Base[36:29]
314         outb((u8) ((SLBase >> 29) & 0xFF), 0x03c5);
315
316         outb(0x6f, 0x03c4);
317         outb(0x00, 0x03c5);
318
319         // Set SVID high byte
320         outb(0x36, 0x03c4);
321         outb(0x11, 0x03c5);
322
323         // Set SVID Low byte
324         outb(0x35, 0x03c4);
325         outb(0x06, 0x03c5);
326
327         // Set SID high byte
328         outb(0x38, 0x03c4);
329         outb(0x51, 0x03c5);
330
331         // Set SID Low byte
332         outb(0x37, 0x03c4);
333         outb(0x22, 0x03c5);
334
335         //start : For enable snapshot mode control
336         // program 3C5 for SNAPSHOT Mode control, set RxF3h=1Ah
337         outb(0xf3, 0x03c4);
338         ByteVal = inb(0x03c5);
339         ByteVal = (ByteVal & 0xE5) | 0x1A;
340         outb(ByteVal, 0x03c5);
341
342
343         outb(0xf3, 0x03d4);
344         ByteVal = inb(0x03d5);
345         ByteVal = (ByteVal & 0xE5) | 0x1A;
346         outb(ByteVal, 0x03d5);
347
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
363         };
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,
382         };
383
384
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,
410         };
411 #if 0
412 //for(i=0;i<0xc0;i++)
413         for (i = 0; i < 0x40; i++)      //
414         {
415                 outb(table3c0space[i], 0x03c0 + i);
416         }
417
418
419         for (i = 0; i < 0x70; i++) {
420                 outb(i, 0x03c4);
421                 outb(table3c43c5[i], 0x03c5);
422         }
423         for (i = 0; i < 0x88; i++) {
424                 outb(i, 0x03d4);
425                 outb(table3d43d5[i], 0x03d5);
426         }
427         outb(0x92, 0x03d4);
428         outb(0x80, 0x03d5);
429
430         outb(0xa3, 0x03d4);
431         outb(0x00, 0x03d5);
432
433         outb(0xe8, 0x03d4);
434         outb(0x40, 0x03d5);
435 #endif
436 //3d4 3d freq
437 //IO Port / Index: 3X5.3D
438 //Scratch Pad Register 4
439
440 //    outb(0x39,0x03c4);//
441         //outb(1 << SLD0F3Val ,0x03c5);
442 //
443 #endif
444
445 }