From 98434934c630151eca01492b40a391972f76ebcd Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Mon, 3 Jun 2019 16:47:50 -0400 Subject: [PATCH] disp: msm: dp: filter modes based on sde resource availability Not considering the currently available sde resources and caps while filtering/validating a mode will report unavailable modes and result in an atomic commit failure. DP should calculate the number of required lms and verify if lms/3dmux are available before a validating a mode. Change-Id: Idadcc655c30f5a831c47cf22b60085052b5b9fcd Signed-off-by: Nilaan Gunabalachandran --- msm/dp/dp_display.c | 16 ++++++++++++++-- msm/dp/dp_display.h | 3 ++- msm/dp/dp_drm.c | 3 ++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 369aeda6f171..be33452ba30e 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -1860,7 +1860,8 @@ end: static enum drm_mode_status dp_display_validate_mode( struct dp_display *dp_display, - void *panel, struct drm_display_mode *mode) + void *panel, struct drm_display_mode *mode, + const struct msm_resource_caps_info *avail_res) { struct dp_display_private *dp; struct drm_dp_link *link_info; @@ -1873,8 +1874,10 @@ static enum drm_mode_status dp_display_validate_mode( int hdis, vdis, vref, ar, _hdis, _vdis, _vref, _ar, rate; struct dp_display_mode dp_mode; bool dsc_en; + u32 num_lm = 0; - if (!dp_display || !mode || !panel) { + if (!dp_display || !mode || !panel || + !avail_res || !avail_res->max_mixer_width) { pr_err("invalid params\n"); return mode_status; } @@ -1917,6 +1920,15 @@ static enum drm_mode_status dp_display_validate_mode( goto end; } + num_lm = (avail_res->max_mixer_width <= mode->hdisplay) ? + 2 : 1; + if (num_lm > avail_res->num_lm || + (num_lm == 2 && !avail_res->num_3dmux)) { + DP_MST_DEBUG("num_lm:%d, req lm:%d 3dmux:%d\n", num_lm, + avail_res->num_lm, avail_res->num_3dmux); + goto end; + } + /* * If the connector exists in the mst connector list and if debug is * enabled for that connector, use the mst connector settings from the diff --git a/msm/dp/dp_display.h b/msm/dp/dp_display.h index 2597aaf59d60..4b69ebb74e27 100644 --- a/msm/dp/dp_display.h +++ b/msm/dp/dp_display.h @@ -78,7 +78,8 @@ struct dp_display { int (*set_mode)(struct dp_display *dp_display, void *panel, struct dp_display_mode *mode); enum drm_mode_status (*validate_mode)(struct dp_display *dp_display, - void *panel, struct drm_display_mode *mode); + void *panel, struct drm_display_mode *mode, + const struct msm_resource_caps_info *avail_res); int (*get_modes)(struct dp_display *dp_display, void *panel, struct dp_display_mode *dp_mode); int (*prepare)(struct dp_display *dp_display, void *panel); diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index 2bc30fc518af..799f9a925f5b 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -600,7 +600,8 @@ enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector, dp_disp = display; mode->vrefresh = drm_mode_vrefresh(mode); - return dp_disp->validate_mode(dp_disp, sde_conn->drv_panel, mode); + return dp_disp->validate_mode(dp_disp, sde_conn->drv_panel, + mode, avail_res); } int dp_connector_update_pps(struct drm_connector *connector,