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

Commit e85c7d66 authored by yanyang1's avatar yanyang1 Committed by Alex Deucher
Browse files

drm/amd/powerplay: update baffin & ellesmere smc_sk firmware.



sync the code form catalyst CL:#1230866.

Signed-off-by: default avataryanyang1 <Young.Yang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a6ece7ff
Loading
Loading
Loading
Loading
+50 −1
Original line number Diff line number Diff line
@@ -222,6 +222,22 @@ void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
			" found a available voltage in VDDC DPM Table \n");
}

/**
* Enable voltage control
*
* @param    pHwMgr  the address of the powerplay hardware manager.
* @return   always PP_Result_OK
*/
int ellesmere_enable_smc_voltage_controller(struct pp_hwmgr *hwmgr)
{
	PP_ASSERT_WITH_CODE(
		(hwmgr->smumgr->smumgr_funcs->send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Voltage_Cntl_Enable) == 0),
		"Failed to enable voltage DPM during DPM Start Function!",
		return 1;
	);

	return 0;
}

/**
* Checks if we want to support voltage control
@@ -586,6 +602,10 @@ static int ellesmere_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
							pcie_table->entries[i].lane_width));
		}
		data->dpm_table.pcie_speed_table.count = max_entry - 1;

		/* Setup BIF_SCLK levels */
		for (i = 0; i < max_entry; i++)
			data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk;
	} else {
		/* Hardcode Pcie Table */
		phm_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 0,
@@ -938,9 +958,13 @@ static int ellesmere_calculate_sclk_params(struct pp_hwmgr *hwmgr,
		sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac;
		sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int;
		sclk_setting->PllRange = dividers.ucSclkPllRange;
		sclk_setting->Sclk_slew_rate = 0x400;
		sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac;
		sclk_setting->Pcc_down_slew_rate = 0xffff;
		sclk_setting->SSc_En = dividers.ucSscEnable;
		sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int;
		sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac;
		sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac;
		return result;
	}

@@ -1174,8 +1198,12 @@ static int ellesmere_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac);
	CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate);
	return 0;
}

@@ -1458,8 +1486,12 @@ static int ellesmere_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_int);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_frac);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_fcw_int);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_slew_rate);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_up_slew_rate);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_down_slew_rate);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_int);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac);
	CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate);

	if (!data->mclk_dpm_key_disabled) {
		/* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */
@@ -1966,6 +1998,7 @@ static int ellesmere_init_smc_table(struct pp_hwmgr *hwmgr)
	const struct ellesmere_ulv_parm *ulv = &(data->ulv);
	uint8_t i;
	struct pp_atomctrl_gpio_pin_assignment gpio_pin;
	pp_atomctrl_clock_dividers_vi dividers;

	result = ellesmere_setup_default_dpm_tables(hwmgr);
	PP_ASSERT_WITH_CODE(0 == result,
@@ -2121,6 +2154,17 @@ static int ellesmere_init_smc_table(struct pp_hwmgr *hwmgr)
		table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE;
	}

	/* Populate BIF_SCLK levels into SMC DPM table */
	for (i = 0; i <= data->dpm_table.pcie_speed_table.count; i++) {
		result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, data->bif_sclk_table[i], &dividers);
		PP_ASSERT_WITH_CODE((result == 0), "Can not find DFS divide id for Sclk", return result);

		if (i == 0)
			table->Ulv.BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider));
		else
			table->LinkLevel[i-1].BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider));
	}

	for (i = 0; i < SMU74_MAX_ENTRIES_SMIO; i++)
		table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]);

@@ -2284,12 +2328,13 @@ static int ellesmere_start_dpm(struct pp_hwmgr *hwmgr)
					VoltageChangeTimeout), 0x1000);
	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE,
			SWRST_COMMAND_1, RESETLC, 0x0);

/*
	PP_ASSERT_WITH_CODE(
			(0 == smum_send_msg_to_smc(hwmgr->smumgr,
					PPSMC_MSG_Voltage_Cntl_Enable)),
			"Failed to enable voltage DPM during DPM Start Function!",
			return -1);
*/

	if (ellesmere_enable_sclk_mclk_dpm(hwmgr)) {
		printk(KERN_ERR "Failed to enable Sclk DPM and Mclk DPM!");
@@ -2450,6 +2495,10 @@ int ellesmere_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
	PP_ASSERT_WITH_CODE((0 == tmp_result),
			"Failed to enable SCLK control!", result = tmp_result);

	tmp_result = ellesmere_enable_smc_voltage_controller(hwmgr);
	PP_ASSERT_WITH_CODE((0 == tmp_result),
			"Failed to enable voltage control!", result = tmp_result);

	tmp_result = ellesmere_enable_ulv(hwmgr);
	PP_ASSERT_WITH_CODE((0 == tmp_result),
			"Failed to enable ULV!", result = tmp_result);
+1 −0
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ struct ellesmere_hwmgr {

	/* ---- DI/DT ---- */
	struct ellesmere_display_timing        display_timing;
	uint32_t                      bif_sclk_table[SMU74_MAX_LEVELS_LINK];

	/* ---- Thermal Temperature Setting ---- */
	struct ellesmere_dpmlevel_enable_mask     dpm_level_enable_mask;
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ typedef struct phm_ppt_v1_voltage_lookup_table phm_ppt_v1_voltage_lookup_table;
struct phm_ppt_v1_pcie_record {
	uint8_t gen_speed;
	uint8_t lane_width;
	uint16_t usreserved;
	uint32_t pcie_sclk;
};
typedef struct phm_ppt_v1_pcie_record phm_ppt_v1_pcie_record;

+14 −0
Original line number Diff line number Diff line
@@ -209,6 +209,20 @@ typedef struct _ATOM_Tonga_PCIE_Table {
	ATOM_Tonga_PCIE_Record entries[1];							/* Dynamically allocate entries. */
} ATOM_Tonga_PCIE_Table;

typedef struct _ATOM_Ellesmere_PCIE_Record {
	UCHAR ucPCIEGenSpeed;
	UCHAR usPCIELaneWidth;
	UCHAR ucReserved[2];
	ULONG ulPCIE_Sclk;
} ATOM_Ellesmere_PCIE_Record;

typedef struct _ATOM_Ellesmere_PCIE_Table {
	UCHAR ucRevId;
	UCHAR ucNumEntries;                                         /* Number of entries. */
	ATOM_Ellesmere_PCIE_Record entries[1];                      /* Dynamically allocate entries. */
} ATOM_Ellesmere_PCIE_Table;


typedef struct _ATOM_Tonga_MM_Dependency_Record {
	UCHAR   ucVddcInd;											 /* VDDC voltage */
	USHORT  usVddgfxOffset;									  /* Offset relative to VDDC voltage */
+72 −29
Original line number Diff line number Diff line
@@ -448,14 +448,54 @@ static int get_sclk_voltage_dependency_table(
static int get_pcie_table(
		struct pp_hwmgr *hwmgr,
		phm_ppt_v1_pcie_table **pp_tonga_pcie_table,
		const ATOM_Tonga_PCIE_Table * atom_pcie_table
		const PPTable_Generic_SubTable_Header * pTable
		)
{
	uint32_t table_size, i, pcie_count;
	phm_ppt_v1_pcie_table *pcie_table;
	struct phm_ppt_v1_information *pp_table_information =
		(struct phm_ppt_v1_information *)(hwmgr->pptable);
	PP_ASSERT_WITH_CODE((0 != atom_pcie_table->ucNumEntries),

	if (pTable->ucRevId < 1) {
		const ATOM_Tonga_PCIE_Table *atom_pcie_table = (ATOM_Tonga_PCIE_Table *)pTable;
		PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0),
			"Invalid PowerPlay Table!", return -1);

		table_size = sizeof(uint32_t) +
			sizeof(phm_ppt_v1_pcie_record) * atom_pcie_table->ucNumEntries;

		pcie_table = (phm_ppt_v1_pcie_table *)kzalloc(table_size, GFP_KERNEL);

		if (pcie_table == NULL)
			return -ENOMEM;

		memset(pcie_table, 0x00, table_size);

		/*
		* Make sure the number of pcie entries are less than or equal to sclk dpm levels.
		* Since first PCIE entry is for ULV, #pcie has to be <= SclkLevel + 1.
		*/
		pcie_count = (pp_table_information->vdd_dep_on_sclk->count) + 1;
		if ((uint32_t)atom_pcie_table->ucNumEntries <= pcie_count)
			pcie_count = (uint32_t)atom_pcie_table->ucNumEntries;
		else
			printk(KERN_ERR "[ powerplay ] Number of Pcie Entries exceed the number of SCLK Dpm Levels! \
			Disregarding the excess entries... \n");

		pcie_table->count = pcie_count;

		for (i = 0; i < pcie_count; i++) {
			pcie_table->entries[i].gen_speed =
				atom_pcie_table->entries[i].ucPCIEGenSpeed;
			pcie_table->entries[i].lane_width =
				atom_pcie_table->entries[i].usPCIELaneWidth;
		}

		*pp_tonga_pcie_table = pcie_table;
	} else {
		/* Ellesmere/Baffin and newer. */
		const ATOM_Ellesmere_PCIE_Table *atom_pcie_table = (ATOM_Ellesmere_PCIE_Table *)pTable;
		PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0),
			"Invalid PowerPlay Table!", return -1);

		table_size = sizeof(uint32_t) +
@@ -463,7 +503,7 @@ static int get_pcie_table(

		pcie_table = (phm_ppt_v1_pcie_table *)kzalloc(table_size, GFP_KERNEL);

	if (NULL == pcie_table)
		if (pcie_table == NULL)
			return -ENOMEM;

		memset(pcie_table, 0x00, table_size);
@@ -486,9 +526,12 @@ static int get_pcie_table(
				atom_pcie_table->entries[i].ucPCIEGenSpeed;
			pcie_table->entries[i].lane_width =
				atom_pcie_table->entries[i].usPCIELaneWidth;
			pcie_table->entries[i].pcie_sclk =
				atom_pcie_table->entries[i].ulPCIE_Sclk;
		}

		*pp_tonga_pcie_table = pcie_table;
	}

	return 0;
}
@@ -668,8 +711,8 @@ static int init_clock_voltage_dependency(
	const ATOM_Tonga_Hard_Limit_Table *pHardLimits =
		(const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) +
		le16_to_cpu(powerplay_table->usHardLimitTableOffset));
	const ATOM_Tonga_PCIE_Table *pcie_table =
		(const ATOM_Tonga_PCIE_Table *)(((unsigned long) powerplay_table) +
	const PPTable_Generic_SubTable_Header *pcie_table =
		(const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
		le16_to_cpu(powerplay_table->usPCIETableOffset));

	pp_table_information->vdd_dep_on_sclk = NULL;
Loading