]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/msm/dpu: Move autorefresh disable from CMD encoder to pingpong
authorMarijn Suijten <marijn.suijten@somainline.org>
Wed, 26 Apr 2023 22:37:27 +0000 (00:37 +0200)
committerDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Mon, 22 May 2023 07:14:17 +0000 (10:14 +0300)
This autorefresh disable logic in the physical command-mode encoder
consumes three callbacks to the pingpong block, and will explode in
unnecessary complexity when the same callbacks need to be called on the
interface block instead to accommodate INTF TE support.  To clean this
up, move the logic into the pingpong block under a disable_autorefresh
callback, replacing the aforementioned three get_autorefresh,
setup_autorefresh and get_vsync_info callbacks.

The same logic will have to be replicated to the interface block when it
receives INTF TE support, but it is less complex than constantly
switching on a "has_intf_te" boolean to choose a callback.

Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/534230/
Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-13-27ce1a5ab5c6@somainline.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h

index 74470d068622e0d42f0c022a590ed3b8d7b85bf5..a60fb8d3736b55d83fcdf3bbe381bd63207633eb 100644 (file)
 #define DEFAULT_TEARCHECK_SYNC_THRESH_START    4
 #define DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE 4
 
-#define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000
-
-#define DPU_ENC_MAX_POLL_TIMEOUT_US    2000
-
 static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc);
 
 static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc)
@@ -574,28 +570,8 @@ static void dpu_encoder_phys_cmd_prepare_for_kickoff(
                        atomic_read(&phys_enc->pending_kickoff_cnt));
 }
 
-static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
-               struct dpu_encoder_phys *phys_enc)
-{
-       struct dpu_hw_pp_vsync_info info;
-
-       if (!phys_enc)
-               return false;
-
-       phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
-       if (info.wr_ptr_line_count > 0 &&
-           info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay)
-               return true;
-
-       return false;
-}
-
 static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc)
 {
-       struct dpu_encoder_phys_cmd *cmd_enc =
-               to_dpu_encoder_phys_cmd(phys_enc);
-       int trial = 0;
-
        if (!phys_enc)
                return;
        if (!phys_enc->hw_pp)
@@ -603,37 +579,11 @@ static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc)
        if (!dpu_encoder_phys_cmd_is_master(phys_enc))
                return;
 
-       /* If autorefresh is already disabled, we have nothing to do */
-       if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
-               return;
-
-       /*
-        * If autorefresh is enabled, disable it and make sure it is safe to
-        * proceed with current frame commit/push. Sequence fallowed is,
-        * 1. Disable TE
-        * 2. Disable autorefresh config
-        * 4. Poll for frame transfer ongoing to be false
-        * 5. Enable TE back
-        */
-       _dpu_encoder_phys_cmd_connect_te(phys_enc, false);
-       phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false);
-
-       do {
-               udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
-               if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US)
-                               > (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) {
-                       DPU_ERROR_CMDENC(cmd_enc,
-                                       "disable autorefresh failed\n");
-                       break;
-               }
-
-               trial++;
-       } while (dpu_encoder_phys_cmd_is_ongoing_pptx(phys_enc));
-
-       _dpu_encoder_phys_cmd_connect_te(phys_enc, true);
-
-       DPU_DEBUG_CMDENC(to_dpu_encoder_phys_cmd(phys_enc),
-                        "disabled autorefresh\n");
+       if (phys_enc->hw_pp->ops.disable_autorefresh) {
+               phys_enc->hw_pp->ops.disable_autorefresh(phys_enc->hw_pp,
+                                                        DRMID(phys_enc->parent),
+                                                        phys_enc->cached_mode.vdisplay);
+       }
 }
 
 static int _dpu_encoder_phys_cmd_wait_for_ctl_start(
index 1dcbb75b80d3d6e7f96baab1a4baa053b64587ef..e366d752bd073c25e5232f62d4f75b955d230747 100644 (file)
@@ -210,6 +210,49 @@ static u32 dpu_hw_pp_get_line_count(struct dpu_hw_pingpong *pp)
        return line;
 }
 
+static void dpu_hw_pp_disable_autorefresh(struct dpu_hw_pingpong *pp,
+                                         uint32_t encoder_id, u16 vdisplay)
+{
+       struct dpu_hw_pp_vsync_info info;
+       int trial = 0;
+
+       /* If autorefresh is already disabled, we have nothing to do */
+       if (!dpu_hw_pp_get_autorefresh_config(pp, NULL))
+               return;
+
+       /*
+        * If autorefresh is enabled, disable it and make sure it is safe to
+        * proceed with current frame commit/push. Sequence followed is,
+        * 1. Disable TE
+        * 2. Disable autorefresh config
+        * 4. Poll for frame transfer ongoing to be false
+        * 5. Enable TE back
+        */
+
+       dpu_hw_pp_connect_external_te(pp, false);
+       dpu_hw_pp_setup_autorefresh_config(pp, 0, false);
+
+       do {
+               udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
+               if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US)
+                               > (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) {
+                       DPU_ERROR("enc%d pp%d disable autorefresh failed\n",
+                                 encoder_id, pp->idx - PINGPONG_0);
+                       break;
+               }
+
+               trial++;
+
+               dpu_hw_pp_get_vsync_info(pp, &info);
+       } while (info.wr_ptr_line_count > 0 &&
+                info.wr_ptr_line_count < vdisplay);
+
+       dpu_hw_pp_connect_external_te(pp, true);
+
+       DPU_DEBUG("enc%d pp%d disabled autorefresh\n",
+                 encoder_id, pp->idx - PINGPONG_0);
+}
+
 static int dpu_hw_pp_dsc_enable(struct dpu_hw_pingpong *pp)
 {
        struct dpu_hw_blk_reg_map *c = &pp->hw;
@@ -242,10 +285,8 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
        c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
        c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
        c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
-       c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
-       c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
-       c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
        c->ops.get_line_count = dpu_hw_pp_get_line_count;
+       c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh;
        c->ops.setup_dsc = dpu_hw_pp_setup_dsc;
        c->ops.enable_dsc = dpu_hw_pp_dsc_enable;
        c->ops.disable_dsc = dpu_hw_pp_dsc_disable;
index 42af9e5b865e2c6014a8d8e596730e466ecec077..336d383f8b6477594b41296b45b2a24a1c382ae8 100644 (file)
@@ -61,9 +61,6 @@ struct dpu_hw_dither_cfg {
  *  Assumption is these functions will be called after clocks are enabled
  *  @setup_tearcheck : program tear check values
  *  @enable_tearcheck : enables tear check
- *  @get_vsync_info : retries timing info of the panel
- *  @setup_autorefresh : configure and enable the autorefresh config
- *  @get_autorefresh : retrieve autorefresh config from hardware
  *  @setup_dither : function to program the dither hw block
  *  @get_line_count: obtain current vertical line counter
  */
@@ -89,28 +86,14 @@ struct dpu_hw_pingpong_ops {
                        bool enable_external_te);
 
        /**
-        * provides the programmed and current
-        * line_count
-        */
-       int (*get_vsync_info)(struct dpu_hw_pingpong *pp,
-                       struct dpu_hw_pp_vsync_info  *info);
-
-       /**
-        * configure and enable the autorefresh config
-        */
-       void (*setup_autorefresh)(struct dpu_hw_pingpong *pp,
-                                 u32 frame_count, bool enable);
-
-       /**
-        * retrieve autorefresh config from hardware
+        * Obtain current vertical line counter
         */
-       bool (*get_autorefresh)(struct dpu_hw_pingpong *pp,
-                               u32 *frame_count);
+       u32 (*get_line_count)(struct dpu_hw_pingpong *pp);
 
        /**
-        * Obtain current vertical line counter
+        * Disable autorefresh if enabled
         */
-       u32 (*get_line_count)(struct dpu_hw_pingpong *pp);
+       void (*disable_autorefresh)(struct dpu_hw_pingpong *pp, uint32_t encoder_id, u16 vdisplay);
 
        /**
         * Setup dither matix for pingpong block
index 15111e433f219f471ea1dcbb71c2e58be1fbb9a1..cd628752455756ddb0a973f5fb9f78098a49a8fc 100644 (file)
@@ -118,6 +118,10 @@ struct vsync_info {
        u32 line_count;
 };
 
+#define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000
+
+#define DPU_ENC_MAX_POLL_TIMEOUT_US    2000
+
 #define to_dpu_kms(x) container_of(x, struct dpu_kms, base)
 
 #define to_dpu_global_state(x) container_of(x, struct dpu_global_state, base)