cpu/amd: Use common AMD's MSR
[coreboot.git] / src / southbridge / amd / sr5650 / sr5650.c
blob1e85c489860512e8105eff14b7d2b064f3307d91
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
5 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <console/console.h>
18 #include <arch/io.h>
19 #include <arch/acpi_ivrs.h>
20 #include <device/device.h>
21 #include <device/pci.h>
22 #include <device/pci_ids.h>
23 #include <device/pci_ops.h>
24 #include <cpu/x86/msr.h>
25 #include <cpu/amd/msr.h>
26 #include <cpu/amd/mtrr.h>
27 #include <stdlib.h>
28 #include <delay.h>
29 #include <option.h>
30 #include "sr5650.h"
31 #include "cmn.h"
34 * extern function declaration
36 struct resource *sr5650_retrieve_cpu_mmio_resource()
38 struct device *domain;
39 struct resource *res;
41 for (domain = all_devices; domain; domain = domain->next) {
42 if (domain->bus->dev->path.type != DEVICE_PATH_DOMAIN)
43 continue;
44 res = probe_resource(domain->bus->dev, MMIO_CONF_BASE);
45 if (res)
46 return res;
49 return NULL;
52 /* extension registers */
53 u32 pci_ext_read_config32(struct device *nb_dev, struct device *dev, u32 reg)
55 /*get BAR3 base address for nbcfg0x1c */
56 u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
57 printk(BIOS_DEBUG, "addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
58 dev->path.pci.devfn);
59 addr |= dev->bus->secondary << 20 | /* bus num */
60 dev->path.pci.devfn << 12 | reg;
61 return *((u32 *) addr);
64 void pci_ext_write_config32(struct device *nb_dev, struct device *dev, u32 reg_pos, u32 mask, u32 val)
66 u32 reg_old, reg;
68 /*get BAR3 base address for nbcfg0x1c */
69 u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
70 /*printk(BIOS_DEBUG, "write: addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
71 dev->path.pci.devfn);*/
72 addr |= dev->bus->secondary << 20 | /* bus num */
73 dev->path.pci.devfn << 12 | reg_pos;
75 reg = reg_old = *((u32 *) addr);
76 reg &= ~mask;
77 reg |= val;
78 if (reg != reg_old) {
79 *((u32 *) addr) = reg;
83 u32 nbpcie_p_read_index(struct device *dev, u32 index)
85 return nb_read_index((dev), NBPCIE_INDEX, (index));
88 void nbpcie_p_write_index(struct device *dev, u32 index, u32 data)
90 nb_write_index((dev), NBPCIE_INDEX, (index), (data));
93 u32 nbpcie_ind_read_index(struct device *nb_dev, u32 index)
95 return nb_read_index((nb_dev), NBPCIE_INDEX, (index));
98 void nbpcie_ind_write_index(struct device *nb_dev, u32 index, u32 data)
100 nb_write_index((nb_dev), NBPCIE_INDEX, (index), (data));
103 uint32_t l2cfg_ind_read_index(struct device *nb_dev, uint32_t index)
105 return nb_read_index((nb_dev), L2CFG_INDEX, (index));
108 void l2cfg_ind_write_index(struct device *nb_dev, uint32_t index, uint32_t data)
110 nb_write_index((nb_dev), L2CFG_INDEX | (0x1 << 8), (index), (data));
113 uint32_t l1cfg_ind_read_index(struct device *nb_dev, uint32_t index)
115 return nb_read_index((nb_dev), L1CFG_INDEX, (index));
118 void l1cfg_ind_write_index(struct device *nb_dev, uint32_t index, uint32_t data)
120 nb_write_index((nb_dev), L1CFG_INDEX | (0x1 << 31), (index), (data));
123 /***********************************************************
124 * To access bar3 we need to program PCI MMIO 7 in K8.
125 * in_out:
126 * 1: enable/enter k8 temp mmio base
127 * 0: disable/restore
128 ***********************************************************/
129 void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add)
131 /* K8 Function1 is address map */
132 struct device *k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
133 struct device *k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
135 if (in_out) {
136 u32 dword, sblk;
138 /* Get SBLink value (HyperTransport I/O Hub Link ID). */
139 dword = pci_read_config32(k8_f0, 0x64);
140 sblk = (dword >> 8) & 0x3;
142 /* Fill MMIO limit/base pair. */
143 pci_write_config32(k8_f1, 0xbc,
144 (((pcie_base_add + 0x10000000 -
145 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4));
146 pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
147 pci_write_config32(k8_f1, 0xb4,
148 (((mmio_base_add + 0x10000000 -
149 1) >> 8) & 0xffffff00) | (sblk << 4));
150 pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
151 } else {
152 pci_write_config32(k8_f1, 0xb8, 0);
153 pci_write_config32(k8_f1, 0xbc, 0);
154 pci_write_config32(k8_f1, 0xb0, 0);
155 pci_write_config32(k8_f1, 0xb4, 0);
159 void PcieReleasePortTraining(struct device *nb_dev, struct device *dev, u32 port)
161 switch (port) {
162 case 2: /* GPP1, bit4-5 */
163 case 3:
164 set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
165 1 << (port + 2), 0 << (port + 2));
166 break;
167 case 4: /* GPP3a, bit20-24 */
168 case 5:
169 case 6:
170 case 7:
171 set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
172 1 << (port + 17), 0 << (port + 17));
173 break;
174 case 9: /* GPP3a, bit25,26 */
175 case 10:
176 set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
177 1 << (port + 16), 0 << (port + 16));
178 break;
179 case 11: /* GPP2, bit6-7 */
180 case 12:
181 set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
182 1 << (port - 5), 0 << (port - 5));
183 break;
184 case 13: /* GPP3b, bit4 of NBMISCIND:0x2A */
185 set_nbmisc_enable_bits(nb_dev, 0x2A,
186 1 << 4, 0 << 4);
187 break;
191 /********************************************************************************************************
192 * Output:
193 * 0: no device is present.
194 * 1: device is present and is trained.
195 ********************************************************************************************************/
196 u8 PcieTrainPort(struct device *nb_dev, struct device *dev, u32 port)
198 u16 count = 5000;
199 u32 lc_state, reg, current_link_width, lane_mask;
200 u8 current, res = 0;
201 u32 gpp_sb_sel = 0;
203 switch (port) {
204 case 2:
205 case 3:
206 gpp_sb_sel = PCIE_CORE_INDEX_GPP1;
207 break;
208 case 4 ... 7:
209 case 9:
210 case 10:
211 gpp_sb_sel = PCIE_CORE_INDEX_GPP3a;
212 break;
213 case 11:
214 case 12:
215 gpp_sb_sel = PCIE_CORE_INDEX_GPP2;
216 break;
217 case 13:
218 gpp_sb_sel = PCIE_CORE_INDEX_GPP3b;
219 break;
222 while (count--) {
223 udelay(40200);
224 lc_state = nbpcie_p_read_index(dev, 0xa5); /* lc_state */
225 printk(BIOS_DEBUG, "PcieLinkTraining port=%x:lc current state=%x\n",
226 port, lc_state);
227 current = lc_state & 0x3f; /* get LC_CURRENT_STATE, bit0-5 */
229 switch (current) {
230 /* 0x00-0x04 means no device is present */
231 case 0x06:
232 /* read back current link width [6:4]. */
233 current_link_width = (nbpcie_p_read_index(dev, 0xA2) >> 4) & 0x7;
234 /* 4 means 7:4 and 15:12
235 * 3 means 7:2 and 15:10
236 * 2 means 7:1 and 15:9
237 * ignoring the reversal case
239 lane_mask = (0xFF << (current_link_width - 2) * 2) & 0xFF;
240 reg = nbpcie_ind_read_index(nb_dev, 0x65 | gpp_sb_sel);
241 reg |= lane_mask << 8 | lane_mask;
242 /* NOTE: See the comments in rs780_pcie.c
243 * switching_gppsb_configurations
244 * In CIMx 4.5.0 and RPR, 4c is done before 5 & 6.
245 * But in this way, a x4 device in port B (dev 4) of
246 * Configuration B can only be detected as x1, instead
247 * of x4. When the port B is being trained, the
248 * LC_CURRENT_STATE is 6 and the LC_LINK_WIDTH_RD is 1.
249 * We have to set the PCIEIND:0x65 as 0xE0E0 and reset
250 * the slot. Then the card seems to work in x1 mode.
252 reg = 0xE0E0; /*I think that the lane_mask calc above is wrong, and this can't be hardcoded because the configuration changes.*/
253 nbpcie_ind_write_index(nb_dev, 0x65 | gpp_sb_sel, reg);
254 printk(BIOS_DEBUG, "link_width=%x, lane_mask=%x",
255 current_link_width, lane_mask);
256 set_pcie_reset();
257 mdelay(1);
258 set_pcie_dereset();
259 break;
260 case 0x07: /* device is in compliance state (training sequence is done). Move to train the next device */
261 res = 1;
262 count = 0;
263 break;
264 case 0x10:
265 reg =
266 pci_ext_read_config32(nb_dev, dev,
267 PCIE_VC0_RESOURCE_STATUS);
268 printk(BIOS_DEBUG, "PcieTrainPort reg=0x%x\n", reg);
269 /* check bit1 */
270 if (reg & VC_NEGOTIATION_PENDING) { /* bit1=1 means the link needs to be re-trained. */
271 /* set bit8=1, bit0-2=bit4-6 */
272 u32 tmp;
273 reg = nbpcie_p_read_index(dev, PCIE_LC_LINK_WIDTH);
274 tmp = (reg >> 4) & 0x7; /* get bit4-6 */
275 reg &= 0xfff8; /* clear bit0-2 */
276 reg += tmp; /* merge */
277 reg |= 1 << 8;
278 nbpcie_p_write_index(dev, PCIE_LC_LINK_WIDTH, reg);
279 count++; /* CIM said "keep in loop"? */
280 } else {
281 res = 1;
282 count = 0;
284 break;
285 default:
286 /* CIMx Unknown Workaround - There is a device that won't train. Try to reset it. */
287 /* if there are no device resets and nothing works, CIMx does a cf9 system reset (yikes!) */
288 set_pcie_reset();
289 mdelay(1);
290 set_pcie_dereset();
291 res = 0;
292 count = 0; /* break loop */
293 break;
296 return res;
300 * Set Top Of Memory below and above 4G.
302 void sr5650_set_tom(struct device *nb_dev)
304 msr_t sysmem;
306 /* The system top memory in SR56X0. */
307 sysmem = rdmsr(0xc001001A);
308 printk(BIOS_DEBUG, "Sysmem TOM = %x_%x\n", sysmem.hi, sysmem.lo);
309 pci_write_config32(nb_dev, 0x90, sysmem.lo);
311 sysmem = rdmsr(0xc001001D);
312 printk(BIOS_DEBUG, "Sysmem TOM2 = %x_%x\n", sysmem.hi, sysmem.lo);
313 htiu_write_index(nb_dev, 0x31, sysmem.hi);
314 htiu_write_index(nb_dev, 0x30, sysmem.lo | 1);
317 u32 get_vid_did(struct device *dev)
319 return pci_read_config32(dev, 0);
322 void detect_and_enable_iommu(struct device *iommu_dev) {
323 uint32_t dword;
324 uint8_t l1_target;
325 unsigned char iommu;
326 void *mmio_base;
328 iommu = 1;
329 get_option(&iommu, "iommu");
331 if (iommu) {
332 printk(BIOS_DEBUG, "Initializing IOMMU\n");
334 struct device *nb_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
336 if (!nb_dev) {
337 printk(BIOS_WARNING, "Unable to find SR5690 device! IOMMU NOT initialized\n");
338 return;
341 mmio_base = (void *)(pci_read_config32(iommu_dev, 0x44) &
342 0xffffc000);
344 // if (get_nb_rev(nb_dev) == REV_SR5650_A11) {
345 // dword = pci_read_config32(iommu_dev, 0x6c);
346 // dword &= ~(0x1 << 8);
347 // pci_write_config32(iommu_dev, 0x6c, dword);
348 // }
350 dword = pci_read_config32(iommu_dev, 0x50);
351 dword &= ~(0x1 << 22);
352 pci_write_config32(iommu_dev, 0x50, dword);
354 dword = pci_read_config32(iommu_dev, 0x44);
355 dword |= 0x1;
356 pci_write_config32(iommu_dev, 0x44, dword);
358 write32((void *)(mmio_base + 0x8), 0x0);
359 write32((void *)(mmio_base + 0xc), 0x08000000);
360 write32((void *)(mmio_base + 0x10), 0x0);
361 write32((void *)(mmio_base + 0x2008), 0x0);
362 write32((void *)(mmio_base + 0x2010), 0x0);
364 /* IOMMU L1 initialization */
365 for (l1_target = 0; l1_target < 6; l1_target++) {
366 dword = l1cfg_ind_read_index(nb_dev, (l1_target << 16) + 0xc);
367 dword |= (0x7 << 28);
368 l1cfg_ind_write_index(nb_dev, (l1_target << 16) + 0xc, dword);
370 dword = l1cfg_ind_read_index(nb_dev, (l1_target << 16) + 0x7);
371 dword |= (0x1 << 5);
372 l1cfg_ind_write_index(nb_dev, (l1_target << 16) + 0x7, dword);
375 /* IOMMU L2 initialization */
376 dword = l2cfg_ind_read_index(nb_dev, 0xc);
377 dword |= (0x7 << 29);
378 l2cfg_ind_write_index(nb_dev, 0xc, dword);
380 dword = l2cfg_ind_read_index(nb_dev, 0x10);
381 dword &= ~(0x3 << 8);
382 dword |= (0x2 << 8);
383 l2cfg_ind_write_index(nb_dev, 0x10, dword);
385 dword = l2cfg_ind_read_index(nb_dev, 0x14);
386 dword &= ~(0x3 << 8);
387 dword |= (0x2 << 8);
388 l2cfg_ind_write_index(nb_dev, 0x14, dword);
390 dword = l2cfg_ind_read_index(nb_dev, 0x18);
391 dword &= ~(0x3 << 8);
392 dword |= (0x2 << 8);
393 l2cfg_ind_write_index(nb_dev, 0x18, dword);
395 dword = l2cfg_ind_read_index(nb_dev, 0x1c);
396 dword &= ~(0x3 << 8);
397 dword |= (0x2 << 8);
398 l2cfg_ind_write_index(nb_dev, 0x1c, dword);
400 dword = l2cfg_ind_read_index(nb_dev, 0x50);
401 dword &= ~(0x3 << 8);
402 dword |= (0x2 << 8);
403 l2cfg_ind_write_index(nb_dev, 0x50, dword);
405 dword = l2cfg_ind_read_index(nb_dev, 0x10);
406 dword |= (0x1 << 4);
407 l2cfg_ind_write_index(nb_dev, 0x10, dword);
409 dword = l2cfg_ind_read_index(nb_dev, 0x14);
410 dword |= (0x1 << 4);
411 l2cfg_ind_write_index(nb_dev, 0x14, dword);
413 dword = l2cfg_ind_read_index(nb_dev, 0x18);
414 dword |= (0x1 << 4);
415 l2cfg_ind_write_index(nb_dev, 0x18, dword);
417 dword = l2cfg_ind_read_index(nb_dev, 0x1c);
418 dword |= (0x1 << 4);
419 l2cfg_ind_write_index(nb_dev, 0x1c, dword);
421 dword = l2cfg_ind_read_index(nb_dev, 0x50);
422 dword |= (0x1 << 4);
423 l2cfg_ind_write_index(nb_dev, 0x50, dword);
425 dword = l2cfg_ind_read_index(nb_dev, 0x6);
426 dword |= (0x1 << 7);
427 l2cfg_ind_write_index(nb_dev, 0x6, dword);
429 dword = l2cfg_ind_read_index(nb_dev, 0x44);
430 dword |= (0x1 << 0);
431 l2cfg_ind_write_index(nb_dev, 0x44, dword);
433 // if (get_nb_rev(nb_dev) == REV_SR5650_A21) {
434 dword = l2cfg_ind_read_index(nb_dev, 0x7);
435 dword |= (0x1 << 1);
436 l2cfg_ind_write_index(nb_dev, 0x7, dword);
438 dword = l2cfg_ind_read_index(nb_dev, 0x44);
439 dword |= (0x1 << 1);
440 l2cfg_ind_write_index(nb_dev, 0x44, dword);
442 dword = l2cfg_ind_read_index(nb_dev, 0x7);
443 dword |= (0x1 << 2);
444 l2cfg_ind_write_index(nb_dev, 0x7, dword);
446 dword = l2cfg_ind_read_index(nb_dev, 0x7);
447 dword |= (0x1 << 3);
448 l2cfg_ind_write_index(nb_dev, 0x7, dword);
450 dword = l2cfg_ind_read_index(nb_dev, 0x44);
451 dword |= (0x1 << 3);
452 l2cfg_ind_write_index(nb_dev, 0x44, dword);
454 dword = l2cfg_ind_read_index(nb_dev, 0x7);
455 dword |= (0x1 << 4);
456 l2cfg_ind_write_index(nb_dev, 0x7, dword);
458 dword = l2cfg_ind_read_index(nb_dev, 0x6);
459 dword |= (0x1 << 5);
460 l2cfg_ind_write_index(nb_dev, 0x6, dword);
462 dword = l2cfg_ind_read_index(nb_dev, 0x6);
463 dword |= (0x1 << 6);
464 l2cfg_ind_write_index(nb_dev, 0x6, dword);
466 dword = l2cfg_ind_read_index(nb_dev, 0x7);
467 dword |= (0x1 << 5);
468 l2cfg_ind_write_index(nb_dev, 0x7, dword);
470 dword = l2cfg_ind_read_index(nb_dev, 0x44);
471 dword |= (0x1 << 4);
472 l2cfg_ind_write_index(nb_dev, 0x44, dword);
474 dword = l2cfg_ind_read_index(nb_dev, 0x7);
475 dword |= (0x1 << 6);
476 l2cfg_ind_write_index(nb_dev, 0x7, dword);
478 dword = l2cfg_ind_read_index(nb_dev, 0x7);
479 dword |= (0x1 << 7);
480 l2cfg_ind_write_index(nb_dev, 0x7, dword);
482 dword = l2cfg_ind_read_index(nb_dev, 0x6);
483 dword |= (0x1 << 8);
484 l2cfg_ind_write_index(nb_dev, 0x6, dword);
485 // }
487 l2cfg_ind_write_index(nb_dev, 0x52, 0xf0000002);
489 dword = l2cfg_ind_read_index(nb_dev, 0x80);
490 dword |= (0x1 << 0);
491 l2cfg_ind_write_index(nb_dev, 0x80, dword);
493 dword = l2cfg_ind_read_index(nb_dev, 0x30);
494 dword |= (0x1 << 0);
495 l2cfg_ind_write_index(nb_dev, 0x30, dword);
499 void sr5650_iommu_read_resources(struct device *dev)
501 unsigned char iommu;
502 struct resource *res;
504 iommu = 1;
505 get_option(&iommu, "iommu");
507 /* Get the normal pci resources of this device */
508 pci_dev_read_resources(dev);
510 if (iommu) {
511 /* Request MMIO range allocation */
512 res = new_resource(dev, 0x44); /* IOMMU */
513 res->base = 0x0;
514 res->size = 0x4000;
515 res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
516 res->align = 14; /* 16k alignment */
517 res->gran = 14;
518 res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE;
521 compact_resources(dev);
524 void sr5650_iommu_set_resources(struct device *dev)
526 unsigned char iommu;
527 struct resource *res;
529 iommu = 1;
530 get_option(&iommu, "iommu");
532 /* Get the normal pci resources of this device */
533 pci_dev_read_resources(dev);
535 if (iommu) {
536 /* Get the allocated range */
537 res = find_resource(dev, 0x44);
539 if (res->base == 0) {
540 printk(BIOS_WARNING, "Unable to allocate MMIO range to IOMMU\n");
543 /* Assign the range to hardware */
544 pci_write_config32(dev, 0x44, res->base & 0xffffc000);
545 pci_write_config32(dev, 0x48, 0x0);
548 /* Run standard resource set routine */
549 pci_dev_set_resources(dev);
552 void sr5650_iommu_enable_resources(struct device *dev)
554 detect_and_enable_iommu(dev);
557 void sr5650_nb_pci_table(struct device *nb_dev)
558 { /* NBPOR_InitPOR function. */
559 u8 temp8;
560 u16 temp16;
561 u32 temp32;
563 /* Program NB PCI table. */
564 temp16 = pci_read_config16(nb_dev, 0x04);
565 printk(BIOS_DEBUG, "NB_PCI_REG04 = %x.\n", temp16);
566 temp32 = pci_read_config32(nb_dev, 0x84);
567 printk(BIOS_DEBUG, "NB_PCI_REG84 = %x.\n", temp32);
568 //Reg4Ch[1]=1 (APIC_ENABLE) force CPU request with address 0xFECx_xxxx to south-bridge
569 //Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
570 pci_write_config8(nb_dev, 0x4c, 0x42);
571 temp8 = pci_read_config8(nb_dev, 0x4e);
572 temp8 |= 0x05; /* BAR1_ENABLE */
573 pci_write_config8(nb_dev, 0x4e, temp8);
575 temp32 = pci_read_config32(nb_dev, 0x4c);
576 printk(BIOS_DEBUG, "NB_PCI_REG4C = %x.\n", temp32);
578 /* disable GFX debug. */
579 temp8 = pci_read_config8(nb_dev, 0x8d);
580 temp8 &= ~(1<<1);
581 pci_write_config8(nb_dev, 0x8d, temp8);
583 /* The system top memory in SR56X0. */
584 sr5650_set_tom(nb_dev);
586 /* Program NB HTIU table. */
587 //set_htiu_enable_bits(nb_dev, 0x05, 1<<10 | 1<<9, 1<<10|1<<9);
588 set_htiu_enable_bits(nb_dev, 0x06, 1, 0x4203a202);
589 //set_htiu_enable_bits(nb_dev, 0x07, 1<<1 | 1<<2, 0x8001);
590 set_htiu_enable_bits(nb_dev, 0x15, 0, 1<<31 | 1<<30 | 1<<27);
591 set_htiu_enable_bits(nb_dev, 0x1c, 0, 0xfffe0000);
592 set_htiu_enable_bits(nb_dev, 0x0c, 0x3f, 1 | 1<<3);
593 set_htiu_enable_bits(nb_dev, 0x19, 0xfffff+(1<<31), 0x186a0+(1<<31));
594 set_htiu_enable_bits(nb_dev, 0x16, 0x3f<<10, 0x7<<10);
595 set_htiu_enable_bits(nb_dev, 0x23, 0, 1<<28);
598 /***********************************************
599 * 0:00.0 NBCFG :
600 * 0:00.1 CLK : bit 0 of nb_cfg 0x4c : 0 - disable, default
601 * 0:01.0 P2P Internal:
602 * 0:02.0 P2P : bit 2 of nbmiscind 0x0c : 0 - enable, default + 32 * 2
603 * 0:03.0 P2P : bit 3 of nbmiscind 0x0c : 0 - enable, default + 32 * 2
604 * 0:04.0 P2P : bit 4 of nbmiscind 0x0c : 0 - enable, default + 32 * 2
605 * 0:05.0 P2P : bit 5 of nbmiscind 0x0c : 0 - enable, default + 32 * 2
606 * 0:06.0 P2P : bit 6 of nbmiscind 0x0c : 0 - enable, default + 32 * 2
607 * 0:07.0 P2P : bit 7 of nbmiscind 0x0c : 0 - enable, default + 32 * 2
608 * 0:08.0 NB2SB : bit 6 of nbmiscind 0x00 : 0 - disable, default + 32 * 1
609 * case 0 will be called twice, one is by CPU in hypertransport.c line458,
610 * the other is by sr5650.
611 ***********************************************/
612 void sr5650_enable(struct device *dev)
614 struct device *nb_dev = NULL, *sb_dev = NULL;
615 int dev_ind;
616 struct southbridge_amd_sr5650_config *cfg;
618 printk(BIOS_INFO, "sr5650_enable: dev=%p, VID_DID=0x%x\n", dev, get_vid_did(dev));
619 nb_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
620 if (!nb_dev) {
621 die("sr5650_enable: CAN NOT FIND SR5650 DEVICE, HALT!\n");
622 /* NOT REACHED */
624 cfg = (struct southbridge_amd_sr5650_config *)nb_dev->chip_info;
626 /* sb_dev (dev 8) is a bridge that links to southbridge. */
627 sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
628 if (!sb_dev) {
629 die("sr5650_enable: CAN NOT FIND SB bridge, HALT!\n");
630 /* NOT REACHED */
633 dev_ind = dev->path.pci.devfn >> 3;
634 switch (dev_ind) {
635 case 0: /* bus0, dev0, fun0; */
636 switch (dev->path.pci.devfn & 0x7) {
637 case 0:
638 printk(BIOS_INFO, "Bus-0, Dev-0, Fun-0.\n");
639 enable_pcie_bar3(nb_dev); /* PCIEMiscInit */
641 config_gpp_core(nb_dev, sb_dev);
642 sr5650_gpp_sb_init(nb_dev, sb_dev, 8);
644 sr5650_nb_pci_table(nb_dev);
645 break;
646 case 1:
647 printk(BIOS_INFO, "Bus-0, Dev-0, Fun-1.\n");
648 break;
649 case 2:
650 printk(BIOS_INFO, "Bus-0, Dev-0, Fun-2.\n");
651 break;
653 break;
655 case 2: /* bus0, dev2,3 GPP1 */
656 case 3:
657 printk(BIOS_INFO, "Bus-0, Dev-2,3, Fun-0. enable=%d\n", dev->enabled);
658 set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << dev_ind,
659 (dev->enabled ? 0 : 1) << dev_ind);
660 if (dev->enabled)
661 sr5650_gpp_sb_init(nb_dev, dev, dev_ind); /* Note, dev 2,3 are generic PCIe ports. */
662 break;
663 case 4: /* bus0, dev4-7, four GPP3a */
664 case 5:
665 case 6:
666 case 7:
667 enable_pcie_bar3(nb_dev); /* PCIEMiscInit */
668 printk(BIOS_INFO, "Bus-0, Dev-4,5,6,7, Fun-0. enable=%d\n",
669 dev->enabled);
670 set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << dev_ind,
671 (dev->enabled ? 0 : 1) << dev_ind);
672 if (dev->enabled)
673 sr5650_gpp_sb_init(nb_dev, dev, dev_ind);
674 break;
675 case 8: /* bus0, dev8, SB */
676 printk(BIOS_INFO, "Bus-0, Dev-8, Fun-0. enable=%d\n", dev->enabled);
677 set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 6,
678 (dev->enabled ? 1 : 0) << 6);
679 if (dev->enabled)
680 sr5650_gpp_sb_init(nb_dev, dev, dev_ind);
681 disable_pcie_bar3(nb_dev);
682 break;
683 case 9: /* bus 0, dev 9,10, GPP3a */
684 case 10:
685 printk(BIOS_INFO, "Bus-0, Dev-9, 10, Fun-0. enable=%d\n",
686 dev->enabled);
687 enable_pcie_bar3(nb_dev); /* PCIEMiscInit */
688 set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << (7 + dev_ind),
689 (dev->enabled ? 0 : 1) << (7 + dev_ind));
690 if (dev->enabled)
691 sr5650_gpp_sb_init(nb_dev, dev, dev_ind);
692 /* Don't call disable_pcie_bar3(nb_dev) here, otherwise the screen will crash. */
693 break;
694 case 11:
695 case 12: /* bus 0, dev 11,12, GPP2 */
696 printk(BIOS_INFO, "Bus-0, Dev-11,12, Fun-0. enable=%d\n", dev->enabled);
697 set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << (7 + dev_ind),
698 (dev->enabled ? 0 : 1) << (7 + dev_ind));
699 if (dev->enabled)
700 sr5650_gpp_sb_init(nb_dev, dev, dev_ind);
701 break;
702 case 13: /* bus 0, dev 12, GPP3b */
703 set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << (7 + dev_ind),
704 (dev->enabled ? 0 : 1) << (7 + dev_ind));
705 if (dev->enabled)
706 sr5650_gpp_sb_init(nb_dev, dev, dev_ind);
707 break;
708 default:
709 printk(BIOS_DEBUG, "unknown dev: %s\n", dev_path(dev));
712 /* Lock HWInit Register after the last device was done */
713 if (dev_ind == 13) {
714 sr56x0_lock_hwinitreg();
715 udelay(cfg->pcie_settling_time);
719 static void add_ivrs_device_entries(struct device *parent, struct device *dev,
720 int depth, int linknum, int8_t *root_level,
721 unsigned long *current, uint16_t *length)
723 uint8_t *p = (uint8_t *) *current;
725 struct device *sibling;
726 struct bus *link;
728 if (!root_level) {
729 root_level = malloc(sizeof(int8_t));
730 if (root_level == NULL)
731 die("Error: Could not allocate a byte!\n");
732 *root_level = -1;
735 if ((dev->path.type == DEVICE_PATH_PCI) &&
736 (dev->bus->secondary == 0x0) && (dev->path.pci.devfn == 0x0))
737 *root_level = depth;
739 if ((dev->path.type == DEVICE_PATH_PCI) && (*root_level != -1) &&
740 (depth >= *root_level) && (dev->enabled)) {
742 *p = 0;
743 if (depth == *root_level) {
744 if (dev->path.pci.devfn < (0x1 << 3)) {
745 /* SR5690 control device */
746 } else if ((dev->path.pci.devfn >= (0x1 << 3)) &&
747 (dev->path.pci.devfn < (0xe << 3))) {
748 /* SR5690 PCIe bridge device */
749 } else if (dev->path.pci.devfn == (0x14 << 3)) {
750 /* SMBUS controller */
751 p[0] = IVHD_DEV_4_BYTE_SELECT; /* Entry type */
752 p[1] = dev->path.pci.devfn; /* Device */
753 p[2] = dev->bus->secondary; /* Bus */
754 p[3] = IVHD_DTE_LINT_1_PASS | /* Data */
755 IVHD_DTE_SYS_MGT_NO_TRANS |
756 IVHD_DTE_NMI_PASS |
757 IVHD_DTE_EXT_INT_PASS |
758 IVHD_DTE_INIT_PASS;
759 } else {
760 /* Other southbridge device */
761 p[0] = IVHD_DEV_4_BYTE_SELECT; /* Entry type */
762 p[1] = dev->path.pci.devfn; /* Device */
763 p[2] = dev->bus->secondary; /* Bus */
764 p[3] = 0x0; /* Data */
766 } else if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) {
767 /* Device behind bridge */
768 if (pci_find_capability(dev, PCI_CAP_ID_PCIE)) {
769 /* Device is PCIe */
770 p[0] = IVHD_DEV_4_BYTE_SELECT; /* Entry type */
771 p[1] = dev->path.pci.devfn; /* Device */
772 p[2] = dev->bus->secondary; /* Bus */
773 p[3] = 0x0; /* Data */
774 } else {
775 /* Device is legacy PCI or PCI-X */
776 p[0] = IVHD_DEV_8_BYTE_ALIAS_SELECT; /* Entry */
777 p[1] = dev->path.pci.devfn; /* Device */
778 p[2] = dev->bus->secondary; /* Bus */
779 p[3] = 0x0; /* Data */
780 p[4] = 0x0; /* Reserved */
781 p[5] = parent->path.pci.devfn; /* Device */
782 p[6] = parent->bus->secondary; /* Bus */
783 p[7] = 0x0; /* Reserved */
787 if (*p == IVHD_DEV_4_BYTE_SELECT) {
788 *length += 4;
789 *current += 4;
790 } else if (*p == IVHD_DEV_8_BYTE_ALIAS_SELECT) {
791 *length += 8;
792 *current += 8;
796 for (link = dev->link_list; link; link = link->next)
797 for (sibling = link->children; sibling;
798 sibling = sibling->sibling)
799 add_ivrs_device_entries(dev, sibling, depth + 1,
800 depth, root_level, current, length);
802 if (depth == 0)
803 free(root_level);
806 unsigned long acpi_fill_mcfg(unsigned long current)
808 struct resource *res;
809 resource_t mmconf_base = EXT_CONF_BASE_ADDRESS;
811 if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
812 res = sr5650_retrieve_cpu_mmio_resource();
813 if (res)
814 mmconf_base = res->base;
816 current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, mmconf_base, 0x0, 0x0, 0x1f);
819 return current;
822 static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current)
824 uint8_t *p;
826 struct device *nb_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
827 if (!nb_dev) {
828 printk(BIOS_WARNING, "acpi_fill_ivrs: Unable to locate SR5650 "
829 "device! IVRS table not generated...\n");
830 return (unsigned long)ivrs;
833 struct device *iommu_dev = dev_find_slot(0, PCI_DEVFN(0, 2));
834 if (!iommu_dev) {
835 printk(BIOS_WARNING, "acpi_fill_ivrs: Unable to locate SR5650 "
836 "IOMMU device! IVRS table not generated...\n");
837 return (unsigned long)ivrs;
840 ivrs->iv_info = IVINFO_VA_SIZE_64_BITS | IVINFO_PA_SIZE_52_BITS;
842 ivrs->ivhd.type = IVHD_BLOCK_TYPE_LEGACY__FIXED;
843 ivrs->ivhd.flags = IVHD_FLAG_ISOC |
844 IVHD_FLAG_RES_PASS_PW |
845 IVHD_FLAG_PASS_PW |
846 IVHD_FLAG_IOTLB_SUP;
848 ivrs->ivhd.length = sizeof(struct acpi_ivrs_ivhd);
850 /* BDF <bus>:00.2 */
851 ivrs->ivhd.device_id = 0x2 | (nb_dev->bus->secondary << 8);
853 /* Capability block 0x40 (type 0xf, "Secure device") */
854 ivrs->ivhd.capability_offset = 0x40;
855 ivrs->ivhd.iommu_base_low = pci_read_config32(iommu_dev, 0x44) &
856 0xffffc000;
857 ivrs->ivhd.iommu_base_high = pci_read_config32(iommu_dev, 0x48);
858 ivrs->ivhd.pci_segment_group = 0x0;
859 ivrs->ivhd.iommu_info = 0x0;
860 ivrs->ivhd.iommu_info |= (0x14 << IOMMU_INFO_UNIT_ID_SHIFT);
861 ivrs->ivhd.iommu_feature_info = 0x0;
863 /* Describe HPET */
864 p = (uint8_t *)current;
865 p[0] = IVHD_DEV_8_BYTE_EXT_SPECIAL_DEV; /* Entry type */
866 p[1] = 0; /* Device */
867 p[2] = 0; /* Bus */
868 p[3] = IVHD_DTE_LINT_1_PASS | /* DTE */
869 IVHD_DTE_LINT_0_PASS |
870 IVHD_DTE_SYS_MGT_INTX_NO_TRANS |
871 IVHD_DTE_NMI_PASS |
872 IVHD_DTE_EXT_INT_PASS |
873 IVHD_DTE_INIT_PASS;
874 p[4] = 0x0; /* HPET number */
875 p[5] = 0x14 << 3; /* HPET device */
876 p[6] = nb_dev->bus->secondary; /* HPET bus */
877 p[7] = IVHD_SPECIAL_DEV_HPET; /* Variety */
878 ivrs->ivhd.length += 8;
879 current += 8;
881 /* Describe PCI devices */
882 add_ivrs_device_entries(NULL, all_devices, 0, -1, NULL, &current,
883 &ivrs->ivhd.length);
885 /* Describe IOAPICs */
886 unsigned long prev_current = current;
887 current = acpi_fill_ivrs_ioapic(ivrs, current);
888 ivrs->ivhd.length += (current - prev_current);
890 return current;
893 unsigned long southbridge_write_acpi_tables(struct device *device,
894 unsigned long current,
895 struct acpi_rsdp *rsdp)
897 unsigned char iommu;
899 iommu = 1;
900 get_option(&iommu, "iommu");
902 if (iommu) {
903 acpi_ivrs_t *ivrs;
905 /* IVRS */
906 current = ALIGN(current, 8);
907 printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
908 ivrs = (acpi_ivrs_t *) current;
909 acpi_create_ivrs(ivrs, acpi_fill_ivrs);
910 current += ivrs->header.length;
911 acpi_add_table(rsdp, ivrs);
914 return current;
917 static struct pci_operations iommu_ops_pci = {
918 .set_subsystem = pci_dev_set_subsystem,
921 static struct device_operations iommu_ops = {
922 .read_resources = sr5650_iommu_read_resources,
923 .set_resources = sr5650_iommu_set_resources,
924 .enable_resources = sr5650_iommu_enable_resources,
925 .write_acpi_tables = southbridge_write_acpi_tables,
926 .init = 0,
927 .scan_bus = 0,
928 .ops_pci = &iommu_ops_pci,
931 static const struct pci_driver ht_driver_sr5690 __pci_driver = {
932 .ops = &iommu_ops,
933 .vendor = PCI_VENDOR_ID_ATI,
934 .device = PCI_DEVICE_ID_AMD_SR5650_IOMMU,
937 struct chip_operations southbridge_amd_sr5650_ops = {
938 CHIP_NAME("ATI SR5650")
939 .enable_dev = sr5650_enable,