1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <types.h>
27#include <lib.h>
28#include <console.h>
29#include <device/pci.h>
30#include <msr.h>
31#include <legacy.h>
32#include <device/pci_ids.h>
33#include <statictree.h>
34#include <config.h>
35#include "rs690.h"
36
37#define CLK_CNTL_INDEX 0x8
38#define CLK_CNTL_DATA 0xC
39
40static u32 clkind_read(struct device * dev, u32 index)
41{
42 u32 gfx_bar2 = pci_read_config32(dev, PCI_BASE_ADDRESS_2) & ~0xF;
43
44 *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
45 return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
46}
47
48static void clkind_write(struct device * dev, u32 index, u32 data)
49{
50 u32 gfx_bar2 = pci_read_config32(dev, PCI_BASE_ADDRESS_2) & ~0xF;
51
52
53 *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
54 *(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
55}
56
57
58
59
60
61static void rs690_gfx_read_resources(struct device * dev)
62{
63 printk(BIOS_INFO, "rs690_gfx_read_resources.\n");
64
65
66
67
68
69 pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);
70
71
72 pci_dev_read_resources(dev);
73 compact_resources(dev);
74}
75
76static void internal_gfx_pci_dev_init(struct device *dev)
77{
78 unsigned short deviceid, vendorid;
79 struct southbridge_amd_rs690_gfx_config *cfg = dev->device_configuration;
80 deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
81 vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
82 printk(BIOS_INFO, "internal_gfx_pci_dev_init device=%x, vendor=%x, vga_rom_address=0x%lx.\n",
83 deviceid, vendorid, cfg->vga_rom_address);
84
85 pci_dev_init(dev);
86
87
88 clkind_write(dev, 0x08, 0x01);
89 clkind_write(dev, 0x0C, 0x22);
90 clkind_write(dev, 0x0F, 0x0);
91 clkind_write(dev, 0x11, 0x0);
92 clkind_write(dev, 0x12, 0x0);
93 clkind_write(dev, 0x14, 0x0);
94 clkind_write(dev, 0x15, 0x0);
95 clkind_write(dev, 0x16, 0x0);
96 clkind_write(dev, 0x17, 0x0);
97 clkind_write(dev, 0x18, 0x0);
98 clkind_write(dev, 0x19, 0x0);
99 clkind_write(dev, 0x1A, 0x0);
100 clkind_write(dev, 0x1B, 0x0);
101 clkind_write(dev, 0x1C, 0x0);
102 clkind_write(dev, 0x1D, 0x0);
103 clkind_write(dev, 0x1E, 0x0);
104 clkind_write(dev, 0x26, 0x0);
105 clkind_write(dev, 0x27, 0x0);
106 clkind_write(dev, 0x28, 0x0);
107 clkind_write(dev, 0x5C, 0x0);
108}
109
110static void rs690_gfx_set_resources(struct device *dev)
111{
112#warning This does nothing. Implement it or remove it.
113 printk(BIOS_INFO, "rs690_gfx_set_resources.\n");
114 pci_set_resources(dev);
115}
116
117
118
119
120
121
122static void rs690_internal_gfx_enable(struct device * dev)
123{
124 u32 l_dword;
125 int i;
126 struct device * k8_f0 = 0, *k8_f2 = 0;
127 struct device * nb_dev = dev_find_slot(0, 0);
128
129 printk(BIOS_INFO, "rs690_internal_gfx_enable dev=%p, nb_dev=%p.\n", dev,
130 nb_dev);
131
132
133 l_dword = pci_read_config32(nb_dev, 0x8c);
134 printk(BIOS_INFO, "nb_dev, 0x8c=0x%x\n", l_dword);
135 l_dword &= 0xffffff8f;
136 pci_write_config32(nb_dev, 0x8c, l_dword);
137
138
139 rs690_set_tom(nb_dev);
140
141
142 k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
143 l_dword = pci_read_config32(k8_f0, 0x68);
144 l_dword &= ~(1 << 22);
145 l_dword |= (1 << 21);
146 pci_write_config32(k8_f0, 0x68, l_dword);
147
148
149 set_nbmc_enable_bits(nb_dev, 0x5f, 0, 1 << 9);
150 set_nbmc_enable_bits(nb_dev, 0xb0, 0, 1 << 8);
151
152
153 set_nbmc_enable_bits(nb_dev, 0x5f, 0x7c00, 0x800);
154
155
156 nbmc_write_index(nb_dev, 0x86, 0x3d);
157
158
159 set_htiu_enable_bits(nb_dev, 0x07, 1 << 7, 0);
160
161
162 set_nbmc_enable_bits(nb_dev, 0x74, 0, 1 << 31);
163
164
165
166 k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
167 for (i = 0; i <= (0x80 - 0x40) / 4; i++) {
168 l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
169 nbmc_write_index(nb_dev, 0x63 + i, l_dword);
170 }
171
172
173 l_dword = pci_read_config32(k8_f2, 0xa0);
174 l_dword |= 0x2c;
175 pci_write_config32(k8_f2, 0xa0, l_dword);
176 l_dword = pci_read_config32(k8_f2, 0x94);
177 l_dword &= 0xf0ffffff;
178 l_dword |= 0x07000000;
179 pci_write_config32(k8_f2, 0x94, l_dword);
180
181
182 nbmc_write_index(nb_dev, 0x1b, 0x00);
183 l_dword = nbmc_read_index(nb_dev, 0x1c);
184 l_dword &= 0xffff0;
185 l_dword |= 0x400 << 20;
186 l_dword |= 0x4;
187 nbmc_write_index(nb_dev, 0x1c, l_dword);
188 l_dword = nbmc_read_index(nb_dev, 0x1d);
189 l_dword &= 0xfffff000;
190 l_dword |= 0x0400;
191 nbmc_write_index(nb_dev, 0x1d, l_dword);
192 nbmc_write_index(nb_dev, 0x100, 0x3fff3800);
193
194
195 set_nbmc_enable_bits(nb_dev, 0x00, 0, 1 << 31);
196 l_dword = nbmc_read_index(nb_dev, 0x91);
197 l_dword |= 0x5;
198 nbmc_write_index(nb_dev, 0x91, l_dword);
199 set_nbmc_enable_bits(nb_dev, 0xb1, 0, 1 << 6);
200 set_nbmc_enable_bits(nb_dev, 0xc3, 0, 1);
201
202
203}
204
205static struct pci_operations lops_pci = {
206 .set_subsystem = pci_dev_set_subsystem,
207};
208
209
210static void single_port_configuration(struct device * nb_dev, struct device * dev)
211{
212 u8 result, width;
213 u32 reg32;
214 struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
215
216 printk(BIOS_INFO, "rs690_gfx_init single_port_configuration.\n");
217
218
219 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0<<4);
220 PcieReleasePortTraining(nb_dev, dev, 2);
221 result = PcieTrainPort(nb_dev, dev, 2);
222 printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step12.\n");
223
224
225
226 set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
227
228
229 if (!result) {
230 set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4);
231 set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2);
232 if (cfg->gfx_tmds)
233 nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
234 else {
235 nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
236 set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
237 }
238 } else {
239
240 reg32 = nbpcie_p_read_index(dev, 0xa2);
241 width = (reg32 >> 4) & 0x7;
242 printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
243 switch (width) {
244 case 1:
245 case 2:
246 nbpcie_ind_write_index(nb_dev, 0x65,
247 cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
248 break;
249 case 4:
250 nbpcie_ind_write_index(nb_dev, 0x65,
251 cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
252 break;
253 case 8:
254 nbpcie_ind_write_index(nb_dev, 0x65,
255 cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
256 break;
257 }
258 }
259 printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step13.\n");
260
261
262 set_pcie_enable_bits(dev, 0x70, 1 << 19, 0 << 19);
263 printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step14.\n");
264}
265
266
267static void dual_port_configuration(struct device * nb_dev, struct device * dev)
268{
269 u8 result, width;
270 u32 reg32;
271 struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
272
273
274 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
275
276 PcieReleasePortTraining(nb_dev, dev, 2);
277
278 result = PcieTrainPort(nb_dev, dev, 2);
279
280
281
282 if (!result) {
283
284 nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f);
285 } else {
286
287 reg32 = nbpcie_p_read_index(dev, 0xa2);
288 width = (reg32 >> 4) & 0x7;
289 printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
290 switch (width) {
291 case 1:
292 case 2:
293 nbpcie_ind_write_index(nb_dev, 0x65,
294 cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
295 break;
296 case 4:
297 nbpcie_ind_write_index(nb_dev, 0x65,
298 cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
299 break;
300 }
301 }
302
303
304 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 5, 0 << 5);
305
306 PcieReleasePortTraining(nb_dev, dev, 3);
307
308 result = PcieTrainPort(nb_dev, dev, 3);
309
310
311
312 if (!result) {
313
314 nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
315 } else {
316
317 reg32 = nbpcie_p_read_index(dev, 0xa2);
318 width = (reg32 >> 4) & 0x7;
319 printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
320 switch (width) {
321 case 1:
322 case 2:
323 nbpcie_ind_write_index(nb_dev, 0x65,
324 cfg->gfx_lane_reversal ? 0x7070 : 0xe0e0);
325 break;
326 case 4:
327 nbpcie_ind_write_index(nb_dev, 0x65,
328 cfg->gfx_lane_reversal ? 0x3030 : 0xc0c0);
329 break;
330 }
331 }
332}
333
334
335
336
337
338
339
340
341
342
343
344
345static void dynamic_link_width_control(struct device * nb_dev, struct device * dev, u8 width)
346{
347 u32 reg32;
348 struct device * sb_dev;
349 struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
350
351
352 reg32 = nbpcie_p_read_index(dev, 0xa2);
353
354
355 set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
356
357 set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
358
359 set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
360
361 if (0 == cfg->gfx_reconfiguration)
362 set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
363
364
365 do {
366 reg32 = nbpcie_p_read_index(dev, 0xa2);
367 }
368 while (reg32 & 0x100);
369
370
371 sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
372 do {
373 reg32 = pci_ext_read_config32(nb_dev, sb_dev,
374 PCIE_VC0_RESOURCE_STATUS);
375 } while (reg32 & VC_NEGOTIATION_PENDING);
376
377
378 reg32 = nbpcie_p_read_index(dev, 0xa2);
379 if (((reg32 & 0x70) >> 4) != 0x6) {
380
381 }
382
383
384 set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
385}
386
387
388
389
390void rs690_gfx_init(struct device * nb_dev, struct device * dev, u32 port)
391{
392 u16 reg16;
393 struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
394
395 printk(BIOS_INFO, "rs690_gfx_init, nb_dev=%p dev=%p, port=0x%x.\n",
396 nb_dev, dev, port);
397
398
399 set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 9,
400 cfg->gfx_dev2_dev3 ? 1 << 9 : 0 << 9);
401 printk(BIOS_INFO, "rs690_gfx_init step0.\n");
402
403
404 if (cfg->gfx_lane_reversal) {
405 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
406 if (cfg->gfx_dual_slot)
407 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
408 }
409 printk(BIOS_INFO, "rs690_gfx_init step1.\n");
410
411
412
413 if (cfg->gfx_dual_slot)
414 set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
415 printk(BIOS_INFO, "rs690_gfx_init step2.\n");
416
417
418 if (cfg->gfx_tmds) {
419 }
420
421
422
423
424
425
426 set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
427
428
429 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
430
431
432 udelay(200);
433
434
435 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
436
437
438
439
440
441
442 mdelay(1);
443 printk(BIOS_INFO, "rs690_gfx_init step4.\n");
444
445
446
447
448
449
450
451
452 if (cfg->gfx_compliance) {
453
454 set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
455
456 set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
457 dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
458 printk(BIOS_INFO, "rs690_gfx_init step7.\n");
459 return;
460 }
461
462
463
464 set_pcie_enable_bits(dev, 0x70, 7 << 16, 3 << 16);
465 printk(BIOS_INFO, "rs690_gfx_init step8.1.\n");
466
467
468 set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
469 printk(BIOS_INFO, "rs690_gfx_init step8.2.\n");
470
471
472 set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
473 printk(BIOS_INFO, "rs690_gfx_init step8.3.\n");
474
475
476
477 set_pcie_enable_bits(dev, 0x02, 1 << 14, 1 << 14);
478 printk(BIOS_INFO, "rs690_gfx_init step8.4.\n");
479
480
481 set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
482 printk(BIOS_INFO, "rs690_gfx_init step8.5.\n");
483
484
485 set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
486 printk(BIOS_INFO, "rs690_gfx_init step8.6.\n");
487
488
489
490 set_pcie_enable_bits(dev, 0xa0, 3 << 30, 3 << 30);
491 printk(BIOS_INFO, "rs690_gfx_init step8.8.\n");
492
493
494
495 reg16 = pci_read_config16(dev, 0x5a);
496 reg16 |= 0x100;
497 pci_write_config16(dev, 0x5a, reg16);
498 printk(BIOS_INFO, "rs690_gfx_init step8.9.\n");
499
500
501
502 set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 31, 0 << 31);
503 printk(BIOS_INFO, "rs690_gfx_init step8.10.\n");
504
505
506 set_pcie_enable_bits(nb_dev, 0x02, 1 << 0, 1 << 0);
507 printk(BIOS_INFO, "rs690_gfx_init step8.11.\n");
508
509
510 set_pcie_enable_bits(nb_dev, 0x02, 1 << 6, 1 << 6);
511 printk(BIOS_INFO, "rs690_gfx_init step8.12.\n");
512
513
514 set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
515 printk(BIOS_INFO, "rs690_gfx_init step8.13.\n");
516
517
518
519
520
521
522
523 set_pcie_enable_bits(nb_dev, 0xF9, 3 << 13, 2 << 13);
524 set_pcie_enable_bits(dev, 0xA0, 0xf << 8, 8 << 8);
525 reg16 = pci_read_config16(dev, 0x68);
526 reg16 |= 1 << 0;
527
528
529
530
531
532
533
534
535
536 set_pcie_enable_bits(nb_dev, 0x40, 1 << 3, 1 << 3);
537 set_pcie_enable_bits(nb_dev, 0x40, 1 << 9, 1 << 9);
538
539
540 set_nbmisc_enable_bits(nb_dev, 0x7, 3, 3);
541 set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 22, 1 << 22);
542 set_pcie_enable_bits(nb_dev, 0x11, 0xf << 4, 0xc << 4);
543
544
545
546
547
548
549
550
551 switch (cfg->gfx_dual_slot) {
552 case 0:
553 single_port_configuration(nb_dev, dev);
554 break;
555 case 1:
556 dual_port_configuration(nb_dev, dev);
557 break;
558 default:
559 printk(BIOS_INFO, "Incorrect configuration of external gfx slot.\n");
560 break;
561 }
562}
563
564struct device_operations rs690_gfx = {
565 .id = {.type = DEVICE_ID_PCI,
566 {.pci = {.vendor = PCI_VENDOR_ID_ATI,
567 .device = PCI_DEVICE_ID_ATI_RS690MT_INT_GFX}}},
568 .constructor = default_device_constructor,
569 .phase3_chip_setup_dev = rs690_enable,
570 .phase3_enable = rs690_internal_gfx_enable,
571 .phase3_scan = 0,
572 .phase4_read_resources = rs690_gfx_read_resources,
573 .phase4_set_resources = rs690_gfx_set_resources,
574 .phase5_enable_resources = pci_dev_enable_resources,
575 .phase6_init = internal_gfx_pci_dev_init,
576 .ops_pci = &lops_pci,
577};
578