diff options
author | Dave Airlie <airlied@redhat.com> | 2017-12-04 19:34:46 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-12-04 19:34:46 -0500 |
commit | c5dd52f653fa74f8f4771425c6db33609ad21258 (patch) | |
tree | e7c934c91b19b7f89ad107199513f298b16edb7e /drivers/gpu/drm | |
parent | ca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (diff) | |
parent | 401712e035c699d569dbd37024f4b21dc76cc870 (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.c | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_plane.c | 75 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_plane.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 64 |
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 | ||
560 | void 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 | |||
569 | void 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 | ||
38 | static 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 | |||
59 | static 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 | |||
37 | static const struct rcar_du_device_info rcar_du_r8a7779_info = { | 80 | static 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 | ||
209 | static const struct of_device_id rcar_du_of_table[] = { | 252 | static 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 = { | |||
265 | static int rcar_du_pm_suspend(struct device *dev) | 310 | static 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, | |||
332 | static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, | 332 | static 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 | ||
568 | static int rcar_du_plane_atomic_check(struct drm_plane *plane, | 569 | int __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 | ||
619 | static 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 | |||
596 | static void rcar_du_plane_atomic_update(struct drm_plane *plane, | 627 | static 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) | |||
73 | int rcar_du_atomic_check_planes(struct drm_device *dev, | 73 | int rcar_du_atomic_check_planes(struct drm_device *dev, |
74 | struct drm_atomic_state *state); | 74 | struct drm_atomic_state *state); |
75 | 75 | ||
76 | int __rcar_du_plane_atomic_check(struct drm_plane *plane, | ||
77 | struct drm_plane_state *state, | ||
78 | const struct rcar_du_format_info **format); | ||
79 | |||
76 | int rcar_du_planes_init(struct rcar_du_group *rgrp); | 80 | int rcar_du_planes_init(struct rcar_du_group *rgrp); |
77 | 81 | ||
78 | void __rcar_du_plane_setup(struct rcar_du_group *rgrp, | 82 | void __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 | ||
295 | static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane, | 279 | static 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, |