imx-drm: core: handling of DI clock flags to ipu_crtc_mode_set()
Subsystems (3)
PATCH 1/1 imx-drm: core: handling of DI clock flags to ipu_crtc_mode_set()
We do not need to track the state of the IPU DI's clock flags by having each display bridge calling back into imx-drm-core, and then back out into ipuv3-crtc.c.
ipuv3-crtc can instead just scan the list of encoders to retrieve their type, and build up a picture of which types of encoders are attached. We can then use this information to configure the IPU DI clocking mode without any uncertainty - if we have multiple bridges connected to the same DI, if one of them requires a synchronous DI clock, that's what we must use.
---
This is a clean-up which I've had sitting around for some time, but which I think would be useful to get into mainline at some point (maybe 3.20?)
drivers/gpu/drm/imx/imx-drm-core.c | 3 +-- drivers/gpu/drm/imx/imx-drm.h | 2 +- drivers/gpu/drm/imx/ipuv3-crtc.c | 40 ++++++++++++++++++++++---------------- 3 files changed, 25 insertions(+), 20 deletions(-)
drivers/gpu/drm/imx/imx-drm-core.c +1 -2
@@ -116,8 +116,7 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder, helper = &imx_crtc->imx_drm_helper_funcs;if (helper->set_interface_pix_fmt)return helper->set_interface_pix_fmt (encoder->crtc, - encoder->encoder_type, interface_pix_fmt, - hsync_pin, vsync_pin); + interface_pix_fmt, hsync_pin, vsync_pin);return 0 ; }EXPORT_SYMBOL_GPL (imx_drm_panel_format_pins);
drivers/gpu/drm/imx/imx-drm.h +1 -1
@@ -17,7 +17,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc);struct imx_drm_crtc_helper_funcs {int (*enable_vblank)(struct drm_crtc *crtc);void (*disable_vblank)(struct drm_crtc *crtc); -int (*set_interface_pix_fmt)(struct drm_crtc *crtc,u32 encoder_type, +int (*set_interface_pix_fmt)(struct drm_crtc *crtc,u32 pix_fmt,int hsync_pin,int vsync_pin);const struct drm_crtc_helper_funcs *crtc_helper_funcs;const struct drm_crtc_funcs *crtc_funcs;
drivers/gpu/drm/imx/ipuv3-crtc.c +23 -17
@@ -46,7 +46,6 @@ struct ipu_crtc {struct drm_framebuffer *newfb;int irq;u32 interface_pix_fmt; -unsigned long di_clkflags;int di_hsync_pin;int di_vsync_pin; };
@@ -141,16 +140,37 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { + struct drm_device *dev = crtc->dev; +struct drm_encoder *encoder;struct ipu_crtc *ipu_crtc =to_ipu_crtc (crtc); -int ret;struct ipu_di_signal_cfg sig_cfg = {}; +unsigned long encoder_types =0 ;u32 out_pixel_fmt; +int ret;dev_dbg (ipu_crtc->dev,"%s: mode->hdisplay: %d\n" , __func__, mode->hdisplay);dev_dbg (ipu_crtc->dev,"%s: mode->vdisplay: %d\n" , __func__, mode->vdisplay); +list_for_each_entry (encoder, &dev->mode_config.encoder_list, head) +if (encoder->crtc == crtc) + encoder_types |=BIT (encoder->encoder_type); + +dev_dbg (ipu_crtc->dev,"%s: attached to encoder types 0x%lx\n" , + __func__, encoder_types); + +/* +* If we have DAC, TVDAC or LDB, then we need the IPU DI clock +* to be the same as the LDB DI clock. +*/ +if (encoder_types & (BIT (DRM_MODE_ENCODER_DAC ) | +BIT (DRM_MODE_ENCODER_TVDAC ) | +BIT (DRM_MODE_ENCODER_LVDS ))) + sig_cfg.clkflags =IPU_DI_CLKMODE_SYNC |IPU_DI_CLKMODE_EXT ; +else + sig_cfg.clkflags =0 ; + out_pixel_fmt = ipu_crtc->interface_pix_fmt;if (mode->flags &DRM_MODE_FLAG_INTERLACE )
@@ -173,7 +193,6 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start; sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay; sig_cfg.pixelclock = mode->clock *1000 ; - sig_cfg.clkflags = ipu_crtc->di_clkflags; sig_cfg.v_to_h_sync =0 ;
@@ -275,7 +294,7 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) ipu_crtc->newfb =NULL ; } -static int ipu_set_interface_pix_fmt (struct drm_crtc *crtc,u32 encoder_type, +static int ipu_set_interface_pix_fmt (struct drm_crtc *crtc,u32 pixfmt,int hsync_pin,int vsync_pin) {struct ipu_crtc *ipu_crtc =to_ipu_crtc (crtc);
@@ -284,19 +303,6 @@ static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type, ipu_crtc->di_hsync_pin = hsync_pin; ipu_crtc->di_vsync_pin = vsync_pin; -switch (encoder_type) { -case DRM_MODE_ENCODER_DAC : -case DRM_MODE_ENCODER_TVDAC : -case DRM_MODE_ENCODER_LVDS : - ipu_crtc->di_clkflags =IPU_DI_CLKMODE_SYNC | -IPU_DI_CLKMODE_EXT ; -break ; -case DRM_MODE_ENCODER_TMDS : -case DRM_MODE_ENCODER_NONE : - ipu_crtc->di_clkflags =0 ; -break ; - } -return 0 ; }
Signature · 6 lines
1.8.3.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Hi Russell,
Quoted 11 lines · Russell King
We do not need to track the state of the IPU DI's clock flags by having each display bridge calling back into imx-drm-core, and then back out into
ipuv3-crtc.c.ipuv3-crtc can instead just scan the list of encoders to retrieve their type, and build up a picture of which types of encoders are attached. We can then use this information to configure the IPU DI clocking mode without any uncertainty - if we have multiple bridges connected to the same DI, if one of them requires a synchronous DI clock, that's what we must use.
Quoted 5 lines
Signed-off-by Russell King <[email protected]>---
This is a clean-up which I've had sitting around for some time, but which I think would be useful to get into mainline at some point (maybe 3.20?)
Looks good to me, I'll add it to the queue.
thanks
Philipp
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel