Commit b93f19d8 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Dmitry Baryshkov
Browse files

drm/msm/hdmi: ensure that HDMI is up if HPD is requested



The HDMI block needs to be enabled to properly generate HPD events. Make
sure it is not turned off in the disable paths if HPD delivery is enabled.

Reviewed-by: default avatarJessica Zhang <quic_jesszhan@quicinc.com>
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/651722/
Link: https://lore.kernel.org/r/20250505-fd-hdmi-hpd-v5-12-48541f76318c@oss.qualcomm.com


Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
parent 969bbbf7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
	hdmi->pdev = pdev;
	hdmi->config = config;
	spin_lock_init(&hdmi->reg_lock);
	mutex_init(&hdmi->state_mutex);

	ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 1, 0, NULL, &hdmi->next_bridge);
	if (ret && ret != -ENODEV)
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ struct hdmi {

	/* video state: */
	bool power_on;
	bool hpd_enabled;
	struct mutex state_mutex; /* protects two booleans */
	unsigned long int pixclock;

	void __iomem *mmio;
+7 −1
Original line number Diff line number Diff line
@@ -302,11 +302,13 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,

	msm_hdmi_set_timings(hdmi, &crtc_state->adjusted_mode);

	mutex_lock(&hdmi->state_mutex);
	if (!hdmi->power_on) {
		msm_hdmi_phy_resource_enable(phy);
		msm_hdmi_power_on(bridge);
		hdmi->power_on = true;
	}
	mutex_unlock(&hdmi->state_mutex);

	if (connector->display_info.is_hdmi)
		msm_hdmi_audio_update(hdmi);
@@ -332,7 +334,10 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
		msm_hdmi_hdcp_off(hdmi->hdcp_ctrl);

	DBG("power down");
	msm_hdmi_set_mode(hdmi, false);

	/* Keep the HDMI enabled if the HPD is enabled */
	mutex_lock(&hdmi->state_mutex);
	msm_hdmi_set_mode(hdmi, hdmi->hpd_enabled);

	msm_hdmi_phy_powerdown(phy);

@@ -343,6 +348,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
			msm_hdmi_audio_update(hdmi);
		msm_hdmi_phy_resource_disable(phy);
	}
	mutex_unlock(&hdmi->state_mutex);
}

static void msm_hdmi_set_timings(struct hdmi *hdmi,
+8 −1
Original line number Diff line number Diff line
@@ -76,10 +76,14 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
	if (ret)
		return ret;

	mutex_lock(&hdmi->state_mutex);
	msm_hdmi_set_mode(hdmi, false);
	msm_hdmi_phy_reset(hdmi);
	msm_hdmi_set_mode(hdmi, true);

	hdmi->hpd_enabled = true;
	mutex_unlock(&hdmi->state_mutex);

	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);

	/* enable HPD events: */
@@ -109,7 +113,10 @@ void msm_hdmi_hpd_disable(struct hdmi *hdmi)
	/* Disable HPD interrupt */
	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);

	msm_hdmi_set_mode(hdmi, false);
	mutex_lock(&hdmi->state_mutex);
	hdmi->hpd_enabled = false;
	msm_hdmi_set_mode(hdmi, hdmi->power_on);
	mutex_unlock(&hdmi->state_mutex);

	pm_runtime_put(dev);
}