From patchwork Mon Jun 25 11:07:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manjunath Hadli X-Patchwork-Id: 1130331 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-davinci@patchwork.kernel.org Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by patchwork2.kernel.org (Postfix) with ESMTP id B86BCDFFEA for ; Fri, 29 Jun 2012 00:19:03 +0000 (UTC) Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id q5PBBm3k003908 for ; Mon, 25 Jun 2012 06:11:48 -0500 Received: from DLEE74.ent.ti.com (dlee74.ent.ti.com [157.170.170.8]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id q5PBBmU8027774 for ; Mon, 25 Jun 2012 06:11:48 -0500 Received: from dlelxv23.itg.ti.com (172.17.1.198) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Mon, 25 Jun 2012 06:11:48 -0500 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlelxv23.itg.ti.com (8.13.8/8.13.8) with ESMTP id q5PBBlvt031199 for ; Mon, 25 Jun 2012 06:11:47 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id E424080627 for ; Mon, 25 Jun 2012 06:11:47 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dbdp20.itg.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by linux.omap.com (Postfix) with ESMTP id A69D380626 for ; Mon, 25 Jun 2012 06:08:13 -0500 (CDT) Received: from DBDE71.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id q5PB8Cmi025226; Mon, 25 Jun 2012 16:38:12 +0530 (IST) Received: from dbdp32.itg.ti.com (172.24.170.251) by DBDE71.ent.ti.com (172.24.170.149) with Microsoft SMTP Server id 14.1.323.3; Mon, 25 Jun 2012 16:38:12 +0530 Received: from psplinux051 (smtpvbd.itg.ti.com [172.24.170.250]) by dbdp32.itg.ti.com (8.13.8/8.13.8) with ESMTP id q5PB8Cfa005187; Mon, 25 Jun 2012 16:38:12 +0530 Received: from x0144960 by psplinux051 with local (Exim 4.74) (envelope-from ) id 1Sj79Q-0002jt-DU; Mon, 25 Jun 2012 16:38:12 +0530 From: Manjunath Hadli To: LMML Subject: [PATCH v3 07/13] davinci: vpif: add support to use videobuf_iolock() Date: Mon, 25 Jun 2012 16:37:29 +0530 Message-ID: <1340622455-10419-8-git-send-email-manjunath.hadli@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1340622455-10419-1-git-send-email-manjunath.hadli@ti.com> References: <1340622455-10419-1-git-send-email-manjunath.hadli@ti.com> MIME-Version: 1.0 CC: dlos X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: Errors-To: davinci-linux-open-source-bounces+patchwork-davinci=patchwork.kernel.org@linux.davincidsp.com add support to use videobuf_iolock() instead of VPIF defined vpif_uservirt_to_phys API. Use videobuf_to_dma_contig API for both memory-mapped and userptr buffer allocations. Correspondingly removed vpif_uservirt_to_phys() VPIF defined API. Signed-off-by: Manjunath Hadli Signed-off-by: Lad, Prabhakar --- drivers/media/video/davinci/vpif_capture.c | 110 +++-------------- drivers/media/video/davinci/vpif_display.c | 183 ++++++---------------------- 2 files changed, 55 insertions(+), 238 deletions(-) diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c index d126fb6..097e136 100644 --- a/drivers/media/video/davinci/vpif_capture.c +++ b/drivers/media/video/davinci/vpif_capture.c @@ -82,52 +82,6 @@ static struct vpif_device vpif_obj = { {NULL} }; static struct device *vpif_dev; /** - * vpif_uservirt_to_phys : translate user/virtual address to phy address - * @virtp: user/virtual address - * - * This inline function is used to convert user space virtual address to - * physical address. - */ -static inline u32 vpif_uservirt_to_phys(u32 virtp) -{ - unsigned long physp = 0; - struct mm_struct *mm = current->mm; - 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 - * addresses - */ - 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(¤t->mm->mmap_sem); - - res = get_user_pages(current, current->mm, - virtp, nr_pages, 1, 0, &pages, NULL); - up_read(¤t->mm->mmap_sem); - - if (res == nr_pages) - physp = __pa(page_address(&pages[0]) + - (virtp & ~PAGE_MASK)); - else { - vpif_err("get_user_pages failed\n"); - return 0; - } - } - return physp; -} - -/** * buffer_prepare : callback function for buffer prepare * @q : buffer queue ptr * @vb: ptr to video buffer @@ -146,7 +100,7 @@ static int vpif_buffer_prepare(struct videobuf_queue *q, struct channel_obj *ch = fh->channel; struct common_obj *common; unsigned long addr; - + int ret; vpif_dbg(2, debug, "vpif_buffer_prepare\n"); @@ -156,32 +110,23 @@ static int vpif_buffer_prepare(struct videobuf_queue *q, if (VIDEOBUF_NEEDS_INIT == vb->state) { vb->width = common->width; vb->height = common->height; - vb->size = vb->width * vb->height; + vb->size = common->fmt.fmt.pix.sizeimage; vb->field = field; - } - vb->state = VIDEOBUF_PREPARED; - /** - * if user pointer memory mechanism is used, get the physical - * address of the buffer - */ - if (V4L2_MEMORY_USERPTR == common->memory) { - if (0 == vb->baddr) { - vpif_dbg(1, debug, "buffer address is 0\n"); - return -EINVAL; - } - vb->boff = vpif_uservirt_to_phys(vb->baddr); - if (!IS_ALIGNED(vb->boff, 8)) + ret = videobuf_iolock(q, vb, NULL); + if (ret < 0) goto exit; - } - addr = vb->boff; - if (q->streaming) { - if (!IS_ALIGNED((addr + common->ytop_off), 8) || - !IS_ALIGNED((addr + common->ybtm_off), 8) || - !IS_ALIGNED((addr + common->ctop_off), 8) || - !IS_ALIGNED((addr + common->cbtm_off), 8)) - goto exit; + addr = videobuf_to_dma_contig(vb); + + if (q->streaming) { + if (!IS_ALIGNED((addr + common->ytop_off), 8) || + !IS_ALIGNED((addr + common->ybtm_off), 8) || + !IS_ALIGNED((addr + common->ctop_off), 8) || + !IS_ALIGNED((addr + common->cbtm_off), 8)) + goto exit; + } + vb->state = VIDEOBUF_PREPARED; } return 0; exit: @@ -328,10 +273,7 @@ static void vpif_schedule_next_buffer(struct common_obj *common) /* Remove that buffer from the buffer queue */ list_del(&common->next_frm->queue); common->next_frm->state = VIDEOBUF_ACTIVE; - if (V4L2_MEMORY_USERPTR == common->memory) - addr = common->next_frm->boff; - else - addr = videobuf_to_dma_contig(common->next_frm); + addr = videobuf_to_dma_contig(common->next_frm); /* Set top and bottom field addresses in VPIF registers */ common->set_addr(addr + common->ytop_off, @@ -505,10 +447,7 @@ static void vpif_calculate_offsets(struct channel_obj *ch) } else vid_ch->buf_field = common->fmt.fmt.pix.field; - if (V4L2_MEMORY_USERPTR == common->memory) - sizeimage = common->fmt.fmt.pix.sizeimage; - else - sizeimage = config_params.channel_bufsize[ch->channel_id]; + sizeimage = common->fmt.fmt.pix.sizeimage; hpitch = common->fmt.fmt.pix.bytesperline; vpitch = sizeimage / (hpitch * 2); @@ -660,10 +599,7 @@ static int vpif_check_format(struct channel_obj *ch, hpitch = vpif_params->std_info.width; } - if (V4L2_MEMORY_USERPTR == common->memory) - sizeimage = pixfmt->sizeimage; - else - sizeimage = config_params.channel_bufsize[ch->channel_id]; + sizeimage = pixfmt->sizeimage; vpitch = sizeimage / (hpitch * 2); @@ -924,7 +860,7 @@ static int vpif_reqbufs(struct file *file, void *priv, reqbuf->type, common->fmt.fmt.pix.field, sizeof(struct videobuf_buffer), fh, - &common->lock); + NULL); /* Set io allowed member of file handle to TRUE */ fh->io_allowed[index] = 1; @@ -1041,10 +977,7 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) buf1->state = VIDEOBUF_ACTIVE; - if (V4L2_MEMORY_USERPTR == common->memory) - addr = buf1->boff; - else - addr = videobuf_to_dma_contig(buf1); + addr = videobuf_to_dma_contig(buf1); common->next_frm = buf1; common->set_addr(addr + common->ytop_off, @@ -1169,10 +1102,7 @@ static int vpif_streamon(struct file *file, void *priv, ch->field_id = 0; common->started = 1; - if (V4L2_MEMORY_USERPTR == common->memory) - addr = common->cur_frm->boff; - else - addr = videobuf_to_dma_contig(common->cur_frm); + addr = videobuf_to_dma_contig(common->cur_frm); /* Calculate the offset for Y and C data in the buffer */ vpif_calculate_offsets(ch); diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index e0070cd..61ea8bc 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -84,46 +84,6 @@ static struct vpif_device vpif_obj = { {NULL} }; static struct device *vpif_dev; /* - * vpif_uservirt_to_phys: This function is used to convert user - * space virtual address to physical address. - */ -static u32 vpif_uservirt_to_phys(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(¤t->mm->mmap_sem); - - res = get_user_pages(current, current->mm, - virtp, nr_pages, 1, 0, &pages, NULL); - up_read(¤t->mm->mmap_sem); - - if (res == nr_pages) { - physp = __pa(page_address(&pages[0]) + - (virtp & ~PAGE_MASK)); - } else { - vpif_err("get_user_pages failed\n"); - return 0; - } - } - - return physp; -} - -/* * buffer_prepare: This is the callback function called from videobuf_qbuf() * function the buffer is prepared and user space virtual address is converted * into physical address @@ -135,36 +95,30 @@ static int vpif_buffer_prepare(struct videobuf_queue *q, struct vpif_fh *fh = q->priv_data; struct common_obj *common; unsigned long addr; + int ret; common = &fh->channel->common[VPIF_VIDEO_INDEX]; if (VIDEOBUF_NEEDS_INIT == vb->state) { vb->width = common->width; vb->height = common->height; - vb->size = vb->width * vb->height; + /* Updating the size based on the application requirement */ + vb->size = common->fmt.fmt.pix.sizeimage; vb->field = field; - } - vb->state = VIDEOBUF_PREPARED; - /* if user pointer memory mechanism is used, get the physical - * address of the buffer */ - if (V4L2_MEMORY_USERPTR == common->memory) { - if (!vb->baddr) { - vpif_err("buffer_address is 0\n"); - return -EINVAL; - } - - vb->boff = vpif_uservirt_to_phys(vb->baddr); - if (!ISALIGNED(vb->boff)) + ret = videobuf_iolock(q, vb, NULL); + if (ret < 0) goto buf_align_exit; - } - addr = vb->boff; - if (q->streaming && (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) { - if (!ISALIGNED(addr + common->ytop_off) || - !ISALIGNED(addr + common->ybtm_off) || - !ISALIGNED(addr + common->ctop_off) || - !ISALIGNED(addr + common->cbtm_off)) - goto buf_align_exit; + addr = videobuf_to_dma_contig(vb); + if (q->streaming && + (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) { + if (!ISALIGNED(addr + common->ytop_off) || + !ISALIGNED(addr + common->ybtm_off) || + !ISALIGNED(addr + common->ctop_off) || + !ISALIGNED(addr + common->cbtm_off)) + goto buf_align_exit; + } + vb->state = VIDEOBUF_PREPARED; } return 0; @@ -241,7 +195,9 @@ static void vpif_buffer_release(struct videobuf_queue *q, common = &ch->common[VPIF_VIDEO_INDEX]; - videobuf_dma_contig_free(q, vb); + if (V4L2_MEMORY_USERPTR != vb->memory) + videobuf_dma_contig_free(q, vb); + vb->state = VIDEOBUF_NEEDS_INIT; if (V4L2_MEMORY_MMAP != common->memory) @@ -464,10 +420,7 @@ static void vpif_calculate_offsets(struct channel_obj *ch) vid_ch->buf_field = common->fmt.fmt.pix.field; } - if (V4L2_MEMORY_USERPTR == common->memory) - sizeimage = common->fmt.fmt.pix.sizeimage; - else - sizeimage = config_params.channel_bufsize[ch->channel_id]; + sizeimage = common->fmt.fmt.pix.sizeimage; hpitch = common->fmt.fmt.pix.bytesperline; vpitch = sizeimage / (hpitch * 2); @@ -544,10 +497,7 @@ static int vpif_check_format(struct channel_obj *ch, if (pixfmt->bytesperline <= 0) goto invalid_pitch_exit; - if (V4L2_MEMORY_USERPTR == common->memory) - sizeimage = pixfmt->sizeimage; - else - sizeimage = config_params.channel_bufsize[ch->channel_id]; + sizeimage = pixfmt->sizeimage; if (vpif_update_resolution(ch)) return -EINVAL; @@ -867,7 +817,7 @@ static int vpif_reqbufs(struct file *file, void *priv, &common->irqlock, reqbuf->type, field, sizeof(struct videobuf_buffer), fh, - &common->lock); + NULL); /* Set io allowed member of file handle to TRUE */ fh->io_allowed[index] = 1; @@ -896,17 +846,20 @@ static int vpif_querybuf(struct file *file, void *priv, static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { + struct vpif_fh *fh = NULL; + struct channel_obj *ch = NULL; + struct common_obj *common = NULL; - struct vpif_fh *fh = priv; - struct channel_obj *ch = fh->channel; - struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; - struct v4l2_buffer tbuf = *buf; - struct videobuf_buffer *buf1; - unsigned long addr = 0; - unsigned long flags; - int ret = 0; + if (!buf || !priv) + return -EINVAL; - if (common->fmt.type != tbuf.type) + fh = priv; + ch = fh->channel; + if (!ch) + return -EINVAL; + + common = &(ch->common[VPIF_VIDEO_INDEX]); + if (common->fmt.type != buf->type) return -EINVAL; if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { @@ -914,73 +867,7 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return -EACCES; } - if (!(list_empty(&common->dma_queue)) || - (common->cur_frm != common->next_frm) || - !(common->started) || - (common->started && (0 == ch->field_id))) - return videobuf_qbuf(&common->buffer_queue, buf); - - /* bufferqueue is empty store buffer address in VPIF registers */ - mutex_lock(&common->buffer_queue.vb_lock); - buf1 = common->buffer_queue.bufs[tbuf.index]; - if (buf1->memory != tbuf.memory) { - vpif_err("invalid buffer type\n"); - goto qbuf_exit; - } - - if ((buf1->state == VIDEOBUF_QUEUED) || - (buf1->state == VIDEOBUF_ACTIVE)) { - vpif_err("invalid state\n"); - goto qbuf_exit; - } - - switch (buf1->memory) { - case V4L2_MEMORY_MMAP: - if (buf1->baddr == 0) - goto qbuf_exit; - break; - - case V4L2_MEMORY_USERPTR: - if (tbuf.length < buf1->bsize) - goto qbuf_exit; - - if ((VIDEOBUF_NEEDS_INIT != buf1->state) - && (buf1->baddr != tbuf.m.userptr)) { - vpif_buffer_release(&common->buffer_queue, buf1); - buf1->baddr = tbuf.m.userptr; - } - break; - - default: - goto qbuf_exit; - } - - local_irq_save(flags); - ret = vpif_buffer_prepare(&common->buffer_queue, buf1, - common->buffer_queue.field); - if (ret < 0) { - local_irq_restore(flags); - goto qbuf_exit; - } - - buf1->state = VIDEOBUF_ACTIVE; - addr = buf1->boff; - common->next_frm = buf1; - if (tbuf.type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { - common->set_addr((addr + common->ytop_off), - (addr + common->ybtm_off), - (addr + common->ctop_off), - (addr + common->cbtm_off)); - } - - local_irq_restore(flags); - list_add_tail(&buf1->stream, &common->buffer_queue.stream); - mutex_unlock(&common->buffer_queue.vb_lock); - return 0; - -qbuf_exit: - mutex_unlock(&common->buffer_queue.vb_lock); - return -EINVAL; + return videobuf_qbuf(&common->buffer_queue, buf); } static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id) @@ -1119,7 +1006,7 @@ static int vpif_streamon(struct file *file, void *priv, ch->field_id = 0; common->started = 1; if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - addr = common->cur_frm->boff; + addr = videobuf_to_dma_contig(common->cur_frm); /* Calculate the offset for Y and C data in the buffer */ vpif_calculate_offsets(ch);