aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-12-21 10:58:19 -0500
committerPhilipp Zabel <p.zabel@pengutronix.de>2015-01-07 15:32:07 -0500
commitd50141d8072e5322ee0518a8c967b5c9caf463d2 (patch)
treee03bdbda1b0727dbba0035c6749d2a5c9d0768b8
parent503f1631ae8f42a386193c92cc4488d35978352e (diff)
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. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c3
-rw-r--r--drivers/gpu/drm/imx/imx-drm.h2
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c40
3 files changed, 25 insertions, 20 deletions
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 06cd2e516db6..a002f53aab0e 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -116,8 +116,7 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
116 helper = &imx_crtc->imx_drm_helper_funcs; 116 helper = &imx_crtc->imx_drm_helper_funcs;
117 if (helper->set_interface_pix_fmt) 117 if (helper->set_interface_pix_fmt)
118 return helper->set_interface_pix_fmt(encoder->crtc, 118 return helper->set_interface_pix_fmt(encoder->crtc,
119 encoder->encoder_type, interface_pix_fmt, 119 interface_pix_fmt, hsync_pin, vsync_pin);
120 hsync_pin, vsync_pin);
121 return 0; 120 return 0;
122} 121}
123EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins); 122EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index 7453ae00c412..3c559ccd6af0 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -17,7 +17,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
17struct imx_drm_crtc_helper_funcs { 17struct imx_drm_crtc_helper_funcs {
18 int (*enable_vblank)(struct drm_crtc *crtc); 18 int (*enable_vblank)(struct drm_crtc *crtc);
19 void (*disable_vblank)(struct drm_crtc *crtc); 19 void (*disable_vblank)(struct drm_crtc *crtc);
20 int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type, 20 int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
21 u32 pix_fmt, int hsync_pin, int vsync_pin); 21 u32 pix_fmt, int hsync_pin, int vsync_pin);
22 const struct drm_crtc_helper_funcs *crtc_helper_funcs; 22 const struct drm_crtc_helper_funcs *crtc_helper_funcs;
23 const struct drm_crtc_funcs *crtc_funcs; 23 const struct drm_crtc_funcs *crtc_funcs;
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index c1fc3735913d..98551e356e12 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -46,7 +46,6 @@ struct ipu_crtc {
46 struct drm_framebuffer *newfb; 46 struct drm_framebuffer *newfb;
47 int irq; 47 int irq;
48 u32 interface_pix_fmt; 48 u32 interface_pix_fmt;
49 unsigned long di_clkflags;
50 int di_hsync_pin; 49 int di_hsync_pin;
51 int di_vsync_pin; 50 int di_vsync_pin;
52}; 51};
@@ -141,22 +140,42 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
141 int x, int y, 140 int x, int y,
142 struct drm_framebuffer *old_fb) 141 struct drm_framebuffer *old_fb)
143{ 142{
143 struct drm_device *dev = crtc->dev;
144 struct drm_encoder *encoder;
144 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 145 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
145 int ret;
146 struct ipu_di_signal_cfg sig_cfg = {}; 146 struct ipu_di_signal_cfg sig_cfg = {};
147 unsigned long encoder_types = 0;
147 u32 out_pixel_fmt; 148 u32 out_pixel_fmt;
149 int ret;
148 150
149 dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, 151 dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
150 mode->hdisplay); 152 mode->hdisplay);
151 dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, 153 dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
152 mode->vdisplay); 154 mode->vdisplay);
153 155
156 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
157 if (encoder->crtc == crtc)
158 encoder_types |= BIT(encoder->encoder_type);
159
160 dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n",
161 __func__, encoder_types);
162
163 /*
164 * If we have DAC, TVDAC or LDB, then we need the IPU DI clock
165 * to be the same as the LDB DI clock.
166 */
167 if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
168 BIT(DRM_MODE_ENCODER_TVDAC) |
169 BIT(DRM_MODE_ENCODER_LVDS)))
170 sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
171 else
172 sig_cfg.clkflags = 0;
173
154 out_pixel_fmt = ipu_crtc->interface_pix_fmt; 174 out_pixel_fmt = ipu_crtc->interface_pix_fmt;
155 175
156 sig_cfg.enable_pol = 1; 176 sig_cfg.enable_pol = 1;
157 sig_cfg.clk_pol = 0; 177 sig_cfg.clk_pol = 0;
158 sig_cfg.pixel_fmt = out_pixel_fmt; 178 sig_cfg.pixel_fmt = out_pixel_fmt;
159 sig_cfg.clkflags = ipu_crtc->di_clkflags;
160 sig_cfg.v_to_h_sync = 0; 179 sig_cfg.v_to_h_sync = 0;
161 sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; 180 sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
162 sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; 181 sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
@@ -271,7 +290,7 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
271 ipu_crtc->newfb = NULL; 290 ipu_crtc->newfb = NULL;
272} 291}
273 292
274static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type, 293static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
275 u32 pixfmt, int hsync_pin, int vsync_pin) 294 u32 pixfmt, int hsync_pin, int vsync_pin)
276{ 295{
277 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 296 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
@@ -280,19 +299,6 @@ static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
280 ipu_crtc->di_hsync_pin = hsync_pin; 299 ipu_crtc->di_hsync_pin = hsync_pin;
281 ipu_crtc->di_vsync_pin = vsync_pin; 300 ipu_crtc->di_vsync_pin = vsync_pin;
282 301
283 switch (encoder_type) {
284 case DRM_MODE_ENCODER_DAC:
285 case DRM_MODE_ENCODER_TVDAC:
286 case DRM_MODE_ENCODER_LVDS:
287 ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC |
288 IPU_DI_CLKMODE_EXT;
289 break;
290 case DRM_MODE_ENCODER_TMDS:
291 case DRM_MODE_ENCODER_NONE:
292 ipu_crtc->di_clkflags = 0;
293 break;
294 }
295
296 return 0; 302 return 0;
297} 303}
298 304