Hans,

I don't see the code you are referring to. Here is the probe() from the next 
branch of v4l-dvb. Could you point out the code that does the allocation of 
frame buffers ? I had used this code as reference when developing vpfe capture 
driver.

Murali

/*
 * vpif_probe: This function creates device entries by register itself to the
 * V4L2 driver and initializes fields of each channel objects
 */
static __init int vpif_probe(struct platform_device *pdev)
{
        const struct subdev_info *subdevdata;
        int i, j = 0, k, q, m, err = 0;
        struct i2c_adapter *i2c_adap;
        struct vpif_config *config;
        struct common_obj *common;
        struct channel_obj *ch;
        struct video_device *vfd;
        struct resource *res;
        int subdev_count;

        vpif_dev = &pdev->dev;
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                v4l2_err(vpif_dev->driver,
                                "Error getting platform resource\n");
                return -ENOENT;
        }

        if (!request_mem_region(res->start, res->end - res->start + 1,
                                                vpif_dev->driver->name)) {
                v4l2_err(vpif_dev->driver, "VPIF: failed request_mem_region\n");
                return -ENXIO;
        }

        vpif_base = ioremap_nocache(res->start, res->end - res->start + 1);
        if (!vpif_base) {
                v4l2_err(vpif_dev->driver, "Unable to ioremap VPIF reg\n");
                err = -ENXIO;
                goto resource_exit;
        }

        vpif_base_addr_init(vpif_base);

        initialize_vpif();

        err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
        if (err) {
                v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
                return err;
        }

        k = 0;
        while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
                for (i = res->start; i <= res->end; i++) {
                        if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
                                        "DM646x_Display",
                                (void *)(&vpif_obj.dev[k]->channel_id))) {
                                err = -EBUSY;
                                goto vpif_int_err;
                        }
                }
                k++;
        }

        for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {

                /* Get the pointer to the channel object */
                ch = vpif_obj.dev[i];

                /* Allocate memory for video device */
                vfd = video_device_alloc();
                if (vfd == NULL) {
                        for (j = 0; j < i; j++) {
                                ch = vpif_obj.dev[j];
                                video_device_release(ch->video_dev);
                        }
                        err = -ENOMEM;
                        goto video_dev_alloc_exit;
                }

                /* Initialize field of video device */
                *vfd = vpif_video_template;
                vfd->v4l2_dev = &vpif_obj.v4l2_dev;
                vfd->release = video_device_release;
                snprintf(vfd->name, sizeof(vfd->name),
                         "DM646x_VPIFDisplay_DRIVER_V%d.%d.%d",
                         (VPIF_DISPLAY_VERSION_CODE >> 16) & 0xff,
                         (VPIF_DISPLAY_VERSION_CODE >> 8) & 0xff,
                         (VPIF_DISPLAY_VERSION_CODE) & 0xff);

                /* Set video_dev to the video device */
                ch->video_dev = vfd;
        }

        for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
                ch = vpif_obj.dev[j];
                /* Initialize field of the channel objects */
                atomic_set(&ch->usrs, 0);
                for (k = 0; k < VPIF_NUMOBJECTS; k++) {
                        ch->common[k].numbuffers = 0;
                        common = &ch->common[k];
                        common->io_usrs = 0;
                        common->started = 0;
                        spin_lock_init(&common->irqlock);
                        mutex_init(&common->lock);
                        common->numbuffers = 0;
                        common->set_addr = NULL;
                        common->ytop_off = common->ybtm_off = 0;
                        common->ctop_off = common->cbtm_off = 0;
                        common->cur_frm = common->next_frm = NULL;
                        memset(&common->fmt, 0, sizeof(common->fmt));
                        common->numbuffers = config_params.numbuffers[k];

                }
                ch->initialized = 0;
                ch->channel_id = j;
                if (j < 2)
                        ch->common[VPIF_VIDEO_INDEX].numbuffers =
                            config_params.numbuffers[ch->channel_id];
                else
                        ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;

                memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));

                /* Initialize prio member of channel object */
                v4l2_prio_init(&ch->prio);
                ch->common[VPIF_VIDEO_INDEX].fmt.type =
                                                V4L2_BUF_TYPE_VIDEO_OUTPUT;

                /* register video device */
                vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
                                (int)ch, (int)&ch->video_dev);

                err = video_register_device(ch->video_dev,
                                          VFL_TYPE_GRABBER, (j ? 3 : 2));
                if (err < 0)
                        goto probe_out;

                video_set_drvdata(ch->video_dev, ch);
        }

        i2c_adap = i2c_get_adapter(1);
        config = pdev->dev.platform_data;
        subdev_count = config->subdev_count;
        subdevdata = config->subdevinfo;
        vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
                                                                GFP_KERNEL);
        if (vpif_obj.sd == NULL) {
                vpif_err("unable to allocate memory for subdevice pointers\n");
                err = -ENOMEM;
                goto probe_out;
        }

        for (i = 0; i < subdev_count; i++) {
                vpif_obj.sd[i] = v4l2_i2c_new_probed_subdev(&vpif_obj.v4l2_dev,
                                                i2c_adap, subdevdata[i].name,
                                                subdevdata[i].name,
                                                &subdevdata[i].addr);
                if (!vpif_obj.sd[i]) {
                        vpif_err("Error registering v4l2 subdevice\n");
                        goto probe_subdev_out;
                }

                if (vpif_obj.sd[i])
                        vpif_obj.sd[i]->grp_id = 1 << i;
        }

        return 0;

probe_subdev_out:
        kfree(vpif_obj.sd);
probe_out:
        for (k = 0; k < j; k++) {
                ch = vpif_obj.dev[k];
                video_unregister_device(ch->video_dev);
                video_device_release(ch->video_dev);
                ch->video_dev = NULL;
        }
vpif_int_err:
        v4l2_device_unregister(&vpif_obj.v4l2_dev);
        vpif_err("VPIF IRQ request failed\n");
        for (q = k; k >= 0; k--) {
                for (m = i; m >= res->start; m--)
                        free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
                res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
                m = res->end;
        }
video_dev_alloc_exit:
        iounmap(vpif_base);
resource_exit:
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(res->start, res->end - res->start + 1);

        return err;
}


Murali Karicheri
Software Design Engineer
Texas Instruments Inc.
Germantown, MD 20874
Phone : 301-515-3736
email: m-kariche...@ti.com

>-----Original Message-----
>From: linux-media-ow...@vger.kernel.org [mailto:linux-media-
>ow...@vger.kernel.org] On Behalf Of Hans Verkuil
>Sent: Thursday, July 30, 2009 2:32 AM
>To: Karicheri, Muralidharan
>Cc: Laurent Pinchart; Mauro Carvalho Chehab; Dongsoo, Nathaniel Kim;
>v4l2_linux; Dongsoo Kim; 박경민; jm105....@samsung.com; �세문;
>대�기; 김형준
>Subject: Re: How to save number of times using memcpy?
>
>On Thursday 30 July 2009 00:05:49 Karicheri, Muralidharan wrote:
>> Hans,
>>
>> I am bit confused about your usage of "davinci". Are you referring to
>> vpfe capture driver and dm6467 display driver vs OMAP ?
>
>Yes, the dm6467 display driver (drivers/media/video/davinci/vpif_display.c).
>
>That driver allocates buffers in the vpif_probe() function, and only if the
>caller wants more buffers in REQBUFS will the driver attempt to allocate
>additional buffers. Just look at the source.
>
>> I know at least
>> in these drivers it doesn’t allocate buffer at init time, but only on
>> REQBUF. I need to add this support (buffer allocation at init time) in
>> the driver. One way to allocate buffer in driver at init time is to use
>> dma_declare_coherent_memory() and pass physical memory address (outside
>> the kernel memory space) to this API. I am not aware of any other way of
>> doing this. Please let me know If there are alternate ways of doing this.
>>
>> Also which OMAP file I can refer to understand the implementation you are
>> referring to?
>
>See the path to the vpif_display.c source above (from our v4l-dvb
>repository). That implementation will work fine as long as the driver is
>compiled into the kernel and not as a module.
>
>There is one disadvantage, though: the memory allocated is rounded up by
>the
>kernel to the next power of two. Depending on the precise number and size
>of the buffers this might lead to wasted memory.
>
>Regards,
>
>       Hans
>
>>
>> Murali Karicheri
>> Software Design Engineer
>> Texas Instruments Inc.
>> Germantown, MD 20874
>> email: m-kariche...@ti.com
>>
>> >-----Original Message-----
>> >From: linux-media-ow...@vger.kernel.org [mailto:linux-media-
>> >ow...@vger.kernel.org] On Behalf Of Hans Verkuil
>> >Sent: Wednesday, July 29, 2009 5:52 PM
>> >To: Karicheri, Muralidharan
>> >Cc: Laurent Pinchart; Mauro Carvalho Chehab; Dongsoo, Nathaniel Kim;
>> >v4l2_linux; Dongsoo Kim; 박경민; jm105....@samsung.com; �세문;
>> >대�기; 김형준
>> >Subject: Re: How to save number of times using memcpy?
>> >
>> >On Wednesday 29 July 2009 21:06:17 Karicheri, Muralidharan wrote:
>> >> Hans,
>> >>
>> >> >True. However, my experience is that this approach isn't needed in
>> >> > most cases as long as the v4l driver is compiled into the kernel. In
>> >> > that case it is called early enough in the boot sequence that there
>> >> > is still enough unfragmented memory available. This should
>> >> > definitely be the default case for drivers merged into v4l-dvb.
>> >>
>> >> In my understanding, the buffer is allocated in the video buffer layer
>> >> when driver makes the videobuf_reqbufs() call.
>> >
>> >That depends completely on the driver implementation. In the case of the
>> >davinci driver it will allocate memory for X buffers when the driver is
>> >first initialized and it will use those when the application calls
>> > reqbufs. If the app wants more than X buffers the driver will attempt
>> > to dynamically allocate additional buffers, but those are usually hard
>> > to obtain.
>> >
>> >In my experience there is no problem for the driver to allocate the
>> >required
>> >memory if it is done during driver initialization and if the driver is
>> >compiled into the kernel.
>> >
>> >> Since this happens after
>> >> the kernel is up, this is indeed a serious issue when we require HD
>> >> resolution buffers. When I have tested vpfe capture from MT9T031 with
>> >> 2048x1536 resolution buffer, the video buffer layer gives an oops due
>> >> to failure to allocate buffer( I think video buffer layer is not
>> >> handling error case when there are not enough buffers to allocate).
>> >> Since buffer allocation happens very late (not at initialization), it
>> >> is unlikely to succeed due to fragmentation issue.
>> >
>> >That is really a driver problem: omap should use the same allocation
>> > scheme as davinci does. That works pretty reliably. Of course, if
>> > someone tries to squeeze the last drop out of their system, then they
>> > still may have to use nasty tricks to get it to work (like using the
>> > mem= kernel option). But such tricks are a last resort in my opinion.
>> >
>> >> So I have added support for USERPTR
>> >> IO in vpfe capture to handle high resolution capture. This requires a
>> >> kernel module to allocate contiguous buffer and the same is returned
>> >> to application using an IOCTL. The physical/logical address can then
>> >> be given to driver through USERPTR IO.
>> >
>> >What exactly is the point of doing this? I gather it is used to pass the
>> >same physical memory from e.g. a capture device to e.g. a resizer
>> > device, right? Otherwise I see no benefit to doing this as opposed to
>> > regular mmap I/O.
>> >
>> >Regards,
>> >
>> >    Hans
>> >
>> >> Another way this can be done, when using mmap IO, is to allocate
>> >> device memory (I have not tried it myself, but this seems to work in
>> >> SOC Camera drivers) using dma_declare_coherent_memory() (Thanks to
>> >> Guennadi Liakhovetski for the suggestion). This function takes
>> >> physical memory address outside the kernel memory space. Then when
>> >> dma_alloc_coherent() is called by video buffer layer, the buffer is
>> >> allocated from the above pre-allocated device memory and will succeed
>> >> always. But for this, the target architecture require support for
>> >> consistent memory allocation.
>> >>
>> >> Murali
>> >>
>> >> >Regards,
>> >> >
>> >> >        Hans
>> >> >
>> >> >--
>> >> >Hans Verkuil - video4linux developer - sponsored by TANDBERG
>> >> >
>> >> >--
>> >> >To unsubscribe from this list: send the line "unsubscribe
>> >> > linux-media" in the body of a message to majord...@vger.kernel.org
>> >> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >>
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe linux-media"
>> >> in the body of a message to majord...@vger.kernel.org
>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >
>> >--
>> >Hans Verkuil - video4linux developer - sponsored by TANDBERG Telecom
>> >--
>> >To unsubscribe from this list: send the line "unsubscribe linux-media"
>> > in the body of a message to majord...@vger.kernel.org
>> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>> ���{.n�+�������+%�����ݶ��w��{.n�+����{��g�
>>����^n�r���z���h����&���z��z�ޗ�+��+zf���h��
>����
>>����~����i��������z_��j:+v���)ߣ�m
>
>
>
>--
>Hans Verkuil - video4linux developer - sponsored by TANDBERG Telecom
>--
>To unsubscribe from this list: send the line "unsubscribe linux-media" in
>the body of a message to majord...@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to