From 5b43a20ac6c4c1b3445618c6e0bed6937709eea8 Mon Sep 17 00:00:00 2001 From: Nishka Dasgupta Date: Tue, 23 Jul 2019 16:23:27 +0530 Subject: phy: marvell: phy-mvebu-cp110-comphy: Add of_node_put() before return Each iteration of for_each_available_child_of_node puts the previous node, but in the case of a return from the middle of the loop, there is no put, thus causing a memory leak. Hence add an of_node_put before the return in two places. Issue found with Coccinelle. Signed-off-by: Nishka Dasgupta Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index d98e0451f6a1..f7a16dc6e171 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -626,12 +626,16 @@ static int mvebu_comphy_probe(struct platform_device *pdev) } lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); - if (!lane) + if (!lane) { + of_node_put(child); return -ENOMEM; + } phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops); - if (IS_ERR(phy)) + if (IS_ERR(phy)) { + of_node_put(child); return PTR_ERR(phy); + } lane->priv = priv; lane->mode = PHY_MODE_INVALID; -- cgit v1.2.3 From 0629d57bbdbf73aed45f057741b19bdfdefe8f5b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:08 +0200 Subject: phy: mvebu-cp110-comphy: Add clocks support There is no public clock tree that implies such dependencies between the MG/MG-core/AXI clocks and the COMPHY IP but accessing the COMPHY registers while one of the three clocks are disabled stalls the CPU. This happens if, for instance, the COMPHY driver probe is deferred (eg. the USB Vbus regulator driver is not yet visible). The MVPP2 driver which also needs these clocks (among others) will prepare/enable the clocks, then be deferred, and disable/unprepare them. Next COMPHY lane to be configured would produce an infinite stall. Signed-off-by: Miquel Raynal Tested-by: Grzegorz Jaszczyk Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 88 +++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index f7a16dc6e171..5a643e4d9b8e 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -5,6 +5,7 @@ * Antoine Tenart */ +#include #include #include #include @@ -160,6 +161,9 @@ struct mvebu_comphy_priv { void __iomem *base; struct regmap *regmap; struct device *dev; + struct clk *mg_domain_clk; + struct clk *mg_core_clk; + struct clk *axi_clk; }; struct mvebu_comphy_lane { @@ -585,12 +589,72 @@ static struct phy *mvebu_comphy_xlate(struct device *dev, return phy; } +static int mvebu_comphy_init_clks(struct mvebu_comphy_priv *priv) +{ + int ret; + + priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk"); + if (IS_ERR(priv->mg_domain_clk)) + return PTR_ERR(priv->mg_domain_clk); + + ret = clk_prepare_enable(priv->mg_domain_clk); + if (ret < 0) + return ret; + + priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk"); + if (IS_ERR(priv->mg_core_clk)) { + ret = PTR_ERR(priv->mg_core_clk); + goto dis_mg_domain_clk; + } + + ret = clk_prepare_enable(priv->mg_core_clk); + if (ret < 0) + goto dis_mg_domain_clk; + + priv->axi_clk = devm_clk_get(priv->dev, "axi_clk"); + if (IS_ERR(priv->axi_clk)) { + ret = PTR_ERR(priv->axi_clk); + goto dis_mg_core_clk; + } + + ret = clk_prepare_enable(priv->axi_clk); + if (ret < 0) + goto dis_mg_core_clk; + + return 0; + +dis_mg_core_clk: + clk_disable_unprepare(priv->mg_core_clk); + +dis_mg_domain_clk: + clk_disable_unprepare(priv->mg_domain_clk); + + priv->mg_domain_clk = NULL; + priv->mg_core_clk = NULL; + priv->axi_clk = NULL; + + return ret; +}; + +static void mvebu_comphy_disable_unprepare_clks(struct mvebu_comphy_priv *priv) +{ + if (priv->axi_clk) + clk_disable_unprepare(priv->axi_clk); + + if (priv->mg_core_clk) + clk_disable_unprepare(priv->mg_core_clk); + + if (priv->mg_domain_clk) + clk_disable_unprepare(priv->mg_domain_clk); +} + static int mvebu_comphy_probe(struct platform_device *pdev) { struct mvebu_comphy_priv *priv; struct phy_provider *provider; struct device_node *child; struct resource *res; + int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -607,10 +671,20 @@ static int mvebu_comphy_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + /* + * Ignore error if clocks have not been initialized properly for DT + * compatibility reasons. + */ + ret = mvebu_comphy_init_clks(priv); + if (ret) { + if (ret == -EPROBE_DEFER) + return ret; + dev_warn(&pdev->dev, "cannot initialize clocks\n"); + } + for_each_available_child_of_node(pdev->dev.of_node, child) { struct mvebu_comphy_lane *lane; struct phy *phy; - int ret; u32 val; ret = of_property_read_u32(child, "reg", &val); @@ -628,13 +702,15 @@ static int mvebu_comphy_probe(struct platform_device *pdev) lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); if (!lane) { of_node_put(child); - return -ENOMEM; + ret = -ENOMEM; + goto disable_clks; } phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops); if (IS_ERR(phy)) { of_node_put(child); - return PTR_ERR(phy); + ret = PTR_ERR(phy); + goto disable_clks; } lane->priv = priv; @@ -653,7 +729,13 @@ static int mvebu_comphy_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); provider = devm_of_phy_provider_register(&pdev->dev, mvebu_comphy_xlate); + return PTR_ERR_OR_ZERO(provider); + +disable_clks: + mvebu_comphy_disable_unprepare_clks(priv); + + return ret; } static const struct of_device_id mvebu_comphy_of_match_table[] = { -- cgit v1.2.3 From d4eda9d847ac3c32012bd28ac15ed68802c14b63 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:09 +0200 Subject: phy: mvebu-cp110-comphy: Explicitly initialize the lane submode Explicitly set the lane submode (enum) to a known invalid value. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 5a643e4d9b8e..ffadb75c78e9 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -715,6 +715,7 @@ static int mvebu_comphy_probe(struct platform_device *pdev) lane->priv = priv; lane->mode = PHY_MODE_INVALID; + lane->submode = PHY_INTERFACE_MODE_NA; lane->id = val; lane->port = -1; phy_set_drvdata(phy, lane); -- cgit v1.2.3 From eb6a1fcb53e2036608b80269429719025f5f1370 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 31 Jul 2019 14:21:10 +0200 Subject: phy: mvebu-cp110-comphy: Add SMC call support Keep the exact same list of supported configurations but first try to use the firmware's implementation. If it fails, try the legacy method: Linux implementation. Signed-off-by: Grzegorz Jaszczyk [miquel.raynal@bootlin.com: adapt the content to the mainline driver] Signed-off-by: Miquel Raynal Tested-by: Maxime Chevallier Tested-by: Grzegorz Jaszczyk Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/Kconfig | 1 + drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 198 ++++++++++++++++++++++++--- 2 files changed, 177 insertions(+), 22 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig index 0e1642419c0b..4053ba6cd0fb 100644 --- a/drivers/phy/marvell/Kconfig +++ b/drivers/phy/marvell/Kconfig @@ -57,6 +57,7 @@ config PHY_MVEBU_CP110_COMPHY tristate "Marvell CP110 comphy driver" depends on ARCH_MVEBU || COMPILE_TEST depends on OF + depends on HAVE_ARM_SMCCC select GENERIC_PHY help This driver allows to control the comphy, an hardware block providing diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index ffadb75c78e9..0191cd1269f4 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -5,6 +5,7 @@ * Antoine Tenart */ +#include #include #include #include @@ -116,45 +117,89 @@ #define MVEBU_COMPHY_LANES 6 #define MVEBU_COMPHY_PORTS 3 +#define COMPHY_SIP_POWER_ON 0x82000001 +#define COMPHY_SIP_POWER_OFF 0x82000002 +#define COMPHY_FW_NOT_SUPPORTED (-1) + +/* + * A lane is described by the following bitfields: + * [ 1- 0]: COMPHY polarity invertion + * [ 2- 7]: COMPHY speed + * [ 5-11]: COMPHY port index + * [12-16]: COMPHY mode + * [17]: Clock source + */ +#define COMPHY_FW_POL_OFFSET 0 +#define COMPHY_FW_POL_MASK GENMASK(1, 0) +#define COMPHY_FW_SPEED_OFFSET 2 +#define COMPHY_FW_SPEED_MASK GENMASK(7, 2) +#define COMPHY_FW_SPEED_MAX COMPHY_FW_SPEED_MASK +#define COMPHY_FW_SPEED_1250 0 +#define COMPHY_FW_SPEED_3125 2 +#define COMPHY_FW_SPEED_5000 3 +#define COMPHY_FW_SPEED_103125 6 +#define COMPHY_FW_PORT_OFFSET 8 +#define COMPHY_FW_PORT_MASK GENMASK(11, 8) +#define COMPHY_FW_MODE_OFFSET 12 +#define COMPHY_FW_MODE_MASK GENMASK(16, 12) + +#define COMPHY_FW_PARAM_FULL(mode, port, speed, pol) \ + ((((pol) << COMPHY_FW_POL_OFFSET) & COMPHY_FW_POL_MASK) | \ + (((mode) << COMPHY_FW_MODE_OFFSET) & COMPHY_FW_MODE_MASK) | \ + (((port) << COMPHY_FW_PORT_OFFSET) & COMPHY_FW_PORT_MASK) | \ + (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK)) + +#define COMPHY_FW_PARAM(mode, port) \ + COMPHY_FW_PARAM_FULL(mode, port, 0, 0) + +#define COMPHY_FW_PARAM_ETH(mode, port, speed) \ + COMPHY_FW_PARAM_FULL(mode, port, speed, 0) + +#define COMPHY_FW_MODE_SGMII 0x2 /* SGMII 1G */ +#define COMPHY_FW_MODE_HS_SGMII 0x3 /* SGMII 2.5G */ +#define COMPHY_FW_MODE_XFI 0x8 /* SFI: 0x9 (is treated like XFI) */ + struct mvebu_comphy_conf { enum phy_mode mode; int submode; unsigned lane; unsigned port; u32 mux; + u32 fw_mode; }; -#define MVEBU_COMPHY_CONF(_lane, _port, _submode, _mux) \ +#define MVEBU_COMPHY_CONF(_lane, _port, _submode, _mux, _fw) \ { \ .lane = _lane, \ .port = _port, \ .mode = PHY_MODE_ETHERNET, \ .submode = _submode, \ .mux = _mux, \ + .fw_mode = _fw, \ } static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 0 */ - MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1), - MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1), + MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 1 */ - MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1), - MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1), + MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 2 */ - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1), - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1), - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1), + MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), /* lane 3 */ - MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2), - MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2), + MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), /* lane 4 */ - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2), - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2), - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2), - MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1), + MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), + MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), + MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), /* lane 5 */ - MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1), - MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1), + MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), }; struct mvebu_comphy_priv { @@ -164,6 +209,7 @@ struct mvebu_comphy_priv { struct clk *mg_domain_clk; struct clk *mg_core_clk; struct clk *axi_clk; + unsigned long cp_phys; }; struct mvebu_comphy_lane { @@ -174,8 +220,18 @@ struct mvebu_comphy_lane { int port; }; -static int mvebu_comphy_get_mux(int lane, int port, - enum phy_mode mode, int submode) +static int mvebu_comphy_smc(unsigned long function, unsigned long phys, + unsigned long lane, unsigned long mode) +{ + struct arm_smccc_res res; + + arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res); + + return res.a0; +} + +static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, + enum phy_mode mode, int submode) { int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes); @@ -194,7 +250,22 @@ static int mvebu_comphy_get_mux(int lane, int port, if (i == n) return -EINVAL; - return mvebu_comphy_cp110_modes[i].mux; + if (fw_mode) + return mvebu_comphy_cp110_modes[i].fw_mode; + else + return mvebu_comphy_cp110_modes[i].mux; +} + +static inline int mvebu_comphy_get_mux(int lane, int port, + enum phy_mode mode, int submode) +{ + return mvebu_comphy_get_mode(false, lane, port, mode, submode); +} + +static inline int mvebu_comphy_get_fw_mode(int lane, int port, + enum phy_mode mode, int submode) +{ + return mvebu_comphy_get_mode(true, lane, port, mode, submode); } static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) @@ -480,7 +551,7 @@ static int mvebu_comphy_set_mode_10gkr(struct phy *phy) return mvebu_comphy_init_plls(lane); } -static int mvebu_comphy_power_on(struct phy *phy) +static int mvebu_comphy_power_on_legacy(struct phy *phy) { struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_priv *priv = lane->priv; @@ -521,6 +592,68 @@ static int mvebu_comphy_power_on(struct phy *phy) return ret; } +static int mvebu_comphy_power_on(struct phy *phy) +{ + struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); + struct mvebu_comphy_priv *priv = lane->priv; + int fw_mode, fw_speed; + u32 fw_param = 0; + int ret; + + fw_mode = mvebu_comphy_get_fw_mode(lane->id, lane->port, + lane->mode, lane->submode); + if (fw_mode < 0) + goto try_legacy; + + /* Try SMC flow first */ + switch (lane->mode) { + case PHY_MODE_ETHERNET: + switch (lane->submode) { + case PHY_INTERFACE_MODE_SGMII: + dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n", + lane->id); + fw_speed = COMPHY_FW_SPEED_1250; + break; + case PHY_INTERFACE_MODE_2500BASEX: + dev_dbg(priv->dev, "set lane %d to 2500BASE-X mode\n", + lane->id); + fw_speed = COMPHY_FW_SPEED_3125; + break; + case PHY_INTERFACE_MODE_10GKR: + dev_dbg(priv->dev, "set lane %d to 10G-KR mode\n", + lane->id); + fw_speed = COMPHY_FW_SPEED_103125; + break; + default: + dev_err(priv->dev, "unsupported Ethernet mode (%d)\n", + lane->submode); + return -ENOTSUPP; + } + fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed); + break; + default: + dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode); + return -ENOTSUPP; + } + + ret = mvebu_comphy_smc(COMPHY_SIP_POWER_ON, priv->cp_phys, lane->id, + fw_param); + if (!ret) + return ret; + + if (ret == COMPHY_FW_NOT_SUPPORTED) + dev_err(priv->dev, + "unsupported SMC call, try updating your firmware\n"); + + dev_warn(priv->dev, + "Firmware could not configure PHY %d with mode %d (ret: %d), trying legacy method\n", + lane->id, lane->mode, ret); + +try_legacy: + /* Fallback to Linux's implementation */ + return mvebu_comphy_power_on_legacy(phy); +} + static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { @@ -532,7 +665,7 @@ static int mvebu_comphy_set_mode(struct phy *phy, if (submode == PHY_INTERFACE_MODE_1000BASEX) submode = PHY_INTERFACE_MODE_SGMII; - if (mvebu_comphy_get_mux(lane->id, lane->port, mode, submode) < 0) + if (mvebu_comphy_get_fw_mode(lane->id, lane->port, mode, submode) < 0) return -EINVAL; lane->mode = mode; @@ -540,7 +673,7 @@ static int mvebu_comphy_set_mode(struct phy *phy, return 0; } -static int mvebu_comphy_power_off(struct phy *phy) +static int mvebu_comphy_power_off_legacy(struct phy *phy) { struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_priv *priv = lane->priv; @@ -563,6 +696,21 @@ static int mvebu_comphy_power_off(struct phy *phy) return 0; } +static int mvebu_comphy_power_off(struct phy *phy) +{ + struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); + struct mvebu_comphy_priv *priv = lane->priv; + int ret; + + ret = mvebu_comphy_smc(COMPHY_SIP_POWER_OFF, priv->cp_phys, + lane->id, 0); + if (!ret) + return ret; + + /* Fallback to Linux's implementation */ + return mvebu_comphy_power_off_legacy(phy); +} + static const struct phy_ops mvebu_comphy_ops = { .power_on = mvebu_comphy_power_on, .power_off = mvebu_comphy_power_off, @@ -682,6 +830,12 @@ static int mvebu_comphy_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "cannot initialize clocks\n"); } + /* + * Hack to retrieve a physical offset relative to this CP that will be + * given to the firmware + */ + priv->cp_phys = res->start; + for_each_available_child_of_node(pdev->dev.of_node, child) { struct mvebu_comphy_lane *lane; struct phy *phy; -- cgit v1.2.3 From ea678b4b637ebe9a7edd758f2480b194c8fbae31 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:11 +0200 Subject: phy: mvebu-cp110-comphy: List already supported Ethernet modes Currently, the driver supports setting lanes to 1000BASEX, 2500BASEX, 10GKR. Complete the COMPHY modes list by adding two (already supported) cases for lane 4. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 0191cd1269f4..73383363e6b4 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -197,6 +197,8 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), + MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), /* lane 5 */ MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), -- cgit v1.2.3 From 461324f0382cf63637d7158da53a5419ba51be54 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 31 Jul 2019 14:21:12 +0200 Subject: phy: mvebu-cp110-comphy: Add RXAUI support Add support for RXAUI mode by adding an entry in the COMPHY modes list. There is no user for this mode yet so we can enforce an up-to-date firmware and return an error otherwise without breaking anywone. Signed-off-by: Grzegorz Jaszczyk [miquel.raynal@bootlin.com: adapt the content to the mainline driver] Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 73383363e6b4..6defe0d81949 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -157,6 +157,7 @@ #define COMPHY_FW_MODE_SGMII 0x2 /* SGMII 1G */ #define COMPHY_FW_MODE_HS_SGMII 0x3 /* SGMII 2.5G */ +#define COMPHY_FW_MODE_RXAUI 0x7 #define COMPHY_FW_MODE_XFI 0x8 /* SFI: 0x9 (is treated like XFI) */ struct mvebu_comphy_conf { @@ -188,18 +189,22 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 2 */ MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), /* lane 3 */ MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), + MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), /* lane 4 */ MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), + MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), /* lane 5 */ + MVEBU_COMPHY_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), }; @@ -611,6 +616,11 @@ static int mvebu_comphy_power_on(struct phy *phy) switch (lane->mode) { case PHY_MODE_ETHERNET: switch (lane->submode) { + case PHY_INTERFACE_MODE_RXAUI: + dev_dbg(priv->dev, "set lane %d to RXAUI mode\n", + lane->id); + fw_speed = 0; + break; case PHY_INTERFACE_MODE_SGMII: dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n", lane->id); -- cgit v1.2.3 From c2afb2fef595805607633b6bffd5600d836e4ead Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:13 +0200 Subject: phy: mvebu-cp110-comphy: Rename the macro handling only Ethernet modes Before adding support for other PHY modes (not Ethernet ones), let's rename the MVEBU_COMPHY_CONF macro to a more specific (and shorter) appellation. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 6defe0d81949..bf7ea3cd4f9f 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -169,7 +169,7 @@ struct mvebu_comphy_conf { u32 fw_mode; }; -#define MVEBU_COMPHY_CONF(_lane, _port, _submode, _mux, _fw) \ +#define ETH_CONF(_lane, _port, _submode, _mux, _fw) \ { \ .lane = _lane, \ .port = _port, \ @@ -181,32 +181,32 @@ struct mvebu_comphy_conf { static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 0 */ - MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 1 */ - MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 2 */ - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), - MVEBU_COMPHY_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), + ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), /* lane 3 */ - MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), - MVEBU_COMPHY_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), + ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), /* lane 4 */ - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), - MVEBU_COMPHY_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), - MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), - MVEBU_COMPHY_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), + ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), + ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), + ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), /* lane 5 */ - MVEBU_COMPHY_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), - MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), - MVEBU_COMPHY_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), + ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), }; struct mvebu_comphy_priv { -- cgit v1.2.3 From 96888aed3d09862c1d80b3ccb405b4bcf6d827c5 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:14 +0200 Subject: phy: mvebu-cp110-comphy: Allow non-Ethernet modes to be configured The COMPHY can configure the SERDES lanes in several non-Ethernet modes: SATA, USB3, PCIe. Drop the condition limiting the driver to Ethernet modes only before adding support for more. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index bf7ea3cd4f9f..78c309571943 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -671,9 +671,6 @@ static int mvebu_comphy_set_mode(struct phy *phy, { struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); - if (mode != PHY_MODE_ETHERNET) - return -EINVAL; - if (submode == PHY_INTERFACE_MODE_1000BASEX) submode = PHY_INTERFACE_MODE_SGMII; -- cgit v1.2.3 From c527a636d6200b0583caa7dee2427b0de218fb2c Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 31 Jul 2019 14:21:15 +0200 Subject: phy: mvebu-cp110-comphy: Add USB3 host/device support Add USB3 host/device support by adding the right entries in the COMPHY modes table. A new macro is created to instantiate a "generic" mode ie. not an Ethernet one. This macro will be re-used when adding SATA support. Signed-off-by: Grzegorz Jaszczyk [miquel.raynal@bootlin.com: adapt the content to the mainline driver] Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 78c309571943..67f44ddefac2 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -157,6 +157,8 @@ #define COMPHY_FW_MODE_SGMII 0x2 /* SGMII 1G */ #define COMPHY_FW_MODE_HS_SGMII 0x3 /* SGMII 2.5G */ +#define COMPHY_FW_MODE_USB3H 0x4 +#define COMPHY_FW_MODE_USB3D 0x5 #define COMPHY_FW_MODE_RXAUI 0x7 #define COMPHY_FW_MODE_XFI 0x8 /* SFI: 0x9 (is treated like XFI) */ @@ -179,11 +181,23 @@ struct mvebu_comphy_conf { .fw_mode = _fw, \ } +#define GEN_CONF(_lane, _port, _mode, _fw) \ + { \ + .lane = _lane, \ + .port = _port, \ + .mode = _mode, \ + .submode = PHY_INTERFACE_MODE_NA, \ + .mux = -1, \ + .fw_mode = _fw, \ + } + static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 0 */ ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 1 */ + GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), + GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 2 */ @@ -191,15 +205,19 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), + GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), /* lane 3 */ ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), /* lane 4 */ ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), + GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), @@ -643,6 +661,11 @@ static int mvebu_comphy_power_on(struct phy *phy) } fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed); break; + case PHY_MODE_USB_HOST_SS: + case PHY_MODE_USB_DEVICE_SS: + dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id); + fw_param = COMPHY_FW_PARAM(fw_mode, lane->port); + break; default: dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode); return -ENOTSUPP; -- cgit v1.2.3 From ef0ac9f24b65bac389a21b2d37ab90200f285062 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 31 Jul 2019 14:21:16 +0200 Subject: phy: mvebu-cp110-comphy: Add SATA support Add the corresponding entries in the COMPHY modes table. SATA support does not need any additional care. Signed-off-by: Grzegorz Jaszczyk [miquel.raynal@bootlin.com: adapt the content to the mainline driver] Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 67f44ddefac2..e4c0ec61dd04 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -155,6 +155,7 @@ #define COMPHY_FW_PARAM_ETH(mode, port, speed) \ COMPHY_FW_PARAM_FULL(mode, port, speed, 0) +#define COMPHY_FW_MODE_SATA 0x1 #define COMPHY_FW_MODE_SGMII 0x2 /* SGMII 1G */ #define COMPHY_FW_MODE_HS_SGMII 0x3 /* SGMII 2.5G */ #define COMPHY_FW_MODE_USB3H 0x4 @@ -195,9 +196,11 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 0 */ ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), /* lane 1 */ GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), + GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 2 */ @@ -206,11 +209,13 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), + GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), /* lane 3 */ ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), + GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), /* lane 4 */ ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), @@ -223,6 +228,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), /* lane 5 */ ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), }; @@ -666,6 +672,10 @@ static int mvebu_comphy_power_on(struct phy *phy) dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id); fw_param = COMPHY_FW_PARAM(fw_mode, lane->port); break; + case PHY_MODE_SATA: + dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id); + fw_param = COMPHY_FW_PARAM(fw_mode, lane->port); + break; default: dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode); return -ENOTSUPP; -- cgit v1.2.3 From 1eb9157ab3ef64e845e10fe40d49638fb408119e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:17 +0200 Subject: phy: mvebu-cp110-comphy: Cosmetic change in a helper Before adding more logic, simplify a bit the writing of the mvebu_comphy_get_mode() helper by using a pointer instead of referencing a configuration with the entire table name. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index e4c0ec61dd04..98cb7298a9fe 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -265,16 +265,18 @@ static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, enum phy_mode mode, int submode) { int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes); + const struct mvebu_comphy_conf *conf; /* Unused PHY mux value is 0x0 */ if (mode == PHY_MODE_INVALID) return 0; for (i = 0; i < n; i++) { - if (mvebu_comphy_cp110_modes[i].lane == lane && - mvebu_comphy_cp110_modes[i].port == port && - mvebu_comphy_cp110_modes[i].mode == mode && - mvebu_comphy_cp110_modes[i].submode == submode) + conf = &mvebu_comphy_cp110_modes[i]; + if (conf->lane == lane && + conf->port == port && + conf->mode == mode && + conf->submode == submode) break; } @@ -282,9 +284,9 @@ static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, return -EINVAL; if (fw_mode) - return mvebu_comphy_cp110_modes[i].fw_mode; + return conf->fw_mode; else - return mvebu_comphy_cp110_modes[i].mux; + return conf->mux; } static inline int mvebu_comphy_get_mux(int lane, int port, -- cgit v1.2.3 From 652488760ea613af0c1207169aeafc9c91203c38 Mon Sep 17 00:00:00 2001 From: Grzegorz Jaszczyk Date: Wed, 31 Jul 2019 14:21:18 +0200 Subject: phy: mvebu-cp110-comphy: Add PCIe support Add PCIe support by filling the COMPHY modes table. Also add a new macro to generate the right value for the firmware depending on the width (PCI x1, x2, x4, etc). The width will be passed by the core as the "submode" argument of the ->set_mode() callback. If this argument is zero, default to x1 mode. Signed-off-by: Grzegorz Jaszczyk [miquel.raynal@bootlin.com: adapt the content to the mainline driver] Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 37 ++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 98cb7298a9fe..43cd99a69372 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -128,6 +128,7 @@ * [ 5-11]: COMPHY port index * [12-16]: COMPHY mode * [17]: Clock source + * [18-20]: PCIe width (x1, x2, x4) */ #define COMPHY_FW_POL_OFFSET 0 #define COMPHY_FW_POL_MASK GENMASK(1, 0) @@ -142,24 +143,31 @@ #define COMPHY_FW_PORT_MASK GENMASK(11, 8) #define COMPHY_FW_MODE_OFFSET 12 #define COMPHY_FW_MODE_MASK GENMASK(16, 12) +#define COMPHY_FW_WIDTH_OFFSET 18 +#define COMPHY_FW_WIDTH_MASK GENMASK(20, 18) -#define COMPHY_FW_PARAM_FULL(mode, port, speed, pol) \ +#define COMPHY_FW_PARAM_FULL(mode, port, speed, pol, width) \ ((((pol) << COMPHY_FW_POL_OFFSET) & COMPHY_FW_POL_MASK) | \ (((mode) << COMPHY_FW_MODE_OFFSET) & COMPHY_FW_MODE_MASK) | \ (((port) << COMPHY_FW_PORT_OFFSET) & COMPHY_FW_PORT_MASK) | \ - (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK)) + (((speed) << COMPHY_FW_SPEED_OFFSET) & COMPHY_FW_SPEED_MASK) | \ + (((width) << COMPHY_FW_WIDTH_OFFSET) & COMPHY_FW_WIDTH_MASK)) #define COMPHY_FW_PARAM(mode, port) \ - COMPHY_FW_PARAM_FULL(mode, port, 0, 0) + COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_MAX, 0, 0) #define COMPHY_FW_PARAM_ETH(mode, port, speed) \ - COMPHY_FW_PARAM_FULL(mode, port, speed, 0) + COMPHY_FW_PARAM_FULL(mode, port, speed, 0, 0) + +#define COMPHY_FW_PARAM_PCIE(mode, port, width) \ + COMPHY_FW_PARAM_FULL(mode, port, COMPHY_FW_SPEED_5000, 0, width) #define COMPHY_FW_MODE_SATA 0x1 #define COMPHY_FW_MODE_SGMII 0x2 /* SGMII 1G */ #define COMPHY_FW_MODE_HS_SGMII 0x3 /* SGMII 2.5G */ #define COMPHY_FW_MODE_USB3H 0x4 #define COMPHY_FW_MODE_USB3D 0x5 +#define COMPHY_FW_MODE_PCIE 0x6 #define COMPHY_FW_MODE_RXAUI 0x7 #define COMPHY_FW_MODE_XFI 0x8 /* SFI: 0x9 (is treated like XFI) */ @@ -194,6 +202,7 @@ struct mvebu_comphy_conf { static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 0 */ + GEN_CONF(0, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), ETH_CONF(0, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(0, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), GEN_CONF(0, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), @@ -201,6 +210,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { GEN_CONF(1, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), GEN_CONF(1, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), GEN_CONF(1, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), + GEN_CONF(1, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), ETH_CONF(1, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(1, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), /* lane 2 */ @@ -210,7 +220,9 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), GEN_CONF(2, 0, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), + GEN_CONF(2, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), /* lane 3 */ + GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), @@ -223,6 +235,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), + GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), @@ -231,6 +244,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(5, 2, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), + GEN_CONF(5, 2, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), }; struct mvebu_comphy_priv { @@ -265,6 +279,8 @@ static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, enum phy_mode mode, int submode) { int i, n = ARRAY_SIZE(mvebu_comphy_cp110_modes); + /* Ignore PCIe submode: it represents the width */ + bool ignore_submode = (mode == PHY_MODE_PCIE); const struct mvebu_comphy_conf *conf; /* Unused PHY mux value is 0x0 */ @@ -276,7 +292,7 @@ static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, if (conf->lane == lane && conf->port == port && conf->mode == mode && - conf->submode == submode) + (conf->submode == submode || ignore_submode)) break; } @@ -678,6 +694,12 @@ static int mvebu_comphy_power_on(struct phy *phy) dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id); fw_param = COMPHY_FW_PARAM(fw_mode, lane->port); break; + case PHY_MODE_PCIE: + dev_dbg(priv->dev, "set lane %d to PCIe mode (x%d)\n", lane->id, + lane->submode); + fw_param = COMPHY_FW_PARAM_PCIE(fw_mode, lane->port, + lane->submode); + break; default: dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode); return -ENOTSUPP; @@ -714,6 +736,11 @@ static int mvebu_comphy_set_mode(struct phy *phy, lane->mode = mode; lane->submode = submode; + + /* PCIe submode represents the width */ + if (mode == PHY_MODE_PCIE && !lane->submode) + lane->submode = 1; + return 0; } -- cgit v1.2.3 From 4e19a76ec08e52dd3ad43dcd49bbb704a2ff420b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 31 Jul 2019 14:21:19 +0200 Subject: phy: mvebu-cp110-comphy: Update comment about powering off all lanes at boot Now that all COMPHY modes are supported by the driver, update the comment stating that mvebu_comphy_power_off() should be called for each lane. This is still wrong because for compatibility reasons, it might break users running an old firmware (the driver only uses SMC calls for SATA, USB and PCIe configuration, there is no code in Linux to fallback on in these cases. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 43cd99a69372..847723a5c8f8 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -946,9 +946,11 @@ static int mvebu_comphy_probe(struct platform_device *pdev) phy_set_drvdata(phy, lane); /* - * Once all modes are supported in this driver we should call + * All modes are supported in this driver so we could call * mvebu_comphy_power_off(phy) here to avoid relying on the - * bootloader/firmware configuration. + * bootloader/firmware configuration, but for compatibility + * reasons we cannot de-configure the COMPHY without being sure + * that the firmware is up-to-date and fully-featured. */ } -- cgit v1.2.3 From f2a857aa2ad7335a54bd7b306ce02488eb269d58 Mon Sep 17 00:00:00 2001 From: Matt Pelland Date: Thu, 1 Aug 2019 15:50:58 -0400 Subject: 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 Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 131 ++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 11 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') 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 @@ #define MVEBU_COMPHY_SERDES_CFG0_PU_RX BIT(11) #define MVEBU_COMPHY_SERDES_CFG0_PU_TX BIT(12) #define MVEBU_COMPHY_SERDES_CFG0_HALF_BUS BIT(14) +#define MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE BIT(15) #define MVEBU_COMPHY_SERDES_CFG1(n) (0x4 + (n) * 0x1000) #define MVEBU_COMPHY_SERDES_CFG1_RESET BIT(3) #define MVEBU_COMPHY_SERDES_CFG1_RX_INIT BIT(4) @@ -113,6 +114,9 @@ #define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4) #define MVEBU_COMPHY_PIPE_SELECTOR 0x1144 #define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4) +#define MVEBU_COMPHY_SD1_CTRL1 0x1148 +#define MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN BIT(26) +#define MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN BIT(27) #define MVEBU_COMPHY_LANES 6 #define MVEBU_COMPHY_PORTS 3 @@ -216,7 +220,7 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = { /* lane 2 */ ETH_CONF(2, 0, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), ETH_CONF(2, 0, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_HS_SGMII), - ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(2, 0, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI), ETH_CONF(2, 0, PHY_INTERFACE_MODE_10GKR, 0x1, COMPHY_FW_MODE_XFI), GEN_CONF(2, 0, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 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[] = { GEN_CONF(3, 0, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), ETH_CONF(3, 1, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(3, 1, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), - ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(3, 1, PHY_INTERFACE_MODE_RXAUI, 0x1, COMPHY_FW_MODE_RXAUI), GEN_CONF(3, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), GEN_CONF(3, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), /* lane 4 */ ETH_CONF(4, 0, PHY_INTERFACE_MODE_SGMII, 0x2, COMPHY_FW_MODE_SGMII), ETH_CONF(4, 0, PHY_INTERFACE_MODE_2500BASEX, 0x2, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(4, 0, PHY_INTERFACE_MODE_10GKR, 0x2, COMPHY_FW_MODE_XFI), - ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(4, 0, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI), GEN_CONF(4, 0, PHY_MODE_USB_DEVICE_SS, COMPHY_FW_MODE_USB3D), GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H), 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[] = { ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_HS_SGMII), ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GKR, -1, COMPHY_FW_MODE_XFI), /* lane 5 */ - ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, -1, COMPHY_FW_MODE_RXAUI), + ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI), GEN_CONF(5, 1, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), ETH_CONF(5, 2, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII), 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, return mvebu_comphy_get_mode(true, lane, port, mode, submode); } -static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) +static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) { struct mvebu_comphy_priv *priv = lane->priv; u32 val; @@ -334,20 +338,61 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) MVEBU_COMPHY_SERDES_CFG0_PU_TX | MVEBU_COMPHY_SERDES_CFG0_HALF_BUS | MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xf) | - MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf)); - if (lane->submode == PHY_INTERFACE_MODE_10GKR) + MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xf) | + MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE); + + switch (lane->submode) { + case PHY_INTERFACE_MODE_10GKR: val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xe) | MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xe); - else if (lane->submode == PHY_INTERFACE_MODE_2500BASEX) + break; + case PHY_INTERFACE_MODE_RXAUI: + val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0xb) | + MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0xb) | + MVEBU_COMPHY_SERDES_CFG0_RXAUI_MODE; + break; + case PHY_INTERFACE_MODE_2500BASEX: val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x8) | MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x8) | MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; - else if (lane->submode == PHY_INTERFACE_MODE_SGMII) + break; + case PHY_INTERFACE_MODE_SGMII: val |= MVEBU_COMPHY_SERDES_CFG0_GEN_RX(0x6) | MVEBU_COMPHY_SERDES_CFG0_GEN_TX(0x6) | MVEBU_COMPHY_SERDES_CFG0_HALF_BUS; + break; + default: + dev_err(priv->dev, + "unsupported comphy submode (%d) on lane %d\n", + lane->submode, + lane->id); + return -ENOTSUPP; + } + writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id)); + if (lane->submode == PHY_INTERFACE_MODE_RXAUI) { + regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val); + + switch (lane->id) { + case 2: + case 3: + val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI0_EN; + break; + case 4: + case 5: + val |= MVEBU_COMPHY_SD1_CTRL1_RXAUI1_EN; + break; + default: + dev_err(priv->dev, + "RXAUI is not supported on comphy lane %d\n", + lane->id); + return -EINVAL; + } + + regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val); + } + /* reset */ val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id)); val &= ~(MVEBU_COMPHY_SERDES_CFG1_RESET | @@ -388,6 +433,8 @@ static void mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane) val &= ~MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x7); val |= MVEBU_COMPHY_LOOPBACK_DBUS_WIDTH(0x1); writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id)); + + return 0; } static int mvebu_comphy_init_plls(struct mvebu_comphy_lane *lane) @@ -436,8 +483,11 @@ static int mvebu_comphy_set_mode_sgmii(struct phy *phy) struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_priv *priv = lane->priv; u32 val; + int err; - mvebu_comphy_ethernet_init_reset(lane); + err = mvebu_comphy_ethernet_init_reset(lane); + if (err) + return err; val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); val &= ~MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; @@ -461,13 +511,69 @@ static int mvebu_comphy_set_mode_sgmii(struct phy *phy) return mvebu_comphy_init_plls(lane); } +static int mvebu_comphy_set_mode_rxaui(struct phy *phy) +{ + struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); + struct mvebu_comphy_priv *priv = lane->priv; + u32 val; + int err; + + err = mvebu_comphy_ethernet_init_reset(lane); + if (err) + return err; + + val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); + val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL | + MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; + writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); + val |= MVEBU_COMPHY_DLT_CTRL_DLT_FLOOP_EN; + writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); + val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN; + writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); + val |= MVEBU_COMPHY_DFE_RES_FORCE_GEN_TBL; + writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); + val &= ~MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xf); + val |= MVEBU_COMPHY_GEN1_S0_TX_EMPH(0xd); + writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); + val &= ~(MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x7) | + MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x7)); + val |= MVEBU_COMPHY_GEN1_S1_RX_MUL_PI(0x1) | + MVEBU_COMPHY_GEN1_S1_RX_MUL_PF(0x1) | + MVEBU_COMPHY_GEN1_S1_RX_DFE_EN; + writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id)); + val &= ~(MVEBU_COMPHY_COEF_DFE_EN | MVEBU_COMPHY_COEF_DFE_CTRL); + writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id)); + + val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); + val &= ~MVEBU_COMPHY_GEN1_S4_DFE_RES(0x3); + val |= MVEBU_COMPHY_GEN1_S4_DFE_RES(0x1); + writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id)); + + return mvebu_comphy_init_plls(lane); +} + static int mvebu_comphy_set_mode_10gkr(struct phy *phy) { struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_priv *priv = lane->priv; u32 val; + int err; - mvebu_comphy_ethernet_init_reset(lane); + err = mvebu_comphy_ethernet_init_reset(lane); + if (err) + return err; val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL | @@ -626,6 +732,9 @@ static int mvebu_comphy_power_on_legacy(struct phy *phy) case PHY_INTERFACE_MODE_2500BASEX: ret = mvebu_comphy_set_mode_sgmii(phy); break; + case PHY_INTERFACE_MODE_RXAUI: + ret = mvebu_comphy_set_mode_rxaui(phy); + break; case PHY_INTERFACE_MODE_10GKR: ret = mvebu_comphy_set_mode_10gkr(phy); break; -- cgit v1.2.3 From 5af67635c36ed92ef172c7bbf4d711364bc3bdf7 Mon Sep 17 00:00:00 2001 From: Matt Pelland Date: Thu, 1 Aug 2019 15:50:59 -0400 Subject: phy: marvell: phy-mvebu-cp110-comphy: rename instances of DLT The documentation for Marvell's cp110 phy refers to these registers/register regions as DTL control, DTL frequency loop enable, etc. This patch aligns the relevant code for these accordingly. Signed-off-by: Matt Pelland Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/phy/marvell/phy-mvebu-cp110-comphy.c') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 091b2f3e5005..e3b87c94aaf6 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -80,8 +80,8 @@ #define MVEBU_COMPHY_TX_SLEW_RATE(n) (0x974 + (n) * 0x1000) #define MVEBU_COMPHY_TX_SLEW_RATE_EMPH(n) ((n) << 5) #define MVEBU_COMPHY_TX_SLEW_RATE_SLC(n) ((n) << 10) -#define MVEBU_COMPHY_DLT_CTRL(n) (0x984 + (n) * 0x1000) -#define MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN BIT(2) +#define MVEBU_COMPHY_DTL_CTRL(n) (0x984 + (n) * 0x1000) +#define MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN BIT(2) #define MVEBU_COMPHY_FRAME_DETECT0(n) (0xa14 + (n) * 0x1000) #define MVEBU_COMPHY_FRAME_DETECT0_PATN(n) ((n) << 7) #define MVEBU_COMPHY_FRAME_DETECT3(n) (0xa20 + (n) * 0x1000) @@ -494,9 +494,9 @@ static int mvebu_comphy_set_mode_sgmii(struct phy *phy) val |= MVEBU_COMPHY_RX_CTRL1_RXCLK2X_SEL; writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); - val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); - val &= ~MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN; - writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); + val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); + val &= ~MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN; + writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val); val &= ~MVEBU_COMPHY_CONF1_USB_PCIE; @@ -527,9 +527,9 @@ static int mvebu_comphy_set_mode_rxaui(struct phy *phy) MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); - val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); - val |= MVEBU_COMPHY_DLT_CTRL_DLT_FLOOP_EN; - writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); + val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); + val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN; + writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id)); val |= MVEBU_COMPHY_SERDES_CFG2_DFE_EN; @@ -580,9 +580,9 @@ static int mvebu_comphy_set_mode_10gkr(struct phy *phy) MVEBU_COMPHY_RX_CTRL1_CLK8T_EN; writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id)); - val = readl(priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); - val |= MVEBU_COMPHY_DLT_CTRL_DTL_FLOOP_EN; - writel(val, priv->base + MVEBU_COMPHY_DLT_CTRL(lane->id)); + val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); + val |= MVEBU_COMPHY_DTL_CTRL_DTL_FLOOP_EN; + writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id)); /* Speed divider */ val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id)); -- cgit v1.2.3