source: trunk/target/linux/ifxmips/files/arch/mips/ifxmips/pci.c @ 9847

Last change on this file since 9847 was 9847, checked in by blogic, 9 years ago

remove dbg printk from pci code

File size: 9.2 KB
Line 
1#include <linux/types.h>
2#include <linux/pci.h>
3#include <linux/kernel.h>
4#include <linux/init.h>
5#include <linux/delay.h>
6#include <linux/mm.h>
7#include <asm/ifxmips/ifxmips.h>
8#include <asm/ifxmips/ifxmips_irq.h>
9#include <asm/addrspace.h>
10#include <linux/vmalloc.h>
11
12#define IFXMIPS_PCI_MEM_BASE    0x18000000
13#define IFXMIPS_PCI_MEM_SIZE    0x02000000
14#define IFXMIPS_PCI_IO_BASE     0x1AE00000
15#define IFXMIPS_PCI_IO_SIZE     0x00200000
16
17#define IFXMIPS_PCI_CFG_BUSNUM_SHF 16
18#define IFXMIPS_PCI_CFG_DEVNUM_SHF 11
19#define IFXMIPS_PCI_CFG_FUNNUM_SHF 8
20
21#define PCI_ACCESS_READ  0
22#define PCI_ACCESS_WRITE 1
23
24//#define CONFIG_IFXMIPS_PCI_HW_SWAP 1
25
26static int ifxmips_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
27static int ifxmips_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
28
29struct pci_ops ifxmips_pci_ops = {
30        .read = ifxmips_pci_read_config_dword,
31        .write = ifxmips_pci_write_config_dword
32};
33
34static struct resource pci_io_resource = {
35        .name = "io pci IO space",
36        .start = IFXMIPS_PCI_IO_BASE,
37        .end = IFXMIPS_PCI_IO_BASE + IFXMIPS_PCI_IO_SIZE - 1,
38        .flags = IORESOURCE_IO
39};
40
41static struct resource pci_mem_resource = {
42        .name = "ext pci memory space",
43        .start = IFXMIPS_PCI_MEM_BASE,
44        .end = IFXMIPS_PCI_MEM_BASE + IFXMIPS_PCI_MEM_SIZE - 1,
45        .flags = IORESOURCE_MEM
46};
47
48static struct pci_controller ifxmips_pci_controller = {
49        .pci_ops = &ifxmips_pci_ops,
50        .mem_resource = &pci_mem_resource,
51        .mem_offset     = 0x00000000UL,
52        .io_resource = &pci_io_resource,
53        .io_offset      = 0x00000000UL,
54};
55
56static u32 ifxmips_pci_mapped_cfg;
57
58static int
59ifxmips_pci_config_access(unsigned char access_type,
60                struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data)
61{
62        unsigned long cfg_base;
63        unsigned long flags;
64
65        u32 temp;
66
67        /* IFXMips support slot from 0 to 15 */
68        /* dev_fn 0&0x68 (AD29) is ifxmips itself */
69        if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
70                        || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
71                return 1;
72
73        local_irq_save(flags);
74
75        cfg_base = ifxmips_pci_mapped_cfg;
76        cfg_base |= (bus->number << IFXMIPS_PCI_CFG_BUSNUM_SHF) | (devfn <<
77                        IFXMIPS_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
78
79        /* Perform access */
80        if (access_type == PCI_ACCESS_WRITE)
81        {
82#ifdef CONFIG_IFXMIPS_PCI_HW_SWAP
83                writel(swab32(*data), ((u32*)cfg_base));
84#else
85                writel(*data, ((u32*)cfg_base));
86#endif
87        } else {
88                *data = readl(((u32*)(cfg_base)));
89#ifdef CONFIG_IFXMIPS_PCI_HW_SWAP
90                *data = swab32(*data);
91#endif
92        }
93        wmb();
94
95        /* clean possible Master abort */
96        cfg_base = (ifxmips_pci_mapped_cfg | (0x0 << IFXMIPS_PCI_CFG_FUNNUM_SHF)) + 4;
97        temp = readl(((u32*)(cfg_base)));
98#ifdef CONFIG_IFXMIPS_PCI_HW_SWAP
99        temp = swab32 (temp);
100#endif
101        cfg_base = (ifxmips_pci_mapped_cfg | (0x68 << IFXMIPS_PCI_CFG_FUNNUM_SHF)) + 4;
102        writel(temp, ((u32*)cfg_base));
103
104        local_irq_restore(flags);
105
106        if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
107                return 1;
108
109        return 0;
110}
111
112static int ifxmips_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
113                int where, int size, u32 * val)
114{
115        u32 data = 0;
116
117        if (ifxmips_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
118                return PCIBIOS_DEVICE_NOT_FOUND;
119
120        if (size == 1)
121                *val = (data >> ((where & 3) << 3)) & 0xff;
122        else if (size == 2)
123                *val = (data >> ((where & 3) << 3)) & 0xffff;
124        else
125                *val = data;
126
127        return PCIBIOS_SUCCESSFUL;
128}
129
130static int ifxmips_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
131                int where, int size, u32 val)
132{
133        u32 data = 0;
134
135        if (size == 4)
136        {
137                data = val;
138        } else {
139                if (ifxmips_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
140                        return PCIBIOS_DEVICE_NOT_FOUND;
141
142                if (size == 1)
143                        data = (data & ~(0xff << ((where & 3) << 3))) |
144                                (val << ((where & 3) << 3));
145                else if (size == 2)
146                        data = (data & ~(0xffff << ((where & 3) << 3))) |
147                                (val << ((where & 3) << 3));
148        }
149
150        if (ifxmips_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
151                return PCIBIOS_DEVICE_NOT_FOUND;
152
153        return PCIBIOS_SUCCESSFUL;
154}
155
156
157int pcibios_plat_dev_init(struct pci_dev *dev){
158        u8 pin;
159
160        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
161
162        switch(pin) {
163                case 0:
164                        break;
165                case 1:
166                        //falling edge level triggered:0x4, low level:0xc, rising edge:0x2
167                        writel(readl(IFXMIPS_EBU_PCC_CON) | 0xc, IFXMIPS_EBU_PCC_CON);
168                        writel(readl(IFXMIPS_EBU_PCC_IEN) | 0x10, IFXMIPS_EBU_PCC_IEN);
169                        break;
170                case 2:
171                case 3:
172                case 4:
173                        printk ("WARNING: interrupt pin %d not supported yet!\n", pin);
174                default:
175                        printk ("WARNING: invalid interrupt pin %d\n", pin);
176                        return 1;
177        }
178
179        return 0;
180}
181
182static void __init ifxmips_pci_startup (void){
183        /*initialize the first PCI device--ifxmips itself */
184        u32 temp_buffer;
185        /*TODO: trigger reset */
186        writel(readl(IFXMIPS_CGU_IFCCR) & ~0xf00000, IFXMIPS_CGU_IFCCR);
187        writel(readl(IFXMIPS_CGU_IFCCR) | 0x800000, IFXMIPS_CGU_IFCCR);
188        /* PCIS of IF_CLK of CGU   : 1 =>PCI Clock output
189           0 =>clock input
190           PADsel of PCI_CR of CGU : 1 =>From CGU
191           : 0 =>From pad
192         */
193        writel(readl(IFXMIPS_CGU_IFCCR) | (1 << 16), IFXMIPS_CGU_IFCCR);
194        writel((1 << 31) | (1 << 30), IFXMIPS_CGU_PCICR);
195
196        /* prepare GPIO */
197        /* PCI_RST: P1.5 ALT 01 */
198        //pliu20060613: start
199        writel(readl(IFXMIPS_GPIO_P1_OUT) | (1 << 5), IFXMIPS_GPIO_P1_OUT);
200        writel(readl(IFXMIPS_GPIO_P1_OD) | (1 << 5), IFXMIPS_GPIO_P1_OD);
201        writel(readl(IFXMIPS_GPIO_P1_DIR) | (1 << 5), IFXMIPS_GPIO_P1_DIR);
202        writel(readl(IFXMIPS_GPIO_P1_ALTSEL1) & ~(1 << 5), IFXMIPS_GPIO_P1_ALTSEL1);
203        writel(readl(IFXMIPS_GPIO_P1_ALTSEL0) & ~(1 << 5), IFXMIPS_GPIO_P1_ALTSEL0);
204        //pliu20060613: end
205        /* PCI_REQ1: P1.13 ALT 01 */
206        /* PCI_GNT1: P1.14 ALT 01 */
207        writel(readl(IFXMIPS_GPIO_P1_DIR) & ~0x2000, IFXMIPS_GPIO_P1_DIR);
208        writel(readl(IFXMIPS_GPIO_P1_DIR) | 0x4000, IFXMIPS_GPIO_P1_DIR);
209        writel(readl(IFXMIPS_GPIO_P1_ALTSEL1) & ~0x6000, IFXMIPS_GPIO_P1_ALTSEL1);
210        writel(readl(IFXMIPS_GPIO_P1_ALTSEL0) | 0x6000, IFXMIPS_GPIO_P1_ALTSEL0);
211        /* PCI_REQ2: P1.15 ALT 10 */
212        /* PCI_GNT2: P1.7 ALT 10 */
213
214
215        /* enable auto-switching between PCI and EBU */
216        writel(0xa, PCI_CR_CLK_CTRL);
217        /* busy, i.e. configuration is not done, PCI access has to be retried */
218        writel(readl(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
219        wmb ();
220        /* BUS Master/IO/MEM access */
221        writel(readl(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
222
223        temp_buffer = readl(PCI_CR_PC_ARB);
224        /* enable external 2 PCI masters */
225        temp_buffer &= (~(0xf << 16));
226        /* enable internal arbiter */
227        temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
228        /* enable internal PCI master reqest */
229        temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
230
231        /* enable EBU reqest */
232        temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
233
234        /* enable all external masters request */
235        temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
236        writel(temp_buffer, PCI_CR_PC_ARB);
237
238        wmb ();
239
240        /* FPI ==> PCI MEM address mapping */
241        /* base: 0xb8000000 == > 0x18000000 */
242        /* size: 8x4M = 32M */
243        writel(0x18000000, PCI_CR_FCI_ADDR_MAP0);
244        writel(0x18400000, PCI_CR_FCI_ADDR_MAP1);
245        writel(0x18800000, PCI_CR_FCI_ADDR_MAP2);
246        writel(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
247        writel(0x19000000, PCI_CR_FCI_ADDR_MAP4);
248        writel(0x19400000, PCI_CR_FCI_ADDR_MAP5);
249        writel(0x19800000, PCI_CR_FCI_ADDR_MAP6);
250        writel(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
251
252        /* FPI ==> PCI IO address mapping */
253        /* base: 0xbAE00000 == > 0xbAE00000 */
254        /* size: 2M */
255        writel(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
256
257        /* PCI ==> FPI address mapping */
258        /* base: 0x0 ==> 0x0 */
259        /* size: 32M */
260        /* BAR1 32M map to SDR address */
261        writel(0x0e000008, PCI_CR_BAR11MASK);
262        writel(0, PCI_CR_PCI_ADDR_MAP11);
263        writel(0, PCI_CS_BASE_ADDR1);
264#ifdef CONFIG_IFXMIPS_PCI_HW_SWAP
265        /* both TX and RX endian swap are enabled */
266        writel(readl(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
267        wmb ();
268#endif
269        /*TODO: disable BAR2 & BAR3 - why was this in the origianl infineon code */
270        writel(readl(PCI_CR_BAR12MASK) | 0x80000000, PCI_CR_BAR12MASK);
271        writel(readl(PCI_CR_BAR13MASK) | 0x80000000, PCI_CR_BAR13MASK);
272        /*use 8 dw burse length */
273        writel(0x303, PCI_CR_FCI_BURST_LENGTH);
274
275        writel(readl(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
276        wmb();
277        writel(readl(IFXMIPS_GPIO_P1_OUT) & ~(1 << 5), IFXMIPS_GPIO_P1_OUT);
278        wmb();
279        mdelay (1);
280        writel(readl(IFXMIPS_GPIO_P1_OUT) | (1 << 5), IFXMIPS_GPIO_P1_OUT);
281}
282
283int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin){
284        switch (slot) {
285                case 13:
286                        /* IDSEL = AD29 --> USB Host Controller */
287                        return (INT_NUM_IM1_IRL0 + 17);
288                case 14:
289                        /* IDSEL = AD30 --> mini PCI connector */
290                        //return (INT_NUM_IM1_IRL0 + 14);
291                        return (INT_NUM_IM0_IRL0 + 22);
292                default:
293                        printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin);
294                        return 0;
295        }
296}
297
298int pcibios_init(void){
299        extern int pci_probe_only;
300
301        pci_probe_only = 0;
302        printk ("PCI: Probing PCI hardware on host bus 0.\n");
303
304        ifxmips_pci_startup ();
305
306        //      IFXMIPS_PCI_REG32(PCI_CR_CLK_CTRL_REG) &= (~8);
307        ifxmips_pci_mapped_cfg = ioremap_nocache(0x17000000, 0x800 * 16);
308        printk("IFXMips PCI mapped to 0x%08X\n", (unsigned long)ifxmips_pci_mapped_cfg);
309
310        ifxmips_pci_controller.io_map_base = (unsigned long)ioremap(IFXMIPS_PCI_IO_BASE, IFXMIPS_PCI_IO_SIZE - 1);
311
312        printk("IFXMips PCI I/O mapped to 0x%08X\n", (unsigned long)ifxmips_pci_controller.io_map_base);
313
314        register_pci_controller(&ifxmips_pci_controller);
315
316        return 0;
317}
318
319arch_initcall(pcibios_init);
Note: See TracBrowser for help on using the repository browser.