forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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,7 +642,10 @@
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:
648
+ case V4L2_FIELD_ALTERNATE:
636649 vnmc = VNMC_IM_ODD_EVEN;
637650 progressive = true;
638651 break;
....@@ -677,11 +690,17 @@
677690
678691 input_is_yuv = true;
679692 break;
693
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
694
+ case MEDIA_BUS_FMT_SGBRG8_1X8:
695
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
696
+ case MEDIA_BUS_FMT_SRGGB8_1X8:
697
+ vnmc |= VNMC_INF_RAW8;
698
+ break;
680699 default:
681700 break;
682701 }
683702
684
- /* Enable VSYNC Field Toogle mode after one VSYNC input */
703
+ /* Enable VSYNC Field Toggle mode after one VSYNC input */
685704 if (vin->info->model == RCAR_GEN3)
686705 dmr2 = VNDMR2_FTEV;
687706 else
....@@ -689,27 +708,39 @@
689708
690709 if (!vin->is_csi) {
691710 /* Hsync Signal Polarity Select */
692
- if (!(vin->parallel->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
711
+ if (!(vin->parallel->bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
693712 dmr2 |= VNDMR2_HPS;
694713
695714 /* Vsync Signal Polarity Select */
696
- if (!(vin->parallel->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
715
+ if (!(vin->parallel->bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
697716 dmr2 |= VNDMR2_VPS;
698717
699718 /* Data Enable Polarity Select */
700
- if (vin->parallel->mbus_flags & V4L2_MBUS_DATA_ENABLE_LOW)
719
+ if (vin->parallel->bus.flags & V4L2_MBUS_DATA_ENABLE_LOW)
701720 dmr2 |= VNDMR2_CES;
721
+
722
+ switch (vin->mbus_code) {
723
+ case MEDIA_BUS_FMT_UYVY8_2X8:
724
+ if (vin->parallel->bus.bus_width == 8 &&
725
+ vin->parallel->bus.data_shift == 8)
726
+ dmr2 |= VNDMR2_YDS;
727
+ break;
728
+ default:
729
+ break;
730
+ }
702731 }
703732
704733 /*
705734 * Output format
706735 */
707736 switch (vin->format.pixelformat) {
737
+ case V4L2_PIX_FMT_NV12:
708738 case V4L2_PIX_FMT_NV16:
709739 rvin_write(vin,
710
- ALIGN(vin->format.width * vin->format.height, 0x80),
711
- VNUVAOF_REG);
712
- dmr = VNDMR_DTMD_YCSEP;
740
+ ALIGN(vin->format.bytesperline * vin->format.height,
741
+ 0x80), VNUVAOF_REG);
742
+ dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ?
743
+ VNDMR_DTMD_YCSEP_420 : VNDMR_DTMD_YCSEP;
713744 output_is_yuv = true;
714745 break;
715746 case V4L2_PIX_FMT_YUYV:
....@@ -721,7 +752,7 @@
721752 output_is_yuv = true;
722753 break;
723754 case V4L2_PIX_FMT_XRGB555:
724
- dmr = VNDMR_DTMD_ARGB1555;
755
+ dmr = VNDMR_DTMD_ARGB;
725756 break;
726757 case V4L2_PIX_FMT_RGB565:
727758 dmr = 0;
....@@ -729,6 +760,18 @@
729760 case V4L2_PIX_FMT_XBGR32:
730761 /* Note: not supported on M1 */
731762 dmr = VNDMR_EXRGB;
763
+ break;
764
+ case V4L2_PIX_FMT_ARGB555:
765
+ dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
766
+ break;
767
+ case V4L2_PIX_FMT_ABGR32:
768
+ dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
769
+ break;
770
+ case V4L2_PIX_FMT_SBGGR8:
771
+ case V4L2_PIX_FMT_SGBRG8:
772
+ case V4L2_PIX_FMT_SGRBG8:
773
+ case V4L2_PIX_FMT_SRGGB8:
774
+ dmr = 0;
732775 break;
733776 default:
734777 vin_err(vin, "Invalid pixelformat (0x%x)\n",
....@@ -788,13 +831,25 @@
788831 return rvin_read(vin, VNMS_REG) & VNMS_CA;
789832 }
790833
834
+static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
835
+{
836
+ if (vin->format.field == V4L2_FIELD_ALTERNATE) {
837
+ /* If FS is set it is an Even field. */
838
+ if (vnms & VNMS_FS)
839
+ return V4L2_FIELD_BOTTOM;
840
+ return V4L2_FIELD_TOP;
841
+ }
842
+
843
+ return vin->format.field;
844
+}
845
+
791846 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
792847 {
793848 const struct rvin_video_format *fmt;
794849 int offsetx, offsety;
795850 dma_addr_t offset;
796851
797
- fmt = rvin_format_from_pixel(vin->format.pixelformat);
852
+ fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
798853
799854 /*
800855 * There is no HW support for composition do the beast we can
....@@ -825,33 +880,63 @@
825880 struct rvin_buffer *buf;
826881 struct vb2_v4l2_buffer *vbuf;
827882 dma_addr_t phys_addr;
883
+ int prev;
828884
829885 /* A already populated slot shall never be overwritten. */
830
- if (WARN_ON(vin->queue_buf[slot] != NULL))
886
+ if (WARN_ON(vin->buf_hw[slot].buffer))
831887 return;
832888
833
- vin_dbg(vin, "Filling HW slot: %d\n", slot);
889
+ prev = (slot == 0 ? HW_BUFFER_NUM : slot) - 1;
834890
835
- if (list_empty(&vin->buf_list)) {
836
- vin->queue_buf[slot] = NULL;
891
+ if (vin->buf_hw[prev].type == HALF_TOP) {
892
+ vbuf = vin->buf_hw[prev].buffer;
893
+ vin->buf_hw[slot].buffer = vbuf;
894
+ vin->buf_hw[slot].type = HALF_BOTTOM;
895
+ switch (vin->format.pixelformat) {
896
+ case V4L2_PIX_FMT_NV12:
897
+ case V4L2_PIX_FMT_NV16:
898
+ phys_addr = vin->buf_hw[prev].phys +
899
+ vin->format.sizeimage / 4;
900
+ break;
901
+ default:
902
+ phys_addr = vin->buf_hw[prev].phys +
903
+ vin->format.sizeimage / 2;
904
+ break;
905
+ }
906
+ } else if (list_empty(&vin->buf_list)) {
907
+ vin->buf_hw[slot].buffer = NULL;
908
+ vin->buf_hw[slot].type = FULL;
837909 phys_addr = vin->scratch_phys;
838910 } else {
839911 /* Keep track of buffer we give to HW */
840912 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
841913 vbuf = &buf->vb;
842914 list_del_init(to_buf_list(vbuf));
843
- vin->queue_buf[slot] = vbuf;
915
+ vin->buf_hw[slot].buffer = vbuf;
916
+
917
+ vin->buf_hw[slot].type =
918
+ V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ?
919
+ HALF_TOP : FULL;
844920
845921 /* Setup DMA */
846922 phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
847923 }
848924
925
+ vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n",
926
+ slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer);
927
+
928
+ vin->buf_hw[slot].phys = phys_addr;
849929 rvin_set_slot_addr(vin, slot, phys_addr);
850930 }
851931
852932 static int rvin_capture_start(struct rvin_dev *vin)
853933 {
854934 int slot, ret;
935
+
936
+ for (slot = 0; slot < HW_BUFFER_NUM; slot++) {
937
+ vin->buf_hw[slot].buffer = NULL;
938
+ vin->buf_hw[slot].type = FULL;
939
+ }
855940
856941 for (slot = 0; slot < HW_BUFFER_NUM; slot++)
857942 rvin_fill_hw_slot(vin, slot);
....@@ -936,13 +1021,24 @@
9361021 }
9371022
9381023 /* 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,
1024
+ if (vin->buf_hw[slot].buffer) {
1025
+ /*
1026
+ * Nothing to do but refill the hardware slot if
1027
+ * capture only filled first half of vb2 buffer.
1028
+ */
1029
+ if (vin->buf_hw[slot].type == HALF_TOP) {
1030
+ vin->buf_hw[slot].buffer = NULL;
1031
+ rvin_fill_hw_slot(vin, slot);
1032
+ goto done;
1033
+ }
1034
+
1035
+ vin->buf_hw[slot].buffer->field =
1036
+ rvin_get_active_field(vin, vnms);
1037
+ vin->buf_hw[slot].buffer->sequence = vin->sequence;
1038
+ vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns();
1039
+ vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf,
9441040 VB2_BUF_STATE_DONE);
945
- vin->queue_buf[slot] = NULL;
1041
+ vin->buf_hw[slot].buffer = NULL;
9461042 } else {
9471043 /* Scratch buffer was used, dropping frame. */
9481044 vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
....@@ -963,14 +1059,22 @@
9631059 enum vb2_buffer_state state)
9641060 {
9651061 struct rvin_buffer *buf, *node;
966
- int i;
1062
+ struct vb2_v4l2_buffer *freed[HW_BUFFER_NUM];
1063
+ unsigned int i, n;
9671064
9681065 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;
1066
+ freed[i] = vin->buf_hw[i].buffer;
1067
+ vin->buf_hw[i].buffer = NULL;
1068
+
1069
+ for (n = 0; n < i; n++) {
1070
+ if (freed[i] == freed[n]) {
1071
+ freed[i] = NULL;
1072
+ break;
1073
+ }
9731074 }
1075
+
1076
+ if (freed[i])
1077
+ vb2_buffer_done(&freed[i]->vb2_buf, state);
9741078 }
9751079
9761080 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
....@@ -1042,11 +1146,27 @@
10421146 case MEDIA_BUS_FMT_UYVY8_2X8:
10431147 case MEDIA_BUS_FMT_UYVY10_2X10:
10441148 case MEDIA_BUS_FMT_RGB888_1X24:
1045
- vin->mbus_code = fmt.format.code;
1149
+ break;
1150
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
1151
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8)
1152
+ return -EPIPE;
1153
+ break;
1154
+ case MEDIA_BUS_FMT_SGBRG8_1X8:
1155
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8)
1156
+ return -EPIPE;
1157
+ break;
1158
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
1159
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8)
1160
+ return -EPIPE;
1161
+ break;
1162
+ case MEDIA_BUS_FMT_SRGGB8_1X8:
1163
+ if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8)
1164
+ return -EPIPE;
10461165 break;
10471166 default:
10481167 return -EPIPE;
10491168 }
1169
+ vin->mbus_code = fmt.format.code;
10501170
10511171 switch (fmt.format.field) {
10521172 case V4L2_FIELD_TOP:
....@@ -1064,6 +1184,7 @@
10641184 case V4L2_FIELD_TOP:
10651185 case V4L2_FIELD_BOTTOM:
10661186 case V4L2_FIELD_NONE:
1187
+ case V4L2_FIELD_ALTERNATE:
10671188 break;
10681189 case V4L2_FIELD_INTERLACED_TB:
10691190 case V4L2_FIELD_INTERLACED_BT:
....@@ -1273,7 +1394,7 @@
12731394 vin->state = STOPPED;
12741395
12751396 for (i = 0; i < HW_BUFFER_NUM; i++)
1276
- vin->queue_buf[i] = NULL;
1397
+ vin->buf_hw[i].buffer = NULL;
12771398
12781399 /* buffer queue */
12791400 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
....@@ -1343,5 +1464,36 @@
13431464
13441465 pm_runtime_put(vin->dev);
13451466
1346
- return ret;
1467
+ return 0;
1468
+}
1469
+
1470
+void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
1471
+{
1472
+ unsigned long flags;
1473
+ u32 dmr;
1474
+
1475
+ spin_lock_irqsave(&vin->qlock, flags);
1476
+
1477
+ vin->alpha = alpha;
1478
+
1479
+ if (vin->state == STOPPED)
1480
+ goto out;
1481
+
1482
+ switch (vin->format.pixelformat) {
1483
+ case V4L2_PIX_FMT_ARGB555:
1484
+ dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
1485
+ if (vin->alpha)
1486
+ dmr |= VNDMR_ABIT;
1487
+ break;
1488
+ case V4L2_PIX_FMT_ABGR32:
1489
+ dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
1490
+ dmr |= VNDMR_A8BIT(vin->alpha);
1491
+ break;
1492
+ default:
1493
+ goto out;
1494
+ }
1495
+
1496
+ rvin_write(vin, dmr, VNDMR_REG);
1497
+out:
1498
+ spin_unlock_irqrestore(&vin->qlock, flags);
13471499 }