3 #include <device/device.h>
4 #include <device/pci.h>
5 #include <device/pci_ops.h>
6 #include <device/pci_ids.h>
7 #include <console/console.h>
8 #include <cpu/amd/gx2def.h>
9 #include <cpu/x86/msr.h>
13 #define PIN_OPT_IDE (1ULL<<0) /* 0 for flash, 1 for IDE */
15 /* Intended value for LBAR_FLSH0: 4KiB, enabled, MMIO, NAND, @0x20000000 */
16 /* NOTE: no longer used, prune at some point */
17 msr_t flsh0 = { .hi=0xFFFFF007, .lo=0x20000000};
20 enable_ide_nand_flash(){
22 printk_err("cs5536: %s\n", __FUNCTION__);
24 /* steve took this one out ... not sure if needed or not */
25 msr = rdmsr(MDD_LBAR_FLSH0);
27 if ( ((msr.hi) & 7) != 7) {
28 printk_err("MDD_LBAR_FLSH0 was 0x%08x%08x\n", msr.hi,msr.lo);
29 wrmsr(MDD_LBAR_FLSH0, flsh0);
31 msr = rdmsr(MDD_LBAR_FLSH0);
32 printk_err("MDD_LBAR_FLSH0 is 0x%08x%08x\n", msr.hi,msr.lo);
34 msr = rdmsr(MDD_PIN_OPT);
35 if (msr.lo & PIN_OPT_IDE) {
36 printk_err("MDD_PIN_OPT was 0x%08x%08x\n", msr.hi,msr.lo);
37 msr.lo &= ~PIN_OPT_IDE;
38 wrmsr(MDD_PIN_OPT, msr);
40 msr = rdmsr(MDD_PIN_OPT);
41 printk_err("MDD_PIN_OPT is 0x%08x%08x\n", msr.hi,msr.lo);
43 msr = rdmsr(MDD_NANDF_DATA);
44 if (msr.lo != 0x00100010) {
45 printk_err("MDD_NANDF_DATA was 0x%08x%08x\n", msr.hi,msr.lo);
47 wrmsr(MDD_NANDF_DATA, msr);
49 msr = rdmsr(MDD_NANDF_DATA);
50 printk_err("MDD_NANDF_DATA is 0x%08x%08x\n", msr.hi,msr.lo);
52 msr = rdmsr(MDD_NADF_CNTL);
53 if (msr.lo != 0x0010) {
54 printk_err("MDD_NADF_CNTL was 0x%08x%08x\n", msr.hi,msr.lo);
56 wrmsr(MDD_NADF_CNTL, msr);
58 msr = rdmsr(MDD_NADF_CNTL);
59 printk_err("MDD_NADF_CNTL is 0x%08x%08x\n", msr.hi,msr.lo);
60 printk_err("cs5536: EXIT %s\n", __FUNCTION__);
64 /* note: this is a candidate for inclusion in src/devices/pci_device.c */
66 setup_irq(unsigned irq, char *name, unsigned level, unsigned bus, unsigned device, unsigned fn){
68 unsigned devfn = PCI_DEVFN(device,fn);
69 device_t dev = dev_find_slot(bus, devfn);
71 pci_write_config8(dev, PCI_INTERRUPT_LINE, irq);
76 printk_err("%s: Can't find %s at 0x%x\n", __FUNCTION__, name, devfn);
81 static void southbridge_init(struct device *dev)
83 struct southbridge_amd_cs5536_config *sb = (struct southbridge_amd_cs5536_config *)dev->chip_info;
84 const unsigned char slots_cpu[4] = {11, 0, 0, 0};
85 const unsigned char slots_sb[4] = {11, 5, 10, 10};
89 * struct device *gpiodev;
90 * unsigned short gpiobase = MDD_GPIO;
93 printk_err("cs5536: %s\n", __FUNCTION__);
96 if (sb->lpc_serirq_enable) {
97 msr.lo = sb->lpc_serirq_enable;
99 wrmsr(MDD_LPC_SIRQ, msr);
102 msr.lo = sb->lpc_irq;
104 wrmsr(MDD_IRQM_LPC, msr);
107 if (sb->enable_gpio0_inta){
108 msr = rdmsr(MDD_IRQM_ZHIGH);
110 wrmsr(MDD_IRQM_ZHIGH, msr);
111 /* todo: look the device up. But we know that gpiobase is 0x6100 */
112 /* oh gosh, all the defines from AMD assume 6100. Don't bother looking up! */
113 outl(GPIOL_0_SET|GPIOL_1_SET|GPIOL_3_SET, GPIOL_INPUT_ENABLE);
114 outl(GPIOL_0_SET,GPIOL_EVENTS_ENABLE);
116 outl(0x3081, GPIOL_INPUT_INVERT_ENABLE);
117 outl(GPIOL_0_SET, GPIO_MAPPER_X);
120 if (sb->enable_uarta){
121 printk_err("cs5536: %s: enable uarta, msr MDD_IRQM_YHIGH(%x) \n",
122 __FUNCTION__, MDD_IRQM_YHIGH);
123 msr = rdmsr(MDD_IRQM_YHIGH);
124 msr.lo |= 0x04000000;
125 wrmsr(MDD_IRQM_YHIGH, msr);
128 printk_err("cs5536: %s: enable_ide_nand_flash is %d\n", __FUNCTION__, sb->enable_ide_nand_flash);
129 if (sb->enable_ide_nand_flash) {
130 enable_ide_nand_flash();
135 setup_irq(sb->audio_irq, "audio", 1, 0, 0xf, 2);
136 setup_irq(sb->usbf4_irq, "usb f4", 1, 0, 0xf, 4);
137 setup_irq(sb->usbf5_irq, "usb f5", 1, 0, 0xf, 5);
138 setup_irq(sb->usbf6_irq, "usb f6", 1, 0, 0xf, 6);
139 setup_irq(sb->usbf7_irq, "usb f7", 1, 0, 0xf, 7);
141 /* CPU (80000800 = 00.01.00) */
142 pci_assign_irqs(0, 0x01, slots_cpu); /* bus=0, device=0x01, slots={11,0,0,0} */
144 /* Southbridge (80007800 = 00.0F.00) */
145 pci_assign_irqs(0, 0x0F, slots_sb); /* bus=0, device=0x0F, slots={11,5,10,10} */
147 /* disable unwanted virtual PCI devices */
148 for (i = 0; (i < MAX_UNWANTED_VPCI) && (0 != sb->unwanted_vpci[i]); i++) {
149 printk_debug("Disabling VPCI device: 0x%08X\n", sb->unwanted_vpci[i]);
150 outl(sb->unwanted_vpci[i] + 0x7C, 0xCF8);
151 outl(0xDEADBEEF, 0xCFC);
156 static void southbridge_enable(struct device *dev)
158 printk_err("cs5536: %s: dev is %p\n", __FUNCTION__, dev);
161 static void cs5536_pci_dev_enable_resources(device_t dev)
163 printk_err("cs5536: %s()\n", __FUNCTION__);
164 pci_dev_enable_resources(dev);
165 enable_childrens_resources(dev);
168 static struct device_operations southbridge_ops = {
169 .read_resources = pci_dev_read_resources,
170 .set_resources = pci_dev_set_resources,
171 .enable_resources = cs5536_pci_dev_enable_resources,
172 .init = southbridge_init,
173 // .enable = southbridge_enable,
174 .scan_bus = scan_static_bus,
177 static struct pci_driver cs5536_pci_driver __pci_driver = {
178 .ops = &southbridge_ops,
179 .vendor = PCI_VENDOR_ID_AMD,
180 .device = PCI_DEVICE_ID_AMD_CS5536_ISA
183 struct chip_operations southbridge_amd_cs5536_ops = {
184 CHIP_NAME("AMD cs5536")
185 /* This only called when this device is listed in the
186 * static device tree.
188 .enable_dev = southbridge_enable,