- Update to 2.6.25-rc3.
[linux-flexiantxendom0-3.2.10.git] / arch / powerpc / platforms / celleb / scc_epci.c
1 /*
2  * Support for SCC external PCI
3  *
4  * (C) Copyright 2004-2007 TOSHIBA CORPORATION
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #undef DEBUG
22
23 #include <linux/kernel.h>
24 #include <linux/threads.h>
25 #include <linux/pci.h>
26 #include <linux/init.h>
27 #include <linux/pci_regs.h>
28 #include <linux/bootmem.h>
29
30 #include <asm/io.h>
31 #include <asm/irq.h>
32 #include <asm/prom.h>
33 #include <asm/machdep.h>
34 #include <asm/pci-bridge.h>
35 #include <asm/ppc-pci.h>
36
37 #include "scc.h"
38 #include "pci.h"
39 #include "interrupt.h"
40
41 #define MAX_PCI_DEVICES   32
42 #define MAX_PCI_FUNCTIONS  8
43
44 #define iob()  __asm__ __volatile__("eieio; sync":::"memory")
45
46 struct epci_private {
47         dma_addr_t      dummy_page_da;
48 };
49
50 static inline PCI_IO_ADDR celleb_epci_get_epci_base(
51                                         struct pci_controller *hose)
52 {
53         /*
54          * Note:
55          * Celleb epci uses cfg_addr as a base address for
56          * epci control registers.
57          */
58
59         return hose->cfg_addr;
60 }
61
62 static inline PCI_IO_ADDR celleb_epci_get_epci_cfg(
63                                         struct pci_controller *hose)
64 {
65         /*
66          * Note:
67          * Celleb epci uses cfg_data as a base address for
68          * configuration area for epci devices.
69          */
70
71         return hose->cfg_data;
72 }
73
74 static void scc_epci_dummy_read(struct pci_controller *hose)
75 {
76         PCI_IO_ADDR epci_base;
77         u32 val;
78
79         epci_base = celleb_epci_get_epci_base(hose);
80
81         val = in_be32(epci_base + SCC_EPCI_WATRP);
82         iosync();
83
84         return;
85 }
86
87 void __init epci_workaround_init(struct pci_controller *hose)
88 {
89         PCI_IO_ADDR epci_base;
90         PCI_IO_ADDR reg;
91         struct epci_private *private = hose->private_data;
92
93         BUG_ON(!private);
94
95         private->dummy_page_da = dma_map_single(hose->parent,
96                 celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
97         if (private->dummy_page_da == DMA_ERROR_CODE) {
98                 printk(KERN_ERR "EPCI: dummy read disabled. "
99                        "Map dummy page failed.\n");
100                 return;
101         }
102
103         celleb_pci_add_one(hose, scc_epci_dummy_read);
104         epci_base = celleb_epci_get_epci_base(hose);
105
106         reg = epci_base + SCC_EPCI_DUMYRADR;
107         out_be32(reg, private->dummy_page_da);
108 }
109
110 static inline void clear_and_disable_master_abort_interrupt(
111                                         struct pci_controller *hose)
112 {
113         PCI_IO_ADDR epci_base;
114         PCI_IO_ADDR reg;
115         epci_base = celleb_epci_get_epci_base(hose);
116         reg = epci_base + PCI_COMMAND;
117         out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
118 }
119
120 static int celleb_epci_check_abort(struct pci_controller *hose,
121                                    PCI_IO_ADDR addr)
122 {
123         PCI_IO_ADDR reg;
124         PCI_IO_ADDR epci_base;
125         u32 val;
126
127         iob();
128         epci_base = celleb_epci_get_epci_base(hose);
129
130         reg = epci_base + PCI_COMMAND;
131         val = in_be32(reg);
132
133         if (val & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
134                 out_be32(reg,
135                          (val & 0xffff) | (PCI_STATUS_REC_MASTER_ABORT << 16));
136
137                 /* clear PCI Controller error, FRE, PMFE */
138                 reg = epci_base + SCC_EPCI_STATUS;
139                 out_be32(reg, SCC_EPCI_INT_PAI);
140
141                 reg = epci_base + SCC_EPCI_VCSR;
142                 val = in_be32(reg) & 0xffff;
143                 val |= SCC_EPCI_VCSR_FRE;
144                 out_be32(reg, val);
145
146                 reg = epci_base + SCC_EPCI_VISTAT;
147                 out_be32(reg, SCC_EPCI_VISTAT_PMFE);
148                 return PCIBIOS_DEVICE_NOT_FOUND;
149         }
150
151         return PCIBIOS_SUCCESSFUL;
152 }
153
154 static PCI_IO_ADDR celleb_epci_make_config_addr(
155                                         struct pci_bus *bus,
156                                         struct pci_controller *hose,
157                                         unsigned int devfn, int where)
158 {
159         PCI_IO_ADDR addr;
160
161         if (bus != hose->bus)
162                 addr = celleb_epci_get_epci_cfg(hose) +
163                        (((bus->number & 0xff) << 16)
164                         | ((devfn & 0xff) << 8)
165                         | (where & 0xff)
166                         | 0x01000000);
167         else
168                 addr = celleb_epci_get_epci_cfg(hose) +
169                        (((devfn & 0xff) << 8) | (where & 0xff));
170
171         pr_debug("EPCI: config_addr = 0x%p\n", addr);
172
173         return addr;
174 }
175
176 static int celleb_epci_read_config(struct pci_bus *bus,
177                         unsigned int devfn, int where, int size, u32 * val)
178 {
179         PCI_IO_ADDR epci_base;
180         PCI_IO_ADDR addr;
181         struct device_node *node;
182         struct pci_controller *hose;
183
184         /* allignment check */
185         BUG_ON(where % size);
186
187         node = (struct device_node *)bus->sysdata;
188         hose = pci_find_hose_for_OF_device(node);
189
190         if (!celleb_epci_get_epci_cfg(hose))
191                 return PCIBIOS_DEVICE_NOT_FOUND;
192
193         if (bus->number == hose->first_busno && devfn == 0) {
194                 /* EPCI controller self */
195
196                 epci_base = celleb_epci_get_epci_base(hose);
197                 addr = epci_base + where;
198
199                 switch (size) {
200                 case 1:
201                         *val = in_8(addr);
202                         break;
203                 case 2:
204                         *val = in_be16(addr);
205                         break;
206                 case 4:
207                         *val = in_be32(addr);
208                         break;
209                 default:
210                         return PCIBIOS_DEVICE_NOT_FOUND;
211                 }
212
213         } else {
214
215                 clear_and_disable_master_abort_interrupt(hose);
216                 addr = celleb_epci_make_config_addr(bus, hose, devfn, where);
217
218                 switch (size) {
219                 case 1:
220                         *val = in_8(addr);
221                         break;
222                 case 2:
223                         *val = in_le16(addr);
224                         break;
225                 case 4:
226                         *val = in_le32(addr);
227                         break;
228                 default:
229                         return PCIBIOS_DEVICE_NOT_FOUND;
230                 }
231         }
232
233         pr_debug("EPCI: "
234                  "addr=0x%p, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n",
235                  addr, devfn, where, size, *val);
236
237         return celleb_epci_check_abort(hose, NULL);
238 }
239
240 static int celleb_epci_write_config(struct pci_bus *bus,
241                         unsigned int devfn, int where, int size, u32 val)
242 {
243         PCI_IO_ADDR epci_base;
244         PCI_IO_ADDR addr;
245         struct device_node *node;
246         struct pci_controller *hose;
247
248         /* allignment check */
249         BUG_ON(where % size);
250
251         node = (struct device_node *)bus->sysdata;
252         hose = pci_find_hose_for_OF_device(node);
253
254
255         if (!celleb_epci_get_epci_cfg(hose))
256                 return PCIBIOS_DEVICE_NOT_FOUND;
257
258         if (bus->number == hose->first_busno && devfn == 0) {
259                 /* EPCI controller self */
260
261                 epci_base = celleb_epci_get_epci_base(hose);
262                 addr = epci_base + where;
263
264                 switch (size) {
265                 case 1:
266                         out_8(addr, val);
267                         break;
268                 case 2:
269                         out_be16(addr, val);
270                         break;
271                 case 4:
272                         out_be32(addr, val);
273                         break;
274                 default:
275                         return PCIBIOS_DEVICE_NOT_FOUND;
276                 }
277
278         } else {
279
280                 clear_and_disable_master_abort_interrupt(hose);
281                 addr = celleb_epci_make_config_addr(bus, hose, devfn, where);
282
283                 switch (size) {
284                 case 1:
285                         out_8(addr, val);
286                         break;
287                 case 2:
288                         out_le16(addr, val);
289                         break;
290                 case 4:
291                         out_le32(addr, val);
292                         break;
293                 default:
294                         return PCIBIOS_DEVICE_NOT_FOUND;
295                 }
296         }
297
298         return celleb_epci_check_abort(hose, addr);
299 }
300
301 struct pci_ops celleb_epci_ops = {
302         .read = celleb_epci_read_config,
303         .write = celleb_epci_write_config,
304 };
305
306 /* to be moved in FW */
307 static int __init celleb_epci_init(struct pci_controller *hose)
308 {
309         u32 val;
310         PCI_IO_ADDR reg;
311         PCI_IO_ADDR epci_base;
312         int hwres = 0;
313
314         epci_base = celleb_epci_get_epci_base(hose);
315
316         /* PCI core reset(Internal bus and PCI clock) */
317         reg = epci_base + SCC_EPCI_CKCTRL;
318         val = in_be32(reg);
319         if (val == 0x00030101)
320                 hwres = 1;
321         else {
322                 val &= ~(SCC_EPCI_CKCTRL_CRST0 | SCC_EPCI_CKCTRL_CRST1);
323                 out_be32(reg, val);
324
325                 /* set PCI core clock */
326                 val = in_be32(reg);
327                 val |= (SCC_EPCI_CKCTRL_OCLKEN | SCC_EPCI_CKCTRL_LCLKEN);
328                 out_be32(reg, val);
329
330                 /* release PCI core reset (internal bus) */
331                 val = in_be32(reg);
332                 val |= SCC_EPCI_CKCTRL_CRST0;
333                 out_be32(reg, val);
334
335                 /* set PCI clock select */
336                 reg = epci_base + SCC_EPCI_CLKRST;
337                 val = in_be32(reg);
338                 val &= ~SCC_EPCI_CLKRST_CKS_MASK;
339                 val |= SCC_EPCI_CLKRST_CKS_2;
340                 out_be32(reg, val);
341
342                 /* set arbiter */
343                 reg = epci_base + SCC_EPCI_ABTSET;
344                 out_be32(reg, 0x0f1f001f);      /* temporary value */
345
346                 /* buffer on */
347                 reg = epci_base + SCC_EPCI_CLKRST;
348                 val = in_be32(reg);
349                 val |= SCC_EPCI_CLKRST_BC;
350                 out_be32(reg, val);
351
352                 /* PCI clock enable */
353                 val = in_be32(reg);
354                 val |= SCC_EPCI_CLKRST_PCKEN;
355                 out_be32(reg, val);
356
357                 /* release PCI core reset (all) */
358                 reg = epci_base + SCC_EPCI_CKCTRL;
359                 val = in_be32(reg);
360                 val |= (SCC_EPCI_CKCTRL_CRST0 | SCC_EPCI_CKCTRL_CRST1);
361                 out_be32(reg, val);
362
363                 /* set base translation registers. (already set by Beat) */
364
365                 /* set base address masks. (already set by Beat) */
366         }
367
368         /* release interrupt masks and clear all interrupts */
369         reg = epci_base + SCC_EPCI_INTSET;
370         out_be32(reg, 0x013f011f);      /* all interrupts enable */
371         reg = epci_base + SCC_EPCI_VIENAB;
372         val = SCC_EPCI_VIENAB_PMPEE | SCC_EPCI_VIENAB_PMFEE;
373         out_be32(reg, val);
374         reg = epci_base + SCC_EPCI_STATUS;
375         out_be32(reg, 0xffffffff);
376         reg = epci_base + SCC_EPCI_VISTAT;
377         out_be32(reg, 0xffffffff);
378
379         /* disable PCI->IB address translation */
380         reg = epci_base + SCC_EPCI_VCSR;
381         val = in_be32(reg);
382         val &= ~(SCC_EPCI_VCSR_DR | SCC_EPCI_VCSR_AT);
383         out_be32(reg, val);
384
385         /* set base addresses. (no need to set?) */
386
387         /* memory space, bus master enable */
388         reg = epci_base + PCI_COMMAND;
389         val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
390         out_be32(reg, val);
391
392         /* endian mode setup */
393         reg = epci_base + SCC_EPCI_ECMODE;
394         val = 0x00550155;
395         out_be32(reg, val);
396
397         /* set control option */
398         reg = epci_base + SCC_EPCI_CNTOPT;
399         val = in_be32(reg);
400         val |= SCC_EPCI_CNTOPT_O2PMB;
401         out_be32(reg, val);
402
403         /* XXX: temporay: set registers for address conversion setup */
404         reg = epci_base + SCC_EPCI_CNF10_REG;
405         out_be32(reg, 0x80000008);
406         reg = epci_base + SCC_EPCI_CNF14_REG;
407         out_be32(reg, 0x40000008);
408
409         reg = epci_base + SCC_EPCI_BAM0;
410         out_be32(reg, 0x80000000);
411         reg = epci_base + SCC_EPCI_BAM1;
412         out_be32(reg, 0xe0000000);
413
414         reg = epci_base + SCC_EPCI_PVBAT;
415         out_be32(reg, 0x80000000);
416
417         if (!hwres) {
418                 /* release external PCI reset */
419                 reg = epci_base + SCC_EPCI_CLKRST;
420                 val = in_be32(reg);
421                 val |= SCC_EPCI_CLKRST_PCIRST;
422                 out_be32(reg, val);
423         }
424
425         return 0;
426 }
427
428 int __init celleb_setup_epci(struct device_node *node,
429                                 struct pci_controller *hose)
430 {
431         struct resource r;
432
433         pr_debug("PCI: celleb_setup_epci()\n");
434
435         /*
436          * Note:
437          * Celleb epci uses cfg_addr and cfg_data member of
438          * pci_controller structure in irregular way.
439          *
440          * cfg_addr is used to map for control registers of
441          * celleb epci.
442          *
443          * cfg_data is used for configuration area of devices
444          * on Celleb epci buses.
445          */
446
447         if (of_address_to_resource(node, 0, &r))
448                 goto error;
449         hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1));
450         if (!hose->cfg_addr)
451                 goto error;
452         pr_debug("EPCI: cfg_addr map 0x%016lx->0x%016lx + 0x%016lx\n",
453                  r.start, (unsigned long)hose->cfg_addr,
454                 (r.end - r.start + 1));
455
456         if (of_address_to_resource(node, 2, &r))
457                 goto error;
458         hose->cfg_data = ioremap(r.start, (r.end - r.start + 1));
459         if (!hose->cfg_data)
460                 goto error;
461         pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n",
462                  r.start, (unsigned long)hose->cfg_data,
463                 (r.end - r.start + 1));
464
465         hose->private_data = kzalloc(sizeof(struct epci_private), GFP_KERNEL);
466         if (hose->private_data == NULL) {
467                 printk(KERN_ERR "EPCI: no memory for private data.\n");
468                 goto error;
469         }
470
471         hose->ops = &celleb_epci_ops;
472         celleb_epci_init(hose);
473
474         return 0;
475
476 error:
477         kfree(hose->private_data);
478
479         if (hose->cfg_addr)
480                 iounmap(hose->cfg_addr);
481
482         if (hose->cfg_data)
483                 iounmap(hose->cfg_data);
484         return 1;
485 }