mirror of
				https://github.com/immortalwrt/immortalwrt.git
				synced 2025-10-30 07:49:55 +08:00 
			
		
		
		
	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@gmail.com> Link: https://github.com/openwrt/openwrt/pull/20472 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
		 Damien Dejean
					Damien Dejean
				
			
				
					committed by
					
						 Robert Marko
						Robert Marko
					
				
			
			
				
	
			
			
			 Robert Marko
						Robert Marko
					
				
			
						parent
						
							93f86627c4
						
					
				
				
					commit
					d76b97bd71
				
			| @ -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; | ||||
| 	int map[] = { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23 }; | ||||
| 	int backsds; | ||||
|  | ||||
| 	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; | ||||
| 	/* First two RTL931x SerDes have 1:1 frontend/backend mapping */ | ||||
| 	if (sds < 2) | ||||
| 		return sds; | ||||
|  | ||||
| 	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); | ||||
| 	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 */ | ||||
|  | ||||
| 	if (ret < 0) { | ||||
| 		dev_err(ctrl->dev, "SerDes I/O timed out\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
|  | ||||
| 	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[] = { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user