e50cb3bdc9453784d95f1d9711ec87638c3b5dc6
[openwrt-10.03/.git] / target / linux / ifxmips / files / arch / mips / pci / pci-ifxmips.c
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/addrspace.h>
8 #include <linux/vmalloc.h>
9 #include <ifxmips.h>
10 #include <ifxmips_irq.h>
11 #include <ifxmips_cgu.h>
12
13 #define IFXMIPS_PCI_MEM_BASE    0x18000000
14 #define IFXMIPS_PCI_MEM_SIZE    0x02000000
15 #define IFXMIPS_PCI_IO_BASE     0x1AE00000
16 #define IFXMIPS_PCI_IO_SIZE     0x00200000
17
18 extern int ifxmips_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
19 extern int ifxmips_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
20
21 struct pci_ops ifxmips_pci_ops =
22 {
23         .read = ifxmips_pci_read_config_dword,
24         .write = ifxmips_pci_write_config_dword
25 };
26
27 static struct resource pci_io_resource =
28 {
29         .name = "io pci IO space",
30         .start = IFXMIPS_PCI_IO_BASE,
31         .end = IFXMIPS_PCI_IO_BASE + IFXMIPS_PCI_IO_SIZE - 1,
32         .flags = IORESOURCE_IO
33 };
34
35 static struct resource pci_mem_resource =
36 {
37         .name = "ext pci memory space",
38         .start = IFXMIPS_PCI_MEM_BASE,
39         .end = IFXMIPS_PCI_MEM_BASE + IFXMIPS_PCI_MEM_SIZE - 1,
40         .flags = IORESOURCE_MEM
41 };
42
43 static struct pci_controller ifxmips_pci_controller =
44 {
45         .pci_ops = &ifxmips_pci_ops,
46         .mem_resource = &pci_mem_resource,
47         .mem_offset     = 0x00000000UL,
48         .io_resource = &pci_io_resource,
49         .io_offset      = 0x00000000UL,
50 };
51
52 /* the cpu can can generate the 33Mhz or rely on an external clock the cgu needs the
53    proper setting, otherwise the cpu hangs. we have no way of runtime detecting this */
54 u32 ifxmips_pci_mapped_cfg;
55 int ifxmips_pci_external_clock = 0;
56
57 static int __init
58 ifxmips_pci_set_external_clk(char *str)
59 {
60         printk("cgu: setting up external pci clock\n");
61         ifxmips_pci_external_clock = 1;
62         return 1;
63 }
64 __setup("pci_external_clk", ifxmips_pci_set_external_clk);
65
66 int
67 pcibios_plat_dev_init(struct pci_dev *dev)
68 {
69         u8 pin;
70
71         pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
72         switch(pin)
73         {
74                 case 0:
75                         break;
76                 case 1:
77                         //falling edge level triggered:0x4, low level:0xc, rising edge:0x2
78                         ifxmips_w32(ifxmips_r32(IFXMIPS_EBU_PCC_CON) | 0xc, IFXMIPS_EBU_PCC_CON);
79                         ifxmips_w32(ifxmips_r32(IFXMIPS_EBU_PCC_IEN) | 0x10, IFXMIPS_EBU_PCC_IEN);
80                         break;
81                 case 2:
82                 case 3:
83                 case 4:
84                         printk ("WARNING: interrupt pin %d not supported yet!\n", pin);
85                 default:
86                         printk ("WARNING: invalid interrupt pin %d\n", pin);
87                         return 1;
88         }
89         return 0;
90 }
91
92 static void __init
93 ifxmips_pci_startup(void)
94 {
95         u32 temp_buffer;
96
97         cgu_setup_pci_clk(ifxmips_pci_external_clock);
98
99         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OUT) | (1 << 5), IFXMIPS_GPIO_P1_OUT);
100         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OD) | (1 << 5), IFXMIPS_GPIO_P1_OD);
101         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_DIR) | (1 << 5), IFXMIPS_GPIO_P1_DIR);
102         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL1) & ~(1 << 5), IFXMIPS_GPIO_P1_ALTSEL1);
103         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL0) & ~(1 << 5), IFXMIPS_GPIO_P1_ALTSEL0);
104         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_DIR) & ~0x2000, IFXMIPS_GPIO_P1_DIR);
105         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_DIR) | 0x4000, IFXMIPS_GPIO_P1_DIR);
106         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL1) & ~0x6000, IFXMIPS_GPIO_P1_ALTSEL1);
107         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL0) | 0x6000, IFXMIPS_GPIO_P1_ALTSEL0);
108         /* enable auto-switching between PCI and EBU */
109         ifxmips_w32(0xa, PCI_CR_CLK_CTRL);
110         /* busy, i.e. configuration is not done, PCI access has to be retried */
111         ifxmips_w32(ifxmips_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
112         wmb ();
113         /* BUS Master/IO/MEM access */
114         ifxmips_w32(ifxmips_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
115
116         /* enable external 2 PCI masters */
117         temp_buffer = ifxmips_r32(PCI_CR_PC_ARB);
118         temp_buffer &= (~(0xf << 16));
119         /* enable internal arbiter */
120         temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
121         /* enable internal PCI master reqest */
122         temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
123
124         /* enable EBU reqest */
125         temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
126
127         /* enable all external masters request */
128         temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
129         ifxmips_w32(temp_buffer, PCI_CR_PC_ARB);
130         wmb ();
131
132         ifxmips_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
133         ifxmips_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
134         ifxmips_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
135         ifxmips_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
136         ifxmips_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
137         ifxmips_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
138         ifxmips_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
139         ifxmips_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
140         ifxmips_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
141         ifxmips_w32(0x0e000008, PCI_CR_BAR11MASK);
142         ifxmips_w32(0, PCI_CR_PCI_ADDR_MAP11);
143         ifxmips_w32(0, PCI_CS_BASE_ADDR1);
144 #ifdef CONFIG_SWAP_IO_SPACE
145         /* both TX and RX endian swap are enabled */
146         ifxmips_w32(ifxmips_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
147         wmb ();
148 #endif
149         /*TODO: disable BAR2 & BAR3 - why was this in the origianl infineon code */
150         ifxmips_w32(ifxmips_r32(PCI_CR_BAR12MASK) | 0x80000000, PCI_CR_BAR12MASK);
151         ifxmips_w32(ifxmips_r32(PCI_CR_BAR13MASK) | 0x80000000, PCI_CR_BAR13MASK);
152         /*use 8 dw burst length */
153         ifxmips_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
154         ifxmips_w32(ifxmips_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
155         wmb();
156         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OUT) & ~(1 << 5), IFXMIPS_GPIO_P1_OUT);
157         wmb();
158         mdelay(1);
159         ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OUT) | (1 << 5), IFXMIPS_GPIO_P1_OUT);
160 }
161
162 int __init
163 pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin){
164         switch(slot)
165         {
166                 case 13:
167                         /* IDSEL = AD29 --> USB Host Controller */
168                         return (INT_NUM_IM1_IRL0 + 17);
169                 case 14:
170                         /* IDSEL = AD30 --> mini PCI connector */
171                         return (INT_NUM_IM0_IRL0 + 22);
172                 default:
173                         printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin);
174                         return 0;
175         }
176 }
177
178 int __init
179 pcibios_init(void)
180 {
181         extern int pci_probe_only;
182
183         pci_probe_only = 0;
184         printk("PCI: Probing PCI hardware on host bus 0.\n");
185         ifxmips_pci_startup ();
186         ifxmips_pci_mapped_cfg = (u32)ioremap_nocache(0x17000000, 0x800 * 16);
187         printk("IFXMips PCI mapped to 0x%08lX\n", (unsigned long)ifxmips_pci_mapped_cfg);
188         ifxmips_pci_controller.io_map_base = (unsigned long)ioremap(IFXMIPS_PCI_IO_BASE, IFXMIPS_PCI_IO_SIZE - 1);
189         printk("IFXMips PCI I/O mapped to 0x%08lX\n", (unsigned long)ifxmips_pci_controller.io_map_base);
190         register_pci_controller(&ifxmips_pci_controller);
191         return 0;
192 }
193
194 arch_initcall(pcibios_init);