drivers/clk/qcom/clk-cpu-8996.c

Source file repositories/reference/linux-study-clean/drivers/clk/qcom/clk-cpu-8996.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/qcom/clk-cpu-8996.c
Extension
.c
Size
17755 bytes
Lines
629
Domain
Driver Families
Bucket
drivers/clk
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 clk_cpu_8996_pmux {
	u32	reg;
	struct notifier_block nb;
	struct clk_regmap clkr;
};

static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
			       void *data);

#define to_clk_cpu_8996_pmux_nb(_nb) \
	container_of(_nb, struct clk_cpu_8996_pmux, nb)

static inline struct clk_cpu_8996_pmux *to_clk_cpu_8996_pmux_hw(struct clk_hw *hw)
{
	return container_of(to_clk_regmap(hw), struct clk_cpu_8996_pmux, clkr);
}

static u8 clk_cpu_8996_pmux_get_parent(struct clk_hw *hw)
{
	struct clk_regmap *clkr = to_clk_regmap(hw);
	struct clk_cpu_8996_pmux *cpuclk = to_clk_cpu_8996_pmux_hw(hw);
	u32 val;

	regmap_read(clkr->regmap, cpuclk->reg, &val);

	return FIELD_GET(PMUX_MASK, val);
}

static int clk_cpu_8996_pmux_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_regmap *clkr = to_clk_regmap(hw);
	struct clk_cpu_8996_pmux *cpuclk = to_clk_cpu_8996_pmux_hw(hw);
	u32 val;

	val = FIELD_PREP(PMUX_MASK, index);

	return regmap_update_bits(clkr->regmap, cpuclk->reg, PMUX_MASK, val);
}

static int clk_cpu_8996_pmux_determine_rate(struct clk_hw *hw,
					   struct clk_rate_request *req)
{
	struct clk_hw *parent;

	if (req->rate < (DIV_2_THRESHOLD / 2))
		return -EINVAL;

	if (req->rate < DIV_2_THRESHOLD)
		parent = clk_hw_get_parent_by_index(hw, SMUX_INDEX);
	else
		parent = clk_hw_get_parent_by_index(hw, ACD_INDEX);
	if (!parent)
		return -EINVAL;

	req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
	req->best_parent_hw = parent;

	return 0;
}

static const struct clk_ops clk_cpu_8996_pmux_ops = {
	.set_parent = clk_cpu_8996_pmux_set_parent,
	.get_parent = clk_cpu_8996_pmux_get_parent,
	.determine_rate = clk_cpu_8996_pmux_determine_rate,
};

static const struct parent_map smux_parent_map[] = {
	{ .cfg = 0, }, /* xo */
	{ .cfg = 1, }, /* pll */
	{ .cfg = 3, }, /* sys_apcs_aux */
};

static const struct clk_parent_data pwrcl_smux_parents[] = {
	{ .fw_name = "xo" },
	{ .hw = &pwrcl_pll_postdiv.hw },
	{ .fw_name = "sys_apcs_aux" },
};

static const struct clk_parent_data perfcl_smux_parents[] = {
	{ .fw_name = "xo" },
	{ .hw = &perfcl_pll_postdiv.hw },
	{ .fw_name = "sys_apcs_aux" },
};

static struct clk_regmap_mux pwrcl_smux = {
	.reg = PWRCL_REG_OFFSET + MUX_OFFSET,
	.shift = 2,
	.width = 2,
	.parent_map = smux_parent_map,
	.clkr.hw.init = &(struct clk_init_data) {

Annotation

Implementation Notes