Merge branch 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
A bit bigger than I would normally like, but most of the large changes are for polaris support and since polaris went upstream in 4.7, I'd like to get the fixes in so it's in good shape when the hw becomes available. The major changes only touch the polaris code so there is little chance for regressions on other asics. The rest are just the usual collection of bug fixes. * 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/linux: drm/amd/powerplay: enable clock stretch feature for polaris drm/amdgpu/gfx8: update golden setting for polaris10 drm/amd/powerplay: enable avfs feature for polaris drm/amdgpu/atombios: add avfs struct for Polaris10/11 drm/amd/powerplay: add avfs related define for polaris drm/amd/powrplay: enable stutter_mode for polaris. drm/amd/powerplay: disable UVD SMU handshake for MCLK. drm/amd/powerplay: initialize variables which were missed. drm/amd/powerplay: enable PowerContainment feature for polaris10/11. drm/amd/powerplay: need to notify system bios pcie device ready drm/amd/powerplay: fix bug that function parameter was incorect. drm/amd/powerplay: fix logic error. drm/amdgpu: initialize amdgpu_cgs_acpi_eval_object result value drm/amdgpu: precedence bug in amdgpu_device_init() drm/amdgpu: fix num_rbs exposed to userspace (v2) drm/amdgpu: missing bounds check in amdgpu_set_pp_force_state()
This commit is contained in:
commit
f939a5f432
|
@ -909,7 +909,7 @@ static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device,
|
|||
struct cgs_acpi_method_argument *argument = NULL;
|
||||
uint32_t i, count;
|
||||
acpi_status status;
|
||||
int result;
|
||||
int result = 0;
|
||||
uint32_t func_no = 0xFFFFFFFF;
|
||||
|
||||
handle = ACPI_HANDLE(&adev->pdev->dev);
|
||||
|
|
|
@ -1535,7 +1535,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
/* Post card if necessary */
|
||||
if (!amdgpu_card_posted(adev) ||
|
||||
(adev->virtualization.is_virtual &&
|
||||
!adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) {
|
||||
!(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) {
|
||||
if (!adev->bios) {
|
||||
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -447,7 +447,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
dev_info.max_memory_clock = adev->pm.default_mclk * 10;
|
||||
}
|
||||
dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
|
||||
dev_info.num_rb_pipes = adev->gfx.config.num_rbs;
|
||||
dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se *
|
||||
adev->gfx.config.max_shader_engines;
|
||||
dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts;
|
||||
dev_info._pad = 0;
|
||||
dev_info.ids_flags = 0;
|
||||
|
|
|
@ -270,30 +270,28 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
|
|||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
enum amd_pm_state_type state = 0;
|
||||
long idx;
|
||||
unsigned long idx;
|
||||
int ret;
|
||||
|
||||
if (strlen(buf) == 1)
|
||||
adev->pp_force_state_enabled = false;
|
||||
else {
|
||||
ret = kstrtol(buf, 0, &idx);
|
||||
else if (adev->pp_enabled) {
|
||||
struct pp_states_info data;
|
||||
|
||||
if (ret) {
|
||||
ret = kstrtoul(buf, 0, &idx);
|
||||
if (ret || idx >= ARRAY_SIZE(data.states)) {
|
||||
count = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (adev->pp_enabled) {
|
||||
struct pp_states_info data;
|
||||
amdgpu_dpm_get_pp_num_states(adev, &data);
|
||||
state = data.states[idx];
|
||||
/* only set user selected power states */
|
||||
if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
|
||||
state != POWER_STATE_TYPE_DEFAULT) {
|
||||
amdgpu_dpm_dispatch_task(adev,
|
||||
AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
|
||||
adev->pp_force_state_enabled = true;
|
||||
}
|
||||
amdgpu_dpm_get_pp_num_states(adev, &data);
|
||||
state = data.states[idx];
|
||||
/* only set user selected power states */
|
||||
if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
|
||||
state != POWER_STATE_TYPE_DEFAULT) {
|
||||
amdgpu_dpm_dispatch_task(adev,
|
||||
AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
|
||||
adev->pp_force_state_enabled = true;
|
||||
}
|
||||
}
|
||||
fail:
|
||||
|
|
|
@ -297,7 +297,8 @@ static const u32 polaris11_golden_common_all[] =
|
|||
static const u32 golden_settings_polaris10_a11[] =
|
||||
{
|
||||
mmATC_MISC_CG, 0x000c0fc0, 0x000c0200,
|
||||
mmCB_HW_CONTROL, 0xfffdf3cf, 0x00006208,
|
||||
mmCB_HW_CONTROL, 0xfffdf3cf, 0x00007208,
|
||||
mmCB_HW_CONTROL_2, 0, 0x0f000000,
|
||||
mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040,
|
||||
mmDB_DEBUG2, 0xf00fffff, 0x00000400,
|
||||
mmPA_SC_ENHANCE, 0xffffffff, 0x20000001,
|
||||
|
|
|
@ -5538,6 +5538,78 @@ typedef struct _ATOM_ASIC_PROFILING_INFO_V3_5
|
|||
ULONG ulReserved[12];
|
||||
}ATOM_ASIC_PROFILING_INFO_V3_5;
|
||||
|
||||
/* for Polars10/11 AVFS parameters */
|
||||
typedef struct _ATOM_ASIC_PROFILING_INFO_V3_6
|
||||
{
|
||||
ATOM_COMMON_TABLE_HEADER asHeader;
|
||||
ULONG ulMaxVddc;
|
||||
ULONG ulMinVddc;
|
||||
USHORT usLkgEuseIndex;
|
||||
UCHAR ucLkgEfuseBitLSB;
|
||||
UCHAR ucLkgEfuseLength;
|
||||
ULONG ulLkgEncodeLn_MaxDivMin;
|
||||
ULONG ulLkgEncodeMax;
|
||||
ULONG ulLkgEncodeMin;
|
||||
EFUSE_LINEAR_FUNC_PARAM sRoFuse;
|
||||
ULONG ulEvvDefaultVddc;
|
||||
ULONG ulEvvNoCalcVddc;
|
||||
ULONG ulSpeed_Model;
|
||||
ULONG ulSM_A0;
|
||||
ULONG ulSM_A1;
|
||||
ULONG ulSM_A2;
|
||||
ULONG ulSM_A3;
|
||||
ULONG ulSM_A4;
|
||||
ULONG ulSM_A5;
|
||||
ULONG ulSM_A6;
|
||||
ULONG ulSM_A7;
|
||||
UCHAR ucSM_A0_sign;
|
||||
UCHAR ucSM_A1_sign;
|
||||
UCHAR ucSM_A2_sign;
|
||||
UCHAR ucSM_A3_sign;
|
||||
UCHAR ucSM_A4_sign;
|
||||
UCHAR ucSM_A5_sign;
|
||||
UCHAR ucSM_A6_sign;
|
||||
UCHAR ucSM_A7_sign;
|
||||
ULONG ulMargin_RO_a;
|
||||
ULONG ulMargin_RO_b;
|
||||
ULONG ulMargin_RO_c;
|
||||
ULONG ulMargin_fixed;
|
||||
ULONG ulMargin_Fmax_mean;
|
||||
ULONG ulMargin_plat_mean;
|
||||
ULONG ulMargin_Fmax_sigma;
|
||||
ULONG ulMargin_plat_sigma;
|
||||
ULONG ulMargin_DC_sigma;
|
||||
ULONG ulLoadLineSlop;
|
||||
ULONG ulaTDClimitPerDPM[8];
|
||||
ULONG ulaNoCalcVddcPerDPM[8];
|
||||
ULONG ulAVFS_meanNsigma_Acontant0;
|
||||
ULONG ulAVFS_meanNsigma_Acontant1;
|
||||
ULONG ulAVFS_meanNsigma_Acontant2;
|
||||
USHORT usAVFS_meanNsigma_DC_tol_sigma;
|
||||
USHORT usAVFS_meanNsigma_Platform_mean;
|
||||
USHORT usAVFS_meanNsigma_Platform_sigma;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSOFF_a0;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSOFF_a1;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSOFF_a2;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSON_a0;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSON_a1;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSON_a2;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSOFF_m1;
|
||||
USHORT usAVFSGB_FUSE_TABLE_CKSOFF_m2;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSOFF_b;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSON_m1;
|
||||
USHORT usAVFSGB_FUSE_TABLE_CKSON_m2;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSON_b;
|
||||
USHORT usMaxVoltage_0_25mv;
|
||||
UCHAR ucEnableGB_VDROOP_TABLE_CKSOFF;
|
||||
UCHAR ucEnableGB_VDROOP_TABLE_CKSON;
|
||||
UCHAR ucEnableGB_FUSE_TABLE_CKSOFF;
|
||||
UCHAR ucEnableGB_FUSE_TABLE_CKSON;
|
||||
USHORT usPSM_Age_ComFactor;
|
||||
UCHAR ucEnableApplyAVFS_CKS_OFF_Voltage;
|
||||
UCHAR ucReserved;
|
||||
}ATOM_ASIC_PROFILING_INFO_V3_6;
|
||||
|
||||
|
||||
typedef struct _ATOM_SCLK_FCW_RANGE_ENTRY_V1{
|
||||
ULONG ulMaxSclkFreq;
|
||||
|
|
|
@ -633,6 +633,8 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vddci_control = FIJI_VOLTAGE_CONTROL_NONE;
|
||||
data->mvdd_control = FIJI_VOLTAGE_CONTROL_NONE;
|
||||
|
||||
data->force_pcie_gen = PP_PCIEGenInvalid;
|
||||
|
||||
if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
|
||||
VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2))
|
||||
data->voltage_control = FIJI_VOLTAGE_CONTROL_BY_SVID2;
|
||||
|
|
|
@ -306,10 +306,14 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr,
|
|||
{
|
||||
PHM_FUNC_CHECK(hwmgr);
|
||||
|
||||
if (hwmgr->hwmgr_func->store_cc6_data == NULL)
|
||||
if (display_config == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
hwmgr->display_config = *display_config;
|
||||
|
||||
if (hwmgr->hwmgr_func->store_cc6_data == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* to do pass other display configuration in furture */
|
||||
|
||||
if (hwmgr->hwmgr_func->store_cc6_data)
|
||||
|
|
|
@ -1296,7 +1296,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
|
|||
}
|
||||
|
||||
mem_level->MclkFrequency = clock;
|
||||
mem_level->StutterEnable = 0;
|
||||
mem_level->EnabledForThrottle = 1;
|
||||
mem_level->EnabledForActivity = 0;
|
||||
mem_level->UpHyst = 0;
|
||||
|
@ -1304,7 +1303,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
|
|||
mem_level->VoltageDownHyst = 0;
|
||||
mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
|
||||
mem_level->StutterEnable = false;
|
||||
|
||||
mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
|
||||
|
||||
data->display_timing.num_existing_displays = info.display_count;
|
||||
|
@ -1363,7 +1361,7 @@ static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
|
|||
* a higher state by default such that we are not effected by
|
||||
* up threshold or and MCLK DPM latency.
|
||||
*/
|
||||
levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target;
|
||||
levels[0].ActivityLevel = 0x1f;
|
||||
CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel);
|
||||
|
||||
data->smc_state_table.MemoryDpmLevelCount =
|
||||
|
@ -1761,12 +1759,9 @@ static int polaris10_populate_smc_initailial_state(struct pp_hwmgr *hwmgr)
|
|||
|
||||
static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks,
|
||||
volt_with_cks, value;
|
||||
uint16_t clock_freq_u16;
|
||||
uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min;
|
||||
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
|
||||
uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2,
|
||||
volt_offset = 0;
|
||||
uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0;
|
||||
struct phm_ppt_v1_information *table_info =
|
||||
(struct phm_ppt_v1_information *)(hwmgr->pptable);
|
||||
struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
|
||||
|
@ -1778,50 +1773,38 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
|
|||
* if the part is SS or FF. if RO >= 1660MHz, part is FF.
|
||||
*/
|
||||
efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixSMU_EFUSE_0 + (146 * 4));
|
||||
efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixSMU_EFUSE_0 + (148 * 4));
|
||||
ixSMU_EFUSE_0 + (67 * 4));
|
||||
efuse &= 0xFF000000;
|
||||
efuse = efuse >> 24;
|
||||
efuse2 &= 0xF;
|
||||
|
||||
if (efuse2 == 1)
|
||||
ro = (2300 - 1350) * efuse / 255 + 1350;
|
||||
else
|
||||
ro = (2500 - 1000) * efuse / 255 + 1000;
|
||||
if (hwmgr->chip_id == CHIP_POLARIS10) {
|
||||
min = 1000;
|
||||
max = 2300;
|
||||
} else {
|
||||
min = 1100;
|
||||
max = 2100;
|
||||
}
|
||||
|
||||
if (ro >= 1660)
|
||||
type = 0;
|
||||
else
|
||||
type = 1;
|
||||
|
||||
/* Populate Stretch amount */
|
||||
data->smc_state_table.ClockStretcherAmount = stretch_amount;
|
||||
ro = efuse * (max -min)/255 + min;
|
||||
|
||||
/* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
|
||||
for (i = 0; i < sclk_table->count; i++) {
|
||||
data->smc_state_table.Sclk_CKS_masterEn0_7 |=
|
||||
sclk_table->entries[i].cks_enable << i;
|
||||
volt_without_cks = (uint32_t)((14041 *
|
||||
(sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 /
|
||||
(4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000)));
|
||||
volt_with_cks = (uint32_t)((13946 *
|
||||
(sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 /
|
||||
(3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000)));
|
||||
|
||||
volt_without_cks = (uint32_t)(((ro - 40) * 1000 - 2753594 - sclk_table->entries[i].clk/100 * 136418 /1000) / \
|
||||
(sclk_table->entries[i].clk/100 * 1132925 /10000 - 242418)/100);
|
||||
|
||||
volt_with_cks = (uint32_t)((ro * 1000 -2396351 - sclk_table->entries[i].clk/100 * 329021/1000) / \
|
||||
(sclk_table->entries[i].clk/10000 * 649434 /1000 - 18005)/10);
|
||||
|
||||
if (volt_without_cks >= volt_with_cks)
|
||||
volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks +
|
||||
sclk_table->entries[i].cks_voffset) * 100 / 625) + 1);
|
||||
|
||||
data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
|
||||
}
|
||||
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
|
||||
STRETCH_ENABLE, 0x0);
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
|
||||
masterReset, 0x1);
|
||||
/* PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, staticEnable, 0x1); */
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
|
||||
masterReset, 0x0);
|
||||
|
||||
/* Populate CKS Lookup Table */
|
||||
if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5)
|
||||
stretch_amount2 = 0;
|
||||
|
@ -1835,69 +1818,6 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
|
|||
return -EINVAL);
|
||||
}
|
||||
|
||||
value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixPWR_CKS_CNTL);
|
||||
value &= 0xFFC2FF87;
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq =
|
||||
polaris10_clock_stretcher_lookup_table[stretch_amount2][0];
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq =
|
||||
polaris10_clock_stretcher_lookup_table[stretch_amount2][1];
|
||||
clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(data->smc_state_table.
|
||||
GraphicsLevel[data->smc_state_table.GraphicsDpmLevelCount - 1].SclkSetting.SclkFrequency) / 100);
|
||||
if (polaris10_clock_stretcher_lookup_table[stretch_amount2][0] < clock_freq_u16
|
||||
&& polaris10_clock_stretcher_lookup_table[stretch_amount2][1] > clock_freq_u16) {
|
||||
/* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */
|
||||
value |= (polaris10_clock_stretcher_lookup_table[stretch_amount2][3]) << 16;
|
||||
/* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */
|
||||
value |= (polaris10_clock_stretcher_lookup_table[stretch_amount2][2]) << 18;
|
||||
/* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */
|
||||
value |= (polaris10_clock_stretch_amount_conversion
|
||||
[polaris10_clock_stretcher_lookup_table[stretch_amount2][3]]
|
||||
[stretch_amount]) << 3;
|
||||
}
|
||||
CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq);
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting =
|
||||
polaris10_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F;
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |=
|
||||
(polaris10_clock_stretcher_lookup_table[stretch_amount2][3]) << 7;
|
||||
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixPWR_CKS_CNTL, value);
|
||||
|
||||
/* Populate DDT Lookup Table */
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* Assign the minimum and maximum VID stored
|
||||
* in the last row of Clock Stretcher Voltage Table.
|
||||
*/
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].minVID =
|
||||
(uint8_t) polaris10_clock_stretcher_ddt_table[type][i][2];
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].maxVID =
|
||||
(uint8_t) polaris10_clock_stretcher_ddt_table[type][i][3];
|
||||
/* Loop through each SCLK and check the frequency
|
||||
* to see if it lies within the frequency for clock stretcher.
|
||||
*/
|
||||
for (j = 0; j < data->smc_state_table.GraphicsDpmLevelCount; j++) {
|
||||
cks_setting = 0;
|
||||
clock_freq = PP_SMC_TO_HOST_UL(
|
||||
data->smc_state_table.GraphicsLevel[j].SclkSetting.SclkFrequency);
|
||||
/* Check the allowed frequency against the sclk level[j].
|
||||
* Sclk's endianness has already been converted,
|
||||
* and it's in 10Khz unit,
|
||||
* as opposed to Data table, which is in Mhz unit.
|
||||
*/
|
||||
if (clock_freq >= (polaris10_clock_stretcher_ddt_table[type][i][0]) * 100) {
|
||||
cks_setting |= 0x2;
|
||||
if (clock_freq < (polaris10_clock_stretcher_ddt_table[type][i][1]) * 100)
|
||||
cks_setting |= 0x1;
|
||||
}
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].setting
|
||||
|= cks_setting << (j * 2);
|
||||
}
|
||||
CONVERT_FROM_HOST_TO_SMC_US(
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].setting);
|
||||
}
|
||||
|
||||
value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL);
|
||||
value &= 0xFFFFFFFE;
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value);
|
||||
|
@ -1956,6 +1876,90 @@ static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr,
|
|||
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
|
||||
*
|
||||
|
@ -2056,6 +2060,10 @@ static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr)
|
|||
"Failed to populate Clock Stretcher Data Table!",
|
||||
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->GraphicsVoltageChangeEnable = 1;
|
||||
table->GraphicsThermThrottleEnable = 1;
|
||||
|
@ -2252,6 +2260,9 @@ static int polaris10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
|
|||
static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
|
||||
uint32_t soft_register_value = 0;
|
||||
uint32_t handshake_disables_offset = data->soft_regs_start
|
||||
+ offsetof(SMU74_SoftRegisters, HandshakeDisables);
|
||||
|
||||
/* enable SCLK dpm */
|
||||
if (!data->sclk_dpm_key_disabled)
|
||||
|
@ -2262,6 +2273,12 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
|
|||
|
||||
/* enable MCLK dpm */
|
||||
if (0 == data->mclk_dpm_key_disabled) {
|
||||
/* Disable UVD - SMU handshake for MCLK. */
|
||||
soft_register_value = cgs_read_ind_register(hwmgr->device,
|
||||
CGS_IND_REG__SMC, handshake_disables_offset);
|
||||
soft_register_value |= SMU7_UVD_MCLK_HANDSHAKE_DISABLE;
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
handshake_disables_offset, soft_register_value);
|
||||
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(0 == smum_send_msg_to_smc(hwmgr->smumgr,
|
||||
|
@ -2269,7 +2286,6 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
|
|||
"Failed to enable MCLK DPM during DPM Start Function!",
|
||||
return -1);
|
||||
|
||||
|
||||
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);
|
||||
|
@ -2606,6 +2622,7 @@ int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
|
|||
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_FanSpeedInTableIsRPM);
|
||||
|
||||
if (hwmgr->chip_id == CHIP_POLARIS11)
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_SPLLShutdownSupport);
|
||||
|
@ -2938,6 +2955,11 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vddci_control = POLARIS10_VOLTAGE_CONTROL_NONE;
|
||||
data->mvdd_control = POLARIS10_VOLTAGE_CONTROL_NONE;
|
||||
|
||||
data->enable_tdc_limit_feature = true;
|
||||
data->enable_pkg_pwr_tracking_feature = true;
|
||||
data->force_pcie_gen = PP_PCIEGenInvalid;
|
||||
data->mclk_stutter_mode_threshold = 40000;
|
||||
|
||||
if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
|
||||
VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2))
|
||||
data->voltage_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2;
|
||||
|
@ -2962,6 +2984,10 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vddci_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2;
|
||||
}
|
||||
|
||||
if (table_info->cac_dtp_table->usClockStretchAmount != 0)
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_ClockStretcher);
|
||||
|
||||
polaris10_set_features_platform_caps(hwmgr);
|
||||
|
||||
polaris10_init_dpm_defaults(hwmgr);
|
||||
|
|
|
@ -312,6 +312,9 @@ struct polaris10_hwmgr {
|
|||
|
||||
/* soft pptable for re-uploading into smu */
|
||||
void *soft_pp_table;
|
||||
|
||||
uint32_t avfs_vdroop_override_setting;
|
||||
bool apply_avfs_cks_off_voltage;
|
||||
};
|
||||
|
||||
/* To convert to Q8.8 format for firmware */
|
||||
|
|
|
@ -625,10 +625,14 @@ static int tf_polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr,
|
|||
int ret;
|
||||
struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
|
||||
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;
|
||||
|
||||
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) ?
|
||||
0 : -1;
|
||||
|
||||
|
|
|
@ -44,6 +44,20 @@ bool acpi_atcs_functions_supported(void *device, uint32_t index)
|
|||
return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
|
||||
}
|
||||
|
||||
bool acpi_atcs_notify_pcie_device_ready(void *device)
|
||||
{
|
||||
int32_t temp_buffer = 1;
|
||||
|
||||
return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
|
||||
ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION,
|
||||
&temp_buffer,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(temp_buffer),
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
|
||||
{
|
||||
struct atcs_pref_req_input atcs_input;
|
||||
|
@ -52,7 +66,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
|
|||
int result;
|
||||
struct cgs_system_info info = {0};
|
||||
|
||||
if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST))
|
||||
if( 0 != acpi_atcs_notify_pcie_device_ready(device))
|
||||
return -EINVAL;
|
||||
|
||||
info.size = sizeof(struct cgs_system_info);
|
||||
|
@ -77,7 +91,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
|
|||
ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
|
||||
&atcs_input,
|
||||
&atcs_output,
|
||||
0,
|
||||
1,
|
||||
sizeof(atcs_input),
|
||||
sizeof(atcs_output));
|
||||
if (result != 0)
|
||||
|
|
|
@ -1302,3 +1302,46 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -250,6 +250,35 @@ struct 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 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);
|
||||
|
@ -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,
|
||||
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_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4489,6 +4489,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_NONE;
|
||||
data->vdd_gfx_control = TONGA_VOLTAGE_CONTROL_NONE;
|
||||
data->mvdd_control = TONGA_VOLTAGE_CONTROL_NONE;
|
||||
data->force_pcie_gen = PP_PCIEGenInvalid;
|
||||
|
||||
if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
|
||||
VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#define PPSMC_MSG_SetGBDroopSettings ((uint16_t) 0x305)
|
||||
|
||||
#define PPSMC_SWSTATE_FLAG_DC 0x01
|
||||
#define PPSMC_SWSTATE_FLAG_UVD 0x02
|
||||
|
|
|
@ -26,3 +26,4 @@ extern bool acpi_atcs_functions_supported(void *device,
|
|||
extern int acpi_pcie_perf_request(void *device,
|
||||
uint8_t perf_req,
|
||||
bool advertise);
|
||||
extern bool acpi_atcs_notify_pcie_device_ready(void *device);
|
||||
|
|
|
@ -34,6 +34,30 @@
|
|||
#define SMU__NUM_LCLK_DPM_LEVELS 8
|
||||
#define SMU__NUM_PCIE_DPM_LEVELS 8
|
||||
|
||||
#define EXP_M1 35
|
||||
#define EXP_M2 92821
|
||||
#define EXP_B 66629747
|
||||
|
||||
#define EXP_M1_1 365
|
||||
#define EXP_M2_1 658700
|
||||
#define EXP_B_1 305506134
|
||||
|
||||
#define EXP_M1_2 189
|
||||
#define EXP_M2_2 379692
|
||||
#define EXP_B_2 194609469
|
||||
|
||||
#define EXP_M1_3 99
|
||||
#define EXP_M2_3 217915
|
||||
#define EXP_B_3 122255994
|
||||
|
||||
#define EXP_M1_4 51
|
||||
#define EXP_M2_4 122643
|
||||
#define EXP_B_4 74893384
|
||||
|
||||
#define EXP_M1_5 423
|
||||
#define EXP_M2_5 1103326
|
||||
#define EXP_B_5 728122621
|
||||
|
||||
enum SID_OPTION {
|
||||
SID_OPTION_HI,
|
||||
SID_OPTION_LO,
|
||||
|
@ -548,20 +572,20 @@ struct SMU74_Firmware_Header {
|
|||
uint32_t CacConfigTable;
|
||||
uint32_t CacStatusTable;
|
||||
|
||||
|
||||
uint32_t mcRegisterTable;
|
||||
|
||||
|
||||
uint32_t mcArbDramTimingTable;
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t PmFuseTable;
|
||||
uint32_t Globals;
|
||||
uint32_t ClockStretcherTable;
|
||||
uint32_t VftTable;
|
||||
uint32_t Reserved[21];
|
||||
uint32_t Reserved1;
|
||||
uint32_t AvfsTable;
|
||||
uint32_t AvfsCksOffGbvTable;
|
||||
uint32_t AvfsMeanNSigma;
|
||||
uint32_t AvfsSclkOffsetTable;
|
||||
uint32_t Reserved[16];
|
||||
uint32_t Signature;
|
||||
};
|
||||
|
||||
|
@ -701,8 +725,6 @@ VR Config info is contained in dpmTable.VRConfig */
|
|||
struct SMU_ClockStretcherDataTableEntry {
|
||||
uint8_t minVID;
|
||||
uint8_t maxVID;
|
||||
|
||||
|
||||
uint16_t setting;
|
||||
};
|
||||
typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry;
|
||||
|
@ -769,6 +791,43 @@ struct VFT_TABLE_t {
|
|||
typedef struct VFT_TABLE_t VFT_TABLE_t;
|
||||
|
||||
|
||||
/* Total margin, root mean square of Fmax + DC + Platform */
|
||||
struct AVFS_Margin_t {
|
||||
VFT_CELL_t Cell[NUM_VFT_COLUMNS];
|
||||
};
|
||||
typedef struct AVFS_Margin_t AVFS_Margin_t;
|
||||
|
||||
#define BTCGB_VDROOP_TABLE_MAX_ENTRIES 2
|
||||
#define AVFSGB_VDROOP_TABLE_MAX_ENTRIES 2
|
||||
|
||||
struct GB_VDROOP_TABLE_t {
|
||||
int32_t a0;
|
||||
int32_t a1;
|
||||
int32_t a2;
|
||||
uint32_t spare;
|
||||
};
|
||||
typedef struct GB_VDROOP_TABLE_t GB_VDROOP_TABLE_t;
|
||||
|
||||
struct AVFS_CksOff_Gbv_t {
|
||||
VFT_CELL_t Cell[NUM_VFT_COLUMNS];
|
||||
};
|
||||
typedef struct AVFS_CksOff_Gbv_t AVFS_CksOff_Gbv_t;
|
||||
|
||||
struct AVFS_meanNsigma_t {
|
||||
uint32_t Aconstant[3];
|
||||
uint16_t DC_tol_sigma;
|
||||
uint16_t Platform_mean;
|
||||
uint16_t Platform_sigma;
|
||||
uint16_t PSM_Age_CompFactor;
|
||||
uint8_t Static_Voltage_Offset[NUM_VFT_COLUMNS];
|
||||
};
|
||||
typedef struct AVFS_meanNsigma_t AVFS_meanNsigma_t;
|
||||
|
||||
struct AVFS_Sclk_Offset_t {
|
||||
uint16_t Sclk_Offset[8];
|
||||
};
|
||||
typedef struct AVFS_Sclk_Offset_t AVFS_Sclk_Offset_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -223,6 +223,16 @@ struct SMU74_Discrete_StateInfo {
|
|||
|
||||
typedef struct SMU74_Discrete_StateInfo SMU74_Discrete_StateInfo;
|
||||
|
||||
struct SMU_QuadraticCoeffs {
|
||||
int32_t m1;
|
||||
uint32_t b;
|
||||
|
||||
int16_t m2;
|
||||
uint8_t m1_shift;
|
||||
uint8_t m2_shift;
|
||||
};
|
||||
typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs;
|
||||
|
||||
struct SMU74_Discrete_DpmTable {
|
||||
|
||||
SMU74_PIDController GraphicsPIDController;
|
||||
|
@ -258,7 +268,14 @@ struct SMU74_Discrete_DpmTable {
|
|||
uint8_t ThermOutPolarity;
|
||||
uint8_t ThermOutMode;
|
||||
uint8_t BootPhases;
|
||||
uint32_t Reserved[4];
|
||||
|
||||
uint8_t VRHotLevel;
|
||||
uint8_t Reserved1[3];
|
||||
uint16_t FanStartTemperature;
|
||||
uint16_t FanStopTemperature;
|
||||
uint16_t MaxVoltage;
|
||||
uint16_t Reserved2;
|
||||
uint32_t Reserved[1];
|
||||
|
||||
SMU74_Discrete_GraphicsLevel GraphicsLevel[SMU74_MAX_LEVELS_GRAPHICS];
|
||||
SMU74_Discrete_MemoryLevel MemoryACPILevel;
|
||||
|
@ -347,6 +364,8 @@ struct SMU74_Discrete_DpmTable {
|
|||
|
||||
uint32_t CurrSclkPllRange;
|
||||
sclkFcwRange_t SclkFcwRangeTable[NUM_SCLK_RANGE];
|
||||
GB_VDROOP_TABLE_t BTCGB_VDROOP_TABLE[BTCGB_VDROOP_TABLE_MAX_ENTRIES];
|
||||
SMU_QuadraticCoeffs AVFSGB_VDROOP_TABLE[AVFSGB_VDROOP_TABLE_MAX_ENTRIES];
|
||||
};
|
||||
|
||||
typedef struct SMU74_Discrete_DpmTable SMU74_Discrete_DpmTable;
|
||||
|
@ -550,16 +569,6 @@ struct SMU7_AcpiScoreboard {
|
|||
|
||||
typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard;
|
||||
|
||||
struct SMU_QuadraticCoeffs {
|
||||
int32_t m1;
|
||||
uint32_t b;
|
||||
|
||||
int16_t m2;
|
||||
uint8_t m1_shift;
|
||||
uint8_t m2_shift;
|
||||
};
|
||||
typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs;
|
||||
|
||||
struct SMU74_Discrete_PmFuses {
|
||||
uint8_t BapmVddCVidHiSidd[8];
|
||||
uint8_t BapmVddCVidLoSidd[8];
|
||||
|
@ -821,6 +830,17 @@ typedef struct SMU7_GfxCuPgScoreboard SMU7_GfxCuPgScoreboard;
|
|||
#define DB_PCC_SHIFT 26
|
||||
#define DB_EDC_SHIFT 27
|
||||
|
||||
#define BTCGB0_Vdroop_Enable_MASK 0x1
|
||||
#define BTCGB1_Vdroop_Enable_MASK 0x2
|
||||
#define AVFSGB0_Vdroop_Enable_MASK 0x4
|
||||
#define AVFSGB1_Vdroop_Enable_MASK 0x8
|
||||
|
||||
#define BTCGB0_Vdroop_Enable_SHIFT 0
|
||||
#define BTCGB1_Vdroop_Enable_SHIFT 1
|
||||
#define AVFSGB0_Vdroop_Enable_SHIFT 2
|
||||
#define AVFSGB1_Vdroop_Enable_SHIFT 3
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
|
|
|
@ -52,19 +52,18 @@
|
|||
static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = {
|
||||
/* Min pcie DeepSleep Activity CgSpll CgSpll CcPwr CcPwr Sclk Enabled Enabled Voltage Power */
|
||||
/* Voltage, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, DynRm, DynRm1 Did, Padding,ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */
|
||||
{ 0x3c0fd047, 0x00, 0x03, 0x1e00, 0x00200410, 0x87020000, 0, 0, 0x16, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x30750000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0xa00fd047, 0x01, 0x04, 0x1e00, 0x00800510, 0x87020000, 0, 0, 0x16, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x409c0000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x0410d047, 0x01, 0x00, 0x1e00, 0x00600410, 0x87020000, 0, 0, 0x0e, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x50c30000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x6810d047, 0x01, 0x00, 0x1e00, 0x00800410, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x60ea0000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0xcc10d047, 0x01, 0x00, 0x1e00, 0x00e00410, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0xe8fd0000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x3011d047, 0x01, 0x00, 0x1e00, 0x00400510, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x70110100, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x9411d047, 0x01, 0x00, 0x1e00, 0x00a00510, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0xf8240100, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0xf811d047, 0x01, 0x00, 0x1e00, 0x00000610, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x80380100, 0, 0, 0, 0, 0, 0, 0 } }
|
||||
{ 0x100ea446, 0x00, 0x03, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x30750000, 0x3000, 0, 0x2600, 0, 0, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } },
|
||||
{ 0x400ea446, 0x01, 0x04, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x409c0000, 0x2000, 0, 0x1e00, 1, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } },
|
||||
{ 0x740ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x50c30000, 0x2800, 0, 0x2000, 1, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } },
|
||||
{ 0xa40ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x60ea0000, 0x3000, 0, 0x2600, 1, 1, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } },
|
||||
{ 0xd80ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x70110100, 0x3800, 0, 0x2c00, 1, 1, 0x0004, 0x1203, 0xffff, 0x3600, 0xc9e2, 0x2e00 } },
|
||||
{ 0x3c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x80380100, 0x2000, 0, 0x1e00, 2, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } },
|
||||
{ 0x6c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x905f0100, 0x2400, 0, 0x1e00, 2, 1, 0x0004, 0x8901, 0xffff, 0x2300, 0x314c, 0x1d00 } },
|
||||
{ 0xa00fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0xa0860100, 0x2800, 0, 0x2000, 2, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } }
|
||||
};
|
||||
|
||||
static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 =
|
||||
{0x50140000, 0x50140000, 0x00320000, 0x00, 0x00,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0000, 0x00, 0x00};
|
||||
{0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* Set the address for reading/writing the SMC SRAM space.
|
||||
|
@ -219,6 +218,18 @@ bool polaris10_is_smc_ram_running(struct pp_smumgr *smumgr)
|
|||
&& (0x20100 <= cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMC_PC_C)));
|
||||
}
|
||||
|
||||
static bool polaris10_is_hw_avfs_present(struct pp_smumgr *smumgr)
|
||||
{
|
||||
uint32_t efuse;
|
||||
|
||||
efuse = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMU_EFUSE_0 + (49*4));
|
||||
efuse &= 0x00000001;
|
||||
if (efuse)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to the SMC, and wait for its response.
|
||||
*
|
||||
|
@ -228,21 +239,27 @@ bool polaris10_is_smc_ram_running(struct pp_smumgr *smumgr)
|
|||
*/
|
||||
int polaris10_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!polaris10_is_smc_ram_running(smumgr))
|
||||
return -1;
|
||||
|
||||
|
||||
SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
|
||||
|
||||
if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP))
|
||||
printk("Failed to send Previous Message.\n");
|
||||
ret = SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP);
|
||||
|
||||
if (ret != 1)
|
||||
printk("\n failed to send pre message %x ret is %d \n", msg, ret);
|
||||
|
||||
cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
|
||||
|
||||
SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
|
||||
|
||||
if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP))
|
||||
printk("Failed to send Message.\n");
|
||||
ret = SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP);
|
||||
|
||||
if (ret != 1)
|
||||
printk("\n failed to send message %x ret is %d \n", msg, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -953,6 +970,11 @@ static int polaris10_smu_init(struct pp_smumgr *smumgr)
|
|||
(cgs_handle_t)smu_data->smu_buffer.handle);
|
||||
return -1;);
|
||||
|
||||
if (polaris10_is_hw_avfs_present(smumgr))
|
||||
smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT;
|
||||
else
|
||||
smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue