Merge tag 'drm-msm-fixes-2023-01-16' into msm-fixes
[linux-block.git] / drivers / gpu / drm / msm / msm_gpu.h
index a89bfdc3d7f90f5db182c60aa91cdf28345baa01..fc1c0d8611a82b300b48819bdebd494c3ab5c19a 100644 (file)
@@ -78,6 +78,15 @@ struct msm_gpu_funcs {
        struct msm_gem_address_space *(*create_private_address_space)
                (struct msm_gpu *gpu);
        uint32_t (*get_rptr)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
+
+       /**
+        * progress: Has the GPU made progress?
+        *
+        * Return true if GPU position in cmdstream has advanced (or changed)
+        * since the last call.  To avoid false negatives, this should account
+        * for cmdstream that is buffered in this FIFO upstream of the CP fw.
+        */
+       bool (*progress)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 };
 
 /* Additional state for iommu faults: */
@@ -100,11 +109,15 @@ struct msm_gpu_devfreq {
        struct mutex lock;
 
        /**
-        * idle_constraint:
+        * idle_freq:
         *
-        * A PM QoS constraint to limit max freq while the GPU is idle.
+        * Shadow frequency used while the GPU is idle.  From the PoV of
+        * the devfreq governor, we are continuing to sample busyness and
+        * adjust frequency while the GPU is idle, but we use this shadow
+        * value as the GPU is actually clamped to minimum frequency while
+        * it is inactive.
         */
-       struct dev_pm_qos_request idle_freq;
+       unsigned long idle_freq;
 
        /**
         * boost_constraint:
@@ -126,8 +139,6 @@ struct msm_gpu_devfreq {
        /** idle_time: Time of last transition to idle: */
        ktime_t idle_time;
 
-       struct devfreq_dev_status average_status;
-
        /**
         * idle_work:
         *
@@ -237,6 +248,7 @@ struct msm_gpu {
 #define DRM_MSM_INACTIVE_PERIOD   66 /* in ms (roughly four frames) */
 
 #define DRM_MSM_HANGCHECK_DEFAULT_PERIOD 500 /* in ms */
+#define DRM_MSM_HANGCHECK_PROGRESS_RETRIES 3
        struct timer_list hangcheck_timer;
 
        /* Fault info for most recent iova fault: */
@@ -265,9 +277,6 @@ struct msm_gpu {
 
        struct msm_gpu_state *crashstate;
 
-       /* Enable clamping to idle freq when inactive: */
-       bool clamp_to_idle;
-
        /* True if the hardware supports expanded apriv (a650 and newer) */
        bool hw_apriv;
 
@@ -548,7 +557,7 @@ static inline void gpu_rmw(struct msm_gpu *gpu, u32 reg, u32 mask, u32 or)
        msm_rmw(gpu->mmio + (reg << 2), mask, or);
 }
 
-static inline u64 gpu_read64(struct msm_gpu *gpu, u32 lo, u32 hi)
+static inline u64 gpu_read64(struct msm_gpu *gpu, u32 reg)
 {
        u64 val;
 
@@ -566,17 +575,17 @@ static inline u64 gpu_read64(struct msm_gpu *gpu, u32 lo, u32 hi)
         * when the lo is read, so make sure to read the lo first to trigger
         * that
         */
-       val = (u64) msm_readl(gpu->mmio + (lo << 2));
-       val |= ((u64) msm_readl(gpu->mmio + (hi << 2)) << 32);
+       val = (u64) msm_readl(gpu->mmio + (reg << 2));
+       val |= ((u64) msm_readl(gpu->mmio + ((reg + 1) << 2)) << 32);
 
        return val;
 }
 
-static inline void gpu_write64(struct msm_gpu *gpu, u32 lo, u32 hi, u64 val)
+static inline void gpu_write64(struct msm_gpu *gpu, u32 reg, u64 val)
 {
        /* Why not a writeq here? Read the screed above */
-       msm_writel(lower_32_bits(val), gpu->mmio + (lo << 2));
-       msm_writel(upper_32_bits(val), gpu->mmio + (hi << 2));
+       msm_writel(lower_32_bits(val), gpu->mmio + (reg << 2));
+       msm_writel(upper_32_bits(val), gpu->mmio + ((reg + 1) << 2));
 }
 
 int msm_gpu_pm_suspend(struct msm_gpu *gpu);