From ab3f86f91859a8b159b2b4e4e3fbf8ca6ddb140d Mon Sep 17 00:00:00 2001 From: Lei Chen Date: Tue, 22 Sep 2020 11:11:30 +0800 Subject: [PATCH] disp: msm: use connector properties to expose and set panel mode Expose panel mode from kernel to SDM with SDE connector property CONNECTOR_PROP_MODE_INFO and set panel mode from SDM to kernel with SDE connector property CONNECTOR_PROP_SET_PANEL_MODE for avoiding private change in upstream code in QGKI kernel. Change-Id: I0629dad9399967cc1118ac02ce30597076ca367d Signed-off-by: Lei Chen --- include/uapi/display/drm/sde_drm.h | 9 +++- msm/dp/dp_drm.c | 3 +- msm/dsi/dsi_defs.h | 25 +++++---- msm/dsi/dsi_display.c | 84 +++++++++++++++++------------- msm/dsi/dsi_drm.c | 83 ++++++++++++++--------------- msm/dsi/dsi_panel.c | 60 ++++++++------------- msm/msm_atomic.c | 15 +++--- msm/msm_drv.h | 11 ++-- msm/msm_kms.h | 66 ++++++++++++++++++++--- msm/sde/sde_connector.c | 30 +++++++++++ msm/sde/sde_connector.h | 2 + msm/sde/sde_encoder.c | 38 +++++--------- msm/sde/sde_encoder_dce.c | 15 ++++-- msm/sde/sde_hw_vdc.c | 4 +- msm/sde/sde_hw_vdc.h | 3 +- msm/sde/sde_rm.c | 4 +- 16 files changed, 267 insertions(+), 185 deletions(-) diff --git a/include/uapi/display/drm/sde_drm.h b/include/uapi/display/drm/sde_drm.h index 71169b5a02..2fbffc6950 100644 --- a/include/uapi/display/drm/sde_drm.h +++ b/include/uapi/display/drm/sde_drm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef _SDE_DRM_H_ @@ -692,6 +692,13 @@ struct drm_msm_display_hint { #define DRM_EVENT_LTM_WB_PB 0X80000009 #define DRM_EVENT_LTM_OFF 0X8000000A +#ifndef DRM_MODE_FLAG_VID_MODE_PANEL +#define DRM_MODE_FLAG_VID_MODE_PANEL 0x01 +#endif +#ifndef DRM_MODE_FLAG_CMD_MODE_PANEL +#define DRM_MODE_FLAG_CMD_MODE_PANEL 0x02 +#endif + /* display hint flags*/ #define DRM_MSM_DISPLAY_EARLY_WAKEUP_HINT 0x01 #define DRM_MSM_DISPLAY_POWER_COLLAPSE_HINT 0x02 diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index 0d26203b98..9dfa073235 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -457,6 +457,7 @@ int dp_connector_get_info(struct drm_connector *connector, info->num_of_h_tiles = 1; info->h_tile_instance[0] = 0; info->is_connected = display->is_sst_connected; + info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE; info->capabilities = MSM_DISPLAY_CAP_VID_MODE | MSM_DISPLAY_CAP_EDID | MSM_DISPLAY_CAP_HOT_PLUG; diff --git a/msm/dsi/dsi_defs.h b/msm/dsi/dsi_defs.h index 9f424781b7..1f2a6c5b5c 100644 --- a/msm/dsi/dsi_defs.h +++ b/msm/dsi/dsi_defs.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _DSI_DEFS_H_ @@ -59,9 +59,9 @@ enum dsi_pixel_format { * @DSI_OP_MODE_MAX: */ enum dsi_op_mode { - DSI_OP_VIDEO_MODE = 0, - DSI_OP_CMD_MODE, - DSI_OP_MODE_MAX + DSI_OP_VIDEO_MODE = BIT(0), + DSI_OP_CMD_MODE = BIT(1), + DSI_OP_MODE_MAX = BIT(2), }; /** @@ -72,10 +72,12 @@ enum dsi_op_mode { * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch * @DSI_MODE_FLAG_VRR: Seamless transition is DynamicFPS. * New timing values are sent from DAL. - * @DSI_MODE_FLAG_POMS: - * Seamless transition is dynamic panel operating mode switch * @DSI_MODE_FLAG_DYN_CLK: Seamless transition is dynamic clock change * @DSI_MODE_FLAG_DMS_FPS: Seamless fps only transition in Dynamic Mode Switch + * @DSI_MODE_FLAG_POMS_TO_VID: + * Seamless transition is dynamic panel operating mode switch to video + * @DSI_MODE_FLAG_POMS_TO_CMD: + * Seamless transition is dynamic panel operating mode switch to cmd */ enum dsi_mode_flags { DSI_MODE_FLAG_SEAMLESS = BIT(0), @@ -83,9 +85,10 @@ enum dsi_mode_flags { DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_DMS = BIT(3), DSI_MODE_FLAG_VRR = BIT(4), - DSI_MODE_FLAG_POMS = BIT(5), - DSI_MODE_FLAG_DYN_CLK = BIT(6), - DSI_MODE_FLAG_DMS_FPS = BIT(7), + DSI_MODE_FLAG_DYN_CLK = BIT(5), + DSI_MODE_FLAG_DMS_FPS = BIT(6), + DSI_MODE_FLAG_POMS_TO_VID = BIT(7), + DSI_MODE_FLAG_POMS_TO_CMD = BIT(8) }; /** @@ -629,7 +632,7 @@ struct dsi_display_mode_priv_info { * @timing: Timing parameters for the panel. * @pixel_clk_khz: Pixel clock in Khz. * @dsi_mode_flags: Flags to signal other drm components via private flags - * @panel_mode: Panel mode + * @panel_mode_caps: panel mode capabilities. * @is_preferred: Is mode preferred * @priv_info: Mode private info */ @@ -637,7 +640,7 @@ struct dsi_display_mode { struct dsi_mode_info timing; u32 pixel_clk_khz; u32 dsi_mode_flags; - enum dsi_op_mode panel_mode; + u32 panel_mode_caps; bool is_preferred; struct dsi_display_mode_priv_info *priv_info; }; diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 746c039974..7af9fdeead 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include @@ -5001,9 +5001,13 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, return -EINVAL; } - SDE_EVT32(mode->dsi_mode_flags, mode->panel_mode); + SDE_EVT32(mode->dsi_mode_flags, display->panel->panel_mode); + + if (mode->dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_VID) + display->panel->panel_mode = DSI_OP_VIDEO_MODE; + else if (mode->dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_CMD) + display->panel->panel_mode = DSI_OP_CMD_MODE; - display->panel->panel_mode = mode->panel_mode; rc = dsi_panel_get_host_cfg_for_mode(display->panel, mode, &display->config); @@ -6602,7 +6606,7 @@ void dsi_display_adjust_mode_timing(struct dsi_display *display, dyn_clk_caps = &(display->panel->dyn_clk_caps); /* Constant FPS is not supported on command mode */ - if (dsi_mode->panel_mode == DSI_OP_CMD_MODE) + if (!(dsi_mode->panel_mode_caps & DSI_OP_VIDEO_MODE)) return; if (!dyn_clk_caps->maintain_const_fps) @@ -6728,7 +6732,7 @@ static void _dsi_display_populate_bit_clks(struct dsi_display *display, dsi_display_adjust_mode_timing(display, dst, lanes, bpp); - + dst->panel_mode_caps = DSI_OP_VIDEO_MODE; dst->pixel_clk_khz = div_u64(dst->timing.clk_rate_hz * lanes, bpp); dst->pixel_clk_khz /= 1000; @@ -6750,7 +6754,7 @@ int dsi_display_get_modes(struct dsi_display *display, struct dsi_dfps_capabilities dfps_caps; struct dsi_display_ctrl *ctrl; struct dsi_host_common_cfg *host = &display->panel->host_config; - bool is_split_link, is_cmd_mode; + bool is_split_link, support_cmd_mode, support_video_mode; u32 num_dfps_rates, timing_mode_count, display_mode_count; u32 sublinks_count, mode_idx, array_idx = 0; struct dsi_dyn_clk_caps *dyn_clk_caps; @@ -6816,16 +6820,17 @@ int dsi_display_get_modes(struct dsi_display *display, goto error; } - is_cmd_mode = (display_mode.panel_mode == DSI_OP_CMD_MODE); + support_cmd_mode = display_mode.panel_mode_caps & DSI_OP_CMD_MODE; + support_video_mode = display_mode.panel_mode_caps & DSI_OP_VIDEO_MODE; /* Setup widebus support */ display_mode.priv_info->widebus_support = ctrl->ctrl->hw.widebus_support; num_dfps_rates = ((!dfps_caps.dfps_support || - is_cmd_mode) ? 1 : dfps_caps.dfps_list_len); + !support_video_mode) ? 1 : dfps_caps.dfps_list_len); /* Calculate dsi frame transfer time */ - if (is_cmd_mode) { + if (support_cmd_mode) { dsi_panel_calc_dsi_transfer_time( &display->panel->host_config, &display_mode, frame_threshold_us); @@ -6874,7 +6879,7 @@ int dsi_display_get_modes(struct dsi_display *display, memcpy(sub_mode, &display_mode, sizeof(display_mode)); array_idx++; - if (!dfps_caps.dfps_support || is_cmd_mode) + if (!dfps_caps.dfps_support || !support_video_mode) continue; curr_refresh_rate = sub_mode->timing.refresh_rate; @@ -6882,18 +6887,9 @@ int dsi_display_get_modes(struct dsi_display *display, dsi_display_get_dfps_timing(display, sub_mode, curr_refresh_rate); + sub_mode->panel_mode_caps = DSI_OP_VIDEO_MODE; } end = array_idx; - /* - * if POMS is enabled and boot up mode is video mode, - * skip bit clk rates update for command mode, - * else if dynamic clk switch is supported then update all - * the bit clk rates. - */ - - if (is_cmd_mode && - (display->panel->panel_mode == DSI_OP_VIDEO_MODE)) - continue; _dsi_display_populate_bit_clks(display, start, end, &array_idx); if (is_preferred) { @@ -7045,7 +7041,6 @@ int dsi_display_find_mode(struct dsi_display *display, if (cmp->timing.v_active == m->timing.v_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.refresh_rate == m->timing.refresh_rate && - cmp->panel_mode == m->panel_mode && cmp->pixel_clk_khz == m->pixel_clk_khz) { *out_mode = m; rc = 0; @@ -7098,8 +7093,9 @@ int dsi_display_validate_mode_change(struct dsi_display *display, int rc = 0; struct dsi_dfps_capabilities dfps_caps; struct dsi_dyn_clk_caps *dyn_clk_caps; + struct sde_connector *sde_conn; - if (!display || !adj_mode) { + if (!display || !adj_mode || !display->drm_conn) { DSI_ERR("Invalid params\n"); return -EINVAL; } @@ -7109,11 +7105,26 @@ int dsi_display_validate_mode_change(struct dsi_display *display, return rc; } + if ((cur_mode->timing.v_active != adj_mode->timing.v_active) || + (cur_mode->timing.h_active != adj_mode->timing.h_active)) { + DSI_DEBUG("Avoid VRR and POMS when resolution is changed\n"); + return rc; + } + + sde_conn = to_sde_connector(display->drm_conn); + mutex_lock(&display->display_lock); - dyn_clk_caps = &(display->panel->dyn_clk_caps); - if ((cur_mode->timing.v_active == adj_mode->timing.v_active) && - (cur_mode->timing.h_active == adj_mode->timing.h_active) && - (cur_mode->panel_mode == adj_mode->panel_mode)) { + + if (sde_conn->expected_panel_mode == MSM_DISPLAY_VIDEO_MODE && + display->config.panel_mode == DSI_OP_CMD_MODE) { + adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_VID; + DSI_DEBUG("Panel operating mode change to video detected\n"); + } else if (sde_conn->expected_panel_mode == MSM_DISPLAY_CMD_MODE && + display->config.panel_mode == DSI_OP_VIDEO_MODE) { + adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_CMD; + DSI_DEBUG("Panel operating mode change to command detected\n"); + } else { + dyn_clk_caps = &(display->panel->dyn_clk_caps); /* dfps and dynamic clock with const fps use case */ if (dsi_display_mode_switch_dfps(cur_mode, adj_mode)) { dsi_panel_get_dfps_caps(display->panel, &dfps_caps); @@ -7679,7 +7690,7 @@ int dsi_display_prepare(struct dsi_display *display) } } - if (!(mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) && + if (!display->poms_pending && (!is_skip_op_required(display))) { /* * For continuous splash/trusted vm, we skip panel @@ -7772,7 +7783,7 @@ int dsi_display_prepare(struct dsi_display *display) goto error_ctrl_link_off; } - if (!(mode->dsi_mode_flags & DSI_MODE_FLAG_POMS)) { + if (!display->poms_pending) { rc = dsi_panel_prepare(display->panel); if (rc) { DSI_ERR("[%s] panel prepare failed, rc=%d\n", @@ -8123,8 +8134,7 @@ int dsi_display_enable(struct dsi_display *display) display->name, rc); goto error; } - } else if (!(display->panel->cur_mode->dsi_mode_flags & - DSI_MODE_FLAG_POMS)){ + } else if (!display->poms_pending) { rc = dsi_panel_enable(display->panel); if (rc) { DSI_ERR("[%s] failed to enable DSI panel, rc=%d\n", @@ -8197,13 +8207,13 @@ int dsi_display_post_enable(struct dsi_display *display) mutex_lock(&display->display_lock); - if (display->panel->cur_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) { - if (display->config.panel_mode == DSI_OP_CMD_MODE) - dsi_panel_mode_switch_to_cmd(display->panel); - - if (display->config.panel_mode == DSI_OP_VIDEO_MODE) - dsi_panel_mode_switch_to_vid(display->panel); - } else { + if (display->panel->cur_mode->dsi_mode_flags & + DSI_MODE_FLAG_POMS_TO_CMD) { + dsi_panel_mode_switch_to_cmd(display->panel); + } else if (display->panel->cur_mode->dsi_mode_flags & + DSI_MODE_FLAG_POMS_TO_VID) + dsi_panel_mode_switch_to_vid(display->panel); + else { rc = dsi_panel_post_enable(display->panel); if (rc) DSI_ERR("[%s] panel post-enable failed, rc=%d\n", diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 6f49918db9..45136bc5c8 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -59,11 +59,6 @@ static void convert_to_dsi_mode(const struct drm_display_mode *drm_mode, !!(drm_mode->flags & DRM_MODE_FLAG_PHSYNC); dsi_mode->timing.v_sync_polarity = !!(drm_mode->flags & DRM_MODE_FLAG_PVSYNC); - - if (drm_mode->flags & DRM_MODE_FLAG_VID_MODE_PANEL) - dsi_mode->panel_mode = DSI_OP_VIDEO_MODE; - if (drm_mode->flags & DRM_MODE_FLAG_CMD_MODE_PANEL) - dsi_mode->panel_mode = DSI_OP_CMD_MODE; } static void msm_parse_mode_priv_info(const struct msm_display_mode *msm_mode, @@ -90,8 +85,10 @@ static void msm_parse_mode_priv_info(const struct msm_display_mode *msm_mode, dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS; if (msm_is_mode_seamless_vrr(msm_mode)) dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR; - if (msm_is_mode_seamless_poms(msm_mode)) - dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS; + if (msm_is_mode_seamless_poms_to_vid(msm_mode)) + dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_VID; + if (msm_is_mode_seamless_poms_to_cmd(msm_mode)) + dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_CMD; if (msm_is_mode_seamless_dyn_clk(msm_mode)) dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DYN_CLK; } @@ -99,7 +96,15 @@ static void msm_parse_mode_priv_info(const struct msm_display_mode *msm_mode, void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, struct drm_display_mode *drm_mode) { - bool video_mode = (dsi_mode->panel_mode == DSI_OP_VIDEO_MODE); + char *panel_caps = "vid"; + + if ((dsi_mode->panel_mode_caps & DSI_OP_VIDEO_MODE) && + (dsi_mode->panel_mode_caps & DSI_OP_CMD_MODE)) + panel_caps = "vid_cmd"; + else if (dsi_mode->panel_mode_caps & DSI_OP_VIDEO_MODE) + panel_caps = "vid"; + else if (dsi_mode->panel_mode_caps & DSI_OP_CMD_MODE) + panel_caps = "cmd"; memset(drm_mode, 0, sizeof(*drm_mode)); @@ -126,16 +131,11 @@ void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, if (dsi_mode->timing.v_sync_polarity) drm_mode->flags |= DRM_MODE_FLAG_PVSYNC; - if (dsi_mode->panel_mode == DSI_OP_VIDEO_MODE) - drm_mode->flags |= DRM_MODE_FLAG_VID_MODE_PANEL; - if (dsi_mode->panel_mode == DSI_OP_CMD_MODE) - drm_mode->flags |= DRM_MODE_FLAG_CMD_MODE_PANEL; - /* set mode name */ snprintf(drm_mode->name, DRM_DISPLAY_MODE_LEN, "%dx%dx%dx%d%s", drm_mode->hdisplay, drm_mode->vdisplay, drm_mode->vrefresh, drm_mode->clock, - video_mode ? "vid" : "cmd"); + panel_caps); } static void dsi_convert_to_msm_mode(const struct dsi_display_mode *dsi_mode, @@ -154,8 +154,10 @@ static void dsi_convert_to_msm_mode(const struct dsi_display_mode *dsi_mode, msm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DMS; if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_VRR) msm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_VRR; - if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) - msm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_POMS; + if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_VID) + msm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_POMS_VID; + if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_CMD) + msm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_POMS_CMD; if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_DYN_CLK) msm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DYN_CLK; } @@ -263,9 +265,11 @@ static void dsi_bridge_enable(struct drm_bridge *bridge) if (display && display->drm_conn) { sde_connector_helper_bridge_enable(display->drm_conn); - if (c_bridge->dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS) + if (display->poms_pending) { + display->poms_pending = false; sde_connector_schedule_status_work(display->drm_conn, true); + } } } @@ -429,6 +433,7 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, /* propagate the private info to the adjusted_mode derived dsi mode */ dsi_mode.priv_info = panel_dsi_mode->priv_info; dsi_mode.dsi_mode_flags = panel_dsi_mode->dsi_mode_flags; + dsi_mode.panel_mode_caps = panel_dsi_mode->panel_mode_caps; dsi_mode.timing.dsc_enabled = dsi_mode.priv_info->dsc_enabled; dsi_mode.timing.dsc = &dsi_mode.priv_info->dsc; @@ -455,25 +460,12 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, return false; } - /* No panel mode switch when drm pipeline is changing */ - if ((dsi_mode.panel_mode != cur_dsi_mode.panel_mode) && - (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR)) && - (crtc_state->enable == - crtc_state->crtc->state->enable)) { - dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_POMS; - - SDE_EVT32(SDE_EVTLOG_FUNC_CASE1, - dsi_mode.timing.h_active, - dsi_mode.timing.v_active, - dsi_mode.timing.refresh_rate, - dsi_mode.pixel_clk_khz, - dsi_mode.panel_mode); - } /* No DMS/VRR when drm pipeline is changing */ if (!drm_mode_equal(cur_mode, adjusted_mode) && (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR)) && - (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS)) && (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_DYN_CLK)) && + (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_VID)) && + (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_CMD)) && (!crtc_state->active_changed || display->is_cont_splash_enabled)) { dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; @@ -483,15 +475,16 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, dsi_mode.timing.v_active, dsi_mode.timing.refresh_rate, dsi_mode.pixel_clk_khz, - dsi_mode.panel_mode); + dsi_mode.panel_mode_caps); } } /* Reject seamless transition when active changed */ if (crtc_state->active_changed && - ((dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) || - (dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS) || - (dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_DYN_CLK))) { + ((dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) || + (dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_DYN_CLK) || + (dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_VID) || + (dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS_TO_CMD))) { DSI_INFO("seamless upon active changed 0x%x %d\n", dsi_mode.dsi_mode_flags, crtc_state->active_changed); return false; @@ -579,6 +572,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector, mode_info->jitter_denom = dsi_mode->priv_info->panel_jitter_denom; mode_info->dfps_maxfps = dsi_drm_get_dfps_maxfps(display); mode_info->clk_rate = dsi_drm_find_bit_clk_rate(display, drm_mode); + mode_info->panel_mode_caps = dsi_mode->panel_mode_caps; mode_info->mdp_transfer_time_us = dsi_mode->priv_info->mdp_transfer_time_us; @@ -1210,6 +1204,7 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector, void *display) { u32 mode_idx = 0, cmp_mode_idx = 0; + u32 common_mode_caps = 0; struct drm_display_mode *drm_mode, *cmp_drm_mode; struct dsi_display_mode dsi_mode, *panel_dsi_mode, *cmp_panel_dsi_mode; struct list_head *mode_list = &connector->modes; @@ -1255,6 +1250,8 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector, cmp_dsi_mode_info = cmp_panel_dsi_mode->priv_info; allow_switch = false; + common_mode_caps = (panel_dsi_mode->panel_mode_caps & + cmp_panel_dsi_mode->panel_mode_caps); /* * FPS switch among video modes, is only supported @@ -1262,14 +1259,12 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector, * Reject any mode switches between video mode timing * nodes if support for those features is not present. */ - if (panel_dsi_mode->panel_mode == - cmp_panel_dsi_mode->panel_mode) { - if (panel_dsi_mode->panel_mode == - DSI_OP_CMD_MODE) - allow_switch = true; - else if (panel->dfps_caps.dfps_support || - panel->dyn_clk_caps.dyn_clk_support) - allow_switch = true; + if (common_mode_caps & DSI_OP_CMD_MODE) { + allow_switch = true; + } else if ((common_mode_caps & DSI_OP_VIDEO_MODE) && + (panel->dfps_caps.dfps_support || + panel->dyn_clk_caps.dyn_clk_support)) { + allow_switch = true; } else { if (is_valid_poms_switch(panel_dsi_mode, cmp_panel_dsi_mode)) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 1c02f98de2..057dafcf71 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include @@ -2481,7 +2481,7 @@ static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode, priv_info->phy_timing_len = len; } - if (mode->panel_mode == DSI_OP_VIDEO_MODE) { + if (mode->panel_mode_caps & DSI_OP_VIDEO_MODE) { /* * For command mode we update the pclk as part of * function dsi_panel_calc_dsi_transfer_time( ) @@ -2677,7 +2677,7 @@ error: } static int dsi_panel_parse_vdc_params(struct dsi_display_mode *mode, - struct dsi_parser_utils *utils, int traffic_mode, int panel_mode) + struct dsi_parser_utils *utils, int traffic_mode) { u32 data; int rc = -EINVAL; @@ -2701,7 +2701,6 @@ static int dsi_panel_parse_vdc_params(struct dsi_display_mode *mode, return 0; } - priv_info->vdc.panel_mode = panel_mode; priv_info->vdc.traffic_mode = traffic_mode; rc = utils->read_u32(utils->data, "qcom,vdc-version", &data); @@ -3090,33 +3089,26 @@ static int dsi_panel_parse_partial_update_caps(struct dsi_display_mode *mode, return rc; } -static int dsi_panel_parse_panel_mode_caps(struct dsi_display_mode *mode, +static bool dsi_panel_parse_panel_mode_caps(struct dsi_display_mode *mode, struct dsi_parser_utils *utils) { - bool vid_mode_support, cmd_mode_support; - if (!mode || !mode->priv_info) { DSI_ERR("invalid arguments\n"); - return -EINVAL; + return false; } - vid_mode_support = utils->read_bool(utils->data, - "qcom,mdss-dsi-video-mode"); + if (utils->read_bool(utils->data, "qcom,mdss-dsi-video-mode")) + mode->panel_mode_caps |= DSI_OP_VIDEO_MODE; - cmd_mode_support = utils->read_bool(utils->data, - "qcom,mdss-dsi-cmd-mode"); + if (utils->read_bool(utils->data, "qcom,mdss-dsi-cmd-mode")) + mode->panel_mode_caps |= DSI_OP_CMD_MODE; - if (cmd_mode_support) - mode->panel_mode = DSI_OP_CMD_MODE; - else if (vid_mode_support) - mode->panel_mode = DSI_OP_VIDEO_MODE; - else - return -EINVAL; + if (!mode->panel_mode_caps) + return false; - return 0; + return true; }; - static int dsi_panel_parse_dms_info(struct dsi_panel *panel) { int dms_enabled; @@ -3980,7 +3972,6 @@ int dsi_panel_get_mode(struct dsi_panel *panel, u32 child_idx = 0; int rc = 0, num_timings; int traffic_mode; - int panel_mode; void *utils_data = NULL; if (!panel || !mode) { @@ -4016,7 +4007,6 @@ int dsi_panel_get_mode(struct dsi_panel *panel, utils_data = utils->data; traffic_mode = panel->video_config.traffic_mode; - panel_mode = panel->panel_mode; dsi_for_each_child_node(timings_np, child_np) { if (index != child_idx++) @@ -4024,6 +4014,16 @@ int dsi_panel_get_mode(struct dsi_panel *panel, utils->data = child_np; + if (panel->panel_mode_switch_enabled) { + if (!dsi_panel_parse_panel_mode_caps(mode, utils)) { + mode->panel_mode_caps = panel->panel_mode; + DSI_INFO("panel mode isn't specified in timing[%d]\n", + child_idx); + } + } else { + mode->panel_mode_caps = panel->panel_mode; + } + rc = dsi_panel_parse_timing(&mode->timing, utils); if (rc) { DSI_ERR("failed to parse panel timing, rc=%d\n", rc); @@ -4036,8 +4036,7 @@ int dsi_panel_get_mode(struct dsi_panel *panel, goto parse_fail; } - rc = dsi_panel_parse_vdc_params(mode, utils, traffic_mode, - panel_mode); + rc = dsi_panel_parse_vdc_params(mode, utils, traffic_mode); if (rc) { DSI_ERR("failed to parse vdc params, rc=%d\n", rc); goto parse_fail; @@ -4071,19 +4070,6 @@ int dsi_panel_get_mode(struct dsi_panel *panel, rc = dsi_panel_parse_partial_update_caps(mode, utils); if (rc) DSI_ERR("failed to partial update caps, rc=%d\n", rc); - - if (panel->panel_mode_switch_enabled) { - rc = dsi_panel_parse_panel_mode_caps(mode, utils); - if (rc) { - rc = 0; - mode->panel_mode = panel->panel_mode; - DSI_INFO( - "POMS: panel mode isn't specified in timing[%d]\n", - child_idx); - } - } else { - mode->panel_mode = panel->panel_mode; - } } goto done; diff --git a/msm/msm_atomic.c b/msm/msm_atomic.c index 790bf0f55f..ed959ee71f 100644 --- a/msm/msm_atomic.c +++ b/msm/msm_atomic.c @@ -180,7 +180,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) old_conn_state->crtc); if (!old_crtc_state->active || - !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state)) + !msm_atomic_needs_modeset(old_conn_state->crtc->state)) continue; encoder = old_conn_state->best_encoder; @@ -221,7 +221,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) const struct drm_crtc_helper_funcs *funcs; /* Shut down everything that needs a full modeset. */ - if (!drm_atomic_crtc_needs_modeset(crtc->state)) + if (!msm_atomic_needs_modeset(crtc->state)) continue; if (!old_crtc_state->active) @@ -294,7 +294,8 @@ msm_crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) old_conn_state, false)) continue; } else if (!new_crtc_state->mode_changed) { - continue; + if (!msm_is_private_mode_changed(old_conn_state->crtc->state)) + continue; } DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n", @@ -372,7 +373,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct msm_display_mode *msm_mode; /* Need to filter out CRTCs where only planes change. */ - if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) + if (!msm_atomic_needs_modeset(new_crtc_state)) continue; if (!new_crtc_state->active) @@ -416,8 +417,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, continue; if (!new_conn_state->crtc->state->active || - !drm_atomic_crtc_needs_modeset( - new_conn_state->crtc->state)) + !msm_atomic_needs_modeset(new_conn_state->crtc->state)) continue; old_conn_state = drm_atomic_get_old_connector_state( @@ -466,8 +466,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, continue; if (!new_conn_state->crtc->state->active || - !drm_atomic_crtc_needs_modeset( - new_conn_state->crtc->state)) + !msm_atomic_needs_modeset(new_conn_state->crtc->state)) continue; old_conn_state = drm_atomic_get_old_connector_state( diff --git a/msm/msm_drv.h b/msm/msm_drv.h index f3ceffa725..c49ea31a58 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -214,6 +214,7 @@ enum msm_mdp_conn_property { CONNECTOR_PROP_FB_TRANSLATION_MODE, CONNECTOR_PROP_QSYNC_MODE, CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE, + CONNECTOR_PROP_SET_PANEL_MODE, /* total # of properties */ CONNECTOR_PROP_COUNT @@ -290,9 +291,9 @@ enum msm_display_caps { * @MODE_MAX: */ enum panel_op_mode { - MSM_DISPLAY_VIDEO_MODE = 0, - MSM_DISPLAY_CMD_MODE, - MSM_DISPLAY_MODE_MAX, + MSM_DISPLAY_VIDEO_MODE = BIT(0), + MSM_DISPLAY_CMD_MODE = BIT(1), + MSM_DISPLAY_MODE_MAX = BIT(2) }; /** @@ -429,7 +430,6 @@ struct msm_display_dsc_info { * @flatqp_sw_nbls: flatness qp somewhat flat NBLs * @chroma_samples: number of chroma samples * @split_panel_enable: indicates whether split panel is enabled - * @panel_mode: indicates panel is in video or cmd mode * @traffic_mode: indicates burst/non-burst mode * @flatness_qp_lut: LUT used to determine flatness QP * @max_qp_lut: LUT used to determine maximum QP @@ -539,7 +539,6 @@ struct msm_display_vdc_info { u8 flatqp_sw_nbls; u8 chroma_samples; u8 split_panel_enable; - u8 panel_mode; u8 traffic_mode; u16 flatness_qp_lut[8]; @@ -693,6 +692,7 @@ struct msm_display_topology { * @comp_info: compression info supported * @roi_caps: panel roi capabilities * @wide_bus_en: wide-bus mode cfg for interface module + * @panel_mode_caps panel mode capabilities * @mdp_transfer_time_us Specifies the mdp transfer time for command mode * panels in microseconds. * @allowed_mode_switches: bit mask to indicate supported mode switch. @@ -709,6 +709,7 @@ struct msm_mode_info { struct msm_compression_info comp_info; struct msm_roi_caps roi_caps; bool wide_bus_en; + u32 panel_mode_caps; u32 mdp_transfer_time_us; u32 allowed_mode_switches; }; diff --git a/msm/msm_kms.h b/msm/msm_kms.h index e7266ab153..00e04a649b 100644 --- a/msm/msm_kms.h +++ b/msm/msm_kms.h @@ -38,12 +38,14 @@ #define MSM_MODE_FLAG_SEAMLESS_DMS (1<<2) /* Request to switch the fps */ #define MSM_MODE_FLAG_SEAMLESS_VRR (1<<3) -/* Request to switch the panel mode */ -#define MSM_MODE_FLAG_SEAMLESS_POMS (1<<4) /* Request to switch the bit clk */ -#define MSM_MODE_FLAG_SEAMLESS_DYN_CLK (1<<5) +#define MSM_MODE_FLAG_SEAMLESS_DYN_CLK (1<<4) /* Request to make the seamless switch */ -#define DRM_MODE_FLAG_SEAMLESS (1<<6) +#define DRM_MODE_FLAG_SEAMLESS (1<<5) +/* Request to switch the panel mode to video */ +#define MSM_MODE_FLAG_SEAMLESS_POMS_VID (1<<6) +/* Request to switch the panel mode to command */ +#define MSM_MODE_FLAG_SEAMLESS_POMS_CMD (1<<7) /* As there are different display controller blocks depending on the * snapdragon version, the kms support is split out and the appropriate @@ -231,13 +233,27 @@ static inline bool msm_is_mode_seamless_vrr(const struct msm_display_mode *mode) : false; } -static inline bool msm_is_mode_seamless_poms( +static inline bool msm_is_mode_seamless_poms_to_vid( const struct msm_display_mode *mode) { - return mode ? (mode->private_flags & MSM_MODE_FLAG_SEAMLESS_POMS) + return mode ? (mode->private_flags & MSM_MODE_FLAG_SEAMLESS_POMS_VID) : false; } +static inline bool msm_is_mode_seamless_poms_to_cmd( + const struct msm_display_mode *mode) +{ + return mode ? (mode->private_flags & MSM_MODE_FLAG_SEAMLESS_POMS_CMD) + : false; +} + +static inline bool msm_is_mode_seamless_poms( + const struct msm_display_mode *mode) +{ + return (msm_is_mode_seamless_poms_to_vid(mode) || + msm_is_mode_seamless_poms_to_cmd(mode)); +} + static inline bool msm_is_mode_seamless_dyn_clk( const struct msm_display_mode *mode) { @@ -250,4 +266,42 @@ static inline bool msm_needs_vblank_pre_modeset( { return (mode->private_flags & MSM_MODE_FLAG_VBLANK_PRE_MODESET); } + +static inline bool msm_is_private_mode_changed( + struct drm_crtc_state *state) +{ + struct msm_display_mode *msm_mode = NULL; + struct msm_drm_private *priv = NULL; + struct msm_kms *kms; + + if (!state || !state->crtc) + return false; + + priv = state->crtc->dev->dev_private; + if (!priv) + return false; + + kms = priv->kms; + if (!kms || !kms->funcs->get_msm_mode) + return false; + + msm_mode = kms->funcs->get_msm_mode(state); + if (!msm_mode) + return false; + + if (msm_is_mode_seamless_poms(msm_mode)) + return true; + + return false; +} + +static inline bool msm_atomic_needs_modeset(struct drm_crtc_state *state) +{ + if (drm_atomic_crtc_needs_modeset(state)) + return true; + + if (msm_is_private_mode_changed(state)) + return true; + return false; +} #endif /* __MSM_KMS_H__ */ diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 817cadb26a..341780758b 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -71,6 +71,11 @@ static const struct drm_prop_enum_list e_frame_trigger_mode[] = { {FRAME_DONE_WAIT_SERIALIZE, "serialize_frame_trigger"}, {FRAME_DONE_WAIT_POSTED_START, "posted_start"}, }; +static const struct drm_prop_enum_list e_panel_mode[] = { + {MSM_DISPLAY_VIDEO_MODE, "video_mode"}, + {MSM_DISPLAY_CMD_MODE, "command_mode"}, + {MSM_DISPLAY_MODE_MAX, "none"}, +}; static inline struct sde_kms *_sde_connector_get_kms(struct drm_connector *conn) { @@ -1553,6 +1558,14 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, msm_property_set_dirty(&c_conn->property_info, &c_state->property_state, idx); break; + case CONNECTOR_PROP_SET_PANEL_MODE: + if (val == DRM_MODE_FLAG_VID_MODE_PANEL) + c_conn->expected_panel_mode = + MSM_DISPLAY_VIDEO_MODE; + else if (val == DRM_MODE_FLAG_CMD_MODE_PANEL) + c_conn->expected_panel_mode = + MSM_DISPLAY_CMD_MODE; + break; default: break; } @@ -2554,6 +2567,7 @@ 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)); @@ -2587,6 +2601,14 @@ 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; @@ -2792,6 +2814,14 @@ static int _sde_connector_install_properties(struct drm_device *dev, ARRAY_SIZE(e_frame_trigger_mode), 0, CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE); + if (display_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE && + display_info->capabilities & MSM_DISPLAY_CAP_VID_MODE) + msm_property_install_enum(&c_conn->property_info, + "panel_mode", 0, 0, + e_panel_mode, + ARRAY_SIZE(e_panel_mode), 0, + CONNECTOR_PROP_SET_PANEL_MODE); + if (sde_kms->catalog->has_demura) { msm_property_install_blob(&c_conn->property_info, "DEMURA_PANEL_ID", DRM_MODE_PROP_IMMUTABLE, diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index f322848057..3782f1ccd3 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -459,6 +459,7 @@ struct sde_connector_dyn_hdr_metadata { * @thermal_max_brightness: thermal max brightness cap * @status_work: work object to perform status checks * @esd_status_interval: variable to change ESD check interval in millisec + * @expected_panel_mode: expected panel mode by usespace * @panel_dead: Flag to indicate if panel has gone bad * @esd_status_check: Flag to indicate if ESD thread is scheduled or not * @bl_scale_dirty: Flag to indicate PP BL scale value(s) is changed @@ -523,6 +524,7 @@ struct sde_connector { u32 esd_status_interval; bool panel_dead; bool esd_status_check; + enum panel_op_mode expected_panel_mode; bool bl_scale_dirty; u32 bl_scale; diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 907c6bb4c1..757197f19b 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -867,7 +867,7 @@ static int _sde_encoder_atomic_check_reserve(struct drm_encoder *drm_enc, int ret = 0; struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode; - if (sde_conn && drm_atomic_crtc_needs_modeset(crtc_state)) { + if (sde_conn && msm_atomic_needs_modeset(crtc_state)) { struct msm_display_topology *topology = NULL; ret = sde_connector_get_mode_info(&sde_conn->base, @@ -2102,30 +2102,30 @@ static void sde_encoder_virt_mode_switch(struct drm_encoder *drm_enc, { int i = 0; struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); + bool poms_to_vid = msm_is_mode_seamless_poms_to_vid(adj_mode); + bool poms_to_cmd = msm_is_mode_seamless_poms_to_cmd(adj_mode); - if (intf_mode == INTF_MODE_CMD) + if (poms_to_vid) sde_enc->disp_info.curr_panel_mode = MSM_DISPLAY_VIDEO_MODE; - else if (intf_mode == INTF_MODE_VIDEO) + else if (poms_to_cmd) sde_enc->disp_info.curr_panel_mode = MSM_DISPLAY_CMD_MODE; _sde_encoder_update_rsc_client(drm_enc, true); - if (intf_mode == INTF_MODE_CMD) { + if (intf_mode == INTF_MODE_CMD && poms_to_vid) { for (i = 0; i < sde_enc->num_phys_encs; i++) sde_enc->phys_encs[i] = sde_enc->phys_vid_encs[i]; SDE_DEBUG_ENC(sde_enc, "switch to video physical encoder\n"); - SDE_EVT32(DRMID(&sde_enc->base), intf_mode, - adj_mode->base->flags, adj_mode->private_flags, - SDE_EVTLOG_FUNC_CASE1); - } else if (intf_mode == INTF_MODE_VIDEO) { + SDE_EVT32(DRMID(&sde_enc->base), intf_mode, poms_to_cmd, poms_to_vid, + SDE_EVTLOG_FUNC_CASE1); + } else if (intf_mode == INTF_MODE_VIDEO && poms_to_cmd) { for (i = 0; i < sde_enc->num_phys_encs; i++) sde_enc->phys_encs[i] = sde_enc->phys_cmd_encs[i]; SDE_DEBUG_ENC(sde_enc, "switch to command physical encoder\n"); - SDE_EVT32(DRMID(&sde_enc->base), intf_mode, - adj_mode->base->flags, adj_mode->private_flags, - SDE_EVTLOG_FUNC_CASE2); + SDE_EVT32(DRMID(&sde_enc->base), intf_mode, poms_to_cmd, poms_to_vid, + SDE_EVTLOG_FUNC_CASE2); } } @@ -2218,19 +2218,6 @@ static void _sde_encoder_virt_populate_hw_res(struct drm_encoder *drm_enc) } } -static bool sde_encoder_detect_panel_mode_switch( - struct drm_display_mode *adj_mode, enum sde_intf_mode intf_mode) -{ - /* don't rely on POMS flag as it may not be set for power-on modeset */ - if ((intf_mode == INTF_MODE_CMD && - adj_mode->flags & DRM_MODE_FLAG_VID_MODE_PANEL) || - (intf_mode == INTF_MODE_VIDEO && - adj_mode->flags & DRM_MODE_FLAG_CMD_MODE_PANEL)) - return true; - - return false; -} - static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc, struct msm_display_mode *msm_mode, bool pre_modeset) { @@ -2262,8 +2249,7 @@ static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc, * modeset to guarantee previous kickoff has finished. */ sde_encoder_dce_disable(sde_enc); - } else if (sde_encoder_detect_panel_mode_switch(msm_mode->base, - intf_mode)) { + } else if (msm_is_mode_seamless_poms(msm_mode)) { _sde_encoder_modeset_helper_locked(drm_enc, SDE_ENC_RC_EVENT_PRE_MODESET); sde_encoder_virt_mode_switch(drm_enc, intf_mode, diff --git a/msm/sde/sde_encoder_dce.c b/msm/sde/sde_encoder_dce.c index 07bf4f6f6f..0dede299a2 100644 --- a/msm/sde/sde_encoder_dce.c +++ b/msm/sde/sde_encoder_dce.c @@ -259,7 +259,8 @@ static void _dce_vdc_pipe_cfg(struct sde_hw_vdc *hw_vdc, struct sde_hw_pingpong *hw_pp, struct msm_display_vdc_info *vdc, enum sde_3d_blend_mode mode_3d, - bool disable_merge_3d, bool enable) + bool disable_merge_3d, bool enable, + bool is_video_mode) { if (!vdc || !hw_vdc || !hw_pp) { @@ -282,7 +283,7 @@ static void _dce_vdc_pipe_cfg(struct sde_hw_vdc *hw_vdc, } if (hw_vdc->ops.vdc_config) - hw_vdc->ops.vdc_config(hw_vdc, vdc); + hw_vdc->ops.vdc_config(hw_vdc, vdc, is_video_mode); if (mode_3d && disable_merge_3d && hw_pp->ops.reset_3d_mode) { SDE_DEBUG("disabling 3d mux\n"); @@ -553,6 +554,7 @@ static int _dce_vdc_setup(struct sde_encoder_virt *sde_enc, int intf_ip_w, enc_ip_w; const struct sde_rm_topology_def *def; int num_intf, num_vdc, num_lm; + bool is_video_mode = false; int i; int ret = 0; @@ -625,6 +627,8 @@ static int _dce_vdc_setup(struct sde_encoder_virt *sde_enc, SDE_DEBUG_DCE(sde_enc, "pic_w: %d pic_h: %d\n", roi->w, roi->h); + is_video_mode = sde_encoder_check_curr_mode(&sde_enc->base, MSM_DISPLAY_VIDEO_MODE); + for (i = 0; i < num_vdc; i++) { bool active = !!((1 << i) & params->affected_displays); @@ -649,7 +653,8 @@ static int _dce_vdc_setup(struct sde_encoder_virt *sde_enc, } _dce_vdc_pipe_cfg(hw_vdc[i], hw_pp[i], - vdc, mode_3d, disable_merge_3d, active); + vdc, mode_3d, disable_merge_3d, + active, is_video_mode); memset(&cfg, 0, sizeof(cfg)); cfg.vdc[cfg.vdc_count++] = hw_vdc[i]->idx; @@ -763,6 +768,7 @@ static void _dce_vdc_disable(struct sde_encoder_virt *sde_enc) struct sde_hw_vdc *hw_vdc = NULL; struct sde_hw_ctl *hw_ctl = NULL; struct sde_hw_intf_cfg_v1 cfg; + bool is_video_mode = false; if (!sde_enc || !sde_enc->phys_encs[0] || !sde_enc->phys_encs[0]->connector) { @@ -776,6 +782,7 @@ static void _dce_vdc_disable(struct sde_encoder_virt *sde_enc) memset(&cfg, 0, sizeof(cfg)); + is_video_mode = sde_encoder_check_curr_mode(&sde_enc->base, MSM_DISPLAY_VIDEO_MODE); /* Disable VDC for all the pp's present in this topology */ for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp = sde_enc->hw_pp[i]; @@ -783,7 +790,7 @@ static void _dce_vdc_disable(struct sde_encoder_virt *sde_enc) _dce_vdc_pipe_cfg(hw_vdc, hw_pp, NULL, BLEND_3D_NONE, false, - false); + false, is_video_mode); if (hw_vdc) { sde_enc->dirty_vdc_ids[i] = hw_vdc->idx; diff --git a/msm/sde/sde_hw_vdc.c b/msm/sde/sde_hw_vdc.c index f806d334bc..724aa13eee 100644 --- a/msm/sde/sde_hw_vdc.c +++ b/msm/sde/sde_hw_vdc.c @@ -108,7 +108,7 @@ static void sde_hw_vdc_disable(struct sde_hw_vdc *hw_vdc) } static void sde_hw_vdc_config(struct sde_hw_vdc *hw_vdc, - struct msm_display_vdc_info *vdc) + struct msm_display_vdc_info *vdc, bool is_video_mode) { struct sde_hw_blk_reg_map *vdc_reg = &hw_vdc->hw; u32 idx; @@ -136,7 +136,7 @@ static void sde_hw_vdc_config(struct sde_hw_vdc *hw_vdc, SDE_REG_WRITE(vdc_reg, ENC_ORIG_SLICE + idx, data); data = 0; - if (vdc->panel_mode == VDC_VIDEO_MODE) + if (is_video_mode) data |= BIT(9); data |= ((vdc->num_of_active_ss - 1) << 12); data |= vdc->initial_lines; diff --git a/msm/sde/sde_hw_vdc.h b/msm/sde/sde_hw_vdc.h index 10ee9541e1..1744eadbb1 100644 --- a/msm/sde/sde_hw_vdc.h +++ b/msm/sde/sde_hw_vdc.h @@ -29,9 +29,10 @@ struct sde_hw_vdc_ops { * vdc_config - configures vdc encoder * @hw_vdc: Pointer to vdc context * @vdc: panel vdc parameters + * @is_video_mode: current panel mode is video */ void (*vdc_config)(struct sde_hw_vdc *hw_vdc, - struct msm_display_vdc_info *vdc); + struct msm_display_vdc_info *vdc, bool is_video_mode); /** * bind_pingpong_blk - enable/disable the connection with pp diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index fd25b861db..36e48dcb65 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s] " fmt, __func__ @@ -2434,7 +2434,7 @@ int sde_rm_reserve( /* Check if this is just a page-flip */ if (!_sde_rm_is_display_in_cont_splash(sde_kms, enc) && - !drm_atomic_crtc_needs_modeset(crtc_state)) + !msm_atomic_needs_modeset(crtc_state)) return 0; comp_info = kzalloc(sizeof(*comp_info), GFP_KERNEL);