drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
Extension
.c
Size
47188 bytes
Lines
1553
Domain
Driver Families
Bucket
drivers/gpu
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 dsi_pll_config {
	bool enable_ssc;
	bool ssc_center;
	u32 ssc_freq;
	u32 ssc_offset;
	u32 ssc_adj_per;

	/* out */
	u32 decimal_div_start;
	u32 frac_div_start;
	u32 pll_clock_inverters;
	u32 ssc_stepsize;
	u32 ssc_div_per;
};

struct pll_7nm_cached_state {
	unsigned long vco_rate;
	u8 bit_clk_div;
	u8 pix_clk_div;
	u8 pll_out_div;
	u8 pll_mux;
};

struct dsi_pll_7nm {
	struct clk_hw clk_hw;

	struct msm_dsi_phy *phy;

	u64 vco_current_rate;

	/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
	spinlock_t postdiv_lock;

	/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG1 register */
	spinlock_t pclk_mux_lock;

	/*
	 * protects REG_DSI_7nm_PHY_CMN_CTRL_0 register and pll_enable_cnt
	 * member
	 */
	spinlock_t pll_enable_lock;
	int pll_enable_cnt;

	struct pll_7nm_cached_state cached_state;

	struct dsi_pll_7nm *slave;
};

#define to_pll_7nm(x)	container_of(x, struct dsi_pll_7nm, clk_hw)

/*
 * Global list of private DSI PLL struct pointers. We need this for bonded DSI
 * mode, where the master PLL's clk_ops needs access the slave's private data
 */
static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];

static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll);
static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll);

static void dsi_pll_setup_config(struct dsi_pll_config *config)
{
	config->ssc_freq = 31500;
	config->ssc_offset = 4800;
	config->ssc_adj_per = 2;

	/* TODO: ssc enable */
	config->enable_ssc = false;
	config->ssc_center = 0;
}

static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
{
	u64 fref = VCO_REF_CLK_RATE;
	u64 pll_freq;
	u64 divider;
	u64 dec, dec_multiple;
	u32 frac;
	u64 multiplier;

	pll_freq = pll->vco_current_rate;

	divider = fref * 2;

	multiplier = 1 << FRAC_BITS;
	dec_multiple = div_u64(pll_freq * multiplier, divider);
	dec = div_u64_rem(dec_multiple, multiplier, &frac);

	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_0) {
		config->pll_clock_inverters = 0x28;
	} else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2)) {

Annotation

Implementation Notes