drivers/phy/rockchip/phy-rockchip-inno-csidphy.c

Source file repositories/reference/linux-study-clean/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
Extension
.c
Size
15854 bytes
Lines
537
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 dphy_reg {
	u32 offset;
	u32 mask;
	u32 shift;
	u8 valid;
};

#define PHY_REG(_offset, _width, _shift) \
	{ .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, .valid = 1, }

static const struct dphy_reg rk1808_grf_dphy_regs[] = {
	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0),
	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 1, 8),
	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 4),
};

static const struct dphy_reg rk3326_grf_dphy_regs[] = {
	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 4, 0),
	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 1, 8),
	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 4, 4),
};

static const struct dphy_reg rk3368_grf_dphy_regs[] = {
	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3368_GRF_SOC_CON6_OFFSET, 4, 8),
};

static const struct dphy_reg rk3568_grf_dphy_regs[] = {
	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3568_GRF_VI_CON0, 4, 0),
	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 4, 4),
	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 1, 8),
};

static const struct dphy_reg rk3588_grf_dphy_regs[] = {
	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 0),
	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 4),
	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 1, 8),
};

struct hsfreq_range {
	u32 range_h;
	u8 cfg_bit;
};

struct dphy_drv_data {
	int pwrctl_offset;
	int ths_settle_offset;
	int calib_offset;
	const struct hsfreq_range *hsfreq_ranges;
	int num_hsfreq_ranges;
	const struct dphy_reg *grf_regs;
	const char *const *resets;
	unsigned int resets_num;
};

struct rockchip_inno_csidphy {
	struct device *dev;
	void __iomem *phy_base;
	struct clk *pclk;
	struct regmap *grf;
	struct reset_control_bulk_data resets[RESETS_MAX];
	unsigned int resets_num;
	const struct dphy_drv_data *drv_data;
	struct phy_configure_opts_mipi_dphy config;
	u8 hsfreq;
};

static inline void write_grf_reg(struct rockchip_inno_csidphy *priv,
				 int index, u8 value)
{
	const struct dphy_drv_data *drv_data = priv->drv_data;
	const struct dphy_reg *reg = &drv_data->grf_regs[index];

	if (reg->valid)
		regmap_write(priv->grf, reg->offset,
			     HIWORD_UPDATE(value, reg->mask, reg->shift));
}

/* These tables must be sorted by .range_h ascending. */
static const struct hsfreq_range rk1808_mipidphy_hsfreq_ranges[] = {
	{ 109, 0x02}, { 149, 0x03}, { 199, 0x06}, { 249, 0x06},
	{ 299, 0x06}, { 399, 0x08}, { 499, 0x0b}, { 599, 0x0e},
	{ 699, 0x10}, { 799, 0x12}, { 999, 0x16}, {1199, 0x1e},
	{1399, 0x23}, {1599, 0x2d}, {1799, 0x32}, {1999, 0x37},
	{2199, 0x3c}, {2399, 0x41}, {2499, 0x46}
};

static const struct hsfreq_range rk3326_mipidphy_hsfreq_ranges[] = {
	{ 109, 0x00}, { 149, 0x01}, { 199, 0x02}, { 249, 0x03},
	{ 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07},
	{ 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b},

Annotation

Implementation Notes