Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] v4l: vsp1: sru: Make the intensity controllable during streaming

The control value is currently stored in the SRU structure by the
control set handler and written to the hardware at stream on time,
making control set during streaming ineffective. Fix it by writing to
the registers from within the control set handler.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Laurent Pinchart and committed by
Mauro Carvalho Chehab
58f896d8 a1606102

+61 -43
+2
drivers/media/platform/vsp1/vsp1_regs.h
··· 336 336 */ 337 337 338 338 #define VI6_SRU_CTRL0 0x2200 339 + #define VI6_SRU_CTRL0_PARAM0_MASK (0x1ff << 16) 339 340 #define VI6_SRU_CTRL0_PARAM0_SHIFT 16 341 + #define VI6_SRU_CTRL0_PARAM1_MASK (0x1f << 8) 340 342 #define VI6_SRU_CTRL0_PARAM1_SHIFT 8 341 343 #define VI6_SRU_CTRL0_MODE_UPSCALE (4 << 4) 342 344 #define VI6_SRU_CTRL0_PARAM2 (1 << 3)
+59 -42
drivers/media/platform/vsp1/vsp1_sru.c
··· 42 42 43 43 #define V4L2_CID_VSP1_SRU_INTENSITY (V4L2_CID_USER_BASE + 1) 44 44 45 - static int sru_s_ctrl(struct v4l2_ctrl *ctrl) 46 - { 47 - struct vsp1_sru *sru = 48 - container_of(ctrl->handler, struct vsp1_sru, ctrls); 49 - 50 - switch (ctrl->id) { 51 - case V4L2_CID_VSP1_SRU_INTENSITY: 52 - sru->intensity = ctrl->val; 53 - break; 54 - } 55 - 56 - return 0; 57 - } 58 - 59 - static const struct v4l2_ctrl_ops sru_ctrl_ops = { 60 - .s_ctrl = sru_s_ctrl, 61 - }; 62 - 63 - static const struct v4l2_ctrl_config sru_intensity_control = { 64 - .ops = &sru_ctrl_ops, 65 - .id = V4L2_CID_VSP1_SRU_INTENSITY, 66 - .name = "Intensity", 67 - .type = V4L2_CTRL_TYPE_INTEGER, 68 - .min = 1, 69 - .max = 6, 70 - .def = 1, 71 - .step = 1, 72 - }; 73 - 74 - /* ----------------------------------------------------------------------------- 75 - * V4L2 Subdevice Core Operations 76 - */ 77 - 78 45 struct vsp1_sru_param { 79 46 u32 ctrl0; 80 47 u32 ctrl2; ··· 78 111 }, 79 112 }; 80 113 114 + static int sru_s_ctrl(struct v4l2_ctrl *ctrl) 115 + { 116 + struct vsp1_sru *sru = 117 + container_of(ctrl->handler, struct vsp1_sru, ctrls); 118 + const struct vsp1_sru_param *param; 119 + u32 value; 120 + 121 + switch (ctrl->id) { 122 + case V4L2_CID_VSP1_SRU_INTENSITY: 123 + param = &vsp1_sru_params[ctrl->val - 1]; 124 + 125 + value = vsp1_sru_read(sru, VI6_SRU_CTRL0); 126 + value &= ~(VI6_SRU_CTRL0_PARAM0_MASK | 127 + VI6_SRU_CTRL0_PARAM1_MASK); 128 + value |= param->ctrl0; 129 + vsp1_sru_write(sru, VI6_SRU_CTRL0, value); 130 + 131 + vsp1_sru_write(sru, VI6_SRU_CTRL2, param->ctrl2); 132 + break; 133 + } 134 + 135 + return 0; 136 + } 137 + 138 + static const struct v4l2_ctrl_ops sru_ctrl_ops = { 139 + .s_ctrl = sru_s_ctrl, 140 + }; 141 + 142 + static const struct v4l2_ctrl_config sru_intensity_control = { 143 + .ops = &sru_ctrl_ops, 144 + .id = V4L2_CID_VSP1_SRU_INTENSITY, 145 + .name = "Intensity", 146 + .type = V4L2_CTRL_TYPE_INTEGER, 147 + .min = 1, 148 + .max = 6, 149 + .def = 1, 150 + .step = 1, 151 + }; 152 + 153 + /* ----------------------------------------------------------------------------- 154 + * V4L2 Subdevice Core Operations 155 + */ 156 + 81 157 static int sru_s_stream(struct v4l2_subdev *subdev, int enable) 82 158 { 83 159 struct vsp1_sru *sru = to_sru(subdev); 84 - const struct vsp1_sru_param *param; 85 160 struct v4l2_mbus_framefmt *input; 86 161 struct v4l2_mbus_framefmt *output; 87 - bool upscale; 88 162 u32 ctrl0; 163 + int ret; 164 + 165 + ret = vsp1_entity_set_streaming(&sru->entity, enable); 166 + if (ret < 0) 167 + return ret; 89 168 90 169 if (!enable) 91 170 return 0; 92 171 93 172 input = &sru->entity.formats[SRU_PAD_SINK]; 94 173 output = &sru->entity.formats[SRU_PAD_SOURCE]; 95 - upscale = input->width != output->width; 96 - param = &vsp1_sru_params[sru->intensity]; 97 174 98 175 if (input->code == V4L2_MBUS_FMT_ARGB8888_1X32) 99 176 ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3 ··· 145 134 else 146 135 ctrl0 = VI6_SRU_CTRL0_PARAM3; 147 136 148 - vsp1_sru_write(sru, VI6_SRU_CTRL0, param->ctrl0 | ctrl0 | 149 - (upscale ? VI6_SRU_CTRL0_MODE_UPSCALE : 0)); 137 + if (input->width != output->width) 138 + ctrl0 |= VI6_SRU_CTRL0_MODE_UPSCALE; 139 + 140 + /* Take the control handler lock to ensure that the CTRL0 value won't be 141 + * changed behind our back by a set control operation. 142 + */ 143 + mutex_lock(sru->ctrls.lock); 144 + ctrl0 |= vsp1_sru_read(sru, VI6_SRU_CTRL0) 145 + & (VI6_SRU_CTRL0_PARAM0_MASK | VI6_SRU_CTRL0_PARAM1_MASK); 146 + mutex_unlock(sru->ctrls.lock); 147 + 150 148 vsp1_sru_write(sru, VI6_SRU_CTRL1, VI6_SRU_CTRL1_PARAM5); 151 - vsp1_sru_write(sru, VI6_SRU_CTRL2, param->ctrl2); 152 149 153 150 return 0; 154 151 } ··· 377 358 vsp1_entity_destroy(&sru->entity); 378 359 return ERR_PTR(ret); 379 360 } 380 - 381 - v4l2_ctrl_handler_setup(&sru->ctrls); 382 361 383 362 return sru; 384 363 }
-1
drivers/media/platform/vsp1/vsp1_sru.h
··· 28 28 struct vsp1_entity entity; 29 29 30 30 struct v4l2_ctrl_handler ctrls; 31 - unsigned int intensity; 32 31 }; 33 32 34 33 static inline struct vsp1_sru *to_sru(struct v4l2_subdev *subdev)