diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2016-06-11 03:11:27 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-06-28 11:25:31 -0400 |
commit | 20fab5e086aa141df5a94fd61706b18dfaadd090 (patch) | |
tree | 38e7a6fc59a8e0816dc8c928387f2fd2c16d5032 | |
parent | f4e37fb73f3037a4a4da976c7d5b28c221fe8a1a (diff) |
[media] v4l: vsp1: clu: Support runtime modification of controls
Allow reconfiguration of the look-up table and processing mode at
runtime.
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 | 41 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_clu.h | 4 |
2 files changed, 30 insertions, 15 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c index dd0cf20bcdda..b63d2dbe5ea3 100644 --- a/drivers/media/platform/vsp1/vsp1_clu.c +++ b/drivers/media/platform/vsp1/vsp1_clu.c | |||
@@ -55,7 +55,9 @@ static int clu_set_table(struct vsp1_clu *clu, struct v4l2_ctrl *ctrl) | |||
55 | for (i = 0; i < 17 * 17 * 17; ++i) | 55 | for (i = 0; i < 17 * 17 * 17; ++i) |
56 | vsp1_dl_fragment_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]); | 56 | vsp1_dl_fragment_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]); |
57 | 57 | ||
58 | spin_lock_irq(&clu->lock); | ||
58 | swap(clu->clu, dlb); | 59 | swap(clu->clu, dlb); |
60 | spin_unlock_irq(&clu->lock); | ||
59 | 61 | ||
60 | vsp1_dl_fragment_free(dlb); | 62 | vsp1_dl_fragment_free(dlb); |
61 | return 0; | 63 | return 0; |
@@ -208,32 +210,39 @@ static void clu_configure(struct vsp1_entity *entity, | |||
208 | struct vsp1_dl_list *dl, bool full) | 210 | struct vsp1_dl_list *dl, bool full) |
209 | { | 211 | { |
210 | struct vsp1_clu *clu = to_clu(&entity->subdev); | 212 | struct vsp1_clu *clu = to_clu(&entity->subdev); |
211 | struct v4l2_mbus_framefmt *format; | 213 | struct vsp1_dl_body *dlb; |
214 | unsigned long flags; | ||
212 | u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN; | 215 | u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN; |
213 | 216 | ||
214 | if (!full) | 217 | /* The format can't be changed during streaming, only verify it at |
218 | * stream start and store the information internally for future partial | ||
219 | * reconfiguration calls. | ||
220 | */ | ||
221 | if (full) { | ||
222 | struct v4l2_mbus_framefmt *format; | ||
223 | |||
224 | format = vsp1_entity_get_pad_format(&clu->entity, | ||
225 | clu->entity.config, | ||
226 | CLU_PAD_SINK); | ||
227 | clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32; | ||
215 | return; | 228 | return; |
216 | 229 | } | |
217 | format = vsp1_entity_get_pad_format(&clu->entity, clu->entity.config, | ||
218 | CLU_PAD_SINK); | ||
219 | |||
220 | mutex_lock(clu->ctrls.lock); | ||
221 | 230 | ||
222 | /* 2D mode can only be used with the YCbCr pixel encoding. */ | 231 | /* 2D mode can only be used with the YCbCr pixel encoding. */ |
223 | if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && | 232 | if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode) |
224 | format->code == MEDIA_BUS_FMT_AYUV8_1X32) | ||
225 | ctrl |= VI6_CLU_CTRL_AX1I_2D | VI6_CLU_CTRL_AX2I_2D | 233 | ctrl |= VI6_CLU_CTRL_AX1I_2D | VI6_CLU_CTRL_AX2I_2D |
226 | | VI6_CLU_CTRL_OS0_2D | VI6_CLU_CTRL_OS1_2D | 234 | | VI6_CLU_CTRL_OS0_2D | VI6_CLU_CTRL_OS1_2D |
227 | | VI6_CLU_CTRL_OS2_2D | VI6_CLU_CTRL_M2D; | 235 | | VI6_CLU_CTRL_OS2_2D | VI6_CLU_CTRL_M2D; |
228 | 236 | ||
229 | if (clu->clu) { | 237 | vsp1_clu_write(clu, dl, VI6_CLU_CTRL, ctrl); |
230 | vsp1_dl_list_add_fragment(dl, clu->clu); | ||
231 | clu->clu = NULL; | ||
232 | } | ||
233 | 238 | ||
234 | mutex_unlock(clu->ctrls.lock); | 239 | spin_lock_irqsave(&clu->lock, flags); |
240 | dlb = clu->clu; | ||
241 | clu->clu = NULL; | ||
242 | spin_unlock_irqrestore(&clu->lock, flags); | ||
235 | 243 | ||
236 | vsp1_clu_write(clu, dl, VI6_CLU_CTRL, ctrl); | 244 | if (dlb) |
245 | vsp1_dl_list_add_fragment(dl, dlb); | ||
237 | } | 246 | } |
238 | 247 | ||
239 | static const struct vsp1_entity_operations clu_entity_ops = { | 248 | static const struct vsp1_entity_operations clu_entity_ops = { |
@@ -253,6 +262,8 @@ struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1) | |||
253 | if (clu == NULL) | 262 | if (clu == NULL) |
254 | return ERR_PTR(-ENOMEM); | 263 | return ERR_PTR(-ENOMEM); |
255 | 264 | ||
265 | spin_lock_init(&clu->lock); | ||
266 | |||
256 | clu->entity.ops = &clu_entity_ops; | 267 | clu->entity.ops = &clu_entity_ops; |
257 | clu->entity.type = VSP1_ENTITY_CLU; | 268 | clu->entity.type = VSP1_ENTITY_CLU; |
258 | 269 | ||
diff --git a/drivers/media/platform/vsp1/vsp1_clu.h b/drivers/media/platform/vsp1/vsp1_clu.h index 33a69029c719..036e0a2f1a42 100644 --- a/drivers/media/platform/vsp1/vsp1_clu.h +++ b/drivers/media/platform/vsp1/vsp1_clu.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #ifndef __VSP1_CLU_H__ | 13 | #ifndef __VSP1_CLU_H__ |
14 | #define __VSP1_CLU_H__ | 14 | #define __VSP1_CLU_H__ |
15 | 15 | ||
16 | #include <linux/spinlock.h> | ||
17 | |||
16 | #include <media/media-entity.h> | 18 | #include <media/media-entity.h> |
17 | #include <media/v4l2-ctrls.h> | 19 | #include <media/v4l2-ctrls.h> |
18 | #include <media/v4l2-subdev.h> | 20 | #include <media/v4l2-subdev.h> |
@@ -30,6 +32,8 @@ struct vsp1_clu { | |||
30 | 32 | ||
31 | struct v4l2_ctrl_handler ctrls; | 33 | struct v4l2_ctrl_handler ctrls; |
32 | 34 | ||
35 | bool yuv_mode; | ||
36 | spinlock_t lock; | ||
33 | unsigned int mode; | 37 | unsigned int mode; |
34 | struct vsp1_dl_body *clu; | 38 | struct vsp1_dl_body *clu; |
35 | }; | 39 | }; |