drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c- Extension
.c- Size
- 65419 bytes
- Lines
- 1656
- 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.
- 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
dccg.hclk_mgr_internal.hdcn401/dcn401_clk_mgr_smu_msg.hdcn20/dcn20_clk_mgr.hdce100/dce_clk_mgr.hdcn31/dcn31_clk_mgr.hdcn32/dcn32_clk_mgr.hdcn401/dcn401_clk_mgr.hreg_helper.hcore_types.hdm_helpers.hlink_service.hdc_state_priv.hatomfirmware.hdcn401_smu14_driver_if.hdcn/dcn_4_1_0_offset.hdcn/dcn_4_1_0_sh_mask.h
Detected Declarations
function dcn401_is_ppclk_dpm_enabledfunction dcn401_is_ppclk_idle_dpm_enabledfunction dcn401_is_df_throttle_opt_enabledfunction dcn401_init_single_clockfunction dcn401_build_wm_range_tablefunction dcn401_init_clocksfunction dcn401_is_dc_mode_presentfunction dcn401_dump_clk_registersfunction dcn401_check_native_scalingfunction dcn401_auto_dpm_test_logfunction dcn401_update_clocks_update_dtb_dtofunction dcn401_update_clocks_update_dpp_dtofunction dcn401_set_hard_min_by_freq_optimizedfunction dcn401_update_clocks_update_dentistfunction dcn401_execute_block_sequencefunction dcn401_build_update_bandwidth_clocks_sequencefunction dcn401_build_update_display_clocks_sequencefunction should_set_clockfunction dcn401_update_clocksfunction dcn401_get_vco_frequency_from_regfunction dcn401_clock_read_ss_infofunction dcn401_notify_wm_rangesfunction dcn401_set_hard_min_memclkfunction dcn401_get_hard_min_memclkfunction dcn401_get_hard_min_fclkfunction dcn401_get_memclk_states_from_smufunction dcn401_are_clock_states_equalfunction dcn401_enable_pme_wafunction dcn401_is_smu_presentfunction dcn401_get_dtb_ref_freq_khzfunction dcn401_get_dispclk_from_dentistfunction dcn401_get_max_clock_khzfunction dcn401_clk_mgr_destroy
Annotated Snippet
if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) {
pipe_ctx_list[active_pipe_count] = pipe_ctx;
active_pipe_count++;
}
}
msleep(5);
mall_ss_size_bytes = context->bw_ctx.bw.dcn.mall_ss_size_bytes;
struct clk_log_info log_info = {0};
struct clk_state_registers_and_bypass clk_register_dump;
dcn401_dump_clk_registers(&clk_register_dump, &clk_mgr->base, &log_info);
// Overrides for these clocks in case there is no p_state change support
dramclk_khz_override = new_clocks->dramclk_khz;
fclk_khz_override = new_clocks->fclk_khz;
num_fclk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_fclk_levels - 1;
if (!new_clocks->p_state_change_support)
dramclk_khz_override = clk_mgr->base.bw_params->max_memclk_mhz * 1000;
if (!new_clocks->fclk_p_state_change_support)
fclk_khz_override = clk_mgr->base.bw_params->clk_table.entries[num_fclk_levels].fclk_mhz * 1000;
////////////////////////////////////////////////////////////////////////////
// IMPORTANT: When adding more clocks to these logs, do NOT put a newline
// anywhere other than at the very end of the string.
//
// Formatting example (make sure to have " - " between each entry):
//
// AutoDPMTest: clk1:%d - clk2:%d - clk3:%d - clk4:%d\n"
////////////////////////////////////////////////////////////////////////////
if (active_pipe_count > 0 &&
new_clocks->dramclk_khz > 0 &&
new_clocks->fclk_khz > 0 &&
new_clocks->dcfclk_khz > 0 &&
new_clocks->dppclk_khz > 0) {
uint32_t pix_clk_list[MAX_PIPES] = {0};
int p_state_list[MAX_PIPES] = {0};
int disp_src_width_list[MAX_PIPES] = {0};
int disp_src_height_list[MAX_PIPES] = {0};
uint64_t disp_src_refresh_list[MAX_PIPES] = {0};
bool is_scaled_list[MAX_PIPES] = {0};
for (int i = 0; i < active_pipe_count; i++) {
struct pipe_ctx *curr_pipe_ctx = pipe_ctx_list[i];
uint64_t refresh_rate;
pix_clk_list[i] = curr_pipe_ctx->stream->timing.pix_clk_100hz;
p_state_list[i] = curr_pipe_ctx->p_state_type;
refresh_rate = (curr_pipe_ctx->stream->timing.pix_clk_100hz * (uint64_t)100 +
curr_pipe_ctx->stream->timing.v_total
* (uint64_t) curr_pipe_ctx->stream->timing.h_total - (uint64_t)1);
refresh_rate = div_u64(refresh_rate, curr_pipe_ctx->stream->timing.v_total);
refresh_rate = div_u64(refresh_rate, curr_pipe_ctx->stream->timing.h_total);
disp_src_refresh_list[i] = refresh_rate;
if (curr_pipe_ctx->plane_state) {
is_scaled_list[i] = !(dcn401_check_native_scaling(curr_pipe_ctx));
disp_src_width_list[i] = curr_pipe_ctx->plane_state->src_rect.width;
disp_src_height_list[i] = curr_pipe_ctx->plane_state->src_rect.height;
}
}
DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk:%d - fclk:%d - "
"dcfclk:%d - dppclk:%d - dispclk_hw:%d - "
"dppclk_hw:%d - dprefclk_hw:%d - dcfclk_hw:%d - "
"dtbclk_hw:%d - fclk_hw:%d - pix_clk_0:%d - pix_clk_1:%d - "
"pix_clk_2:%d - pix_clk_3:%d - mall_ss_size:%d - p_state_type_0:%d - "
"p_state_type_1:%d - p_state_type_2:%d - p_state_type_3:%d - "
"pix_width_0:%d - pix_height_0:%d - refresh_rate_0:%lld - is_scaled_0:%d - "
"pix_width_1:%d - pix_height_1:%d - refresh_rate_1:%lld - is_scaled_1:%d - "
"pix_width_2:%d - pix_height_2:%d - refresh_rate_2:%lld - is_scaled_2:%d - "
"pix_width_3:%d - pix_height_3:%d - refresh_rate_3:%lld - is_scaled_3:%d - LOG_END\n",
dramclk_khz_override,
fclk_khz_override,
new_clocks->dcfclk_khz,
new_clocks->dppclk_khz,
clk_register_dump.dispclk,
clk_register_dump.dppclk,
clk_register_dump.dprefclk,
clk_register_dump.dcfclk,
clk_register_dump.dtbclk,
clk_register_dump.fclk,
Annotation
- Immediate include surface: `dccg.h`, `clk_mgr_internal.h`, `dcn401/dcn401_clk_mgr_smu_msg.h`, `dcn20/dcn20_clk_mgr.h`, `dce100/dce_clk_mgr.h`, `dcn31/dcn31_clk_mgr.h`, `dcn32/dcn32_clk_mgr.h`, `dcn401/dcn401_clk_mgr.h`.
- Detected declarations: `function dcn401_is_ppclk_dpm_enabled`, `function dcn401_is_ppclk_idle_dpm_enabled`, `function dcn401_is_df_throttle_opt_enabled`, `function dcn401_init_single_clock`, `function dcn401_build_wm_range_table`, `function dcn401_init_clocks`, `function dcn401_is_dc_mode_present`, `function dcn401_dump_clk_registers`, `function dcn401_check_native_scaling`, `function dcn401_auto_dpm_test_log`.
- 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.