mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
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: Jessica Zhang <quic_jesszhan@quicinc.com> Signed-off-by: Dmitry 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: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
This commit is contained in:
parent
969bbbf7fb
commit
b93f19d8d0
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user