[PATCH] ppc32: Update board-specific code of the CPM UART users
[linux-2.6/libata-dev.git] / arch / ppc / platforms / mpc866ads_setup.c
blob6ce3b842defee25ffb7fb23f7ac8fd704719777a
1 /*arch/ppc/platforms/mpc885ads-setup.c
3 * Platform setup for the Freescale mpc885ads board
5 * Vitaly Bordug <vbordug@ru.mvista.com>
7 * Copyright 2005 MontaVista Software Inc.
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.
14 #include <linux/config.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/param.h>
18 #include <linux/string.h>
19 #include <linux/ioport.h>
20 #include <linux/device.h>
22 #include <linux/fs_enet_pd.h>
23 #include <linux/fs_uart_pd.h>
24 #include <linux/mii.h>
26 #include <asm/delay.h>
27 #include <asm/io.h>
28 #include <asm/machdep.h>
29 #include <asm/page.h>
30 #include <asm/processor.h>
31 #include <asm/system.h>
32 #include <asm/time.h>
33 #include <asm/ppcboot.h>
34 #include <asm/8xx_immap.h>
35 #include <asm/commproc.h>
36 #include <asm/ppc_sys.h>
37 #include <asm/mpc8xx.h>
39 extern unsigned char __res[];
41 static void setup_fec1_ioports(void);
42 static void setup_scc1_ioports(void);
43 static void setup_smc1_ioports(void);
44 static void setup_smc2_ioports(void);
46 static struct fs_mii_bus_info fec_mii_bus_info = {
47 .method = fsmii_fec,
48 .id = 0,
51 static struct fs_mii_bus_info scc_mii_bus_info = {
52 .method = fsmii_fixed,
53 .id = 0,
54 .i.fixed.speed = 10,
55 .i.fixed.duplex = 0,
58 static struct fs_platform_info mpc8xx_fec_pdata[] = {
60 .rx_ring = 128,
61 .tx_ring = 16,
62 .rx_copybreak = 240,
64 .use_napi = 1,
65 .napi_weight = 17,
67 .phy_addr = 15,
68 .phy_irq = -1,
70 .use_rmii = 0,
72 .bus_info = &fec_mii_bus_info,
76 static struct fs_platform_info mpc8xx_scc_pdata = {
77 .rx_ring = 64,
78 .tx_ring = 8,
79 .rx_copybreak = 240,
81 .use_napi = 1,
82 .napi_weight = 17,
84 .phy_addr = -1,
85 .phy_irq = -1,
87 .bus_info = &scc_mii_bus_info,
91 static struct fs_uart_platform_info mpc866_uart_pdata[] = {
92 [fsid_smc1_uart] = {
93 .brg = 1,
94 .fs_no = fsid_smc1_uart,
95 .init_ioports = setup_smc1_ioports,
96 .tx_num_fifo = 4,
97 .tx_buf_size = 32,
98 .rx_num_fifo = 4,
99 .rx_buf_size = 32,
101 [fsid_smc2_uart] = {
102 .brg = 2,
103 .fs_no = fsid_smc2_uart,
104 .init_ioports = setup_smc2_ioports,
105 .tx_num_fifo = 4,
106 .tx_buf_size = 32,
107 .rx_num_fifo = 4,
108 .rx_buf_size = 32,
112 void __init board_init(void)
114 volatile cpm8xx_t *cp = cpmp;
115 unsigned *bcsr_io;
117 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
119 if (bcsr_io == NULL) {
120 printk(KERN_CRIT "Could not remap BCSR1\n");
121 return;
124 #ifdef CONFIG_SERIAL_CPM_SMC1
125 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
126 clrbits32(bcsr_io,(0x80000000 >> 7));
127 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
128 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
129 #else
130 setbits32(bcsr_io,(0x80000000 >> 7));
132 cp->cp_pbpar &= ~(0x000000c0);
133 cp->cp_pbdir |= 0x000000c0;
134 cp->cp_smc[0].smc_smcmr = 0;
135 cp->cp_smc[0].smc_smce = 0;
136 #endif
138 #ifdef CONFIG_SERIAL_CPM_SMC2
139 cp->cp_simode &= ~(0xe0000000 >> 1);
140 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
141 clrbits32(bcsr_io,(0x80000000 >> 13));
142 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
143 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
144 #else
145 clrbits32(bcsr_io,(0x80000000 >> 13));
146 cp->cp_pbpar &= ~(0x00000c00);
147 cp->cp_pbdir |= 0x00000c00;
148 cp->cp_smc[1].smc_smcmr = 0;
149 cp->cp_smc[1].smc_smce = 0;
150 #endif
151 iounmap(bcsr_io);
154 static void setup_fec1_ioports(void)
156 immap_t *immap = (immap_t *) IMAP_ADDR;
158 setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
159 setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
162 static void setup_scc1_ioports(void)
164 immap_t *immap = (immap_t *) IMAP_ADDR;
165 unsigned *bcsr_io;
167 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
169 if (bcsr_io == NULL) {
170 printk(KERN_CRIT "Could not remap BCSR1\n");
171 return;
174 /* Enable the PHY.
176 clrbits32(bcsr_io,BCSR1_ETHEN);
178 /* Configure port A pins for Txd and Rxd.
180 /* Disable receive and transmit in case EPPC-Bug started it.
182 setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
183 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
184 clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
186 /* Configure port C pins to enable CLSN and RENA.
188 clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
189 clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
190 setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
191 /* Configure port A for TCLK and RCLK.
193 setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
194 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
195 clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
196 clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
198 /* Configure Serial Interface clock routing.
199 * First, clear all SCC bits to zero, then set the ones we want.
201 clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
202 setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
204 /* In the original SCC enet driver the following code is placed at
205 the end of the initialization */
206 setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
207 setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
211 static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
213 struct fs_platform_info *fpi = pdev->dev.platform_data;
215 volatile cpm8xx_t *cp;
216 bd_t *bd = (bd_t *) __res;
217 char *e;
218 int i;
220 /* Get pointer to Communication Processor */
221 cp = cpmp;
222 switch (fs_no) {
223 case fsid_fec1:
224 fpi = &mpc8xx_fec_pdata[0];
225 fpi->init_ioports = &setup_fec1_ioports;
227 break;
228 case fsid_scc1:
229 fpi = &mpc8xx_scc_pdata;
230 fpi->init_ioports = &setup_scc1_ioports;
232 break;
233 default:
234 printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
235 return;
238 pdev->dev.platform_data = fpi;
239 fpi->fs_no = fs_no;
241 e = (unsigned char *)&bd->bi_enetaddr;
242 for (i = 0; i < 6; i++)
243 fpi->macaddr[i] = *e++;
245 fpi->macaddr[5 - pdev->id]++;
249 static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
250 int idx)
252 /* This is for FEC devices only */
253 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
254 return;
255 mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
258 static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
259 int idx)
261 /* This is for SCC devices only */
262 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
263 return;
265 mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
268 static void setup_smc1_ioports(void)
270 immap_t *immap = (immap_t *) IMAP_ADDR;
271 unsigned *bcsr_io;
272 unsigned int iobits = 0x000000c0;
274 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
276 if (bcsr_io == NULL) {
277 printk(KERN_CRIT "Could not remap BCSR1\n");
278 return;
281 clrbits32(bcsr_io,BCSR1_RS232EN_1);
282 iounmap(bcsr_io);
284 setbits32(&immap->im_cpm.cp_pbpar, iobits);
285 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
286 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
290 static void setup_smc2_ioports(void)
292 immap_t *immap = (immap_t *) IMAP_ADDR;
293 unsigned *bcsr_io;
294 unsigned int iobits = 0x00000c00;
296 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
298 if (bcsr_io == NULL) {
299 printk(KERN_CRIT "Could not remap BCSR1\n");
300 return;
303 clrbits32(bcsr_io,BCSR1_RS232EN_2);
305 iounmap(bcsr_io);
307 #ifndef CONFIG_SERIAL_CPM_ALT_SMC2
308 setbits32(&immap->im_cpm.cp_pbpar, iobits);
309 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
310 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
311 #else
312 setbits16(&immap->im_ioport.iop_papar, iobits);
313 clrbits16(&immap->im_ioport.iop_padir, iobits);
314 clrbits16(&immap->im_ioport.iop_paodr, iobits);
315 #endif
319 static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
320 int idx)
322 bd_t *bd = (bd_t *) __res;
323 struct fs_uart_platform_info *pinfo;
324 int num = ARRAY_SIZE(mpc866_uart_pdata);
326 int id = fs_uart_id_smc2fsid(idx);
328 /* no need to alter anything if console */
329 if ((id <= num) && (!pdev->dev.platform_data)) {
330 pinfo = &mpc866_uart_pdata[id];
331 pinfo->uart_clk = bd->bi_intfreq;
332 pdev->dev.platform_data = pinfo;
336 static int mpc866ads_platform_notify(struct device *dev)
338 static const struct platform_notify_dev_map dev_map[] = {
340 .bus_id = "fsl-cpm-fec",
341 .rtn = mpc866ads_fixup_fec_enet_pdata,
344 .bus_id = "fsl-cpm-scc",
345 .rtn = mpc866ads_fixup_scc_enet_pdata,
348 .bus_id = "fsl-cpm-smc:uart",
349 .rtn = mpc866ads_fixup_uart_pdata
352 .bus_id = NULL
356 platform_notify_map(dev_map,dev);
358 return 0;
361 int __init mpc866ads_init(void)
363 printk(KERN_NOTICE "mpc866ads: Init\n");
365 platform_notify = mpc866ads_platform_notify;
367 ppc_sys_device_initfunc();
368 ppc_sys_device_disable_all();
370 #ifdef MPC8xx_SECOND_ETH_SCC1
371 ppc_sys_device_enable(MPC8xx_CPM_SCC1);
372 #endif
373 ppc_sys_device_enable(MPC8xx_CPM_FEC1);
375 /* Since either of the uarts could be used as console, they need to ready */
376 #ifdef CONFIG_SERIAL_CPM_SMC1
377 ppc_sys_device_enable(MPC8xx_CPM_SMC1);
378 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
379 #endif
381 #ifdef CONFIG_SERIAL_CPM_SMCer
382 ppc_sys_device_enable(MPC8xx_CPM_SMC2);
383 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
384 #endif
386 return 0;
390 To prevent confusion, console selection is gross:
391 by 0 assumed SMC1 and by 1 assumed SMC2
393 struct platform_device* early_uart_get_pdev(int index)
395 bd_t *bd = (bd_t *) __res;
396 struct fs_uart_platform_info *pinfo;
398 struct platform_device* pdev = NULL;
399 if(index) { /*assume SMC2 here*/
400 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
401 pinfo = &mpc866_uart_pdata[1];
402 } else { /*over SMC1*/
403 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
404 pinfo = &mpc866_uart_pdata[0];
407 pinfo->uart_clk = bd->bi_intfreq;
408 pdev->dev.platform_data = pinfo;
409 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
410 return NULL;
413 arch_initcall(mpc866ads_init);