aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-08-15 02:41:45 -0400
committerDave Airlie <airlied@redhat.com>2016-08-15 02:41:45 -0400
commita02b5a155e21b6d324045eca2e30e93f4ff4c51c (patch)
tree149f949925fd0bbc020a4189c5b33979ee23c585
parentc13eb9315f80f4b4cc0cbaad8c57068b2665e1f9 (diff)
parentdc80d7038883feca2abd08975165bc0d83c84762 (diff)
Merge tag 'imx-drm-next-2016-08-12' of git://git.pengutronix.de/git/pza/linux into drm-next
imx-drm updates and encoder atomic_mode_set helper callback - add pixel clock and DE polarity configuration from device tree using display timing bindings for parallel and LVDS output - cleanup/remove trivial functions - cleanup and fixes in preparation for capture support - add atomic_mode_set helper and use it in imx-ldb - this is an alternative to the encoder mode_set callback that passes the crtc and connector state instead of just the mode. It allows drivers to get information from the attached connector without having to iterate over all connectors - add drm_bridge support to imx-ldb, for bridges attached via LVDS * tag 'imx-drm-next-2016-08-12' of git://git.pengutronix.de/git/pza/linux: drm/imx-ldb: Add support to drm-bridge drm/imx: imx-ldb: use encoder atomic_mode_set callback drm/atomic-helper: Add atomic_mode_set helper callback drm/imx: Remove imx_drm_handle_vblank() gpu: ipu-v3: Add missing IDMAC channel names gpu: ipu-v3: rename CSI client device gpu: ipu-v3: Fix IRT usage gpu: ipu-v3: Fix CSI data format for 16-bit media bus formats gpu: ipu-v3: set correct full sensor frame for PAL/NTSC gpu: ipu-v3: Add VDI input IDMAC channels gpu: ipu-v3: Add ipu_get_num() gpu: ipu-cpmem: Add ipu_cpmem_get_burstsize() gpu: ipu-cpmem: Add ipu_cpmem_set_uv_offset() drm/imx: Remove imx_drm_crtc_id() drm/imx: Remove imx_drm_crtc_vblank_get/_put() drm/imx: convey the pixelclk-active and de-active flags from DT to the ipu-di driver drm: add a helper function to extract 'de-active' and 'pixelclk-active' from DT
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c6
-rw-r--r--drivers/gpu/drm/drm_modes.c20
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c24
-rw-r--r--drivers/gpu/drm/imx/imx-drm.h6
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c151
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c2
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c10
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c12
-rw-r--r--drivers/gpu/ipu-v3/ipu-cpmem.c13
-rw-r--r--drivers/gpu/ipu-v3/ipu-csi.c26
-rw-r--r--drivers/gpu/ipu-v3/ipu-ic.c40
-rw-r--r--drivers/gpu/ipu-v3/ipu-prv.h1
-rw-r--r--include/drm/drm_modes.h5
-rw-r--r--include/drm/drm_modeset_helper_vtables.h29
-rw-r--r--include/video/imx-ipu-v3.h18
15 files changed, 247 insertions, 116 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 20be86d89a20..99365087645b 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -886,8 +886,12 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
886 * Each encoder has at most one connector (since we always steal 886 * Each encoder has at most one connector (since we always steal
887 * it away), so we won't call mode_set hooks twice. 887 * it away), so we won't call mode_set hooks twice.
888 */ 888 */
889 if (funcs && funcs->mode_set) 889 if (funcs && funcs->atomic_mode_set) {
890 funcs->atomic_mode_set(encoder, new_crtc_state,
891 connector->state);
892 } else if (funcs && funcs->mode_set) {
890 funcs->mode_set(encoder, mode, adjusted_mode); 893 funcs->mode_set(encoder, mode, adjusted_mode);
894 }
891 895
892 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode); 896 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
893 } 897 }
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index fc5040ae5f25..15704873fd61 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -657,6 +657,21 @@ void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
657} 657}
658EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode); 658EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
659 659
660void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)
661{
662 *bus_flags = 0;
663 if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
664 *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
665 if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
666 *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
667
668 if (vm->flags & DISPLAY_FLAGS_DE_LOW)
669 *bus_flags |= DRM_BUS_FLAG_DE_LOW;
670 if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
671 *bus_flags |= DRM_BUS_FLAG_DE_HIGH;
672}
673EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode);
674
660#ifdef CONFIG_OF 675#ifdef CONFIG_OF
661/** 676/**
662 * of_get_drm_display_mode - get a drm_display_mode from devicetree 677 * of_get_drm_display_mode - get a drm_display_mode from devicetree
@@ -672,7 +687,8 @@ EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
672 * 0 on success, a negative errno code when no of videomode node was found. 687 * 0 on success, a negative errno code when no of videomode node was found.
673 */ 688 */
674int of_get_drm_display_mode(struct device_node *np, 689int of_get_drm_display_mode(struct device_node *np,
675 struct drm_display_mode *dmode, int index) 690 struct drm_display_mode *dmode, u32 *bus_flags,
691 int index)
676{ 692{
677 struct videomode vm; 693 struct videomode vm;
678 int ret; 694 int ret;
@@ -682,6 +698,8 @@ int of_get_drm_display_mode(struct device_node *np,
682 return ret; 698 return ret;
683 699
684 drm_display_mode_from_videomode(&vm, dmode); 700 drm_display_mode_from_videomode(&vm, dmode);
701 if (bus_flags)
702 drm_bus_flags_from_videomode(&vm, bus_flags);
685 703
686 pr_debug("%s: got %dx%d display mode from %s\n", 704 pr_debug("%s: got %dx%d display mode from %s\n",
687 of_node_full_name(np), vm.hactive, vm.vactive, np->name); 705 of_node_full_name(np), vm.hactive, vm.vactive, np->name);
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 9f7dafce3a4c..6dc0ef4cc677 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -58,12 +58,6 @@ static int legacyfb_depth = 16;
58module_param(legacyfb_depth, int, 0444); 58module_param(legacyfb_depth, int, 0444);
59#endif 59#endif
60 60
61unsigned int imx_drm_crtc_id(struct imx_drm_crtc *crtc)
62{
63 return drm_crtc_index(crtc->crtc);
64}
65EXPORT_SYMBOL_GPL(imx_drm_crtc_id);
66
67static void imx_drm_driver_lastclose(struct drm_device *drm) 61static void imx_drm_driver_lastclose(struct drm_device *drm)
68{ 62{
69 struct imx_drm_device *imxdrm = drm->dev_private; 63 struct imx_drm_device *imxdrm = drm->dev_private;
@@ -90,24 +84,6 @@ static int imx_drm_driver_unload(struct drm_device *drm)
90 return 0; 84 return 0;
91} 85}
92 86
93int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
94{
95 return drm_crtc_vblank_get(imx_drm_crtc->crtc);
96}
97EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get);
98
99void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc)
100{
101 drm_crtc_vblank_put(imx_drm_crtc->crtc);
102}
103EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put);
104
105void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc)
106{
107 drm_crtc_handle_vblank(imx_drm_crtc->crtc);
108}
109EXPORT_SYMBOL_GPL(imx_drm_handle_vblank);
110
111static int imx_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) 87static int imx_drm_enable_vblank(struct drm_device *drm, unsigned int pipe)
112{ 88{
113 struct imx_drm_device *imxdrm = drm->dev_private; 89 struct imx_drm_device *imxdrm = drm->dev_private;
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index 07d33e45f90f..5a91cb16c8fa 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -13,8 +13,6 @@ struct drm_plane;
13struct imx_drm_crtc; 13struct imx_drm_crtc;
14struct platform_device; 14struct platform_device;
15 15
16unsigned int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
17
18struct imx_crtc_state { 16struct imx_crtc_state {
19 struct drm_crtc_state base; 17 struct drm_crtc_state base;
20 u32 bus_format; 18 u32 bus_format;
@@ -44,10 +42,6 @@ int imx_drm_init_drm(struct platform_device *pdev,
44 int preferred_bpp); 42 int preferred_bpp);
45int imx_drm_exit_drm(void); 43int imx_drm_exit_drm(void);
46 44
47int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc);
48void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc);
49void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc);
50
51void imx_drm_mode_config_init(struct drm_device *drm); 45void imx_drm_mode_config_init(struct drm_device *drm);
52 46
53struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); 47struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index b03919ed60ba..4eed3a6addad 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -57,7 +57,11 @@ struct imx_ldb_channel {
57 struct imx_ldb *ldb; 57 struct imx_ldb *ldb;
58 struct drm_connector connector; 58 struct drm_connector connector;
59 struct drm_encoder encoder; 59 struct drm_encoder encoder;
60
61 /* Defines what is connected to the ldb, only one at a time */
60 struct drm_panel *panel; 62 struct drm_panel *panel;
63 struct drm_bridge *bridge;
64
61 struct device_node *child; 65 struct device_node *child;
62 struct i2c_adapter *ddc; 66 struct i2c_adapter *ddc;
63 int chno; 67 int chno;
@@ -66,6 +70,7 @@ struct imx_ldb_channel {
66 struct drm_display_mode mode; 70 struct drm_display_mode mode;
67 int mode_valid; 71 int mode_valid;
68 u32 bus_format; 72 u32 bus_format;
73 u32 bus_flags;
69}; 74};
70 75
71static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector *c) 76static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector *c)
@@ -251,11 +256,13 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
251 drm_panel_enable(imx_ldb_ch->panel); 256 drm_panel_enable(imx_ldb_ch->panel);
252} 257}
253 258
254static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, 259static void
255 struct drm_display_mode *orig_mode, 260imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder,
256 struct drm_display_mode *mode) 261 struct drm_crtc_state *crtc_state,
262 struct drm_connector_state *connector_state)
257{ 263{
258 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 264 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
265 struct drm_display_mode *mode = &crtc_state->adjusted_mode;
259 struct imx_ldb *ldb = imx_ldb_ch->ldb; 266 struct imx_ldb *ldb = imx_ldb_ch->ldb;
260 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 267 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
261 unsigned long serial_clk; 268 unsigned long serial_clk;
@@ -297,17 +304,11 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
297 } 304 }
298 305
299 if (!bus_format) { 306 if (!bus_format) {
300 struct drm_connector *connector; 307 struct drm_connector *connector = connector_state->connector;
301 308 struct drm_display_info *di = &connector->display_info;
302 drm_for_each_connector(connector, encoder->dev) {
303 struct drm_display_info *di = &connector->display_info;
304 309
305 if (connector->encoder == encoder && 310 if (di->num_bus_formats)
306 di->num_bus_formats) { 311 bus_format = di->bus_formats[0];
307 bus_format = di->bus_formats[0];
308 break;
309 }
310 }
311 } 312 }
312 imx_ldb_ch_set_bus_format(imx_ldb_ch, bus_format); 313 imx_ldb_ch_set_bus_format(imx_ldb_ch, bus_format);
313} 314}
@@ -379,8 +380,13 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
379 u32 bus_format = imx_ldb_ch->bus_format; 380 u32 bus_format = imx_ldb_ch->bus_format;
380 381
381 /* Bus format description in DT overrides connector display info. */ 382 /* Bus format description in DT overrides connector display info. */
382 if (!bus_format && di->num_bus_formats) 383 if (!bus_format && di->num_bus_formats) {
383 bus_format = di->bus_formats[0]; 384 bus_format = di->bus_formats[0];
385 imx_crtc_state->bus_flags = di->bus_flags;
386 } else {
387 bus_format = imx_ldb_ch->bus_format;
388 imx_crtc_state->bus_flags = imx_ldb_ch->bus_flags;
389 }
384 switch (bus_format) { 390 switch (bus_format) {
385 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 391 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
386 imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18; 392 imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
@@ -420,7 +426,7 @@ static const struct drm_encoder_funcs imx_ldb_encoder_funcs = {
420}; 426};
421 427
422static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { 428static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
423 .mode_set = imx_ldb_encoder_mode_set, 429 .atomic_mode_set = imx_ldb_encoder_atomic_mode_set,
424 .enable = imx_ldb_encoder_enable, 430 .enable = imx_ldb_encoder_enable,
425 .disable = imx_ldb_encoder_disable, 431 .disable = imx_ldb_encoder_disable,
426 .atomic_check = imx_ldb_encoder_atomic_check, 432 .atomic_check = imx_ldb_encoder_atomic_check,
@@ -466,10 +472,30 @@ static int imx_ldb_register(struct drm_device *drm,
466 drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs, 472 drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs,
467 DRM_MODE_ENCODER_LVDS, NULL); 473 DRM_MODE_ENCODER_LVDS, NULL);
468 474
469 drm_connector_helper_add(&imx_ldb_ch->connector, 475 if (imx_ldb_ch->bridge) {
470 &imx_ldb_connector_helper_funcs); 476 imx_ldb_ch->bridge->encoder = encoder;
471 drm_connector_init(drm, &imx_ldb_ch->connector, 477
472 &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 478 imx_ldb_ch->encoder.bridge = imx_ldb_ch->bridge;
479 ret = drm_bridge_attach(drm, imx_ldb_ch->bridge);
480 if (ret) {
481 DRM_ERROR("Failed to initialize bridge with drm\n");
482 return ret;
483 }
484 } else {
485 /*
486 * We want to add the connector whenever there is no bridge
487 * that brings its own, not only when there is a panel. For
488 * historical reasons, the ldb driver can also work without
489 * a panel.
490 */
491 drm_connector_helper_add(&imx_ldb_ch->connector,
492 &imx_ldb_connector_helper_funcs);
493 drm_connector_init(drm, &imx_ldb_ch->connector,
494 &imx_ldb_connector_funcs,
495 DRM_MODE_CONNECTOR_LVDS);
496 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
497 encoder);
498 }
473 499
474 if (imx_ldb_ch->panel) { 500 if (imx_ldb_ch->panel) {
475 ret = drm_panel_attach(imx_ldb_ch->panel, 501 ret = drm_panel_attach(imx_ldb_ch->panel,
@@ -478,8 +504,6 @@ static int imx_ldb_register(struct drm_device *drm,
478 return ret; 504 return ret;
479 } 505 }
480 506
481 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, encoder);
482
483 return 0; 507 return 0;
484} 508}
485 509
@@ -548,6 +572,46 @@ static const struct of_device_id imx_ldb_dt_ids[] = {
548}; 572};
549MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); 573MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
550 574
575static int imx_ldb_panel_ddc(struct device *dev,
576 struct imx_ldb_channel *channel, struct device_node *child)
577{
578 struct device_node *ddc_node;
579 const u8 *edidp;
580 int ret;
581
582 ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
583 if (ddc_node) {
584 channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
585 of_node_put(ddc_node);
586 if (!channel->ddc) {
587 dev_warn(dev, "failed to get ddc i2c adapter\n");
588 return -EPROBE_DEFER;
589 }
590 }
591
592 if (!channel->ddc) {
593 /* if no DDC available, fallback to hardcoded EDID */
594 dev_dbg(dev, "no ddc available\n");
595
596 edidp = of_get_property(child, "edid",
597 &channel->edid_len);
598 if (edidp) {
599 channel->edid = kmemdup(edidp,
600 channel->edid_len,
601 GFP_KERNEL);
602 } else if (!channel->panel) {
603 /* fallback to display-timings node */
604 ret = of_get_drm_display_mode(child,
605 &channel->mode,
606 &channel->bus_flags,
607 OF_USE_NATIVE_MODE);
608 if (!ret)
609 channel->mode_valid = 1;
610 }
611 }
612 return 0;
613}
614
551static int imx_ldb_bind(struct device *dev, struct device *master, void *data) 615static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
552{ 616{
553 struct drm_device *drm = data; 617 struct drm_device *drm = data;
@@ -555,7 +619,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
555 const struct of_device_id *of_id = 619 const struct of_device_id *of_id =
556 of_match_device(imx_ldb_dt_ids, dev); 620 of_match_device(imx_ldb_dt_ids, dev);
557 struct device_node *child; 621 struct device_node *child;
558 const u8 *edidp;
559 struct imx_ldb *imx_ldb; 622 struct imx_ldb *imx_ldb;
560 int dual; 623 int dual;
561 int ret; 624 int ret;
@@ -605,7 +668,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
605 668
606 for_each_child_of_node(np, child) { 669 for_each_child_of_node(np, child) {
607 struct imx_ldb_channel *channel; 670 struct imx_ldb_channel *channel;
608 struct device_node *ddc_node;
609 struct device_node *ep; 671 struct device_node *ep;
610 int bus_format; 672 int bus_format;
611 673
@@ -638,46 +700,25 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
638 700
639 remote = of_graph_get_remote_port_parent(ep); 701 remote = of_graph_get_remote_port_parent(ep);
640 of_node_put(ep); 702 of_node_put(ep);
641 if (remote) 703 if (remote) {
642 channel->panel = of_drm_find_panel(remote); 704 channel->panel = of_drm_find_panel(remote);
643 else 705 channel->bridge = of_drm_find_bridge(remote);
706 } else
644 return -EPROBE_DEFER; 707 return -EPROBE_DEFER;
645 of_node_put(remote); 708 of_node_put(remote);
646 if (!channel->panel) {
647 dev_err(dev, "panel not found: %s\n",
648 remote->full_name);
649 return -EPROBE_DEFER;
650 }
651 }
652 709
653 ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); 710 if (!channel->panel && !channel->bridge) {
654 if (ddc_node) { 711 dev_err(dev, "panel/bridge not found: %s\n",
655 channel->ddc = of_find_i2c_adapter_by_node(ddc_node); 712 remote->full_name);
656 of_node_put(ddc_node);
657 if (!channel->ddc) {
658 dev_warn(dev, "failed to get ddc i2c adapter\n");
659 return -EPROBE_DEFER; 713 return -EPROBE_DEFER;
660 } 714 }
661 } 715 }
662 716
663 if (!channel->ddc) { 717 /* panel ddc only if there is no bridge */
664 /* if no DDC available, fallback to hardcoded EDID */ 718 if (!channel->bridge) {
665 dev_dbg(dev, "no ddc available\n"); 719 ret = imx_ldb_panel_ddc(dev, channel, child);
666 720 if (ret)
667 edidp = of_get_property(child, "edid", 721 return ret;
668 &channel->edid_len);
669 if (edidp) {
670 channel->edid = kmemdup(edidp,
671 channel->edid_len,
672 GFP_KERNEL);
673 } else if (!channel->panel) {
674 /* fallback to display-timings node */
675 ret = of_get_drm_display_mode(child,
676 &channel->mode,
677 OF_USE_NATIVE_MODE);
678 if (!ret)
679 channel->mode_valid = 1;
680 }
681 } 722 }
682 723
683 bus_format = of_get_bus_format(dev, child); 724 bus_format = of_get_bus_format(dev, child);
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 08e188bc10fc..5950b12a15c8 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -134,7 +134,7 @@ static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
134{ 134{
135 struct ipu_crtc *ipu_crtc = dev_id; 135 struct ipu_crtc *ipu_crtc = dev_id;
136 136
137 imx_drm_handle_vblank(ipu_crtc->imx_crtc); 137 drm_crtc_handle_vblank(&ipu_crtc->base);
138 138
139 return IRQ_HANDLED; 139 return IRQ_HANDLED;
140} 140}
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 1dad297b01fd..74b0ac06fdab 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -33,6 +33,7 @@ struct imx_parallel_display {
33 void *edid; 33 void *edid;
34 int edid_len; 34 int edid_len;
35 u32 bus_format; 35 u32 bus_format;
36 u32 bus_flags;
36 struct drm_display_mode mode; 37 struct drm_display_mode mode;
37 struct drm_panel *panel; 38 struct drm_panel *panel;
38 struct drm_bridge *bridge; 39 struct drm_bridge *bridge;
@@ -80,6 +81,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
80 return -EINVAL; 81 return -EINVAL;
81 82
82 ret = of_get_drm_display_mode(np, &imxpd->mode, 83 ret = of_get_drm_display_mode(np, &imxpd->mode,
84 &imxpd->bus_flags,
83 OF_USE_NATIVE_MODE); 85 OF_USE_NATIVE_MODE);
84 if (ret) 86 if (ret)
85 return ret; 87 return ret;
@@ -125,11 +127,13 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
125 struct drm_display_info *di = &conn_state->connector->display_info; 127 struct drm_display_info *di = &conn_state->connector->display_info;
126 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 128 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
127 129
128 imx_crtc_state->bus_flags = di->bus_flags; 130 if (!imxpd->bus_format && di->num_bus_formats) {
129 if (!imxpd->bus_format && di->num_bus_formats) 131 imx_crtc_state->bus_flags = di->bus_flags;
130 imx_crtc_state->bus_format = di->bus_formats[0]; 132 imx_crtc_state->bus_format = di->bus_formats[0];
131 else 133 } else {
134 imx_crtc_state->bus_flags = imxpd->bus_flags;
132 imx_crtc_state->bus_format = imxpd->bus_format; 135 imx_crtc_state->bus_format = imxpd->bus_format;
136 }
133 imx_crtc_state->di_hsync_pin = 2; 137 imx_crtc_state->di_hsync_pin = 2;
134 imx_crtc_state->di_vsync_pin = 3; 138 imx_crtc_state->di_vsync_pin = 3;
135 139
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 99dcacf05b99..d230988ddb8f 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -45,6 +45,12 @@ static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
45 writel(value, ipu->cm_reg + offset); 45 writel(value, ipu->cm_reg + offset);
46} 46}
47 47
48int ipu_get_num(struct ipu_soc *ipu)
49{
50 return ipu->id;
51}
52EXPORT_SYMBOL_GPL(ipu_get_num);
53
48void ipu_srm_dp_sync_update(struct ipu_soc *ipu) 54void ipu_srm_dp_sync_update(struct ipu_soc *ipu)
49{ 55{
50 u32 val; 56 u32 val;
@@ -1004,14 +1010,14 @@ static struct ipu_platform_reg client_reg[] = {
1004 .dma[0] = IPUV3_CHANNEL_CSI0, 1010 .dma[0] = IPUV3_CHANNEL_CSI0,
1005 .dma[1] = -EINVAL, 1011 .dma[1] = -EINVAL,
1006 }, 1012 },
1007 .name = "imx-ipuv3-camera", 1013 .name = "imx-ipuv3-csi",
1008 }, { 1014 }, {
1009 .pdata = { 1015 .pdata = {
1010 .csi = 1, 1016 .csi = 1,
1011 .dma[0] = IPUV3_CHANNEL_CSI1, 1017 .dma[0] = IPUV3_CHANNEL_CSI1,
1012 .dma[1] = -EINVAL, 1018 .dma[1] = -EINVAL,
1013 }, 1019 },
1014 .name = "imx-ipuv3-camera", 1020 .name = "imx-ipuv3-csi",
1015 }, { 1021 }, {
1016 .pdata = { 1022 .pdata = {
1017 .di = 0, 1023 .di = 0,
@@ -1209,6 +1215,7 @@ static int ipu_probe(struct platform_device *pdev)
1209{ 1215{
1210 const struct of_device_id *of_id = 1216 const struct of_device_id *of_id =
1211 of_match_device(imx_ipu_dt_ids, &pdev->dev); 1217 of_match_device(imx_ipu_dt_ids, &pdev->dev);
1218 struct device_node *np = pdev->dev.of_node;
1212 struct ipu_soc *ipu; 1219 struct ipu_soc *ipu;
1213 struct resource *res; 1220 struct resource *res;
1214 unsigned long ipu_base; 1221 unsigned long ipu_base;
@@ -1237,6 +1244,7 @@ static int ipu_probe(struct platform_device *pdev)
1237 ipu->channel[i].ipu = ipu; 1244 ipu->channel[i].ipu = ipu;
1238 ipu->devtype = devtype; 1245 ipu->devtype = devtype;
1239 ipu->ipu_type = devtype->type; 1246 ipu->ipu_type = devtype->type;
1247 ipu->id = of_alias_get_id(np, "ipu");
1240 1248
1241 spin_lock_init(&ipu->lock); 1249 spin_lock_init(&ipu->lock);
1242 mutex_init(&ipu->channel_lock); 1250 mutex_init(&ipu->channel_lock);
diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c
index 6494a4d28171..fcb7dc86167b 100644
--- a/drivers/gpu/ipu-v3/ipu-cpmem.c
+++ b/drivers/gpu/ipu-v3/ipu-cpmem.c
@@ -253,6 +253,13 @@ void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf)
253} 253}
254EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer); 254EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer);
255 255
256void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
257{
258 ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8);
259 ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8);
260}
261EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset);
262
256void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride) 263void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride)
257{ 264{
258 ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1); 265 ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1);
@@ -268,6 +275,12 @@ void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id)
268} 275}
269EXPORT_SYMBOL_GPL(ipu_cpmem_set_axi_id); 276EXPORT_SYMBOL_GPL(ipu_cpmem_set_axi_id);
270 277
278int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch)
279{
280 return ipu_ch_param_read_field(ch, IPU_FIELD_NPB) + 1;
281}
282EXPORT_SYMBOL_GPL(ipu_cpmem_get_burstsize);
283
271void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize) 284void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize)
272{ 285{
273 ipu_ch_param_write_field(ch, IPU_FIELD_NPB, burstsize - 1); 286 ipu_ch_param_write_field(ch, IPU_FIELD_NPB, burstsize - 1);
diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c
index 06631ac61b04..d6e5ded24418 100644
--- a/drivers/gpu/ipu-v3/ipu-csi.c
+++ b/drivers/gpu/ipu-v3/ipu-csi.c
@@ -258,12 +258,8 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code)
258 cfg->data_width = IPU_CSI_DATA_WIDTH_8; 258 cfg->data_width = IPU_CSI_DATA_WIDTH_8;
259 break; 259 break;
260 case MEDIA_BUS_FMT_UYVY8_1X16: 260 case MEDIA_BUS_FMT_UYVY8_1X16:
261 cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
262 cfg->mipi_dt = MIPI_DT_YUV422;
263 cfg->data_width = IPU_CSI_DATA_WIDTH_16;
264 break;
265 case MEDIA_BUS_FMT_YUYV8_1X16: 261 case MEDIA_BUS_FMT_YUYV8_1X16:
266 cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; 262 cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
267 cfg->mipi_dt = MIPI_DT_YUV422; 263 cfg->mipi_dt = MIPI_DT_YUV422;
268 cfg->data_width = IPU_CSI_DATA_WIDTH_16; 264 cfg->data_width = IPU_CSI_DATA_WIDTH_16;
269 break; 265 break;
@@ -365,10 +361,14 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
365{ 361{
366 struct ipu_csi_bus_config cfg; 362 struct ipu_csi_bus_config cfg;
367 unsigned long flags; 363 unsigned long flags;
368 u32 data = 0; 364 u32 width, height, data = 0;
369 365
370 fill_csi_bus_cfg(&cfg, mbus_cfg, mbus_fmt); 366 fill_csi_bus_cfg(&cfg, mbus_cfg, mbus_fmt);
371 367
368 /* set default sensor frame width and height */
369 width = mbus_fmt->width;
370 height = mbus_fmt->height;
371
372 /* Set the CSI_SENS_CONF register remaining fields */ 372 /* Set the CSI_SENS_CONF register remaining fields */
373 data |= cfg.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT | 373 data |= cfg.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
374 cfg.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT | 374 cfg.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
@@ -386,11 +386,6 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
386 386
387 ipu_csi_write(csi, data, CSI_SENS_CONF); 387 ipu_csi_write(csi, data, CSI_SENS_CONF);
388 388
389 /* Setup sensor frame size */
390 ipu_csi_write(csi,
391 (mbus_fmt->width - 1) | ((mbus_fmt->height - 1) << 16),
392 CSI_SENS_FRM_SIZE);
393
394 /* Set CCIR registers */ 389 /* Set CCIR registers */
395 390
396 switch (cfg.clk_mode) { 391 switch (cfg.clk_mode) {
@@ -408,11 +403,12 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
408 * Field1BlankEnd = 0x7, Field1BlankStart = 0x3, 403 * Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
409 * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1 404 * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
410 */ 405 */
406 height = 625; /* framelines for PAL */
407
411 ipu_csi_write(csi, 0x40596 | CSI_CCIR_ERR_DET_EN, 408 ipu_csi_write(csi, 0x40596 | CSI_CCIR_ERR_DET_EN,
412 CSI_CCIR_CODE_1); 409 CSI_CCIR_CODE_1);
413 ipu_csi_write(csi, 0xD07DF, CSI_CCIR_CODE_2); 410 ipu_csi_write(csi, 0xD07DF, CSI_CCIR_CODE_2);
414 ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3); 411 ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3);
415
416 } else if (mbus_fmt->width == 720 && mbus_fmt->height == 480) { 412 } else if (mbus_fmt->width == 720 && mbus_fmt->height == 480) {
417 /* 413 /*
418 * NTSC case 414 * NTSC case
@@ -422,6 +418,8 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
422 * Field1BlankEnd = 0x6, Field1BlankStart = 0x2, 418 * Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
423 * Field1ActiveEnd = 0x4, Field1ActiveStart = 0 419 * Field1ActiveEnd = 0x4, Field1ActiveStart = 0
424 */ 420 */
421 height = 525; /* framelines for NTSC */
422
425 ipu_csi_write(csi, 0xD07DF | CSI_CCIR_ERR_DET_EN, 423 ipu_csi_write(csi, 0xD07DF | CSI_CCIR_ERR_DET_EN,
426 CSI_CCIR_CODE_1); 424 CSI_CCIR_CODE_1);
427 ipu_csi_write(csi, 0x40596, CSI_CCIR_CODE_2); 425 ipu_csi_write(csi, 0x40596, CSI_CCIR_CODE_2);
@@ -447,6 +445,10 @@ int ipu_csi_init_interface(struct ipu_csi *csi,
447 break; 445 break;
448 } 446 }
449 447
448 /* Setup sensor frame size */
449 ipu_csi_write(csi, (width - 1) | ((height - 1) << 16),
450 CSI_SENS_FRM_SIZE);
451
450 dev_dbg(csi->ipu->dev, "CSI_SENS_CONF = 0x%08X\n", 452 dev_dbg(csi->ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
451 ipu_csi_read(csi, CSI_SENS_CONF)); 453 ipu_csi_read(csi, CSI_SENS_CONF));
452 dev_dbg(csi->ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n", 454 dev_dbg(csi->ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
index 1dcb96ccda66..1a37afcd85bd 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/ipu-v3/ipu-ic.c
@@ -160,6 +160,7 @@ struct ipu_ic_priv {
160 spinlock_t lock; 160 spinlock_t lock;
161 struct ipu_soc *ipu; 161 struct ipu_soc *ipu;
162 int use_count; 162 int use_count;
163 int irt_use_count;
163 struct ipu_ic task[IC_NUM_TASKS]; 164 struct ipu_ic task[IC_NUM_TASKS];
164}; 165};
165 166
@@ -379,8 +380,6 @@ void ipu_ic_task_disable(struct ipu_ic *ic)
379 380
380 ipu_ic_write(ic, ic_conf, IC_CONF); 381 ipu_ic_write(ic, ic_conf, IC_CONF);
381 382
382 ic->rotation = ic->graphics = false;
383
384 spin_unlock_irqrestore(&priv->lock, flags); 383 spin_unlock_irqrestore(&priv->lock, flags);
385} 384}
386EXPORT_SYMBOL_GPL(ipu_ic_task_disable); 385EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
@@ -629,22 +628,41 @@ unlock:
629} 628}
630EXPORT_SYMBOL_GPL(ipu_ic_task_idma_init); 629EXPORT_SYMBOL_GPL(ipu_ic_task_idma_init);
631 630
631static void ipu_irt_enable(struct ipu_ic *ic)
632{
633 struct ipu_ic_priv *priv = ic->priv;
634
635 if (!priv->irt_use_count)
636 ipu_module_enable(priv->ipu, IPU_CONF_ROT_EN);
637
638 priv->irt_use_count++;
639}
640
641static void ipu_irt_disable(struct ipu_ic *ic)
642{
643 struct ipu_ic_priv *priv = ic->priv;
644
645 if (priv->irt_use_count) {
646 if (!--priv->irt_use_count)
647 ipu_module_disable(priv->ipu, IPU_CONF_ROT_EN);
648 }
649}
650
632int ipu_ic_enable(struct ipu_ic *ic) 651int ipu_ic_enable(struct ipu_ic *ic)
633{ 652{
634 struct ipu_ic_priv *priv = ic->priv; 653 struct ipu_ic_priv *priv = ic->priv;
635 unsigned long flags; 654 unsigned long flags;
636 u32 module = IPU_CONF_IC_EN;
637 655
638 spin_lock_irqsave(&priv->lock, flags); 656 spin_lock_irqsave(&priv->lock, flags);
639 657
640 if (ic->rotation)
641 module |= IPU_CONF_ROT_EN;
642
643 if (!priv->use_count) 658 if (!priv->use_count)
644 ipu_module_enable(priv->ipu, module); 659 ipu_module_enable(priv->ipu, IPU_CONF_IC_EN);
645 660
646 priv->use_count++; 661 priv->use_count++;
647 662
663 if (ic->rotation)
664 ipu_irt_enable(ic);
665
648 spin_unlock_irqrestore(&priv->lock, flags); 666 spin_unlock_irqrestore(&priv->lock, flags);
649 667
650 return 0; 668 return 0;
@@ -655,18 +673,22 @@ int ipu_ic_disable(struct ipu_ic *ic)
655{ 673{
656 struct ipu_ic_priv *priv = ic->priv; 674 struct ipu_ic_priv *priv = ic->priv;
657 unsigned long flags; 675 unsigned long flags;
658 u32 module = IPU_CONF_IC_EN | IPU_CONF_ROT_EN;
659 676
660 spin_lock_irqsave(&priv->lock, flags); 677 spin_lock_irqsave(&priv->lock, flags);
661 678
662 priv->use_count--; 679 priv->use_count--;
663 680
664 if (!priv->use_count) 681 if (!priv->use_count)
665 ipu_module_disable(priv->ipu, module); 682 ipu_module_disable(priv->ipu, IPU_CONF_IC_EN);
666 683
667 if (priv->use_count < 0) 684 if (priv->use_count < 0)
668 priv->use_count = 0; 685 priv->use_count = 0;
669 686
687 if (ic->rotation)
688 ipu_irt_disable(ic);
689
690 ic->rotation = ic->graphics = false;
691
670 spin_unlock_irqrestore(&priv->lock, flags); 692 spin_unlock_irqrestore(&priv->lock, flags);
671 693
672 return 0; 694 return 0;
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h
index bfb1e8a4483f..fd47f8f555cd 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/ipu-v3/ipu-prv.h
@@ -152,6 +152,7 @@ struct ipu_soc {
152 void __iomem *cm_reg; 152 void __iomem *cm_reg;
153 void __iomem *idmac_reg; 153 void __iomem *idmac_reg;
154 154
155 int id;
155 int usecount; 156 int usecount;
156 157
157 struct clk *clk; 158 struct clk *clk;
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index ff481770d76b..48e1a56ea283 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -434,7 +434,7 @@ struct drm_cmdline_mode;
434struct drm_display_mode *drm_mode_create(struct drm_device *dev); 434struct drm_display_mode *drm_mode_create(struct drm_device *dev);
435void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); 435void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
436void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, 436void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
437 const struct drm_display_mode *in); 437 const struct drm_display_mode *in);
438int drm_mode_convert_umode(struct drm_display_mode *out, 438int drm_mode_convert_umode(struct drm_display_mode *out,
439 const struct drm_mode_modeinfo *in); 439 const struct drm_mode_modeinfo *in);
440void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); 440void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
@@ -457,8 +457,9 @@ void drm_display_mode_from_videomode(const struct videomode *vm,
457 struct drm_display_mode *dmode); 457 struct drm_display_mode *dmode);
458void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, 458void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
459 struct videomode *vm); 459 struct videomode *vm);
460void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags);
460int of_get_drm_display_mode(struct device_node *np, 461int of_get_drm_display_mode(struct device_node *np,
461 struct drm_display_mode *dmode, 462 struct drm_display_mode *dmode, u32 *bus_flags,
462 int index); 463 int index);
463 464
464void drm_mode_set_name(struct drm_display_mode *mode); 465void drm_mode_set_name(struct drm_display_mode *mode);
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index b55f21857a98..686feec6b4c8 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -523,12 +523,41 @@ struct drm_encoder_helper_funcs {
523 * 523 *
524 * This callback is used both by the legacy CRTC helpers and the atomic 524 * This callback is used both by the legacy CRTC helpers and the atomic
525 * modeset helpers. It is optional in the atomic helpers. 525 * modeset helpers. It is optional in the atomic helpers.
526 *
527 * NOTE:
528 *
529 * If the driver uses the atomic modeset helpers and needs to inspect
530 * the connector state or connector display info during mode setting,
531 * @atomic_mode_set can be used instead.
526 */ 532 */
527 void (*mode_set)(struct drm_encoder *encoder, 533 void (*mode_set)(struct drm_encoder *encoder,
528 struct drm_display_mode *mode, 534 struct drm_display_mode *mode,
529 struct drm_display_mode *adjusted_mode); 535 struct drm_display_mode *adjusted_mode);
530 536
531 /** 537 /**
538 * @atomic_mode_set:
539 *
540 * This callback is used to update the display mode of an encoder.
541 *
542 * Note that the display pipe is completely off when this function is
543 * called. Drivers which need hardware to be running before they program
544 * the new display mode (because they implement runtime PM) should not
545 * use this hook, because the helper library calls it only once and not
546 * every time the display pipeline is suspended using either DPMS or the
547 * new "ACTIVE" property. Such drivers should instead move all their
548 * encoder setup into the ->enable() callback.
549 *
550 * This callback is used by the atomic modeset helpers in place of the
551 * @mode_set callback, if set by the driver. It is optional and should
552 * be used instead of @mode_set if the driver needs to inspect the
553 * connector state or display info, since there is no direct way to
554 * go from the encoder to the current connector.
555 */
556 void (*atomic_mode_set)(struct drm_encoder *encoder,
557 struct drm_crtc_state *crtc_state,
558 struct drm_connector_state *conn_state);
559
560 /**
532 * @get_crtc: 561 * @get_crtc:
533 * 562 *
534 * This callback is used by the legacy CRTC helpers to work around 563 * This callback is used by the legacy CRTC helpers to work around
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h
index 7adeaae06961..c3de7406474b 100644
--- a/include/video/imx-ipu-v3.h
+++ b/include/video/imx-ipu-v3.h
@@ -97,20 +97,34 @@ enum ipu_channel_irq {
97#define IPUV3_CHANNEL_CSI2 2 97#define IPUV3_CHANNEL_CSI2 2
98#define IPUV3_CHANNEL_CSI3 3 98#define IPUV3_CHANNEL_CSI3 3
99#define IPUV3_CHANNEL_VDI_MEM_IC_VF 5 99#define IPUV3_CHANNEL_VDI_MEM_IC_VF 5
100#define IPUV3_CHANNEL_MEM_VDI_PREV 8
101#define IPUV3_CHANNEL_MEM_VDI_CUR 9
102#define IPUV3_CHANNEL_MEM_VDI_NEXT 10
100#define IPUV3_CHANNEL_MEM_IC_PP 11 103#define IPUV3_CHANNEL_MEM_IC_PP 11
101#define IPUV3_CHANNEL_MEM_IC_PRP_VF 12 104#define IPUV3_CHANNEL_MEM_IC_PRP_VF 12
105#define IPUV3_CHANNEL_VDI_MEM_RECENT 13
102#define IPUV3_CHANNEL_G_MEM_IC_PRP_VF 14 106#define IPUV3_CHANNEL_G_MEM_IC_PRP_VF 14
103#define IPUV3_CHANNEL_G_MEM_IC_PP 15 107#define IPUV3_CHANNEL_G_MEM_IC_PP 15
108#define IPUV3_CHANNEL_G_MEM_IC_PRP_VF_ALPHA 17
109#define IPUV3_CHANNEL_G_MEM_IC_PP_ALPHA 18
110#define IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB_ALPHA 19
104#define IPUV3_CHANNEL_IC_PRP_ENC_MEM 20 111#define IPUV3_CHANNEL_IC_PRP_ENC_MEM 20
105#define IPUV3_CHANNEL_IC_PRP_VF_MEM 21 112#define IPUV3_CHANNEL_IC_PRP_VF_MEM 21
106#define IPUV3_CHANNEL_IC_PP_MEM 22 113#define IPUV3_CHANNEL_IC_PP_MEM 22
107#define IPUV3_CHANNEL_MEM_BG_SYNC 23 114#define IPUV3_CHANNEL_MEM_BG_SYNC 23
108#define IPUV3_CHANNEL_MEM_BG_ASYNC 24 115#define IPUV3_CHANNEL_MEM_BG_ASYNC 24
116#define IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB 25
117#define IPUV3_CHANNEL_MEM_VDI_PLANE3_COMB 26
109#define IPUV3_CHANNEL_MEM_FG_SYNC 27 118#define IPUV3_CHANNEL_MEM_FG_SYNC 27
110#define IPUV3_CHANNEL_MEM_DC_SYNC 28 119#define IPUV3_CHANNEL_MEM_DC_SYNC 28
111#define IPUV3_CHANNEL_MEM_FG_ASYNC 29 120#define IPUV3_CHANNEL_MEM_FG_ASYNC 29
112#define IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA 31 121#define IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA 31
122#define IPUV3_CHANNEL_MEM_FG_ASYNC_ALPHA 33
123#define IPUV3_CHANNEL_DC_MEM_READ 40
113#define IPUV3_CHANNEL_MEM_DC_ASYNC 41 124#define IPUV3_CHANNEL_MEM_DC_ASYNC 41
125#define IPUV3_CHANNEL_MEM_DC_COMMAND 42
126#define IPUV3_CHANNEL_MEM_DC_COMMAND2 43
127#define IPUV3_CHANNEL_MEM_DC_OUTPUT_MASK 44
114#define IPUV3_CHANNEL_MEM_ROT_ENC 45 128#define IPUV3_CHANNEL_MEM_ROT_ENC 45
115#define IPUV3_CHANNEL_MEM_ROT_VF 46 129#define IPUV3_CHANNEL_MEM_ROT_VF 46
116#define IPUV3_CHANNEL_MEM_ROT_PP 47 130#define IPUV3_CHANNEL_MEM_ROT_PP 47
@@ -118,6 +132,7 @@ enum ipu_channel_irq {
118#define IPUV3_CHANNEL_ROT_VF_MEM 49 132#define IPUV3_CHANNEL_ROT_VF_MEM 49
119#define IPUV3_CHANNEL_ROT_PP_MEM 50 133#define IPUV3_CHANNEL_ROT_PP_MEM 50
120#define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA 51 134#define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA 51
135#define IPUV3_CHANNEL_MEM_BG_ASYNC_ALPHA 52
121 136
122int ipu_map_irq(struct ipu_soc *ipu, int irq); 137int ipu_map_irq(struct ipu_soc *ipu, int irq);
123int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, 138int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
@@ -138,6 +153,7 @@ int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
138/* 153/*
139 * IPU Common functions 154 * IPU Common functions
140 */ 155 */
156int ipu_get_num(struct ipu_soc *ipu);
141void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2); 157void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2);
142void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi); 158void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi);
143void ipu_dump(struct ipu_soc *ipu); 159void ipu_dump(struct ipu_soc *ipu);
@@ -184,8 +200,10 @@ void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres);
184void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride); 200void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride);
185void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch); 201void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch);
186void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf); 202void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf);
203void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off);
187void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride); 204void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride);
188void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id); 205void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id);
206int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch);
189void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize); 207void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize);
190void ipu_cpmem_set_block_mode(struct ipuv3_channel *ch); 208void ipu_cpmem_set_block_mode(struct ipuv3_channel *ch);
191void ipu_cpmem_set_rotation(struct ipuv3_channel *ch, 209void ipu_cpmem_set_rotation(struct ipuv3_channel *ch,