Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +30 −0 Original line number Diff line number Diff line Loading @@ -1945,6 +1945,36 @@ void dsi_ctrl_disable_status_interrupt(struct dsi_ctrl *dsi_ctrl, spin_unlock_irqrestore(&dsi_ctrl->irq_info.irq_lock, flags); } int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl) { if (!dsi_ctrl) { pr_err("Invalid params\n"); return -EINVAL; } if (dsi_ctrl->hw.ops.host_setup) dsi_ctrl->hw.ops.host_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config); if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE) { if (dsi_ctrl->hw.ops.cmd_engine_setup) dsi_ctrl->hw.ops.cmd_engine_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config, &dsi_ctrl->host_config.u.cmd_engine); if (dsi_ctrl->hw.ops.setup_cmd_stream) dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw, &dsi_ctrl->host_config.video_timing, dsi_ctrl->host_config.video_timing.h_active * 3, 0x0, NULL); } else { pr_err("invalid panel mode for resolution switch\n"); return -EINVAL; } return 0; } /** * dsi_ctrl_host_init() - Initialize DSI host hardware. * @dsi_ctrl: DSI controller handle. Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +11 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,17 @@ int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable); */ int dsi_ctrl_soft_reset(struct dsi_ctrl *dsi_ctrl); /** * dsi_ctrl_host_timing_update - reinitialize host with new timing values * @dsi_ctrl: DSI controller handle. * * Reinitialize DSI controller hardware with new display timing values * when resolution is switched dynamically. * * Return: error code */ int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl); /** * dsi_ctrl_host_init() - Initialize DSI host hardware. * @dsi_ctrl: DSI controller handle. Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c +1 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,7 @@ void dsi_ctrl_hw_cmn_host_setup(struct dsi_ctrl_hw *ctrl, DSI_W32(ctrl, DSI_CLK_CTRL, 0x23F); /* Setup DSI control register */ reg_value = 0; reg_value = DSI_R32(ctrl, DSI_CTRL); reg_value |= (cfg->en_crc_check ? BIT(24) : 0); reg_value |= (cfg->en_ecc_check ? BIT(20) : 0); reg_value |= BIT(8); /* Clock lane */ Loading drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +3 −1 Original line number Diff line number Diff line Loading @@ -76,11 +76,13 @@ enum dsi_op_mode { * @DSI_MODE_FLAG_SEAMLESS: Seamless transition requested by user * @DSI_MODE_FLAG_DFPS: Seamless transition is DynamicFPS * @DSI_MODE_FLAG_VBLANK_PRE_MODESET: Transition needs VBLANK before Modeset * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch */ enum dsi_mode_flags { DSI_MODE_FLAG_SEAMLESS = BIT(0), DSI_MODE_FLAG_DFPS = BIT(1), DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2) DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_DMS = BIT(3), }; /** Loading drivers/gpu/drm/msm/dsi-staging/dsi_display.c +112 −5 Original line number Diff line number Diff line Loading @@ -1107,6 +1107,32 @@ static int dsi_display_phy_reset_config(struct dsi_display *display, return 0; } static int dsi_display_ctrl_update(struct dsi_display *display) { int rc = 0; int i; struct dsi_display_ctrl *ctrl; for (i = 0 ; i < display->ctrl_count; i++) { ctrl = &display->ctrl[i]; rc = dsi_ctrl_host_timing_update(ctrl->ctrl); if (rc) { pr_err("[%s] failed to update host_%d, rc=%d\n", display->name, i, rc); goto error_host_deinit; } } return 0; error_host_deinit: for (i = i - 1; i >= 0; i--) { ctrl = &display->ctrl[i]; (void)dsi_ctrl_host_deinit(ctrl->ctrl); } return rc; } static int dsi_display_ctrl_init(struct dsi_display *display) { int rc = 0; Loading Loading @@ -3588,17 +3614,80 @@ int dsi_display_set_tpg_state(struct dsi_display *display, bool enable) return rc; } static int dsi_display_pre_switch(struct dsi_display *display) { int rc = 0; rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_CORE_CLK, DSI_CLK_ON); if (rc) { pr_err("[%s] failed to enable DSI core clocks, rc=%d\n", display->name, rc); goto error; } rc = dsi_display_ctrl_update(display); if (rc) { pr_err("[%s] failed to update DSI controller, rc=%d\n", display->name, rc); goto error_ctrl_clk_off; } rc = dsi_display_set_clk_src(display); if (rc) { pr_err("[%s] failed to set DSI link clock source, rc=%d\n", display->name, rc); goto error_ctrl_deinit; } rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_LINK_CLK, DSI_CLK_ON); if (rc) { pr_err("[%s] failed to enable DSI link clocks, rc=%d\n", display->name, rc); goto error_ctrl_deinit; } goto error; error_ctrl_deinit: (void)dsi_display_ctrl_deinit(display); error_ctrl_clk_off: (void)dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_CORE_CLK, DSI_CLK_OFF); error: return rc; } int dsi_display_prepare(struct dsi_display *display) { int rc = 0; struct dsi_display_mode *mode; if (!display) { pr_err("Invalid params\n"); return -EINVAL; } if (!display->panel->cur_mode) { pr_err("no valid mode set for the display"); return -EINVAL; } mutex_lock(&display->display_lock); mode = display->panel->cur_mode; if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { /* update dsi ctrl for new mode */ rc = dsi_display_pre_switch(display); if (rc) pr_err("[%s] panel pre-prepare-res-switch failed, rc=%d\n", display->name, rc); goto error; } rc = dsi_panel_pre_prepare(display->panel); if (rc) { pr_err("[%s] panel pre-prepare failed, rc=%d\n", Loading Loading @@ -3812,12 +3901,21 @@ int dsi_display_enable(struct dsi_display *display) mode = display->panel->cur_mode; if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { rc = dsi_panel_post_switch(display->panel); if (rc) { pr_err("[%s] failed to switch DSI panel mode, rc=%d\n", display->name, rc); goto error; } } else { rc = dsi_panel_enable(display->panel); if (rc) { pr_err("[%s] failed to enable DSI panel, rc=%d\n", display->name, rc); goto error; } } if (mode->priv_info->dsc_enabled) { mode->priv_info->dsc.pic_width *= display->ctrl_count; Loading @@ -3829,6 +3927,15 @@ int dsi_display_enable(struct dsi_display *display) } } if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { rc = dsi_panel_switch(display->panel); if (rc) pr_err("[%s] failed to switch DSI panel mode, rc=%d\n", display->name, rc); goto error_disable_panel; } if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { rc = dsi_display_vid_engine_enable(display); if (rc) { Loading Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +30 −0 Original line number Diff line number Diff line Loading @@ -1945,6 +1945,36 @@ void dsi_ctrl_disable_status_interrupt(struct dsi_ctrl *dsi_ctrl, spin_unlock_irqrestore(&dsi_ctrl->irq_info.irq_lock, flags); } int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl) { if (!dsi_ctrl) { pr_err("Invalid params\n"); return -EINVAL; } if (dsi_ctrl->hw.ops.host_setup) dsi_ctrl->hw.ops.host_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config); if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE) { if (dsi_ctrl->hw.ops.cmd_engine_setup) dsi_ctrl->hw.ops.cmd_engine_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config, &dsi_ctrl->host_config.u.cmd_engine); if (dsi_ctrl->hw.ops.setup_cmd_stream) dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw, &dsi_ctrl->host_config.video_timing, dsi_ctrl->host_config.video_timing.h_active * 3, 0x0, NULL); } else { pr_err("invalid panel mode for resolution switch\n"); return -EINVAL; } return 0; } /** * dsi_ctrl_host_init() - Initialize DSI host hardware. * @dsi_ctrl: DSI controller handle. Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +11 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,17 @@ int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable); */ int dsi_ctrl_soft_reset(struct dsi_ctrl *dsi_ctrl); /** * dsi_ctrl_host_timing_update - reinitialize host with new timing values * @dsi_ctrl: DSI controller handle. * * Reinitialize DSI controller hardware with new display timing values * when resolution is switched dynamically. * * Return: error code */ int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl); /** * dsi_ctrl_host_init() - Initialize DSI host hardware. * @dsi_ctrl: DSI controller handle. Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c +1 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,7 @@ void dsi_ctrl_hw_cmn_host_setup(struct dsi_ctrl_hw *ctrl, DSI_W32(ctrl, DSI_CLK_CTRL, 0x23F); /* Setup DSI control register */ reg_value = 0; reg_value = DSI_R32(ctrl, DSI_CTRL); reg_value |= (cfg->en_crc_check ? BIT(24) : 0); reg_value |= (cfg->en_ecc_check ? BIT(20) : 0); reg_value |= BIT(8); /* Clock lane */ Loading
drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +3 −1 Original line number Diff line number Diff line Loading @@ -76,11 +76,13 @@ enum dsi_op_mode { * @DSI_MODE_FLAG_SEAMLESS: Seamless transition requested by user * @DSI_MODE_FLAG_DFPS: Seamless transition is DynamicFPS * @DSI_MODE_FLAG_VBLANK_PRE_MODESET: Transition needs VBLANK before Modeset * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch */ enum dsi_mode_flags { DSI_MODE_FLAG_SEAMLESS = BIT(0), DSI_MODE_FLAG_DFPS = BIT(1), DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2) DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2), DSI_MODE_FLAG_DMS = BIT(3), }; /** Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display.c +112 −5 Original line number Diff line number Diff line Loading @@ -1107,6 +1107,32 @@ static int dsi_display_phy_reset_config(struct dsi_display *display, return 0; } static int dsi_display_ctrl_update(struct dsi_display *display) { int rc = 0; int i; struct dsi_display_ctrl *ctrl; for (i = 0 ; i < display->ctrl_count; i++) { ctrl = &display->ctrl[i]; rc = dsi_ctrl_host_timing_update(ctrl->ctrl); if (rc) { pr_err("[%s] failed to update host_%d, rc=%d\n", display->name, i, rc); goto error_host_deinit; } } return 0; error_host_deinit: for (i = i - 1; i >= 0; i--) { ctrl = &display->ctrl[i]; (void)dsi_ctrl_host_deinit(ctrl->ctrl); } return rc; } static int dsi_display_ctrl_init(struct dsi_display *display) { int rc = 0; Loading Loading @@ -3588,17 +3614,80 @@ int dsi_display_set_tpg_state(struct dsi_display *display, bool enable) return rc; } static int dsi_display_pre_switch(struct dsi_display *display) { int rc = 0; rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_CORE_CLK, DSI_CLK_ON); if (rc) { pr_err("[%s] failed to enable DSI core clocks, rc=%d\n", display->name, rc); goto error; } rc = dsi_display_ctrl_update(display); if (rc) { pr_err("[%s] failed to update DSI controller, rc=%d\n", display->name, rc); goto error_ctrl_clk_off; } rc = dsi_display_set_clk_src(display); if (rc) { pr_err("[%s] failed to set DSI link clock source, rc=%d\n", display->name, rc); goto error_ctrl_deinit; } rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_LINK_CLK, DSI_CLK_ON); if (rc) { pr_err("[%s] failed to enable DSI link clocks, rc=%d\n", display->name, rc); goto error_ctrl_deinit; } goto error; error_ctrl_deinit: (void)dsi_display_ctrl_deinit(display); error_ctrl_clk_off: (void)dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_CORE_CLK, DSI_CLK_OFF); error: return rc; } int dsi_display_prepare(struct dsi_display *display) { int rc = 0; struct dsi_display_mode *mode; if (!display) { pr_err("Invalid params\n"); return -EINVAL; } if (!display->panel->cur_mode) { pr_err("no valid mode set for the display"); return -EINVAL; } mutex_lock(&display->display_lock); mode = display->panel->cur_mode; if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { /* update dsi ctrl for new mode */ rc = dsi_display_pre_switch(display); if (rc) pr_err("[%s] panel pre-prepare-res-switch failed, rc=%d\n", display->name, rc); goto error; } rc = dsi_panel_pre_prepare(display->panel); if (rc) { pr_err("[%s] panel pre-prepare failed, rc=%d\n", Loading Loading @@ -3812,12 +3901,21 @@ int dsi_display_enable(struct dsi_display *display) mode = display->panel->cur_mode; if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { rc = dsi_panel_post_switch(display->panel); if (rc) { pr_err("[%s] failed to switch DSI panel mode, rc=%d\n", display->name, rc); goto error; } } else { rc = dsi_panel_enable(display->panel); if (rc) { pr_err("[%s] failed to enable DSI panel, rc=%d\n", display->name, rc); goto error; } } if (mode->priv_info->dsc_enabled) { mode->priv_info->dsc.pic_width *= display->ctrl_count; Loading @@ -3829,6 +3927,15 @@ int dsi_display_enable(struct dsi_display *display) } } if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) { rc = dsi_panel_switch(display->panel); if (rc) pr_err("[%s] failed to switch DSI panel mode, rc=%d\n", display->name, rc); goto error_disable_panel; } if (display->config.panel_mode == DSI_OP_VIDEO_MODE) { rc = dsi_display_vid_engine_enable(display); if (rc) { Loading