diff options
Diffstat (limited to 'drivers/media/platform/vsp1/vsp1_drm.c')
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_drm.c | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index a918bb4ab46c..8c76086caa67 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -254,7 +254,26 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, EXPORT_SYMBOL_GPL(vsp1_du_setup_lif); /** - * vsp1_du_setup_rpf - Setup one RPF input of the VSP pipeline + * vsp1_du_atomic_begin - Prepare for an atomic update + * @dev: the VSP device + */ +void vsp1_du_atomic_begin(struct device *dev) +{ + struct vsp1_device *vsp1 = dev_get_drvdata(dev); + struct vsp1_pipeline *pipe = &vsp1->drm->pipe; + unsigned long flags; + + spin_lock_irqsave(&pipe->irqlock, flags); + + vsp1->drm->num_inputs = pipe->num_inputs; + vsp1->drm->update = false; + + spin_unlock_irqrestore(&pipe->irqlock, flags); +} +EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin); + +/** + * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline * @dev: the VSP device * @rpf_index: index of the RPF to setup (0-based) * @pixelformat: V4L2 pixel format for the RPF memory input @@ -288,10 +307,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_setup_lif); * * Return 0 on success or a negative error code on failure. */ -int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index, - u32 pixelformat, unsigned int pitch, - dma_addr_t mem[2], const struct v4l2_rect *src, - const struct v4l2_rect *dst) +int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index, + u32 pixelformat, unsigned int pitch, + dma_addr_t mem[2], const struct v4l2_rect *src, + const struct v4l2_rect *dst) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_pipeline *pipe = &vsp1->drm->pipe; @@ -301,7 +320,6 @@ int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index, struct vsp1_rwpf_memory memory; struct vsp1_rwpf *rpf; unsigned long flags; - bool start_stop = false; int ret; if (rpf_index >= vsp1->pdata.rpf_count) @@ -322,16 +340,11 @@ int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index, vsp1->bru->inputs[rpf_index].rpf = NULL; pipe->inputs[rpf_index] = NULL; - vsp1->drm->update = true; - start_stop = --pipe->num_inputs == 0; + pipe->num_inputs--; } spin_unlock_irqrestore(&pipe->irqlock, flags); - /* Stop the pipeline if we're the last user. */ - if (start_stop) - vsp1_pipeline_stop(pipe); - return 0; } @@ -459,19 +472,42 @@ int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index, if (!pipe->inputs[rpf->entity.index]) { vsp1->bru->inputs[rpf_index].rpf = rpf; pipe->inputs[rpf->entity.index] = rpf; - start_stop = pipe->num_inputs++ == 0; + pipe->num_inputs++; } - /* Start the pipeline if it's currently stopped. */ + spin_unlock_irqrestore(&pipe->irqlock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(vsp1_du_atomic_update); + +/** + * vsp1_du_atomic_flush - Commit an atomic update + * @dev: the VSP device + */ +void vsp1_du_atomic_flush(struct device *dev) +{ + struct vsp1_device *vsp1 = dev_get_drvdata(dev); + struct vsp1_pipeline *pipe = &vsp1->drm->pipe; + unsigned long flags; + bool stop = false; + + spin_lock_irqsave(&pipe->irqlock, flags); + vsp1->drm->update = true; - if (start_stop) + + /* Start or stop the pipeline if needed. */ + if (!vsp1->drm->num_inputs && pipe->num_inputs) vsp1_drm_pipeline_run(pipe); + else if (vsp1->drm->num_inputs && !pipe->num_inputs) + stop = true; spin_unlock_irqrestore(&pipe->irqlock, flags); - return 0; + if (stop) + vsp1_pipeline_stop(pipe); } -EXPORT_SYMBOL_GPL(vsp1_du_setup_rpf); +EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush); /* ----------------------------------------------------------------------------- * Initialization |