drm/rockchip: add loader protect for encoder
authorHuang Jiachai <hjc@rock-chips.com>
Thu, 27 Jul 2017 07:23:31 +0000 (15:23 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 3 Aug 2017 12:23:17 +0000 (20:23 +0800)
Change-Id: I9fa1e949a55d8778b44ff809630337d5d35ffa11
Signed-off-by: Huang Jiachai <hjc@rock-chips.com>
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/rockchip/rockchip_lvds.c
include/drm/drm_crtc.h
include/drm/drm_crtc_helper.h

index ccd713baa86cdb4bbd8a2be6ba91b9d94c2c6f96..c486b977474b13371f20c284543f85999c1574a3 100644 (file)
@@ -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);
index 3699a94a7897e770abade8ca31499247edd26ce4..76151586df6ef55d5386e66edead5336984435c3 100644 (file)
@@ -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;
 }
 
index 6102657a6f7f73050168fabbb13adeca503f5c7e..4b424911447752b4175df7df4d521663143077f4 100644 (file)
@@ -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)
index a5ab023edfa5794ae6871bb76ec4827104f4020b..1b904d9d280868dfe729dd69f8eda1e217e73267 100644 (file)
@@ -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;
index 53644897c50adbadb565985e21e1423086f76be5..8b41a8323eda709330205ee4148687abdfdb8b5a 100644 (file)
@@ -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);