diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2016-09-12 08:50:13 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-09-19 13:58:59 -0400 |
commit | 8ddf3784295f1b3341ccc206740afd4235dbcbe0 (patch) | |
tree | 8f2c39ca7f49fd022192662ac65b3e344f31bb5a | |
parent | d21fbbb4e9705189cabd724de0dec3f01fb362d1 (diff) |
[media] v4l: vsp1: Replace .set_memory() with VSP1_ENTITY_PARAMS_PARTITION
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>
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_clu.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_drm.c | 9 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_entity.h | 6 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_lut.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_rpf.c | 78 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_rwpf.h | 13 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_video.c | 17 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_wpf.c | 85 |
8 files changed, 100 insertions, 114 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c index a0a69dfc38fc..f052abd05166 100644 --- a/drivers/media/platform/vsp1/vsp1_clu.c +++ b/drivers/media/platform/vsp1/vsp1_clu.c | |||
@@ -237,6 +237,9 @@ static void clu_configure(struct vsp1_entity *entity, | |||
237 | break; | 237 | break; |
238 | } | 238 | } |
239 | 239 | ||
240 | case VSP1_ENTITY_PARAMS_PARTITION: | ||
241 | break; | ||
242 | |||
240 | case VSP1_ENTITY_PARAMS_RUNTIME: | 243 | case VSP1_ENTITY_PARAMS_RUNTIME: |
241 | /* 2D mode can only be used with the YCbCr pixel encoding. */ | 244 | /* 2D mode can only be used with the YCbCr pixel encoding. */ |
242 | if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode) | 245 | if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode) |
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 6cbd3aeedbe3..832286975e71 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c | |||
@@ -496,14 +496,9 @@ void vsp1_du_atomic_flush(struct device *dev) | |||
496 | VSP1_ENTITY_PARAMS_INIT); | 496 | VSP1_ENTITY_PARAMS_INIT); |
497 | entity->ops->configure(entity, pipe, pipe->dl, | 497 | entity->ops->configure(entity, pipe, pipe->dl, |
498 | VSP1_ENTITY_PARAMS_RUNTIME); | 498 | VSP1_ENTITY_PARAMS_RUNTIME); |
499 | entity->ops->configure(entity, pipe, pipe->dl, | ||
500 | VSP1_ENTITY_PARAMS_PARTITION); | ||
499 | } | 501 | } |
500 | |||
501 | /* The memory buffer address must be applied after configuring | ||
502 | * the RPF to make sure the crop offset are computed. | ||
503 | */ | ||
504 | if (entity->type == VSP1_ENTITY_RPF) | ||
505 | vsp1_rwpf_set_memory(to_rwpf(&entity->subdev), | ||
506 | pipe->dl); | ||
507 | } | 502 | } |
508 | 503 | ||
509 | vsp1_dl_list_commit(pipe->dl); | 504 | vsp1_dl_list_commit(pipe->dl); |
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index 51835e73308d..0e3e394c44cd 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h | |||
@@ -38,10 +38,12 @@ enum vsp1_entity_type { | |||
38 | /* | 38 | /* |
39 | * enum vsp1_entity_params - Entity configuration parameters class | 39 | * enum vsp1_entity_params - Entity configuration parameters class |
40 | * @VSP1_ENTITY_PARAMS_INIT - Initial parameters | 40 | * @VSP1_ENTITY_PARAMS_INIT - Initial parameters |
41 | * @VSP1_ENTITY_PARAMS_PARTITION - Per-image partition parameters | ||
41 | * @VSP1_ENTITY_PARAMS_RUNTIME - Runtime-configurable parameters | 42 | * @VSP1_ENTITY_PARAMS_RUNTIME - Runtime-configurable parameters |
42 | */ | 43 | */ |
43 | enum vsp1_entity_params { | 44 | enum vsp1_entity_params { |
44 | VSP1_ENTITY_PARAMS_INIT, | 45 | VSP1_ENTITY_PARAMS_INIT, |
46 | VSP1_ENTITY_PARAMS_PARTITION, | ||
45 | VSP1_ENTITY_PARAMS_RUNTIME, | 47 | VSP1_ENTITY_PARAMS_RUNTIME, |
46 | }; | 48 | }; |
47 | 49 | ||
@@ -73,15 +75,11 @@ struct vsp1_route { | |||
73 | /** | 75 | /** |
74 | * struct vsp1_entity_operations - Entity operations | 76 | * struct vsp1_entity_operations - Entity operations |
75 | * @destroy: Destroy the entity. | 77 | * @destroy: Destroy the entity. |
76 | * @set_memory: Setup memory buffer access. This operation applies the settings | ||
77 | * stored in the rwpf mem field to the display list. Valid for RPF | ||
78 | * and WPF only. | ||
79 | * @configure: Setup the hardware based on the entity state (pipeline, formats, | 78 | * @configure: Setup the hardware based on the entity state (pipeline, formats, |
80 | * selection rectangles, ...) | 79 | * selection rectangles, ...) |
81 | */ | 80 | */ |
82 | struct vsp1_entity_operations { | 81 | struct vsp1_entity_operations { |
83 | void (*destroy)(struct vsp1_entity *); | 82 | void (*destroy)(struct vsp1_entity *); |
84 | void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl); | ||
85 | void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, | 83 | void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, |
86 | struct vsp1_dl_list *, enum vsp1_entity_params); | 84 | struct vsp1_dl_list *, enum vsp1_entity_params); |
87 | }; | 85 | }; |
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c index ace8acce2076..c67cc60db0db 100644 --- a/drivers/media/platform/vsp1/vsp1_lut.c +++ b/drivers/media/platform/vsp1/vsp1_lut.c | |||
@@ -202,6 +202,9 @@ static void lut_configure(struct vsp1_entity *entity, | |||
202 | vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN); | 202 | vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN); |
203 | break; | 203 | break; |
204 | 204 | ||
205 | case VSP1_ENTITY_PARAMS_PARTITION: | ||
206 | break; | ||
207 | |||
205 | case VSP1_ENTITY_PARAMS_RUNTIME: | 208 | case VSP1_ENTITY_PARAMS_RUNTIME: |
206 | spin_lock_irqsave(&lut->lock, flags); | 209 | spin_lock_irqsave(&lut->lock, flags); |
207 | dlb = lut->lut; | 210 | dlb = lut->lut; |
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 795bf0fd1761..de5ef76c5004 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c | |||
@@ -46,18 +46,6 @@ static const struct v4l2_subdev_ops rpf_ops = { | |||
46 | * VSP1 Entity Operations | 46 | * VSP1 Entity Operations |
47 | */ | 47 | */ |
48 | 48 | ||
49 | static void rpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl) | ||
50 | { | ||
51 | struct vsp1_rwpf *rpf = entity_to_rwpf(entity); | ||
52 | |||
53 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_Y, | ||
54 | rpf->mem.addr[0] + rpf->offsets[0]); | ||
55 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C0, | ||
56 | rpf->mem.addr[1] + rpf->offsets[1]); | ||
57 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C1, | ||
58 | rpf->mem.addr[2] + rpf->offsets[1]); | ||
59 | } | ||
60 | |||
61 | static void rpf_configure(struct vsp1_entity *entity, | 49 | static void rpf_configure(struct vsp1_entity *entity, |
62 | struct vsp1_pipeline *pipe, | 50 | struct vsp1_pipeline *pipe, |
63 | struct vsp1_dl_list *dl, | 51 | struct vsp1_dl_list *dl, |
@@ -68,7 +56,6 @@ static void rpf_configure(struct vsp1_entity *entity, | |||
68 | const struct v4l2_pix_format_mplane *format = &rpf->format; | 56 | const struct v4l2_pix_format_mplane *format = &rpf->format; |
69 | const struct v4l2_mbus_framefmt *source_format; | 57 | const struct v4l2_mbus_framefmt *source_format; |
70 | const struct v4l2_mbus_framefmt *sink_format; | 58 | const struct v4l2_mbus_framefmt *sink_format; |
71 | const struct v4l2_rect *crop; | ||
72 | unsigned int left = 0; | 59 | unsigned int left = 0; |
73 | unsigned int top = 0; | 60 | unsigned int top = 0; |
74 | u32 pstride; | 61 | u32 pstride; |
@@ -84,35 +71,51 @@ static void rpf_configure(struct vsp1_entity *entity, | |||
84 | return; | 71 | return; |
85 | } | 72 | } |
86 | 73 | ||
87 | /* Source size, stride and crop offsets. | 74 | if (params == VSP1_ENTITY_PARAMS_PARTITION) { |
88 | * | 75 | const struct v4l2_rect *crop; |
89 | * The crop offsets correspond to the location of the crop rectangle top | 76 | unsigned int offsets[2]; |
90 | * left corner in the plane buffer. Only two offsets are needed, as | 77 | |
91 | * planes 2 and 3 always have identical strides. | 78 | /* Source size and crop offsets. |
92 | */ | 79 | * |
93 | crop = vsp1_rwpf_get_crop(rpf, rpf->entity.config); | 80 | * The crop offsets correspond to the location of the crop |
94 | 81 | * rectangle top left corner in the plane buffer. Only two | |
95 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_BSIZE, | 82 | * offsets are needed, as planes 2 and 3 always have identical |
96 | (crop->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) | | 83 | * strides. |
97 | (crop->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT)); | 84 | */ |
98 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_ESIZE, | 85 | crop = vsp1_rwpf_get_crop(rpf, rpf->entity.config); |
99 | (crop->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) | | 86 | |
100 | (crop->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT)); | 87 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_BSIZE, |
88 | (crop->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) | | ||
89 | (crop->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT)); | ||
90 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_ESIZE, | ||
91 | (crop->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) | | ||
92 | (crop->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT)); | ||
93 | |||
94 | offsets[0] = crop->top * format->plane_fmt[0].bytesperline | ||
95 | + crop->left * fmtinfo->bpp[0] / 8; | ||
96 | |||
97 | if (format->num_planes > 1) | ||
98 | offsets[1] = crop->top * format->plane_fmt[1].bytesperline | ||
99 | + crop->left / fmtinfo->hsub | ||
100 | * fmtinfo->bpp[1] / 8; | ||
101 | else | ||
102 | offsets[1] = 0; | ||
103 | |||
104 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_Y, | ||
105 | rpf->mem.addr[0] + offsets[0]); | ||
106 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C0, | ||
107 | rpf->mem.addr[1] + offsets[1]); | ||
108 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C1, | ||
109 | rpf->mem.addr[2] + offsets[1]); | ||
110 | return; | ||
111 | } | ||
101 | 112 | ||
102 | rpf->offsets[0] = crop->top * format->plane_fmt[0].bytesperline | 113 | /* Stride */ |
103 | + crop->left * fmtinfo->bpp[0] / 8; | ||
104 | pstride = format->plane_fmt[0].bytesperline | 114 | pstride = format->plane_fmt[0].bytesperline |
105 | << VI6_RPF_SRCM_PSTRIDE_Y_SHIFT; | 115 | << VI6_RPF_SRCM_PSTRIDE_Y_SHIFT; |
106 | 116 | if (format->num_planes > 1) | |
107 | if (format->num_planes > 1) { | ||
108 | rpf->offsets[1] = crop->top * format->plane_fmt[1].bytesperline | ||
109 | + crop->left / fmtinfo->hsub * fmtinfo->bpp[1] | ||
110 | / 8; | ||
111 | pstride |= format->plane_fmt[1].bytesperline | 117 | pstride |= format->plane_fmt[1].bytesperline |
112 | << VI6_RPF_SRCM_PSTRIDE_C_SHIFT; | 118 | << VI6_RPF_SRCM_PSTRIDE_C_SHIFT; |
113 | } else { | ||
114 | rpf->offsets[1] = 0; | ||
115 | } | ||
116 | 119 | ||
117 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_PSTRIDE, pstride); | 120 | vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_PSTRIDE, pstride); |
118 | 121 | ||
@@ -217,7 +220,6 @@ static void rpf_configure(struct vsp1_entity *entity, | |||
217 | } | 220 | } |
218 | 221 | ||
219 | static const struct vsp1_entity_operations rpf_entity_ops = { | 222 | static const struct vsp1_entity_operations rpf_entity_ops = { |
220 | .set_memory = rpf_set_memory, | ||
221 | .configure = rpf_configure, | 223 | .configure = rpf_configure, |
222 | }; | 224 | }; |
223 | 225 | ||
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index cb20484e80da..1c98aff3da5d 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h | |||
@@ -61,7 +61,6 @@ struct vsp1_rwpf { | |||
61 | unsigned int active; | 61 | unsigned int active; |
62 | } flip; | 62 | } flip; |
63 | 63 | ||
64 | unsigned int offsets[2]; | ||
65 | struct vsp1_rwpf_memory mem; | 64 | struct vsp1_rwpf_memory mem; |
66 | 65 | ||
67 | struct vsp1_dl_manager *dlm; | 66 | struct vsp1_dl_manager *dlm; |
@@ -86,17 +85,5 @@ extern const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops; | |||
86 | 85 | ||
87 | struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, | 86 | struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, |
88 | struct v4l2_subdev_pad_config *config); | 87 | struct v4l2_subdev_pad_config *config); |
89 | /** | ||
90 | * vsp1_rwpf_set_memory - Configure DMA addresses for a [RW]PF | ||
91 | * @rwpf: the [RW]PF instance | ||
92 | * @dl: the display list | ||
93 | * | ||
94 | * This function applies the cached memory buffer address to the display list. | ||
95 | */ | ||
96 | static inline void vsp1_rwpf_set_memory(struct vsp1_rwpf *rwpf, | ||
97 | struct vsp1_dl_list *dl) | ||
98 | { | ||
99 | rwpf->entity.ops->set_memory(&rwpf->entity, dl); | ||
100 | } | ||
101 | 88 | ||
102 | #endif /* __VSP1_RWPF_H__ */ | 89 | #endif /* __VSP1_RWPF_H__ */ |
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index c66f0b480989..b8339d874df4 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c | |||
@@ -245,29 +245,20 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe, | |||
245 | 245 | ||
246 | static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) | 246 | static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) |
247 | { | 247 | { |
248 | struct vsp1_device *vsp1 = pipe->output->entity.vsp1; | ||
249 | struct vsp1_entity *entity; | 248 | struct vsp1_entity *entity; |
250 | unsigned int i; | ||
251 | 249 | ||
252 | if (!pipe->dl) | 250 | if (!pipe->dl) |
253 | pipe->dl = vsp1_dl_list_get(pipe->output->dlm); | 251 | pipe->dl = vsp1_dl_list_get(pipe->output->dlm); |
254 | 252 | ||
255 | list_for_each_entry(entity, &pipe->entities, list_pipe) { | 253 | list_for_each_entry(entity, &pipe->entities, list_pipe) { |
256 | if (entity->ops->configure) | 254 | if (entity->ops->configure) { |
257 | entity->ops->configure(entity, pipe, pipe->dl, | 255 | entity->ops->configure(entity, pipe, pipe->dl, |
258 | VSP1_ENTITY_PARAMS_RUNTIME); | 256 | VSP1_ENTITY_PARAMS_RUNTIME); |
257 | entity->ops->configure(entity, pipe, pipe->dl, | ||
258 | VSP1_ENTITY_PARAMS_PARTITION); | ||
259 | } | ||
259 | } | 260 | } |
260 | 261 | ||
261 | for (i = 0; i < vsp1->info->rpf_count; ++i) { | ||
262 | struct vsp1_rwpf *rwpf = pipe->inputs[i]; | ||
263 | |||
264 | if (rwpf) | ||
265 | vsp1_rwpf_set_memory(rwpf, pipe->dl); | ||
266 | } | ||
267 | |||
268 | if (!pipe->lif) | ||
269 | vsp1_rwpf_set_memory(pipe->output, pipe->dl); | ||
270 | |||
271 | vsp1_dl_list_commit(pipe->dl); | 262 | vsp1_dl_list_commit(pipe->dl); |
272 | pipe->dl = NULL; | 263 | pipe->dl = NULL; |
273 | 264 | ||
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index adf348d08c64..717c0be58bfb 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c | |||
@@ -173,37 +173,6 @@ static void vsp1_wpf_destroy(struct vsp1_entity *entity) | |||
173 | vsp1_dlm_destroy(wpf->dlm); | 173 | vsp1_dlm_destroy(wpf->dlm); |
174 | } | 174 | } |
175 | 175 | ||
176 | static void wpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl) | ||
177 | { | ||
178 | struct vsp1_rwpf *wpf = entity_to_rwpf(entity); | ||
179 | const struct v4l2_pix_format_mplane *format = &wpf->format; | ||
180 | struct vsp1_rwpf_memory mem = wpf->mem; | ||
181 | unsigned int flip = wpf->flip.active; | ||
182 | unsigned int offset; | ||
183 | |||
184 | /* Update the memory offsets based on flipping configuration. The | ||
185 | * destination addresses point to the locations where the VSP starts | ||
186 | * writing to memory, which can be different corners of the image | ||
187 | * depending on vertical flipping. Horizontal flipping is handled | ||
188 | * through a line buffer and doesn't modify the start address. | ||
189 | */ | ||
190 | if (flip & BIT(WPF_CTRL_VFLIP)) { | ||
191 | mem.addr[0] += (format->height - 1) | ||
192 | * format->plane_fmt[0].bytesperline; | ||
193 | |||
194 | if (format->num_planes > 1) { | ||
195 | offset = (format->height / wpf->fmtinfo->vsub - 1) | ||
196 | * format->plane_fmt[1].bytesperline; | ||
197 | mem.addr[1] += offset; | ||
198 | mem.addr[2] += offset; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]); | ||
203 | vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]); | ||
204 | vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]); | ||
205 | } | ||
206 | |||
207 | static void wpf_configure(struct vsp1_entity *entity, | 176 | static void wpf_configure(struct vsp1_entity *entity, |
208 | struct vsp1_pipeline *pipe, | 177 | struct vsp1_pipeline *pipe, |
209 | struct vsp1_dl_list *dl, | 178 | struct vsp1_dl_list *dl, |
@@ -237,7 +206,6 @@ static void wpf_configure(struct vsp1_entity *entity, | |||
237 | return; | 206 | return; |
238 | } | 207 | } |
239 | 208 | ||
240 | /* Format */ | ||
241 | sink_format = vsp1_entity_get_pad_format(&wpf->entity, | 209 | sink_format = vsp1_entity_get_pad_format(&wpf->entity, |
242 | wpf->entity.config, | 210 | wpf->entity.config, |
243 | RWPF_PAD_SINK); | 211 | RWPF_PAD_SINK); |
@@ -245,13 +213,53 @@ static void wpf_configure(struct vsp1_entity *entity, | |||
245 | wpf->entity.config, | 213 | wpf->entity.config, |
246 | RWPF_PAD_SOURCE); | 214 | RWPF_PAD_SOURCE); |
247 | 215 | ||
248 | vsp1_wpf_write(wpf, dl, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN | | 216 | if (params == VSP1_ENTITY_PARAMS_PARTITION) { |
249 | (0 << VI6_WPF_SZCLIP_OFST_SHIFT) | | 217 | const struct v4l2_pix_format_mplane *format = &wpf->format; |
250 | (source_format->width << VI6_WPF_SZCLIP_SIZE_SHIFT)); | 218 | struct vsp1_rwpf_memory mem = wpf->mem; |
251 | vsp1_wpf_write(wpf, dl, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN | | 219 | unsigned int flip = wpf->flip.active; |
252 | (0 << VI6_WPF_SZCLIP_OFST_SHIFT) | | 220 | unsigned int width = source_format->width; |
253 | (source_format->height << VI6_WPF_SZCLIP_SIZE_SHIFT)); | 221 | unsigned int height = source_format->height; |
222 | unsigned int offset; | ||
223 | |||
224 | /* Cropping. The partition algorithm can split the image into | ||
225 | * multiple slices. | ||
226 | */ | ||
227 | vsp1_wpf_write(wpf, dl, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN | | ||
228 | (0 << VI6_WPF_SZCLIP_OFST_SHIFT) | | ||
229 | (width << VI6_WPF_SZCLIP_SIZE_SHIFT)); | ||
230 | vsp1_wpf_write(wpf, dl, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN | | ||
231 | (0 << VI6_WPF_SZCLIP_OFST_SHIFT) | | ||
232 | (height << VI6_WPF_SZCLIP_SIZE_SHIFT)); | ||
233 | |||
234 | if (pipe->lif) | ||
235 | return; | ||
236 | |||
237 | /* Update the memory offsets based on flipping configuration. | ||
238 | * The destination addresses point to the locations where the | ||
239 | * VSP starts writing to memory, which can be different corners | ||
240 | * of the image depending on vertical flipping. Horizontal | ||
241 | * flipping is handled through a line buffer and doesn't modify | ||
242 | * the start address. | ||
243 | */ | ||
244 | if (flip & BIT(WPF_CTRL_VFLIP)) { | ||
245 | mem.addr[0] += (format->height - 1) | ||
246 | * format->plane_fmt[0].bytesperline; | ||
247 | |||
248 | if (format->num_planes > 1) { | ||
249 | offset = (format->height / wpf->fmtinfo->vsub - 1) | ||
250 | * format->plane_fmt[1].bytesperline; | ||
251 | mem.addr[1] += offset; | ||
252 | mem.addr[2] += offset; | ||
253 | } | ||
254 | } | ||
254 | 255 | ||
256 | vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]); | ||
257 | vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]); | ||
258 | vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]); | ||
259 | return; | ||
260 | } | ||
261 | |||
262 | /* Format */ | ||
255 | if (!pipe->lif) { | 263 | if (!pipe->lif) { |
256 | const struct v4l2_pix_format_mplane *format = &wpf->format; | 264 | const struct v4l2_pix_format_mplane *format = &wpf->format; |
257 | const struct vsp1_format_info *fmtinfo = wpf->fmtinfo; | 265 | const struct vsp1_format_info *fmtinfo = wpf->fmtinfo; |
@@ -320,7 +328,6 @@ static void wpf_configure(struct vsp1_entity *entity, | |||
320 | 328 | ||
321 | static const struct vsp1_entity_operations wpf_entity_ops = { | 329 | static const struct vsp1_entity_operations wpf_entity_ops = { |
322 | .destroy = vsp1_wpf_destroy, | 330 | .destroy = vsp1_wpf_destroy, |
323 | .set_memory = wpf_set_memory, | ||
324 | .configure = wpf_configure, | 331 | .configure = wpf_configure, |
325 | }; | 332 | }; |
326 | 333 | ||