MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / arm / mach-moxart / ftpci.c
blobe4f08aede781a7ed8e2c23a1fd085b13f35983c3
1 /*
2 ftpci.h
3 maintened by ivan wang 2004/8/18 11:25
4 */
6 #include <linux/config.h>
7 #include <linux/sched.h>
8 #include <linux/kernel.h>
9 #include <linux/pci.h>
10 #include <linux/ptrace.h>
11 #include <linux/slab.h>
12 #include <linux/ioport.h>
13 #include <linux/interrupt.h>
14 #include <linux/spinlock.h>
15 #include <linux/init.h>
16 #include <asm/hardware.h>
17 #include <asm/irq.h>
18 #include <asm/system.h>
19 #include <asm/mach/pci.h>
20 #include <asm/sizes.h>
21 #include <asm/arch/moxa.h>
22 #include <asm/arch/irq.h>
23 #include <asm/arch/ftpci.h>
26 #ifdef CONFIG_CPE120_PLATFORM
27 #include <asm/arch/cpe/cpe_ext_int.h>
28 #endif
30 #define DEBUG_FTPCI 1
32 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3) )
33 static spinlock_t ftpci_lock;
34 struct pci_dev *pci_bridge=NULL;
35 static unsigned int pci_config_addr;
36 static unsigned int pci_config_data;
37 int ftpci_probed=0;
39 static int ftpci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
41 unsigned long flags;
42 u32 v;
43 unsigned int shift;
45 spin_lock_irqsave(&ftpci_lock, flags);
46 *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(dev->bus->number,dev->devfn,where);
47 v=*(volatile unsigned int *)pci_config_data;
48 spin_unlock_irqrestore(&ftpci_lock, flags);
49 shift = (where&0x3)*8;
50 *val = (v>>shift)&0xff;
51 return PCIBIOS_SUCCESSFUL;
54 static int ftpci_read_config_word(struct pci_dev *dev, int where, u16 *val)
56 unsigned long flags;
57 u32 v;
58 unsigned int shift;
60 spin_lock_irqsave(&ftpci_lock, flags);
61 *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(dev->bus->number,dev->devfn,where);
62 v=*(volatile unsigned int *)pci_config_data;
63 spin_unlock_irqrestore(&ftpci_lock, flags);
64 shift = (where&0x3)*8;
65 *val = (v>>shift)&0xffff;
66 return PCIBIOS_SUCCESSFUL;
69 static int ftpci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
71 unsigned long flags;
72 u32 v;
74 spin_lock_irqsave(&ftpci_lock, flags);
75 *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(dev->bus->number,dev->devfn,where);
76 v=*(volatile unsigned int *)pci_config_data;
77 spin_unlock_irqrestore(&ftpci_lock, flags);
78 *val = v;
79 return PCIBIOS_SUCCESSFUL;
82 static int ftpci_write_config_byte(struct pci_dev *dev, int where, u8 val)
84 u32 org_val;
85 unsigned long flags;
86 unsigned int shift;
88 shift = (where&0x3)*8;
89 spin_lock_irqsave(&ftpci_lock, flags);
90 *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(dev->bus->number,dev->devfn,where);
91 org_val=*(volatile unsigned int *)pci_config_data;
92 org_val=(org_val&~(0xff<<shift))|((u32)val<<shift);
93 *(volatile unsigned int *)pci_config_data=org_val;
94 spin_unlock_irqrestore(&ftpci_lock, flags);
95 return PCIBIOS_SUCCESSFUL;
98 static int ftpci_write_config_word(struct pci_dev *dev, int where, u16 val)
100 u32 org_val;
101 unsigned long flags;
102 unsigned int shift;
104 shift = (where&0x3)*8;
105 spin_lock_irqsave(&ftpci_lock, flags);
106 *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(dev->bus->number, dev->devfn, where);
107 org_val=*(volatile unsigned int *)pci_config_data;
108 org_val=(org_val&~(0xffff<<shift))|((u32)val<<shift);
109 *(volatile unsigned int *)pci_config_data=org_val;
110 spin_unlock_irqrestore(&ftpci_lock, flags);
111 return PCIBIOS_SUCCESSFUL;
114 static int ftpci_write_config_dword(struct pci_dev *dev, int where, u32 val)
116 unsigned long flags;
117 spin_lock_irqsave(&ftpci_lock, flags);
118 *(volatile unsigned int *)pci_config_addr=CONFIG_CMD(dev->bus->number, dev->devfn, where);
119 *(volatile unsigned int *)pci_config_data=val;
120 spin_unlock_irqrestore(&ftpci_lock, flags);
121 return PCIBIOS_SUCCESSFUL;
124 static struct pci_ops ftpci_ops = {
125 .read = ftpci_read_config_byte,
126 //.read_word = ftpci_read_config_word,
127 // .read_dword = ftpci_read_config_dword,
128 .write = ftpci_write_config_byte,
129 // .write_word = ftpci_write_config_word,
130 // .write_dword= ftpci_write_config_dword,
133 /* using virtual address for pci_resource_start() function*/
134 static struct resource pci_io = {
135 .name = "PCI io",
136 .start = (CPE_PCI_BASE+SZ_4K),
137 .end = (CPE_PCI_BASE+SZ_1M),
138 .flags = IORESOURCE_IO,
140 /* using physical address for memory resource*/
141 static struct resource pci_mem = {
142 .name = "PCI non-prefetchable",
143 .start = PCI_MEM_BASE,
144 .end = PCI_MEM_END,
145 .flags = IORESOURCE_MEM,
148 //int __init ftpci_setup_resource(struct resource **resource)
149 void __init ftpci_setup_resource(struct resource **resource)
151 if (request_resource(&ioport_resource, &pci_io)) {
152 printk(KERN_ERR "PCI: unable to allocate io region\n");
153 // return -EBUSY;
155 if (request_resource(&iomem_resource, &pci_mem)) {
156 printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
157 "memory region\n");
158 // return -EBUSY;
162 * bus->resource[0] is the IO resource for this bus
163 * bus->resource[1] is the mem resource for this bus
164 * bus->resource[2] is the prefetch mem resource for this bus
167 resource[0] = &pci_io;
168 resource[1] = &pci_mem;
170 // return 1;
173 inline int ftpci_get_irq(void)
175 unsigned int status;
176 ftpci_read_config_dword(pci_bridge, 0x4c, &status);
177 //printk("ftpci_get_irq,status=0x%x\n",status);
178 status=(status>>28);
179 if(status&0x1)
180 return 0;
181 if(status&0x2)
182 return 1;
183 if(status&0x4)
184 return 2;
185 if(status&0x8)
186 return 3;
187 return -1;
190 void ftpci_clear_irq(unsigned int irq)
192 //int i;
193 unsigned int status;
194 ftpci_read_config_dword(pci_bridge, 0x4c, &status);
195 if(irq==0)
196 status=(status&0xfffffff)|((0x1)<<28);
197 else if(irq==1)
198 status=(status&0xfffffff)|((0x2)<<28);
199 else if(irq==2)
200 status=(status&0xfffffff)|((0x4)<<28);
201 else if(irq==3)
202 status=(status&0xfffffff)|((0x8)<<28);
203 ftpci_write_config_dword(pci_bridge, 0x4c, status);
206 static int ftpci_probe(unsigned int addr_p)
208 unsigned int *addr=(unsigned int*)addr_p;
209 *(volatile unsigned int *)addr=0x80000000;
210 if(*(volatile unsigned int *)addr==0x80000000)
211 ftpci_probed=1;
212 else
213 ftpci_probed=0;
214 *(volatile unsigned int *)addr=0x0;
215 return ftpci_probed;
219 void __init ftpci_init(void *sysdata)
221 u16 val;
223 pci_config_addr=CPE_PCI_BASE+FTPCI_CFG_ADR_REG;
224 pci_config_data=CPE_PCI_BASE+FTPCI_CFG_DATA_REG;
226 if(!ftpci_probe(pci_config_addr))
227 return;
229 pci_scan_bus(0, &ftpci_ops, sysdata);
230 pci_bridge=pci_find_device(PCI_BRIDGE_VENID,PCI_BRIDGE_DEVID,NULL);
231 if (pci_bridge == NULL)
232 return;
234 spin_lock_init(&ftpci_lock);
236 // Enable the Interrupt Mask (INTA/INTB/INTC/INTD)
237 ftpci_read_config_word(pci_bridge,PCI_INT_MASK,&val);
238 val|=(PCI_INTA_ENABLE|PCI_INTB_ENABLE|PCI_INTC_ENABLE|PCI_INTD_ENABLE);
239 ftpci_write_config_word(pci_bridge,PCI_INT_MASK,val);
241 // Write DMA Start Address/Size Data to the Bridge configuration space
242 ftpci_write_config_dword(pci_bridge, PCI_MEM_BASE_SIZE1, FTPCI_BASE_ADR_SIZE_1GB);
246 * This routine handles multiple bridges.
248 static u8 __init cpe_swizzle(struct pci_dev *dev, u8 *pinp)
250 return 0;
253 static int __init cpe_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
255 //printk("cpe_map_irq,slot=%d pin=%d\n",PCI_SLOT(dev->devfn),pin);
256 switch(PCI_SLOT(dev->devfn))
258 case 8:
259 return VIRQ_PCI_A;
260 case 9:
261 return VIRQ_PCI_B;
262 case 10:
263 return VIRQ_PCI_C;
264 case 11:
265 return VIRQ_PCI_D;
266 default:
267 //printk("Not Support Slot %d\n",slot);
268 break;
270 return -1;
273 struct hw_pci cpe_pci __initdata = {
274 // .setup_resources = ftpci_setup_resource,
275 // .init = ftpci_init,
276 .swizzle = cpe_swizzle,
277 .map_irq = cpe_map_irq,