aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2016-06-11 03:07:56 -0400
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-06-28 11:23:43 -0400
commitfc845e520baf00af12f6c39708c5e9e9a6eec661 (patch)
tree1df2b8feedada74f30a307f951b451d3c8eb351b
parent1fd87bf2f3a76200fe2b57f5b744b1b341cd7690 (diff)
[media] v4l: vsp1: Support runtime modification of controls
Controls are applied to the hardware in the configure operation of the VSP entities, which is only called when starting the video stream. To enable runtime modification of controls we need to call the configure operations for every frame. Doing so is currently not safe, as most parameters shouldn't be modified during streaming. Furthermore the configure operation can sleep, preventing it from being called from the frame completion interrupt handler for the next frame. Fix this by adding an argument to the configure operation to tell entities whether to perform a full configuration (as done now) or a partial runtime configuration. In the latter case the operation will only configure the subset of parameters related to runtime-configurable controls, and won't be allowed to sleep when doing so. Because partial reconfiguration can depend on parameters computed when performing a full configuration, the core guarantees that the configure operation will always be called with full and partial modes in that order at stream start. Entities thus don't have to duplicate configuration steps in the full and partial code paths. This change affects the VSP driver core only, all entities return immediately from the configure operation when called for a partial runtime configuration. Entities will be modified one by one in further commits. 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_bru.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_clu.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.c6
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c8
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c5
12 files changed, 48 insertions, 13 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index cae911726778..8268b87727a7 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -269,13 +269,16 @@ static const struct v4l2_subdev_ops bru_ops = {
269 269
270static void bru_configure(struct vsp1_entity *entity, 270static void bru_configure(struct vsp1_entity *entity,
271 struct vsp1_pipeline *pipe, 271 struct vsp1_pipeline *pipe,
272 struct vsp1_dl_list *dl) 272 struct vsp1_dl_list *dl, bool full)
273{ 273{
274 struct vsp1_bru *bru = to_bru(&entity->subdev); 274 struct vsp1_bru *bru = to_bru(&entity->subdev);
275 struct v4l2_mbus_framefmt *format; 275 struct v4l2_mbus_framefmt *format;
276 unsigned int flags; 276 unsigned int flags;
277 unsigned int i; 277 unsigned int i;
278 278
279 if (!full)
280 return;
281
279 format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config, 282 format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config,
280 bru->entity.source_pad); 283 bru->entity.source_pad);
281 284
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
index cea86e77f7f1..dd0cf20bcdda 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -205,12 +205,15 @@ static const struct v4l2_subdev_ops clu_ops = {
205 205
206static void clu_configure(struct vsp1_entity *entity, 206static void clu_configure(struct vsp1_entity *entity,
207 struct vsp1_pipeline *pipe, 207 struct vsp1_pipeline *pipe,
208 struct vsp1_dl_list *dl) 208 struct vsp1_dl_list *dl, bool full)
209{ 209{
210 struct vsp1_clu *clu = to_clu(&entity->subdev); 210 struct vsp1_clu *clu = to_clu(&entity->subdev);
211 struct v4l2_mbus_framefmt *format; 211 struct v4l2_mbus_framefmt *format;
212 u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN; 212 u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN;
213 213
214 if (!full)
215 return;
216
214 format = vsp1_entity_get_pad_format(&clu->entity, clu->entity.config, 217 format = vsp1_entity_get_pad_format(&clu->entity, clu->entity.config,
215 CLU_PAD_SINK); 218 CLU_PAD_SINK);
216 219
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 14730119687f..fe9665e57b3b 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -491,8 +491,10 @@ void vsp1_du_atomic_flush(struct device *dev)
491 491
492 vsp1_entity_route_setup(entity, pipe->dl); 492 vsp1_entity_route_setup(entity, pipe->dl);
493 493
494 if (entity->ops->configure) 494 if (entity->ops->configure) {
495 entity->ops->configure(entity, pipe, pipe->dl); 495 entity->ops->configure(entity, pipe, pipe->dl, true);
496 entity->ops->configure(entity, pipe, pipe->dl, false);
497 }
496 498
497 /* The memory buffer address must be applied after configuring 499 /* The memory buffer address must be applied after configuring
498 * the RPF to make sure the crop offset are computed. 500 * the RPF to make sure the crop offset are computed.
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index f289ed237c8d..b43457fd2c43 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -73,7 +73,7 @@ struct vsp1_entity_operations {
73 void (*destroy)(struct vsp1_entity *); 73 void (*destroy)(struct vsp1_entity *);
74 void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl); 74 void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl);
75 void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, 75 void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *,
76 struct vsp1_dl_list *); 76 struct vsp1_dl_list *, bool);
77}; 77};
78 78
79struct vsp1_entity { 79struct vsp1_entity {
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index ab3cae307ba5..6e5077beb38c 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -125,10 +125,13 @@ static const struct v4l2_subdev_ops hsit_ops = {
125 125
126static void hsit_configure(struct vsp1_entity *entity, 126static void hsit_configure(struct vsp1_entity *entity,
127 struct vsp1_pipeline *pipe, 127 struct vsp1_pipeline *pipe,
128 struct vsp1_dl_list *dl) 128 struct vsp1_dl_list *dl, bool full)
129{ 129{
130 struct vsp1_hsit *hsit = to_hsit(&entity->subdev); 130 struct vsp1_hsit *hsit = to_hsit(&entity->subdev);
131 131
132 if (!full)
133 return;
134
132 if (hsit->inverse) 135 if (hsit->inverse)
133 vsp1_hsit_write(hsit, dl, VI6_HSI_CTRL, VI6_HSI_CTRL_EN); 136 vsp1_hsit_write(hsit, dl, VI6_HSI_CTRL, VI6_HSI_CTRL_EN);
134 else 137 else
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index e006f0df3ce9..a720063f38c5 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -122,7 +122,7 @@ static const struct v4l2_subdev_ops lif_ops = {
122 122
123static void lif_configure(struct vsp1_entity *entity, 123static void lif_configure(struct vsp1_entity *entity,
124 struct vsp1_pipeline *pipe, 124 struct vsp1_pipeline *pipe,
125 struct vsp1_dl_list *dl) 125 struct vsp1_dl_list *dl, bool full)
126{ 126{
127 const struct v4l2_mbus_framefmt *format; 127 const struct v4l2_mbus_framefmt *format;
128 struct vsp1_lif *lif = to_lif(&entity->subdev); 128 struct vsp1_lif *lif = to_lif(&entity->subdev);
@@ -130,6 +130,9 @@ static void lif_configure(struct vsp1_entity *entity,
130 unsigned int obth = 400; 130 unsigned int obth = 400;
131 unsigned int lbth = 200; 131 unsigned int lbth = 200;
132 132
133 if (!full)
134 return;
135
133 format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, 136 format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
134 LIF_PAD_SOURCE); 137 LIF_PAD_SOURCE);
135 138
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index db8f01dbab84..9619b9a43be4 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -181,10 +181,13 @@ static const struct v4l2_subdev_ops lut_ops = {
181 181
182static void lut_configure(struct vsp1_entity *entity, 182static void lut_configure(struct vsp1_entity *entity,
183 struct vsp1_pipeline *pipe, 183 struct vsp1_pipeline *pipe,
184 struct vsp1_dl_list *dl) 184 struct vsp1_dl_list *dl, bool full)
185{ 185{
186 struct vsp1_lut *lut = to_lut(&entity->subdev); 186 struct vsp1_lut *lut = to_lut(&entity->subdev);
187 187
188 if (!full)
189 return;
190
188 vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN); 191 vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN);
189 192
190 mutex_lock(lut->ctrls.lock); 193 mutex_lock(lut->ctrls.lock);
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 47b1714f6163..390040a22b0c 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -60,7 +60,7 @@ static void rpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
60 60
61static void rpf_configure(struct vsp1_entity *entity, 61static void rpf_configure(struct vsp1_entity *entity,
62 struct vsp1_pipeline *pipe, 62 struct vsp1_pipeline *pipe,
63 struct vsp1_dl_list *dl) 63 struct vsp1_dl_list *dl, bool full)
64{ 64{
65 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); 65 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
66 const struct vsp1_format_info *fmtinfo = rpf->fmtinfo; 66 const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
@@ -73,6 +73,9 @@ static void rpf_configure(struct vsp1_entity *entity,
73 u32 pstride; 73 u32 pstride;
74 u32 infmt; 74 u32 infmt;
75 75
76 if (!full)
77 return;
78
76 /* Source size, stride and crop offsets. 79 /* Source size, stride and crop offsets.
77 * 80 *
78 * The crop offsets correspond to the location of the crop rectangle top 81 * The crop offsets correspond to the location of the crop rectangle top
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index e13afd5e4d8b..47f5e0cea2ce 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -257,7 +257,7 @@ static const struct v4l2_subdev_ops sru_ops = {
257 257
258static void sru_configure(struct vsp1_entity *entity, 258static void sru_configure(struct vsp1_entity *entity,
259 struct vsp1_pipeline *pipe, 259 struct vsp1_pipeline *pipe,
260 struct vsp1_dl_list *dl) 260 struct vsp1_dl_list *dl, bool full)
261{ 261{
262 const struct vsp1_sru_param *param; 262 const struct vsp1_sru_param *param;
263 struct vsp1_sru *sru = to_sru(&entity->subdev); 263 struct vsp1_sru *sru = to_sru(&entity->subdev);
@@ -265,6 +265,9 @@ static void sru_configure(struct vsp1_entity *entity,
265 struct v4l2_mbus_framefmt *output; 265 struct v4l2_mbus_framefmt *output;
266 u32 ctrl0; 266 u32 ctrl0;
267 267
268 if (!full)
269 return;
270
268 input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, 271 input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
269 SRU_PAD_SINK); 272 SRU_PAD_SINK);
270 output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, 273 output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index f22945101bc8..5d5720f2e5fe 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -244,7 +244,7 @@ static const struct v4l2_subdev_ops uds_ops = {
244 244
245static void uds_configure(struct vsp1_entity *entity, 245static void uds_configure(struct vsp1_entity *entity,
246 struct vsp1_pipeline *pipe, 246 struct vsp1_pipeline *pipe,
247 struct vsp1_dl_list *dl) 247 struct vsp1_dl_list *dl, bool full)
248{ 248{
249 struct vsp1_uds *uds = to_uds(&entity->subdev); 249 struct vsp1_uds *uds = to_uds(&entity->subdev);
250 const struct v4l2_mbus_framefmt *output; 250 const struct v4l2_mbus_framefmt *output;
@@ -253,6 +253,9 @@ static void uds_configure(struct vsp1_entity *entity,
253 unsigned int vscale; 253 unsigned int vscale;
254 bool multitap; 254 bool multitap;
255 255
256 if (!full)
257 return;
258
256 input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, 259 input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
257 UDS_PAD_SINK); 260 UDS_PAD_SINK);
258 output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, 261 output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index f6208b9d8118..01654232b695 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -251,11 +251,17 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
251static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) 251static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe)
252{ 252{
253 struct vsp1_device *vsp1 = pipe->output->entity.vsp1; 253 struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
254 struct vsp1_entity *entity;
254 unsigned int i; 255 unsigned int i;
255 256
256 if (!pipe->dl) 257 if (!pipe->dl)
257 pipe->dl = vsp1_dl_list_get(pipe->output->dlm); 258 pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
258 259
260 list_for_each_entry(entity, &pipe->entities, list_pipe) {
261 if (entity->ops->configure)
262 entity->ops->configure(entity, pipe, pipe->dl, false);
263 }
264
259 for (i = 0; i < vsp1->info->rpf_count; ++i) { 265 for (i = 0; i < vsp1->info->rpf_count; ++i) {
260 struct vsp1_rwpf *rwpf = pipe->inputs[i]; 266 struct vsp1_rwpf *rwpf = pipe->inputs[i];
261 267
@@ -632,7 +638,7 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
632 vsp1_entity_route_setup(entity, pipe->dl); 638 vsp1_entity_route_setup(entity, pipe->dl);
633 639
634 if (entity->ops->configure) 640 if (entity->ops->configure)
635 entity->ops->configure(entity, pipe, pipe->dl); 641 entity->ops->configure(entity, pipe, pipe->dl, true);
636 } 642 }
637 643
638 return 0; 644 return 0;
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 70fb979d4f94..474feac67155 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -93,7 +93,7 @@ static void wpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
93 93
94static void wpf_configure(struct vsp1_entity *entity, 94static void wpf_configure(struct vsp1_entity *entity,
95 struct vsp1_pipeline *pipe, 95 struct vsp1_pipeline *pipe,
96 struct vsp1_dl_list *dl) 96 struct vsp1_dl_list *dl, bool full)
97{ 97{
98 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev); 98 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
99 struct vsp1_device *vsp1 = wpf->entity.vsp1; 99 struct vsp1_device *vsp1 = wpf->entity.vsp1;
@@ -104,6 +104,9 @@ static void wpf_configure(struct vsp1_entity *entity,
104 u32 outfmt = 0; 104 u32 outfmt = 0;
105 u32 srcrpf = 0; 105 u32 srcrpf = 0;
106 106
107 if (!full)
108 return;
109
107 /* Cropping */ 110 /* Cropping */
108 crop = vsp1_rwpf_get_crop(wpf, wpf->entity.config); 111 crop = vsp1_rwpf_get_crop(wpf, wpf->entity.config);
109 112