drm/amd/pm: conditionally disable pcie lane switching for some sienna_cichlid SKUs
commit 38e4ced804796c5725e2a52ec3601951552c4a97 upstream. Disable the pcie lane switching for some sienna_cichlid SKUs since it might not work well on some platforms. Signed-off-by: Evan Quan <evan.quan@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8d42c563e4
commit
416ba40ff3
@ -2067,33 +2067,94 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sienna_cichlid_get_override_pcie_settings(struct smu_context *smu,
|
||||||
|
uint32_t *gen_speed_override,
|
||||||
|
uint32_t *lane_width_override)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
|
||||||
|
*gen_speed_override = 0xff;
|
||||||
|
*lane_width_override = 0xff;
|
||||||
|
|
||||||
|
switch (adev->pdev->device) {
|
||||||
|
case 0x73A0:
|
||||||
|
case 0x73A1:
|
||||||
|
case 0x73A2:
|
||||||
|
case 0x73A3:
|
||||||
|
case 0x73AB:
|
||||||
|
case 0x73AE:
|
||||||
|
/* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 */
|
||||||
|
*lane_width_override = 6;
|
||||||
|
break;
|
||||||
|
case 0x73E0:
|
||||||
|
case 0x73E1:
|
||||||
|
case 0x73E3:
|
||||||
|
*lane_width_override = 4;
|
||||||
|
break;
|
||||||
|
case 0x7420:
|
||||||
|
case 0x7421:
|
||||||
|
case 0x7422:
|
||||||
|
case 0x7423:
|
||||||
|
case 0x7424:
|
||||||
|
*lane_width_override = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
|
static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
|
||||||
uint32_t pcie_gen_cap,
|
uint32_t pcie_gen_cap,
|
||||||
uint32_t pcie_width_cap)
|
uint32_t pcie_width_cap)
|
||||||
{
|
{
|
||||||
struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
|
struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
|
||||||
|
struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table;
|
||||||
uint32_t smu_pcie_arg;
|
uint32_t gen_speed_override, lane_width_override;
|
||||||
uint8_t *table_member1, *table_member2;
|
uint8_t *table_member1, *table_member2;
|
||||||
|
uint32_t min_gen_speed, max_gen_speed;
|
||||||
|
uint32_t min_lane_width, max_lane_width;
|
||||||
|
uint32_t smu_pcie_arg;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1);
|
GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1);
|
||||||
GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2);
|
GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2);
|
||||||
|
|
||||||
/* lclk dpm table setup */
|
sienna_cichlid_get_override_pcie_settings(smu,
|
||||||
for (i = 0; i < MAX_PCIE_CONF; i++) {
|
&gen_speed_override,
|
||||||
dpm_context->dpm_tables.pcie_table.pcie_gen[i] = table_member1[i];
|
&lane_width_override);
|
||||||
dpm_context->dpm_tables.pcie_table.pcie_lane[i] = table_member2[i];
|
|
||||||
|
/* PCIE gen speed override */
|
||||||
|
if (gen_speed_override != 0xff) {
|
||||||
|
min_gen_speed = MIN(pcie_gen_cap, gen_speed_override);
|
||||||
|
max_gen_speed = MIN(pcie_gen_cap, gen_speed_override);
|
||||||
|
} else {
|
||||||
|
min_gen_speed = MAX(0, table_member1[0]);
|
||||||
|
max_gen_speed = MIN(pcie_gen_cap, table_member1[1]);
|
||||||
|
min_gen_speed = min_gen_speed > max_gen_speed ?
|
||||||
|
max_gen_speed : min_gen_speed;
|
||||||
}
|
}
|
||||||
|
pcie_table->pcie_gen[0] = min_gen_speed;
|
||||||
|
pcie_table->pcie_gen[1] = max_gen_speed;
|
||||||
|
|
||||||
|
/* PCIE lane width override */
|
||||||
|
if (lane_width_override != 0xff) {
|
||||||
|
min_lane_width = MIN(pcie_width_cap, lane_width_override);
|
||||||
|
max_lane_width = MIN(pcie_width_cap, lane_width_override);
|
||||||
|
} else {
|
||||||
|
min_lane_width = MAX(1, table_member2[0]);
|
||||||
|
max_lane_width = MIN(pcie_width_cap, table_member2[1]);
|
||||||
|
min_lane_width = min_lane_width > max_lane_width ?
|
||||||
|
max_lane_width : min_lane_width;
|
||||||
|
}
|
||||||
|
pcie_table->pcie_lane[0] = min_lane_width;
|
||||||
|
pcie_table->pcie_lane[1] = max_lane_width;
|
||||||
|
|
||||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||||
smu_pcie_arg = (i << 16) |
|
smu_pcie_arg = (i << 16 |
|
||||||
((table_member1[i] <= pcie_gen_cap) ?
|
pcie_table->pcie_gen[i] << 8 |
|
||||||
(table_member1[i] << 8) :
|
pcie_table->pcie_lane[i]);
|
||||||
(pcie_gen_cap << 8)) |
|
|
||||||
((table_member2[i] <= pcie_width_cap) ?
|
|
||||||
table_member2[i] :
|
|
||||||
pcie_width_cap);
|
|
||||||
|
|
||||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||||
SMU_MSG_OverridePcieParameters,
|
SMU_MSG_OverridePcieParameters,
|
||||||
@ -2101,11 +2162,6 @@ static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
|
|||||||
NULL);
|
NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (table_member1[i] > pcie_gen_cap)
|
|
||||||
dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap;
|
|
||||||
if (table_member2[i] > pcie_width_cap)
|
|
||||||
dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user