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(-)
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(-)
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;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
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
--
0-DAY CI Kernel Test Service
https://01.org/lkp
© 2016 - 2026 Red Hat, Inc.