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.

Dependency Surface

Detected Declarations

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

Implementation Notes