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

Commit 3ff21127 authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

drm/amd/powerplay: update powerplay table parsing



to handle pptable format change on Polaris boards

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 7c4021d4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record {
	uint8_t phases;
	uint8_t cks_enable;
	uint8_t cks_voffset;
	uint32_t sclk_offset;
};

typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record;
+16 −7
Original line number Diff line number Diff line
@@ -3520,10 +3520,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
	ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state;
	ATOM_Tonga_POWERPLAYTABLE *powerplay_table =
			(ATOM_Tonga_POWERPLAYTABLE *)pp_table;
	ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table =
			(ATOM_Tonga_SCLK_Dependency_Table *)
	PPTable_Generic_SubTable_Header *sclk_dep_table =
			(PPTable_Generic_SubTable_Header *)
			(((unsigned long)powerplay_table) +
				le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));

	ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
			(ATOM_Tonga_MCLK_Dependency_Table *)
			(((unsigned long)powerplay_table) +
@@ -3575,7 +3576,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
	/* Performance levels are arranged from low to high. */
	performance_level->memory_clock = mclk_dep_table->entries
			[state_entry->ucMemoryClockIndexLow].ulMclk;
	performance_level->engine_clock = sclk_dep_table->entries
	if (sclk_dep_table->ucRevId == 0)
		performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries
			[state_entry->ucEngineClockIndexLow].ulSclk;
	else if (sclk_dep_table->ucRevId == 1)
		performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries
			[state_entry->ucEngineClockIndexLow].ulSclk;
	performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
			state_entry->ucPCIEGenLow);
@@ -3586,8 +3591,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
			[polaris10_power_state->performance_level_count++]);
	performance_level->memory_clock = mclk_dep_table->entries
			[state_entry->ucMemoryClockIndexHigh].ulMclk;
	performance_level->engine_clock = sclk_dep_table->entries

	if (sclk_dep_table->ucRevId == 0)
		performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries
			[state_entry->ucEngineClockIndexHigh].ulSclk;
	else if (sclk_dep_table->ucRevId == 1)
		performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries
			[state_entry->ucEngineClockIndexHigh].ulSclk;

	performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
			state_entry->ucPCIEGenHigh);
	performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap,
@@ -3645,7 +3656,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
		switch (state->classification.ui_label) {
		case PP_StateUILabel_Performance:
			data->use_pcie_performance_levels = true;

			for (i = 0; i < ps->performance_level_count; i++) {
				if (data->pcie_gen_performance.max <
						ps->performance_levels[i].pcie_gen)
@@ -3661,7 +3671,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
						ps->performance_levels[i].pcie_lane)
					data->pcie_lane_performance.max =
							ps->performance_levels[i].pcie_lane;

				if (data->pcie_lane_performance.min >
						ps->performance_levels[i].pcie_lane)
					data->pcie_lane_performance.min =
+16 −0
Original line number Diff line number Diff line
@@ -197,6 +197,22 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table {
	ATOM_Tonga_SCLK_Dependency_Record entries[1];				 /* Dynamically allocate entries. */
} ATOM_Tonga_SCLK_Dependency_Table;

typedef struct _ATOM_Polaris_SCLK_Dependency_Record {
	UCHAR  ucVddInd;											/* Base voltage */
	USHORT usVddcOffset;										/* Offset relative to base voltage */
	ULONG ulSclk;
	USHORT usEdcCurrent;
	UCHAR  ucReliabilityTemperature;
	UCHAR  ucCKSVOffsetandDisable;			/* Bits 0~6: Voltage offset for CKS, Bit 7: Disable/enable for the SCLK level. */
	ULONG  ulSclkOffset;
} ATOM_Polaris_SCLK_Dependency_Record;

typedef struct _ATOM_Polaris_SCLK_Dependency_Table {
	UCHAR ucRevId;
	UCHAR ucNumEntries;							/* Number of entries. */
	ATOM_Polaris_SCLK_Dependency_Record entries[1];				 /* Dynamically allocate entries. */
} ATOM_Polaris_SCLK_Dependency_Table;

typedef struct _ATOM_Tonga_PCIE_Record {
	UCHAR ucPCIEGenSpeed;
	UCHAR usPCIELaneWidth;
+64 −27
Original line number Diff line number Diff line
@@ -408,17 +408,21 @@ static int get_mclk_voltage_dependency_table(
static int get_sclk_voltage_dependency_table(
		struct pp_hwmgr *hwmgr,
		phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table,
		const ATOM_Tonga_SCLK_Dependency_Table * sclk_dep_table
		const PPTable_Generic_SubTable_Header *sclk_dep_table
		)
{
	uint32_t table_size, i;
	phm_ppt_v1_clock_voltage_dependency_table *sclk_table;

	PP_ASSERT_WITH_CODE((0 != sclk_dep_table->ucNumEntries),
	if (sclk_dep_table->ucRevId < 1) {
		const ATOM_Tonga_SCLK_Dependency_Table *tonga_table =
			    (ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table;

		PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries),
			"Invalid PowerPlay Table!", return -1);

		table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record)
		* sclk_dep_table->ucNumEntries;
			* tonga_table->ucNumEntries;

		sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
			kzalloc(table_size, GFP_KERNEL);
@@ -428,21 +432,54 @@ static int get_sclk_voltage_dependency_table(

		memset(sclk_table, 0x00, table_size);

	sclk_table->count = (uint32_t)sclk_dep_table->ucNumEntries;
		sclk_table->count = (uint32_t)tonga_table->ucNumEntries;

	for (i = 0; i < sclk_dep_table->ucNumEntries; i++) {
		for (i = 0; i < tonga_table->ucNumEntries; i++) {
			sclk_table->entries[i].vddInd =
			sclk_dep_table->entries[i].ucVddInd;
				tonga_table->entries[i].ucVddInd;
			sclk_table->entries[i].vdd_offset =
			sclk_dep_table->entries[i].usVddcOffset;
				tonga_table->entries[i].usVddcOffset;
			sclk_table->entries[i].clk =
			sclk_dep_table->entries[i].ulSclk;
				tonga_table->entries[i].ulSclk;
			sclk_table->entries[i].cks_enable =
			(((sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
				(((tonga_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
			sclk_table->entries[i].cks_voffset =
			(sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x7F);
				(tonga_table->entries[i].ucCKSVOffsetandDisable & 0x7F);
		}
	} else {
		const ATOM_Polaris_SCLK_Dependency_Table *polaris_table =
			    (ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table;

		PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries),
			"Invalid PowerPlay Table!", return -1);

		table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record)
			* polaris_table->ucNumEntries;

		sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
			kzalloc(table_size, GFP_KERNEL);

		if (NULL == sclk_table)
			return -ENOMEM;

		memset(sclk_table, 0x00, table_size);

		sclk_table->count = (uint32_t)polaris_table->ucNumEntries;

		for (i = 0; i < polaris_table->ucNumEntries; i++) {
			sclk_table->entries[i].vddInd =
				polaris_table->entries[i].ucVddInd;
			sclk_table->entries[i].vdd_offset =
				polaris_table->entries[i].usVddcOffset;
			sclk_table->entries[i].clk =
				polaris_table->entries[i].ulSclk;
			sclk_table->entries[i].cks_enable =
				(((polaris_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
			sclk_table->entries[i].cks_voffset =
				(polaris_table->entries[i].ucCKSVOffsetandDisable & 0x7F);
			sclk_table->entries[i].sclk_offset = polaris_table->entries[i].ulSclkOffset;
		}
	}
	*pp_tonga_sclk_dep_table = sclk_table;

	return 0;
@@ -708,8 +745,8 @@ static int init_clock_voltage_dependency(
	const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
		(const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) +
		le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
	const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table =
		(const ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long) powerplay_table) +
	const PPTable_Generic_SubTable_Header *sclk_dep_table =
		(const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
		le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
	const ATOM_Tonga_Hard_Limit_Table *pHardLimits =
		(const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) +