20 #include <linux/module.h>
21 #include <linux/export.h>
22 #include <linux/device.h>
35 #define DRIVER_DESC "i.MX IPUv3 Graphics"
65 #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
69 unsigned long htotal, vtotal;
74 if (!htotal || !vtotal)
77 return mode->
clock * 1000 / vtotal / htotal;
100 static void ipu_fb_disable(
struct ipu_crtc *ipu_crtc)
119 dev_info(ipu_crtc->
dev,
"%s mode: %d\n", __func__, mode);
123 ipu_fb_enable(ipu_crtc);
128 ipu_fb_disable(ipu_crtc);
133 static int ipu_page_flip(
struct drm_crtc *crtc,
135 struct drm_pending_vblank_event *
event)
145 dev_dbg(ipu_crtc->
dev,
"failed to acquire vblank counter\n");
160 .page_flip = ipu_page_flip,
163 static int ipu_drm_set_base(
struct drm_crtc *crtc,
int x,
int y)
172 DRM_LOG_KMS(
"entry is null.\n");
176 phys = cma_obj->
paddr;
180 dev_dbg(ipu_crtc->
dev,
"%s: phys: 0x%lx\n", __func__, phys);
181 dev_dbg(ipu_crtc->
dev,
"%s: xy: %dx%d\n", __func__, x, y);
190 static int ipu_crtc_mode_set(
struct drm_crtc *crtc,
205 dev_dbg(ipu_crtc->
dev,
"%s: mode->hdisplay: %d\n", __func__,
207 dev_dbg(ipu_crtc->
dev,
"%s: mode->vdisplay: %d\n", __func__,
210 ipu_ch_param_zero(cpmem);
227 dev_err(ipu_crtc->
dev,
"unsupported pixel format 0x%08x\n",
263 "initializing display processor failed with %d\n",
274 "initializing display controller failed with %d\n",
282 "initializing panel failed with %d\n", ret);
293 "initializing dmfc channel failed with %d\n",
299 calc_bandwidth(mode, calc_vref(mode)), 64);
302 "allocating dmfc bandwidth failed with %d\n",
307 ipu_drm_set_base(crtc, x, y);
312 static void ipu_crtc_handle_pageflip(
struct ipu_crtc *ipu_crtc)
314 struct drm_pending_vblank_event *
e;
323 spin_unlock_irqrestore(&drm->event_lock, flags);
328 e->event.sequence = 0;
329 e->event.tv_sec = now.tv_sec;
330 e->event.tv_usec = now.tv_usec;
335 list_add_tail(&e->base.link, &e->base.file_priv->event_list);
339 spin_unlock_irqrestore(&drm->event_lock, flags);
344 struct ipu_crtc *ipu_crtc =
dev_id;
348 if (ipu_crtc->
newfb) {
351 ipu_drm_set_base(&ipu_crtc->
base, 0, 0);
352 ipu_crtc_handle_pageflip(ipu_crtc);
358 static bool ipu_crtc_mode_fixup(
struct drm_crtc *crtc,
365 static void ipu_crtc_prepare(
struct drm_crtc *crtc)
369 ipu_fb_disable(ipu_crtc);
372 static void ipu_crtc_commit(
struct drm_crtc *crtc)
376 ipu_fb_enable(ipu_crtc);
379 static void ipu_crtc_load_lut(
struct drm_crtc *crtc)
384 .dpms = ipu_crtc_dpms,
385 .mode_fixup = ipu_crtc_mode_fixup,
386 .mode_set = ipu_crtc_mode_set,
387 .prepare = ipu_crtc_prepare,
388 .commit = ipu_crtc_commit,
389 .load_lut = ipu_crtc_load_lut,
392 static int ipu_enable_vblank(
struct drm_crtc *crtc)
401 static void ipu_disable_vblank(
struct drm_crtc *crtc)
408 static int ipu_set_interface_pix_fmt(
struct drm_crtc *crtc,
u32 encoder_type,
415 switch (encoder_type) {
429 .enable_vblank = ipu_enable_vblank,
430 .disable_vblank = ipu_disable_vblank,
431 .set_interface_pix_fmt = ipu_set_interface_pix_fmt,
432 .crtc_funcs = &ipu_crtc_funcs,
433 .crtc_helper_funcs = &ipu_helper_funcs,
436 static void ipu_put_resources(
struct ipu_crtc *ipu_crtc)
438 if (!IS_ERR_OR_NULL(ipu_crtc->
ipu_ch))
440 if (!IS_ERR_OR_NULL(ipu_crtc->
dmfc))
442 if (!IS_ERR_OR_NULL(ipu_crtc->
dp))
444 if (!IS_ERR_OR_NULL(ipu_crtc->
di))
448 static int ipu_get_resources(
struct ipu_crtc *ipu_crtc,
455 if (IS_ERR_OR_NULL(ipu_crtc->
ipu_ch)) {
456 ret = PTR_ERR(ipu_crtc->
ipu_ch);
461 if (IS_ERR(ipu_crtc->
dc)) {
462 ret = PTR_ERR(ipu_crtc->
dc);
467 if (IS_ERR(ipu_crtc->
dmfc)) {
468 ret = PTR_ERR(ipu_crtc->
dmfc);
472 if (pdata->
dp >= 0) {
474 if (IS_ERR(ipu_crtc->
dp)) {
475 ret = PTR_ERR(ipu_crtc->
ipu_ch);
481 if (IS_ERR(ipu_crtc->
di)) {
482 ret = PTR_ERR(ipu_crtc->
di);
488 ret = devm_request_irq(ipu_crtc->
dev, ipu_crtc->
irq, ipu_irq_handler, 0,
489 "imx_drm", ipu_crtc);
491 dev_err(ipu_crtc->
dev,
"irq request failed with %d.\n", ret);
499 ipu_put_resources(ipu_crtc);
504 static int ipu_crtc_init(
struct ipu_crtc *ipu_crtc,
509 ret = ipu_get_resources(ipu_crtc, pdata);
511 dev_err(ipu_crtc->
dev,
"getting resources failed with %d.\n",
519 ipu_crtc->
dev->parent->of_node, pdata->
di);
521 dev_err(ipu_crtc->
dev,
"adding crtc failed with %d.\n", ret);
522 goto err_put_resources;
528 ipu_put_resources(ipu_crtc);
536 struct ipu_crtc *ipu_crtc;
548 ipu_crtc->
dev = &pdev->
dev;
550 ret = ipu_crtc_init(ipu_crtc, pdata);
552 platform_set_drvdata(pdev, ipu_crtc);
559 struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev);
563 ipu_put_resources(ipu_crtc);
570 .name =
"imx-ipuv3-crtc",
572 .probe = ipu_drm_probe,