Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
On Wed October 10 2012 23:02:06 Rob Clark wrote: > On Wed, Oct 10, 2012 at 1:17 PM, Alan Cox wrote: > > On Wed, 10 Oct 2012 08:56:32 -0700 > > Robert Morell wrote: > > > >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > >> issue, and not really an interface". The dma-buf infrastructure is > >> explicitly intended as an interface between modules/drivers, so it > >> should use EXPORT_SYMBOL instead. > > > > NAK. This needs at the very least the approval of all rights holders for > > the files concerned and all code exposed by this change. > > Well, for my contributions to dmabuf, I don't object.. and I think > because we are planning to use dma-buf in userspace for dri3 / > dri-next, I think that basically makes it a userspace facing kernel > infrastructure which would be required for open and proprietary > drivers alike. So I don't see much alternative to making this > EXPORT_SYMBOL(). Of course, IANAL. The whole purpose of this API is to let DRM and V4L drivers share buffers for zero-copy pipelines. Unfortunately it is a fact that several popular DRM drivers are closed source. So we have a choice between keeping the export symbols GPL and forcing those closed-source drivers to make their own incompatible API, thus defeating the whole point of DMABUF, or using EXPORT_SYMBOL and letting the closed source vendors worry about the legality. They are already using such functions (at least nvidia is), so they clearly accept that risk. I prefer the evil where the DMABUF API uses EXPORT_SYMBOL to prevent the worse evil where an incompatible API is created to work around the EXPORT_SYMBOL_GPL limitation. Neither situation is paradise, but at least one is a slightly less depressing world than the other :-) In other words, I'm OK with EXPORT_SYMBOL for whatever it is worth as I did not do any coding but only some initial design help and reviewing. Regards, Hans ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
re: drm/nouveau: port all engines to new engine module format
Hello Ben Skeggs, The patch ebb945a94bba: "drm/nouveau: port all engines to new engine module format" from Jul 20, 2012, leads to the following warning: drivers/gpu/drm/nouveau/nouveau_abi16.c:264 nouveau_abi16_ioctl_channel_alloc() warn: should '1 << init->channel' be a 64 bit type 262 INIT_LIST_HEAD(&chan->notifiers); 263 list_add(&chan->head, &abi16->channels); 264 abi16->handles |= (1 << init->channel); This will only work for the first 30 channels, otherwise it needs to be: abi16->handles |= (u64)1 << init->channel; 265 But I don't couldn't tell how many channels are actually possible and I was confused by this. 132 /* destroy channel object, all children will be killed too */ 133 if (chan->chan) { 134 abi16->handles &= ~(1 << (chan->chan->handle & 0x)); Is that bitwise AND in the right place? Oxff would be enough to hold 0-63. 135 nouveau_channel_del(&chan->chan); 136 } regards, dan carpenter ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 40211] texture probleme in wolfenstein enemy territory rv770
https://bugs.freedesktop.org/show_bug.cgi?id=40211 --- Comment #12 from Michel Dänzer --- (In reply to comment #11) > err:winediag:X11DRV_WineGL_InitOpenglInfo Direct rendering is disabled, most > likely your OpenGL drivers haven't been installed correctly (using GL > renderer "Gallium 0.4 on AMD RV770", version "1.4 (2.1 Mesa 8.0.4)"). Did you install libgl1-mesa-dri:i386? -- You are receiving this mail because: You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
Em Thu, 11 Oct 2012 09:22:34 +1000 Dave Airlie escreveu: > On Thu, Oct 11, 2012 at 4:17 AM, Alan Cox wrote: > > On Wed, 10 Oct 2012 08:56:32 -0700 > > Robert Morell wrote: > > > >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > >> issue, and not really an interface". The dma-buf infrastructure is > >> explicitly intended as an interface between modules/drivers, so it > >> should use EXPORT_SYMBOL instead. > > > > NAK. This needs at the very least the approval of all rights holders for > > the files concerned and all code exposed by this change. > > I think he has that. Maybe he just needs to list them. My understanding it that he doesn't, as the dmabuf interface exposes not only the code written by this driver's author, but other parts of the Kernel. Even if someone consider just the dmabuf driver, I participated and actively contributed, together with other open source developers, during the 3 days discussions that happened at Linaro's forum where most of dmabuf design was decided, and participated, reviewed, gave suggestions approved the code, etc via email. So, even not writing the dmabuf stuff myself, I consider myself as one of the intelectual authors of the solution. Also, as dmabuf will also expose media interfaces, my understaning is that the drivers/media/ authors should also ack with this licensing (possible) change. I am one of the main contributors there. Alan also has copyrights there, and at other parts of the Linux Kernel, including the driver's core, from where all Linux Kernel drivers are derivative work, including this one. As Alan well said, many other core Linux Kernel authors very likely share this point of view. So, developers implicitly or explicitly copied in this thread that might be considering the usage of dmabuf on proprietary drivers should consider this email as a formal notification of my viewpoint: e. g. that I consider any attempt of using DMABUF or media core/drivers together with proprietary Kernelspace code as a possible GPL infringement. Regards, Mauro ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] dma-buf: Use EXPORT_SYMBOL
Em Thu, 11 Oct 2012 09:22:34 +1000 Dave Airlie escreveu: > On Thu, Oct 11, 2012 at 4:17 AM, Alan Cox wrote: > > On Wed, 10 Oct 2012 08:56:32 -0700 > > Robert Morell wrote: > > > >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > >> issue, and not really an interface". The dma-buf infrastructure is > >> explicitly intended as an interface between modules/drivers, so it > >> should use EXPORT_SYMBOL instead. > > > > NAK. This needs at the very least the approval of all rights holders for > > the files concerned and all code exposed by this change. > > I think he has that. Maybe he just needs to list them. My understanding it that he doesn't, as the dmabuf interface exposes not only the code written by this driver's author, but other parts of the Kernel. Even if someone consider just the dmabuf driver, I participated and actively contributed, together with other open source developers, during the 3 days discussions that happened at Linaro's forum where most of dmabuf design was decided, and participated, reviewed, gave suggestions approved the code, etc via email. So, even not writing the dmabuf stuff myself, I consider myself as one of the intelectual authors of the solution. Also, as dmabuf will also expose media interfaces, my understaning is that the drivers/media/ authors should also ack with this licensing (possible) change. I am one of the main contributors there. Alan also has copyrights there, and at other parts of the Linux Kernel, including the driver's core, from where all Linux Kernel drivers are derivative work, including this one. As Alan well said, many other core Linux Kernel authors very likely share this point of view. So, developers implicitly or explicitly copied in this thread that might be considering the usage of dmabuf on proprietary drivers should consider this email as a formal notification of my viewpoint: e. g. that I consider any attempt of using DMABUF or media core/drivers together with proprietary Kernelspace code as a possible GPL infringement. Regards, Mauro
[Bug 40211] texture probleme in wolfenstein enemy territory rv770
https://bugs.freedesktop.org/show_bug.cgi?id=40211 --- Comment #11 from pitamila at free.fr --- yes, using Debian Sid, the libgl1-mesa-* package are multi-arch ready. dpkg -L libgl1-mesa-glx:i386 shows: . /usr/lib/i386-linux-gnu/libGL.so.1.2 . . . I have installed the libtxc-dxtn-s2tc0 both x86_64 and i386 I suppose Enemy Territory would complain if 32bit libGL was not installed. However, using wine on simple win32 opengGL binary demo http://freewebs.com/mannymax/cpp/GLTest.exe I get: err:winediag:X11DRV_WineGL_InitOpenglInfo Direct rendering is disabled, most likely your OpenGL drivers haven't been installed correctly (using GL renderer "Gallium 0.4 on AMD RV770", version "1.4 (2.1 Mesa 8.0.4)"). Despite the above error, the demo run (I see a multicolor pyramyd and cube, moving) I don't know what to think, wine is reporting Gallium and Mesa 8.0.4... -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/d2f271bf/attachment.html>
[Linaro-mm-sig] [PATCHv9 00/25] Integration of videobuf2 with DMABUF
On 10/10/12, Mauro Carvalho Chehab wrote: > Hi, > > Em Tue, 02 Oct 2012 16:27:11 +0200 > Tomasz Stanislawski escreveu: > >> Hello everyone, >> This patchset adds support for DMABUF [2] importing and exporting to V4L2 >> stack. >> >> v9: >> - rebase on 3.6 >> - change type for fs to __s32 >> - add support for vb2_ioctl_expbuf >> - remove patch 'v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING', >> it will be posted as a separate patch >> - fix typos and style in Documentation (from Hans Verkuil) >> - only vb2-core and vb2-dma-contig selects DMA_SHARED_BUFFER in Kconfig >> - use data_offset and length while queueing DMABUF >> - return the most recently used fd at VIDIOC_DQBUF >> - use (buffer-type, index, plane) tuple instead of mem_offset >> to identify a for exporting (from Hans Verkuil) >> - support for DMABUF mmap in vb2-dma-contig (from Laurent Pinchart) >> - add testing alignment of vaddr and size while verifying userptr >> against DMA capabilities (from Laurent Pinchart) >> - substitute VM_DONTDUMP with VM_RESERVED >> - simplify error handling in vb2_dc_get_dmabuf (from Laurent Pinchart) > > For now, NACK. See below. Sad news! It's failed to merge by very poor samsung board support at mainline. CC arm & samsung mailing list. Thank you, Kyungmin Park > > I spent 4 days trying to setup an environment that would allow testing > DMABUF with video4linux without success (long story, see below). Also, > Laurent tried the same without any luck, and it seems that it even > corrupted his test machine. > > Basically Samsung generously donated me two boards that it could be > used on this test (Origen and SMDK310). None of them actually worked > with the upstream kernel: patches are needed to avoid OOPSes on > Origen; both Origen/SMDK310 defconfigs are completely broken, and drivers > don't even boot if someone tries to use the Kernel's defconfigs. > > Even after spending _days_ trying to figure out the needed .config options > (as the config files are not easily available), both boards have... issues: > > - lack of any display output driver at SMDK310; > > - lack of any network driver at Origen: it seems that none of > the available network options on Origen was upstreamed: no Bluetooth, no > OTG, > no Wifi. > > The only test I was able to do (yesterday, late night), the DMABUF caused > an OOPS at the Origen board. So, for sure it is not ready for upstream. > > It is now, too late for 3.7. I might consider it to 3.8, if something > can be done to fix the existing issues, and setup a proper setup, using > the upstream Kernel. > > Regards, > Mauro > > ___ > Linaro-mm-sig mailing list > Linaro-mm-sig at lists.linaro.org > http://lists.linaro.org/mailman/listinfo/linaro-mm-sig >
Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
>> On Thu, Oct 11, 2012 at 4:17 AM, Alan Cox wrote: >> > On Wed, 10 Oct 2012 08:56:32 -0700 >> > Robert Morell wrote: >> > >> >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation >> >> issue, and not really an interface". The dma-buf infrastructure is >> >> explicitly intended as an interface between modules/drivers, so it >> >> should use EXPORT_SYMBOL instead. >> > >> > NAK. This needs at the very least the approval of all rights holders for >> > the files concerned and all code exposed by this change. >> >> I think he has that. Maybe he just needs to list them. > > My understanding it that he doesn't, as the dmabuf interface exposes not only > the code written by this driver's author, but other parts of the Kernel. > > Even if someone consider just the dmabuf driver, I participated and actively > contributed, together with other open source developers, during the 3 days > discussions that happened at Linaro's forum where most of dmabuf design was > decided, and participated, reviewed, gave suggestions approved the code, etc > via email. So, even not writing the dmabuf stuff myself, I consider myself as > one of the intelectual authors of the solution. > > Also, as dmabuf will also expose media interfaces, my understaning is > that the drivers/media/ authors should also ack with this licensing > (possible) change. I am one of the main contributors there. Alan also has > copyrights there, and at other parts of the Linux Kernel, including the > driver's > core, from where all Linux Kernel drivers are derivative work, including this > one. > > As Alan well said, many other core Linux Kernel authors very likely share > this point of view. > > So, developers implicitly or explicitly copied in this thread that might be > considering the usage of dmabuf on proprietary drivers should consider > this email as a formal notification of my viewpoint: e. g. that I consider > any attempt of using DMABUF or media core/drivers together with proprietary > Kernelspace code as a possible GPL infringement. Though that does beg the question why you care about this patch :-) Dave. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] dma-buf: Use EXPORT_SYMBOL
On Wed, 10 Oct 2012 08:56:32 -0700 Robert Morell wrote: > EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > issue, and not really an interface". The dma-buf infrastructure is > explicitly intended as an interface between modules/drivers, so it > should use EXPORT_SYMBOL instead. NAK. This needs at the very least the approval of all rights holders for the files concerned and all code exposed by this change. Also I'd note if you are trying to do this for the purpose of combining it with proprietary code then you are still in my view as a (and the view of many other) rights holder to the kernel likely to be in breach of the GPL requirements for a derivative work. You may consider that formal notification of my viewpoint. Your corporate legal team can explain to you why the fact you are now aware of my view is important to them. Alan
[Bug 55829] [Regression]Smokin-guns crash when change resolution
https://bugs.freedesktop.org/show_bug.cgi?id=55829 --- Comment #4 from meng --- The problem also exists on most 3D games such as gl-117, warsow,Extreme TuxRacer,padman. -- You are receiving this mail because: You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[BUG] drm/nouveau: NULL pointer dereference in nouveau_channel_new()
Hi, Current nouveau code in Linus' tree oopses with noaccel. Didn't happen in 3.6. Full dmesg attached. Ortwin BUG: unable to handle kernel NULL pointer dereference at 0018 Oct 10 18:05:49 localhost kernel: IP: [] nouveau_channel_new+0x41e/0x670 Oct 10 18:05:49 localhost kernel: PGD 22ddd7067 PUD 22f76f067 PMD 0 Oct 10 18:05:49 localhost kernel: Oops: [#1] PREEMPT SMP Oct 10 18:05:49 localhost kernel: Modules linked in: Oct 10 18:05:49 localhost kernel: CPU 0 Oct 10 18:05:49 localhost kernel: Pid: 2723, comm: X Not tainted 3.7.0-pre #1 Hewlett-Packard HP EliteBook 8540w/1521 Oct 10 18:05:49 localhost kernel: RIP: 0010:[] [] nouveau_channel_new+0x41e/0x670 Oct 10 18:05:49 localhost kernel: RSP: 0018:88023026bc68 EFLAGS: 00010202 Oct 10 18:05:49 localhost kernel: RAX: RBX: 88022ceeca80 RCX: 0088 Oct 10 18:05:49 localhost kernel: RDX: c900127e408c RSI: c900127e408c RDI: 88022ceeca80 Oct 10 18:05:49 localhost kernel: RBP: 88023026bce8 R08: R09: Oct 10 18:05:49 localhost kernel: R10: 0010 R11: 000f R12: Oct 10 18:05:49 localhost kernel: R13: 880231f36800 R14: 88022f68ca00 R15: 88022f68ca00 Oct 10 18:05:49 localhost kernel: FS: 7f129a597880() GS:88023bc0() knlGS: Oct 10 18:05:49 localhost kernel: CS: 0010 DS: ES: CR0: 80050033 Oct 10 18:05:49 localhost kernel: CR2: 0018 CR3: 0002300a1000 CR4: 07f0 Oct 10 18:05:49 localhost kernel: DR0: DR1: DR2: Oct 10 18:05:49 localhost kernel: DR3: DR6: 0ff0 DR7: 0400 Oct 10 18:05:49 localhost kernel: Process X (pid: 2723, threadinfo 88023026a000, task 880231edbde0) Oct 10 18:05:49 localhost kernel: Stack: Oct 10 18:05:49 localhost kernel: 88023026bcb0 88022f68ca00 88022f68caa8 8802311be9c0 Oct 10 18:05:49 localhost kernel: d801d802 88023026bc98 2000 Oct 10 18:05:49 localhost kernel: 00ff 880231f9afa0 8802323c0840 Oct 10 18:05:49 localhost kernel: Call Trace: Oct 10 18:05:49 localhost kernel: [] nouveau_abi16_ioctl_channel_alloc+0x15c/0x360 Oct 10 18:05:49 localhost kernel: [] drm_ioctl+0x2a0/0x4f0 Oct 10 18:05:49 localhost kernel: [] ? nouveau_abi16_ioctl_setparam+0x10/0x10 Oct 10 18:05:49 localhost kernel: [] ? __do_page_fault+0x1c4/0x490 Oct 10 18:05:49 localhost kernel: [] do_vfs_ioctl+0x97/0x4f0 Oct 10 18:05:49 localhost kernel: [] sys_ioctl+0x57/0x90 Oct 10 18:05:49 localhost kernel: [] system_call_fastpath+0x16/0x1b Oct 10 18:05:49 localhost kernel: Code: e2 02 48 89 df e8 d3 02 00 00 8b 83 80 00 00 00 89 83 84 00 00 00 0f 1f 80 00 00 00 00 48 8b 43 08 48 89 df 48 8b 80 f8 06 00 00 50 18 41 89 c4 85 c0 0f 84 65 fd ff ff 0f 1f 40 00 4c 89 ff Oct 10 18:05:49 localhost kernel: RIP [] nouveau_channel_new+0x41e/0x670 Oct 10 18:05:49 localhost kernel: RSP Oct 10 18:05:49 localhost kernel: CR2: 0018 Oct 10 18:05:49 localhost kernel: ---[ end trace e23ae1067c361c88 ]--- -- next part -- Oct 10 18:05:42 localhost kernel: Initializing cgroup subsys cpu Oct 10 18:05:42 localhost kernel: Linux version 3.7.0-pre (root at localhost) (gcc version 4.5.4 (Gentoo 4.5.4 p1.0, pie-0.4.7) ) #1 SMP PREEMPT Wed Oct 10 17:35:48 CEST 2012 Oct 10 18:05:42 localhost kernel: Command line: root=/dev/sda1 rootfstype=ext4 nouveau.noaccel=1 Oct 10 18:05:42 localhost kernel: e820: BIOS-provided physical RAM map: Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0x-0x0009fbff] usable Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0x0009fc00-0x0009] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0x000e-0x000f] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0x0010-0xbefc1fff] usable Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xbefc2000-0xbf6c1fff] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xbf6c2000-0xbf7c1fff] ACPI NVS Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xbf7c2000-0xbf7fefff] ACPI data Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xbf7ff000-0xbf7f] usable Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xbf80-0xbfff] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xe000-0xefff] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xfec0-0xfec00fff] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xfed1-0xfed13fff] reserved Oct 10 18:05:42 localhost kernel: BIOS-e820: [mem 0xfed19000-0xfed19fff] reserved Oct 10 18:05:42 localhost kernel:
RC6 for an Intel GU doesn't always work
Sometimes - after a reboot or after wakeup from s2disk I'm observed at my ThinkPad T420 (i5-2540M CPU) w/ integrated intel graphic (i915 module) since 3.6-rc(5?), that the temperature is above 80?C (usually it is around/lower than 50 ?C). Powertop-2.1 shows, that the all 4 CPU cores are mostly idle, but the GPU is running at 100%. It looks for me that the power saving mode RC6 isn't active. After 1-2 s2ram's however the issue went away. I'm observing the issue both under my Gentoo Linux and under a RH system (kernel 3.6.1 each). It is hard to bisect b/c not reliable. -- MfG/Sincerely Toralf F?rster pgp finger print: 7B1A 07F4 EC82 0F90 D4C2 8936 872A E508 7DB6 9DA3
[Bug 55829] [Regression]Smokin-guns crash when change resolution
https://bugs.freedesktop.org/show_bug.cgi?id=55829 meng changed: What|Removed |Added Status|NEEDINFO|NEW --- Comment #3 from meng --- bt - #0 0x7fffe66d280b in ?? () #1 0x0003 in ?? () #2 0x023995e0 in ?? () #3 0x0278f2f0 in ?? () #4 0x in ?? () -- You are receiving this mail because: You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH] drm/i915: Add atomic page flip support
From: Ville Syrj?l? Utilize drm_flip to implement "atomic page flip". When involving multiple planes on one pipe, the operations on the planes must be synchronized via software since the hardware doesn't provide the means. drm_flip is used to make that happen, and to track the progress of the flip operations. Signed-off-by: Ville Syrj?l? --- drivers/gpu/drm/i915/i915_dma.c |5 + drivers/gpu/drm/i915/i915_drv.h |4 + drivers/gpu/drm/i915/i915_irq.c | 18 +- drivers/gpu/drm/i915/intel_atomic.c | 813 +- drivers/gpu/drm/i915/intel_display.c |2 + drivers/gpu/drm/i915/intel_drv.h |6 + 6 files changed, 832 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e958e54..79ad32d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1762,6 +1762,8 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file) idr_init(&file_priv->context_idr); + INIT_LIST_HEAD(&file_priv->pending_flips); + return 0; } @@ -1792,10 +1794,13 @@ void i915_driver_lastclose(struct drm_device * dev) i915_dma_cleanup(dev); } +void intel_atomic_free_events(struct drm_device *dev, struct drm_file *file); + void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { i915_gem_context_close(dev, file_priv); i915_gem_release(dev, file_priv); + intel_atomic_free_events(dev, file_priv); } void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57e4894..80645df 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -845,6 +846,8 @@ typedef struct drm_i915_private { struct work_struct parity_error_work; bool hw_contexts_disabled; uint32_t hw_context_size; + + struct drm_flip_driver flip_driver; } drm_i915_private_t; /* Iterate over initialised rings */ @@ -1055,6 +1058,7 @@ struct drm_i915_file_private { struct list_head request_list; } mm; struct idr context_idr; + struct list_head pending_flips; }; #define INTEL_INFO(dev)(((struct drm_i915_private *) (dev)->dev_private)->info) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 23f2ea0..f816dab 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -37,6 +37,8 @@ #include "i915_trace.h" #include "intel_drv.h" +void intel_atomic_handle_vblank(struct drm_device *dev, int pipe); + /* For display hotplug interrupt */ static void ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) @@ -547,8 +549,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); for_each_pipe(pipe) { - if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) + if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) { drm_handle_vblank(dev, pipe); + intel_atomic_handle_vblank(dev, pipe); + } if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { intel_prepare_page_flip(dev, pipe); @@ -685,8 +689,10 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) intel_prepare_page_flip(dev, i); intel_finish_page_flip_plane(dev, i); } - if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) + if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) { drm_handle_vblank(dev, i); + intel_atomic_handle_vblank(dev, i); + } } /* check event from PCH */ @@ -778,11 +784,15 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) intel_finish_page_flip_plane(dev, 1); } - if (de_iir & DE_PIPEA_VBLANK) + if (de_iir & DE_PIPEA_VBLANK) { drm_handle_vblank(dev, 0); + intel_atomic_handle_vblank(dev, 0); + } - if (de_iir & DE_PIPEB_VBLANK) + if (de_iir & DE_PIPEB_VBLANK) { drm_handle_vblank(dev, 1); + intel_atomic_handle_vblank(dev, 1); + } /* check event from PCH */ if (de_iir & DE_PCH_EVENT) { diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 363018f..9fa95d3 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -3,6 +3,7 @@ #include #include +#include #include "intel_drv.h" @@ -2
[RFC PATCH] drm/i915: Implement atomic modesetting
From: Ville Syrj?l? Implement the atomic modeset operations. TODO: need to rewrite this for the new intel modeset code Signed-off-by: Ville Syrj?l? --- drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/intel_atomic.c | 1462 ++ drivers/gpu/drm/i915/intel_display.c |7 + 3 files changed, 1470 insertions(+), 0 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_atomic.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b0bacdb..377d100 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -16,6 +16,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ i915_gem_tiling.o \ i915_sysfs.o \ i915_trace_points.o \ + intel_atomic.o \ intel_display.o \ intel_crt.o \ intel_lvds.o \ diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c new file mode 100644 index 000..363018f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -0,0 +1,1462 @@ +/* + */ + +#include +#include + +#include "intel_drv.h" + +static struct drm_property *prop_src_x; +static struct drm_property *prop_src_y; +static struct drm_property *prop_src_w; +static struct drm_property *prop_src_h; +static struct drm_property *prop_crtc_x; +static struct drm_property *prop_crtc_y; +static struct drm_property *prop_crtc_w; +static struct drm_property *prop_crtc_h; +static struct drm_property *prop_fb_id; +static struct drm_property *prop_crtc_id; +static struct drm_property *prop_mode; +static struct drm_property *prop_connector_ids; +static struct drm_property *prop_cursor_id; +static struct drm_property *prop_cursor_x; +static struct drm_property *prop_cursor_y; +static struct drm_property *prop_cursor_w; +static struct drm_property *prop_cursor_h; + +struct intel_plane_state { + struct drm_plane *plane; + struct drm_framebuffer *old_fb; + struct intel_plane_coords coords; + bool dirty; + bool pinned; +}; + +struct intel_crtc_state { + struct drm_crtc *crtc; + struct drm_framebuffer *old_fb; + struct drm_i915_gem_object *old_cursor_bo; + bool mode_dirty; + bool fb_dirty; + bool cursor_dirty; + bool active_dirty; + bool pinned; + bool cursor_pinned; + unsigned long connectors_bitmask; + unsigned long encoders_bitmask; +}; + +struct intel_atomic_state { + struct drm_file *file; + struct intel_plane_state *plane; + struct intel_crtc_state *crtc; + bool dirty; + bool restore_hw; + unsigned int flags; + uint64_t user_data; + struct drm_plane *saved_planes; + struct intel_crtc *saved_crtcs; + struct drm_connector *saved_connectors; + struct drm_encoder *saved_encoders; +}; + +static void update_connectors_bitmask(struct intel_crtc_state *st) +{ + struct drm_device *dev = st->crtc->dev; + struct drm_connector *connector; + unsigned int i; + + st->connectors_bitmask = 0; + + i = 0; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->encoder && connector->encoder->crtc == st->crtc) + __set_bit(i, &st->connectors_bitmask); + + i++; + } +} + +static void update_encoders_bitmask(struct intel_crtc_state *st) +{ + struct drm_device *dev = st->crtc->dev; + struct drm_encoder *encoder; + unsigned int i; + + st->encoders_bitmask = 0; + + i = 0; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + if (encoder->crtc == st->crtc) + __set_bit(i, &st->encoders_bitmask); + + i++; + } +} + +static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, int count_ids) +{ + struct drm_crtc *crtc = s->crtc; + struct drm_device *dev = crtc->dev; + struct drm_connector *connectors[count_ids]; + struct drm_connector *connector; + struct drm_encoder *encoder; + int i; + + for (i = 0; i < count_ids; i++) { + struct drm_encoder *encoder; + const struct drm_connector_helper_funcs *connector_funcs; + struct drm_mode_object *obj; + int j; + + /* don't accept duplicates */ + for (j = i + 1; j < count_ids; j++) + if (ids[i] == ids[j]) + return -EINVAL; + + obj = drm_mode_object_find(dev, ids[i], DRM_MODE_OBJECT_CONNECTOR); + if (!obj) + return -ENOENT; + + connector = obj_to_connector(obj); + connector_funcs = connector->helper_private; + + encoder = connector_funcs->best_encoder(connector); + + if (!drm_encoder_crtc_ok(encoder, crtc)) + retu
[RFC PATCH] drm: Atomic modeset ioctl
From: Ville Syrj?l? The atomic modeset ioctl cna be used to push any number of new values for object properties. The driver can then check the full device configuration as single unit, and try to apply the changes atomically. The ioctl simply takes a list of object IDs and property IDs and their values. For setting values to blob properties, the property value indicates the length of the data, and the actual data is passed via another blob pointer. The caller can demand non-blocking operation from the ioctl, and if the driver can't satisfy that requirement an error will be returned. The caller can also request to receive asynchronous completion events after the operation has reached the hardware. An event is sent for each object specified by the caller, whether or not the actual state of that object changed. Each event also carries a framebuffer ID, which indicates to user space that the specified object is no longer accessing that framebuffer. TODO: detailed error reporting? Signed-off-by: Ville Syrj?l? --- drivers/gpu/drm/drm_crtc.c | 146 drivers/gpu/drm/drm_drv.c |1 + include/drm/drm.h | 12 include/drm/drmP.h |8 +++ include/drm/drm_crtc.h | 13 include/drm/drm_mode.h | 16 + 6 files changed, 196 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b313958..38c6604 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4162,3 +4162,149 @@ int drm_calc_vscale(struct drm_region *src, struct drm_region *dst, return vscale; } EXPORT_SYMBOL(drm_calc_vscale); + +int drm_mode_atomic_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_atomic *arg = data; + uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); + uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); + uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); + uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); + uint64_t __user *blob_values_ptr = (uint64_t __user *)(unsigned long)(arg->blob_values_ptr); + unsigned int copied_objs = 0; + unsigned int copied_props = 0; + unsigned int copied_blobs = 0; + void *state; + int ret = 0; + unsigned int i, j; + + if (!dev->driver->atomic_funcs || + !dev->driver->atomic_funcs->begin || + !dev->driver->atomic_funcs->set || + !dev->driver->atomic_funcs->check || + !dev->driver->atomic_funcs->commit || + !dev->driver->atomic_funcs->end) + return -ENOSYS; + + if (arg->flags & ~(DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_EVENT | DRM_MODE_ATOMIC_NONBLOCK)) + return -EINVAL; + + /* can't test and expect an event at the same time. */ + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY && arg->flags & DRM_MODE_ATOMIC_EVENT) + return -EINVAL; + + mutex_lock(&dev->mode_config.mutex); + + state = dev->driver->atomic_funcs->begin(dev, file_priv, arg->flags, arg->user_data); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + goto unlock; + } + + for (i = 0; i < arg->count_objs; i++) { + uint32_t obj_id, count_props; + struct drm_mode_object *obj; + + if (get_user(obj_id, objs_ptr + copied_objs)) { + ret = -EFAULT; + goto out; + } + + obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY); + if (!obj || !obj->properties) { + ret = -ENOENT; + goto out; + } + + if (get_user(count_props, count_props_ptr + copied_objs)) { + ret = -EFAULT; + goto out; + } + + copied_objs++; + + for (j = 0; j < count_props; j++) { + uint32_t prop_id; + uint64_t prop_value; + struct drm_mode_object *prop_obj; + struct drm_property *prop; + void *blob_data = NULL; + + if (get_user(prop_id, props_ptr + copied_props)) { + ret = -EFAULT; + goto out; + } + + if (!object_has_prop(obj, prop_id)) { + ret = -EINVAL; + goto out; + } + + prop_obj = drm_mode_object_find(dev, prop_id, DRM_MODE_OBJECT_PROPERTY); + if (!prop_obj) { + ret = -ENOENT; +
[RFC PATCH] Atomic modeset/pageflip update
Here's another set of atomic modeset and pageflip patches. I just skipped spamming the list with all the patches that contain the gritty details for now. These three provide an eagle eye view of the whole thing. The full series can be found here [1]. The accompanying libdrm stuff is here [2]. So what are the significant changes since the last time: - Pass the display modes as blobs as opposed to mode object IDs - Fixed blob passing (it was simply broken in my earlier patches) - Add completion events - Add the non-blocking flag - Clean up the history a bit to make the patches easier on the eye Unfortunately the whole thing is still based on the pre i915 modeset rework code. So porting the modesetting side over to the current i915 code is one two bigger tasks that I have left. The other is implementing non-blocking synchronization with the GPU. [1] https://gitorious.org/vsyrjala/linux/commits/drm_atomic_9 [2] https://gitorious.org/vsyrjala/drm/commits/drm_atomic_7
[PATCHv10 26/26] v4l: s5p-mfc: support for dmabuf exporting
This patch enhances s5p-mfc with support for DMABUF exporting via VIDIOC_EXPBUF ioctl. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: Kamil Debski Acked-by: Hans Verkuil --- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 14 ++ drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 14 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index eb6a70b..6dad9a7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -636,6 +636,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return -EINVAL; } +/* Export DMA buffer */ +static int vidioc_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + + if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return vb2_expbuf(&ctx->vq_src, eb); + if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return vb2_expbuf(&ctx->vq_dst, eb); + return -EINVAL; +} + /* Stream on */ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) @@ -813,6 +826,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = { .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_expbuf = vidioc_expbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_g_crop = vidioc_g_crop, diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 2af6d52..22bf684 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1165,6 +1165,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return ret; } +/* Export DMA buffer */ +static int vidioc_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + + if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return vb2_expbuf(&ctx->vq_src, eb); + if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return vb2_expbuf(&ctx->vq_dst, eb); + return -EINVAL; +} + /* Stream on */ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) @@ -1568,6 +1581,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = { .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_expbuf = vidioc_expbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_s_parm = vidioc_s_parm, -- 1.7.9.5
[PATCHv10 25/26] v4l: s5p-tv: mixer: support for dmabuf exporting
This patch enhances s5p-tv with support for DMABUF exporting via VIDIOC_EXPBUF ioctl. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/platform/s5p-tv/mixer_video.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index 2421e527..5e3cdb2 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c @@ -698,6 +698,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK); } +static int mxr_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct mxr_layer *layer = video_drvdata(file); + + mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__); + return vb2_expbuf(&layer->vb_queue, eb); +} + static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct mxr_layer *layer = video_drvdata(file); @@ -725,6 +734,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = { .vidioc_querybuf = mxr_querybuf, .vidioc_qbuf = mxr_qbuf, .vidioc_dqbuf = mxr_dqbuf, + .vidioc_expbuf = mxr_expbuf, /* Streaming control */ .vidioc_streamon = mxr_streamon, .vidioc_streamoff = mxr_streamoff, -- 1.7.9.5
[PATCHv10 24/26] v4l: s5p-fimc: support for dmabuf exporting
This patch enhances s5p-fimc with support for DMABUF exporting via VIDIOC_EXPBUF ioctl. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: Sylwester Nawrocki Acked-by: Hans Verkuil --- drivers/media/platform/s5p-fimc/fimc-capture.c |9 + drivers/media/platform/s5p-fimc/fimc-m2m.c | 10 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 246bb32..e5fd159 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -1231,6 +1231,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv, return vb2_qbuf(&fimc->vid_cap.vbq, buf); } +static int fimc_cap_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct fimc_dev *fimc = video_drvdata(file); + + return vb2_expbuf(&fimc->vid_cap.vbq, eb); +} + static int fimc_cap_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { @@ -1355,6 +1363,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { .vidioc_qbuf= fimc_cap_qbuf, .vidioc_dqbuf = fimc_cap_dqbuf, + .vidioc_expbuf = fimc_cap_expbuf, .vidioc_prepare_buf = fimc_cap_prepare_buf, .vidioc_create_bufs = fimc_cap_create_bufs, diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c index 17067a7..1cd4fcf 100644 --- a/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c @@ -439,6 +439,15 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh, return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); } +static int fimc_m2m_expbuf(struct file *file, void *fh, + struct v4l2_exportbuffer *eb) +{ + struct fimc_ctx *ctx = fh_to_ctx(fh); + + return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb); +} + + static int fimc_m2m_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { @@ -607,6 +616,7 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { .vidioc_querybuf= fimc_m2m_querybuf, .vidioc_qbuf= fimc_m2m_qbuf, .vidioc_dqbuf = fimc_m2m_dqbuf, + .vidioc_expbuf = fimc_m2m_expbuf, .vidioc_streamon= fimc_m2m_streamon, .vidioc_streamoff = fimc_m2m_streamoff, .vidioc_g_crop = fimc_m2m_g_crop, -- 1.7.9.5
[PATCHv10 23/26] v4l: vb2-dma-contig: align buffer size to PAGE_SIZE
Most operations on DMA and DMABUF framework need page aligned buffers. This fix guarantees this requirement for vb2-dma-contig buffers. Signed-off-by: Tomasz Stanislawski --- drivers/media/v4l2-core/videobuf2-dma-contig.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 571a919..002ee50 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -162,6 +162,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) if (!buf) return ERR_PTR(-ENOMEM); + /* align image size to PAGE_SIZE */ + size = PAGE_ALIGN(size); + buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL); if (!buf->vaddr) { dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); -- 1.7.9.5
[PATCHv10 22/26] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned
From: Marek Szyprowski The DMA transfer must be aligned to a specific value. If userptr is not aligned to DMA requirements then unexpected corruptions of the memory may occur before or after a buffer. To prevent such situations, all unligned userptr buffers are rejected at VIDIOC_QBUF. Signed-off-by: Marek Szyprowski Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 2d661fd..571a919 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -493,6 +493,18 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, struct vm_area_struct *vma; struct sg_table *sgt; unsigned long contig_size; + unsigned long dma_align = dma_get_cache_alignment(); + + /* Only cache aligned DMA transfers are reliable */ + if (!IS_ALIGNED(vaddr | size, dma_align)) { + pr_debug("user data must be aligned to %lu bytes\n", dma_align); + return ERR_PTR(-EINVAL); + } + + if (!size) { + pr_debug("size is zero\n"); + return ERR_PTR(-EINVAL); + } buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) -- 1.7.9.5
[PATCHv10 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context
This patch adds taking reference to the device for MMAP buffers. Such buffers, may be exported using DMABUF mechanism. If the driver that created a queue is unloaded then the queue is released, the device might be released too. However, buffers cannot be released if they are referenced by DMABUF descriptor(s). The device pointer kept in a buffer must be valid for the whole buffer's lifetime. Therefore MMAP buffers should take a reference to the device to avoid risk of dangling pointers. Signed-off-by: Tomasz Stanislawski Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index b138b5c..2d661fd 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv) kfree(buf->sgt_base); } dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); + put_device(buf->dev); kfree(buf); } @@ -168,6 +169,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) return ERR_PTR(-ENOMEM); } + /* prevent the device from release while the buffer is exported */ + get_device(dev); + buf->dev = dev; buf->size = size; -- 1.7.9.5
[PATCHv10 20/26] v4l: vb2-dma-contig: add support for DMABUF exporting
This patch adds support for exporting a dma-contig buffer using DMABUF interface. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 200 1 file changed, 200 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 0e065ce..b138b5c 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -36,6 +36,7 @@ struct vb2_dc_buf { /* MMAP related */ struct vb2_vmarea_handler handler; atomic_trefcount; + struct sg_table *sgt_base; /* USERPTR related */ struct vm_area_struct *vma; @@ -142,6 +143,10 @@ static void vb2_dc_put(void *buf_priv) if (!atomic_dec_and_test(&buf->refcount)) return; + if (buf->sgt_base) { + sg_free_table(buf->sgt_base); + kfree(buf->sgt_base); + } dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); kfree(buf); } @@ -213,6 +218,200 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) } /*/ +/* DMABUF ops for exporters */ +/*/ + +struct vb2_dc_attachment { + struct sg_table sgt; + enum dma_data_direction dir; +}; + +static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev, + struct dma_buf_attachment *dbuf_attach) +{ + struct vb2_dc_attachment *attach; + unsigned int i; + struct scatterlist *rd, *wr; + struct sg_table *sgt; + struct vb2_dc_buf *buf = dbuf->priv; + int ret; + + attach = kzalloc(sizeof(*attach), GFP_KERNEL); + if (!attach) + return -ENOMEM; + + sgt = &attach->sgt; + /* Copy the buf->base_sgt scatter list to the attachment, as we can't +* map the same scatter list to multiple attachments at the same time. +*/ + ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL); + if (ret) { + kfree(attach); + return -ENOMEM; + } + + rd = buf->sgt_base->sgl; + wr = sgt->sgl; + for (i = 0; i < sgt->orig_nents; ++i) { + sg_set_page(wr, sg_page(rd), rd->length, rd->offset); + rd = sg_next(rd); + wr = sg_next(wr); + } + + attach->dir = DMA_NONE; + dbuf_attach->priv = attach; + + return 0; +} + +static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *db_attach) +{ + struct vb2_dc_attachment *attach = db_attach->priv; + struct sg_table *sgt; + + if (!attach) + return; + + sgt = &attach->sgt; + + /* release the scatterlist cache */ + if (attach->dir != DMA_NONE) + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dir); + sg_free_table(sgt); + kfree(attach); + db_attach->priv = NULL; +} + +static struct sg_table *vb2_dc_dmabuf_ops_map( + struct dma_buf_attachment *db_attach, enum dma_data_direction dir) +{ + struct vb2_dc_attachment *attach = db_attach->priv; + /* stealing dmabuf mutex to serialize map/unmap operations */ + struct mutex *lock = &db_attach->dmabuf->lock; + struct sg_table *sgt; + int ret; + + mutex_lock(lock); + + sgt = &attach->sgt; + /* return previously mapped sg table */ + if (attach->dir == dir) { + mutex_unlock(lock); + return sgt; + } + + /* release any previous cache */ + if (attach->dir != DMA_NONE) { + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dir); + attach->dir = DMA_NONE; + } + + /* mapping to the client with new direction */ + ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir); + if (ret <= 0) { + pr_err("failed to map scatterlist\n"); + mutex_unlock(lock); + return ERR_PTR(-EIO); + } + + attach->dir = dir; + + mutex_unlock(lock); + + return sgt; +} + +static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach, + struct sg_table *sgt, enum dma_data_direction dir) +{ + /* nothing to be done here */ +} + +static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf) +{ + /* drop reference obtained in vb2_dc_get_dmabuf */ + vb2_dc_put(dbuf->priv); +} + +static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum) +{ + struct vb2_dc_buf *buf = dbuf->priv; + + return buf->vaddr + pgnum * PAGE_SIZE; +} + +static void *vb2_dc_dmabuf_ops_vmap(struct dma
[PATCHv10 19/26] v4l: vb2: add buffer exporting via dmabuf
This patch adds extension to videobuf2-core. It allow to export a mmap buffer as a file descriptor. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-mem2mem.c | 13 + drivers/media/v4l2-core/videobuf2-core.c | 83 ++ include/media/v4l2-mem2mem.h |3 ++ include/media/videobuf2-core.h |4 ++ 4 files changed, 103 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 3ac8358..9aa7cc7 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -369,6 +369,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); /** + * v4l2_m2m_expbuf() - export a source or destination buffer, depending on + * the type + */ +int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_exportbuffer *eb) +{ + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(m2m_ctx, eb->type); + return vb2_expbuf(vq, eb); +} +EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf); +/** * v4l2_m2m_streamon() - turn on streaming for a video queue */ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 613dea1..9f81be2 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1751,6 +1751,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, } /** + * vb2_expbuf() - Export a buffer as a file descriptor + * @q: videobuf2 queue + * @eb:export buffer structure passed from userspace to vidioc_expbuf + * handler in driver + * + * The return values from this function are intended to be directly returned + * from vidioc_expbuf handler in driver. + */ +int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) +{ + struct vb2_buffer *vb = NULL; + struct vb2_plane *vb_plane; + int ret; + struct dma_buf *dbuf; + + if (q->memory != V4L2_MEMORY_MMAP) { + dprintk(1, "Queue is not currently set up for mmap\n"); + return -EINVAL; + } + + if (!q->mem_ops->get_dmabuf) { + dprintk(1, "Queue does not support DMA buffer exporting\n"); + return -EINVAL; + } + + if (eb->flags & ~O_CLOEXEC) { + dprintk(1, "Queue does support only O_CLOEXEC flag\n"); + return -EINVAL; + } + + if (eb->type != q->type) { + dprintk(1, "qbuf: invalid buffer type\n"); + return -EINVAL; + } + + if (eb->index >= q->num_buffers) { + dprintk(1, "buffer index out of range\n"); + return -EINVAL; + } + + vb = q->bufs[eb->index]; + + if (eb->plane >= vb->num_planes) { + dprintk(1, "buffer plane out of range\n"); + return -EINVAL; + } + + vb_plane = &vb->planes[eb->plane]; + + dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv); + if (IS_ERR_OR_NULL(dbuf)) { + dprintk(1, "Failed to export buffer %d, plane %d\n", + eb->index, eb->plane); + return -EINVAL; + } + + ret = dma_buf_fd(dbuf, eb->flags); + if (ret < 0) { + dprintk(3, "buffer %d, plane %d failed to export (%d)\n", + eb->index, eb->plane, ret); + dma_buf_put(dbuf); + return ret; + } + + dprintk(3, "buffer %d, plane %d exported as %d descriptor\n", + eb->index, eb->plane, ret); + eb->fd = ret; + + return 0; +} +EXPORT_SYMBOL_GPL(vb2_expbuf); + +/** * vb2_mmap() - map video buffers into application address space * @q: videobuf2 queue * @vma: vma passed to the mmap file operation handler in the driver @@ -2456,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) } EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff); +int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p) +{ + struct video_device *vdev = video_devdata(file); + + if (vb2_queue_is_busy(vdev, file)) + return -EBUSY; + return vb2_expbuf(vdev->queue, p); +} +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf); + /* v4l2_file_operations helpers */ int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 131cc4a..7e82d2b 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -111,6 +111,9 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
[PATCHv10 18/26] v4l: add buffer exporting via dmabuf
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by mmap and return a file descriptor on success. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c |1 + drivers/media/v4l2-core/v4l2-dev.c|1 + drivers/media/v4l2-core/v4l2-ioctl.c | 10 + include/linux/videodev2.h | 28 + include/media/v4l2-ioctl.h|2 ++ 5 files changed, 42 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index cc5998b..7157af3 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1018,6 +1018,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_S_FBUF32: case VIDIOC_OVERLAY32: case VIDIOC_QBUF32: + case VIDIOC_EXPBUF: case VIDIOC_DQBUF32: case VIDIOC_STREAMON32: case VIDIOC_STREAMOFF32: diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index a2df842..98dcad9 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -571,6 +571,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); + SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf); SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf); SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 530a67e..aa6e7c7 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -454,6 +454,15 @@ static void v4l_print_buffer(const void *arg, bool write_only) tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); } +static void v4l_print_exportbuffer(const void *arg, bool write_only) +{ + const struct v4l2_exportbuffer *p = arg; + + pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n", + p->fd, prt_names(p->type, v4l2_type_names), + p->index, p->plane, p->flags); +} + static void v4l_print_create_buffers(const void *arg, bool write_only) { const struct v4l2_create_buffers *p = arg; @@ -1961,6 +1970,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE), + IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)), IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE), IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 07bc5d6..19765df 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -696,6 +696,33 @@ struct v4l2_buffer { #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 +/** + * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor + * + * @index: id number of the buffer + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * @fd:file descriptor associated with DMABUF (set by driver) + * + * Contains data used for exporting a video buffer as DMABUF file descriptor. + * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF + * (identical to the cookie used to mmap() the buffer to userspace). All + * reserved fields must be set to zero. The field reserved0 is expected to + * become a structure 'type' allowing an alternative layout of the structure + * content. Therefore this field should not be used for any other extensions. + */ +struct v4l2_exportbuffer { + __u32 type; /* enum v4l2_buf_type */ + __u32 index; + __u32 plane; + __u32 flags; + __s32 fd; + __u32
[PATCHv10 17/26] Documentation: media: description of DMABUF exporting in V4L2
This patch adds description and usage examples for exporting DMABUF file descriptor in V4L2. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: linux-doc at vger.kernel.org --- Documentation/DocBook/media/v4l/compat.xml|3 + Documentation/DocBook/media/v4l/io.xml|3 + Documentation/DocBook/media/v4l/v4l2.xml |1 + Documentation/DocBook/media/v4l/vidioc-expbuf.xml | 212 + 4 files changed, 219 insertions(+) create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index 50eb630..3dd9e78 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2590,6 +2590,9 @@ ioctls. Importing DMABUF file descriptors as a new IO method described in . + + Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl. + diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index 0abb5cb..81d0ed4 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml @@ -488,6 +488,9 @@ DMA buffer from userspace using a file descriptor previously exported for a different or the same device (known as the importer role), or both. This section describes the DMABUF importer role API in V4L2. +Refer to DMABUF exporting for +details about exporting V4L2 buffers as DMABUF file descriptors. + Input and output devices support the streaming I/O method when the V4L2_CAP_STREAMING flag in the capabilities field of &v4l2-capability; returned by diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index 10ccde9..4d110b1 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml @@ -543,6 +543,7 @@ and discussions on the V4L mailing list. &sub-enuminput; &sub-enumoutput; &sub-enumstd; +&sub-expbuf; &sub-g-audio; &sub-g-audioout; &sub-g-crop; diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml new file mode 100644 index 000..72dfbd2 --- /dev/null +++ b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml @@ -0,0 +1,212 @@ + + + +ioctl VIDIOC_EXPBUF +&manvol; + + + +VIDIOC_EXPBUF +Export a buffer as a DMABUF file descriptor. + + + + + + int ioctl + int fd + int request + struct v4l2_exportbuffer *argp + + + + + +Arguments + + + + fd + + &fd; + + + + request + + VIDIOC_EXPBUF + + + + argp + + + + + + + + +Description + + + Experimental + This is an experimental + interface and may change in the future. + + +This ioctl is an extension to the memory +mapping I/O method, therefore it is available only for +V4L2_MEMORY_MMAP buffers. It can be used to export a +buffer as a DMABUF file at any time after buffers have been allocated with the +&VIDIOC-REQBUFS; ioctl. + + To export a buffer, applications fill &v4l2-exportbuffer;. The + type field is set to the same buffer type as was +previously used with &v4l2-requestbuffers; type . +Applications must also set the index field. Valid +index numbers range from zero to the number of buffers allocated with +&VIDIOC-REQBUFS; (&v4l2-requestbuffers; count ) +minus one. For the multi-planar API, applications set the plane + field to the index of the plane to be exported. Valid planes +range from zero to the maximal number of valid planes for the currently active +format. For the single-planar API, applications must set plane + to zero. Additional flags may be posted in the +flags field. Refer to a manual for open() for details. +Currently only O_CLOEXEC is supported. All other fields must be set to zero. +In the case of multi-planar API, every plane is exported separately using +multiple VIDIOC_EXPBUF calls. + + After calling VIDIOC_EXPBUF the fd + field will be set by a driver. This is a DMABUF file +descriptor. The application may pass it to other DMABUF-aware devices. Refer to +DMABUF importing for details about importing +DMABUF files into V4L2 nodes. It is recommended to close a DMABUF file when it +is no longer used to allow the associated memory to be reclaimed. + + + + + Examples + + + Exporting a buffer. + +int buffer_export(int v4lfd, &v4l2-buf-type; bt, int index, int *dmafd) +{ + &v4l2-exportbuffer; expbuf; + + memset(&expbuf, 0, sizeof(expbuf)); + expbuf.type = bt; + expbuf.index = index; + if (ioctl(v4lfd, &VIDIOC-EXPBUF;, &expbuf) == -1) { + perror("VIDIOC_EXPBUF"); + return -1; + } +
[PATCHv10 16/26] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call
From: Marek Szyprowski Let mmap method to use dma_mmap_coherent call. Moreover, this patch removes vb2_mmap_pfn_range from videobuf2 helpers as it was suggested by Laurent Pinchart. The function is no longer used in vb2 code. Signed-off-by: Marek Szyprowski Signed-off-by: Tomasz Stanislawski Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 28 +++-- drivers/media/v4l2-core/videobuf2-memops.c | 40 include/media/videobuf2-memops.h |5 --- 3 files changed, 26 insertions(+), 47 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index a5804cf..0e065ce 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -178,14 +178,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dc_buf *buf = buf_priv; + int ret; if (!buf) { printk(KERN_ERR "No buffer to map\n"); return -EINVAL; } - return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size, - &vb2_common_vm_ops, &buf->handler); + /* +* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to +* map whole buffer +*/ + vma->vm_pgoff = 0; + + ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr, + buf->dma_addr, buf->size); + + if (ret) { + pr_err("Remapping memory failed, error: %d\n", ret); + return ret; + } + + vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; + vma->vm_private_data= &buf->handler; + vma->vm_ops = &vb2_common_vm_ops; + + vma->vm_ops->open(vma); + + pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n", + __func__, (unsigned long)buf->dma_addr, vma->vm_start, + buf->size); + + return 0; } /*/ diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c index 504cd4c..81c1ad8 100644 --- a/drivers/media/v4l2-core/videobuf2-memops.c +++ b/drivers/media/v4l2-core/videobuf2-memops.c @@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, EXPORT_SYMBOL_GPL(vb2_get_contig_userptr); /** - * vb2_mmap_pfn_range() - map physical pages to userspace - * @vma: virtual memory region for the mapping - * @paddr: starting physical address of the memory to be mapped - * @size: size of the memory to be mapped - * @vm_ops:vm operations to be assigned to the created area - * @priv: private data to be associated with the area - * - * Returns 0 on success. - */ -int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr, - unsigned long size, - const struct vm_operations_struct *vm_ops, - void *priv) -{ - int ret; - - size = min_t(unsigned long, vma->vm_end - vma->vm_start, size); - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT, - size, vma->vm_page_prot); - if (ret) { - printk(KERN_ERR "Remapping memory failed, error: %d\n", ret); - return ret; - } - - vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; - vma->vm_private_data= priv; - vma->vm_ops = vm_ops; - - vma->vm_ops->open(vma); - - pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n", - __func__, paddr, vma->vm_start, size); - - return 0; -} -EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range); - -/** * vb2_common_vm_open() - increase refcount of the vma * @vma: virtual memory region for the mapping * diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h index 84e1f6c..f05444c 100644 --- a/include/media/videobuf2-memops.h +++ b/include/media/videobuf2-memops.h @@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops; int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, struct vm_area_struct **res_vma, dma_addr_t *res_pa); -int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr, - unsigned long size, - const struct vm_operations_struct *vm_ops, - void *priv); - struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma); void vb2_put_vma(struct vm_area_struct *vma); -- 1.7.9.5
[PATCHv10 15/26] v4l: s5p-fimc: support for dmabuf importing
This patch enhances s5p-fimc with support for DMABUF importing via V4L2_MEMORY_DMABUF memory type. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Sylwester Nawrocki Acked-by: Hans Verkuil --- drivers/media/platform/s5p-fimc/fimc-capture.c |2 +- drivers/media/platform/s5p-fimc/fimc-m2m.c |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 367efd1..246bb32 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -1730,7 +1730,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, q = &fimc->vid_cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - q->io_modes = VB2_MMAP | VB2_USERPTR; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = fimc->vid_cap.ctx; q->ops = &fimc_capture_qops; q->mem_ops = &vb2_dma_contig_memops; diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c index 4500e44..17067a7 100644 --- a/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c @@ -622,7 +622,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, int ret; src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - src_vq->io_modes = VB2_MMAP | VB2_USERPTR; + src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->ops = &fimc_qops; src_vq->mem_ops = &vb2_dma_contig_memops; @@ -633,7 +633,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, return ret; dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->ops = &fimc_qops; dst_vq->mem_ops = &vb2_dma_contig_memops; -- 1.7.9.5
[PATCHv10 14/26] v4l: s5p-tv: mixer: support for dmabuf importing
This patch enhances s5p-tv with support for DMABUF importing via V4L2_MEMORY_DMABUF memory type. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/platform/s5p-tv/mixer_video.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index 0c1cd89..2421e527 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c @@ -1093,7 +1093,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev, layer->vb_queue = (struct vb2_queue) { .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - .io_modes = VB2_MMAP | VB2_USERPTR, + .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF, .drv_priv = layer, .buf_struct_size = sizeof(struct mxr_buffer), .ops = &mxr_video_qops, -- 1.7.9.5
[PATCHv10 13/26] v4l: vivi: support for dmabuf importing
This patch enhances VIVI driver with a support for importing a buffer from DMABUF file descriptors. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/platform/vivi.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c index b366b05..9e077bb 100644 --- a/drivers/media/platform/vivi.c +++ b/drivers/media/platform/vivi.c @@ -1308,7 +1308,7 @@ static int __init vivi_create_instance(int inst) /* initialize queue */ q = &dev->vb_vidq; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivi_buffer); q->ops = &vivi_video_qops; -- 1.7.9.5
[PATCHv10 12/26] v4l: vb2-vmalloc: add support for dmabuf importing
This patch adds support for importing DMABUF files for vmalloc allocator in Videobuf2. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/Kconfig |1 + drivers/media/v4l2-core/videobuf2-vmalloc.c | 56 +++ 2 files changed, 57 insertions(+) diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index e30583b..65875c3 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -75,6 +75,7 @@ config VIDEOBUF2_VMALLOC tristate select VIDEOBUF2_CORE select VIDEOBUF2_MEMOPS + select DMA_SHARED_BUFFER config VIDEOBUF2_DMA_SG tristate diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 94efa04..a47fd4f 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -30,6 +30,7 @@ struct vb2_vmalloc_buf { unsigned intn_pages; atomic_trefcount; struct vb2_vmarea_handler handler; + struct dma_buf *dbuf; }; static void vb2_vmalloc_put(void *buf_priv); @@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; } +/*/ +/* callbacks for DMABUF buffers*/ +/*/ + +static int vb2_vmalloc_map_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + buf->vaddr = dma_buf_vmap(buf->dbuf); + + return buf->vaddr ? 0 : -EFAULT; +} + +static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + dma_buf_vunmap(buf->dbuf, buf->vaddr); + buf->vaddr = NULL; +} + +static void vb2_vmalloc_detach_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + if (buf->vaddr) + dma_buf_vunmap(buf->dbuf, buf->vaddr); + + kfree(buf); +} + +static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_vmalloc_buf *buf; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dbuf = dbuf; + buf->write = write; + buf->size = size; + + return buf; +} + + const struct vb2_mem_ops vb2_vmalloc_memops = { .alloc = vb2_vmalloc_alloc, .put= vb2_vmalloc_put, .get_userptr= vb2_vmalloc_get_userptr, .put_userptr= vb2_vmalloc_put_userptr, + .map_dmabuf = vb2_vmalloc_map_dmabuf, + .unmap_dmabuf = vb2_vmalloc_unmap_dmabuf, + .attach_dmabuf = vb2_vmalloc_attach_dmabuf, + .detach_dmabuf = vb2_vmalloc_detach_dmabuf, .vaddr = vb2_vmalloc_vaddr, .mmap = vb2_vmalloc_mmap, .num_users = vb2_vmalloc_num_users, -- 1.7.9.5
[PATCHv10 11/26] v4l: vb2-dma-contig: add support for dma_buf importing
From: Sumit Semwal This patch makes changes for adding dma-contig as a dma_buf user. It provides function implementations for the {attach, detach, map, unmap}_dmabuf() mem_ops of DMABUF memory type. Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal [author of the original patch] Signed-off-by: Tomasz Stanislawski [integration with refactored dma-contig allocator] Acked-by: Laurent Pinchart --- drivers/media/v4l2-core/Kconfig|1 + drivers/media/v4l2-core/videobuf2-dma-contig.c | 120 +++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 2e787cc..e30583b 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -69,6 +69,7 @@ config VIDEOBUF2_DMA_CONTIG tristate select VIDEOBUF2_CORE select VIDEOBUF2_MEMOPS + select DMA_SHARED_BUFFER config VIDEOBUF2_VMALLOC tristate diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 494a824..a5804cf 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -10,6 +10,7 @@ * the Free Software Foundation. */ +#include #include #include #include @@ -38,6 +39,9 @@ struct vb2_dc_buf { /* USERPTR related */ struct vm_area_struct *vma; + + /* DMABUF related */ + struct dma_buf_attachment *db_attach; }; /*/ @@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - if (!sgt) + /* DMABUF exporter will flush the cache for us */ + if (!sgt || buf->db_attach) return; dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); @@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - if (!sgt) + /* DMABUF exporter will flush the cache for us */ + if (!sgt || buf->db_attach) return; dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); @@ -377,6 +383,112 @@ fail_buf: } /*/ +/* callbacks for DMABUF buffers*/ +/*/ + +static int vb2_dc_map_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + struct sg_table *sgt; + unsigned long contig_size; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to pin a non attached buffer\n"); + return -EINVAL; + } + + if (WARN_ON(buf->dma_sgt)) { + pr_err("dmabuf buffer is already pinned\n"); + return 0; + } + + /* get the associated scatterlist for this buffer */ + sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); + if (IS_ERR_OR_NULL(sgt)) { + pr_err("Error getting dmabuf scatterlist\n"); + return -EINVAL; + } + + /* checking if dmabuf is big enough to store contiguous chunk */ + contig_size = vb2_dc_get_contiguous_size(sgt); + if (contig_size < buf->size) { + pr_err("contiguous chunk is too small %lu/%lu b\n", + contig_size, buf->size); + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + return -EFAULT; + } + + buf->dma_addr = sg_dma_address(sgt->sgl); + buf->dma_sgt = sgt; + + return 0; +} + +static void vb2_dc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to unpin a not attached buffer\n"); + return; + } + + if (WARN_ON(!sgt)) { + pr_err("dmabuf buffer is already unpinned\n"); + return; + } + + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + + buf->dma_addr = 0; + buf->dma_sgt = NULL; +} + +static void vb2_dc_detach_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + + /* if vb2 works correctly you should never detach mapped buffer */ + if (WARN_ON(buf->dma_addr)) + vb2_dc_unmap_dmabuf(buf); + + /* detach this attachment */ + dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach); + kfree(buf); +} + +static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_dc_conf *conf = alloc_ctx; + struct vb2_dc_buf *buf; + struct dma_buf_attachment *dba; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(siz
[PATCHv10 10/26] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator
From: Marek Szyprowski Add prepare/finish callbacks to vb2-dma-contig allocator. Signed-off-by: Marek Szyprowski Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 8486e06..494a824 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv) return atomic_read(&buf->refcount); } +static void vb2_dc_prepare(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (!sgt) + return; + + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); +} + +static void vb2_dc_finish(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (!sgt) + return; + + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); +} + /*/ /*callbacks for MMAP buffers */ /*/ @@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = { .mmap = vb2_dc_mmap, .get_userptr= vb2_dc_get_userptr, .put_userptr= vb2_dc_put_userptr, + .prepare= vb2_dc_prepare, + .finish = vb2_dc_finish, .num_users = vb2_dc_num_users, }; EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); -- 1.7.9.5
[PATCHv10 09/26] v4l: vb2: add prepare/finish callbacks to allocators
From: Marek Szyprowski This patch adds support for prepare/finish callbacks in VB2 allocators. These callback are used for buffer flushing. Signed-off-by: Marek Szyprowski Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-core.c | 11 +++ include/media/videobuf2-core.h |7 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index a51dad6..613dea1 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -844,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) { struct vb2_queue *q = vb->vb2_queue; unsigned long flags; + unsigned int plane; if (vb->state != VB2_BUF_STATE_ACTIVE) return; @@ -854,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) dprintk(4, "Done processing on buffer %d, state: %d\n", vb->v4l2_buf.index, vb->state); + /* sync buffers */ + for (plane = 0; plane < vb->num_planes; ++plane) + call_memop(q, finish, vb->planes[plane].mem_priv); + /* Add the buffer to the done buffers list */ spin_lock_irqsave(&q->done_lock, flags); vb->state = state; @@ -1136,9 +1141,15 @@ err: static void __enqueue_in_driver(struct vb2_buffer *vb) { struct vb2_queue *q = vb->vb2_queue; + unsigned int plane; vb->state = VB2_BUF_STATE_ACTIVE; atomic_inc(&q->queued_count); + + /* sync buffers */ + for (plane = 0; plane < vb->num_planes; ++plane) + call_memop(q, prepare, vb->planes[plane].mem_priv); + q->ops->buf_queue(vb); } diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 689ae4a..24b9c90 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -56,6 +56,10 @@ struct vb2_fileio_data; * dmabuf * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified * that this driver is done using the dmabuf for now + * @prepare: called every time the buffer is passed from userspace to the + * driver, useful for cache synchronisation, optional + * @finish:called every time the buffer is passed back from the driver + * to the userspace, also optional * @vaddr: return a kernel virtual address to a given memory buffer * associated with the passed private structure or NULL if no * such mapping exists @@ -82,6 +86,9 @@ struct vb2_mem_ops { unsigned long size, int write); void(*put_userptr)(void *buf_priv); + void(*prepare)(void *buf_priv); + void(*finish)(void *buf_priv); + void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf, unsigned long size, int write); void(*detach_dmabuf)(void *buf_priv); -- 1.7.9.5
[PATCHv10 08/26] v4l: vb2-dma-contig: add support for scatterlist in userptr mode
This patch introduces usage of dma_map_sg to map memory behind a userspace pointer to a device as dma-contiguous mapping. This patch contains some of the code kindly provided by Marek Szyprowski and Kamil Debski and Andrzej Pietrasiewicz . Kind thanks for bug reports from Laurent Pinchart and Seung-Woo Kim . Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 226 ++-- 1 file changed, 210 insertions(+), 16 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index daac2b2..8486e06 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -11,6 +11,8 @@ */ #include +#include +#include #include #include @@ -27,6 +29,8 @@ struct vb2_dc_buf { void*vaddr; unsigned long size; dma_addr_t dma_addr; + enum dma_data_direction dma_dir; + struct sg_table *dma_sgt; /* MMAP related */ struct vb2_vmarea_handler handler; @@ -37,6 +41,44 @@ struct vb2_dc_buf { }; /*/ +/*scatterlist table functions*/ +/*/ + + +static void vb2_dc_sgt_foreach_page(struct sg_table *sgt, + void (*cb)(struct page *pg)) +{ + struct scatterlist *s; + unsigned int i; + + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { + struct page *page = sg_page(s); + unsigned int n_pages = PAGE_ALIGN(s->offset + s->length) + >> PAGE_SHIFT; + unsigned int j; + + for (j = 0; j < n_pages; ++j, ++page) + cb(page); + } +} + +static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) +{ + struct scatterlist *s; + dma_addr_t expected = sg_dma_address(sgt->sgl); + unsigned int i; + unsigned long size = 0; + + for_each_sg(sgt->sgl, s, sgt->nents, i) { + if (sg_dma_address(s) != expected) + break; + expected = sg_dma_address(s) + sg_dma_len(s); + size += sg_dma_len(s); + } + return size; +} + +/*/ /* callbacks for all buffers */ /*/ @@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) /* callbacks for USERPTR buffers */ /*/ +static inline int vma_is_io(struct vm_area_struct *vma) +{ + return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); +} + +static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, + int n_pages, struct vm_area_struct *vma, int write) +{ + if (vma_is_io(vma)) { + unsigned int i; + + for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) { + unsigned long pfn; + int ret = follow_pfn(vma, start, &pfn); + + if (ret) { + pr_err("no page for address %lu\n", start); + return ret; + } + pages[i] = pfn_to_page(pfn); + } + } else { + int n; + + n = get_user_pages(current, current->mm, start & PAGE_MASK, + n_pages, write, 1, pages, NULL); + /* negative error means that no page was pinned */ + n = max(n, 0); + if (n != n_pages) { + pr_err("got only %d of %d user pages\n", n, n_pages); + while (n) + put_page(pages[--n]); + return -EFAULT; + } + } + + return 0; +} + +static void vb2_dc_put_dirty_page(struct page *page) +{ + set_page_dirty_lock(page); + put_page(page); +} + +static void vb2_dc_put_userptr(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + struct sg_table *sgt = buf->dma_sgt; + + dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + if (!vma_is_io(buf->vma)) + vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); + + sg_free_table(sgt); + kfree(sgt); + vb2_put_vma(buf->vma); + kfree(buf); +} + static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, - unsigned long size, int write) + unsigned long size, int write) { + struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; + unsigned long start; + unsigned long end; + unsigned long offset; +
[PATCHv10 07/26] v4l: vb2-dma-contig: reorder functions
From: Laurent Pinchart Group functions by buffer type. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 92 ++-- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 20c95da..daac2b2 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -25,14 +25,56 @@ struct vb2_dc_conf { struct vb2_dc_buf { struct device *dev; void*vaddr; - dma_addr_t dma_addr; unsigned long size; - struct vm_area_struct *vma; - atomic_trefcount; + dma_addr_t dma_addr; + + /* MMAP related */ struct vb2_vmarea_handler handler; + atomic_trefcount; + + /* USERPTR related */ + struct vm_area_struct *vma; }; -static void vb2_dc_put(void *buf_priv); +/*/ +/* callbacks for all buffers */ +/*/ + +static void *vb2_dc_cookie(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + return &buf->dma_addr; +} + +static void *vb2_dc_vaddr(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + return buf->vaddr; +} + +static unsigned int vb2_dc_num_users(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + return atomic_read(&buf->refcount); +} + +/*/ +/*callbacks for MMAP buffers */ +/*/ + +static void vb2_dc_put(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + if (!atomic_dec_and_test(&buf->refcount)) + return; + + dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); + kfree(buf); +} static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) { @@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) return buf; } -static void vb2_dc_put(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - - if (atomic_dec_and_test(&buf->refcount)) { - dma_free_coherent(buf->dev, buf->size, buf->vaddr, - buf->dma_addr); - kfree(buf); - } -} - -static void *vb2_dc_cookie(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - - return &buf->dma_addr; -} - -static void *vb2_dc_vaddr(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - if (!buf) - return NULL; - - return buf->vaddr; -} - -static unsigned int vb2_dc_num_users(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - - return atomic_read(&buf->refcount); -} - static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dc_buf *buf = buf_priv; @@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) &vb2_common_vm_ops, &buf->handler); } +/*/ +/* callbacks for USERPTR buffers */ +/*/ + static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { @@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv) kfree(buf); } +/*/ +/* DMA CONTIG exported functions */ +/*/ + const struct vb2_mem_ops vb2_dma_contig_memops = { .alloc = vb2_dc_alloc, .put= vb2_dc_put, -- 1.7.9.5
[PATCHv10 06/26] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
This patch removes a reference to alloc_ctx from an instance of a DMA contiguous buffer. It helps to avoid a risk of a dangling pointer if the context is released while the buffer is still valid. Moreover it removes one dereference step while accessing a device structure. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index a05784f..20c95da 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -23,7 +23,7 @@ struct vb2_dc_conf { }; struct vb2_dc_buf { - struct vb2_dc_conf *conf; + struct device *dev; void*vaddr; dma_addr_t dma_addr; unsigned long size; @@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv); static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) { struct vb2_dc_conf *conf = alloc_ctx; + struct device *dev = conf->dev; struct vb2_dc_buf *buf; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM); - buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr, - GFP_KERNEL); + buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL); if (!buf->vaddr) { - dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", - size); + dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); kfree(buf); return ERR_PTR(-ENOMEM); } - buf->conf = conf; + buf->dev = dev; buf->size = size; buf->handler.refcount = &buf->refcount; @@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; if (atomic_dec_and_test(&buf->refcount)) { - dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr, + dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); kfree(buf); } -- 1.7.9.5
[PATCHv10 05/26] v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc
From: Laurent Pinchart Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 36 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 4b71326..a05784f 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -32,9 +32,9 @@ struct vb2_dc_buf { struct vb2_vmarea_handler handler; }; -static void vb2_dma_contig_put(void *buf_priv); +static void vb2_dc_put(void *buf_priv); -static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) +static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) { struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; @@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) buf->size = size; buf->handler.refcount = &buf->refcount; - buf->handler.put = vb2_dma_contig_put; + buf->handler.put = vb2_dc_put; buf->handler.arg = buf; atomic_inc(&buf->refcount); @@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) return buf; } -static void vb2_dma_contig_put(void *buf_priv) +static void vb2_dc_put(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; @@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv) } } -static void *vb2_dma_contig_cookie(void *buf_priv) +static void *vb2_dc_cookie(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; return &buf->dma_addr; } -static void *vb2_dma_contig_vaddr(void *buf_priv) +static void *vb2_dc_vaddr(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; if (!buf) @@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv) return buf->vaddr; } -static unsigned int vb2_dma_contig_num_users(void *buf_priv) +static unsigned int vb2_dc_num_users(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; return atomic_read(&buf->refcount); } -static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma) +static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dc_buf *buf = buf_priv; @@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma) &vb2_common_vm_ops, &buf->handler); } -static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr, +static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { struct vb2_dc_buf *buf; @@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr, return buf; } -static void vb2_dma_contig_put_userptr(void *mem_priv) +static void vb2_dc_put_userptr(void *mem_priv) { struct vb2_dc_buf *buf = mem_priv; @@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv) } const struct vb2_mem_ops vb2_dma_contig_memops = { - .alloc = vb2_dma_contig_alloc, - .put= vb2_dma_contig_put, - .cookie = vb2_dma_contig_cookie, - .vaddr = vb2_dma_contig_vaddr, - .mmap = vb2_dma_contig_mmap, - .get_userptr= vb2_dma_contig_get_userptr, - .put_userptr= vb2_dma_contig_put_userptr, - .num_users = vb2_dma_contig_num_users, + .alloc = vb2_dc_alloc, + .put= vb2_dc_put, + .cookie = vb2_dc_cookie, + .vaddr = vb2_dc_vaddr, + .mmap = vb2_dc_mmap, + .get_userptr= vb2_dc_get_userptr, + .put_userptr= vb2_dc_put_userptr, + .num_users = vb2_dc_num_users, }; EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); -- 1.7.9.5
[PATCHv10 04/26] v4l: vb: remove warnings about MEMORY_DMABUF
From: Sumit Semwal Adding DMABUF memory type causes videobuf to complain about not using it in some switch cases. This patch removes these warnings. Signed-off-by: Sumit Semwal Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf-core.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c index bf7a326..5449e8a 100644 --- a/drivers/media/v4l2-core/videobuf-core.c +++ b/drivers/media/v4l2-core/videobuf-core.c @@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, case V4L2_MEMORY_OVERLAY: b->m.offset = vb->boff; break; + case V4L2_MEMORY_DMABUF: + /* DMABUF is not handled in videobuf framework */ + break; } b->flags= 0; @@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q, break; case V4L2_MEMORY_USERPTR: case V4L2_MEMORY_OVERLAY: + case V4L2_MEMORY_DMABUF: /* nothing */ break; } -- 1.7.9.5
[PATCHv10 03/26] v4l: vb2: add support for shared buffer (dma_buf)
From: Sumit Semwal This patch adds support for DMABUF memory type in videobuf2. It calls relevant APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations. For this version, the support is for videobuf2 as a user of the shared buffer; so the allocation of the buffer is done outside of V4L2. [A sample allocator of dma-buf shared buffer is given at [1]] [1]: Rob Clark's DRM: https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf Signed-off-by: Tomasz Stanislawski [original work in the PoC for buffer sharing] Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/Kconfig |1 + drivers/media/v4l2-core/videobuf2-core.c | 206 +- include/media/videobuf2-core.h | 27 3 files changed, 231 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 0c54e19..2e787cc 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -59,6 +59,7 @@ config VIDEOBUF_DVB # Used by drivers that need Videobuf2 modules config VIDEOBUF2_CORE + select DMA_SHARED_BUFFER tristate config VIDEOBUF2_MEMOPS diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 432df11..a51dad6 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb) } /** + * __vb2_plane_dmabuf_put() - release memory associated with + * a DMABUF shared plane + */ +static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p) +{ + if (!p->mem_priv) + return; + + if (p->dbuf_mapped) + call_memop(q, unmap_dmabuf, p->mem_priv); + + call_memop(q, detach_dmabuf, p->mem_priv); + dma_buf_put(p->dbuf); + memset(p, 0, sizeof(*p)); +} + +/** + * __vb2_buf_dmabuf_put() - release memory associated with + * a DMABUF shared buffer + */ +static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb) +{ + struct vb2_queue *q = vb->vb2_queue; + unsigned int plane; + + for (plane = 0; plane < vb->num_planes; ++plane) + __vb2_plane_dmabuf_put(q, &vb->planes[plane]); +} + +/** * __setup_offsets() - setup unique offsets ("cookies") for every plane in * every buffer on the queue */ @@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers) /* Free MMAP buffers or release USERPTR buffers */ if (q->memory == V4L2_MEMORY_MMAP) __vb2_buf_mem_free(vb); + else if (q->memory == V4L2_MEMORY_DMABUF) + __vb2_buf_dmabuf_put(vb); else __vb2_buf_userptr_put(vb); } @@ -362,6 +394,8 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) b->m.offset = vb->v4l2_planes[0].m.mem_offset; else if (q->memory == V4L2_MEMORY_USERPTR) b->m.userptr = vb->v4l2_planes[0].m.userptr; + else if (q->memory == V4L2_MEMORY_DMABUF) + b->m.fd = vb->v4l2_planes[0].m.fd; } /* @@ -454,13 +488,28 @@ static int __verify_mmap_ops(struct vb2_queue *q) } /** + * __verify_dmabuf_ops() - verify that all memory operations required for + * DMABUF queue type have been provided + */ +static int __verify_dmabuf_ops(struct vb2_queue *q) +{ + if (!(q->io_modes & VB2_DMABUF) || !q->mem_ops->attach_dmabuf || + !q->mem_ops->detach_dmabuf || !q->mem_ops->map_dmabuf || + !q->mem_ops->unmap_dmabuf) + return -EINVAL; + + return 0; +} + +/** * __verify_memory_type() - Check whether the memory type and buffer type * passed to a buffer operation are compatible with the queue. */ static int __verify_memory_type(struct vb2_queue *q, enum v4l2_memory memory, enum v4l2_buf_type type) { - if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) { + if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR && + memory != V4L2_MEMORY_DMABUF) { dprintk(1, "reqbufs: unsupported memory type\n"); return -EINVAL; } @@ -484,6 +533,11 @@ static int __verify_memory_type(struct vb2_queue *q, return -EINVAL; } + if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) { + dprintk(1, "reqbufs: DMABUF for current setup unsupported\n"); + return -EINVAL; + } + /* * Place the busy tests at the end: -EBUSY can be ignored when * create_bufs is called with count == 0, but count == 0 should still @@ -845,6 +899,16 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
[PATCHv10 02/26] Documentation: media: description of DMABUF importing in V4L2
This patch adds description and usage examples for importing DMABUF file descriptor in V4L2. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: linux-doc at vger.kernel.org --- Documentation/DocBook/media/v4l/compat.xml |4 + Documentation/DocBook/media/v4l/io.xml | 181 +++- .../DocBook/media/v4l/vidioc-create-bufs.xml | 16 +- Documentation/DocBook/media/v4l/vidioc-qbuf.xml| 17 ++ Documentation/DocBook/media/v4l/vidioc-reqbufs.xml | 47 ++--- 5 files changed, 235 insertions(+), 30 deletions(-) diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index 4fdf6b5..50eb630 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2586,6 +2586,10 @@ ioctls. Vendor and device specific media bus pixel formats. . + + Importing DMABUF file descriptors as a new IO method described + in . + diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index b5d1cbd..0abb5cb 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml @@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By default outgoing queue. When the O_NONBLOCK flag was given to the &func-open; function, VIDIOC_DQBUF returns immediately with an &EAGAIN; when no buffer is available. The -&func-select; or &func-poll; function are always available. +&func-select; or &func-poll; functions are always available. To start and stop capturing or output applications call the &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note @@ -472,6 +472,162 @@ rest should be evident. + +Streaming I/O (DMA buffer importing) + + + Experimental + This is an experimental + interface and may change in the future. + + +The DMABUF framework provides a generic method for sharing buffers +between multiple devices. Device drivers that support DMABUF can export a DMA +buffer to userspace as a file descriptor (known as the exporter role), import a +DMA buffer from userspace using a file descriptor previously exported for a +different or the same device (known as the importer role), or both. This +section describes the DMABUF importer role API in V4L2. + +Input and output devices support the streaming I/O method when the +V4L2_CAP_STREAMING flag in the +capabilities field of &v4l2-capability; returned by +the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through +DMABUF file descriptors is supported is determined by calling the +&VIDIOC-REQBUFS; ioctl with the memory type set to +V4L2_MEMORY_DMABUF. + +This I/O method is dedicated to sharing DMA buffers between different +devices, which may be V4L devices or other video-related devices (e.g. DRM). +Buffers (planes) are allocated by a driver on behalf of an application. Next, +these buffers are exported to the application as file descriptors using an API +which is specific for an allocator driver. Only such file descriptor are +exchanged. The descriptors and meta-information are passed in &v4l2-buffer; (or +in &v4l2-plane; in the multi-planar API case). The driver must be switched +into DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the desired buffer +type. + + + Initiating streaming I/O with DMABUF file descriptors + + +&v4l2-requestbuffers; reqbuf; + +memset(&reqbuf, 0, sizeof (reqbuf)); +reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +reqbuf.memory = V4L2_MEMORY_DMABUF; +reqbuf.count = 1; + +if (ioctl(fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) { + if (errno == EINVAL) + printf("Video capturing or DMABUF streaming is not supported\n"); + else + perror("VIDIOC_REQBUFS"); + + exit(EXIT_FAILURE); +} + + + +The buffer (plane) file descriptor is passed on the fly with the +&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be +associated with a different DMABUF descriptor. Although buffers are commonly +cycled, applications can pass a different DMABUF descriptor at each +VIDIOC_QBUF call. + + + Queueing DMABUF using single plane API + + +int buffer_queue(int v4lfd, int index, int dmafd) +{ + &v4l2-buffer; buf; + + memset(&buf, 0, sizeof buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_DMABUF; + buf.index = index; + buf.m.fd = dmafd; + + if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) { + perror("VIDIOC_QBUF"); + return -1; + } + + return 0; +} + + + + + Queueing DMABUF using multi plane API + + +int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes) +{ + &v4l2-buffer; buf; + &v4l2-plane; planes[VIDEO_MAX_PLANES]; + int i; + + memset(&buf, 0, size
[PATCHv10 01/26] v4l: Add DMABUF as a memory type
From: Sumit Semwal Adds DMABUF memory type to v4l framework. Also adds the related file descriptor in v4l2_plane and v4l2_buffer. Signed-off-by: Tomasz Stanislawski [original work in the PoC for buffer sharing] Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 18 ++ drivers/media/v4l2-core/v4l2-ioctl.c |1 + include/linux/videodev2.h |7 +++ 3 files changed, 26 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 83ffb64..cc5998b 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -297,6 +297,7 @@ struct v4l2_plane32 { union { __u32 mem_offset; compat_long_t userptr; + __s32 fd; } m; __u32 data_offset; __u32 reserved[11]; @@ -318,6 +319,7 @@ struct v4l2_buffer32 { __u32 offset; compat_long_t userptr; compat_caddr_t planes; + __s32 fd; } m; __u32 length; __u32 reserved2; @@ -341,6 +343,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32, up_pln = compat_ptr(p); if (put_user((unsigned long)up_pln, &up->m.userptr)) return -EFAULT; + } else if (memory == V4L2_MEMORY_DMABUF) { + if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int))) + return -EFAULT; } else { if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset, sizeof(__u32))) @@ -364,6 +369,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32, if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset, sizeof(__u32))) return -EFAULT; + /* For DMABUF, driver might've set up the fd, so copy it back. */ + if (memory == V4L2_MEMORY_DMABUF) + if (copy_in_user(&up32->m.fd, &up->m.fd, + sizeof(int))) + return -EFAULT; return 0; } @@ -446,6 +456,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user if (get_user(kp->m.offset, &up->m.offset)) return -EFAULT; break; + case V4L2_MEMORY_DMABUF: + if (get_user(kp->m.fd, &up->m.fd)) + return -EFAULT; + break; } } @@ -510,6 +524,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user if (put_user(kp->m.offset, &up->m.offset)) return -EFAULT; break; + case V4L2_MEMORY_DMABUF: + if (put_user(kp->m.fd, &up->m.fd)) + return -EFAULT; + break; } } diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 8f388ff..530a67e 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = { [V4L2_MEMORY_MMAP]= "mmap", [V4L2_MEMORY_USERPTR] = "userptr", [V4L2_MEMORY_OVERLAY] = "overlay", + [V4L2_MEMORY_DMABUF] = "dmabuf", }; #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown") diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 873adbe..07bc5d6 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -188,6 +188,7 @@ enum v4l2_memory { V4L2_MEMORY_MMAP = 1, V4L2_MEMORY_USERPTR = 2, V4L2_MEMORY_OVERLAY = 3, + V4L2_MEMORY_DMABUF = 4, }; /* see also http://vektor.theorem.ca/graphics/ycbcr/ */ @@ -604,6 +605,8 @@ struct v4l2_requestbuffers { * should be passed to mmap() called on the video node) * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer * pointing to this plane + * @fd:when memory is V4L2_MEMORY_DMABUF, a userspace file + * descriptor associated with this plane * @data_offset: offset in the plane to the start of data; usually 0, * unless there is a header in front of the data * @@ -618,6 +621,7 @@ struct v4l2_plane { union { __u32
[PATCHv10 00/26] Integration of videobuf2 with DMABUF
Hello everyone, This patchset adds support for DMABUF [2] importing and exporting to V4L2 stack. v10: - rebase on media-next 3.7 - typos and style fixes in Documentation (from Hans Verkuil) - fix compilation error with __fill_vb2_buffer - fix uninitialized data_offset for single-planar queue - support for DMABUF importing in S5P-FIMC mem-to-mem interface - update layout of v4l2_exportbuffer structure - update ioctl flags in v4l2_ioctls for VIDIOC_EXPBUF - support for DMABUF exporting in m2m framework - allow exporting for file handles that calle REQBUBS/CREATE_BUF - simplify handling of get_device in vb2_dc_alloc - reduce pr_err to pr_debug while checking alignment of userptr - check size of userptr buffer against zero - align size to PAGE_SIZE at allocation of dma-contig buffer v9: - rebase on 3.6 - change type for fs to __s32 - add support for vb2_ioctl_expbuf - remove patch 'v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING', it will be posted as a separate patch - fix typos and style in Documentation (from Hans Verkuil) - only vb2-core and vb2-dma-contig selects DMA_SHARED_BUFFER in Kconfig - use data_offset and length while queueing DMABUF - return the most recently used fd at VIDIOC_DQBUF - use (buffer-type, index, plane) tuple instead of mem_offset to identify a for exporting (from Hans Verkuil) - support for DMABUF mmap in vb2-dma-contig (from Laurent Pinchart) - add testing alignment of vaddr and size while verifying userptr against DMA capabilities (from Laurent Pinchart) - substitute VM_DONTDUMP with VM_RESERVED - simplify error handling in vb2_dc_get_dmabuf (from Laurent Pinchart) v8: - rebased on 3.6-rc1 - merged importer and exporter patchsets - fixed missing fields in v4l2_plane32 and v4l2_buffer32 structs - fixed typos/style in documentation - significant reduction of warnings from checkpatch.pl - fixed STREAMOFF issues reported by Dima Zavin [4] by adding __vb2_dqbuf helper to vb2-core - DC fails if userptr is not correctly aligned - add support for DMA attributes in DC - add support for buffers with no kernel mapping - add reference counting on device from allocator context - dummy support for mmap - use dma_get_sgtable, drop vb2_dc_kaddr_to_pages hack and vb2_dc_get_base_sgt helper v7: - support for V4L2_MEMORY_DMABUF in v4l2-compact-ioctl32.c - cosmetic fixes to the documentation - added importing for vmalloc because vmap support in dmabuf for 3.5 was pull-requested - support for dmabuf importing for VIVI - resurrect allocation of dma-contig context - remove reference of alloc_ctx in dma-contig buffer - use sg_alloc_table_from_pages - fix DMA scatterlist calls to use orig_nents instead of nents - fix memleak in vb2_dc_sgt_foreach_page (use orig_nents instead of nents) v6: - fixed missing entry in v4l2_memory_names - fixed a bug occuring after get_user_pages failure - fixed a bug caused by using invalid vma for get_user_pages - prepare/finish no longer call dma_sync for dmabuf buffers v5: - removed change of importer/exporter behaviour - fixes vb2_dc_pages_to_sgt basing on Laurent's hints - changed pin/unpin words to lock/unlock in Doc v4: - rebased on mainline 3.4-rc2 - included missing importing support for s5p-fimc and s5p-tv - added patch for changing map/unmap for importers - fixes to Documentation part - coding style fixes - pairing {map/unmap}_dmabuf in vb2-core - fixing variable types and semantic of arguments in videobufb2-dma-contig.c v3: - rebased on mainline 3.4-rc1 - split 'code refactor' patch to multiple smaller patches - squashed fixes to Sumit's patches - patchset is no longer dependant on 'DMA mapping redesign' - separated path for handling IO and non-IO mappings - add documentation for DMABUF importing to V4L - removed all DMABUF exporter related code - removed usage of dma_get_pages extension v2: - extended VIDIOC_EXPBUF argument from integer memoffset to struct v4l2_exportbuffer - added patch that breaks DMABUF spec on (un)map_atachment callcacks but allows to work with existing implementation of DMABUF prime in DRM - all dma-contig code refactoring patches were squashed - bugfixes v1: List of changes since [1]. - support for DMA api extension dma_get_pages, the function is used to retrieve pages used to create DMA mapping. - small fixes/code cleanup to videobuf2 - added prepare and finish callbacks to vb2 allocators, it is used keep consistency between dma-cpu acess to the memory (by Marek Szyprowski) - support for exporting of DMABUF buffer in V4L2 and Videobuf2, originated from [3]. - support for dma-buf exporting in vb2-dma-contig allocator - support for DMABUF for s5p-tv and s5p-fimc (capture interface) drivers, originated from [3] - changed handling for userptr buffers (by Marek Szyprowski, Andrzej Pietrasiewicz) - let mmap method to use dma_mmap_writecombine call (by Marek Szyprowski) [1] http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/42966/focus=42968 [2] https://lkml.org/lkml/2011/12/26/29 [3]
Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
On Thu, Oct 11, 2012 at 4:17 AM, Alan Cox wrote: > On Wed, 10 Oct 2012 08:56:32 -0700 > Robert Morell wrote: > >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation >> issue, and not really an interface". The dma-buf infrastructure is >> explicitly intended as an interface between modules/drivers, so it >> should use EXPORT_SYMBOL instead. > > NAK. This needs at the very least the approval of all rights holders for > the files concerned and all code exposed by this change. I think he has that. Maybe he just needs to list them. But this doesn't change the license on the code at all really, so its actually not like a re-license where you need approval. But in any case I personally don't care about this interface being used if the alternative is they do it themselves. I'm still not going to debug things with a binary module taint. Dave. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv9 19/25] v4l: vb2: add buffer exporting via dmabuf
On 10/06/2012 02:22 PM, Hans Verkuil wrote: > On Tue October 2 2012 16:27:30 Tomasz Stanislawski wrote: >> This patch adds extension to videobuf2-core. It allow to export a mmap buffer >> as a file descriptor. >> >> Signed-off-by: Tomasz Stanislawski >> Signed-off-by: Kyungmin Park >> Acked-by: Laurent Pinchart >> --- >> drivers/media/video/videobuf2-core.c | 82 >> ++ >> include/media/videobuf2-core.h |4 ++ >> 2 files changed, 86 insertions(+) >> >> diff --git a/drivers/media/video/videobuf2-core.c >> b/drivers/media/video/videobuf2-core.c >> index 05da3b4..a97815b 100644 >> --- a/drivers/media/video/videobuf2-core.c >> +++ b/drivers/media/video/videobuf2-core.c > > > >> @@ -2455,6 +2528,15 @@ int vb2_ioctl_streamoff(struct file *file, void >> *priv, enum v4l2_buf_type i) >> } >> EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff); >> >> +int vb2_ioctl_expbuf(struct file *file, void *priv, struct >> v4l2_exportbuffer *p) >> +{ >> +struct video_device *vdev = video_devdata(file); >> + >> +/* No need to call vb2_queue_is_busy(), anyone can export buffers. */ Hi Hans, > > After thinking about this some more I'm not so sure we should allow this. > Exporting a buffer also means that the memory can't be freed as long as the > exported filehandle remains open. > You are completely right. But the problem is much more complex ... see below. > That means that it is possible to make a malicious application that exports > the buffers and never frees them, which can cause havoc. What kind of havoc do you mean? Resource leakage? > I think that only > the filehandle that called REQBUFS/CREATE_BUFS should be allowed to export > buffers. Notice that you should allow to call mmap() only for the file handles that called REQBUFS/CREATE_BUFS. The mmap() creates a vma that holds a reference to a buffer. As long as the mapping exists, the buffers cannot be freed and REQBUFS(count=0) returns -EBUSY. According to V4L2 spec all the nodes share the same context, therefore one process can call REQBUFS, and the other can call QUERYBUF and mmap(). Therefore if EXPBUF has to check vb2_queue_is_busy() then vb2_fop_mmap() should do the same check too. IMO, it is very difficult to develop a useful multi-client API that would protect V4L2 from creating non-freeable buffers by a rogue applications. I think that the requirements below: - the buffers should be sharable between processes by mmap(), or DMABUF exporting - the REQBUFS(count=0) should release the buffers are contradictory and cannot be *reliably* satisfied at the same time. Notice that REQBUFS(count=0) that unexpectedly return -EBUSY is not a reliable solution. The application cannot do anything fix the problem after receiving -EBUSY. Anyway, I will apply the check for vb2_queue_is_busy() in v2b_ioctl_expbuf(). Regards, Tomasz Stanislawski > > What do you think? > > Regards, > > Hans > >> +return vb2_expbuf(vdev->queue, p); >> +} >> +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf); >> + >> /* v4l2_file_operations helpers */ >> >> int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
[PATCH] dma-buf: Use EXPORT_SYMBOL
On Wed, Oct 10, 2012 at 1:17 PM, Alan Cox wrote: > On Wed, 10 Oct 2012 08:56:32 -0700 > Robert Morell wrote: > >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation >> issue, and not really an interface". The dma-buf infrastructure is >> explicitly intended as an interface between modules/drivers, so it >> should use EXPORT_SYMBOL instead. > > NAK. This needs at the very least the approval of all rights holders for > the files concerned and all code exposed by this change. Well, for my contributions to dmabuf, I don't object.. and I think because we are planning to use dma-buf in userspace for dri3 / dri-next, I think that basically makes it a userspace facing kernel infrastructure which would be required for open and proprietary drivers alike. So I don't see much alternative to making this EXPORT_SYMBOL(). Of course, IANAL. BR, -R > Also I'd note if you are trying to do this for the purpose of combining > it with proprietary code then you are still in my view as a (and the view > of many other) rights holder to the kernel likely to be in breach > of the GPL requirements for a derivative work. You may consider that > formal notification of my viewpoint. Your corporate legal team can > explain to you why the fact you are now aware of my view is important to > them. > > Alan > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv9 00/25] Integration of videobuf2 with DMABUF
Hi Mauro, On Wednesday 10 October 2012 07:54:18 Mauro Carvalho Chehab wrote: > Em Tue, 02 Oct 2012 16:27:11 +0200 Tomasz Stanislawski escreveu: > > Hello everyone, > > This patchset adds support for DMABUF [2] importing and exporting to V4L2 > > stack. > > > > v9: > > - rebase on 3.6 > > - change type for fs to __s32 > > - add support for vb2_ioctl_expbuf > > - remove patch 'v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING', > > it will be posted as a separate patch > > - fix typos and style in Documentation (from Hans Verkuil) > > - only vb2-core and vb2-dma-contig selects DMA_SHARED_BUFFER in Kconfig > > - use data_offset and length while queueing DMABUF > > - return the most recently used fd at VIDIOC_DQBUF > > - use (buffer-type, index, plane) tuple instead of mem_offset > > to identify a for exporting (from Hans Verkuil) > > - support for DMABUF mmap in vb2-dma-contig (from Laurent Pinchart) > > - add testing alignment of vaddr and size while verifying userptr > > against DMA capabilities (from Laurent Pinchart) > > - substitute VM_DONTDUMP with VM_RESERVED > > - simplify error handling in vb2_dc_get_dmabuf (from Laurent Pinchart) > > For now, NACK. See below. > > I spent 4 days trying to setup an environment that would allow testing > DMABUF with video4linux without success (long story, see below). Also, > Laurent tried the same without any luck, and it seems that it even > corrupted his test machine. To be exact, the i915 driver crashed, not due to DMABUF but because it lacks support for YUV frame buffer on the CRTC (YUV is only supported in extra planes) and failed to properly reject the set mode ioctl. My test machine is doing fine :-) I'll modify the test application to create a YUV plane and will let you know about the result. > Basically Samsung generously donated me two boards that it could be > used on this test (Origen and SMDK310). None of them actually worked > with the upstream kernel: patches are needed to avoid OOPSes on > Origen; both Origen/SMDK310 defconfigs are completely broken, and drivers > don't even boot if someone tries to use the Kernel's defconfigs. > > Even after spending _days_ trying to figure out the needed .config options > (as the config files are not easily available), both boards have... issues: > > - lack of any display output driver at SMDK310; > > - lack of any network driver at Origen: it seems that none of > the available network options on Origen was upstreamed: no Bluetooth, no > OTG, no Wifi. > > The only test I was able to do (yesterday, late night), the DMABUF caused > an OOPS at the Origen board. So, for sure it is not ready for upstream. > > It is now, too late for 3.7. I might consider it to 3.8, if something > can be done to fix the existing issues, and setup a proper setup, using > the upstream Kernel. -- Regards, Laurent Pinchart
Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
Em Wed, 10 Oct 2012 08:56:32 -0700 Robert Morell escreveu: > EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > issue, and not really an interface". The dma-buf infrastructure is > explicitly intended as an interface between modules/drivers, so it > should use EXPORT_SYMBOL instead. > > Signed-off-by: Robert Morell NAK, as already explained at: http://lists.freedesktop.org/archives/dri-devel/2012-January/018281.html Regards, Mauro ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCHv9 00/25] Integration of videobuf2 with DMABUF
Hi, Em Tue, 02 Oct 2012 16:27:11 +0200 Tomasz Stanislawski escreveu: > Hello everyone, > This patchset adds support for DMABUF [2] importing and exporting to V4L2 > stack. > > v9: > - rebase on 3.6 > - change type for fs to __s32 > - add support for vb2_ioctl_expbuf > - remove patch 'v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING', > it will be posted as a separate patch > - fix typos and style in Documentation (from Hans Verkuil) > - only vb2-core and vb2-dma-contig selects DMA_SHARED_BUFFER in Kconfig > - use data_offset and length while queueing DMABUF > - return the most recently used fd at VIDIOC_DQBUF > - use (buffer-type, index, plane) tuple instead of mem_offset > to identify a for exporting (from Hans Verkuil) > - support for DMABUF mmap in vb2-dma-contig (from Laurent Pinchart) > - add testing alignment of vaddr and size while verifying userptr > against DMA capabilities (from Laurent Pinchart) > - substitute VM_DONTDUMP with VM_RESERVED > - simplify error handling in vb2_dc_get_dmabuf (from Laurent Pinchart) For now, NACK. See below. I spent 4 days trying to setup an environment that would allow testing DMABUF with video4linux without success (long story, see below). Also, Laurent tried the same without any luck, and it seems that it even corrupted his test machine. Basically Samsung generously donated me two boards that it could be used on this test (Origen and SMDK310). None of them actually worked with the upstream kernel: patches are needed to avoid OOPSes on Origen; both Origen/SMDK310 defconfigs are completely broken, and drivers don't even boot if someone tries to use the Kernel's defconfigs. Even after spending _days_ trying to figure out the needed .config options (as the config files are not easily available), both boards have... issues: - lack of any display output driver at SMDK310; - lack of any network driver at Origen: it seems that none of the available network options on Origen was upstreamed: no Bluetooth, no OTG, no Wifi. The only test I was able to do (yesterday, late night), the DMABUF caused an OOPS at the Origen board. So, for sure it is not ready for upstream. It is now, too late for 3.7. I might consider it to 3.8, if something can be done to fix the existing issues, and setup a proper setup, using the upstream Kernel. Regards, Mauro ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 55819] Mouse cursor corruption when moving between monitors
https://bugs.freedesktop.org/show_bug.cgi?id=55819 --- Comment #8 from Nikolaus Rath --- On 10/10/2012 09:39 AM, bugzilla-daemon at freedesktop.org wrote: > *Comment # 7 <https://bugs.freedesktop.org/show_bug.cgi?id=55819#c7> on > bug 55819 <https://bugs.freedesktop.org/show_bug.cgi?id=55819> from > Michel D?nzer <mailto:michel at daenzer.net> * > > (In reply to comment #6 ) >> I'm using 3.2.0 from Jul 23, so I believe I have the fix. > > It's unlikely, as the fix was only backported to the upstream 3.2 stable > branch > on August 2nd. > >> Is there a way to know for sure? > > Sure, inspecting the source code for your kernel. :) You're right, the patch wasn't included. Luckily it applies cleanly though. I'm rebuilding 3.2.0 with the patch now. Will report back if the problem occurs again. Best, -Nikolaus -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/5a439774/attachment.html>
Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
On Wed, Oct 10, 2012 at 1:17 PM, Alan Cox wrote: > On Wed, 10 Oct 2012 08:56:32 -0700 > Robert Morell wrote: > >> EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation >> issue, and not really an interface". The dma-buf infrastructure is >> explicitly intended as an interface between modules/drivers, so it >> should use EXPORT_SYMBOL instead. > > NAK. This needs at the very least the approval of all rights holders for > the files concerned and all code exposed by this change. Well, for my contributions to dmabuf, I don't object.. and I think because we are planning to use dma-buf in userspace for dri3 / dri-next, I think that basically makes it a userspace facing kernel infrastructure which would be required for open and proprietary drivers alike. So I don't see much alternative to making this EXPORT_SYMBOL(). Of course, IANAL. BR, -R > Also I'd note if you are trying to do this for the purpose of combining > it with proprietary code then you are still in my view as a (and the view > of many other) rights holder to the kernel likely to be in breach > of the GPL requirements for a derivative work. You may consider that > formal notification of my viewpoint. Your corporate legal team can > explain to you why the fact you are now aware of my view is important to > them. > > Alan > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 40211] texture probleme in wolfenstein enemy territory rv770
https://bugs.freedesktop.org/show_bug.cgi?id=40211 --- Comment #11 from pitam...@free.fr --- yes, using Debian Sid, the libgl1-mesa-* package are multi-arch ready. dpkg -L libgl1-mesa-glx:i386 shows: . /usr/lib/i386-linux-gnu/libGL.so.1.2 . . . I have installed the libtxc-dxtn-s2tc0 both x86_64 and i386 I suppose Enemy Territory would complain if 32bit libGL was not installed. However, using wine on simple win32 opengGL binary demo http://freewebs.com/mannymax/cpp/GLTest.exe I get: err:winediag:X11DRV_WineGL_InitOpenglInfo Direct rendering is disabled, most likely your OpenGL drivers haven't been installed correctly (using GL renderer "Gallium 0.4 on AMD RV770", version "1.4 (2.1 Mesa 8.0.4)"). Despite the above error, the demo run (I see a multicolor pyramyd and cube, moving) I don't know what to think, wine is reporting Gallium and Mesa 8.0.4... -- You are receiving this mail because: You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm: avoid passing null pointer to memset
On Tue, 9 Oct 2012 16:56:58 -0300, Rodrigo Vivi wrote: > When cmd isn't IOC_IN | IOC_OUT a null "kdata" goes to "memset", which > dereferences it. > > v2: simpler version just using usize = 0 instead of allocating useless memory > > Signed-off-by: Rodrigo Vivi Presuming that coverity is smart enough not to complain about memcpy(NULL, src, 0), Reviewed-by: Chris Wilson -Chris -- Chris Wilson, Intel Open Source Technology Centre
[Bug 55819] Mouse cursor corruption when moving between monitors
https://bugs.freedesktop.org/show_bug.cgi?id=55819 --- Comment #7 from Michel D?nzer --- (In reply to comment #6) > I'm using 3.2.0 from Jul 23, so I believe I have the fix. It's unlikely, as the fix was only backported to the upstream 3.2 stable branch on August 2nd. > Is there a way to know for sure? Sure, inspecting the source code for your kernel. :) -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/701969b4/attachment.html>
[PATCH] dma-buf: Use EXPORT_SYMBOL
Em Wed, 10 Oct 2012 08:56:32 -0700 Robert Morell escreveu: > EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > issue, and not really an interface". The dma-buf infrastructure is > explicitly intended as an interface between modules/drivers, so it > should use EXPORT_SYMBOL instead. > > Signed-off-by: Robert Morell NAK, as already explained at: http://lists.freedesktop.org/archives/dri-devel/2012-January/018281.html Regards, Mauro
[PATCH -next] drm: fix radeon printk format warnings
From: Randy Dunlap Fix printk format warnings in gpu/drm/radeon/: drivers/gpu/drm/radeon/radeon_atpx_handler.c:151:3: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'size_t' drivers/gpu/drm/radeon/radeon_acpi.c:204:3: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'size_t' drivers/gpu/drm/radeon/radeon_acpi.c:488:3: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'size_t' Signed-off-by: Randy Dunlap Cc: David Airlie Cc: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/radeon/radeon_acpi.c |4 ++-- drivers/gpu/drm/radeon/radeon_atpx_handler.c |2 +- 2 files changed, 3 insertions(+), 3 deletions(-) --- linux-next-20121010.orig/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ linux-next-20121010/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -148,7 +148,7 @@ static int radeon_atpx_verify_interface( size = *(u16 *) info->buffer.pointer; if (size < 8) { - printk("ATPX buffer is too small: %lu\n", size); + printk("ATPX buffer is too small: %zu\n", size); err = -EINVAL; goto out; } --- linux-next-20121010.orig/drivers/gpu/drm/radeon/radeon_acpi.c +++ linux-next-20121010/drivers/gpu/drm/radeon/radeon_acpi.c @@ -201,7 +201,7 @@ static int radeon_atif_verify_interface( size = *(u16 *) info->buffer.pointer; if (size < 12) { - DRM_INFO("ATIF buffer is too small: %lu\n", size); + DRM_INFO("ATIF buffer is too small: %zu\n", size); err = -EINVAL; goto out; } @@ -485,7 +485,7 @@ static int radeon_atcs_verify_interface( size = *(u16 *) info->buffer.pointer; if (size < 8) { - DRM_INFO("ATCS buffer is too small: %lu\n", size); + DRM_INFO("ATCS buffer is too small: %zu\n", size); err = -EINVAL; goto out; } ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH -next] drm: fix radeon printk format warnings
From: Randy Dunlap Fix printk format warnings in gpu/drm/radeon/: drivers/gpu/drm/radeon/radeon_atpx_handler.c:151:3: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'size_t' drivers/gpu/drm/radeon/radeon_acpi.c:204:3: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'size_t' drivers/gpu/drm/radeon/radeon_acpi.c:488:3: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'size_t' Signed-off-by: Randy Dunlap Cc: David Airlie Cc: dri-devel at lists.freedesktop.org --- drivers/gpu/drm/radeon/radeon_acpi.c |4 ++-- drivers/gpu/drm/radeon/radeon_atpx_handler.c |2 +- 2 files changed, 3 insertions(+), 3 deletions(-) --- linux-next-20121010.orig/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ linux-next-20121010/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -148,7 +148,7 @@ static int radeon_atpx_verify_interface( size = *(u16 *) info->buffer.pointer; if (size < 8) { - printk("ATPX buffer is too small: %lu\n", size); + printk("ATPX buffer is too small: %zu\n", size); err = -EINVAL; goto out; } --- linux-next-20121010.orig/drivers/gpu/drm/radeon/radeon_acpi.c +++ linux-next-20121010/drivers/gpu/drm/radeon/radeon_acpi.c @@ -201,7 +201,7 @@ static int radeon_atif_verify_interface( size = *(u16 *) info->buffer.pointer; if (size < 12) { - DRM_INFO("ATIF buffer is too small: %lu\n", size); + DRM_INFO("ATIF buffer is too small: %zu\n", size); err = -EINVAL; goto out; } @@ -485,7 +485,7 @@ static int radeon_atcs_verify_interface( size = *(u16 *) info->buffer.pointer; if (size < 8) { - DRM_INFO("ATCS buffer is too small: %lu\n", size); + DRM_INFO("ATCS buffer is too small: %zu\n", size); err = -EINVAL; goto out; }
[Bug 55819] Mouse cursor corruption when moving between monitors
https://bugs.freedesktop.org/show_bug.cgi?id=55819 --- Comment #6 from Nikolaus Rath --- I'm using 3.2.0 from Jul 23, so I believe I have the fix. Is there a way to know for sure? -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/d86533f2/attachment.html>
Re: [PATCH] dma-buf: Use EXPORT_SYMBOL
On Wed, 10 Oct 2012 08:56:32 -0700 Robert Morell wrote: > EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation > issue, and not really an interface". The dma-buf infrastructure is > explicitly intended as an interface between modules/drivers, so it > should use EXPORT_SYMBOL instead. NAK. This needs at the very least the approval of all rights holders for the files concerned and all code exposed by this change. Also I'd note if you are trying to do this for the purpose of combining it with proprietary code then you are still in my view as a (and the view of many other) rights holder to the kernel likely to be in breach of the GPL requirements for a derivative work. You may consider that formal notification of my viewpoint. Your corporate legal team can explain to you why the fact you are now aware of my view is important to them. Alan ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/3] Android support
On 10/07/2012 10:50 PM, Tapani Pälli wrote: > Upstreaming old set of patches here to enable Android support in libdrm. > Some little rebasing was required for the first one. > > Chad Versace (2): > libdrm,intel: Factor source file lists into sources.mk > libdrm,intel: Add Android makefiles (v2) > > Haitao Huang (1): > Android.mk: use LOCAL_COPY_HEADERS to export headers. > > Android.mk| 62 > +++ > Makefile.am | 9 > intel/Android.mk | 57 ++ > intel/Makefile.am | 9 > intel/sources.mk | 30 +++ > sources.mk| 30 +++ This series looks good to me. Before committing, though, I'd like to see either an Acked-by or an "Sure, whatever" from one of the regular libdrm_intel committers. -Chad ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/3] Android support
On 10/07/2012 10:50 PM, Tapani P?lli wrote: > Upstreaming old set of patches here to enable Android support in libdrm. > Some little rebasing was required for the first one. > > Chad Versace (2): > libdrm,intel: Factor source file lists into sources.mk > libdrm,intel: Add Android makefiles (v2) > > Haitao Huang (1): > Android.mk: use LOCAL_COPY_HEADERS to export headers. > > Android.mk| 62 > +++ > Makefile.am | 9 > intel/Android.mk | 57 ++ > intel/Makefile.am | 9 > intel/sources.mk | 30 +++ > sources.mk| 30 +++ This series looks good to me. Before committing, though, I'd like to see either an Acked-by or an "Sure, whatever" from one of the regular libdrm_intel committers. -Chad
Re: [PATCH] Android.mk: use LOCAL_COPY_HEADERS to export headers. v2
Is the only difference between v2 and v1 of this patch the removal of the Change-ID tag? On 10/08/2012 02:23 AM, Tapani Pälli wrote: > From: Haitao Huang > > Export necessary header files used by other components for Android, > such as libva intel-driver, gralloc, hwcomposer, etc. > > Signed-off-by: Haitao Huang > [chad: Fixed inconsistent indentation.] > Signed-off-by: Chad Versace > --- > Android.mk | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/Android.mk b/Android.mk > index 1029dc6..68db5df 100644 > --- a/Android.mk > +++ b/Android.mk > @@ -1,5 +1,5 @@ > # > -# Copyright © 2011 Intel Corporation > +# Copyright © 2011-2012 Intel Corporation > # > # Permission is hereby granted, free of charge, to any person obtaining a > # copy of this software and associated documentation files (the "Software"), > @@ -45,6 +45,16 @@ LOCAL_C_INCLUDES := \ > LOCAL_CFLAGS := \ > -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 > > +LOCAL_COPY_HEADERS :=\ > + xf86drm.h\ > + include/drm/drm_fourcc.h \ > + include/drm/drm.h\ > + include/drm/drm_mode.h \ > + include/drm/drm_sarea.h \ > + include/drm/i915_drm.h \ > + intel/intel_bufmgr.h \ > + > +LOCAL_COPY_HEADERS_TO := libdrm > include $(BUILD_SHARED_LIBRARY) > > include $(LOCAL_PATH)/intel/Android.mk > ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] Android.mk: use LOCAL_COPY_HEADERS to export headers. v2
Is the only difference between v2 and v1 of this patch the removal of the Change-ID tag? On 10/08/2012 02:23 AM, Tapani P?lli wrote: > From: Haitao Huang > > Export necessary header files used by other components for Android, > such as libva intel-driver, gralloc, hwcomposer, etc. > > Signed-off-by: Haitao Huang > [chad: Fixed inconsistent indentation.] > Signed-off-by: Chad Versace > --- > Android.mk | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/Android.mk b/Android.mk > index 1029dc6..68db5df 100644 > --- a/Android.mk > +++ b/Android.mk > @@ -1,5 +1,5 @@ > # > -# Copyright ? 2011 Intel Corporation > +# Copyright ? 2011-2012 Intel Corporation > # > # Permission is hereby granted, free of charge, to any person obtaining a > # copy of this software and associated documentation files (the "Software"), > @@ -45,6 +45,16 @@ LOCAL_C_INCLUDES := \ > LOCAL_CFLAGS := \ > -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 > > +LOCAL_COPY_HEADERS :=\ > + xf86drm.h\ > + include/drm/drm_fourcc.h \ > + include/drm/drm.h\ > + include/drm/drm_mode.h \ > + include/drm/drm_sarea.h \ > + include/drm/i915_drm.h \ > + intel/intel_bufmgr.h \ > + > +LOCAL_COPY_HEADERS_TO := libdrm > include $(BUILD_SHARED_LIBRARY) > > include $(LOCAL_PATH)/intel/Android.mk >
[Bug 55829] [Regression]Smokin-guns crash when change resolution
https://bugs.freedesktop.org/show_bug.cgi?id=55829 Chris Wilson changed: What|Removed |Added Status|NEW |NEEDINFO --- Comment #2 from Chris Wilson --- Maybe a bt from smokinguns as it crashes? -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/1b1e9604/attachment-0001.html>
RC6 for an Intel GU doesn't always work
Sometimes - after a reboot or after wakeup from s2disk I'm observed at my ThinkPad T420 (i5-2540M CPU) w/ integrated intel graphic (i915 module) since 3.6-rc(5?), that the temperature is above 80°C (usually it is around/lower than 50 °C). Powertop-2.1 shows, that the all 4 CPU cores are mostly idle, but the GPU is running at 100%. It looks for me that the power saving mode RC6 isn't active. After 1-2 s2ram's however the issue went away. I'm observing the issue both under my Gentoo Linux and under a RH system (kernel 3.6.1 each). It is hard to bisect b/c not reliable. -- MfG/Sincerely Toralf Förster pgp finger print: 7B1A 07F4 EC82 0F90 D4C2 8936 872A E508 7DB6 9DA3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 1/3] drm: Add user-defined EDID quirks capability
On Tue, 09 Oct 2012, Ian Pilcher wrote: > OK. I'm done. Sincerely, if you want to get your stuff in the kernel, you need to not give up so easily. > I've literally been discussing these patches on this list for months, and > you bring this up now? Apologies, I have only been reading the list for a few months, and this is the first time I look at the patches. I don't think a patch should get any special treatment for reaching v5. > It's far easier to simply recompile every kernel that comes out than to > continue this dance. Please note that I don't make the calls about pushing the patches. I can merely offer my review comments and opinions to hopefully make those decisions easier for others. Patches that attract review probably have a better chance of getting pushed than patches that nobody cares about. BR, Jani. > On Oct 9, 2012 7:10 AM, "Jani Nikula" wrote: > >> On Fri, 28 Sep 2012, Ian Pilcher wrote: >> > Add the ability for users to define their own EDID quirks via a >> > module parameter or sysfs attribute. >> >> Hi Ian - >> >> IMHO this patch should be chopped up to smaller pieces. For example, >> change the edid_quirk_list format first (if you must), then add module >> parameter support, then add sysfs support, in separate patches. It'll be >> easier to review. >> >> Please see some other comments inline. >> >> BR, >> Jani. >> >> > >> > Signed-off-by: Ian Pilcher >> > --- >> > Documentation/EDID/edid_quirks.txt | 126 ++ >> > drivers/gpu/drm/drm_drv.c | 2 + >> > drivers/gpu/drm/drm_edid.c | 500 >> - >> > drivers/gpu/drm/drm_stub.c | 6 + >> > drivers/gpu/drm/drm_sysfs.c| 19 ++ >> > include/drm/drmP.h | 10 + >> > include/drm/drm_edid.h | 13 +- >> > 7 files changed, 615 insertions(+), 61 deletions(-) >> > create mode 100644 Documentation/EDID/edid_quirks.txt >> > >> > diff --git a/Documentation/EDID/edid_quirks.txt >> b/Documentation/EDID/edid_quirks.txt >> > new file mode 100644 >> > index 000..0c9c746 >> > --- /dev/null >> > +++ b/Documentation/EDID/edid_quirks.txt >> > @@ -0,0 +1,126 @@ >> > + EDID Quirks >> > + = >> > + Ian Pilcher >> > +August 11, 2012 >> > + >> > + >> > +"EDID blocks out in the wild have a variety of bugs" >> > +-- from drivers/gpu/drm/drm_edid.c >> > + >> > + >> > +Overview >> > + >> > + >> > +EDID quirks provide a mechanism for working around display hardware >> with buggy >> > +EDID data. >> > + >> > +An individual EDID quirk maps a display type (identified by its EDID >> > +manufacturer ID and product code[1]) to a set of "quirk flags." The >> kernel >> > +includes a variety of built-in quirks. (They are stored in the >> edid_quirk_list >> > +array in drivers/gpu/drm/drm_edid.c.) >> > + >> > +An example of a built-in EDID quirk is: >> > + >> > +ACR:0xad46:0x0001 >> > + >> > +The first field is the manufacturer ID (Acer, Inc.), the second field >> is the >> > +manufacturer's product code, and the third field contains the quirk >> flags for >> > +that display type. >> > + >> > +The quirk flags are defined in drivers/gpu/drm/drm_edid.c. Each flag >> has a >> > +symbolic name beginning with EDID_QUIRK_, along with a numerical value. >> Each >> > +flag should also have an associated comment which provides an idea of >> its >> > +effect. Note that the values in the source file are expressed as bit >> shifts[2]: >> > + >> > +* 1 << 0: 0x0001 >> > +* 1 << 1: 0x0002 >> > +* 1 << 2: 0x0004 >> > +* etc. >> > + >> > + >> > +sysfs interface >> > +=== >> > + >> > +The current EDID quirk list can be read from /sys/class/drm/edid_quirks: >> > + >> > +# cat /sys/class/drm/edid_quirks >> > + ACR:0xad46:0x0001 >> > + API:0x7602:0x0001 >> > + ACR:0x0977:0x0020 >> > +0x9e6a:0x077e:0x0080 >> > +... >> > + >> > +("Nonconformant" manufacturer IDs are displayed as hexadecimal values.) >> > + >> > +The number of total "slots" in the list can be read from >> > +/sys/class/drm/edid_quirks_size. This total includes both occupied >> slots (i.e. >> > +the current list) and any slots available for additional quirks. The >> number of >> > +available slots can be calculated by subtracting the number of quirks >> in the >> > +current list from the total number of slots. >> > + >> > +If a slot is available, an additional quirk can be added to the list by >> writing >> > +it to /sys/class/drm/edid_quirks: >> > + >> > +# echo FOO:0x:0x100 > /sys/class/drm/edid_quirks >> > + >> > +Manufacturer IDs can also be specified numerically. (This is the only >> way to >> > +specify a nonconformant ID.) This command is equivalent to the previous >> one: >> > + >> > +# echo 0x19ef:0x:0x100 > /sys/class/drm/edid_quirks >> > + >> > +Numeri
[Bug 55829] [Regression]Smokin-guns crash when change resolution
https://bugs.freedesktop.org/show_bug.cgi?id=55829 --- Comment #1 from meng --- Created attachment 68393 --> https://bugs.freedesktop.org/attachment.cgi?id=68393&action=edit Xorg.0.log -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/4ace4d87/attachment.html>
[Bug 55829] New: [Regression]Smokin-guns crash when change resolution
https://bugs.freedesktop.org/show_bug.cgi?id=55829 Priority: high Bug ID: 55829 Assignee: dri-devel at lists.freedesktop.org Summary: [Regression]Smokin-guns crash when change resolution Severity: major Classification: Unclassified OS: Linux (All) Reporter: mengmeng.meng at intel.com Hardware: x86 (IA32) Status: NEW Version: unspecified Component: libdrm Product: DRI System Environment: -- Platform: IVB,Piketon Libdrm:(master)libdrm-2.4.39-18-g844d75e5a0b3b8f3466a24256955e886275fb298 Mesa:(master)87a34131c427b40a561cfef1513b446a0eeabc39 Xserver:(master)xorg-server-1.13.0-51-g4b7f00346daed20c96f3e8ea13ae411858a5424b Xf86_video_intel:(master)2.20.9-47-gd73f5b5bb1a81421f1fdc3ac3b460a8ad90be0ad Kernel:(drm-intel-nightly) 4517f84e2981dddf4715997767c252a16579364b Bug detailed description: - Smokin-guns crash when change resolution on IVB and Piketon. It's libdrm regression, the good commit is 2.4.31. Reproduce steps: 1, xinit& 2, ./smokinguns.x86_64 3, change resolution(Settings/System/Video Mode) -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/6df9dbd7/attachment.html>
[Bug 40211] texture probleme in wolfenstein enemy territory rv770
https://bugs.freedesktop.org/show_bug.cgi?id=40211 --- Comment #10 from Michel D?nzer --- (In reply to comment #8) > my glxinfo output with mesa 8.0.4 That's actually a post-8.0 Git snapshot... Did you sort out the 32 vs. 64 bit issues? -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20121010/403c8910/attachment.html>
[PATCH] dma-buf: Use EXPORT_SYMBOL
EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation issue, and not really an interface". The dma-buf infrastructure is explicitly intended as an interface between modules/drivers, so it should use EXPORT_SYMBOL instead. Signed-off-by: Robert Morell --- This patch is based on Linus's master branch. We held a discussion at ELC, and agreed that EXPORT_SYMBOL is more appropriate for this interface than EXPORT_SYMBOL_GPL. drivers/base/dma-buf.c | 34 +- 1 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 460e22d..24c28be 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -122,7 +122,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, return dmabuf; } -EXPORT_SYMBOL_GPL(dma_buf_export); +EXPORT_SYMBOL(dma_buf_export); /** @@ -148,7 +148,7 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags) return fd; } -EXPORT_SYMBOL_GPL(dma_buf_fd); +EXPORT_SYMBOL(dma_buf_fd); /** * dma_buf_get - returns the dma_buf structure related to an fd @@ -174,7 +174,7 @@ struct dma_buf *dma_buf_get(int fd) return file->private_data; } -EXPORT_SYMBOL_GPL(dma_buf_get); +EXPORT_SYMBOL(dma_buf_get); /** * dma_buf_put - decreases refcount of the buffer @@ -189,7 +189,7 @@ void dma_buf_put(struct dma_buf *dmabuf) fput(dmabuf->file); } -EXPORT_SYMBOL_GPL(dma_buf_put); +EXPORT_SYMBOL(dma_buf_put); /** * dma_buf_attach - Add the device to dma_buf's attachments list; optionally, @@ -234,7 +234,7 @@ err_attach: mutex_unlock(&dmabuf->lock); return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(dma_buf_attach); +EXPORT_SYMBOL(dma_buf_attach); /** * dma_buf_detach - Remove the given attachment from dmabuf's attachments list; @@ -256,7 +256,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) mutex_unlock(&dmabuf->lock); kfree(attach); } -EXPORT_SYMBOL_GPL(dma_buf_detach); +EXPORT_SYMBOL(dma_buf_detach); /** * dma_buf_map_attachment - Returns the scatterlist table of the attachment; @@ -283,7 +283,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, return sg_table; } -EXPORT_SYMBOL_GPL(dma_buf_map_attachment); +EXPORT_SYMBOL(dma_buf_map_attachment); /** * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might @@ -304,7 +304,7 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction); } -EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); +EXPORT_SYMBOL(dma_buf_unmap_attachment); /** @@ -332,7 +332,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, return ret; } -EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); +EXPORT_SYMBOL(dma_buf_begin_cpu_access); /** * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the @@ -354,7 +354,7 @@ void dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, if (dmabuf->ops->end_cpu_access) dmabuf->ops->end_cpu_access(dmabuf, start, len, direction); } -EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); +EXPORT_SYMBOL(dma_buf_end_cpu_access); /** * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address @@ -371,7 +371,7 @@ void *dma_buf_kmap_atomic(struct dma_buf *dmabuf, unsigned long page_num) return dmabuf->ops->kmap_atomic(dmabuf, page_num); } -EXPORT_SYMBOL_GPL(dma_buf_kmap_atomic); +EXPORT_SYMBOL(dma_buf_kmap_atomic); /** * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. @@ -389,7 +389,7 @@ void dma_buf_kunmap_atomic(struct dma_buf *dmabuf, unsigned long page_num, if (dmabuf->ops->kunmap_atomic) dmabuf->ops->kunmap_atomic(dmabuf, page_num, vaddr); } -EXPORT_SYMBOL_GPL(dma_buf_kunmap_atomic); +EXPORT_SYMBOL(dma_buf_kunmap_atomic); /** * dma_buf_kmap - Map a page of the buffer object into kernel address space. The @@ -406,7 +406,7 @@ void *dma_buf_kmap(struct dma_buf *dmabuf, unsigned long page_num) return dmabuf->ops->kmap(dmabuf, page_num); } -EXPORT_SYMBOL_GPL(dma_buf_kmap); +EXPORT_SYMBOL(dma_buf_kmap); /** * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. @@ -424,7 +424,7 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long page_num, if (dmabuf->ops->kunmap) dmabuf->ops->kunmap(dmabuf, page_num, vaddr); } -EXPORT_SYMBOL_GPL(dma_buf_kunmap); +EXPORT_SYMBOL(dma_buf_kunmap); /** @@ -466,7 +466,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, return dmabuf->ops->mmap(dmabuf, vma); } -EXPORT_SYMBOL_GPL(dma_buf_mmap); +EXPORT_SYMBOL(dma_buf_mmap); /** * dma_buf_vmap - Create virtual mapping for the buffer object into kernel @@ -487,
[PATCH] dma-buf: Use EXPORT_SYMBOL
EXPORT_SYMBOL_GPL is intended to be used for "an internal implementation issue, and not really an interface". The dma-buf infrastructure is explicitly intended as an interface between modules/drivers, so it should use EXPORT_SYMBOL instead. Signed-off-by: Robert Morell --- This patch is based on Linus's master branch. We held a discussion at ELC, and agreed that EXPORT_SYMBOL is more appropriate for this interface than EXPORT_SYMBOL_GPL. drivers/base/dma-buf.c | 34 +- 1 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 460e22d..24c28be 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -122,7 +122,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, return dmabuf; } -EXPORT_SYMBOL_GPL(dma_buf_export); +EXPORT_SYMBOL(dma_buf_export); /** @@ -148,7 +148,7 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags) return fd; } -EXPORT_SYMBOL_GPL(dma_buf_fd); +EXPORT_SYMBOL(dma_buf_fd); /** * dma_buf_get - returns the dma_buf structure related to an fd @@ -174,7 +174,7 @@ struct dma_buf *dma_buf_get(int fd) return file->private_data; } -EXPORT_SYMBOL_GPL(dma_buf_get); +EXPORT_SYMBOL(dma_buf_get); /** * dma_buf_put - decreases refcount of the buffer @@ -189,7 +189,7 @@ void dma_buf_put(struct dma_buf *dmabuf) fput(dmabuf->file); } -EXPORT_SYMBOL_GPL(dma_buf_put); +EXPORT_SYMBOL(dma_buf_put); /** * dma_buf_attach - Add the device to dma_buf's attachments list; optionally, @@ -234,7 +234,7 @@ err_attach: mutex_unlock(&dmabuf->lock); return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(dma_buf_attach); +EXPORT_SYMBOL(dma_buf_attach); /** * dma_buf_detach - Remove the given attachment from dmabuf's attachments list; @@ -256,7 +256,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) mutex_unlock(&dmabuf->lock); kfree(attach); } -EXPORT_SYMBOL_GPL(dma_buf_detach); +EXPORT_SYMBOL(dma_buf_detach); /** * dma_buf_map_attachment - Returns the scatterlist table of the attachment; @@ -283,7 +283,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, return sg_table; } -EXPORT_SYMBOL_GPL(dma_buf_map_attachment); +EXPORT_SYMBOL(dma_buf_map_attachment); /** * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might @@ -304,7 +304,7 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction); } -EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); +EXPORT_SYMBOL(dma_buf_unmap_attachment); /** @@ -332,7 +332,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, return ret; } -EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); +EXPORT_SYMBOL(dma_buf_begin_cpu_access); /** * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the @@ -354,7 +354,7 @@ void dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, if (dmabuf->ops->end_cpu_access) dmabuf->ops->end_cpu_access(dmabuf, start, len, direction); } -EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); +EXPORT_SYMBOL(dma_buf_end_cpu_access); /** * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address @@ -371,7 +371,7 @@ void *dma_buf_kmap_atomic(struct dma_buf *dmabuf, unsigned long page_num) return dmabuf->ops->kmap_atomic(dmabuf, page_num); } -EXPORT_SYMBOL_GPL(dma_buf_kmap_atomic); +EXPORT_SYMBOL(dma_buf_kmap_atomic); /** * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. @@ -389,7 +389,7 @@ void dma_buf_kunmap_atomic(struct dma_buf *dmabuf, unsigned long page_num, if (dmabuf->ops->kunmap_atomic) dmabuf->ops->kunmap_atomic(dmabuf, page_num, vaddr); } -EXPORT_SYMBOL_GPL(dma_buf_kunmap_atomic); +EXPORT_SYMBOL(dma_buf_kunmap_atomic); /** * dma_buf_kmap - Map a page of the buffer object into kernel address space. The @@ -406,7 +406,7 @@ void *dma_buf_kmap(struct dma_buf *dmabuf, unsigned long page_num) return dmabuf->ops->kmap(dmabuf, page_num); } -EXPORT_SYMBOL_GPL(dma_buf_kmap); +EXPORT_SYMBOL(dma_buf_kmap); /** * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. @@ -424,7 +424,7 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long page_num, if (dmabuf->ops->kunmap) dmabuf->ops->kunmap(dmabuf, page_num, vaddr); } -EXPORT_SYMBOL_GPL(dma_buf_kunmap); +EXPORT_SYMBOL(dma_buf_kunmap); /** @@ -466,7 +466,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, return dmabuf->ops->mmap(dmabuf, vma); } -EXPORT_SYMBOL_GPL(dma_buf_mmap); +EXPORT_SYMBOL(dma_buf_mmap); /** * dma_buf_vmap - Create virtual mapping for the buffer object into kernel @@ -487,7 +487,7 @@ void *dma_buf_v
[RFC PATCH] drm/i915: Add atomic page flip support
From: Ville Syrjälä Utilize drm_flip to implement "atomic page flip". When involving multiple planes on one pipe, the operations on the planes must be synchronized via software since the hardware doesn't provide the means. drm_flip is used to make that happen, and to track the progress of the flip operations. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_dma.c |5 + drivers/gpu/drm/i915/i915_drv.h |4 + drivers/gpu/drm/i915/i915_irq.c | 18 +- drivers/gpu/drm/i915/intel_atomic.c | 813 +- drivers/gpu/drm/i915/intel_display.c |2 + drivers/gpu/drm/i915/intel_drv.h |6 + 6 files changed, 832 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e958e54..79ad32d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1762,6 +1762,8 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file) idr_init(&file_priv->context_idr); + INIT_LIST_HEAD(&file_priv->pending_flips); + return 0; } @@ -1792,10 +1794,13 @@ void i915_driver_lastclose(struct drm_device * dev) i915_dma_cleanup(dev); } +void intel_atomic_free_events(struct drm_device *dev, struct drm_file *file); + void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { i915_gem_context_close(dev, file_priv); i915_gem_release(dev, file_priv); + intel_atomic_free_events(dev, file_priv); } void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57e4894..80645df 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -845,6 +846,8 @@ typedef struct drm_i915_private { struct work_struct parity_error_work; bool hw_contexts_disabled; uint32_t hw_context_size; + + struct drm_flip_driver flip_driver; } drm_i915_private_t; /* Iterate over initialised rings */ @@ -1055,6 +1058,7 @@ struct drm_i915_file_private { struct list_head request_list; } mm; struct idr context_idr; + struct list_head pending_flips; }; #define INTEL_INFO(dev)(((struct drm_i915_private *) (dev)->dev_private)->info) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 23f2ea0..f816dab 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -37,6 +37,8 @@ #include "i915_trace.h" #include "intel_drv.h" +void intel_atomic_handle_vblank(struct drm_device *dev, int pipe); + /* For display hotplug interrupt */ static void ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) @@ -547,8 +549,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); for_each_pipe(pipe) { - if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) + if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) { drm_handle_vblank(dev, pipe); + intel_atomic_handle_vblank(dev, pipe); + } if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { intel_prepare_page_flip(dev, pipe); @@ -685,8 +689,10 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) intel_prepare_page_flip(dev, i); intel_finish_page_flip_plane(dev, i); } - if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) + if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) { drm_handle_vblank(dev, i); + intel_atomic_handle_vblank(dev, i); + } } /* check event from PCH */ @@ -778,11 +784,15 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) intel_finish_page_flip_plane(dev, 1); } - if (de_iir & DE_PIPEA_VBLANK) + if (de_iir & DE_PIPEA_VBLANK) { drm_handle_vblank(dev, 0); + intel_atomic_handle_vblank(dev, 0); + } - if (de_iir & DE_PIPEB_VBLANK) + if (de_iir & DE_PIPEB_VBLANK) { drm_handle_vblank(dev, 1); + intel_atomic_handle_vblank(dev, 1); + } /* check event from PCH */ if (de_iir & DE_PCH_EVENT) { diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 363018f..9fa95d3 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -3,6 +3,7 @@ #include #include +#include #include "int
[RFC PATCH] drm: Atomic modeset ioctl
From: Ville Syrjälä The atomic modeset ioctl cna be used to push any number of new values for object properties. The driver can then check the full device configuration as single unit, and try to apply the changes atomically. The ioctl simply takes a list of object IDs and property IDs and their values. For setting values to blob properties, the property value indicates the length of the data, and the actual data is passed via another blob pointer. The caller can demand non-blocking operation from the ioctl, and if the driver can't satisfy that requirement an error will be returned. The caller can also request to receive asynchronous completion events after the operation has reached the hardware. An event is sent for each object specified by the caller, whether or not the actual state of that object changed. Each event also carries a framebuffer ID, which indicates to user space that the specified object is no longer accessing that framebuffer. TODO: detailed error reporting? Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_crtc.c | 146 drivers/gpu/drm/drm_drv.c |1 + include/drm/drm.h | 12 include/drm/drmP.h |8 +++ include/drm/drm_crtc.h | 13 include/drm/drm_mode.h | 16 + 6 files changed, 196 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b313958..38c6604 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4162,3 +4162,149 @@ int drm_calc_vscale(struct drm_region *src, struct drm_region *dst, return vscale; } EXPORT_SYMBOL(drm_calc_vscale); + +int drm_mode_atomic_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_atomic *arg = data; + uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); + uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); + uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); + uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); + uint64_t __user *blob_values_ptr = (uint64_t __user *)(unsigned long)(arg->blob_values_ptr); + unsigned int copied_objs = 0; + unsigned int copied_props = 0; + unsigned int copied_blobs = 0; + void *state; + int ret = 0; + unsigned int i, j; + + if (!dev->driver->atomic_funcs || + !dev->driver->atomic_funcs->begin || + !dev->driver->atomic_funcs->set || + !dev->driver->atomic_funcs->check || + !dev->driver->atomic_funcs->commit || + !dev->driver->atomic_funcs->end) + return -ENOSYS; + + if (arg->flags & ~(DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_EVENT | DRM_MODE_ATOMIC_NONBLOCK)) + return -EINVAL; + + /* can't test and expect an event at the same time. */ + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY && arg->flags & DRM_MODE_ATOMIC_EVENT) + return -EINVAL; + + mutex_lock(&dev->mode_config.mutex); + + state = dev->driver->atomic_funcs->begin(dev, file_priv, arg->flags, arg->user_data); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + goto unlock; + } + + for (i = 0; i < arg->count_objs; i++) { + uint32_t obj_id, count_props; + struct drm_mode_object *obj; + + if (get_user(obj_id, objs_ptr + copied_objs)) { + ret = -EFAULT; + goto out; + } + + obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY); + if (!obj || !obj->properties) { + ret = -ENOENT; + goto out; + } + + if (get_user(count_props, count_props_ptr + copied_objs)) { + ret = -EFAULT; + goto out; + } + + copied_objs++; + + for (j = 0; j < count_props; j++) { + uint32_t prop_id; + uint64_t prop_value; + struct drm_mode_object *prop_obj; + struct drm_property *prop; + void *blob_data = NULL; + + if (get_user(prop_id, props_ptr + copied_props)) { + ret = -EFAULT; + goto out; + } + + if (!object_has_prop(obj, prop_id)) { + ret = -EINVAL; + goto out; + } + + prop_obj = drm_mode_object_find(dev, prop_id, DRM_MODE_OBJECT_PROPERTY); + if (!prop_obj) { + ret = -ENOENT; +
[RFC PATCH] drm/i915: Implement atomic modesetting
From: Ville Syrjälä Implement the atomic modeset operations. TODO: need to rewrite this for the new intel modeset code Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/intel_atomic.c | 1462 ++ drivers/gpu/drm/i915/intel_display.c |7 + 3 files changed, 1470 insertions(+), 0 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_atomic.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b0bacdb..377d100 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -16,6 +16,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ i915_gem_tiling.o \ i915_sysfs.o \ i915_trace_points.o \ + intel_atomic.o \ intel_display.o \ intel_crt.o \ intel_lvds.o \ diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c new file mode 100644 index 000..363018f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -0,0 +1,1462 @@ +/* + */ + +#include +#include + +#include "intel_drv.h" + +static struct drm_property *prop_src_x; +static struct drm_property *prop_src_y; +static struct drm_property *prop_src_w; +static struct drm_property *prop_src_h; +static struct drm_property *prop_crtc_x; +static struct drm_property *prop_crtc_y; +static struct drm_property *prop_crtc_w; +static struct drm_property *prop_crtc_h; +static struct drm_property *prop_fb_id; +static struct drm_property *prop_crtc_id; +static struct drm_property *prop_mode; +static struct drm_property *prop_connector_ids; +static struct drm_property *prop_cursor_id; +static struct drm_property *prop_cursor_x; +static struct drm_property *prop_cursor_y; +static struct drm_property *prop_cursor_w; +static struct drm_property *prop_cursor_h; + +struct intel_plane_state { + struct drm_plane *plane; + struct drm_framebuffer *old_fb; + struct intel_plane_coords coords; + bool dirty; + bool pinned; +}; + +struct intel_crtc_state { + struct drm_crtc *crtc; + struct drm_framebuffer *old_fb; + struct drm_i915_gem_object *old_cursor_bo; + bool mode_dirty; + bool fb_dirty; + bool cursor_dirty; + bool active_dirty; + bool pinned; + bool cursor_pinned; + unsigned long connectors_bitmask; + unsigned long encoders_bitmask; +}; + +struct intel_atomic_state { + struct drm_file *file; + struct intel_plane_state *plane; + struct intel_crtc_state *crtc; + bool dirty; + bool restore_hw; + unsigned int flags; + uint64_t user_data; + struct drm_plane *saved_planes; + struct intel_crtc *saved_crtcs; + struct drm_connector *saved_connectors; + struct drm_encoder *saved_encoders; +}; + +static void update_connectors_bitmask(struct intel_crtc_state *st) +{ + struct drm_device *dev = st->crtc->dev; + struct drm_connector *connector; + unsigned int i; + + st->connectors_bitmask = 0; + + i = 0; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->encoder && connector->encoder->crtc == st->crtc) + __set_bit(i, &st->connectors_bitmask); + + i++; + } +} + +static void update_encoders_bitmask(struct intel_crtc_state *st) +{ + struct drm_device *dev = st->crtc->dev; + struct drm_encoder *encoder; + unsigned int i; + + st->encoders_bitmask = 0; + + i = 0; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + if (encoder->crtc == st->crtc) + __set_bit(i, &st->encoders_bitmask); + + i++; + } +} + +static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, int count_ids) +{ + struct drm_crtc *crtc = s->crtc; + struct drm_device *dev = crtc->dev; + struct drm_connector *connectors[count_ids]; + struct drm_connector *connector; + struct drm_encoder *encoder; + int i; + + for (i = 0; i < count_ids; i++) { + struct drm_encoder *encoder; + const struct drm_connector_helper_funcs *connector_funcs; + struct drm_mode_object *obj; + int j; + + /* don't accept duplicates */ + for (j = i + 1; j < count_ids; j++) + if (ids[i] == ids[j]) + return -EINVAL; + + obj = drm_mode_object_find(dev, ids[i], DRM_MODE_OBJECT_CONNECTOR); + if (!obj) + return -ENOENT; + + connector = obj_to_connector(obj); + connector_funcs = connector->helper_private; + + encoder = connector_funcs->best_encoder(connector); + + if (!drm_encoder_crtc_ok(encoder, crtc)) + retu
[RFC PATCH] Atomic modeset/pageflip update
Here's another set of atomic modeset and pageflip patches. I just skipped spamming the list with all the patches that contain the gritty details for now. These three provide an eagle eye view of the whole thing. The full series can be found here [1]. The accompanying libdrm stuff is here [2]. So what are the significant changes since the last time: - Pass the display modes as blobs as opposed to mode object IDs - Fixed blob passing (it was simply broken in my earlier patches) - Add completion events - Add the non-blocking flag - Clean up the history a bit to make the patches easier on the eye Unfortunately the whole thing is still based on the pre i915 modeset rework code. So porting the modesetting side over to the current i915 code is one two bigger tasks that I have left. The other is implementing non-blocking synchronization with the GPU. [1] https://gitorious.org/vsyrjala/linux/commits/drm_atomic_9 [2] https://gitorious.org/vsyrjala/drm/commits/drm_atomic_7 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 26/26] v4l: s5p-mfc: support for dmabuf exporting
This patch enhances s5p-mfc with support for DMABUF exporting via VIDIOC_EXPBUF ioctl. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: Kamil Debski Acked-by: Hans Verkuil --- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 14 ++ drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 14 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index eb6a70b..6dad9a7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -636,6 +636,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return -EINVAL; } +/* Export DMA buffer */ +static int vidioc_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + + if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return vb2_expbuf(&ctx->vq_src, eb); + if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return vb2_expbuf(&ctx->vq_dst, eb); + return -EINVAL; +} + /* Stream on */ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) @@ -813,6 +826,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = { .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_expbuf = vidioc_expbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_g_crop = vidioc_g_crop, diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 2af6d52..22bf684 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1165,6 +1165,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return ret; } +/* Export DMA buffer */ +static int vidioc_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + + if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return vb2_expbuf(&ctx->vq_src, eb); + if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return vb2_expbuf(&ctx->vq_dst, eb); + return -EINVAL; +} + /* Stream on */ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) @@ -1568,6 +1581,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = { .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_expbuf = vidioc_expbuf, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_s_parm = vidioc_s_parm, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 25/26] v4l: s5p-tv: mixer: support for dmabuf exporting
This patch enhances s5p-tv with support for DMABUF exporting via VIDIOC_EXPBUF ioctl. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/platform/s5p-tv/mixer_video.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index 2421e527..5e3cdb2 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c @@ -698,6 +698,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK); } +static int mxr_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct mxr_layer *layer = video_drvdata(file); + + mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__); + return vb2_expbuf(&layer->vb_queue, eb); +} + static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct mxr_layer *layer = video_drvdata(file); @@ -725,6 +734,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = { .vidioc_querybuf = mxr_querybuf, .vidioc_qbuf = mxr_qbuf, .vidioc_dqbuf = mxr_dqbuf, + .vidioc_expbuf = mxr_expbuf, /* Streaming control */ .vidioc_streamon = mxr_streamon, .vidioc_streamoff = mxr_streamoff, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 24/26] v4l: s5p-fimc: support for dmabuf exporting
This patch enhances s5p-fimc with support for DMABUF exporting via VIDIOC_EXPBUF ioctl. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: Sylwester Nawrocki Acked-by: Hans Verkuil --- drivers/media/platform/s5p-fimc/fimc-capture.c |9 + drivers/media/platform/s5p-fimc/fimc-m2m.c | 10 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 246bb32..e5fd159 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -1231,6 +1231,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv, return vb2_qbuf(&fimc->vid_cap.vbq, buf); } +static int fimc_cap_expbuf(struct file *file, void *priv, + struct v4l2_exportbuffer *eb) +{ + struct fimc_dev *fimc = video_drvdata(file); + + return vb2_expbuf(&fimc->vid_cap.vbq, eb); +} + static int fimc_cap_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { @@ -1355,6 +1363,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { .vidioc_qbuf= fimc_cap_qbuf, .vidioc_dqbuf = fimc_cap_dqbuf, + .vidioc_expbuf = fimc_cap_expbuf, .vidioc_prepare_buf = fimc_cap_prepare_buf, .vidioc_create_bufs = fimc_cap_create_bufs, diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c index 17067a7..1cd4fcf 100644 --- a/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c @@ -439,6 +439,15 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh, return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); } +static int fimc_m2m_expbuf(struct file *file, void *fh, + struct v4l2_exportbuffer *eb) +{ + struct fimc_ctx *ctx = fh_to_ctx(fh); + + return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb); +} + + static int fimc_m2m_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { @@ -607,6 +616,7 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { .vidioc_querybuf= fimc_m2m_querybuf, .vidioc_qbuf= fimc_m2m_qbuf, .vidioc_dqbuf = fimc_m2m_dqbuf, + .vidioc_expbuf = fimc_m2m_expbuf, .vidioc_streamon= fimc_m2m_streamon, .vidioc_streamoff = fimc_m2m_streamoff, .vidioc_g_crop = fimc_m2m_g_crop, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 23/26] v4l: vb2-dma-contig: align buffer size to PAGE_SIZE
Most operations on DMA and DMABUF framework need page aligned buffers. This fix guarantees this requirement for vb2-dma-contig buffers. Signed-off-by: Tomasz Stanislawski --- drivers/media/v4l2-core/videobuf2-dma-contig.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 571a919..002ee50 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -162,6 +162,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) if (!buf) return ERR_PTR(-ENOMEM); + /* align image size to PAGE_SIZE */ + size = PAGE_ALIGN(size); + buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL); if (!buf->vaddr) { dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 22/26] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned
From: Marek Szyprowski The DMA transfer must be aligned to a specific value. If userptr is not aligned to DMA requirements then unexpected corruptions of the memory may occur before or after a buffer. To prevent such situations, all unligned userptr buffers are rejected at VIDIOC_QBUF. Signed-off-by: Marek Szyprowski Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 2d661fd..571a919 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -493,6 +493,18 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, struct vm_area_struct *vma; struct sg_table *sgt; unsigned long contig_size; + unsigned long dma_align = dma_get_cache_alignment(); + + /* Only cache aligned DMA transfers are reliable */ + if (!IS_ALIGNED(vaddr | size, dma_align)) { + pr_debug("user data must be aligned to %lu bytes\n", dma_align); + return ERR_PTR(-EINVAL); + } + + if (!size) { + pr_debug("size is zero\n"); + return ERR_PTR(-EINVAL); + } buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context
This patch adds taking reference to the device for MMAP buffers. Such buffers, may be exported using DMABUF mechanism. If the driver that created a queue is unloaded then the queue is released, the device might be released too. However, buffers cannot be released if they are referenced by DMABUF descriptor(s). The device pointer kept in a buffer must be valid for the whole buffer's lifetime. Therefore MMAP buffers should take a reference to the device to avoid risk of dangling pointers. Signed-off-by: Tomasz Stanislawski Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index b138b5c..2d661fd 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv) kfree(buf->sgt_base); } dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); + put_device(buf->dev); kfree(buf); } @@ -168,6 +169,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) return ERR_PTR(-ENOMEM); } + /* prevent the device from release while the buffer is exported */ + get_device(dev); + buf->dev = dev; buf->size = size; -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 20/26] v4l: vb2-dma-contig: add support for DMABUF exporting
This patch adds support for exporting a dma-contig buffer using DMABUF interface. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 200 1 file changed, 200 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 0e065ce..b138b5c 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -36,6 +36,7 @@ struct vb2_dc_buf { /* MMAP related */ struct vb2_vmarea_handler handler; atomic_trefcount; + struct sg_table *sgt_base; /* USERPTR related */ struct vm_area_struct *vma; @@ -142,6 +143,10 @@ static void vb2_dc_put(void *buf_priv) if (!atomic_dec_and_test(&buf->refcount)) return; + if (buf->sgt_base) { + sg_free_table(buf->sgt_base); + kfree(buf->sgt_base); + } dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); kfree(buf); } @@ -213,6 +218,200 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) } /*/ +/* DMABUF ops for exporters */ +/*/ + +struct vb2_dc_attachment { + struct sg_table sgt; + enum dma_data_direction dir; +}; + +static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev, + struct dma_buf_attachment *dbuf_attach) +{ + struct vb2_dc_attachment *attach; + unsigned int i; + struct scatterlist *rd, *wr; + struct sg_table *sgt; + struct vb2_dc_buf *buf = dbuf->priv; + int ret; + + attach = kzalloc(sizeof(*attach), GFP_KERNEL); + if (!attach) + return -ENOMEM; + + sgt = &attach->sgt; + /* Copy the buf->base_sgt scatter list to the attachment, as we can't +* map the same scatter list to multiple attachments at the same time. +*/ + ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL); + if (ret) { + kfree(attach); + return -ENOMEM; + } + + rd = buf->sgt_base->sgl; + wr = sgt->sgl; + for (i = 0; i < sgt->orig_nents; ++i) { + sg_set_page(wr, sg_page(rd), rd->length, rd->offset); + rd = sg_next(rd); + wr = sg_next(wr); + } + + attach->dir = DMA_NONE; + dbuf_attach->priv = attach; + + return 0; +} + +static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *db_attach) +{ + struct vb2_dc_attachment *attach = db_attach->priv; + struct sg_table *sgt; + + if (!attach) + return; + + sgt = &attach->sgt; + + /* release the scatterlist cache */ + if (attach->dir != DMA_NONE) + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dir); + sg_free_table(sgt); + kfree(attach); + db_attach->priv = NULL; +} + +static struct sg_table *vb2_dc_dmabuf_ops_map( + struct dma_buf_attachment *db_attach, enum dma_data_direction dir) +{ + struct vb2_dc_attachment *attach = db_attach->priv; + /* stealing dmabuf mutex to serialize map/unmap operations */ + struct mutex *lock = &db_attach->dmabuf->lock; + struct sg_table *sgt; + int ret; + + mutex_lock(lock); + + sgt = &attach->sgt; + /* return previously mapped sg table */ + if (attach->dir == dir) { + mutex_unlock(lock); + return sgt; + } + + /* release any previous cache */ + if (attach->dir != DMA_NONE) { + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dir); + attach->dir = DMA_NONE; + } + + /* mapping to the client with new direction */ + ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir); + if (ret <= 0) { + pr_err("failed to map scatterlist\n"); + mutex_unlock(lock); + return ERR_PTR(-EIO); + } + + attach->dir = dir; + + mutex_unlock(lock); + + return sgt; +} + +static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach, + struct sg_table *sgt, enum dma_data_direction dir) +{ + /* nothing to be done here */ +} + +static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf) +{ + /* drop reference obtained in vb2_dc_get_dmabuf */ + vb2_dc_put(dbuf->priv); +} + +static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum) +{ + struct vb2_dc_buf *buf = dbuf->priv; + + return buf->vaddr + pgnum * PAGE_SIZE; +} + +static void *vb2_dc_dmabuf_ops_vmap(struct
[PATCHv10 19/26] v4l: vb2: add buffer exporting via dmabuf
This patch adds extension to videobuf2-core. It allow to export a mmap buffer as a file descriptor. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-mem2mem.c | 13 + drivers/media/v4l2-core/videobuf2-core.c | 83 ++ include/media/v4l2-mem2mem.h |3 ++ include/media/videobuf2-core.h |4 ++ 4 files changed, 103 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 3ac8358..9aa7cc7 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -369,6 +369,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); /** + * v4l2_m2m_expbuf() - export a source or destination buffer, depending on + * the type + */ +int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_exportbuffer *eb) +{ + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(m2m_ctx, eb->type); + return vb2_expbuf(vq, eb); +} +EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf); +/** * v4l2_m2m_streamon() - turn on streaming for a video queue */ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 613dea1..9f81be2 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1751,6 +1751,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, } /** + * vb2_expbuf() - Export a buffer as a file descriptor + * @q: videobuf2 queue + * @eb:export buffer structure passed from userspace to vidioc_expbuf + * handler in driver + * + * The return values from this function are intended to be directly returned + * from vidioc_expbuf handler in driver. + */ +int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) +{ + struct vb2_buffer *vb = NULL; + struct vb2_plane *vb_plane; + int ret; + struct dma_buf *dbuf; + + if (q->memory != V4L2_MEMORY_MMAP) { + dprintk(1, "Queue is not currently set up for mmap\n"); + return -EINVAL; + } + + if (!q->mem_ops->get_dmabuf) { + dprintk(1, "Queue does not support DMA buffer exporting\n"); + return -EINVAL; + } + + if (eb->flags & ~O_CLOEXEC) { + dprintk(1, "Queue does support only O_CLOEXEC flag\n"); + return -EINVAL; + } + + if (eb->type != q->type) { + dprintk(1, "qbuf: invalid buffer type\n"); + return -EINVAL; + } + + if (eb->index >= q->num_buffers) { + dprintk(1, "buffer index out of range\n"); + return -EINVAL; + } + + vb = q->bufs[eb->index]; + + if (eb->plane >= vb->num_planes) { + dprintk(1, "buffer plane out of range\n"); + return -EINVAL; + } + + vb_plane = &vb->planes[eb->plane]; + + dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv); + if (IS_ERR_OR_NULL(dbuf)) { + dprintk(1, "Failed to export buffer %d, plane %d\n", + eb->index, eb->plane); + return -EINVAL; + } + + ret = dma_buf_fd(dbuf, eb->flags); + if (ret < 0) { + dprintk(3, "buffer %d, plane %d failed to export (%d)\n", + eb->index, eb->plane, ret); + dma_buf_put(dbuf); + return ret; + } + + dprintk(3, "buffer %d, plane %d exported as %d descriptor\n", + eb->index, eb->plane, ret); + eb->fd = ret; + + return 0; +} +EXPORT_SYMBOL_GPL(vb2_expbuf); + +/** * vb2_mmap() - map video buffers into application address space * @q: videobuf2 queue * @vma: vma passed to the mmap file operation handler in the driver @@ -2456,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) } EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff); +int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p) +{ + struct video_device *vdev = video_devdata(file); + + if (vb2_queue_is_busy(vdev, file)) + return -EBUSY; + return vb2_expbuf(vdev->queue, p); +} +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf); + /* v4l2_file_operations helpers */ int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 131cc4a..7e82d2b 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -111,6 +111,9 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
[PATCHv10 18/26] v4l: add buffer exporting via dmabuf
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by mmap and return a file descriptor on success. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c |1 + drivers/media/v4l2-core/v4l2-dev.c|1 + drivers/media/v4l2-core/v4l2-ioctl.c | 10 + include/linux/videodev2.h | 28 + include/media/v4l2-ioctl.h|2 ++ 5 files changed, 42 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index cc5998b..7157af3 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1018,6 +1018,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_S_FBUF32: case VIDIOC_OVERLAY32: case VIDIOC_QBUF32: + case VIDIOC_EXPBUF: case VIDIOC_DQBUF32: case VIDIOC_STREAMON32: case VIDIOC_STREAMOFF32: diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index a2df842..98dcad9 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -571,6 +571,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); + SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf); SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf); SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 530a67e..aa6e7c7 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -454,6 +454,15 @@ static void v4l_print_buffer(const void *arg, bool write_only) tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); } +static void v4l_print_exportbuffer(const void *arg, bool write_only) +{ + const struct v4l2_exportbuffer *p = arg; + + pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n", + p->fd, prt_names(p->type, v4l2_type_names), + p->index, p->plane, p->flags); +} + static void v4l_print_create_buffers(const void *arg, bool write_only) { const struct v4l2_create_buffers *p = arg; @@ -1961,6 +1970,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE), + IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)), IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE), IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE), diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 07bc5d6..19765df 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -696,6 +696,33 @@ struct v4l2_buffer { #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 +/** + * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor + * + * @index: id number of the buffer + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * @fd:file descriptor associated with DMABUF (set by driver) + * + * Contains data used for exporting a video buffer as DMABUF file descriptor. + * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF + * (identical to the cookie used to mmap() the buffer to userspace). All + * reserved fields must be set to zero. The field reserved0 is expected to + * become a structure 'type' allowing an alternative layout of the structure + * content. Therefore this field should not be used for any other extensions. + */ +struct v4l2_exportbuffer { + __u32 type; /* enum v4l2_buf_type */ + __u32 index; + __u32 plane; + __u32 flags; + __s32 fd; + __u
[PATCHv10 17/26] Documentation: media: description of DMABUF exporting in V4L2
This patch adds description and usage examples for exporting DMABUF file descriptor in V4L2. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park CC: linux-...@vger.kernel.org --- Documentation/DocBook/media/v4l/compat.xml|3 + Documentation/DocBook/media/v4l/io.xml|3 + Documentation/DocBook/media/v4l/v4l2.xml |1 + Documentation/DocBook/media/v4l/vidioc-expbuf.xml | 212 + 4 files changed, 219 insertions(+) create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index 50eb630..3dd9e78 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2590,6 +2590,9 @@ ioctls. Importing DMABUF file descriptors as a new IO method described in . + + Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl. + diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index 0abb5cb..81d0ed4 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml @@ -488,6 +488,9 @@ DMA buffer from userspace using a file descriptor previously exported for a different or the same device (known as the importer role), or both. This section describes the DMABUF importer role API in V4L2. +Refer to DMABUF exporting for +details about exporting V4L2 buffers as DMABUF file descriptors. + Input and output devices support the streaming I/O method when the V4L2_CAP_STREAMING flag in the capabilities field of &v4l2-capability; returned by diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index 10ccde9..4d110b1 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml @@ -543,6 +543,7 @@ and discussions on the V4L mailing list. &sub-enuminput; &sub-enumoutput; &sub-enumstd; +&sub-expbuf; &sub-g-audio; &sub-g-audioout; &sub-g-crop; diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml new file mode 100644 index 000..72dfbd2 --- /dev/null +++ b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml @@ -0,0 +1,212 @@ + + + +ioctl VIDIOC_EXPBUF +&manvol; + + + +VIDIOC_EXPBUF +Export a buffer as a DMABUF file descriptor. + + + + + + int ioctl + int fd + int request + struct v4l2_exportbuffer *argp + + + + + +Arguments + + + + fd + + &fd; + + + + request + + VIDIOC_EXPBUF + + + + argp + + + + + + + + +Description + + + Experimental + This is an experimental + interface and may change in the future. + + +This ioctl is an extension to the memory +mapping I/O method, therefore it is available only for +V4L2_MEMORY_MMAP buffers. It can be used to export a +buffer as a DMABUF file at any time after buffers have been allocated with the +&VIDIOC-REQBUFS; ioctl. + + To export a buffer, applications fill &v4l2-exportbuffer;. The + type field is set to the same buffer type as was +previously used with &v4l2-requestbuffers; type . +Applications must also set the index field. Valid +index numbers range from zero to the number of buffers allocated with +&VIDIOC-REQBUFS; (&v4l2-requestbuffers; count ) +minus one. For the multi-planar API, applications set the plane + field to the index of the plane to be exported. Valid planes +range from zero to the maximal number of valid planes for the currently active +format. For the single-planar API, applications must set plane + to zero. Additional flags may be posted in the +flags field. Refer to a manual for open() for details. +Currently only O_CLOEXEC is supported. All other fields must be set to zero. +In the case of multi-planar API, every plane is exported separately using +multiple VIDIOC_EXPBUF calls. + + After calling VIDIOC_EXPBUF the fd + field will be set by a driver. This is a DMABUF file +descriptor. The application may pass it to other DMABUF-aware devices. Refer to +DMABUF importing for details about importing +DMABUF files into V4L2 nodes. It is recommended to close a DMABUF file when it +is no longer used to allow the associated memory to be reclaimed. + + + + + Examples + + + Exporting a buffer. + +int buffer_export(int v4lfd, &v4l2-buf-type; bt, int index, int *dmafd) +{ + &v4l2-exportbuffer; expbuf; + + memset(&expbuf, 0, sizeof(expbuf)); + expbuf.type = bt; + expbuf.index = index; + if (ioctl(v4lfd, &VIDIOC-EXPBUF;, &expbuf) == -1) { + perror("VIDIOC_EXPBUF"); + return -1; + } + +
[PATCHv10 16/26] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call
From: Marek Szyprowski Let mmap method to use dma_mmap_coherent call. Moreover, this patch removes vb2_mmap_pfn_range from videobuf2 helpers as it was suggested by Laurent Pinchart. The function is no longer used in vb2 code. Signed-off-by: Marek Szyprowski Signed-off-by: Tomasz Stanislawski Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 28 +++-- drivers/media/v4l2-core/videobuf2-memops.c | 40 include/media/videobuf2-memops.h |5 --- 3 files changed, 26 insertions(+), 47 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index a5804cf..0e065ce 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -178,14 +178,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dc_buf *buf = buf_priv; + int ret; if (!buf) { printk(KERN_ERR "No buffer to map\n"); return -EINVAL; } - return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size, - &vb2_common_vm_ops, &buf->handler); + /* +* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to +* map whole buffer +*/ + vma->vm_pgoff = 0; + + ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr, + buf->dma_addr, buf->size); + + if (ret) { + pr_err("Remapping memory failed, error: %d\n", ret); + return ret; + } + + vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; + vma->vm_private_data= &buf->handler; + vma->vm_ops = &vb2_common_vm_ops; + + vma->vm_ops->open(vma); + + pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n", + __func__, (unsigned long)buf->dma_addr, vma->vm_start, + buf->size); + + return 0; } /*/ diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c index 504cd4c..81c1ad8 100644 --- a/drivers/media/v4l2-core/videobuf2-memops.c +++ b/drivers/media/v4l2-core/videobuf2-memops.c @@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, EXPORT_SYMBOL_GPL(vb2_get_contig_userptr); /** - * vb2_mmap_pfn_range() - map physical pages to userspace - * @vma: virtual memory region for the mapping - * @paddr: starting physical address of the memory to be mapped - * @size: size of the memory to be mapped - * @vm_ops:vm operations to be assigned to the created area - * @priv: private data to be associated with the area - * - * Returns 0 on success. - */ -int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr, - unsigned long size, - const struct vm_operations_struct *vm_ops, - void *priv) -{ - int ret; - - size = min_t(unsigned long, vma->vm_end - vma->vm_start, size); - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT, - size, vma->vm_page_prot); - if (ret) { - printk(KERN_ERR "Remapping memory failed, error: %d\n", ret); - return ret; - } - - vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; - vma->vm_private_data= priv; - vma->vm_ops = vm_ops; - - vma->vm_ops->open(vma); - - pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n", - __func__, paddr, vma->vm_start, size); - - return 0; -} -EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range); - -/** * vb2_common_vm_open() - increase refcount of the vma * @vma: virtual memory region for the mapping * diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h index 84e1f6c..f05444c 100644 --- a/include/media/videobuf2-memops.h +++ b/include/media/videobuf2-memops.h @@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops; int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, struct vm_area_struct **res_vma, dma_addr_t *res_pa); -int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr, - unsigned long size, - const struct vm_operations_struct *vm_ops, - void *priv); - struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma); void vb2_put_vma(struct vm_area_struct *vma); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org ht
[PATCHv10 15/26] v4l: s5p-fimc: support for dmabuf importing
This patch enhances s5p-fimc with support for DMABUF importing via V4L2_MEMORY_DMABUF memory type. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Sylwester Nawrocki Acked-by: Hans Verkuil --- drivers/media/platform/s5p-fimc/fimc-capture.c |2 +- drivers/media/platform/s5p-fimc/fimc-m2m.c |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 367efd1..246bb32 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -1730,7 +1730,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, q = &fimc->vid_cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - q->io_modes = VB2_MMAP | VB2_USERPTR; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = fimc->vid_cap.ctx; q->ops = &fimc_capture_qops; q->mem_ops = &vb2_dma_contig_memops; diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c index 4500e44..17067a7 100644 --- a/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c @@ -622,7 +622,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, int ret; src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - src_vq->io_modes = VB2_MMAP | VB2_USERPTR; + src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->ops = &fimc_qops; src_vq->mem_ops = &vb2_dma_contig_memops; @@ -633,7 +633,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, return ret; dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->ops = &fimc_qops; dst_vq->mem_ops = &vb2_dma_contig_memops; -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 14/26] v4l: s5p-tv: mixer: support for dmabuf importing
This patch enhances s5p-tv with support for DMABUF importing via V4L2_MEMORY_DMABUF memory type. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/platform/s5p-tv/mixer_video.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index 0c1cd89..2421e527 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c @@ -1093,7 +1093,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev, layer->vb_queue = (struct vb2_queue) { .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - .io_modes = VB2_MMAP | VB2_USERPTR, + .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF, .drv_priv = layer, .buf_struct_size = sizeof(struct mxr_buffer), .ops = &mxr_video_qops, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 13/26] v4l: vivi: support for dmabuf importing
This patch enhances VIVI driver with a support for importing a buffer from DMABUF file descriptors. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Hans Verkuil --- drivers/media/platform/vivi.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c index b366b05..9e077bb 100644 --- a/drivers/media/platform/vivi.c +++ b/drivers/media/platform/vivi.c @@ -1308,7 +1308,7 @@ static int __init vivi_create_instance(int inst) /* initialize queue */ q = &dev->vb_vidq; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivi_buffer); q->ops = &vivi_video_qops; -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 12/26] v4l: vb2-vmalloc: add support for dmabuf importing
This patch adds support for importing DMABUF files for vmalloc allocator in Videobuf2. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/Kconfig |1 + drivers/media/v4l2-core/videobuf2-vmalloc.c | 56 +++ 2 files changed, 57 insertions(+) diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index e30583b..65875c3 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -75,6 +75,7 @@ config VIDEOBUF2_VMALLOC tristate select VIDEOBUF2_CORE select VIDEOBUF2_MEMOPS + select DMA_SHARED_BUFFER config VIDEOBUF2_DMA_SG tristate diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 94efa04..a47fd4f 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -30,6 +30,7 @@ struct vb2_vmalloc_buf { unsigned intn_pages; atomic_trefcount; struct vb2_vmarea_handler handler; + struct dma_buf *dbuf; }; static void vb2_vmalloc_put(void *buf_priv); @@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; } +/*/ +/* callbacks for DMABUF buffers*/ +/*/ + +static int vb2_vmalloc_map_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + buf->vaddr = dma_buf_vmap(buf->dbuf); + + return buf->vaddr ? 0 : -EFAULT; +} + +static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + dma_buf_vunmap(buf->dbuf, buf->vaddr); + buf->vaddr = NULL; +} + +static void vb2_vmalloc_detach_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + if (buf->vaddr) + dma_buf_vunmap(buf->dbuf, buf->vaddr); + + kfree(buf); +} + +static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_vmalloc_buf *buf; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dbuf = dbuf; + buf->write = write; + buf->size = size; + + return buf; +} + + const struct vb2_mem_ops vb2_vmalloc_memops = { .alloc = vb2_vmalloc_alloc, .put= vb2_vmalloc_put, .get_userptr= vb2_vmalloc_get_userptr, .put_userptr= vb2_vmalloc_put_userptr, + .map_dmabuf = vb2_vmalloc_map_dmabuf, + .unmap_dmabuf = vb2_vmalloc_unmap_dmabuf, + .attach_dmabuf = vb2_vmalloc_attach_dmabuf, + .detach_dmabuf = vb2_vmalloc_detach_dmabuf, .vaddr = vb2_vmalloc_vaddr, .mmap = vb2_vmalloc_mmap, .num_users = vb2_vmalloc_num_users, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 11/26] v4l: vb2-dma-contig: add support for dma_buf importing
From: Sumit Semwal This patch makes changes for adding dma-contig as a dma_buf user. It provides function implementations for the {attach, detach, map, unmap}_dmabuf() mem_ops of DMABUF memory type. Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal [author of the original patch] Signed-off-by: Tomasz Stanislawski [integration with refactored dma-contig allocator] Acked-by: Laurent Pinchart --- drivers/media/v4l2-core/Kconfig|1 + drivers/media/v4l2-core/videobuf2-dma-contig.c | 120 +++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 2e787cc..e30583b 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -69,6 +69,7 @@ config VIDEOBUF2_DMA_CONTIG tristate select VIDEOBUF2_CORE select VIDEOBUF2_MEMOPS + select DMA_SHARED_BUFFER config VIDEOBUF2_VMALLOC tristate diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 494a824..a5804cf 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -10,6 +10,7 @@ * the Free Software Foundation. */ +#include #include #include #include @@ -38,6 +39,9 @@ struct vb2_dc_buf { /* USERPTR related */ struct vm_area_struct *vma; + + /* DMABUF related */ + struct dma_buf_attachment *db_attach; }; /*/ @@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - if (!sgt) + /* DMABUF exporter will flush the cache for us */ + if (!sgt || buf->db_attach) return; dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); @@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - if (!sgt) + /* DMABUF exporter will flush the cache for us */ + if (!sgt || buf->db_attach) return; dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); @@ -377,6 +383,112 @@ fail_buf: } /*/ +/* callbacks for DMABUF buffers*/ +/*/ + +static int vb2_dc_map_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + struct sg_table *sgt; + unsigned long contig_size; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to pin a non attached buffer\n"); + return -EINVAL; + } + + if (WARN_ON(buf->dma_sgt)) { + pr_err("dmabuf buffer is already pinned\n"); + return 0; + } + + /* get the associated scatterlist for this buffer */ + sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); + if (IS_ERR_OR_NULL(sgt)) { + pr_err("Error getting dmabuf scatterlist\n"); + return -EINVAL; + } + + /* checking if dmabuf is big enough to store contiguous chunk */ + contig_size = vb2_dc_get_contiguous_size(sgt); + if (contig_size < buf->size) { + pr_err("contiguous chunk is too small %lu/%lu b\n", + contig_size, buf->size); + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + return -EFAULT; + } + + buf->dma_addr = sg_dma_address(sgt->sgl); + buf->dma_sgt = sgt; + + return 0; +} + +static void vb2_dc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to unpin a not attached buffer\n"); + return; + } + + if (WARN_ON(!sgt)) { + pr_err("dmabuf buffer is already unpinned\n"); + return; + } + + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + + buf->dma_addr = 0; + buf->dma_sgt = NULL; +} + +static void vb2_dc_detach_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + + /* if vb2 works correctly you should never detach mapped buffer */ + if (WARN_ON(buf->dma_addr)) + vb2_dc_unmap_dmabuf(buf); + + /* detach this attachment */ + dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach); + kfree(buf); +} + +static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_dc_conf *conf = alloc_ctx; + struct vb2_dc_buf *buf; + struct dma_buf_attachment *dba; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kz
[PATCHv10 10/26] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator
From: Marek Szyprowski Add prepare/finish callbacks to vb2-dma-contig allocator. Signed-off-by: Marek Szyprowski Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 8486e06..494a824 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv) return atomic_read(&buf->refcount); } +static void vb2_dc_prepare(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (!sgt) + return; + + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); +} + +static void vb2_dc_finish(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (!sgt) + return; + + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); +} + /*/ /*callbacks for MMAP buffers */ /*/ @@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = { .mmap = vb2_dc_mmap, .get_userptr= vb2_dc_get_userptr, .put_userptr= vb2_dc_put_userptr, + .prepare= vb2_dc_prepare, + .finish = vb2_dc_finish, .num_users = vb2_dc_num_users, }; EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 09/26] v4l: vb2: add prepare/finish callbacks to allocators
From: Marek Szyprowski This patch adds support for prepare/finish callbacks in VB2 allocators. These callback are used for buffer flushing. Signed-off-by: Marek Szyprowski Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-core.c | 11 +++ include/media/videobuf2-core.h |7 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index a51dad6..613dea1 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -844,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) { struct vb2_queue *q = vb->vb2_queue; unsigned long flags; + unsigned int plane; if (vb->state != VB2_BUF_STATE_ACTIVE) return; @@ -854,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) dprintk(4, "Done processing on buffer %d, state: %d\n", vb->v4l2_buf.index, vb->state); + /* sync buffers */ + for (plane = 0; plane < vb->num_planes; ++plane) + call_memop(q, finish, vb->planes[plane].mem_priv); + /* Add the buffer to the done buffers list */ spin_lock_irqsave(&q->done_lock, flags); vb->state = state; @@ -1136,9 +1141,15 @@ err: static void __enqueue_in_driver(struct vb2_buffer *vb) { struct vb2_queue *q = vb->vb2_queue; + unsigned int plane; vb->state = VB2_BUF_STATE_ACTIVE; atomic_inc(&q->queued_count); + + /* sync buffers */ + for (plane = 0; plane < vb->num_planes; ++plane) + call_memop(q, prepare, vb->planes[plane].mem_priv); + q->ops->buf_queue(vb); } diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 689ae4a..24b9c90 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -56,6 +56,10 @@ struct vb2_fileio_data; * dmabuf * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified * that this driver is done using the dmabuf for now + * @prepare: called every time the buffer is passed from userspace to the + * driver, useful for cache synchronisation, optional + * @finish:called every time the buffer is passed back from the driver + * to the userspace, also optional * @vaddr: return a kernel virtual address to a given memory buffer * associated with the passed private structure or NULL if no * such mapping exists @@ -82,6 +86,9 @@ struct vb2_mem_ops { unsigned long size, int write); void(*put_userptr)(void *buf_priv); + void(*prepare)(void *buf_priv); + void(*finish)(void *buf_priv); + void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf, unsigned long size, int write); void(*detach_dmabuf)(void *buf_priv); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 08/26] v4l: vb2-dma-contig: add support for scatterlist in userptr mode
This patch introduces usage of dma_map_sg to map memory behind a userspace pointer to a device as dma-contiguous mapping. This patch contains some of the code kindly provided by Marek Szyprowski and Kamil Debski and Andrzej Pietrasiewicz . Kind thanks for bug reports from Laurent Pinchart and Seung-Woo Kim . Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 226 ++-- 1 file changed, 210 insertions(+), 16 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index daac2b2..8486e06 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -11,6 +11,8 @@ */ #include +#include +#include #include #include @@ -27,6 +29,8 @@ struct vb2_dc_buf { void*vaddr; unsigned long size; dma_addr_t dma_addr; + enum dma_data_direction dma_dir; + struct sg_table *dma_sgt; /* MMAP related */ struct vb2_vmarea_handler handler; @@ -37,6 +41,44 @@ struct vb2_dc_buf { }; /*/ +/*scatterlist table functions*/ +/*/ + + +static void vb2_dc_sgt_foreach_page(struct sg_table *sgt, + void (*cb)(struct page *pg)) +{ + struct scatterlist *s; + unsigned int i; + + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { + struct page *page = sg_page(s); + unsigned int n_pages = PAGE_ALIGN(s->offset + s->length) + >> PAGE_SHIFT; + unsigned int j; + + for (j = 0; j < n_pages; ++j, ++page) + cb(page); + } +} + +static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) +{ + struct scatterlist *s; + dma_addr_t expected = sg_dma_address(sgt->sgl); + unsigned int i; + unsigned long size = 0; + + for_each_sg(sgt->sgl, s, sgt->nents, i) { + if (sg_dma_address(s) != expected) + break; + expected = sg_dma_address(s) + sg_dma_len(s); + size += sg_dma_len(s); + } + return size; +} + +/*/ /* callbacks for all buffers */ /*/ @@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) /* callbacks for USERPTR buffers */ /*/ +static inline int vma_is_io(struct vm_area_struct *vma) +{ + return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); +} + +static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, + int n_pages, struct vm_area_struct *vma, int write) +{ + if (vma_is_io(vma)) { + unsigned int i; + + for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) { + unsigned long pfn; + int ret = follow_pfn(vma, start, &pfn); + + if (ret) { + pr_err("no page for address %lu\n", start); + return ret; + } + pages[i] = pfn_to_page(pfn); + } + } else { + int n; + + n = get_user_pages(current, current->mm, start & PAGE_MASK, + n_pages, write, 1, pages, NULL); + /* negative error means that no page was pinned */ + n = max(n, 0); + if (n != n_pages) { + pr_err("got only %d of %d user pages\n", n, n_pages); + while (n) + put_page(pages[--n]); + return -EFAULT; + } + } + + return 0; +} + +static void vb2_dc_put_dirty_page(struct page *page) +{ + set_page_dirty_lock(page); + put_page(page); +} + +static void vb2_dc_put_userptr(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + struct sg_table *sgt = buf->dma_sgt; + + dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + if (!vma_is_io(buf->vma)) + vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); + + sg_free_table(sgt); + kfree(sgt); + vb2_put_vma(buf->vma); + kfree(buf); +} + static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, - unsigned long size, int write) + unsigned long size, int write) { + struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; + unsigned long start; + unsigned long end; + unsigned long offse
[PATCHv10 07/26] v4l: vb2-dma-contig: reorder functions
From: Laurent Pinchart Group functions by buffer type. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 92 ++-- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 20c95da..daac2b2 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -25,14 +25,56 @@ struct vb2_dc_conf { struct vb2_dc_buf { struct device *dev; void*vaddr; - dma_addr_t dma_addr; unsigned long size; - struct vm_area_struct *vma; - atomic_trefcount; + dma_addr_t dma_addr; + + /* MMAP related */ struct vb2_vmarea_handler handler; + atomic_trefcount; + + /* USERPTR related */ + struct vm_area_struct *vma; }; -static void vb2_dc_put(void *buf_priv); +/*/ +/* callbacks for all buffers */ +/*/ + +static void *vb2_dc_cookie(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + return &buf->dma_addr; +} + +static void *vb2_dc_vaddr(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + return buf->vaddr; +} + +static unsigned int vb2_dc_num_users(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + return atomic_read(&buf->refcount); +} + +/*/ +/*callbacks for MMAP buffers */ +/*/ + +static void vb2_dc_put(void *buf_priv) +{ + struct vb2_dc_buf *buf = buf_priv; + + if (!atomic_dec_and_test(&buf->refcount)) + return; + + dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); + kfree(buf); +} static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) { @@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) return buf; } -static void vb2_dc_put(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - - if (atomic_dec_and_test(&buf->refcount)) { - dma_free_coherent(buf->dev, buf->size, buf->vaddr, - buf->dma_addr); - kfree(buf); - } -} - -static void *vb2_dc_cookie(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - - return &buf->dma_addr; -} - -static void *vb2_dc_vaddr(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - if (!buf) - return NULL; - - return buf->vaddr; -} - -static unsigned int vb2_dc_num_users(void *buf_priv) -{ - struct vb2_dc_buf *buf = buf_priv; - - return atomic_read(&buf->refcount); -} - static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dc_buf *buf = buf_priv; @@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) &vb2_common_vm_ops, &buf->handler); } +/*/ +/* callbacks for USERPTR buffers */ +/*/ + static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { @@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv) kfree(buf); } +/*/ +/* DMA CONTIG exported functions */ +/*/ + const struct vb2_mem_ops vb2_dma_contig_memops = { .alloc = vb2_dc_alloc, .put= vb2_dc_put, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 06/26] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
This patch removes a reference to alloc_ctx from an instance of a DMA contiguous buffer. It helps to avoid a risk of a dangling pointer if the context is released while the buffer is still valid. Moreover it removes one dereference step while accessing a device structure. Signed-off-by: Tomasz Stanislawski Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index a05784f..20c95da 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -23,7 +23,7 @@ struct vb2_dc_conf { }; struct vb2_dc_buf { - struct vb2_dc_conf *conf; + struct device *dev; void*vaddr; dma_addr_t dma_addr; unsigned long size; @@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv); static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) { struct vb2_dc_conf *conf = alloc_ctx; + struct device *dev = conf->dev; struct vb2_dc_buf *buf; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM); - buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr, - GFP_KERNEL); + buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL); if (!buf->vaddr) { - dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", - size); + dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); kfree(buf); return ERR_PTR(-ENOMEM); } - buf->conf = conf; + buf->dev = dev; buf->size = size; buf->handler.refcount = &buf->refcount; @@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; if (atomic_dec_and_test(&buf->refcount)) { - dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr, + dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); kfree(buf); } -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv10 05/26] v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc
From: Laurent Pinchart Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 36 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 4b71326..a05784f 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -32,9 +32,9 @@ struct vb2_dc_buf { struct vb2_vmarea_handler handler; }; -static void vb2_dma_contig_put(void *buf_priv); +static void vb2_dc_put(void *buf_priv); -static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) +static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size) { struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; @@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) buf->size = size; buf->handler.refcount = &buf->refcount; - buf->handler.put = vb2_dma_contig_put; + buf->handler.put = vb2_dc_put; buf->handler.arg = buf; atomic_inc(&buf->refcount); @@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) return buf; } -static void vb2_dma_contig_put(void *buf_priv) +static void vb2_dc_put(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; @@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv) } } -static void *vb2_dma_contig_cookie(void *buf_priv) +static void *vb2_dc_cookie(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; return &buf->dma_addr; } -static void *vb2_dma_contig_vaddr(void *buf_priv) +static void *vb2_dc_vaddr(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; if (!buf) @@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv) return buf->vaddr; } -static unsigned int vb2_dma_contig_num_users(void *buf_priv) +static unsigned int vb2_dc_num_users(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; return atomic_read(&buf->refcount); } -static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma) +static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dc_buf *buf = buf_priv; @@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma) &vb2_common_vm_ops, &buf->handler); } -static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr, +static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { struct vb2_dc_buf *buf; @@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr, return buf; } -static void vb2_dma_contig_put_userptr(void *mem_priv) +static void vb2_dc_put_userptr(void *mem_priv) { struct vb2_dc_buf *buf = mem_priv; @@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv) } const struct vb2_mem_ops vb2_dma_contig_memops = { - .alloc = vb2_dma_contig_alloc, - .put= vb2_dma_contig_put, - .cookie = vb2_dma_contig_cookie, - .vaddr = vb2_dma_contig_vaddr, - .mmap = vb2_dma_contig_mmap, - .get_userptr= vb2_dma_contig_get_userptr, - .put_userptr= vb2_dma_contig_put_userptr, - .num_users = vb2_dma_contig_num_users, + .alloc = vb2_dc_alloc, + .put= vb2_dc_put, + .cookie = vb2_dc_cookie, + .vaddr = vb2_dc_vaddr, + .mmap = vb2_dc_mmap, + .get_userptr= vb2_dc_get_userptr, + .put_userptr= vb2_dc_put_userptr, + .num_users = vb2_dc_num_users, }; EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCHv9 00/25] Integration of videobuf2 with DMABUF
Hi, Em Tue, 02 Oct 2012 16:27:11 +0200 Tomasz Stanislawski escreveu: > Hello everyone, > This patchset adds support for DMABUF [2] importing and exporting to V4L2 > stack. > > v9: > - rebase on 3.6 > - change type for fs to __s32 > - add support for vb2_ioctl_expbuf > - remove patch 'v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING', > it will be posted as a separate patch > - fix typos and style in Documentation (from Hans Verkuil) > - only vb2-core and vb2-dma-contig selects DMA_SHARED_BUFFER in Kconfig > - use data_offset and length while queueing DMABUF > - return the most recently used fd at VIDIOC_DQBUF > - use (buffer-type, index, plane) tuple instead of mem_offset > to identify a for exporting (from Hans Verkuil) > - support for DMABUF mmap in vb2-dma-contig (from Laurent Pinchart) > - add testing alignment of vaddr and size while verifying userptr > against DMA capabilities (from Laurent Pinchart) > - substitute VM_DONTDUMP with VM_RESERVED > - simplify error handling in vb2_dc_get_dmabuf (from Laurent Pinchart) For now, NACK. See below. I spent 4 days trying to setup an environment that would allow testing DMABUF with video4linux without success (long story, see below). Also, Laurent tried the same without any luck, and it seems that it even corrupted his test machine. Basically Samsung generously donated me two boards that it could be used on this test (Origen and SMDK310). None of them actually worked with the upstream kernel: patches are needed to avoid OOPSes on Origen; both Origen/SMDK310 defconfigs are completely broken, and drivers don't even boot if someone tries to use the Kernel's defconfigs. Even after spending _days_ trying to figure out the needed .config options (as the config files are not easily available), both boards have... issues: - lack of any display output driver at SMDK310; - lack of any network driver at Origen: it seems that none of the available network options on Origen was upstreamed: no Bluetooth, no OTG, no Wifi. The only test I was able to do (yesterday, late night), the DMABUF caused an OOPS at the Origen board. So, for sure it is not ready for upstream. It is now, too late for 3.7. I might consider it to 3.8, if something can be done to fix the existing issues, and setup a proper setup, using the upstream Kernel. Regards, Mauro
[PATCHv10 04/26] v4l: vb: remove warnings about MEMORY_DMABUF
From: Sumit Semwal Adding DMABUF memory type causes videobuf to complain about not using it in some switch cases. This patch removes these warnings. Signed-off-by: Sumit Semwal Acked-by: Laurent Pinchart Acked-by: Hans Verkuil --- drivers/media/v4l2-core/videobuf-core.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c index bf7a326..5449e8a 100644 --- a/drivers/media/v4l2-core/videobuf-core.c +++ b/drivers/media/v4l2-core/videobuf-core.c @@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, case V4L2_MEMORY_OVERLAY: b->m.offset = vb->boff; break; + case V4L2_MEMORY_DMABUF: + /* DMABUF is not handled in videobuf framework */ + break; } b->flags= 0; @@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q, break; case V4L2_MEMORY_USERPTR: case V4L2_MEMORY_OVERLAY: + case V4L2_MEMORY_DMABUF: /* nothing */ break; } -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel