drm/rockchip: Make the DRM panel as part of Rockchip DRM sub devices for panel loader protect

In order to support the loader protect function of more panel
drivers, we add the DRM panel as part of Rockchip DRM sub devices.

The panel-simple driver always is regarded as a panel driver demo of
Rockchip platforms, so we first add the Rockchip DRM sub_dev for it.

The panel drivers that adapt to Rockchip DRM drivers can call
rockchip_drm_register_sub_dev()/rockchip_drm_unregister_sub_dev() to
register/unregister DRM sub_dev, and then invoke
rockchip_drm_panel_loader_protect() to achieve the panel loader
protect function.

Change-Id: Ibc302c3f3677e0c55545e90af29d7a87444c2e21
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
This commit is contained in:
Damon Ding
2025-06-29 16:11:58 +08:00
parent d8e42edcd6
commit 65f19639f9
9 changed files with 51 additions and 40 deletions

View File

@@ -45,7 +45,7 @@
#include <drm/drm_panel.h>
#include <drm/display/drm_dsc.h>
#include "panel-simple.h"
#include "../rockchip/rockchip_drm_drv.h"
enum panel_simple_cmd_type {
CMD_TYPE_DEFAULT,
@@ -220,6 +220,8 @@ struct panel_simple {
enum drm_panel_orientation orientation;
struct rockchip_panel_notifier panel_notifier;
struct rockchip_drm_sub_dev sub_dev;
};
static inline void panel_simple_msleep(unsigned int msecs)
@@ -519,23 +521,29 @@ static int panel_simple_regulator_disable(struct panel_simple *p)
return 0;
}
int panel_simple_loader_protect(struct drm_panel *panel)
static int panel_simple_loader_protect(struct rockchip_drm_sub_dev *sub_dev, bool on)
{
struct panel_simple *p = to_panel_simple(panel);
struct panel_simple *p = container_of(sub_dev, struct panel_simple, sub_dev);
int err;
err = panel_simple_regulator_enable(p);
if (err < 0) {
dev_err(panel->dev, "failed to enable supply: %d\n", err);
return err;
}
if (on) {
err = panel_simple_regulator_enable(p);
if (err < 0) {
dev_err(p->base.dev, "failed to enable supply: %d\n", err);
return err;
}
p->prepared = true;
p->enabled = true;
p->prepared = true;
p->enabled = true;
} else {
p->enabled = false;
p->prepared = false;
panel_simple_regulator_disable(p);
}
return 0;
}
EXPORT_SYMBOL(panel_simple_loader_protect);
static int panel_simple_disable(struct drm_panel *panel)
{
@@ -1003,6 +1011,10 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
drm_panel_add(&panel->base);
panel->sub_dev.of_node = dev->of_node;
panel->sub_dev.loader_protect = panel_simple_loader_protect;
rockchip_drm_register_sub_dev(&panel->sub_dev);
return 0;
free_ddc:
@@ -1016,6 +1028,8 @@ static void panel_simple_remove(struct device *dev)
{
struct panel_simple *panel = dev_get_drvdata(dev);
rockchip_drm_unregister_sub_dev(&panel->sub_dev);
drm_panel_remove(&panel->base);
drm_panel_disable(&panel->base);
drm_panel_unprepare(&panel->base);

View File

@@ -1,19 +0,0 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2021 Rockchip Electronics Co., Ltd.
* Author: Sandy Huang <hjc@rock-chips.com>
*/
#ifndef PANEL_SIMPLE_H
#define PANEL_SIMPLE_H
#include <drm/drm_panel.h>
#if IS_REACHABLE(CONFIG_DRM_PANEL_SIMPLE)
int panel_simple_loader_protect(struct drm_panel *panel);
#else
static inline int panel_simple_loader_protect(struct drm_panel *panel)
{
return 0;
}
#endif
#endif

View File

@@ -270,7 +270,7 @@ static int rockchip_dp_loader_protect(struct rockchip_drm_sub_dev *sub_dev, bool
return 0;
if (plat_data->panel)
panel_simple_loader_protect(plat_data->panel);
rockchip_drm_panel_loader_protect(plat_data->panel, on);
ret = analogix_dp_loader_protect(dp->adp);
if (ret) {

View File

@@ -921,7 +921,7 @@ static int dw_mipi_dsi_rockchip_encoder_loader_protect(struct rockchip_drm_sub_d
sub_dev);
if (dsi->panel)
panel_simple_loader_protect(dsi->panel);
rockchip_drm_panel_loader_protect(dsi->panel, on);
dw_mipi_dsi_rockchip_loader_protect(dsi, on);

View File

@@ -1196,7 +1196,7 @@ static int dw_mipi_dsi2_encoder_loader_protect(struct rockchip_drm_sub_dev *sub_
struct dw_mipi_dsi2 *dsi2 = container_of(sub_dev, struct dw_mipi_dsi2, sub_dev);
if (dsi2->panel)
panel_simple_loader_protect(dsi2->panel);
rockchip_drm_panel_loader_protect(dsi2->panel, on);
dw_mipi_dsi2_loader_protect(dsi2, on);

View File

@@ -382,7 +382,7 @@ void rockchip_connector_update_vfp_for_vrr(struct drm_crtc *crtc, struct drm_dis
mutex_lock(&rockchip_drm_sub_dev_lock);
list_for_each_entry(sub_dev, &rockchip_drm_sub_dev_list, list) {
if (sub_dev->connector->state->crtc == crtc) {
if (sub_dev->connector && sub_dev->connector->state->crtc == crtc) {
if (sub_dev->update_vfp_for_vrr)
sub_dev->update_vfp_for_vrr(sub_dev->connector, mode, vfp);
}
@@ -432,7 +432,7 @@ int rockchip_drm_get_sub_dev_type(void)
mutex_lock(&rockchip_drm_sub_dev_lock);
list_for_each_entry(sub_dev, &rockchip_drm_sub_dev_list, list) {
if (sub_dev->connector->encoder) {
if (sub_dev->connector && sub_dev->connector->encoder) {
connector_type = sub_dev->connector->connector_type;
break;
}
@@ -451,7 +451,8 @@ u32 rockchip_drm_get_scan_line_time_ns(void)
mutex_lock(&rockchip_drm_sub_dev_lock);
list_for_each_entry(sub_dev, &rockchip_drm_sub_dev_list, list) {
if (sub_dev->connector->encoder && sub_dev->connector->state->crtc) {
if (sub_dev->connector && sub_dev->connector->encoder &&
sub_dev->connector->state->crtc) {
mode = &sub_dev->connector->state->crtc->state->adjusted_mode;
linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, mode->crtc_clock);
break;
@@ -1790,6 +1791,21 @@ static void rockchip_drm_error_event_fini(struct drm_device *drm_dev)
device_remove_file(drm_dev->dev, &dev_attr_error_event);
}
int rockchip_drm_panel_loader_protect(struct drm_panel *panel, bool on)
{
struct rockchip_drm_sub_dev *sub_dev;
if (!panel)
return -EINVAL;
sub_dev = rockchip_drm_get_sub_dev(panel->dev->of_node);
if (sub_dev && sub_dev->loader_protect)
return sub_dev->loader_protect(sub_dev, on);
return 0;
}
EXPORT_SYMBOL(rockchip_drm_panel_loader_protect);
static int rockchip_drm_bind(struct device *dev)
{
struct drm_device *drm_dev;

View File

@@ -15,6 +15,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_edid.h>
#include <drm/drm_gem.h>
#include <drm/drm_panel.h>
#include <drm/rockchip_drm.h>
#include <linux/media-bus-format.h>
@@ -23,8 +24,6 @@
#include <soc/rockchip/rockchip_dmc.h>
#include "../panel/panel-simple.h"
#include "rockchip_drm_debugfs.h"
#define ROCKCHIP_MAX_FB_BUFFER 3
@@ -693,6 +692,7 @@ const char *rockchip_drm_modifier_to_string(uint64_t modifier);
void rockchip_drm_reset_iommu_fault_handler_rate_limit(void);
void rockchip_drm_send_error_event(struct rockchip_drm_private *priv,
enum rockchip_drm_error_event_type event);
int rockchip_drm_panel_loader_protect(struct drm_panel *panel, bool on);
__printf(3, 4)
void rockchip_drm_dbg(const struct device *dev,

View File

@@ -436,7 +436,7 @@ static int rockchip_lvds_encoder_loader_protect(struct rockchip_drm_sub_dev *sub
struct rockchip_lvds *lvds = container_of(sub_dev, struct rockchip_lvds, sub_dev);
if (lvds->panel)
panel_simple_loader_protect(lvds->panel);
rockchip_drm_panel_loader_protect(lvds->panel, on);
if (on) {

View File

@@ -417,7 +417,7 @@ static int rockchip_rgb_encoder_loader_protect(struct rockchip_drm_sub_dev *sub_
}
if (rgb->panel)
panel_simple_loader_protect(rgb->panel);
rockchip_drm_panel_loader_protect(rgb->panel, on);
if (on) {
phy_init(rgb->phy);