accel/ivpu: Read clock rate only if device is up
authorKarol Wachowski <karol.wachowski@linux.intel.com>
Fri, 20 Oct 2023 10:44:58 +0000 (12:44 +0200)
committerStanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Mon, 23 Oct 2023 06:59:20 +0000 (08:59 +0200)
Do not unnecessarily wake up device to read clock rate.
Return 0 as clk_rate if device is suspended.

Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231020104501.697763-4-stanislaw.gruszka@linux.intel.com
drivers/accel/ivpu/ivpu_drv.c
drivers/accel/ivpu/ivpu_pm.c
drivers/accel/ivpu/ivpu_pm.h

index 7851ff7..b6aa889 100644 (file)
@@ -131,6 +131,22 @@ static int ivpu_get_capabilities(struct ivpu_device *vdev, struct drm_ivpu_param
        return 0;
 }
 
+static int ivpu_get_core_clock_rate(struct ivpu_device *vdev, u64 *clk_rate)
+{
+       int ret;
+
+       ret = ivpu_rpm_get_if_active(vdev);
+       if (ret < 0)
+               return ret;
+
+       *clk_rate = ret ? ivpu_hw_reg_pll_freq_get(vdev) : 0;
+
+       if (ret)
+               ivpu_rpm_put(vdev);
+
+       return 0;
+}
+
 static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 {
        struct ivpu_file_priv *file_priv = file->driver_priv;
@@ -154,7 +170,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
                args->value = vdev->platform;
                break;
        case DRM_IVPU_PARAM_CORE_CLOCK_RATE:
-               args->value = ivpu_hw_reg_pll_freq_get(vdev);
+               ret = ivpu_get_core_clock_rate(vdev, &args->value);
                break;
        case DRM_IVPU_PARAM_NUM_CONTEXTS:
                args->value = ivpu_get_context_count(vdev);
index e359ba3..d14b6fd 100644 (file)
@@ -246,6 +246,19 @@ int ivpu_rpm_get(struct ivpu_device *vdev)
        return ret;
 }
 
+int ivpu_rpm_get_if_active(struct ivpu_device *vdev)
+{
+       int ret;
+
+       ivpu_dbg(vdev, RPM, "rpm_get_if_active count %d\n",
+                atomic_read(&vdev->drm.dev->power.usage_count));
+
+       ret = pm_runtime_get_if_active(vdev->drm.dev, false);
+       drm_WARN_ON(&vdev->drm, ret < 0);
+
+       return ret;
+}
+
 void ivpu_rpm_put(struct ivpu_device *vdev)
 {
        pm_runtime_mark_last_busy(vdev->drm.dev);
index f41c30a..044db15 100644 (file)
@@ -33,6 +33,7 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev);
 void ivpu_pm_reset_done_cb(struct pci_dev *pdev);
 
 int __must_check ivpu_rpm_get(struct ivpu_device *vdev);
+int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev);
 void ivpu_rpm_put(struct ivpu_device *vdev);
 
 void ivpu_pm_schedule_recovery(struct ivpu_device *vdev);