2 * i.MX IPUv3 Graphics driver
4 * Copyright (C) 2011 Sascha Hauer, Pengutronix
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 #include <linux/component.h>
16 #include <linux/module.h>
17 #include <linux/export.h>
18 #include <linux/device.h>
19 #include <linux/platform_device.h>
21 #include <drm/drm_crtc_helper.h>
23 #include <linux/clk.h>
24 #include <linux/errno.h>
25 #include <drm/drm_gem_cma_helper.h>
26 #include <drm/drm_fb_cma_helper.h>
28 #include <video/imx-ipu-v3.h>
30 #include "ipuv3-plane.h"
32 #define DRIVER_DESC "i.MX IPUv3 Graphics"
37 struct imx_drm_crtc
*imx_crtc
;
39 /* plane[0] is the full plane, plane[1] is the partial plane */
40 struct ipu_plane
*plane
[2];
45 struct drm_pending_vblank_event
*page_flip_event
;
46 struct drm_framebuffer
*newfb
;
53 #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
55 static void ipu_fb_enable(struct ipu_crtc
*ipu_crtc
)
57 struct ipu_soc
*ipu
= dev_get_drvdata(ipu_crtc
->dev
->parent
);
59 if (ipu_crtc
->enabled
)
63 ipu_plane_enable(ipu_crtc
->plane
[0]);
64 /* Start DC channel and DI after IDMAC */
65 ipu_dc_enable_channel(ipu_crtc
->dc
);
66 ipu_di_enable(ipu_crtc
->di
);
68 ipu_crtc
->enabled
= 1;
71 static void ipu_fb_disable(struct ipu_crtc
*ipu_crtc
)
73 struct ipu_soc
*ipu
= dev_get_drvdata(ipu_crtc
->dev
->parent
);
75 if (!ipu_crtc
->enabled
)
78 /* Stop DC channel and DI before IDMAC */
79 ipu_dc_disable_channel(ipu_crtc
->dc
);
80 ipu_di_disable(ipu_crtc
->di
);
81 ipu_plane_disable(ipu_crtc
->plane
[0]);
84 ipu_crtc
->enabled
= 0;
87 static void ipu_crtc_dpms(struct drm_crtc
*crtc
, int mode
)
89 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
91 dev_dbg(ipu_crtc
->dev
, "%s mode: %d\n", __func__
, mode
);
94 case DRM_MODE_DPMS_ON
:
95 ipu_fb_enable(ipu_crtc
);
97 case DRM_MODE_DPMS_STANDBY
:
98 case DRM_MODE_DPMS_SUSPEND
:
99 case DRM_MODE_DPMS_OFF
:
100 ipu_fb_disable(ipu_crtc
);
105 static int ipu_page_flip(struct drm_crtc
*crtc
,
106 struct drm_framebuffer
*fb
,
107 struct drm_pending_vblank_event
*event
,
108 uint32_t page_flip_flags
)
110 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
116 ret
= imx_drm_crtc_vblank_get(ipu_crtc
->imx_crtc
);
118 dev_dbg(ipu_crtc
->dev
, "failed to acquire vblank counter\n");
119 list_del(&event
->base
.link
);
124 ipu_crtc
->newfb
= fb
;
125 ipu_crtc
->page_flip_event
= event
;
126 crtc
->primary
->fb
= fb
;
131 static const struct drm_crtc_funcs ipu_crtc_funcs
= {
132 .set_config
= drm_crtc_helper_set_config
,
133 .destroy
= drm_crtc_cleanup
,
134 .page_flip
= ipu_page_flip
,
137 static int ipu_crtc_mode_set(struct drm_crtc
*crtc
,
138 struct drm_display_mode
*orig_mode
,
139 struct drm_display_mode
*mode
,
141 struct drm_framebuffer
*old_fb
)
143 struct drm_device
*dev
= crtc
->dev
;
144 struct drm_encoder
*encoder
;
145 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
146 struct ipu_di_signal_cfg sig_cfg
= {};
147 unsigned long encoder_types
= 0;
150 dev_dbg(ipu_crtc
->dev
, "%s: mode->hdisplay: %d\n", __func__
,
152 dev_dbg(ipu_crtc
->dev
, "%s: mode->vdisplay: %d\n", __func__
,
155 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
)
156 if (encoder
->crtc
== crtc
)
157 encoder_types
|= BIT(encoder
->encoder_type
);
159 dev_dbg(ipu_crtc
->dev
, "%s: attached to encoder types 0x%lx\n",
160 __func__
, encoder_types
);
163 * If we have DAC or LDB, then we need the IPU DI clock to be
164 * the same as the LDB DI clock. For TVDAC, derive the IPU DI
165 * clock from 27 MHz TVE_DI clock, but allow to divide it.
167 if (encoder_types
& (BIT(DRM_MODE_ENCODER_DAC
) |
168 BIT(DRM_MODE_ENCODER_LVDS
)))
169 sig_cfg
.clkflags
= IPU_DI_CLKMODE_SYNC
| IPU_DI_CLKMODE_EXT
;
170 else if (encoder_types
& BIT(DRM_MODE_ENCODER_TVDAC
))
171 sig_cfg
.clkflags
= IPU_DI_CLKMODE_EXT
;
173 sig_cfg
.clkflags
= 0;
175 sig_cfg
.enable_pol
= 1;
177 sig_cfg
.bus_format
= ipu_crtc
->bus_format
;
178 sig_cfg
.v_to_h_sync
= 0;
179 sig_cfg
.hsync_pin
= ipu_crtc
->di_hsync_pin
;
180 sig_cfg
.vsync_pin
= ipu_crtc
->di_vsync_pin
;
182 drm_display_mode_to_videomode(mode
, &sig_cfg
.mode
);
184 ret
= ipu_dc_init_sync(ipu_crtc
->dc
, ipu_crtc
->di
,
185 mode
->flags
& DRM_MODE_FLAG_INTERLACE
,
186 ipu_crtc
->bus_format
, mode
->hdisplay
);
188 dev_err(ipu_crtc
->dev
,
189 "initializing display controller failed with %d\n",
194 ret
= ipu_di_init_sync_panel(ipu_crtc
->di
, &sig_cfg
);
196 dev_err(ipu_crtc
->dev
,
197 "initializing panel failed with %d\n", ret
);
201 return ipu_plane_mode_set(ipu_crtc
->plane
[0], crtc
, mode
,
203 0, 0, mode
->hdisplay
, mode
->vdisplay
,
204 x
, y
, mode
->hdisplay
, mode
->vdisplay
,
205 mode
->flags
& DRM_MODE_FLAG_INTERLACE
);
208 static void ipu_crtc_handle_pageflip(struct ipu_crtc
*ipu_crtc
)
211 struct drm_device
*drm
= ipu_crtc
->base
.dev
;
213 spin_lock_irqsave(&drm
->event_lock
, flags
);
214 if (ipu_crtc
->page_flip_event
)
215 drm_send_vblank_event(drm
, -1, ipu_crtc
->page_flip_event
);
216 ipu_crtc
->page_flip_event
= NULL
;
217 imx_drm_crtc_vblank_put(ipu_crtc
->imx_crtc
);
218 spin_unlock_irqrestore(&drm
->event_lock
, flags
);
221 static irqreturn_t
ipu_irq_handler(int irq
, void *dev_id
)
223 struct ipu_crtc
*ipu_crtc
= dev_id
;
225 imx_drm_handle_vblank(ipu_crtc
->imx_crtc
);
227 if (ipu_crtc
->newfb
) {
228 struct ipu_plane
*plane
= ipu_crtc
->plane
[0];
230 ipu_crtc
->newfb
= NULL
;
231 ipu_plane_set_base(plane
, ipu_crtc
->base
.primary
->fb
,
233 ipu_crtc_handle_pageflip(ipu_crtc
);
239 static bool ipu_crtc_mode_fixup(struct drm_crtc
*crtc
,
240 const struct drm_display_mode
*mode
,
241 struct drm_display_mode
*adjusted_mode
)
243 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
247 drm_display_mode_to_videomode(adjusted_mode
, &vm
);
249 ret
= ipu_di_adjust_videomode(ipu_crtc
->di
, &vm
);
253 drm_display_mode_from_videomode(&vm
, adjusted_mode
);
258 static void ipu_crtc_prepare(struct drm_crtc
*crtc
)
260 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
262 ipu_fb_disable(ipu_crtc
);
265 static void ipu_crtc_commit(struct drm_crtc
*crtc
)
267 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
269 ipu_fb_enable(ipu_crtc
);
272 static struct drm_crtc_helper_funcs ipu_helper_funcs
= {
273 .dpms
= ipu_crtc_dpms
,
274 .mode_fixup
= ipu_crtc_mode_fixup
,
275 .mode_set
= ipu_crtc_mode_set
,
276 .prepare
= ipu_crtc_prepare
,
277 .commit
= ipu_crtc_commit
,
280 static int ipu_enable_vblank(struct drm_crtc
*crtc
)
285 static void ipu_disable_vblank(struct drm_crtc
*crtc
)
287 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
289 ipu_crtc
->page_flip_event
= NULL
;
290 ipu_crtc
->newfb
= NULL
;
293 static int ipu_set_interface_pix_fmt(struct drm_crtc
*crtc
,
294 u32 bus_format
, int hsync_pin
, int vsync_pin
)
296 struct ipu_crtc
*ipu_crtc
= to_ipu_crtc(crtc
);
298 ipu_crtc
->bus_format
= bus_format
;
299 ipu_crtc
->di_hsync_pin
= hsync_pin
;
300 ipu_crtc
->di_vsync_pin
= vsync_pin
;
305 static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs
= {
306 .enable_vblank
= ipu_enable_vblank
,
307 .disable_vblank
= ipu_disable_vblank
,
308 .set_interface_pix_fmt
= ipu_set_interface_pix_fmt
,
309 .crtc_funcs
= &ipu_crtc_funcs
,
310 .crtc_helper_funcs
= &ipu_helper_funcs
,
313 static void ipu_put_resources(struct ipu_crtc
*ipu_crtc
)
315 if (!IS_ERR_OR_NULL(ipu_crtc
->dc
))
316 ipu_dc_put(ipu_crtc
->dc
);
317 if (!IS_ERR_OR_NULL(ipu_crtc
->di
))
318 ipu_di_put(ipu_crtc
->di
);
321 static int ipu_get_resources(struct ipu_crtc
*ipu_crtc
,
322 struct ipu_client_platformdata
*pdata
)
324 struct ipu_soc
*ipu
= dev_get_drvdata(ipu_crtc
->dev
->parent
);
327 ipu_crtc
->dc
= ipu_dc_get(ipu
, pdata
->dc
);
328 if (IS_ERR(ipu_crtc
->dc
)) {
329 ret
= PTR_ERR(ipu_crtc
->dc
);
333 ipu_crtc
->di
= ipu_di_get(ipu
, pdata
->di
);
334 if (IS_ERR(ipu_crtc
->di
)) {
335 ret
= PTR_ERR(ipu_crtc
->di
);
341 ipu_put_resources(ipu_crtc
);
346 static int ipu_crtc_init(struct ipu_crtc
*ipu_crtc
,
347 struct ipu_client_platformdata
*pdata
, struct drm_device
*drm
)
349 struct ipu_soc
*ipu
= dev_get_drvdata(ipu_crtc
->dev
->parent
);
354 ret
= ipu_get_resources(ipu_crtc
, pdata
);
356 dev_err(ipu_crtc
->dev
, "getting resources failed with %d.\n",
361 ret
= imx_drm_add_crtc(drm
, &ipu_crtc
->base
, &ipu_crtc
->imx_crtc
,
362 &ipu_crtc_helper_funcs
, ipu_crtc
->dev
->of_node
);
364 dev_err(ipu_crtc
->dev
, "adding crtc failed with %d.\n", ret
);
365 goto err_put_resources
;
369 dp
= IPU_DP_FLOW_SYNC_BG
;
370 id
= imx_drm_crtc_id(ipu_crtc
->imx_crtc
);
371 ipu_crtc
->plane
[0] = ipu_plane_init(ipu_crtc
->base
.dev
, ipu
,
372 pdata
->dma
[0], dp
, BIT(id
), true);
373 ret
= ipu_plane_get_resources(ipu_crtc
->plane
[0]);
375 dev_err(ipu_crtc
->dev
, "getting plane 0 resources failed with %d.\n",
377 goto err_remove_crtc
;
380 /* If this crtc is using the DP, add an overlay plane */
381 if (pdata
->dp
>= 0 && pdata
->dma
[1] > 0) {
382 ipu_crtc
->plane
[1] = ipu_plane_init(ipu_crtc
->base
.dev
, ipu
,
386 if (IS_ERR(ipu_crtc
->plane
[1]))
387 ipu_crtc
->plane
[1] = NULL
;
390 ipu_crtc
->irq
= ipu_plane_irq(ipu_crtc
->plane
[0]);
391 ret
= devm_request_irq(ipu_crtc
->dev
, ipu_crtc
->irq
, ipu_irq_handler
, 0,
392 "imx_drm", ipu_crtc
);
394 dev_err(ipu_crtc
->dev
, "irq request failed with %d.\n", ret
);
395 goto err_put_plane_res
;
401 ipu_plane_put_resources(ipu_crtc
->plane
[0]);
403 imx_drm_remove_crtc(ipu_crtc
->imx_crtc
);
405 ipu_put_resources(ipu_crtc
);
410 static struct device_node
*ipu_drm_get_port_by_id(struct device_node
*parent
,
413 struct device_node
*port
;
416 port
= of_get_child_by_name(parent
, "port");
418 ret
= of_property_read_u32(port
, "reg", &id
);
419 if (!ret
&& id
== port_id
)
423 port
= of_get_next_child(parent
, port
);
426 } while (of_node_cmp(port
->name
, "port"));
432 static int ipu_drm_bind(struct device
*dev
, struct device
*master
, void *data
)
434 struct ipu_client_platformdata
*pdata
= dev
->platform_data
;
435 struct drm_device
*drm
= data
;
436 struct ipu_crtc
*ipu_crtc
;
439 ipu_crtc
= devm_kzalloc(dev
, sizeof(*ipu_crtc
), GFP_KERNEL
);
445 ret
= ipu_crtc_init(ipu_crtc
, pdata
, drm
);
449 dev_set_drvdata(dev
, ipu_crtc
);
454 static void ipu_drm_unbind(struct device
*dev
, struct device
*master
,
457 struct ipu_crtc
*ipu_crtc
= dev_get_drvdata(dev
);
459 imx_drm_remove_crtc(ipu_crtc
->imx_crtc
);
461 ipu_plane_put_resources(ipu_crtc
->plane
[0]);
462 ipu_put_resources(ipu_crtc
);
465 static const struct component_ops ipu_crtc_ops
= {
466 .bind
= ipu_drm_bind
,
467 .unbind
= ipu_drm_unbind
,
470 static int ipu_drm_probe(struct platform_device
*pdev
)
472 struct device
*dev
= &pdev
->dev
;
473 struct ipu_client_platformdata
*pdata
= dev
->platform_data
;
476 if (!dev
->platform_data
)
480 /* Associate crtc device with the corresponding DI port node */
481 dev
->of_node
= ipu_drm_get_port_by_id(dev
->parent
->of_node
,
484 dev_err(dev
, "missing port@%d node in %s\n",
485 pdata
->di
+ 2, dev
->parent
->of_node
->full_name
);
490 ret
= dma_set_coherent_mask(dev
, DMA_BIT_MASK(32));
494 return component_add(dev
, &ipu_crtc_ops
);
497 static int ipu_drm_remove(struct platform_device
*pdev
)
499 component_del(&pdev
->dev
, &ipu_crtc_ops
);
503 static struct platform_driver ipu_drm_driver
= {
505 .name
= "imx-ipuv3-crtc",
507 .probe
= ipu_drm_probe
,
508 .remove
= ipu_drm_remove
,
510 module_platform_driver(ipu_drm_driver
);
512 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
513 MODULE_DESCRIPTION(DRIVER_DESC
);
514 MODULE_LICENSE("GPL");
515 MODULE_ALIAS("platform:imx-ipuv3-crtc");