diff mbox series

[v2] drm/msm/dp: force link training for display resolution change

Message ID 1653606555-18675-1-git-send-email-quic_khsieh@quicinc.com (mailing list archive)
State New, archived
Headers show
Series [v2] drm/msm/dp: force link training for display resolution change | expand

Commit Message

Kuogee Hsieh May 26, 2022, 11:09 p.m. UTC
During display resolution changes display have to be disabled first
followed by display enable with new resolution. This patch force
main link always be retrained during display enable procedure to
simplify implementation instead of manually kicking of irq_hpd
handle.

Changes in v2:
-- set force_link_train flag on DP only (is_edp == false)

Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
---
 drivers/gpu/drm/msm/dp/dp_ctrl.c    |  6 +++---
 drivers/gpu/drm/msm/dp/dp_ctrl.h    |  2 +-
 drivers/gpu/drm/msm/dp/dp_display.c | 15 ++++++++-------
 3 files changed, 12 insertions(+), 11 deletions(-)

Comments

kernel test robot May 27, 2022, 6:43 a.m. UTC | #1
Hi Kuogee,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on next-20220526]
[cannot apply to v5.18]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-force-link-training-for-display-resolution-change/20220527-071202
base:   git://anongit.freedesktop.org/drm/drm drm-next
config: sparc-allmodconfig (https://download.01.org/0day-ci/archive/20220527/202205271424.ApfrMbAm-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/42816831cad7ced23cdedbb77ef2ebf13247c623
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Kuogee-Hsieh/drm-msm-dp-force-link-training-for-display-resolution-change/20220527-071202
        git checkout 42816831cad7ced23cdedbb77ef2ebf13247c623
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/msm/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/msm/dp/dp_ctrl.c: In function 'dp_ctrl_on_stream':
>> drivers/gpu/drm/msm/dp/dp_ctrl.c:1852:13: error: 'force_link_tarin' undeclared (first use in this function); did you mean 'force_link_train'?
    1852 |         if (force_link_tarin || !dp_ctrl_channel_eq_ok(ctrl))
         |             ^~~~~~~~~~~~~~~~
         |             force_link_train
   drivers/gpu/drm/msm/dp/dp_ctrl.c:1852:13: note: each undeclared identifier is reported only once for each function it appears in


vim +1852 drivers/gpu/drm/msm/dp/dp_ctrl.c

  1810	
  1811	int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train)
  1812	{
  1813		int ret = 0;
  1814		bool mainlink_ready = false;
  1815		struct dp_ctrl_private *ctrl;
  1816		unsigned long pixel_rate_orig;
  1817	
  1818		if (!dp_ctrl)
  1819			return -EINVAL;
  1820	
  1821		ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
  1822	
  1823		ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
  1824	
  1825		pixel_rate_orig = ctrl->dp_ctrl.pixel_rate;
  1826		if (dp_ctrl->wide_bus_en)
  1827			ctrl->dp_ctrl.pixel_rate >>= 1;
  1828	
  1829		drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%d\n",
  1830			ctrl->link->link_params.rate,
  1831			ctrl->link->link_params.num_lanes, ctrl->dp_ctrl.pixel_rate);
  1832	
  1833		if (!dp_power_clk_status(ctrl->power, DP_CTRL_PM)) { /* link clk is off */
  1834			ret = dp_ctrl_enable_mainlink_clocks(ctrl);
  1835			if (ret) {
  1836				DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
  1837				goto end;
  1838			}
  1839		}
  1840	
  1841		ret = dp_ctrl_enable_stream_clocks(ctrl);
  1842		if (ret) {
  1843			DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
  1844			goto end;
  1845		}
  1846	
  1847		if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
  1848			dp_ctrl_send_phy_test_pattern(ctrl);
  1849			return 0;
  1850		}
  1851	
> 1852		if (force_link_tarin || !dp_ctrl_channel_eq_ok(ctrl))
  1853			dp_ctrl_link_retrain(ctrl);
  1854	
  1855		/* stop txing train pattern to end link training */
  1856		dp_ctrl_clear_training_pattern(ctrl);
  1857	
  1858		/*
  1859		 * Set up transfer unit values and set controller state to send
  1860		 * video.
  1861		 */
  1862		reinit_completion(&ctrl->video_comp);
  1863	
  1864		dp_ctrl_configure_source_params(ctrl);
  1865	
  1866		dp_catalog_ctrl_config_msa(ctrl->catalog,
  1867			ctrl->link->link_params.rate,
  1868			pixel_rate_orig, dp_ctrl_use_fixed_nvid(ctrl));
  1869	
  1870		dp_ctrl_setup_tr_unit(ctrl);
  1871	
  1872		dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
  1873	
  1874		ret = dp_ctrl_wait4video_ready(ctrl);
  1875		if (ret)
  1876			return ret;
  1877	
  1878		mainlink_ready = dp_catalog_ctrl_mainlink_ready(ctrl->catalog);
  1879		drm_dbg_dp(ctrl->drm_dev,
  1880			"mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
  1881	
  1882	end:
  1883		return ret;
  1884	}
  1885
diff mbox series

Patch

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index af7a80c..ac226f5 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1551,7 +1551,7 @@  static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl)
 
 	ret = dp_ctrl_on_link(&ctrl->dp_ctrl);
 	if (!ret)
-		ret = dp_ctrl_on_stream(&ctrl->dp_ctrl);
+		ret = dp_ctrl_on_stream(&ctrl->dp_ctrl, false);
 	else
 		DRM_ERROR("failed to enable DP link controller\n");
 
@@ -1807,7 +1807,7 @@  static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl)
 	return dp_ctrl_setup_main_link(ctrl, &training_step);
 }
 
-int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
+int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train)
 {
 	int ret = 0;
 	bool mainlink_ready = false;
@@ -1848,7 +1848,7 @@  int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl)
 		return 0;
 	}
 
-	if (!dp_ctrl_channel_eq_ok(ctrl))
+	if (force_link_tarin || !dp_ctrl_channel_eq_ok(ctrl))
 		dp_ctrl_link_retrain(ctrl);
 
 	/* stop txing train pattern to end link training */
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
index 0745fde..b563e2e 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -21,7 +21,7 @@  struct dp_ctrl {
 };
 
 int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
-int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl);
+int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train);
 int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl);
 int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl);
 int dp_ctrl_off(struct dp_ctrl *dp_ctrl);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index c388323..370348d 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -872,7 +872,7 @@  static int dp_display_enable(struct dp_display_private *dp, u32 data)
 		return 0;
 	}
 
-	rc = dp_ctrl_on_stream(dp->ctrl);
+	rc = dp_ctrl_on_stream(dp->ctrl, data);
 	if (!rc)
 		dp_display->power_on = true;
 
@@ -1654,6 +1654,7 @@  void dp_bridge_enable(struct drm_bridge *drm_bridge)
 	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) {
@@ -1688,10 +1689,14 @@  void dp_bridge_enable(struct drm_bridge *drm_bridge)
 
 	state =  dp_display->hpd_state;
 
-	if (state == ST_DISPLAY_OFF)
+	if (state == ST_DISPLAY_OFF) {
 		dp_display_host_phy_init(dp_display);
 
-	dp_display_enable(dp_display, 0);
+		if (!dp->is_edp)
+			force_link_train = true;
+	}
+
+	dp_display_enable(dp_display, force_link_train);
 
 	rc = dp_display_post_enable(dp);
 	if (rc) {
@@ -1700,10 +1705,6 @@  void dp_bridge_enable(struct drm_bridge *drm_bridge)
 		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;