drivers/clk/spacemit/ccu_mix.c

Source file repositories/reference/linux-study-clean/drivers/clk/spacemit/ccu_mix.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/spacemit/ccu_mix.c
Extension
.c
Size
7528 bytes
Lines
284
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

if (abs(tmp - rate) < abs(best_rate - rate)) {
				best_rate = tmp;

				if (div_val)
					*div_val = j - 1;

				if (best_parent) {
					*best_parent      = parent;
					*best_parent_rate = parent_rate;
				}
			}
		}
	}

	return best_rate;
}

static int ccu_mix_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	req->rate = ccu_mix_calc_best_rate(hw, req->rate,
					   &req->best_parent_hw,
					   &req->best_parent_rate,
					   NULL);
	return 0;
}

static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{
	struct ccu_mix *mix = hw_to_ccu_mix(hw);
	struct ccu_common *common = &mix->common;
	struct ccu_div_config *div = &mix->div;
	u32 current_div, target_div, mask;

	ccu_mix_calc_best_rate(hw, rate, NULL, NULL, &target_div);

	current_div = ccu_read(common, ctrl) >> div->shift;
	current_div &= (1 << div->width) - 1;

	if (current_div == target_div)
		return 0;

	mask = GENMASK(div->width + div->shift - 1, div->shift);

	ccu_update(common, ctrl, mask, target_div << div->shift);

	return ccu_mix_trigger_fc(hw);
}

static u8 ccu_mux_get_parent(struct clk_hw *hw)
{
	struct ccu_mix *mix = hw_to_ccu_mix(hw);
	struct ccu_mux_config *mux = &mix->mux;
	u8 parent;

	parent = ccu_read(&mix->common, ctrl) >> mux->shift;
	parent &= (1 << mux->width) - 1;

	return parent;
}

static int ccu_mux_set_parent(struct clk_hw *hw, u8 index)
{
	struct ccu_mix *mix = hw_to_ccu_mix(hw);
	struct ccu_mux_config *mux = &mix->mux;
	u32 mask;

	mask = GENMASK(mux->width + mux->shift - 1, mux->shift);

	ccu_update(&mix->common, ctrl, mask, index << mux->shift);

	return ccu_mix_trigger_fc(hw);
}

const struct clk_ops spacemit_ccu_gate_ops = {
	.disable	= ccu_gate_disable,
	.enable		= ccu_gate_enable,
	.is_enabled	= ccu_gate_is_enabled,
};
EXPORT_SYMBOL_NS_GPL(spacemit_ccu_gate_ops, "CLK_SPACEMIT");

const struct clk_ops spacemit_ccu_factor_ops = {
	.determine_rate = ccu_factor_determine_rate,
	.recalc_rate	= ccu_factor_recalc_rate,
	.set_rate	= ccu_factor_set_rate,
};
EXPORT_SYMBOL_NS_GPL(spacemit_ccu_factor_ops, "CLK_SPACEMIT");

const struct clk_ops spacemit_ccu_mux_ops = {

Annotation

Implementation Notes