drm/rockchip: analogix_dp: Protect kernel logo with loader_protect callback

Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
Change-Id: I16a1653aac3f6475f898390e83b09c93b706429e
This commit is contained in:
Wyon Bi
2021-08-11 16:23:45 +08:00
committed by Tao Huang
parent bb1c2a5cc5
commit 48fb554efc
3 changed files with 67 additions and 13 deletions

View File

@@ -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)
{

View File

@@ -29,8 +29,6 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#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;

View File

@@ -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_ */