[media] v4l: vsp1: Replace .set_memory() with VSP1_ENTITY_PARAMS_PARTITION
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Mon, 12 Sep 2016 12:50:13 +0000 (09:50 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Mon, 19 Sep 2016 17:58:59 +0000 (14:58 -0300)
The new VSP1_ENTITY_PARAMS_PARTITION configuration parameters type
covers all registers that need to be configured for every partition.
This prepares for support of image partitioning, and replaces the
.set_memory() operation as the memory registers take different values
for every partition.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/vsp1/vsp1_clu.c
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/platform/vsp1/vsp1_entity.h
drivers/media/platform/vsp1/vsp1_lut.c
drivers/media/platform/vsp1/vsp1_rpf.c
drivers/media/platform/vsp1/vsp1_rwpf.h
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/vsp1/vsp1_wpf.c

index a0a69dfc38fcaa2360b046aecaa43031a037b831..f052abd05166c0999b0752af5299e0eeaa438aac 100644 (file)
@@ -237,6 +237,9 @@ static void clu_configure(struct vsp1_entity *entity,
                break;
        }
 
+       case VSP1_ENTITY_PARAMS_PARTITION:
+               break;
+
        case VSP1_ENTITY_PARAMS_RUNTIME:
                /* 2D mode can only be used with the YCbCr pixel encoding. */
                if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode)
index 6cbd3aeedbe38c02789464a59d73d849f7b68c88..832286975e7132ef5ca6f20e312bcafee7bb801e 100644 (file)
@@ -496,14 +496,9 @@ void vsp1_du_atomic_flush(struct device *dev)
                                               VSP1_ENTITY_PARAMS_INIT);
                        entity->ops->configure(entity, pipe, pipe->dl,
                                               VSP1_ENTITY_PARAMS_RUNTIME);
+                       entity->ops->configure(entity, pipe, pipe->dl,
+                                              VSP1_ENTITY_PARAMS_PARTITION);
                }
-
-               /* The memory buffer address must be applied after configuring
-                * the RPF to make sure the crop offset are computed.
-                */
-               if (entity->type == VSP1_ENTITY_RPF)
-                       vsp1_rwpf_set_memory(to_rwpf(&entity->subdev),
-                                            pipe->dl);
        }
 
        vsp1_dl_list_commit(pipe->dl);
index 51835e73308d0a03a6dab501470e5f71e2b2e825..0e3e394c44cd5af50ed0d0d481d10705ab971db9 100644 (file)
@@ -38,10 +38,12 @@ enum vsp1_entity_type {
 /*
  * enum vsp1_entity_params - Entity configuration parameters class
  * @VSP1_ENTITY_PARAMS_INIT - Initial parameters
+ * @VSP1_ENTITY_PARAMS_PARTITION - Per-image partition parameters
  * @VSP1_ENTITY_PARAMS_RUNTIME - Runtime-configurable parameters
  */
 enum vsp1_entity_params {
        VSP1_ENTITY_PARAMS_INIT,
+       VSP1_ENTITY_PARAMS_PARTITION,
        VSP1_ENTITY_PARAMS_RUNTIME,
 };
 
@@ -73,15 +75,11 @@ struct vsp1_route {
 /**
  * struct vsp1_entity_operations - Entity operations
  * @destroy:   Destroy the entity.
- * @set_memory:        Setup memory buffer access. This operation applies the settings
- *             stored in the rwpf mem field to the display list. Valid for RPF
- *             and WPF only.
  * @configure: Setup the hardware based on the entity state (pipeline, formats,
  *             selection rectangles, ...)
  */
 struct vsp1_entity_operations {
        void (*destroy)(struct vsp1_entity *);
-       void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl);
        void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *,
                          struct vsp1_dl_list *, enum vsp1_entity_params);
 };
index ace8acce20765bfb535dcf654aae1ef2401ece53..c67cc60db0dba118c4cde72e414f7ecf793096af 100644 (file)
@@ -202,6 +202,9 @@ static void lut_configure(struct vsp1_entity *entity,
                vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN);
                break;
 
+       case VSP1_ENTITY_PARAMS_PARTITION:
+               break;
+
        case VSP1_ENTITY_PARAMS_RUNTIME:
                spin_lock_irqsave(&lut->lock, flags);
                dlb = lut->lut;
index 795bf0fd1761d16c7cd9567fa2ac103ef7192902..de5ef76c50041f1ec780bf8651906830a770b6b7 100644 (file)
@@ -46,18 +46,6 @@ static const struct v4l2_subdev_ops rpf_ops = {
  * VSP1 Entity Operations
  */
 
-static void rpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
-{
-       struct vsp1_rwpf *rpf = entity_to_rwpf(entity);
-
-       vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_Y,
-                      rpf->mem.addr[0] + rpf->offsets[0]);
-       vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C0,
-                      rpf->mem.addr[1] + rpf->offsets[1]);
-       vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C1,
-                      rpf->mem.addr[2] + rpf->offsets[1]);
-}
-
 static void rpf_configure(struct vsp1_entity *entity,
                          struct vsp1_pipeline *pipe,
                          struct vsp1_dl_list *dl,
@@ -68,7 +56,6 @@ static void rpf_configure(struct vsp1_entity *entity,
        const struct v4l2_pix_format_mplane *format = &rpf->format;
        const struct v4l2_mbus_framefmt *source_format;
        const struct v4l2_mbus_framefmt *sink_format;
-       const struct v4l2_rect *crop;
        unsigned int left = 0;
        unsigned int top = 0;
        u32 pstride;
@@ -84,35 +71,51 @@ static void rpf_configure(struct vsp1_entity *entity,
                return;
        }
 
-       /* Source size, stride and crop offsets.
-        *
-        * The crop offsets correspond to the location of the crop rectangle top
-        * left corner in the plane buffer. Only two offsets are needed, as
-        * planes 2 and 3 always have identical strides.
-        */
-       crop = vsp1_rwpf_get_crop(rpf, rpf->entity.config);
-
-       vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_BSIZE,
-                      (crop->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) |
-                      (crop->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT));
-       vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_ESIZE,
-                      (crop->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) |
-                      (crop->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT));
+       if (params == VSP1_ENTITY_PARAMS_PARTITION) {
+               const struct v4l2_rect *crop;
+               unsigned int offsets[2];
+
+               /* Source size and crop offsets.
+                *
+                * The crop offsets correspond to the location of the crop
+                * rectangle top left corner in the plane buffer. Only two
+                * offsets are needed, as planes 2 and 3 always have identical
+                * strides.
+                */
+               crop = vsp1_rwpf_get_crop(rpf, rpf->entity.config);
+
+               vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_BSIZE,
+                              (crop->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) |
+                              (crop->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT));
+               vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_ESIZE,
+                              (crop->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) |
+                              (crop->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT));
+
+               offsets[0] = crop->top * format->plane_fmt[0].bytesperline
+                          + crop->left * fmtinfo->bpp[0] / 8;
+
+               if (format->num_planes > 1)
+                       offsets[1] = crop->top * format->plane_fmt[1].bytesperline
+                                  + crop->left / fmtinfo->hsub
+                                  * fmtinfo->bpp[1] / 8;
+               else
+                       offsets[1] = 0;
+
+               vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_Y,
+                              rpf->mem.addr[0] + offsets[0]);
+               vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C0,
+                              rpf->mem.addr[1] + offsets[1]);
+               vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C1,
+                              rpf->mem.addr[2] + offsets[1]);
+               return;
+       }
 
-       rpf->offsets[0] = crop->top * format->plane_fmt[0].bytesperline
-                       + crop->left * fmtinfo->bpp[0] / 8;
+       /* Stride */
        pstride = format->plane_fmt[0].bytesperline
                << VI6_RPF_SRCM_PSTRIDE_Y_SHIFT;
-
-       if (format->num_planes > 1) {
-               rpf->offsets[1] = crop->top * format->plane_fmt[1].bytesperline
-                               + crop->left / fmtinfo->hsub * fmtinfo->bpp[1]
-                               / 8;
+       if (format->num_planes > 1)
                pstride |= format->plane_fmt[1].bytesperline
                        << VI6_RPF_SRCM_PSTRIDE_C_SHIFT;
-       } else {
-               rpf->offsets[1] = 0;
-       }
 
        vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_PSTRIDE, pstride);
 
@@ -217,7 +220,6 @@ static void rpf_configure(struct vsp1_entity *entity,
 }
 
 static const struct vsp1_entity_operations rpf_entity_ops = {
-       .set_memory = rpf_set_memory,
        .configure = rpf_configure,
 };
 
index cb20484e80da8f0f08733355309cb8c05dbb089e..1c98aff3da5dbf569187790edf0a863aa2478c07 100644 (file)
@@ -61,7 +61,6 @@ struct vsp1_rwpf {
                unsigned int active;
        } flip;
 
-       unsigned int offsets[2];
        struct vsp1_rwpf_memory mem;
 
        struct vsp1_dl_manager *dlm;
@@ -86,17 +85,5 @@ extern const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops;
 
 struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf,
                                     struct v4l2_subdev_pad_config *config);
-/**
- * vsp1_rwpf_set_memory - Configure DMA addresses for a [RW]PF
- * @rwpf: the [RW]PF instance
- * @dl: the display list
- *
- * This function applies the cached memory buffer address to the display list.
- */
-static inline void vsp1_rwpf_set_memory(struct vsp1_rwpf *rwpf,
-                                       struct vsp1_dl_list *dl)
-{
-       rwpf->entity.ops->set_memory(&rwpf->entity, dl);
-}
 
 #endif /* __VSP1_RWPF_H__ */
index c66f0b48098917c41242716b12b8f84e2a990971..b8339d874df4fa077b6b5adbddbb7014b0774a5f 100644 (file)
@@ -245,29 +245,20 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 
 static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe)
 {
-       struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
        struct vsp1_entity *entity;
-       unsigned int i;
 
        if (!pipe->dl)
                pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
 
        list_for_each_entry(entity, &pipe->entities, list_pipe) {
-               if (entity->ops->configure)
+               if (entity->ops->configure) {
                        entity->ops->configure(entity, pipe, pipe->dl,
                                               VSP1_ENTITY_PARAMS_RUNTIME);
+                       entity->ops->configure(entity, pipe, pipe->dl,
+                                              VSP1_ENTITY_PARAMS_PARTITION);
+               }
        }
 
-       for (i = 0; i < vsp1->info->rpf_count; ++i) {
-               struct vsp1_rwpf *rwpf = pipe->inputs[i];
-
-               if (rwpf)
-                       vsp1_rwpf_set_memory(rwpf, pipe->dl);
-       }
-
-       if (!pipe->lif)
-               vsp1_rwpf_set_memory(pipe->output, pipe->dl);
-
        vsp1_dl_list_commit(pipe->dl);
        pipe->dl = NULL;
 
index adf348d08c64b902732d7874896fa3d8301eb17c..717c0be58bfbfa463553a6c98368811afbbf23b6 100644 (file)
@@ -173,37 +173,6 @@ static void vsp1_wpf_destroy(struct vsp1_entity *entity)
        vsp1_dlm_destroy(wpf->dlm);
 }
 
-static void wpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
-{
-       struct vsp1_rwpf *wpf = entity_to_rwpf(entity);
-       const struct v4l2_pix_format_mplane *format = &wpf->format;
-       struct vsp1_rwpf_memory mem = wpf->mem;
-       unsigned int flip = wpf->flip.active;
-       unsigned int offset;
-
-       /* Update the memory offsets based on flipping configuration. The
-        * destination addresses point to the locations where the VSP starts
-        * writing to memory, which can be different corners of the image
-        * depending on vertical flipping. Horizontal flipping is handled
-        * through a line buffer and doesn't modify the start address.
-        */
-       if (flip & BIT(WPF_CTRL_VFLIP)) {
-               mem.addr[0] += (format->height - 1)
-                            * format->plane_fmt[0].bytesperline;
-
-               if (format->num_planes > 1) {
-                       offset = (format->height / wpf->fmtinfo->vsub - 1)
-                              * format->plane_fmt[1].bytesperline;
-                       mem.addr[1] += offset;
-                       mem.addr[2] += offset;
-               }
-       }
-
-       vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]);
-       vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]);
-       vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]);
-}
-
 static void wpf_configure(struct vsp1_entity *entity,
                          struct vsp1_pipeline *pipe,
                          struct vsp1_dl_list *dl,
@@ -237,7 +206,6 @@ static void wpf_configure(struct vsp1_entity *entity,
                return;
        }
 
-       /* Format */
        sink_format = vsp1_entity_get_pad_format(&wpf->entity,
                                                 wpf->entity.config,
                                                 RWPF_PAD_SINK);
@@ -245,13 +213,53 @@ static void wpf_configure(struct vsp1_entity *entity,
                                                   wpf->entity.config,
                                                   RWPF_PAD_SOURCE);
 
-       vsp1_wpf_write(wpf, dl, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN |
-                      (0 << VI6_WPF_SZCLIP_OFST_SHIFT) |
-                      (source_format->width << VI6_WPF_SZCLIP_SIZE_SHIFT));
-       vsp1_wpf_write(wpf, dl, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN |
-                      (0 << VI6_WPF_SZCLIP_OFST_SHIFT) |
-                      (source_format->height << VI6_WPF_SZCLIP_SIZE_SHIFT));
+       if (params == VSP1_ENTITY_PARAMS_PARTITION) {
+               const struct v4l2_pix_format_mplane *format = &wpf->format;
+               struct vsp1_rwpf_memory mem = wpf->mem;
+               unsigned int flip = wpf->flip.active;
+               unsigned int width = source_format->width;
+               unsigned int height = source_format->height;
+               unsigned int offset;
+
+               /* Cropping. The partition algorithm can split the image into
+                * multiple slices.
+                */
+               vsp1_wpf_write(wpf, dl, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN |
+                              (0 << VI6_WPF_SZCLIP_OFST_SHIFT) |
+                              (width << VI6_WPF_SZCLIP_SIZE_SHIFT));
+               vsp1_wpf_write(wpf, dl, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN |
+                              (0 << VI6_WPF_SZCLIP_OFST_SHIFT) |
+                              (height << VI6_WPF_SZCLIP_SIZE_SHIFT));
+
+               if (pipe->lif)
+                       return;
+
+               /* Update the memory offsets based on flipping configuration.
+                * The destination addresses point to the locations where the
+                * VSP starts writing to memory, which can be different corners
+                * of the image depending on vertical flipping. Horizontal
+                * flipping is handled through a line buffer and doesn't modify
+                * the start address.
+                */
+               if (flip & BIT(WPF_CTRL_VFLIP)) {
+                       mem.addr[0] += (format->height - 1)
+                                    * format->plane_fmt[0].bytesperline;
+
+                       if (format->num_planes > 1) {
+                               offset = (format->height / wpf->fmtinfo->vsub - 1)
+                                      * format->plane_fmt[1].bytesperline;
+                               mem.addr[1] += offset;
+                               mem.addr[2] += offset;
+                       }
+               }
 
+               vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]);
+               vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]);
+               vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]);
+               return;
+       }
+
+       /* Format */
        if (!pipe->lif) {
                const struct v4l2_pix_format_mplane *format = &wpf->format;
                const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
@@ -320,7 +328,6 @@ static void wpf_configure(struct vsp1_entity *entity,
 
 static const struct vsp1_entity_operations wpf_entity_ops = {
        .destroy = vsp1_wpf_destroy,
-       .set_memory = wpf_set_memory,
        .configure = wpf_configure,
 };