From b05ec6d2403c01093cbf6c774e8628d03eb397a6 Mon Sep 17 00:00:00 2001 From: Huang Jiachai Date: Thu, 27 Jul 2017 15:23:31 +0800 Subject: [PATCH] drm/rockchip: add loader protect for encoder Change-Id: I9fa1e949a55d8778b44ff809630337d5d35ffa11 Signed-off-by: Huang Jiachai --- drivers/gpu/drm/drm_atomic_helper.c | 5 ++++ drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 8 +++++++ drivers/gpu/drm/rockchip/rockchip_lvds.c | 26 ++++++++++++++------- include/drm/drm_crtc.h | 1 + include/drm/drm_crtc_helper.h | 1 + 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ccd713baa86c..c486b977474b 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -628,6 +628,11 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) */ drm_bridge_disable(encoder->bridge); + if (encoder->loader_protect) { + if (funcs->loader_protect) + funcs->loader_protect(encoder, false); + encoder->loader_protect = false; + } /* Right function depends upon target state. */ if (connector->state->crtc && funcs->prepare) funcs->prepare(encoder); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 3699a94a7897..76151586df6e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -344,6 +344,7 @@ int setup_initial_state(struct drm_device *drm_dev, struct drm_plane_state *primary_state; struct drm_display_mode *mode = NULL; const struct drm_connector_helper_funcs *funcs; + const struct drm_encoder_helper_funcs *encoder_funcs; bool is_crtc_enabled = true; int hdisplay, vdisplay; int fb_width, fb_height; @@ -363,6 +364,10 @@ int setup_initial_state(struct drm_device *drm_dev, if (funcs->loader_protect) funcs->loader_protect(connector, true); connector->loader_protect = true; + encoder_funcs = conn_state->best_encoder->helper_private; + if (encoder_funcs->loader_protect) + encoder_funcs->loader_protect(conn_state->best_encoder, true); + conn_state->best_encoder->loader_protect = true; num_modes = connector->funcs->fill_modes(connector, 4096, 4096); if (!num_modes) { dev_err(drm_dev->dev, "connector[%s] can't found any modes\n", @@ -472,6 +477,9 @@ error: if (funcs->loader_protect) funcs->loader_protect(connector, false); connector->loader_protect = false; + if (encoder_funcs->loader_protect) + encoder_funcs->loader_protect(conn_state->best_encoder, false); + conn_state->best_encoder->loader_protect = false; return ret; } diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c index 6102657a6f7f..4b4249114477 100644 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -429,19 +429,15 @@ static enum drm_mode_status rockchip_lvds_connector_mode_valid( return MODE_OK; } -static int rockchip_lvds_loader_protect(struct drm_connector *connector, - bool on) +static +int rockchip_lvds_connector_loader_protect(struct drm_connector *connector, + bool on) { struct rockchip_lvds *lvds = connector_to_lvds(connector); if (lvds->panel) drm_panel_loader_protect(lvds->panel, on); - if (on) - pm_runtime_get_sync(lvds->dev); - else - pm_runtime_put(lvds->dev); - return 0; } @@ -450,7 +446,7 @@ struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = { .get_modes = rockchip_lvds_connector_get_modes, .mode_valid = rockchip_lvds_connector_mode_valid, .best_encoder = rockchip_lvds_connector_best_encoder, - .loader_protect = rockchip_lvds_loader_protect, + .loader_protect = rockchip_lvds_connector_loader_protect, }; static void rockchip_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) @@ -655,12 +651,26 @@ static void rockchip_lvds_encoder_disable(struct drm_encoder *encoder) rockchip_lvds_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); } +static int rockchip_lvds_encoder_loader_protect(struct drm_encoder *encoder, + bool on) +{ + struct rockchip_lvds *lvds = encoder_to_lvds(encoder); + + if (on) + pm_runtime_get_sync(lvds->dev); + else + pm_runtime_put(lvds->dev); + + return 0; +} + static struct drm_encoder_helper_funcs rockchip_lvds_encoder_helper_funcs = { .mode_fixup = rockchip_lvds_encoder_mode_fixup, .mode_set = rockchip_lvds_encoder_mode_set, .enable = rockchip_lvds_encoder_enable, .disable = rockchip_lvds_encoder_disable, .atomic_check = rockchip_lvds_encoder_atomic_check, + .loader_protect = rockchip_lvds_encoder_loader_protect, }; static void rockchip_lvds_encoder_destroy(struct drm_encoder *encoder) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index a5ab023edfa5..1b904d9d2808 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -745,6 +745,7 @@ struct drm_encoder { int encoder_type; uint32_t possible_crtcs; uint32_t possible_clones; + bool loader_protect; struct drm_crtc *crtc; struct drm_bridge *bridge; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 53644897c50a..8b41a8323eda 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -139,6 +139,7 @@ struct drm_crtc_helper_funcs { * @mode_set (like shared PLLs). */ struct drm_encoder_helper_funcs { + int (*loader_protect)(struct drm_encoder *encoder, bool on); void (*dpms)(struct drm_encoder *encoder, int mode); void (*save)(struct drm_encoder *encoder); void (*restore)(struct drm_encoder *encoder); -- 2.34.1