From 48fb554efc598b6a7846b3868eec19faf3c9f23f Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Wed, 11 Aug 2021 16:23:45 +0800 Subject: [PATCH] drm/rockchip: analogix_dp: Protect kernel logo with loader_protect callback Signed-off-by: Wyon Bi Change-Id: I16a1653aac3f6475f898390e83b09c93b706429e --- .../drm/bridge/analogix/analogix_dp_core.c | 25 +++++++++ .../gpu/drm/rockchip/analogix_dp-rockchip.c | 53 ++++++++++++++----- include/drm/bridge/analogix_dp.h | 2 + 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index b8d4a5f49924..01d4eea49933 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1222,6 +1222,14 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, return 0; } +static void analogix_dp_bridge_detach(struct drm_bridge *bridge) +{ + struct analogix_dp_device *dp = bridge->driver_private; + + if (dp->plat_data->detach) + dp->plat_data->detach(dp->plat_data, bridge); +} + static struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp, struct drm_atomic_state *state) @@ -1538,6 +1546,7 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = { .atomic_post_disable = analogix_dp_bridge_atomic_post_disable, .mode_set = analogix_dp_bridge_mode_set, .attach = analogix_dp_bridge_attach, + .detach = analogix_dp_bridge_detach, .mode_valid = analogix_dp_bridge_mode_valid, }; @@ -1651,6 +1660,22 @@ int analogix_dp_audio_get_eld(struct analogix_dp_device *dp, u8 *buf, size_t len } EXPORT_SYMBOL_GPL(analogix_dp_audio_get_eld); +int analogix_dp_loader_protect(struct analogix_dp_device *dp) +{ + int ret; + + ret = pm_runtime_resume_and_get(dp->dev); + if (ret) { + dev_err(dp->dev, "failed to get runtime PM: %d\n", ret); + return ret; + } + + dp->dpms_mode = DRM_MODE_DPMS_ON; + + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_loader_protect); + struct analogix_dp_device * analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) { diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 463e3eb4e475..61bb9a26cf57 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -29,8 +29,6 @@ #include #include -#include "../bridge/analogix/analogix_dp_core.h" - #include "rockchip_drm_drv.h" #include "rockchip_drm_vop.h" @@ -169,11 +167,26 @@ static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data, return 0; } +static void rockchip_dp_loader_protect(struct drm_encoder *encoder, bool on) +{ + struct rockchip_dp_device *dp = to_dp(encoder); + struct analogix_dp_plat_data *plat_data = &dp->plat_data; + + if (!on) + return; + + if (plat_data->panel) + panel_simple_loader_protect(plat_data->panel); + + analogix_dp_loader_protect(dp->adp); +} + static int rockchip_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, struct drm_bridge *bridge, struct drm_connector *connector) { struct rockchip_dp_device *dp = to_dp(plat_data); + struct rockchip_drm_sub_dev *sdev = &dp->sub_dev; int ret; if (dp->bridge) { @@ -184,9 +197,26 @@ static int rockchip_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, } } + if (connector) { + sdev->connector = connector; + sdev->of_node = dp->dev->of_node; + sdev->loader_protect = rockchip_dp_loader_protect; + rockchip_drm_register_sub_dev(sdev); + } + return 0; } +static void rockchip_dp_bridge_detach(struct analogix_dp_plat_data *plat_data, + struct drm_bridge *bridge) +{ + struct rockchip_dp_device *dp = to_dp(plat_data); + struct rockchip_drm_sub_dev *sdev = &dp->sub_dev; + + if (sdev->connector) + rockchip_drm_unregister_sub_dev(sdev); +} + static bool rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, @@ -390,10 +420,6 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, dp->plat_data.encoder = &dp->encoder; - ret = analogix_dp_bind(dp->adp, drm_dev); - if (ret) - goto err_cleanup_encoder; - if (dp->data->audio) { struct hdmi_codec_pdata codec_data = { .ops = &rockchip_dp_audio_codec_ops, @@ -413,13 +439,15 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, } } - dp->sub_dev.connector = &dp->adp->connector; - if (dp->sub_dev.connector) { - dp->sub_dev.of_node = dev->of_node; - rockchip_drm_register_sub_dev(&dp->sub_dev); - } + ret = analogix_dp_bind(dp->adp, drm_dev); + if (ret) + goto err_unregister_audio_pdev; return 0; + +err_unregister_audio_pdev: + if (dp->audio_pdev) + platform_device_unregister(dp->audio_pdev); err_cleanup_encoder: dp->encoder.funcs->destroy(&dp->encoder); return ret; @@ -430,8 +458,6 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master, { struct rockchip_dp_device *dp = dev_get_drvdata(dev); - if (dp->sub_dev.connector) - rockchip_drm_unregister_sub_dev(&dp->sub_dev); if (dp->audio_pdev) platform_device_unregister(dp->audio_pdev); analogix_dp_unbind(dp->adp); @@ -474,6 +500,7 @@ static int rockchip_dp_probe(struct platform_device *pdev) dp->plat_data.power_off = rockchip_dp_powerdown; dp->plat_data.get_modes = rockchip_dp_get_modes; dp->plat_data.attach = rockchip_dp_bridge_attach; + dp->plat_data.detach = rockchip_dp_bridge_detach; dp->plat_data.skip_connector = !!bridge; dp->bridge = bridge; diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 2ffa52afcf43..6f97396232dd 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -44,6 +44,7 @@ struct analogix_dp_plat_data { int (*power_off)(struct analogix_dp_plat_data *); int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *, struct drm_connector *); + void (*detach)(struct analogix_dp_plat_data *, struct drm_bridge *); int (*get_modes)(struct analogix_dp_plat_data *, struct drm_connector *); }; @@ -67,5 +68,6 @@ void analogix_dp_audio_shutdown(struct analogix_dp_device *dp); int analogix_dp_audio_startup(struct analogix_dp_device *dp); int analogix_dp_audio_get_eld(struct analogix_dp_device *dp, u8 *buf, size_t len); +int analogix_dp_loader_protect(struct analogix_dp_device *dp); #endif /* _ANALOGIX_DP_H_ */