diff mbox

[v2,0/7] imx-drm: ipuv3-crtc: Implement mode_fixup

Message ID 1422029904.3017.37.camel@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Philipp Zabel Jan. 23, 2015, 4:18 p.m. UTC
Am Freitag, den 23.01.2015, 13:06 -0200 schrieb Fabio Estevam:
> On Fri, Jan 23, 2015 at 12:56 AM, Liu Ying <Ying.Liu@freescale.com> wrote:
> > Hi,
> >
> > It looks that the below commit makes my Hannstar XGA LVDS panel stop working
> > on the i.MX6DL SabreSD board.  Any idea?
> 
> Yes, with eb10d6355532def3a ("mx-drm: encoder prepare/mode_set must
> use adjusted mode") applied
> the DI clock is 0:

My bad, the problem is we are misusing encoder_prepare to enable the
display interface clock needed for the following crtc mode set.

What we really want is to use is adjusted_mode given to
encoder_funcs->mode_set, before the clock is enabled by
crtc_funcs->commit.

How about this patch:

-----8<-----

Comments

Fabio Estevam Jan. 23, 2015, 4:27 p.m. UTC | #1
Hi Philipp,

On Fri, Jan 23, 2015 at 2:18 PM, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> @@ -281,6 +267,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_ldb_get_mux_id(imx_ldb_ch);

I can't find imx_ldb_get_mux_id() on linux-next.
Philipp Zabel Jan. 23, 2015, 4:39 p.m. UTC | #2
Am Freitag, den 23.01.2015, 14:27 -0200 schrieb Fabio Estevam:
> Hi Philipp,
> 
> On Fri, Jan 23, 2015 at 2:18 PM, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> > @@ -281,6 +267,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_ldb_get_mux_id(imx_ldb_ch);
> 
> I can't find imx_ldb_get_mux_id() on linux-next.

Sorry, that should be

	int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);

regards
Philipp
Fabio Estevam Jan. 23, 2015, 4:41 p.m. UTC | #3
On Fri, Jan 23, 2015 at 2:39 PM, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> Am Freitag, den 23.01.2015, 14:27 -0200 schrieb Fabio Estevam:
>> Hi Philipp,
>>
>> On Fri, Jan 23, 2015 at 2:18 PM, Philipp Zabel <p.zabel@pengutronix.de> wrote:
>> > @@ -281,6 +267,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_ldb_get_mux_id(imx_ldb_ch);
>>
>> I can't find imx_ldb_get_mux_id() on linux-next.
>
> Sorry, that should be
>
>         int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);

It works fine now, thanks:

Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
diff mbox

Patch

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index abceb3d..99fe4bb 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -193,22 +193,8 @@  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_ldb_get_mux_id(imx_ldb_ch);
 
-	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:
@@ -281,6 +267,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_ldb_get_mux_id(imx_ldb_ch);
 
 	if (mode->clock > 170000) {
 		dev_warn(ldb->dev,
@@ -291,6 +280,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)