From: Jerome Brunet <jbrunet@baylibre.com> To: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net> Cc: Jerome Brunet <jbrunet@baylibre.com>, linux-amlogic@lists.infradead.org, Kevin Hilman <khilman@baylibre.com>, Neil Armstrong <neil.armstrong@linaro.org>, Da Xue <da@lessconfused.com>, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next 2/2] net: mdio: add amlogic gxl mdio mux support Date: Mon, 16 Jan 2023 10:16:36 +0100 [thread overview] Message-ID: <20230116091637.272923-3-jbrunet@baylibre.com> (raw) In-Reply-To: <20230116091637.272923-1-jbrunet@baylibre.com> Add support for the mdio mux and internal phy glue of the GXL SoC family Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> --- drivers/net/mdio/Kconfig | 11 ++ drivers/net/mdio/Makefile | 1 + drivers/net/mdio/mdio-mux-meson-gxl.c | 160 ++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 drivers/net/mdio/mdio-mux-meson-gxl.c diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig index bfa16826a6e1..80f3e10b1be1 100644 --- a/drivers/net/mdio/Kconfig +++ b/drivers/net/mdio/Kconfig @@ -215,6 +215,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_MESON_GXL + tristate "Amlogic GXL based MDIO bus multiplexer" + depends on ARCH_MESON || COMPILE_TEST + depends on OF_MDIO && HAS_IOMEM && COMMON_CLK + select MDIO_BUS_MUX + default m if ARCH_MESON + help + This module provides a driver for the MDIO multiplexer/glue of + the amlogic gxl 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) diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile index 15f8dc4042ce..7d4cb4c11e4e 100644 --- a/drivers/net/mdio/Makefile +++ b/drivers/net/mdio/Makefile @@ -28,5 +28,6 @@ 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 +obj-$(CONFIG_MDIO_BUS_MUX_MESON_GXL) += mdio-mux-meson-gxl.o obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o obj-$(CONFIG_MDIO_BUS_MUX_MULTIPLEXER) += mdio-mux-multiplexer.o diff --git a/drivers/net/mdio/mdio-mux-meson-gxl.c b/drivers/net/mdio/mdio-mux-meson-gxl.c new file mode 100644 index 000000000000..205095d845ea --- /dev/null +++ b/drivers/net/mdio/mdio-mux-meson-gxl.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2022 Baylibre, SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/mdio-mux.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#define ETH_REG2 0x0 +#define REG2_PHYID GENMASK(21, 0) +#define EPHY_GXL_ID 0x110181 +#define REG2_LEDACT GENMASK(23, 22) +#define REG2_LEDLINK GENMASK(25, 24) +#define REG2_DIV4SEL BIT(27) +#define REG2_ADCBYPASS BIT(30) +#define REG2_CLKINSEL BIT(31) +#define ETH_REG3 0x4 +#define REG3_ENH BIT(3) +#define REG3_CFGMODE GENMASK(6, 4) +#define REG3_AUTOMDIX BIT(7) +#define REG3_PHYADDR GENMASK(12, 8) +#define REG3_PWRUPRST BIT(21) +#define REG3_PWRDOWN BIT(22) +#define REG3_LEDPOL BIT(23) +#define REG3_PHYMDI BIT(26) +#define REG3_CLKINEN BIT(29) +#define REG3_PHYIP BIT(30) +#define REG3_PHYEN BIT(31) +#define ETH_REG4 0x8 +#define REG4_PWRUPRSTSIG BIT(0) + +#define MESON_GXL_MDIO_EXTERNAL_ID 0 +#define MESON_GXL_MDIO_INTERNAL_ID 1 + +struct gxl_mdio_mux { + void __iomem *regs; + void *mux_handle; +}; + +static int gxl_enable_internal_mdio(struct gxl_mdio_mux *priv) +{ + u32 val; + + /* Setup the internal phy */ + val = (REG3_ENH | + FIELD_PREP(REG3_CFGMODE, 0x7) | + REG3_AUTOMDIX | + FIELD_PREP(REG3_PHYADDR, 8) | + REG3_LEDPOL | + REG3_PHYMDI | + REG3_CLKINEN | + REG3_PHYIP); + + writel_relaxed(REG4_PWRUPRSTSIG, priv->regs + ETH_REG4); + writel_relaxed(val, priv->regs + ETH_REG3); + mdelay(10); + + /* Set the internal phy id */ + writel_relaxed(FIELD_PREP(REG2_PHYID, 0x110181), + priv->regs + ETH_REG2); + + /* Enable the internal phy */ + val |= REG3_PHYEN; + writel_relaxed(val, priv->regs + ETH_REG3); + writel_relaxed(0, priv->regs + ETH_REG4); + + /* The phy needs a bit of time to come up */ + mdelay(10); + + return 0; +} + +static int gxl_enable_external_mdio(struct gxl_mdio_mux *priv) +{ + /* Reset the mdio bus mux to the external phy */ + writel_relaxed(0, priv->regs + ETH_REG3); + + return 0; +} + +static int gxl_mdio_switch_fn(int current_child, int desired_child, + void *data) +{ + struct gxl_mdio_mux *priv = dev_get_drvdata(data); + + if (current_child == desired_child) + return 0; + + switch (desired_child) { + case MESON_GXL_MDIO_EXTERNAL_ID: + return gxl_enable_external_mdio(priv); + case MESON_GXL_MDIO_INTERNAL_ID: + return gxl_enable_internal_mdio(priv); + default: + return -EINVAL; + } +} + +static const struct of_device_id gxl_mdio_mux_match[] = { + { .compatible = "amlogic,gxl-mdio-mux", }, + {}, +}; +MODULE_DEVICE_TABLE(of, gxl_mdio_mux_match); + + +static int gxl_mdio_mux_probe(struct platform_device *pdev){ + struct device *dev = &pdev->dev; + struct clk *rclk; + struct gxl_mdio_mux *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + platform_set_drvdata(pdev, priv); + + priv->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + rclk = devm_clk_get_enabled(dev, "ref"); + if (IS_ERR(rclk)) + return dev_err_probe(dev, PTR_ERR(rclk), + "failed to get reference clock\n"); + + ret = mdio_mux_init(dev, dev->of_node, gxl_mdio_switch_fn, + &priv->mux_handle, dev, NULL); + if (ret) + dev_err_probe(dev, ret, "mdio multiplexer init failed\n"); + + return ret; +} + +static int gxl_mdio_mux_remove(struct platform_device *pdev) +{ + struct gxl_mdio_mux *priv = platform_get_drvdata(pdev); + + mdio_mux_uninit(priv->mux_handle); + + return 0; +} + +static struct platform_driver gxl_mdio_mux_driver = { + .probe = gxl_mdio_mux_probe, + .remove = gxl_mdio_mux_remove, + .driver = { + .name = "gxl-mdio-mux", + .of_match_table = gxl_mdio_mux_match, + }, +}; +module_platform_driver(gxl_mdio_mux_driver); + +MODULE_DESCRIPTION("Amlogic GXL MDIO multiplexer driver"); +MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); +MODULE_LICENSE("GPL v2"); -- 2.39.0
WARNING: multiple messages have this Message-ID (diff)
From: Jerome Brunet <jbrunet@baylibre.com> To: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net> Cc: Jerome Brunet <jbrunet@baylibre.com>, linux-amlogic@lists.infradead.org, Kevin Hilman <khilman@baylibre.com>, Neil Armstrong <neil.armstrong@linaro.org>, Da Xue <da@lessconfused.com>, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next 2/2] net: mdio: add amlogic gxl mdio mux support Date: Mon, 16 Jan 2023 10:16:36 +0100 [thread overview] Message-ID: <20230116091637.272923-3-jbrunet@baylibre.com> (raw) In-Reply-To: <20230116091637.272923-1-jbrunet@baylibre.com> Add support for the mdio mux and internal phy glue of the GXL SoC family Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> --- drivers/net/mdio/Kconfig | 11 ++ drivers/net/mdio/Makefile | 1 + drivers/net/mdio/mdio-mux-meson-gxl.c | 160 ++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 drivers/net/mdio/mdio-mux-meson-gxl.c diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig index bfa16826a6e1..80f3e10b1be1 100644 --- a/drivers/net/mdio/Kconfig +++ b/drivers/net/mdio/Kconfig @@ -215,6 +215,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_MESON_GXL + tristate "Amlogic GXL based MDIO bus multiplexer" + depends on ARCH_MESON || COMPILE_TEST + depends on OF_MDIO && HAS_IOMEM && COMMON_CLK + select MDIO_BUS_MUX + default m if ARCH_MESON + help + This module provides a driver for the MDIO multiplexer/glue of + the amlogic gxl 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) diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile index 15f8dc4042ce..7d4cb4c11e4e 100644 --- a/drivers/net/mdio/Makefile +++ b/drivers/net/mdio/Makefile @@ -28,5 +28,6 @@ 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 +obj-$(CONFIG_MDIO_BUS_MUX_MESON_GXL) += mdio-mux-meson-gxl.o obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o obj-$(CONFIG_MDIO_BUS_MUX_MULTIPLEXER) += mdio-mux-multiplexer.o diff --git a/drivers/net/mdio/mdio-mux-meson-gxl.c b/drivers/net/mdio/mdio-mux-meson-gxl.c new file mode 100644 index 000000000000..205095d845ea --- /dev/null +++ b/drivers/net/mdio/mdio-mux-meson-gxl.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2022 Baylibre, SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/mdio-mux.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#define ETH_REG2 0x0 +#define REG2_PHYID GENMASK(21, 0) +#define EPHY_GXL_ID 0x110181 +#define REG2_LEDACT GENMASK(23, 22) +#define REG2_LEDLINK GENMASK(25, 24) +#define REG2_DIV4SEL BIT(27) +#define REG2_ADCBYPASS BIT(30) +#define REG2_CLKINSEL BIT(31) +#define ETH_REG3 0x4 +#define REG3_ENH BIT(3) +#define REG3_CFGMODE GENMASK(6, 4) +#define REG3_AUTOMDIX BIT(7) +#define REG3_PHYADDR GENMASK(12, 8) +#define REG3_PWRUPRST BIT(21) +#define REG3_PWRDOWN BIT(22) +#define REG3_LEDPOL BIT(23) +#define REG3_PHYMDI BIT(26) +#define REG3_CLKINEN BIT(29) +#define REG3_PHYIP BIT(30) +#define REG3_PHYEN BIT(31) +#define ETH_REG4 0x8 +#define REG4_PWRUPRSTSIG BIT(0) + +#define MESON_GXL_MDIO_EXTERNAL_ID 0 +#define MESON_GXL_MDIO_INTERNAL_ID 1 + +struct gxl_mdio_mux { + void __iomem *regs; + void *mux_handle; +}; + +static int gxl_enable_internal_mdio(struct gxl_mdio_mux *priv) +{ + u32 val; + + /* Setup the internal phy */ + val = (REG3_ENH | + FIELD_PREP(REG3_CFGMODE, 0x7) | + REG3_AUTOMDIX | + FIELD_PREP(REG3_PHYADDR, 8) | + REG3_LEDPOL | + REG3_PHYMDI | + REG3_CLKINEN | + REG3_PHYIP); + + writel_relaxed(REG4_PWRUPRSTSIG, priv->regs + ETH_REG4); + writel_relaxed(val, priv->regs + ETH_REG3); + mdelay(10); + + /* Set the internal phy id */ + writel_relaxed(FIELD_PREP(REG2_PHYID, 0x110181), + priv->regs + ETH_REG2); + + /* Enable the internal phy */ + val |= REG3_PHYEN; + writel_relaxed(val, priv->regs + ETH_REG3); + writel_relaxed(0, priv->regs + ETH_REG4); + + /* The phy needs a bit of time to come up */ + mdelay(10); + + return 0; +} + +static int gxl_enable_external_mdio(struct gxl_mdio_mux *priv) +{ + /* Reset the mdio bus mux to the external phy */ + writel_relaxed(0, priv->regs + ETH_REG3); + + return 0; +} + +static int gxl_mdio_switch_fn(int current_child, int desired_child, + void *data) +{ + struct gxl_mdio_mux *priv = dev_get_drvdata(data); + + if (current_child == desired_child) + return 0; + + switch (desired_child) { + case MESON_GXL_MDIO_EXTERNAL_ID: + return gxl_enable_external_mdio(priv); + case MESON_GXL_MDIO_INTERNAL_ID: + return gxl_enable_internal_mdio(priv); + default: + return -EINVAL; + } +} + +static const struct of_device_id gxl_mdio_mux_match[] = { + { .compatible = "amlogic,gxl-mdio-mux", }, + {}, +}; +MODULE_DEVICE_TABLE(of, gxl_mdio_mux_match); + + +static int gxl_mdio_mux_probe(struct platform_device *pdev){ + struct device *dev = &pdev->dev; + struct clk *rclk; + struct gxl_mdio_mux *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + platform_set_drvdata(pdev, priv); + + priv->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + rclk = devm_clk_get_enabled(dev, "ref"); + if (IS_ERR(rclk)) + return dev_err_probe(dev, PTR_ERR(rclk), + "failed to get reference clock\n"); + + ret = mdio_mux_init(dev, dev->of_node, gxl_mdio_switch_fn, + &priv->mux_handle, dev, NULL); + if (ret) + dev_err_probe(dev, ret, "mdio multiplexer init failed\n"); + + return ret; +} + +static int gxl_mdio_mux_remove(struct platform_device *pdev) +{ + struct gxl_mdio_mux *priv = platform_get_drvdata(pdev); + + mdio_mux_uninit(priv->mux_handle); + + return 0; +} + +static struct platform_driver gxl_mdio_mux_driver = { + .probe = gxl_mdio_mux_probe, + .remove = gxl_mdio_mux_remove, + .driver = { + .name = "gxl-mdio-mux", + .of_match_table = gxl_mdio_mux_match, + }, +}; +module_platform_driver(gxl_mdio_mux_driver); + +MODULE_DESCRIPTION("Amlogic GXL MDIO multiplexer driver"); +MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); +MODULE_LICENSE("GPL v2"); -- 2.39.0 _______________________________________________ linux-amlogic mailing list linux-amlogic@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-amlogic
next prev parent reply other threads:[~2023-01-16 9:17 UTC|newest] Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-01-16 9:16 [PATCH net-next 0/2] net: mdio: add amlogic gxl mdio mux support Jerome Brunet 2023-01-16 9:16 ` Jerome Brunet 2023-01-16 9:16 ` [PATCH net-next 1/2] dt-bindings: net: add amlogic gxl mdio multiplexer Jerome Brunet 2023-01-16 9:16 ` Jerome Brunet 2023-01-17 8:31 ` Krzysztof Kozlowski 2023-01-17 8:31 ` Krzysztof Kozlowski 2023-01-17 9:05 ` Jerome Brunet 2023-01-17 9:05 ` Jerome Brunet 2023-01-17 10:39 ` Krzysztof Kozlowski 2023-01-17 10:39 ` Krzysztof Kozlowski 2023-01-16 9:16 ` Jerome Brunet [this message] 2023-01-16 9:16 ` [PATCH net-next 2/2] net: mdio: add amlogic gxl mdio mux support Jerome Brunet 2023-01-16 12:11 ` Simon Horman 2023-01-16 12:11 ` Simon Horman 2023-01-16 13:27 ` Jerome Brunet 2023-01-16 13:27 ` Jerome Brunet 2023-01-16 13:51 ` Simon Horman 2023-01-16 13:51 ` Simon Horman 2023-01-18 2:56 ` Andrew Lunn 2023-01-18 2:56 ` Andrew Lunn 2023-01-18 12:41 ` Simon Horman 2023-01-18 12:41 ` Simon Horman 2023-01-18 3:02 ` Andrew Lunn 2023-01-18 3:02 ` Andrew Lunn 2023-01-19 10:55 ` Jerome Brunet 2023-01-19 10:55 ` Jerome Brunet 2023-01-19 17:17 ` Andrew Lunn 2023-01-19 17:17 ` Andrew Lunn 2023-01-20 10:16 ` Jerome Brunet 2023-01-20 10:16 ` Jerome Brunet 2023-01-18 3:08 ` [PATCH net-next 0/2] " Andrew Lunn 2023-01-18 3:08 ` Andrew Lunn 2023-01-19 10:42 ` Jerome Brunet 2023-01-19 10:42 ` Jerome Brunet 2023-01-19 17:21 ` Andrew Lunn 2023-01-19 17:21 ` Andrew Lunn
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230116091637.272923-3-jbrunet@baylibre.com \ --to=jbrunet@baylibre.com \ --cc=da@lessconfused.com \ --cc=davem@davemloft.net \ --cc=devicetree@vger.kernel.org \ --cc=khilman@baylibre.com \ --cc=linux-amlogic@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=neil.armstrong@linaro.org \ --cc=netdev@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.