3 maintened by ivan wang 2004/8/18 11:25
6 #include <linux/config.h>
7 #include <linux/sched.h>
8 #include <linux/kernel.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>
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>
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
;
39 static int ftpci_read_config_byte(struct pci_dev
*dev
, int where
, u8
*val
)
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
)
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
)
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
);
79 return PCIBIOS_SUCCESSFUL
;
82 static int ftpci_write_config_byte(struct pci_dev
*dev
, int where
, u8 val
)
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
)
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
)
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
= {
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
,
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");
155 if (request_resource(&iomem_resource
, &pci_mem
)) {
156 printk(KERN_ERR
"PCI: unable to allocate non-prefetchable "
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
;
173 inline int ftpci_get_irq(void)
176 ftpci_read_config_dword(pci_bridge
, 0x4c, &status
);
177 //printk("ftpci_get_irq,status=0x%x\n",status);
190 void ftpci_clear_irq(unsigned int irq
)
194 ftpci_read_config_dword(pci_bridge
, 0x4c, &status
);
196 status
=(status
&0xfffffff)|((0x1)<<28);
198 status
=(status
&0xfffffff)|((0x2)<<28);
200 status
=(status
&0xfffffff)|((0x4)<<28);
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)
214 *(volatile unsigned int *)addr
=0x0;
219 void __init
ftpci_init(void *sysdata
)
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
))
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
)
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
)
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
))
267 //printk("Not Support Slot %d\n",slot);
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
,