[2/4] media i.MX27 camera: add start_stream and stop_stream callbacks.

Message ID 1327059392-29240-3-git-send-email-javier.martin@vista-silicon.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Javier Martin Jan. 20, 2012, 11:36 a.m. UTC
  Add "start_stream" and "stop_stream" callback in order to enable
and disable the eMMa-PrP properly and save CPU usage avoiding
IRQs when the device is not streaming.

Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
 drivers/media/video/mx2_camera.c |  107 +++++++++++++++++++++++++++-----------
 1 files changed, 77 insertions(+), 30 deletions(-)
  

Comments

Guennadi Liakhovetski Jan. 25, 2012, 10:26 a.m. UTC | #1
As discussed before, please, merge this patch with

"media i.MX27 camera: properly detect frame loss."

One more cosmetic note:

On Fri, 20 Jan 2012, Javier Martin wrote:

> Add "start_stream" and "stop_stream" callback in order to enable
> and disable the eMMa-PrP properly and save CPU usage avoiding
> IRQs when the device is not streaming.
> 
> Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
> ---
>  drivers/media/video/mx2_camera.c |  107 +++++++++++++++++++++++++++-----------
>  1 files changed, 77 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
> index 290ac9d..4816da6 100644
> --- a/drivers/media/video/mx2_camera.c
> +++ b/drivers/media/video/mx2_camera.c
> @@ -560,7 +560,6 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
>  	struct soc_camera_host *ici =
>  		to_soc_camera_host(icd->parent);
>  	struct mx2_camera_dev *pcdev = ici->priv;
> -	struct mx2_fmt_cfg *prp = pcdev->emma_prp;
>  	struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
>  	unsigned long flags;
>  
> @@ -572,29 +571,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
>  	buf->state = MX2_STATE_QUEUED;
>  	list_add_tail(&buf->queue, &pcdev->capture);
>  
> -	if (mx27_camera_emma(pcdev)) {
> -		if (prp->cfg.channel == 1) {
> -			writel(PRP_CNTL_CH1EN |
> -				PRP_CNTL_CSIEN |
> -				prp->cfg.in_fmt |
> -				prp->cfg.out_fmt |
> -				PRP_CNTL_CH1_LEN |
> -				PRP_CNTL_CH1BYP |
> -				PRP_CNTL_CH1_TSKIP(0) |
> -				PRP_CNTL_IN_TSKIP(0),
> -				pcdev->base_emma + PRP_CNTL);
> -		} else {
> -			writel(PRP_CNTL_CH2EN |
> -				PRP_CNTL_CSIEN |
> -				prp->cfg.in_fmt |
> -				prp->cfg.out_fmt |
> -				PRP_CNTL_CH2_LEN |
> -				PRP_CNTL_CH2_TSKIP(0) |
> -				PRP_CNTL_IN_TSKIP(0),
> -				pcdev->base_emma + PRP_CNTL);
> -		}
> -		goto out;
> -	} else { /* cpu_is_mx25() */
> +	if (!mx27_camera_emma(pcdev)) { /* cpu_is_mx25() */
>  		u32 csicr3, dma_inten = 0;
>  
>  		if (pcdev->fb1_active == NULL) {
> @@ -629,8 +606,6 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
>  			writel(csicr3, pcdev->base_csi + CSICR3);
>  		}
>  	}
> -
> -out:

To my taste you're a bit too aggressive on blank lines;-) This also holds 
for the previous patch. Unless you absolutely have to edit your sources in 
a 24-line terminal, keeping those empty lines would be appreciated:-)

Thanks
Guennadi

>  	spin_unlock_irqrestore(&pcdev->lock, flags);
>  }
>  
> @@ -692,11 +667,83 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
>  	spin_unlock_irqrestore(&pcdev->lock, flags);
>  }
>  
> +static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> +	struct soc_camera_device *icd = soc_camera_from_vb2q(q);
> +	struct soc_camera_host *ici =
> +		to_soc_camera_host(icd->parent);
> +	struct mx2_camera_dev *pcdev = ici->priv;
> +	struct mx2_fmt_cfg *prp = pcdev->emma_prp;
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(&pcdev->lock, flags);
> +	if (mx27_camera_emma(pcdev)) {
> +		if (count < 2) {
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +
> +		if (prp->cfg.channel == 1) {
> +			writel(PRP_CNTL_CH1EN |
> +				PRP_CNTL_CSIEN |
> +				prp->cfg.in_fmt |
> +				prp->cfg.out_fmt |
> +				PRP_CNTL_CH1_LEN |
> +				PRP_CNTL_CH1BYP |
> +				PRP_CNTL_CH1_TSKIP(0) |
> +				PRP_CNTL_IN_TSKIP(0),
> +				pcdev->base_emma + PRP_CNTL);
> +		} else {
> +			writel(PRP_CNTL_CH2EN |
> +				PRP_CNTL_CSIEN |
> +				prp->cfg.in_fmt |
> +				prp->cfg.out_fmt |
> +				PRP_CNTL_CH2_LEN |
> +				PRP_CNTL_CH2_TSKIP(0) |
> +				PRP_CNTL_IN_TSKIP(0),
> +				pcdev->base_emma + PRP_CNTL);
> +		}
> +	}
> +err:
> +	spin_unlock_irqrestore(&pcdev->lock, flags);
> +
> +	return ret;
> +}
> +
> +static int mx2_stop_streaming(struct vb2_queue *q)
> +{
> +	struct soc_camera_device *icd = soc_camera_from_vb2q(q);
> +	struct soc_camera_host *ici =
> +		to_soc_camera_host(icd->parent);
> +	struct mx2_camera_dev *pcdev = ici->priv;
> +	struct mx2_fmt_cfg *prp = pcdev->emma_prp;
> +	unsigned long flags;
> +	u32 cntl;
> +
> +	spin_lock_irqsave(&pcdev->lock, flags);
> +	if (mx27_camera_emma(pcdev)) {
> +		cntl = readl(pcdev->base_emma + PRP_CNTL);
> +		if (prp->cfg.channel == 1) {
> +			writel(cntl & ~PRP_CNTL_CH1EN,
> +			       pcdev->base_emma + PRP_CNTL);
> +		} else {
> +			writel(cntl & ~PRP_CNTL_CH2EN,
> +			       pcdev->base_emma + PRP_CNTL);
> +		}
> +	}
> +	spin_unlock_irqrestore(&pcdev->lock, flags);
> +
> +	return 0;
> +}
> +
>  static struct vb2_ops mx2_videobuf_ops = {
> -	.queue_setup	= mx2_videobuf_setup,
> -	.buf_prepare	= mx2_videobuf_prepare,
> -	.buf_queue	= mx2_videobuf_queue,
> -	.buf_cleanup	= mx2_videobuf_release,
> +	.queue_setup	 = mx2_videobuf_setup,
> +	.buf_prepare	 = mx2_videobuf_prepare,
> +	.buf_queue	 = mx2_videobuf_queue,
> +	.buf_cleanup	 = mx2_videobuf_release,
> +	.start_streaming = mx2_start_streaming,
> +	.stop_streaming  = mx2_stop_streaming,
>  };
>  
>  static int mx2_camera_init_videobuf(struct vb2_queue *q,
> -- 
> 1.7.0.4
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
Javier Martin Jan. 25, 2012, 3:51 p.m. UTC | #2
Hi Guennadi,

On 25 January 2012 11:26, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote:
> As discussed before, please, merge this patch with
>
> "media i.MX27 camera: properly detect frame loss."

Yes. You can drop that patch already.

> One more cosmetic note:
>
> On Fri, 20 Jan 2012, Javier Martin wrote:
>
>> Add "start_stream" and "stop_stream" callback in order to enable
>> and disable the eMMa-PrP properly and save CPU usage avoiding
>> IRQs when the device is not streaming.
>>
>> Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
>> ---
>>  drivers/media/video/mx2_camera.c |  107 +++++++++++++++++++++++++++-----------
>>  1 files changed, 77 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
>> index 290ac9d..4816da6 100644
>> --- a/drivers/media/video/mx2_camera.c
>> +++ b/drivers/media/video/mx2_camera.c
>> @@ -560,7 +560,6 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
>>       struct soc_camera_host *ici =
>>               to_soc_camera_host(icd->parent);
>>       struct mx2_camera_dev *pcdev = ici->priv;
>> -     struct mx2_fmt_cfg *prp = pcdev->emma_prp;
>>       struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
>>       unsigned long flags;
>>
>> @@ -572,29 +571,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
>>       buf->state = MX2_STATE_QUEUED;
>>       list_add_tail(&buf->queue, &pcdev->capture);
>>
>> -     if (mx27_camera_emma(pcdev)) {
>> -             if (prp->cfg.channel == 1) {
>> -                     writel(PRP_CNTL_CH1EN |
>> -                             PRP_CNTL_CSIEN |
>> -                             prp->cfg.in_fmt |
>> -                             prp->cfg.out_fmt |
>> -                             PRP_CNTL_CH1_LEN |
>> -                             PRP_CNTL_CH1BYP |
>> -                             PRP_CNTL_CH1_TSKIP(0) |
>> -                             PRP_CNTL_IN_TSKIP(0),
>> -                             pcdev->base_emma + PRP_CNTL);
>> -             } else {
>> -                     writel(PRP_CNTL_CH2EN |
>> -                             PRP_CNTL_CSIEN |
>> -                             prp->cfg.in_fmt |
>> -                             prp->cfg.out_fmt |
>> -                             PRP_CNTL_CH2_LEN |
>> -                             PRP_CNTL_CH2_TSKIP(0) |
>> -                             PRP_CNTL_IN_TSKIP(0),
>> -                             pcdev->base_emma + PRP_CNTL);
>> -             }
>> -             goto out;
>> -     } else { /* cpu_is_mx25() */
>> +     if (!mx27_camera_emma(pcdev)) { /* cpu_is_mx25() */
>>               u32 csicr3, dma_inten = 0;
>>
>>               if (pcdev->fb1_active == NULL) {
>> @@ -629,8 +606,6 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
>>                       writel(csicr3, pcdev->base_csi + CSICR3);
>>               }
>>       }
>> -
>> -out:
>
> To my taste you're a bit too aggressive on blank lines;-) This also holds
> for the previous patch. Unless you absolutely have to edit your sources in
> a 24-line terminal, keeping those empty lines would be appreciated:-)

OK. I'll try to overcome my anger ^^

Regards.
  

Patch

diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 290ac9d..4816da6 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -560,7 +560,6 @@  static void mx2_videobuf_queue(struct vb2_buffer *vb)
 	struct soc_camera_host *ici =
 		to_soc_camera_host(icd->parent);
 	struct mx2_camera_dev *pcdev = ici->priv;
-	struct mx2_fmt_cfg *prp = pcdev->emma_prp;
 	struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
 	unsigned long flags;
 
@@ -572,29 +571,7 @@  static void mx2_videobuf_queue(struct vb2_buffer *vb)
 	buf->state = MX2_STATE_QUEUED;
 	list_add_tail(&buf->queue, &pcdev->capture);
 
-	if (mx27_camera_emma(pcdev)) {
-		if (prp->cfg.channel == 1) {
-			writel(PRP_CNTL_CH1EN |
-				PRP_CNTL_CSIEN |
-				prp->cfg.in_fmt |
-				prp->cfg.out_fmt |
-				PRP_CNTL_CH1_LEN |
-				PRP_CNTL_CH1BYP |
-				PRP_CNTL_CH1_TSKIP(0) |
-				PRP_CNTL_IN_TSKIP(0),
-				pcdev->base_emma + PRP_CNTL);
-		} else {
-			writel(PRP_CNTL_CH2EN |
-				PRP_CNTL_CSIEN |
-				prp->cfg.in_fmt |
-				prp->cfg.out_fmt |
-				PRP_CNTL_CH2_LEN |
-				PRP_CNTL_CH2_TSKIP(0) |
-				PRP_CNTL_IN_TSKIP(0),
-				pcdev->base_emma + PRP_CNTL);
-		}
-		goto out;
-	} else { /* cpu_is_mx25() */
+	if (!mx27_camera_emma(pcdev)) { /* cpu_is_mx25() */
 		u32 csicr3, dma_inten = 0;
 
 		if (pcdev->fb1_active == NULL) {
@@ -629,8 +606,6 @@  static void mx2_videobuf_queue(struct vb2_buffer *vb)
 			writel(csicr3, pcdev->base_csi + CSICR3);
 		}
 	}
-
-out:
 	spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
@@ -692,11 +667,83 @@  static void mx2_videobuf_release(struct vb2_buffer *vb)
 	spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
+static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct soc_camera_device *icd = soc_camera_from_vb2q(q);
+	struct soc_camera_host *ici =
+		to_soc_camera_host(icd->parent);
+	struct mx2_camera_dev *pcdev = ici->priv;
+	struct mx2_fmt_cfg *prp = pcdev->emma_prp;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&pcdev->lock, flags);
+	if (mx27_camera_emma(pcdev)) {
+		if (count < 2) {
+			ret = -EINVAL;
+			goto err;
+		}
+
+		if (prp->cfg.channel == 1) {
+			writel(PRP_CNTL_CH1EN |
+				PRP_CNTL_CSIEN |
+				prp->cfg.in_fmt |
+				prp->cfg.out_fmt |
+				PRP_CNTL_CH1_LEN |
+				PRP_CNTL_CH1BYP |
+				PRP_CNTL_CH1_TSKIP(0) |
+				PRP_CNTL_IN_TSKIP(0),
+				pcdev->base_emma + PRP_CNTL);
+		} else {
+			writel(PRP_CNTL_CH2EN |
+				PRP_CNTL_CSIEN |
+				prp->cfg.in_fmt |
+				prp->cfg.out_fmt |
+				PRP_CNTL_CH2_LEN |
+				PRP_CNTL_CH2_TSKIP(0) |
+				PRP_CNTL_IN_TSKIP(0),
+				pcdev->base_emma + PRP_CNTL);
+		}
+	}
+err:
+	spin_unlock_irqrestore(&pcdev->lock, flags);
+
+	return ret;
+}
+
+static int mx2_stop_streaming(struct vb2_queue *q)
+{
+	struct soc_camera_device *icd = soc_camera_from_vb2q(q);
+	struct soc_camera_host *ici =
+		to_soc_camera_host(icd->parent);
+	struct mx2_camera_dev *pcdev = ici->priv;
+	struct mx2_fmt_cfg *prp = pcdev->emma_prp;
+	unsigned long flags;
+	u32 cntl;
+
+	spin_lock_irqsave(&pcdev->lock, flags);
+	if (mx27_camera_emma(pcdev)) {
+		cntl = readl(pcdev->base_emma + PRP_CNTL);
+		if (prp->cfg.channel == 1) {
+			writel(cntl & ~PRP_CNTL_CH1EN,
+			       pcdev->base_emma + PRP_CNTL);
+		} else {
+			writel(cntl & ~PRP_CNTL_CH2EN,
+			       pcdev->base_emma + PRP_CNTL);
+		}
+	}
+	spin_unlock_irqrestore(&pcdev->lock, flags);
+
+	return 0;
+}
+
 static struct vb2_ops mx2_videobuf_ops = {
-	.queue_setup	= mx2_videobuf_setup,
-	.buf_prepare	= mx2_videobuf_prepare,
-	.buf_queue	= mx2_videobuf_queue,
-	.buf_cleanup	= mx2_videobuf_release,
+	.queue_setup	 = mx2_videobuf_setup,
+	.buf_prepare	 = mx2_videobuf_prepare,
+	.buf_queue	 = mx2_videobuf_queue,
+	.buf_cleanup	 = mx2_videobuf_release,
+	.start_streaming = mx2_start_streaming,
+	.stop_streaming  = mx2_stop_streaming,
 };
 
 static int mx2_camera_init_videobuf(struct vb2_queue *q,