drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42b/dcn42b_clk_mgr.c- Extension
.c- Size
- 15995 bytes
- Lines
- 484
- 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
dcn42b_clk_mgr.hdccg.hclk_mgr_internal.hdce100/dce_clk_mgr.hdcn20/dcn20_clk_mgr.hreg_helper.hcore_types.hdcn42/dcn42_smu.hdcn42/dcn42_clk_mgr.hdm_helpers.hdcn30/dcn30_clk_mgr.hdcn31/dcn31_clk_mgr.hdcn35/dcn35_clk_mgr.hdc_dmub_srv.hlink_service.hlogger_types.hclk/clk_15_0_5_offset.hclk/clk_15_0_5_sh_mask.hdcn/dcn_4_2_1_offset.hdcn/dcn_4_2_1_sh_mask.h
Detected Declarations
function dcn42b_dump_clk_registers_internalfunction dcn42b_dump_clk_registersfunction init_clk_statesfunction dcn42b_init_clocksfunction dcn42b_read_ss_info_from_lutfunction dcn42b_get_clock_freq_from_clkipfunction dcn42b_clk_mgr_construct
Annotated Snippet
if (clk_mgr->dprefclk_ss_percentage != 0) {
clk_mgr->ss_on_dprefclk = true;
clk_mgr->dprefclk_ss_divider = dcn42_ss_info_table.ss_divider;
}
}
}
uint32_t dcn42b_get_clock_freq_from_clkip(struct clk_mgr *clk_mgr_base, enum clock_type clock)
{
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
uint64_t clock_freq_mhz = 0;
uint32_t timer_threshold = 0;
// always safer to read the timer threshold instead of using cached value
REG_GET(CLK5_CLK_TICK_CNT_CONFIG_REG, TIMER_THRESHOLD, &timer_threshold);
if (timer_threshold == 0) {
BREAK_TO_DEBUGGER();
return 0;
}
switch (clock) {
case clock_type_dispclk:
clock_freq_mhz = REG_READ(CLK5_CLK0_CURRENT_CNT);
break;
case clock_type_dppclk:
clock_freq_mhz = REG_READ(CLK5_CLK1_CURRENT_CNT);
break;
case clock_type_dprefclk:
clock_freq_mhz = REG_READ(CLK5_CLK2_CURRENT_CNT);
break;
case clock_type_dcfclk:
clock_freq_mhz = REG_READ(CLK5_CLK3_CURRENT_CNT);
break;
case clock_type_dtbclk:
/* DTBCLK tied off in DCN42B - CLK5_CLK4 register doesn't exist.
* Should never be called since dtbclk_en is always false.
*/
ASSERT(false);
clock_freq_mhz = 0;
break;
default:
break;
}
clock_freq_mhz *= DCN42_CLKIP_REFCLK;
clock_freq_mhz = div_u64(clock_freq_mhz, timer_threshold);
// there are no DCN clocks over 0xFFFFFFFF MHz
ASSERT(clock_freq_mhz <= 0xFFFFFFFF);
return (uint32_t)clock_freq_mhz;
}
/* dcn42b_get_dispclk_from_dentist removed: reuse dcn42_get_dispclk_from_dentist.
* DENTIST_DISPCLK_CNTL is a DCN register with the same offset on both dcn42 and dcn42b.
*/
static struct clk_mgr_funcs dcn42b_funcs = {
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
.update_clocks = dcn42_update_clocks,
.init_clocks = dcn42b_init_clocks,
.enable_pme_wa = dcn42_enable_pme_wa,
.are_clock_states_equal = dcn42_are_clock_states_equal,
.notify_wm_ranges = NULL,
.set_low_power_state = dcn42_set_low_power_state,
.exit_low_power_state = dcn42_exit_low_power_state,
.get_max_clock_khz = dcn42_get_max_clock_khz,
.get_dispclk_from_dentist = dcn42_get_dispclk_from_dentist,
.is_smu_present = dcn42_is_smu_present,
};
void dcn42b_clk_mgr_construct(
struct dc_context *ctx,
struct clk_mgr_dcn42 *clk_mgr,
struct pp_smu_funcs *pp_smu,
struct dccg *dccg)
{
clk_mgr->base.base.ctx = ctx;
clk_mgr->base.base.funcs = &dcn42b_funcs;
clk_mgr->base.regs = &clk_mgr_regs_dcn42b;
clk_mgr->base.clk_mgr_shift = &clk_mgr_shift_dcn42b;
clk_mgr->base.clk_mgr_mask = &clk_mgr_mask_dcn42b;
clk_mgr->base.pp_smu = pp_smu;
clk_mgr->base.dccg = dccg;
clk_mgr->base.dfs_bypass_disp_clk = 0;
Annotation
- Immediate include surface: `dcn42b_clk_mgr.h`, `dccg.h`, `clk_mgr_internal.h`, `dce100/dce_clk_mgr.h`, `dcn20/dcn20_clk_mgr.h`, `reg_helper.h`, `core_types.h`, `dcn42/dcn42_smu.h`.
- Detected declarations: `function dcn42b_dump_clk_registers_internal`, `function dcn42b_dump_clk_registers`, `function init_clk_states`, `function dcn42b_init_clocks`, `function dcn42b_read_ss_info_from_lut`, `function dcn42b_get_clock_freq_from_clkip`, `function dcn42b_clk_mgr_construct`.
- 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.