From cd51e4eb733850648d5ee34b118b8a3ef4b89682 Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Tue, 17 Dec 2024 10:27:25 +0800 Subject: [PATCH] drm/bridge: synopsys: dw-hdmi-qp: support pre disable/post enable crtc Change-Id: If11faf7c1ca6079f2f6fef4c8b914b07615b65b3 Signed-off-by: Zhang Yubing --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 5 +++ drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 44 ++++++++++++++++++++ include/drm/bridge/dw_hdmi.h | 2 + 3 files changed, 51 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 36ba988e288a..8dbe50439f84 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -3496,6 +3496,8 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge, extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false); handle_plugged_change(hdmi, false); + if (hdmi->plat_data->crtc_pre_disable) + hdmi->plat_data->crtc_pre_disable(data, bridge->encoder->crtc); mutex_lock(&hdmi->mutex); if (hdmi->dclk_en) { @@ -3570,6 +3572,9 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, if (link_cfg && link_cfg->frl_mode) queue_work(hdmi->workqueue, &hdmi->flt_work); + if (hdmi->plat_data->crtc_post_enable) + hdmi->plat_data->crtc_post_enable(data, bridge->encoder->crtc); + dw_hdmi_qp_init_audio_infoframe(hdmi); dw_hdmi_qp_audio_enable(hdmi); hdmi_clk_regenerator_update_pixel_clock(hdmi); diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 232d6a60e406..e05b61cea886 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -3200,6 +3200,46 @@ static void dw_hdmi_rockchip_get_mode_color_caps(struct drm_connector *connector hdmi->mode_color_caps, &connector->base, property); } +static void dw_hdmi_rockchip_crtc_post_enable(void *data, struct drm_crtc *crtc) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + int output_if; + + switch (hdmi->id) { + case 0: + output_if = VOP_OUTPUT_IF_HDMI0; + break; + case 1: + output_if = VOP_OUTPUT_IF_HDMI1; + break; + default: + dev_err(hdmi->dev, "invalid id:%d\n", hdmi->id); + return; + } + + rockchip_drm_crtc_output_post_enable(crtc, output_if); +} + +static void dw_hdmi_rockchip_crtc_pre_disable(void *data, struct drm_crtc *crtc) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + int output_if; + + switch (hdmi->id) { + case 0: + output_if = VOP_OUTPUT_IF_HDMI0; + break; + case 1: + output_if = VOP_OUTPUT_IF_HDMI1; + break; + default: + dev_err(hdmi->dev, "invalid id:%d\n", hdmi->id); + return; + } + + rockchip_drm_crtc_output_pre_disable(crtc, output_if); +} + static const struct drm_prop_enum_list color_depth_enum_list[] = { { 0, "Automatic" }, /* Prefer highest color depth */ { 8, "24bit" }, @@ -4433,6 +4473,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, dw_hdmi_rockchip_force_frl_rate; plat_data->get_mode_color_caps = dw_hdmi_rockchip_get_mode_color_caps; + plat_data->crtc_pre_disable = + dw_hdmi_rockchip_crtc_pre_disable; + plat_data->crtc_post_enable = + dw_hdmi_rockchip_crtc_post_enable; plat_data->property_ops = &dw_hdmi_rockchip_property_ops; secondary = rockchip_hdmi_find_by_id(dev->driver, !hdmi->id); diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index d02952ceafeb..9580f6e43d3c 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -284,6 +284,8 @@ struct dw_hdmi_plat_data { void (*force_frl_rate)(void *data, u8 rate); void (*get_mode_color_caps)(struct drm_connector *connector, struct drm_display_info *info, void *data); + void (*crtc_pre_disable)(void *data, struct drm_crtc *crtc); + void (*crtc_post_enable)(void *data, struct drm_crtc *crtc); /* Vendor Property support */ const struct dw_hdmi_property_ops *property_ops;