drivers/gpu/drm/bridge/samsung-dsim.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/samsung-dsim.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/samsung-dsim.c
Extension
.c
Size
66173 bytes
Lines
2339
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (delta < min_delta) {
				best_p = _p;
				best_m = _m;
				best_s = _s;
				min_delta = delta;
				best_freq = tmp;
			}
		}
	}

	if (best_freq) {
		*p = best_p;
		*m = best_m;
		*s = best_s;
	}

	return best_freq;
}

static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
					  unsigned long freq)
{
	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
	unsigned long fin, fout;
	int timeout;
	u8 p, s;
	u16 m;
	u32 reg;

	if (dsi->pll_clk) {
		/*
		 * Ensure that the reference clock is generated with a power of
		 * two divider from its parent, but close to the PLLs upper
		 * limit.
		 */
		fin = clk_get_rate(clk_get_parent(dsi->pll_clk));
		while (fin > driver_data->pll_fin_max * HZ_PER_MHZ)
			fin /= 2;
		clk_set_rate(dsi->pll_clk, fin);

		fin = clk_get_rate(dsi->pll_clk);
	} else {
		fin = dsi->pll_clk_rate;
	}
	dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin);

	fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s);
	if (!fout) {
		dev_err(dsi->dev,
			"failed to find PLL PMS for requested frequency\n");
		return 0;
	}
	dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);

	writel(driver_data->reg_values[PLL_TIMER],
	       dsi->reg_base + driver_data->plltmr_reg);

	reg = DSIM_PLL_EN | DSIM_PLL(p, driver_data->pll_p_offset)
			  | DSIM_PLL(m, driver_data->pll_m_offset)
			  | DSIM_PLL(s, driver_data->pll_s_offset);

	if (driver_data->has_freqband) {
		static const unsigned long freq_bands[] = {
			100 * HZ_PER_MHZ, 120 * HZ_PER_MHZ, 160 * HZ_PER_MHZ,
			200 * HZ_PER_MHZ, 270 * HZ_PER_MHZ, 320 * HZ_PER_MHZ,
			390 * HZ_PER_MHZ, 450 * HZ_PER_MHZ, 510 * HZ_PER_MHZ,
			560 * HZ_PER_MHZ, 640 * HZ_PER_MHZ, 690 * HZ_PER_MHZ,
			770 * HZ_PER_MHZ, 870 * HZ_PER_MHZ, 950 * HZ_PER_MHZ,
		};
		int band;

		for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)
			if (fout < freq_bands[band])
				break;

		dev_dbg(dsi->dev, "band %d\n", band);

		reg |= DSIM_FREQ_BAND(band);
	}

	if (dsi->swap_dn_dp_clk)
		reg |= DSIM_PLL_DPDNSWAP_CLK;
	if (dsi->swap_dn_dp_data)
		reg |= DSIM_PLL_DPDNSWAP_DAT;

	samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);

	timeout = 3000;
	do {
		if (timeout-- == 0) {

Annotation

Implementation Notes