diff options
Diffstat (limited to 'arch/ppc/platforms/mpc8272ads_setup.c')
-rw-r--r-- | arch/ppc/platforms/mpc8272ads_setup.c | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c new file mode 100644 index 000000000000..bc9b94f77e39 --- /dev/null +++ b/arch/ppc/platforms/mpc8272ads_setup.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/82xx/pq2ads_pd.c | ||
3 | * | ||
4 | * MPC82xx Board-specific PlatformDevice descriptions | ||
5 | * | ||
6 | * 2005 (c) MontaVista Software, Inc. | ||
7 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
8 | * | ||
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. | ||
12 | */ | ||
13 | |||
14 | |||
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> | ||
21 | |||
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 | |||
30 | #include "pq2ads_pd.h" | ||
31 | |||
32 | static void init_fcc1_ioports(void); | ||
33 | static void init_fcc2_ioports(void); | ||
34 | |||
35 | static struct fs_mii_bus_info mii_bus_info = { | ||
36 | .method = fsmii_bitbang, | ||
37 | .id = 0, | ||
38 | .i.bitbang = { | ||
39 | .mdio_port = fsiop_portc, | ||
40 | .mdio_bit = 18, | ||
41 | .mdc_port = fsiop_portc, | ||
42 | .mdc_bit = 19, | ||
43 | .delay = 1, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | static struct fs_platform_info mpc82xx_fcc1_pdata = { | ||
48 | .fs_no = fsid_fcc1, | ||
49 | .cp_page = CPM_CR_FCC1_PAGE, | ||
50 | .cp_block = CPM_CR_FCC1_SBLOCK, | ||
51 | .clk_trx = (PC_F1RXCLK | PC_F1TXCLK), | ||
52 | .clk_route = CMX1_CLK_ROUTE, | ||
53 | .clk_mask = CMX1_CLK_MASK, | ||
54 | .init_ioports = init_fcc1_ioports, | ||
55 | |||
56 | .phy_addr = 0, | ||
57 | #ifdef PHY_INTERRUPT | ||
58 | .phy_irq = PHY_INTERRUPT, | ||
59 | #else | ||
60 | .phy_irq = -1; | ||
61 | #endif | ||
62 | .mem_offset = FCC1_MEM_OFFSET, | ||
63 | .bus_info = &mii_bus_info, | ||
64 | .rx_ring = 32, | ||
65 | .tx_ring = 32, | ||
66 | .rx_copybreak = 240, | ||
67 | .use_napi = 0, | ||
68 | .napi_weight = 17, | ||
69 | }; | ||
70 | |||
71 | static struct fs_platform_info mpc82xx_fcc2_pdata = { | ||
72 | .fs_no = fsid_fcc2, | ||
73 | .cp_page = CPM_CR_FCC2_PAGE, | ||
74 | .cp_block = CPM_CR_FCC2_SBLOCK, | ||
75 | .clk_trx = (PC_F2RXCLK | PC_F2TXCLK), | ||
76 | .clk_route = CMX2_CLK_ROUTE, | ||
77 | .clk_mask = CMX2_CLK_MASK, | ||
78 | .init_ioports = init_fcc2_ioports, | ||
79 | |||
80 | .phy_addr = 3, | ||
81 | #ifdef PHY_INTERRUPT | ||
82 | .phy_irq = PHY_INTERRUPT, | ||
83 | #else | ||
84 | .phy_irq = -1; | ||
85 | #endif | ||
86 | .mem_offset = FCC2_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, | ||
93 | }; | ||
94 | |||
95 | static void init_fcc1_ioports(void) | ||
96 | { | ||
97 | struct io_port *io; | ||
98 | u32 tempval; | ||
99 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); | ||
100 | u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32)); | ||
101 | |||
102 | io = &immap->im_ioport; | ||
103 | |||
104 | /* Enable the PHY */ | ||
105 | clrbits32(bcsr, BCSR1_FETHIEN); | ||
106 | setbits32(bcsr, BCSR1_FETH_RST); | ||
107 | |||
108 | /* FCC1 pins are on port A/C. */ | ||
109 | /* Configure port A and C pins for FCC1 Ethernet. */ | ||
110 | |||
111 | tempval = in_be32(&io->iop_pdira); | ||
112 | tempval &= ~PA1_DIRA0; | ||
113 | tempval |= PA1_DIRA1; | ||
114 | out_be32(&io->iop_pdira, tempval); | ||
115 | |||
116 | tempval = in_be32(&io->iop_psora); | ||
117 | tempval &= ~PA1_PSORA0; | ||
118 | tempval |= PA1_PSORA1; | ||
119 | out_be32(&io->iop_psora, tempval); | ||
120 | |||
121 | setbits32(&io->iop_ppara,PA1_DIRA0 | PA1_DIRA1); | ||
122 | |||
123 | /* Alter clocks */ | ||
124 | tempval = PC_F1TXCLK|PC_F1RXCLK; | ||
125 | |||
126 | clrbits32(&io->iop_psorc, tempval); | ||
127 | clrbits32(&io->iop_pdirc, tempval); | ||
128 | setbits32(&io->iop_pparc, tempval); | ||
129 | |||
130 | clrbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_MASK); | ||
131 | setbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_ROUTE); | ||
132 | iounmap(bcsr); | ||
133 | iounmap(immap); | ||
134 | } | ||
135 | |||
136 | static void init_fcc2_ioports(void) | ||
137 | { | ||
138 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); | ||
139 | u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32)); | ||
140 | |||
141 | struct io_port *io; | ||
142 | u32 tempval; | ||
143 | |||
144 | immap = cpm2_immr; | ||
145 | |||
146 | io = &immap->im_ioport; | ||
147 | |||
148 | /* Enable the PHY */ | ||
149 | clrbits32(bcsr, BCSR3_FETHIEN2); | ||
150 | setbits32(bcsr, BCSR3_FETH2_RST); | ||
151 | |||
152 | /* FCC2 are port B/C. */ | ||
153 | /* Configure port A and C pins for FCC2 Ethernet. */ | ||
154 | |||
155 | tempval = in_be32(&io->iop_pdirb); | ||
156 | tempval &= ~PB2_DIRB0; | ||
157 | tempval |= PB2_DIRB1; | ||
158 | out_be32(&io->iop_pdirb, tempval); | ||
159 | |||
160 | tempval = in_be32(&io->iop_psorb); | ||
161 | tempval &= ~PB2_PSORB0; | ||
162 | tempval |= PB2_PSORB1; | ||
163 | out_be32(&io->iop_psorb, tempval); | ||
164 | |||
165 | setbits32(&io->iop_pparb,PB2_DIRB0 | PB2_DIRB1); | ||
166 | |||
167 | tempval = PC_F2RXCLK|PC_F2TXCLK; | ||
168 | |||
169 | /* Alter clocks */ | ||
170 | clrbits32(&io->iop_psorc,tempval); | ||
171 | clrbits32(&io->iop_pdirc,tempval); | ||
172 | setbits32(&io->iop_pparc,tempval); | ||
173 | |||
174 | clrbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_MASK); | ||
175 | setbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_ROUTE); | ||
176 | |||
177 | iounmap(bcsr); | ||
178 | iounmap(immap); | ||
179 | } | ||
180 | |||
181 | |||
182 | static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev, | ||
183 | int idx) | ||
184 | { | ||
185 | bd_t* bi = (void*)__res; | ||
186 | int fs_no = fsid_fcc1+pdev->id-1; | ||
187 | |||
188 | mpc82xx_fcc1_pdata.dpram_offset = mpc82xx_fcc2_pdata.dpram_offset = (u32)cpm2_immr->im_dprambase; | ||
189 | mpc82xx_fcc1_pdata.fcc_regs_c = mpc82xx_fcc2_pdata.fcc_regs_c = (u32)cpm2_immr->im_fcc_c; | ||
190 | |||
191 | switch(fs_no) { | ||
192 | case fsid_fcc1: | ||
193 | memcpy(&mpc82xx_fcc1_pdata.macaddr,bi->bi_enetaddr,6); | ||
194 | pdev->dev.platform_data = &mpc82xx_fcc1_pdata; | ||
195 | break; | ||
196 | case fsid_fcc2: | ||
197 | memcpy(&mpc82xx_fcc2_pdata.macaddr,bi->bi_enetaddr,6); | ||
198 | mpc82xx_fcc2_pdata.macaddr[5] ^= 1; | ||
199 | pdev->dev.platform_data = &mpc82xx_fcc2_pdata; | ||
200 | break; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static int mpc8272ads_platform_notify(struct device *dev) | ||
205 | { | ||
206 | static const struct platform_notify_dev_map dev_map[] = { | ||
207 | { | ||
208 | .bus_id = "fsl-cpm-fcc", | ||
209 | .rtn = mpc8272ads_fixup_enet_pdata | ||
210 | }, | ||
211 | { | ||
212 | .bus_id = NULL | ||
213 | } | ||
214 | }; | ||
215 | platform_notify_map(dev_map,dev); | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | } | ||
220 | |||
221 | int __init mpc8272ads_init(void) | ||
222 | { | ||
223 | printk(KERN_NOTICE "mpc8272ads: Init\n"); | ||
224 | |||
225 | platform_notify = mpc8272ads_platform_notify; | ||
226 | |||
227 | ppc_sys_device_initfunc(); | ||
228 | |||
229 | ppc_sys_device_disable_all(); | ||
230 | ppc_sys_device_enable(MPC82xx_CPM_FCC1); | ||
231 | ppc_sys_device_enable(MPC82xx_CPM_FCC2); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | arch_initcall(mpc8272ads_init); | ||