diff options
Diffstat (limited to 'arch/ppc/syslib/mpc10x_common.c')
-rw-r--r-- | arch/ppc/syslib/mpc10x_common.c | 203 |
1 files changed, 158 insertions, 45 deletions
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c index fd93adfd464c..8fc5f4154521 100644 --- a/arch/ppc/syslib/mpc10x_common.c +++ b/arch/ppc/syslib/mpc10x_common.c | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/serial_8250.h> | ||
25 | #include <linux/fsl_devices.h> | ||
26 | #include <linux/device.h> | ||
24 | 27 | ||
25 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
26 | #include <asm/io.h> | 29 | #include <asm/io.h> |
@@ -30,16 +33,7 @@ | |||
30 | #include <asm/pci-bridge.h> | 33 | #include <asm/pci-bridge.h> |
31 | #include <asm/open_pic.h> | 34 | #include <asm/open_pic.h> |
32 | #include <asm/mpc10x.h> | 35 | #include <asm/mpc10x.h> |
33 | #include <asm/ocp.h> | 36 | #include <asm/ppc_sys.h> |
34 | |||
35 | /* The OCP structure is fixed by code below, before OCP initialises. | ||
36 | paddr depends on where the board places the EUMB. | ||
37 | - fixed in mpc10x_bridge_init(). | ||
38 | irq depends on two things: | ||
39 | > does the board use the EPIC at all? (PCORE does not). | ||
40 | > is the EPIC in serial or parallel mode? | ||
41 | - fixed in mpc10x_set_openpic(). | ||
42 | */ | ||
43 | 37 | ||
44 | #ifdef CONFIG_MPC10X_OPENPIC | 38 | #ifdef CONFIG_MPC10X_OPENPIC |
45 | #ifdef CONFIG_EPIC_SERIAL_MODE | 39 | #ifdef CONFIG_EPIC_SERIAL_MODE |
@@ -50,35 +44,140 @@ | |||
50 | #define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS) | 44 | #define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS) |
51 | #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS) | 45 | #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS) |
52 | #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS) | 46 | #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS) |
47 | #define MPC10X_UART0_IRQ (EPIC_IRQ_BASE + 4 + NUM_8259_INTERRUPTS) | ||
53 | #else | 48 | #else |
54 | #define MPC10X_I2C_IRQ OCP_IRQ_NA | 49 | #define MPC10X_I2C_IRQ -1 |
55 | #define MPC10X_DMA0_IRQ OCP_IRQ_NA | 50 | #define MPC10X_DMA0_IRQ -1 |
56 | #define MPC10X_DMA1_IRQ OCP_IRQ_NA | 51 | #define MPC10X_DMA1_IRQ -1 |
52 | #define MPC10X_UART0_IRQ -1 | ||
57 | #endif | 53 | #endif |
58 | 54 | ||
59 | 55 | static struct fsl_i2c_platform_data mpc10x_i2c_pdata = { | |
60 | struct ocp_def core_ocp[] = { | 56 | .device_flags = 0, |
61 | { .vendor = OCP_VENDOR_INVALID | ||
62 | } | ||
63 | }; | 57 | }; |
64 | 58 | ||
65 | static struct ocp_fs_i2c_data mpc10x_i2c_data = { | 59 | static struct plat_serial8250_port serial_platform_data[] = { |
66 | .flags = 0 | 60 | [0] = { |
61 | .mapbase = 0x4500, | ||
62 | .iotype = UPIO_MEM, | ||
63 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
64 | }, | ||
65 | [1] = { | ||
66 | .mapbase = 0x4600, | ||
67 | .iotype = UPIO_MEM, | ||
68 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
69 | }, | ||
70 | { }, | ||
67 | }; | 71 | }; |
68 | static struct ocp_def mpc10x_i2c_ocp = { | 72 | |
69 | .vendor = OCP_VENDOR_MOTOROLA, | 73 | struct platform_device ppc_sys_platform_devices[] = { |
70 | .function = OCP_FUNC_IIC, | 74 | [MPC10X_IIC1] = { |
71 | .index = 0, | 75 | .name = "fsl-i2c", |
72 | .additions = &mpc10x_i2c_data | 76 | .id = 1, |
77 | .dev.platform_data = &mpc10x_i2c_pdata, | ||
78 | .num_resources = 2, | ||
79 | .resource = (struct resource[]) { | ||
80 | { | ||
81 | .start = MPC10X_EUMB_I2C_OFFSET, | ||
82 | .end = MPC10X_EUMB_I2C_OFFSET + | ||
83 | MPC10X_EUMB_I2C_SIZE - 1, | ||
84 | .flags = IORESOURCE_MEM, | ||
85 | }, | ||
86 | { | ||
87 | .flags = IORESOURCE_IRQ | ||
88 | }, | ||
89 | }, | ||
90 | }, | ||
91 | [MPC10X_DMA0] = { | ||
92 | .name = "fsl-dma", | ||
93 | .id = 0, | ||
94 | .num_resources = 2, | ||
95 | .resource = (struct resource[]) { | ||
96 | { | ||
97 | .start = MPC10X_EUMB_DMA_OFFSET + 0x10, | ||
98 | .end = MPC10X_EUMB_DMA_OFFSET + 0x1f, | ||
99 | .flags = IORESOURCE_MEM, | ||
100 | }, | ||
101 | { | ||
102 | .flags = IORESOURCE_IRQ, | ||
103 | }, | ||
104 | }, | ||
105 | }, | ||
106 | [MPC10X_DMA1] = { | ||
107 | .name = "fsl-dma", | ||
108 | .id = 1, | ||
109 | .num_resources = 2, | ||
110 | .resource = (struct resource[]) { | ||
111 | { | ||
112 | .start = MPC10X_EUMB_DMA_OFFSET + 0x20, | ||
113 | .end = MPC10X_EUMB_DMA_OFFSET + 0x2f, | ||
114 | .flags = IORESOURCE_MEM, | ||
115 | }, | ||
116 | { | ||
117 | .flags = IORESOURCE_IRQ, | ||
118 | }, | ||
119 | }, | ||
120 | }, | ||
121 | [MPC10X_DMA1] = { | ||
122 | .name = "fsl-dma", | ||
123 | .id = 1, | ||
124 | .num_resources = 2, | ||
125 | .resource = (struct resource[]) { | ||
126 | { | ||
127 | .start = MPC10X_EUMB_DMA_OFFSET + 0x20, | ||
128 | .end = MPC10X_EUMB_DMA_OFFSET + 0x2f, | ||
129 | .flags = IORESOURCE_MEM, | ||
130 | }, | ||
131 | { | ||
132 | .flags = IORESOURCE_IRQ, | ||
133 | }, | ||
134 | }, | ||
135 | }, | ||
136 | [MPC10X_DUART] = { | ||
137 | .name = "serial8250", | ||
138 | .id = 0, | ||
139 | .dev.platform_data = serial_platform_data, | ||
140 | }, | ||
73 | }; | 141 | }; |
74 | 142 | ||
75 | static struct ocp_def mpc10x_dma_ocp[2] = { | 143 | /* We use the PCI ID to match on */ |
76 | { .vendor = OCP_VENDOR_MOTOROLA, | 144 | struct ppc_sys_spec *cur_ppc_sys_spec; |
77 | .function = OCP_FUNC_DMA, | 145 | struct ppc_sys_spec ppc_sys_specs[] = { |
78 | .index = 0 }, | 146 | { |
79 | { .vendor = OCP_VENDOR_MOTOROLA, | 147 | .ppc_sys_name = "8245", |
80 | .function = OCP_FUNC_DMA, | 148 | .mask = 0xFFFFFFFF, |
81 | .index = 1 } | 149 | .value = MPC10X_BRIDGE_8245, |
150 | .num_devices = 4, | ||
151 | .device_list = (enum ppc_sys_devices[]) | ||
152 | { | ||
153 | MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, MPC10X_DUART, | ||
154 | }, | ||
155 | }, | ||
156 | { | ||
157 | .ppc_sys_name = "8240", | ||
158 | .mask = 0xFFFFFFFF, | ||
159 | .value = MPC10X_BRIDGE_8240, | ||
160 | .num_devices = 3, | ||
161 | .device_list = (enum ppc_sys_devices[]) | ||
162 | { | ||
163 | MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, | ||
164 | }, | ||
165 | }, | ||
166 | { | ||
167 | .ppc_sys_name = "107", | ||
168 | .mask = 0xFFFFFFFF, | ||
169 | .value = MPC10X_BRIDGE_107, | ||
170 | .num_devices = 3, | ||
171 | .device_list = (enum ppc_sys_devices[]) | ||
172 | { | ||
173 | MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, | ||
174 | }, | ||
175 | }, | ||
176 | { /* default match */ | ||
177 | .ppc_sys_name = "", | ||
178 | .mask = 0x00000000, | ||
179 | .value = 0x00000000, | ||
180 | }, | ||
82 | }; | 181 | }; |
83 | 182 | ||
84 | /* Set resources to match bridge memory map */ | 183 | /* Set resources to match bridge memory map */ |
@@ -132,7 +231,7 @@ mpc10x_bridge_init(struct pci_controller *hose, | |||
132 | uint new_map, | 231 | uint new_map, |
133 | uint phys_eumb_base) | 232 | uint phys_eumb_base) |
134 | { | 233 | { |
135 | int host_bridge, picr1, picr1_bit; | 234 | int host_bridge, picr1, picr1_bit, i; |
136 | ulong pci_config_addr, pci_config_data; | 235 | ulong pci_config_addr, pci_config_data; |
137 | u_char pir, byte; | 236 | u_char pir, byte; |
138 | 237 | ||
@@ -273,7 +372,7 @@ mpc10x_bridge_init(struct pci_controller *hose, | |||
273 | printk("Host bridge in Agent mode\n"); | 372 | printk("Host bridge in Agent mode\n"); |
274 | /* Read or Set LMBAR & PCSRBAR? */ | 373 | /* Read or Set LMBAR & PCSRBAR? */ |
275 | } | 374 | } |
276 | 375 | ||
277 | /* Set base addr of the 8240/107 EUMB. */ | 376 | /* Set base addr of the 8240/107 EUMB. */ |
278 | early_write_config_dword(hose, | 377 | early_write_config_dword(hose, |
279 | 0, | 378 | 0, |
@@ -287,17 +386,6 @@ mpc10x_bridge_init(struct pci_controller *hose, | |||
287 | ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, | 386 | ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, |
288 | MPC10X_EUMB_EPIC_SIZE); | 387 | MPC10X_EUMB_EPIC_SIZE); |
289 | #endif | 388 | #endif |
290 | mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET; | ||
291 | mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ; | ||
292 | ocp_add_one_device(&mpc10x_i2c_ocp); | ||
293 | mpc10x_dma_ocp[0].paddr = phys_eumb_base + | ||
294 | MPC10X_EUMB_DMA_OFFSET + 0x100; | ||
295 | mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ; | ||
296 | ocp_add_one_device(&mpc10x_dma_ocp[0]); | ||
297 | mpc10x_dma_ocp[1].paddr = phys_eumb_base + | ||
298 | MPC10X_EUMB_DMA_OFFSET + 0x200; | ||
299 | mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ; | ||
300 | ocp_add_one_device(&mpc10x_dma_ocp[1]); | ||
301 | } | 389 | } |
302 | 390 | ||
303 | #ifdef CONFIG_MPC10X_STORE_GATHERING | 391 | #ifdef CONFIG_MPC10X_STORE_GATHERING |
@@ -306,6 +394,29 @@ mpc10x_bridge_init(struct pci_controller *hose, | |||
306 | mpc10x_disable_store_gathering(hose); | 394 | mpc10x_disable_store_gathering(hose); |
307 | #endif | 395 | #endif |
308 | 396 | ||
397 | /* setup platform devices for MPC10x bridges */ | ||
398 | identify_ppc_sys_by_id (host_bridge); | ||
399 | |||
400 | for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) { | ||
401 | unsigned int dev_id = cur_ppc_sys_spec->device_list[i]; | ||
402 | ppc_sys_fixup_mem_resource(&ppc_sys_platform_devices[dev_id], | ||
403 | phys_eumb_base); | ||
404 | } | ||
405 | |||
406 | /* IRQ's are determined at runtime */ | ||
407 | ppc_sys_platform_devices[MPC10X_IIC1].resource[1].start = MPC10X_I2C_IRQ; | ||
408 | ppc_sys_platform_devices[MPC10X_IIC1].resource[1].end = MPC10X_I2C_IRQ; | ||
409 | ppc_sys_platform_devices[MPC10X_DMA0].resource[1].start = MPC10X_DMA0_IRQ; | ||
410 | ppc_sys_platform_devices[MPC10X_DMA0].resource[1].end = MPC10X_DMA0_IRQ; | ||
411 | ppc_sys_platform_devices[MPC10X_DMA1].resource[1].start = MPC10X_DMA1_IRQ; | ||
412 | ppc_sys_platform_devices[MPC10X_DMA1].resource[1].end = MPC10X_DMA1_IRQ; | ||
413 | |||
414 | serial_platform_data[0].mapbase += phys_eumb_base; | ||
415 | serial_platform_data[0].irq = MPC10X_UART0_IRQ; | ||
416 | |||
417 | serial_platform_data[1].mapbase += phys_eumb_base; | ||
418 | serial_platform_data[1].irq = MPC10X_UART0_IRQ + 1; | ||
419 | |||
309 | /* | 420 | /* |
310 | * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative | 421 | * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative |
311 | * PCI reads may return stale data so turn off. | 422 | * PCI reads may return stale data so turn off. |
@@ -330,7 +441,7 @@ mpc10x_bridge_init(struct pci_controller *hose, | |||
330 | * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd. | 441 | * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd. |
331 | */ | 442 | */ |
332 | if (host_bridge == MPC10X_BRIDGE_8245) { | 443 | if (host_bridge == MPC10X_BRIDGE_8245) { |
333 | ulong picr2; | 444 | u32 picr2; |
334 | 445 | ||
335 | early_read_config_dword(hose, 0, PCI_DEVFN(0,0), | 446 | early_read_config_dword(hose, 0, PCI_DEVFN(0,0), |
336 | MPC10X_CFG_PICR2_REG, &picr2); | 447 | MPC10X_CFG_PICR2_REG, &picr2); |
@@ -504,6 +615,8 @@ void __init mpc10x_set_openpic(void) | |||
504 | openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020); | 615 | openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020); |
505 | /* Skip reserved space and map Message Unit Interrupt (I2O) */ | 616 | /* Skip reserved space and map Message Unit Interrupt (I2O) */ |
506 | openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0); | 617 | openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0); |
618 | /* Skip reserved space and map Serial Interupts */ | ||
619 | openpic_set_sources(EPIC_IRQ_BASE + 4, 2, OpenPIC_Addr + 0x11120); | ||
507 | 620 | ||
508 | openpic_init(NUM_8259_INTERRUPTS); | 621 | openpic_init(NUM_8259_INTERRUPTS); |
509 | } | 622 | } |