Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc845e52 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 1fd87bf2
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -269,13 +269,16 @@ static const struct v4l2_subdev_ops bru_ops = {

static void bru_configure(struct vsp1_entity *entity,
			  struct vsp1_pipeline *pipe,
			  struct vsp1_dl_list *dl)
			  struct vsp1_dl_list *dl, bool full)
{
	struct vsp1_bru *bru = to_bru(&entity->subdev);
	struct v4l2_mbus_framefmt *format;
	unsigned int flags;
	unsigned int i;

	if (!full)
		return;

	format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config,
					    bru->entity.source_pad);

+4 −1
Original line number Diff line number Diff line
@@ -205,12 +205,15 @@ static const struct v4l2_subdev_ops clu_ops = {

static void clu_configure(struct vsp1_entity *entity,
			  struct vsp1_pipeline *pipe,
			  struct vsp1_dl_list *dl)
			  struct vsp1_dl_list *dl, bool full)
{
	struct vsp1_clu *clu = to_clu(&entity->subdev);
	struct v4l2_mbus_framefmt *format;
	u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN;

	if (!full)
		return;

	format = vsp1_entity_get_pad_format(&clu->entity, clu->entity.config,
					    CLU_PAD_SINK);

+4 −2
Original line number Diff line number Diff line
@@ -491,8 +491,10 @@ void vsp1_du_atomic_flush(struct device *dev)

		vsp1_entity_route_setup(entity, pipe->dl);

		if (entity->ops->configure)
			entity->ops->configure(entity, pipe, pipe->dl);
		if (entity->ops->configure) {
			entity->ops->configure(entity, pipe, pipe->dl, true);
			entity->ops->configure(entity, pipe, pipe->dl, false);
		}

		/* The memory buffer address must be applied after configuring
		 * the RPF to make sure the crop offset are computed.
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ struct vsp1_entity_operations {
	void (*destroy)(struct vsp1_entity *);
	void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl);
	void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *,
			  struct vsp1_dl_list *);
			  struct vsp1_dl_list *, bool);
};

struct vsp1_entity {
+4 −1
Original line number Diff line number Diff line
@@ -125,10 +125,13 @@ static const struct v4l2_subdev_ops hsit_ops = {

static void hsit_configure(struct vsp1_entity *entity,
			   struct vsp1_pipeline *pipe,
			   struct vsp1_dl_list *dl)
			   struct vsp1_dl_list *dl, bool full)
{
	struct vsp1_hsit *hsit = to_hsit(&entity->subdev);

	if (!full)
		return;

	if (hsit->inverse)
		vsp1_hsit_write(hsit, dl, VI6_HSI_CTRL, VI6_HSI_CTRL_EN);
	else
Loading