drivers/gpu/drm/radeon/ni_dpm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/ni_dpm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/radeon/ni_dpm.c- Extension
.c- Size
- 131660 bytes
- Lines
- 4380
- 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
linux/math64.hlinux/pci.hlinux/seq_file.hatom.hevergreen.hni_dpm.hnid.hr600_dpm.hrv770.hradeon.hradeon_asic.h
Detected Declarations
function ni_calculate_leakage_for_v_and_t_formulafunction ni_calculate_leakage_for_v_and_tfunction ni_dpm_vblank_too_shortfunction ni_apply_state_adjust_rulesfunction ni_cg_clockgating_defaultfunction ni_gfx_clockgating_enablefunction ni_mg_clockgating_defaultfunction ni_mg_clockgating_enablefunction ni_ls_clockgating_defaultfunction ni_ls_clockgating_enablefunction ni_patch_single_dependency_table_based_on_leakagefunction ni_patch_dependency_tables_based_on_leakagefunction ni_stop_dpmfunction ni_notify_hw_of_power_sourcefunction ni_send_msg_to_smc_with_parameterfunction ni_restrict_performance_levels_before_switchfunction ni_dpm_force_performance_levelfunction ni_stop_smcfunction ni_process_firmware_headerfunction ni_read_clock_registersfunction ni_enter_ulp_statefunction ni_program_response_timesfunction ni_populate_smc_voltage_tablefunction ni_populate_smc_voltage_tablesfunction ni_populate_voltage_valuefunction ni_populate_mvdd_valuefunction ni_get_std_voltage_valuefunction ni_populate_std_voltage_valuefunction ni_get_smc_power_scaling_factorfunction ni_scale_power_for_smcfunction ni_calculate_power_boost_limitfunction ni_calculate_adjusted_tdp_limitsfunction ni_populate_smc_tdp_limitsfunction ni_copy_and_switch_arb_setsfunction ni_init_arb_table_indexfunction ni_initial_switch_from_arb_f0_to_f1function ni_force_switch_to_arb_f0function ni_populate_memory_timing_parametersfunction ni_do_program_memory_timing_parametersfunction ni_program_memory_timing_parametersfunction ni_populate_initial_mvdd_valuefunction ni_populate_smc_initial_statefunction ni_populate_smc_acpi_statefunction ni_init_smc_tablefunction ni_calculate_sclk_paramsfunction ni_populate_sclk_valuefunction ni_init_smc_spll_tablefunction ni_populate_mclk_value
Annotated Snippet
if (0xff01 == table->entries[i].v) {
if (pi->max_vddc == 0)
return -EINVAL;
table->entries[i].v = pi->max_vddc;
}
}
}
return 0;
}
static int ni_patch_dependency_tables_based_on_leakage(struct radeon_device *rdev)
{
int ret = 0;
ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
return ret;
}
static void ni_stop_dpm(struct radeon_device *rdev)
{
WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
}
#if 0
static int ni_notify_hw_of_power_source(struct radeon_device *rdev,
bool ac_power)
{
if (ac_power)
return (rv770_send_msg_to_smc(rdev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
0 : -EINVAL;
return 0;
}
#endif
static PPSMC_Result ni_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
PPSMC_Msg msg, u32 parameter)
{
WREG32(SMC_SCRATCH0, parameter);
return rv770_send_msg_to_smc(rdev, msg);
}
static int ni_restrict_performance_levels_before_switch(struct radeon_device *rdev)
{
if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
return -EINVAL;
return (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
0 : -EINVAL;
}
int ni_dpm_force_performance_level(struct radeon_device *rdev,
enum radeon_dpm_forced_level level)
{
if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK)
return -EINVAL;
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)
return -EINVAL;
} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
return -EINVAL;
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)
return -EINVAL;
} else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
return -EINVAL;
if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK)
return -EINVAL;
}
rdev->pm.dpm.forced_level = level;
return 0;
}
static void ni_stop_smc(struct radeon_device *rdev)
{
u32 tmp;
int i;
for (i = 0; i < rdev->usec_timeout; i++) {
tmp = RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK;
Annotation
- Immediate include surface: `linux/math64.h`, `linux/pci.h`, `linux/seq_file.h`, `atom.h`, `evergreen.h`, `ni_dpm.h`, `nid.h`, `r600_dpm.h`.
- Detected declarations: `function ni_calculate_leakage_for_v_and_t_formula`, `function ni_calculate_leakage_for_v_and_t`, `function ni_dpm_vblank_too_short`, `function ni_apply_state_adjust_rules`, `function ni_cg_clockgating_default`, `function ni_gfx_clockgating_enable`, `function ni_mg_clockgating_default`, `function ni_mg_clockgating_enable`, `function ni_ls_clockgating_default`, `function ni_ls_clockgating_enable`.
- 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.