forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/media/platform/rcar-vin/rcar-dma.c
....@@ -85,6 +85,7 @@
8585 #define VNMC_INF_YUV8_BT601 (1 << 16)
8686 #define VNMC_INF_YUV10_BT656 (2 << 16)
8787 #define VNMC_INF_YUV10_BT601 (3 << 16)
88
+#define VNMC_INF_RAW8 (4 << 16)
8889 #define VNMC_INF_YUV16 (5 << 16)
8990 #define VNMC_INF_RGB888 (6 << 16)
9091 #define VNMC_VUP (1 << 10)
....@@ -111,15 +112,20 @@
111112 #define VNIE_EFE (1 << 1)
112113
113114 /* Video n Data Mode Register bits */
115
+#define VNDMR_A8BIT(n) (((n) & 0xff) << 24)
116
+#define VNDMR_A8BIT_MASK (0xff << 24)
114117 #define VNDMR_EXRGB (1 << 8)
115118 #define VNDMR_BPSM (1 << 4)
119
+#define VNDMR_ABIT (1 << 2)
116120 #define VNDMR_DTMD_YCSEP (1 << 1)
117
-#define VNDMR_DTMD_ARGB1555 (1 << 0)
121
+#define VNDMR_DTMD_ARGB (1 << 0)
122
+#define VNDMR_DTMD_YCSEP_420 (3 << 0)
118123
119124 /* Video n Data Mode Register 2 bits */
120125 #define VNDMR2_VPS (1 << 30)
121126 #define VNDMR2_HPS (1 << 29)
122127 #define VNDMR2_CES (1 << 28)
128
+#define VNDMR2_YDS (1 << 22)
123129 #define VNDMR2_FTEV (1 << 17)
124130 #define VNDMR2_VLV(n) ((n & 0xf) << 12)
125131
....@@ -486,7 +492,7 @@
486492 }
487493
488494 /* Use previous value if its XS value is closer */
489
- if (p_prev_set && p_set &&
495
+ if (p_prev_set &&
490496 xs - p_prev_set->xs_value < p_set->xs_value - xs)
491497 p_set = p_prev_set;
492498
....@@ -526,12 +532,17 @@
526532
527533 static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
528534 {
535
+ unsigned int crop_height;
529536 u32 xs, ys;
530537
531538 /* Set scaling coefficient */
539
+ crop_height = vin->crop.height;
540
+ if (V4L2_FIELD_HAS_BOTH(vin->format.field))
541
+ crop_height *= 2;
542
+
532543 ys = 0;
533
- if (vin->crop.height != vin->compose.height)
534
- ys = (4096 * vin->crop.height) / vin->compose.height;
544
+ if (crop_height != vin->compose.height)
545
+ ys = (4096 * crop_height) / vin->compose.height;
535546 rvin_write(vin, ys, VNYS_REG);
536547
537548 xs = 0;
....@@ -554,16 +565,11 @@
554565 rvin_write(vin, 0, VNSPPOC_REG);
555566 rvin_write(vin, 0, VNSLPOC_REG);
556567 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);
557
- switch (vin->format.field) {
558
- case V4L2_FIELD_INTERLACED:
559
- case V4L2_FIELD_INTERLACED_TB:
560
- case V4L2_FIELD_INTERLACED_BT:
568
+
569
+ if (V4L2_FIELD_HAS_BOTH(vin->format.field))
561570 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);
562
- break;
563
- default:
571
+ else
564572 rvin_write(vin, vin->format.height - 1, VNELPOC_REG);
565
- break;
566
- }
567573
568574 vin_dbg(vin,
569575 "Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n",
....@@ -574,33 +580,37 @@
574580
575581 void rvin_crop_scale_comp(struct rvin_dev *vin)
576582 {
583
+ const struct rvin_video_format *fmt;
584
+ u32 stride;
585
+
577586 /* Set Start/End Pixel/Line Pre-Clip */
578587 rvin_write(vin, vin->crop.left, VNSPPRC_REG);
579588 rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
580
-
581
- switch (vin->format.field) {
582
- case V4L2_FIELD_INTERLACED:
583
- case V4L2_FIELD_INTERLACED_TB:
584
- case V4L2_FIELD_INTERLACED_BT:
585
- rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
586
- rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
587
- VNELPRC_REG);
588
- break;
589
- default:
590
- rvin_write(vin, vin->crop.top, VNSLPRC_REG);
591
- rvin_write(vin, vin->crop.top + vin->crop.height - 1,
592
- VNELPRC_REG);
593
- break;
594
- }
589
+ rvin_write(vin, vin->crop.top, VNSLPRC_REG);
590
+ rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);
595591
596592 /* TODO: Add support for the UDS scaler. */
597593 if (vin->info->model != RCAR_GEN3)
598594 rvin_crop_scale_comp_gen2(vin);
599595
600
- if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
601
- rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
602
- else
603
- rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
596
+ fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
597
+ stride = vin->format.bytesperline / fmt->bpp;
598
+
599
+ /* For RAW8 format bpp is 1, but the hardware process RAW8
600
+ * format in 2 pixel unit hence configure VNIS_REG as stride / 2.
601
+ */
602
+ switch (vin->format.pixelformat) {
603
+ case V4L2_PIX_FMT_SBGGR8:
604
+ case V4L2_PIX_FMT_SGBRG8:
605
+ case V4L2_PIX_FMT_SGRBG8:
606
+ case V4L2_PIX_FMT_SRGGB8:
607
+ stride /= 2;
608
+ break;
609
+ default:
610
+ break;
611
+ }
612
+
613
+ rvin_write(vin, stride, VNIS_REG);
604614 }
605615
606616 /* -----------------------------------------------------------------------------
....@@ -632,9 +642,14 @@
632642 case V4L2_FIELD_INTERLACED_BT:
633643 vnmc = VNMC_IM_FULL | VNMC_FOC;
634644 break;
645
+ case V4L2_FIELD_SEQ_TB:
646
+ case V4L2_FIELD_SEQ_BT:
635647 case V4L2_FIELD_NONE:
636648 vnmc = VNMC_IM_ODD_EVEN;
637649 progressive = true;
650
+ break;
651
+ case V4L2_FIELD_ALTERNATE:
652
+ vnmc = VNMC_IM_ODD_EVEN;
638653 break;
639654 default:
640655 vnmc = VNMC_IM_ODD;
....@@ -677,11 +692,17 @@
677692
678693 input_is_yuv = true;
679694 break;
695
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
696
+ case MEDIA_BUS_FMT_SGBRG8_1X8:
697
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
698
+ case MEDIA_BUS_FMT_SRGGB8_1X8:
699
+ vnmc |= VNMC_INF_RAW8;
700
+ break;
680701 default:
681702 break;
682703 }
683704
684
- /* Enable VSYNC Field Toogle mode after one VSYNC input */
705
+ /* Enable VSYNC Field Toggle mode after one VSYNC input */
685706 if (vin->info->model == RCAR_GEN3)
686707 dmr2 = VNDMR2_FTEV;
687708 else
....@@ -689,27 +710,39 @@
689710
690711 if (!vin->is_csi) {
691712 /* Hsync Signal Polarity Select */
692
- if (!(vin->parallel->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
713
+ if (!(vin->parallel->bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
693714 dmr2 |= VNDMR2_HPS;
694715
695716 /* Vsync Signal Polarity Select */
696
- if (!(vin->parallel->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
717
+ if (!(vin->parallel->bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
697718 dmr2 |= VNDMR2_VPS;
698719
699720 /* Data Enable Polarity Select */
700
- if (vin->parallel->mbus_flags & V4L2_MBUS_DATA_ENABLE_LOW)
721
+ if (vin->parallel->bus.flags & V4L2_MBUS_DATA_ENABLE_LOW)
701722 dmr2 |= VNDMR2_CES;
723
+
724
+ switch (vin->mbus_code) {
725
+ case MEDIA_BUS_FMT_UYVY8_2X8:
726
+ if (vin->parallel->bus.bus_width == 8 &&
727
+ vin->parallel->bus.data_shift == 8)
728
+ dmr2 |= VNDMR2_YDS;
729
+ break;
730
+ default:
731
+ break;
732
+ }
702733 }
703734
704735 /*
705736 * Output format
706737 */
707738 switch (vin->format.pixelformat) {
739
+ case V4L2_PIX_FMT_NV12:
708740 case V4L2_PIX_FMT_NV16:
709741 rvin_write(vin,
710
- ALIGN(vin->format.width * vin->format.height, 0x80),
711
- VNUVAOF_REG);
712
- dmr = VNDMR_DTMD_YCSEP;
742
+ ALIGN(vin->format.bytesperline * vin->format.height,
743
+ 0x80), VNUVAOF_REG);
744
+ dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ?
745
+ VNDMR_DTMD_YCSEP_420 : VNDMR_DTMD_YCSEP;
713746 output_is_yuv = true;
714747 break;
715748 case V4L2_PIX_FMT_YUYV:
....@@ -721,7 +754,7 @@
721754 output_is_yuv = true;
722755 break;
723756 case V4L2_PIX_FMT_XRGB555:
724
- dmr = VNDMR_DTMD_ARGB1555;
757
+ dmr = VNDMR_DTMD_ARGB;
725758 break;
726759 case V4L2_PIX_FMT_RGB565:
727760 dmr = 0;
....@@ -729,6 +762,18 @@
729762 case V4L2_PIX_FMT_XBGR32:
730763 /* Note: not supported on M1 */
731764 dmr = VNDMR_EXRGB;
765
+ break;
766
+ case V4L2_PIX_FMT_ARGB555:
767
+ dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
768
+ break;
769
+ case V4L2_PIX_FMT_ABGR32:
770
+ dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
771
+ break;
772
+ case V4L2_PIX_FMT_SBGGR8:
773
+ case V4L2_PIX_FMT_SGBRG8:
774
+ case V4L2_PIX_FMT_SGRBG8:
775
+ case V4L2_PIX_FMT_SRGGB8:
776
+ dmr = 0;
732777 break;
733778 default:
734779 vin_err(vin, "Invalid pixelformat (0x%x)\n",
....@@ -788,13 +833,25 @@
788833 return rvin_read(vin, VNMS_REG) & VNMS_CA;
789834 }
790835
836
+static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
837
+{
838
+ if (vin->format.field == V4L2_FIELD_ALTERNATE) {
839
+ /* If FS is set it is an Even field. */
840
+ if (vnms & VNMS_FS)
841
+ return V4L2_FIELD_BOTTOM;
842
+ return V4L2_FIELD_TOP;
843
+ }
844
+
845
+ return vin->format.field;
846
+}
847
+
791848 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
792849 {
793850 const struct rvin_video_format *fmt;
794851 int offsetx, offsety;
795852 dma_addr_t offset;
796853
797
- fmt = rvin_format_from_pixel(vin->format.pixelformat);
854
+ fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
798855
799856 /*
800857 * There is no HW support for composition do the beast we can
....@@ -825,33 +882,63 @@
825882 struct rvin_buffer *buf;
826883 struct vb2_v4l2_buffer *vbuf;
827884 dma_addr_t phys_addr;
885
+ int prev;
828886
829887 /* A already populated slot shall never be overwritten. */
830
- if (WARN_ON(vin->queue_buf[slot] != NULL))
888
+ if (WARN_ON(vin->buf_hw[slot].buffer))
831889 return;
832890
833
- vin_dbg(vin, "Filling HW slot: %d\n", slot);
891
+ prev = (slot == 0 ? HW_BUFFER_NUM : slot) - 1;
834892
835
- if (list_empty(&vin->buf_list)) {
836
- vin->queue_buf[slot] = NULL;
893
+ if (vin->buf_hw[prev].type == HALF_TOP) {
894
+ vbuf = vin->buf_hw[prev].buffer;
895
+ vin->buf_hw[slot].buffer = vbuf;
896
+ vin->buf_hw[slot].type = HALF_BOTTOM;
897
+ switch (vin->format.pixelformat) {
898
+ case V4L2_PIX_FMT_NV12:
899
+ case V4L2_PIX_FMT_NV16:
900
+ phys_addr = vin->buf_hw[prev].phys +
901
+ vin->format.sizeimage / 4;
902
+ break;
903
+ default:
904
+ phys_addr = vin->buf_hw[prev].phys +
905
+ vin->format.sizeimage / 2;
906
+ break;
907
+ }
908
+ } else if (list_empty(&vin->buf_list)) {
909
+ vin->buf_hw[slot].buffer = NULL;
910
+ vin->buf_hw[slot].type = FULL;
837911 phys_addr = vin->scratch_phys;
838912 } else {
839913 /* Keep track of buffer we give to HW */
840914 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
841915 vbuf = &buf->vb;
842916 list_del_init(to_buf_list(vbuf));
843
- vin->queue_buf[slot] = vbuf;
917
+ vin->buf_hw[slot].buffer = vbuf;
918
+
919
+ vin->buf_hw[slot].type =
920
+ V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ?
921
+ HALF_TOP : FULL;
844922
845923 /* Setup DMA */
846924 phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
847925 }
848926
927
+ vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n",
928
+ slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer);
929
+
930
+ vin->buf_hw[slot].phys = phys_addr;
849931 rvin_set_slot_addr(vin, slot, phys_addr);
850932 }
851933
852934 static int rvin_capture_start(struct rvin_dev *vin)
853935 {
854936 int slot, ret;
937
+
938
+ for (slot = 0; slot < HW_BUFFER_NUM; slot++) {
939
+ vin->buf_hw[slot].buffer = NULL;
940
+ vin->buf_hw[slot].type = FULL;
941
+ }
855942
856943 for (slot = 0; slot < HW_BUFFER_NUM; slot++)
857944 rvin_fill_hw_slot(vin, slot);
....@@ -936,13 +1023,24 @@
9361023 }
9371024
9381025 /* Capture frame */
939
- if (vin->queue_buf[slot]) {
940
- vin->queue_buf[slot]->field = vin->format.field;
941
- vin->queue_buf[slot]->sequence = vin->sequence;
942
- vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
943
- vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf,
1026
+ if (vin->buf_hw[slot].buffer) {
1027
+ /*
1028
+ * Nothing to do but refill the hardware slot if
1029
+ * capture only filled first half of vb2 buffer.
1030
+ */
1031
+ if (vin->buf_hw[slot].type == HALF_TOP) {
1032
+ vin->buf_hw[slot].buffer = NULL;
1033
+ rvin_fill_hw_slot(vin, slot);
1034
+ goto done;
1035
+ }
1036
+
1037
+ vin->buf_hw[slot].buffer->field =
1038
+ rvin_get_active_field(vin, vnms);
1039
+ vin->buf_hw[slot].buffer->sequence = vin->sequence;
1040
+ vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns();
1041
+ vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf,
9441042 VB2_BUF_STATE_DONE);
945
- vin->queue_buf[slot] = NULL;
1043
+ vin->buf_hw[slot].buffer = NULL;
9461044 } else {
9471045 /* Scratch buffer was used, dropping frame. */
9481046 vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
....@@ -963,14 +1061,22 @@
9631061 enum vb2_buffer_state state)
9641062 {
9651063 struct rvin_buffer *buf, *node;
966
- int i;
1064
+ struct vb2_v4l2_buffer *freed[HW_BUFFER_NUM];
1065
+ unsigned int i, n;
9671066
9681067 for (i = 0; i < HW_BUFFER_NUM; i++) {
969
- if (vin->queue_buf[i]) {
970
- vb2_buffer_done(&vin->queue_buf[i]->vb2_buf,
971
- state);
972
- vin->queue_buf[i] = NULL;
1068
+ freed[i] = vin->buf_hw[i].buffer;
1069
+ vin->buf_hw[i].buffer = NULL;
1070
+
1071
+ for (n = 0; n < i; n++) {
1072
+ if (freed[i] == freed[n]) {
1073
+ freed[i] = NULL;
1074
+ break;
1075
+ }
9731076 }
1077
+
1078
+ if (freed[i])
1079
+ vb2_buffer_done(&freed[i]->vb2_buf, state);
9741080 }
9751081
9761082 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
....@@ -1042,11 +1148,27 @@
10421148 case MEDIA_BUS_FMT_UYVY8_2X8:
10431149 case MEDIA_BUS_FMT_UYVY10_2X10:
10441150 case MEDIA_BUS_FMT_RGB888_1X24:
1045
- vin->mbus_code = fmt.format.code;
1151
+ break;
1152
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
1153
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8)
1154
+ return -EPIPE;
1155
+ break;
1156
+ case MEDIA_BUS_FMT_SGBRG8_1X8:
1157
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8)
1158
+ return -EPIPE;
1159
+ break;
1160
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
1161
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8)
1162
+ return -EPIPE;
1163
+ break;
1164
+ case MEDIA_BUS_FMT_SRGGB8_1X8:
1165
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8)
1166
+ return -EPIPE;
10461167 break;
10471168 default:
10481169 return -EPIPE;
10491170 }
1171
+ vin->mbus_code = fmt.format.code;
10501172
10511173 switch (fmt.format.field) {
10521174 case V4L2_FIELD_TOP:
....@@ -1064,6 +1186,7 @@
10641186 case V4L2_FIELD_TOP:
10651187 case V4L2_FIELD_BOTTOM:
10661188 case V4L2_FIELD_NONE:
1189
+ case V4L2_FIELD_ALTERNATE:
10671190 break;
10681191 case V4L2_FIELD_INTERLACED_TB:
10691192 case V4L2_FIELD_INTERLACED_BT:
....@@ -1273,7 +1396,7 @@
12731396 vin->state = STOPPED;
12741397
12751398 for (i = 0; i < HW_BUFFER_NUM; i++)
1276
- vin->queue_buf[i] = NULL;
1399
+ vin->buf_hw[i].buffer = NULL;
12771400
12781401 /* buffer queue */
12791402 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
....@@ -1343,5 +1466,36 @@
13431466
13441467 pm_runtime_put(vin->dev);
13451468
1346
- return ret;
1469
+ return 0;
1470
+}
1471
+
1472
+void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
1473
+{
1474
+ unsigned long flags;
1475
+ u32 dmr;
1476
+
1477
+ spin_lock_irqsave(&vin->qlock, flags);
1478
+
1479
+ vin->alpha = alpha;
1480
+
1481
+ if (vin->state == STOPPED)
1482
+ goto out;
1483
+
1484
+ switch (vin->format.pixelformat) {
1485
+ case V4L2_PIX_FMT_ARGB555:
1486
+ dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
1487
+ if (vin->alpha)
1488
+ dmr |= VNDMR_ABIT;
1489
+ break;
1490
+ case V4L2_PIX_FMT_ABGR32:
1491
+ dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
1492
+ dmr |= VNDMR_A8BIT(vin->alpha);
1493
+ break;
1494
+ default:
1495
+ goto out;
1496
+ }
1497
+
1498
+ rvin_write(vin, dmr, VNDMR_REG);
1499
+out:
1500
+ spin_unlock_irqrestore(&vin->qlock, flags);
13471501 }