drivers/gpu/drm/i915/display/vlv_clock.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/vlv_clock.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/i915/display/vlv_clock.c- Extension
.c- Size
- 2500 bytes
- Lines
- 90
- 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_display_core.hintel_display_types.hvlv_clock.hvlv_sideband.h
Detected Declarations
function vlv_clock_get_hpll_vcofunction vlv_clock_get_cckfunction vlv_clock_get_hrawclkfunction vlv_clock_get_czclkfunction vlv_clock_get_cdclkfunction vlv_clock_get_gpll
Annotated Snippet
// SPDX-License-Identifier: MIT
/* Copyright © 2025 Intel Corporation */
#include <drm/drm_print.h>
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "vlv_clock.h"
#include "vlv_sideband.h"
/*
* FIXME: The caching of hpll_freq and czclk_freq relies on the first calls
* occurring at a time when they can actually be read. This appears to be the
* case, but is somewhat fragile. Make the initialization explicit at a point
* where they can be reliably read.
*/
/* returns HPLL frequency in kHz */
int vlv_clock_get_hpll_vco(struct drm_device *drm)
{
struct intel_display *display = to_intel_display(drm);
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
if (!display->vlv_clock.hpll_freq) {
vlv_cck_get(display);
/* Obtain SKU information */
hpll_freq = vlv_cck_read(display, CCK_FUSE_REG) &
CCK_FUSE_HPLL_FREQ_MASK;
vlv_cck_put(display);
display->vlv_clock.hpll_freq = vco_freq[hpll_freq] * 1000;
drm_dbg_kms(drm, "HPLL frequency: %d kHz\n", display->vlv_clock.hpll_freq);
}
return display->vlv_clock.hpll_freq;
}
static int vlv_clock_get_cck(struct drm_device *drm,
const char *name, u32 reg, int ref_freq)
{
struct intel_display *display = to_intel_display(drm);
u32 val;
int divider;
vlv_cck_get(display);
val = vlv_cck_read(display, reg);
vlv_cck_put(display);
divider = val & CCK_FREQUENCY_VALUES;
drm_WARN(drm, (val & CCK_FREQUENCY_STATUS) !=
(divider << CCK_FREQUENCY_STATUS_SHIFT),
"%s change in progress\n", name);
return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
}
int vlv_clock_get_hrawclk(struct drm_device *drm)
{
/* RAWCLK_FREQ_VLV register updated from power well code */
return vlv_clock_get_cck(drm, "hrawclk", CCK_DISPLAY_REF_CLOCK_CONTROL,
vlv_clock_get_hpll_vco(drm));
}
int vlv_clock_get_czclk(struct drm_device *drm)
{
struct intel_display *display = to_intel_display(drm);
if (!display->vlv_clock.czclk_freq) {
display->vlv_clock.czclk_freq = vlv_clock_get_cck(drm, "czclk", CCK_CZ_CLOCK_CONTROL,
vlv_clock_get_hpll_vco(drm));
drm_dbg_kms(drm, "CZ clock rate: %d kHz\n", display->vlv_clock.czclk_freq);
}
return display->vlv_clock.czclk_freq;
}
int vlv_clock_get_cdclk(struct drm_device *drm)
{
return vlv_clock_get_cck(drm, "cdclk", CCK_DISPLAY_CLOCK_CONTROL,
vlv_clock_get_hpll_vco(drm));
}
int vlv_clock_get_gpll(struct drm_device *drm)
{
return vlv_clock_get_cck(drm, "GPLL ref", CCK_GPLL_CLOCK_CONTROL,
vlv_clock_get_czclk(drm));
}
Annotation
- Immediate include surface: `drm/drm_print.h`, `intel_display_core.h`, `intel_display_types.h`, `vlv_clock.h`, `vlv_sideband.h`.
- Detected declarations: `function vlv_clock_get_hpll_vco`, `function vlv_clock_get_cck`, `function vlv_clock_get_hrawclk`, `function vlv_clock_get_czclk`, `function vlv_clock_get_cdclk`, `function vlv_clock_get_gpll`.
- 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.