forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
....@@ -1,21 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2014 Free Electrons
34 * Copyright (C) 2014 Atmel
45 *
56 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License version 2 as published by
9
- * the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful, but WITHOUT
12
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
- * more details.
15
- *
16
- * You should have received a copy of the GNU General Public License along with
17
- * this program. If not, see <http://www.gnu.org/licenses/>.
187 */
8
+
9
+#include <linux/dmapool.h>
10
+#include <linux/mfd/atmel-hlcdc.h>
11
+
12
+#include <drm/drm_atomic.h>
13
+#include <drm/drm_atomic_helper.h>
14
+#include <drm/drm_fb_cma_helper.h>
15
+#include <drm/drm_fourcc.h>
16
+#include <drm/drm_gem_cma_helper.h>
17
+#include <drm/drm_plane_helper.h>
1918
2019 #include "atmel_hlcdc_dc.h"
2120
....@@ -372,7 +371,7 @@
372371 atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_HLCDC_LAYER_DMA_CFG,
373372 cfg);
374373
375
- cfg = ATMEL_HLCDC_LAYER_DMA;
374
+ cfg = ATMEL_HLCDC_LAYER_DMA | ATMEL_HLCDC_LAYER_REP;
376375
377376 if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
378377 cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL |
....@@ -549,7 +548,8 @@
549548
550549 ovl_state = drm_plane_state_to_atmel_hlcdc_plane_state(ovl_s);
551550
552
- if (!ovl_s->fb ||
551
+ if (!ovl_s->visible ||
552
+ !ovl_s->fb ||
553553 ovl_s->fb->format->has_alpha ||
554554 ovl_s->alpha != DRM_BLEND_ALPHA_OPAQUE)
555555 continue;
....@@ -601,31 +601,30 @@
601601 struct drm_framebuffer *fb = state->base.fb;
602602 const struct drm_display_mode *mode;
603603 struct drm_crtc_state *crtc_state;
604
- unsigned int patched_crtc_w;
605
- unsigned int patched_crtc_h;
606
- unsigned int patched_src_w;
607
- unsigned int patched_src_h;
608
- unsigned int tmp;
609
- int x_offset = 0;
610
- int y_offset = 0;
611
- int hsub = 1;
612
- int vsub = 1;
604
+ int ret;
613605 int i;
614606
615
- if (!state->base.crtc || !fb)
607
+ if (!state->base.crtc || WARN_ON(!fb))
616608 return 0;
617609
618610 crtc_state = drm_atomic_get_existing_crtc_state(s->state, s->crtc);
619611 mode = &crtc_state->adjusted_mode;
620612
621
- state->src_x = s->src_x;
622
- state->src_y = s->src_y;
623
- state->src_h = s->src_h;
624
- state->src_w = s->src_w;
625
- state->crtc_x = s->crtc_x;
626
- state->crtc_y = s->crtc_y;
627
- state->crtc_h = s->crtc_h;
628
- state->crtc_w = s->crtc_w;
613
+ ret = drm_atomic_helper_check_plane_state(s, crtc_state,
614
+ (1 << 16) / 2048,
615
+ INT_MAX, true, true);
616
+ if (ret || !s->visible)
617
+ return ret;
618
+
619
+ state->src_x = s->src.x1;
620
+ state->src_y = s->src.y1;
621
+ state->src_w = drm_rect_width(&s->src);
622
+ state->src_h = drm_rect_height(&s->src);
623
+ state->crtc_x = s->dst.x1;
624
+ state->crtc_y = s->dst.y1;
625
+ state->crtc_w = drm_rect_width(&s->dst);
626
+ state->crtc_h = drm_rect_height(&s->dst);
627
+
629628 if ((state->src_x | state->src_y | state->src_w | state->src_h) &
630629 SUBPIXEL_MASK)
631630 return -EINVAL;
....@@ -639,52 +638,10 @@
639638 if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES)
640639 return -EINVAL;
641640
642
- /*
643
- * Swap width and size in case of 90 or 270 degrees rotation
644
- */
645
- if (drm_rotation_90_or_270(state->base.rotation)) {
646
- tmp = state->crtc_w;
647
- state->crtc_w = state->crtc_h;
648
- state->crtc_h = tmp;
649
- tmp = state->src_w;
650
- state->src_w = state->src_h;
651
- state->src_h = tmp;
652
- }
653
-
654
- if (state->crtc_x + state->crtc_w > mode->hdisplay)
655
- patched_crtc_w = mode->hdisplay - state->crtc_x;
656
- else
657
- patched_crtc_w = state->crtc_w;
658
-
659
- if (state->crtc_x < 0) {
660
- patched_crtc_w += state->crtc_x;
661
- x_offset = -state->crtc_x;
662
- state->crtc_x = 0;
663
- }
664
-
665
- if (state->crtc_y + state->crtc_h > mode->vdisplay)
666
- patched_crtc_h = mode->vdisplay - state->crtc_y;
667
- else
668
- patched_crtc_h = state->crtc_h;
669
-
670
- if (state->crtc_y < 0) {
671
- patched_crtc_h += state->crtc_y;
672
- y_offset = -state->crtc_y;
673
- state->crtc_y = 0;
674
- }
675
-
676
- patched_src_w = DIV_ROUND_CLOSEST(patched_crtc_w * state->src_w,
677
- state->crtc_w);
678
- patched_src_h = DIV_ROUND_CLOSEST(patched_crtc_h * state->src_h,
679
- state->crtc_h);
680
-
681
- hsub = drm_format_horz_chroma_subsampling(fb->format->format);
682
- vsub = drm_format_vert_chroma_subsampling(fb->format->format);
683
-
684641 for (i = 0; i < state->nplanes; i++) {
685642 unsigned int offset = 0;
686
- int xdiv = i ? hsub : 1;
687
- int ydiv = i ? vsub : 1;
643
+ int xdiv = i ? fb->format->hsub : 1;
644
+ int ydiv = i ? fb->format->vsub : 1;
688645
689646 state->bpp[i] = fb->format->cpp[i];
690647 if (!state->bpp[i])
....@@ -692,41 +649,38 @@
692649
693650 switch (state->base.rotation & DRM_MODE_ROTATE_MASK) {
694651 case DRM_MODE_ROTATE_90:
695
- offset = ((y_offset + state->src_y + patched_src_w - 1) /
696
- ydiv) * fb->pitches[i];
697
- offset += ((x_offset + state->src_x) / xdiv) *
698
- state->bpp[i];
699
- state->xstride[i] = ((patched_src_w - 1) / ydiv) *
700
- fb->pitches[i];
701
- state->pstride[i] = -fb->pitches[i] - state->bpp[i];
702
- break;
703
- case DRM_MODE_ROTATE_180:
704
- offset = ((y_offset + state->src_y + patched_src_h - 1) /
705
- ydiv) * fb->pitches[i];
706
- offset += ((x_offset + state->src_x + patched_src_w - 1) /
707
- xdiv) * state->bpp[i];
708
- state->xstride[i] = ((((patched_src_w - 1) / xdiv) - 1) *
709
- state->bpp[i]) - fb->pitches[i];
710
- state->pstride[i] = -2 * state->bpp[i];
711
- break;
712
- case DRM_MODE_ROTATE_270:
713
- offset = ((y_offset + state->src_y) / ydiv) *
652
+ offset = (state->src_y / ydiv) *
714653 fb->pitches[i];
715
- offset += ((x_offset + state->src_x + patched_src_h - 1) /
654
+ offset += ((state->src_x + state->src_w - 1) /
716655 xdiv) * state->bpp[i];
717
- state->xstride[i] = -(((patched_src_w - 1) / ydiv) *
656
+ state->xstride[i] = -(((state->src_h - 1) / ydiv) *
718657 fb->pitches[i]) -
719658 (2 * state->bpp[i]);
720659 state->pstride[i] = fb->pitches[i] - state->bpp[i];
721660 break;
661
+ case DRM_MODE_ROTATE_180:
662
+ offset = ((state->src_y + state->src_h - 1) /
663
+ ydiv) * fb->pitches[i];
664
+ offset += ((state->src_x + state->src_w - 1) /
665
+ xdiv) * state->bpp[i];
666
+ state->xstride[i] = ((((state->src_w - 1) / xdiv) - 1) *
667
+ state->bpp[i]) - fb->pitches[i];
668
+ state->pstride[i] = -2 * state->bpp[i];
669
+ break;
670
+ case DRM_MODE_ROTATE_270:
671
+ offset = ((state->src_y + state->src_h - 1) /
672
+ ydiv) * fb->pitches[i];
673
+ offset += (state->src_x / xdiv) * state->bpp[i];
674
+ state->xstride[i] = ((state->src_h - 1) / ydiv) *
675
+ fb->pitches[i];
676
+ state->pstride[i] = -fb->pitches[i] - state->bpp[i];
677
+ break;
722678 case DRM_MODE_ROTATE_0:
723679 default:
724
- offset = ((y_offset + state->src_y) / ydiv) *
725
- fb->pitches[i];
726
- offset += ((x_offset + state->src_x) / xdiv) *
727
- state->bpp[i];
680
+ offset = (state->src_y / ydiv) * fb->pitches[i];
681
+ offset += (state->src_x / xdiv) * state->bpp[i];
728682 state->xstride[i] = fb->pitches[i] -
729
- ((patched_src_w / xdiv) *
683
+ ((state->src_w / xdiv) *
730684 state->bpp[i]);
731685 state->pstride[i] = 0;
732686 break;
....@@ -735,20 +689,16 @@
735689 state->offsets[i] = offset + fb->offsets[i];
736690 }
737691
738
- state->src_w = patched_src_w;
739
- state->src_h = patched_src_h;
740
- state->crtc_w = patched_crtc_w;
741
- state->crtc_h = patched_crtc_h;
692
+ /*
693
+ * Swap width and size in case of 90 or 270 degrees rotation
694
+ */
695
+ if (drm_rotation_90_or_270(state->base.rotation)) {
696
+ swap(state->src_w, state->src_h);
697
+ }
742698
743699 if (!desc->layout.size &&
744700 (mode->hdisplay != state->crtc_w ||
745701 mode->vdisplay != state->crtc_h))
746
- return -EINVAL;
747
-
748
- if (desc->max_height && state->crtc_h > desc->max_height)
749
- return -EINVAL;
750
-
751
- if (desc->max_width && state->crtc_w > desc->max_width)
752702 return -EINVAL;
753703
754704 if ((state->crtc_h != state->src_h || state->crtc_w != state->src_w) &&
....@@ -756,14 +706,26 @@
756706 state->base.fb->format->has_alpha))
757707 return -EINVAL;
758708
759
- if (state->crtc_x < 0 || state->crtc_y < 0)
760
- return -EINVAL;
761
-
762
- if (state->crtc_w + state->crtc_x > mode->hdisplay ||
763
- state->crtc_h + state->crtc_y > mode->vdisplay)
764
- return -EINVAL;
765
-
766709 return 0;
710
+}
711
+
712
+static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
713
+ struct drm_plane_state *old_state)
714
+{
715
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
716
+
717
+ /* Disable interrupts */
718
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
719
+ 0xffffffff);
720
+
721
+ /* Disable the layer */
722
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHDR,
723
+ ATMEL_HLCDC_LAYER_RST |
724
+ ATMEL_HLCDC_LAYER_A2Q |
725
+ ATMEL_HLCDC_LAYER_UPDATE);
726
+
727
+ /* Clear all pending interrupts */
728
+ atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
767729 }
768730
769731 static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
....@@ -776,6 +738,11 @@
776738
777739 if (!p->state->crtc || !p->state->fb)
778740 return;
741
+
742
+ if (!state->base.visible) {
743
+ atmel_hlcdc_plane_atomic_disable(p, old_s);
744
+ return;
745
+ }
779746
780747 atmel_hlcdc_plane_update_pos_and_size(plane, state);
781748 atmel_hlcdc_plane_update_general_settings(plane, state);
....@@ -796,25 +763,6 @@
796763 ATMEL_HLCDC_LAYER_UPDATE |
797764 (sr & ATMEL_HLCDC_LAYER_EN ?
798765 ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
799
-}
800
-
801
-static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
802
- struct drm_plane_state *old_state)
803
-{
804
- struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
805
-
806
- /* Disable interrupts */
807
- atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
808
- 0xffffffff);
809
-
810
- /* Disable the layer */
811
- atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHDR,
812
- ATMEL_HLCDC_LAYER_RST |
813
- ATMEL_HLCDC_LAYER_A2Q |
814
- ATMEL_HLCDC_LAYER_UPDATE);
815
-
816
- /* Clear all pending interrupts */
817
- atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
818766 }
819767
820768 static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
....@@ -942,10 +890,7 @@
942890 "Failed to allocate initial plane state\n");
943891 return;
944892 }
945
-
946
- p->state = &state->base;
947
- p->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
948
- p->state->plane = p;
893
+ __drm_atomic_helper_plane_reset(p, &state->base);
949894 }
950895 }
951896