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>
23 #include <asm/mpc8260.h>
25 #include <asm/immap_cpm2.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
[] = {
40 .init_ioports
= init_scc1_uart_ioports
,
41 .fs_no
= fsid_scc1_uart
,
49 .init_ioports
= init_scc4_uart_ioports
,
50 .fs_no
= fsid_scc4_uart
,
59 static struct fs_mii_bus_info mii_bus_info
= {
60 .method
= fsmii_bitbang
,
63 .mdio_port
= fsiop_portc
,
65 .mdc_port
= fsiop_portc
,
71 static struct fs_platform_info mpc82xx_fcc1_pdata
= {
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
,
82 .phy_irq
= PHY_INTERRUPT
,
86 .mem_offset
= FCC1_MEM_OFFSET
,
87 .bus_info
= &mii_bus_info
,
95 static struct fs_platform_info mpc82xx_fcc2_pdata
= {
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
,
106 .phy_irq
= PHY_INTERRUPT
,
110 .mem_offset
= FCC2_MEM_OFFSET
,
111 .bus_info
= &mii_bus_info
,
119 static void init_fcc1_ioports(void)
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
;
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
);
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
);
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
));
170 io
= &immap
->im_ioport
;
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
;
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
);
206 static void __init
mpc8272ads_fixup_enet_pdata(struct platform_device
*pdev
,
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
;
217 memcpy(&mpc82xx_fcc1_pdata
.macaddr
,bi
->bi_enetaddr
,6);
218 pdev
->dev
.platform_data
= &mpc82xx_fcc1_pdata
;
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
;
228 static void mpc8272ads_fixup_uart_pdata(struct platform_device
*pdev
,
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);
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);
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
,
292 platform_notify_map(dev_map
,dev
);
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
);
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
);
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
);
350 arch_initcall(mpc8272ads_init
);