[PATCH v1 1/3] media: rkisp1: resizer: Use V4L2 subdev active state

Paul Elder paul.elder at ideasonboard.com
Wed Apr 26 20:52:04 PDT 2023


On Fri, Jan 27, 2023 at 02:31:22AM +0200, Laurent Pinchart wrote:
> Use the V4L2 subdev active state API to store the active format and crop
> rectangle. This simplifies the driver not only by dropping the state
> stored in the rkisp1_resizer structure, but also by replacing the
> ops_lock with the state lock.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>

> ---
>  .../platform/rockchip/rkisp1/rkisp1-common.h  |   6 -
>  .../platform/rockchip/rkisp1/rkisp1-resizer.c | 184 +++++++-----------
>  2 files changed, 66 insertions(+), 124 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> index a1293c45aae1..e9626e59e1c8 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -390,10 +390,7 @@ struct rkisp1_params {
>   * @id:	       id of the resizer, one of RKISP1_SELFPATH, RKISP1_MAINPATH
>   * @rkisp1:    pointer to the rkisp1 device
>   * @pads:      media pads
> - * @pad_cfg:   configurations for the pads
>   * @config:    the set of registers to configure the resizer
> - * @pixel_enc: pixel encoding of the resizer
> - * @ops_lock:  a lock for the subdev ops
>   */
>  struct rkisp1_resizer {
>  	struct v4l2_subdev sd;
> @@ -401,10 +398,7 @@ struct rkisp1_resizer {
>  	enum rkisp1_stream_id id;
>  	struct rkisp1_device *rkisp1;
>  	struct media_pad pads[RKISP1_RSZ_PAD_MAX];
> -	struct v4l2_subdev_pad_config pad_cfg[RKISP1_RSZ_PAD_MAX];
>  	const struct rkisp1_rsz_config *config;
> -	enum v4l2_pixel_encoding pixel_enc;
> -	struct mutex ops_lock; /* serialize the subdevice ops */
>  };
>  
>  /*
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> index f76afd8112b2..62728ee6d058 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> @@ -117,34 +117,6 @@ static inline void rkisp1_rsz_write(struct rkisp1_resizer *rsz, u32 offset,
>  	rkisp1_write(rsz->rkisp1, rsz->regs_base + offset, value);
>  }
>  
> -static struct v4l2_mbus_framefmt *
> -rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
> -		       struct v4l2_subdev_state *sd_state,
> -		       unsigned int pad, u32 which)
> -{
> -	struct v4l2_subdev_state state = {
> -		.pads = rsz->pad_cfg
> -		};
> -	if (which == V4L2_SUBDEV_FORMAT_TRY)
> -		return v4l2_subdev_get_try_format(&rsz->sd, sd_state, pad);
> -	else
> -		return v4l2_subdev_get_try_format(&rsz->sd, &state, pad);
> -}
> -
> -static struct v4l2_rect *
> -rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
> -			struct v4l2_subdev_state *sd_state,
> -			unsigned int pad, u32 which)
> -{
> -	struct v4l2_subdev_state state = {
> -		.pads = rsz->pad_cfg
> -		};
> -	if (which == V4L2_SUBDEV_FORMAT_TRY)
> -		return v4l2_subdev_get_try_crop(&rsz->sd, sd_state, pad);
> -	else
> -		return v4l2_subdev_get_try_crop(&rsz->sd, &state, pad);
> -}
> -
>  /* ----------------------------------------------------------------------------
>   * Dual crop hw configs
>   */
> @@ -165,17 +137,18 @@ static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
>  }
>  
>  /* configure dual-crop unit */
> -static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
> +static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz,
> +				struct v4l2_subdev_state *sd_state)
>  {
>  	struct rkisp1_device *rkisp1 = rsz->rkisp1;
>  	struct v4l2_mbus_framefmt *sink_fmt;
>  	struct v4l2_rect *sink_crop;
>  	u32 dc_ctrl;
>  
> -	sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
> -					    V4L2_SUBDEV_FORMAT_ACTIVE);
> -	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
> -					  V4L2_SUBDEV_FORMAT_ACTIVE);
> +	sink_crop = v4l2_subdev_get_pad_crop(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SINK);
> +	sink_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					      RKISP1_RSZ_PAD_SINK);
>  
>  	if (sink_crop->width == sink_fmt->width &&
>  	    sink_crop->height == sink_fmt->height &&
> @@ -296,6 +269,7 @@ static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
>  }
>  
>  static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
> +			      struct v4l2_subdev_state *sd_state,
>  			      enum rkisp1_shadow_regs_when when)
>  {
>  	const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
> @@ -303,20 +277,21 @@ static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
>  	struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
>  	struct v4l2_rect *sink_crop;
>  
> -	sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
> -					    V4L2_SUBDEV_FORMAT_ACTIVE);
> -	src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
> -					 V4L2_SUBDEV_FORMAT_ACTIVE);
> -	src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
> -	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
> -					  V4L2_SUBDEV_FORMAT_ACTIVE);
> +	sink_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					      RKISP1_RSZ_PAD_SINK);
> +	sink_crop = v4l2_subdev_get_pad_crop(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SINK);
> +	src_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SRC);
> +
>  	sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code);
> +	src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
>  
>  	/*
>  	 * The resizer only works on yuv formats,
>  	 * so return if it is bayer format.
>  	 */
> -	if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
> +	if (!sink_yuv_info) {
>  		rkisp1_rsz_disable(rsz, when);
>  		return;
>  	}
> @@ -405,7 +380,7 @@ static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
>  	struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
>  	struct v4l2_rect *sink_crop;
>  
> -	sink_fmt = v4l2_subdev_get_try_format(sd, sd_state,
> +	sink_fmt = v4l2_subdev_get_pad_format(sd, sd_state,
>  					      RKISP1_RSZ_PAD_SRC);
>  	sink_fmt->width = RKISP1_DEFAULT_WIDTH;
>  	sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
> @@ -423,7 +398,7 @@ static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
>  	sink_crop->left = 0;
>  	sink_crop->top = 0;
>  
> -	src_fmt = v4l2_subdev_get_try_format(sd, sd_state,
> +	src_fmt = v4l2_subdev_get_pad_format(sd, sd_state,
>  					     RKISP1_RSZ_PAD_SINK);
>  	*src_fmt = *sink_fmt;
>  
> @@ -434,16 +409,16 @@ static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
>  
>  static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
>  				   struct v4l2_subdev_state *sd_state,
> -				   struct v4l2_mbus_framefmt *format,
> -				   unsigned int which)
> +				   struct v4l2_mbus_framefmt *format)
>  {
>  	const struct rkisp1_mbus_info *sink_mbus_info;
>  	struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
>  
> -	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
> -					  which);
> -	src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC,
> -					 which);
> +	sink_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					      RKISP1_RSZ_PAD_SINK);
> +	src_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SRC);
> +
>  	sink_mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
>  
>  	/* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
> @@ -463,18 +438,16 @@ static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
>  
>  static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
>  				     struct v4l2_subdev_state *sd_state,
> -				     struct v4l2_rect *r,
> -				     unsigned int which)
> +				     struct v4l2_rect *r)
>  {
>  	const struct rkisp1_mbus_info *mbus_info;
>  	struct v4l2_mbus_framefmt *sink_fmt;
>  	struct v4l2_rect *sink_crop;
>  
> -	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
> -					  which);
> -	sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state,
> -					    RKISP1_RSZ_PAD_SINK,
> -					    which);
> +	sink_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					      RKISP1_RSZ_PAD_SINK);
> +	sink_crop = v4l2_subdev_get_pad_crop(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SINK);
>  
>  	/* Not crop for MP bayer raw data */
>  	mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
> @@ -501,21 +474,20 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
>  
>  static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
>  				    struct v4l2_subdev_state *sd_state,
> -				    struct v4l2_mbus_framefmt *format,
> -				    unsigned int which)
> +				    struct v4l2_mbus_framefmt *format)
>  {
>  	const struct rkisp1_mbus_info *mbus_info;
>  	struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
>  	struct v4l2_rect *sink_crop;
>  	bool is_yuv;
>  
> -	sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK,
> -					  which);
> -	src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC,
> -					 which);
> -	sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state,
> -					    RKISP1_RSZ_PAD_SINK,
> -					    which);
> +	sink_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					      RKISP1_RSZ_PAD_SINK);
> +	src_fmt = v4l2_subdev_get_pad_format(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SRC);
> +	sink_crop = v4l2_subdev_get_pad_crop(&rsz->sd, sd_state,
> +					     RKISP1_RSZ_PAD_SINK);
> +
>  	if (rsz->id == RKISP1_SELFPATH)
>  		sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
>  	else
> @@ -526,8 +498,6 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
>  		sink_fmt->code = RKISP1_DEF_FMT;
>  		mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
>  	}
> -	if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
> -		rsz->pixel_enc = mbus_info->pixel_enc;
>  
>  	sink_fmt->width = clamp_t(u32, format->width,
>  				  RKISP1_ISP_MIN_WIDTH,
> @@ -576,21 +546,7 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
>  	src_fmt->quantization = sink_fmt->quantization;
>  
>  	/* Update sink crop */
> -	rkisp1_rsz_set_sink_crop(rsz, sd_state, sink_crop, which);
> -}
> -
> -static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
> -			      struct v4l2_subdev_state *sd_state,
> -			      struct v4l2_subdev_format *fmt)
> -{
> -	struct rkisp1_resizer *rsz =
> -		container_of(sd, struct rkisp1_resizer, sd);
> -
> -	mutex_lock(&rsz->ops_lock);
> -	fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, sd_state, fmt->pad,
> -					      fmt->which);
> -	mutex_unlock(&rsz->ops_lock);
> -	return 0;
> +	rkisp1_rsz_set_sink_crop(rsz, sd_state, sink_crop);
>  }
>  
>  static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
> @@ -600,15 +556,11 @@ static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
>  	struct rkisp1_resizer *rsz =
>  		container_of(sd, struct rkisp1_resizer, sd);
>  
> -	mutex_lock(&rsz->ops_lock);
>  	if (fmt->pad == RKISP1_RSZ_PAD_SINK)
> -		rkisp1_rsz_set_sink_fmt(rsz, sd_state, &fmt->format,
> -					fmt->which);
> +		rkisp1_rsz_set_sink_fmt(rsz, sd_state, &fmt->format);
>  	else
> -		rkisp1_rsz_set_src_fmt(rsz, sd_state, &fmt->format,
> -				       fmt->which);
> +		rkisp1_rsz_set_src_fmt(rsz, sd_state, &fmt->format);
>  
> -	mutex_unlock(&rsz->ops_lock);
>  	return 0;
>  }
>  
> @@ -616,35 +568,32 @@ static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
>  				    struct v4l2_subdev_state *sd_state,
>  				    struct v4l2_subdev_selection *sel)
>  {
> -	struct rkisp1_resizer *rsz =
> -		container_of(sd, struct rkisp1_resizer, sd);
>  	struct v4l2_mbus_framefmt *mf_sink;
>  	int ret = 0;
>  
>  	if (sel->pad == RKISP1_RSZ_PAD_SRC)
>  		return -EINVAL;
>  
> -	mutex_lock(&rsz->ops_lock);
>  	switch (sel->target) {
>  	case V4L2_SEL_TGT_CROP_BOUNDS:
> -		mf_sink = rkisp1_rsz_get_pad_fmt(rsz, sd_state,
> -						 RKISP1_RSZ_PAD_SINK,
> -						 sel->which);
> +		mf_sink = v4l2_subdev_get_pad_format(sd, sd_state,
> +						     RKISP1_RSZ_PAD_SINK);
>  		sel->r.height = mf_sink->height;
>  		sel->r.width = mf_sink->width;
>  		sel->r.left = 0;
>  		sel->r.top = 0;
>  		break;
> +
>  	case V4L2_SEL_TGT_CROP:
> -		sel->r = *rkisp1_rsz_get_pad_crop(rsz, sd_state,
> -						  RKISP1_RSZ_PAD_SINK,
> -						  sel->which);
> +		sel->r = *v4l2_subdev_get_pad_crop(sd, sd_state,
> +						   RKISP1_RSZ_PAD_SINK);
>  		break;
> +
>  	default:
>  		ret = -EINVAL;
> +		break;
>  	}
>  
> -	mutex_unlock(&rsz->ops_lock);
>  	return ret;
>  }
>  
> @@ -661,9 +610,7 @@ static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
>  	dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
>  		sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
>  
> -	mutex_lock(&rsz->ops_lock);
> -	rkisp1_rsz_set_sink_crop(rsz, sd_state, &sel->r, sel->which);
> -	mutex_unlock(&rsz->ops_lock);
> +	rkisp1_rsz_set_sink_crop(rsz, sd_state, &sel->r);
>  
>  	return 0;
>  }
> @@ -677,7 +624,7 @@ static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
>  	.get_selection = rkisp1_rsz_get_selection,
>  	.set_selection = rkisp1_rsz_set_selection,
>  	.init_cfg = rkisp1_rsz_init_config,
> -	.get_fmt = rkisp1_rsz_get_fmt,
> +	.get_fmt = v4l2_subdev_get_fmt,
>  	.set_fmt = rkisp1_rsz_set_fmt,
>  	.link_validate = v4l2_subdev_link_validate_default,
>  };
> @@ -693,6 +640,7 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
>  	struct rkisp1_device *rkisp1 = rsz->rkisp1;
>  	struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
>  	enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
> +	struct v4l2_subdev_state *sd_state;
>  
>  	if (!enable) {
>  		rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
> @@ -703,11 +651,13 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
>  	if (other->is_streaming)
>  		when = RKISP1_SHADOW_REGS_ASYNC;
>  
> -	mutex_lock(&rsz->ops_lock);
> -	rkisp1_rsz_config(rsz, when);
> -	rkisp1_dcrop_config(rsz);
> +	sd_state = v4l2_subdev_lock_and_get_active_state(sd);
> +
> +	rkisp1_rsz_config(rsz, sd_state, when);
> +	rkisp1_dcrop_config(rsz, sd_state);
> +
> +	v4l2_subdev_unlock_state(sd_state);
>  
> -	mutex_unlock(&rsz->ops_lock);
>  	return 0;
>  }
>  
> @@ -726,15 +676,12 @@ static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
>  		return;
>  
>  	v4l2_device_unregister_subdev(&rsz->sd);
> +	v4l2_subdev_cleanup(&rsz->sd);
>  	media_entity_cleanup(&rsz->sd.entity);
> -	mutex_destroy(&rsz->ops_lock);
>  }
>  
>  static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
>  {
> -	struct v4l2_subdev_state state = {
> -		.pads = rsz->pad_cfg
> -		};
>  	static const char * const dev_names[] = {
>  		RKISP1_RSZ_MP_DEV_NAME,
>  		RKISP1_RSZ_SP_DEV_NAME
> @@ -763,25 +710,26 @@ static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
>  	pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
>  					 MEDIA_PAD_FL_MUST_CONNECT;
>  
> -	rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
> -
> -	mutex_init(&rsz->ops_lock);
>  	ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
>  	if (ret)
> -		goto error;
> +		goto err_entity_cleanup;
> +
> +	ret = v4l2_subdev_init_finalize(sd);
> +	if (ret)
> +		goto err_entity_cleanup;
>  
>  	ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
>  	if (ret) {
>  		dev_err(sd->dev, "Failed to register resizer subdev\n");
> -		goto error;
> +		goto err_subdev_cleanup;
>  	}
>  
> -	rkisp1_rsz_init_config(sd, &state);
>  	return 0;
>  
> -error:
> +err_subdev_cleanup:
> +	v4l2_subdev_cleanup(sd);
> +err_entity_cleanup:
>  	media_entity_cleanup(&sd->entity);
> -	mutex_destroy(&rsz->ops_lock);
>  	return ret;
>  }
>  
> -- 
> Regards,
> 
> Laurent Pinchart
> 



More information about the Linux-rockchip mailing list