[openwrt/openwrt] realtek: add serdes mapping for rtl930x

LEDE Commits lede-commits at lists.infradead.org
Sun Oct 26 03:24:55 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/d76b97bd7174d77978aed081189affaca1df286d

commit d76b97bd7174d77978aed081189affaca1df286d
Author: Damien Dejean <dam.dejean at gmail.com>
AuthorDate: Sat Oct 18 17:01:24 2025 +0200

    realtek: add serdes mapping for rtl930x
    
    On the RTL930x series the serdes #3 is backed by serdes #10 when pages
    0, 1, 2 or 3 are accessed [1]. This changeset modifies the sds mapping
    function from a single implementation for the 3 families to one
    implementation per chip family. In particular it implements the mapping
    required for the rtl930x one.
    
    [1] https://github.com/ddejean/dms-1250-oss-release/blob/main/sdk/sdk_rtk_switch/rtk-sdk/src/dal/longan/dal_longan_sds.c#L624
    
    Signed-off-by: Damien Dejean <dam.dejean at gmail.com>
    Link: https://github.com/openwrt/openwrt/pull/20472
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../drivers/net/mdio/mdio-realtek-otto-serdes.c    | 134 ++++++++++++---------
 1 file changed, 76 insertions(+), 58 deletions(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto-serdes.c b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto-serdes.c
index 6ae8f15e41..46a426a69a 100644
--- a/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto-serdes.c
+++ b/target/linux/realtek/files-6.12/drivers/net/mdio/mdio-realtek-otto-serdes.c
@@ -52,6 +52,7 @@ struct rtsds_config {
 	int sds_cnt;
 	int page_cnt;
 	int base;
+	int (*get_backing_sds)(struct rtsds_ctrl *ctrl, int sds, int page);
 	int (*read)(struct rtsds_ctrl *ctrl, int sds, int page, int regnum);
 	int (*write)(struct rtsds_ctrl *ctrl, int sds, int page, int regnum, u16 value);
 };
@@ -68,24 +69,6 @@ static bool rtsds_mmd_to_sds(struct rtsds_ctrl *ctrl, int addr, int devad, int m
 		 devad != MDIO_MMD_VEND1);
 }
 
-static int rtsds_get_backing_sds(struct rtsds_ctrl *ctrl, int sds, int page)
-{
-	int map[] = { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23 };
-	int backsds;
-
-	/* non-RTL931x and first two RTL931x SerDes have 1:1 frontend/backend mapping */
-	if (ctrl->cfg->base != RTSDS_931X_BASE || sds < 2)
-		return sds;
-
-	backsds = map[sds];
-	if (sds & 1)
-		backsds += (page >> 6); /* distribute "odd" to 3 background SerDes */
-	else
-		backsds += (page >> 7); /* distribute "even" to 2 background SerDes */
-
-	return backsds;
-}
-
 #ifdef CONFIG_DEBUG_FS
 
 /*
@@ -137,7 +120,7 @@ static int rtsds_dbg_registers_show(struct seq_file *seqf, void *unused)
 	do {
 		subpage = RTSDS_SUBPAGE(page);
 		if (!subpage) {
-			seq_printf(seqf, "Back SDS %02d:", rtsds_get_backing_sds(ctrl, sds, page));
+			seq_printf(seqf, "Back SDS %02d:", ctrl->cfg->get_backing_sds(ctrl, sds, page));
 			for (regnum = 0; regnum < RTSDS_REG_CNT; regnum++)
 				seq_printf(seqf, "   %02X", regnum);
 			seq_puts(seqf, "\n");
@@ -302,6 +285,32 @@ static int rtsds_839x_write(struct rtsds_ctrl *ctrl, int sds, int page, int regn
 	return regmap_write(ctrl->map, ctrl->cfg->base + offset, write_value);
 }
 
+static int rtsds_83xx_get_backing_sds(struct rtsds_ctrl *ctrl, int sds, int page)
+{
+	return sds;
+}
+
+static int rtsds_rt93xx_io(struct rtsds_ctrl *ctrl, int sds, int page, int regnum, int cmd)
+{
+	int ret, op, value;
+
+	op = FIELD_PREP(RTSDS_93XX_CMD_SDS_MASK, sds) |
+	     FIELD_PREP(RTSDS_93XX_CMD_PAGE_MASK, page) |
+	     FIELD_PREP(RTSDS_93XX_CMD_REG_MASK, regnum) |
+	     RTSDS_93XX_CMD_BUSY | cmd;
+
+	regmap_write(ctrl->map, ctrl->cfg->base, op);
+	ret = regmap_read_poll_timeout(ctrl->map, ctrl->cfg->base, value,
+				       !(value & RTSDS_93XX_CMD_BUSY), 30, 1000000);
+
+	if (ret < 0) {
+		dev_err(ctrl->dev, "SerDes I/O timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 /*
  * RTL93xx targets use a shared implementation. Their SerDes data is accessed through two IO
  * registers which simulate commands to an internal MDIO bus.
@@ -311,7 +320,16 @@ static int rtsds_839x_write(struct rtsds_ctrl *ctrl, int sds, int page, int regn
  * - SerDes 0-1 exist on the RTL9301 and 9302B and are QSGMII capable
  * - SerDes 2-9 are USXGMII capabable with either quad or single configuration
  * - SerDes 10-11 are 10GBase-R capable
- *
+ */
+static int rtsds_930x_get_backing_sds(struct rtsds_ctrl *ctrl, int sds, int page)
+{
+	if (sds == 3 && page < 4)
+		return 10;
+
+	return sds;
+}
+
+/*
  * The RTL931x family has 14 "frontend" SerDes that are cascaded. All operations (e.g. reset) work
  * on this frontend view while their registers are distributed over a total of least 26 background
  * SerDes with 64 pages and 32 registers. Three types of SerDes exist:
@@ -342,26 +360,22 @@ static int rtsds_839x_write(struct rtsds_ctrl *ctrl, int sds, int page, int regn
  * page 0x40-0x7f (digi 1):	page 0x00-0x3f back SDS		page 0x00-0x3f back SDS+1
  * page 0x80-0xbf (digi 2):	page 0x00-0x3f back SDS+1	page 0x00-0x3f back SDS+2
  */
-
-static int rtsds_rt93xx_io(struct rtsds_ctrl *ctrl, int sds, int page, int regnum, int cmd)
+static int rtsds_931x_get_backing_sds(struct rtsds_ctrl *ctrl, int sds, int page)
 {
-	int ret, op, value;
-
-	op = FIELD_PREP(RTSDS_93XX_CMD_SDS_MASK, sds) |
-	     FIELD_PREP(RTSDS_93XX_CMD_PAGE_MASK, page) |
-	     FIELD_PREP(RTSDS_93XX_CMD_REG_MASK, regnum) |
-	     RTSDS_93XX_CMD_BUSY | cmd;
+	int map[] = { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23 };
+	int backsds;
 
-	regmap_write(ctrl->map, ctrl->cfg->base, op);
-	ret = regmap_read_poll_timeout(ctrl->map, ctrl->cfg->base, value,
-				       !(value & RTSDS_93XX_CMD_BUSY), 30, 1000000);
+	/* First two RTL931x SerDes have 1:1 frontend/backend mapping */
+	if (sds < 2)
+		return sds;
 
-	if (ret < 0) {
-		dev_err(ctrl->dev, "SerDes I/O timed out\n");
-		return -ETIMEDOUT;
-	}
+	backsds = map[sds];
+	if (sds & 1)
+		backsds += (page >> 6); /* distribute "odd" to 3 background SerDes */
+	else
+		backsds += (page >> 7); /* distribute "even" to 2 background SerDes */
 
-	return 0;
+	return backsds;
 }
 
 static int rtsds_93xx_read(struct rtsds_ctrl *ctrl, int sds, int page, int regnum)
@@ -369,7 +383,7 @@ static int rtsds_93xx_read(struct rtsds_ctrl *ctrl, int sds, int page, int regnu
 	int subpage = RTSDS_SUBPAGE(page);
 	int ret, backsds, value;
 
-	backsds = rtsds_get_backing_sds(ctrl, sds, page);
+	backsds = ctrl->cfg->get_backing_sds(ctrl, sds, page);
 	ret = rtsds_rt93xx_io(ctrl, backsds, subpage, regnum, RTSDS_93XX_CMD_READ);
 	if (ret)
 		return ret;
@@ -384,7 +398,7 @@ static int rtsds_93xx_write(struct rtsds_ctrl *ctrl, int sds, int page, int regn
 	int subpage = RTSDS_SUBPAGE(page);
 	int ret, backsds;
 
-	backsds = rtsds_get_backing_sds(ctrl, sds, page);
+	backsds = ctrl->cfg->get_backing_sds(ctrl, sds, page);
 	ret = regmap_write(ctrl->map, ctrl->cfg->base + 4, value);
 	if (ret)
 		return ret;
@@ -458,35 +472,39 @@ static int rtsds_probe(struct platform_device *pdev)
 }
 
 static const struct rtsds_config rtsds_838x_cfg = {
-	.sds_cnt	= RTSDS_838X_SDS_CNT,
-	.page_cnt	= RTSDS_838X_PAGE_CNT,
-	.base		= RTSDS_838X_BASE,
-	.read		= rtsds_838x_read,
-	.write		= rtsds_838x_write,
+	.sds_cnt		= RTSDS_838X_SDS_CNT,
+	.page_cnt		= RTSDS_838X_PAGE_CNT,
+	.base			= RTSDS_838X_BASE,
+	.get_backing_sds	= rtsds_83xx_get_backing_sds,
+	.read			= rtsds_838x_read,
+	.write			= rtsds_838x_write,
 };
 
 static const struct rtsds_config rtsds_839x_cfg = {
-	.sds_cnt	= RTSDS_839X_SDS_CNT,
-	.page_cnt	= RTSDS_839X_PAGE_CNT,
-	.base		= RTSDS_839X_BASE,
-	.read		= rtsds_839x_read,
-	.write		= rtsds_839x_write,
+	.sds_cnt		= RTSDS_839X_SDS_CNT,
+	.page_cnt		= RTSDS_839X_PAGE_CNT,
+	.base			= RTSDS_839X_BASE,
+	.get_backing_sds	= rtsds_83xx_get_backing_sds,
+	.read			= rtsds_839x_read,
+	.write			= rtsds_839x_write,
 };
 
 static const struct rtsds_config rtsds_930x_cfg = {
-	.sds_cnt	= RTSDS_930X_SDS_CNT,
-	.page_cnt	= RTSDS_930X_PAGE_CNT,
-	.base		= RTSDS_930X_BASE,
-	.read		= rtsds_93xx_read,
-	.write		= rtsds_93xx_write,
+	.sds_cnt		= RTSDS_930X_SDS_CNT,
+	.page_cnt		= RTSDS_930X_PAGE_CNT,
+	.base			= RTSDS_930X_BASE,
+	.get_backing_sds	= rtsds_930x_get_backing_sds,
+	.read			= rtsds_93xx_read,
+	.write			= rtsds_93xx_write,
 };
 
 static const struct rtsds_config rtsds_931x_cfg = {
-	.sds_cnt	= RTSDS_931X_SDS_CNT,
-	.page_cnt	= RTSDS_931X_PAGE_CNT,
-	.base		= RTSDS_931X_BASE,
-	.read		= rtsds_93xx_read,
-	.write		= rtsds_93xx_write,
+	.sds_cnt		= RTSDS_931X_SDS_CNT,
+	.page_cnt		= RTSDS_931X_PAGE_CNT,
+	.base			= RTSDS_931X_BASE,
+	.get_backing_sds	= rtsds_931x_get_backing_sds,
+	.read			= rtsds_93xx_read,
+	.write			= rtsds_93xx_write,
 };
 
 static const struct of_device_id rtsds_of_match[] = {




More information about the lede-commits mailing list