]>
Commit | Line | Data |
---|---|---|
fc9a8e8d KM |
1 | /* |
2 | * Ethernet driver for TI K2HK EVM. | |
3 | * | |
4 | * (C) Copyright 2012-2014 | |
5 | * Texas Instruments Incorporated, <www.ti.com> | |
6 | * | |
7 | * SPDX-License-Identifier: GPL-2.0+ | |
8 | */ | |
9 | #include <common.h> | |
10 | #include <command.h> | |
11 | ||
12 | #include <net.h> | |
13 | #include <miiphy.h> | |
14 | #include <malloc.h> | |
15 | #include <asm/arch/emac_defs.h> | |
16 | #include <asm/arch/psc_defs.h> | |
ef454717 | 17 | #include <asm/ti-common/keystone_nav.h> |
fc9a8e8d KM |
18 | |
19 | unsigned int emac_dbg; | |
20 | ||
21 | unsigned int emac_open; | |
22 | static unsigned int sys_has_mdio = 1; | |
23 | ||
24 | #ifdef KEYSTONE2_EMAC_GIG_ENABLE | |
25 | #define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) | |
26 | #else | |
27 | #define emac_gigabit_enable(x) /* no gigabit to enable */ | |
28 | #endif | |
29 | ||
30 | #define RX_BUFF_NUMS 24 | |
31 | #define RX_BUFF_LEN 1520 | |
32 | #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN | |
33 | ||
34 | static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); | |
35 | ||
36 | struct rx_buff_desc net_rx_buffs = { | |
37 | .buff_ptr = rx_buffs, | |
38 | .num_buffs = RX_BUFF_NUMS, | |
39 | .buff_len = RX_BUFF_LEN, | |
40 | .rx_flow = 22, | |
41 | }; | |
42 | ||
43 | static void keystone2_eth_mdio_enable(void); | |
44 | ||
45 | static int gen_get_link_speed(int phy_addr); | |
46 | ||
47 | /* EMAC Addresses */ | |
48 | static volatile struct emac_regs *adap_emac = | |
49 | (struct emac_regs *)EMAC_EMACSL_BASE_ADDR; | |
50 | static volatile struct mdio_regs *adap_mdio = | |
51 | (struct mdio_regs *)EMAC_MDIO_BASE_ADDR; | |
52 | ||
53 | int keystone2_eth_read_mac_addr(struct eth_device *dev) | |
54 | { | |
55 | struct eth_priv_t *eth_priv; | |
56 | u32 maca = 0; | |
57 | u32 macb = 0; | |
58 | ||
59 | eth_priv = (struct eth_priv_t *)dev->priv; | |
60 | ||
61 | /* Read the e-fuse mac address */ | |
62 | if (eth_priv->slave_port == 1) { | |
63 | maca = __raw_readl(MAC_ID_BASE_ADDR); | |
64 | macb = __raw_readl(MAC_ID_BASE_ADDR + 4); | |
65 | } | |
66 | ||
67 | dev->enetaddr[0] = (macb >> 8) & 0xff; | |
68 | dev->enetaddr[1] = (macb >> 0) & 0xff; | |
69 | dev->enetaddr[2] = (maca >> 24) & 0xff; | |
70 | dev->enetaddr[3] = (maca >> 16) & 0xff; | |
71 | dev->enetaddr[4] = (maca >> 8) & 0xff; | |
72 | dev->enetaddr[5] = (maca >> 0) & 0xff; | |
73 | ||
74 | return 0; | |
75 | } | |
76 | ||
77 | static void keystone2_eth_mdio_enable(void) | |
78 | { | |
79 | u_int32_t clkdiv; | |
80 | ||
81 | clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; | |
82 | ||
83 | writel((clkdiv & 0xffff) | | |
84 | MDIO_CONTROL_ENABLE | | |
85 | MDIO_CONTROL_FAULT | | |
86 | MDIO_CONTROL_FAULT_ENABLE, | |
87 | &adap_mdio->control); | |
88 | ||
89 | while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE) | |
90 | ; | |
91 | } | |
92 | ||
93 | /* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */ | |
94 | int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) | |
95 | { | |
96 | int tmp; | |
97 | ||
98 | while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) | |
99 | ; | |
100 | ||
101 | writel(MDIO_USERACCESS0_GO | | |
102 | MDIO_USERACCESS0_WRITE_READ | | |
103 | ((reg_num & 0x1f) << 21) | | |
104 | ((phy_addr & 0x1f) << 16), | |
105 | &adap_mdio->useraccess0); | |
106 | ||
107 | /* Wait for command to complete */ | |
108 | while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO) | |
109 | ; | |
110 | ||
111 | if (tmp & MDIO_USERACCESS0_ACK) { | |
112 | *data = tmp & 0xffff; | |
113 | return 0; | |
114 | } | |
115 | ||
116 | *data = -1; | |
117 | return -1; | |
118 | } | |
119 | ||
120 | /* | |
121 | * Write to a PHY register via MDIO inteface. | |
122 | * Blocks until operation is complete. | |
123 | */ | |
124 | int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) | |
125 | { | |
126 | while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) | |
127 | ; | |
128 | ||
129 | writel(MDIO_USERACCESS0_GO | | |
130 | MDIO_USERACCESS0_WRITE_WRITE | | |
131 | ((reg_num & 0x1f) << 21) | | |
132 | ((phy_addr & 0x1f) << 16) | | |
133 | (data & 0xffff), | |
134 | &adap_mdio->useraccess0); | |
135 | ||
136 | /* Wait for command to complete */ | |
137 | while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) | |
138 | ; | |
139 | ||
140 | return 0; | |
141 | } | |
142 | ||
143 | /* PHY functions for a generic PHY */ | |
144 | static int gen_get_link_speed(int phy_addr) | |
145 | { | |
146 | u_int16_t tmp; | |
147 | ||
148 | if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) && | |
149 | (tmp & 0x04)) { | |
150 | return 0; | |
151 | } | |
152 | ||
153 | return -1; | |
154 | } | |
155 | ||
156 | static void __attribute__((unused)) | |
157 | keystone2_eth_gigabit_enable(struct eth_device *dev) | |
158 | { | |
159 | u_int16_t data; | |
160 | struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; | |
161 | ||
162 | if (sys_has_mdio) { | |
163 | if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) || | |
164 | !(data & (1 << 6))) /* speed selection MSB */ | |
165 | return; | |
166 | } | |
167 | ||
168 | /* | |
169 | * Check if link detected is giga-bit | |
170 | * If Gigabit mode detected, enable gigbit in MAC | |
171 | */ | |
172 | writel(readl(&(adap_emac[eth_priv->slave_port - 1].maccontrol)) | | |
173 | EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, | |
174 | &(adap_emac[eth_priv->slave_port - 1].maccontrol)) | |
175 | ; | |
176 | } | |
177 | ||
178 | int keystone_sgmii_link_status(int port) | |
179 | { | |
180 | u32 status = 0; | |
181 | ||
182 | status = __raw_readl(SGMII_STATUS_REG(port)); | |
183 | ||
184 | return status & SGMII_REG_STATUS_LINK; | |
185 | } | |
186 | ||
187 | ||
188 | int keystone_get_link_status(struct eth_device *dev) | |
189 | { | |
190 | struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; | |
191 | int sgmii_link; | |
192 | int link_state = 0; | |
193 | #if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1 | |
194 | int j; | |
195 | ||
196 | for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0); | |
197 | j++) { | |
198 | #endif | |
199 | sgmii_link = | |
200 | keystone_sgmii_link_status(eth_priv->slave_port - 1); | |
201 | ||
202 | if (sgmii_link) { | |
203 | link_state = 1; | |
204 | ||
205 | if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) | |
206 | if (gen_get_link_speed(eth_priv->phy_addr)) | |
207 | link_state = 0; | |
208 | } | |
209 | #if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1 | |
210 | } | |
211 | #endif | |
212 | return link_state; | |
213 | } | |
214 | ||
215 | int keystone_sgmii_config(int port, int interface) | |
216 | { | |
217 | unsigned int i, status, mask; | |
218 | unsigned int mr_adv_ability, control; | |
219 | ||
220 | switch (interface) { | |
221 | case SGMII_LINK_MAC_MAC_AUTONEG: | |
222 | mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | | |
223 | SGMII_REG_MR_ADV_LINK | | |
224 | SGMII_REG_MR_ADV_FULL_DUPLEX | | |
225 | SGMII_REG_MR_ADV_GIG_MODE); | |
226 | control = (SGMII_REG_CONTROL_MASTER | | |
227 | SGMII_REG_CONTROL_AUTONEG); | |
228 | ||
229 | break; | |
230 | case SGMII_LINK_MAC_PHY: | |
231 | case SGMII_LINK_MAC_PHY_FORCED: | |
232 | mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; | |
233 | control = SGMII_REG_CONTROL_AUTONEG; | |
234 | ||
235 | break; | |
236 | case SGMII_LINK_MAC_MAC_FORCED: | |
237 | mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | | |
238 | SGMII_REG_MR_ADV_LINK | | |
239 | SGMII_REG_MR_ADV_FULL_DUPLEX | | |
240 | SGMII_REG_MR_ADV_GIG_MODE); | |
241 | control = SGMII_REG_CONTROL_MASTER; | |
242 | ||
243 | break; | |
244 | case SGMII_LINK_MAC_FIBER: | |
245 | mr_adv_ability = 0x20; | |
246 | control = SGMII_REG_CONTROL_AUTONEG; | |
247 | ||
248 | break; | |
249 | default: | |
250 | mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; | |
251 | control = SGMII_REG_CONTROL_AUTONEG; | |
252 | } | |
253 | ||
254 | __raw_writel(0, SGMII_CTL_REG(port)); | |
255 | ||
256 | /* | |
257 | * Wait for the SerDes pll to lock, | |
258 | * but don't trap if lock is never read | |
259 | */ | |
260 | for (i = 0; i < 1000; i++) { | |
261 | udelay(2000); | |
262 | status = __raw_readl(SGMII_STATUS_REG(port)); | |
263 | if ((status & SGMII_REG_STATUS_LOCK) != 0) | |
264 | break; | |
265 | } | |
266 | ||
267 | __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); | |
268 | __raw_writel(control, SGMII_CTL_REG(port)); | |
269 | ||
270 | ||
271 | mask = SGMII_REG_STATUS_LINK; | |
272 | ||
273 | if (control & SGMII_REG_CONTROL_AUTONEG) | |
274 | mask |= SGMII_REG_STATUS_AUTONEG; | |
275 | ||
276 | for (i = 0; i < 1000; i++) { | |
277 | status = __raw_readl(SGMII_STATUS_REG(port)); | |
278 | if ((status & mask) == mask) | |
279 | break; | |
280 | } | |
281 | ||
282 | return 0; | |
283 | } | |
284 | ||
285 | int mac_sl_reset(u32 port) | |
286 | { | |
287 | u32 i, v; | |
288 | ||
289 | if (port >= DEVICE_N_GMACSL_PORTS) | |
290 | return GMACSL_RET_INVALID_PORT; | |
291 | ||
292 | /* Set the soft reset bit */ | |
e6c9428a KI |
293 | writel(CPGMAC_REG_RESET_VAL_RESET, |
294 | DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); | |
fc9a8e8d KM |
295 | |
296 | /* Wait for the bit to clear */ | |
297 | for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { | |
e6c9428a | 298 | v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); |
fc9a8e8d KM |
299 | if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != |
300 | CPGMAC_REG_RESET_VAL_RESET) | |
301 | return GMACSL_RET_OK; | |
302 | } | |
303 | ||
304 | /* Timeout on the reset */ | |
305 | return GMACSL_RET_WARN_RESET_INCOMPLETE; | |
306 | } | |
307 | ||
308 | int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) | |
309 | { | |
310 | u32 v, i; | |
311 | int ret = GMACSL_RET_OK; | |
312 | ||
313 | if (port >= DEVICE_N_GMACSL_PORTS) | |
314 | return GMACSL_RET_INVALID_PORT; | |
315 | ||
316 | if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) { | |
317 | cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN; | |
318 | ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; | |
319 | } | |
320 | ||
321 | /* Must wait if the device is undergoing reset */ | |
322 | for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { | |
e6c9428a | 323 | v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); |
fc9a8e8d KM |
324 | if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != |
325 | CPGMAC_REG_RESET_VAL_RESET) | |
326 | break; | |
327 | } | |
328 | ||
329 | if (i == DEVICE_EMACSL_RESET_POLL_COUNT) | |
330 | return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE; | |
331 | ||
e6c9428a KI |
332 | writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN); |
333 | writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL); | |
fc9a8e8d KM |
334 | |
335 | return ret; | |
336 | } | |
337 | ||
338 | int ethss_config(u32 ctl, u32 max_pkt_size) | |
339 | { | |
340 | u32 i; | |
341 | ||
342 | /* Max length register */ | |
e6c9428a | 343 | writel(max_pkt_size, DEVICE_CPSW_BASE + CPSW_REG_MAXLEN); |
fc9a8e8d KM |
344 | |
345 | /* Control register */ | |
e6c9428a | 346 | writel(ctl, DEVICE_CPSW_BASE + CPSW_REG_CTL); |
fc9a8e8d KM |
347 | |
348 | /* All statistics enabled by default */ | |
e6c9428a KI |
349 | writel(CPSW_REG_VAL_STAT_ENABLE_ALL, |
350 | DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN); | |
fc9a8e8d KM |
351 | |
352 | /* Reset and enable the ALE */ | |
e6c9428a KI |
353 | writel(CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE | |
354 | CPSW_REG_VAL_ALE_CTL_BYPASS, | |
355 | DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL); | |
fc9a8e8d KM |
356 | |
357 | /* All ports put into forward mode */ | |
358 | for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) | |
e6c9428a KI |
359 | writel(CPSW_REG_VAL_PORTCTL_FORWARD_MODE, |
360 | DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i)); | |
fc9a8e8d KM |
361 | |
362 | return 0; | |
363 | } | |
364 | ||
365 | int ethss_start(void) | |
366 | { | |
367 | int i; | |
368 | struct mac_sl_cfg cfg; | |
369 | ||
370 | cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER; | |
371 | cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; | |
372 | ||
373 | for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) { | |
374 | mac_sl_reset(i); | |
375 | mac_sl_config(i, &cfg); | |
376 | } | |
377 | ||
378 | return 0; | |
379 | } | |
380 | ||
381 | int ethss_stop(void) | |
382 | { | |
383 | int i; | |
384 | ||
385 | for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) | |
386 | mac_sl_reset(i); | |
387 | ||
388 | return 0; | |
389 | } | |
390 | ||
391 | int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) | |
392 | { | |
393 | if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) | |
394 | num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE; | |
395 | ||
9ea9021a KI |
396 | return ksnav_send(&netcp_pktdma, buffer, |
397 | num_bytes, (slave_port_num) << 16); | |
fc9a8e8d KM |
398 | } |
399 | ||
400 | /* Eth device open */ | |
401 | static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) | |
402 | { | |
403 | u_int32_t clkdiv; | |
404 | int link; | |
405 | struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; | |
406 | ||
407 | debug("+ emac_open\n"); | |
408 | ||
409 | net_rx_buffs.rx_flow = eth_priv->rx_flow; | |
410 | ||
411 | sys_has_mdio = | |
412 | (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; | |
413 | ||
414 | psc_enable_module(KS2_LPSC_PA); | |
415 | psc_enable_module(KS2_LPSC_CPGMAC); | |
416 | ||
417 | sgmii_serdes_setup_156p25mhz(); | |
418 | ||
419 | if (sys_has_mdio) | |
420 | keystone2_eth_mdio_enable(); | |
421 | ||
422 | keystone_sgmii_config(eth_priv->slave_port - 1, | |
423 | eth_priv->sgmii_link_type); | |
424 | ||
425 | udelay(10000); | |
426 | ||
427 | /* On chip switch configuration */ | |
428 | ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); | |
429 | ||
430 | /* TODO: add error handling code */ | |
431 | if (qm_init()) { | |
432 | printf("ERROR: qm_init()\n"); | |
433 | return -1; | |
434 | } | |
9ea9021a | 435 | if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) { |
fc9a8e8d KM |
436 | qm_close(); |
437 | printf("ERROR: netcp_init()\n"); | |
438 | return -1; | |
439 | } | |
440 | ||
441 | /* | |
442 | * Streaming switch configuration. If not present this | |
443 | * statement is defined to void in target.h. | |
444 | * If present this is usually defined to a series of register writes | |
445 | */ | |
446 | hw_config_streaming_switch(); | |
447 | ||
448 | if (sys_has_mdio) { | |
449 | /* Init MDIO & get link state */ | |
450 | clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; | |
451 | writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | | |
452 | MDIO_CONTROL_FAULT, &adap_mdio->control) | |
453 | ; | |
454 | ||
455 | /* We need to wait for MDIO to start */ | |
456 | udelay(1000); | |
457 | ||
458 | link = keystone_get_link_status(dev); | |
459 | if (link == 0) { | |
9ea9021a | 460 | ksnav_close(&netcp_pktdma); |
fc9a8e8d KM |
461 | qm_close(); |
462 | return -1; | |
463 | } | |
464 | } | |
465 | ||
466 | emac_gigabit_enable(dev); | |
467 | ||
468 | ethss_start(); | |
469 | ||
470 | debug("- emac_open\n"); | |
471 | ||
472 | emac_open = 1; | |
473 | ||
474 | return 0; | |
475 | } | |
476 | ||
477 | /* Eth device close */ | |
478 | void keystone2_eth_close(struct eth_device *dev) | |
479 | { | |
480 | debug("+ emac_close\n"); | |
481 | ||
482 | if (!emac_open) | |
483 | return; | |
484 | ||
485 | ethss_stop(); | |
486 | ||
9ea9021a | 487 | ksnav_close(&netcp_pktdma); |
fc9a8e8d KM |
488 | qm_close(); |
489 | ||
490 | emac_open = 0; | |
491 | ||
492 | debug("- emac_close\n"); | |
493 | } | |
494 | ||
495 | static int tx_send_loop; | |
496 | ||
497 | /* | |
498 | * This function sends a single packet on the network and returns | |
499 | * positive number (number of bytes transmitted) or negative for error | |
500 | */ | |
501 | static int keystone2_eth_send_packet(struct eth_device *dev, | |
502 | void *packet, int length) | |
503 | { | |
504 | int ret_status = -1; | |
505 | struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; | |
506 | ||
507 | tx_send_loop = 0; | |
508 | ||
509 | if (keystone_get_link_status(dev) == 0) | |
510 | return -1; | |
511 | ||
512 | emac_gigabit_enable(dev); | |
513 | ||
514 | if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0) | |
515 | return ret_status; | |
516 | ||
517 | if (keystone_get_link_status(dev) == 0) | |
518 | return -1; | |
519 | ||
520 | emac_gigabit_enable(dev); | |
521 | ||
522 | return length; | |
523 | } | |
524 | ||
525 | /* | |
526 | * This function handles receipt of a packet from the network | |
527 | */ | |
528 | static int keystone2_eth_rcv_packet(struct eth_device *dev) | |
529 | { | |
530 | void *hd; | |
531 | int pkt_size; | |
532 | u32 *pkt; | |
533 | ||
9ea9021a | 534 | hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size); |
fc9a8e8d KM |
535 | if (hd == NULL) |
536 | return 0; | |
537 | ||
538 | NetReceive((uchar *)pkt, pkt_size); | |
539 | ||
9ea9021a | 540 | ksnav_release_rxhd(&netcp_pktdma, hd); |
fc9a8e8d KM |
541 | |
542 | return pkt_size; | |
543 | } | |
544 | ||
545 | /* | |
546 | * This function initializes the EMAC hardware. | |
547 | */ | |
548 | int keystone2_emac_initialize(struct eth_priv_t *eth_priv) | |
549 | { | |
550 | struct eth_device *dev; | |
551 | ||
552 | dev = malloc(sizeof(struct eth_device)); | |
553 | if (dev == NULL) | |
554 | return -1; | |
555 | ||
556 | memset(dev, 0, sizeof(struct eth_device)); | |
557 | ||
558 | strcpy(dev->name, eth_priv->int_name); | |
559 | dev->priv = eth_priv; | |
560 | ||
561 | keystone2_eth_read_mac_addr(dev); | |
562 | ||
563 | dev->iobase = 0; | |
564 | dev->init = keystone2_eth_open; | |
565 | dev->halt = keystone2_eth_close; | |
566 | dev->send = keystone2_eth_send_packet; | |
567 | dev->recv = keystone2_eth_rcv_packet; | |
568 | ||
569 | eth_register(dev); | |
570 | ||
571 | return 0; | |
572 | } | |
573 | ||
574 | void sgmii_serdes_setup_156p25mhz(void) | |
575 | { | |
576 | unsigned int cnt; | |
577 | ||
578 | /* | |
579 | * configure Serializer/Deserializer (SerDes) hardware. SerDes IP | |
580 | * hardware vendor published only register addresses and their values | |
581 | * to be used for configuring SerDes. So had to use hardcoded values | |
582 | * below. | |
583 | */ | |
584 | clrsetbits_le32(0x0232a000, 0xffff0000, 0x00800000); | |
585 | clrsetbits_le32(0x0232a014, 0x0000ffff, 0x00008282); | |
586 | clrsetbits_le32(0x0232a060, 0x00ffffff, 0x00142438); | |
587 | clrsetbits_le32(0x0232a064, 0x00ffff00, 0x00c3c700); | |
588 | clrsetbits_le32(0x0232a078, 0x0000ff00, 0x0000c000); | |
589 | ||
590 | clrsetbits_le32(0x0232a204, 0xff0000ff, 0x38000080); | |
591 | clrsetbits_le32(0x0232a208, 0x000000ff, 0x00000000); | |
592 | clrsetbits_le32(0x0232a20c, 0xff000000, 0x02000000); | |
593 | clrsetbits_le32(0x0232a210, 0xff000000, 0x1b000000); | |
594 | clrsetbits_le32(0x0232a214, 0x0000ffff, 0x00006fb8); | |
595 | clrsetbits_le32(0x0232a218, 0xffff00ff, 0x758000e4); | |
596 | clrsetbits_le32(0x0232a2ac, 0x0000ff00, 0x00004400); | |
597 | clrsetbits_le32(0x0232a22c, 0x00ffff00, 0x00200800); | |
598 | clrsetbits_le32(0x0232a280, 0x00ff00ff, 0x00820082); | |
599 | clrsetbits_le32(0x0232a284, 0xffffffff, 0x1d0f0385); | |
600 | ||
601 | clrsetbits_le32(0x0232a404, 0xff0000ff, 0x38000080); | |
602 | clrsetbits_le32(0x0232a408, 0x000000ff, 0x00000000); | |
603 | clrsetbits_le32(0x0232a40c, 0xff000000, 0x02000000); | |
604 | clrsetbits_le32(0x0232a410, 0xff000000, 0x1b000000); | |
605 | clrsetbits_le32(0x0232a414, 0x0000ffff, 0x00006fb8); | |
606 | clrsetbits_le32(0x0232a418, 0xffff00ff, 0x758000e4); | |
607 | clrsetbits_le32(0x0232a4ac, 0x0000ff00, 0x00004400); | |
608 | clrsetbits_le32(0x0232a42c, 0x00ffff00, 0x00200800); | |
609 | clrsetbits_le32(0x0232a480, 0x00ff00ff, 0x00820082); | |
610 | clrsetbits_le32(0x0232a484, 0xffffffff, 0x1d0f0385); | |
611 | ||
612 | clrsetbits_le32(0x0232a604, 0xff0000ff, 0x38000080); | |
613 | clrsetbits_le32(0x0232a608, 0x000000ff, 0x00000000); | |
614 | clrsetbits_le32(0x0232a60c, 0xff000000, 0x02000000); | |
615 | clrsetbits_le32(0x0232a610, 0xff000000, 0x1b000000); | |
616 | clrsetbits_le32(0x0232a614, 0x0000ffff, 0x00006fb8); | |
617 | clrsetbits_le32(0x0232a618, 0xffff00ff, 0x758000e4); | |
618 | clrsetbits_le32(0x0232a6ac, 0x0000ff00, 0x00004400); | |
619 | clrsetbits_le32(0x0232a62c, 0x00ffff00, 0x00200800); | |
620 | clrsetbits_le32(0x0232a680, 0x00ff00ff, 0x00820082); | |
621 | clrsetbits_le32(0x0232a684, 0xffffffff, 0x1d0f0385); | |
622 | ||
623 | clrsetbits_le32(0x0232a804, 0xff0000ff, 0x38000080); | |
624 | clrsetbits_le32(0x0232a808, 0x000000ff, 0x00000000); | |
625 | clrsetbits_le32(0x0232a80c, 0xff000000, 0x02000000); | |
626 | clrsetbits_le32(0x0232a810, 0xff000000, 0x1b000000); | |
627 | clrsetbits_le32(0x0232a814, 0x0000ffff, 0x00006fb8); | |
628 | clrsetbits_le32(0x0232a818, 0xffff00ff, 0x758000e4); | |
629 | clrsetbits_le32(0x0232a8ac, 0x0000ff00, 0x00004400); | |
630 | clrsetbits_le32(0x0232a82c, 0x00ffff00, 0x00200800); | |
631 | clrsetbits_le32(0x0232a880, 0x00ff00ff, 0x00820082); | |
632 | clrsetbits_le32(0x0232a884, 0xffffffff, 0x1d0f0385); | |
633 | ||
634 | clrsetbits_le32(0x0232aa00, 0x0000ff00, 0x00000800); | |
635 | clrsetbits_le32(0x0232aa08, 0xffff0000, 0x38a20000); | |
636 | clrsetbits_le32(0x0232aa30, 0x00ffff00, 0x008a8a00); | |
637 | clrsetbits_le32(0x0232aa84, 0x0000ff00, 0x00000600); | |
638 | clrsetbits_le32(0x0232aa94, 0xff000000, 0x10000000); | |
639 | clrsetbits_le32(0x0232aaa0, 0xff000000, 0x81000000); | |
640 | clrsetbits_le32(0x0232aabc, 0xff000000, 0xff000000); | |
641 | clrsetbits_le32(0x0232aac0, 0x000000ff, 0x0000008b); | |
642 | clrsetbits_le32(0x0232ab08, 0xffff0000, 0x583f0000); | |
643 | clrsetbits_le32(0x0232ab0c, 0x000000ff, 0x0000004e); | |
644 | clrsetbits_le32(0x0232a000, 0x000000ff, 0x00000003); | |
645 | clrsetbits_le32(0x0232aa00, 0x000000ff, 0x0000005f); | |
646 | ||
647 | clrsetbits_le32(0x0232aa48, 0x00ffff00, 0x00fd8c00); | |
648 | clrsetbits_le32(0x0232aa54, 0x00ffffff, 0x002fec72); | |
649 | clrsetbits_le32(0x0232aa58, 0xffffff00, 0x00f92100); | |
650 | clrsetbits_le32(0x0232aa5c, 0xffffffff, 0x00040060); | |
651 | clrsetbits_le32(0x0232aa60, 0xffffffff, 0x00008000); | |
652 | clrsetbits_le32(0x0232aa64, 0xffffffff, 0x0c581220); | |
653 | clrsetbits_le32(0x0232aa68, 0xffffffff, 0xe13b0602); | |
654 | clrsetbits_le32(0x0232aa6c, 0xffffffff, 0xb8074cc1); | |
655 | clrsetbits_le32(0x0232aa70, 0xffffffff, 0x3f02e989); | |
656 | clrsetbits_le32(0x0232aa74, 0x000000ff, 0x00000001); | |
657 | clrsetbits_le32(0x0232ab20, 0x00ff0000, 0x00370000); | |
658 | clrsetbits_le32(0x0232ab1c, 0xff000000, 0x37000000); | |
659 | clrsetbits_le32(0x0232ab20, 0x000000ff, 0x0000005d); | |
660 | ||
661 | /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/ | |
662 | clrbits_le32(0x0232a010, 1 << 28); | |
663 | ||
664 | /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */ | |
665 | clrbits_le32(0x0232a228, 1 << 29); | |
666 | writel(0xF800F8C0, 0x0232bfe0); | |
667 | clrbits_le32(0x0232a428, 1 << 29); | |
668 | writel(0xF800F8C0, 0x0232bfe4); | |
669 | clrbits_le32(0x0232a628, 1 << 29); | |
670 | writel(0xF800F8C0, 0x0232bfe8); | |
671 | clrbits_le32(0x0232a828, 1 << 29); | |
672 | writel(0xF800F8C0, 0x0232bfec); | |
673 | ||
674 | /*Enable pll via the pll_ctrl 0x0014*/ | |
675 | writel(0xe0000000, 0x0232bff4) | |
676 | ; | |
677 | ||
678 | /*Waiting for SGMII Serdes PLL lock.*/ | |
679 | for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--) | |
680 | ; | |
681 | ||
682 | for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--) | |
683 | ; | |
684 | ||
685 | for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--) | |
686 | ; | |
687 | ||
688 | for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--) | |
689 | ; | |
690 | ||
691 | udelay(45000); | |
692 | } | |
693 | ||
694 | void sgmii_serdes_shutdown(void) | |
695 | { | |
696 | /* | |
697 | * shutdown SerDes hardware. SerDes hardware vendor published only | |
698 | * register addresses and their values. So had to use hardcoded | |
699 | * values below. | |
700 | */ | |
701 | clrbits_le32(0x0232bfe0, 3 << 29 | 3 << 13); | |
702 | setbits_le32(0x02320228, 1 << 29); | |
703 | clrbits_le32(0x0232bfe4, 3 << 29 | 3 << 13); | |
704 | setbits_le32(0x02320428, 1 << 29); | |
705 | clrbits_le32(0x0232bfe8, 3 << 29 | 3 << 13); | |
706 | setbits_le32(0x02320628, 1 << 29); | |
707 | clrbits_le32(0x0232bfec, 3 << 29 | 3 << 13); | |
708 | setbits_le32(0x02320828, 1 << 29); | |
709 | ||
710 | clrbits_le32(0x02320034, 3 << 29); | |
711 | setbits_le32(0x02320010, 1 << 28); | |
712 | } |