drivers/media/i2c/ccs-pll.c
Source file repositories/reference/linux-study-clean/drivers/media/i2c/ccs-pll.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/i2c/ccs-pll.c- Extension
.c- Size
- 27069 bytes
- Lines
- 911
- Domain
- Driver Families
- Bucket
- drivers/media
- 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/device.hlinux/gcd.hlinux/lcm.hlinux/module.hccs-pll.h
Detected Declarations
function Copyrightfunction clk_div_even_upfunction is_one_or_evenfunction one_or_morefunction bounds_checkfunction print_pllfunction print_pll_flagsfunction op_sys_ddrfunction op_pix_ddrfunction check_fr_boundsfunction check_bk_boundsfunction check_ext_boundsfunction ccs_pll_find_vt_sys_divfunction __ccs_pll_calculate_vt_treefunction ccs_pll_calculate_vt_treefunction ccs_pll_calculate_vtfunction ccs_pll_calculate_opfunction ccs_pll_calculateexport ccs_pll_calculate
Annotated Snippet
if (pix_div * sys_div <= best_pix_div) {
best_pix_div = pix_div;
best_div = pix_div * sys_div;
}
}
if (best_pix_div == SHRT_MAX >> 1)
return -EINVAL;
pll_bk->sys_clk_div = best_div / best_pix_div;
pll_bk->pix_clk_div = best_pix_div;
pll_bk->sys_clk_freq_hz =
pll_fr->pll_op_clk_freq_hz / pll_bk->sys_clk_div;
pll_bk->pix_clk_freq_hz =
pll_bk->sys_clk_freq_hz / pll_bk->pix_clk_div;
pll->pixel_rate_pixel_array =
pll_bk->pix_clk_freq_hz * pll->vt_lanes;
return 0;
}
static int ccs_pll_calculate_vt_tree(struct device *dev,
const struct ccs_pll_limits *lim,
struct ccs_pll *pll)
{
const struct ccs_pll_branch_limits_fr *lim_fr = &lim->vt_fr;
struct ccs_pll_branch_fr *pll_fr = &pll->vt_fr;
u16 min_pre_pll_clk_div = lim_fr->min_pre_pll_clk_div;
u16 max_pre_pll_clk_div = lim_fr->max_pre_pll_clk_div;
u32 pre_mul, pre_div;
pre_div = gcd(pll->pixel_rate_csi,
pll->ext_clk_freq_hz * pll->vt_lanes);
pre_mul = pll->pixel_rate_csi / pre_div;
pre_div = pll->ext_clk_freq_hz * pll->vt_lanes / pre_div;
/* Make sure PLL input frequency is within limits */
max_pre_pll_clk_div =
min_t(u16, max_pre_pll_clk_div,
DIV_ROUND_UP(pll->ext_clk_freq_hz,
lim_fr->min_pll_ip_clk_freq_hz));
min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
pll->ext_clk_freq_hz /
lim_fr->max_pll_ip_clk_freq_hz);
if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
min_pre_pll_clk_div = clk_div_even(min_pre_pll_clk_div);
dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
min_pre_pll_clk_div, max_pre_pll_clk_div);
for (pll_fr->pre_pll_clk_div = min_pre_pll_clk_div;
pll_fr->pre_pll_clk_div <= max_pre_pll_clk_div;
pll_fr->pre_pll_clk_div +=
(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER) ? 1 :
2 - (pll_fr->pre_pll_clk_div & 1)) {
u32 mul, div;
int rval;
div = gcd(pre_mul * pll_fr->pre_pll_clk_div, pre_div);
mul = pre_mul * pll_fr->pre_pll_clk_div / div;
div = pre_div / div;
dev_dbg(dev, "vt pre-div/mul/div: %u,%u,%u\n",
pll_fr->pre_pll_clk_div, mul, div);
rval = __ccs_pll_calculate_vt_tree(dev, lim, pll,
mul, div);
if (rval)
continue;
rval = check_fr_bounds(dev, lim, pll, PLL_VT);
if (rval)
continue;
rval = check_bk_bounds(dev, lim, pll, PLL_VT);
if (rval)
continue;
return 0;
}
dev_dbg(dev, "unable to compute VT pre_pll divisor\n");
return -EINVAL;
}
static int
ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
const struct ccs_pll_branch_limits_bk *op_lim_bk,
Annotation
- Immediate include surface: `linux/device.h`, `linux/gcd.h`, `linux/lcm.h`, `linux/module.h`, `ccs-pll.h`.
- Detected declarations: `function Copyright`, `function clk_div_even_up`, `function is_one_or_even`, `function one_or_more`, `function bounds_check`, `function print_pll`, `function print_pll_flags`, `function op_sys_ddr`, `function op_pix_ddr`, `function check_fr_bounds`.
- Atlas domain: Driver Families / drivers/media.
- 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.