summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Pelland <mpelland@starry.com>2019-08-01 15:50:58 -0400
committerKishon Vijay Abraham I <kishon@ti.com>2019-08-27 02:07:09 -0400
commitf2a857aa2ad7335a54bd7b306ce02488eb269d58 (patch)
treeca5188d094f150e3e4210a48cfbe29d18acd40b7
parent0c79cf1f486135929f4370b6d919be0facdc1c8e (diff)
phy: marvell: phy-mvebu-cp110-comphy: implement RXAUI support
Marvell's cp110 phy supports RXAUI on lanes 2, 3, 4, and 5 when connected to port zero. When used in this mode, lanes operate in pairs of two (2 and 3, 4 and 5). Signed-off-by: Matt Pelland <mpelland@starry.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
-rw-r--r--drivers/phy/marvell/phy-mvebu-cp110-comphy.c131
1 files changed, 120 insertions, 11 deletions
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index 847723a5c8f8..091b2f3e5005 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -24,6 +24,7 @@
24#define MVEBU_COMPHY_SERDES_CFG0_PU_RX BIT(11) 24#define MVEBU_COMPHY_SERDES_CFG0_PU_RX BIT(11)
25#define MVEBU_COMPHY_SERDES_CFG0_PU_TX BIT(12) 25#define MVEBU_COMPHY_SERDES_CFG0_PU_TX BIT(12)
26#define MVEBU_COMPHY_SERDES_CFG0_HALF_BUS BIT(14) 26#define MVEBU_COMPHY_SERDES_CFG0_HALF_BUS BIT(14)
27#define MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE BIT(15)
27#define MVEBU_COMPHY_SERDES_CFG1(n) (0x4 + (n) * 0x1000) 28#define MVEBU_COMPHY_SERDES_CFG1(n) (0x4 + (n) * 0x1000)
28#define MVEBU_COMPHY_SERDES_CFG1_RESET BIT(3) 29#define MVEBU_COMPHY_SERDES_CFG1_RESET BIT(3)
29#define MVEBU_COMPHY_SERDES_CFG1_RX_INIT BIT(4) 30#define MVEBU_COMPHY_SERDES_CFG1_RX_INIT BIT(4)
@@ -113,6 +114,9 @@
113#define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4) 114#define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4)
114#define MVEBU_COMPHY_PIPE_SELECTOR 0x1144 115#define MVEBU_COMPHY_PIPE_SELECTOR 0x1144
115#define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4) 116#define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4)
117#define MVEBU_COMPHY_SD1_CTRL1 0x1148
118#define MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN BIT(26)
119#define MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN BIT(27)
116 120
117#define MVEBU_COMPHY_LANES 6 121#define MVEBU_COMPHY_LANES 6
118#define MVEBU_COMPHY_PORTS 3 122#define MVEBU_COMPHY_PORTS 3
@@ -216,7 +220,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
216 /* lane 2 */ 220 /* lane 2 */
217 ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 221 ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
218 ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), 222 ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
219 ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), 223 ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
220 ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), 224 ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI),
221 GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 225 GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
222 GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 226 GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
@@ -225,14 +229,14 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
225 GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 229 GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
226 ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), 230 ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
227 ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), 231 ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII),
228 ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), 232 ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI),
229 GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 233 GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
230 GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 234 GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
231 /* lane 4 */ 235 /* lane 4 */
232 ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), 236 ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII),
233 ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), 237 ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII),
234 ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), 238 ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI),
235 ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), 239 ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
236 GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), 240 GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D),
237 GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 241 GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
238 GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), 242 GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
@@ -240,7 +244,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
240 ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), 244 ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII),
241 ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), 245 ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI),
242 /* lane 5 */ 246 /* lane 5 */
243 ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), 247 ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
244 GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), 248 GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA),
245 ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 249 ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
246 ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), 250 ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII),
@@ -317,7 +321,7 @@ static inline int mvebu_comphy_get_fw_mode(int lane, int port,
317 return mvebu_comphy_get_mode(true, lane, port, mode, submode); 321 return mvebu_comphy_get_mode(true, lane, port, mode, submode);
318} 322}
319 323
320static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) 324static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
321{ 325{
322 struct mvebu_comphy_priv *priv = lane->priv; 326 struct mvebu_comphy_priv *priv = lane->priv;
323 u32 val; 327 u32 val;
@@ -334,20 +338,61 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
334 MVEBU_COMPHY_SERDES_CFG0_PU_TX | 338 MVEBU_COMPHY_SERDES_CFG0_PU_TX |
335 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS | 339 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS |
336 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) | 340 MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) |
337 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf)); 341 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf) |
338 if (lane->submode == PHY_INTERFACE_MODE_10GKR) 342 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE);
343
344 switch (lane->submode) {
345 case PHY_INTERFACE_MODE_10GKR:
339 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) | 346 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) |
340 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe); 347 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe);
341 else if (lane->submode == PHY_INTERFACE_MODE_2500BASEX) 348 break;
349 case PHY_INTERFACE_MODE_RXAUI:
350 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xb) |
351 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xb) |
352 MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE;
353 break;
354 case PHY_INTERFACE_MODE_2500BASEX:
342 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) | 355 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) |
343 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) | 356 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) |
344 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; 357 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
345 else if (lane->submode == PHY_INTERFACE_MODE_SGMII) 358 break;
359 case PHY_INTERFACE_MODE_SGMII:
346 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) | 360 val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) |
347 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) | 361 MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) |
348 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; 362 MVEBU_COMPHY_SERDES_CFG0_HALF_BUS;
363 break;
364 default:
365 dev_err(priv->dev,
366 "unsupported comphy submode (%d) on lane %d\n",
367 lane->submode,
368 lane->id);
369 return -ENOTSUPP;
370 }
371
349 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); 372 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
350 373
374 if (lane->submode == PHY_INTERFACE_MODE_RXAUI) {
375 regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val);
376
377 switch (lane->id) {
378 case 2:
379 case 3:
380 val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN;
381 break;
382 case 4:
383 case 5:
384 val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN;
385 break;
386 default:
387 dev_err(priv->dev,
388 "RXAUI is not supported on comphy lane %d\n",
389 lane->id);
390 return -EINVAL;
391 }
392
393 regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val);
394 }
395
351 /* reset */ 396 /* reset */
352 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); 397 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
353 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET | 398 val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET |
@@ -388,6 +433,8 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
388 val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7); 433 val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7);
389 val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1); 434 val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1);
390 writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id)); 435 writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
436
437 return 0;
391} 438}
392 439
393static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane) 440static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane)
@@ -436,8 +483,11 @@ static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
436 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 483 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
437 struct mvebu_comphy_priv *priv = lane->priv; 484 struct mvebu_comphy_priv *priv = lane->priv;
438 u32 val; 485 u32 val;
486 int err;
439 487
440 mvebu_comphy_ethernet_init_reset(lane); 488 err = mvebu_comphy_ethernet_init_reset(lane);
489 if (err)
490 return err;
441 491
442 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 492 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
443 val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; 493 val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
@@ -461,13 +511,69 @@ static int mvebu_comphy_set_mode_sgmii(struct phy *phy)
461 return mvebu_comphy_init_plls(lane); 511 return mvebu_comphy_init_plls(lane);
462} 512}
463 513
514static int mvebu_comphy_set_mode_rxaui(struct phy *phy)
515{
516 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
517 struct mvebu_comphy_priv *priv = lane->priv;
518 u32 val;
519 int err;
520
521 err = mvebu_comphy_ethernet_init_reset(lane);
522 if (err)
523 return err;
524
525 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
526 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
527 MVEBU_COMPHY_RX_CTRL1_CLK8T_EN;
528 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
529
530 val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id));
531 val |= MVEBU_COMPHY_DLT_CTRL_DLT_FLOOP_EN;
532 writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id));
533
534 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
535 val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN;
536 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
537
538 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
539 val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL;
540 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
541
542 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
543 val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf);
544 val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xd);
545 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
546
547 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
548 val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) |
549 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7));
550 val |= MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x1) |
551 MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x1) |
552 MVEBU_COMPHY_GEN1_S1_RX_DFE_EN;
553 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
554
555 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
556 val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL);
557 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
558
559 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
560 val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3);
561 val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1);
562 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
563
564 return mvebu_comphy_init_plls(lane);
565}
566
464static int mvebu_comphy_set_mode_10gkr(struct phy *phy) 567static int mvebu_comphy_set_mode_10gkr(struct phy *phy)
465{ 568{
466 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 569 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
467 struct mvebu_comphy_priv *priv = lane->priv; 570 struct mvebu_comphy_priv *priv = lane->priv;
468 u32 val; 571 u32 val;
572 int err;
469 573
470 mvebu_comphy_ethernet_init_reset(lane); 574 err = mvebu_comphy_ethernet_init_reset(lane);
575 if (err)
576 return err;
471 577
472 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); 578 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
473 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL | 579 val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL |
@@ -626,6 +732,9 @@ static int mvebu_comphy_power_on_legacy(struct phy *phy)
626 case PHY_INTERFACE_MODE_2500BASEX: 732 case PHY_INTERFACE_MODE_2500BASEX:
627 ret = mvebu_comphy_set_mode_sgmii(phy); 733 ret = mvebu_comphy_set_mode_sgmii(phy);
628 break; 734 break;
735 case PHY_INTERFACE_MODE_RXAUI:
736 ret = mvebu_comphy_set_mode_rxaui(phy);
737 break;
629 case PHY_INTERFACE_MODE_10GKR: 738 case PHY_INTERFACE_MODE_10GKR:
630 ret = mvebu_comphy_set_mode_10gkr(phy); 739 ret = mvebu_comphy_set_mode_10gkr(phy);
631 break; 740 break;