drivers/clk/sophgo/clk-sg2044-pll.c

Source file repositories/reference/linux-study-clean/drivers/clk/sophgo/clk-sg2044-pll.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/sophgo/clk-sg2044-pll.c
Extension
.c
Size
16269 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 sg2044_pll_limit {
	u64 min;
	u64 max;
};

struct sg2044_pll_internal {
	u32 ctrl_offset;
	u32 status_offset;
	u32 enable_offset;

	u8 status_lock_bit;
	u8 status_updating_bit;
	u8 enable_bit;

	const struct sg2044_pll_limit *limits;
};

struct sg2044_clk_common {
	struct clk_hw	hw;
	struct regmap	*regmap;
	spinlock_t	*lock;
	unsigned int	id;
};

struct sg2044_pll {
	struct sg2044_clk_common	common;
	struct sg2044_pll_internal	pll;
	unsigned int			syscon_offset;
};

struct sg2044_pll_desc_data {
	struct sg2044_clk_common	* const *pll;
	u16				num_pll;
};

#define SG2044_SYSCON_PLL_OFFSET	0x98

struct sg2044_pll_ctrl {
	spinlock_t			lock;
	struct clk_hw_onecell_data	data;
};

#define hw_to_sg2044_clk_common(_hw)					\
	container_of((_hw), struct sg2044_clk_common, hw)

static inline bool sg2044_clk_fit_limit(u64 value,
					const struct sg2044_pll_limit *limit)
{
	return value >= limit->min && value <= limit->max;
}

static inline struct sg2044_pll *hw_to_sg2044_pll(struct clk_hw *hw)
{
	return container_of(hw_to_sg2044_clk_common(hw),
			    struct sg2044_pll, common);
}

static unsigned long sg2044_pll_calc_vco_rate(unsigned long parent_rate,
					      unsigned long refdiv,
					      unsigned long fbdiv)
{
	u64 numerator = parent_rate * fbdiv;

	return div64_ul(numerator, refdiv);
}

static unsigned long sg2044_pll_calc_rate(unsigned long parent_rate,
					  unsigned long refdiv,
					  unsigned long fbdiv,
					  unsigned long postdiv1,
					  unsigned long postdiv2)
{
	u64 numerator, denominator;

	numerator = parent_rate * fbdiv;
	denominator = refdiv * (postdiv1 + 1) * (postdiv2 + 1);

	return div64_u64(numerator, denominator);
}

static unsigned long sg2044_pll_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	struct sg2044_pll *pll = hw_to_sg2044_pll(hw);
	u32 value;
	int ret;

	ret = regmap_read(pll->common.regmap,
			  pll->syscon_offset + pll->pll.ctrl_offset + PLL_HIGH_CTRL_OFFSET,
			  &value);

Annotation

Implementation Notes