blob: 9a359e3dd9ee82f793c462bc72c536ba94f2fb84 [file] [log] [blame]
Yinghai Luc34e3ab2006-10-12 00:58:20 +00001#include <console/console.h>
2#include <device/pci.h>
3#include <string.h>
4#include <stdint.h>
5#include <arch/pirq_routing.h>
6#include <cpu/amd/amdk8_sysconf.h>
7
8#include "mb_sysconf.h"
9
Stefan Reinauer14e22772010-04-27 06:56:47 +000010static void write_pirq_info(struct irq_info *pirq_info, uint8_t bus, uint8_t devfn, uint8_t link0, uint16_t bitmap0,
Yinghai Luc34e3ab2006-10-12 00:58:20 +000011 uint8_t link1, uint16_t bitmap1, uint8_t link2, uint16_t bitmap2,uint8_t link3, uint16_t bitmap3,
12 uint8_t slot, uint8_t rfu)
13{
Stefan Reinauer14e22772010-04-27 06:56:47 +000014 pirq_info->bus = bus;
Yinghai Luc34e3ab2006-10-12 00:58:20 +000015 pirq_info->devfn = devfn;
16
17 pirq_info->irq[0].link = link0;
18 pirq_info->irq[0].bitmap = bitmap0;
19 pirq_info->irq[1].link = link1;
20 pirq_info->irq[1].bitmap = bitmap1;
21 pirq_info->irq[2].link = link2;
22 pirq_info->irq[2].bitmap = bitmap2;
23 pirq_info->irq[3].link = link3;
24 pirq_info->irq[3].bitmap = bitmap3;
25
26 pirq_info->slot = slot;
27 pirq_info->rfu = rfu;
28}
29
30
Stefan Reinauere9de1e22010-04-07 15:30:11 +000031
Yinghai Luc34e3ab2006-10-12 00:58:20 +000032
33unsigned long write_pirq_routing_table(unsigned long addr)
34{
35
36 struct irq_routing_table *pirq;
37 struct irq_info *pirq_info;
38 unsigned slot_num;
39 uint8_t *v;
40
41 uint8_t sum=0;
42 int i;
43
44 struct mb_sysconf_t *m;
45
46 get_bus_conf(); // it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c
Stefan Reinauer14e22772010-04-27 06:56:47 +000047
Yinghai Luc34e3ab2006-10-12 00:58:20 +000048 m = sysconf.mb;
49
50 /* Align the table to be 16 byte aligned. */
51 addr += 15;
52 addr &= ~15;
53
Kyösti Mälkki9533d832014-06-26 05:30:54 +030054 /* This table must be between 0xf0000 & 0x100000 */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000055 printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000056
57 pirq = (void *)(addr);
58 v = (uint8_t *)(addr);
Stefan Reinauer14e22772010-04-27 06:56:47 +000059
Yinghai Luc34e3ab2006-10-12 00:58:20 +000060 pirq->signature = PIRQ_SIGNATURE;
61 pirq->version = PIRQ_VERSION;
Stefan Reinauer14e22772010-04-27 06:56:47 +000062
Yinghai Luc34e3ab2006-10-12 00:58:20 +000063 pirq->rtr_bus = m->bus_8111_0;
64 pirq->rtr_devfn = ((sysconf.sbdn+1)<<3)|0;
65
66 pirq->exclusive_irqs = 0;
Stefan Reinauer14e22772010-04-27 06:56:47 +000067
Yinghai Luc34e3ab2006-10-12 00:58:20 +000068 pirq->rtr_vendor = 0x1022;
69 pirq->rtr_device = 0x746b;
70
71 pirq->miniport_data = 0;
72
73 memset(pirq->rfu, 0, sizeof(pirq->rfu));
Stefan Reinauer14e22772010-04-27 06:56:47 +000074
Yinghai Luc34e3ab2006-10-12 00:58:20 +000075 pirq_info = (void *) ( &pirq->checksum + 1);
76 slot_num = 0;
Stefan Reinauer14e22772010-04-27 06:56:47 +000077
Yinghai Luc34e3ab2006-10-12 00:58:20 +000078 {
79 device_t dev;
80 dev = dev_find_slot(m->bus_8111_0, PCI_DEVFN(sysconf.sbdn+1,3));
81 if (dev) {
82 /* initialize PCI interupts - these assignments depend
83 on the PCB routing of PINTA-D
84
85 PINTA = IRQ3
86 PINTB = IRQ5
87 PINTC = IRQ10
88 PINTD = IRQ11
89 */
90 pci_write_config16(dev, 0x56, 0xba53);
91 }
92 }
93
94//pci bridge
Elyes HAOUASaedcc102014-07-21 08:07:19 +020095 printk(BIOS_DEBUG, "setting Onboard AMD Southbridge\n");
Yinghai Luc34e3ab2006-10-12 00:58:20 +000096 static const unsigned char slotIrqs_1_4[4] = { 3, 5, 10, 11 };
97 pci_assign_irqs(m->bus_8111_0, sysconf.sbdn+1, slotIrqs_1_4);
98 write_pirq_info(pirq_info, m->bus_8111_0, ((sysconf.sbdn+1)<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
99 pirq_info++; slot_num++;
100
Elyes HAOUASaedcc102014-07-21 08:07:19 +0200101 printk(BIOS_DEBUG, "setting Onboard AMD USB\n");
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000102 static const unsigned char slotIrqs_8111_1_0[4] = { 0, 0, 0, 11};
103 pci_assign_irqs(m->bus_8111_1, 0, slotIrqs_8111_1_0);
104 write_pirq_info(pirq_info, m->bus_8111_1,0, 0, 0, 0, 0, 0, 0, 0x4, 0xdef8, 0, 0);
105 pirq_info++; slot_num++;
106
107//pcix bridge
108// write_pirq_info(pirq_info, m->bus_8132_0, (sbdn3<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
109// pirq_info++; slot_num++;
110
111 int j = 0;
112
113 for(i=1; i< sysconf.hc_possible_num; i++) {
114 if(!(sysconf.pci1234[i] & 0x1) ) continue;
115 unsigned busn = (sysconf.pci1234[i] >> 16) & 0xff;
116 unsigned devn = sysconf.hcdn[i] & 0xff;
117
118 write_pirq_info(pirq_info, busn, (devn<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
119 pirq_info++; slot_num++;
120 j++;
121
122 }
Stefan Reinauer14e22772010-04-27 06:56:47 +0000123
124 pirq->size = 32 + 16 * slot_num;
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000125
126 for (i = 0; i < pirq->size; i++)
Stefan Reinauer14e22772010-04-27 06:56:47 +0000127 sum += v[i];
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000128
129 sum = pirq->checksum - sum;
130
131 if (sum != pirq->checksum) {
132 pirq->checksum = sum;
133 }
134
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000135 printk(BIOS_INFO, "done.\n");
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000136
137 return (unsigned long) pirq_info;
138
139}