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.

Dependency Surface

Detected Declarations

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

Implementation Notes