Re: [PATCH-V1 09/10] VPFE Capture: Add support for USERPTR mode of operation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Vaibhav,

There are changes to vpfe capture on Arago tree on top of this. For
example, vpfe_uservirt_to_phys() is removed and is replaced with
videobuf_iolock(). So please get the latest changes to upstream.

Murali

On Tue, Feb 23, 2010 at 3:34 AM,  <hvaibhav@xxxxxx> wrote:
> From: Vaibhav Hiremath <hvaibhav@xxxxxx>
>
>
> Signed-off-by: Vaibhav Hiremath <hvaibhav@xxxxxx>
> Signed-off-by: Muralidharan Karicheri <m-karicheri2@xxxxxx>
> ---
>  drivers/media/video/ti-media/vpfe_capture.c |   94 ++++++++++++++++++++++----
>  1 files changed, 79 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/media/video/ti-media/vpfe_capture.c b/drivers/media/video/ti-media/vpfe_capture.c
> index cece265..7d4ab44 100644
> --- a/drivers/media/video/ti-media/vpfe_capture.c
> +++ b/drivers/media/video/ti-media/vpfe_capture.c
> @@ -538,7 +538,24 @@ static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
>                                        struct videobuf_buffer, queue);
>        list_del(&vpfe_dev->next_frm->queue);
>        vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
> -       addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
> +       if (V4L2_MEMORY_USERPTR == vpfe_dev->memory)
> +               addr = vpfe_dev->cur_frm->boff;
> +       else
> +               addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
> +
> +       ccdc_dev->hw_ops.setfbaddr(addr);
> +}
> +
> +static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
> +{
> +       unsigned long addr;
> +
> +       if (V4L2_MEMORY_USERPTR == vpfe_dev->memory)
> +               addr = vpfe_dev->cur_frm->boff;
> +       else
> +               addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
> +
> +       addr += vpfe_dev->field_off;
>        ccdc_dev->hw_ops.setfbaddr(addr);
>  }
>
> @@ -559,7 +576,6 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
>  {
>        struct vpfe_device *vpfe_dev = dev_id;
>        enum v4l2_field field;
> -       unsigned long addr;
>        int fid;
>
>        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
> @@ -604,10 +620,7 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
>                         * the CCDC memory address
>                         */
>                        if (field == V4L2_FIELD_SEQ_TB) {
> -                               addr =
> -                                 videobuf_to_dma_contig(vpfe_dev->cur_frm);
> -                               addr += vpfe_dev->field_off;
> -                               ccdc_dev->hw_ops.setfbaddr(addr);
> +                               vpfe_schedule_bottom_field(vpfe_dev);
>                        }
>                        goto clear_intr;
>                }
> @@ -1234,7 +1247,10 @@ static int vpfe_videobuf_setup(struct videobuf_queue *vq,
>        struct vpfe_device *vpfe_dev = fh->vpfe_dev;
>
>        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
> -       *size = config_params.device_bufsize;
> +       *size = vpfe_dev->fmt.fmt.pix.sizeimage;
> +       if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
> +               vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
> +               *size = config_params.device_bufsize;
>
>        if (*count < config_params.min_numbuffers)
>                *count = config_params.min_numbuffers;
> @@ -1243,6 +1259,46 @@ static int vpfe_videobuf_setup(struct videobuf_queue *vq,
>        return 0;
>  }
>
> +/*
> + * vpfe_uservirt_to_phys: This function is used to convert user
> + * space virtual address to physical address.
> + */
> +static u32 vpfe_uservirt_to_phys(struct vpfe_device *vpfe_dev, u32 virtp)
> +{
> +       struct mm_struct *mm = current->mm;
> +       unsigned long physp = 0;
> +       struct vm_area_struct *vma;
> +
> +       vma = find_vma(mm, virtp);
> +
> +       /* For kernel direct-mapped memory, take the easy way */
> +       if (virtp >= PAGE_OFFSET)
> +               physp = virt_to_phys((void *)virtp);
> +       else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
> +               /* this will catch, kernel-allocated, mmaped-to-usermode addr */
> +               physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
> +       else {
> +               /* otherwise, use get_user_pages() for general userland pages */
> +               int res, nr_pages = 1;
> +               struct page *pages;
> +               down_read(&current->mm->mmap_sem);
> +
> +               res = get_user_pages(current, current->mm,
> +                                    virtp, nr_pages, 1, 0, &pages, NULL);
> +               up_read(&current->mm->mmap_sem);
> +
> +               if (res == nr_pages)
> +                       physp = __pa(page_address(&pages[0]) +
> +                                    (virtp & ~PAGE_MASK));
> +               else {
> +                       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
> +                               "get_user_pages failed\n");
> +                       return 0;
> +               }
> +       }
> +       return physp;
> +}
> +
>  static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
>                                struct videobuf_buffer *vb,
>                                enum v4l2_field field)
> @@ -1259,6 +1315,18 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
>                vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
>                vb->field = field;
>        }
> +
> +       if (V4L2_MEMORY_USERPTR == vpfe_dev->memory) {
> +               if (!vb->baddr) {
> +                       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
> +                               "buffer address is 0\n");
> +                       return -EINVAL;
> +               }
> +               vb->boff = vpfe_uservirt_to_phys(vpfe_dev, vb->baddr);
> +               /* Make sure user addresses are aligned to 32 bytes */
> +               if (!ALIGN(vb->boff, 32))
> +                       return -EINVAL;
> +       }
>        vb->state = VIDEOBUF_PREPARED;
>        return 0;
>  }
> @@ -1327,13 +1395,6 @@ static int vpfe_reqbufs(struct file *file, void *priv,
>                return -EINVAL;
>        }
>
> -       if (V4L2_MEMORY_USERPTR == req_buf->memory) {
> -               /* we don't support user ptr IO */
> -               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:"
> -                        " USERPTR IO not supported\n");
> -               return  -EINVAL;
> -       }
> -
>        ret = mutex_lock_interruptible(&vpfe_dev->lock);
>        if (ret)
>                return ret;
> @@ -1541,7 +1602,10 @@ static int vpfe_streamon(struct file *file, void *priv,
>        vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
>        /* Initialize field_id and started member */
>        vpfe_dev->field_id = 0;
> -       addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
> +       if (V4L2_MEMORY_USERPTR == vpfe_dev->memory)
> +               addr = vpfe_dev->cur_frm->boff;
> +       else
> +               addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
>
>        /* Calculate field offset */
>        vpfe_calculate_offsets(vpfe_dev);
> --
> 1.6.2.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Murali Karicheri
mkaricheri@xxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux