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

Commit 8693e8f6 authored by Sandeep Panda's avatar Sandeep Panda
Browse files

drm/msm/dsi-staging: register dsi irq before splash handoff



In the current implementation dsi irq enable is tied to
dsi core clock enable and disable. But in continuous splash
scenario dsi core is getting enabled before dsi irq can be
registered. So when from core clock enable function, dsi irq
enable call is made, it is returning early since irq is not
registered yet and later this is resulting in irq storm if
any dsi irq is getting triggered. This change fixes the same
by registering dsi irq before splash handoff sequence begins.

Change-Id: I06528884667d63b25df5aa8276a34233315e8395
Signed-off-by: default avatarSandeep Panda <spanda@codeaurora.org>
parent 14681b57
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -651,10 +651,9 @@ static int dsi_display_status_reg_read(struct dsi_display *display)
		}
	}
exit:
	if (rc <= 0) {
		dsi_display_ctrl_irq_update(display, false);
	/* mask only error interrupts */
	if (rc <= 0)
		dsi_display_mask_ctrl_error_interrupts(display);
	}

	dsi_display_cmd_engine_disable(display);
done:
@@ -3921,22 +3920,24 @@ static int _dsi_display_dev_deinit(struct dsi_display *display)
}

/**
 * dsi_display_splash_res_init() - Initialize resources for continuous splash
 * @display:    Pointer to dsi display
 * dsi_display_cont_splash_config() - Initialize resources for continuous splash
 * @dsi_display:    Pointer to dsi display
 * Returns:     Zero on success
 */
static int dsi_display_splash_res_init(struct  dsi_display *display)
int dsi_display_cont_splash_config(void *dsi_display)
{
	struct dsi_display *display = dsi_display;
	int rc = 0;

	/* Continuous splash not supported by external bridge */
	if (dsi_display_has_ext_bridge(display)) {
	if (!display || dsi_display_has_ext_bridge(display)) {
		display->is_cont_splash_enabled = false;
		return 0;
	}

	/* Vote for gdsc required to read register address space */
	mutex_lock(&display->display_lock);

	/* Vote for gdsc required to read register address space */
	display->cont_splash_client = sde_power_client_create(display->phandle,
						"cont_splash_client");
	rc = sde_power_resource_enable(display->phandle,
@@ -3944,6 +3945,7 @@ static int dsi_display_splash_res_init(struct dsi_display *display)
	if (rc) {
		pr_err("failed to vote gdsc for continuous splash, rc=%d\n",
							rc);
		mutex_unlock(&display->display_lock);
		return -EINVAL;
	}

@@ -3961,6 +3963,9 @@ static int dsi_display_splash_res_init(struct dsi_display *display)
	dsi_display_clk_mngr_update_splash_status(display->clk_mngr,
				display->is_cont_splash_enabled);

	/* Set up ctrl isr before enabling core clk */
	dsi_display_ctrl_isr_configure(display, true);

	/* Vote for Core clk and link clk. Votes on ctrl and phy
	 * regulator are inplicit from  pre clk on callback
	 */
@@ -3981,6 +3986,7 @@ static int dsi_display_splash_res_init(struct dsi_display *display)
	}

	dsi_config_host_engine_state_for_cont_splash(display);
	mutex_unlock(&display->display_lock);

	return rc;

@@ -3989,6 +3995,7 @@ static int dsi_display_splash_res_init(struct dsi_display *display)
			DSI_ALL_CLKS, DSI_CLK_OFF);

clk_manager_update:
	dsi_display_ctrl_isr_configure(display, false);
	/* Update splash status for clock manager */
	dsi_display_clk_mngr_update_splash_status(display->clk_mngr,
				false);
@@ -3997,6 +4004,7 @@ static int dsi_display_splash_res_init(struct dsi_display *display)
	(void)sde_power_resource_enable(display->phandle,
			display->cont_splash_client, false);
	display->is_cont_splash_enabled = false;
	mutex_unlock(&display->display_lock);
	return rc;
}

@@ -4214,11 +4222,6 @@ static int dsi_display_bind(struct device *dev,
	/* register te irq handler */
	dsi_display_register_te_irq(display);

	/* Initialize resources for continuous splash */
	rc = dsi_display_splash_res_init(display);
	if (rc)
		pr_err("Continuous splash resource init failed, rc=%d\n", rc);

	goto error;

error_host_deinit:
+7 −0
Original line number Diff line number Diff line
@@ -634,4 +634,11 @@ int dsi_display_pre_kickoff(struct dsi_display *display,
 */
enum dsi_pixel_format dsi_display_get_dst_format(void *display);

/**
 * dsi_display_cont_splash_config() - initialize splash resources
 * @display:         Handle to display
 *
 * Return: Zero on Success
 */
int dsi_display_cont_splash_config(void *display);
#endif /* _DSI_DISPLAY_H_ */
+6 −0
Original line number Diff line number Diff line
@@ -251,6 +251,12 @@ struct sde_connector_ops {
	int (*config_hdr)(void *display,
		struct sde_connector_state *c_state);

	/**
	 * cont_splash_config - initialize splash resources
	 * @display: Pointer to private display handle
	 * Returns: zero for success, negetive for failure
	 */
	int (*cont_splash_config)(void *display);
};

/**
+9 −0
Original line number Diff line number Diff line
@@ -926,6 +926,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
		.check_status = dsi_display_check_status,
		.enable_event = dsi_conn_enable_event,
		.cmd_transfer = dsi_display_cmd_transfer,
		.cont_splash_config = dsi_display_cont_splash_config,
	};
	static const struct sde_connector_ops wb_ops = {
		.post_init =    sde_wb_connector_post_init,
@@ -939,6 +940,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
		.get_dst_format = NULL,
		.check_status = NULL,
		.cmd_transfer = NULL,
		.cont_splash_config = NULL,
	};
	static const struct sde_connector_ops dp_ops = {
		.post_init  = dp_connector_post_init,
@@ -951,6 +953,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
		.check_status = NULL,
		.config_hdr = dp_connector_config_hdr,
		.cmd_transfer = NULL,
		.cont_splash_config = NULL,
	};
	static const struct sde_connector_ops ext_bridge_ops = {
		.set_info_blob = dsi_conn_set_info_blob,
@@ -962,6 +965,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
		.get_dst_format = dsi_display_get_dst_format,
		.enable_event = dsi_conn_enable_event,
		.cmd_transfer = NULL,
		.cont_splash_config = NULL,
	};
	struct msm_display_info info;
	struct drm_encoder *encoder;
@@ -2251,6 +2255,7 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms)
	struct list_head *connector_list = NULL;
	struct drm_connector *conn_iter = NULL;
	struct drm_connector *connector = NULL;
	struct sde_connector *sde_conn = NULL;

	if (!kms) {
		SDE_ERROR("invalid kms\n");
@@ -2362,6 +2367,10 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms)

	sde_crtc_update_cont_splash_mixer_settings(crtc);

	sde_conn = to_sde_connector(connector);
	if (sde_conn && sde_conn->ops.cont_splash_config)
		sde_conn->ops.cont_splash_config(sde_conn->display);

	return rc;
}