drivers/gpu/drm/i915/display/intel_pch_refclk.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_pch_refclk.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/i915/display/intel_pch_refclk.c- Extension
.c- Size
- 18126 bytes
- Lines
- 684
- Domain
- Driver Families
- Bucket
- drivers/gpu
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
drm/drm_print.hintel_de.hintel_display_regs.hintel_display_types.hintel_display_utils.hintel_panel.hintel_pch_refclk.hintel_sbi.hintel_sbi_regs.h
Detected Declarations
struct iclkip_paramsfunction lpt_fdi_reset_mphyfunction lpt_fdi_program_mphyfunction lpt_disable_iclkipfunction iclkip_params_initfunction lpt_iclkip_freqfunction lpt_compute_iclkipfunction lpt_iclkipfunction lpt_program_iclkipfunction lpt_get_iclkipfunction lpt_enable_clkout_dpfunction lpt_disable_clkout_dpfunction lpt_bend_clkout_dpfunction spll_uses_pch_sscfunction wrpll_uses_pch_sscfunction lpt_init_pch_refclkfunction for_each_intel_encoderfunction ilk_init_pch_refclkfunction intel_init_pch_refclk
Annotated Snippet
struct iclkip_params {
u32 iclk_virtual_root_freq;
u32 iclk_pi_range;
u32 divsel, phaseinc, auxdiv, phasedir, desired_divisor;
};
static void iclkip_params_init(struct iclkip_params *p)
{
memset(p, 0, sizeof(*p));
p->iclk_virtual_root_freq = 172800 * 1000;
p->iclk_pi_range = 64;
}
static int lpt_iclkip_freq(struct iclkip_params *p)
{
return DIV_ROUND_CLOSEST(p->iclk_virtual_root_freq,
p->desired_divisor << p->auxdiv);
}
static void lpt_compute_iclkip(struct iclkip_params *p, int clock)
{
iclkip_params_init(p);
/* The iCLK virtual clock root frequency is in MHz,
* but the adjusted_mode->crtc_clock in KHz. To get the
* divisors, it is necessary to divide one by another, so we
* convert the virtual clock precision to KHz here for higher
* precision.
*/
for (p->auxdiv = 0; p->auxdiv < 2; p->auxdiv++) {
p->desired_divisor = DIV_ROUND_CLOSEST(p->iclk_virtual_root_freq,
clock << p->auxdiv);
p->divsel = (p->desired_divisor / p->iclk_pi_range) - 2;
p->phaseinc = p->desired_divisor % p->iclk_pi_range;
/*
* Near 20MHz is a corner case which is
* out of range for the 7-bit divisor
*/
if (p->divsel <= 0x7f)
break;
}
}
int lpt_iclkip(const struct intel_crtc_state *crtc_state)
{
struct iclkip_params p;
lpt_compute_iclkip(&p, crtc_state->hw.adjusted_mode.crtc_clock);
return lpt_iclkip_freq(&p);
}
/* Program iCLKIP clock to the desired frequency */
void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
int clock = crtc_state->hw.adjusted_mode.crtc_clock;
struct iclkip_params p;
u32 temp;
lpt_disable_iclkip(display);
lpt_compute_iclkip(&p, clock);
drm_WARN_ON(display->drm, lpt_iclkip_freq(&p) != clock);
/* This should not happen with any sane values */
drm_WARN_ON(display->drm, SBI_SSCDIVINTPHASE_DIVSEL(p.divsel) &
~SBI_SSCDIVINTPHASE_DIVSEL_MASK);
drm_WARN_ON(display->drm, SBI_SSCDIVINTPHASE_DIR(p.phasedir) &
~SBI_SSCDIVINTPHASE_INCVAL_MASK);
drm_dbg_kms(display->drm,
"iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
clock, p.auxdiv, p.divsel, p.phasedir, p.phaseinc);
intel_sbi_lock(display);
/* Program SSCDIVINTPHASE6 */
temp = intel_sbi_read(display, SBI_SSCDIVINTPHASE6, SBI_ICLK);
temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK;
temp |= SBI_SSCDIVINTPHASE_DIVSEL(p.divsel);
temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK;
temp |= SBI_SSCDIVINTPHASE_INCVAL(p.phaseinc);
temp |= SBI_SSCDIVINTPHASE_DIR(p.phasedir);
temp |= SBI_SSCDIVINTPHASE_PROPAGATE;
intel_sbi_write(display, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK);
/* Program SSCAUXDIV */
Annotation
- Immediate include surface: `drm/drm_print.h`, `intel_de.h`, `intel_display_regs.h`, `intel_display_types.h`, `intel_display_utils.h`, `intel_panel.h`, `intel_pch_refclk.h`, `intel_sbi.h`.
- Detected declarations: `struct iclkip_params`, `function lpt_fdi_reset_mphy`, `function lpt_fdi_program_mphy`, `function lpt_disable_iclkip`, `function iclkip_params_init`, `function lpt_iclkip_freq`, `function lpt_compute_iclkip`, `function lpt_iclkip`, `function lpt_program_iclkip`, `function lpt_get_iclkip`.
- Atlas domain: Driver Families / drivers/gpu.
- 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.