From b89a3f739a4814fe60b310c5386b61415b4d3dd3 Mon Sep 17 00:00:00 2001 From: Raviteja Tamatam Date: Wed, 28 Apr 2021 11:28:19 +0530 Subject: [PATCH] disp: msm: populate submode blob information Mode information apart from the fields in drm_mode_modeinfo that can trigger a modeset like dsc-nondsc, video-cmd are defined in sub mode. For each mode in connector->modes there can be multiple submodes. Change-Id: Ib8697d3fa4ea5261d9ac4943b1a4149e22c4da2f Signed-off-by: Raviteja Tamatam --- msm/dsi/dsi_display.c | 2 +- msm/dsi/dsi_display.h | 9 ++++++ msm/dsi/dsi_drm.c | 61 +++++++++++++++++++++++++++++++++++++++++ msm/dsi/dsi_drm.h | 10 +++++++ msm/dsi/dsi_panel.c | 5 ++++ msm/sde/sde_connector.c | 52 +++++++++++++++++++---------------- msm/sde/sde_connector.h | 13 +++++++++ msm/sde/sde_kms.c | 1 + 8 files changed, 129 insertions(+), 24 deletions(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 722689c48f..c6e1455193 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -7150,7 +7150,7 @@ end: return is_matching; } -static bool dsi_display_mode_match(const struct dsi_display_mode *mode1, +bool dsi_display_mode_match(const struct dsi_display_mode *mode1, struct dsi_display_mode *mode2, unsigned int match_flags) { if (!mode1 && !mode2) diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index 27f7f9bd92..86a51412a1 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -814,5 +814,14 @@ int dsi_display_update_dyn_bit_clk(struct dsi_display *display, struct dsi_displ */ int dsi_display_restore_bit_clk(struct dsi_display *display, struct dsi_display_mode *mode); +/** + * dsi_display_mode_match() - compares two dsi mode structures + * @mode1: dsi_display_mode to be compared + * @mode2: dsi_display_mode to be compared + * @match_flags: Values to compare + * Return: True if mode matches + */ +bool dsi_display_mode_match(const struct dsi_display_mode *mode1, + struct dsi_display_mode *mode2, unsigned int match_flags); #endif /* _DSI_DISPLAY_H_ */ diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 095017e909..51cf865bbd 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -803,6 +803,67 @@ end: return 0; } +void dsi_conn_set_submode_blob_info(struct drm_connector *conn, + void *info, void *display, struct drm_display_mode *drm_mode) +{ + struct dsi_display *dsi_display = display; + struct dsi_display_mode partial_dsi_mode; + int count, i; + int preferred_submode_idx = -EINVAL; + + if (!conn || !display || !drm_mode) { + DSI_ERR("Invalid params\n"); + return; + } + + convert_to_dsi_mode(drm_mode, &partial_dsi_mode); + + mutex_lock(&dsi_display->display_lock); + count = dsi_display->panel->num_display_modes; + for (i = 0; i < count; i++) { + struct dsi_display_mode *dsi_mode = &dsi_display->modes[i]; + + u32 panel_mode_caps = 0; + const char *topo_name = NULL; + + if (dsi_display_mode_match(&partial_dsi_mode, dsi_mode, + DSI_MODE_MATCH_FULL_TIMINGS)) { + + sde_kms_info_add_keyint(info, "submode_idx", i); + + if (dsi_mode->is_preferred) + preferred_submode_idx = i; + + if (dsi_mode->panel_mode_caps & DSI_OP_CMD_MODE) + panel_mode_caps |= DRM_MODE_FLAG_CMD_MODE_PANEL; + if (dsi_mode->panel_mode_caps & DSI_OP_VIDEO_MODE) + panel_mode_caps |= DRM_MODE_FLAG_VID_MODE_PANEL; + + sde_kms_info_add_keyint(info, "panel_mode_capabilities", + panel_mode_caps); + + sde_kms_info_add_keyint(info, "dsc_mode", + dsi_mode->priv_info->dsc_enabled ? MSM_DISPLAY_DSC_MODE_ENABLED : + MSM_DISPLAY_DSC_MODE_DISABLED); + topo_name = sde_conn_get_topology_name(conn, + dsi_mode->priv_info->topology); + if (topo_name) + sde_kms_info_add_keystr(info, "topology", topo_name); + + if (dsi_mode->priv_info->bit_clk_list.count > 0) + sde_kms_info_add_list(info, "dyn_bitclk_list", + dsi_mode->priv_info->bit_clk_list.rates, + dsi_mode->priv_info->bit_clk_list.count); + } + } + + if (preferred_submode_idx >= 0) + sde_kms_info_add_keyint(info, "preferred_submode_idx", + preferred_submode_idx); + + mutex_unlock(&dsi_display->display_lock); +} + enum drm_connector_status dsi_conn_detect(struct drm_connector *conn, bool force, void *display) diff --git a/msm/dsi/dsi_drm.h b/msm/dsi/dsi_drm.h index c91cd3bf3f..8910d52002 100644 --- a/msm/dsi/dsi_drm.h +++ b/msm/dsi/dsi_drm.h @@ -162,4 +162,14 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector, int dsi_conn_set_dyn_bit_clk(struct drm_connector *connector, uint64_t value); +/** + * dsi_conn_set_submode_blob_info - populate given sub mode blob + * @connector: Pointer to drm connector structure + * @info: Pointer to sde connector info structure + * @display: Pointer to private display handle + * @drm_mode: Pointer to drm_display_mode structure + */ +void dsi_conn_set_submode_blob_info(struct drm_connector *conn, + void *info, void *display, struct drm_display_mode *drm_mode); + #endif /* _DSI_DRM_H_ */ diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 6a9e3f4ab8..5ce3c9da25 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -3025,6 +3025,11 @@ static int dsi_panel_parse_topology( goto parse_fail; } + if (priv_info->dsc_enabled) + topology[top_sel].comp_type = MSM_DISPLAY_COMPRESSION_DSC; + else if (priv_info->vdc_enabled) + topology[top_sel].comp_type = MSM_DISPLAY_COMPRESSION_VDC; + DSI_INFO("default topology: lm: %d comp_enc:%d intf: %d\n", topology[top_sel].num_lm, topology[top_sel].num_enc, diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 5d0d6130fb..d6cfa940e9 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2512,6 +2512,29 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn, conn->base.base.id, conn->encoder->base.id); } +const char *sde_conn_get_topology_name(struct drm_connector *conn, + struct msm_display_topology topology) +{ + struct sde_kms *sde_kms; + int topology_idx = 0; + + sde_kms = _sde_connector_get_kms(conn); + if (!sde_kms) { + SDE_ERROR("invalid kms\n"); + return NULL; + } + + topology_idx = (int)sde_rm_get_topology_name(&sde_kms->rm, + topology); + + if (topology_idx >= SDE_RM_TOPOLOGY_MAX) { + SDE_ERROR("invalid topology\n"); + return NULL; + } + + return e_topology_name[topology_idx].name; +} + int sde_connector_esd_status(struct drm_connector *conn) { struct sde_connector *sde_conn = NULL; @@ -2617,6 +2640,7 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn, struct sde_connector *c_conn = NULL; struct drm_display_mode *mode; struct msm_mode_info mode_info; + const char *topo_name = NULL; int rc = 0; sde_kms = _sde_connector_get_kms(conn); @@ -2632,8 +2656,6 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn, } list_for_each_entry(mode, &conn->modes, head) { - int topology_idx = 0; - u32 panel_mode_caps = 0; memset(&mode_info, 0, sizeof(mode_info)); @@ -2651,20 +2673,12 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn, sde_kms_info_add_keyint(info, "bit_clk_rate", mode_info.clk_rate); - if (mode_info.bit_clk_count > 0) - sde_kms_info_add_list(info, "dyn_bitclk_list", - mode_info.bit_clk_rates, - mode_info.bit_clk_count); - - - topology_idx = (int)sde_rm_get_topology_name(&sde_kms->rm, - mode_info.topology); - if (topology_idx < SDE_RM_TOPOLOGY_MAX) { - sde_kms_info_add_keystr(info, "topology", - e_topology_name[topology_idx].name); + if (c_conn->ops.set_submode_info) { + c_conn->ops.set_submode_info(conn, info, c_conn->display, mode); } else { - SDE_ERROR_CONN(c_conn, "invalid topology\n"); - continue; + topo_name = sde_conn_get_topology_name(conn, mode_info.topology); + if (topo_name) + sde_kms_info_add_keystr(info, "topology", topo_name); } sde_kms_info_add_keyint(info, "has_cwb_crop", sde_kms->catalog->has_cwb_crop); @@ -2677,14 +2691,6 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn, sde_kms_info_add_keyint(info, "allowed_mode_switch", mode_info.allowed_mode_switches); - if (mode_info.panel_mode_caps & DSI_OP_CMD_MODE) - panel_mode_caps |= DRM_MODE_FLAG_CMD_MODE_PANEL; - if (mode_info.panel_mode_caps & DSI_OP_VIDEO_MODE) - panel_mode_caps |= DRM_MODE_FLAG_VID_MODE_PANEL; - - sde_kms_info_add_keyint(info, "panel_mode_capabilities", - panel_mode_caps); - if (!mode_info.roi_caps.num_roi) continue; diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 50f1781f55..d98a11fb11 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -399,6 +399,16 @@ struct sde_connector_ops { * Returns: AVR step fps value on success */ int (*get_avr_step_req)(void *display, u32 mode_fps); + + /** + * set_submode_info - populate given sub mode blob + * @connector: Pointer to drm connector structure + * @info: Pointer to sde connector info structure + * @display: Pointer to private display handle + * @drm_mode: Pointer to drm_display_mode structure + */ + void (*set_submode_info)(struct drm_connector *conn, + void *info, void *display, struct drm_display_mode *drm_mode); }; /** @@ -1139,4 +1149,7 @@ int sde_connector_get_panel_vfp(struct drm_connector *connector, */ int sde_connector_esd_status(struct drm_connector *connector); +const char *sde_conn_get_topology_name(struct drm_connector *conn, + struct msm_display_topology topology); + #endif /* _SDE_CONNECTOR_H_ */ diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 5e2ddf02be..31fbf6c206 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1770,6 +1770,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .get_qsync_min_fps = dsi_display_get_qsync_min_fps, .get_avr_step_req = dsi_display_get_avr_step_req_fps, .prepare_commit = dsi_conn_prepare_commit, + .set_submode_info = dsi_conn_set_submode_blob_info, }; static const struct sde_connector_ops wb_ops = { .post_init = sde_wb_connector_post_init,