Loading msm/dsi/dsi_defs.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,8 @@ enum dsi_op_mode { * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch * @DSI_MODE_FLAG_VRR: Seamless transition is DynamicFPS. * @DSI_MODE_FLAG_VRR: Seamless transition is DynamicFPS. * New timing values are sent from DAL. * New timing values are sent from DAL. * @DSI_MODE_FLAG_POMS: * Seamless transition is dynamic panel operating mode switch */ */ enum dsi_mode_flags { enum dsi_mode_flags { DSI_MODE_FLAG_SEAMLESS = BIT(0), DSI_MODE_FLAG_SEAMLESS = BIT(0), Loading @@ -81,6 +83,7 @@ enum dsi_mode_flags { DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_DMS = BIT(3), DSI_MODE_FLAG_DMS = BIT(3), DSI_MODE_FLAG_VRR = BIT(4), DSI_MODE_FLAG_VRR = BIT(4), DSI_MODE_FLAG_POMS = BIT(5), }; }; /** /** Loading Loading @@ -555,12 +558,14 @@ struct dsi_display_mode_priv_info { * @timing: Timing parameters for the panel. * @timing: Timing parameters for the panel. * @pixel_clk_khz: Pixel clock in Khz. * @pixel_clk_khz: Pixel clock in Khz. * @dsi_mode_flags: Flags to signal other drm components via private flags * @dsi_mode_flags: Flags to signal other drm components via private flags * @panel_mode: Panel mode * @priv_info: Mode private info * @priv_info: Mode private info */ */ struct dsi_display_mode { struct dsi_display_mode { struct dsi_mode_info timing; struct dsi_mode_info timing; u32 pixel_clk_khz; u32 pixel_clk_khz; u32 dsi_mode_flags; u32 dsi_mode_flags; enum dsi_op_mode panel_mode; struct dsi_display_mode_priv_info *priv_info; struct dsi_display_mode_priv_info *priv_info; }; }; Loading msm/dsi/dsi_display.c +68 −33 Original line number Original line Diff line number Diff line Loading @@ -3971,6 +3971,10 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, return -EINVAL; return -EINVAL; } } if (mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) { display->config.panel_mode = mode->panel_mode; display->panel->panel_mode = mode->panel_mode; } rc = dsi_panel_get_host_cfg_for_mode(display->panel, rc = dsi_panel_get_host_cfg_for_mode(display->panel, mode, mode, &display->config); &display->config); Loading Loading @@ -5040,6 +5044,7 @@ static int dsi_display_ext_get_info(struct drm_connector *connector, info->capabilities |= (MSM_DISPLAY_CAP_VID_MODE | info->capabilities |= (MSM_DISPLAY_CAP_VID_MODE | MSM_DISPLAY_CAP_EDID | MSM_DISPLAY_CAP_HOT_PLUG); MSM_DISPLAY_CAP_EDID | MSM_DISPLAY_CAP_HOT_PLUG); info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE; mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); return 0; return 0; Loading Loading @@ -5403,10 +5408,16 @@ int dsi_display_get_info(struct drm_connector *connector, switch (display->panel->panel_mode) { switch (display->panel->panel_mode) { case DSI_OP_VIDEO_MODE: case DSI_OP_VIDEO_MODE: info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE; info->capabilities |= MSM_DISPLAY_CAP_VID_MODE; info->capabilities |= MSM_DISPLAY_CAP_VID_MODE; if (display->panel->panel_mode_switch_enabled) info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE; break; break; case DSI_OP_CMD_MODE: case DSI_OP_CMD_MODE: info->curr_panel_mode = MSM_DISPLAY_CMD_MODE; info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE; info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE; if (display->panel->panel_mode_switch_enabled) info->capabilities |= MSM_DISPLAY_CAP_VID_MODE; info->is_te_using_watchdog_timer = info->is_te_using_watchdog_timer = display->panel->te_using_watchdog_timer | display->panel->te_using_watchdog_timer | display->sw_te_using_wd; display->sw_te_using_wd; Loading Loading @@ -5704,7 +5715,8 @@ int dsi_display_find_mode(struct dsi_display *display, if (cmp->timing.v_active == m->timing.v_active && if (cmp->timing.v_active == m->timing.v_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.refresh_rate == m->timing.refresh_rate) { cmp->timing.refresh_rate == m->timing.refresh_rate && cmp->panel_mode == m->panel_mode) { *out_mode = m; *out_mode = m; rc = 0; rc = 0; break; break; Loading Loading @@ -6314,7 +6326,8 @@ int dsi_display_prepare(struct dsi_display *display) goto error; goto error; } } if (!display->is_cont_splash_enabled) { if (!(mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) && (!display->is_cont_splash_enabled)) { /* /* * For continuous splash usecase we skip panel * For continuous splash usecase we skip panel * pre prepare since the regulator vote is already * pre prepare since the regulator vote is already Loading Loading @@ -6403,6 +6416,7 @@ int dsi_display_prepare(struct dsi_display *display) goto error_ctrl_link_off; goto error_ctrl_link_off; } } if (!(mode->dsi_mode_flags & DSI_MODE_FLAG_POMS)) { rc = dsi_panel_prepare(display->panel); rc = dsi_panel_prepare(display->panel); if (rc) { if (rc) { pr_err("[%s] panel prepare failed, rc=%d\n", pr_err("[%s] panel prepare failed, rc=%d\n", Loading @@ -6410,6 +6424,7 @@ int dsi_display_prepare(struct dsi_display *display) goto error_ctrl_link_off; goto error_ctrl_link_off; } } } } } goto error; goto error; error_ctrl_link_off: error_ctrl_link_off: Loading Loading @@ -6728,7 +6743,8 @@ int dsi_display_enable(struct dsi_display *display) display->name, rc); display->name, rc); goto error; goto error; } } } else { } else if (!(display->panel->cur_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS)){ rc = dsi_panel_enable(display->panel); rc = dsi_panel_enable(display->panel); if (rc) { if (rc) { pr_err("[%s] failed to enable DSI panel, rc=%d\n", pr_err("[%s] failed to enable DSI panel, rc=%d\n", Loading Loading @@ -6757,6 +6773,7 @@ int dsi_display_enable(struct dsi_display *display) } } if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { pr_debug("%s:enable video timing eng\n", __func__); rc = dsi_display_vid_engine_enable(display); rc = dsi_display_vid_engine_enable(display); if (rc) { if (rc) { pr_err("[%s]failed to enable DSI video engine, rc=%d\n", pr_err("[%s]failed to enable DSI video engine, rc=%d\n", Loading @@ -6764,6 +6781,7 @@ int dsi_display_enable(struct dsi_display *display) goto error_disable_panel; goto error_disable_panel; } } } else if (display->config.panel_mode == DSI_OP_CMD_MODE) { } else if (display->config.panel_mode == DSI_OP_CMD_MODE) { pr_debug("%s:enable command timing eng\n", __func__); rc = dsi_display_cmd_engine_enable(display); rc = dsi_display_cmd_engine_enable(display); if (rc) { if (rc) { pr_err("[%s]failed to enable DSI cmd engine, rc=%d\n", pr_err("[%s]failed to enable DSI cmd engine, rc=%d\n", Loading Loading @@ -6797,10 +6815,18 @@ int dsi_display_post_enable(struct dsi_display *display) mutex_lock(&display->display_lock); 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 { rc = dsi_panel_post_enable(display->panel); rc = dsi_panel_post_enable(display->panel); if (rc) if (rc) pr_err("[%s] panel post-enable failed, rc=%d\n", pr_err("[%s] panel post-enable failed, rc=%d\n", display->name, rc); display->name, rc); } /* remove the clk vote for CMD mode panels */ /* remove the clk vote for CMD mode panels */ if (display->config.panel_mode == DSI_OP_CMD_MODE) if (display->config.panel_mode == DSI_OP_CMD_MODE) Loading @@ -6826,12 +6852,18 @@ int dsi_display_pre_disable(struct dsi_display *display) if (display->config.panel_mode == DSI_OP_CMD_MODE) if (display->config.panel_mode == DSI_OP_CMD_MODE) dsi_display_clk_ctrl(display->dsi_clk_handle, dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); DSI_ALL_CLKS, DSI_CLK_ON); if (display->poms_pending) { if (display->config.panel_mode == DSI_OP_CMD_MODE) dsi_panel_pre_mode_switch_to_video(display->panel); if (display->config.panel_mode == DSI_OP_VIDEO_MODE) dsi_panel_pre_mode_switch_to_cmd(display->panel); } else { rc = dsi_panel_pre_disable(display->panel); rc = dsi_panel_pre_disable(display->panel); if (rc) if (rc) pr_err("[%s] panel pre-disable failed, rc=%d\n", pr_err("[%s] panel pre-disable failed, rc=%d\n", display->name, rc); display->name, rc); } mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); return rc; return rc; } } Loading Loading @@ -6868,11 +6900,12 @@ int dsi_display_disable(struct dsi_display *display) rc = -EINVAL; rc = -EINVAL; } } if (!display->poms_pending) { rc = dsi_panel_disable(display->panel); rc = dsi_panel_disable(display->panel); if (rc) if (rc) pr_err("[%s] failed to disable DSI panel, rc=%d\n", pr_err("[%s] failed to disable DSI panel, rc=%d\n", display->name, rc); display->name, rc); } mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); SDE_EVT32(SDE_EVTLOG_FUNC_EXIT); SDE_EVT32(SDE_EVTLOG_FUNC_EXIT); return rc; return rc; Loading Loading @@ -6911,12 +6944,12 @@ int dsi_display_unprepare(struct dsi_display *display) if (rc) if (rc) pr_err("[%s] display wake up failed, rc=%d\n", pr_err("[%s] display wake up failed, rc=%d\n", display->name, rc); display->name, rc); if (!display->poms_pending) { rc = dsi_panel_unprepare(display->panel); rc = dsi_panel_unprepare(display->panel); if (rc) if (rc) pr_err("[%s] panel unprepare failed, rc=%d\n", pr_err("[%s] panel unprepare failed, rc=%d\n", display->name, rc); display->name, rc); } rc = dsi_display_ctrl_host_disable(display); rc = dsi_display_ctrl_host_disable(display); if (rc) if (rc) pr_err("[%s] failed to disable DSI host, rc=%d\n", pr_err("[%s] failed to disable DSI host, rc=%d\n", Loading Loading @@ -6949,10 +6982,12 @@ int dsi_display_unprepare(struct dsi_display *display) /* destrory dsi isr set up */ /* destrory dsi isr set up */ dsi_display_ctrl_isr_configure(display, false); dsi_display_ctrl_isr_configure(display, false); if (!display->poms_pending) { rc = dsi_panel_post_unprepare(display->panel); rc = dsi_panel_post_unprepare(display->panel); if (rc) if (rc) pr_err("[%s] panel post-unprepare failed, rc=%d\n", pr_err("[%s] panel post-unprepare failed, rc=%d\n", display->name, rc); display->name, rc); } mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); Loading msm/dsi/dsi_display.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -166,6 +166,7 @@ struct dsi_display_ext_bridge { * @cmdline_topology: Display topology shared from kernel command line. * @cmdline_topology: Display topology shared from kernel command line. * @cmdline_timing: Display timing shared from kernel command line. * @cmdline_timing: Display timing shared from kernel command line. * @is_tpg_enabled: TPG state. * @is_tpg_enabled: TPG state. * @poms_pending; Flag indicating the pending panel operating mode switch. * @ulps_enabled: ulps state. * @ulps_enabled: ulps state. * @clamp_enabled: clamp state. * @clamp_enabled: clamp state. * @phy_idle_power_off: PHY power state. * @phy_idle_power_off: PHY power state. Loading Loading @@ -226,6 +227,7 @@ struct dsi_display { int cmdline_topology; int cmdline_topology; int cmdline_timing; int cmdline_timing; bool is_tpg_enabled; bool is_tpg_enabled; bool poms_pending; bool ulps_enabled; bool ulps_enabled; bool clamp_enabled; bool clamp_enabled; bool phy_idle_power_off; bool phy_idle_power_off; Loading msm/dsi/dsi_drm.c +34 −2 Original line number Original line Diff line number Diff line Loading @@ -71,11 +71,18 @@ static void convert_to_dsi_mode(const struct drm_display_mode *drm_mode, dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS; dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS; if (msm_is_mode_seamless_vrr(drm_mode)) if (msm_is_mode_seamless_vrr(drm_mode)) dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR; dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR; if (msm_is_mode_seamless_poms(drm_mode)) dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS; dsi_mode->timing.h_sync_polarity = dsi_mode->timing.h_sync_polarity = !!(drm_mode->flags & DRM_MODE_FLAG_PHSYNC); !!(drm_mode->flags & DRM_MODE_FLAG_PHSYNC); dsi_mode->timing.v_sync_polarity = dsi_mode->timing.v_sync_polarity = !!(drm_mode->flags & DRM_MODE_FLAG_PVSYNC); !!(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; } } void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, Loading Loading @@ -113,12 +120,19 @@ void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DMS; drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DMS; if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_VRR) if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_VRR) drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_VRR; drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_VRR; if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_POMS; if (dsi_mode->timing.h_sync_polarity) if (dsi_mode->timing.h_sync_polarity) drm_mode->flags |= DRM_MODE_FLAG_PHSYNC; drm_mode->flags |= DRM_MODE_FLAG_PHSYNC; if (dsi_mode->timing.v_sync_polarity) if (dsi_mode->timing.v_sync_polarity) drm_mode->flags |= DRM_MODE_FLAG_PVSYNC; 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; drm_mode_set_name(drm_mode); drm_mode_set_name(drm_mode); } } Loading Loading @@ -233,8 +247,18 @@ static void dsi_bridge_disable(struct drm_bridge *bridge) } } display = c_bridge->display; display = c_bridge->display; if (display && display->drm_conn) if (display && display->drm_conn) { if (bridge->encoder->crtc->state->adjusted_mode.private_flags & MSM_MODE_FLAG_SEAMLESS_POMS) { display->poms_pending = true; /* Disable ESD thread, during panel mode switch */ sde_connector_schedule_status_work(display->drm_conn, false); } else { display->poms_pending = false; sde_connector_helper_bridge_disable(display->drm_conn); sde_connector_helper_bridge_disable(display->drm_conn); } } rc = dsi_display_pre_disable(c_bridge->display); rc = dsi_display_pre_disable(c_bridge->display); if (rc) { if (rc) { Loading Loading @@ -363,9 +387,17 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, cur_mode = crtc_state->crtc->mode; cur_mode = crtc_state->crtc->mode; /* 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->active_changed || display->is_cont_splash_enabled)) dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_POMS; /* No DMS/VRR when drm pipeline is changing */ /* No DMS/VRR when drm pipeline is changing */ if (!drm_mode_equal(&cur_mode, adjusted_mode) && 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_VRR)) && (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS)) && (!crtc_state->active_changed || (!crtc_state->active_changed || display->is_cont_splash_enabled)) display->is_cont_splash_enabled)) dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; Loading msm/dsi/dsi_panel.c +128 −2 Original line number Original line Diff line number Diff line Loading @@ -1365,6 +1365,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) { { int rc = 0; int rc = 0; struct dsi_parser_utils *utils = &panel->utils; struct dsi_parser_utils *utils = &panel->utils; bool panel_mode_switch_enabled; enum dsi_op_mode panel_mode; enum dsi_op_mode panel_mode; const char *mode; const char *mode; Loading @@ -1383,7 +1384,13 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) goto error; goto error; } } if (panel_mode == DSI_OP_VIDEO_MODE) { panel_mode_switch_enabled = utils->read_bool(utils->data, "qcom,mdss-dsi-panel-mode-switch"); pr_info("%s: panel operating mode switch feature %s\n", __func__, (panel_mode_switch_enabled ? "enabled" : "disabled")); if (panel_mode == DSI_OP_VIDEO_MODE || panel_mode_switch_enabled) { rc = dsi_panel_parse_video_host_config(&panel->video_config, rc = dsi_panel_parse_video_host_config(&panel->video_config, utils, utils, panel->name); panel->name); Loading @@ -1394,7 +1401,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) } } } } if (panel_mode == DSI_OP_CMD_MODE) { if (panel_mode == DSI_OP_CMD_MODE || panel_mode_switch_enabled) { rc = dsi_panel_parse_cmd_host_config(&panel->cmd_config, rc = dsi_panel_parse_cmd_host_config(&panel->cmd_config, utils, utils, panel->name); panel->name); Loading @@ -1406,6 +1413,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) } } panel->panel_mode = panel_mode; panel->panel_mode = panel_mode; panel->panel_mode_switch_enabled = panel_mode_switch_enabled; error: error: return rc; return rc; } } Loading Loading @@ -2663,6 +2671,33 @@ static int dsi_panel_parse_partial_update_caps(struct dsi_display_mode *mode, return rc; return rc; } } static int 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) { pr_err("invalid arguments\n"); return -EINVAL; } vid_mode_support = utils->read_bool(utils->data, "qcom,mdss-dsi-video-mode"); cmd_mode_support = utils->read_bool(utils->data, "qcom,mdss-dsi-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; return 0; }; static int dsi_panel_parse_dms_info(struct dsi_panel *panel) static int dsi_panel_parse_dms_info(struct dsi_panel *panel) { { int dms_enabled; int dms_enabled; Loading Loading @@ -3349,6 +3384,17 @@ int dsi_panel_get_mode(struct dsi_panel *panel, rc = dsi_panel_parse_partial_update_caps(mode, utils); rc = dsi_panel_parse_partial_update_caps(mode, utils); if (rc) if (rc) pr_err("failed to partial update caps, rc=%d\n", rc); pr_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) { pr_err("PMS: failed to parse panel mode\n"); rc = 0; mode->panel_mode = panel->panel_mode; } } else { mode->panel_mode = panel->panel_mode; } } } goto done; goto done; Loading Loading @@ -3707,6 +3753,86 @@ int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx, return rc; return rc; } } int dsi_panel_pre_mode_switch_to_video(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_CMD_TO_VID_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_pre_mode_switch_to_cmd(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_VID_TO_CMD_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_mode_switch_to_cmd(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_VID_TO_CMD_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_mode_switch_to_vid(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_CMD_TO_VID_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_switch(struct dsi_panel *panel) int dsi_panel_switch(struct dsi_panel *panel) { { int rc = 0; int rc = 0; Loading Loading
msm/dsi/dsi_defs.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,8 @@ enum dsi_op_mode { * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch * @DSI_MODE_FLAG_VRR: Seamless transition is DynamicFPS. * @DSI_MODE_FLAG_VRR: Seamless transition is DynamicFPS. * New timing values are sent from DAL. * New timing values are sent from DAL. * @DSI_MODE_FLAG_POMS: * Seamless transition is dynamic panel operating mode switch */ */ enum dsi_mode_flags { enum dsi_mode_flags { DSI_MODE_FLAG_SEAMLESS = BIT(0), DSI_MODE_FLAG_SEAMLESS = BIT(0), Loading @@ -81,6 +83,7 @@ enum dsi_mode_flags { DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_DMS = BIT(3), DSI_MODE_FLAG_DMS = BIT(3), DSI_MODE_FLAG_VRR = BIT(4), DSI_MODE_FLAG_VRR = BIT(4), DSI_MODE_FLAG_POMS = BIT(5), }; }; /** /** Loading Loading @@ -555,12 +558,14 @@ struct dsi_display_mode_priv_info { * @timing: Timing parameters for the panel. * @timing: Timing parameters for the panel. * @pixel_clk_khz: Pixel clock in Khz. * @pixel_clk_khz: Pixel clock in Khz. * @dsi_mode_flags: Flags to signal other drm components via private flags * @dsi_mode_flags: Flags to signal other drm components via private flags * @panel_mode: Panel mode * @priv_info: Mode private info * @priv_info: Mode private info */ */ struct dsi_display_mode { struct dsi_display_mode { struct dsi_mode_info timing; struct dsi_mode_info timing; u32 pixel_clk_khz; u32 pixel_clk_khz; u32 dsi_mode_flags; u32 dsi_mode_flags; enum dsi_op_mode panel_mode; struct dsi_display_mode_priv_info *priv_info; struct dsi_display_mode_priv_info *priv_info; }; }; Loading
msm/dsi/dsi_display.c +68 −33 Original line number Original line Diff line number Diff line Loading @@ -3971,6 +3971,10 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, return -EINVAL; return -EINVAL; } } if (mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) { display->config.panel_mode = mode->panel_mode; display->panel->panel_mode = mode->panel_mode; } rc = dsi_panel_get_host_cfg_for_mode(display->panel, rc = dsi_panel_get_host_cfg_for_mode(display->panel, mode, mode, &display->config); &display->config); Loading Loading @@ -5040,6 +5044,7 @@ static int dsi_display_ext_get_info(struct drm_connector *connector, info->capabilities |= (MSM_DISPLAY_CAP_VID_MODE | info->capabilities |= (MSM_DISPLAY_CAP_VID_MODE | MSM_DISPLAY_CAP_EDID | MSM_DISPLAY_CAP_HOT_PLUG); MSM_DISPLAY_CAP_EDID | MSM_DISPLAY_CAP_HOT_PLUG); info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE; mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); return 0; return 0; Loading Loading @@ -5403,10 +5408,16 @@ int dsi_display_get_info(struct drm_connector *connector, switch (display->panel->panel_mode) { switch (display->panel->panel_mode) { case DSI_OP_VIDEO_MODE: case DSI_OP_VIDEO_MODE: info->curr_panel_mode = MSM_DISPLAY_VIDEO_MODE; info->capabilities |= MSM_DISPLAY_CAP_VID_MODE; info->capabilities |= MSM_DISPLAY_CAP_VID_MODE; if (display->panel->panel_mode_switch_enabled) info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE; break; break; case DSI_OP_CMD_MODE: case DSI_OP_CMD_MODE: info->curr_panel_mode = MSM_DISPLAY_CMD_MODE; info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE; info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE; if (display->panel->panel_mode_switch_enabled) info->capabilities |= MSM_DISPLAY_CAP_VID_MODE; info->is_te_using_watchdog_timer = info->is_te_using_watchdog_timer = display->panel->te_using_watchdog_timer | display->panel->te_using_watchdog_timer | display->sw_te_using_wd; display->sw_te_using_wd; Loading Loading @@ -5704,7 +5715,8 @@ int dsi_display_find_mode(struct dsi_display *display, if (cmp->timing.v_active == m->timing.v_active && if (cmp->timing.v_active == m->timing.v_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.refresh_rate == m->timing.refresh_rate) { cmp->timing.refresh_rate == m->timing.refresh_rate && cmp->panel_mode == m->panel_mode) { *out_mode = m; *out_mode = m; rc = 0; rc = 0; break; break; Loading Loading @@ -6314,7 +6326,8 @@ int dsi_display_prepare(struct dsi_display *display) goto error; goto error; } } if (!display->is_cont_splash_enabled) { if (!(mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) && (!display->is_cont_splash_enabled)) { /* /* * For continuous splash usecase we skip panel * For continuous splash usecase we skip panel * pre prepare since the regulator vote is already * pre prepare since the regulator vote is already Loading Loading @@ -6403,6 +6416,7 @@ int dsi_display_prepare(struct dsi_display *display) goto error_ctrl_link_off; goto error_ctrl_link_off; } } if (!(mode->dsi_mode_flags & DSI_MODE_FLAG_POMS)) { rc = dsi_panel_prepare(display->panel); rc = dsi_panel_prepare(display->panel); if (rc) { if (rc) { pr_err("[%s] panel prepare failed, rc=%d\n", pr_err("[%s] panel prepare failed, rc=%d\n", Loading @@ -6410,6 +6424,7 @@ int dsi_display_prepare(struct dsi_display *display) goto error_ctrl_link_off; goto error_ctrl_link_off; } } } } } goto error; goto error; error_ctrl_link_off: error_ctrl_link_off: Loading Loading @@ -6728,7 +6743,8 @@ int dsi_display_enable(struct dsi_display *display) display->name, rc); display->name, rc); goto error; goto error; } } } else { } else if (!(display->panel->cur_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS)){ rc = dsi_panel_enable(display->panel); rc = dsi_panel_enable(display->panel); if (rc) { if (rc) { pr_err("[%s] failed to enable DSI panel, rc=%d\n", pr_err("[%s] failed to enable DSI panel, rc=%d\n", Loading Loading @@ -6757,6 +6773,7 @@ int dsi_display_enable(struct dsi_display *display) } } if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { pr_debug("%s:enable video timing eng\n", __func__); rc = dsi_display_vid_engine_enable(display); rc = dsi_display_vid_engine_enable(display); if (rc) { if (rc) { pr_err("[%s]failed to enable DSI video engine, rc=%d\n", pr_err("[%s]failed to enable DSI video engine, rc=%d\n", Loading @@ -6764,6 +6781,7 @@ int dsi_display_enable(struct dsi_display *display) goto error_disable_panel; goto error_disable_panel; } } } else if (display->config.panel_mode == DSI_OP_CMD_MODE) { } else if (display->config.panel_mode == DSI_OP_CMD_MODE) { pr_debug("%s:enable command timing eng\n", __func__); rc = dsi_display_cmd_engine_enable(display); rc = dsi_display_cmd_engine_enable(display); if (rc) { if (rc) { pr_err("[%s]failed to enable DSI cmd engine, rc=%d\n", pr_err("[%s]failed to enable DSI cmd engine, rc=%d\n", Loading Loading @@ -6797,10 +6815,18 @@ int dsi_display_post_enable(struct dsi_display *display) mutex_lock(&display->display_lock); 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 { rc = dsi_panel_post_enable(display->panel); rc = dsi_panel_post_enable(display->panel); if (rc) if (rc) pr_err("[%s] panel post-enable failed, rc=%d\n", pr_err("[%s] panel post-enable failed, rc=%d\n", display->name, rc); display->name, rc); } /* remove the clk vote for CMD mode panels */ /* remove the clk vote for CMD mode panels */ if (display->config.panel_mode == DSI_OP_CMD_MODE) if (display->config.panel_mode == DSI_OP_CMD_MODE) Loading @@ -6826,12 +6852,18 @@ int dsi_display_pre_disable(struct dsi_display *display) if (display->config.panel_mode == DSI_OP_CMD_MODE) if (display->config.panel_mode == DSI_OP_CMD_MODE) dsi_display_clk_ctrl(display->dsi_clk_handle, dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_ALL_CLKS, DSI_CLK_ON); DSI_ALL_CLKS, DSI_CLK_ON); if (display->poms_pending) { if (display->config.panel_mode == DSI_OP_CMD_MODE) dsi_panel_pre_mode_switch_to_video(display->panel); if (display->config.panel_mode == DSI_OP_VIDEO_MODE) dsi_panel_pre_mode_switch_to_cmd(display->panel); } else { rc = dsi_panel_pre_disable(display->panel); rc = dsi_panel_pre_disable(display->panel); if (rc) if (rc) pr_err("[%s] panel pre-disable failed, rc=%d\n", pr_err("[%s] panel pre-disable failed, rc=%d\n", display->name, rc); display->name, rc); } mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); return rc; return rc; } } Loading Loading @@ -6868,11 +6900,12 @@ int dsi_display_disable(struct dsi_display *display) rc = -EINVAL; rc = -EINVAL; } } if (!display->poms_pending) { rc = dsi_panel_disable(display->panel); rc = dsi_panel_disable(display->panel); if (rc) if (rc) pr_err("[%s] failed to disable DSI panel, rc=%d\n", pr_err("[%s] failed to disable DSI panel, rc=%d\n", display->name, rc); display->name, rc); } mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); SDE_EVT32(SDE_EVTLOG_FUNC_EXIT); SDE_EVT32(SDE_EVTLOG_FUNC_EXIT); return rc; return rc; Loading Loading @@ -6911,12 +6944,12 @@ int dsi_display_unprepare(struct dsi_display *display) if (rc) if (rc) pr_err("[%s] display wake up failed, rc=%d\n", pr_err("[%s] display wake up failed, rc=%d\n", display->name, rc); display->name, rc); if (!display->poms_pending) { rc = dsi_panel_unprepare(display->panel); rc = dsi_panel_unprepare(display->panel); if (rc) if (rc) pr_err("[%s] panel unprepare failed, rc=%d\n", pr_err("[%s] panel unprepare failed, rc=%d\n", display->name, rc); display->name, rc); } rc = dsi_display_ctrl_host_disable(display); rc = dsi_display_ctrl_host_disable(display); if (rc) if (rc) pr_err("[%s] failed to disable DSI host, rc=%d\n", pr_err("[%s] failed to disable DSI host, rc=%d\n", Loading Loading @@ -6949,10 +6982,12 @@ int dsi_display_unprepare(struct dsi_display *display) /* destrory dsi isr set up */ /* destrory dsi isr set up */ dsi_display_ctrl_isr_configure(display, false); dsi_display_ctrl_isr_configure(display, false); if (!display->poms_pending) { rc = dsi_panel_post_unprepare(display->panel); rc = dsi_panel_post_unprepare(display->panel); if (rc) if (rc) pr_err("[%s] panel post-unprepare failed, rc=%d\n", pr_err("[%s] panel post-unprepare failed, rc=%d\n", display->name, rc); display->name, rc); } mutex_unlock(&display->display_lock); mutex_unlock(&display->display_lock); Loading
msm/dsi/dsi_display.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -166,6 +166,7 @@ struct dsi_display_ext_bridge { * @cmdline_topology: Display topology shared from kernel command line. * @cmdline_topology: Display topology shared from kernel command line. * @cmdline_timing: Display timing shared from kernel command line. * @cmdline_timing: Display timing shared from kernel command line. * @is_tpg_enabled: TPG state. * @is_tpg_enabled: TPG state. * @poms_pending; Flag indicating the pending panel operating mode switch. * @ulps_enabled: ulps state. * @ulps_enabled: ulps state. * @clamp_enabled: clamp state. * @clamp_enabled: clamp state. * @phy_idle_power_off: PHY power state. * @phy_idle_power_off: PHY power state. Loading Loading @@ -226,6 +227,7 @@ struct dsi_display { int cmdline_topology; int cmdline_topology; int cmdline_timing; int cmdline_timing; bool is_tpg_enabled; bool is_tpg_enabled; bool poms_pending; bool ulps_enabled; bool ulps_enabled; bool clamp_enabled; bool clamp_enabled; bool phy_idle_power_off; bool phy_idle_power_off; Loading
msm/dsi/dsi_drm.c +34 −2 Original line number Original line Diff line number Diff line Loading @@ -71,11 +71,18 @@ static void convert_to_dsi_mode(const struct drm_display_mode *drm_mode, dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS; dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS; if (msm_is_mode_seamless_vrr(drm_mode)) if (msm_is_mode_seamless_vrr(drm_mode)) dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR; dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR; if (msm_is_mode_seamless_poms(drm_mode)) dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS; dsi_mode->timing.h_sync_polarity = dsi_mode->timing.h_sync_polarity = !!(drm_mode->flags & DRM_MODE_FLAG_PHSYNC); !!(drm_mode->flags & DRM_MODE_FLAG_PHSYNC); dsi_mode->timing.v_sync_polarity = dsi_mode->timing.v_sync_polarity = !!(drm_mode->flags & DRM_MODE_FLAG_PVSYNC); !!(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; } } void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, Loading Loading @@ -113,12 +120,19 @@ void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode, drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DMS; drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DMS; if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_VRR) if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_VRR) drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_VRR; drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_VRR; if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_POMS) drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_POMS; if (dsi_mode->timing.h_sync_polarity) if (dsi_mode->timing.h_sync_polarity) drm_mode->flags |= DRM_MODE_FLAG_PHSYNC; drm_mode->flags |= DRM_MODE_FLAG_PHSYNC; if (dsi_mode->timing.v_sync_polarity) if (dsi_mode->timing.v_sync_polarity) drm_mode->flags |= DRM_MODE_FLAG_PVSYNC; 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; drm_mode_set_name(drm_mode); drm_mode_set_name(drm_mode); } } Loading Loading @@ -233,8 +247,18 @@ static void dsi_bridge_disable(struct drm_bridge *bridge) } } display = c_bridge->display; display = c_bridge->display; if (display && display->drm_conn) if (display && display->drm_conn) { if (bridge->encoder->crtc->state->adjusted_mode.private_flags & MSM_MODE_FLAG_SEAMLESS_POMS) { display->poms_pending = true; /* Disable ESD thread, during panel mode switch */ sde_connector_schedule_status_work(display->drm_conn, false); } else { display->poms_pending = false; sde_connector_helper_bridge_disable(display->drm_conn); sde_connector_helper_bridge_disable(display->drm_conn); } } rc = dsi_display_pre_disable(c_bridge->display); rc = dsi_display_pre_disable(c_bridge->display); if (rc) { if (rc) { Loading Loading @@ -363,9 +387,17 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, cur_mode = crtc_state->crtc->mode; cur_mode = crtc_state->crtc->mode; /* 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->active_changed || display->is_cont_splash_enabled)) dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_POMS; /* No DMS/VRR when drm pipeline is changing */ /* No DMS/VRR when drm pipeline is changing */ if (!drm_mode_equal(&cur_mode, adjusted_mode) && 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_VRR)) && (!(dsi_mode.dsi_mode_flags & DSI_MODE_FLAG_POMS)) && (!crtc_state->active_changed || (!crtc_state->active_changed || display->is_cont_splash_enabled)) display->is_cont_splash_enabled)) dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; Loading
msm/dsi/dsi_panel.c +128 −2 Original line number Original line Diff line number Diff line Loading @@ -1365,6 +1365,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) { { int rc = 0; int rc = 0; struct dsi_parser_utils *utils = &panel->utils; struct dsi_parser_utils *utils = &panel->utils; bool panel_mode_switch_enabled; enum dsi_op_mode panel_mode; enum dsi_op_mode panel_mode; const char *mode; const char *mode; Loading @@ -1383,7 +1384,13 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) goto error; goto error; } } if (panel_mode == DSI_OP_VIDEO_MODE) { panel_mode_switch_enabled = utils->read_bool(utils->data, "qcom,mdss-dsi-panel-mode-switch"); pr_info("%s: panel operating mode switch feature %s\n", __func__, (panel_mode_switch_enabled ? "enabled" : "disabled")); if (panel_mode == DSI_OP_VIDEO_MODE || panel_mode_switch_enabled) { rc = dsi_panel_parse_video_host_config(&panel->video_config, rc = dsi_panel_parse_video_host_config(&panel->video_config, utils, utils, panel->name); panel->name); Loading @@ -1394,7 +1401,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) } } } } if (panel_mode == DSI_OP_CMD_MODE) { if (panel_mode == DSI_OP_CMD_MODE || panel_mode_switch_enabled) { rc = dsi_panel_parse_cmd_host_config(&panel->cmd_config, rc = dsi_panel_parse_cmd_host_config(&panel->cmd_config, utils, utils, panel->name); panel->name); Loading @@ -1406,6 +1413,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel) } } panel->panel_mode = panel_mode; panel->panel_mode = panel_mode; panel->panel_mode_switch_enabled = panel_mode_switch_enabled; error: error: return rc; return rc; } } Loading Loading @@ -2663,6 +2671,33 @@ static int dsi_panel_parse_partial_update_caps(struct dsi_display_mode *mode, return rc; return rc; } } static int 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) { pr_err("invalid arguments\n"); return -EINVAL; } vid_mode_support = utils->read_bool(utils->data, "qcom,mdss-dsi-video-mode"); cmd_mode_support = utils->read_bool(utils->data, "qcom,mdss-dsi-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; return 0; }; static int dsi_panel_parse_dms_info(struct dsi_panel *panel) static int dsi_panel_parse_dms_info(struct dsi_panel *panel) { { int dms_enabled; int dms_enabled; Loading Loading @@ -3349,6 +3384,17 @@ int dsi_panel_get_mode(struct dsi_panel *panel, rc = dsi_panel_parse_partial_update_caps(mode, utils); rc = dsi_panel_parse_partial_update_caps(mode, utils); if (rc) if (rc) pr_err("failed to partial update caps, rc=%d\n", rc); pr_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) { pr_err("PMS: failed to parse panel mode\n"); rc = 0; mode->panel_mode = panel->panel_mode; } } else { mode->panel_mode = panel->panel_mode; } } } goto done; goto done; Loading Loading @@ -3707,6 +3753,86 @@ int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx, return rc; return rc; } } int dsi_panel_pre_mode_switch_to_video(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_CMD_TO_VID_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_pre_mode_switch_to_cmd(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_VID_TO_CMD_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_mode_switch_to_cmd(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_VID_TO_CMD_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_mode_switch_to_vid(struct dsi_panel *panel) { int rc = 0; if (!panel) { pr_err("Invalid params\n"); return -EINVAL; } mutex_lock(&panel->panel_lock); rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_CMD_TO_VID_SWITCH); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n", panel->name, rc); mutex_unlock(&panel->panel_lock); return rc; } int dsi_panel_switch(struct dsi_panel *panel) int dsi_panel_switch(struct dsi_panel *panel) { { int rc = 0; int rc = 0; Loading