summaryrefslogtreecommitdiff
path: root/drivers/media/platform/vsp1
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2016-06-11 07:07:56 (GMT)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-06-28 15:23:43 (GMT)
commitfc845e520baf00af12f6c39708c5e9e9a6eec661 (patch)
tree1df2b8feedada74f30a307f951b451d3c8eb351b /drivers/media/platform/vsp1
parent1fd87bf2f3a76200fe2b57f5b744b1b341cd7690 (diff)
downloadlinux-fc845e520baf00af12f6c39708c5e9e9a6eec661.tar.xz
[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: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/platform/vsp1')
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_clu.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.c6
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c8
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c5
12 files changed, 48 insertions, 13 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index cae9117..8268b87 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -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);
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
index cea86e7..dd0cf20 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -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);
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 1473011..fe9665e 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -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.
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index f289ed2..b43457f 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -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 {
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index ab3cae3..6e5077b 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -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
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index e006f0d..a720063 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -122,7 +122,7 @@ static const struct v4l2_subdev_ops lif_ops = {
static void lif_configure(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl)
+ struct vsp1_dl_list *dl, bool full)
{
const struct v4l2_mbus_framefmt *format;
struct vsp1_lif *lif = to_lif(&entity->subdev);
@@ -130,6 +130,9 @@ static void lif_configure(struct vsp1_entity *entity,
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);
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index db8f01d..9619b9a 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -181,10 +181,13 @@ static const struct v4l2_subdev_ops lut_ops = {
static void lut_configure(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl)
+ struct vsp1_dl_list *dl, bool full)
{
struct vsp1_lut *lut = to_lut(&entity->subdev);
+ if (!full)
+ return;
+
vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN);
mutex_lock(lut->ctrls.lock);
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 47b1714..390040a 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -60,7 +60,7 @@ static void rpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
static void rpf_configure(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl)
+ struct vsp1_dl_list *dl, bool full)
{
struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
@@ -73,6 +73,9 @@ static void rpf_configure(struct vsp1_entity *entity,
u32 pstride;
u32 infmt;
+ if (!full)
+ return;
+
/* Source size, stride and crop offsets.
*
* The crop offsets correspond to the location of the crop rectangle top
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index e13afd5..47f5e0c 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -257,7 +257,7 @@ static const struct v4l2_subdev_ops sru_ops = {
static void sru_configure(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl)
+ struct vsp1_dl_list *dl, bool full)
{
const struct vsp1_sru_param *param;
struct vsp1_sru *sru = to_sru(&entity->subdev);
@@ -265,6 +265,9 @@ static void sru_configure(struct vsp1_entity *entity,
struct v4l2_mbus_framefmt *output;
u32 ctrl0;
+ if (!full)
+ return;
+
input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
SRU_PAD_SINK);
output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index f229451..5d5720f 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -244,7 +244,7 @@ static const struct v4l2_subdev_ops uds_ops = {
static void uds_configure(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl)
+ struct vsp1_dl_list *dl, bool full)
{
struct vsp1_uds *uds = to_uds(&entity->subdev);
const struct v4l2_mbus_framefmt *output;
@@ -253,6 +253,9 @@ static void uds_configure(struct vsp1_entity *entity,
unsigned int vscale;
bool multitap;
+ if (!full)
+ return;
+
input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
UDS_PAD_SINK);
output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index f6208b9..0165423 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -251,11 +251,17 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe)
{
struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
+ struct vsp1_entity *entity;
unsigned int i;
if (!pipe->dl)
pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
+ list_for_each_entry(entity, &pipe->entities, list_pipe) {
+ if (entity->ops->configure)
+ entity->ops->configure(entity, pipe, pipe->dl, false);
+ }
+
for (i = 0; i < vsp1->info->rpf_count; ++i) {
struct vsp1_rwpf *rwpf = pipe->inputs[i];
@@ -632,7 +638,7 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
vsp1_entity_route_setup(entity, pipe->dl);
if (entity->ops->configure)
- entity->ops->configure(entity, pipe, pipe->dl);
+ entity->ops->configure(entity, pipe, pipe->dl, true);
}
return 0;
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 70fb979..474feac 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -93,7 +93,7 @@ static void wpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
static void wpf_configure(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl)
+ struct vsp1_dl_list *dl, bool full)
{
struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
struct vsp1_device *vsp1 = wpf->entity.vsp1;
@@ -104,6 +104,9 @@ static void wpf_configure(struct vsp1_entity *entity,
u32 outfmt = 0;
u32 srcrpf = 0;
+ if (!full)
+ return;
+
/* Cropping */
crop = vsp1_rwpf_get_crop(wpf, wpf->entity.config);