From 9f76f7e87871230698901f8e2b459366f36da49a Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Thu, 7 May 2020 12:39:18 +0800 Subject: drm/amdgpu: cleanup unnecessary virt sriov check in amdgpu attribute the amdgpu device attribute node will be created accordding to sriov vf mode at runtime. cleanup unnecessary sriov check in attribute operation function. Signed-off-by: Kevin Wang Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 105 --------------------------------- 1 file changed, 105 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index b75362bf0742..bc7de2f62d12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -163,9 +163,6 @@ static ssize_t amdgpu_get_power_dpm_state(struct device *dev, enum amd_pm_state_type pm; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -199,9 +196,6 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev, enum amd_pm_state_type state; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - if (strncmp("battery", buf, strlen("battery")) == 0) state = POWER_STATE_TYPE_BATTERY; else if (strncmp("balanced", buf, strlen("balanced")) == 0) @@ -303,9 +297,6 @@ static ssize_t amdgpu_get_power_dpm_force_performance_level(struct device *dev, enum amd_dpm_forced_level level = 0xff; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -343,9 +334,6 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, enum amd_dpm_forced_level current_level = 0xff; int ret = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - if (strncmp("low", buf, strlen("low")) == 0) { level = AMD_DPM_FORCED_LEVEL_LOW; } else if (strncmp("high", buf, strlen("high")) == 0) { @@ -475,9 +463,6 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev, enum amd_pm_state_type pm = 0; int i = 0, ret = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -514,9 +499,6 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - if (adev->pp_force_state_enabled) return amdgpu_get_pp_cur_state(dev, attr, buf); else @@ -534,9 +516,6 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, unsigned long idx; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - if (strlen(buf) == 1) adev->pp_force_state_enabled = false; else if (is_support_sw_smu(adev)) @@ -592,9 +571,6 @@ static ssize_t amdgpu_get_pp_table(struct device *dev, char *table = NULL; int size, ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -634,9 +610,6 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; int ret = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -739,9 +712,6 @@ 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)) - return -EINVAL; - if (count > 127) return -EINVAL; @@ -831,9 +801,6 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -883,9 +850,6 @@ static ssize_t amdgpu_set_pp_features(struct device *dev, uint64_t featuremask; int ret; - if (amdgpu_sriov_vf(adev)) - return -EINVAL; - ret = kstrtou64(buf, 0, &featuremask); if (ret) return -EINVAL; @@ -926,9 +890,6 @@ static ssize_t amdgpu_get_pp_features(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -985,9 +946,6 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1051,9 +1009,6 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, int ret; uint32_t mask = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1085,9 +1040,6 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1115,9 +1067,6 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, uint32_t mask = 0; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1149,9 +1098,6 @@ static ssize_t amdgpu_get_pp_dpm_socclk(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1179,9 +1125,6 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev, int ret; uint32_t mask = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1215,9 +1158,6 @@ static ssize_t amdgpu_get_pp_dpm_fclk(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1245,9 +1185,6 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev, int ret; uint32_t mask = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1281,9 +1218,6 @@ static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1311,9 +1245,6 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev, int ret; uint32_t mask = 0; - if (amdgpu_sriov_vf(adev)) - return -EINVAL; - ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1347,9 +1278,6 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1377,9 +1305,6 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, int ret; uint32_t mask = 0; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - ret = amdgpu_read_mask(buf, count, &mask); if (ret) return ret; @@ -1413,9 +1338,6 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev, uint32_t value = 0; int ret; - if (amdgpu_sriov_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1441,9 +1363,6 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, int ret; long int value; - if (amdgpu_sriov_vf(adev)) - return -EINVAL; - ret = kstrtol(buf, 0, &value); if (ret) @@ -1482,9 +1401,6 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, uint32_t value = 0; int ret; - if (amdgpu_sriov_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1510,9 +1426,6 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, int ret; long int value; - if (amdgpu_sriov_vf(adev)) - return 0; - ret = kstrtol(buf, 0, &value); if (ret) @@ -1571,9 +1484,6 @@ static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev, ssize_t size; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1615,9 +1525,6 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, if (ret) return -EINVAL; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return -EINVAL; - if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { if (count < 2 || count > 127) return -EINVAL; @@ -1671,9 +1578,6 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; int r, value, size = sizeof(value); - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - r = pm_runtime_get_sync(ddev->dev); if (r < 0) return r; @@ -1707,9 +1611,6 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; int r, value, size = sizeof(value); - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - r = pm_runtime_get_sync(ddev->dev); if (r < 0) return r; @@ -1748,9 +1649,6 @@ static ssize_t amdgpu_get_pcie_bw(struct device *dev, uint64_t count0, count1; int ret; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; @@ -1781,9 +1679,6 @@ static ssize_t amdgpu_get_unique_id(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; - if (adev->unique_id) return snprintf(buf, PAGE_SIZE, "%016llx\n", adev->unique_id); -- cgit From 62cc895c02fb9d1170f02dc1dfa3c2135ebe100b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 20 May 2020 18:25:56 +0300 Subject: drm/amdgpu: off by one in amdgpu_device_attr_create_groups() error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This loop in the error handling code should start a "i - 1" and end at "i == 0". Currently it starts a "i" and ends at "i == 1". The result is that it removes one attribute that wasn't created yet, and leaks the zeroeth attribute. Fixes: 4e01847c38f7 ("drm/amdgpu: optimize amdgpu device attribute code") Acked-by: Michael J. Ruhl Reviewed-by: Christian König Reviewed-by: Kevin Wang Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index bc7de2f62d12..17bc7f530898 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1837,9 +1837,8 @@ static int amdgpu_device_attr_create_groups(struct amdgpu_device *adev, return 0; failed: - for (; i > 0; i--) { + while (i--) amdgpu_device_attr_remove(adev, &attrs[i]); - } return ret; } -- cgit From d08d692ebbc0fccb96506b80b5063b9309f219a7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 19 May 2020 16:54:55 -0400 Subject: drm/amdgpu: improve error handling in pcie_bw 1. Initialize the counters to 0 in case the callback fails to initialize them. 2. The counters don't exist on APUs so return an error for them. 3. Return an error if the callback doesn't exist. Reviewed-by: Yong Zhao Reviewed-By: Kent Russell Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 17bc7f530898..2fc51f815eaa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1646,9 +1646,15 @@ static ssize_t amdgpu_get_pcie_bw(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; - uint64_t count0, count1; + uint64_t count0 = 0, count1 = 0; int ret; + if (adev->flags & AMD_IS_APU) + return -ENODATA; + + if (!adev->asic_funcs->get_pcie_usage) + return -ENODATA; + ret = pm_runtime_get_sync(ddev->dev); if (ret < 0) return ret; -- cgit From d5c8ffb966377b6f8c0e1a8b9b040ade89b151b1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 21 May 2020 10:08:11 -0400 Subject: drm/amdgpu: fix pm sysfs node handling (v2) Fix typos that prevented them from showing up. v2: switch other files in addition to pp_clk_voltage Fixes: 4e01847c38f7a5 ("drm/amdgpu: optimize amdgpu device attribute code") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1150 Signed-off-by: Alex Deucher Acked-by: Evan Quan --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 2fc51f815eaa..e06fef6174e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1731,10 +1731,10 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ #define DEVICE_ATTR_IS(_name) (!strcmp(attr_name, #_name)) if (DEVICE_ATTR_IS(pp_dpm_socclk)) { - if (asic_type <= CHIP_VEGA10) + if (asic_type < CHIP_VEGA10) attr->states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dcefclk)) { - if (asic_type <= CHIP_VEGA10 || asic_type == CHIP_ARCTURUS) + if (asic_type < CHIP_VEGA10 || asic_type == CHIP_ARCTURUS) attr->states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_fclk)) { if (asic_type < CHIP_VEGA20) @@ -1746,7 +1746,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ attr->states = ATTR_STATE_UNSUPPORTED; if ((is_support_sw_smu(adev) && adev->smu.od_enabled) || (!is_support_sw_smu(adev) && hwmgr->od_enabled)) - attr->states = ATTR_STATE_UNSUPPORTED; + attr->states = ATTR_STATE_SUPPORTED; } else if (DEVICE_ATTR_IS(mem_busy_percent)) { if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10) attr->states = ATTR_STATE_UNSUPPORTED; @@ -1758,7 +1758,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ if (!adev->unique_id) attr->states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_features)) { - if (adev->flags & AMD_IS_APU || asic_type <= CHIP_VEGA10) + if (adev->flags & AMD_IS_APU || asic_type < CHIP_VEGA10) attr->states = ATTR_STATE_UNSUPPORTED; } -- cgit From cbd2d08c7463e78d625a69e9db27ad3004cbbd99 Mon Sep 17 00:00:00 2001 From: chen gong Date: Thu, 21 May 2020 17:15:34 +0800 Subject: drm/amd/powerpay: Disable gfxoff when setting manual mode on picasso and raven MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Problem description] 1. Boot up picasso platform, launches desktop, Don't do anything (APU enter into "gfxoff" state) 2. Remote login to platform using SSH, then type the command line: sudo su -c "echo manual > /sys/class/drm/card0/device/power_dpm_force_performance_level" sudo su -c "echo 2 > /sys/class/drm/card0/device/pp_dpm_sclk" (fix SCLK to 1400MHz) 3. Move the mouse around in Window 4. Phenomenon : The screen frozen Tester will switch sclk level during glmark2 run time. APU will enter "gfxoff" state intermittently during glmark2 run time. The system got hanged if fix GFXCLK to 1400MHz when APU is in "gfxoff" state. [Debug] 1. Fix SCLK to X MHz 1400: screen frozen, screen black, then OS will reboot. 1300: screen frozen. 1200: screen frozen, screen black. 1100: screen frozen, screen black, then OS will reboot. 1000: screen frozen, screen black. 900: screen frozen, screen black, then OS will reboot. 800: Situation Nomal, issue disappear. 700: Situation Nomal, issue disappear. 2. SBIOS setting: AMD CBS --> SMU Debug Options -->SMU Debug --> "GFX DLDO Psm Margin Control": 50 : Situation Nomal, issue disappear. 45 : Situation Nomal, issue disappear. 40 : Situation Nomal, issue disappear. 35 : Situation Nomal, issue disappear. 30 : screen black. 25 : screen frozen, then blurred screen. 20 : screen frozen. 15 : screen black. 10 : screen frozen. 5 : screen frozen, then blurred screen. 3. Disable GFXOFF feature Situation Nomal, issue disappear. [Why] Through a period of time debugging with Sys Eng team and SMU team, Sys Eng team said this is voltage/frequency marginal issue not a F/W or H/W bug. This experiment proves that default targetPsm [for f=1400MHz] is not sufficient when GFXOFF is enabled on Picasso. SMU team think it is an odd test conditions to force sclk="1400MHz" when GPU is in "gfxoff" state,then wake up the GFX. SCLK should be in the "lowest frequency" when gfxoff. [How] Disable gfxoff when setting manual mode. Enable gfxoff when setting other mode(exiting manual mode) again. By the way, from the user point of view, now that user switch to manual mode and force SCLK Frequency, he don't want SCLK be controlled by workload.It becomes meaningless to "switch to manual mode" if APU enter "gfxoff" due to lack of workload at this point. Tips: Same issue observed on Raven. Signed-off-by: chen gong Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index e06fef6174e5..655f0d3fb1e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -371,6 +371,15 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, return count; } + if (adev->asic_type == CHIP_RAVEN) { + if (adev->rev_id < 8) { + if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL && level == AMD_DPM_FORCED_LEVEL_MANUAL) + amdgpu_gfx_off_ctrl(adev, false); + else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL && level != AMD_DPM_FORCED_LEVEL_MANUAL) + amdgpu_gfx_off_ctrl(adev, true); + } + } + /* profile_exit setting is valid only when current mode is in profile mode */ if (!(current_level & (AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | -- cgit From 54f78a7655e20792253fdf6969513c5f9169c897 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 15 May 2020 14:18:29 -0400 Subject: drm/amdgpu: add apu flags (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some APU flags to simplify handling of different APU variants. It's easier to understand the special cases if we use names flags rather than checking device ids and silicon revisions. v2: rebase on latest code Acked-by: Evan Quan Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 16 ++++++++-------- drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 5 ++--- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/soc15.c | 17 +++++++++++++---- drivers/gpu/drm/amd/include/amd_shared.h | 7 +++++++ drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 3 +-- drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c | 3 ++- 15 files changed, 48 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 4922a2a6abb2..cd913986863e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -739,6 +739,7 @@ struct amdgpu_device { uint32_t rev_id; uint32_t external_rev_id; unsigned long flags; + unsigned long apu_flags; int usec_timeout; const struct amdgpu_asic_funcs *asic_funcs; bool shutdown; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d46b400cb67f..a027a8f7b281 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1567,9 +1567,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) chip_name = "vega12"; break; case CHIP_RAVEN: - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) chip_name = "raven2"; - else if (adev->pdev->device == 0x15d8) + else if (adev->apu_flags & AMD_APU_IS_PICASSO) chip_name = "picasso"; else chip_name = "raven"; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 84cee27cd7ef..f7143d927b6d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -523,7 +523,8 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, break; case CHIP_RAVEN: /* enable S/G on PCO and RV2 */ - if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) + if ((adev->apu_flags & AMD_APU_IS_RAVEN2) || + (adev->apu_flags & AMD_APU_IS_PICASSO)) domain |= AMDGPU_GEM_DOMAIN_GTT; break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 655f0d3fb1e4..702a3a03c707 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -372,7 +372,7 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, } if (adev->asic_type == CHIP_RAVEN) { - if (adev->rev_id < 8) { + if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) { if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL && level == AMD_DPM_FORCED_LEVEL_MANUAL) amdgpu_gfx_off_ctrl(adev, false); else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL && level != AMD_DPM_FORCED_LEVEL_MANUAL) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 2de99b441601..2badbc0355f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -70,9 +70,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) switch (adev->asic_type) { case CHIP_RAVEN: - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) fw_name = FIRMWARE_RAVEN2; - else if (adev->pdev->device == 0x15d8) + else if (adev->apu_flags & AMD_APU_IS_PICASSO) fw_name = FIRMWARE_PICASSO; else fw_name = FIRMWARE_RAVEN; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 1573ac1f03b2..711e9dd19705 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -959,7 +959,7 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) case CHIP_RAVEN: soc15_program_register_sequence(adev, golden_settings_gc_9_1, ARRAY_SIZE(golden_settings_gc_9_1)); - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) soc15_program_register_sequence(adev, golden_settings_gc_9_1_rv2, ARRAY_SIZE(golden_settings_gc_9_1_rv2)); @@ -1274,7 +1274,8 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) case CHIP_VEGA20: break; case CHIP_RAVEN: - if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) && + if (!((adev->apu_flags & AMD_APU_IS_RAVEN2) || + (adev->apu_flags & AMD_APU_IS_PICASSO)) && ((!is_raven_kicker(adev) && adev->gfx.rlc_fw_version < 531) || (adev->gfx.rlc_feature_version < 1) || @@ -1617,9 +1618,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) chip_name = "vega20"; break; case CHIP_RAVEN: - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) chip_name = "raven2"; - else if (adev->pdev->device == 0x15d8) + else if (adev->apu_flags & AMD_APU_IS_PICASSO) chip_name = "picasso"; else chip_name = "raven"; @@ -2119,7 +2120,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.config.sc_prim_fifo_size_backend = 0x100; adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0; - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) gb_addr_config = RAVEN2_GB_ADDR_CONFIG_GOLDEN; else gb_addr_config = RAVEN_GB_ADDR_CONFIG_GOLDEN; @@ -2968,8 +2969,7 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) */ if (adev->gfx.rlc.is_rlc_v2_1) { if (adev->asic_type == CHIP_VEGA12 || - (adev->asic_type == CHIP_RAVEN && - adev->rev_id >= 8)) + (adev->apu_flags & AMD_APU_IS_RAVEN2)) gfx_v9_1_init_rlc_save_restore_list(adev); gfx_v9_0_enable_save_restore_machine(adev); } @@ -6881,7 +6881,7 @@ static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev) adev->gds.gds_compute_max_wave_id = 0x27f; break; case CHIP_RAVEN: - if (adev->rev_id >= 0x8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) adev->gds.gds_compute_max_wave_id = 0x77; /* raven2 */ else adev->gds.gds_compute_max_wave_id = 0x15f; /* raven1 */ diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c index 1a2f18b908fe..6682b843bafe 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c @@ -80,7 +80,7 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) WREG32_SOC15_RLC(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); - if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) /* * Raven2 has a HW issue that it is unable to use the * vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 055ecba754ff..11e93a82131d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -441,9 +441,8 @@ static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev, return ((vmhub == AMDGPU_MMHUB_0 || vmhub == AMDGPU_MMHUB_1) && (!amdgpu_sriov_vf(adev)) && - (!(adev->asic_type == CHIP_RAVEN && - adev->rev_id < 0x8 && - adev->pdev->device == 0x15d8))); + (!(!(adev->apu_flags & AMD_APU_IS_RAVEN2) && + (adev->apu_flags & AMD_APU_IS_PICASSO)))); } static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index bd2d2b8d1f42..405767208a4d 100755 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -96,7 +96,7 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); - if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) /* * Raven2 has a HW issue that it is unable to use the vram which * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c index 90727cfb4447..d7f92634eba2 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c @@ -55,9 +55,9 @@ static int psp_v10_0_init_microcode(struct psp_context *psp) switch (adev->asic_type) { case CHIP_RAVEN: - if (adev->rev_id >= 0x8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) chip_name = "raven2"; - else if (adev->pdev->device == 0x15d8) + else if (adev->apu_flags & AMD_APU_IS_PICASSO) chip_name = "picasso"; else chip_name = "raven"; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index ebd723a0bcfc..33501c6c7189 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -486,7 +486,7 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) soc15_program_register_sequence(adev, golden_settings_sdma_4_1, ARRAY_SIZE(golden_settings_sdma_4_1)); - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) soc15_program_register_sequence(adev, golden_settings_sdma_rv2, ARRAY_SIZE(golden_settings_sdma_rv2)); @@ -575,9 +575,9 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) chip_name = "vega20"; break; case CHIP_RAVEN: - if (adev->rev_id >= 8) + if (adev->apu_flags & AMD_APU_IS_RAVEN2) chip_name = "raven2"; - else if (adev->pdev->device == 0x15d8) + else if (adev->apu_flags & AMD_APU_IS_PICASSO) chip_name = "picasso"; else chip_name = "raven"; diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 58a440a15525..c7c9e07962b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -564,7 +564,8 @@ soc15_asic_reset_method(struct amdgpu_device *adev) static int soc15_asic_reset(struct amdgpu_device *adev) { /* original raven doesn't have full asic reset */ - if (adev->pdev->device == 0x15dd && adev->rev_id < 0x8) + if ((adev->apu_flags & AMD_APU_IS_RAVEN) && + !(adev->apu_flags & AMD_APU_IS_RAVEN2)) return 0; switch (soc15_asic_reset_method(adev)) { @@ -1129,16 +1130,23 @@ static int soc15_common_early_init(void *handle) break; case CHIP_RAVEN: adev->asic_funcs = &soc15_asic_funcs; + if (adev->pdev->device == 0x15dd) + adev->apu_flags |= AMD_APU_IS_RAVEN; + if (adev->pdev->device == 0x15d8) + adev->apu_flags |= AMD_APU_IS_PICASSO; if (adev->rev_id >= 0x8) + adev->apu_flags |= AMD_APU_IS_RAVEN2; + + if (adev->apu_flags & AMD_APU_IS_RAVEN2) adev->external_rev_id = adev->rev_id + 0x79; - else if (adev->pdev->device == 0x15d8) + else if (adev->apu_flags & AMD_APU_IS_PICASSO) adev->external_rev_id = adev->rev_id + 0x41; else if (adev->rev_id == 1) adev->external_rev_id = adev->rev_id + 0x20; else adev->external_rev_id = adev->rev_id + 0x01; - if (adev->rev_id >= 0x8) { + if (adev->apu_flags & AMD_APU_IS_RAVEN2) { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | @@ -1156,7 +1164,7 @@ static int soc15_common_early_init(void *handle) AMD_CG_SUPPORT_VCN_MGCG; adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; - } else if (adev->pdev->device == 0x15d8) { + } else if (adev->apu_flags & AMD_APU_IS_PICASSO) { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | @@ -1222,6 +1230,7 @@ static int soc15_common_early_init(void *handle) break; case CHIP_RENOIR: adev->asic_funcs = &soc15_asic_funcs; + adev->apu_flags |= AMD_APU_IS_RENOIR; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_3D_CGCG | diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 92126c54cb1c..e98c84ef206f 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -40,6 +40,13 @@ enum amd_chip_flags { AMD_EXP_HW_SUPPORT = 0x00080000UL, }; +enum amd_apu_flags { + AMD_APU_IS_RAVEN = 0x00000001UL, + AMD_APU_IS_RAVEN2 = 0x00000002UL, + AMD_APU_IS_PICASSO = 0x00000004UL, + AMD_APU_IS_RENOIR = 0x00000008UL, +}; + enum amd_ip_block_type { AMD_IP_BLOCK_TYPE_COMMON, AMD_IP_BLOCK_TYPE_GMC, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index d1f0cc77d460..c9cfe90a2947 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1302,8 +1302,7 @@ static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) static bool smu10_is_raven1_refresh(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; - if ((adev->asic_type == CHIP_RAVEN) && - (adev->rev_id != 0x15d8) && + if ((adev->apu_flags & AMD_APU_IS_RAVEN) && (hwmgr->smu_version >= 0x41e2b)) return true; else diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c index 801ba9ca6094..ea2279bb8cbf 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c @@ -226,7 +226,8 @@ static int smu10_start_smu(struct pp_hwmgr *hwmgr) smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion, &hwmgr->smu_version); adev->pm.fw_version = hwmgr->smu_version >> 8; - if (adev->rev_id < 0x8 && adev->pdev->device != 0x15d8 && + if (!(adev->apu_flags & AMD_APU_IS_RAVEN2) && + (adev->apu_flags & AMD_APU_IS_RAVEN) && adev->pm.fw_version < 0x1e45) adev->pm.pp_feature &= ~PP_GFXOFF_MASK; -- cgit From ba02fd6b1ce5536ad8d052468166dd9eb083c2b9 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Fri, 22 May 2020 22:06:17 +0800 Subject: drm/amdgpu: fix device attribute node create failed with multi gpu the origin design will use varible of "attr->states" to save node supported states on current gpu device, but for multi gpu device, when probe second gpu device, the driver will check attribute node states from previous gpu device wthether to create attribute node. it will cause other gpu device create attribute node faild. 1. add member attr_list into amdgpu_device to link supported device attribute node. 2. add new structure "struct amdgpu_device_attr_entry{}" to track device attribute state. 3. drop member "states" from amdgpu_device_attr. v2: 1. move "attr_list" into amdgpu_pm and rename to "pm_attr_list". 2. refine create & remove device node functions parameter. fix: drm/amdgpu: optimize amdgpu device attribute code Signed-off-by: Kevin Wang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 85 +++++++++++++++++++-------------- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h | 13 +++-- 3 files changed, 58 insertions(+), 41 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index 956f6c710670..6a8aae70a0e6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h @@ -450,6 +450,7 @@ struct amdgpu_pm { /* Used for I2C access to various EEPROMs on relevant ASICs */ struct i2c_adapter smu_i2c; + struct list_head pm_attr_list; }; #define R600_SSTU_DFLT 0 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 702a3a03c707..d7646cbce346 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1725,7 +1725,7 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = { }; static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, - uint32_t mask) + uint32_t mask, enum amdgpu_device_attr_states *states) { struct device_attribute *dev_attr = &attr->dev_attr; const char *attr_name = dev_attr->attr.name; @@ -1733,7 +1733,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ enum amd_asic_type asic_type = adev->asic_type; if (!(attr->flags & mask)) { - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; return 0; } @@ -1741,34 +1741,34 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ if (DEVICE_ATTR_IS(pp_dpm_socclk)) { if (asic_type < CHIP_VEGA10) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dcefclk)) { if (asic_type < CHIP_VEGA10 || asic_type == CHIP_ARCTURUS) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_fclk)) { if (asic_type < CHIP_VEGA20) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_pcie)) { if (asic_type == CHIP_ARCTURUS) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) { - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; if ((is_support_sw_smu(adev) && adev->smu.od_enabled) || (!is_support_sw_smu(adev) && hwmgr->od_enabled)) - attr->states = ATTR_STATE_SUPPORTED; + *states = ATTR_STATE_SUPPORTED; } else if (DEVICE_ATTR_IS(mem_busy_percent)) { if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pcie_bw)) { /* PCIe Perf counters won't work on APU nodes */ if (adev->flags & AMD_IS_APU) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(unique_id)) { if (!adev->unique_id) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_features)) { if (adev->flags & AMD_IS_APU || asic_type < CHIP_VEGA10) - attr->states = ATTR_STATE_UNSUPPORTED; + *states = ATTR_STATE_UNSUPPORTED; } if (asic_type == CHIP_ARCTURUS) { @@ -1789,27 +1789,29 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ static int amdgpu_device_attr_create(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, - uint32_t mask) + uint32_t mask, struct list_head *attr_list) { int ret = 0; struct device_attribute *dev_attr = &attr->dev_attr; const char *name = dev_attr->attr.name; + enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED; + struct amdgpu_device_attr_entry *attr_entry; + int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, - uint32_t mask) = default_attr_update; + uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update; BUG_ON(!attr); attr_update = attr->attr_update ? attr_update : default_attr_update; - ret = attr_update(adev, attr, mask); + ret = attr_update(adev, attr, mask, &attr_states); if (ret) { dev_err(adev->dev, "failed to update device file %s, ret = %d\n", name, ret); return ret; } - /* the attr->states maybe changed after call attr->attr_update function */ - if (attr->states == ATTR_STATE_UNSUPPORTED) + if (attr_states == ATTR_STATE_UNSUPPORTED) return 0; ret = device_create_file(adev->dev, dev_attr); @@ -1818,7 +1820,14 @@ static int amdgpu_device_attr_create(struct amdgpu_device *adev, name, ret); } - attr->states = ATTR_STATE_SUPPORTED; + attr_entry = kmalloc(sizeof(*attr_entry), GFP_KERNEL); + if (!attr_entry) + return -ENOMEM; + + attr_entry->attr = attr; + INIT_LIST_HEAD(&attr_entry->entry); + + list_add_tail(&attr_entry->entry, attr_list); return ret; } @@ -1827,24 +1836,23 @@ static void amdgpu_device_attr_remove(struct amdgpu_device *adev, struct amdgpu_ { struct device_attribute *dev_attr = &attr->dev_attr; - if (attr->states == ATTR_STATE_UNSUPPORTED) - return; - device_remove_file(adev->dev, dev_attr); - - attr->states = ATTR_STATE_UNSUPPORTED; } +static void amdgpu_device_attr_remove_groups(struct amdgpu_device *adev, + struct list_head *attr_list); + static int amdgpu_device_attr_create_groups(struct amdgpu_device *adev, struct amdgpu_device_attr *attrs, uint32_t counts, - uint32_t mask) + uint32_t mask, + struct list_head *attr_list) { int ret = 0; uint32_t i = 0; for (i = 0; i < counts; i++) { - ret = amdgpu_device_attr_create(adev, &attrs[i], mask); + ret = amdgpu_device_attr_create(adev, &attrs[i], mask, attr_list); if (ret) goto failed; } @@ -1852,20 +1860,24 @@ static int amdgpu_device_attr_create_groups(struct amdgpu_device *adev, return 0; failed: - while (i--) - amdgpu_device_attr_remove(adev, &attrs[i]); + amdgpu_device_attr_remove_groups(adev, attr_list); return ret; } static void amdgpu_device_attr_remove_groups(struct amdgpu_device *adev, - struct amdgpu_device_attr *attrs, - uint32_t counts) + struct list_head *attr_list) { - uint32_t i = 0; + struct amdgpu_device_attr_entry *entry, *entry_tmp; - for (i = 0; i < counts; i++) - amdgpu_device_attr_remove(adev, &attrs[i]); + if (list_empty(attr_list)) + return ; + + list_for_each_entry_safe(entry, entry_tmp, attr_list, entry) { + amdgpu_device_attr_remove(adev, entry->attr); + list_del(&entry->entry); + kfree(entry); + } } static ssize_t amdgpu_hwmon_show_temp(struct device *dev, @@ -3276,6 +3288,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) if (adev->pm.dpm_enabled == 0) return 0; + INIT_LIST_HEAD(&adev->pm.pm_attr_list); + adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, DRIVER_NAME, adev, hwmon_groups); @@ -3302,7 +3316,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) ret = amdgpu_device_attr_create_groups(adev, amdgpu_device_attrs, ARRAY_SIZE(amdgpu_device_attrs), - mask); + mask, + &adev->pm.pm_attr_list); if (ret) return ret; @@ -3319,9 +3334,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) if (adev->pm.int_hwmon_dev) hwmon_device_unregister(adev->pm.int_hwmon_dev); - amdgpu_device_attr_remove_groups(adev, - amdgpu_device_attrs, - ARRAY_SIZE(amdgpu_device_attrs)); + amdgpu_device_attr_remove_groups(adev, &adev->pm.pm_attr_list); } void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h index 48e8086baf33..d9ae2b49a402 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h @@ -47,10 +47,14 @@ enum amdgpu_device_attr_states { struct amdgpu_device_attr { struct device_attribute dev_attr; enum amdgpu_device_attr_flags flags; - enum amdgpu_device_attr_states states; - int (*attr_update)(struct amdgpu_device *adev, - struct amdgpu_device_attr* attr, - uint32_t mask); + int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, + uint32_t mask, enum amdgpu_device_attr_states *states); + +}; + +struct amdgpu_device_attr_entry { + struct list_head entry; + struct amdgpu_device_attr *attr; }; #define to_amdgpu_device_attr(_dev_attr) \ @@ -59,7 +63,6 @@ struct amdgpu_device_attr { #define __AMDGPU_DEVICE_ATTR(_name, _mode, _show, _store, _flags, ...) \ { .dev_attr = __ATTR(_name, _mode, _show, _store), \ .flags = _flags, \ - .states = ATTR_STATE_SUPPORTED, \ ##__VA_ARGS__, } #define AMDGPU_DEVICE_ATTR(_name, _mode, _flags, ...) \ -- cgit