|
@@ -196,26 +196,16 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
struct channel_obj *ch = vb2_get_drv_priv(vq);
|
|
struct channel_obj *ch = vb2_get_drv_priv(vq);
|
|
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
|
|
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
|
|
struct vpif_params *vpif = &ch->vpifparams;
|
|
struct vpif_params *vpif = &ch->vpifparams;
|
|
- unsigned long addr = 0;
|
|
|
|
- unsigned long flags;
|
|
|
|
|
|
+ struct vpif_disp_buffer *buf, *tmp;
|
|
|
|
+ unsigned long addr, flags;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
spin_lock_irqsave(&common->irqlock, flags);
|
|
spin_lock_irqsave(&common->irqlock, flags);
|
|
|
|
|
|
- /* Get the next frame from the buffer queue */
|
|
|
|
- common->next_frm = common->cur_frm =
|
|
|
|
- list_entry(common->dma_queue.next,
|
|
|
|
- struct vpif_disp_buffer, list);
|
|
|
|
-
|
|
|
|
- list_del(&common->cur_frm->list);
|
|
|
|
- spin_unlock_irqrestore(&common->irqlock, flags);
|
|
|
|
- /* Mark state of the current frame to active */
|
|
|
|
- common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
|
|
|
|
-
|
|
|
|
/* Initialize field_id and started member */
|
|
/* Initialize field_id and started member */
|
|
ch->field_id = 0;
|
|
ch->field_id = 0;
|
|
common->started = 1;
|
|
common->started = 1;
|
|
- addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
|
|
|
|
|
|
+
|
|
/* Calculate the offset for Y and C data in the buffer */
|
|
/* Calculate the offset for Y and C data in the buffer */
|
|
vpif_calculate_offsets(ch);
|
|
vpif_calculate_offsets(ch);
|
|
|
|
|
|
@@ -225,7 +215,8 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
|| (!ch->vpifparams.std_info.frm_fmt
|
|
|| (!ch->vpifparams.std_info.frm_fmt
|
|
&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
|
|
&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
|
|
vpif_err("conflict in field format and std format\n");
|
|
vpif_err("conflict in field format and std format\n");
|
|
- return -EINVAL;
|
|
|
|
|
|
+ ret = -EINVAL;
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
|
|
|
|
/* clock settings */
|
|
/* clock settings */
|
|
@@ -234,17 +225,28 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
ycmux_mode, ch->vpifparams.std_info.hd_sd);
|
|
ycmux_mode, ch->vpifparams.std_info.hd_sd);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
vpif_err("can't set clock\n");
|
|
vpif_err("can't set clock\n");
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* set the parameters and addresses */
|
|
/* set the parameters and addresses */
|
|
ret = vpif_set_video_params(vpif, ch->channel_id + 2);
|
|
ret = vpif_set_video_params(vpif, ch->channel_id + 2);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
- return ret;
|
|
|
|
|
|
+ goto err;
|
|
|
|
|
|
common->started = ret;
|
|
common->started = ret;
|
|
vpif_config_addr(ch, ret);
|
|
vpif_config_addr(ch, ret);
|
|
|
|
+ /* Get the next frame from the buffer queue */
|
|
|
|
+ common->next_frm = common->cur_frm =
|
|
|
|
+ list_entry(common->dma_queue.next,
|
|
|
|
+ struct vpif_disp_buffer, list);
|
|
|
|
+
|
|
|
|
+ list_del(&common->cur_frm->list);
|
|
|
|
+ spin_unlock_irqrestore(&common->irqlock, flags);
|
|
|
|
+ /* Mark state of the current frame to active */
|
|
|
|
+ common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
|
|
|
|
+
|
|
|
|
+ addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
|
|
common->set_addr((addr + common->ytop_off),
|
|
common->set_addr((addr + common->ytop_off),
|
|
(addr + common->ybtm_off),
|
|
(addr + common->ybtm_off),
|
|
(addr + common->ctop_off),
|
|
(addr + common->ctop_off),
|
|
@@ -271,6 +273,14 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
+
|
|
|
|
+err:
|
|
|
|
+ list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
|
|
|
|
+ list_del(&buf->list);
|
|
|
|
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
/* abort streaming and wait for last buffer */
|
|
/* abort streaming and wait for last buffer */
|