hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/platform/vsp1/vsp1_drm.c
....@@ -34,14 +34,16 @@
3434 unsigned int completion)
3535 {
3636 struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
37
- bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
3837
3938 if (drm_pipe->du_complete) {
4039 struct vsp1_entity *uif = drm_pipe->uif;
40
+ unsigned int status = completion
41
+ & (VSP1_DU_STATUS_COMPLETE |
42
+ VSP1_DU_STATUS_WRITEBACK);
4143 u32 crc;
4244
4345 crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
44
- drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
46
+ drm_pipe->du_complete(drm_pipe->du_private, status, crc);
4547 }
4648
4749 if (completion & VSP1_DL_FRAME_END_INTERNAL) {
....@@ -333,19 +335,19 @@
333335 * on the BRx sink pad 0 and propagated inside the entity, not on the
334336 * source pad.
335337 */
336
- format.pad = pipe->brx->source_pad;
338
+ format.pad = brx->source_pad;
337339 format.format.width = drm_pipe->width;
338340 format.format.height = drm_pipe->height;
339341 format.format.field = V4L2_FIELD_NONE;
340342
341
- ret = v4l2_subdev_call(&pipe->brx->subdev, pad, set_fmt, NULL,
343
+ ret = v4l2_subdev_call(&brx->subdev, pad, set_fmt, NULL,
342344 &format);
343345 if (ret < 0)
344346 return ret;
345347
346348 dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
347349 __func__, format.format.width, format.format.height,
348
- format.format.code, BRX_NAME(pipe->brx), pipe->brx->source_pad);
350
+ format.format.code, BRX_NAME(brx), brx->source_pad);
349351
350352 if (format.format.width != drm_pipe->width ||
351353 format.format.height != drm_pipe->height) {
....@@ -537,6 +539,12 @@
537539 struct vsp1_entity *next;
538540 struct vsp1_dl_list *dl;
539541 struct vsp1_dl_body *dlb;
542
+ unsigned int dl_flags = 0;
543
+
544
+ if (drm_pipe->force_brx_release)
545
+ dl_flags |= VSP1_DL_FRAME_END_INTERNAL;
546
+ if (pipe->output->writeback)
547
+ dl_flags |= VSP1_DL_FRAME_END_WRITEBACK;
540548
541549 dl = vsp1_dl_list_get(pipe->output->dlm);
542550 dlb = vsp1_dl_list_get_body0(dl);
....@@ -554,12 +562,42 @@
554562 }
555563
556564 vsp1_entity_route_setup(entity, pipe, dlb);
557
- vsp1_entity_configure_stream(entity, pipe, dlb);
565
+ vsp1_entity_configure_stream(entity, pipe, dl, dlb);
558566 vsp1_entity_configure_frame(entity, pipe, dl, dlb);
559567 vsp1_entity_configure_partition(entity, pipe, dl, dlb);
560568 }
561569
562
- vsp1_dl_list_commit(dl, drm_pipe->force_brx_release);
570
+ vsp1_dl_list_commit(dl, dl_flags);
571
+}
572
+
573
+static int vsp1_du_pipeline_set_rwpf_format(struct vsp1_device *vsp1,
574
+ struct vsp1_rwpf *rwpf,
575
+ u32 pixelformat, unsigned int pitch)
576
+{
577
+ const struct vsp1_format_info *fmtinfo;
578
+ unsigned int chroma_hsub;
579
+
580
+ fmtinfo = vsp1_get_format_info(vsp1, pixelformat);
581
+ if (!fmtinfo) {
582
+ dev_dbg(vsp1->dev, "Unsupported pixel format %08x\n",
583
+ pixelformat);
584
+ return -EINVAL;
585
+ }
586
+
587
+ /*
588
+ * Only formats with three planes can affect the chroma planes pitch.
589
+ * All formats with two planes have a horizontal subsampling value of 2,
590
+ * but combine U and V in a single chroma plane, which thus results in
591
+ * the luma plane and chroma plane having the same pitch.
592
+ */
593
+ chroma_hsub = (fmtinfo->planes == 3) ? fmtinfo->hsub : 1;
594
+
595
+ rwpf->fmtinfo = fmtinfo;
596
+ rwpf->format.num_planes = fmtinfo->planes;
597
+ rwpf->format.plane_fmt[0].bytesperline = pitch;
598
+ rwpf->format.plane_fmt[1].bytesperline = pitch / chroma_hsub;
599
+
600
+ return 0;
563601 }
564602
565603 /* -----------------------------------------------------------------------------
....@@ -700,8 +738,8 @@
700738 drm_pipe->du_private = cfg->callback_data;
701739
702740 /* Disable the display interrupts. */
703
- vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
704
- vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
741
+ vsp1_write(vsp1, VI6_DISP_IRQ_STA(pipe_index), 0);
742
+ vsp1_write(vsp1, VI6_DISP_IRQ_ENB(pipe_index), 0);
705743
706744 /* Configure all entities in the pipeline. */
707745 vsp1_du_pipeline_configure(pipe);
....@@ -769,9 +807,8 @@
769807 {
770808 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
771809 struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
772
- const struct vsp1_format_info *fmtinfo;
773
- unsigned int chroma_hsub;
774810 struct vsp1_rwpf *rpf;
811
+ int ret;
775812
776813 if (rpf_index >= vsp1->info->rpf_count)
777814 return -EINVAL;
....@@ -804,25 +841,11 @@
804841 * Store the format, stride, memory buffer address, crop and compose
805842 * rectangles and Z-order position and for the input.
806843 */
807
- fmtinfo = vsp1_get_format_info(vsp1, cfg->pixelformat);
808
- if (!fmtinfo) {
809
- dev_dbg(vsp1->dev, "Unsupported pixel format %08x for RPF\n",
810
- cfg->pixelformat);
811
- return -EINVAL;
812
- }
844
+ ret = vsp1_du_pipeline_set_rwpf_format(vsp1, rpf, cfg->pixelformat,
845
+ cfg->pitch);
846
+ if (ret < 0)
847
+ return ret;
813848
814
- /*
815
- * Only formats with three planes can affect the chroma planes pitch.
816
- * All formats with two planes have a horizontal subsampling value of 2,
817
- * but combine U and V in a single chroma plane, which thus results in
818
- * the luma plane and chroma plane having the same pitch.
819
- */
820
- chroma_hsub = (fmtinfo->planes == 3) ? fmtinfo->hsub : 1;
821
-
822
- rpf->fmtinfo = fmtinfo;
823
- rpf->format.num_planes = fmtinfo->planes;
824
- rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
825
- rpf->format.plane_fmt[1].bytesperline = cfg->pitch / chroma_hsub;
826849 rpf->alpha = cfg->alpha;
827850
828851 rpf->mem.addr[0] = cfg->mem[0];
....@@ -851,12 +874,31 @@
851874 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
852875 struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
853876 struct vsp1_pipeline *pipe = &drm_pipe->pipe;
877
+ int ret;
854878
855879 drm_pipe->crc = cfg->crc;
856880
857881 mutex_lock(&vsp1->drm->lock);
882
+
883
+ if (cfg->writeback.pixelformat) {
884
+ const struct vsp1_du_writeback_config *wb_cfg = &cfg->writeback;
885
+
886
+ ret = vsp1_du_pipeline_set_rwpf_format(vsp1, pipe->output,
887
+ wb_cfg->pixelformat,
888
+ wb_cfg->pitch);
889
+ if (WARN_ON(ret < 0))
890
+ goto done;
891
+
892
+ pipe->output->mem.addr[0] = wb_cfg->mem[0];
893
+ pipe->output->mem.addr[1] = wb_cfg->mem[1];
894
+ pipe->output->mem.addr[2] = wb_cfg->mem[2];
895
+ pipe->output->writeback = true;
896
+ }
897
+
858898 vsp1_du_pipeline_setup_inputs(vsp1, pipe);
859899 vsp1_du_pipeline_configure(pipe);
900
+
901
+done:
860902 mutex_unlock(&vsp1->drm->lock);
861903 }
862904 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
....@@ -870,8 +912,8 @@
870912 * skip cache sync. This will need to be revisited when support for
871913 * non-coherent buffers will be added to the DU driver.
872914 */
873
- return dma_map_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
874
- DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
915
+ return dma_map_sgtable(vsp1->bus_master, sgt, DMA_TO_DEVICE,
916
+ DMA_ATTR_SKIP_CPU_SYNC);
875917 }
876918 EXPORT_SYMBOL_GPL(vsp1_du_map_sg);
877919
....@@ -879,8 +921,8 @@
879921 {
880922 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
881923
882
- dma_unmap_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
883
- DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
924
+ dma_unmap_sgtable(vsp1->bus_master, sgt, DMA_TO_DEVICE,
925
+ DMA_ATTR_SKIP_CPU_SYNC);
884926 }
885927 EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
886928