drivers/phy/mscc/phy-ocelot-serdes.c

Source file repositories/reference/linux-study-clean/drivers/phy/mscc/phy-ocelot-serdes.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/mscc/phy-ocelot-serdes.c
Extension
.c
Size
15149 bytes
Lines
551
Domain
Driver Families
Bucket
drivers/phy
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct serdes_ctrl {
	struct regmap		*regs;
	struct device		*dev;
	struct phy		*phys[SERDES_MAX];
};

struct serdes_macro {
	u8			idx;
	/* Not used when in QSGMII or PCIe mode */
	int			port;
	struct serdes_ctrl	*ctrl;
};

#define MCB_S6G_CFG_TIMEOUT     50

static int __serdes_write_mcb_s6g(struct regmap *regmap, u8 macro, u32 op)
{
	unsigned int regval = 0;

	regmap_write(regmap, HSIO_MCB_S6G_ADDR_CFG, op |
		     HSIO_MCB_S6G_ADDR_CFG_SERDES6G_ADDR(BIT(macro)));

	return regmap_read_poll_timeout(regmap, HSIO_MCB_S6G_ADDR_CFG, regval,
					(regval & op) != op, 100,
					MCB_S6G_CFG_TIMEOUT * 1000);
}

static int serdes_commit_mcb_s6g(struct regmap *regmap, u8 macro)
{
	return __serdes_write_mcb_s6g(regmap, macro,
		HSIO_MCB_S6G_ADDR_CFG_SERDES6G_WR_ONE_SHOT);
}

static int serdes_update_mcb_s6g(struct regmap *regmap, u8 macro)
{
	return __serdes_write_mcb_s6g(regmap, macro,
		HSIO_MCB_S6G_ADDR_CFG_SERDES6G_RD_ONE_SHOT);
}

static int serdes_init_s6g(struct regmap *regmap, u8 serdes, int mode)
{
	u32 pll_fsm_ctrl_data;
	u32 ob_ena1v_mode;
	u32 des_bw_ana;
	u32 ob_ena_cas;
	u32 if_mode;
	u32 ob_lev;
	u32 qrate;
	int ret;

	if (mode == PHY_INTERFACE_MODE_QSGMII) {
		pll_fsm_ctrl_data = 120;
		ob_ena1v_mode = 0;
		ob_ena_cas = 0;
		des_bw_ana = 5;
		ob_lev = 24;
		if_mode = 3;
		qrate = 0;
	} else {
		pll_fsm_ctrl_data = 60;
		ob_ena1v_mode = 1;
		ob_ena_cas = 2;
		des_bw_ana = 3;
		ob_lev = 48;
		if_mode = 1;
		qrate = 1;
	}

	ret = serdes_update_mcb_s6g(regmap, serdes);
	if (ret)
		return ret;

	/* Test pattern */

	regmap_update_bits(regmap, HSIO_S6G_COMMON_CFG,
			   HSIO_S6G_COMMON_CFG_SYS_RST, 0);

	regmap_update_bits(regmap, HSIO_S6G_PLL_CFG,
			   HSIO_S6G_PLL_CFG_PLL_FSM_ENA, 0);

	regmap_update_bits(regmap, HSIO_S6G_IB_CFG,
			   HSIO_S6G_IB_CFG_IB_SIG_DET_ENA |
			   HSIO_S6G_IB_CFG_IB_REG_ENA |
			   HSIO_S6G_IB_CFG_IB_SAM_ENA |
			   HSIO_S6G_IB_CFG_IB_EQZ_ENA |
			   HSIO_S6G_IB_CFG_IB_CONCUR |
			   HSIO_S6G_IB_CFG_IB_CAL_ENA,
			   HSIO_S6G_IB_CFG_IB_SIG_DET_ENA |
			   HSIO_S6G_IB_CFG_IB_REG_ENA |
			   HSIO_S6G_IB_CFG_IB_SAM_ENA |

Annotation

Implementation Notes