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

Commit abb1d6be 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: notify hpd status when audio codec is ready"

parents 4952fa00 c74b2c0e
Loading
Loading
Loading
Loading
+24 −23
Original line number Diff line number Diff line
@@ -934,7 +934,6 @@ static void _sde_hdmi_hotplug_work(struct work_struct *work)
	} else
		sde_free_edid((void **)&sde_hdmi->edid_ctrl);

	sde_hdmi_notify_clients(connector, sde_hdmi->connected);
	drm_helper_hpd_irq_event(connector->dev);
}

@@ -964,7 +963,6 @@ static void _sde_hdmi_connector_irq(struct sde_hdmi *sde_hdmi)
			hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT;
		hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl);

		if (!sde_hdmi->non_pluggable)
		queue_work(hdmi->workq, &sde_hdmi->hpd_work);
	}
}
@@ -1054,6 +1052,25 @@ static int _sde_hdmi_get_cable_status(struct platform_device *pdev, u32 vote)
	return hdmi->power_on && display->connected;
}

static void _sde_hdmi_audio_codec_ready(struct platform_device *pdev)
{
	struct sde_hdmi *display = platform_get_drvdata(pdev);

	if (!display) {
		SDE_ERROR("invalid param(s), display %pK\n", display);
		return;
	}

	mutex_lock(&display->display_lock);
	if (!display->codec_ready) {
		display->codec_ready = true;

		if (display->client_notify_pending)
			sde_hdmi_notify_clients(display, display->connected);
	}
	mutex_unlock(&display->display_lock);
}

static int _sde_hdmi_ext_disp_init(struct sde_hdmi *display)
{
	int rc = 0;
@@ -1073,6 +1090,8 @@ static int _sde_hdmi_ext_disp_init(struct sde_hdmi *display)
		_sde_hdmi_get_audio_edid_blk;
	display->ext_audio_data.codec_ops.cable_status =
		_sde_hdmi_get_cable_status;
	display->ext_audio_data.codec_ops.codec_ready =
		_sde_hdmi_audio_codec_ready;

	if (!display->pdev->dev.of_node) {
		SDE_ERROR("[%s]cannot find sde_hdmi of_node\n", display->name);
@@ -1101,17 +1120,14 @@ static int _sde_hdmi_ext_disp_init(struct sde_hdmi *display)
	return rc;
}

void sde_hdmi_notify_clients(struct drm_connector *connector,
	bool connected)
void sde_hdmi_notify_clients(struct sde_hdmi *display, bool connected)
{
	struct sde_connector *c_conn = to_sde_connector(connector);
	struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;
	int state = connected ?
		EXT_DISPLAY_CABLE_CONNECT : EXT_DISPLAY_CABLE_DISCONNECT;

	if (display && display->ext_audio_data.intf_ops.hpd) {
		struct hdmi *hdmi = display->ctrl.ctrl;
		u32 flags = MSM_EXT_DISP_HPD_VIDEO;
		u32 flags = MSM_EXT_DISP_HPD_ASYNC_VIDEO;

		if (hdmi->hdmi_mode)
			flags |= MSM_EXT_DISP_HPD_AUDIO;
@@ -1121,21 +1137,6 @@ void sde_hdmi_notify_clients(struct drm_connector *connector,
	}
}

void sde_hdmi_ack_state(struct drm_connector *connector,
	enum drm_connector_status status)
{
	struct sde_connector *c_conn = to_sde_connector(connector);
	struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;

	if (display) {
		struct hdmi *hdmi = display->ctrl.ctrl;

		if (hdmi->hdmi_mode && display->ext_audio_data.intf_ops.notify)
			display->ext_audio_data.intf_ops.notify(
				display->ext_pdev, status);
	}
}

void sde_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
{
	uint32_t ctrl = 0;
+6 −3
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ struct sde_hdmi_ctrl {
 * @connected:        If HDMI display is connected.
 * @is_tpg_enabled:   TPG state.
 * @hpd_work:         HPD work structure.
 * @codec_ready:      If audio codec is ready.
 * @client_notify_pending: If there is client notification pending.
 * @root:             Debug fs root entry.
 */
struct sde_hdmi {
@@ -109,6 +111,8 @@ struct sde_hdmi {
	bool is_tpg_enabled;

	struct work_struct hpd_work;
	bool codec_ready;
	bool client_notify_pending;

	/* DEBUG FS */
	struct dentry *root;
@@ -379,13 +383,12 @@ int sde_hdmi_config_avmute(struct hdmi *hdmi, bool set);

/**
 * sde_hdmi_notify_clients() - notify hdmi clients of the connection status.
 * @connector:     Handle to the drm_connector.
 * @display:       Handle to sde_hdmi.
 * @connected:     connection status.
 *
 * Return: void.
 */
void sde_hdmi_notify_clients(struct drm_connector *connector,
	bool connected);
void sde_hdmi_notify_clients(struct sde_hdmi *display, bool connected);

/**
 * sde_hdmi_ack_state() - acknowledge the connection status.
+12 −29
Original line number Diff line number Diff line
@@ -372,6 +372,8 @@ static void _sde_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
	struct hdmi_phy *phy = hdmi->phy;
	struct sde_connector *c_conn = to_sde_connector(hdmi->connector);
	struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;

	DRM_DEBUG("power up");

@@ -388,41 +390,20 @@ static void _sde_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
	if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
		hdmi_hdcp_ctrl_on(hdmi->hdcp_ctrl);

	sde_hdmi_ack_state(hdmi->connector, EXT_DISPLAY_CABLE_CONNECT);
}

static void sde_hdmi_force_update_audio(struct drm_connector *connector,
	enum drm_connector_status status)
{
	struct sde_connector *c_conn = to_sde_connector(connector);
	struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;

	if (display && display->non_pluggable) {
		display->ext_audio_data.intf_ops.hpd(display->ext_pdev,
				display->ext_audio_data.type,
				status,
				MSM_EXT_DISP_HPD_AUDIO);
	}
	mutex_lock(&display->display_lock);
	if (display->codec_ready)
		sde_hdmi_notify_clients(display, display->connected);
	else
		display->client_notify_pending = true;
	mutex_unlock(&display->display_lock);
}

static void _sde_hdmi_bridge_enable(struct drm_bridge *bridge)
{
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;

	/* force update audio ops when there's no HPD event */
	sde_hdmi_force_update_audio(hdmi->connector,
		EXT_DISPLAY_CABLE_CONNECT);
}

static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge)
{
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;

	/* force update audio ops when there's no HPD event */
	sde_hdmi_force_update_audio(hdmi->connector,
		EXT_DISPLAY_CABLE_DISCONNECT);
}

static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
@@ -430,6 +411,10 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
	struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
	struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
	struct hdmi_phy *phy = hdmi->phy;
	struct sde_connector *c_conn = to_sde_connector(hdmi->connector);
	struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;

	sde_hdmi_notify_clients(display, display->connected);

	if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
		hdmi_hdcp_ctrl_off(hdmi->hdcp_ctrl);
@@ -446,8 +431,6 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
		_sde_hdmi_bridge_power_off(bridge);
		hdmi->power_on = false;
	}

	sde_hdmi_ack_state(hdmi->connector, EXT_DISPLAY_CABLE_DISCONNECT);
}

static void _sde_hdmi_bridge_set_avi_infoframe(struct hdmi *hdmi,
+12 −5
Original line number Diff line number Diff line
@@ -654,6 +654,7 @@ int msm_ext_disp_register_audio_codec(struct platform_device *pdev,
{
	int ret = 0;
	struct msm_ext_disp *ext_disp = NULL;
	struct msm_ext_disp_list *node = NULL;

	if (!pdev || !ops) {
		pr_err("Invalid params\n");
@@ -671,17 +672,23 @@ int msm_ext_disp_register_audio_codec(struct platform_device *pdev,
	if ((ext_disp->current_disp != EXT_DISPLAY_TYPE_MAX)
			&& ext_disp->ops) {
		pr_err("Codec already registered\n");
		ret = -EINVAL;
		goto end;
		mutex_unlock(&ext_disp->lock);
		return -EINVAL;
	}

	ext_disp->ops = ops;

	pr_debug("audio codec registered\n");

end:
	mutex_unlock(&ext_disp->lock);

	list_for_each_entry(node, &ext_disp->display_list, list) {
		struct msm_ext_disp_init_data *data = node->data;

		if (data->codec_ops.codec_ready)
			data->codec_ops.codec_ready(data->pdev);
	}

	pr_debug("audio codec registered\n");

	return ret;
}

+2 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ struct msm_ext_disp_intf_ops {
 * @cable_status: cable connected/disconnected
 * @get_intf_id: id of connected interface
 * @acknowledge: acknowledge audio status
 * @codec_ready: notify when codec is ready
 */
struct msm_ext_disp_audio_codec_ops {
	int (*audio_info_setup)(struct platform_device *pdev,
@@ -124,6 +125,7 @@ struct msm_ext_disp_audio_codec_ops {
	int (*get_intf_id)(struct platform_device *pdev);
	void (*teardown_done)(struct platform_device *pdev);
	int (*acknowledge)(struct platform_device *pdev, u32 ack);
	void (*codec_ready)(struct platform_device *pdev);
};

/*