- Added suport for enabling USB P4 on the olpc
[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 /* OOPS: steve's changes don't work, so we have to keep this */
18 msr_t flsh0 = { .hi=0xFFFFF007, .lo=0x20000000};
19
20 static void
21 enable_ide_nand_flash(){
22         msr_t msr;
23         printk_err("cs5536: %s\n", __FUNCTION__);
24 #if 1
25         printk_err("WARNING: using deprecated flash enable mechanism\n");
26         /* steve took this one out ... not sure if needed or not */
27         msr = rdmsr(MDD_LBAR_FLSH0);
28
29         if ( ((msr.hi) & 7) != 7) {
30                 printk_err("MDD_LBAR_FLSH0 was 0x%08x%08x\n", msr.hi,msr.lo);
31                 wrmsr(MDD_LBAR_FLSH0, flsh0);
32         }
33         msr = rdmsr(MDD_LBAR_FLSH0);
34         printk_err("MDD_LBAR_FLSH0 is 0x%08x%08x\n", msr.hi,msr.lo);
35 #endif
36         msr = rdmsr(MDD_PIN_OPT);
37         if (msr.lo & PIN_OPT_IDE) {
38                 printk_err("MDD_PIN_OPT was 0x%08x%08x\n", msr.hi,msr.lo);
39                 msr.lo &= ~PIN_OPT_IDE;
40                 wrmsr(MDD_PIN_OPT, msr);
41         }
42         msr = rdmsr(MDD_PIN_OPT);
43         printk_err("MDD_PIN_OPT is 0x%08x%08x\n", msr.hi,msr.lo);
44
45         msr = rdmsr(MDD_NANDF_DATA);
46         if (msr.lo != 0x00100010) {
47                 printk_err("MDD_NANDF_DATA was 0x%08x%08x\n", msr.hi,msr.lo);
48                 msr.lo = 0x00100010;
49                 wrmsr(MDD_NANDF_DATA, msr);
50         }
51         msr = rdmsr(MDD_NANDF_DATA);
52         printk_err("MDD_NANDF_DATA is 0x%08x%08x\n", msr.hi,msr.lo);
53
54         msr = rdmsr(MDD_NADF_CNTL);
55         if (msr.lo != 0x0010) {
56                 printk_err("MDD_NADF_CNTL was 0x%08x%08x\n", msr.hi,msr.lo);
57                 msr.lo = 0x0010;
58                 wrmsr(MDD_NADF_CNTL, msr);
59         }
60         msr = rdmsr(MDD_NADF_CNTL);
61         printk_err("MDD_NADF_CNTL is 0x%08x%08x\n", msr.hi,msr.lo);
62         printk_err("cs5536: EXIT %s\n", __FUNCTION__);
63 }
64
65 #if 0
66 /* note: this is a candidate for inclusion in src/devices/pci_device.c */
67 void
68 setup_irq(unsigned irq, char *name, unsigned level, unsigned bus, unsigned device, unsigned fn){
69         if (irq)  {
70                 unsigned devfn = PCI_DEVFN(device,fn);
71                 device_t dev  = dev_find_slot(bus, devfn);
72                 if (dev) {
73                         pci_write_config8(dev, PCI_INTERRUPT_LINE, irq);
74                         if (level)
75                                 pci_level_irq(irq);
76                 }
77                 else
78                         printk_err("%s: Can't find %s at 0x%x\n", __FUNCTION__, name, devfn);
79         }
80 }
81 #endif
82
83 static void southbridge_init(struct device *dev)
84 {
85         struct southbridge_amd_cs5536_config  *sb = (struct southbridge_amd_cs5536_config *)dev->chip_info;
86         const unsigned char slots_cpu[4] = {11, 0, 0, 0};
87         const unsigned char slots_sb[4] = {11, 5, 10, 10};
88         msr_t msr;
89         int i;
90         /*
91          * struct device *gpiodev;
92          * unsigned short gpiobase = MDD_GPIO;
93          */
94
95         printk_err("cs5536: %s\n", __FUNCTION__);
96         setup_i8259(); 
97
98         if (sb->lpc_serirq_enable) {
99                 msr.lo = sb->lpc_serirq_enable;
100                 msr.hi  = 0;
101                 wrmsr(MDD_LPC_SIRQ, msr);
102         }
103         if (sb->lpc_irq) {
104                 msr.lo = sb->lpc_irq;
105                 msr.hi = 0;
106                 wrmsr(MDD_IRQM_LPC, msr);
107         }
108
109         if (sb->enable_gpio0_inta){
110           msr = rdmsr(MDD_IRQM_ZHIGH);
111                 msr.lo |= 0x10;
112                 wrmsr(MDD_IRQM_ZHIGH, msr);
113                 /* todo: look the device up. But we know that gpiobase is 0x6100 */
114                 /* oh gosh, all the defines from AMD assume 6100. Don't bother looking up! */
115                 outl(GPIOL_0_SET|GPIOL_1_SET|GPIOL_3_SET, GPIOL_INPUT_ENABLE);
116                 outl(GPIOL_0_SET,GPIOL_EVENTS_ENABLE);
117                 /* magic stuff */
118                 outl(0x3081, GPIOL_INPUT_INVERT_ENABLE);
119                 outl(GPIOL_0_SET, GPIO_MAPPER_X);
120         }
121
122         if (sb->enable_uarta){
123                 printk_err("cs5536: %s: enable uarta, msr MDD_IRQM_YHIGH(%x) \n",
124                                  __FUNCTION__, MDD_IRQM_YHIGH);
125                 msr = rdmsr(MDD_IRQM_YHIGH);
126                 msr.lo |= 0x04000000;
127                 wrmsr(MDD_IRQM_YHIGH, msr);
128         }
129
130         printk_err("cs5536: %s: enable_ide_nand_flash is %d\n", __FUNCTION__, sb->enable_ide_nand_flash);
131         if (sb->enable_ide_nand_flash) {
132                 enable_ide_nand_flash();
133         }
134
135 #if 0
136         /* irq handling */
137         setup_irq(sb->audio_irq, "audio", 1, 0, 0xf, 2);
138         setup_irq(sb->usbf4_irq, "usb f4", 1, 0, 0xf, 4);
139         setup_irq(sb->usbf5_irq, "usb f5", 1, 0, 0xf, 5);
140         setup_irq(sb->usbf6_irq, "usb f6", 1, 0, 0xf, 6);
141         setup_irq(sb->usbf7_irq, "usb f7", 1, 0, 0xf, 7);
142 #else
143         /* CPU (80000800 = 00.01.00) */
144         pci_assign_irqs(0, 0x01, slots_cpu);    /* bus=0, device=0x01, slots={11,0,0,0} */
145         
146         /* Southbridge (80007800 = 00.0F.00) */
147         pci_assign_irqs(0, 0x0F, slots_sb);     /* bus=0, device=0x0F, slots={11,5,10,10} */
148 #endif
149         /* disable unwanted virtual PCI devices */
150         for (i = 0; (i < MAX_UNWANTED_VPCI) && (0 != sb->unwanted_vpci[i]); i++) {
151                 printk_debug("Disabling VPCI device: 0x%08X\n", sb->unwanted_vpci[i]);
152                 outl(sb->unwanted_vpci[i] + 0x7C, 0xCF8);
153                 outl(0xDEADBEEF,                  0xCFC);
154         }
155
156         if (sb->enable_USBP4_host) {
157                 volatile unsigned long* uocmux;
158                 unsigned long val;
159
160                 printk_err("Base 0x%08x\n",USB2_SB_GLD_MSR_CAP);
161                 
162                 msr = rdmsr(USB2_SB_GLD_MSR_CAP);
163                 printk_err("CAP 0x%08x%08x\n", msr.hi,msr.lo);
164
165                 msr = rdmsr(USB2_SB_GLD_MSR_OHCI_BASE);
166                 printk_err("OHCI base 0x%08x%08x\n", msr.hi,msr.lo);
167
168                 msr = rdmsr(USB2_SB_GLD_MSR_EHCI_BASE);
169                 printk_err("EHCI base 0x%08x%08x\n", msr.hi,msr.lo);
170
171                 msr = rdmsr(USB2_SB_GLD_MSR_DEVCTL_BASE);
172                 printk_err("DevCtl base 0x%08x%08x\n", msr.hi,msr.lo);
173
174                 msr = rdmsr(USB2_SB_GLD_MSR_UOC_BASE);
175                 printk_err("Old UOC Base 0x%08x%08x\n", msr.hi,msr.lo);
176                 msr.hi |= 0xa;
177                 msr.lo |= 0xfe010000;
178         
179 #if 0   
180                 wrmsr(USB2_SB_GLD_MSR_UOC_BASE, msr);
181
182                 msr = rdmsr(USB2_SB_GLD_MSR_UOC_BASE);
183                 printk_err("New UOC Base 0x%08x%08x\n", msr.hi,msr.lo);
184
185                 uocmux = (unsigned long *)msr.lo+4;
186                 val = *uocmux;
187
188                 printk_err("UOCMUX is 0x%lx\n",*val);
189                 val &= ~(0xc0);
190                 val |= 0x2;
191
192                 *uocmux = val;
193 #endif
194
195         }
196
197 }
198
199
200 static void southbridge_enable(struct device *dev)
201 {
202         printk_err("cs5536: %s: dev is %p\n", __FUNCTION__, dev);
203  }
204
205 static void cs5536_pci_dev_enable_resources(device_t dev)
206 {
207         printk_err("cs5536: %s()\n", __FUNCTION__);
208         pci_dev_enable_resources(dev);
209         enable_childrens_resources(dev);
210 }
211
212 static struct device_operations southbridge_ops = {
213         .read_resources   = pci_dev_read_resources,
214         .set_resources    = pci_dev_set_resources,
215         .enable_resources = cs5536_pci_dev_enable_resources,
216         .init             = southbridge_init,
217 //      .enable           = southbridge_enable,
218         .scan_bus         = scan_static_bus,
219 };
220
221 static struct pci_driver cs5536_pci_driver __pci_driver = {
222         .ops    = &southbridge_ops,
223         .vendor = PCI_VENDOR_ID_AMD,
224         .device = PCI_DEVICE_ID_AMD_CS5536_ISA
225 };
226
227 struct chip_operations southbridge_amd_cs5536_ops = {
228         CHIP_NAME("AMD cs5536")
229         /* This only called when this device is listed in the 
230         * static device tree.
231         */
232         .enable_dev = southbridge_enable,
233 };