@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
#include <linux/slab.h>
#include <media/media-entity.h>
@@ -648,7 +649,9 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
struct vsp1_pipeline *pipe;
unsigned long flags;
unsigned int i;
+ bool started;
int ret;
+ u32 v;
if (pipe_index >= vsp1->info->lif_count)
return -EINVAL;
@@ -757,11 +760,25 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
if (ret < 0)
return ret;
+ /* Clear VI6_DISP_IRQ_STA_DST flag */
+ v = vsp1_read(vsp1, VI6_DISP_IRQ_STA(pipe->output->entity.index));
+ vsp1_write(vsp1, VI6_DISP_IRQ_STA(pipe->output->entity.index),
+ ~v & VI6_DISP_IRQ_STA_DST);
+
/* Start the pipeline. */
spin_lock_irqsave(&pipe->irqlock, flags);
- vsp1_pipeline_run(pipe);
+ started = vsp1_pipeline_run(pipe);
spin_unlock_irqrestore(&pipe->irqlock, flags);
+ if (started) {
+ /* Wait for VI6_DISP_IRQ_STA_DST flag */
+ ret = readl_poll_timeout(vsp1->mmio + VI6_DISP_IRQ_STA(pipe->output->entity.index),
+ v, v & VI6_DISP_IRQ_STA_DST, 1, 100 * USEC_PER_MSEC);
+ if (ret)
+ dev_warn(vsp1->dev,
+ "Timeout waiting for VI6_DISP_IRQ_STA_DST\n");
+ }
+
dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
return 0;
@@ -302,17 +302,22 @@ void vsp1_pipeline_init(struct vsp1_pipeline *pipe)
}
/* Must be called with the pipe irqlock held. */
-void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
+bool vsp1_pipeline_run(struct vsp1_pipeline *pipe)
{
struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
+ bool started = false;
if (pipe->state == VSP1_PIPELINE_STOPPED) {
vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),
VI6_CMD_STRCMD);
pipe->state = VSP1_PIPELINE_RUNNING;
+
+ started = true;
}
pipe->buffers_ready = 0;
+
+ return started;
}
bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe)
@@ -155,7 +155,7 @@ struct vsp1_pipeline {
void vsp1_pipeline_reset(struct vsp1_pipeline *pipe);
void vsp1_pipeline_init(struct vsp1_pipeline *pipe);
-void vsp1_pipeline_run(struct vsp1_pipeline *pipe);
+bool vsp1_pipeline_run(struct vsp1_pipeline *pipe);
bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe);
int vsp1_pipeline_stop(struct vsp1_pipeline *pipe);
bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe);