From: Álvaro Fernández Rojas Date: Tue, 16 Mar 2021 19:06:00 +0000 (+0100) Subject: bmips: backport bcm6368-mdio-mux support X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=34f898ec29fa1e5254347b8a3dc41c9fecd87fd1;p=openwrt%2Fstaging%2Fnoltari.git bmips: backport bcm6368-mdio-mux support This patch has been accepted for linux v5.13. Signed-off-by: Álvaro Fernández Rojas --- diff --git a/target/linux/bmips/patches-5.10/046-v5.13-dt-bindings-net-Add-bcm6368-mdio-mux-bindings.patch b/target/linux/bmips/patches-5.10/046-v5.13-dt-bindings-net-Add-bcm6368-mdio-mux-bindings.patch new file mode 100644 index 0000000000..05d688fe03 --- /dev/null +++ b/target/linux/bmips/patches-5.10/046-v5.13-dt-bindings-net-Add-bcm6368-mdio-mux-bindings.patch @@ -0,0 +1,96 @@ +From da6557edb9f3f4513b01d9a20a36c2fbc31810a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Mon, 15 Mar 2021 16:45:27 +0100 +Subject: [PATCH 1/2] dt-bindings: net: Add bcm6368-mdio-mux bindings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add documentations for bcm6368 mdio mux driver. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: David S. Miller +--- + .../bindings/net/brcm,bcm6368-mdio-mux.yaml | 76 +++++++++++++++++++ + 1 file changed, 76 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/brcm,bcm6368-mdio-mux.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/brcm,bcm6368-mdio-mux.yaml +@@ -0,0 +1,76 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/brcm,bcm6368-mdio-mux.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Broadcom BCM6368 MDIO bus multiplexer ++ ++maintainers: ++ - Álvaro Fernández Rojas ++ ++description: ++ This MDIO bus multiplexer defines buses that could be internal as well as ++ external to SoCs. When child bus is selected, one needs to select these two ++ properties as well to generate desired MDIO transaction on appropriate bus. ++ ++allOf: ++ - $ref: "mdio.yaml#" ++ ++properties: ++ compatible: ++ const: brcm,bcm6368-mdio-mux ++ ++ "#address-cells": ++ const: 1 ++ ++ "#size-cells": ++ const: 0 ++ ++ reg: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ ++patternProperties: ++ '^mdio@[0-1]$': ++ type: object ++ properties: ++ reg: ++ maxItems: 1 ++ ++ "#address-cells": ++ const: 1 ++ ++ "#size-cells": ++ const: 0 ++ ++ required: ++ - reg ++ - "#address-cells" ++ - "#size-cells" ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ mdio0: mdio@10e000b0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,bcm6368-mdio-mux"; ++ reg = <0x10e000b0 0x6>; ++ ++ mdio_int: mdio@0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ }; ++ ++ mdio_ext: mdio@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <1>; ++ }; ++ }; diff --git a/target/linux/bmips/patches-5.10/047-v5.13-net-mdio-Add-BCM6368-MDIO-mux-bus-controller.patch b/target/linux/bmips/patches-5.10/047-v5.13-net-mdio-Add-BCM6368-MDIO-mux-bus-controller.patch new file mode 100644 index 0000000000..0f1a2cd9ca --- /dev/null +++ b/target/linux/bmips/patches-5.10/047-v5.13-net-mdio-Add-BCM6368-MDIO-mux-bus-controller.patch @@ -0,0 +1,237 @@ +From e239756717b5c866958823a1609e2ccf268435be Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Mon, 15 Mar 2021 16:45:28 +0100 +Subject: [PATCH 2/2] net: mdio: Add BCM6368 MDIO mux bus controller +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This controller is present on BCM6318, BCM6328, BCM6362, BCM6368 and BCM63268 +SoCs. + +Signed-off-by: Álvaro Fernández Rojas +Signed-off-by: David S. Miller +--- + drivers/net/mdio/Kconfig | 11 ++ + drivers/net/mdio/Makefile | 1 + + drivers/net/mdio/mdio-mux-bcm6368.c | 184 ++++++++++++++++++++++++++++ + 3 files changed, 196 insertions(+) + create mode 100644 drivers/net/mdio/mdio-mux-bcm6368.c + +--- a/drivers/net/mdio/Kconfig ++++ b/drivers/net/mdio/Kconfig +@@ -200,6 +200,17 @@ config MDIO_BUS_MUX_MESON_G12A + the amlogic g12a SoC. The multiplexers connects either the external + or the internal MDIO bus to the parent bus. + ++config MDIO_BUS_MUX_BCM6368 ++ tristate "Broadcom BCM6368 MDIO bus multiplexers" ++ depends on OF && OF_MDIO && (BMIPS_GENERIC || COMPILE_TEST) ++ select MDIO_BUS_MUX ++ default BMIPS_GENERIC ++ help ++ This module provides a driver for MDIO bus multiplexers found in ++ BCM6368 based Broadcom SoCs. This multiplexer connects one of several ++ child MDIO bus to a parent bus. Buses could be internal as well as ++ external and selection logic lies inside the same multiplexer. ++ + config MDIO_BUS_MUX_BCM_IPROC + tristate "Broadcom iProc based MDIO bus multiplexers" + depends on OF && OF_MDIO && (ARCH_BCM_IPROC || COMPILE_TEST) +--- a/drivers/net/mdio/Makefile ++++ b/drivers/net/mdio/Makefile +@@ -22,6 +22,7 @@ obj-$(CONFIG_MDIO_THUNDER) += mdio-thun + obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o + + obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o ++obj-$(CONFIG_MDIO_BUS_MUX_BCM6368) += mdio-mux-bcm6368.o + obj-$(CONFIG_MDIO_BUS_MUX_BCM_IPROC) += mdio-mux-bcm-iproc.o + obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o + obj-$(CONFIG_MDIO_BUS_MUX_MESON_G12A) += mdio-mux-meson-g12a.o +--- /dev/null ++++ b/drivers/net/mdio/mdio-mux-bcm6368.c +@@ -0,0 +1,184 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Broadcom BCM6368 mdiomux bus controller driver ++ * ++ * Copyright (C) 2021 Álvaro Fernández Rojas ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MDIOC_REG 0x0 ++#define MDIOC_EXT_MASK BIT(16) ++#define MDIOC_REG_SHIFT 20 ++#define MDIOC_PHYID_SHIFT 25 ++#define MDIOC_RD_MASK BIT(30) ++#define MDIOC_WR_MASK BIT(31) ++ ++#define MDIOD_REG 0x4 ++ ++struct bcm6368_mdiomux_desc { ++ void *mux_handle; ++ void __iomem *base; ++ struct device *dev; ++ struct mii_bus *mii_bus; ++ int ext_phy; ++}; ++ ++static int bcm6368_mdiomux_read(struct mii_bus *bus, int phy_id, int loc) ++{ ++ struct bcm6368_mdiomux_desc *md = bus->priv; ++ uint32_t reg; ++ int ret; ++ ++ __raw_writel(0, md->base + MDIOC_REG); ++ ++ reg = MDIOC_RD_MASK | ++ (phy_id << MDIOC_PHYID_SHIFT) | ++ (loc << MDIOC_REG_SHIFT); ++ if (md->ext_phy) ++ reg |= MDIOC_EXT_MASK; ++ ++ __raw_writel(reg, md->base + MDIOC_REG); ++ udelay(50); ++ ret = __raw_readw(md->base + MDIOD_REG); ++ ++ return ret; ++} ++ ++static int bcm6368_mdiomux_write(struct mii_bus *bus, int phy_id, int loc, ++ uint16_t val) ++{ ++ struct bcm6368_mdiomux_desc *md = bus->priv; ++ uint32_t reg; ++ ++ __raw_writel(0, md->base + MDIOC_REG); ++ ++ reg = MDIOC_WR_MASK | ++ (phy_id << MDIOC_PHYID_SHIFT) | ++ (loc << MDIOC_REG_SHIFT); ++ if (md->ext_phy) ++ reg |= MDIOC_EXT_MASK; ++ reg |= val; ++ ++ __raw_writel(reg, md->base + MDIOC_REG); ++ udelay(50); ++ ++ return 0; ++} ++ ++static int bcm6368_mdiomux_switch_fn(int current_child, int desired_child, ++ void *data) ++{ ++ struct bcm6368_mdiomux_desc *md = data; ++ ++ md->ext_phy = desired_child; ++ ++ return 0; ++} ++ ++static int bcm6368_mdiomux_probe(struct platform_device *pdev) ++{ ++ struct bcm6368_mdiomux_desc *md; ++ struct mii_bus *bus; ++ struct resource *res; ++ int rc; ++ ++ md = devm_kzalloc(&pdev->dev, sizeof(*md), GFP_KERNEL); ++ if (!md) ++ return -ENOMEM; ++ md->dev = &pdev->dev; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -EINVAL; ++ ++ /* ++ * Just ioremap, as this MDIO block is usually integrated into an ++ * Ethernet MAC controller register range ++ */ ++ md->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); ++ if (!md->base) { ++ dev_err(&pdev->dev, "failed to ioremap register\n"); ++ return -ENOMEM; ++ } ++ ++ md->mii_bus = devm_mdiobus_alloc(&pdev->dev); ++ if (!md->mii_bus) { ++ dev_err(&pdev->dev, "mdiomux bus alloc failed\n"); ++ return ENOMEM; ++ } ++ ++ bus = md->mii_bus; ++ bus->priv = md; ++ bus->name = "BCM6368 MDIO mux bus"; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id); ++ bus->parent = &pdev->dev; ++ bus->read = bcm6368_mdiomux_read; ++ bus->write = bcm6368_mdiomux_write; ++ bus->phy_mask = 0x3f; ++ bus->dev.of_node = pdev->dev.of_node; ++ ++ rc = mdiobus_register(bus); ++ if (rc) { ++ dev_err(&pdev->dev, "mdiomux registration failed\n"); ++ return rc; ++ } ++ ++ platform_set_drvdata(pdev, md); ++ ++ rc = mdio_mux_init(md->dev, md->dev->of_node, ++ bcm6368_mdiomux_switch_fn, &md->mux_handle, md, ++ md->mii_bus); ++ if (rc) { ++ dev_info(md->dev, "mdiomux initialization failed\n"); ++ goto out_register; ++ } ++ ++ dev_info(&pdev->dev, "Broadcom BCM6368 MDIO mux bus\n"); ++ ++ return 0; ++ ++out_register: ++ mdiobus_unregister(bus); ++ return rc; ++} ++ ++static int bcm6368_mdiomux_remove(struct platform_device *pdev) ++{ ++ struct bcm6368_mdiomux_desc *md = platform_get_drvdata(pdev); ++ ++ mdio_mux_uninit(md->mux_handle); ++ mdiobus_unregister(md->mii_bus); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm6368_mdiomux_ids[] = { ++ { .compatible = "brcm,bcm6368-mdio-mux", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, bcm6368_mdiomux_ids); ++ ++static struct platform_driver bcm6368_mdiomux_driver = { ++ .driver = { ++ .name = "bcm6368-mdio-mux", ++ .of_match_table = bcm6368_mdiomux_ids, ++ }, ++ .probe = bcm6368_mdiomux_probe, ++ .remove = bcm6368_mdiomux_remove, ++}; ++module_platform_driver(bcm6368_mdiomux_driver); ++ ++MODULE_AUTHOR("Álvaro Fernández Rojas "); ++MODULE_DESCRIPTION("BCM6368 mdiomux bus controller driver"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bmips/patches-5.10/504-net-mdio-Add-BCM6368-MDIO-mux-bus-controller.patch b/target/linux/bmips/patches-5.10/504-net-mdio-Add-BCM6368-MDIO-mux-bus-controller.patch deleted file mode 100644 index a869681312..0000000000 --- a/target/linux/bmips/patches-5.10/504-net-mdio-Add-BCM6368-MDIO-mux-bus-controller.patch +++ /dev/null @@ -1,231 +0,0 @@ -From b6ecb2bca2b8ff80ae4b1b15f09dcf071f4ceaf4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Mon, 1 Mar 2021 16:42:12 +0100 -Subject: [PATCH] net: mdio: Add BCM6368 MDIO mux bus controller -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This controller is present on BCM6318, BCM6328, BCM6362, BCM6368 and BCM63268 -SoCs. - -Signed-off-by: Álvaro Fernández Rojas ---- - drivers/net/mdio/Kconfig | 11 ++ - drivers/net/mdio/Makefile | 1 + - drivers/net/mdio/mdio-mux-bcm6368.c | 179 ++++++++++++++++++++++++++++ - 3 files changed, 191 insertions(+) - create mode 100644 drivers/net/mdio/mdio-mux-bcm6368.c - ---- a/drivers/net/mdio/Kconfig -+++ b/drivers/net/mdio/Kconfig -@@ -200,6 +200,17 @@ config MDIO_BUS_MUX_MESON_G12A - the amlogic g12a SoC. The multiplexers connects either the external - or the internal MDIO bus to the parent bus. - -+config MDIO_BUS_MUX_BCM6368 -+ tristate "Broadcom BCM6368 MDIO bus multiplexers" -+ depends on OF && OF_MDIO && (BMIPS_GENERIC || COMPILE_TEST) -+ select MDIO_BUS_MUX -+ default BMIPS_GENERIC -+ help -+ This module provides a driver for MDIO bus multiplexers found in -+ BCM6368 based Broadcom SoCs. This multiplexer connects one of several -+ child MDIO bus to a parent bus. Buses could be internal as well as -+ external and selection logic lies inside the same multiplexer. -+ - config MDIO_BUS_MUX_BCM_IPROC - tristate "Broadcom iProc based MDIO bus multiplexers" - depends on OF && OF_MDIO && (ARCH_BCM_IPROC || COMPILE_TEST) ---- a/drivers/net/mdio/Makefile -+++ b/drivers/net/mdio/Makefile -@@ -22,6 +22,7 @@ obj-$(CONFIG_MDIO_THUNDER) += mdio-thun - obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o - - obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o -+obj-$(CONFIG_MDIO_BUS_MUX_BCM6368) += mdio-mux-bcm6368.o - obj-$(CONFIG_MDIO_BUS_MUX_BCM_IPROC) += mdio-mux-bcm-iproc.o - obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o - obj-$(CONFIG_MDIO_BUS_MUX_MESON_G12A) += mdio-mux-meson-g12a.o ---- /dev/null -+++ b/drivers/net/mdio/mdio-mux-bcm6368.c -@@ -0,0 +1,179 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Broadcom BCM6368 mdiomux bus controller driver -+ * -+ * Copyright (C) 2021 Álvaro Fernández Rojas -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MDIOC_REG 0x0 -+#define MDIOC_EXT_MASK BIT(16) -+#define MDIOC_REG_SHIFT 20 -+#define MDIOC_PHYID_SHIFT 25 -+#define MDIOC_RD_MASK BIT(30) -+#define MDIOC_WR_MASK BIT(31) -+ -+#define MDIOD_REG 0x4 -+ -+struct bcm6368_mdiomux_desc { -+ void *mux_handle; -+ void __iomem *base; -+ struct device *dev; -+ struct mii_bus *mii_bus; -+ int ext_phy; -+}; -+ -+static int bcm6368_mdiomux_read(struct mii_bus *bus, int phy_id, int loc) -+{ -+ struct bcm6368_mdiomux_desc *md = bus->priv; -+ uint32_t reg; -+ int ret; -+ -+ __raw_writel(0, md->base + MDIOC_REG); -+ -+ reg = MDIOC_RD_MASK | -+ (phy_id << MDIOC_PHYID_SHIFT) | -+ (loc << MDIOC_REG_SHIFT); -+ if (md->ext_phy) -+ reg |= MDIOC_EXT_MASK; -+ -+ __raw_writel(reg, md->base + MDIOC_REG); -+ udelay(50); -+ ret = __raw_readw(md->base + MDIOD_REG); -+ -+ return ret; -+} -+ -+static int bcm6368_mdiomux_write(struct mii_bus *bus, int phy_id, int loc, -+ uint16_t val) -+{ -+ struct bcm6368_mdiomux_desc *md = bus->priv; -+ uint32_t reg; -+ -+ __raw_writel(0, md->base + MDIOC_REG); -+ -+ reg = MDIOC_WR_MASK | -+ (phy_id << MDIOC_PHYID_SHIFT) | -+ (loc << MDIOC_REG_SHIFT); -+ if (md->ext_phy) -+ reg |= MDIOC_EXT_MASK; -+ reg |= val; -+ -+ __raw_writel(reg, md->base + MDIOC_REG); -+ udelay(50); -+ -+ return 0; -+} -+ -+static int bcm6368_mdiomux_switch_fn(int current_child, int desired_child, -+ void *data) -+{ -+ struct bcm6368_mdiomux_desc *md = data; -+ -+ md->ext_phy = desired_child; -+ -+ return 0; -+} -+ -+static int bcm6368_mdiomux_probe(struct platform_device *pdev) -+{ -+ struct bcm6368_mdiomux_desc *md; -+ struct mii_bus *bus; -+ struct resource *res; -+ int rc; -+ -+ md = devm_kzalloc(&pdev->dev, sizeof(*md), GFP_KERNEL); -+ if (!md) -+ return -ENOMEM; -+ md->dev = &pdev->dev; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ /* Just ioremap, as this MDIO block is usually integrated into an -+ * Ethernet MAC controller register range -+ */ -+ md->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); -+ if (!md->base) { -+ dev_err(&pdev->dev, "failed to ioremap register\n"); -+ return -ENOMEM; -+ } -+ -+ md->mii_bus = devm_mdiobus_alloc(&pdev->dev); -+ if (!md->mii_bus) { -+ dev_err(&pdev->dev, "mdiomux bus alloc failed\n"); -+ return ENOMEM; -+ } -+ -+ bus = md->mii_bus; -+ bus->priv = md; -+ bus->name = "BCM6368 MDIO mux bus"; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id); -+ bus->parent = &pdev->dev; -+ bus->read = bcm6368_mdiomux_read; -+ bus->write = bcm6368_mdiomux_write; -+ bus->phy_mask = 0x3f; -+ bus->dev.of_node = pdev->dev.of_node; -+ -+ rc = mdiobus_register(bus); -+ if (rc) { -+ dev_err(&pdev->dev, "mdiomux registration failed\n"); -+ return rc; -+ } -+ -+ platform_set_drvdata(pdev, md); -+ -+ rc = mdio_mux_init(md->dev, md->dev->of_node, -+ bcm6368_mdiomux_switch_fn, &md->mux_handle, md, -+ md->mii_bus); -+ if (rc) { -+ dev_info(md->dev, "mdiomux initialization failed\n"); -+ goto out_register; -+ } -+ -+ dev_info(&pdev->dev, "Broadcom BCM6368 MDIO mux bus\n"); -+ -+ return 0; -+ -+out_register: -+ mdiobus_unregister(bus); -+ return rc; -+} -+ -+static int bcm6368_mdiomux_remove(struct platform_device *pdev) -+{ -+ struct bcm6368_mdiomux_desc *md = platform_get_drvdata(pdev); -+ -+ mdio_mux_uninit(md->mux_handle); -+ mdiobus_unregister(md->mii_bus); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm6368_mdiomux_ids[] = { -+ { .compatible = "brcm,bcm6368-mdio-mux", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, bcm6368_mdiomux_ids); -+ -+static struct platform_driver bcm6368_mdiomux_driver = { -+ .driver = { -+ .name = "bcm6368-mdio-mux", -+ .of_match_table = bcm6368_mdiomux_ids, -+ }, -+ .probe = bcm6368_mdiomux_probe, -+ .remove = bcm6368_mdiomux_remove, -+}; -+module_platform_driver(bcm6368_mdiomux_driver);