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

Commit 8f4978ef authored by Ajay Singh Parmar's avatar Ajay Singh Parmar
Browse files

msm: mdss: hdmi: refactor event handler



HDMI driver handles many MDP events. Currently all the events
are handled in one function. Create different functions for
each event for a cleaner approach.

Change-Id: Ib48c02b2b89f7fdb347afd3a02d8b6b7c1c03e85
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 2966dd97
Loading
Loading
Loading
Loading
+251 −181
Original line number Diff line number Diff line
@@ -468,15 +468,14 @@ static inline bool hdmi_tx_is_cec_wakeup_en(struct hdmi_tx_ctrl *hdmi_ctrl)
	return hdmi_cec_is_wakeup_en(fd);
}

static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl,
		bool suspend)
static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	void *fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);

	if (!hdmi_ctrl || !fd)
		return;

	hdmi_cec_device_suspend(fd, suspend);
	hdmi_cec_device_suspend(fd, hdmi_ctrl->panel_suspend);
}


@@ -3698,17 +3697,18 @@ static inline void hdmi_tx_audio_off(struct hdmi_tx_ctrl *hdmi_ctrl)
		sizeof(struct msm_hdmi_audio_setup_params));
}

static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
static int hdmi_tx_power_off(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	struct dss_io_data *io = NULL;
	struct hdmi_tx_ctrl *hdmi_ctrl =
		hdmi_tx_get_drvdata_from_panel_data(panel_data);
	struct mdss_panel_data *panel_data;

	if (!hdmi_ctrl) {
		DEV_ERR("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	panel_data = &hdmi_ctrl->panel_data;

	io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
	if (!io->base) {
		DEV_ERR("%s: Core io is not initialized\n", __func__);
@@ -3744,14 +3744,13 @@ end:
	return 0;
} /* hdmi_tx_power_off */

static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int rc = 0;
	int res_changed = RESOLUTION_UNCHANGED;
	struct dss_io_data *io = NULL;
	struct mdss_panel_info *panel_info = NULL;
	struct hdmi_tx_ctrl *hdmi_ctrl =
		hdmi_tx_get_drvdata_from_panel_data(panel_data);
	struct mdss_panel_data *panel_data;

	if (!hdmi_ctrl) {
		DEV_ERR("%s: invalid input\n", __func__);
@@ -3770,6 +3769,8 @@ static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
		goto end;
	}

	panel_data = &hdmi_ctrl->panel_data;

	rc = hdmi_tx_check_clk_state(hdmi_ctrl, HDMI_TX_HPD_PM);
	if (rc)
		goto end;
@@ -4407,73 +4408,58 @@ static void hdmi_tx_fps_work(struct work_struct *work)
	hdmi_tx_update_fps(hdmi_ctrl);
}

static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
	int event, void *arg)
static int hdmi_tx_evt_handle_register(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int rc = 0, new_vic = -1;
	struct hdmi_tx_ctrl *hdmi_ctrl =
		hdmi_tx_get_drvdata_from_panel_data(panel_data);

	if (!hdmi_ctrl) {
		DEV_ERR("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	/* UPDATE FPS is called from atomic context */
	if (event == MDSS_EVENT_PANEL_UPDATE_FPS) {
		hdmi_ctrl->dynamic_fps = (u32) (unsigned long)arg;
		queue_work(hdmi_ctrl->workq, &hdmi_ctrl->fps_work);
		return rc;
	}

	mutex_lock(&hdmi_ctrl->tx_lock);

	DEV_DBG("%s: event = %s suspend=%d, hpd_feature=%d\n", __func__,
		hdmi_tx_get_event_name(event), hdmi_ctrl->panel_suspend,
		hdmi_ctrl->hpd_feature_on);
	int rc = 0;

	switch (event) {
	case MDSS_EVENT_FB_REGISTERED:
		rc = hdmi_tx_sysfs_create(hdmi_ctrl, arg);
	rc = hdmi_tx_sysfs_create(hdmi_ctrl, hdmi_ctrl->evt_arg);
	if (rc) {
		DEV_ERR("%s: hdmi_tx_sysfs_create failed.rc=%d\n",
			__func__, rc);
			goto end;
		goto sysfs_err;
	}
		rc = hdmi_tx_init_features(hdmi_ctrl, arg);
	rc = hdmi_tx_init_features(hdmi_ctrl, hdmi_ctrl->evt_arg);
	if (rc) {
			DEV_ERR("%s: init_features failed.rc=%d\n",
					__func__, rc);
			hdmi_tx_sysfs_remove(hdmi_ctrl);
			goto end;
		DEV_ERR("%s: init_features failed.rc=%d\n", __func__, rc);
		goto init_err;
	}

	rc = hdmi_tx_init_switch_dev(hdmi_ctrl);
	if (rc) {
			DEV_ERR("%s: init switch dev failed.rc=%d\n",
				__func__, rc);
			hdmi_tx_sysfs_remove(hdmi_ctrl);
			goto end;
		DEV_ERR("%s: init switch dev failed.rc=%d\n", __func__, rc);
		goto switch_err;
	}

	if (hdmi_ctrl->pdata.primary || !hdmi_ctrl->pdata.pluggable) {
		reinit_completion(&hdmi_ctrl->hpd_int_done);
		rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
		if (rc) {
				DEV_ERR("%s: hpd_enable failed. rc=%d\n",
					__func__, rc);
				hdmi_tx_sysfs_remove(hdmi_ctrl);
				goto end;
			DEV_ERR("%s: hpd_enable failed. rc=%d\n", __func__, rc);
			goto primary_err;
		} else {
			hdmi_ctrl->hpd_feature_on = true;
		}
	}

		break;
	return 0;

primary_err:
	switch_dev_unregister(&hdmi_ctrl->sdev);
switch_err:
	hdmi_tx_deinit_features(hdmi_ctrl, HDMI_TX_FEAT_MAX);
init_err:
	hdmi_tx_sysfs_remove(hdmi_ctrl);
sysfs_err:
	return rc;
}

static int hdmi_tx_evt_handle_check_param(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int new_vic = -1;
	int rc = 0;

	case MDSS_EVENT_CHECK_PARAMS:
	new_vic = hdmi_tx_get_vic_from_panel_info(hdmi_ctrl,
			(struct mdss_panel_info *)arg);
			hdmi_ctrl->evt_arg);
	if ((new_vic < 0) || (new_vic > HDMI_VFRMT_MAX)) {
		DEV_ERR("%s: invalid or not supported vic\n", __func__);
		goto end;
@@ -4484,15 +4470,21 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
	 * needs a reconfig due to new resolution and
	 * it will issue close and open subsequently.
	 */
		if (new_vic != hdmi_ctrl->vid_cfg.vic)
	if (new_vic != hdmi_ctrl->vid_cfg.vic) {
		rc = 1;
		else
			DEV_DBG("%s: no res change.\n", __func__);
		break;
		DEV_DBG("%s: res change %d ==> %d\n", __func__,
			hdmi_ctrl->vid_cfg.vic, new_vic);
	}
end:
	return rc;
}

static int hdmi_tx_evt_handle_resume(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int rc = 0;

	case MDSS_EVENT_RESUME:
	hdmi_ctrl->panel_suspend = false;
		hdmi_tx_cec_device_suspend(hdmi_ctrl, hdmi_ctrl->panel_suspend);
	hdmi_tx_cec_device_suspend(hdmi_ctrl);

	if (!hdmi_ctrl->hpd_feature_on)
		goto end;
@@ -4511,47 +4503,55 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
		timeout = wait_for_completion_timeout(
			&hdmi_ctrl->hpd_int_done, HZ/10);
		if (!timeout && !hdmi_ctrl->hpd_state) {
				DEV_DBG("%s: cable removed during suspend\n",
					__func__);
			DEV_DBG("%s: cable removed during suspend\n", __func__);
			hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
			hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
			hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
		}
	}
end:
	return rc;
}

		break;

	case MDSS_EVENT_RESET:
		if (!hdmi_ctrl->pdata.cont_splash_enabled &&
static int hdmi_tx_evt_handle_reset(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	if (!hdmi_ctrl->panel_data.panel_info.cont_splash_enabled &&
	    hdmi_ctrl->hpd_initialized) {
		hdmi_tx_set_mode(hdmi_ctrl, false);
		hdmi_tx_phy_reset(hdmi_ctrl);
		hdmi_tx_set_mode(hdmi_ctrl, true);
	}

		break;
	return 0;
}

static int hdmi_tx_evt_handle_unblank(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int rc;

	case MDSS_EVENT_UNBLANK:
	rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, true);
	if (rc) {
			DEV_ERR("%s: ddc power on failed. rc=%d\n",
				__func__, rc);
		} else {
			rc = hdmi_tx_power_on(panel_data);
		DEV_ERR("%s: ddc power on failed. rc=%d\n", __func__, rc);
		goto end;
	}

	rc = hdmi_tx_power_on(hdmi_ctrl);
	if (rc)
				DEV_ERR("%s: hdmi_tx_power_on failed. rc=%d\n",
					__func__, rc);
		DEV_ERR("%s: hdmi_tx_power_on failed. rc=%d\n", __func__, rc);
end:
	return rc;
}
		break;

	case MDSS_EVENT_PANEL_ON:
static int hdmi_tx_evt_handle_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int rc = 0;

	if (!hdmi_ctrl->sim_mode) {
		hdmi_tx_update_hdcp_info(hdmi_ctrl);

		rc = hdmi_tx_start_hdcp(hdmi_ctrl);
		if (rc)
				DEV_ERR("%s: hdcp start failed rc=%d\n",
					__func__, rc);
			DEV_ERR("%s: hdcp start failed rc=%d\n", __func__, rc);
	}

	hdmi_ctrl->timing_gen_on = true;
@@ -4563,9 +4563,12 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
		hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
		hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
	}
		break;

	case MDSS_EVENT_SUSPEND:
	return rc;
}

static int hdmi_tx_evt_handle_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	if (!hdmi_ctrl->hpd_feature_on)
		goto end;

@@ -4573,53 +4576,90 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,
		hdmi_tx_hpd_off(hdmi_ctrl);

	hdmi_ctrl->panel_suspend = true;
		hdmi_tx_cec_device_suspend(hdmi_ctrl, hdmi_ctrl->panel_suspend);
		break;
	hdmi_tx_cec_device_suspend(hdmi_ctrl);
end:
	return 0;
}

	case MDSS_EVENT_BLANK:
static int hdmi_tx_evt_handle_blank(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl))
		hdmi_tx_hdcp_off(hdmi_ctrl);

		break;
	return 0;
}

static int hdmi_tx_evt_handle_panel_off(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	int rc;

	case MDSS_EVENT_PANEL_OFF:
	rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, false);
	if (rc) {
		DEV_ERR("%s: Failed to disable ddc power\n", __func__);
			return rc;
		goto end;
	}

	if (hdmi_ctrl->panel_power_on) {
		hdmi_tx_config_avmute(hdmi_ctrl, 1);
			rc = hdmi_tx_power_off(panel_data);
		rc = hdmi_tx_power_off(hdmi_ctrl);
		if (rc)
			DEV_ERR("%s: hdmi_tx_power_off failed.rc=%d\n",
				__func__, rc);
	} else {
			DEV_DBG("%s: hdmi is already powered off\n", __func__);
		DEV_DBG("%s: hdmi_ctrl is already powered off\n", __func__);
	}

	hdmi_ctrl->timing_gen_on = false;
		break;
end:
	return rc;
}

	case MDSS_EVENT_CLOSE:
		if (panel_data->panel_info.cont_splash_enabled) {
			hdmi_tx_power_off(panel_data);
			panel_data->panel_info.cont_splash_enabled = false;
static int hdmi_tx_evt_handle_close(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	if (hdmi_ctrl->hpd_feature_on && hdmi_ctrl->hpd_initialized &&
	    !hdmi_ctrl->hpd_state)
		hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);

	return 0;
}

static int hdmi_tx_event_handler(struct mdss_panel_data *panel_data,
	int event, void *arg)
{
	int rc = 0;
	hdmi_tx_evt_handler handler;
	struct hdmi_tx_ctrl *hdmi_ctrl =
		hdmi_tx_get_drvdata_from_panel_data(panel_data);

	if (!hdmi_ctrl) {
		DEV_ERR("%s: invalid input\n", __func__);
		rc = -EINVAL;
		goto end;
	}

		if (hdmi_ctrl->hpd_feature_on && hdmi_ctrl->hpd_initialized &&
			!hdmi_ctrl->hpd_state)
			hdmi_tx_hpd_polarity_setup(hdmi_ctrl,
				HPD_CONNECT_POLARITY);
		break;
	/* UPDATE FPS is called from atomic context */
	if (event == MDSS_EVENT_PANEL_UPDATE_FPS) {
		hdmi_ctrl->dynamic_fps = (u32) (unsigned long)arg;
		queue_work(hdmi_ctrl->workq, &hdmi_ctrl->fps_work);
		return rc;
	}
end:

	mutex_lock(&hdmi_ctrl->tx_lock);

	hdmi_ctrl->evt_arg = arg;

	DEV_DBG("%s: event = %s suspend=%d, hpd_feature=%d\n", __func__,
		hdmi_tx_get_event_name(event), hdmi_ctrl->panel_suspend,
		hdmi_ctrl->hpd_feature_on);

	handler = hdmi_ctrl->evt_handler[event];
	if (handler)
		rc = handler(hdmi_ctrl);

	mutex_unlock(&hdmi_ctrl->tx_lock);
end:
	return rc;
} /* hdmi_tx_panel_event_handler */
}

static int hdmi_tx_register_panel(struct hdmi_tx_ctrl *hdmi_ctrl)
{
@@ -4630,7 +4670,7 @@ static int hdmi_tx_register_panel(struct hdmi_tx_ctrl *hdmi_ctrl)
		return -EINVAL;
	}

	hdmi_ctrl->panel_data.event_handler = hdmi_tx_panel_event_handler;
	hdmi_ctrl->panel_data.event_handler = hdmi_tx_event_handler;

	if (!hdmi_ctrl->pdata.primary)
		hdmi_ctrl->vid_cfg.vic = DEFAULT_VIDEO_RESOLUTION;
@@ -5220,6 +5260,29 @@ error:
	return rc;
} /* hdmi_tx_get_dt_data */

static int hdmi_tx_init_event_handler(struct hdmi_tx_ctrl *hdmi_ctrl)
{
	hdmi_tx_evt_handler *handler;

	if (!hdmi_ctrl)
		return -EINVAL;

	handler = hdmi_ctrl->evt_handler;

	handler[MDSS_EVENT_FB_REGISTERED] = hdmi_tx_evt_handle_register;
	handler[MDSS_EVENT_CHECK_PARAMS]  = hdmi_tx_evt_handle_check_param;
	handler[MDSS_EVENT_RESUME]        = hdmi_tx_evt_handle_resume;
	handler[MDSS_EVENT_RESET]         = hdmi_tx_evt_handle_reset;
	handler[MDSS_EVENT_UNBLANK]       = hdmi_tx_evt_handle_unblank;
	handler[MDSS_EVENT_PANEL_ON]      = hdmi_tx_evt_handle_panel_on;
	handler[MDSS_EVENT_SUSPEND]       = hdmi_tx_evt_handle_suspend;
	handler[MDSS_EVENT_BLANK]         = hdmi_tx_evt_handle_blank;
	handler[MDSS_EVENT_PANEL_OFF]     = hdmi_tx_evt_handle_panel_off;
	handler[MDSS_EVENT_CLOSE]         = hdmi_tx_evt_handle_close;

	return 0;
}

static int hdmi_tx_probe(struct platform_device *pdev)
{
	int rc = 0, i;
@@ -5301,6 +5364,13 @@ static int hdmi_tx_probe(struct platform_device *pdev)
		goto failed_dev_init;
	}

	rc = hdmi_tx_init_event_handler(hdmi_ctrl);
	if (rc) {
		DEV_ERR("%s: FAILED: hdmi_tx_init_event_handler. rc=%d\n",
			__func__, rc);
		goto failed_dev_init;
	}

	rc = hdmi_tx_register_panel(hdmi_ctrl);
	if (rc) {
		DEV_ERR("%s: FAILED: register_panel. rc=%d\n", __func__, rc);
+6 −0
Original line number Diff line number Diff line
@@ -121,6 +121,9 @@ struct hdmi_video_config {
	struct hdmi_avi_infoframe_config avi_iframe;
};

struct hdmi_tx_ctrl;
typedef int (*hdmi_tx_evt_handler) (struct hdmi_tx_ctrl *);

struct hdmi_tx_ctrl {
	struct platform_device *pdev;
	u32 hdmi_tx_ver;
@@ -200,6 +203,9 @@ struct hdmi_tx_ctrl {

	char disp_switch_name[MAX_SWITCH_NAME_SIZE];
	bool power_data_enable[HDMI_TX_MAX_PM];

	hdmi_tx_evt_handler evt_handler[MDSS_EVENT_MAX];
	void *evt_arg;
};

#endif /* __MDSS_HDMI_TX_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -260,6 +260,7 @@ enum mdss_intf_events {
	MDSS_EVENT_DSI_RECONFIG_CMD,
	MDSS_EVENT_DSI_RESET_WRITE_PTR,
	MDSS_EVENT_PANEL_TIMING_SWITCH,
	MDSS_EVENT_MAX,
};

struct lcd_panel_info {