FROMLIST: drm/rockchip: get rid of rockchip_drm_crtc_mode_config
authorMark Yao <mark.yao@rock-chips.com>
Wed, 20 Apr 2016 02:13:30 +0000 (10:13 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 4 May 2016 10:15:26 +0000 (18:15 +0800)
We need to take care of the vop status when use
rockchip_drm_crtc_mode_config, if vop is disabled,
the function would failed, that is terrible.

Save output_type and output_mode into rockchip_crtc_state,
it's nice to make them into atomic.

Conflicts:

drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
drivers/gpu/drm/rockchip/dw-mipi-dsi.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
drivers/gpu/drm/rockchip/inno_hdmi.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
drivers/gpu/drm/rockchip/rockchip_drm_vop.c

Change-Id: I43c49a92b2b9df02ce8a055bd16948b400ab0f47
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
(am from https://patchwork.kernel.org/patch/8844321/)

drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
drivers/gpu/drm/rockchip/dw-mipi-dsi.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
drivers/gpu/drm/rockchip/rockchip_drm_vop.c

index f4996ec78fb1918607a14565e486ecbd5215ad6a..26303b649564c9b3b312374a80456a5f3739e669 100644 (file)
@@ -125,41 +125,6 @@ rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
                                   const struct drm_display_mode *mode,
                                   struct drm_display_mode *adjusted_mode)
 {
-       struct rockchip_dp_device *dp = to_dp(encoder);
-       int private_flags;
-       int ret;
-
-       /*
-        * The hardware IC designed that VOP must output the RGB10 video
-        * format to eDP contoller, and if eDP panel only support RGB8,
-        * then eDP contoller should cut down the video data, not via VOP
-        * contoller, that's why we need to hardcode the VOP output mode
-        * to RGA10 here.
-        */
-
-       ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
-       if (ret < 0)
-               return true;
-
-       switch (dp->data->chip_type) {
-       case RK3399_EDP:
-               /*
-                * For RK3399, VOP Lit must code the out mode to RGB888,
-                * VOP Big must code the out mode to RGB10.
-                */
-               if (ret)
-                       private_flags = ROCKCHIP_DSP_MODE(eDP, P888);
-               else
-                       private_flags = ROCKCHIP_DSP_MODE(eDP, AAAA);
-               break;
-
-       default:
-               private_flags = ROCKCHIP_DSP_MODE(eDP, AAAA);
-               break;
-       }
-
-       adjusted_mode->private_flags = private_flags;
-
        return true;
 }
 
@@ -199,11 +164,54 @@ static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
        /* do nothing */
 }
 
+static int
+rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
+                                    struct drm_crtc_state *crtc_state,
+                                    struct drm_connector_state *conn_state)
+{
+       struct rockchip_dp_device *dp = to_dp(encoder);
+       struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+       int ret;
+
+       /*
+        * The hardware IC designed that VOP must output the RGB10 video
+        * format to eDP contoller, and if eDP panel only support RGB8,
+        * then eDP contoller should cut down the video data, not via VOP
+        * contoller, that's why we need to hardcode the VOP output mode
+        * to RGA10 here.
+        */
+
+       ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
+       if (ret < 0)
+               return true;
+
+       switch (dp->data->chip_type) {
+       case RK3399_EDP:
+               /*
+                * For RK3399, VOP Lit must code the out mode to RGB888,
+                * VOP Big must code the out mode to RGB10.
+                */
+               if (ret)
+                       s->output_mode = ROCKCHIP_OUT_MODE_P888;
+               else
+                       s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+               break;
+
+       default:
+               s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+               break;
+       }
+       s->output_type = DRM_MODE_CONNECTOR_eDP;
+
+       return 0;
+}
+
 static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
        .mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
        .mode_set = rockchip_dp_drm_encoder_mode_set,
        .enable = rockchip_dp_drm_encoder_enable,
        .disable = rockchip_dp_drm_encoder_nop,
+       .atomic_check = rockchip_dp_drm_encoder_atomic_check,
 };
 
 static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
index 5519000271cd4146c6009723dab0889817c9414e..610025a78e1f14e09b2740fc5e3ab4ffada0d94c 100644 (file)
@@ -902,23 +902,6 @@ static bool dw_mipi_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
                                        const struct drm_display_mode *mode,
                                        struct drm_display_mode *adjusted_mode)
 {
-       struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
-
-       switch (dsi->format) {
-       case MIPI_DSI_FMT_RGB888:
-               adjusted_mode->private_flags = ROCKCHIP_DSP_MODE(DSI, P888);
-               break;
-       case MIPI_DSI_FMT_RGB666:
-               adjusted_mode->private_flags = ROCKCHIP_DSP_MODE(DSI, P666);
-               break;
-       case MIPI_DSI_FMT_RGB565:
-               adjusted_mode->private_flags = ROCKCHIP_DSP_MODE(DSI, P565);
-               break;
-       default:
-               WARN_ON(1);
-               return false;
-       }
-
        return true;
 }
 
@@ -955,12 +938,41 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
        dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
 }
 
+static int
+dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
+                                struct drm_crtc_state *crtc_state,
+                                struct drm_connector_state *conn_state)
+{
+       struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+       struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
+
+       switch (dsi->format) {
+       case MIPI_DSI_FMT_RGB888:
+               s->output_mode = ROCKCHIP_OUT_MODE_P888;
+               break;
+       case MIPI_DSI_FMT_RGB666:
+               s->output_mode = ROCKCHIP_OUT_MODE_P666;
+               break;
+       case MIPI_DSI_FMT_RGB565:
+               s->output_mode = ROCKCHIP_OUT_MODE_P565;
+               break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       s->output_type = DRM_MODE_CONNECTOR_DSI;
+
+       return 0;
+}
+
 static struct drm_encoder_helper_funcs
 dw_mipi_dsi_encoder_helper_funcs = {
        .mode_fixup = dw_mipi_dsi_encoder_mode_fixup,
        .commit = dw_mipi_dsi_encoder_commit,
        .mode_set = dw_mipi_dsi_encoder_mode_set,
        .disable = dw_mipi_dsi_encoder_disable,
+       .atomic_check = dw_mipi_dsi_encoder_atomic_check,
 };
 
 static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
index 5e80d1eaf64c96486da27c1f089cb83c8cfcf1c7..dca61c8e73e3e9b10acd75d07edae03756a9419e 100644 (file)
@@ -186,8 +186,6 @@ dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
                                    const struct drm_display_mode *mode,
                                    struct drm_display_mode *adj_mode)
 {
-       adj_mode->private_flags = ROCKCHIP_DSP_MODE(HDMIA, AAAA);
-
        return true;
 }
 
@@ -214,11 +212,25 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
                (mux) ? "LIT" : "BIG");
 }
 
+static int
+dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
+                                     struct drm_crtc_state *crtc_state,
+                                     struct drm_connector_state *conn_state)
+{
+       struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+
+       s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+       s->output_type = DRM_MODE_CONNECTOR_HDMIA;
+
+       return 0;
+}
+
 static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
        .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
        .mode_set   = dw_hdmi_rockchip_encoder_mode_set,
        .enable     = dw_hdmi_rockchip_encoder_enable,
        .disable    = dw_hdmi_rockchip_encoder_disable,
+       .atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
 };
 
 static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
index 841c5b8c3ac0a4701963b7b1e81c71ce4cc9cf79..bfd5facfd36b2544b7b5ae9fb32704ff07a8c915 100644 (file)
@@ -61,6 +61,15 @@ struct rockchip_atomic_commit {
        struct mutex lock;
 };
 
+struct rockchip_crtc_state {
+       struct drm_crtc_state base;
+       int output_type;
+       int output_mode;
+};
+
+#define to_rockchip_crtc_state(s) \
+               container_of(s, struct rockchip_crtc_state, base)
+
 /*
  * Rockchip drm_file private structure.
  *
index 77cc63e89b9fe39700e7a20164b9d27e648c7ceb..d3c80337b083cb48a869facfeb0ca047fe8d9f6b 100644 (file)
@@ -898,6 +898,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 static void vop_crtc_enable(struct drm_crtc *crtc)
 {
        struct vop *vop = to_vop(crtc);
+       struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
        struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
        u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
        u16 hdisplay = adjusted_mode->hdisplay;
@@ -909,9 +910,7 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
        u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
        u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
        u16 vact_end = vact_st + vdisplay;
-       uint32_t pin_pol, val;
-       int type = ROCKCHIP_OUT_MODE_TYPE(adjusted_mode->private_flags);
-       int out_mode = ROCKCHIP_OUT_MODE(adjusted_mode->private_flags);
+       uint32_t val;
 
        vop_enable(crtc);
        /*
@@ -950,32 +949,27 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
                vop_dsp_hold_valid_irq_disable(vop);
        }
 
-       pin_pol = 0x8;
-       pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
-       pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
-       VOP_CTRL_SET(vop, pin_pol, pin_pol);
-
-       switch(type) {
+       val = 0x8;
+       val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
+       val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
+       VOP_CTRL_SET(vop, pin_pol, val);
+       switch (s->output_type) {
        case DRM_MODE_CONNECTOR_LVDS:
                VOP_CTRL_SET(vop, rgb_en, 1);
-               VOP_CTRL_SET(vop, rgb_pin_pol, pin_pol);
                break;
        case DRM_MODE_CONNECTOR_eDP:
-               VOP_CTRL_SET(vop, edp_pin_pol, pin_pol);
                VOP_CTRL_SET(vop, edp_en, 1);
                break;
        case DRM_MODE_CONNECTOR_HDMIA:
-               VOP_CTRL_SET(vop, hdmi_pin_pol, pin_pol);
                VOP_CTRL_SET(vop, hdmi_en, 1);
                break;
        case DRM_MODE_CONNECTOR_DSI:
-               VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol);
                VOP_CTRL_SET(vop, mipi_en, 1);
                break;
        default:
-               DRM_ERROR("unsupport connector_type[%d]\n", type);
+               DRM_ERROR("unsupport connector_type[%d]\n", s->output_type);
        }
-       VOP_CTRL_SET(vop, out_mode, out_mode);
+       VOP_CTRL_SET(vop, out_mode, s->output_mode);
 
        VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
        val = hact_st << 16;
@@ -1035,13 +1029,34 @@ static void vop_crtc_destroy(struct drm_crtc *crtc)
        drm_crtc_cleanup(crtc);
 }
 
+static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+       struct rockchip_crtc_state *rockchip_state;
+
+       rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
+       if (!rockchip_state)
+               return NULL;
+
+       __drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base);
+       return &rockchip_state->base;
+}
+
+static void vop_crtc_destroy_state(struct drm_crtc *crtc,
+                                  struct drm_crtc_state *state)
+{
+       struct rockchip_crtc_state *s = to_rockchip_crtc_state(state);
+
+       __drm_atomic_helper_crtc_destroy_state(crtc, &s->base);
+       kfree(s);
+}
+
 static const struct drm_crtc_funcs vop_crtc_funcs = {
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
        .destroy = vop_crtc_destroy,
        .reset = drm_atomic_helper_crtc_reset,
-       .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
-       .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+       .atomic_duplicate_state = vop_crtc_duplicate_state,
+       .atomic_destroy_state = vop_crtc_destroy_state,
 };
 
 static bool vop_win_pending_is_complete(struct vop_win *vop_win)