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-karicheri2@xxxxxx >-----Original Message----- >From: linux-media-owner@xxxxxxxxxxxxxxx [mailto:linux-media- >owner@xxxxxxxxxxxxxxx] 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.lee@xxxxxxxxxxx; ì�´ì„¸ë¬¸; >대ì�¸ê¸°; 김형준 >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-karicheri2@xxxxxx >> >> >-----Original Message----- >> >From: linux-media-owner@xxxxxxxxxxxxxxx [mailto:linux-media- >> >owner@xxxxxxxxxxxxxxx] 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.lee@xxxxxxxxxxx; ì�´ì„¸ë¬¸; >> >대ì�¸ê¸°; 김형준 >> >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 majordomo@xxxxxxxxxxxxxxx >> >> >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 majordomo@xxxxxxxxxxxxxxx >> >> 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 majordomo@xxxxxxxxxxxxxxx >> >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 majordomo@xxxxxxxxxxxxxxx >More majordomo info at http://vger.kernel.org/majordomo-info.html ��.n��������+%������w��{.n�����{��g����^n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�m