These changes incorporate steve goodrich'es fixes, and one bug that is
[coreboot.git] / src / southbridge / amd / cs5536 / cs5536.c
1
2 #include <arch/io.h>
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>
10 #include "chip.h"
11
12
13 #define PIN_OPT_IDE             (1ULL<<0)       /* 0 for flash, 1 for IDE */
14
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};
18
19 static void
20 enable_ide_nand_flash(){
21         msr_t msr;
22         printk_err("cs5536: %s\n", __FUNCTION__);
23 #if 0
24         /* steve took this one out ... not sure if needed or not */
25         msr = rdmsr(MDD_LBAR_FLSH0);
26
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);
30         }
31         msr = rdmsr(MDD_LBAR_FLSH0);
32         printk_err("MDD_LBAR_FLSH0 is 0x%08x%08x\n", msr.hi,msr.lo);
33 #endif
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);
39         }
40         msr = rdmsr(MDD_PIN_OPT);
41         printk_err("MDD_PIN_OPT is 0x%08x%08x\n", msr.hi,msr.lo);
42
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);
46                 msr.lo = 0x00100010;
47                 wrmsr(MDD_NANDF_DATA, msr);
48         }
49         msr = rdmsr(MDD_NANDF_DATA);
50         printk_err("MDD_NANDF_DATA is 0x%08x%08x\n", msr.hi,msr.lo);
51
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);
55                 msr.lo = 0x0010;
56                 wrmsr(MDD_NADF_CNTL, msr);
57         }
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__);
61 }
62
63 #if 0
64 /* note: this is a candidate for inclusion in src/devices/pci_device.c */
65 void
66 setup_irq(unsigned irq, char *name, unsigned level, unsigned bus, unsigned device, unsigned fn){
67         if (irq)  {
68                 unsigned devfn = PCI_DEVFN(device,fn);
69                 device_t dev  = dev_find_slot(bus, devfn);
70                 if (dev) {
71                         pci_write_config8(dev, PCI_INTERRUPT_LINE, irq);
72                         if (level)
73                                 pci_level_irq(irq);
74                 }
75                 else
76                         printk_err("%s: Can't find %s at 0x%x\n", __FUNCTION__, name, devfn);
77         }
78 }
79 #endif
80
81 static void southbridge_init(struct device *dev)
82 {
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};
86         msr_t msr;
87         int i;
88         /*
89          * struct device *gpiodev;
90          * unsigned short gpiobase = MDD_GPIO;
91          */
92
93         printk_err("cs5536: %s\n", __FUNCTION__);
94         setup_i8259(); 
95
96         if (sb->lpc_serirq_enable) {
97                 msr.lo = sb->lpc_serirq_enable;
98                 msr.hi  = 0;
99                 wrmsr(MDD_LPC_SIRQ, msr);
100         }
101         if (sb->lpc_irq) {
102                 msr.lo = sb->lpc_irq;
103                 msr.hi = 0;
104                 wrmsr(MDD_IRQM_LPC, msr);
105         }
106
107         if (sb->enable_gpio0_inta){
108           msr = rdmsr(MDD_IRQM_ZHIGH);
109                 msr.lo |= 0x10;
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);
115                 /* magic stuff */
116                 outl(0x3081, GPIOL_INPUT_INVERT_ENABLE);
117                 outl(GPIOL_0_SET, GPIO_MAPPER_X);
118         }
119
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);
126         }
127
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();
131         }
132
133 #if 0
134         /* irq handling */
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);
140 #else
141         /* CPU (80000800 = 00.01.00) */
142         pci_assign_irqs(0, 0x01, slots_cpu);    /* bus=0, device=0x01, slots={11,0,0,0} */
143         
144         /* Southbridge (80007800 = 00.0F.00) */
145         pci_assign_irqs(0, 0x0F, slots_sb);     /* bus=0, device=0x0F, slots={11,5,10,10} */
146 #endif
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);
152         }
153 }
154
155
156 static void southbridge_enable(struct device *dev)
157 {
158         printk_err("cs5536: %s: dev is %p\n", __FUNCTION__, dev);
159  }
160
161 static void cs5536_pci_dev_enable_resources(device_t dev)
162 {
163         printk_err("cs5536: %s()\n", __FUNCTION__);
164         pci_dev_enable_resources(dev);
165         enable_childrens_resources(dev);
166 }
167
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,
175 };
176
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
181 };
182
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.
187         */
188         .enable_dev = southbridge_enable,
189 };