blob: 7c81b8b65bb505cbcaf58fad69364ee148cbc434 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Support functions for the ST40 PCI hardware.
8 */
9
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <linux/kernel.h>
11#include <linux/smp.h>
12#include <linux/smp_lock.h>
13#include <linux/init.h>
14#include <linux/errno.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <linux/types.h>
18#include <asm/pci.h>
19#include <linux/irq.h>
20#include <linux/interrupt.h> /* irqreturn_t */
21
22#include "pci-st40.h"
23
24/* This is in P2 of course */
25#define ST40PCI_BASE_ADDRESS (0xb0000000)
26#define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0)
27#define ST40PCI_IO_ADDRESS (ST40PCI_BASE_ADDRESS+0x06000000)
28#define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000)
29
30#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
31#define ST40PCI_REG_INDEXED(reg, index) \
32 (ST40PCI_REG(reg##0) + \
33 ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
34
35#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
36#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
37#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
38#define ST40PCI_WRITE_INDEXED(reg, index, val) \
39 writel((val), ST40PCI_REG_INDEXED(reg, index));
40
41#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
42#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
43#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
44
45#define ST40PCI_SERR_IRQ 64
46#define ST40PCI_ERR_IRQ 65
47
48
49/* Macros to extract PLL params */
50#define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff )
51#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
52#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
53#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
54
55/* Build up the appropriate settings */
56#define PLL_SET(mdiv,ndiv,pdiv,setup) \
57( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
58
59#define PLLPCICR (0xbb040000+0x10)
60
61#define PLLPCICR_POWERON (1<<28)
62#define PLLPCICR_OUT_EN (1<<29)
63#define PLLPCICR_LOCKSELECT (1<<30)
64#define PLLPCICR_LOCK (1<<31)
65
66
67#define PLL_25MHZ 0x793c8512
68#define PLL_33MHZ PLL_SET(18,88,3,295)
69
70static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
71 unsigned long pciOffset, unsigned long regionSize);
72
73/*
74 * The pcibios_map_platform_irq function is defined in the appropriate
75 * board specific code and referenced here
76 */
77extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
78
79static __init void SetPCIPLL(void)
80{
81 {
82 /* Lets play with the PLL values */
83 unsigned long pll1cr1;
84 unsigned long mdiv, ndiv, pdiv;
85 unsigned long muxcr;
86 unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
87 unsigned int freq;
88
89#define CLKGENA 0xbb040000
90#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
91 pll1cr1 = ctrl_inl(PLLPCICR);
92 printk("PLL1CR1 %08lx\n", pll1cr1);
93 mdiv = PLL_MDIV(pll1cr1);
94 ndiv = PLL_NDIV(pll1cr1);
95 pdiv = PLL_PDIV(pll1cr1);
96 printk("mdiv %02lx ndiv %02lx pdiv %02lx\n", mdiv, ndiv, pdiv);
97 freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
98 printk("PLL freq %dMHz\n", freq);
99 muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
100 printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
101 }
102}
103
104
105struct pci_err {
106 unsigned mask;
107 const char *error_string;
108};
109
110static struct pci_err int_error[]={
111 { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
112 { INT_TTADI, "TTADI: Illegal byte enable in I/O transfer"},
113 { INT_TMTO, "TMTO: Target memory read/write timeout"},
114 { INT_MDEI, "MDEI: Master function disable error"},
115 { INT_APEDI, "APEDI: Address parity error"},
116 { INT_SDI, "SDI: SERR detected"},
117 { INT_DPEITW, "DPEITW: Data parity error target write"},
118 { INT_PEDITR, "PEDITR: PERR detected"},
119 { INT_TADIM, "TADIM: Target abort detected"},
120 { INT_MADIM, "MADIM: Master abort detected"},
121 { INT_MWPDI, "MWPDI: PERR from target at data write"},
122 { INT_MRDPEI, "MRDPEI: Master read data parity error"}
123};
124#define NUM_PCI_INT_ERRS (sizeof(int_error)/sizeof(struct pci_err))
125
126static struct pci_err aint_error[]={
127 { AINT_MBI, "MBI: Master broken"},
128 { AINT_TBTOI, "TBTOI: Target bus timeout"},
129 { AINT_MBTOI, "MBTOI: Master bus timeout"},
130 { AINT_TAI, "TAI: Target abort"},
131 { AINT_MAI, "MAI: Master abort"},
132 { AINT_RDPEI, "RDPEI: Read data parity"},
133 { AINT_WDPE, "WDPE: Write data parity"}
134};
135
136#define NUM_PCI_AINT_ERRS (sizeof(aint_error)/sizeof(struct pci_err))
137
138static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
139{
140 int i;
141
142 for(i=0;i<num_errors;i++) {
143 if(reg & error[i].mask) {
144 printk("%s\n",error[i].error_string);
145 }
146 }
147
148}
149
150
151static char * pci_commands[16]={
152 "Int Ack",
153 "Special Cycle",
154 "I/O Read",
155 "I/O Write",
156 "Reserved",
157 "Reserved",
158 "Memory Read",
159 "Memory Write",
160 "Reserved",
161 "Reserved",
162 "Configuration Read",
163 "Configuration Write",
164 "Memory Read Multiple",
165 "Dual Address Cycle",
166 "Memory Read Line",
167 "Memory Write-and-Invalidate"
168};
169
170static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
171{
172 unsigned pci_int, pci_air, pci_cir, pci_aint;
173 static int count=0;
174
175
176 pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
177 pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
178
179 /* Reset state to stop multiple interrupts */
180 ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0);
181
182
183 if(++count>1) return IRQ_HANDLED;
184
185 printk("** PCI ERROR **\n");
186
187 if(pci_int) {
188 printk("** INT register status\n");
189 print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
190 }
191
192 if(pci_aint) {
193 printk("** AINT register status\n");
194 print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
195 }
196
197 printk("** Address and command info\n");
198
199 printk("** Command %s : Address 0x%x\n",
200 pci_commands[pci_cir&0xf],pci_air);
201
202 if(pci_cir&CIR_PIOTEM) {
203 printk("CIR_PIOTEM:PIO transfer error for master\n");
204 }
205 if(pci_cir&CIR_RWTET) {
206 printk("CIR_RWTET:Read/Write transfer error for target\n");
207 }
208
209 return IRQ_HANDLED;
210}
211
212
213/* Rounds a number UP to the nearest power of two. Used for
214 * sizing the PCI window.
215 */
216static u32 r2p2(u32 num)
217{
218 int i = 31;
219 u32 tmp = num;
220
221 if (num == 0)
222 return 0;
223
224 do {
225 if (tmp & (1 << 31))
226 break;
227 i--;
228 tmp <<= 1;
229 } while (i >= 0);
230
231 tmp = 1 << i;
232 /* If the original number isn't a power of 2, round it up */
233 if (tmp != num)
234 tmp <<= 1;
235
236 return tmp;
237}
238
239static void __init pci_fixup_ide_bases(struct pci_dev *d)
240{
241 int i;
242
243 /*
244 * PCI IDE controllers use non-standard I/O port decoding, respect it.
245 */
246 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
247 return;
248 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
249 for(i=0; i<4; i++) {
250 struct resource *r = &d->resource[i];
251 if ((r->start & ~0x80) == 0x374) {
252 r->start |= 2;
253 r->end = r->start;
254 }
255 }
256}
257DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
258
259int __init st40pci_init(unsigned memStart, unsigned memSize)
260{
261 u32 lsr0;
262
263 SetPCIPLL();
264
265 /* Initialises the ST40 pci subsystem, performing a reset, then programming
266 * up the address space decoders appropriately
267 */
268
269 /* Should reset core here as well methink */
270
271 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
272
273 /* Loop while core resets */
274 while (ST40PCI_READ(CR) & CR_SOFT_RESET);
275
276 /* Switch off interrupts */
277 ST40PCI_WRITE(INTM, 0);
278 ST40PCI_WRITE(AINT, 0);
279
280 /* Now, lets reset all the cards on the bus with extreme prejudice */
281 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
282 udelay(250);
283
284 /* Set bus active, take it out of reset */
285 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
286
287 /* The PCI spec says that no access must be made to the bus until 1 second
288 * after reset. This seem ludicrously long, but some delay is needed here
289 */
290 mdelay(1000);
291
292 /* Switch off interrupts */
293 ST40PCI_WRITE(INTM, 0);
294 ST40PCI_WRITE(AINT, 0);
295
296 /* Allow it to be a master */
297
298 ST40PCI_WRITE_SHORT(CSR_CMD,
299 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
300 PCI_COMMAND_IO);
301
302 /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
303 * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
304 */
305
306
307 ST40PCI_WRITE(MBR, 0x10000000);
308 /* Always set the max size 128M (actually, it is only 96MB wide) */
309 ST40PCI_WRITE(MBMR, 0x07ff0000);
310
311 /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to
312 * allow cards that have legacy io such as vga to function correctly. This gives a
313 * maximum of 64K of io/space as only the bottom 16 bits of the address are copied
314 * over to the bus when the transaction is made. 64K of io space is more than enough
315 */
316 ST40PCI_WRITE(IOBR, 0x0);
317 /* Set up the 64K window */
318 ST40PCI_WRITE(IOBMR, 0x0);
319
320 /* Now we set up the mbars so the PCI bus can see the local memory */
321 /* Expose a 256M window starting at PCI address 0... */
322 ST40PCI_WRITE(CSR_MBAR0, 0);
323 ST40PCI_WRITE(LSR0, 0x0fff0001);
324
325 /* ... and set up the initial incomming window to expose all of RAM */
326 pci_set_rbar_region(7, memStart, memStart, memSize);
327
328 /* Maximise timeout values */
329 ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
330 ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
331 ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
332
333 ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
334
335 return 1;
336}
337
338char * __init pcibios_setup(char *str)
339{
340 return str;
341}
342
343
344#define SET_CONFIG_BITS(bus,devfn,where)\
345 (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
346
347#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
348
349
350static int CheckForMasterAbort(void)
351{
352 if (ST40PCI_READ(INT) & INT_MADIM) {
353 /* Should we clear config space version as well ??? */
354 ST40PCI_WRITE(INT, INT_MADIM);
355 ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
356 return 1;
357 }
358
359 return 0;
360}
361
362/* Write to config register */
363static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
364{
365 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
366 switch (size) {
367 case 1:
368 *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
369 break;
370 case 2:
371 *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
372 break;
373 case 4:
374 *val = ST40PCI_READ(PDR);
375 break;
376 }
377
378 if (CheckForMasterAbort()){
379 switch (size) {
380 case 1:
381 *val = (u8)0xff;
382 break;
383 case 2:
384 *val = (u16)0xffff;
385 break;
386 case 4:
387 *val = 0xffffffff;
388 break;
389 }
390 }
391
392 return PCIBIOS_SUCCESSFUL;
393}
394
395static int st40pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
396{
397 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
398
399 switch (size) {
400 case 1:
401 ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
402 break;
403 case 2:
404 ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
405 break;
406 case 4:
407 ST40PCI_WRITE(PDR, val);
408 break;
409 }
410
411 CheckForMasterAbort();
412
413 return PCIBIOS_SUCCESSFUL;
414}
415
416struct pci_ops st40pci_config_ops = {
417 .read = st40pci_read,
418 .write = st40pci_write,
419};
420
421
422/* Everything hangs off this */
423static struct pci_bus *pci_root_bus;
424
425
426static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
427{
428 return PCI_SLOT(dev->devfn);
429}
430
431
432static int __init pcibios_init(void)
433{
434 extern unsigned long memory_start, memory_end;
435
436 printk(KERN_ALERT "pci-st40.c: pcibios_init\n");
437
438 if (sh_mv.mv_init_pci != NULL) {
439 sh_mv.mv_init_pci();
440 }
441
442 /* The pci subsytem needs to know where memory is and how much
443 * of it there is. I've simply made these globals. A better mechanism
444 * is probably needed.
445 */
446 st40pci_init(PHYSADDR(memory_start),
447 PHYSADDR(memory_end) - PHYSADDR(memory_start));
448
449 if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq,
Thomas Gleixner6d208192006-07-01 19:29:25 -0700450 IRQF_DISABLED, "st40pci", NULL)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
452 return -EIO;
453 }
454
455 /* Enable the PCI interrupts on the device */
456 ST40PCI_WRITE(INTM, ~0);
457 ST40PCI_WRITE(AINT, ~0);
458
459 /* Map the io address apprioately */
460#ifdef CONFIG_HD64465
461 hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
462 ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
463#endif
464
465 /* ok, do the scan man */
466 pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
467 pci_assign_unassigned_resources();
468 pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq);
469
470 return 0;
471}
472
473subsys_initcall(pcibios_init);
474
475void __init pcibios_fixup_bus(struct pci_bus *bus)
476{
477}
478
479/*
480 * Publish a region of local address space over the PCI bus
481 * to other devices.
482 */
483static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
484 unsigned long pciOffset, unsigned long regionSize)
485{
486 unsigned long mask;
487
488 if (region > 7)
489 return;
490
491 if (regionSize > (512 * 1024 * 1024))
492 return;
493
494 mask = r2p2(regionSize) - 0x10000;
495
496 /* Diable the region (in case currently in use, should never happen) */
497 ST40PCI_WRITE_INDEXED(RSR, region, 0);
498
499 /* Start of local address space to publish */
500 ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
501
502 /* Start of region in PCI address space as an offset from MBAR0 */
503 ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
504
505 /* Size of region */
506 ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
507}
508