浏览代码

drm/imx: use bus_flags for pixel clock polarity

This patch allows panels to set pixel clock and data enable pin polarity
other than the default of driving data at the falling pixel clock edge
and active high display enable.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Philipp Zabel 9 年之前
父节点
当前提交
4ed094fd73

+ 8 - 5
drivers/gpu/drm/imx/imx-drm-core.c

@@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
 	return NULL;
 	return NULL;
 }
 }
 
 
-int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
-		int hsync_pin, int vsync_pin)
+int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
+		int hsync_pin, int vsync_pin, u32 bus_flags)
 {
 {
 	struct imx_drm_crtc_helper_funcs *helper;
 	struct imx_drm_crtc_helper_funcs *helper;
 	struct imx_drm_crtc *imx_crtc;
 	struct imx_drm_crtc *imx_crtc;
@@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
 	helper = &imx_crtc->imx_drm_helper_funcs;
 	helper = &imx_crtc->imx_drm_helper_funcs;
 	if (helper->set_interface_pix_fmt)
 	if (helper->set_interface_pix_fmt)
 		return helper->set_interface_pix_fmt(encoder->crtc,
 		return helper->set_interface_pix_fmt(encoder->crtc,
-					bus_format, hsync_pin, vsync_pin);
+					bus_format, hsync_pin, vsync_pin,
+					bus_flags);
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins);
+EXPORT_SYMBOL_GPL(imx_drm_set_bus_config);
 
 
 int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
 int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
 {
 {
-	return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3);
+	return imx_drm_set_bus_config(encoder, bus_format, 2, 3,
+				      DRM_BUS_FLAG_DE_HIGH |
+				      DRM_BUS_FLAG_PIXDATA_NEGEDGE);
 }
 }
 EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
 EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
 
 

+ 4 - 3
drivers/gpu/drm/imx/imx-drm.h

@@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
 	int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
 	int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
-			u32 bus_format, int hsync_pin, int vsync_pin);
+			u32 bus_format, int hsync_pin, int vsync_pin,
+			u32 bus_flags);
 	const struct drm_crtc_helper_funcs *crtc_helper_funcs;
 	const struct drm_crtc_helper_funcs *crtc_helper_funcs;
 	const struct drm_crtc_funcs *crtc_funcs;
 	const struct drm_crtc_funcs *crtc_funcs;
 };
 };
@@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm);
 
 
 struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
 struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
 
 
-int imx_drm_set_bus_format_pins(struct drm_encoder *encoder,
-		u32 bus_format, int hsync_pin, int vsync_pin);
+int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
+		int hsync_pin, int vsync_pin, u32 bus_flags);
 int imx_drm_set_bus_format(struct drm_encoder *encoder,
 int imx_drm_set_bus_format(struct drm_encoder *encoder,
 		u32 bus_format);
 		u32 bus_format);
 
 

+ 4 - 2
drivers/gpu/drm/imx/imx-tve.c

@@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
 
 
 	switch (tve->mode) {
 	switch (tve->mode) {
 	case TVE_MODE_VGA:
 	case TVE_MODE_VGA:
-		imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24,
-					    tve->hsync_pin, tve->vsync_pin);
+		imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24,
+				       tve->hsync_pin, tve->vsync_pin,
+				       DRM_BUS_FLAG_DE_HIGH |
+				       DRM_BUS_FLAG_PIXDATA_NEGEDGE);
 		break;
 		break;
 	case TVE_MODE_TVOUT:
 	case TVE_MODE_TVOUT:
 		imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);
 		imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);

+ 7 - 3
drivers/gpu/drm/imx/ipuv3-crtc.c

@@ -66,6 +66,7 @@ struct ipu_crtc {
 	struct ipu_flip_work	*flip_work;
 	struct ipu_flip_work	*flip_work;
 	int			irq;
 	int			irq;
 	u32			bus_format;
 	u32			bus_format;
+	u32			bus_flags;
 	int			di_hsync_pin;
 	int			di_hsync_pin;
 	int			di_vsync_pin;
 	int			di_vsync_pin;
 };
 };
@@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
 	else
 	else
 		sig_cfg.clkflags = 0;
 		sig_cfg.clkflags = 0;
 
 
-	sig_cfg.enable_pol = 1;
-	sig_cfg.clk_pol = 0;
+	sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW);
+	/* Default to driving pixel data on negative clock edges */
+	sig_cfg.clk_pol = !!(ipu_crtc->bus_flags &
+			     DRM_BUS_FLAG_PIXDATA_POSEDGE);
 	sig_cfg.bus_format = ipu_crtc->bus_format;
 	sig_cfg.bus_format = ipu_crtc->bus_format;
 	sig_cfg.v_to_h_sync = 0;
 	sig_cfg.v_to_h_sync = 0;
 	sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
 	sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
@@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
 }
 }
 
 
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
-		u32 bus_format, int hsync_pin, int vsync_pin)
+		u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags)
 {
 {
 	struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
 	struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
 
 
 	ipu_crtc->bus_format = bus_format;
 	ipu_crtc->bus_format = bus_format;
+	ipu_crtc->bus_flags = bus_flags;
 	ipu_crtc->di_hsync_pin = hsync_pin;
 	ipu_crtc->di_hsync_pin = hsync_pin;
 	ipu_crtc->di_vsync_pin = vsync_pin;
 	ipu_crtc->di_vsync_pin = vsync_pin;
 
 

+ 2 - 2
drivers/gpu/drm/imx/parallel-display.c

@@ -115,8 +115,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
 static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
 static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
 {
 {
 	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
 	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
-
-	imx_drm_set_bus_format(encoder, imxpd->bus_format);
+	imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3,
+			       imxpd->connector.display_info.bus_flags);
 }
 }
 
 
 static void imx_pd_encoder_commit(struct drm_encoder *encoder)
 static void imx_pd_encoder_commit(struct drm_encoder *encoder)