drivers/clk/bcm/clk-iproc-armpll.c
Source file repositories/reference/linux-study-clean/drivers/clk/bcm/clk-iproc-armpll.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/bcm/clk-iproc-armpll.c- Extension
.c- Size
- 7252 bytes
- Lines
- 274
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/slab.hlinux/err.hlinux/clk-provider.hlinux/io.hlinux/of.hlinux/clkdev.hlinux/of_address.hclk-iproc.h
Detected Declarations
struct iproc_arm_pllenum iproc_arm_pll_fidfunction __get_fidfunction mdivfunction __get_ndivfunction iproc_arm_pll_recalc_ratefunction iproc_armpll_setup
Annotated Snippet
struct iproc_arm_pll {
struct clk_hw hw;
void __iomem *base;
unsigned long rate;
};
#define to_iproc_arm_pll(hw) container_of(hw, struct iproc_arm_pll, hw)
static unsigned int __get_fid(struct iproc_arm_pll *pll)
{
u32 val;
unsigned int policy, fid, active_fid;
val = readl(pll->base + IPROC_CLK_ARM_DIV_OFFSET);
if (val & (1 << IPROC_CLK_ARM_DIV_PLL_SELECT_OVERRIDE_SHIFT))
policy = val & IPROC_CLK_ARM_DIV_ARM_PLL_SELECT_MASK;
else
policy = 0;
/* something is seriously wrong */
BUG_ON(policy > IPROC_CLK_MAX_FREQ_POLICY);
val = readl(pll->base + IPROC_CLK_POLICY_FREQ_OFFSET);
fid = (val >> (IPROC_CLK_POLICY_FREQ_POLICY_FREQ_SHIFT * policy)) &
IPROC_CLK_POLICY_FREQ_POLICY_FREQ_MASK;
val = readl(pll->base + IPROC_CLK_POLICY_DBG_OFFSET);
active_fid = IPROC_CLK_POLICY_DBG_ACT_FREQ_MASK &
(val >> IPROC_CLK_POLICY_DBG_ACT_FREQ_SHIFT);
if (fid != active_fid) {
pr_debug("%s: fid override %u->%u\n", __func__, fid,
active_fid);
fid = active_fid;
}
pr_debug("%s: active fid: %u\n", __func__, fid);
return fid;
}
/*
* Determine the mdiv (post divider) based on the frequency ID being used.
* There are 4 sources that can be used to derive the output clock rate:
* - 25 MHz Crystal
* - System clock
* - PLL channel 0 (slow clock)
* - PLL channel 1 (fast clock)
*/
static int __get_mdiv(struct iproc_arm_pll *pll)
{
unsigned int fid;
int mdiv;
u32 val;
fid = __get_fid(pll);
switch (fid) {
case ARM_PLL_FID_CRYSTAL_CLK:
case ARM_PLL_FID_SYS_CLK:
mdiv = 1;
break;
case ARM_PLL_FID_CH0_SLOW_CLK:
val = readl(pll->base + IPROC_CLK_PLLARMC_OFFSET);
mdiv = val & IPROC_CLK_PLLARMC_MDIV_MASK;
if (mdiv == 0)
mdiv = 256;
break;
case ARM_PLL_FID_CH1_FAST_CLK:
val = readl(pll->base + IPROC_CLK_PLLARMCTL5_OFFSET);
mdiv = val & IPROC_CLK_PLLARMCTL5_H_MDIV_MASK;
if (mdiv == 0)
mdiv = 256;
break;
default:
mdiv = -EFAULT;
}
return mdiv;
}
static unsigned int __get_ndiv(struct iproc_arm_pll *pll)
{
u32 val;
unsigned int ndiv_int, ndiv_frac, ndiv;
val = readl(pll->base + IPROC_CLK_PLLARM_OFFSET_OFFSET);
if (val & (1 << IPROC_CLK_PLLARM_SW_CTL_SHIFT)) {
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/err.h`, `linux/clk-provider.h`, `linux/io.h`, `linux/of.h`, `linux/clkdev.h`, `linux/of_address.h`.
- Detected declarations: `struct iproc_arm_pll`, `enum iproc_arm_pll_fid`, `function __get_fid`, `function mdiv`, `function __get_ndiv`, `function iproc_arm_pll_recalc_rate`, `function iproc_armpll_setup`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: source 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.