Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aca8791e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: handle atomic commit with dynamic mode switch"

parents 7b8e5e67 6993462f
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -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.
+11 −0
Original line number Diff line number Diff line
@@ -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.
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+3 −1
Original line number Diff line number Diff line
@@ -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),
};

/**
+112 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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",
@@ -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;
@@ -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