drm/imx: imx-ldb: enable DI clock in encoder_mode_set
authorPhilipp Zabel <p.zabel@pengutronix.de>
Fri, 23 Jan 2015 16:10:01 +0000 (17:10 +0100)
committerPhilipp Zabel <p.zabel@pengutronix.de>
Mon, 23 Feb 2015 16:19:01 +0000 (17:19 +0100)
Commit eb10d6355532 ("imx-drm: encoder prepare/mode_set must use adjusted mode")
broke the first LVDS modeset by using crtc->hwmode before crtc mode_set is
called. In fact, encoder prepare is not supposed to prepare the display clock
at all. Rather encoder mode_set should be used to set the DI clock rate, before
it is enabled by crtc commit.

Reported-by: Liu Ying <Ying.Liu@freescale.com>
Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
drivers/gpu/drm/imx/imx-ldb.c

index 1b86aac..2d6dc94 100644 (file)
@@ -163,22 +163,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
 {
        struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
        struct imx_ldb *ldb = imx_ldb_ch->ldb;
-       struct drm_display_mode *mode = &encoder->crtc->hwmode;
        u32 pixel_fmt;
-       unsigned long serial_clk;
-       unsigned long di_clk = mode->clock * 1000;
-       int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
-
-       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
-               /* dual channel LVDS mode */
-               serial_clk = 3500UL * mode->clock;
-               imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
-               imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk);
-       } else {
-               serial_clk = 7000UL * mode->clock;
-               imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk,
-                               di_clk);
-       }
 
        switch (imx_ldb_ch->chno) {
        case 0:
@@ -247,6 +232,9 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
        struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
        struct imx_ldb *ldb = imx_ldb_ch->ldb;
        int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+       unsigned long serial_clk;
+       unsigned long di_clk = mode->clock * 1000;
+       int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
 
        if (mode->clock > 170000) {
                dev_warn(ldb->dev,
@@ -257,6 +245,16 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
                         "%s: mode exceeds 85 MHz pixel clock\n", __func__);
        }
 
+       if (dual) {
+               serial_clk = 3500UL * mode->clock;
+               imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
+               imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk);
+       } else {
+               serial_clk = 7000UL * mode->clock;
+               imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk,
+                                 di_clk);
+       }
+
        /* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */
        if (imx_ldb_ch == &ldb->channel[0]) {
                if (mode->flags & DRM_MODE_FLAG_NVSYNC)