drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c

Source file repositories/reference/linux-study-clean/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
Extension
.c
Size
19177 bytes
Lines
750
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 mixel_dphy_devdata {
	u8 reg_tx_rcal;
	u8 reg_auto_pd_en;
	u8 reg_rxlprp;
	u8 reg_rxcdrp;
	u8 reg_rxhs_settle;
	bool is_combo;	/* MIPI DPHY and LVDS PHY combo */
};

static const struct mixel_dphy_devdata mixel_dphy_devdata[] = {
	[MIXEL_IMX8MQ] = {
		.reg_tx_rcal = 0x38,
		.reg_auto_pd_en = 0x3c,
		.reg_rxlprp = 0x40,
		.reg_rxcdrp = 0x44,
		.reg_rxhs_settle = 0x48,
		.is_combo = false,
	},
	[MIXEL_IMX8QXP] = {
		.is_combo = true,
	},
};

struct mixel_dphy_cfg {
	/* DPHY PLL parameters */
	u32 cm;
	u32 cn;
	u32 co;
	/* DPHY register values */
	u8 mc_prg_hs_prepare;
	u8 m_prg_hs_prepare;
	u8 mc_prg_hs_zero;
	u8 m_prg_hs_zero;
	u8 mc_prg_hs_trail;
	u8 m_prg_hs_trail;
	u8 rxhs_settle;
};

struct mixel_dphy_priv {
	struct mixel_dphy_cfg cfg;
	struct regmap *regmap;
	struct regmap *lvds_regmap;
	struct clk *phy_ref_clk;
	const struct mixel_dphy_devdata *devdata;
	struct imx_sc_ipc *ipc_handle;
	bool is_slave;
	int id;
};

static const struct regmap_config mixel_dphy_regmap_config = {
	.reg_bits = 8,
	.val_bits = 32,
	.reg_stride = 4,
	.max_register = DPHY_REG_BYPASS_PLL,
	.name = "mipi-dphy",
};

static int phy_write(struct phy *phy, u32 value, unsigned int reg)
{
	struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
	int ret;

	ret = regmap_write(priv->regmap, reg, value);
	if (ret < 0)
		dev_err(&phy->dev, "Failed to write DPHY reg %d: %d\n", reg,
			ret);
	return ret;
}

/*
 * Find a ratio close to the desired one using continued fraction
 * approximation ending either at exact match or maximum allowed
 * nominator, denominator.
 */
static void get_best_ratio(u32 *pnum, u32 *pdenom, u32 max_n, u32 max_d)
{
	u32 a = *pnum;
	u32 b = *pdenom;
	u32 c;
	u32 n[] = {0, 1};
	u32 d[] = {1, 0};
	u32 whole;
	unsigned int i = 1;

	while (b) {
		i ^= 1;
		whole = a / b;
		n[i] += (n[i ^ 1] * whole);
		d[i] += (d[i ^ 1] * whole);
		if ((n[i] > max_n) || (d[i] > max_d)) {

Annotation

Implementation Notes