aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-12-04 19:34:46 -0500
committerDave Airlie <airlied@redhat.com>2017-12-04 19:34:46 -0500
commitc5dd52f653fa74f8f4771425c6db33609ad21258 (patch)
treee7c934c91b19b7f89ad107199513f298b16edb7e /drivers/gpu/drm
parentca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (diff)
parent401712e035c699d569dbd37024f4b21dc76cc870 (diff)
Merge branch 'drm/next/du' of git://linuxtv.org/pinchartl/media into drm-next
The series contains one patch that touches the V4L2 VSP driver. Mauro has acked it for merge through your tree, it doesn't conflict with anything scheduled for merge in v4.16 through Mauro's tree. * 'drm/next/du' of git://linuxtv.org/pinchartl/media: drm: rcar-du: Clip planes to screen boundaries drm: rcar-du: Share plane atomic check code between Gen2 and Gen3 v4l: vsp1: Start and stop DRM pipeline independently of planes drm: rcar-du: Remove unused CRTC suspend/resume functions drm: rcar-du: Implement system suspend/resume support drm: rcar-du: Don't set connector DPMS property drm: rcar-du: Add R8A7745 support drm: rcar-du: Add R8A7743 support dt-bindings: display: rcar-du: Document R8A774[35] DU
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c38
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c62
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.h1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c75
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c64
7 files changed, 143 insertions, 105 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 301ea1a8018e..5685d5af6998 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -319,7 +319,8 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
319 struct rcar_du_plane *plane = &rcrtc->group->planes[i]; 319 struct rcar_du_plane *plane = &rcrtc->group->planes[i];
320 unsigned int j; 320 unsigned int j;
321 321
322 if (plane->plane.state->crtc != &rcrtc->crtc) 322 if (plane->plane.state->crtc != &rcrtc->crtc ||
323 !plane->plane.state->visible)
323 continue; 324 continue;
324 325
325 /* Insert the plane in the sorted planes array. */ 326 /* Insert the plane in the sorted planes array. */
@@ -557,41 +558,6 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
557 rcar_du_group_start_stop(rcrtc->group, false); 558 rcar_du_group_start_stop(rcrtc->group, false);
558} 559}
559 560
560void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
561{
562 if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
563 rcar_du_vsp_disable(rcrtc);
564
565 rcar_du_crtc_stop(rcrtc);
566 rcar_du_crtc_put(rcrtc);
567}
568
569void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
570{
571 unsigned int i;
572
573 if (!rcrtc->crtc.state->active)
574 return;
575
576 rcar_du_crtc_get(rcrtc);
577 rcar_du_crtc_setup(rcrtc);
578
579 /* Commit the planes state. */
580 if (!rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
581 for (i = 0; i < rcrtc->group->num_planes; ++i) {
582 struct rcar_du_plane *plane = &rcrtc->group->planes[i];
583
584 if (plane->plane.state->crtc != &rcrtc->crtc)
585 continue;
586
587 rcar_du_plane_setup(plane);
588 }
589 }
590
591 rcar_du_crtc_update_planes(rcrtc);
592 rcar_du_crtc_start(rcrtc);
593}
594
595/* ----------------------------------------------------------------------------- 561/* -----------------------------------------------------------------------------
596 * CRTC Functions 562 * CRTC Functions
597 */ 563 */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d2f29e6b1112..6e02c762a557 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -22,6 +22,7 @@
22#include <linux/wait.h> 22#include <linux/wait.h>
23 23
24#include <drm/drmP.h> 24#include <drm/drmP.h>
25#include <drm/drm_atomic_helper.h>
25#include <drm/drm_crtc_helper.h> 26#include <drm/drm_crtc_helper.h>
26#include <drm/drm_fb_cma_helper.h> 27#include <drm/drm_fb_cma_helper.h>
27#include <drm/drm_gem_cma_helper.h> 28#include <drm/drm_gem_cma_helper.h>
@@ -34,6 +35,48 @@
34 * Device Information 35 * Device Information
35 */ 36 */
36 37
38static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
39 .gen = 2,
40 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
41 | RCAR_DU_FEATURE_EXT_CTRL_REGS,
42 .num_crtcs = 2,
43 .routes = {
44 /*
45 * R8A7743 has one RGB output and one LVDS output
46 */
47 [RCAR_DU_OUTPUT_DPAD0] = {
48 .possible_crtcs = BIT(1) | BIT(0),
49 .port = 0,
50 },
51 [RCAR_DU_OUTPUT_LVDS0] = {
52 .possible_crtcs = BIT(0),
53 .port = 1,
54 },
55 },
56 .num_lvds = 1,
57};
58
59static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
60 .gen = 2,
61 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
62 | RCAR_DU_FEATURE_EXT_CTRL_REGS,
63 .num_crtcs = 2,
64 .routes = {
65 /*
66 * R8A7745 has two RGB outputs
67 */
68 [RCAR_DU_OUTPUT_DPAD0] = {
69 .possible_crtcs = BIT(0),
70 .port = 0,
71 },
72 [RCAR_DU_OUTPUT_DPAD1] = {
73 .possible_crtcs = BIT(1),
74 .port = 1,
75 },
76 },
77 .num_lvds = 0,
78};
79
37static const struct rcar_du_device_info rcar_du_r8a7779_info = { 80static const struct rcar_du_device_info rcar_du_r8a7779_info = {
38 .gen = 2, 81 .gen = 2,
39 .features = 0, 82 .features = 0,
@@ -207,6 +250,8 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
207}; 250};
208 251
209static const struct of_device_id rcar_du_of_table[] = { 252static const struct of_device_id rcar_du_of_table[] = {
253 { .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
254 { .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
210 { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info }, 255 { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
211 { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info }, 256 { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
212 { .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info }, 257 { .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
@@ -265,9 +310,19 @@ static struct drm_driver rcar_du_driver = {
265static int rcar_du_pm_suspend(struct device *dev) 310static int rcar_du_pm_suspend(struct device *dev)
266{ 311{
267 struct rcar_du_device *rcdu = dev_get_drvdata(dev); 312 struct rcar_du_device *rcdu = dev_get_drvdata(dev);
313 struct drm_atomic_state *state;
268 314
269 drm_kms_helper_poll_disable(rcdu->ddev); 315 drm_kms_helper_poll_disable(rcdu->ddev);
270 /* TODO Suspend the CRTC */ 316 drm_fbdev_cma_set_suspend_unlocked(rcdu->fbdev, true);
317
318 state = drm_atomic_helper_suspend(rcdu->ddev);
319 if (IS_ERR(state)) {
320 drm_fbdev_cma_set_suspend_unlocked(rcdu->fbdev, false);
321 drm_kms_helper_poll_enable(rcdu->ddev);
322 return PTR_ERR(state);
323 }
324
325 rcdu->suspend_state = state;
271 326
272 return 0; 327 return 0;
273} 328}
@@ -276,9 +331,10 @@ static int rcar_du_pm_resume(struct device *dev)
276{ 331{
277 struct rcar_du_device *rcdu = dev_get_drvdata(dev); 332 struct rcar_du_device *rcdu = dev_get_drvdata(dev);
278 333
279 /* TODO Resume the CRTC */ 334 drm_atomic_helper_resume(rcdu->ddev, rcdu->suspend_state);
280 335 drm_fbdev_cma_set_suspend_unlocked(rcdu->fbdev, false);
281 drm_kms_helper_poll_enable(rcdu->ddev); 336 drm_kms_helper_poll_enable(rcdu->ddev);
337
282 return 0; 338 return 0;
283} 339}
284#endif 340#endif
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index f8cd79488ece..f400fde65a0c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -81,6 +81,7 @@ struct rcar_du_device {
81 81
82 struct drm_device *ddev; 82 struct drm_device *ddev;
83 struct drm_fbdev_cma *fbdev; 83 struct drm_fbdev_cma *fbdev;
84 struct drm_atomic_state *suspend_state;
84 85
85 struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS]; 86 struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS];
86 unsigned int num_crtcs; 87 unsigned int num_crtcs;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
index b373ad48ef5f..e96f2df0c305 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
@@ -79,10 +79,6 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
79 79
80 drm_connector_helper_add(connector, &connector_helper_funcs); 80 drm_connector_helper_add(connector, &connector_helper_funcs);
81 81
82 connector->dpms = DRM_MODE_DPMS_OFF;
83 drm_object_property_set_value(&connector->base,
84 rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
85
86 ret = drm_mode_connector_attach_encoder(connector, encoder); 82 ret = drm_mode_connector_attach_encoder(connector, encoder);
87 if (ret < 0) 83 if (ret < 0)
88 return ret; 84 return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 61833cc1c699..4a3d16cf3ed6 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -332,8 +332,8 @@ static void rcar_du_plane_write(struct rcar_du_group *rgrp,
332static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, 332static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
333 const struct rcar_du_plane_state *state) 333 const struct rcar_du_plane_state *state)
334{ 334{
335 unsigned int src_x = state->state.src_x >> 16; 335 unsigned int src_x = state->state.src.x1 >> 16;
336 unsigned int src_y = state->state.src_y >> 16; 336 unsigned int src_y = state->state.src.y1 >> 16;
337 unsigned int index = state->hwindex; 337 unsigned int index = state->hwindex;
338 unsigned int pitch; 338 unsigned int pitch;
339 bool interlaced; 339 bool interlaced;
@@ -357,7 +357,7 @@ static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
357 dma[i] = gem->paddr + fb->offsets[i]; 357 dma[i] = gem->paddr + fb->offsets[i];
358 } 358 }
359 } else { 359 } else {
360 pitch = state->state.src_w >> 16; 360 pitch = drm_rect_width(&state->state.src) >> 16;
361 dma[0] = 0; 361 dma[0] = 0;
362 dma[1] = 0; 362 dma[1] = 0;
363 } 363 }
@@ -521,6 +521,7 @@ static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp,
521 const struct rcar_du_plane_state *state) 521 const struct rcar_du_plane_state *state)
522{ 522{
523 struct rcar_du_device *rcdu = rgrp->dev; 523 struct rcar_du_device *rcdu = rgrp->dev;
524 const struct drm_rect *dst = &state->state.dst;
524 525
525 if (rcdu->info->gen < 3) 526 if (rcdu->info->gen < 3)
526 rcar_du_plane_setup_format_gen2(rgrp, index, state); 527 rcar_du_plane_setup_format_gen2(rgrp, index, state);
@@ -528,10 +529,10 @@ static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp,
528 rcar_du_plane_setup_format_gen3(rgrp, index, state); 529 rcar_du_plane_setup_format_gen3(rgrp, index, state);
529 530
530 /* Destination position and size */ 531 /* Destination position and size */
531 rcar_du_plane_write(rgrp, index, PnDSXR, state->state.crtc_w); 532 rcar_du_plane_write(rgrp, index, PnDSXR, drm_rect_width(dst));
532 rcar_du_plane_write(rgrp, index, PnDSYR, state->state.crtc_h); 533 rcar_du_plane_write(rgrp, index, PnDSYR, drm_rect_height(dst));
533 rcar_du_plane_write(rgrp, index, PnDPXR, state->state.crtc_x); 534 rcar_du_plane_write(rgrp, index, PnDPXR, dst->x1);
534 rcar_du_plane_write(rgrp, index, PnDPYR, state->state.crtc_y); 535 rcar_du_plane_write(rgrp, index, PnDPYR, dst->y1);
535 536
536 if (rcdu->info->gen < 3) { 537 if (rcdu->info->gen < 3) {
537 /* Wrap-around and blinking, disabled */ 538 /* Wrap-around and blinking, disabled */
@@ -565,27 +566,49 @@ void __rcar_du_plane_setup(struct rcar_du_group *rgrp,
565 } 566 }
566} 567}
567 568
568static int rcar_du_plane_atomic_check(struct drm_plane *plane, 569int __rcar_du_plane_atomic_check(struct drm_plane *plane,
569 struct drm_plane_state *state) 570 struct drm_plane_state *state,
571 const struct rcar_du_format_info **format)
570{ 572{
571 struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); 573 struct drm_device *dev = plane->dev;
572 struct rcar_du_plane *rplane = to_rcar_plane(plane); 574 struct drm_crtc_state *crtc_state;
573 struct rcar_du_device *rcdu = rplane->group->dev; 575 struct drm_rect clip;
576 int ret;
574 577
575 if (!state->fb || !state->crtc) { 578 if (!state->crtc) {
576 rstate->format = NULL; 579 /*
580 * The visible field is not reset by the DRM core but only
581 * updated by drm_plane_helper_check_state(), set it manually.
582 */
583 state->visible = false;
584 *format = NULL;
577 return 0; 585 return 0;
578 } 586 }
579 587
580 if (state->src_w >> 16 != state->crtc_w || 588 crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
581 state->src_h >> 16 != state->crtc_h) { 589 if (IS_ERR(crtc_state))
582 dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__); 590 return PTR_ERR(crtc_state);
583 return -EINVAL; 591
592 clip.x1 = 0;
593 clip.y1 = 0;
594 clip.x2 = crtc_state->mode.hdisplay;
595 clip.y2 = crtc_state->mode.vdisplay;
596
597 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
598 DRM_PLANE_HELPER_NO_SCALING,
599 DRM_PLANE_HELPER_NO_SCALING,
600 true, true);
601 if (ret < 0)
602 return ret;
603
604 if (!state->visible) {
605 *format = NULL;
606 return 0;
584 } 607 }
585 608
586 rstate->format = rcar_du_format_info(state->fb->format->format); 609 *format = rcar_du_format_info(state->fb->format->format);
587 if (rstate->format == NULL) { 610 if (*format == NULL) {
588 dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__, 611 dev_dbg(dev->dev, "%s: unsupported format %08x\n", __func__,
589 state->fb->format->format); 612 state->fb->format->format);
590 return -EINVAL; 613 return -EINVAL;
591 } 614 }
@@ -593,6 +616,14 @@ static int rcar_du_plane_atomic_check(struct drm_plane *plane,
593 return 0; 616 return 0;
594} 617}
595 618
619static int rcar_du_plane_atomic_check(struct drm_plane *plane,
620 struct drm_plane_state *state)
621{
622 struct rcar_du_plane_state *rstate = to_rcar_plane_state(state);
623
624 return __rcar_du_plane_atomic_check(plane, state, &rstate->format);
625}
626
596static void rcar_du_plane_atomic_update(struct drm_plane *plane, 627static void rcar_du_plane_atomic_update(struct drm_plane *plane,
597 struct drm_plane_state *old_state) 628 struct drm_plane_state *old_state)
598{ 629{
@@ -600,7 +631,7 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
600 struct rcar_du_plane_state *old_rstate; 631 struct rcar_du_plane_state *old_rstate;
601 struct rcar_du_plane_state *new_rstate; 632 struct rcar_du_plane_state *new_rstate;
602 633
603 if (!plane->state->crtc) 634 if (!plane->state->visible)
604 return; 635 return;
605 636
606 rcar_du_plane_setup(rplane); 637 rcar_du_plane_setup(rplane);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index f62e09f195de..890321b4665d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -73,6 +73,10 @@ to_rcar_plane_state(struct drm_plane_state *state)
73int rcar_du_atomic_check_planes(struct drm_device *dev, 73int rcar_du_atomic_check_planes(struct drm_device *dev,
74 struct drm_atomic_state *state); 74 struct drm_atomic_state *state);
75 75
76int __rcar_du_plane_atomic_check(struct drm_plane *plane,
77 struct drm_plane_state *state,
78 const struct rcar_du_format_info **format);
79
76int rcar_du_planes_init(struct rcar_du_group *rgrp); 80int rcar_du_planes_init(struct rcar_du_group *rgrp);
77 81
78void __rcar_du_plane_setup(struct rcar_du_group *rgrp, 82void __rcar_du_plane_setup(struct rcar_du_group *rgrp,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 2c96147bc444..2c260c33840b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -55,14 +55,14 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
55 struct rcar_du_plane_state state = { 55 struct rcar_du_plane_state state = {
56 .state = { 56 .state = {
57 .crtc = &crtc->crtc, 57 .crtc = &crtc->crtc,
58 .crtc_x = 0, 58 .dst.x1 = 0,
59 .crtc_y = 0, 59 .dst.y1 = 0,
60 .crtc_w = mode->hdisplay, 60 .dst.x2 = mode->hdisplay,
61 .crtc_h = mode->vdisplay, 61 .dst.y2 = mode->vdisplay,
62 .src_x = 0, 62 .src.x1 = 0,
63 .src_y = 0, 63 .src.y1 = 0,
64 .src_w = mode->hdisplay << 16, 64 .src.x2 = mode->hdisplay << 16,
65 .src_h = mode->vdisplay << 16, 65 .src.y2 = mode->vdisplay << 16,
66 .zpos = 0, 66 .zpos = 0,
67 }, 67 },
68 .format = rcar_du_format_info(DRM_FORMAT_ARGB8888), 68 .format = rcar_du_format_info(DRM_FORMAT_ARGB8888),
@@ -178,15 +178,15 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
178 }; 178 };
179 unsigned int i; 179 unsigned int i;
180 180
181 cfg.src.left = state->state.src_x >> 16; 181 cfg.src.left = state->state.src.x1 >> 16;
182 cfg.src.top = state->state.src_y >> 16; 182 cfg.src.top = state->state.src.y1 >> 16;
183 cfg.src.width = state->state.src_w >> 16; 183 cfg.src.width = drm_rect_width(&state->state.src) >> 16;
184 cfg.src.height = state->state.src_h >> 16; 184 cfg.src.height = drm_rect_height(&state->state.src) >> 16;
185 185
186 cfg.dst.left = state->state.crtc_x; 186 cfg.dst.left = state->state.dst.x1;
187 cfg.dst.top = state->state.crtc_y; 187 cfg.dst.top = state->state.dst.y1;
188 cfg.dst.width = state->state.crtc_w; 188 cfg.dst.width = drm_rect_width(&state->state.dst);
189 cfg.dst.height = state->state.crtc_h; 189 cfg.dst.height = drm_rect_height(&state->state.dst);
190 190
191 for (i = 0; i < state->format->planes; ++i) 191 for (i = 0; i < state->format->planes; ++i)
192 cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl) 192 cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
@@ -212,7 +212,11 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
212 unsigned int i; 212 unsigned int i;
213 int ret; 213 int ret;
214 214
215 if (!state->fb) 215 /*
216 * There's no need to prepare (and unprepare) the framebuffer when the
217 * plane is not visible, as it will not be displayed.
218 */
219 if (!state->visible)
216 return 0; 220 return 0;
217 221
218 for (i = 0; i < rstate->format->planes; ++i) { 222 for (i = 0; i < rstate->format->planes; ++i) {
@@ -253,7 +257,7 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
253 struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; 257 struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
254 unsigned int i; 258 unsigned int i;
255 259
256 if (!state->fb) 260 if (!state->visible)
257 return; 261 return;
258 262
259 for (i = 0; i < rstate->format->planes; ++i) { 263 for (i = 0; i < rstate->format->planes; ++i) {
@@ -268,28 +272,8 @@ static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
268 struct drm_plane_state *state) 272 struct drm_plane_state *state)
269{ 273{
270 struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state); 274 struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
271 struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
272 struct rcar_du_device *rcdu = rplane->vsp->dev;
273 275
274 if (!state->fb || !state->crtc) { 276 return __rcar_du_plane_atomic_check(plane, state, &rstate->format);
275 rstate->format = NULL;
276 return 0;
277 }
278
279 if (state->src_w >> 16 != state->crtc_w ||
280 state->src_h >> 16 != state->crtc_h) {
281 dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__);
282 return -EINVAL;
283 }
284
285 rstate->format = rcar_du_format_info(state->fb->format->format);
286 if (rstate->format == NULL) {
287 dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__,
288 state->fb->format->format);
289 return -EINVAL;
290 }
291
292 return 0;
293} 277}
294 278
295static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane, 279static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
@@ -298,7 +282,7 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
298 struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane); 282 struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
299 struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc); 283 struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
300 284
301 if (plane->state->crtc) 285 if (plane->state->visible)
302 rcar_du_vsp_plane_setup(rplane); 286 rcar_du_vsp_plane_setup(rplane);
303 else 287 else
304 vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe, 288 vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,