Update olpc target kernel to 2.26.5.
[openwrt.git] / target / linux / olpc / files-2.6.23 / arch / i386 / pci / olpc.c
1 /*
2  * olpcpci.c - Low-level PCI config space access for OLPC systems
3  * without the VSA PCI virtualization software.
4  *
5  * The AMD Geode chipset (GX2 processor, cs5536 I/O companion device)
6  * has some I/O functions (display, southbridge, sound, USB HCIs, etc)
7  * that more or less behave like PCI devices, but the hardware doesn't
8  * directly implement the PCI configuration space headers.  AMD provides
9  * "VSA" (Virtual System Architecture) software that emulates PCI config
10  * space for these devices, by trapping I/O accesses to PCI config register
11  * (CF8/CFC) and running some code in System Management Mode interrupt state.
12  * On the OLPC platform, we don't want to use that VSA code because
13  * (a) it slows down suspend/resume, and (b) recompiling it requires special
14  * compilers that are hard to get.  So instead of letting the complex VSA
15  * code simulate the PCI config registers for the on-chip devices, we
16  * just simulate them the easy way, by inserting the code into the
17  * pci_write_config and pci_read_config path.  Most of the config registers
18  * are read-only anyway, so the bulk of the simulation is just table lookup.
19  */
20
21 #include <linux/pci.h>
22 #include <linux/init.h>
23 #include <asm/olpc.h>
24 #include <asm/geode.h>
25 #include "pci.h"
26
27 static int is_lx;
28
29 /*
30  * In the tables below, the first two line (8 longwords) are the
31  * size masks that are used when the higher level PCI code determines
32  * the size of the region by writing ~0 to a base address register
33  * and reading back the result.
34  *
35  * The following lines are the values that are read during normal
36  * PCI config access cycles, i.e. not after just having written
37  * ~0 to a base address register.
38  */
39
40 static const u32 lxnb_hdr[] = {  /* dev 1 function 0 - devfn = 8 */
41          0x0 ,        0x0 ,        0x0 ,        0x0 ,
42          0x0 ,        0x0 ,        0x0 ,        0x0 ,
43
44     0x281022 ,  0x2200005 ,  0x6000021 ,   0x80f808 ,  /* AMD Vendor ID */
45          0x0 ,        0x0 ,        0x0 ,        0x0 ,  /* No virtual registers, hence no BAR for them */
46          0x0 ,        0x0 ,        0x0 ,   0x28100b ,
47          0x0 ,        0x0 ,        0x0 ,        0x0 ,
48          0x0 ,        0x0 ,        0x0 ,        0x0 ,
49          0x0 ,        0x0 ,        0x0 ,        0x0 ,
50          0x0 ,        0x0 ,        0x0 ,        0x0 ,
51 };
52
53 static const u32 gxnb_hdr[] = {  /* dev 1 function 0 - devfn = 8 */
54   0xfffffffd ,        0x0 ,        0x0 ,        0x0 ,
55          0x0 ,        0x0 ,        0x0 ,        0x0 ,
56
57     0x28100b ,  0x2200005 ,  0x6000021 ,   0x80f808 ,  /* NSC Vendor ID */
58       0xac1d ,        0x0 ,        0x0 ,        0x0 ,  /* I/O BAR - base of virtual registers */
59          0x0 ,        0x0 ,        0x0 ,   0x28100b ,
60          0x0 ,        0x0 ,        0x0 ,        0x0 ,
61          0x0 ,        0x0 ,        0x0 ,        0x0 ,
62          0x0 ,        0x0 ,        0x0 ,        0x0 ,
63          0x0 ,        0x0 ,        0x0 ,        0x0 ,
64 };
65
66 static const u32 lxfb_hdr[] = {  /* dev 1 function 1 - devfn = 9 */
67   0xff800008 , 0xffffc000 , 0xffffc000 , 0xffffc000 ,
68          0x0 ,        0x0 ,        0x0 ,        0x0 ,
69
70   0x20811022 ,  0x2200003 ,  0x3000000 ,        0x0 , /* AMD Vendor ID */
71   0xfd000000 , 0xfe000000 , 0xfe004000 , 0xfe008000 , /* FB, GP, VG, DF */
72   0xfe00c000 ,        0x0 ,        0x0 ,   0x30100b , /* VIP */
73          0x0 ,        0x0 ,        0x0 ,      0x10e , /* INTA, IRQ14 for graphics accel */
74          0x0 ,        0x0 ,        0x0 ,        0x0 ,
75        0x3d0 ,      0x3c0 ,    0xa0000 ,        0x0 , /* VG IO, VG IO, EGA FB, MONO FB */
76          0x0 ,        0x0 ,        0x0 ,        0x0 ,
77 };
78
79 static const u32 gxfb_hdr[] = {  /* dev 1 function 1 - devfn = 9 */
80   0xff800008 , 0xffffc000 , 0xffffc000 , 0xffffc000 ,
81          0x0 ,        0x0 ,        0x0 ,        0x0 ,
82
83     0x30100b ,  0x2200003 ,  0x3000000 ,        0x0 , /* NSC Vendor ID */
84   0xfd000000 , 0xfe000000 , 0xfe004000 , 0xfe008000 , /* FB, GP, VG, DF */
85          0x0 ,        0x0 ,        0x0 ,   0x30100b ,
86          0x0 ,        0x0 ,        0x0 ,        0x0 ,
87          0x0 ,        0x0 ,        0x0 ,        0x0 ,
88        0x3d0 ,      0x3c0 ,    0xa0000 ,        0x0 , /* VG IO, VG IO, EGA FB, MONO FB */
89          0x0 ,        0x0 ,        0x0 ,        0x0 ,
90 };
91
92 static const u32 aes_hdr[] = {  /* dev 1 function 2 - devfn = 0xa */
93   0xffffc000 ,        0x0 ,        0x0 ,        0x0 ,
94          0x0 ,        0x0 ,        0x0 ,        0x0 ,
95
96   0x20821022 ,  0x2a00006 , 0x10100000 ,        0x8 , /* NSC Vendor ID */
97   0xfe010000 ,        0x0 ,        0x0 ,        0x0 , /* AES registers */
98          0x0 ,        0x0 ,        0x0 , 0x20821022 ,
99          0x0 ,        0x0 ,        0x0 ,        0x0 ,
100          0x0 ,        0x0 ,        0x0 ,        0x0 ,
101          0x0 ,        0x0 ,        0x0 ,        0x0 ,
102          0x0 ,        0x0 ,        0x0 ,        0x0 ,
103 };
104
105
106 static const u32 isa_hdr[] = {  /* dev f function 0 - devfn = 78 */
107   0xfffffff9 , 0xffffff01 , 0xffffffc1 , 0xffffffe1 ,
108   0xffffff81 , 0xffffffc1 ,        0x0 ,        0x0 ,
109
110   0x20901022 ,  0x2a00049 ,  0x6010003 ,   0x802000 ,
111       0x18b1 ,     0x1001 ,     0x1801 ,     0x1881 , /* SMB-8   GPIO-256  MFGPT-64  IRQ-32 */
112       0x1401 ,     0x1841 ,        0x0 , 0x20901022 , /* PMS-128 ACPI-64 */
113          0x0 ,        0x0 ,        0x0 ,        0x0 ,
114          0x0 ,        0x0 ,        0x0 ,        0x0 ,
115          0x0 ,        0x0 ,        0x0 ,     0xaa5b , /* interrupt steering */
116          0x0 ,        0x0 ,        0x0 ,        0x0 ,
117 };
118
119 static const u32 ac97_hdr[] = {  /* dev f function 3 - devfn = 7b */
120   0xffffff81 ,        0x0 ,        0x0 ,        0x0 ,
121          0x0 ,        0x0 ,        0x0 ,        0x0 ,
122
123   0x20931022 ,  0x2a00041 ,  0x4010001 ,        0x0 ,
124       0x1481 ,        0x0 ,        0x0 ,        0x0 , /* I/O BAR-128 */
125          0x0 ,        0x0 ,        0x0 , 0x20931022 ,
126          0x0 ,        0x0 ,        0x0 ,      0x205 , /* IntB , IRQ5 */
127          0x0 ,        0x0 ,        0x0 ,        0x0 ,
128          0x0 ,        0x0 ,        0x0 ,        0x0 ,
129          0x0 ,        0x0 ,        0x0 ,        0x0 ,
130 };
131
132 static const u32 ohci_hdr[] = {  /* dev f function 4 - devfn = 7c */
133   0xfffff000 ,        0x0 ,        0x0 ,        0x0 ,
134          0x0 ,        0x0 ,        0x0 ,        0x0 ,
135
136   0x20941022 ,  0x2300006 ,  0xc031002 ,        0x0 ,
137   0xfe01a000 ,        0x0 ,        0x0 ,        0x0 , /* MEMBAR-1000 */
138          0x0 ,        0x0 ,        0x0 , 0x20941022 ,
139          0x0 ,       0x40 ,        0x0 ,      0x40a , /* CapPtr  INT-D, IRQ A */
140   0xc8020001 ,        0x0 ,        0x0 ,        0x0 , /* Capabilities - 40 is R/O, 44 is mask 8103 (power control) */
141          0x0 ,        0x0 ,        0x0 ,        0x0 ,
142          0x0 ,        0x0 ,        0x0 ,        0x0 ,
143 };
144
145 static const u32 ehci_hdr[] = {  /* dev f function 4 - devfn = 7d */
146   0xfffff000 ,        0x0 ,        0x0 ,        0x0 ,
147          0x0 ,        0x0 ,        0x0 ,        0x0 ,
148
149   0x20951022 ,  0x2300006 ,  0xc032002 ,        0x0 ,
150   0xfe01b000 ,        0x0 ,        0x0 ,        0x0 , /* MEMBAR-1000 */
151          0x0 ,        0x0 ,        0x0 , 0x20951022 ,
152          0x0 ,       0x40 ,        0x0 ,      0x40a , /* CapPtr  INT-D, IRQ A */
153   0xc8020001 ,        0x0 ,        0x0 ,        0x0 , /* Capabilities - 40 is R/O, 44 is mask 8103 (power control) */
154 #if 0
155          0x1 , 0x40080000 ,        0x0 ,        0x0 , /* EECP - see section 2.1.7 of EHCI spec */
156 #endif
157   0x01000001 , 0x00000000 ,        0x0 ,        0x0 , /* EECP - see section 2.1.7 of EHCI spec */
158       0x2020 ,        0x0 ,        0x0 ,        0x0 , /* (EHCI page 8) 60 SBRN (R/O), 61 FLADJ (R/W), PORTWAKECAP  */
159 };
160
161 static u32 ff_loc    = ~0;
162 static u32 zero_loc  =  0;
163
164 static int bar_probing = 0;       /* Set after a write of ~0 to a BAR */
165
166 #define NB_SLOT 0x1      /* Northbridge - GX chip - Device 1 */
167 #define SB_SLOT 0xf      /* Southbridge - CS5536 chip - Device F */
168 #define SIMULATED(bus, devfn)  (((bus) == 0) && ((PCI_SLOT(devfn) == NB_SLOT) || (PCI_SLOT(devfn) == SB_SLOT)))
169
170 static u32 *hdr_addr(const u32 *hdr, int reg)
171 {
172         u32 addr;
173
174         /*
175          * This is a little bit tricky.  The header maps consist of
176          * 0x20 bytes of size masks, followed by 0x70 bytes of header data.
177          * In the normal case, when not probing a BAR's size, we want
178          * to access the header data, so we add 0x20 to the reg offset,
179          * thus skipping the size mask area.
180          * In the BAR probing case, we want to access the size mask for
181          * the BAR, so we subtract 0x10 (the config header offset for
182          * BAR0), and don't skip the size mask area.
183          */
184
185         addr = (u32)hdr + reg + (bar_probing ? -0x10 : 0x20);
186
187         bar_probing = 0;
188         return (u32 *)addr;
189 }
190
191 static int pci_olpc_read(unsigned int seg, unsigned int bus,
192                 unsigned int devfn, int reg, int len, u32 *value)
193 {
194         u32 *addr;
195
196         /* Use the hardware mechanism for non-simulated devices */
197         if (!SIMULATED(bus, devfn))
198                 return pci_conf1_read(seg, bus, devfn, reg, len, value);
199
200         /*
201          * No device has config registers past 0x70, so we save table space
202          * by not storing entries for the nonexistent registers
203          */
204         if (reg >= 0x70)
205                 addr = &zero_loc;
206         else {
207                 switch (devfn) {
208                         case  0x8:
209                                 addr = hdr_addr(is_lx ? lxnb_hdr : gxnb_hdr, reg);
210                                 break;
211                         case  0x9:
212                                 addr = hdr_addr(is_lx ? lxfb_hdr : gxfb_hdr, reg);
213                                 break;
214                         case  0xa:
215                                 addr = is_lx ? hdr_addr(aes_hdr, reg) : &ff_loc;
216                                 break;
217                         case 0x78:
218                                 addr = hdr_addr(isa_hdr, reg);
219                                 break;
220                         case 0x7b:
221                                 addr = hdr_addr(ac97_hdr, reg);
222                                 break;
223                         case 0x7c:
224                                 addr = hdr_addr(ohci_hdr, reg);
225                                 break;
226                         case 0x7d:
227                                 addr = hdr_addr(ehci_hdr, reg);
228                                 break;
229                         default:
230                                 addr = &ff_loc;
231                                 break;
232                 }
233         }
234         switch (len) {
235                 case 1:
236                         *value = *(u8 *) addr;
237                         break;
238                 case 2:
239                         *value = *(u16 *) addr;
240                         break;
241                 case 4:
242                         *value = *addr;
243                         break;
244                 default:
245                         BUG();
246         }
247
248         return 0;
249 }
250
251 static int pci_olpc_write(unsigned int seg, unsigned int bus,
252                 unsigned int devfn, int reg, int len, u32 value)
253 {
254         /* Use the hardware mechanism for non-simulated devices */
255         if (!SIMULATED(bus, devfn))
256                 return pci_conf1_write(seg, bus, devfn, reg, len, value);
257
258         /* XXX we may want to extend this to simulate EHCI power management */
259
260         /*
261          * Mostly we just discard writes, but if the write is a size probe
262          * (i.e. writing ~0 to a BAR), we remember it and arrange to return
263          * the appropriate size mask on the next read.  This is cheating
264          * to some extent, because it depends on the fact that the next
265          * access after such a write will always be a read to the same BAR.
266          */
267
268         if ((reg >= 0x10) && (reg < 0x2c)) {
269                 /* Write is to a BAR */
270                 if (value == ~0)
271                         bar_probing = 1;
272         } else {
273                 /*
274                  * No warning on writes to ROM BAR, CMD, LATENCY_TIMER,
275                  * CACHE_LINE_SIZE, or PM registers.
276                  */
277                 if ((reg != 0x30) && (reg != 0x04) && (reg != 0x0d) &&
278                     (reg != 0x0c) && (reg != 0x44))
279                         printk(KERN_WARNING "OLPC PCI: Config write to devfn %x reg %x value %x\n", devfn, reg, value);
280         }
281
282         return 0;
283 }
284
285 static struct pci_raw_ops pci_olpc_conf = {
286         .read =         pci_olpc_read,
287         .write =        pci_olpc_write,
288 };
289
290 void __init pci_olpc_init(void)
291 {
292         if (!machine_is_olpc() || olpc_has_vsa())
293                 return;
294
295         printk(KERN_INFO "PCI: Using configuration type OLPC\n");
296         raw_pci_ops = &pci_olpc_conf;
297         is_lx = is_geode_lx();
298 }