aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-11-01 09:19:42 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-04-13 16:42:43 -0400
commitbd2fdd5aa919e3cb750147c9270034f11d106d94 (patch)
treed296852eabf9da568727d6e5e663764b4a6dc621
parent5fb2107346cfc6d8fe62117a2cbf91fc1f92cc84 (diff)
[media] v4l: vsp1: rwpf: Don't program alpha value in control set handler
The datasheet clearly states that all but a few registers can't be modified when the device is running. Programming the alpha value in the control set handler is thus prohibited. Program it when starting the module instead. This requires storing the alpha value internally as the module can be started from the frame completion interrupt handler, and accessing control values requires taking a mutex. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c51
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.c35
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h5
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c55
4 files changed, 47 insertions, 99 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 5bc1d1574a43..9ccfb572b4a5 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -33,36 +33,6 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data)
33} 33}
34 34
35/* ----------------------------------------------------------------------------- 35/* -----------------------------------------------------------------------------
36 * Controls
37 */
38
39static int rpf_s_ctrl(struct v4l2_ctrl *ctrl)
40{
41 struct vsp1_rwpf *rpf =
42 container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
43 struct vsp1_pipeline *pipe;
44
45 if (!vsp1_entity_is_streaming(&rpf->entity))
46 return 0;
47
48 switch (ctrl->id) {
49 case V4L2_CID_ALPHA_COMPONENT:
50 vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
51 ctrl->val << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
52
53 pipe = to_vsp1_pipeline(&rpf->entity.subdev.entity);
54 vsp1_pipeline_propagate_alpha(pipe, &rpf->entity, ctrl->val);
55 break;
56 }
57
58 return 0;
59}
60
61static const struct v4l2_ctrl_ops rpf_ctrl_ops = {
62 .s_ctrl = rpf_s_ctrl,
63};
64
65/* -----------------------------------------------------------------------------
66 * V4L2 Subdevice Core Operations 36 * V4L2 Subdevice Core Operations
67 */ 37 */
68 38
@@ -70,7 +40,6 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
70{ 40{
71 struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity); 41 struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
72 struct vsp1_rwpf *rpf = to_rwpf(subdev); 42 struct vsp1_rwpf *rpf = to_rwpf(subdev);
73 struct vsp1_device *vsp1 = rpf->entity.vsp1;
74 const struct vsp1_format_info *fmtinfo = rpf->fmtinfo; 43 const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
75 const struct v4l2_pix_format_mplane *format = &rpf->format; 44 const struct v4l2_pix_format_mplane *format = &rpf->format;
76 const struct v4l2_rect *crop = &rpf->crop; 45 const struct v4l2_rect *crop = &rpf->crop;
@@ -151,13 +120,10 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
151 (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED 120 (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED
152 : VI6_RPF_ALPH_SEL_ASEL_FIXED)); 121 : VI6_RPF_ALPH_SEL_ASEL_FIXED));
153 122
154 if (vsp1->info->uapi)
155 mutex_lock(rpf->ctrls.lock);
156 vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET, 123 vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
157 rpf->alpha->cur.val << VI6_RPF_VRTCOL_SET_LAYA_SHIFT); 124 rpf->alpha << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
158 vsp1_pipeline_propagate_alpha(pipe, &rpf->entity, rpf->alpha->cur.val); 125
159 if (vsp1->info->uapi) 126 vsp1_pipeline_propagate_alpha(pipe, &rpf->entity, rpf->alpha);
160 mutex_unlock(rpf->ctrls.lock);
161 127
162 vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0); 128 vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0);
163 vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0); 129 vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0);
@@ -255,17 +221,10 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
255 vsp1_entity_init_formats(subdev, NULL); 221 vsp1_entity_init_formats(subdev, NULL);
256 222
257 /* Initialize the control handler. */ 223 /* Initialize the control handler. */
258 v4l2_ctrl_handler_init(&rpf->ctrls, 1); 224 ret = vsp1_rwpf_init_ctrls(rpf);
259 rpf->alpha = v4l2_ctrl_new_std(&rpf->ctrls, &rpf_ctrl_ops, 225 if (ret < 0) {
260 V4L2_CID_ALPHA_COMPONENT,
261 0, 255, 1, 255);
262
263 rpf->entity.subdev.ctrl_handler = &rpf->ctrls;
264
265 if (rpf->ctrls.error) {
266 dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n", 226 dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n",
267 index); 227 index);
268 ret = rpf->ctrls.error;
269 goto error; 228 goto error;
270 } 229 }
271 230
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index 9688c219b30e..ba50386db35c 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -230,3 +230,38 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
230 230
231 return 0; 231 return 0;
232} 232}
233
234/* -----------------------------------------------------------------------------
235 * Controls
236 */
237
238static int vsp1_rwpf_s_ctrl(struct v4l2_ctrl *ctrl)
239{
240 struct vsp1_rwpf *rwpf =
241 container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
242
243 switch (ctrl->id) {
244 case V4L2_CID_ALPHA_COMPONENT:
245 rwpf->alpha = ctrl->val;
246 break;
247 }
248
249 return 0;
250}
251
252static const struct v4l2_ctrl_ops vsp1_rwpf_ctrl_ops = {
253 .s_ctrl = vsp1_rwpf_s_ctrl,
254};
255
256int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf)
257{
258 rwpf->alpha = 255;
259
260 v4l2_ctrl_handler_init(&rwpf->ctrls, 1);
261 v4l2_ctrl_new_std(&rwpf->ctrls, &vsp1_rwpf_ctrl_ops,
262 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
263
264 rwpf->entity.subdev.ctrl_handler = &rwpf->ctrls;
265
266 return rwpf->ctrls.error;
267}
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index d04df39b2737..66af2a06dd8b 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -42,7 +42,6 @@ struct vsp1_rwpf_operations {
42struct vsp1_rwpf { 42struct vsp1_rwpf {
43 struct vsp1_entity entity; 43 struct vsp1_entity entity;
44 struct v4l2_ctrl_handler ctrls; 44 struct v4l2_ctrl_handler ctrls;
45 struct v4l2_ctrl *alpha;
46 45
47 struct vsp1_video *video; 46 struct vsp1_video *video;
48 47
@@ -59,6 +58,8 @@ struct vsp1_rwpf {
59 } location; 58 } location;
60 struct v4l2_rect crop; 59 struct v4l2_rect crop;
61 60
61 unsigned int alpha;
62
62 unsigned int offsets[2]; 63 unsigned int offsets[2];
63 dma_addr_t buf_addr[3]; 64 dma_addr_t buf_addr[3];
64 65
@@ -73,6 +74,8 @@ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev)
73struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); 74struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index);
74struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); 75struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index);
75 76
77int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf);
78
76int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, 79int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev,
77 struct v4l2_subdev_pad_config *cfg, 80 struct v4l2_subdev_pad_config *cfg,
78 struct v4l2_subdev_mbus_code_enum *code); 81 struct v4l2_subdev_mbus_code_enum *code);
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 6afc9c8d9adc..2135cca2490e 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -27,12 +27,6 @@
27 * Device Access 27 * Device Access
28 */ 28 */
29 29
30static inline u32 vsp1_wpf_read(struct vsp1_rwpf *wpf, u32 reg)
31{
32 return vsp1_read(wpf->entity.vsp1,
33 reg + wpf->entity.index * VI6_WPF_OFFSET);
34}
35
36static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data) 30static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data)
37{ 31{
38 vsp1_mod_write(&wpf->entity, 32 vsp1_mod_write(&wpf->entity,
@@ -40,35 +34,6 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data)
40} 34}
41 35
42/* ----------------------------------------------------------------------------- 36/* -----------------------------------------------------------------------------
43 * Controls
44 */
45
46static int wpf_s_ctrl(struct v4l2_ctrl *ctrl)
47{
48 struct vsp1_rwpf *wpf =
49 container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
50 u32 value;
51
52 if (!vsp1_entity_is_streaming(&wpf->entity))
53 return 0;
54
55 switch (ctrl->id) {
56 case V4L2_CID_ALPHA_COMPONENT:
57 value = vsp1_wpf_read(wpf, VI6_WPF_OUTFMT);
58 value &= ~VI6_WPF_OUTFMT_PDV_MASK;
59 value |= ctrl->val << VI6_WPF_OUTFMT_PDV_SHIFT;
60 vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, value);
61 break;
62 }
63
64 return 0;
65}
66
67static const struct v4l2_ctrl_ops wpf_ctrl_ops = {
68 .s_ctrl = wpf_s_ctrl,
69};
70
71/* -----------------------------------------------------------------------------
72 * V4L2 Subdevice Core Operations 37 * V4L2 Subdevice Core Operations
73 */ 38 */
74 39
@@ -153,15 +118,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
153 wpf->entity.formats[RWPF_PAD_SOURCE].code) 118 wpf->entity.formats[RWPF_PAD_SOURCE].code)
154 outfmt |= VI6_WPF_OUTFMT_CSC; 119 outfmt |= VI6_WPF_OUTFMT_CSC;
155 120
156 /* Take the control handler lock to ensure that the PDV value won't be 121 outfmt |= wpf->alpha << VI6_WPF_OUTFMT_PDV_SHIFT;
157 * changed behind our back by a set control operation.
158 */
159 if (vsp1->info->uapi)
160 mutex_lock(wpf->ctrls.lock);
161 outfmt |= wpf->alpha->cur.val << VI6_WPF_OUTFMT_PDV_SHIFT;
162 vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt); 122 vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);
163 if (vsp1->info->uapi)
164 mutex_unlock(wpf->ctrls.lock);
165 123
166 vsp1_mod_write(&wpf->entity, VI6_DPR_WPF_FPORCH(wpf->entity.index), 124 vsp1_mod_write(&wpf->entity, VI6_DPR_WPF_FPORCH(wpf->entity.index),
167 VI6_DPR_WPF_FPORCH_FP_WPFN); 125 VI6_DPR_WPF_FPORCH_FP_WPFN);
@@ -272,17 +230,10 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
272 vsp1_entity_init_formats(subdev, NULL); 230 vsp1_entity_init_formats(subdev, NULL);
273 231
274 /* Initialize the control handler. */ 232 /* Initialize the control handler. */
275 v4l2_ctrl_handler_init(&wpf->ctrls, 1); 233 ret = vsp1_rwpf_init_ctrls(wpf);
276 wpf->alpha = v4l2_ctrl_new_std(&wpf->ctrls, &wpf_ctrl_ops, 234 if (ret < 0) {
277 V4L2_CID_ALPHA_COMPONENT,
278 0, 255, 1, 255);
279
280 wpf->entity.subdev.ctrl_handler = &wpf->ctrls;
281
282 if (wpf->ctrls.error) {
283 dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n", 235 dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n",
284 index); 236 index);
285 ret = wpf->ctrls.error;
286 goto error; 237 goto error;
287 } 238 }
288 239