drm/rockchip: Move the init/cleanup of self refresh helper from VOP/VOP2 to eDP/RGB drivers

Before this commit, the drm_self_refresh_helper_init() was called
in &component_ops.bind() of VOP/VOP2 drivers. The VOP or VPs,
which do not want to enable PSR functionality, will also initialize
the self refresh helper.

Since it wastes resources(e.g., allocating &drm_self_refresh_data and
initializing &drm_self_refresh_data.entry_work), we move the init and
cleanup process from bind()/unbind() of VOP/VOP2 drivers to the ones
of eDP/RGB drivers, which can support PSR functionality.

Change-Id: Ie7643b54f42ea3d5ab7b0cdbc77ccfdb06c614b9
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
This commit is contained in:
Damon Ding
2025-07-12 09:38:16 +08:00
parent 554eda652f
commit 3b97d716d5
4 changed files with 73 additions and 16 deletions

View File

@@ -27,6 +27,7 @@
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include "rockchip_drm_drv.h"
@@ -634,6 +635,38 @@ static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
return 0;
}
static void rockchip_dp_drm_self_refresh_helper_init(struct rockchip_dp_device *dp)
{
struct drm_encoder *encoder = &dp->encoder.encoder;
struct drm_crtc *crtc;
int ret;
if (!dp->plat_data.disable_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc)) {
ret = drm_self_refresh_helper_init(crtc);
if (ret)
dev_warn(dp->dev,
"Failed to init self refresh helper for crtc-%d\n",
drm_crtc_index(crtc));
}
}
}
}
static void rockchip_dp_drm_self_refresh_helper_cleanup(struct rockchip_dp_device *dp)
{
struct drm_encoder *encoder = &dp->encoder.encoder;
struct drm_crtc *crtc;
if (!dp->plat_data.disable_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc))
drm_self_refresh_helper_cleanup(crtc);
}
}
}
static int rockchip_dp_bind(struct device *dev, struct device *master,
void *data)
{
@@ -657,6 +690,8 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
if (ret)
goto err_unregister_audio_pdev;
rockchip_dp_drm_self_refresh_helper_init(dp);
return 0;
err_unregister_audio_pdev:
@@ -672,6 +707,7 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
if (dp->audio_pdev)
platform_device_unregister(dp->audio_pdev);
rockchip_dp_drm_self_refresh_helper_cleanup(dp);
analogix_dp_unbind(dp->adp);
dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder);
}

View File

@@ -37,7 +37,6 @@
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_vblank.h>
#include <drm/drm_writeback.h>
@@ -5744,11 +5743,6 @@ static int vop_create_crtc(struct vop *vop)
VOP_ATTACH_MODE_CONFIG_PROP(tv_bottom_margin_property, 100);
#undef VOP_ATTACH_MODE_CONFIG_PROP
vop_crtc_create_feature_property(vop, crtc);
ret = drm_self_refresh_helper_init(crtc);
if (ret)
DRM_DEV_DEBUG_KMS(vop->dev,
"Failed to init %s with SR helpers %d, ignoring\n",
crtc->name, ret);
if (vop->lut_regs) {
u16 *r_base, *g_base, *b_base;
@@ -5802,8 +5796,6 @@ static void vop_destroy_crtc(struct vop *vop)
struct drm_device *drm_dev = vop->drm_dev;
struct drm_plane *plane, *tmp;
drm_self_refresh_helper_cleanup(crtc);
of_node_put(crtc->port);
/*

View File

@@ -15,7 +15,6 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_writeback.h>
#ifdef CONFIG_DRM_ANALOGIX_DP
@@ -15370,12 +15369,6 @@ static int vop2_create_crtc(struct vop2 *vop2, uint8_t enabled_vp_mask)
vop2_crtc_create_feature_property(vop2, crtc);
vop2_crtc_create_vrr_property(vop2, crtc);
ret = drm_self_refresh_helper_init(crtc);
if (ret)
DRM_DEV_DEBUG_KMS(vop2->dev,
"Failed to init %s with SR helpers %d, ignoring\n",
crtc->name, ret);
if (vp_data->feature & (VOP_FEATURE_VIVID_HDR | VOP_FEATURE_DOVI))
vop2_crtc_create_hdr_property(vop2, crtc);
if (vp_data->feature & VOP_FEATURE_POST_ACM)
@@ -15463,7 +15456,6 @@ static void vop2_destroy_crtc(struct drm_crtc *crtc)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
drm_self_refresh_helper_cleanup(crtc);
if (vp->hdr_lut_gem_obj)
rockchip_gem_free_object(&vp->hdr_lut_gem_obj->base);

View File

@@ -22,6 +22,7 @@
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <uapi/linux/videodev2.h>
@@ -914,6 +915,38 @@ static struct backlight_device *rockchip_mcu_panel_find_backlight(struct rockchi
return bd;
}
static void rockchip_rgb_drm_self_refresh_helper_init(struct rockchip_rgb *rgb)
{
struct drm_encoder *encoder = &rgb->encoder;
struct drm_crtc *crtc;
int ret;
if (rgb->np_mcu_panel && rgb->support_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc)) {
ret = drm_self_refresh_helper_init(crtc);
if (ret)
dev_warn(rgb->dev,
"Failed to init self refresh helper for crtc-%d\n",
drm_crtc_index(crtc));
}
}
}
}
static void rockchip_rgb_drm_self_refresh_helper_cleanup(struct rockchip_rgb *rgb)
{
struct drm_encoder *encoder = &rgb->encoder;
struct drm_crtc *crtc;
if (rgb->np_mcu_panel && rgb->support_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc))
drm_self_refresh_helper_cleanup(crtc);
}
}
}
static int rockchip_rgb_bind(struct device *dev, struct device *master,
void *data)
{
@@ -1019,6 +1052,8 @@ static int rockchip_rgb_bind(struct device *dev, struct device *master,
rockchip_drm_register_sub_dev(&rgb->sub_dev);
}
rockchip_rgb_drm_self_refresh_helper_init(rgb);
return 0;
err_free_connector:
@@ -1033,6 +1068,8 @@ static void rockchip_rgb_unbind(struct device *dev, struct device *master,
{
struct rockchip_rgb *rgb = dev_get_drvdata(dev);
rockchip_rgb_drm_self_refresh_helper_cleanup(rgb);
if (rgb->sub_dev.connector)
rockchip_drm_unregister_sub_dev(&rgb->sub_dev);
if (rgb->panel)