RE: How to save number of times using memcpy?

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

 



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


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux