Since amdgpu_drm_ioctl() was removed, amdgpu_info_ioctl() no longer
holds a runtime PM reference. When the GPU is runtime suspended, the
queries that touch the hardware run against a powered down device:

  - AMDGPU_INFO_READ_MMR_REG reads all ones,
  - AMDGPU_INFO_TIMESTAMP returns ~0ull,
  - AMDGPU_INFO_DEV_INFO reports 0 for the engine and memory clock
    limits because the SMU is down,
  - AMDGPU_INFO_SENSOR fails with -ENOENT.

On Navi31 with an idle GPU in BAMACO, GRBM_STATUS reads 0xffffffff
instead of 0x0000302c, the timestamp is 0xffffffffffffffff, and the
min/max sclk is reported as 0/0 kHz instead of 500000/1880000 kHz.

Resume the GPU for these queries, the same way the CS ioctl does.

Fixes: a66aee8f3057 ("drm/amdgpu: get rid of amdgpu_drm_ioctl")
Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 28 ++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index f34150d20a2f..1589b6a6575f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -780,9 +780,16 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
 
                return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0;
        }
-       case AMDGPU_INFO_TIMESTAMP:
+       case AMDGPU_INFO_TIMESTAMP: {
+               PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(dev->dev, pm);
+
+               ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+               if (ret)
+                       return ret;
+
                ui64 = amdgpu_gfx_get_gpu_clock_counter(adev);
                return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
+       }
        case AMDGPU_INFO_FW_VERSION: {
                struct drm_amdgpu_info_firmware fw_info;
 
@@ -906,6 +913,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                if (info->read_mmr_reg.count > 128)
                        return -EINVAL;
 
+               PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(dev->dev, pm);
+
+               ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+               if (ret)
+                       return ret;
+
                regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs),
                                     GFP_KERNEL);
                if (!regs)
@@ -940,6 +953,13 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                uint64_t vm_size;
                uint32_t pcie_gen_mask, pcie_width_mask;
 
+               /* The clock limits are only available while the SMU is up. */
+               PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(dev->dev, pm);
+
+               ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+               if (ret)
+                       return ret;
+
                dev_info = kzalloc_obj(*dev_info);
                if (!dev_info)
                        return -ENOMEM;
@@ -1167,6 +1187,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void 
*data, struct drm_file *filp)
                }
        }
        case AMDGPU_INFO_SENSOR: {
+               PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(dev->dev, pm);
+
+               ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+               if (ret)
+                       return ret;
+
                if (!adev->pm.dpm_enabled)
                        return -ENOENT;
 
-- 
2.50.1

Reply via email to