diff options
author | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 2011-03-07 16:59:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-14 17:10:15 -0400 |
commit | 8fcd496151b4354569283056076339239b86fabe (patch) | |
tree | 54ebf3e52e9cc3c2a79361f534ace0b22c680b6c | |
parent | e47c90523484518aac30498150e427d824ace705 (diff) |
net: sh_eth: add support for SH7757's GETHER
The SH7757 have GETHER and ETHER both. This patch supports them.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/sh_eth.c | 136 |
1 files changed, 135 insertions, 1 deletions
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 5d28ce68f357..dcf9f87d021f 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -94,7 +94,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
94 | .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */ | 94 | .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */ |
95 | }; | 95 | }; |
96 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) | 96 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) |
97 | #define SH_ETH_RESET_DEFAULT 1 | 97 | #define SH_ETH_HAS_BOTH_MODULES 1 |
98 | #define SH_ETH_HAS_TSU 1 | ||
98 | static void sh_eth_set_duplex(struct net_device *ndev) | 99 | static void sh_eth_set_duplex(struct net_device *ndev) |
99 | { | 100 | { |
100 | struct sh_eth_private *mdp = netdev_priv(ndev); | 101 | struct sh_eth_private *mdp = netdev_priv(ndev); |
@@ -141,6 +142,135 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
141 | .no_ade = 1, | 142 | .no_ade = 1, |
142 | }; | 143 | }; |
143 | 144 | ||
145 | #define SH_GIGA_ETH_BASE 0xfee00000 | ||
146 | #define GIGA_MALR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8) | ||
147 | #define GIGA_MAHR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0) | ||
148 | static void sh_eth_chip_reset_giga(struct net_device *ndev) | ||
149 | { | ||
150 | int i; | ||
151 | unsigned long mahr[2], malr[2]; | ||
152 | |||
153 | /* save MAHR and MALR */ | ||
154 | for (i = 0; i < 2; i++) { | ||
155 | malr[i] = readl(GIGA_MALR(i)); | ||
156 | mahr[i] = readl(GIGA_MAHR(i)); | ||
157 | } | ||
158 | |||
159 | /* reset device */ | ||
160 | writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800); | ||
161 | mdelay(1); | ||
162 | |||
163 | /* restore MAHR and MALR */ | ||
164 | for (i = 0; i < 2; i++) { | ||
165 | writel(malr[i], GIGA_MALR(i)); | ||
166 | writel(mahr[i], GIGA_MAHR(i)); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static int sh_eth_is_gether(struct sh_eth_private *mdp); | ||
171 | static void sh_eth_reset(struct net_device *ndev) | ||
172 | { | ||
173 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
174 | int cnt = 100; | ||
175 | |||
176 | if (sh_eth_is_gether(mdp)) { | ||
177 | sh_eth_write(ndev, 0x03, EDSR); | ||
178 | sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, | ||
179 | EDMR); | ||
180 | while (cnt > 0) { | ||
181 | if (!(sh_eth_read(ndev, EDMR) & 0x3)) | ||
182 | break; | ||
183 | mdelay(1); | ||
184 | cnt--; | ||
185 | } | ||
186 | if (cnt < 0) | ||
187 | printk(KERN_ERR "Device reset fail\n"); | ||
188 | |||
189 | /* Table Init */ | ||
190 | sh_eth_write(ndev, 0x0, TDLAR); | ||
191 | sh_eth_write(ndev, 0x0, TDFAR); | ||
192 | sh_eth_write(ndev, 0x0, TDFXR); | ||
193 | sh_eth_write(ndev, 0x0, TDFFR); | ||
194 | sh_eth_write(ndev, 0x0, RDLAR); | ||
195 | sh_eth_write(ndev, 0x0, RDFAR); | ||
196 | sh_eth_write(ndev, 0x0, RDFXR); | ||
197 | sh_eth_write(ndev, 0x0, RDFFR); | ||
198 | } else { | ||
199 | sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, | ||
200 | EDMR); | ||
201 | mdelay(3); | ||
202 | sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, | ||
203 | EDMR); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | static void sh_eth_set_duplex_giga(struct net_device *ndev) | ||
208 | { | ||
209 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
210 | |||
211 | if (mdp->duplex) /* Full */ | ||
212 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); | ||
213 | else /* Half */ | ||
214 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); | ||
215 | } | ||
216 | |||
217 | static void sh_eth_set_rate_giga(struct net_device *ndev) | ||
218 | { | ||
219 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
220 | |||
221 | switch (mdp->speed) { | ||
222 | case 10: /* 10BASE */ | ||
223 | sh_eth_write(ndev, 0x00000000, GECMR); | ||
224 | break; | ||
225 | case 100:/* 100BASE */ | ||
226 | sh_eth_write(ndev, 0x00000010, GECMR); | ||
227 | break; | ||
228 | case 1000: /* 1000BASE */ | ||
229 | sh_eth_write(ndev, 0x00000020, GECMR); | ||
230 | break; | ||
231 | default: | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /* SH7757(GETHERC) */ | ||
237 | static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = { | ||
238 | .chip_reset = sh_eth_chip_reset_giga, | ||
239 | .set_duplex = sh_eth_set_duplex_giga, | ||
240 | .set_rate = sh_eth_set_rate_giga, | ||
241 | |||
242 | .ecsr_value = ECSR_ICD | ECSR_MPD, | ||
243 | .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, | ||
244 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, | ||
245 | |||
246 | .tx_check = EESR_TC1 | EESR_FTC, | ||
247 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ | ||
248 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ | ||
249 | EESR_ECI, | ||
250 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ | ||
251 | EESR_TFE, | ||
252 | .fdr_value = 0x0000072f, | ||
253 | .rmcr_value = 0x00000001, | ||
254 | |||
255 | .apr = 1, | ||
256 | .mpr = 1, | ||
257 | .tpauser = 1, | ||
258 | .bculr = 1, | ||
259 | .hw_swap = 1, | ||
260 | .rpadir = 1, | ||
261 | .rpadir_value = 2 << 16, | ||
262 | .no_trimd = 1, | ||
263 | .no_ade = 1, | ||
264 | }; | ||
265 | |||
266 | static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp) | ||
267 | { | ||
268 | if (sh_eth_is_gether(mdp)) | ||
269 | return &sh_eth_my_cpu_data_giga; | ||
270 | else | ||
271 | return &sh_eth_my_cpu_data; | ||
272 | } | ||
273 | |||
144 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 274 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
145 | #define SH_ETH_HAS_TSU 1 | 275 | #define SH_ETH_HAS_TSU 1 |
146 | static void sh_eth_chip_reset(struct net_device *ndev) | 276 | static void sh_eth_chip_reset(struct net_device *ndev) |
@@ -1677,7 +1807,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
1677 | mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); | 1807 | mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); |
1678 | 1808 | ||
1679 | /* set cpu data */ | 1809 | /* set cpu data */ |
1810 | #if defined(SH_ETH_HAS_BOTH_MODULES) | ||
1811 | mdp->cd = sh_eth_get_cpu_data(mdp); | ||
1812 | #else | ||
1680 | mdp->cd = &sh_eth_my_cpu_data; | 1813 | mdp->cd = &sh_eth_my_cpu_data; |
1814 | #endif | ||
1681 | sh_eth_set_default_cpu_data(mdp->cd); | 1815 | sh_eth_set_default_cpu_data(mdp->cd); |
1682 | 1816 | ||
1683 | /* set function */ | 1817 | /* set function */ |