From 52ffef647152578ba89d2e4c1f9f2f869a3fc8a8 Mon Sep 17 00:00:00 2001 From: Sander Vanheule Date: Sat, 18 Jan 2025 13:28:44 +0100 Subject: [PATCH] realtek: Update aux-mdio driver For RTL839x, the driver was producing frequent timeouts on bus accesses. Increasing the timeout to the one from a recent Realtek SDK resolves these timeouts. To minimize overhead on different SoCs, each controller can specify their own timeout. This also add support for the register format as used on RTL93xx. Support is added for the RTL930x "ext gpio" controller. Signed-off-by: Sander Vanheule --- ...dd-Realtek-Otto-auxiliary-controller.patch | 130 +++++++++++------- 1 file changed, 82 insertions(+), 48 deletions(-) diff --git a/target/linux/realtek/patches-6.6/723-net-mdio-Add-Realtek-Otto-auxiliary-controller.patch b/target/linux/realtek/patches-6.6/723-net-mdio-Add-Realtek-Otto-auxiliary-controller.patch index a58cc496ef..7315899b3f 100644 --- a/target/linux/realtek/patches-6.6/723-net-mdio-Add-Realtek-Otto-auxiliary-controller.patch +++ b/target/linux/realtek/patches-6.6/723-net-mdio-Add-Realtek-Otto-auxiliary-controller.patch @@ -1,21 +1,21 @@ -From c7ddb74c981c1a29bad82d555d08724aca93b687 Mon Sep 17 00:00:00 2001 +From ffb7da9aa25765b2115e7ff3ee4f6dafa60f5421 Mon Sep 17 00:00:00 2001 From: Sander Vanheule Date: Fri, 27 Dec 2024 14:55:31 +0100 Subject: [PATCH] net: mdio: Add Realtek Otto auxiliary controller -SoCs in Realtek's Otto platform such as the RTL8380 and RTL8391 have a -simple auxiliary MDIO controller that is commonly used to manage RTL8231 -GPIO expanders on switch devices. +SoCs in Realtek's Otto platform such as the RTL8380, RTL8391, and +RTL9302 have a simple auxiliary MDIO controller that is commonly used to +manage RTL8231 GPIO expanders on switch devices. -Add a new MDIO controller driver supporting the RTL838x (maple) and -RTL839x (cypress) SoCs. +Add a new MDIO controller driver supporting the RTL838x (maple), RTL839x +(cypress), and RTL930x (longan) SoCs. Signed-off-by: Sander Vanheule --- drivers/net/mdio/Kconfig | 10 ++ drivers/net/mdio/Makefile | 1 + - drivers/net/mdio/mdio-realtek-otto-aux.c | 129 +++++++++++++++++++++++ - 3 files changed, 140 insertions(+) + drivers/net/mdio/mdio-realtek-otto-aux.c | 175 +++++++++++++++++++++++ + 3 files changed, 186 insertions(+) create mode 100644 drivers/net/mdio/mdio-realtek-otto-aux.c --- a/drivers/net/mdio/Kconfig @@ -49,7 +49,7 @@ Signed-off-by: Sander Vanheule obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o --- /dev/null +++ b/drivers/net/mdio/mdio-realtek-otto-aux.c -@@ -0,0 +1,141 @@ +@@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include @@ -64,65 +64,95 @@ Signed-off-by: Sander Vanheule + +#define RTL8380_EXT_GPIO_INDIRECT_ACCESS 0xA09C +#define RTL8390_EXT_GPIO_INDIRECT_ACCESS 0x0224 ++#define RTL9300_EXT_GPIO_INDIRECT_ACCESS 0xC620 + -+#define RTL83XX_AUX_MDIO_DATA GENMASK(31, 16) -+#define RTL83XX_AUX_MDIO_REG GENMASK(11, 7) -+#define RTL83XX_AUX_MDIO_PHY_ADDR GENMASK(6, 2) -+#define RTL83XX_AUX_MDIO_WRITE BIT(1) -+#define RTL83XX_AUX_MDIO_READ 0 -+#define RTL83XX_AUX_MDIO_EXEC BIT(0) ++#define RTL83XX_AUX_MDIO_DATA_OFFSET 16 ++#define RTL83XX_AUX_MDIO_RCMD_FAIL 0 ++ ++#define RTL93XX_AUX_MDIO_DATA_OFFSET 12 ++#define RTL93XX_AUX_MDIO_RCMD_FAIL BIT(28) ++ ++#define REALTEK_AUX_MDIO_REG GENMASK(11, 7) ++#define REALTEK_AUX_MDIO_PHY_ADDR GENMASK(6, 2) ++#define REALTEK_AUX_MDIO_WRITE BIT(1) ++#define REALTEK_AUX_MDIO_READ 0 ++#define REALTEK_AUX_MDIO_EXEC BIT(0) ++ ++struct realtek_aux_mdio_info { ++ unsigned int cmd_reg; ++ unsigned int data_offset; ++ unsigned int rcmd_fail_mask; ++ unsigned int timeout_us; ++}; ++ ++static const struct realtek_aux_mdio_info info_rtl838x = { ++ .cmd_reg = RTL8380_EXT_GPIO_INDIRECT_ACCESS, ++ .data_offset = RTL83XX_AUX_MDIO_DATA_OFFSET, ++ .rcmd_fail_mask = RTL83XX_AUX_MDIO_RCMD_FAIL, ++ .timeout_us = 1700, ++}; ++ ++static const struct realtek_aux_mdio_info info_rtl839x = { ++ .cmd_reg = RTL8390_EXT_GPIO_INDIRECT_ACCESS, ++ .data_offset = RTL83XX_AUX_MDIO_DATA_OFFSET, ++ .rcmd_fail_mask = RTL83XX_AUX_MDIO_RCMD_FAIL, ++ .timeout_us = 4120, ++}; ++ ++static const struct realtek_aux_mdio_info info_rtl930x = { ++ .cmd_reg = RTL9300_EXT_GPIO_INDIRECT_ACCESS, ++ .data_offset = RTL93XX_AUX_MDIO_DATA_OFFSET, ++ .rcmd_fail_mask = RTL93XX_AUX_MDIO_RCMD_FAIL, ++ .timeout_us = 19000, ++}; + +struct realtek_aux_mdio_ctrl { + struct device *dev; + struct regmap *map; -+ unsigned int cmd_reg; ++ const struct realtek_aux_mdio_info *info; +}; + +#define mii_bus_to_ctrl(bus) ((struct realtek_aux_mdio_ctrl *) bus->priv) + -+static int rtl83xx_aux_mdio_cmd(struct realtek_aux_mdio_ctrl *ctrl, int addr, int regnum, ++static int realtek_aux_mdio_cmd(struct realtek_aux_mdio_ctrl *ctrl, int addr, int regnum, + u32 rw_bit, u16 *data) +{ -+ unsigned int mask_volatile; + unsigned int cmd; -+ unsigned int run; + int err; + -+ cmd = rw_bit | RTL83XX_AUX_MDIO_EXEC; -+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_PHY_ADDR, addr); -+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_REG, regnum); ++ cmd = rw_bit | REALTEK_AUX_MDIO_EXEC; ++ cmd |= FIELD_PREP(REALTEK_AUX_MDIO_PHY_ADDR, addr); ++ cmd |= FIELD_PREP(REALTEK_AUX_MDIO_REG, regnum); + -+ mask_volatile = RTL83XX_AUX_MDIO_EXEC; ++ if (rw_bit == REALTEK_AUX_MDIO_WRITE) ++ cmd |= *data << ctrl->info->data_offset; + -+ if (rw_bit == RTL83XX_AUX_MDIO_WRITE) -+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_DATA, *data); -+ else -+ mask_volatile |= RTL83XX_AUX_MDIO_DATA; ++ err = regmap_write(ctrl->map, ctrl->info->cmd_reg, cmd); ++ if (err) ++ return err; + -+ err = regmap_write(ctrl->map, ctrl->cmd_reg, cmd); ++ err = regmap_read_poll_timeout_atomic(ctrl->map, ctrl->info->cmd_reg, cmd, ++ !(cmd & REALTEK_AUX_MDIO_EXEC), 3, ctrl->info->timeout_us); + if (err) + return err; + -+ err = regmap_read_poll_timeout_atomic(ctrl->map, ctrl->cmd_reg, run, (run != cmd), 3, 100); ++ if (rw_bit == REALTEK_AUX_MDIO_READ) { ++ if (cmd & ctrl->info->rcmd_fail_mask) ++ return -EIO; + -+ if ((run & ~mask_volatile) != (cmd & ~mask_volatile)) { -+ dev_err(ctrl->dev, "Command modified. Is offloading still active?"); -+ return -EIO; ++ *data = (cmd >> ctrl->info->data_offset) & GENMASK(15, 0); + } + -+ if (!err && (rw_bit == RTL83XX_AUX_MDIO_READ)) -+ *data = FIELD_GET(RTL83XX_AUX_MDIO_DATA, run); -+ -+ return err; ++ return 0; +} + -+static int rtl83xx_aux_mdio_read(struct mii_bus *bus, int addr, int regnum) ++static int realtek_aux_mdio_read(struct mii_bus *bus, int addr, int regnum) +{ + struct realtek_aux_mdio_ctrl *ctrl = mii_bus_to_ctrl(bus); + u16 data; + int err; + -+ err = rtl83xx_aux_mdio_cmd(ctrl, addr, regnum, RTL83XX_AUX_MDIO_READ, &data); ++ err = realtek_aux_mdio_cmd(ctrl, addr, regnum, REALTEK_AUX_MDIO_READ, &data); + + if (err) + return err; @@ -130,11 +160,11 @@ Signed-off-by: Sander Vanheule + return data; +} + -+static int rtl83xx_aux_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val) ++static int realtek_aux_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val) +{ + struct realtek_aux_mdio_ctrl *ctrl = mii_bus_to_ctrl(bus); + -+ return rtl83xx_aux_mdio_cmd(ctrl, addr, regnum, RTL83XX_AUX_MDIO_WRITE, &val); ++ return realtek_aux_mdio_cmd(ctrl, addr, regnum, REALTEK_AUX_MDIO_WRITE, &val); +} + +static int realtek_aux_mdio_probe(struct platform_device *pdev) @@ -149,16 +179,16 @@ Signed-off-by: Sander Vanheule + + ctrl = bus->priv; + ctrl->dev = &pdev->dev; -+ ctrl->cmd_reg = (unsigned int) device_get_match_data(ctrl->dev); ++ ctrl->info = (const struct realtek_aux_mdio_info *) device_get_match_data(ctrl->dev); + ctrl->map = syscon_node_to_regmap(np->parent); + if (IS_ERR(ctrl->map)) + return PTR_ERR(ctrl->map); + -+ bus->name = "RTL83xx auxiliary MDIO bus"; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "rtl83xx-aux-mdio") ; ++ bus->name = "Realtek auxiliary MDIO bus"; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "realtek-aux-mdio") ; + bus->parent = ctrl->dev; -+ bus->read = rtl83xx_aux_mdio_read; -+ bus->write = rtl83xx_aux_mdio_write; ++ bus->read = realtek_aux_mdio_read; ++ bus->write = realtek_aux_mdio_write; + /* Don't have interrupts */ + for (unsigned int i = 0; i < PHY_MAX_ADDR; i++) + bus->irq[i] = PHY_POLL; @@ -169,11 +199,15 @@ Signed-off-by: Sander Vanheule +static const struct of_device_id realtek_aux_mdio_of_match[] = { + { + .compatible = "realtek,rtl8380-aux-mdio", -+ .data = (void *) RTL8380_EXT_GPIO_INDIRECT_ACCESS, ++ .data = &info_rtl838x, + }, + { + .compatible = "realtek,rtl8390-aux-mdio", -+ .data = (void *) RTL8390_EXT_GPIO_INDIRECT_ACCESS, ++ .data = &info_rtl839x, ++ }, ++ { ++ .compatible = "realtek,rtl9300-aux-mdio", ++ .data = &info_rtl930x, + }, + { /* sentinel */ } +}; @@ -189,5 +223,5 @@ Signed-off-by: Sander Vanheule +module_platform_driver(realtek_aux_mdio_driver); + +MODULE_AUTHOR("Sander Vanheule "); -+MODULE_DESCRIPTION("Realtek RTL83xx auxiliary MDIO bus"); ++MODULE_DESCRIPTION("Realtek otto auxiliary MDIO bus"); +MODULE_LICENSE("GPL v2"); -- 2.30.2