MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / arch / arm / mach-moxacpu / ftpci.c.bak-05232006
blobec0c73c86fc2384690ef88c811823661e9421c23
1 /* 
2         History:
3         Date            Author                  Comment
4         11-04-2005      Victor Yu.              Create it.
5 */
7 #include <linux/config.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/pci.h>
11 #include <linux/ptrace.h>
12 #include <linux/slab.h>
13 #include <linux/ioport.h>
14 #include <linux/interrupt.h>
15 #include <linux/spinlock.h>
16 #include <linux/init.h>
17 #include <asm/hardware.h>
18 #include <asm/irq.h>
19 #include <asm/system.h>
20 #include <asm/mach/pci.h>
21 #include <asm/sizes.h>
22 #include <asm/arch/cpe/cpe.h>
23 #include <asm/arch/cpe_int.h>
24 #include <asm/arch/ftpci.h>
25 #include <asm/mach-types.h>
27 #define LOCAL_READ_WRITE_LOCK_IRQ       1
29 //#define DEBUG_FTPCI                   1
31 #ifdef DEBUG_FTPCI
32 #define dbg_printk(x...)                printk(x)
33 #else
34 #define dbg_printk(x...)
35 #endif
37 #define CONFIG_CMD(bus, device_fn, where)   (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3) )
38 static spinlock_t       ftpci_lock;
39 static unsigned int     pci_config_addr;
40 static unsigned int     pci_config_data;
41 int                     ftpci_probed=1;
43 static int ftpci_read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 *val)
45         unsigned long   flags;
46         u32             v;
47         unsigned int    shift;
49         spin_lock_irqsave(&ftpci_lock, flags);
50         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(bus->number,devfn,where);  
51         v=*(volatile unsigned int *)pci_config_data;
52         spin_unlock_irqrestore(&ftpci_lock, flags);
53         shift = (where&0x3)*8;
54         *val = (v>>shift)&0xff;
55         return PCIBIOS_SUCCESSFUL;
58 #if 0   // mask by Victor Yu. 01-09-2006, No used, so I mask it.
59 static int ftpci_local_read_config_byte(int where, u8 *val)
61         unsigned long   flags;
62         u32             v;
63         unsigned int    shift;
65         spin_lock_irqsave(&ftpci_lock, flags);
66         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(0,0,where);        
67         v=*(volatile unsigned int *)pci_config_data;
68         spin_unlock_irqrestore(&ftpci_lock, flags);
69         shift = (where&0x3)*8;
70         *val = (v>>shift)&0xff;
71         return PCIBIOS_SUCCESSFUL;
73 #endif
75 static int ftpci_read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 *val)
77         unsigned long   flags;
78         u32             v;
79         unsigned int    shift;
81         spin_lock_irqsave(&ftpci_lock, flags);
82         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(bus->number,devfn,where);
83         v=*(volatile unsigned int *)pci_config_data;
84         spin_unlock_irqrestore(&ftpci_lock, flags);
85         shift = (where&0x3)*8;
86         *val = (v>>shift)&0xffff;
87         return PCIBIOS_SUCCESSFUL;
90 static void ftpci_local_read_config_word(int where, u16 *val)
92 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
93         unsigned long   flags;
94 #endif
95         u32             v;
96         unsigned int    shift;
98 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
99         spin_lock_irqsave(&ftpci_lock, flags);
100 #endif
101         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(0,0,where);
102         v=*(volatile unsigned int *)pci_config_data;
103 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
104         spin_unlock_irqrestore(&ftpci_lock, flags);
105 #endif
106         shift = (where&0x3)*8;
107         *val = (v>>shift)&0xffff;
110 static int ftpci_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 *val)
112         unsigned long   flags;
113         u32             v;
115         spin_lock_irqsave(&ftpci_lock, flags);
116         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(bus->number,devfn,where);
117         v=*(volatile unsigned int *)pci_config_data;
118         spin_unlock_irqrestore(&ftpci_lock, flags);
119         *val = v;
120         return PCIBIOS_SUCCESSFUL;
123 static void ftpci_local_read_config_dword(int where, u32 *val)
125 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
126         unsigned long   flags;
127 #endif
128         u32             v;
130 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
131         spin_lock_irqsave(&ftpci_lock, flags);
132 #endif
133         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(0,0,where);
134         v=*(volatile unsigned int *)pci_config_data;
135 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
136         spin_unlock_irqrestore(&ftpci_lock, flags);
137 #endif
138         *val = v;
141 static int ftpci_write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
143         u32             org_val;
144         unsigned long   flags;
145         unsigned int    shift;
147         shift = (where&0x3)*8;
148         spin_lock_irqsave(&ftpci_lock, flags);
149         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(bus->number,devfn,where);
150         org_val=*(volatile unsigned int *)pci_config_data;
151         org_val=(org_val&~(0xff<<shift))|((u32)val<<shift);
152         *(volatile unsigned int *)pci_config_data=org_val;
153         spin_unlock_irqrestore(&ftpci_lock, flags);
154         return PCIBIOS_SUCCESSFUL;
157 #if 0   // mask by Victor Yu. 01-09-2006, No used, so I mask it.
158 static int ftpci_local_write_config_byte(int where, u8 val)
160         u32             org_val;
161         unsigned long   flags;
162         unsigned int    shift;
164         shift = (where&0x3)*8;
165         spin_lock_irqsave(&ftpci_lock, flags);
166         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(0,0,where);
167         org_val=*(volatile unsigned int *)pci_config_data;
168         org_val=(org_val&~(0xff<<shift))|((u32)val<<shift);
169         *(volatile unsigned int *)pci_config_data=org_val;
170         spin_unlock_irqrestore(&ftpci_lock, flags);
171         return PCIBIOS_SUCCESSFUL;
173 #endif
175 static int ftpci_write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
177         u32             org_val;
178         unsigned long   flags;
179         unsigned int    shift;
181         shift = (where&0x3)*8;
182         spin_lock_irqsave(&ftpci_lock, flags);
183         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(bus->number, devfn, where);
184         org_val=*(volatile unsigned int *)pci_config_data;
185         org_val=(org_val&~(0xffff<<shift))|((u32)val<<shift);
186         *(volatile unsigned int *)pci_config_data=org_val;
187         spin_unlock_irqrestore(&ftpci_lock, flags);
188         return PCIBIOS_SUCCESSFUL;
191 static void ftpci_local_write_config_word(int where, u16 val)
193         u32             org_val;
194 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
195         unsigned long   flags;
196 #endif
197         unsigned int    shift;
199         shift = (where&0x3)*8;
200 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
201         spin_lock_irqsave(&ftpci_lock, flags);
202 #endif
203         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(0, 0, where);
204         org_val=*(volatile unsigned int *)pci_config_data;
205         org_val=(org_val&~(0xffff<<shift))|((u32)val<<shift);
206         *(volatile unsigned int *)pci_config_data=org_val;
207 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
208         spin_unlock_irqrestore(&ftpci_lock, flags);
209 #endif
212 static int ftpci_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
214         unsigned long flags;
215         spin_lock_irqsave(&ftpci_lock, flags);
216         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(bus->number, devfn, where);
217         *(volatile unsigned int *)pci_config_data=val;
218         spin_unlock_irqrestore(&ftpci_lock, flags);
219         return PCIBIOS_SUCCESSFUL;
222 static void ftpci_local_write_config_dword(int where, u32 val)
224 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
225         unsigned long flags;
226         spin_lock_irqsave(&ftpci_lock, flags);
227 #endif
228         *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(0, 0, where);
229         *(volatile unsigned int *)pci_config_data=val;
230 #if LOCAL_READ_WRITE_LOCK_IRQ   // mask by Victor Yu. 05-15-2006
231         spin_unlock_irqrestore(&ftpci_lock, flags);
232 #endif
235 static int ftpci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
236                           int size, u32 *val)
238         int r; 
240         switch (size) {
241         case 1:
242                 r = ftpci_read_config_byte(bus,devfn,where,(u8*)val);
243                 break;
245         case 2:
246                 r = ftpci_read_config_word(bus,devfn,where,(u16*)val);
247                 break;
249         default:
250                 r = ftpci_read_config_dword(bus,devfn,where,val);
251                 break;
252         }
254         return r;
257 static int ftpci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
258                               int size, u32 val)
260         int r; 
262         switch (size) {
263         case 1:
264                 r = ftpci_write_config_byte(bus, devfn, where, (u8)val);
265                 break;
267         case 2:
268                 r = ftpci_write_config_word(bus, devfn, where, (u16)val);
269                 break;
271         case 4:
272                 r = ftpci_write_config_dword(bus, devfn, where, val);
273                 break;
274         default:
275                 printk( "Invalid size for ftpci_write()\n" );
276                 r = PCIBIOS_FUNC_NOT_SUPPORTED;  // Luke Lee 03/23/2005 ins 1
277         }
279         return r;
282 static struct pci_ops ftpci_ops = {
283         .read  = ftpci_read_config,
284         .write = ftpci_write_config,
287 /* You need to write the physical address to PCI mapping for bridge */
288 /* You need to modify the source file drivers/pci/setup-res.c */
289 static struct resource pci_io = {
290         .name   = "PCI I/O Space",
291 #if 1   // mask by Victor Yu. 01-09-2006
292         .start  = PCI_IO_VA_BASE,
293         .end    = PCI_IO_VA_END-1,
294 #else
295         .start  = CPE_PCI_IO_BASE,
296         .end    = CPE_PCI_IO_END-1,
297 #endif
298         .flags  = IORESOURCE_IO,
300 /* using physical address for memory resource*/
301 static struct resource pci_mem = {
302         .name   = "PCI Memory Space",
303 #if 1
304         .start  = PCI_MEM_VA_BASE,
305         .end    = PCI_MEM_VA_END-1,
306 #else
307         .start  = PCI_MEM_BASE,
308         .end    = PCI_MEM_END-1,
309 #endif
310         .flags  = IORESOURCE_MEM,
313 // Luke Lee 03/23/2005 unrem 1 rem 1
314 int __init ftpci_setup_resource(struct resource **resource)
316         if ( ftpci_probed == 0 )
317                 return 0;
319         if (request_resource(&ioport_resource, &pci_io)) {
320                 printk(KERN_ERR "PCI: unable to allocate io region\n");
321                 return 0;
322         }
323         if (request_resource(&iomem_resource, &pci_mem)) {
324                 printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
325                        "memory region\n");
326                 return 0;
327         }
329         /*
330          * bus->resource[0] is the IO resource for this bus
331          * bus->resource[1] is the mem resource for this bus
332          * bus->resource[2] is the prefetch mem resource for this bus
333          */
335         resource[0] = &pci_io;
336         resource[1] = &pci_mem;
337         resource[2] = NULL;
339         return 1;
342 inline int ftpci_get_irq(void)
344         unsigned int     status;
346         ftpci_local_read_config_dword(0x4c, &status);
347         status >>= 28;
348         if(status&0x1)
349                 return 0;
350         if(status&0x2)
351                 return 1;
352         if(status&0x4)
353                 return 2;
354         if(status&0x8)
355                 return 3;
356         return -1;
359 void ftpci_clear_irq(unsigned int irq)
361         unsigned int     status;
363         ftpci_local_read_config_dword(0x4c, &status);
364         if(irq==0)
365                 status=(status&0xfffffff)|((0x1)<<28);
366         else if(irq==1)
367                 status=(status&0xfffffff)|((0x2)<<28);
368         else if(irq==2)
369                 status=(status&0xfffffff)|((0x4)<<28);
370         else if(irq==3)
371                 status=(status&0xfffffff)|((0x8)<<28);
372         ftpci_local_write_config_dword(0x4c, status);
375 static int ftpci_probe(void)
377         *(volatile unsigned int *)pci_config_addr=0x80000000;
378         if(*(volatile unsigned int *)pci_config_addr==0x80000000)
379                 ftpci_probed=1;
380         else
381                 ftpci_probed=0;
382         *(volatile unsigned int *)pci_config_addr=0x0;
384         return ftpci_probed;
387 void __init ftpci_preinit(void)
389         u16             val;
391         dbg_printk("[ftpci_preinit test01]\n");
392         pci_config_addr=CPE_PCI_VA_BASE+FTPCI_CFG_ADR_REG;
393         pci_config_data=CPE_PCI_VA_BASE+FTPCI_CFG_DATA_REG;
395         if( !ftpci_probe() )
396                 return;
397         
398         dbg_printk("[ftpci_preinit test03]\n");
399         spin_lock_init(&ftpci_lock);
400         
401         ftpci_local_read_config_word(PCI_INT_MASK,&val);
402         val|=(PCI_INTA_ENABLE|PCI_INTB_ENABLE|PCI_INTC_ENABLE|PCI_INTD_ENABLE);
403         ftpci_local_write_config_word(PCI_INT_MASK,val);
404 #if 1
405         ftpci_local_write_config_dword(PCI_MEM_BASE_SIZE1, FTPCI_BASE_ADR_SIZE_1GB);
406 #else
407         ftpci_local_write_config_dword(PCI_MEM_BASE_SIZE1, FTPCI_BASE_ADR_SIZE_1GB);
408         ftpci_local_write_config_dword(PCI_MEM_BASE_SIZE2, FTPCI_BASE_ADR_SIZE_1GB);
409         ftpci_local_write_config_dword(PCI_MEM_BASE_SIZE3, FTPCI_BASE_ADR_SIZE_1GB);
410 #endif
414  * This routine handles multiple bridges.
415  */
416 static u8 __init cpe_swizzle(struct pci_dev *dev, u8 *pinp)
418         dbg_printk( "cpe_swizzle(%X,%X)\n\r",(unsigned)dev,(unsigned)pinp );
419         return 0;
422 static int __init cpe_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
424         dbg_printk("cpe_map_irq,slot=%d pin=%d\n",PCI_SLOT(dev->devfn),pin);
425 #if 1   // mask by Victor Yu. 12-28-2005
426         switch(PCI_SLOT(dev->devfn)) {
427         case 8:
428         case 12:
429         case 13:
430                 return VIRQ_PCI_A;
431         case 9:
432                 return VIRQ_PCI_B;
433         case 10:
434                 return VIRQ_PCI_C;
435         case 11:
436                 return VIRQ_PCI_B;
437 #else   // add by Victor Yu. 12-28-2005
438         switch( PCI_SLOT(dev->devfn) & 0x3 ) {
439         case 0:
440                 return VIRQ_PCI_A;
441         case 1:
442                 return VIRQ_PCI_B;
443         case 2:
444                 return VIRQ_PCI_C;
445         case 3:
446                 return VIRQ_PCI_D;
447 #endif
448         default:
449                 dbg_printk("Not Support Slot %d\n",slot);
450         break;
451         }
453         return -1;
456 int __init ftpci_setup(int nr, struct pci_sys_data *sys)
458         int ret = 0;
460         dbg_printk("[ftpci_setup test01]\n");
461         if ( ftpci_probed == 0 || nr >= 1 )
462                 return ret;
463         dbg_printk("[ftpci_setup test02]\n");
464 #if 0   // mask by Victor Yu. 10-27-2005
465         if (nr == 0) {
466                 sys->mem_offset = CPE_PCI_MEM;
467                 ret = ftpci_setup_resource(sys->resource);
468         }
469         return ret;
470 #else   // add by Victor Yu. 10-27-2005
471         return ftpci_setup_resource(sys->resource);
472 #endif
475 static struct pci_bus *ftpci_scan_bus(int nr, struct pci_sys_data *sys)
477         dbg_printk("[ftpci_scan_bus test01]\n");
478         if ( ftpci_probed == 0 )
479                 return NULL;
480         return pci_scan_bus(sys->busnr, &ftpci_ops, sys);
483 static struct hw_pci cpe_pci  __initdata = {
484         .swizzle                = cpe_swizzle,
485         .map_irq                = cpe_map_irq,
486         .setup                  = ftpci_setup,
487         .nr_controllers         = 1,
488         .scan                   = ftpci_scan_bus,
489         .preinit                = ftpci_preinit,
492 static int __init a320_pci_init(void)
494         dbg_printk("[pci_init test01]\n");
495         if (machine_is_moxacpu())
496                 pci_common_init(&cpe_pci);
497         return 0;
500 subsys_initcall(a320_pci_init);