drivers/gpu/drm/radeon/trinity_dpm.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/trinity_dpm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/radeon/trinity_dpm.c- Extension
.c- Size
- 59519 bytes
- Lines
- 2060
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/pci.hlinux/seq_file.hr600_dpm.hradeon.hradeon_asic.htrinity_dpm.htrinityd.hvce.h
Detected Declarations
function trinity_gfx_powergating_initializefunction trinity_mg_clockgating_enablefunction trinity_mg_clockgating_initializefunction trinity_gfx_clockgating_enablefunction trinity_program_clk_gating_hw_sequencefunction trinity_program_override_mgpg_sequencesfunction trinity_override_dynamic_mg_powergatingfunction trinity_ls_clockgating_enablefunction trinity_gfx_powergating_enablefunction trinity_gfx_dynamic_mgpg_enablefunction trinity_enable_clock_power_gatingfunction trinity_disable_clock_power_gatingfunction trinity_set_divider_valuefunction trinity_set_ds_dividersfunction trinity_set_ss_dividersfunction trinity_set_vidfunction trinity_set_allos_gnb_slowfunction trinity_set_force_nbp_statefunction trinity_set_display_wmfunction trinity_set_vce_wmfunction trinity_set_atfunction trinity_program_power_levelfunction trinity_power_level_enable_disablefunction trinity_dpm_enabledfunction trinity_start_dpmfunction trinity_wait_for_dpm_enabledfunction trinity_stop_dpmfunction trinity_start_amfunction trinity_reset_amfunction trinity_wait_for_level_0function trinity_enable_power_level_0function trinity_force_level_0function trinity_unforce_levelsfunction trinity_program_power_levels_0_to_nfunction trinity_program_bootup_statefunction trinity_setup_uvd_clock_tablefunction trinity_setup_uvd_dpm_intervalfunction trinity_uvd_clocks_zerofunction trinity_uvd_clocks_equalfunction trinity_setup_uvd_clocksfunction trinity_set_uvd_clock_before_set_eng_clockfunction trinity_set_uvd_clock_after_set_eng_clockfunction trinity_set_vce_clockfunction trinity_program_tttfunction trinity_enable_attfunction trinity_program_sclk_dpmfunction trinity_set_thermal_temperature_rangefunction trinity_update_current_ps
Annotated Snippet
if (trinity_uvd_clocks_zero(old_rps)) {
u32 tmp = RREG32(CG_MISC_REG);
tmp &= 0xfffffffd;
WREG32(CG_MISC_REG, tmp);
radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
trinity_setup_uvd_dpm_interval(rdev, 3000);
}
}
trinity_uvd_dpm_config(rdev);
} else {
if (trinity_uvd_clocks_zero(new_rps) ||
trinity_uvd_clocks_equal(new_rps, old_rps))
return;
radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
}
if (pi->enable_gfx_power_gating) {
trinity_gfx_powergating_enable(rdev, true);
}
}
static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
struct radeon_ps *new_rps,
struct radeon_ps *old_rps)
{
struct trinity_ps *new_ps = trinity_get_ps(new_rps);
struct trinity_ps *current_ps = trinity_get_ps(new_rps);
if (new_ps->levels[new_ps->num_levels - 1].sclk >=
current_ps->levels[current_ps->num_levels - 1].sclk)
return;
trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
}
static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
struct radeon_ps *new_rps,
struct radeon_ps *old_rps)
{
struct trinity_ps *new_ps = trinity_get_ps(new_rps);
struct trinity_ps *current_ps = trinity_get_ps(old_rps);
if (new_ps->levels[new_ps->num_levels - 1].sclk <
current_ps->levels[current_ps->num_levels - 1].sclk)
return;
trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
}
static void trinity_set_vce_clock(struct radeon_device *rdev,
struct radeon_ps *new_rps,
struct radeon_ps *old_rps)
{
if ((old_rps->evclk != new_rps->evclk) ||
(old_rps->ecclk != new_rps->ecclk)) {
/* turn the clocks on when encoding, off otherwise */
if (new_rps->evclk || new_rps->ecclk)
vce_v1_0_enable_mgcg(rdev, false);
else
vce_v1_0_enable_mgcg(rdev, true);
radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk);
}
}
static void trinity_program_ttt(struct radeon_device *rdev)
{
struct trinity_power_info *pi = trinity_get_pi(rdev);
u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT);
value &= ~(HT_MASK | LT_MASK);
value |= HT((pi->thermal_auto_throttling + 49) * 8);
value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8);
WREG32_SMC(SMU_SCLK_DPM_TTT, value);
}
static void trinity_enable_att(struct radeon_device *rdev)
{
u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL);
value &= ~SCLK_TT_EN_MASK;
value |= SCLK_TT_EN(1);
WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value);
}
static void trinity_program_sclk_dpm(struct radeon_device *rdev)
{
u32 p, u;
Annotation
- Immediate include surface: `linux/pci.h`, `linux/seq_file.h`, `r600_dpm.h`, `radeon.h`, `radeon_asic.h`, `trinity_dpm.h`, `trinityd.h`, `vce.h`.
- Detected declarations: `function trinity_gfx_powergating_initialize`, `function trinity_mg_clockgating_enable`, `function trinity_mg_clockgating_initialize`, `function trinity_gfx_clockgating_enable`, `function trinity_program_clk_gating_hw_sequence`, `function trinity_program_override_mgpg_sequences`, `function trinity_override_dynamic_mg_powergating`, `function trinity_ls_clockgating_enable`, `function trinity_gfx_powergating_enable`, `function trinity_gfx_dynamic_mgpg_enable`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.