drivers/clk/meson/clk-pll.c
Source file repositories/reference/linux-study-clean/drivers/clk/meson/clk-pll.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/meson/clk-pll.c- Extension
.c- Size
- 13017 bytes
- Lines
- 508
- 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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk-provider.hlinux/delay.hlinux/err.hlinux/io.hlinux/math64.hlinux/module.hclk-regmap.hclk-pll.h
Detected Declarations
function Copyrightfunction __pll_round_closest_multfunction __pll_params_to_ratefunction meson_clk_pll_recalc_ratefunction __pll_params_with_fracfunction meson_clk_pll_is_betterfunction meson_clk_get_pll_table_indexfunction meson_clk_get_pll_range_mfunction meson_clk_get_pll_range_indexfunction meson_clk_get_pll_get_indexfunction meson_clk_get_pll_settingsfunction meson_clk_pll_determine_ratefunction meson_clk_pll_wait_lockfunction meson_clk_pll_is_enabledfunction meson_clk_pll_initfunction meson_clk_pcie_pll_enablefunction meson_clk_pll_enablefunction meson_clk_pll_disablefunction meson_clk_pll_set_rate
Annotated Snippet
if (rate <= pll->range->min * parent_rate) {
*m = pll->range->min;
return -ENODATA;
} else if (rate >= pll->range->max * parent_rate) {
*m = pll->range->max;
return -ENODATA;
}
}
*m = meson_clk_get_pll_range_m(rate, parent_rate, *n, pll);
/* the pre-divider gives a multiplier too big - stop */
if (*m >= (1 << pll->m.width))
return -EINVAL;
return 0;
}
static int meson_clk_get_pll_get_index(unsigned long rate,
unsigned long parent_rate,
unsigned int index,
unsigned int *m,
unsigned int *n,
struct meson_clk_pll_data *pll)
{
if (pll->range)
return meson_clk_get_pll_range_index(rate, parent_rate,
index, m, n, pll);
else if (pll->table)
return meson_clk_get_pll_table_index(index, m, n, pll);
return -EINVAL;
}
static int meson_clk_get_pll_settings(unsigned long rate,
unsigned long parent_rate,
unsigned int *best_m,
unsigned int *best_n,
struct meson_clk_pll_data *pll)
{
unsigned long best = 0, now = 0;
unsigned int i, m, n;
int ret;
for (i = 0, ret = 0; !ret; i++) {
ret = meson_clk_get_pll_get_index(rate, parent_rate,
i, &m, &n, pll);
if (ret == -EINVAL)
break;
now = __pll_params_to_rate(parent_rate, m, n, 0, pll);
if (meson_clk_pll_is_better(rate, best, now, pll)) {
best = now;
*best_m = m;
*best_n = n;
if (now == rate)
break;
}
}
return best ? 0 : -EINVAL;
}
static int meson_clk_pll_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
unsigned int m, n, frac;
unsigned long round;
int ret;
ret = meson_clk_get_pll_settings(req->rate, req->best_parent_rate,
&m, &n, pll);
if (ret)
return ret;
round = __pll_params_to_rate(req->best_parent_rate, m, n, 0, pll);
if (!MESON_PARM_APPLICABLE(&pll->frac) || req->rate == round) {
req->rate = round;
return 0;
}
/*
* The rate provided by the setting is not an exact match, let's
* try to improve the result using the fractional parameter
*/
frac = __pll_params_with_frac(req->rate, req->best_parent_rate, m, n, pll);
Annotation
- Immediate include surface: `linux/clk-provider.h`, `linux/delay.h`, `linux/err.h`, `linux/io.h`, `linux/math64.h`, `linux/module.h`, `clk-regmap.h`, `clk-pll.h`.
- Detected declarations: `function Copyright`, `function __pll_round_closest_mult`, `function __pll_params_to_rate`, `function meson_clk_pll_recalc_rate`, `function __pll_params_with_frac`, `function meson_clk_pll_is_better`, `function meson_clk_get_pll_table_index`, `function meson_clk_get_pll_range_m`, `function meson_clk_get_pll_range_index`, `function meson_clk_get_pll_get_index`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.