Re: [PATCH 04/10] drm/amd/pp: Implement update_dpm_settings on Polaris
Again, it still has risk when updating smc table without calling smu7_freeze/unfreeze_sclk_mclk_dpm(). Regards, Eric On 2018-02-08 04:14 AM, Rex Zhu wrote: Change-Id: I4533826ef6e18df125ae4445016873be3b5fe0ce Signed-off-by: Rex Zhu --- .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 104 + 1 file changed, 104 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index bfb2c85..559572d 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -2575,6 +2575,109 @@ static int polaris10_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, array_size, SMC_RAM_END); } +uint32_t polaris10_set_field_to_u32(u32 offset, u32 original_data, u32 field, u32 size) +{ + u32 mask = 0; + u32 shift = 0; + + shift = (offset % 4) << 3; + if (size == sizeof(uint8_t)) + mask = 0xFF << shift; + else if (size == sizeof(uint16_t)) + mask = 0x << shift; + + original_data &= ~mask; + original_data |= (field << shift); + return original_data; +} + +static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr, + void *profile_setting) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *) + (hwmgr->smu_backend); + struct profile_mode_setting *setting; + struct SMU74_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); + + uint32_t mclk_array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, MemoryLevel); + struct SMU74_Discrete_MemoryLevel *mclk_levels = + smu_data->smc_state_table.MemoryLevel; + uint32_t i; + uint32_t offset, up_hyst_offset, down_hyst_offset, clk_activity_offset, tmp; + + if (profile_setting == NULL) + return -EINVAL; + + setting = (struct profile_mode_setting *)profile_setting; + + if (setting->bupdate_sclk) { + for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { + if (levels[i].ActivityLevel != + cpu_to_be16(setting->sclk_activity)) { + levels[i].ActivityLevel = cpu_to_be16(setting->sclk_activity); + + clk_activity_offset = array + (sizeof(SMU74_Discrete_GraphicsLevel) * i) + + offsetof(SMU74_Discrete_GraphicsLevel, ActivityLevel); + offset = clk_activity_offset & ~0x3; + tmp = PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset)); + tmp = polaris10_set_field_to_u32(clk_activity_offset, tmp, levels[i].ActivityLevel, sizeof(uint16_t)); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset, PP_HOST_TO_SMC_UL(tmp)); + + } + if (levels[i].UpHyst != setting->sclk_up_hyst || + levels[i].DownHyst != setting->sclk_down_hyst) { + levels[i].UpHyst = setting->sclk_up_hyst; + levels[i].DownHyst = setting->sclk_down_hyst; + up_hyst_offset = array + (sizeof(SMU74_Discrete_GraphicsLevel) * i) + + offsetof(SMU74_Discrete_GraphicsLevel, UpHyst); + down_hyst_offset = array + (sizeof(SMU74_Discrete_GraphicsLevel) * i) + + offsetof(SMU74_Discrete_GraphicsLevel, DownHyst); + offset = up_hyst_offset & ~0x3; + tmp = PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset)); + tmp = polaris10_set_field_to_u32(up_hyst_offset, tmp, levels[i].UpHyst, sizeof(uint8_t)); + tmp = polaris10_set_field_to_u32(down_hyst_offset, tmp, levels[i].DownHyst, sizeof(uint8_t)); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset, PP_HOST_TO_SMC_UL(tmp)); + } + } + } + + if (setting->bupdate_mclk) { + for (i = 0; i < smu_data->smc_state_table.MemoryDpmLevelCount; i++) { + if (mclk_levels[i].ActivityLevel != + cpu_to_be16(setting->mclk_activity)) { + mclk_levels[i].ActivityLevel = cp
Re: [PATCH 04/10] drm/amd/pp: Implement update_dpm_settings on Polaris
On Thu, Feb 8, 2018 at 4:14 AM, Rex Zhu wrote: > Change-Id: I4533826ef6e18df125ae4445016873be3b5fe0ce > Signed-off-by: Rex Zhu Please provide a patch description, with that fixed: Reviewed-by: Alex Deucher > --- > .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 104 > + > 1 file changed, 104 insertions(+) > > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > index bfb2c85..559572d 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > @@ -2575,6 +2575,109 @@ static int > polaris10_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, > array_size, SMC_RAM_END); > } > > +uint32_t polaris10_set_field_to_u32(u32 offset, u32 original_data, u32 > field, u32 size) > +{ > + u32 mask = 0; > + u32 shift = 0; > + > + shift = (offset % 4) << 3; > + if (size == sizeof(uint8_t)) > + mask = 0xFF << shift; > + else if (size == sizeof(uint16_t)) > + mask = 0x << shift; > + > + original_data &= ~mask; > + original_data |= (field << shift); > + return original_data; > +} > + > +static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr, > + void *profile_setting) > +{ > + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *) > + (hwmgr->smu_backend); > + struct profile_mode_setting *setting; > + struct SMU74_Discrete_GraphicsLevel *levels = > + smu_data->smc_state_table.GraphicsLevel; > + uint32_t array = smu_data->smu7_data.dpm_table_start + > + offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); > + > + uint32_t mclk_array = smu_data->smu7_data.dpm_table_start + > + offsetof(SMU74_Discrete_DpmTable, MemoryLevel); > + struct SMU74_Discrete_MemoryLevel *mclk_levels = > + smu_data->smc_state_table.MemoryLevel; > + uint32_t i; > + uint32_t offset, up_hyst_offset, down_hyst_offset, > clk_activity_offset, tmp; > + > + if (profile_setting == NULL) > + return -EINVAL; > + > + setting = (struct profile_mode_setting *)profile_setting; > + > + if (setting->bupdate_sclk) { > + for (i = 0; i < > smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { > + if (levels[i].ActivityLevel != > + cpu_to_be16(setting->sclk_activity)) { > + levels[i].ActivityLevel = > cpu_to_be16(setting->sclk_activity); > + > + clk_activity_offset = array + > (sizeof(SMU74_Discrete_GraphicsLevel) * i) > + + > offsetof(SMU74_Discrete_GraphicsLevel, ActivityLevel); > + offset = clk_activity_offset & ~0x3; > + tmp = > PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, > offset)); > + tmp = > polaris10_set_field_to_u32(clk_activity_offset, tmp, levels[i].ActivityLevel, > sizeof(uint16_t)); > + cgs_write_ind_register(hwmgr->device, > CGS_IND_REG__SMC, offset, PP_HOST_TO_SMC_UL(tmp)); > + > + } > + if (levels[i].UpHyst != setting->sclk_up_hyst || > + levels[i].DownHyst != > setting->sclk_down_hyst) { > + levels[i].UpHyst = setting->sclk_up_hyst; > + levels[i].DownHyst = setting->sclk_down_hyst; > + up_hyst_offset = array + > (sizeof(SMU74_Discrete_GraphicsLevel) * i) > + + > offsetof(SMU74_Discrete_GraphicsLevel, UpHyst); > + down_hyst_offset = array + > (sizeof(SMU74_Discrete_GraphicsLevel) * i) > + + > offsetof(SMU74_Discrete_GraphicsLevel, DownHyst); > + offset = up_hyst_offset & ~0x3; > + tmp = > PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, > offset)); > + tmp = > polaris10_set_field_to_u32(up_hyst_offset, tmp, levels[i].UpHyst, > sizeof(uint8_t)); > + tmp = > polaris10_set_field_to_u32(down_hyst_offset, tmp, levels[i].DownHyst, > sizeof(uint8_t)); > + cgs_write_ind_register(hwmgr->device, > CGS_IND_REG__SMC, offset, PP_HOST_TO_SMC_UL(tmp)); > + } > + } > + } > + > + if (setting->bupdate_mclk) { > + for (i = 0; i < > smu_data->smc_state_table.MemoryDpmLevelCount; i++) { > +
[PATCH 04/10] drm/amd/pp: Implement update_dpm_settings on Polaris
Change-Id: I4533826ef6e18df125ae4445016873be3b5fe0ce Signed-off-by: Rex Zhu --- .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 104 + 1 file changed, 104 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index bfb2c85..559572d 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -2575,6 +2575,109 @@ static int polaris10_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, array_size, SMC_RAM_END); } +uint32_t polaris10_set_field_to_u32(u32 offset, u32 original_data, u32 field, u32 size) +{ + u32 mask = 0; + u32 shift = 0; + + shift = (offset % 4) << 3; + if (size == sizeof(uint8_t)) + mask = 0xFF << shift; + else if (size == sizeof(uint16_t)) + mask = 0x << shift; + + original_data &= ~mask; + original_data |= (field << shift); + return original_data; +} + +static int polaris10_update_dpm_settings(struct pp_hwmgr *hwmgr, + void *profile_setting) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *) + (hwmgr->smu_backend); + struct profile_mode_setting *setting; + struct SMU74_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); + + uint32_t mclk_array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, MemoryLevel); + struct SMU74_Discrete_MemoryLevel *mclk_levels = + smu_data->smc_state_table.MemoryLevel; + uint32_t i; + uint32_t offset, up_hyst_offset, down_hyst_offset, clk_activity_offset, tmp; + + if (profile_setting == NULL) + return -EINVAL; + + setting = (struct profile_mode_setting *)profile_setting; + + if (setting->bupdate_sclk) { + for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { + if (levels[i].ActivityLevel != + cpu_to_be16(setting->sclk_activity)) { + levels[i].ActivityLevel = cpu_to_be16(setting->sclk_activity); + + clk_activity_offset = array + (sizeof(SMU74_Discrete_GraphicsLevel) * i) + + offsetof(SMU74_Discrete_GraphicsLevel, ActivityLevel); + offset = clk_activity_offset & ~0x3; + tmp = PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset)); + tmp = polaris10_set_field_to_u32(clk_activity_offset, tmp, levels[i].ActivityLevel, sizeof(uint16_t)); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset, PP_HOST_TO_SMC_UL(tmp)); + + } + if (levels[i].UpHyst != setting->sclk_up_hyst || + levels[i].DownHyst != setting->sclk_down_hyst) { + levels[i].UpHyst = setting->sclk_up_hyst; + levels[i].DownHyst = setting->sclk_down_hyst; + up_hyst_offset = array + (sizeof(SMU74_Discrete_GraphicsLevel) * i) + + offsetof(SMU74_Discrete_GraphicsLevel, UpHyst); + down_hyst_offset = array + (sizeof(SMU74_Discrete_GraphicsLevel) * i) + + offsetof(SMU74_Discrete_GraphicsLevel, DownHyst); + offset = up_hyst_offset & ~0x3; + tmp = PP_HOST_TO_SMC_UL(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset)); + tmp = polaris10_set_field_to_u32(up_hyst_offset, tmp, levels[i].UpHyst, sizeof(uint8_t)); + tmp = polaris10_set_field_to_u32(down_hyst_offset, tmp, levels[i].DownHyst, sizeof(uint8_t)); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset, PP_HOST_TO_SMC_UL(tmp)); + } + } + } + + if (setting->bupdate_mclk) { + for (i = 0; i < smu_data->smc_state_table.MemoryDpmLevelCount; i++) { + if (mclk_levels[i].ActivityLevel != + cpu_to_be16(setting->mclk_activity)) { + mclk_levels[i].ActivityLevel = cpu_to_be16(setting->mclk_activity); + + clk_activity_offset = mclk_array + (sizeof(SMU74_Discrete_MemoryLevel) * i) +