Merge tag 'drm-msm-fixes-2022-06-20' of https://gitlab.freedesktop.org/drm/msm into...
authorDave Airlie <airlied@redhat.com>
Fri, 24 Jun 2022 00:11:26 +0000 (10:11 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 24 Jun 2022 00:11:27 +0000 (10:11 +1000)
Fixes for v5.19-rc4

- Workaround for parade DSI bridge power sequencing
- Fix for multi-planar YUV format offsets
- Limiting WB modes to max sspp linewidth
- Fixing the supported rotations to add 180 back for IGT
- Fix to handle pm_runtime_get_sync() errors to avoid unclocked access
  in the bind() path for dpu driver
- Fix the irq_free() without request issue which was a being hit frequently
  in CI.
- Fix to add minimum ICC vote in the msm_mdss pm_resume path to address
  bootup splats
- Fix to avoid dereferencing without checking in WB encoder
- Fix to avoid crash during suspend in DP driver by ensuring interrupt
  mask bits are updated
- Remove unused code from dpu_encoder_virt_atomic_check()
- Fix to remove redundant init of dsc variable
- Fix to ensure mmap offset is initialized to avoid memory corruption
  from unpin/evict
- Fix double runpm disable in probe-defer path
- VMA fenced-unpin fixes
- Fix for WB max-width
- Fix for rare dp resolution change issue

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGvdsOF1-+WfTWyEyu33XPcvxOCU00G-dz7EF2J+fdyUHg@mail.gmail.com
1  2 
drivers/gpu/drm/msm/dp/dp_ctrl.c
drivers/gpu/drm/msm/dp/dp_display.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_gem_submit.c

index b7f5b8d3bbd6138bed6903bc3d3ae9974ee0911f,f18588aecea2c1897e52e2b9282076260d1b017e..703249384e7c7d0b000b2b51f89c45791ab6684e
@@@ -11,9 -11,8 +11,9 @@@
  #include <linux/phy/phy.h>
  #include <linux/phy/phy-dp.h>
  #include <linux/pm_opp.h>
 +
 +#include <drm/display/drm_dp_helper.h>
  #include <drm/drm_fixed.h>
 -#include <drm/dp/drm_dp_helper.h>
  #include <drm/drm_print.h>
  
  #include "dp_reg.h"
@@@ -1534,6 -1533,8 +1534,8 @@@ end
        return ret;
  }
  
+ static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl);
  static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl)
  {
        int ret = 0;
  
        ret = dp_ctrl_on_link(&ctrl->dp_ctrl);
        if (!ret)
-               ret = dp_ctrl_on_stream(&ctrl->dp_ctrl);
+               ret = dp_ctrl_on_stream_phy_test_report(&ctrl->dp_ctrl);
        else
                DRM_ERROR("failed to enable DP link controller\n");
  
@@@ -1813,7 -1814,27 +1815,27 @@@ static int dp_ctrl_link_retrain(struct 
        return dp_ctrl_setup_main_link(ctrl, &training_step);
  }
  
- int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
+ static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl)
+ {
+       int ret;
+       struct dp_ctrl_private *ctrl;
+       ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+       ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
+       ret = dp_ctrl_enable_stream_clocks(ctrl);
+       if (ret) {
+               DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
+               return ret;
+       }
+       dp_ctrl_send_phy_test_pattern(ctrl);
+       return 0;
+ }
+ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train)
  {
        int ret = 0;
        bool mainlink_ready = false;
                goto end;
        }
  
-       if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
-               dp_ctrl_send_phy_test_pattern(ctrl);
-               return 0;
-       }
-       if (!dp_ctrl_channel_eq_ok(ctrl))
+       if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl))
                dp_ctrl_link_retrain(ctrl);
  
        /* stop txing train pattern to end link training */
index bce77935394f07c96d162c6e27a1ff7062693e8f,a6117926a27422373bedd5c3b700227e462eaf81..ec26855079c181a76cfb0d405f70d3c5a6ec6575
@@@ -10,7 -10,7 +10,7 @@@
  #include <linux/component.h>
  #include <linux/of_irq.h>
  #include <linux/delay.h>
 -#include <drm/dp/drm_dp_aux_bus.h>
 +#include <drm/display/drm_dp_aux_bus.h>
  
  #include "msm_drv.h"
  #include "msm_kms.h"
@@@ -309,7 -309,8 +309,8 @@@ static void dp_display_unbind(struct de
        struct msm_drm_private *priv = dev_get_drvdata(master);
  
        /* disable all HPD interrupts */
-       dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+       if (dp->core_initialized)
+               dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
  
        kthread_stop(dp->ev_tsk);
  
@@@ -872,7 -873,7 +873,7 @@@ static int dp_display_enable(struct dp_
                return 0;
        }
  
-       rc = dp_ctrl_on_stream(dp->ctrl);
+       rc = dp_ctrl_on_stream(dp->ctrl, data);
        if (!rc)
                dp_display->power_on = true;
  
@@@ -1659,6 -1660,7 +1660,7 @@@ void dp_bridge_enable(struct drm_bridg
        int rc = 0;
        struct dp_display_private *dp_display;
        u32 state;
+       bool force_link_train = false;
  
        dp_display = container_of(dp, struct dp_display_private, dp_display);
        if (!dp_display->dp_mode.drm_mode.clock) {
  
        state =  dp_display->hpd_state;
  
-       if (state == ST_DISPLAY_OFF)
+       if (state == ST_DISPLAY_OFF) {
                dp_display_host_phy_init(dp_display);
+               force_link_train = true;
+       }
  
-       dp_display_enable(dp_display, 0);
+       dp_display_enable(dp_display, force_link_train);
  
        rc = dp_display_post_enable(dp);
        if (rc) {
                dp_display_unprepare(dp);
        }
  
-       /* manual kick off plug event to train link */
-       if (state == ST_DISPLAY_OFF)
-               dp_add_event(dp_display, EV_IRQ_HPD_INT, 0, 0);
        /* completed connection */
        dp_display->hpd_state = ST_CONNECTED;
  
index 08388d742d6538234544a63b302bbaaa6c9ab4a6,34f74d47b3c1fa19185ee3a6f68ffe45fe9927ae..099a67d10c3a76ae3e0d13adb1fd6fd93f942d71
@@@ -30,7 -30,7 +30,7 @@@
  #include <drm/drm_plane_helper.h>
  #include <drm/drm_probe_helper.h>
  #include <drm/drm_fb_helper.h>
 -#include <drm/drm_dsc.h>
 +#include <drm/display/drm_dsc.h>
  #include <drm/msm_drm.h>
  #include <drm/drm_gem.h>
  
@@@ -246,6 -246,7 +246,7 @@@ unsigned long msm_gem_shrinker_shrink(s
  void msm_gem_shrinker_init(struct drm_device *dev);
  void msm_gem_shrinker_cleanup(struct drm_device *dev);
  
+ int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
  struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
  int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
  void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
index 97d5b4d8b9b05c645a8b6acd663e9d8749560d25,916e7f418fe1a7970b04cab310ebf80744b8d938..7f92231785a0e49c25181bd875da60fa7d2b0fb2
@@@ -439,14 -439,12 +439,12 @@@ int msm_gem_pin_vma_locked(struct drm_g
        return ret;
  }
  
- void msm_gem_unpin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma)
+ void msm_gem_unpin_locked(struct drm_gem_object *obj)
  {
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
  
        GEM_WARN_ON(!msm_gem_is_locked(obj));
  
-       msm_gem_unpin_vma(vma);
        msm_obj->pin_count--;
        GEM_WARN_ON(msm_obj->pin_count < 0);
  
@@@ -586,7 -584,8 +584,8 @@@ void msm_gem_unpin_iova(struct drm_gem_
        msm_gem_lock(obj);
        vma = lookup_vma(obj, aspace);
        if (!GEM_WARN_ON(!vma)) {
-               msm_gem_unpin_vma_locked(obj, vma);
+               msm_gem_unpin_vma(vma);
+               msm_gem_unpin_locked(obj);
        }
        msm_gem_unlock(obj);
  }
@@@ -877,8 -876,7 +876,8 @@@ int msm_gem_cpu_prep(struct drm_gem_obj
                op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout);
        long ret;
  
 -      ret = dma_resv_wait_timeout(obj->resv, write, true,  remain);
 +      ret = dma_resv_wait_timeout(obj->resv, dma_resv_usage_rw(write),
 +                                  true,  remain);
        if (ret == 0)
                return remain == 0 ? -EBUSY : -ETIMEDOUT;
        else if (ret < 0)
@@@ -956,7 -954,6 +955,7 @@@ void msm_gem_describe(struct drm_gem_ob
                                        get_pid_task(aspace->pid, PIDTYPE_PID);
                                if (task) {
                                        comm = kstrdup(task->comm, GFP_KERNEL);
 +                                      put_task_struct(task);
                                } else {
                                        comm = NULL;
                                }
index 80975229b4dea3764be045556cf2b62fe7e55ad5,286124008445dc026b1583389b5b2f5f6ac04b5a..3c3a0cfade369b96e39ce408990079eaa8e0c6cf
@@@ -232,8 -232,11 +232,11 @@@ static void submit_cleanup_bo(struct ms
         */
        submit->bos[i].flags &= ~cleanup_flags;
  
-       if (flags & BO_PINNED)
-               msm_gem_unpin_vma_locked(obj, submit->bos[i].vma);
+       if (flags & BO_VMA_PINNED)
+               msm_gem_unpin_vma(submit->bos[i].vma);
+       if (flags & BO_OBJ_PINNED)
+               msm_gem_unpin_locked(obj);
  
        if (flags & BO_ACTIVE)
                msm_gem_active_put(obj);
  
  static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
  {
-       submit_cleanup_bo(submit, i, BO_PINNED | BO_ACTIVE | BO_LOCKED);
+       unsigned cleanup_flags = BO_VMA_PINNED | BO_OBJ_PINNED |
+                                BO_ACTIVE | BO_LOCKED;
+       submit_cleanup_bo(submit, i, cleanup_flags);
  
        if (!(submit->bos[i].flags & BO_VALID))
                submit->bos[i].iova = 0;
@@@ -319,14 -324,16 +324,14 @@@ static int submit_fence_sync(struct msm
                struct drm_gem_object *obj = &submit->bos[i].obj->base;
                bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE;
  
 -              if (!write) {
 -                      /* NOTE: _reserve_shared() must happen before
 -                       * _add_shared_fence(), which makes this a slightly
 -                       * strange place to call it.  OTOH this is a
 -                       * convenient can-fail point to hook it in.
 -                       */
 -                      ret = dma_resv_reserve_shared(obj->resv, 1);
 -                      if (ret)
 -                              return ret;
 -              }
 +              /* NOTE: _reserve_shared() must happen before
 +               * _add_shared_fence(), which makes this a slightly
 +               * strange place to call it.  OTOH this is a
 +               * convenient can-fail point to hook it in.
 +               */
 +              ret = dma_resv_reserve_fences(obj->resv, 1);
 +              if (ret)
 +                      return ret;
  
                /* exclusive fences must be ordered */
                if (no_implicit && !write)
@@@ -375,7 -382,7 +380,7 @@@ static int submit_pin_objects(struct ms
                if (ret)
                        break;
  
-               submit->bos[i].flags |= BO_PINNED;
+               submit->bos[i].flags |= BO_OBJ_PINNED | BO_VMA_PINNED;
                submit->bos[i].vma = vma;
  
                if (vma->iova == submit->bos[i].iova) {
@@@ -399,11 -406,9 +404,11 @@@ static void submit_attach_object_fences
                struct drm_gem_object *obj = &submit->bos[i].obj->base;
  
                if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE)
 -                      dma_resv_add_excl_fence(obj->resv, submit->user_fence);
 +                      dma_resv_add_fence(obj->resv, submit->user_fence,
 +                                         DMA_RESV_USAGE_WRITE);
                else if (submit->bos[i].flags & MSM_SUBMIT_BO_READ)
 -                      dma_resv_add_shared_fence(obj->resv, submit->user_fence);
 +                      dma_resv_add_fence(obj->resv, submit->user_fence,
 +                                         DMA_RESV_USAGE_READ);
        }
  }
  
@@@ -511,7 -516,7 +516,7 @@@ static void submit_cleanup(struct msm_g
        unsigned i;
  
        if (error)
-               cleanup_flags |= BO_PINNED | BO_ACTIVE;
+               cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED | BO_ACTIVE;
  
        for (i = 0; i < submit->nr_bos; i++) {
                struct msm_gem_object *msm_obj = submit->bos[i].obj;
@@@ -529,7 -534,8 +534,8 @@@ void msm_submit_retire(struct msm_gem_s
                struct drm_gem_object *obj = &submit->bos[i].obj->base;
  
                msm_gem_lock(obj);
-               submit_cleanup_bo(submit, i, BO_PINNED | BO_ACTIVE);
+               /* Note, VMA already fence-unpinned before submit: */
+               submit_cleanup_bo(submit, i, BO_OBJ_PINNED | BO_ACTIVE);
                msm_gem_unlock(obj);
                drm_gem_object_put(obj);
        }