[PATCH] ppc32 CPM_UART: various fixes for pq2 uart users
[linux-2.6/x86.git] / arch / ppc / platforms / mpc8272ads_setup.c
blobabb7154de2c7fcba30125b5b1971da761a2a59df
1 /*
2 * arch/ppc/platforms/82xx/pq2ads_pd.c
4 * MPC82xx Board-specific PlatformDevice descriptions
6 * 2005 (c) MontaVista Software, Inc.
7 * Vitaly Bordug <vbordug@ru.mvista.com>
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/device.h>
18 #include <linux/ioport.h>
19 #include <linux/fs_enet_pd.h>
20 #include <linux/platform_device.h>
22 #include <asm/io.h>
23 #include <asm/mpc8260.h>
24 #include <asm/cpm2.h>
25 #include <asm/immap_cpm2.h>
26 #include <asm/irq.h>
27 #include <asm/ppc_sys.h>
28 #include <asm/ppcboot.h>
29 #include <linux/fs_uart_pd.h>
31 #include "pq2ads_pd.h"
33 static void init_fcc1_ioports(void);
34 static void init_fcc2_ioports(void);
35 static void init_scc1_uart_ioports(void);
36 static void init_scc4_uart_ioports(void);
38 static struct fs_uart_platform_info mpc8272_uart_pdata[] = {
39 [fsid_scc1_uart] = {
40 .init_ioports = init_scc1_uart_ioports,
41 .fs_no = fsid_scc1_uart,
42 .brg = 1,
43 .tx_num_fifo = 4,
44 .tx_buf_size = 32,
45 .rx_num_fifo = 4,
46 .rx_buf_size = 32,
48 [fsid_scc4_uart] = {
49 .init_ioports = init_scc4_uart_ioports,
50 .fs_no = fsid_scc4_uart,
51 .brg = 4,
52 .tx_num_fifo = 4,
53 .tx_buf_size = 32,
54 .rx_num_fifo = 4,
55 .rx_buf_size = 32,
59 static struct fs_mii_bus_info mii_bus_info = {
60 .method = fsmii_bitbang,
61 .id = 0,
62 .i.bitbang = {
63 .mdio_port = fsiop_portc,
64 .mdio_bit = 18,
65 .mdc_port = fsiop_portc,
66 .mdc_bit = 19,
67 .delay = 1,
71 static struct fs_platform_info mpc82xx_fcc1_pdata = {
72 .fs_no = fsid_fcc1,
73 .cp_page = CPM_CR_FCC1_PAGE,
74 .cp_block = CPM_CR_FCC1_SBLOCK,
75 .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
76 .clk_route = CMX1_CLK_ROUTE,
77 .clk_mask = CMX1_CLK_MASK,
78 .init_ioports = init_fcc1_ioports,
80 .phy_addr = 0,
81 #ifdef PHY_INTERRUPT
82 .phy_irq = PHY_INTERRUPT,
83 #else
84 .phy_irq = -1;
85 #endif
86 .mem_offset = FCC1_MEM_OFFSET,
87 .bus_info = &mii_bus_info,
88 .rx_ring = 32,
89 .tx_ring = 32,
90 .rx_copybreak = 240,
91 .use_napi = 0,
92 .napi_weight = 17,
95 static struct fs_platform_info mpc82xx_fcc2_pdata = {
96 .fs_no = fsid_fcc2,
97 .cp_page = CPM_CR_FCC2_PAGE,
98 .cp_block = CPM_CR_FCC2_SBLOCK,
99 .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
100 .clk_route = CMX2_CLK_ROUTE,
101 .clk_mask = CMX2_CLK_MASK,
102 .init_ioports = init_fcc2_ioports,
104 .phy_addr = 3,
105 #ifdef PHY_INTERRUPT
106 .phy_irq = PHY_INTERRUPT,
107 #else
108 .phy_irq = -1;
109 #endif
110 .mem_offset = FCC2_MEM_OFFSET,
111 .bus_info = &mii_bus_info,
112 .rx_ring = 32,
113 .tx_ring = 32,
114 .rx_copybreak = 240,
115 .use_napi = 0,
116 .napi_weight = 17,
119 static void init_fcc1_ioports(void)
121 struct io_port *io;
122 u32 tempval;
123 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
124 u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32));
126 io = &immap->im_ioport;
128 /* Enable the PHY */
129 clrbits32(bcsr, BCSR1_FETHIEN);
130 setbits32(bcsr, BCSR1_FETH_RST);
132 /* FCC1 pins are on port A/C. */
133 /* Configure port A and C pins for FCC1 Ethernet. */
135 tempval = in_be32(&io->iop_pdira);
136 tempval &= ~PA1_DIRA0;
137 tempval |= PA1_DIRA1;
138 out_be32(&io->iop_pdira, tempval);
140 tempval = in_be32(&io->iop_psora);
141 tempval &= ~PA1_PSORA0;
142 tempval |= PA1_PSORA1;
143 out_be32(&io->iop_psora, tempval);
145 setbits32(&io->iop_ppara,PA1_DIRA0 | PA1_DIRA1);
147 /* Alter clocks */
148 tempval = PC_F1TXCLK|PC_F1RXCLK;
150 clrbits32(&io->iop_psorc, tempval);
151 clrbits32(&io->iop_pdirc, tempval);
152 setbits32(&io->iop_pparc, tempval);
154 clrbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_MASK);
155 setbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_ROUTE);
156 iounmap(bcsr);
157 iounmap(immap);
160 static void init_fcc2_ioports(void)
162 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
163 u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
165 struct io_port *io;
166 u32 tempval;
168 immap = cpm2_immr;
170 io = &immap->im_ioport;
172 /* Enable the PHY */
173 clrbits32(bcsr, BCSR3_FETHIEN2);
174 setbits32(bcsr, BCSR3_FETH2_RST);
176 /* FCC2 are port B/C. */
177 /* Configure port A and C pins for FCC2 Ethernet. */
179 tempval = in_be32(&io->iop_pdirb);
180 tempval &= ~PB2_DIRB0;
181 tempval |= PB2_DIRB1;
182 out_be32(&io->iop_pdirb, tempval);
184 tempval = in_be32(&io->iop_psorb);
185 tempval &= ~PB2_PSORB0;
186 tempval |= PB2_PSORB1;
187 out_be32(&io->iop_psorb, tempval);
189 setbits32(&io->iop_pparb,PB2_DIRB0 | PB2_DIRB1);
191 tempval = PC_F2RXCLK|PC_F2TXCLK;
193 /* Alter clocks */
194 clrbits32(&io->iop_psorc,tempval);
195 clrbits32(&io->iop_pdirc,tempval);
196 setbits32(&io->iop_pparc,tempval);
198 clrbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_MASK);
199 setbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_ROUTE);
201 iounmap(bcsr);
202 iounmap(immap);
206 static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev,
207 int idx)
209 bd_t* bi = (void*)__res;
210 int fs_no = fsid_fcc1+pdev->id-1;
212 mpc82xx_fcc1_pdata.dpram_offset = mpc82xx_fcc2_pdata.dpram_offset = (u32)cpm2_immr->im_dprambase;
213 mpc82xx_fcc1_pdata.fcc_regs_c = mpc82xx_fcc2_pdata.fcc_regs_c = (u32)cpm2_immr->im_fcc_c;
215 switch(fs_no) {
216 case fsid_fcc1:
217 memcpy(&mpc82xx_fcc1_pdata.macaddr,bi->bi_enetaddr,6);
218 pdev->dev.platform_data = &mpc82xx_fcc1_pdata;
219 break;
220 case fsid_fcc2:
221 memcpy(&mpc82xx_fcc2_pdata.macaddr,bi->bi_enetaddr,6);
222 mpc82xx_fcc2_pdata.macaddr[5] ^= 1;
223 pdev->dev.platform_data = &mpc82xx_fcc2_pdata;
224 break;
228 static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
229 int idx)
231 bd_t *bd = (bd_t *) __res;
232 struct fs_uart_platform_info *pinfo;
233 int num = ARRAY_SIZE(mpc8272_uart_pdata);
234 int id = fs_uart_id_scc2fsid(idx);
236 /* no need to alter anything if console */
237 if ((id <= num) && (!pdev->dev.platform_data)) {
238 pinfo = &mpc8272_uart_pdata[id];
239 pinfo->uart_clk = bd->bi_intfreq;
240 pdev->dev.platform_data = pinfo;
244 static void init_scc1_uart_ioports(void)
246 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
248 /* SCC1 is only on port D */
249 setbits32(&immap->im_ioport.iop_ppard,0x00000003);
250 clrbits32(&immap->im_ioport.iop_psord,0x00000001);
251 setbits32(&immap->im_ioport.iop_psord,0x00000002);
252 clrbits32(&immap->im_ioport.iop_pdird,0x00000001);
253 setbits32(&immap->im_ioport.iop_pdird,0x00000002);
255 /* Wire BRG1 to SCC1 */
256 clrbits32(&immap->im_cpmux.cmx_scr,0x00ffffff);
258 iounmap(immap);
261 static void init_scc4_uart_ioports(void)
263 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
265 setbits32(&immap->im_ioport.iop_ppard,0x00000600);
266 clrbits32(&immap->im_ioport.iop_psord,0x00000600);
267 clrbits32(&immap->im_ioport.iop_pdird,0x00000200);
268 setbits32(&immap->im_ioport.iop_pdird,0x00000400);
270 /* Wire BRG4 to SCC4 */
271 clrbits32(&immap->im_cpmux.cmx_scr,0x000000ff);
272 setbits32(&immap->im_cpmux.cmx_scr,0x0000001b);
274 iounmap(immap);
277 static int mpc8272ads_platform_notify(struct device *dev)
279 static const struct platform_notify_dev_map dev_map[] = {
281 .bus_id = "fsl-cpm-fcc",
282 .rtn = mpc8272ads_fixup_enet_pdata,
285 .bus_id = "fsl-cpm-scc:uart",
286 .rtn = mpc8272ads_fixup_uart_pdata,
289 .bus_id = NULL
292 platform_notify_map(dev_map,dev);
294 return 0;
298 int __init mpc8272ads_init(void)
300 printk(KERN_NOTICE "mpc8272ads: Init\n");
302 platform_notify = mpc8272ads_platform_notify;
304 ppc_sys_device_initfunc();
306 ppc_sys_device_disable_all();
307 ppc_sys_device_enable(MPC82xx_CPM_FCC1);
308 ppc_sys_device_enable(MPC82xx_CPM_FCC2);
310 /* to be ready for console, let's attach pdata here */
311 #ifdef CONFIG_SERIAL_CPM_SCC1
312 ppc_sys_device_setfunc(MPC82xx_CPM_SCC1, PPC_SYS_FUNC_UART);
313 ppc_sys_device_enable(MPC82xx_CPM_SCC1);
315 #endif
317 #ifdef CONFIG_SERIAL_CPM_SCC4
318 ppc_sys_device_setfunc(MPC82xx_CPM_SCC4, PPC_SYS_FUNC_UART);
319 ppc_sys_device_enable(MPC82xx_CPM_SCC4);
320 #endif
323 return 0;
327 To prevent confusion, console selection is gross:
328 by 0 assumed SCC1 and by 1 assumed SCC4
330 struct platform_device* early_uart_get_pdev(int index)
332 bd_t *bd = (bd_t *) __res;
333 struct fs_uart_platform_info *pinfo;
335 struct platform_device* pdev = NULL;
336 if(index) { /*assume SCC4 here*/
337 pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC4];
338 pinfo = &mpc8272_uart_pdata[fsid_scc4_uart];
339 } else { /*over SCC1*/
340 pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC1];
341 pinfo = &mpc8272_uart_pdata[fsid_scc1_uart];
344 pinfo->uart_clk = bd->bi_intfreq;
345 pdev->dev.platform_data = pinfo;
346 ppc_sys_fixup_mem_resource(pdev, CPM_MAP_ADDR);
347 return NULL;
350 arch_initcall(mpc8272ads_init);