drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c
Extension
.c
Size
56132 bytes
Lines
2023
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 (i < SMU8_NUM_NBPMEMORYCLOCK) {
			data->sys_info.nbp_memory_clock[i] =
			  le32_to_cpu(info->ulNbpStateMemclkFreq[i]);
		}
		data->sys_info.nbp_n_clock[i] =
			    le32_to_cpu(info->ulNbpStateNClkFreq[i]);
	}

	for (i = 0; i < MAX_DISPLAY_CLOCK_LEVEL; i++) {
		data->sys_info.display_clock[i] =
					le32_to_cpu(info->sDispClkVoltageMapping[i].ulMaximumSupportedCLK);
	}

	/* Here use 4 levels, make sure not exceed */
	for (i = 0; i < SMU8_NUM_NBPSTATES; i++) {
		data->sys_info.nbp_voltage_index[i] =
			     le16_to_cpu(info->usNBPStateVoltage[i]);
	}

	if (!data->sys_info.nb_dpm_enable) {
		for (i = 1; i < SMU8_NUM_NBPSTATES; i++) {
			if (i < SMU8_NUM_NBPMEMORYCLOCK) {
				data->sys_info.nbp_memory_clock[i] =
				    data->sys_info.nbp_memory_clock[0];
			}
			data->sys_info.nbp_n_clock[i] =
				    data->sys_info.nbp_n_clock[0];
			data->sys_info.nbp_voltage_index[i] =
				    data->sys_info.nbp_voltage_index[0];
		}
	}

	if (le32_to_cpu(info->ulGPUCapInfo) &
		SYS_INFO_GPUCAPS__ENABLE_DFS_BYPASS) {
		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
				    PHM_PlatformCaps_EnableDFSBypass);
	}

	data->sys_info.uma_channel_number = info->ucUMAChannelNumber;

	smu8_construct_max_power_limits_table (hwmgr,
				    &hwmgr->dyn_state.max_clock_voltage_on_ac);

	return result;
}

static int smu8_construct_boot_state(struct pp_hwmgr *hwmgr)
{
	struct smu8_hwmgr *data = hwmgr->backend;

	data->boot_power_level.engineClock =
				data->sys_info.bootup_engine_clock;

	data->boot_power_level.vddcIndex =
			(uint8_t)data->sys_info.bootup_nb_voltage_index;

	data->boot_power_level.dsDividerIndex = 0;
	data->boot_power_level.ssDividerIndex = 0;
	data->boot_power_level.allowGnbSlow = 1;
	data->boot_power_level.forceNBPstate = 0;
	data->boot_power_level.hysteresis_up = 0;
	data->boot_power_level.numSIMDToPowerDown = 0;
	data->boot_power_level.display_wm = 0;
	data->boot_power_level.vce_wm = 0;

	return 0;
}

static int smu8_upload_pptable_to_smu(struct pp_hwmgr *hwmgr)
{
	struct SMU8_Fusion_ClkTable *clock_table;
	int ret;
	uint32_t i;
	void *table = NULL;
	pp_atomctrl_clock_dividers_kong dividers;

	struct phm_clock_voltage_dependency_table *vddc_table =
		hwmgr->dyn_state.vddc_dependency_on_sclk;
	struct phm_clock_voltage_dependency_table *vdd_gfx_table =
		hwmgr->dyn_state.vdd_gfx_dependency_on_sclk;
	struct phm_acp_clock_voltage_dependency_table *acp_table =
		hwmgr->dyn_state.acp_clock_voltage_dependency_table;
	struct phm_uvd_clock_voltage_dependency_table *uvd_table =
		hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
	struct phm_vce_clock_voltage_dependency_table *vce_table =
		hwmgr->dyn_state.vce_clock_voltage_dependency_table;

	if (!hwmgr->need_pp_table_upload)
		return 0;

Annotation

Implementation Notes