[PATCH] drm/amd/powerplay: enable pp one vf mode for vega10

Tao, Yintian Yintian.Tao at amd.com
Mon Dec 9 17:16:18 UTC 2019


Hi  Alex

Many thanks for your review. Please see inline comments. I will submit the v3 patch according to your comment. Thanks again.

Best Regards
Yintian Tao

-----Original Message-----
From: Alex Deucher <alexdeucher at gmail.com> 
Sent: 2019年12月10日 0:52
To: Tao, Yintian <Yintian.Tao at amd.com>
Cc: Deucher, Alexander <Alexander.Deucher at amd.com>; Feng, Kenneth <Kenneth.Feng at amd.com>; amd-gfx list <amd-gfx at lists.freedesktop.org>
Subject: Re: [PATCH] drm/amd/powerplay: enable pp one vf mode for vega10

On Mon, Dec 9, 2019 at 5:39 AM Yintian Tao <yttao at amd.com> wrote:
>
> Originally, due to the restriction from PSP and SMU, VF has
> to send message to hypervisor driver to handle powerplay
> change which is complicated and redundant. Currently, SMU
> and PSP can support VF to directly handle powerplay
> change by itself. Therefore, the old code about the handshake
> between VF and PF to handle powerplay will be removed and VF
> will use new the registers below to handshake with SMU.
> mmMP1_SMN_C2PMSG_101: register to handle SMU message
> mmMP1_SMN_C2PMSG_102: register to handle SMU parameter
> mmMP1_SMN_C2PMSG_103: register to handle SMU response
>
> v2: remove module parameter pp_one_vf
>
> Signed-off-by: Yintian Tao <yttao at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |  13 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |   4 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c        | 121 +++++++-------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      |  51 ------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h      |  14 +-
>  drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c         |  78 ---------
>  drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h         |   4 -
>  drivers/gpu/drm/amd/amdgpu/soc15.c            |   8 +-
>  drivers/gpu/drm/amd/powerplay/amd_powerplay.c |   4 +-
>  drivers/gpu/drm/amd/powerplay/amdgpu_smu.c    |  24 +--
>  .../drm/amd/powerplay/hwmgr/hardwaremanager.c |  15 +-
>  drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c   |   7 +
>  drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c  |  30 ++--
>  .../drm/amd/powerplay/hwmgr/vega10_hwmgr.c    | 157 ++++++++++++------
>  drivers/gpu/drm/amd/powerplay/inc/hwmgr.h     |   1 +
>  .../drm/amd/powerplay/smumgr/smu9_smumgr.c    |  55 ++++--
>  .../drm/amd/powerplay/smumgr/vega10_smumgr.c  |   6 +
>  17 files changed, 280 insertions(+), 312 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index b9ca7e728d3e..30eb42593a20 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1880,6 +1880,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
>                 }
>         }
>
> +       if (amdgpu_sriov_vf(adev))
> +               amdgpu_virt_init_data_exchange(adev);
> +
>         r = amdgpu_ib_pool_init(adev);
>         if (r) {
>                 dev_err(adev->dev, "IB initialization failed (%d).\n", r);
> @@ -1922,8 +1925,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
>
>  init_failed:
>         if (amdgpu_sriov_vf(adev)) {
> -               if (!r)
> -                       amdgpu_virt_init_data_exchange(adev);
>                 amdgpu_virt_release_full_gpu(adev, true);
>         }
>
> @@ -2819,7 +2820,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>         mutex_init(&adev->virt.vf_errors.lock);
>         hash_init(adev->mn_hash);
>         mutex_init(&adev->lock_reset);
> -       mutex_init(&adev->virt.dpm_mutex);
>         mutex_init(&adev->psp.mutex);
>
>         r = amdgpu_device_check_arguments(adev);
> @@ -3040,9 +3040,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>
>         amdgpu_fbdev_init(adev);
>
> -       if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev))
> -               amdgpu_pm_virt_sysfs_init(adev);
> -
>         r = amdgpu_pm_sysfs_init(adev);
>         if (r) {
>                 adev->pm_sysfs_en = false;
> @@ -3187,8 +3184,6 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
>         iounmap(adev->rmmio);
>         adev->rmmio = NULL;
>         amdgpu_device_doorbell_fini(adev);
> -       if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev))
> -               amdgpu_pm_virt_sysfs_fini(adev);
>
>         amdgpu_debugfs_regs_cleanup(adev);
>         device_remove_file(adev->dev, &dev_attr_pcie_replay_count);
> @@ -3669,6 +3664,7 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
>         if (r)
>                 goto error;
>
> +       amdgpu_virt_init_data_exchange(adev);
>         /* we need recover gart prior to run SMC/CP/SDMA resume */
>         amdgpu_gtt_mgr_recover(&adev->mman.bdev.man[TTM_PL_TT]);
>
> @@ -3686,7 +3682,6 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
>         amdgpu_amdkfd_post_reset(adev);
>
>  error:
> -       amdgpu_virt_init_data_exchange(adev);
>         amdgpu_virt_release_full_gpu(adev, true);
>         if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
>                 amdgpu_inc_vram_lost(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 5ec1415d1755..3a0ea9096498 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -703,10 +703,6 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
>                 if (adev->pm.dpm_enabled) {
>                         dev_info.max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;
>                         dev_info.max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;
> -               } else if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) &&
> -                          adev->virt.ops->get_pp_clk) {
> -                       dev_info.max_engine_clock = amdgpu_virt_get_sclk(adev, false) * 10;
> -                       dev_info.max_memory_clock = amdgpu_virt_get_mclk(adev, false) * 10;
>                 } else {
>                         dev_info.max_engine_clock = adev->clock.default_sclk * 10;
>                         dev_info.max_memory_clock = adev->clock.default_mclk * 10;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 0c7324bc31a7..b8a42ebb2f5a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -160,7 +160,8 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,
>         enum amd_pm_state_type pm;
>
>         if (is_support_sw_smu(adev)) {
> -               if (adev->smu.ppt_funcs->get_current_power_state)
> +               if (adev->smu.ppt_funcs &&
> +                   adev->smu.ppt_funcs->get_current_power_state)

This looks like a bug fix which should be broken out separately.
[yttao]: Thanks a lot. I will separate it.

>                         pm = smu_get_current_power_state(&adev->smu);
>                 else
>                         pm = adev->pm.dpm.user_state;
> @@ -283,7 +284,7 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
>         struct amdgpu_device *adev = ddev->dev_private;
>         enum amd_dpm_forced_level level = 0xff;
>
> -       if (amdgpu_sriov_vf(adev))
> +       if (amdgpu_sriov_vf(adev) && !amdgim_is_pp_one_vf(adev))
>                 return 0;
>
>         if ((adev->flags & AMD_IS_PX) &&
> @@ -320,6 +321,9 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
>         enum amd_dpm_forced_level current_level = 0xff;
>         int ret = 0;
>
> +       if (amdgpu_sriov_vf(adev) && !amdgim_is_pp_one_vf(adev))
> +               return -EINVAL;
> +
>         /* Can't force performance level when the card is off */
>         if  ((adev->flags & AMD_IS_PX) &&
>              (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
> @@ -348,19 +352,6 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
>                 goto fail;
>         }
>
> -       /* handle sriov case here */
> -       if (amdgpu_sriov_vf(adev)) {
> -               if (amdgim_is_hwperf(adev) &&
> -                   adev->virt.ops->force_dpm_level) {
> -                       mutex_lock(&adev->pm.mutex);
> -                       adev->virt.ops->force_dpm_level(adev, level);
> -                       mutex_unlock(&adev->pm.mutex);
> -                       return count;
> -               } else {
> -                       return -EINVAL;
> -               }
> -       }
> -
>         if (is_support_sw_smu(adev))
>                 current_level = smu_get_performance_level(&adev->smu);
>         else if (adev->powerplay.pp_funcs->get_performance_level)
> @@ -654,6 +645,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
>         const char delimiter[3] = {' ', '\n', '\0'};
>         uint32_t type;
>
> +       if (amdgpu_sriov_vf(adev) && !amdgim_is_pp_one_vf(adev))
> +               return 0;
> +
>         if (count > 127)
>                 return -EINVAL;
>
> @@ -841,9 +835,10 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,
>         struct drm_device *ddev = dev_get_drvdata(dev);
>         struct amdgpu_device *adev = ddev->dev_private;
>
> -       if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) &&
> -           adev->virt.ops->get_pp_clk)
> -               return adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf);
> +       if (amdgpu_sriov_vf(adev)) {
> +               if (!amdgim_is_pp_one_vf(adev))
> +                       return -EINVAL;
> +       }
>
>         if (is_support_sw_smu(adev))
>                 return smu_print_clk_levels(&adev->smu, SMU_SCLK, buf);
> @@ -878,7 +873,6 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask)
>         while (tmp[0]) {
>                 sub_str = strsep(&tmp, delimiter);
>                 if (strlen(sub_str)) {
> -                       ret = kstrtol(sub_str, 0, &level);
>                         if (ret)
>                                 return -EINVAL;
>                         *mask |= 1 << level;
> @@ -899,8 +893,10 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
>         int ret;
>         uint32_t mask = 0;
>
> -       if (amdgpu_sriov_vf(adev))
> -               return 0;
> +       if (amdgpu_sriov_vf(adev)) {
> +               if (!amdgim_is_pp_one_vf(adev))
> +                       return -EINVAL;
> +       }
>
>         ret = amdgpu_read_mask(buf, count, &mask);
>         if (ret)
> @@ -924,9 +920,10 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev,
>         struct drm_device *ddev = dev_get_drvdata(dev);
>         struct amdgpu_device *adev = ddev->dev_private;
>
> -       if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) &&
> -           adev->virt.ops->get_pp_clk)
> -               return adev->virt.ops->get_pp_clk(adev, PP_MCLK, buf);
> +       if (amdgpu_sriov_vf(adev)) {
> +               if (!amdgim_is_pp_one_vf(adev))
> +                       return -EINVAL;
> +       }
>
>         if (is_support_sw_smu(adev))
>                 return smu_print_clk_levels(&adev->smu, SMU_MCLK, buf);
> @@ -946,8 +943,11 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
>         int ret;
>         uint32_t mask = 0;
>
> -       if (amdgpu_sriov_vf(adev))
> -               return 0;
> +       if (amdgpu_sriov_vf(adev)) {
> +               if (!amdgim_is_pp_one_vf(adev))
> +                       return -EINVAL;
> +
> +       }
>
>         ret = amdgpu_read_mask(buf, count, &mask);
>         if (ret)
> @@ -971,6 +971,11 @@ static ssize_t amdgpu_get_pp_dpm_socclk(struct device *dev,
>         struct drm_device *ddev = dev_get_drvdata(dev);
>         struct amdgpu_device *adev = ddev->dev_private;
>
> +       if (amdgpu_sriov_vf(adev)) {
> +               if (!amdgim_is_pp_one_vf(adev))
> +                       return -EINVAL;
> +       }
> +
>         if (is_support_sw_smu(adev))
>                 return smu_print_clk_levels(&adev->smu, SMU_SOCCLK, buf);
>         else if (adev->powerplay.pp_funcs->print_clock_levels)
> @@ -989,6 +994,9 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev,
>         int ret;
>         uint32_t mask = 0;
>
> +       if (amdgpu_sriov_vf(adev))
> +               return 0;
> +
>         ret = amdgpu_read_mask(buf, count, &mask);
>         if (ret)
>                 return ret;
> @@ -1029,6 +1037,11 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev,
>         int ret;
>         uint32_t mask = 0;
>
> +       if (amdgpu_sriov_vf(adev)) {
> +               if (!amdgim_is_pp_one_vf(adev))
> +                       return -EINVAL;
> +       }
> +
>         ret = amdgpu_read_mask(buf, count, &mask);
>         if (ret)
>                 return ret;
> @@ -1051,6 +1064,9 @@ static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev,
>         struct drm_device *ddev = dev_get_drvdata(dev);
>         struct amdgpu_device *adev = ddev->dev_private;
>
> +       if (amdgpu_sriov_vf(adev))
> +               return 0;
> +
>         if (is_support_sw_smu(adev))
>                 return smu_print_clk_levels(&adev->smu, SMU_DCEFCLK, buf);
>         else if (adev->powerplay.pp_funcs->print_clock_levels)
> @@ -1069,6 +1085,9 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev,
>         int ret;
>         uint32_t mask = 0;
>
> +       if (amdgpu_sriov_vf(adev))
> +               return 0;
> +
>         ret = amdgpu_read_mask(buf, count, &mask);
>         if (ret)
>                 return ret;
> @@ -1091,6 +1110,9 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev,
>         struct drm_device *ddev = dev_get_drvdata(dev);
>         struct amdgpu_device *adev = ddev->dev_private;
>
> +       if (amdgpu_sriov_vf(adev))
> +               return 0;
> +
>         if (is_support_sw_smu(adev))
>                 return smu_print_clk_levels(&adev->smu, SMU_PCIE, buf);
>         else if (adev->powerplay.pp_funcs->print_clock_levels)
> @@ -1109,6 +1131,9 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
>         int ret;
>         uint32_t mask = 0;
>
> +       if (amdgpu_sriov_vf(adev))
> +               return 0;
> +
>         ret = amdgpu_read_mask(buf, count, &mask);
>         if (ret)
>                 return ret;
> @@ -1150,6 +1175,9 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev,
>         int ret;
>         long int value;
>
> +       if (amdgpu_sriov_vf(adev) && !amdgim_is_pp_one_vf(adev))
> +               return 0;
> +
>         ret = kstrtol(buf, 0, &value);
>
>         if (ret) {
> @@ -1201,6 +1229,9 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
>         int ret;
>         long int value;
>
> +       if (amdgpu_sriov_vf(adev) && !amdgim_is_pp_one_vf(adev))
> +               return 0;
> +
>         ret = kstrtol(buf, 0, &value);
>
>         if (ret) {
> @@ -2730,44 +2761,6 @@ void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
>         }
>  }
>
> -int amdgpu_pm_virt_sysfs_init(struct amdgpu_device *adev)
> -{
> -       int ret = 0;
> -
> -       if (!(amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev)))
> -               return ret;
> -
> -       ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk);
> -       if (ret) {
> -               DRM_ERROR("failed to create device file pp_dpm_sclk\n");
> -               return ret;
> -       }
> -
> -       ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk);
> -       if (ret) {
> -               DRM_ERROR("failed to create device file pp_dpm_mclk\n");
> -               return ret;
> -       }
> -
> -       ret = device_create_file(adev->dev, &dev_attr_power_dpm_force_performance_level);
> -       if (ret) {
> -               DRM_ERROR("failed to create device file for dpm state\n");
> -               return ret;
> -       }
> -
> -       return ret;
> -}
> -
> -void amdgpu_pm_virt_sysfs_fini(struct amdgpu_device *adev)
> -{
> -       if (!(amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev)))
> -               return;
> -
> -       device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level);
> -       device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk);
> -       device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk);
> -}
> -

Are you sure you want to remove this functionality for the other
cases?  Won't this regress multi-VF pm?  Or was this functionality
always single VF, but just handled in the host rather than the guest?
[yttao]: yes, under multi-VF condition, the VF can't send dpm request because it will influence other running VF
		The pp one vf mode will only work with only single VF enabled. The legacy virt sysfs interface will not work with 
		latest host driver and host driver will not support the legacy mode anymore.
		

>  int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
>  {
>         int r;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index e32ae906d797..103033f96f13 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -379,54 +379,3 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
>                 }
>         }
>  }
> -
> -static uint32_t parse_clk(char *buf, bool min)
> -{
> -        char *ptr = buf;
> -        uint32_t clk = 0;
> -
> -        do {
> -                ptr = strchr(ptr, ':');
> -                if (!ptr)
> -                        break;
> -                ptr+=2;
> -               if (kstrtou32(ptr, 10, &clk))
> -                       return 0;
> -        } while (!min);
> -
> -        return clk * 100;
> -}
> -
> -uint32_t amdgpu_virt_get_sclk(struct amdgpu_device *adev, bool lowest)
> -{
> -       char *buf = NULL;
> -       uint32_t clk = 0;
> -
> -       buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -       if (!buf)
> -               return -ENOMEM;
> -
> -       adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf);
> -       clk = parse_clk(buf, lowest);
> -
> -       kfree(buf);
> -
> -       return clk;
> -}
> -
> -uint32_t amdgpu_virt_get_mclk(struct amdgpu_device *adev, bool lowest)
> -{
> -       char *buf = NULL;
> -       uint32_t clk = 0;
> -
> -       buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -       if (!buf)
> -               return -ENOMEM;
> -
> -       adev->virt.ops->get_pp_clk(adev, PP_MCLK, buf);
> -       clk = parse_clk(buf, lowest);
> -
> -       kfree(buf);
> -
> -       return clk;
> -}

Same comment here as above regarding multi-VF pm.

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index b0b2bdc750df..63db2a6f008d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -57,8 +57,6 @@ struct amdgpu_virt_ops {
>         int (*reset_gpu)(struct amdgpu_device *adev);
>         int (*wait_reset)(struct amdgpu_device *adev);
>         void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
> -       int (*get_pp_clk)(struct amdgpu_device *adev, u32 type, char *buf);
> -       int (*force_dpm_level)(struct amdgpu_device *adev, u32 level);
>  };
>
>  /*
> @@ -85,8 +83,8 @@ enum AMDGIM_FEATURE_FLAG {
>         AMDGIM_FEATURE_GIM_LOAD_UCODES   = 0x2,
>         /* VRAM LOST by GIM */
>         AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4,
> -       /* HW PERF SIM in GIM */
> -       AMDGIM_FEATURE_HW_PERF_SIMULATION = (1 << 3),
> +       /* PP ONE VF MODE in GIM */
> +       AMDGIM_FEATURE_PP_ONE_VF = (1 << 4),
>  };
>
>  struct amd_sriov_msg_pf2vf_info_header {
> @@ -257,8 +255,6 @@ struct amdgpu_virt {
>         struct amdgpu_vf_error_buffer   vf_errors;
>         struct amdgpu_virt_fw_reserve   fw_reserve;
>         uint32_t gim_feature;
> -       /* protect DPM events to GIM */
> -       struct mutex                    dpm_mutex;
>         uint32_t reg_access_mode;
>  };
>
> @@ -286,8 +282,8 @@ static inline bool is_virtual_machine(void)
>  #endif
>  }
>
> -#define amdgim_is_hwperf(adev) \
> -       ((adev)->virt.gim_feature & AMDGIM_FEATURE_HW_PERF_SIMULATION)
> +#define amdgim_is_pp_one_vf(adev) \
> +       ((adev)->virt.gim_feature & AMDGIM_FEATURE_PP_ONE_VF)
>
>  bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
>  void amdgpu_virt_init_setting(struct amdgpu_device *adev);
> @@ -306,6 +302,4 @@ int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
>                                         unsigned int key,
>                                         unsigned int chksum);
>  void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev);
> -uint32_t amdgpu_virt_get_sclk(struct amdgpu_device *adev, bool lowest);
> -uint32_t amdgpu_virt_get_mclk(struct amdgpu_device *adev, bool lowest);
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
> index cc5bf595f9b1..43305afa3d6f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
> @@ -158,82 +158,6 @@ static void xgpu_ai_mailbox_trans_msg (struct amdgpu_device *adev,
>         xgpu_ai_mailbox_set_valid(adev, false);
>  }
>
> -static int xgpu_ai_get_pp_clk(struct amdgpu_device *adev, u32 type, char *buf)
> -{
> -        int r = 0;
> -        u32 req, val, size;
> -
> -        if (!amdgim_is_hwperf(adev) || buf == NULL)
> -                return -EBADRQC;
> -
> -        switch(type) {
> -        case PP_SCLK:
> -                req = IDH_IRQ_GET_PP_SCLK;
> -                break;
> -        case PP_MCLK:
> -                req = IDH_IRQ_GET_PP_MCLK;
> -                break;
> -        default:
> -                return -EBADRQC;
> -        }
> -
> -        mutex_lock(&adev->virt.dpm_mutex);
> -
> -        xgpu_ai_mailbox_trans_msg(adev, req, 0, 0, 0);
> -
> -        r = xgpu_ai_poll_msg(adev, IDH_SUCCESS);
> -        if (!r && adev->fw_vram_usage.va != NULL) {
> -                val = RREG32_NO_KIQ(
> -                        SOC15_REG_OFFSET(NBIO, 0,
> -                                         mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW1));
> -                size = strnlen((((char *)adev->virt.fw_reserve.p_pf2vf) +
> -                                val), PAGE_SIZE);
> -
> -                if (size < PAGE_SIZE)
> -                        strcpy(buf,((char *)adev->virt.fw_reserve.p_pf2vf + val));
> -                else
> -                        size = 0;
> -
> -                r = size;
> -                goto out;
> -        }
> -
> -        r = xgpu_ai_poll_msg(adev, IDH_FAIL);
> -        if(r)
> -                pr_info("%s DPM request failed",
> -                        (type == PP_SCLK)? "SCLK" : "MCLK");
> -
> -out:
> -        mutex_unlock(&adev->virt.dpm_mutex);
> -        return r;
> -}
> -
> -static int xgpu_ai_force_dpm_level(struct amdgpu_device *adev, u32 level)
> -{
> -        int r = 0;
> -        u32 req = IDH_IRQ_FORCE_DPM_LEVEL;
> -
> -        if (!amdgim_is_hwperf(adev))
> -                return -EBADRQC;
> -
> -        mutex_lock(&adev->virt.dpm_mutex);
> -        xgpu_ai_mailbox_trans_msg(adev, req, level, 0, 0);
> -
> -        r = xgpu_ai_poll_msg(adev, IDH_SUCCESS);
> -        if (!r)
> -                goto out;
> -
> -        r = xgpu_ai_poll_msg(adev, IDH_FAIL);
> -        if (!r)
> -                pr_info("DPM request failed");
> -        else
> -                pr_info("Mailbox is broken");
> -
> -out:
> -        mutex_unlock(&adev->virt.dpm_mutex);
> -        return r;
> -}
> -
>  static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
>                                         enum idh_request req)
>  {
> @@ -455,6 +379,4 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = {
>         .reset_gpu = xgpu_ai_request_reset,
>         .wait_reset = NULL,
>         .trans_msg = xgpu_ai_mailbox_trans_msg,
> -       .get_pp_clk = xgpu_ai_get_pp_clk,
> -       .force_dpm_level = xgpu_ai_force_dpm_level,
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
> index 077e91a33d62..37dbe0f2142f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
> +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
> @@ -35,10 +35,6 @@ enum idh_request {
>         IDH_REL_GPU_FINI_ACCESS,
>         IDH_REQ_GPU_RESET_ACCESS,
>
> -       IDH_IRQ_FORCE_DPM_LEVEL = 10,
> -       IDH_IRQ_GET_PP_SCLK,
> -       IDH_IRQ_GET_PP_MCLK,
> -
>         IDH_LOG_VF_ERROR       = 200,
>  };
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
> index 48649f55f3ba..59f5f2a39fe4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/soc15.c
> +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
> @@ -777,11 +777,11 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
>                 }
>                 amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
>                 amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
> -               if (!amdgpu_sriov_vf(adev)) {
> -                       if (is_support_sw_smu(adev))
> +               if (is_support_sw_smu(adev)) {
> +                       if (!amdgpu_sriov_vf(adev))
>                                 amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
> -                       else
> -                               amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
> +               } else {
> +                       amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
>                 }
>                 if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
>                         amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
> diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> index 7932eb163a00..5087d6bdba60 100644
> --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
> @@ -48,7 +48,6 @@ static int amd_powerplay_create(struct amdgpu_device *adev)
>
>         hwmgr->adev = adev;
>         hwmgr->not_vf = !amdgpu_sriov_vf(adev);
> -       hwmgr->pm_en = (amdgpu_dpm && hwmgr->not_vf) ? true : false;
>         hwmgr->device = amdgpu_cgs_create_device(adev);
>         mutex_init(&hwmgr->smu_lock);
>         hwmgr->chip_family = adev->family;
> @@ -276,6 +275,9 @@ static int pp_dpm_load_fw(void *handle)
>  {
>         struct pp_hwmgr *hwmgr = handle;
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->start_smu)
>                 return -EINVAL;
>
> diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
> index 36001a4f65d7..714b8381d02c 100644
> --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
> @@ -1653,11 +1653,13 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,
>         if (!smu->pm_enabled)
>                 return -EINVAL;
>
> -       if (!skip_display_settings) {
> -               ret = smu_display_config_changed(smu);
> -               if (ret) {
> -                       pr_err("Failed to change display config!");
> -                       return ret;
> +       if (!amdgpu_sriov_vf(smu->adev)) {
> +               if (!skip_display_settings) {
> +                       ret = smu_display_config_changed(smu);
> +                       if (ret) {
> +                               pr_err("Failed to change display config!");
> +                               return ret;
> +                       }
>                 }
>         }
>
> @@ -1667,11 +1669,13 @@ int smu_adjust_power_state_dynamic(struct smu_context *smu,
>                 return ret;
>         }
>
> -       if (!skip_display_settings) {
> -               ret = smu_notify_smc_dispaly_config(smu);
> -               if (ret) {
> -                       pr_err("Failed to notify smc display config!");
> -                       return ret;
> +       if (amdgpu_sriov_vf(smu->adev)) {
> +               if (!skip_display_settings) {
> +                       ret = smu_notify_smc_dispaly_config(smu);
> +                       if (ret) {
> +                               pr_err("Failed to notify smc display config!");
> +                               return ret;
> +                       }
>                 }
>         }
>
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
> index cc57fb953e62..253860d30b20 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
> @@ -81,8 +81,8 @@ int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
>         adev = hwmgr->adev;
>
>         /* Skip for suspend/resume case */
> -       if (smum_is_dpm_running(hwmgr) && !amdgpu_passthrough(adev)
> -               && adev->in_suspend) {
> +       if (!hwmgr->pp_one_vf && smum_is_dpm_running(hwmgr)
> +           && !amdgpu_passthrough(adev) && adev->in_suspend) {
>                 pr_info("dpm has been enabled\n");
>                 return 0;
>         }
> @@ -200,6 +200,9 @@ int phm_stop_thermal_controller(struct pp_hwmgr *hwmgr)
>  {
>         PHM_FUNC_CHECK(hwmgr);
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         if (hwmgr->hwmgr_func->stop_thermal_controller == NULL)
>                 return -EINVAL;
>
> @@ -237,6 +240,9 @@ int phm_start_thermal_controller(struct pp_hwmgr *hwmgr)
>                 TEMP_RANGE_MAX};
>         struct amdgpu_device *adev = hwmgr->adev;
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         if (hwmgr->hwmgr_func->get_thermal_temperature_range)
>                 hwmgr->hwmgr_func->get_thermal_temperature_range(
>                                 hwmgr, &range);
> @@ -263,6 +269,8 @@ int phm_start_thermal_controller(struct pp_hwmgr *hwmgr)
>  bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
>  {
>         PHM_FUNC_CHECK(hwmgr);
> +       if (hwmgr->pp_one_vf)
> +               return false;
>
>         if (hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration == NULL)
>                 return false;
> @@ -482,6 +490,9 @@ int phm_disable_smc_firmware_ctf(struct pp_hwmgr *hwmgr)
>  {
>         PHM_FUNC_CHECK(hwmgr);
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         if (hwmgr->hwmgr_func->disable_smc_firmware_ctf == NULL)
>                 return -EINVAL;
>
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
> index d2909c91d65b..f8c81f963649 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
> @@ -221,6 +221,9 @@ int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
>  {
>         int ret = 0;
>
> +       hwmgr->pp_one_vf = amdgim_is_pp_one_vf((struct amdgpu_device *)hwmgr->adev);
> +       hwmgr->pm_en = (amdgpu_dpm && (hwmgr->not_vf || hwmgr->pp_one_vf))
> +                       ? true : false;
>         if (!hwmgr->pm_en)
>                 return 0;
>
> @@ -365,6 +368,8 @@ int hwmgr_handle_task(struct pp_hwmgr *hwmgr, enum amd_pp_task task_id,
>
>         switch (task_id) {
>         case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:
> +               if (!hwmgr->not_vf)
> +                       return ret;
>                 ret = phm_pre_display_configuration_changed(hwmgr);
>                 if (ret)
>                         return ret;
> @@ -381,6 +386,8 @@ int hwmgr_handle_task(struct pp_hwmgr *hwmgr, enum amd_pp_task task_id,
>                 enum PP_StateUILabel requested_ui_label;
>                 struct pp_power_state *requested_ps = NULL;
>
> +               if (!hwmgr->not_vf)
> +                       return ret;
>                 if (user_state == NULL) {
>                         ret = -EINVAL;
>                         break;
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c
> index 6bf48934fdc4..31a32a79cfc2 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c
> @@ -262,20 +262,22 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
>         uint32_t index;
>         long workload;
>
> -       if (!skip_display_settings)
> -               phm_display_configuration_changed(hwmgr);
> -
> -       if (hwmgr->ps)
> -               power_state_management(hwmgr, new_ps);
> -       else
> -               /*
> -                * for vega12/vega20 which does not support power state manager
> -                * DAL clock limits should also be honoured
> -                */
> -               phm_apply_clock_adjust_rules(hwmgr);
> -
> -       if (!skip_display_settings)
> -               phm_notify_smc_display_config_after_ps_adjustment(hwmgr);
> +       if (hwmgr->not_vf) {
> +               if (!skip_display_settings)
> +                       phm_display_configuration_changed(hwmgr);
> +
> +               if (hwmgr->ps)
> +                       power_state_management(hwmgr, new_ps);
> +               else
> +                       /*
> +                        * for vega12/vega20 which does not support power state manager
> +                        * DAL clock limits should also be honoured
> +                        */
> +                       phm_apply_clock_adjust_rules(hwmgr);
> +
> +               if (!skip_display_settings)
> +                       phm_notify_smc_display_config_after_ps_adjustment(hwmgr);
> +       }
>
>         if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))
>                 hwmgr->dpm_level = hwmgr->request_dpm_level;
> diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> index b29e996df1d4..41a9b8699001 100644
> --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
> @@ -912,6 +912,9 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
>         hwmgr->platform_descriptor.clockStep.memoryClock = 500;
>
>         data->total_active_cus = adev->gfx.cu_info.number;
> +       if (!hwmgr->not_vf)
> +               return result;
> +
>         /* Setup default Overdrive Fan control settings */
>         data->odn_fan_table.target_fan_speed =
>                         hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM;
> @@ -979,6 +982,9 @@ static int vega10_setup_dpm_led_config(struct pp_hwmgr *hwmgr)
>
>  static int vega10_setup_asic_task(struct pp_hwmgr *hwmgr)
>  {
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         PP_ASSERT_WITH_CODE(!vega10_init_sclk_threshold(hwmgr),
>                         "Failed to init sclk threshold!",
>                         return -EINVAL);
> @@ -2503,6 +2509,9 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
>                         "Failed to setup default DPM tables!",
>                         return result);
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         /* initialize ODN table */
>         if (hwmgr->od_enabled) {
>                 if (odn_table->max_vddc) {
> @@ -2932,61 +2941,75 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
>         struct vega10_hwmgr *data = hwmgr->backend;
>         int tmp_result, result = 0;
>
> -       vega10_enable_disable_PCC_limit_feature(hwmgr, true);
> -
> -       smum_send_msg_to_smc_with_parameter(hwmgr,
> -               PPSMC_MSG_ConfigureTelemetry, data->config_telemetry);
> +       if (hwmgr->not_vf) {
> +               vega10_enable_disable_PCC_limit_feature(hwmgr, true);
>
> -       tmp_result = vega10_construct_voltage_tables(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to construct voltage tables!",
> -                       result = tmp_result);
> +               smum_send_msg_to_smc_with_parameter(hwmgr,
> +                       PPSMC_MSG_ConfigureTelemetry, data->config_telemetry);
>
> -       tmp_result = vega10_init_smc_table(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to initialize SMC table!",
> -                       result = tmp_result);
> +               tmp_result = vega10_construct_voltage_tables(hwmgr);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to construct voltage tables!",
> +                                   result = tmp_result);
> +       }
>
> -       if (PP_CAP(PHM_PlatformCaps_ThermalController)) {
> -               tmp_result = vega10_enable_thermal_protection(hwmgr);
> +       if (hwmgr->not_vf || hwmgr->pp_one_vf) {
> +               tmp_result = vega10_init_smc_table(hwmgr);
>                 PP_ASSERT_WITH_CODE(!tmp_result,
> -                               "Failed to enable thermal protection!",
> -                               result = tmp_result);
> +                                   "Failed to initialize SMC table!",
> +                                   result = tmp_result);
>         }
>
> -       tmp_result = vega10_enable_vrhot_feature(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to enable VR hot feature!",
> -                       result = tmp_result);
> +       if (hwmgr->not_vf) {
> +               if (PP_CAP(PHM_PlatformCaps_ThermalController)) {
> +                       tmp_result = vega10_enable_thermal_protection(hwmgr);
> +                       PP_ASSERT_WITH_CODE(!tmp_result,
> +                                           "Failed to enable thermal protection!",
> +                                           result = tmp_result);
> +               }
>
> -       tmp_result = vega10_enable_deep_sleep_master_switch(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to enable deep sleep master switch!",
> -                       result = tmp_result);
> +               tmp_result = vega10_enable_vrhot_feature(hwmgr);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to enable VR hot feature!",
> +                                   result = tmp_result);
>
> -       tmp_result = vega10_start_dpm(hwmgr, SMC_DPM_FEATURES);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to start DPM!", result = tmp_result);
> +               tmp_result = vega10_enable_deep_sleep_master_switch(hwmgr);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to enable deep sleep master switch!",
> +                                   result = tmp_result);
> +       }
>
> -       /* enable didt, do not abort if failed didt */
> -       tmp_result = vega10_enable_didt_config(hwmgr);
> -       PP_ASSERT(!tmp_result,
> -                       "Failed to enable didt config!");
> +       if (hwmgr->not_vf) {
> +               tmp_result = vega10_start_dpm(hwmgr, SMC_DPM_FEATURES);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to start DPM!", result = tmp_result);
> +       }
>
> -       tmp_result = vega10_enable_power_containment(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to enable power containment!",
> -                       result = tmp_result);
> +       if (hwmgr->not_vf) {
> +               /* enable didt, do not abort if failed didt */
> +               tmp_result = vega10_enable_didt_config(hwmgr);
> +               PP_ASSERT(!tmp_result,
> +                         "Failed to enable didt config!");
> +       }
>
> -       tmp_result = vega10_power_control_set_level(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to power control set level!",
> -                       result = tmp_result);
> +       if (hwmgr->not_vf) {
> +               tmp_result = vega10_enable_power_containment(hwmgr);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to enable power containment!",
> +                                   result = tmp_result);
> +       }
>
> -       tmp_result = vega10_enable_ulv(hwmgr);
> -       PP_ASSERT_WITH_CODE(!tmp_result,
> -                       "Failed to enable ULV!",
> -                       result = tmp_result);
> +       if (hwmgr->not_vf) {
> +               tmp_result = vega10_power_control_set_level(hwmgr);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to power control set level!",
> +                                   result = tmp_result);
> +
> +               tmp_result = vega10_enable_ulv(hwmgr);
> +               PP_ASSERT_WITH_CODE(!tmp_result,
> +                                   "Failed to enable ULV!",
> +                                   result = tmp_result);
> +       }
>
>         return result;
>  }
> @@ -3080,11 +3103,22 @@ static int vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
>         performance_level->soc_clock = socclk_dep_table->entries
>                                 [state_entry->ucSocClockIndexHigh].ulClk;
>         if (gfxclk_dep_table->ucRevId == 0) {
> -               performance_level->gfx_clock = gfxclk_dep_table->entries
> -                       [state_entry->ucGfxClockIndexHigh].ulClk;
> +               /* under vega10 pp one vf mode, the gfx clk dpm need be lower
> +                * to level-4 due to the limited 110w-power
> +                */
> +               if (hwmgr->pp_one_vf && (state_entry->ucGfxClockIndexHigh > 0))
> +                       performance_level->gfx_clock =
> +                               gfxclk_dep_table->entries[4].ulClk;
> +               else
> +                       performance_level->gfx_clock = gfxclk_dep_table->entries
> +                               [state_entry->ucGfxClockIndexHigh].ulClk;
>         } else if (gfxclk_dep_table->ucRevId == 1) {
>                 patom_record_V2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)gfxclk_dep_table->entries;
> -               performance_level->gfx_clock = patom_record_V2[state_entry->ucGfxClockIndexHigh].ulClk;
> +               if (hwmgr->pp_one_vf && (state_entry->ucGfxClockIndexHigh > 0))
> +                       performance_level->gfx_clock = patom_record_V2[4].ulClk;
> +               else
> +                       performance_level->gfx_clock =
> +                               patom_record_V2[state_entry->ucGfxClockIndexHigh].ulClk;
>         }
>
>         performance_level->mem_clock = mclk_dep_table->entries
> @@ -3495,6 +3529,7 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
>                         smum_send_msg_to_smc_with_parameter(hwmgr,
>                                 PPSMC_MSG_SetSoftMinGfxclkByIndex,
>                                 data->smc_state_table.gfx_boot_level);
> +
>                         data->dpm_table.gfx_table.dpm_state.soft_min_level =
>                                         data->smc_state_table.gfx_boot_level;
>                 }
> @@ -3518,6 +3553,9 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
>                 }
>         }
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         if (!data->registry_data.socclk_dpm_key_disabled) {
>                 if (data->smc_state_table.soc_boot_level !=
>                                 data->dpm_table.soc_table.dpm_state.soft_min_level) {
> @@ -3560,6 +3598,9 @@ static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
>                 }
>         }
>
> +       if (!hwmgr->not_vf)
> +               return 0;
> +
>         if (!data->registry_data.socclk_dpm_key_disabled) {
>                 if (data->smc_state_table.soc_max_level !=
>                         data->dpm_table.soc_table.dpm_state.soft_max_level) {
> @@ -4054,15 +4095,25 @@ static int vega10_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_fo
>         } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
>                 *mclk_mask = 0;
>         } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
> -               *sclk_mask = table_info->vdd_dep_on_sclk->count - 1;
> +               /* under vega10  pp one vf mode, the gfx clk dpm need be lower
> +                * to level-4 due to the limited power
> +                */
> +               if (hwmgr->pp_one_vf)
> +                       *sclk_mask = 4;
> +               else
> +                       *sclk_mask = table_info->vdd_dep_on_sclk->count - 1;
>                 *soc_mask = table_info->vdd_dep_on_socclk->count - 1;
>                 *mclk_mask = table_info->vdd_dep_on_mclk->count - 1;
>         }
> +
>         return 0;
>  }
>
>  static void vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
>  {
> +       if (!hwmgr->not_vf)
> +               return;
> +
>         switch (mode) {
>         case AMD_FAN_CTRL_NONE:
>                 vega10_fan_ctrl_set_fan_speed_percent(hwmgr, 100);
> @@ -4176,6 +4227,9 @@ static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
>                 break;
>         }
>
> +       if (!hwmgr->not_vf)
> +               return ret;
> +
>         if (!ret) {
>                 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
>                         vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE);
> @@ -4480,7 +4534,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
>         struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
>         struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL;
>
> -       int i, now, size = 0;
> +       int i, now, size, count = 0;
>
>         switch (type) {
>         case PP_SCLK:
> @@ -4490,7 +4544,12 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
>                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex);
>                 now = smum_get_argument(hwmgr);
>
> -               for (i = 0; i < sclk_table->count; i++)
> +               if (hwmgr->pp_one_vf &&
> +                   (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK))
> +                       count = 5;
> +               else
> +                       count = sclk_table->count;
> +               for (i = 0; i < count; i++)

Would it be better to just limit sclktable->count directly for the
sr-iov case, or do you still want all the states available for regular
dpm?
[yttao]: it is a workaround due to the 110w power limit for pp one vf. The performance tool like RGP will check whether the peak dpm level is constant.
		Under peak mode, the max dpm level should be 5 but under highest mode, the max dpm level should be 7 though it will be down after a while
		Due to the 110w power limit.


>                         size += sprintf(buf + size, "%d: %uMhz %s\n",
>                                         i, sclk_table->dpm_levels[i].value / 100,
>                                         (i == now) ? "*" : "");
> diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
> index af977675fd33..2ffb666b97e6 100644
> --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
> +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
> @@ -741,6 +741,7 @@ struct pp_hwmgr {
>         uint32_t smu_version;
>         bool not_vf;
>         bool pm_en;
> +       bool pp_one_vf;
>         struct mutex smu_lock;
>
>         uint32_t pp_table_version;
> diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c
> index 742b3dc1f6cb..a8578a27cab2 100644
> --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c
> @@ -61,15 +61,29 @@ static uint32_t smu9_wait_for_response(struct pp_hwmgr *hwmgr)
>         uint32_t reg;
>         uint32_t ret;
>
> -       reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
> +       /* Due to the L1 policy problem under SRIOV, we have to use
> +        * mmMP1_SMN_C2PMSG_103 as the driver response register
> +        */
> +       if (hwmgr->pp_one_vf) {
> +               reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_103);
>
> -       ret = phm_wait_for_register_unequal(hwmgr, reg,
> -                       0, MP1_C2PMSG_90__CONTENT_MASK);
> +               ret = phm_wait_for_register_unequal(hwmgr, reg,
> +                               0, MP1_C2PMSG_103__CONTENT_MASK);
>
> -       if (ret)
> -               pr_err("No response from smu\n");
> +               if (ret)
> +                       pr_err("No response from smu\n");
>
> -       return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
> +               return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_103);
> +       } else {
> +               reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
> +
> +               ret = phm_wait_for_register_unequal(hwmgr, reg,
> +                               0, MP1_C2PMSG_90__CONTENT_MASK);
> +
> +               if (ret)
> +                       pr_err("No response from smu\n");
> +               return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
> +       }
>  }
>
>  /*
> @@ -83,7 +97,10 @@ static int smu9_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
>  {
>         struct amdgpu_device *adev = hwmgr->adev;
>
> -       WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
> +       if (hwmgr->pp_one_vf) {
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_101, msg);
> +       } else
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);

Please fix up the parens here to be consistent.

Thanks,

Alex

>
>         return 0;
>  }
> @@ -101,7 +118,10 @@ int smu9_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
>
>         smu9_wait_for_response(hwmgr);
>
> -       WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
> +       if (hwmgr->pp_one_vf)
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_103, 0);
> +       else
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
>
>         smu9_send_msg_to_smc_without_waiting(hwmgr, msg);
>
> @@ -127,9 +147,17 @@ int smu9_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
>
>         smu9_wait_for_response(hwmgr);
>
> -       WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
> -
> -       WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
> +       /* Due to the L1 policy problem under SRIOV, we have to use
> +        * mmMP1_SMN_C2PMSG_101 as the driver message register and
> +        * mmMP1_SMN_C2PMSG_102 as the driver parameter register.
> +        */
> +       if (hwmgr->pp_one_vf) {
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_103, 0);
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_102, parameter);
> +       } else {
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
> +               WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
> +       }
>
>         smu9_send_msg_to_smc_without_waiting(hwmgr, msg);
>
> @@ -144,5 +172,8 @@ uint32_t smu9_get_argument(struct pp_hwmgr *hwmgr)
>  {
>         struct amdgpu_device *adev = hwmgr->adev;
>
> -       return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
> +       if (hwmgr->pp_one_vf)
> +               return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_102);
> +       else
> +               return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
>  }
> diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
> index 0f3836fd9666..bea337a6c5b7 100644
> --- a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
> @@ -71,6 +71,12 @@ static int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
>  {
>         struct vega10_smumgr *priv = hwmgr->smu_backend;
>
> +       /* under pp_one_vf mode, vbios or hypervisor driver
> +        * has already copy table to smc so here only skip it
> +        */
> +       if (!hwmgr->not_vf && !hwmgr->pp_one_vf)
> +               return 0;
> +
>         PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
>                         "Invalid SMU Table ID!", return -EINVAL);
>         PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=02%7C01%7CYintian.Tao%40amd.com%7Ca8cf686986344c8a914808d77cc82f09%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637115071536373981&sdata=LQSVdrCIjrLDcG3lAGohhkq4nJ4lGTfzyhVD%2BfjX8VA%3D&reserved=0


More information about the amd-gfx mailing list