drivers/clk/imx/clk-fracn-gppll.c

Source file repositories/reference/linux-study-clean/drivers/clk/imx/clk-fracn-gppll.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/imx/clk-fracn-gppll.c
Extension
.c
Size
10581 bytes
Lines
413
Domain
Driver Families
Bucket
drivers/clk
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

struct clk_fracn_gppll {
	struct clk_hw			hw;
	void __iomem			*base;
	const struct imx_fracn_gppll_rate_table *rate_table;
	int rate_count;
	u32 flags;
};

/*
 * Fvco = (Fref / rdiv) * (MFI + MFN / MFD)
 * Fout = Fvco / odiv
 * The (Fref / rdiv) should be in range 20MHz to 40MHz
 * The Fvco should be in range 2.5Ghz to 5Ghz
 */
static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
	PLL_FRACN_GP(1039500000U, 173, 25, 100, 1, 4),
	PLL_FRACN_GP(650000000U, 162, 50, 100, 0, 6),
	PLL_FRACN_GP(594000000U, 198, 0, 1, 0, 8),
	PLL_FRACN_GP(560000000U, 140, 0, 1, 0, 6),
	PLL_FRACN_GP(519750000U, 173, 25, 100, 1, 8),
	PLL_FRACN_GP(498000000U, 166, 0, 1, 0, 8),
	PLL_FRACN_GP(484000000U, 121, 0, 1, 0, 6),
	PLL_FRACN_GP(477400000U, 119, 35, 100, 0, 6),
	PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9),
	PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12),
	PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10),
	PLL_FRACN_GP(333333333U, 125, 0, 1, 1, 9),
	PLL_FRACN_GP(332600000U, 138, 584, 1000, 0, 10),
	PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12),
	PLL_FRACN_GP(241900000U, 201, 584, 1000, 0, 20),
};

struct imx_fracn_gppll_clk imx_fracn_gppll = {
	.rate_table = fracn_tbl,
	.rate_count = ARRAY_SIZE(fracn_tbl),
};
EXPORT_SYMBOL_GPL(imx_fracn_gppll);

/*
 * Fvco = (Fref / rdiv) * MFI
 * Fout = Fvco / odiv
 * The (Fref / rdiv) should be in range 20MHz to 40MHz
 * The Fvco should be in range 2.5Ghz to 5Ghz
 */
static const struct imx_fracn_gppll_rate_table int_tbl[] = {
	PLL_FRACN_GP_INTEGER(1700000000U, 141, 1, 2),
	PLL_FRACN_GP_INTEGER(1400000000U, 175, 1, 3),
	PLL_FRACN_GP_INTEGER(900000000U, 150, 1, 4),
	PLL_FRACN_GP_INTEGER(800000000U, 200, 1, 6),
};

struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
	.rate_table = int_tbl,
	.rate_count = ARRAY_SIZE(int_tbl),
};
EXPORT_SYMBOL_GPL(imx_fracn_gppll_integer);

static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw)
{
	return container_of(hw, struct clk_fracn_gppll, hw);
}

static const struct imx_fracn_gppll_rate_table *
imx_get_pll_settings(struct clk_fracn_gppll *pll, unsigned long rate)
{
	const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table;
	int i;

	for (i = 0; i < pll->rate_count; i++)
		if (rate == rate_table[i].rate)
			return &rate_table[i];

	return NULL;
}

static int clk_fracn_gppll_determine_rate(struct clk_hw *hw,
					  struct clk_rate_request *req)
{
	struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw);
	const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table;
	int i;

	/* Assuming rate_table is in descending order */
	for (i = 0; i < pll->rate_count; i++)
		if (req->rate >= rate_table[i].rate) {
			req->rate = rate_table[i].rate;

			return 0;
		}

Annotation

Implementation Notes