blob: f70cd9bb7902bf7f975dc3ae94bcc9c868eb83cf [file] [log] [blame]
Zheng Bao1088bbf2010-03-16 01:41:14 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 Advanced Micro Devices, 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/*
21 * for rs780 internal graphics device
22 * device id of internal grphics:
23 * RS780: 0x9610
24 * RS780C: 0x9611
25 * RS780M: 0x9612
26 * RS780MC:0x9613
27 * RS780E: 0x9615
Rudolf Marekf932c2e2010-04-05 19:21:18 +000028 * RS785G: 0x9710 - just works, not much tested
Zheng Bao40992d32010-12-31 01:46:12 +000029 * RS785C: 0x9711
30 * RS785M: 0x9712
31 * RS785MC:0x9713
32 * RS785D: 0x9714
Zheng Bao1088bbf2010-03-16 01:41:14 +000033 */
34#include <console/console.h>
35#include <device/device.h>
36#include <device/pci.h>
37#include <device/pci_ids.h>
38#include <device/pci_ops.h>
39#include <delay.h>
40#include <cpu/x86/msr.h>
41#include "rs780.h"
Wang Qing Pei543f7672010-08-17 11:11:09 +000042extern int is_dev3_present(void);
Zheng Baob63bdbe2010-03-23 06:46:01 +000043void set_pcie_reset(void);
44void set_pcie_dereset(void);
Zheng Bao1088bbf2010-03-16 01:41:14 +000045
Stefan Reinauere46c1c82010-04-15 23:01:59 +000046/* Trust the original resource allocation. Don't do it again. */
47#undef DONT_TRUST_RESOURCE_ALLOCATION
48//#define DONT_TRUST_RESOURCE_ALLOCATION
49
Zheng Bao1088bbf2010-03-16 01:41:14 +000050#define CLK_CNTL_INDEX 0x8
51#define CLK_CNTL_DATA 0xC
52
53/* The Integrated Info Table. */
54ATOM_INTEGRATED_SYSTEM_INFO_V2 vgainfo;
55
Stefan Reinauere46c1c82010-04-15 23:01:59 +000056#ifdef UNUSED_CODE
Zheng Bao1088bbf2010-03-16 01:41:14 +000057static u32 clkind_read(device_t dev, u32 index)
58{
59 u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
60
61 *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
62 return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
63}
Stefan Reinauere46c1c82010-04-15 23:01:59 +000064#endif
Zheng Bao1088bbf2010-03-16 01:41:14 +000065
66static void clkind_write(device_t dev, u32 index, u32 data)
67{
68 u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +000069 /* printk(BIOS_DEBUG, "gfx bar 2 %02x\n", gfx_bar2); */
Zheng Bao1088bbf2010-03-16 01:41:14 +000070
71 *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
72 *(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
73}
74
75/*
76* pci_dev_read_resources thinks it is a IO type.
77* We have to force it to mem type.
78*/
79static void rs780_gfx_read_resources(device_t dev)
80{
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +000081 printk(BIOS_DEBUG, "rs780_gfx_read_resources.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +000082
83 /* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
84 Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
85 which tells us it is a memory address base.
86 */
87 pci_write_config32(dev, 0x24, 0x00000000);
88
89 /* Get the normal pci resources of this device */
90 pci_dev_read_resources(dev);
91 compact_resources(dev);
92}
93
94typedef struct _MMIORANGE
95{
96 u32 Base;
97 u32 Limit;
98 u8 Attribute;
99} MMIORANGE;
100
101MMIORANGE MMIO[8], CreativeMMIO[8];
102
Zheng Bao1088bbf2010-03-16 01:41:14 +0000103#define CIM_STATUS u32
104#define CIM_SUCCESS 0x00000000
105#define CIM_ERROR 0x80000000
106#define CIM_UNSUPPORTED 0x80000001
107#define CIM_DISABLEPORT 0x80000002
108
109#define MMIO_ATTRIB_NP_ONLY 1
110#define MMIO_ATTRIB_BOTTOM_TO_TOP 1<<1
111#define MMIO_ATTRIB_SKIP_ZERO 1<<2
112
Stefan Reinauerd55e26f2010-04-25 13:54:30 +0000113#ifdef DONT_TRUST_RESOURCE_ALLOCATION
Stefan Reinauer5e33e822010-07-07 21:59:06 +0000114static MMIORANGE* AllocMMIO(MMIORANGE* pMMIO)
115{
116 int i;
117 for (i=0; i<8; i++) {
118 if (pMMIO[i].Limit == 0)
119 return &pMMIO[i];
120 }
121 return 0;
122}
123
124static void FreeMMIO(MMIORANGE* pMMIO)
125{
126 pMMIO->Base = 0;
127 pMMIO->Limit = 0;
128}
129
Zheng Baob63bdbe2010-03-23 06:46:01 +0000130static u32 SetMMIO(u32 Base, u32 Limit, u8 Attribute, MMIORANGE *pMMIO)
Zheng Bao1088bbf2010-03-16 01:41:14 +0000131{
132 int i;
133 MMIORANGE * TempRange;
134 for(i=0; i<8; i++)
135 {
136 if(pMMIO[i].Attribute != Attribute && Base >= pMMIO[i].Base && Limit <= pMMIO[i].Limit)
137 {
138 TempRange = AllocMMIO(pMMIO);
139 if(TempRange == 0) return 0x80000000;
140 TempRange->Base = Limit;
141 TempRange->Limit = pMMIO[i].Limit;
142 TempRange->Attribute = pMMIO[i].Attribute;
143 pMMIO[i].Limit = Base;
144 }
145 }
146 TempRange = AllocMMIO(pMMIO);
147 if(TempRange == 0) return 0x80000000;
148 TempRange->Base = Base;
149 TempRange->Limit = Limit;
150 TempRange->Attribute = Attribute;
151 return 0;
152}
153
Zheng Baob63bdbe2010-03-23 06:46:01 +0000154static u8 FinalizeMMIO(MMIORANGE *pMMIO)
Zheng Bao1088bbf2010-03-16 01:41:14 +0000155{
156 int i, j, n = 0;
157 for(i=0; i<8; i++)
158 {
159 if (pMMIO[i].Base == pMMIO[i].Limit)
160 {
161 FreeMMIO(&pMMIO[i]);
162 continue;
163 }
164 for(j=0; j<i; j++)
165 {
166 if (i!=j && pMMIO[i].Attribute == pMMIO[j].Attribute)
167 {
168 if (pMMIO[i].Base == pMMIO[j].Limit)
169 {
170 pMMIO[j].Limit = pMMIO[i].Limit;
171 FreeMMIO(&pMMIO[i]);
172 }
173 if (pMMIO[i].Limit == pMMIO[j].Base)
174 {
175 pMMIO[j].Base = pMMIO[i].Base;
176 FreeMMIO(&pMMIO[i]);
177 }
178 }
179 }
180 }
181 for (i=0; i<8; i++)
182 {
183 if (pMMIO[i].Limit != 0) n++;
184 }
185 return n;
186}
187
Zheng Baob63bdbe2010-03-23 06:46:01 +0000188static CIM_STATUS GetCreativeMMIO(MMIORANGE *pMMIO)
Zheng Bao1088bbf2010-03-16 01:41:14 +0000189{
190 CIM_STATUS Status = CIM_UNSUPPORTED;
191 u8 Bus, Dev, Reg, BusStart, BusEnd;
192 u32 Value;
193 device_t dev0x14 = dev_find_slot(0, PCI_DEVFN(0x14, 4));
194 device_t tempdev;
195 Value = pci_read_config32(dev0x14, 0x18);
196 BusStart = (Value >> 8) & 0xFF;
197 BusEnd = (Value >> 16) & 0xFF;
198 for(Bus = BusStart; Bus <= BusEnd; Bus++)
199 {
200 for(Dev = 0; Dev <= 0x1f; Dev++)
201 {
202 tempdev = dev_find_slot(Bus, Dev << 3);
203 Value = pci_read_config32(tempdev, 0);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000204 printk(BIOS_DEBUG, "Dev ID %x \n", Value);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000205 if((Value & 0xffff) == 0x1102)
206 {//Creative
207 //Found Creative SB
208 u32 MMIOStart = 0xffffffff;
209 u32 MMIOLimit = 0;
210 for(Reg = 0x10; Reg < 0x20; Reg+=4)
211 {
212 u32 BaseA, LimitA;
213 BaseA = pci_read_config32(tempdev, Reg);
214 Value = BaseA;
215 if(!(Value & 0x01))
216 {
217 Value = Value & 0xffffff00;
218 if(Value != 0)
219 {
220 if(MMIOStart > Value)
221 MMIOStart = Value;
222 LimitA = 0xffffffff;
223 //WritePCI(PciAddress,AccWidthUint32,&LimitA);
224 pci_write_config32(tempdev, Reg, LimitA);
225 //ReadPCI(PciAddress,AccWidthUint32,&LimitA);
226 LimitA = pci_read_config32(tempdev, Reg);
227 LimitA = Value + (~LimitA + 1);
228 //WritePCI(PciAddress,AccWidthUint32,&BaseA);
229 pci_write_config32(tempdev, Reg, BaseA);
230 if (LimitA > MMIOLimit)
231 MMIOLimit = LimitA;
232 }
233 }
234 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000235 printk(BIOS_DEBUG, " MMIOStart %x MMIOLimit %x \n", MMIOStart, MMIOLimit);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000236 if (MMIOStart < MMIOLimit)
237 {
238 Status = SetMMIO(MMIOStart>>8, MMIOLimit>>8, 0x80, pMMIO);
239 if(Status == CIM_ERROR) return Status;
240 }
241 }
242 }
243 }
244 if(Status == CIM_SUCCESS)
245 {
246 //Lets optimize MMIO
247 if(FinalizeMMIO(pMMIO) > 4)
248 {
249 Status = CIM_ERROR;
250 }
251 }
252
253 return Status;
254}
255
Zheng Baob63bdbe2010-03-23 06:46:01 +0000256static void ProgramMMIO(MMIORANGE *pMMIO, u8 LinkID, u8 Attribute)
Zheng Bao1088bbf2010-03-16 01:41:14 +0000257{
258 int i, j, n = 7;
259 device_t k8_f1;
Zheng Bao1088bbf2010-03-16 01:41:14 +0000260
261 k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
262
263 for(i = 0; i < 8; i++)
264 {
265 int k = 0, MmioReg;
266 u32 Base = 0;
267 u32 Limit = 0;
268 for(j = 0; j < 8; j++)
269 {
270 if (Base < pMMIO[j].Base)
271 {
272 Base = pMMIO[j].Base;
273 k = j;
274 }
275 }
276 if(pMMIO[k].Limit != 0)
277 {
278 if(Attribute & MMIO_ATTRIB_NP_ONLY && pMMIO[k].Attribute == 0 )
279 {
280 Base = 0;
281 }
282 else
283 {
284 Base = pMMIO[k].Base | 0x3;
285 Limit= ((pMMIO[k].Limit - 1) & 0xffffff00) | pMMIO[k].Attribute | (LinkID << 4);
286 }
287 FreeMMIO(&pMMIO[k]);
288 }
289 if (Attribute & MMIO_ATTRIB_SKIP_ZERO && Base == 0 && Limit == 0) continue;
290 MmioReg = (Attribute & MMIO_ATTRIB_BOTTOM_TO_TOP)?n:(7-n);
291 n--;
292 //RWPCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x80+MmioReg*8),AccWidthUint32 |S3_SAVE,0x0,0x0);
293 pci_write_config32(k8_f1, 0x80+MmioReg*8, 0);
294
295 //WritePCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x84+MmioReg*8),AccWidthUint32 |S3_SAVE,&Limit);
296 pci_write_config32(k8_f1, 0x84+MmioReg*8, Limit);
297
298 //WritePCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x80+MmioReg*8),AccWidthUint32 |S3_SAVE,&Base);
299 pci_write_config32(k8_f1, 0x80+MmioReg*8, Base);
300 }
301}
Stefan Reinauere46c1c82010-04-15 23:01:59 +0000302#endif
Zheng Bao1088bbf2010-03-16 01:41:14 +0000303
Kerry Shefaafd142011-05-07 08:51:32 +0000304#define GFX_CONFIG_DDI1 0x04
305#define GFX_CONFIG_DDI2 0x08
306#define GFX_CONFIG_DDI (GFX_CONFIG_DDI1 | GFX_CONFIG_DDI2)
307
308/**
309 * Force poweron pads for lanes used for DDI
310 * reference CIMx PCIEL_PowerOnDDILanes()
311 *
312 * Inactive B_PRX_PDNB_FDIS B_PTX_PDNB_FDIS
313 * Lanes
314 * Lanes 0-1 Bit 8 Bit 0
315 * Lanes 2-3 Bit 9 Bit 1
316 * Lanes 4-5 Bit 10 Bit 2
317 * Lanes 6-7 Bit 11 Bit 3
318 * Lanes 8-9 Bit 12 Bit 4
319 * Lanes 10-11 Bit 13 Bit 5
320 * Lanes 12-13 Bit 14 Bit 6
321 * Lanes 14-15 Bit 15 Bit 7
322 */
323static void poweron_ddi_lanes(device_t nb_dev)
324{
325 u8 i;
326 u32 gfx_cfg = 0;
327 u32 ddi_pads = 0;
328
329 ddi_pads = ~(nbpcie_ind_read_index(nb_dev, 0x65)); /* save original setting */
330 gfx_cfg = nbmisc_read_index(nb_dev, 0x74);
331 for (i = 0; i < 3 ; i++) {
332 if (gfx_cfg & GFX_CONFIG_DDI) {
333 ddi_pads |= (3 << (i * 2));
334 }
335 gfx_cfg >>= 8;
336 }
337 ddi_pads |= ddi_pads << 8; /* both TX and RX */
338 nbpcie_ind_write_index(nb_dev, 0x65, ~ddi_pads);
339}
340
Zheng Bao1088bbf2010-03-16 01:41:14 +0000341static void internal_gfx_pci_dev_init(struct device *dev)
342{
343 unsigned char * bpointer;
344 volatile u32 * GpuF0MMReg;
345 volatile u32 * pointer;
346 int i;
347 u16 command;
Scott Duplichan88dc5312010-11-24 00:39:44 +0000348 u32 value;
Zheng Bao1088bbf2010-03-16 01:41:14 +0000349 u16 deviceid, vendorid;
350 device_t nb_dev = dev_find_slot(0, 0);
351 device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
Zheng Bao1088bbf2010-03-16 01:41:14 +0000352 device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
Scott Duplichan88dc5312010-11-24 00:39:44 +0000353 static const u8 ht_freq_lookup [] = {2, 0, 4, 0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 0, 0, 28, 30, 32};
354 static const u8 ht_width_lookup [] = {8, 16, 0, 0, 2, 4, 0, 0};
355 static const u16 memclk_lookup_fam0F [] = {100, 0, 133, 0, 0, 166, 0, 200};
356 static const u16 memclk_lookup_fam10 [] = {200, 266, 333, 400, 533, 667, 800, 800};
Zheng Bao1088bbf2010-03-16 01:41:14 +0000357
Zheng Baob63bdbe2010-03-23 06:46:01 +0000358 /* We definetely will use this in future. Just leave it here. */
359 /*struct southbridge_amd_rs780_config *cfg =
360 (struct southbridge_amd_rs780_config *)dev->chip_info;*/
Zheng Bao1088bbf2010-03-16 01:41:14 +0000361
362 deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
363 vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +0000364 printk(BIOS_DEBUG, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
Zheng Bao1088bbf2010-03-16 01:41:14 +0000365 deviceid, vendorid);
366
367 command = pci_read_config16(dev, 0x04);
368 command |= 0x7;
369 pci_write_config16(dev, 0x04, command);
370
371 /* Clear vgainfo. */
372 bpointer = (unsigned char *) &vgainfo;
373 for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i++)
374 {
375 *bpointer = 0;
376 bpointer++;
377 }
378
379 GpuF0MMReg = (u32 *)pci_read_config32(dev, 0x18);
380
381 /* GFX_InitFBAccess. */
382 value = nbmc_read_index(nb_dev, 0x10);
383 *(GpuF0MMReg + 0x2000/4) = 0x11;
384 *(GpuF0MMReg + 0x2180/4) = ((value&0xff00)>>8)|((value&0xff000000)>>8);
Zheng Bao5d6aede2010-06-03 07:51:09 +0000385 *(GpuF0MMReg + 0x2c04/4) = ((value&0xff00)<<8);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000386 *(GpuF0MMReg + 0x5428/4) = ((value&0xffff0000)+0x10000)-((value&0xffff)<<16);
Scott Duplichan88dc5312010-11-24 00:39:44 +0000387 *(GpuF0MMReg + 0xF774/4) = 0xffffffff;
388 *(GpuF0MMReg + 0xF770/4) = 0x00000001;
Zheng Bao1088bbf2010-03-16 01:41:14 +0000389 *(GpuF0MMReg + 0x2000/4) = 0x00000011;
390 *(GpuF0MMReg + 0x200c/4) = 0x00000020;
391 *(GpuF0MMReg + 0x2010/4) = 0x10204810;
392 *(GpuF0MMReg + 0x2010/4) = 0x00204810;
393 *(GpuF0MMReg + 0x2014/4) = 0x10408810;
394 *(GpuF0MMReg + 0x2014/4) = 0x00408810;
395 *(GpuF0MMReg + 0x2414/4) = 0x00000080;
396 *(GpuF0MMReg + 0x2418/4) = 0x84422415;
397 *(GpuF0MMReg + 0x2418/4) = 0x04422415;
398 *(GpuF0MMReg + 0x5490/4) = 0x00000001;
399 *(GpuF0MMReg + 0x7de4/4) |= (1<<3) | (1<<4);
400 /* Force allow LDT_STOP Cool'n'Quiet workaround. */
401 *(GpuF0MMReg + 0x655c/4) |= 1<<4;
Scott Duplichan88dc5312010-11-24 00:39:44 +0000402
Zheng Bao6b8c7212010-11-30 02:05:17 +0000403 // disable write combining, needed for stability
404 // reference bios does this only for RS780 rev A11
405 // need to figure out why we need it for all revs
Scott Duplichan88dc5312010-11-24 00:39:44 +0000406 *(GpuF0MMReg + 0x2000/4) = 0x00000010;
407 *(GpuF0MMReg + 0x2408/4) = 1 << 9;
408 *(GpuF0MMReg + 0x2000/4) = 0x00000011;
409
Zheng Bao1088bbf2010-03-16 01:41:14 +0000410 /* GFX_InitFBAccess finished. */
411
Patrick Georgif8f00622012-05-05 15:50:17 +0200412#if CONFIG_GFXUMA /* for UMA mode. */
Scott Duplichan88dc5312010-11-24 00:39:44 +0000413 /* GFX_StartMC. */
414 set_nbmc_enable_bits(nb_dev, 0x02, 0x00000000, 0x80000000);
415 set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000001);
416 set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000004);
417 set_nbmc_enable_bits(nb_dev, 0x01, 0x00040000, 0x00000000);
418 set_nbmc_enable_bits(nb_dev, 0xB1, 0xFFFF0000, 0x00000040);
419 set_nbmc_enable_bits(nb_dev, 0xC3, 0x00000000, 0x00000001);
420 set_nbmc_enable_bits(nb_dev, 0x07, 0xFFFFFFFF, 0x00000018);
421 set_nbmc_enable_bits(nb_dev, 0x06, 0xFFFFFFFF, 0x00000102);
422 set_nbmc_enable_bits(nb_dev, 0x09, 0xFFFFFFFF, 0x40000008);
423 set_nbmc_enable_bits(nb_dev, 0x06, 0x00000000, 0x80000000);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000424 /* GFX_StartMC finished. */
425#else
426 /* for SP mode. */
427 set_nbmc_enable_bits(nb_dev, 0xaa, 0xf0, 0x30);
428 set_nbmc_enable_bits(nb_dev, 0xce, 0xf0, 0x30);
429 set_nbmc_enable_bits(nb_dev, 0xca, 0xff000000, 0x47000000);
430 set_nbmc_enable_bits(nb_dev, 0xcb, 0x3f000000, 0x01000000);
431 set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<0);
432 set_nbmc_enable_bits(nb_dev, 0x04, 0, 1<<31);
433 set_nbmc_enable_bits(nb_dev, 0xb4, 0x3f, 0x3f);
434 set_nbmc_enable_bits(nb_dev, 0xb4, 0, 1<<6);
435 set_nbmc_enable_bits(nb_dev, 0xc3, 1<<11, 0);
436 set_nbmc_enable_bits(nb_dev, 0xa0, 1<<29, 0);
437 nbmc_write_index(nb_dev, 0xa4, 0x3484576f);
438 nbmc_write_index(nb_dev, 0xa5, 0x222222df);
439 nbmc_write_index(nb_dev, 0xa6, 0x00000000);
440 nbmc_write_index(nb_dev, 0xa7, 0x00000000);
441 set_nbmc_enable_bits(nb_dev, 0xc3, 1<<8, 0);
442 udelay(10);
443 set_nbmc_enable_bits(nb_dev, 0xc3, 1<<9, 0);
444 udelay(10);
445 set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<2);
446 udelay(200);
447 set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<3);
448 set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<31);
449 udelay(500);
450 set_nbmc_enable_bits(nb_dev, 0x02, 0, 1<<31);
451 set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<30);
452 set_nbmc_enable_bits(nb_dev, 0xa0, 1<<31, 0);
453 set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<29);
454 nbmc_write_index(nb_dev, 0xa4, 0x23484576);
455 nbmc_write_index(nb_dev, 0xa5, 0x00000000);
456 nbmc_write_index(nb_dev, 0xa6, 0x00000000);
457 nbmc_write_index(nb_dev, 0xa7, 0x00000000);
458 /* GFX_StartMC finished. */
459
460 /* GFX_SPPowerManagment, don't care for new. */
461 /* Post MC Init table programming. */
462 set_nbmc_enable_bits(nb_dev, 0xac, ~(0xfffffff0), 0x0b);
463
464 /* Do we need Write and Read Calibration? */
465 /* GFX_Init finished. */
466#endif
467
468 /* GFX_InitIntegratedInfo. */
469 /* fill the Integrated Info Table. */
470 vgainfo.sHeader.usStructureSize = sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2);
471 vgainfo.sHeader.ucTableFormatRevision = 1;
472 vgainfo.sHeader.ucTableContentRevision = 2;
473
Patrick Georgif8f00622012-05-05 15:50:17 +0200474#if !CONFIG_GFXUMA /* SP mode. */
Scott Duplichan88dc5312010-11-24 00:39:44 +0000475 // Side port support is incomplete, do not use it
476 // These parameters must match the motherboard
Zheng Bao1088bbf2010-03-16 01:41:14 +0000477 vgainfo.ulBootUpSidePortClock = 667*100;
Scott Duplichan88dc5312010-11-24 00:39:44 +0000478 vgainfo.ucMemoryType = 3; // 3=ddr3 sp mem, 2=ddr2 sp mem
Zheng Bao1088bbf2010-03-16 01:41:14 +0000479 vgainfo.ulMinSidePortClock = 333*100;
480#endif
481
Scott Duplichan88dc5312010-11-24 00:39:44 +0000482 vgainfo.ulBootUpEngineClock = 500 * 100; // setup option on reference BIOS, 500 is default
483
484 // find the DDR memory frequency
485 if (is_family10h()) {
486 value = pci_read_config32(k8_f2, 0x94); // read channel 0 DRAM Configuration High Register
487 if (extractbit(value, 14)) // if channel 0 disabled, channel 1 must have memory
488 value = pci_read_config32(k8_f2, 0x194);// read channel 1 DRAM Configuration High Register
489 vgainfo.ulBootUpUMAClock = memclk_lookup_fam10 [extractbits (value, 0, 2)] * 100;
490 }
491 if (is_family0Fh()) {
492 value = pci_read_config32(k8_f2, 0x94);
493 vgainfo.ulBootUpUMAClock = memclk_lookup_fam0F [extractbits (value, 20, 22)] * 100;
494 }
495
Zheng Bao1088bbf2010-03-16 01:41:14 +0000496 /* UMA Channel Number: 1 or 2. */
Scott Duplichan88dc5312010-11-24 00:39:44 +0000497 vgainfo.ucUMAChannelNumber = 1;
498 if (is_family0Fh()) {
499 value = pci_read_config32(k8_f2, 0x90);
500 if (extractbit(value, 11)) // 128-bit mode
501 vgainfo.ucUMAChannelNumber = 2;
502 }
503 if (is_family10h()) {
504 u32 dch0 = pci_read_config32(k8_f2, 0x94);
505 u32 dch1 = pci_read_config32(k8_f2, 0x194);
506 if (extractbit(dch0, 14) == 0 && extractbit(dch1, 14) == 0) { // both channels enabled
507 value = pci_read_config32(k8_f2, 0x110);
508 if (extractbit(value, 4)) // ganged mode
509 vgainfo.ucUMAChannelNumber = 2;
510 }
511 }
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700512
Scott Duplichan88dc5312010-11-24 00:39:44 +0000513 // processor type
514 if (is_family0Fh())
515 vgainfo.ulCPUCapInfo = 3;
516 if (is_family10h())
517 vgainfo.ulCPUCapInfo = 2;
Liu Taodfecd272010-10-17 21:34:45 +0000518
519 /* HT speed */
Scott Duplichan88dc5312010-11-24 00:39:44 +0000520 value = pci_read_config8(nb_dev, 0xd1);
521 value = ht_freq_lookup [value] * 100; // HT link frequency in MHz
522 vgainfo.ulHTLinkFreq = value * 100; // HT frequency in units of 100 MHz
523 vgainfo.ulHighVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
524 vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
525
526 if (value <= 1800)
527 vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
528 else {
529 int sblink, cpuLnkFreqCap, nbLnkFreqCap;
530 value = pci_read_config32(k8_f0, 0x64);
531 sblink = extractbits(value, 8, 10);
532 cpuLnkFreqCap = pci_read_config16(k8_f0, 0x8a + sblink * 0x20);
533 nbLnkFreqCap = pci_read_config16(nb_dev, 0xd2);
534 if (cpuLnkFreqCap & nbLnkFreqCap & (1 << 10)) // if both 1800 MHz capable
535 vgainfo.ulLowVoltageHTLinkFreq = 1800*100;
536 }
Zheng Bao1088bbf2010-03-16 01:41:14 +0000537
538 /* HT width. */
Scott Duplichan88dc5312010-11-24 00:39:44 +0000539 value = pci_read_config8(nb_dev, 0xcb);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700540 vgainfo.usMinDownStreamHTLinkWidth =
541 vgainfo.usMaxDownStreamHTLinkWidth =
542 vgainfo.usMinUpStreamHTLinkWidth =
Scott Duplichan88dc5312010-11-24 00:39:44 +0000543 vgainfo.usMaxUpStreamHTLinkWidth =
544 vgainfo.usMinHTLinkWidth =
545 vgainfo.usMaxHTLinkWidth = ht_width_lookup [extractbits(value, 0, 2)];
546
547 if (is_family0Fh()) {
548 vgainfo.usUMASyncStartDelay = 322;
549 vgainfo.usUMADataReturnTime = 286;
550 }
551
552 if (is_family10h()) {
553 static u16 t0mult_lookup [] = {10, 50, 200, 2000};
554 int t0time, t0scale;
555 value = pci_read_config32(k8_f0, 0x16c);
556 t0time = extractbits(value, 0, 3);
557 t0scale = extractbits(value, 4, 5);
558 vgainfo.usLinkStatusZeroTime = t0mult_lookup [t0scale] * t0time;
559 vgainfo.usUMASyncStartDelay = 100;
560 if (vgainfo.ulHTLinkFreq < 1000 * 100) { // less than 1000 MHz
561 vgainfo.usUMADataReturnTime = 300;
562 vgainfo.usLinkStatusZeroTime = 6 * 100; // 6us for GH in HT1 mode
563 }
564 else {
565 int lssel;
566 value = pci_read_config32(nb_dev, 0xac);
567 lssel = extractbits (value, 7, 8);
568 vgainfo.usUMADataReturnTime = 1300;
569 if (lssel == 0) vgainfo.usUMADataReturnTime = 150;
570 }
571 }
Zheng Bao1088bbf2010-03-16 01:41:14 +0000572
Kerry Shefaafd142011-05-07 08:51:32 +0000573 /* Poweron DDI Lanes */
574 poweron_ddi_lanes(nb_dev);
575
Denis 'GNUtoo' Carikli7519d772011-11-27 13:43:16 +0100576 printk(BIOS_DEBUG,"vgainfo:\n"
577 " ulBootUpEngineClock:%lu \n"
578 " ulBootUpUMAClock:%lu \n"
579 " ulBootUpSidePortClock:%lu \n"
580 " ulMinSidePortClock:%lu \n"
581 " ulSystemConfig:%lu \n"
582 " ulBootUpReqDisplayVector:%lu \n"
583 " ulOtherDisplayMisc:%lu \n"
584 " ulDDISlot1Config:%lu \n"
585 " ulDDISlot2Config:%lu \n"
586
587 " ucMemoryType:%u \n"
588 " ucUMAChannelNumber:%u \n"
589 " ucDockingPinBit:%u \n"
590 " ucDockingPinPolarity:%u \n"
591
592 " ulDockingPinCFGInfo:%lu \n"
593 " ulCPUCapInfo: %lu \n"
594
595 " usNumberOfCyclesInPeriod:%hu \n"
596 " usMaxNBVoltage:%hu \n"
597 " usMinNBVoltage:%hu \n"
598 " usBootUpNBVoltage:%hu \n"
599
600 " ulHTLinkFreq:%lu \n"
601
602 " usMinHTLinkWidth:%hu \n"
603 " usMaxHTLinkWidth:%hu \n"
604 " usUMASyncStartDelay:%hu \n"
605 " usUMADataReturnTime:%hu \n"
606 " usLinkStatusZeroTime:%hu \n"
607
608 " ulHighVoltageHTLinkFreq:%lu \n"
609 " ulLowVoltageHTLinkFreq:%lu \n"
610
611 " usMaxUpStreamHTLinkWidth:%hu \n"
612 " usMaxDownStreamHTLinkWidth:%hu \n"
613 " usMinUpStreamHTLinkWidth:%hu \n"
614 " usMinDownStreamHTLinkWidth:%hu \n",
615
616 (unsigned long)vgainfo.ulBootUpEngineClock,
617 (unsigned long)vgainfo.ulBootUpUMAClock,
618 (unsigned long)vgainfo.ulBootUpSidePortClock,
619 (unsigned long)vgainfo.ulMinSidePortClock,
620 (unsigned long)vgainfo.ulSystemConfig,
621 (unsigned long)vgainfo.ulBootUpReqDisplayVector,
622 (unsigned long)vgainfo.ulOtherDisplayMisc,
623 (unsigned long)vgainfo.ulDDISlot1Config,
624 (unsigned long)vgainfo.ulDDISlot2Config,
625
626 vgainfo.ucMemoryType,
627 vgainfo.ucUMAChannelNumber,
628 vgainfo.ucDockingPinBit,
629 vgainfo.ucDockingPinPolarity,
630
631 (unsigned long)vgainfo.ulDockingPinCFGInfo,
632 (unsigned long)vgainfo.ulCPUCapInfo,
633
634 vgainfo.usNumberOfCyclesInPeriod,
635 vgainfo.usMaxNBVoltage,
636 vgainfo.usMinNBVoltage,
637 vgainfo.usBootUpNBVoltage,
638
639 (unsigned long)vgainfo.ulHTLinkFreq,
640
641 vgainfo.usMinHTLinkWidth,
642 vgainfo.usMaxHTLinkWidth,
643 vgainfo.usUMASyncStartDelay,
644 vgainfo.usUMADataReturnTime,
645 vgainfo.usLinkStatusZeroTime,
646
647 (unsigned long)vgainfo.ulHighVoltageHTLinkFreq,
648 (unsigned long)vgainfo.ulLowVoltageHTLinkFreq,
649
650 vgainfo.usMaxUpStreamHTLinkWidth,
651 vgainfo.usMaxDownStreamHTLinkWidth,
652 vgainfo.usMinUpStreamHTLinkWidth,
653 vgainfo.usMinDownStreamHTLinkWidth);
654
655
Zheng Bao1088bbf2010-03-16 01:41:14 +0000656 /* Transfer the Table to VBIOS. */
657 pointer = (u32 *)&vgainfo;
658 for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i+=4)
659 {
Patrick Georgie1667822012-05-05 15:29:32 +0200660#if CONFIG_GFXUMA
Scott Duplichan88dc5312010-11-24 00:39:44 +0000661 *GpuF0MMReg = 0x80000000 + uma_memory_size - 512 + i;
Zheng Bao1088bbf2010-03-16 01:41:14 +0000662#else
663 *GpuF0MMReg = 0x80000000 + 0x8000000 - 512 + i;
664#endif
665 *(GpuF0MMReg+1) = *pointer++;
666 }
667
668 /* GFX_InitLate. */
669 {
Scott Duplichan88dc5312010-11-24 00:39:44 +0000670 u32 temp;
671 temp = pci_read_config8(dev, 0x4);
672 //temp &= ~1; /* CIM clears this bit. Strangely, I can'd. */
673 temp |= 1<<1|1<<2;
674 pci_write_config8(dev, 0x4, temp);
675
676 // if the GFX debug bar is writable, then it has
677 // been programmed and can be safely enabled now
678 temp = pci_read_config32(nb_dev, 0x8c);
679
680 // if bits 1 (intgfx_enable) and 9 (gfx_debug_bar_enable)
681 // then enable gfx debug bar (set gxf_debug_decode_enable)
682 if (temp & 0x202)
683 temp |= (1 << 10);
684 pci_write_config32(nb_dev, 0x8c, temp);
685
Zheng Bao1088bbf2010-03-16 01:41:14 +0000686 }
687
Stefan Reinauere46c1c82010-04-15 23:01:59 +0000688#ifdef DONT_TRUST_RESOURCE_ALLOCATION
Zheng Bao1088bbf2010-03-16 01:41:14 +0000689 /* NB_SetupMGMMIO. */
690
691 /* clear MMIO and CreativeMMIO. */
692 bpointer = (unsigned char *)MMIO;
693 for(i=0; i<sizeof(MMIO); i++)
694 {
695 *bpointer = 0;
696 bpointer++;
697 }
698 bpointer = (unsigned char *)CreativeMMIO;
699 for(i=0; i<sizeof(CreativeMMIO); i++)
700 {
701 *bpointer = 0;
702 bpointer++;
703 }
704
705 /* Set MMIO ranges in K8. */
706 /* Set MMIO TOM - 4G. */
707 SetMMIO(0x400<<12, 0x1000000, 0x80, &MMIO[0]);
708 /* Set MMIO for VGA Legacy FB. */
709 SetMMIO(0xa00, 0xc00, 0x80, &MMIO[0]);
710
711 /* Set MMIO for non prefetchable P2P. */
712 temp = pci_read_config32(dev0x14, 0x20);
713 Base32 = (temp & 0x0fff0) << 8;
714 Limit32 = ((temp & 0x0fff00000) + 0x100000) >> 8;
715 if(Base32 < Limit32)
716 {
717 Status = GetCreativeMMIO(&CreativeMMIO[0]);
718 if(Status != CIM_ERROR)
719 SetMMIO(Base32, Limit32, 0x0, &MMIO[0]);
720 }
721 /* Set MMIO for prefetchable P2P. */
722 if(Status != CIM_ERROR)
723 {
724 temp = pci_read_config32(dev0x14, 0x24);
725
726 Base32 = (temp & 0x0fff0) <<8;
727 Limit32 = ((temp & 0x0fff00000) + 0x100000) >> 8;
728 if(Base32 < Limit32)
729 SetMMIO(Base32, Limit32, 0x0, &MMIO[0]);
730 }
731
732 FinalizeMMIO(&MMIO[0]);
733
734 ProgramMMIO(&CreativeMMIO[0], 0, MMIO_ATTRIB_NP_ONLY);
735 ProgramMMIO(&MMIO[0], 0, MMIO_ATTRIB_NP_ONLY | MMIO_ATTRIB_BOTTOM_TO_TOP | MMIO_ATTRIB_SKIP_ZERO);
736#endif
737
738 pci_dev_init(dev);
739
740 /* clk ind */
741 clkind_write(dev, 0x08, 0x01);
742 clkind_write(dev, 0x0C, 0x22);
743 clkind_write(dev, 0x0F, 0x0);
744 clkind_write(dev, 0x11, 0x0);
745 clkind_write(dev, 0x12, 0x0);
746 clkind_write(dev, 0x14, 0x0);
747 clkind_write(dev, 0x15, 0x0);
748 clkind_write(dev, 0x16, 0x0);
749 clkind_write(dev, 0x17, 0x0);
750 clkind_write(dev, 0x18, 0x0);
751 clkind_write(dev, 0x19, 0x0);
752 clkind_write(dev, 0x1A, 0x0);
753 clkind_write(dev, 0x1B, 0x0);
754 clkind_write(dev, 0x1C, 0x0);
755 clkind_write(dev, 0x1D, 0x0);
756 clkind_write(dev, 0x1E, 0x0);
757 clkind_write(dev, 0x26, 0x0);
758 clkind_write(dev, 0x27, 0x0);
759 clkind_write(dev, 0x28, 0x0);
760 clkind_write(dev, 0x5C, 0x0);
761}
762
763
764/*
765* Set registers in RS780 and CPU to enable the internal GFX.
766* Please refer to CIM source code and BKDG.
767*/
Zheng Bao1088bbf2010-03-16 01:41:14 +0000768
769static void rs780_internal_gfx_enable(device_t dev)
770{
771 u32 l_dword;
772 int i;
Zheng Bao1088bbf2010-03-16 01:41:14 +0000773 device_t nb_dev = dev_find_slot(0, 0);
774 msr_t sysmem;
775
Patrick Georgie1667822012-05-05 15:29:32 +0200776#if !CONFIG_GFXUMA
Zheng Bao1088bbf2010-03-16 01:41:14 +0000777 u32 FB_Start, FB_End;
778#endif
779
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +0000780 printk(BIOS_DEBUG, "rs780_internal_gfx_enable dev = 0x%p, nb_dev = 0x%p.\n", dev, nb_dev);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000781
Zheng Bao1088bbf2010-03-16 01:41:14 +0000782 /* The system top memory in 780. */
Marc Jones484281b2011-04-12 01:12:46 +0000783 sysmem = rdmsr(0xc001001a);
784 printk(BIOS_DEBUG, "Sysmem TOM = %x_%x\n", sysmem.hi, sysmem.lo);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000785 pci_write_config32(nb_dev, 0x90, sysmem.lo);
Marc Jones484281b2011-04-12 01:12:46 +0000786
787 sysmem = rdmsr(0xc001001D);
788 printk(BIOS_DEBUG, "Sysmem TOM2 = %x_%x\n", sysmem.hi, sysmem.lo);
789 htiu_write_index(nb_dev, 0x31, sysmem.hi);
790 htiu_write_index(nb_dev, 0x30, sysmem.lo | 1);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000791
792 /* Disable external GFX and enable internal GFX. */
793 l_dword = pci_read_config32(nb_dev, 0x8c);
794 l_dword &= ~(1<<0);
795 l_dword |= 1<<1;
796 pci_write_config32(nb_dev, 0x8c, l_dword);
797
798 /* NB_SetDefaultIndexes */
799 pci_write_config32(nb_dev, 0x94, 0x7f);
800 pci_write_config32(nb_dev, 0x60, 0x7f);
801 pci_write_config32(nb_dev, 0xe0, 0);
802
803 /* NB_InitEarlyNB finished. */
804
805 /* LPC DMA Deadlock workaround? */
806 /* GFX_InitCommon*/
Stefan Reinauer5e33e822010-07-07 21:59:06 +0000807 device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
Zheng Bao1088bbf2010-03-16 01:41:14 +0000808 l_dword = pci_read_config32(k8_f0, 0x68);
809 l_dword &= ~(3 << 21);
810 l_dword |= (1 << 21);
811 pci_write_config32(k8_f0, 0x68, l_dword);
812
813 /* GFX_InitCommon. */
814 nbmc_write_index(nb_dev, 0x23, 0x00c00010);
815 set_nbmc_enable_bits(nb_dev, 0x16, 1<<15, 1<<15);
816 set_nbmc_enable_bits(nb_dev, 0x25, 0xffffffff, 0x111f111f);
817 set_htiu_enable_bits(nb_dev, 0x37, 1<<24, 1<<24);
818
Patrick Georgie1667822012-05-05 15:29:32 +0200819#if CONFIG_GFXUMA
Zheng Bao1088bbf2010-03-16 01:41:14 +0000820 /* GFX_InitUMA. */
821 /* Copy CPU DDR Controller to NB MC. */
Scott Duplichan88dc5312010-11-24 00:39:44 +0000822 device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
Stefan Reinauer5e33e822010-07-07 21:59:06 +0000823 device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
Scott Duplichan88dc5312010-11-24 00:39:44 +0000824 device_t k8_f4 = dev_find_slot(0, PCI_DEVFN(0x18, 4));
Zheng Bao1088bbf2010-03-16 01:41:14 +0000825 for (i = 0; i < 12; i++)
826 {
827 l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
828 nbmc_write_index(nb_dev, 0x30 + i, l_dword);
829 }
830
831 l_dword = pci_read_config32(k8_f2, 0x80);
832 nbmc_write_index(nb_dev, 0x3c, l_dword);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000833 l_dword = pci_read_config32(k8_f2, 0x94);
Scott Duplichan88dc5312010-11-24 00:39:44 +0000834 set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<22))<<16);
835 set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<< 8))<<17);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000836 l_dword = pci_read_config32(k8_f2, 0x90);
Scott Duplichan88dc5312010-11-24 00:39:44 +0000837 set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<10))<<18);
838 if (is_family10h())
839 {
840 for (i = 0; i < 12; i++)
841 {
842 l_dword = pci_read_config32(k8_f2, 0x140 + i * 4);
843 nbmc_write_index(nb_dev, 0x3d + i, l_dword);
844 }
845
846 l_dword = pci_read_config32(k8_f2, 0x180);
847 nbmc_write_index(nb_dev, 0x49, l_dword);
848 l_dword = pci_read_config32(k8_f2, 0x194);
849 set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<22))<<16);
850 set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<< 8))<<17);
851 l_dword = pci_read_config32(k8_f2, 0x190);
852 set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<10))<<18);
853
854 l_dword = pci_read_config32(k8_f2, 0x110);
855 nbmc_write_index(nb_dev, 0x4a, l_dword);
856 l_dword = pci_read_config32(k8_f2, 0x114);
857 nbmc_write_index(nb_dev, 0x4b, l_dword);
858 l_dword = pci_read_config32(k8_f4, 0x44);
859 set_nbmc_enable_bits(nb_dev, 0x4a, 0, !!(l_dword & (1<<22))<<24);
860 l_dword = pci_read_config32(k8_f1, 0x40);
861 nbmc_write_index(nb_dev, 0x4c, l_dword);
862 l_dword = pci_read_config32(k8_f1, 0xf0);
863 nbmc_write_index(nb_dev, 0x4d, l_dword);
864 }
865
Zheng Bao1088bbf2010-03-16 01:41:14 +0000866
867 /* Set UMA in the 780 side. */
868 /* UMA start address, size. */
Rudolf Marekae7a4252010-08-17 06:18:47 +0000869 /* The UMA starts at 0xC0000000 of internal RS780 address space
870 [31:16] addr of last byte | [31:16] addr of first byte
871 */
872 nbmc_write_index(nb_dev, 0x10, ((uma_memory_size - 1 + 0xC0000000) & (~0xffff)) | 0xc000);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000873 nbmc_write_index(nb_dev, 0x11, uma_memory_base);
874 nbmc_write_index(nb_dev, 0x12, 0);
Scott Duplichan88dc5312010-11-24 00:39:44 +0000875 nbmc_write_index(nb_dev, 0xf0, uma_memory_size >> 20);
Zheng Bao1088bbf2010-03-16 01:41:14 +0000876 /* GFX_InitUMA finished. */
877#else
878 /* GFX_InitSP. */
879 /* SP memory:Hynix HY5TQ1G631ZNFP. 128MB = 64M * 16. 667MHz. DDR3. */
880
881 /* Enable Async mode. */
882 set_nbmc_enable_bits(nb_dev, 0x06, 7<<8, 1<<8);
883 set_nbmc_enable_bits(nb_dev, 0x08, 1<<10, 0);
884 /* The last item in AsynchMclkTaskFileIndex. Why? */
885 /* MC_MPLL_CONTROL2. */
886 nbmc_write_index(nb_dev, 0x07, 0x40100028);
887 /* MC_MPLL_DIV_CONTROL. */
888 nbmc_write_index(nb_dev, 0x0b, 0x00000028);
889 /* MC_MPLL_FREQ_CONTROL. */
890 set_nbmc_enable_bits(nb_dev, 0x09, 3<<12|15<<16|15<<8, 1<<12|4<<16|0<<8);
891 /* MC_MPLL_CONTROL3. For PM. */
892 set_nbmc_enable_bits(nb_dev, 0x08, 0xff<<13, 1<<13|1<<18);
893 /* MPLL_CAL_TRIGGER. */
894 set_nbmc_enable_bits(nb_dev, 0x06, 0, 1<<0);
895 udelay(200); /* time is long enough? */
896 set_nbmc_enable_bits(nb_dev, 0x06, 0, 1<<1);
897 set_nbmc_enable_bits(nb_dev, 0x06, 1<<0, 0);
898 /* MCLK_SRC_USE_MPLL. */
899 set_nbmc_enable_bits(nb_dev, 0x02, 0, 1<<20);
900
901 /* Pre Init MC. */
902 nbmc_write_index(nb_dev, 0x01, 0x88108280);
903 set_nbmc_enable_bits(nb_dev, 0x02, ~(1<<20), 0x00030200);
904 nbmc_write_index(nb_dev, 0x04, 0x08881018);
905 nbmc_write_index(nb_dev, 0x05, 0x000000bb);
906 nbmc_write_index(nb_dev, 0x0c, 0x0f00001f);
907 nbmc_write_index(nb_dev, 0xa1, 0x01f10000);
908 /* MCA_INIT_DLL_PM. */
909 set_nbmc_enable_bits(nb_dev, 0xc9, 1<<24, 1<<24);
910 nbmc_write_index(nb_dev, 0xa2, 0x74f20000);
911 nbmc_write_index(nb_dev, 0xa3, 0x8af30000);
912 nbmc_write_index(nb_dev, 0xaf, 0x47d0a41c);
913 nbmc_write_index(nb_dev, 0xb0, 0x88800130);
914 nbmc_write_index(nb_dev, 0xb1, 0x00000040);
915 nbmc_write_index(nb_dev, 0xb4, 0x41247000);
916 nbmc_write_index(nb_dev, 0xb5, 0x00066664);
917 nbmc_write_index(nb_dev, 0xb6, 0x00000022);
918 nbmc_write_index(nb_dev, 0xb7, 0x00000044);
919 nbmc_write_index(nb_dev, 0xb8, 0xbbbbbbbb);
920 nbmc_write_index(nb_dev, 0xb9, 0xbbbbbbbb);
921 nbmc_write_index(nb_dev, 0xba, 0x55555555);
922 nbmc_write_index(nb_dev, 0xc1, 0x00000000);
923 nbmc_write_index(nb_dev, 0xc2, 0x00000000);
924 nbmc_write_index(nb_dev, 0xc3, 0x80006b00);
925 nbmc_write_index(nb_dev, 0xc4, 0x00066664);
926 nbmc_write_index(nb_dev, 0xc5, 0x00000000);
927 nbmc_write_index(nb_dev, 0xd2, 0x00000022);
928 nbmc_write_index(nb_dev, 0xd3, 0x00000044);
929 nbmc_write_index(nb_dev, 0xd6, 0x00050005);
930 nbmc_write_index(nb_dev, 0xd7, 0x00000000);
931 nbmc_write_index(nb_dev, 0xd8, 0x00700070);
932 nbmc_write_index(nb_dev, 0xd9, 0x00700070);
933 nbmc_write_index(nb_dev, 0xe0, 0x00200020);
934 nbmc_write_index(nb_dev, 0xe1, 0x00200020);
935 nbmc_write_index(nb_dev, 0xe8, 0x00200020);
936 nbmc_write_index(nb_dev, 0xe9, 0x00200020);
937 nbmc_write_index(nb_dev, 0xe0, 0x00180018);
938 nbmc_write_index(nb_dev, 0xe1, 0x00180018);
939 nbmc_write_index(nb_dev, 0xe8, 0x00180018);
940 nbmc_write_index(nb_dev, 0xe9, 0x00180018);
941
942 /* Misc options. */
943 /* Memory Termination. */
944 set_nbmc_enable_bits(nb_dev, 0xa1, 0x0ff, 0x044);
945 set_nbmc_enable_bits(nb_dev, 0xb4, 0xf00, 0xb00);
946#if 0
947 /* Controller Termation. */
948 set_nbmc_enable_bits(nb_dev, 0xb1, 0x77770000, 0x77770000);
949#endif
950
951 /* OEM Init MC. 667MHz. */
952 nbmc_write_index(nb_dev, 0xa8, 0x7a5aaa78);
953 nbmc_write_index(nb_dev, 0xa9, 0x514a2319);
954 nbmc_write_index(nb_dev, 0xaa, 0x54400520);
955 nbmc_write_index(nb_dev, 0xab, 0x441460ff);
956 nbmc_write_index(nb_dev, 0xa0, 0x20f00a48);
957 set_nbmc_enable_bits(nb_dev, 0xa2, ~(0xffffffc7), 0x10);
958 nbmc_write_index(nb_dev, 0xb2, 0x00000303);
959 set_nbmc_enable_bits(nb_dev, 0xb1, ~(0xffffff70), 0x45);
960 /* Do it later. */
961 /* set_nbmc_enable_bits(nb_dev, 0xac, ~(0xfffffff0), 0x0b); */
962
963 /* Init PM timing. */
964 for(i=0; i<4; i++)
965 {
966 l_dword = nbmc_read_index(nb_dev, 0xa0+i);
967 nbmc_write_index(nb_dev, 0xc8+i, l_dword);
968 }
969 for(i=0; i<4; i++)
970 {
971 l_dword = nbmc_read_index(nb_dev, 0xa8+i);
972 nbmc_write_index(nb_dev, 0xcc+i, l_dword);
973 }
974 l_dword = nbmc_read_index(nb_dev, 0xb1);
975 set_nbmc_enable_bits(nb_dev, 0xc8, 0xff<<24, ((l_dword&0x0f)<<24)|((l_dword&0xf00)<<20));
976
977 /* Init MC FB. */
978 /* FB_Start = ; FB_End = ; iSpSize = 0x0080, 128MB. */
979 nbmc_write_index(nb_dev, 0x11, 0x40000000);
980 FB_Start = 0xc00 + 0x080;
981 FB_End = 0xc00 + 0x080;
982 nbmc_write_index(nb_dev, 0x10, (((FB_End&0xfff)<<20)-0x10000)|(((FB_Start&0xfff)-0x080)<<4));
983 set_nbmc_enable_bits(nb_dev, 0x0d, ~0x000ffff0, (FB_Start&0xfff)<<20);
984 nbmc_write_index(nb_dev, 0x0f, 0);
985 nbmc_write_index(nb_dev, 0x0e, (FB_Start&0xfff)|(0xaaaa<<12));
986#endif
987
988 /* GFX_InitSP finished. */
989}
990
991static struct pci_operations lops_pci = {
992 .set_subsystem = pci_dev_set_subsystem,
993};
994
995static struct device_operations pcie_ops = {
996 .read_resources = rs780_gfx_read_resources,
997 .set_resources = pci_dev_set_resources,
998 .enable_resources = pci_dev_enable_resources,
999 .init = internal_gfx_pci_dev_init, /* The option ROM initializes the device. rs780_gfx_init, */
1000 .scan_bus = 0,
1001 .enable = rs780_internal_gfx_enable,
1002 .ops_pci = &lops_pci,
1003};
1004
1005/*
1006 * We should list all of them here.
1007 * */
Patrick Georgiefff7332012-07-26 19:48:23 +02001008static const unsigned short pcie_780_ids[] = {
1009 PCI_DEVICE_ID_ATI_RS780_INT_GFX,
1010 PCI_DEVICE_ID_ATI_RS780C_INT_GFX,
1011 PCI_DEVICE_ID_ATI_RS780M_INT_GFX,
1012 PCI_DEVICE_ID_ATI_RS780MC_INT_GFX,
1013 PCI_DEVICE_ID_ATI_RS780E_INT_GFX,
1014 PCI_DEVICE_ID_ATI_RS785G_INT_GFX,
1015 PCI_DEVICE_ID_ATI_RS785C_INT_GFX,
1016 PCI_DEVICE_ID_ATI_RS785M_INT_GFX,
1017 PCI_DEVICE_ID_ATI_RS785MC_INT_GFX,
1018 PCI_DEVICE_ID_ATI_RS785D_INT_GFX,
1019 0
1020};
1021
Stefan Reinauer8e96ba22010-03-16 23:33:29 +00001022static const struct pci_driver pcie_driver_780 __pci_driver = {
Zheng Bao1088bbf2010-03-16 01:41:14 +00001023 .ops = &pcie_ops,
1024 .vendor = PCI_VENDOR_ID_ATI,
Patrick Georgiefff7332012-07-26 19:48:23 +02001025 .devices = pcie_780_ids,
Zheng Bao40992d32010-12-31 01:46:12 +00001026};
Zheng Bao1088bbf2010-03-16 01:41:14 +00001027
1028/* step 12 ~ step 14 from rpr */
1029static void single_port_configuration(device_t nb_dev, device_t dev)
1030{
1031 u8 result, width;
1032 u32 reg32;
1033 struct southbridge_amd_rs780_config *cfg =
1034 (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
1035
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001036 printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001037
1038 /* step 12 training, releases hold training for GFX port 0 (device 2) */
1039 PcieReleasePortTraining(nb_dev, dev, 2);
1040 result = PcieTrainPort(nb_dev, dev, 2);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001041 printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step12.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001042
1043 /* step 13 Power Down Control */
1044 /* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
1045 set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
1046
1047 /* step 13.a Link Training was NOT successful */
1048 if (!result) {
1049 set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4); /* prevent from training. */
1050 set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2); /* hide the GFX bridge. */
1051 if (cfg->gfx_tmds)
1052 nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
1053 else {
1054 nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
1055 set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
1056 }
1057 } else { /* step 13.b Link Training was successful */
Kerry Sheh8c69b1d2011-09-14 10:04:19 +08001058 AtiPcieCfg.PortDetect |= 1 << 2; /* Port 2 */
Zheng Bao1088bbf2010-03-16 01:41:14 +00001059 set_pcie_enable_bits(dev, 0xA2, 0xFF, 0x1);
1060 reg32 = nbpcie_p_read_index(dev, 0x29);
1061 width = reg32 & 0xFF;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001062 printk(BIOS_DEBUG, "GFX Inactive Lanes = 0x%x.\n", width);
Zheng Bao1088bbf2010-03-16 01:41:14 +00001063 switch (width) {
1064 case 1:
1065 case 2:
1066 nbpcie_ind_write_index(nb_dev, 0x65,
1067 cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
1068 break;
1069 case 4:
1070 nbpcie_ind_write_index(nb_dev, 0x65,
1071 cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
1072 break;
1073 case 8:
1074 nbpcie_ind_write_index(nb_dev, 0x65,
1075 cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
1076 break;
1077 }
1078 }
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001079 printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step13.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001080
1081 /* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
1082 set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001083 printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step14.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001084}
1085
1086static void dual_port_configuration(device_t nb_dev, device_t dev)
1087{
1088 u8 result, width;
1089 u32 reg32, dev_ind = dev->path.pci.devfn >> 3;
1090 struct southbridge_amd_rs780_config *cfg =
1091 (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
1092
1093 /* 5.4.1.2 Dual Port Configuration */
1094 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
1095 set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
1096 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
1097
1098 /* 5.7. Training for Device 2 */
1099 /* 5.7.1. Releases hold training for GFX port 0 (device 2) */
1100 PcieReleasePortTraining(nb_dev, dev, dev_ind);
1101 /* 5.7.2- 5.7.9. PCIE Link Training Sequence */
1102 result = PcieTrainPort(nb_dev, dev, dev_ind);
1103
1104 /* Power Down Control for Device 2 */
1105 /* Link Training was NOT successful */
1106 if (!result) {
1107 /* Powers down all lanes for port A */
1108 /* nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f); */
1109 /* Note: I have to disable the slot where there isnt a device,
1110 * otherwise the system will hang. I dont know why. */
1111 set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << dev_ind, 1 << dev_ind);
1112
1113 } else { /* step 16.b Link Training was successful */
Kerry Sheh8c69b1d2011-09-14 10:04:19 +08001114 AtiPcieCfg.PortDetect |= 1 << dev_ind;
Zheng Bao1088bbf2010-03-16 01:41:14 +00001115 reg32 = nbpcie_p_read_index(dev, 0xa2);
1116 width = (reg32 >> 4) & 0x7;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001117 printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
Zheng Bao1088bbf2010-03-16 01:41:14 +00001118 switch (width) {
1119 case 1:
1120 case 2:
1121 nbpcie_ind_write_index(nb_dev, 0x65,
1122 cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
1123 break;
1124 case 4:
1125 nbpcie_ind_write_index(nb_dev, 0x65,
1126 cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
1127 break;
1128 }
1129 }
1130}
1131
1132/* For single port GFX configuration Only
1133* width:
1134* 000 = x16
1135* 001 = x1
1136* 010 = x2
1137* 011 = x4
1138* 100 = x8
1139* 101 = x12 (not supported)
1140* 110 = x16
1141*/
1142static void dynamic_link_width_control(device_t nb_dev, device_t dev, u8 width)
1143{
1144 u32 reg32;
1145 device_t sb_dev;
1146 struct southbridge_amd_rs780_config *cfg =
1147 (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
1148
1149 /* step 5.9.1.1 */
1150 reg32 = nbpcie_p_read_index(dev, 0xa2);
1151
1152 /* step 5.9.1.2 */
1153 set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
1154 /* step 5.9.1.3 */
1155 set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
1156 /* step 5.9.1.4 */
1157 set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
1158 /* step 5.9.2.4 */
1159 if (0 == cfg->gfx_reconfiguration)
1160 set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
1161
1162 /* step 5.9.1.5 */
1163 do {
1164 reg32 = nbpcie_p_read_index(dev, 0xa2);
1165 }
1166 while (reg32 & 0x100);
1167
1168 /* step 5.9.1.6 */
1169 sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
1170 do {
1171 reg32 = pci_ext_read_config32(nb_dev, sb_dev,
1172 PCIE_VC0_RESOURCE_STATUS);
1173 } while (reg32 & VC_NEGOTIATION_PENDING);
1174
1175 /* step 5.9.1.7 */
1176 reg32 = nbpcie_p_read_index(dev, 0xa2);
1177 if (((reg32 & 0x70) >> 4) != 0x6) {
1178 /* the unused lanes should be powered off. */
1179 }
1180
1181 /* step 5.9.1.8 */
1182 set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
1183}
1184
1185/*
1186* GFX Core initialization, dev2, dev3
1187*/
1188void rs780_gfx_init(device_t nb_dev, device_t dev, u32 port)
1189{
Zheng Bao1088bbf2010-03-16 01:41:14 +00001190 u32 reg32;
1191 struct southbridge_amd_rs780_config *cfg =
1192 (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
1193
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001194 printk(BIOS_DEBUG, "rs780_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
Zheng Bao1088bbf2010-03-16 01:41:14 +00001195 nb_dev, dev, port);
1196
1197 /* GFX Core Initialization */
1198 //if (port == 2) return;
1199
Zheng Bao1088bbf2010-03-16 01:41:14 +00001200 /* step 2, TMDS, (only need if CMOS option is enabled) */
1201 if (cfg->gfx_tmds) {
Kerry Shefaafd142011-05-07 08:51:32 +00001202 /**
1203 * PCIe Initialization for DDI.
1204 * The VBIOS/Driver is responsible for DDI programming sequence,
1205 * The SBIOS is responsible for programming the lane and clock muxing specific to each case.
1206 * Refer to RPR Chapter 7: "PCIe Initialization for DDI".
1207 * Note: This programming must be done before hold training is released.
1208 */
1209 switch (cfg->gfx_pcie_config) {
1210 case 1: /* 1x16 GFX -default case, no programming required */
1211 break;
1212 case 2: /* 1x8 GFX on Lanes 0-7 */
1213 case 5: /* 1x4 GPP on Lanes 0-3 */
1214 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 6, 0x1 << 6); /* Disables PCIe mode on PHY Lanes 8-11 */
1215 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 7, 0x1 << 7); /* Disables PCIe mode on PHY Lanes 12-15 */
1216 break;
1217 case 3: /* 1x8 on Lanes 8-15 */
1218 case 7: /* 1x4 GPP on Lanes 8-11 */
1219 /* TXCLK */
1220 set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 16, 1 << 16);
1221 set_nbmisc_enable_bits(nb_dev, 0x07, 0xF << 12, 0xF << 12);
1222 set_nbmisc_enable_bits(nb_dev, 0x07, 0x3 << 24, 0x2 << 24);
1223 set_nbmisc_enable_bits(nb_dev, 0x28, 0x3 << 0, 0x0 << 0);
1224 /* RXCLK */
1225 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 8, 0x2 << 8);
1226 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 10, 0x2 << 10);
1227 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 12, 0x2 << 12);
1228 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 14, 0x2 << 14);
1229 /* TX Lane Muxing */
1230 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 2, 0x1 << 2);
1231 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 3, 0x1 << 3);
1232 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 4, 0x1 << 4);
1233 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 5, 0x1 << 5);
1234 break;
1235 case 4: /* 2x8 */
1236 case 10: /* 1x4 GPP on Lanes 0-3 and 1x4 GPP on Lanes 8-11 */
1237 case 14: /* 1x8 GFX on Lanes 0-7 and 1x4 GPP on Lanes 8-11 */
1238 case 17: /* 1x4 GPP on Lanes 0-3 and 1x8 GFX on Lanes 8-15 */
1239 /* Set dual slot configuration */
1240 set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
1241 break;
1242 case 9: /* PCIe 2x4 GPPs on Lanes 0-7 */
1243 case 6: /* PCIe 1x4 GPP on Lanes 4-7 */
1244 /* Set dual slot configuration */
1245 set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
1246 /* TXCLK */
1247 set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 16, 0 << 16);
1248 set_nbmisc_enable_bits(nb_dev, 0x07, 0xF << 12, 0x0 << 12);
1249 set_nbmisc_enable_bits(nb_dev, 0x07, 0x3 << 20, 0x0 << 20);
1250 set_nbmisc_enable_bits(nb_dev, 0x28, 0x1 << 0, 0x0 << 0);
1251 /* RXCLK */
1252 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 8, 0x0 << 8);
1253 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 10, 0x1 << 10);
1254 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 12, 0x3 << 12);
1255 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 14, 0x0 << 14);
1256 /* TX Lane Muxing */
1257 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 1, 0x1 << 1);
1258 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 6, 0x1 << 6);
1259 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 7, 0x1 << 7);
1260 break;
1261 case 13: /* 2x4 GPPs on Lanes 8-15 */
1262 case 8: /* 1x4 GPP on Lanes 12-15 */
1263 /* Set dual slot configuration */
1264 set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
1265 /* TXCLK */
1266 set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 16, 1 << 16);
1267 set_nbmisc_enable_bits(nb_dev, 0x07, 0xF << 12, 0xF << 12);
1268 set_nbmisc_enable_bits(nb_dev, 0x07, 0x3 << 24, 0x2 << 24);
1269 set_nbmisc_enable_bits(nb_dev, 0x28, 0x3 << 0, 0x3 << 0);
1270 /* RXCLK */
1271 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 8, 0x2 << 8);
1272 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 10, 0x3 << 10);
1273 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 12, 0x1 << 12);
1274 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 14, 0x2 << 14);
1275 /* TX Lane Muxing */
1276 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 2, 0x1 << 2);
1277 set_nbmisc_enable_bits(nb_dev, 0x28, 0x1 << 14, 0x1 << 14);
1278 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 4, 0x1 << 4);
1279 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 5, 0x1 << 5);
1280 break;
1281 case 15: /* 1x8 GFX on Lanes 0-7 and 1x4 GPP on Lanes 12-15 */
1282 case 11: /* 1x4 GPP on Lanes 0-3 and 1x4 GPP on Lanes 12-15 */
1283 /* Set dual slot configuration */
1284 set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
1285 /* TXCLK */
1286 set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 16, 0 << 16);
1287 set_nbmisc_enable_bits(nb_dev, 0x07, 0xF << 12, 0x0 << 12);
1288 set_nbmisc_enable_bits(nb_dev, 0x07, 0x3 << 20, 0x0 << 20);
1289 set_nbmisc_enable_bits(nb_dev, 0x28, 0x3 << 0, 0x1 << 0);
1290 /* RXCLK */
1291 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 8, 0x0 << 8);
1292 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 10, 0x0 << 10);
1293 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 12, 0x1 << 12);
1294 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 14, 0x3 << 14);
1295 /* TX Lane Muxing */
1296 set_nbmisc_enable_bits(nb_dev, 0x28, 0x1 << 14, 0x1 << 14);
1297 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 6, 0x1 << 6);
1298 break;
1299 case 16: /* 1x8 GFX on Lanes 8-15 and 1x4 GPP on Lanes 4-7 */
1300 case 12: /* 1x4 GPP on Lanes 4-7 and 1x8 GFX on Lanes 8-15 */
1301 /* Set dual slot configuration */
1302 set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
1303 /* TXCLK */
1304 set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 16, 1 << 16);
1305 set_nbmisc_enable_bits(nb_dev, 0x07, 0xF << 12, 0xF << 12);
1306 set_nbmisc_enable_bits(nb_dev, 0x07, 0x3 << 24, 0x2 << 24);
1307 set_nbmisc_enable_bits(nb_dev, 0x07, 0x3 << 22, 0x2 << 22);
1308 set_nbmisc_enable_bits(nb_dev, 0x28, 0x3 << 0, 0x2 << 0);
1309 /* RXCLK */
1310 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 8, 0x2 << 8);
1311 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 10, 0x2 << 10);
1312 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 12, 0x3 << 12);
1313 set_nbmisc_enable_bits(nb_dev, 0x27, 0x3 << 14, 0x1 << 14);
1314 /* TX Lane Muxing */
1315 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 2, 0x1 << 2);
1316 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 3, 0x1 << 3);
1317 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 1, 0x1 << 1);
1318 set_nbmisc_enable_bits(nb_dev, 0x27, 0x1 << 4, 0x1 << 4);
1319 break;
1320 default:
1321 printk(BIOS_INFO, "Incorrect configuration of external GFX slot.\n");
1322 break;
1323 }
1324
1325 /* DDI Configuration */
1326 switch (cfg->gfx_ddi_config) {
1327 case 1: /* DDI_SL lanes0-3 */
1328 nbmisc_write_index(nb_dev, 0x74, GFX_CONFIG_DDI);
1329 break;
1330 case 2: /* DDI_SL lanes4-7 */
1331 nbmisc_write_index(nb_dev, 0x74, (GFX_CONFIG_DDI << 8));
1332 break;
1333 case 5: /* DDI_SL lanes0-4, lanes4-7 */
1334 nbmisc_write_index(nb_dev, 0x74, (GFX_CONFIG_DDI << 8) | GFX_CONFIG_DDI);
1335 break;
1336 case 6: /* DDI_DL lanes0-7 */
1337 nbmisc_write_index(nb_dev, 0x74, (GFX_CONFIG_DDI << 8) | GFX_CONFIG_DDI);
1338 break;
1339 default:
1340 printk(BIOS_INFO, "Incorrect configuration of external GFX slot.\n");
1341 break;
1342 }
Zheng Bao1088bbf2010-03-16 01:41:14 +00001343 }
1344
1345#if 1 /* external clock mode */
1346 /* table 5-22, 5.9.1. REFCLK */
1347 /* 5.9.1.1. Disables the GFX REFCLK transmitter so that the GFX
1348 * REFCLK PAD can be driven by an external source. */
1349 /* 5.9.1.2. Enables GFX REFCLK receiver to receive the REFCLK from an external source. */
Scott Duplichan88dc5312010-11-24 00:39:44 +00001350 set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28 | 1 << 26, 1 << 28);
Zheng Bao1088bbf2010-03-16 01:41:14 +00001351
1352 /* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */
1353 /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
1354 /* 5.9.1.5 Selects the GFX REFCLK to be the source for PLL C. */
Zheng Bao1088bbf2010-03-16 01:41:14 +00001355 reg32 = nbmisc_read_index(nb_dev, 0x28);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001356 printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
Zheng Bao1088bbf2010-03-16 01:41:14 +00001357
1358 /* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
1359 set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 1 << 31);
1360#else /* internal clock mode */
1361 /* table 5-23, 5.9.1. REFCLK */
1362 /* 5.9.1.1. Enables the GFX REFCLK transmitter so that the GFX
1363 * REFCLK PAD can be driven by the SB REFCLK. */
1364 /* 5.9.1.2. Disables GFX REFCLK receiver from receiving the
1365 * REFCLK from an external source.*/
1366 set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28, 1 << 29 | 0 << 28);
1367
1368 /* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */
1369 /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
1370 /* 5.9.1.5 Selects the GFX REFCLK to be the source for PLL C. */
1371 set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
1372 0);
1373 reg32 = nbmisc_read_index(nb_dev, 0x28);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001374 printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
Zheng Bao1088bbf2010-03-16 01:41:14 +00001375
1376 /* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
1377 set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 0 << 31);
1378#endif
1379
1380 /* step 5.9.3, GFX overclocking, (only need if CMOS option is enabled) */
1381 /* 5.9.3.1. Increases PLL BW for 6G operation.*/
1382 /* set_nbmisc_enable_bits(nb_dev, 0x36, 0x3FF << 4, 0xB5 << 4); */
1383 /* skip */
1384
1385 /* step 5.9.4, reset the GFX link */
1386 /* step 5.9.4.1 asserts both calibration reset and global reset */
1387 set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
1388
1389 /* step 5.9.4.2 de-asserts calibration reset */
1390 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
1391
1392 /* step 5.9.4.3 wait for at least 200us */
1393 udelay(300);
1394
1395 /* step 5.9.4.4 de-asserts global reset */
1396 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
1397
1398 /* 5.9.5 Reset PCIE_GFX Slot */
1399 /* It is done in mainboard.c */
1400 set_pcie_reset();
1401 mdelay(1);
1402 set_pcie_dereset();
1403
1404 /* step 5.9.8 program PCIE memory mapped configuration space */
1405 /* done by enable_pci_bar3() before */
1406
1407 /* step 7 compliance state, (only need if CMOS option is enabled) */
1408 /* the compliance stete is just for test. refer to 4.2.5.2 of PCIe specification */
1409 if (cfg->gfx_compliance) {
1410 /* force compliance */
1411 set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
1412 /* release hold training for device 2. GFX initialization is done. */
1413 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
1414 dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001415 printk(BIOS_DEBUG, "rs780_gfx_init step7.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001416 return;
1417 }
1418
1419 /* 5.9.12 Core Initialization. */
1420 /* 5.9.12.1 sets RCB timeout to be 25ms */
1421 /* 5.9.12.2. RCB Cpl timeout on link down. */
1422 set_pcie_enable_bits(dev, 0x70, 7 << 16 | 1 << 19, 4 << 16 | 1 << 19);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001423 printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.1.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001424
1425 /* step 5.9.12.3 disables slave ordering logic */
1426 set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001427 printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.3.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001428
1429 /* step 5.9.12.4 sets DMA payload size to 64 bytes */
1430 set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
1431 /* 5.9.12.5. Blocks DMA traffic during C3 state. */
1432 set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
1433
1434 /* 5.9.12.6. Disables RC ordering logic */
1435 set_pcie_enable_bits(nb_dev, 0x20, 1 << 9, 1 << 9);
1436
1437 /* Enabels TLP flushing. */
1438 /* Note: It is got from RS690. The system will hang without this action. */
1439 set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
1440
1441 /* 5.9.12.7. Ignores DLLPs during L1 so that txclk can be turned off */
1442 set_pcie_enable_bits(nb_dev, 0x2, 1 << 0, 1 << 0);
1443
1444 /* 5.9.12.8 Prevents LC to go from L0 to Rcv_L0s if L1 is armed. */
1445 set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
1446
1447 /* 5.9.12.9 CMGOOD_OVERRIDE for end point initiated lane degradation. */
1448 set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001449 printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.9.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001450
1451 /* 5.9.12.10 Sets the timer in Config state from 20us to */
1452 /* 5.9.12.11 De-asserts RX_EN in L0s. */
1453 /* 5.9.12.12 Enables de-assertion of PG2RX_CR_EN to lock clock
1454 * recovery parameter when lane is in electrical idle in L0s.*/
1455 set_pcie_enable_bits(dev, 0xB1, 1 << 23 | 1 << 19 | 1 << 28, 1 << 23 | 1 << 19 | 1 << 28);
1456
1457 /* 5.9.12.13. Turns off offset calibration. */
1458 /* 5.9.12.14. Enables Rx Clock gating in CDR */
1459 set_nbmisc_enable_bits(nb_dev, 0x34, 1 << 10/* | 1 << 22 */, 1 << 10/* | 1 << 22 */);
1460
1461 /* 5.9.12.15. Sets number of TX Clocks to drain TX Pipe to 3. */
1462 set_pcie_enable_bits(dev, 0xA0, 0xF << 4, 3 << 4);
1463
1464 /* 5.9.12.16. Lets PI use Electrical Idle from PHY when
1465 * turning off PLL in L1 at Gen2 speed instead Inferred Electrical Idle. */
1466 set_pcie_enable_bits(nb_dev, 0x40, 3 << 14, 2 << 14);
1467
1468 /* 5.9.12.17. Prevents the Electrical Idle from causing a transition from Rcv_L0 to Rcv_L0s. */
1469 set_pcie_enable_bits(dev, 0xB1, 1 << 20, 1 << 20);
1470
1471 /* 5.9.12.18. Prevents the LTSSM from going to Rcv_L0s if it has already
1472 * acknowledged a request to go to L1. */
1473 set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
1474
1475 /* 5.9.12.19. LDSK only taking deskew on deskewing error detect */
1476 set_pcie_enable_bits(nb_dev, 0x40, 1 << 28, 0 << 28);
1477
1478 /* 5.9.12.20. Bypasses lane de-skew logic if in x1 */
1479 set_pcie_enable_bits(nb_dev, 0xC2, 1 << 14, 1 << 14);
1480
1481 /* 5.9.12.21. Sets Electrical Idle Threshold. */
1482 set_nbmisc_enable_bits(nb_dev, 0x35, 3 << 21, 2 << 21);
1483
1484 /* 5.9.12.22. Advertises -6 dB de-emphasis value in TS1 Data Rate Identifier
1485 * Only if CMOS Option in section. skip */
1486
1487 /* 5.9.12.23. Disables GEN2 capability of the device. */
1488 set_pcie_enable_bits(dev, 0xA4, 1 << 0, 0 << 0);
1489
1490 /* 5.9.12.24.Disables advertising Upconfigure Support. */
1491 set_pcie_enable_bits(dev, 0xA2, 1 << 13, 1 << 13);
1492
1493 /* 5.9.12.25. No comment in RPR. */
1494 set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 10, 0 << 10);
1495
1496 /* 5.9.12.26. This capacity is required since links wider than x1 and/or multiple link
1497 * speed are supported */
1498 set_pcie_enable_bits(nb_dev, 0xC1, 1 << 0, 1 << 0);
1499
1500 /* 5.9.12.27. Enables NVG86 ECO. A13 above only. */
1501 if (get_nb_rev(nb_dev) == REV_RS780_A12) /* A12 */
1502 set_pcie_enable_bits(dev, 0x02, 1 << 11, 1 << 11);
1503
1504 /* 5.9.12.28 Hides and disables the completion timeout method. */
1505 set_pcie_enable_bits(nb_dev, 0xC1, 1 << 2, 0 << 2);
1506
1507 /* 5.9.12.29. Use the bif_core de-emphasis strength by default. */
1508 /* set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 28, 1 << 28); */
1509
1510 /* 5.9.12.30. Set TX arbitration algorithm to round robin */
1511 set_pcie_enable_bits(nb_dev, 0x1C,
1512 1 << 0 | 0x1F << 1 | 0x1F << 6,
1513 1 << 0 | 0x04 << 1 | 0x04 << 6);
1514
1515 /* Single-port/Dual-port configureation. */
1516 switch (cfg->gfx_dual_slot) {
1517 case 0:
Zheng Bao52a3c3b2010-08-17 02:14:53 +00001518 /* step 1, lane reversal (only need if build config option is enabled) */
Zheng Baob63bdbe2010-03-23 06:46:01 +00001519 if (cfg->gfx_lane_reversal) {
Zheng Bao52a3c3b2010-08-17 02:14:53 +00001520 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
Zheng Baob63bdbe2010-03-23 06:46:01 +00001521 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
Zheng Bao52a3c3b2010-08-17 02:14:53 +00001522 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
Zheng Baob63bdbe2010-03-23 06:46:01 +00001523 }
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001524 printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
Zheng Baob63bdbe2010-03-23 06:46:01 +00001525
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001526 printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
1527 if((dev->path.pci.devfn >> 3) == 2) {
Zheng Baob63bdbe2010-03-23 06:46:01 +00001528 single_port_configuration(nb_dev, dev);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001529 } else {
Zheng Baob63bdbe2010-03-23 06:46:01 +00001530 set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001531 printk(BIOS_INFO, "Single port. Do nothing.\n"); // If dev3
Zheng Baob63bdbe2010-03-23 06:46:01 +00001532 }
1533
Zheng Bao1088bbf2010-03-16 01:41:14 +00001534 break;
1535 case 1:
Zheng Bao52a3c3b2010-08-17 02:14:53 +00001536 /* step 1, lane reversal (only need if build config option is enabled) */
Zheng Baob63bdbe2010-03-23 06:46:01 +00001537 if (cfg->gfx_lane_reversal) {
Zheng Bao52a3c3b2010-08-17 02:14:53 +00001538 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
Zheng Baob63bdbe2010-03-23 06:46:01 +00001539 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
1540 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
Zheng Bao52a3c3b2010-08-17 02:14:53 +00001541 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
Zheng Baob63bdbe2010-03-23 06:46:01 +00001542 }
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001543 printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
Zheng Baob63bdbe2010-03-23 06:46:01 +00001544 /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
1545 /* AMD calls the configuration CrossFire */
1546 set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001547 printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
Zheng Baob63bdbe2010-03-23 06:46:01 +00001548
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001549 printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
Zheng Bao1088bbf2010-03-16 01:41:14 +00001550 dual_port_configuration(nb_dev, dev);
1551 break;
Wang Qing Pei543f7672010-08-17 11:11:09 +00001552
1553 case 2:
Wang Qing Pei543f7672010-08-17 11:11:09 +00001554 if(is_dev3_present()){
1555 /* step 1, lane reversal (only need if CMOS option is enabled) */
1556 if (cfg->gfx_lane_reversal) {
Zheng Bao29cb06a2010-12-06 08:19:38 +00001557 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
Wang Qing Pei543f7672010-08-17 11:11:09 +00001558 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
1559 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
Zheng Bao29cb06a2010-12-06 08:19:38 +00001560 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
Wang Qing Pei543f7672010-08-17 11:11:09 +00001561 }
1562 printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
1563 /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
1564 /* AMD calls the configuration CrossFire */
1565 set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
1566 printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
1567
1568
1569 printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
1570 dual_port_configuration(nb_dev, dev);
1571
1572 }else{
1573 if (cfg->gfx_lane_reversal) {
Zheng Bao29cb06a2010-12-06 08:19:38 +00001574 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
Wang Qing Pei543f7672010-08-17 11:11:09 +00001575 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
Zheng Bao29cb06a2010-12-06 08:19:38 +00001576 set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
Wang Qing Pei543f7672010-08-17 11:11:09 +00001577 }
1578 printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
Wang Qing Pei543f7672010-08-17 11:11:09 +00001579
1580 if((dev->path.pci.devfn >> 3) == 2)
1581 single_port_configuration(nb_dev, dev);
1582 else{
1583 set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
1584 printk(BIOS_DEBUG, "If dev3.., single port. Do nothing.\n");
1585 }
1586 }
Zheng Bao4a778db2010-12-09 06:18:29 +00001587 break;
Wang Qing Pei543f7672010-08-17 11:11:09 +00001588
Zheng Bao1088bbf2010-03-16 01:41:14 +00001589 default:
Stefan Reinauerf0aa09b2010-03-23 13:23:40 +00001590 printk(BIOS_INFO, "Incorrect configuration of external GFX slot.\n");
Zheng Bao1088bbf2010-03-16 01:41:14 +00001591 break;
1592 }
1593}