drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c- Extension
.c- Size
- 39972 bytes
- Lines
- 1011
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
amdgpu.hamdgpu_i2c.hamdgpu_atombios.hatom.hamd_pcie.hlegacy_dpm.hamdgpu_dpm_internal.hamdgpu_display.h
Detected Declarations
function filesfunction amdgpu_dpm_dbg_print_cap_infofunction amdgpu_dpm_dbg_print_ps_statusfunction amdgpu_pm_print_power_statesfunction amdgpu_get_platform_capsfunction amdgpu_parse_clk_voltage_dep_tablefunction amdgpu_parse_extended_power_tablefunction amdgpu_free_extended_power_tablefunction amdgpu_add_thermal_controllerfunction amdgpu_get_vce_clock_statefunction amdgpu_dpm_change_power_state_lockedfunction amdgpu_legacy_dpm_compute_clocksfunction amdgpu_dpm_thermal_work_handler
Annotated Snippet
sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
if (power_info->pplib3.usFanTableOffset) {
fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib3.usFanTableOffset));
adev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
adev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
adev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
adev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
adev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
adev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
adev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
if (fan_info->fan.ucFanTableFormat >= 2)
adev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
else
adev->pm.dpm.fan.t_max = 10900;
adev->pm.dpm.fan.cycle_delay = 100000;
if (fan_info->fan.ucFanTableFormat >= 3) {
adev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
adev->pm.dpm.fan.default_max_fan_pwm =
le16_to_cpu(fan_info->fan3.usFanPWMMax);
adev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
adev->pm.dpm.fan.fan_output_sensitivity =
le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
}
adev->pm.dpm.fan.ucode_fan_control = true;
}
}
/* clock dependancy tables, shedding tables */
if (le16_to_cpu(power_info->pplib.usTableSize) >=
sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
dep_table);
if (ret)
return ret;
}
if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
dep_table);
if (ret)
return ret;
}
if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
dep_table);
if (ret)
return ret;
}
if (power_info->pplib4.usMvddDependencyOnMCLKOffset) {
dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset));
ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
dep_table);
if (ret)
return ret;
}
if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
(ATOM_PPLIB_Clock_Voltage_Limit_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
if (clk_v->ucNumEntries) {
adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
le16_to_cpu(clk_v->entries[0].usSclkLow) |
(clk_v->entries[0].ucSclkHigh << 16);
adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
le16_to_cpu(clk_v->entries[0].usMclkLow) |
(clk_v->entries[0].ucMclkHigh << 16);
adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
le16_to_cpu(clk_v->entries[0].usVddc);
adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
le16_to_cpu(clk_v->entries[0].usVddci);
}
}
if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
(ATOM_PPLIB_PhaseSheddingLimits_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
Annotation
- Immediate include surface: `amdgpu.h`, `amdgpu_i2c.h`, `amdgpu_atombios.h`, `atom.h`, `amd_pcie.h`, `legacy_dpm.h`, `amdgpu_dpm_internal.h`, `amdgpu_display.h`.
- Detected declarations: `function files`, `function amdgpu_dpm_dbg_print_cap_info`, `function amdgpu_dpm_dbg_print_ps_status`, `function amdgpu_pm_print_power_states`, `function amdgpu_get_platform_caps`, `function amdgpu_parse_clk_voltage_dep_table`, `function amdgpu_parse_extended_power_table`, `function amdgpu_free_extended_power_table`, `function amdgpu_add_thermal_controller`, `function amdgpu_get_vce_clock_state`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.