Example #1
0
static int bru_set_selection(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_pad_config *cfg,
			     struct v4l2_subdev_selection *sel)
{
	struct vsp1_bru *bru = to_bru(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *compose;

	if (sel->pad == bru->entity.source_pad)
		return -EINVAL;

	if (sel->target != V4L2_SEL_TGT_COMPOSE)
		return -EINVAL;

	/* The compose rectangle top left corner must be inside the output
	 * frame.
	 */
	format = vsp1_entity_get_pad_format(&bru->entity, cfg,
					    bru->entity.source_pad, sel->which);
	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);

	/* Scaling isn't supported, the compose rectangle size must be identical
	 * to the sink format size.
	 */
	format = vsp1_entity_get_pad_format(&bru->entity, cfg, sel->pad,
					    sel->which);
	sel->r.width = format->width;
	sel->r.height = format->height;

	compose = bru_get_compose(bru, cfg, sel->pad, sel->which);
	*compose = sel->r;

	return 0;
}
Example #2
0
static int lut_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_lut *lut = to_lut(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	int ret = 0;

	mutex_lock(&lut->entity.lock);

	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
	if (!config) {
		ret = -EINVAL;
		goto done;
	}

	/* Default to YUV if the requested format is not supported. */
	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);

	if (fmt->pad == LUT_PAD_SOURCE) {
		/* The LUT output format can't be modified. */
		fmt->format = *format;
		goto done;
	}

	format->code = fmt->format.code;
	format->width = clamp_t(unsigned int, fmt->format.width,
				LUT_MIN_SIZE, LUT_MAX_SIZE);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 LUT_MIN_SIZE, LUT_MAX_SIZE);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&lut->entity, config,
					    LUT_PAD_SOURCE);
	*format = fmt->format;

done:
	mutex_unlock(&lut->entity.lock);
	return ret;
}
Example #3
0
int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
			 struct v4l2_subdev_format *fmt)
{
	struct vsp1_rwpf *rwpf = to_rwpf(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *crop;

	/* Default to YUV if the requested format is not supported. */
	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

	format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad,
					    fmt->which);

	if (fmt->pad == RWPF_PAD_SOURCE) {
		/* The RWPF performs format conversion but can't scale, only the
		 * format code can be changed on the source pad.
		 */
		format->code = fmt->format.code;
		fmt->format = *format;
		return 0;
	}

	format->code = fmt->format.code;
	format->width = clamp_t(unsigned int, fmt->format.width,
				RWPF_MIN_WIDTH, rwpf->max_width);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 RWPF_MIN_HEIGHT, rwpf->max_height);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Update the sink crop rectangle. */
	crop = vsp1_rwpf_get_crop(rwpf, cfg, fmt->which);
	crop->left = 0;
	crop->top = 0;
	crop->width = fmt->format.width;
	crop->height = fmt->format.height;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE,
					    fmt->which);
	*format = fmt->format;

	return 0;
}
Example #4
0
static int brx_set_selection(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_pad_config *cfg,
			     struct v4l2_subdev_selection *sel)
{
	struct vsp1_brx *brx = to_brx(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *compose;
	int ret = 0;

	if (sel->pad == brx->entity.source_pad)
		return -EINVAL;

	if (sel->target != V4L2_SEL_TGT_COMPOSE)
		return -EINVAL;

	mutex_lock(&brx->entity.lock);

	config = vsp1_entity_get_pad_config(&brx->entity, cfg, sel->which);
	if (!config) {
		ret = -EINVAL;
		goto done;
	}

	/*
	 * The compose rectangle top left corner must be inside the output
	 * frame.
	 */
	format = vsp1_entity_get_pad_format(&brx->entity, config,
					    brx->entity.source_pad);
	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);

	/*
	 * Scaling isn't supported, the compose rectangle size must be identical
	 * to the sink format size.
	 */
	format = vsp1_entity_get_pad_format(&brx->entity, config, sel->pad);
	sel->r.width = format->width;
	sel->r.height = format->height;

	compose = brx_get_compose(brx, config, sel->pad);
	*compose = sel->r;

done:
	mutex_unlock(&brx->entity.lock);
	return ret;
}
Example #5
0
static int brx_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_brx *brx = to_brx(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	int ret = 0;

	mutex_lock(&brx->entity.lock);

	config = vsp1_entity_get_pad_config(&brx->entity, cfg, fmt->which);
	if (!config) {
		ret = -EINVAL;
		goto done;
	}

	brx_try_format(brx, config, fmt->pad, &fmt->format);

	format = vsp1_entity_get_pad_format(&brx->entity, config, fmt->pad);
	*format = fmt->format;

	/* Reset the compose rectangle */
	if (fmt->pad != brx->entity.source_pad) {
		struct v4l2_rect *compose;

		compose = brx_get_compose(brx, config, fmt->pad);
		compose->left = 0;
		compose->top = 0;
		compose->width = format->width;
		compose->height = format->height;
	}

	/* Propagate the format code to all pads */
	if (fmt->pad == BRX_PAD_SINK(0)) {
		unsigned int i;

		for (i = 0; i <= brx->entity.source_pad; ++i) {
			format = vsp1_entity_get_pad_format(&brx->entity,
							    config, i);
			format->code = fmt->format.code;
		}
	}

done:
	mutex_unlock(&brx->entity.lock);
	return ret;
}
Example #6
0
int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
			    struct v4l2_subdev_fh *fh,
			    struct v4l2_subdev_selection *sel)
{
	struct vsp1_rwpf *rwpf = to_rwpf(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *crop;

	/* Cropping is implemented on the sink pad. */
	if (sel->pad != RWPF_PAD_SINK)
		return -EINVAL;

	if (sel->target != V4L2_SEL_TGT_CROP)
		return -EINVAL;

	/* Make sure the crop rectangle is entirely contained in the image. The
	 * WPF top and left offsets are limited to 255.
	 */
	format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SINK,
					    sel->which);
	sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2);
	sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2);
	if (rwpf->entity.type == VSP1_ENTITY_WPF) {
		sel->r.left = min_t(unsigned int, sel->r.left, 255);
		sel->r.top = min_t(unsigned int, sel->r.top, 255);
	}
Example #7
0
static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_pad_config *cfg,
			   unsigned int pad, struct v4l2_mbus_framefmt *fmt,
			   enum v4l2_subdev_format_whence which)
{
	struct v4l2_mbus_framefmt *format;
	unsigned int minimum;
	unsigned int maximum;

	switch (pad) {
	case UDS_PAD_SINK:
		/* Default to YUV if the requested format is not supported. */
		if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
		    fmt->code != MEDIA_BUS_FMT_AYUV8_1X32)
			fmt->code = MEDIA_BUS_FMT_AYUV8_1X32;

		fmt->width = clamp(fmt->width, UDS_MIN_SIZE, UDS_MAX_SIZE);
		fmt->height = clamp(fmt->height, UDS_MIN_SIZE, UDS_MAX_SIZE);
		break;

	case UDS_PAD_SOURCE:
		/* The UDS scales but can't perform format conversion. */
		format = vsp1_entity_get_pad_format(&uds->entity, cfg,
						    UDS_PAD_SINK, which);
		fmt->code = format->code;

		uds_output_limits(format->width, &minimum, &maximum);
		fmt->width = clamp(fmt->width, minimum, maximum);
		uds_output_limits(format->height, &minimum, &maximum);
		fmt->height = clamp(fmt->height, minimum, maximum);
		break;
	}

	fmt->field = V4L2_FIELD_NONE;
	fmt->colorspace = V4L2_COLORSPACE_SRGB;
}
Example #8
0
static int uds_enum_frame_size(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_frame_size_enum *fse)
{
	struct vsp1_uds *uds = to_uds(subdev);
	struct v4l2_mbus_framefmt *format;

	format = vsp1_entity_get_pad_format(&uds->entity, cfg,
					    UDS_PAD_SINK, fse->which);

	if (fse->index || fse->code != format->code)
		return -EINVAL;

	if (fse->pad == UDS_PAD_SINK) {
		fse->min_width = UDS_MIN_SIZE;
		fse->max_width = UDS_MAX_SIZE;
		fse->min_height = UDS_MIN_SIZE;
		fse->max_height = UDS_MAX_SIZE;
	} else {
		uds_output_limits(format->width, &fse->min_width,
				  &fse->max_width);
		uds_output_limits(format->height, &fse->min_height,
				  &fse->max_height);
	}

	return 0;
}
Example #9
0
static int histo_set_crop(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *config,
			 struct v4l2_subdev_selection *sel)
{
	struct vsp1_histogram *histo = subdev_to_histo(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *selection;

	/* The crop rectangle must be inside the input frame. */
	format = vsp1_entity_get_pad_format(&histo->entity, config,
					    HISTO_PAD_SINK);
	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
	sel->r.width = clamp_t(unsigned int, sel->r.width, HISTO_MIN_SIZE,
			       format->width - sel->r.left);
	sel->r.height = clamp_t(unsigned int, sel->r.height, HISTO_MIN_SIZE,
				format->height - sel->r.top);

	/* Set the crop rectangle and reset the compose rectangle. */
	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
						  sel->pad, V4L2_SEL_TGT_CROP);
	*selection = sel->r;

	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
						  sel->pad,
						  V4L2_SEL_TGT_COMPOSE);
	*selection = sel->r;

	return 0;
}
Example #10
0
int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
			    struct v4l2_subdev_pad_config *cfg,
			    struct v4l2_subdev_selection *sel)
{
	struct vsp1_rwpf *rwpf = to_rwpf(subdev);
	struct v4l2_mbus_framefmt *format;

	/* Cropping is implemented on the sink pad. */
	if (sel->pad != RWPF_PAD_SINK)
		return -EINVAL;

	switch (sel->target) {
	case V4L2_SEL_TGT_CROP:
		sel->r = *vsp1_rwpf_get_crop(rwpf, cfg, sel->which);
		break;

	case V4L2_SEL_TGT_CROP_BOUNDS:
		format = vsp1_entity_get_pad_format(&rwpf->entity, cfg,
						    RWPF_PAD_SINK, sel->which);
		sel->r.left = 0;
		sel->r.top = 0;
		sel->r.width = format->width;
		sel->r.height = format->height;
		break;

	default:
		return -EINVAL;
	}

	return 0;
}
Example #11
0
static void lif_configure(struct vsp1_entity *entity,
			  struct vsp1_pipeline *pipe,
			  struct vsp1_dl_list *dl, bool full)
{
	const struct v4l2_mbus_framefmt *format;
	struct vsp1_lif *lif = to_lif(&entity->subdev);
	unsigned int hbth = 1300;
	unsigned int obth = 400;
	unsigned int lbth = 200;

	if (!full)
		return;

	format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
					    LIF_PAD_SOURCE);

	obth = min(obth, (format->width + 1) / 2 * format->height - 4);

	vsp1_lif_write(lif, dl, VI6_LIF_CSBTH,
			(hbth << VI6_LIF_CSBTH_HBTH_SHIFT) |
			(lbth << VI6_LIF_CSBTH_LBTH_SHIFT));

	vsp1_lif_write(lif, dl, VI6_LIF_CTRL,
			(obth << VI6_LIF_CTRL_OBTH_SHIFT) |
			(format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
			VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
}
Example #12
0
int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
			      struct v4l2_subdev_pad_config *cfg,
			      struct v4l2_subdev_frame_size_enum *fse)
{
	struct vsp1_rwpf *rwpf = to_rwpf(subdev);
	struct v4l2_mbus_framefmt *format;

	format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fse->pad,
					    fse->which);

	if (fse->index || fse->code != format->code)
		return -EINVAL;

	if (fse->pad == RWPF_PAD_SINK) {
		fse->min_width = RWPF_MIN_WIDTH;
		fse->max_width = rwpf->max_width;
		fse->min_height = RWPF_MIN_HEIGHT;
		fse->max_height = rwpf->max_height;
	} else {
		/* The size on the source pad are fixed and always identical to
		 * the size on the sink pad.
		 */
		fse->min_width = format->width;
		fse->max_width = format->width;
		fse->min_height = format->height;
		fse->max_height = format->height;
	}

	return 0;
}
Example #13
0
static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
			      struct v4l2_subdev_pad_config *cfg,
			      struct v4l2_subdev_mbus_code_enum *code)
{
	static const unsigned int codes[] = {
		MEDIA_BUS_FMT_ARGB8888_1X32,
		MEDIA_BUS_FMT_AHSV8888_1X32,
		MEDIA_BUS_FMT_AYUV8_1X32,
	};
	struct vsp1_lut *lut = to_lut(subdev);
	struct v4l2_mbus_framefmt *format;

	if (code->pad == LUT_PAD_SINK) {
		if (code->index >= ARRAY_SIZE(codes))
			return -EINVAL;

		code->code = codes[code->index];
	} else {
		/* The LUT can't perform format conversion, the sink format is
		 * always identical to the source format.
		 */
		if (code->index)
			return -EINVAL;

		format = vsp1_entity_get_pad_format(&lut->entity, cfg,
						    LUT_PAD_SINK, code->which);
		code->code = format->code;
	}

	return 0;
}
Example #14
0
static int lut_enum_frame_size(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_frame_size_enum *fse)
{
	struct vsp1_lut *lut = to_lut(subdev);
	struct v4l2_mbus_framefmt *format;

	format = vsp1_entity_get_pad_format(&lut->entity, cfg,
					    fse->pad, fse->which);

	if (fse->index || fse->code != format->code)
		return -EINVAL;

	if (fse->pad == LUT_PAD_SINK) {
		fse->min_width = LUT_MIN_SIZE;
		fse->max_width = LUT_MAX_SIZE;
		fse->min_height = LUT_MIN_SIZE;
		fse->max_height = LUT_MAX_SIZE;
	} else {
		/* The size on the source pad are fixed and always identical to
		 * the size on the sink pad.
		 */
		fse->min_width = format->width;
		fse->max_width = format->width;
		fse->min_height = format->height;
		fse->max_height = format->height;
	}

	return 0;
}
Example #15
0
static int bru_enum_mbus_code(struct v4l2_subdev *subdev,
			      struct v4l2_subdev_pad_config *cfg,
			      struct v4l2_subdev_mbus_code_enum *code)
{
	static const unsigned int codes[] = {
		MEDIA_BUS_FMT_ARGB8888_1X32,
		MEDIA_BUS_FMT_AYUV8_1X32,
	};
	struct vsp1_bru *bru = to_bru(subdev);
	struct v4l2_mbus_framefmt *format;

	if (code->pad == BRU_PAD_SINK(0)) {
		if (code->index >= ARRAY_SIZE(codes))
			return -EINVAL;

		code->code = codes[code->index];
	} else {
		if (code->index)
			return -EINVAL;

		format = vsp1_entity_get_pad_format(&bru->entity, cfg,
						    BRU_PAD_SINK(0), code->which);
		code->code = format->code;
	}

	return 0;
}
Example #16
0
static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_pad_config *cfg,
			   unsigned int pad, struct v4l2_mbus_framefmt *fmt,
			   enum v4l2_subdev_format_whence which)
{
	struct v4l2_mbus_framefmt *format;

	switch (pad) {
	case BRU_PAD_SINK(0):
		/* Default to YUV if the requested format is not supported. */
		if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
		    fmt->code != MEDIA_BUS_FMT_AYUV8_1X32)
			fmt->code = MEDIA_BUS_FMT_AYUV8_1X32;
		break;

	default:
		/* The BRU can't perform format conversion. */
		format = vsp1_entity_get_pad_format(&bru->entity, cfg,
						    BRU_PAD_SINK(0), which);
		fmt->code = format->code;
		break;
	}

	fmt->width = clamp(fmt->width, BRU_MIN_SIZE, BRU_MAX_SIZE);
	fmt->height = clamp(fmt->height, BRU_MIN_SIZE, BRU_MAX_SIZE);
	fmt->field = V4L2_FIELD_NONE;
	fmt->colorspace = V4L2_COLORSPACE_SRGB;
}
Example #17
0
static int histo_get_selection(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_selection *sel)
{
	struct vsp1_histogram *histo = subdev_to_histo(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *crop;
	int ret = 0;

	if (sel->pad != HISTO_PAD_SINK)
		return -EINVAL;

	mutex_lock(&histo->entity.lock);

	config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which);
	if (!config) {
		ret = -EINVAL;
		goto done;
	}

	switch (sel->target) {
	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
		crop = vsp1_entity_get_pad_selection(&histo->entity, config,
						     HISTO_PAD_SINK,
						     V4L2_SEL_TGT_CROP);
		sel->r.left = 0;
		sel->r.top = 0;
		sel->r.width = crop->width;
		sel->r.height = crop->height;
		break;

	case V4L2_SEL_TGT_CROP_BOUNDS:
	case V4L2_SEL_TGT_CROP_DEFAULT:
		format = vsp1_entity_get_pad_format(&histo->entity, config,
						    HISTO_PAD_SINK);
		sel->r.left = 0;
		sel->r.top = 0;
		sel->r.width = format->width;
		sel->r.height = format->height;
		break;

	case V4L2_SEL_TGT_COMPOSE:
	case V4L2_SEL_TGT_CROP:
		sel->r = *vsp1_entity_get_pad_selection(&histo->entity, config,
							sel->pad, sel->target);
		break;

	default:
		ret = -EINVAL;
		break;
	}

done:
	mutex_unlock(&histo->entity.lock);
	return ret;
}
Example #18
0
static void lif_configure_stream(struct vsp1_entity *entity,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_body *dlb)
{
	const struct v4l2_mbus_framefmt *format;
	struct vsp1_lif *lif = to_lif(&entity->subdev);
	unsigned int hbth;
	unsigned int obth;
	unsigned int lbth;

	format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
					    LIF_PAD_SOURCE);

	switch (entity->vsp1->version & VI6_IP_VERSION_SOC_MASK) {
	case VI6_IP_VERSION_MODEL_VSPD_GEN2:
	case VI6_IP_VERSION_MODEL_VSPD_V2H:
		hbth = 1536;
		obth = min(128U, (format->width + 1) / 2 * format->height - 4);
		lbth = 1520;
		break;

	case VI6_IP_VERSION_MODEL_VSPDL_GEN3:
	case VI6_IP_VERSION_MODEL_VSPD_V3:
		hbth = 0;
		obth = 1500;
		lbth = 0;
		break;

	case VI6_IP_VERSION_MODEL_VSPD_GEN3:
	default:
		hbth = 0;
		obth = 3000;
		lbth = 0;
		break;
	}

	vsp1_lif_write(lif, dlb, VI6_LIF_CSBTH,
			(hbth << VI6_LIF_CSBTH_HBTH_SHIFT) |
			(lbth << VI6_LIF_CSBTH_LBTH_SHIFT));

	vsp1_lif_write(lif, dlb, VI6_LIF_CTRL,
			(obth << VI6_LIF_CTRL_OBTH_SHIFT) |
			(format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
			VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);

	/*
	 * On R-Car V3M the LIF0 buffer attribute register has to be set to a
	 * non-default value to guarantee proper operation (otherwise artifacts
	 * may appear on the output). The value required by the manual is not
	 * explained but is likely a buffer size or threshold.
	 */
	if ((entity->vsp1->version & VI6_IP_VERSION_MASK) ==
	    (VI6_IP_VERSION_MODEL_VSPD_V3 | VI6_IP_VERSION_SOC_V3M))
		vsp1_lif_write(lif, dlb, VI6_LIF_LBA,
			       VI6_LIF_LBA_LBA0 |
			       (1536 << VI6_LIF_LBA_LBA1_SHIFT));
}
Example #19
0
static int lif_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_lif *lif = to_lif(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	/* Default to YUV if the requested format is not supported. */
	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);

	if (fmt->pad == LIF_PAD_SOURCE) {
		/* The LIF source format is always identical to its sink
		 * format.
		 */
		fmt->format = *format;
		return 0;
	}

	format->code = fmt->format.code;
	format->width = clamp_t(unsigned int, fmt->format.width,
				LIF_MIN_SIZE, LIF_MAX_SIZE);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 LIF_MIN_SIZE, LIF_MAX_SIZE);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&lif->entity, config,
					    LIF_PAD_SOURCE);
	*format = fmt->format;

	return 0;
}
Example #20
0
static int clu_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_clu *clu = to_clu(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	/* Default to YUV if the requested format is not supported. */
	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);

	if (fmt->pad == CLU_PAD_SOURCE) {
		/* The CLU output format can't be modified. */
		fmt->format = *format;
		return 0;
	}

	format->code = fmt->format.code;
	format->width = clamp_t(unsigned int, fmt->format.width,
				CLU_MIN_SIZE, CLU_MAX_SIZE);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 CLU_MIN_SIZE, CLU_MAX_SIZE);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&clu->entity, config,
					    CLU_PAD_SOURCE);
	*format = fmt->format;

	return 0;
}
Example #21
0
int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
			 struct v4l2_subdev_format *fmt)
{
	struct vsp1_rwpf *rwpf = to_rwpf(subdev);

	fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad,
						  fmt->which);

	return 0;
}
Example #22
0
static int lut_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
                          struct v4l2_subdev_format *fmt)
{
    struct vsp1_lut *lut = to_lut(subdev);

    fmt->format = *vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad,
                  fmt->which);

    return 0;
}
Example #23
0
static int uds_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_uds *uds = to_uds(subdev);

	fmt->format = *vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad,
						  fmt->which);

	return 0;
}
Example #24
0
static int bru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_bru *bru = to_bru(subdev);

	fmt->format = *vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
						  fmt->which);

	return 0;
}
Example #25
0
static int hsit_set_format(struct v4l2_subdev *subdev,
			   struct v4l2_subdev_pad_config *cfg,
			   struct v4l2_subdev_format *fmt)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad);

	if (fmt->pad == HSIT_PAD_SOURCE) {
		/* The HST and HSI output format code and resolution can't be
		 * modified.
		 */
		fmt->format = *format;
		return 0;
	}

	format->code = hsit->inverse ? MEDIA_BUS_FMT_AHSV8888_1X32
		     : MEDIA_BUS_FMT_ARGB8888_1X32;
	format->width = clamp_t(unsigned int, fmt->format.width,
				HSIT_MIN_SIZE, HSIT_MAX_SIZE);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 HSIT_MIN_SIZE, HSIT_MAX_SIZE);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&hsit->entity, config,
					    HSIT_PAD_SOURCE);
	*format = fmt->format;
	format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32
		     : MEDIA_BUS_FMT_AHSV8888_1X32;

	return 0;
}
Example #26
0
static int hsit_get_format(struct v4l2_subdev *subdev,
			   struct v4l2_subdev_fh *fh,
			   struct v4l2_subdev_format *fmt)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);

	fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad,
						  fmt->which);

	return 0;
}
Example #27
0
static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_uds *uds = to_uds(subdev);
	struct v4l2_mbus_framefmt *format;

	uds_try_format(uds, cfg, fmt->pad, &fmt->format, fmt->which);

	format = vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad,
					    fmt->which);
	*format = fmt->format;

	if (fmt->pad == UDS_PAD_SINK) {
		/* Propagate the format to the source pad. */
		format = vsp1_entity_get_pad_format(&uds->entity, cfg,
						    UDS_PAD_SOURCE, fmt->which);
		*format = fmt->format;

		uds_try_format(uds, cfg, UDS_PAD_SOURCE, format, fmt->which);
	}

	return 0;
}
Example #28
0
static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_bru *bru = to_bru(subdev);
	struct v4l2_mbus_framefmt *format;

	bru_try_format(bru, cfg, fmt->pad, &fmt->format, fmt->which);

	format = vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
					    fmt->which);
	*format = fmt->format;

	/* Reset the compose rectangle */
	if (fmt->pad != bru->entity.source_pad) {
		struct v4l2_rect *compose;

		compose = bru_get_compose(bru, cfg, fmt->pad, fmt->which);
		compose->left = 0;
		compose->top = 0;
		compose->width = format->width;
		compose->height = format->height;
	}

	/* Propagate the format code to all pads */
	if (fmt->pad == BRU_PAD_SINK(0)) {
		unsigned int i;

		for (i = 0; i <= bru->entity.source_pad; ++i) {
			format = vsp1_entity_get_pad_format(&bru->entity, cfg,
							    i, fmt->which);
			format->code = fmt->format.code;
		}
	}

	return 0;
}
Example #29
0
static void clu_configure(struct vsp1_entity *entity,
			  struct vsp1_pipeline *pipe,
			  struct vsp1_dl_list *dl, bool full)
{
	struct vsp1_clu *clu = to_clu(&entity->subdev);
	struct vsp1_dl_body *dlb;
	unsigned long flags;
	u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN;

	/* The format can't be changed during streaming, only verify it at
	 * stream start and store the information internally for future partial
	 * reconfiguration calls.
	 */
	if (full) {
		struct v4l2_mbus_framefmt *format;

		format = vsp1_entity_get_pad_format(&clu->entity,
						    clu->entity.config,
						    CLU_PAD_SINK);
		clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32;
		return;
	}

	/* 2D mode can only be used with the YCbCr pixel encoding. */
	if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode)
		ctrl |= VI6_CLU_CTRL_AX1I_2D | VI6_CLU_CTRL_AX2I_2D
		     |  VI6_CLU_CTRL_OS0_2D | VI6_CLU_CTRL_OS1_2D
		     |  VI6_CLU_CTRL_OS2_2D | VI6_CLU_CTRL_M2D;

	vsp1_clu_write(clu, dl, VI6_CLU_CTRL, ctrl);

	spin_lock_irqsave(&clu->lock, flags);
	dlb = clu->clu;
	clu->clu = NULL;
	spin_unlock_irqrestore(&clu->lock, flags);

	if (dlb)
		vsp1_dl_list_add_fragment(dl, dlb);
}
Example #30
0
int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
			    struct v4l2_subdev_pad_config *cfg,
			    struct v4l2_subdev_selection *sel)
{
	struct vsp1_rwpf *rwpf = to_rwpf(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *crop;

	/* Cropping is implemented on the sink pad. */
	if (sel->pad != RWPF_PAD_SINK)
		return -EINVAL;

	if (sel->target != V4L2_SEL_TGT_CROP)
		return -EINVAL;

	/* Make sure the crop rectangle is entirely contained in the image. The
	 * WPF top and left offsets are limited to 255.
	 */
	format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SINK,
					    sel->which);

	/* Restrict the crop rectangle coordinates to multiples of 2 to avoid
	 * shifting the color plane.
	 */
	if (format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
		sel->r.left = ALIGN(sel->r.left, 2);
		sel->r.top = ALIGN(sel->r.top, 2);
		sel->r.width = round_down(sel->r.width, 2);
		sel->r.height = round_down(sel->r.height, 2);
	}

	sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2);
	sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2);
	if (rwpf->entity.type == VSP1_ENTITY_WPF) {
		sel->r.left = min_t(unsigned int, sel->r.left, 255);
		sel->r.top = min_t(unsigned int, sel->r.top, 255);
	}