Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 432c3a3c authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

drm/amd/powerplay: enable avfs feature for polaris



avfs feature is for voltage control based on
gpu system clock on polaris10

Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c11cb704
Loading
Loading
Loading
Loading
+88 −2
Original line number Original line Diff line number Diff line
@@ -1303,7 +1303,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
	mem_level->VoltageDownHyst = 0;
	mem_level->VoltageDownHyst = 0;
	mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
	mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
	mem_level->StutterEnable = false;
	mem_level->StutterEnable = false;

	mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
	mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;


	data->display_timing.num_existing_displays = info.display_count;
	data->display_timing.num_existing_displays = info.display_count;
@@ -1955,6 +1954,90 @@ static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr,
	return 0;
	return 0;
}
}



int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
{
	struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
	SMU74_Discrete_DpmTable  *table = &(data->smc_state_table);
	int result = 0;
	struct pp_atom_ctrl__avfs_parameters avfs_params = {0};
	AVFS_meanNsigma_t AVFS_meanNsigma = { {0} };
	AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} };
	uint32_t tmp, i;
	struct pp_smumgr *smumgr = hwmgr->smumgr;
	struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);

	struct phm_ppt_v1_information *table_info =
			(struct phm_ppt_v1_information *)hwmgr->pptable;
	struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
			table_info->vdd_dep_on_sclk;


	if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
		return result;

	result = atomctrl_get_avfs_information(hwmgr, &avfs_params);

	if (0 == result) {
		table->BTCGB_VDROOP_TABLE[0].a0  = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0);
		table->BTCGB_VDROOP_TABLE[0].a1  = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1);
		table->BTCGB_VDROOP_TABLE[0].a2  = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2);
		table->BTCGB_VDROOP_TABLE[1].a0  = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0);
		table->BTCGB_VDROOP_TABLE[1].a1  = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1);
		table->BTCGB_VDROOP_TABLE[1].a2  = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2);
		table->AVFSGB_VDROOP_TABLE[0].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1);
		table->AVFSGB_VDROOP_TABLE[0].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2);
		table->AVFSGB_VDROOP_TABLE[0].b  = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b);
		table->AVFSGB_VDROOP_TABLE[0].m1_shift = 24;
		table->AVFSGB_VDROOP_TABLE[0].m2_shift  = 12;
		table->AVFSGB_VDROOP_TABLE[1].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1);
		table->AVFSGB_VDROOP_TABLE[1].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2);
		table->AVFSGB_VDROOP_TABLE[1].b  = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b);
		table->AVFSGB_VDROOP_TABLE[1].m1_shift = 24;
		table->AVFSGB_VDROOP_TABLE[1].m2_shift  = 12;
		table->MaxVoltage                = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv);
		AVFS_meanNsigma.Aconstant[0]      = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0);
		AVFS_meanNsigma.Aconstant[1]      = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1);
		AVFS_meanNsigma.Aconstant[2]      = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2);
		AVFS_meanNsigma.DC_tol_sigma      = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma);
		AVFS_meanNsigma.Platform_mean     = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean);
		AVFS_meanNsigma.PSM_Age_CompFactor = PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor);
		AVFS_meanNsigma.Platform_sigma     = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma);

		for (i = 0; i < NUM_VFT_COLUMNS; i++) {
			AVFS_meanNsigma.Static_Voltage_Offset[i] = (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625);
			AVFS_SclkOffset.Sclk_Offset[i] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table->entries[i].sclk_offset) / 100);
		}

		result = polaris10_read_smc_sram_dword(smumgr,
				SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsMeanNSigma),
				&tmp, data->sram_end);

		polaris10_copy_bytes_to_smc(smumgr,
					tmp,
					(uint8_t *)&AVFS_meanNsigma,
					sizeof(AVFS_meanNsigma_t),
					data->sram_end);

		result = polaris10_read_smc_sram_dword(smumgr,
				SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsSclkOffsetTable),
				&tmp, data->sram_end);
		polaris10_copy_bytes_to_smc(smumgr,
					tmp,
					(uint8_t *)&AVFS_SclkOffset,
					sizeof(AVFS_Sclk_Offset_t),
					data->sram_end);

		data->avfs_vdroop_override_setting = (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) |
						(avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) |
						(avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) |
						(avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT);
		data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false;
	}
	return result;
}


/**
/**
* Initializes the SMC table and uploads it
* Initializes the SMC table and uploads it
*
*
@@ -2055,6 +2138,10 @@ static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr)
				"Failed to populate Clock Stretcher Data Table!",
				"Failed to populate Clock Stretcher Data Table!",
				return result);
				return result);
	}
	}

	result = polaris10_populate_avfs_parameters(hwmgr);
	PP_ASSERT_WITH_CODE(0 == result, "Failed to populate AVFS Parameters!", return result;);

	table->CurrSclkPllRange = 0xff;
	table->CurrSclkPllRange = 0xff;
	table->GraphicsVoltageChangeEnable  = 1;
	table->GraphicsVoltageChangeEnable  = 1;
	table->GraphicsThermThrottleEnable  = 1;
	table->GraphicsThermThrottleEnable  = 1;
@@ -2277,7 +2364,6 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
				"Failed to enable MCLK DPM during DPM Start Function!",
				"Failed to enable MCLK DPM during DPM Start Function!",
				return -1);
				return -1);



		PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);
		PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);


		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x5);
		cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x5);
+3 −0
Original line number Original line Diff line number Diff line
@@ -312,6 +312,9 @@ struct polaris10_hwmgr {


	/* soft pptable for re-uploading into smu */
	/* soft pptable for re-uploading into smu */
	void *soft_pp_table;
	void *soft_pp_table;

	uint32_t                              avfs_vdroop_override_setting;
	bool                                  apply_avfs_cks_off_voltage;
};
};


/* To convert to Q8.8 format for firmware */
/* To convert to Q8.8 format for firmware */
+5 −1
Original line number Original line Diff line number Diff line
@@ -625,10 +625,14 @@ static int tf_polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr,
	int ret;
	int ret;
	struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
	struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
	struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
	struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
	struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);


	if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS)
	if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
		return 0;
		return 0;


	ret = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
			PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting);

	ret = (smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs) == 0) ?
	ret = (smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs) == 0) ?
			0 : -1;
			0 : -1;


+43 −0
Original line number Original line Diff line number Diff line
@@ -1302,3 +1302,46 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr


	return 0;
	return 0;
}
}

int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param)
{
	ATOM_ASIC_PROFILING_INFO_V3_6 *profile = NULL;

	if (param == NULL)
		return -EINVAL;

	profile = (ATOM_ASIC_PROFILING_INFO_V3_6 *)
			cgs_atom_get_data_table(hwmgr->device,
					GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
					NULL, NULL, NULL);
	if (!profile)
		return -1;

	param->ulAVFS_meanNsigma_Acontant0 = profile->ulAVFS_meanNsigma_Acontant0;
	param->ulAVFS_meanNsigma_Acontant1 = profile->ulAVFS_meanNsigma_Acontant1;
	param->ulAVFS_meanNsigma_Acontant2 = profile->ulAVFS_meanNsigma_Acontant2;
	param->usAVFS_meanNsigma_DC_tol_sigma = profile->usAVFS_meanNsigma_DC_tol_sigma;
	param->usAVFS_meanNsigma_Platform_mean = profile->usAVFS_meanNsigma_Platform_mean;
	param->usAVFS_meanNsigma_Platform_sigma = profile->usAVFS_meanNsigma_Platform_sigma;
	param->ulGB_VDROOP_TABLE_CKSOFF_a0 = profile->ulGB_VDROOP_TABLE_CKSOFF_a0;
	param->ulGB_VDROOP_TABLE_CKSOFF_a1 = profile->ulGB_VDROOP_TABLE_CKSOFF_a1;
	param->ulGB_VDROOP_TABLE_CKSOFF_a2 = profile->ulGB_VDROOP_TABLE_CKSOFF_a2;
	param->ulGB_VDROOP_TABLE_CKSON_a0 = profile->ulGB_VDROOP_TABLE_CKSON_a0;
	param->ulGB_VDROOP_TABLE_CKSON_a1 = profile->ulGB_VDROOP_TABLE_CKSON_a1;
	param->ulGB_VDROOP_TABLE_CKSON_a2 = profile->ulGB_VDROOP_TABLE_CKSON_a2;
	param->ulAVFSGB_FUSE_TABLE_CKSOFF_m1 = profile->ulAVFSGB_FUSE_TABLE_CKSOFF_m1;
	param->usAVFSGB_FUSE_TABLE_CKSOFF_m2 = profile->usAVFSGB_FUSE_TABLE_CKSOFF_m2;
	param->ulAVFSGB_FUSE_TABLE_CKSOFF_b = profile->ulAVFSGB_FUSE_TABLE_CKSOFF_b;
	param->ulAVFSGB_FUSE_TABLE_CKSON_m1 = profile->ulAVFSGB_FUSE_TABLE_CKSON_m1;
	param->usAVFSGB_FUSE_TABLE_CKSON_m2 = profile->usAVFSGB_FUSE_TABLE_CKSON_m2;
	param->ulAVFSGB_FUSE_TABLE_CKSON_b = profile->ulAVFSGB_FUSE_TABLE_CKSON_b;
	param->usMaxVoltage_0_25mv = profile->usMaxVoltage_0_25mv;
	param->ucEnableGB_VDROOP_TABLE_CKSOFF = profile->ucEnableGB_VDROOP_TABLE_CKSOFF;
	param->ucEnableGB_VDROOP_TABLE_CKSON = profile->ucEnableGB_VDROOP_TABLE_CKSON;
	param->ucEnableGB_FUSE_TABLE_CKSOFF = profile->ucEnableGB_FUSE_TABLE_CKSOFF;
	param->ucEnableGB_FUSE_TABLE_CKSON = profile->ucEnableGB_FUSE_TABLE_CKSON;
	param->usPSM_Age_ComFactor = profile->usPSM_Age_ComFactor;
	param->ucEnableApplyAVFS_CKS_OFF_Voltage = profile->ucEnableApplyAVFS_CKS_OFF_Voltage;

	return 0;
}
+32 −0
Original line number Original line Diff line number Diff line
@@ -250,6 +250,35 @@ struct pp_atomctrl_gpio_pin_assignment {
};
};
typedef struct pp_atomctrl_gpio_pin_assignment pp_atomctrl_gpio_pin_assignment;
typedef struct pp_atomctrl_gpio_pin_assignment pp_atomctrl_gpio_pin_assignment;


struct pp_atom_ctrl__avfs_parameters {
	uint32_t  ulAVFS_meanNsigma_Acontant0;
	uint32_t  ulAVFS_meanNsigma_Acontant1;
	uint32_t  ulAVFS_meanNsigma_Acontant2;
	uint16_t usAVFS_meanNsigma_DC_tol_sigma;
	uint16_t usAVFS_meanNsigma_Platform_mean;
	uint16_t usAVFS_meanNsigma_Platform_sigma;
	uint32_t  ulGB_VDROOP_TABLE_CKSOFF_a0;
	uint32_t  ulGB_VDROOP_TABLE_CKSOFF_a1;
	uint32_t  ulGB_VDROOP_TABLE_CKSOFF_a2;
	uint32_t  ulGB_VDROOP_TABLE_CKSON_a0;
	uint32_t  ulGB_VDROOP_TABLE_CKSON_a1;
	uint32_t  ulGB_VDROOP_TABLE_CKSON_a2;
	uint32_t  ulAVFSGB_FUSE_TABLE_CKSOFF_m1;
	uint16_t  usAVFSGB_FUSE_TABLE_CKSOFF_m2;
	uint32_t  ulAVFSGB_FUSE_TABLE_CKSOFF_b;
	uint32_t  ulAVFSGB_FUSE_TABLE_CKSON_m1;
	uint16_t  usAVFSGB_FUSE_TABLE_CKSON_m2;
	uint32_t  ulAVFSGB_FUSE_TABLE_CKSON_b;
	uint16_t  usMaxVoltage_0_25mv;
	uint8_t  ucEnableGB_VDROOP_TABLE_CKSOFF;
	uint8_t  ucEnableGB_VDROOP_TABLE_CKSON;
	uint8_t  ucEnableGB_FUSE_TABLE_CKSOFF;
	uint8_t  ucEnableGB_FUSE_TABLE_CKSON;
	uint16_t usPSM_Age_ComFactor;
	uint8_t  ucEnableApplyAVFS_CKS_OFF_Voltage;
	uint8_t  ucReserved;
};

extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment);
extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment);
extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
extern uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr);
extern uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr);
@@ -278,5 +307,8 @@ extern int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clo
extern int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
extern int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
				uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
				uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
extern int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl_sclk_range_table *table);
extern int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl_sclk_range_table *table);

extern int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param);

#endif
#endif
Loading