Message ID | 20250310211039.29843-2-alex.vinarskis@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | drm/msm/dp: Introduce link training per-segment for LTTPRs | expand |
On 25-03-10 22:05:51, Aleksandrs Vinarskis wrote: > Take into account LTTPR capabilities when selecting maximum allowed > link rate, number of data lines. Initialize LTTPR before > msm_dp_panel_read_sink_caps, as > a) Link params computation need to take into account LTTPR's caps > b) It appears DPTX shall (re)read DPRX caps after LTTPR detection > > Return lttpr_count to prepare for per-segment link training. > > Signed-off-by: Aleksandrs Vinarskis <alex.vinarskis@gmail.com> > --- > drivers/gpu/drm/msm/dp/dp_display.c | 31 +++++++++++++++++++---------- > drivers/gpu/drm/msm/dp/dp_panel.c | 30 +++++++++++++++++++--------- > drivers/gpu/drm/msm/dp/dp_panel.h | 2 ++ > 3 files changed, 44 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c > index bbc47d86ae9e..2edbc6adfde5 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -108,6 +108,8 @@ struct msm_dp_display_private { > struct msm_dp_event event_list[DP_EVENT_Q_MAX]; > spinlock_t event_lock; > > + u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]; > + > bool wide_bus_supported; > > struct msm_dp_audio *audio; > @@ -367,17 +369,21 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d > return 0; > } > > -static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp) > +static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd) > { > - u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE]; > - int rc; > + int rc, lttpr_count; > > - if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps)) > - return; > + if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->lttpr_common_caps)) > + return 0; > > - rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps)); > - if (rc) > - DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc); > + lttpr_count = drm_dp_lttpr_count(dp->lttpr_common_caps); > + rc = drm_dp_lttpr_init(dp->aux, lttpr_count); > + if (rc) { > + DRM_ERROR("fialed to set LTTPRs transparency mode, rc=%d\n", rc); Nitpick: failed With that fixed, LGTM: Reviewed-by: Abel Vesa <abel.vesa@linaro.org> > + return 0; > + } > + > + return lttpr_count; > } > > static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) > @@ -385,12 +391,17 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) > struct drm_connector *connector = dp->msm_dp_display.connector; > const struct drm_display_info *info = &connector->display_info; > int rc = 0; > + u8 dpcd[DP_RECEIVER_CAP_SIZE]; > > - rc = msm_dp_panel_read_sink_caps(dp->panel, connector); > + rc = drm_dp_read_dpcd_caps(dp->aux, dpcd); > if (rc) > goto end; > > - msm_dp_display_lttpr_init(dp); > + msm_dp_display_lttpr_init(dp, dpcd); > + > + rc = msm_dp_panel_read_sink_caps(dp->panel, dp->lttpr_common_caps, connector); > + if (rc) > + goto end; > > msm_dp_link_process_request(dp->link); > > diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c > index 92415bf8aa16..f41b4cf7002e 100644 > --- a/drivers/gpu/drm/msm/dp/dp_panel.c > +++ b/drivers/gpu/drm/msm/dp/dp_panel.c > @@ -45,9 +45,12 @@ static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel) > } > } > > -static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel) > +static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel, > + const u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]) > { > int rc; > + int max_sink_lanes, max_source_lanes, max_lttpr_lanes; > + int max_sink_rate, max_source_rate, max_lttpr_rate; > struct msm_dp_panel_private *panel; > struct msm_dp_link_info *link_info; > u8 *dpcd, major, minor; > @@ -64,16 +67,24 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel) > major = (link_info->revision >> 4) & 0x0f; > minor = link_info->revision & 0x0f; > > - link_info->rate = drm_dp_max_link_rate(dpcd); > - link_info->num_lanes = drm_dp_max_lane_count(dpcd); > + max_source_lanes = msm_dp_panel->max_dp_lanes; > + max_source_rate = msm_dp_panel->max_dp_link_rate; > > - /* Limit data lanes from data-lanes of endpoint property of dtsi */ > - if (link_info->num_lanes > msm_dp_panel->max_dp_lanes) > - link_info->num_lanes = msm_dp_panel->max_dp_lanes; > + max_sink_lanes = drm_dp_max_lane_count(dpcd); > + max_sink_rate = drm_dp_max_link_rate(dpcd); > + > + max_lttpr_lanes = drm_dp_lttpr_max_lane_count(lttpr_common_caps); > + max_lttpr_rate = drm_dp_lttpr_max_link_rate(lttpr_common_caps); > > + if (max_lttpr_lanes) > + max_sink_lanes = min(max_sink_lanes, max_lttpr_lanes); > + if (max_lttpr_rate) > + max_sink_rate = min(max_sink_rate, max_lttpr_rate); > + > + /* Limit data lanes from data-lanes of endpoint property of dtsi */ > + link_info->num_lanes = min(max_sink_lanes, max_source_lanes); > /* Limit link rate from link-frequencies of endpoint property of dtsi */ > - if (link_info->rate > msm_dp_panel->max_dp_link_rate) > - link_info->rate = msm_dp_panel->max_dp_link_rate; > + link_info->rate = min(max_sink_rate, max_source_rate); > > drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor); > drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate); > @@ -109,6 +120,7 @@ static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel, > } > > int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, > + const u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE], > struct drm_connector *connector) > { > int rc, bw_code; > @@ -125,7 +137,7 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, > drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n", > msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate); > > - rc = msm_dp_panel_read_dpcd(msm_dp_panel); > + rc = msm_dp_panel_read_dpcd(msm_dp_panel, lttpr_common_caps); > if (rc) { > DRM_ERROR("read dpcd failed %d\n", rc); > return rc; > diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h > index 4906f4f09f24..d89e17a9add5 100644 > --- a/drivers/gpu/drm/msm/dp/dp_panel.h > +++ b/drivers/gpu/drm/msm/dp/dp_panel.h > @@ -7,6 +7,7 @@ > #define _DP_PANEL_H_ > > #include <drm/msm_drm.h> > +#include <drm/display/drm_dp_helper.h> > > #include "dp_aux.h" > #include "dp_link.h" > @@ -49,6 +50,7 @@ int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel); > int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel); > int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel); > int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, > + const u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE], > struct drm_connector *connector); > u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp, > u32 mode_pclk_khz); > -- > 2.45.2 >
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index bbc47d86ae9e..2edbc6adfde5 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -108,6 +108,8 @@ struct msm_dp_display_private { struct msm_dp_event event_list[DP_EVENT_Q_MAX]; spinlock_t event_lock; + u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]; + bool wide_bus_supported; struct msm_dp_audio *audio; @@ -367,17 +369,21 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d return 0; } -static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp) +static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd) { - u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE]; - int rc; + int rc, lttpr_count; - if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps)) - return; + if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->lttpr_common_caps)) + return 0; - rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps)); - if (rc) - DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc); + lttpr_count = drm_dp_lttpr_count(dp->lttpr_common_caps); + rc = drm_dp_lttpr_init(dp->aux, lttpr_count); + if (rc) { + DRM_ERROR("fialed to set LTTPRs transparency mode, rc=%d\n", rc); + return 0; + } + + return lttpr_count; } static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) @@ -385,12 +391,17 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) struct drm_connector *connector = dp->msm_dp_display.connector; const struct drm_display_info *info = &connector->display_info; int rc = 0; + u8 dpcd[DP_RECEIVER_CAP_SIZE]; - rc = msm_dp_panel_read_sink_caps(dp->panel, connector); + rc = drm_dp_read_dpcd_caps(dp->aux, dpcd); if (rc) goto end; - msm_dp_display_lttpr_init(dp); + msm_dp_display_lttpr_init(dp, dpcd); + + rc = msm_dp_panel_read_sink_caps(dp->panel, dp->lttpr_common_caps, connector); + if (rc) + goto end; msm_dp_link_process_request(dp->link); diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 92415bf8aa16..f41b4cf7002e 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -45,9 +45,12 @@ static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel) } } -static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel) +static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel, + const u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]) { int rc; + int max_sink_lanes, max_source_lanes, max_lttpr_lanes; + int max_sink_rate, max_source_rate, max_lttpr_rate; struct msm_dp_panel_private *panel; struct msm_dp_link_info *link_info; u8 *dpcd, major, minor; @@ -64,16 +67,24 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel) major = (link_info->revision >> 4) & 0x0f; minor = link_info->revision & 0x0f; - link_info->rate = drm_dp_max_link_rate(dpcd); - link_info->num_lanes = drm_dp_max_lane_count(dpcd); + max_source_lanes = msm_dp_panel->max_dp_lanes; + max_source_rate = msm_dp_panel->max_dp_link_rate; - /* Limit data lanes from data-lanes of endpoint property of dtsi */ - if (link_info->num_lanes > msm_dp_panel->max_dp_lanes) - link_info->num_lanes = msm_dp_panel->max_dp_lanes; + max_sink_lanes = drm_dp_max_lane_count(dpcd); + max_sink_rate = drm_dp_max_link_rate(dpcd); + + max_lttpr_lanes = drm_dp_lttpr_max_lane_count(lttpr_common_caps); + max_lttpr_rate = drm_dp_lttpr_max_link_rate(lttpr_common_caps); + if (max_lttpr_lanes) + max_sink_lanes = min(max_sink_lanes, max_lttpr_lanes); + if (max_lttpr_rate) + max_sink_rate = min(max_sink_rate, max_lttpr_rate); + + /* Limit data lanes from data-lanes of endpoint property of dtsi */ + link_info->num_lanes = min(max_sink_lanes, max_source_lanes); /* Limit link rate from link-frequencies of endpoint property of dtsi */ - if (link_info->rate > msm_dp_panel->max_dp_link_rate) - link_info->rate = msm_dp_panel->max_dp_link_rate; + link_info->rate = min(max_sink_rate, max_source_rate); drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor); drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate); @@ -109,6 +120,7 @@ static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel, } int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, + const u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE], struct drm_connector *connector) { int rc, bw_code; @@ -125,7 +137,7 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n", msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate); - rc = msm_dp_panel_read_dpcd(msm_dp_panel); + rc = msm_dp_panel_read_dpcd(msm_dp_panel, lttpr_common_caps); if (rc) { DRM_ERROR("read dpcd failed %d\n", rc); return rc; diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h index 4906f4f09f24..d89e17a9add5 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.h +++ b/drivers/gpu/drm/msm/dp/dp_panel.h @@ -7,6 +7,7 @@ #define _DP_PANEL_H_ #include <drm/msm_drm.h> +#include <drm/display/drm_dp_helper.h> #include "dp_aux.h" #include "dp_link.h" @@ -49,6 +50,7 @@ int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel); int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel); int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel); int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, + const u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE], struct drm_connector *connector); u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp, u32 mode_pclk_khz);
Take into account LTTPR capabilities when selecting maximum allowed link rate, number of data lines. Initialize LTTPR before msm_dp_panel_read_sink_caps, as a) Link params computation need to take into account LTTPR's caps b) It appears DPTX shall (re)read DPRX caps after LTTPR detection Return lttpr_count to prepare for per-segment link training. Signed-off-by: Aleksandrs Vinarskis <alex.vinarskis@gmail.com> --- drivers/gpu/drm/msm/dp/dp_display.c | 31 +++++++++++++++++++---------- drivers/gpu/drm/msm/dp/dp_panel.c | 30 +++++++++++++++++++--------- drivers/gpu/drm/msm/dp/dp_panel.h | 2 ++ 3 files changed, 44 insertions(+), 19 deletions(-)