[PATCH v2] of: Add videomode helper
On Wed, 11 Jul 2012, Sascha Hauer wrote: > Hi Guennadi, > > On Wed, Jul 11, 2012 at 10:34:54AM +0200, Guennadi Liakhovetski wrote: > > Hi Sascha > > > > > + > > > +Optional properties: > > > + - width-mm, height-mm: Display dimensions in mm > > > + - hsync-active-high (bool): Hsync pulse is active high > > > + - vsync-active-high (bool): Vsync pulse is active high > > > > How about > > > > + - hsync-active: Hsync pulse polarity: 1 for high, 0 for low > > I am unsure if it's good to mix this with the other bool flags like: > > > > > > + - interlaced (bool): This is an interlaced mode > > > + - doublescan (bool): This is a doublescan mode > > Which behave differently. 'interlaced' will be evaluated as true if > the property is present, no matter which value it has. This might > lead to confusion. I don't feel strongly either way either. I don't think it'd be confusing - you have integer properties there too, and the logic in this case is not "active high - yes or now," but rather "active level - logical 1 (high) or 0 (low)." But as I said - that was just an idea, unless someone has strong arguments either way - you're the original author, it's your call:-) Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/
[PATCH v2] of: Add videomode helper
Hi Guennadi, On Wed, Jul 11, 2012 at 10:34:54AM +0200, Guennadi Liakhovetski wrote: > Hi Sascha > > > + > > +Optional properties: > > + - width-mm, height-mm: Display dimensions in mm > > + - hsync-active-high (bool): Hsync pulse is active high > > + - vsync-active-high (bool): Vsync pulse is active high > > How about > > + - hsync-active: Hsync pulse polarity: 1 for high, 0 for low I am unsure if it's good to mix this with the other bool flags like: > > > + - interlaced (bool): This is an interlaced mode > > + - doublescan (bool): This is a doublescan mode Which behave differently. 'interlaced' will be evaluated as true if the property is present, no matter which value it has. This might lead to confusion. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH v3] DRM: Add DRM kms/fb cma helper
On Mon, Jul 02, 2012 at 04:37:47PM +0200, Lars-Peter Clausen wrote: > This patchset introduces a set of helper function for implementing the KMS > framebuffer layer for drivers which use the drm gem CMA helper function. > > Signed-off-by: Lars-Peter Clausen > > --- > Note: This patch depends on Sascha's "DRM: add drm gem CMA helper" patch > > Changes since v2: > * Adapt to changes in the GEM CMA helper > * Add basic buffer size checking in drm_fb_cma_create > Changes since v1: > * Some spelling fixes > * Add missing kfree in drm_fb_cma_alloc error path > * Add multi-plane support > --- > drivers/gpu/drm/Kconfig | 10 + > drivers/gpu/drm/Makefile|1 + > drivers/gpu/drm/drm_fb_cma_helper.c | 393 > +++ > include/drm/drm_fb_cma_helper.h | 27 +++ > 4 files changed, 431 insertions(+) > create mode 100644 drivers/gpu/drm/drm_fb_cma_helper.c > create mode 100644 include/drm/drm_fb_cma_helper.h Tested-by: Sascha Hauer Would be good if this could go into the next merge window. Sascha > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 41bbd95..e511c9a 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -41,6 +41,16 @@ config DRM_GEM_CMA_HELPER > help > Choose this if you need the GEM CMA helper functions > > +config DRM_KMS_CMA_HELPER > + tristate > + select DRM_GEM_CMA_HELPER > + select DRM_KMS_HELPER > + select FB_SYS_FILLRECT > + select FB_SYS_COPYAREA > + select FB_SYS_IMAGEBLIT > + help > + Choose this if you need the KMS cma helper functions > + > config DRM_TDFX > tristate "3dfx Banshee/Voodoo3+" > depends on DRM && PCI > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 6e9e948..5dcb1a5 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -18,6 +18,7 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o > drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o > > drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o > +drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o > > obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o > > diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c > b/drivers/gpu/drm/drm_fb_cma_helper.c > new file mode 100644 > index 000..9042233 > --- /dev/null > +++ b/drivers/gpu/drm/drm_fb_cma_helper.c > @@ -0,0 +1,393 @@ > +/* > + * drm kms/fb cma (contiguous memory allocator) helper functions > + * > + * Copyright (C) 2012 Analog Device Inc. > + * Author: Lars-Peter Clausen > + * > + * Based on udl_fbdev.c > + * Copyright (C) 2012 Red Hat > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct drm_fb_cma { > + struct drm_framebuffer fb; > + struct drm_gem_cma_object *obj[4]; > +}; > + > +struct drm_fbdev_cma { > + struct drm_fb_helperfb_helper; > + struct drm_fb_cma *fb; > +}; > + > +static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper > *helper) > +{ > + return container_of(helper, struct drm_fbdev_cma, fb_helper); > +} > + > +static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb) > +{ > + return container_of(fb, struct drm_fb_cma, fb); > +} > + > +static void drm_fb_cma_destroy(struct drm_framebuffer *fb) > +{ > + struct drm_fb_cma *fb_cma = to_fb_cma(fb); > + int i; > + > + for (i = 0; i < 4; i++) { > + if (fb_cma->obj[i]) > + > drm_gem_object_unreference_unlocked(&fb_cma->obj[i]->base); > + } > + > + drm_framebuffer_cleanup(fb); > + kfree(fb_cma); > +} > + > +static int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > + struct drm_file *file_priv, unsigned int *handle) > +{ > + struct drm_fb_cma *fb_cma = to_fb_cma(fb); > + > + return drm_gem_handle_create(file_priv, > + &fb_cma->obj[0]->base, handle); > +} > + > +static struct drm_framebuffer_funcs drm_fb_cma_funcs = { > + .destroy= drm_fb_cma_destroy, > + .create_handle = drm_fb_cma_create_handle, > +}; > + > +static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, > + struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj, > + unsigned int num_planes) > +{ > + struct drm_fb_cma *fb_cma; > + int ret; > + int i; > + > +
[PATCH] dma-fence: dma-buf synchronization
On Wed, Jul 11, 2012 at 6:49 PM, Maarten Lankhorst wrote: > Op 12-07-12 00:29, Rob Clark schreef: >> From: Rob Clark >> >> A dma-fence can be attached to a buffer which is being filled or consumed >> by hw, to allow userspace to pass the buffer without waiting to another >> device. For example, userspace can call page_flip ioctl to display the >> next frame of graphics after kicking the GPU but while the GPU is still >> rendering. The display device sharing the buffer with the GPU would >> attach a callback to get notified when the GPU's rendering-complete IRQ >> fires, to update the scan-out address of the display, without having to >> wake up userspace. >> >> A dma-fence is transient, one-shot deal. It is allocated and attached >> to dma-buf's list of fences. When the one that attached it is done, >> with the pending operation, it can signal the fence removing it from the >> dma-buf's list of fences: >> >> + dma_buf_attach_fence() >> + dma_fence_signal() >> >> Other drivers can access the current fence on the dma-buf (if any), >> which increment's the fences refcnt: >> >> + dma_buf_get_fence() >> + dma_fence_put() >> >> The one pending on the fence can add an async callback (and optionally >> cancel it.. for example, to recover from GPU hangs): >> >> + dma_fence_add_callback() >> + dma_fence_cancel_callback() >> >> Or wait synchronously (optionally with timeout or from atomic context): >> >> + dma_fence_wait() > Waiting for an undefined time from atomic context is probably > not a good idea. However just checking non-blocking if the fence > has passed would be fine. yeah, the intention was to use short timeout or no-blocking if from atomic ctxt, or interruptible with whatever timeout if non-atomic (for example, to implement a CPU_PREP sort of ioctl) >> A default software-only implementation is provided, which can be used >> by drivers attaching a fence to a buffer when they have no other means >> for hw sync. But a memory backed fence is also envisioned, because it >> is common that GPU's can write to, or poll on some memory location for >> synchronization. For example: >> >> fence = dma_buf_get_fence(dmabuf); >> if (fence->ops == &mem_dma_fence_ops) { >> dma_buf *fence_buf; >> mem_dma_fence_get_buf(fence, &fence_buf, &offset); >> ... tell the hw the memory location to wait on ... >> } else { >> /* fall-back to sw sync * / >> dma_fence_add_callback(fence, my_cb); >> } > This will probably have to be done on dma-buf attach time instead, > so drivers that support both know if an interrupt needs to be inserted > in the command stream or not. probably a hint, ie. add a flags parameter to attach() would do the job? >> The memory location is itself backed by dma-buf, to simplify mapping >> to the device's address space, an idea borrowed from Maarten Lankhorst. >> >> NOTE: the memory location fence is not implemented yet, the above is >> just for explaining how it would work. >> >> On SoC platforms, if some other hw mechanism is provided for synchronizing >> between IP blocks, it could be supported as an alternate implementation >> with it's own fence ops in a similar way. >> >> The other non-sw implementations would wrap the add/cancel_callback and >> wait fence ops, so that they can keep track if a device not supporting >> hw sync is waiting on the fence, and in this case should arrange to > Standardizing an errno in case the device already signalled the fence > would be nice. I was just using EINVAL, but perhaps there is a better choice? >> call dma_fence_signal() at some point after the condition has changed, >> to notify other devices waiting on the fence. If there are no sw >> waiters, this can be skipped to avoid waking the CPU unnecessarily. > Can this be done inside interrupt context? I could insert some > semaphores into intel that would block execution, but I would > save a context switch if intel could release the command blocking > from inside irq context. yeah, it was the intention that signal() could be from irq handler directly (and that registered cb's can be called from atomic ctxt.. which is sufficient if they just have to bang a register or two, otherwise they can schedule a worker) >> The intention is to provide a userspace interface (presumably via eventfd) >> later, to be used in conjunction with dma-buf's mmap support for sw access >> to buffers (or for userspace apps that would prefer to do their own >> synchronization). > I'll have to look at this more in the morning but I see no barrier for > this being used with dmabufmgr right now. > > The fence lock should probably not be static but shared with the > dmabufmgr code, with _locked variants. > Oh and in your example code I noticed inconsistent use of spin_lock > and spin_lock_irqsave, do you intend it to be used in hardirq context? oh, whoops, I started w/ spin_lock() an then realized I wanted signal() from irq handlers and forgot to update all the other places where spin_loc
[RFC] dma-fence: dma-buf synchronization
oh, btw, this should be an [RFC] On Wed, Jul 11, 2012 at 5:29 PM, Rob Clark wrote: > From: Rob Clark > > A dma-fence can be attached to a buffer which is being filled or consumed > by hw, to allow userspace to pass the buffer without waiting to another > device. For example, userspace can call page_flip ioctl to display the > next frame of graphics after kicking the GPU but while the GPU is still > rendering. The display device sharing the buffer with the GPU would > attach a callback to get notified when the GPU's rendering-complete IRQ > fires, to update the scan-out address of the display, without having to > wake up userspace. > > A dma-fence is transient, one-shot deal. It is allocated and attached > to dma-buf's list of fences. When the one that attached it is done, > with the pending operation, it can signal the fence removing it from the > dma-buf's list of fences: > > + dma_buf_attach_fence() > + dma_fence_signal() > > Other drivers can access the current fence on the dma-buf (if any), > which increment's the fences refcnt: > > + dma_buf_get_fence() > + dma_fence_put() > > The one pending on the fence can add an async callback (and optionally > cancel it.. for example, to recover from GPU hangs): > > + dma_fence_add_callback() > + dma_fence_cancel_callback() > > Or wait synchronously (optionally with timeout or from atomic context): > > + dma_fence_wait() > > A default software-only implementation is provided, which can be used > by drivers attaching a fence to a buffer when they have no other means > for hw sync. But a memory backed fence is also envisioned, because it > is common that GPU's can write to, or poll on some memory location for > synchronization. For example: > > fence = dma_buf_get_fence(dmabuf); > if (fence->ops == &mem_dma_fence_ops) { > dma_buf *fence_buf; > mem_dma_fence_get_buf(fence, &fence_buf, &offset); > ... tell the hw the memory location to wait on ... > } else { > /* fall-back to sw sync * / > dma_fence_add_callback(fence, my_cb); > } > > The memory location is itself backed by dma-buf, to simplify mapping > to the device's address space, an idea borrowed from Maarten Lankhorst. > > NOTE: the memory location fence is not implemented yet, the above is > just for explaining how it would work. > > On SoC platforms, if some other hw mechanism is provided for synchronizing > between IP blocks, it could be supported as an alternate implementation > with it's own fence ops in a similar way. > > The other non-sw implementations would wrap the add/cancel_callback and > wait fence ops, so that they can keep track if a device not supporting > hw sync is waiting on the fence, and in this case should arrange to > call dma_fence_signal() at some point after the condition has changed, > to notify other devices waiting on the fence. If there are no sw > waiters, this can be skipped to avoid waking the CPU unnecessarily. > > The intention is to provide a userspace interface (presumably via eventfd) > later, to be used in conjunction with dma-buf's mmap support for sw access > to buffers (or for userspace apps that would prefer to do their own > synchronization). > --- > drivers/base/Makefile |2 +- > drivers/base/dma-buf.c|3 + > drivers/base/dma-fence.c | 325 > + > include/linux/dma-buf.h |3 + > include/linux/dma-fence.h | 118 > 5 files changed, 450 insertions(+), 1 deletion(-) > create mode 100644 drivers/base/dma-fence.c > create mode 100644 include/linux/dma-fence.h > > diff --git a/drivers/base/Makefile b/drivers/base/Makefile > index 5aa2d70..6e9f217 100644 > --- a/drivers/base/Makefile > +++ b/drivers/base/Makefile > @@ -10,7 +10,7 @@ obj-$(CONFIG_CMA) += dma-contiguous.o > obj-y += power/ > obj-$(CONFIG_HAS_DMA) += dma-mapping.o > obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o > -obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o > +obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o dma-fence.o > obj-$(CONFIG_ISA) += isa.o > obj-$(CONFIG_FW_LOADER)+= firmware_class.o > obj-$(CONFIG_NUMA) += node.o > diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c > index 24e88fe..b053236 100644 > --- a/drivers/base/dma-buf.c > +++ b/drivers/base/dma-buf.c > @@ -39,6 +39,8 @@ static int dma_buf_release(struct inode *inode, struct file > *file) > > dmabuf = file->private_data; > > + WARN_ON(!list_empty(&dmabuf->fence_list)); > + > dmabuf->ops->release(dmabuf); > kfree(dmabuf); > return 0; > @@ -119,6 +121,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct > dma_buf_ops *ops, > > mutex_init(&dmabuf->lock); > INIT_LIST_HEAD(&dmabuf->attachments); > + INIT_LIST_HEAD(&dmabuf->fence_list); > > return dmabuf; > } > diff --git a/drivers/base/dma-fence.c b/drivers/base/dma-fence.c > new file mode 100644 > index 000..a94ed01 > --
[PATCH] dma-fence: dma-buf synchronization
From: Rob Clark A dma-fence can be attached to a buffer which is being filled or consumed by hw, to allow userspace to pass the buffer without waiting to another device. For example, userspace can call page_flip ioctl to display the next frame of graphics after kicking the GPU but while the GPU is still rendering. The display device sharing the buffer with the GPU would attach a callback to get notified when the GPU's rendering-complete IRQ fires, to update the scan-out address of the display, without having to wake up userspace. A dma-fence is transient, one-shot deal. It is allocated and attached to dma-buf's list of fences. When the one that attached it is done, with the pending operation, it can signal the fence removing it from the dma-buf's list of fences: + dma_buf_attach_fence() + dma_fence_signal() Other drivers can access the current fence on the dma-buf (if any), which increment's the fences refcnt: + dma_buf_get_fence() + dma_fence_put() The one pending on the fence can add an async callback (and optionally cancel it.. for example, to recover from GPU hangs): + dma_fence_add_callback() + dma_fence_cancel_callback() Or wait synchronously (optionally with timeout or from atomic context): + dma_fence_wait() A default software-only implementation is provided, which can be used by drivers attaching a fence to a buffer when they have no other means for hw sync. But a memory backed fence is also envisioned, because it is common that GPU's can write to, or poll on some memory location for synchronization. For example: fence = dma_buf_get_fence(dmabuf); if (fence->ops == &mem_dma_fence_ops) { dma_buf *fence_buf; mem_dma_fence_get_buf(fence, &fence_buf, &offset); ... tell the hw the memory location to wait on ... } else { /* fall-back to sw sync * / dma_fence_add_callback(fence, my_cb); } The memory location is itself backed by dma-buf, to simplify mapping to the device's address space, an idea borrowed from Maarten Lankhorst. NOTE: the memory location fence is not implemented yet, the above is just for explaining how it would work. On SoC platforms, if some other hw mechanism is provided for synchronizing between IP blocks, it could be supported as an alternate implementation with it's own fence ops in a similar way. The other non-sw implementations would wrap the add/cancel_callback and wait fence ops, so that they can keep track if a device not supporting hw sync is waiting on the fence, and in this case should arrange to call dma_fence_signal() at some point after the condition has changed, to notify other devices waiting on the fence. If there are no sw waiters, this can be skipped to avoid waking the CPU unnecessarily. The intention is to provide a userspace interface (presumably via eventfd) later, to be used in conjunction with dma-buf's mmap support for sw access to buffers (or for userspace apps that would prefer to do their own synchronization). --- drivers/base/Makefile |2 +- drivers/base/dma-buf.c|3 + drivers/base/dma-fence.c | 325 + include/linux/dma-buf.h |3 + include/linux/dma-fence.h | 118 5 files changed, 450 insertions(+), 1 deletion(-) create mode 100644 drivers/base/dma-fence.c create mode 100644 include/linux/dma-fence.h diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 5aa2d70..6e9f217 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_CMA) += dma-contiguous.o obj-y += power/ obj-$(CONFIG_HAS_DMA) += dma-mapping.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o -obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o +obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o dma-fence.o obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER)+= firmware_class.o obj-$(CONFIG_NUMA) += node.o diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 24e88fe..b053236 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -39,6 +39,8 @@ static int dma_buf_release(struct inode *inode, struct file *file) dmabuf = file->private_data; + WARN_ON(!list_empty(&dmabuf->fence_list)); + dmabuf->ops->release(dmabuf); kfree(dmabuf); return 0; @@ -119,6 +121,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, mutex_init(&dmabuf->lock); INIT_LIST_HEAD(&dmabuf->attachments); + INIT_LIST_HEAD(&dmabuf->fence_list); return dmabuf; } diff --git a/drivers/base/dma-fence.c b/drivers/base/dma-fence.c new file mode 100644 index 000..a94ed01 --- /dev/null +++ b/drivers/base/dma-fence.c @@ -0,0 +1,325 @@ +/* + * Fence mechanism for dma-buf to allow for asynchronous dma access + * + * Copyright (C) 2012 Texas Instruments + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GN
Re: [PATCH] dma-fence: dma-buf synchronization
On Wed, Jul 11, 2012 at 6:49 PM, Maarten Lankhorst wrote: > Op 12-07-12 00:29, Rob Clark schreef: >> From: Rob Clark >> >> A dma-fence can be attached to a buffer which is being filled or consumed >> by hw, to allow userspace to pass the buffer without waiting to another >> device. For example, userspace can call page_flip ioctl to display the >> next frame of graphics after kicking the GPU but while the GPU is still >> rendering. The display device sharing the buffer with the GPU would >> attach a callback to get notified when the GPU's rendering-complete IRQ >> fires, to update the scan-out address of the display, without having to >> wake up userspace. >> >> A dma-fence is transient, one-shot deal. It is allocated and attached >> to dma-buf's list of fences. When the one that attached it is done, >> with the pending operation, it can signal the fence removing it from the >> dma-buf's list of fences: >> >> + dma_buf_attach_fence() >> + dma_fence_signal() >> >> Other drivers can access the current fence on the dma-buf (if any), >> which increment's the fences refcnt: >> >> + dma_buf_get_fence() >> + dma_fence_put() >> >> The one pending on the fence can add an async callback (and optionally >> cancel it.. for example, to recover from GPU hangs): >> >> + dma_fence_add_callback() >> + dma_fence_cancel_callback() >> >> Or wait synchronously (optionally with timeout or from atomic context): >> >> + dma_fence_wait() > Waiting for an undefined time from atomic context is probably > not a good idea. However just checking non-blocking if the fence > has passed would be fine. yeah, the intention was to use short timeout or no-blocking if from atomic ctxt, or interruptible with whatever timeout if non-atomic (for example, to implement a CPU_PREP sort of ioctl) >> A default software-only implementation is provided, which can be used >> by drivers attaching a fence to a buffer when they have no other means >> for hw sync. But a memory backed fence is also envisioned, because it >> is common that GPU's can write to, or poll on some memory location for >> synchronization. For example: >> >> fence = dma_buf_get_fence(dmabuf); >> if (fence->ops == &mem_dma_fence_ops) { >> dma_buf *fence_buf; >> mem_dma_fence_get_buf(fence, &fence_buf, &offset); >> ... tell the hw the memory location to wait on ... >> } else { >> /* fall-back to sw sync * / >> dma_fence_add_callback(fence, my_cb); >> } > This will probably have to be done on dma-buf attach time instead, > so drivers that support both know if an interrupt needs to be inserted > in the command stream or not. probably a hint, ie. add a flags parameter to attach() would do the job? >> The memory location is itself backed by dma-buf, to simplify mapping >> to the device's address space, an idea borrowed from Maarten Lankhorst. >> >> NOTE: the memory location fence is not implemented yet, the above is >> just for explaining how it would work. >> >> On SoC platforms, if some other hw mechanism is provided for synchronizing >> between IP blocks, it could be supported as an alternate implementation >> with it's own fence ops in a similar way. >> >> The other non-sw implementations would wrap the add/cancel_callback and >> wait fence ops, so that they can keep track if a device not supporting >> hw sync is waiting on the fence, and in this case should arrange to > Standardizing an errno in case the device already signalled the fence > would be nice. I was just using EINVAL, but perhaps there is a better choice? >> call dma_fence_signal() at some point after the condition has changed, >> to notify other devices waiting on the fence. If there are no sw >> waiters, this can be skipped to avoid waking the CPU unnecessarily. > Can this be done inside interrupt context? I could insert some > semaphores into intel that would block execution, but I would > save a context switch if intel could release the command blocking > from inside irq context. yeah, it was the intention that signal() could be from irq handler directly (and that registered cb's can be called from atomic ctxt.. which is sufficient if they just have to bang a register or two, otherwise they can schedule a worker) >> The intention is to provide a userspace interface (presumably via eventfd) >> later, to be used in conjunction with dma-buf's mmap support for sw access >> to buffers (or for userspace apps that would prefer to do their own >> synchronization). > I'll have to look at this more in the morning but I see no barrier for > this being used with dmabufmgr right now. > > The fence lock should probably not be static but shared with the > dmabufmgr code, with _locked variants. > Oh and in your example code I noticed inconsistent use of spin_lock > and spin_lock_irqsave, do you intend it to be used in hardirq context? oh, whoops, I started w/ spin_lock() an then realized I wanted signal() from irq handlers and forgot to update all the other places where spin_loc
Re: [PATCH] dma-fence: dma-buf synchronization
Op 12-07-12 00:29, Rob Clark schreef: > From: Rob Clark > > A dma-fence can be attached to a buffer which is being filled or consumed > by hw, to allow userspace to pass the buffer without waiting to another > device. For example, userspace can call page_flip ioctl to display the > next frame of graphics after kicking the GPU but while the GPU is still > rendering. The display device sharing the buffer with the GPU would > attach a callback to get notified when the GPU's rendering-complete IRQ > fires, to update the scan-out address of the display, without having to > wake up userspace. > > A dma-fence is transient, one-shot deal. It is allocated and attached > to dma-buf's list of fences. When the one that attached it is done, > with the pending operation, it can signal the fence removing it from the > dma-buf's list of fences: > > + dma_buf_attach_fence() > + dma_fence_signal() > > Other drivers can access the current fence on the dma-buf (if any), > which increment's the fences refcnt: > > + dma_buf_get_fence() > + dma_fence_put() > > The one pending on the fence can add an async callback (and optionally > cancel it.. for example, to recover from GPU hangs): > > + dma_fence_add_callback() > + dma_fence_cancel_callback() > > Or wait synchronously (optionally with timeout or from atomic context): > > + dma_fence_wait() Waiting for an undefined time from atomic context is probably not a good idea. However just checking non-blocking if the fence has passed would be fine. > A default software-only implementation is provided, which can be used > by drivers attaching a fence to a buffer when they have no other means > for hw sync. But a memory backed fence is also envisioned, because it > is common that GPU's can write to, or poll on some memory location for > synchronization. For example: > > fence = dma_buf_get_fence(dmabuf); > if (fence->ops == &mem_dma_fence_ops) { > dma_buf *fence_buf; > mem_dma_fence_get_buf(fence, &fence_buf, &offset); > ... tell the hw the memory location to wait on ... > } else { > /* fall-back to sw sync * / > dma_fence_add_callback(fence, my_cb); > } This will probably have to be done on dma-buf attach time instead, so drivers that support both know if an interrupt needs to be inserted in the command stream or not. > The memory location is itself backed by dma-buf, to simplify mapping > to the device's address space, an idea borrowed from Maarten Lankhorst. > > NOTE: the memory location fence is not implemented yet, the above is > just for explaining how it would work. > > On SoC platforms, if some other hw mechanism is provided for synchronizing > between IP blocks, it could be supported as an alternate implementation > with it's own fence ops in a similar way. > > The other non-sw implementations would wrap the add/cancel_callback and > wait fence ops, so that they can keep track if a device not supporting > hw sync is waiting on the fence, and in this case should arrange to Standardizing an errno in case the device already signalled the fence would be nice. > call dma_fence_signal() at some point after the condition has changed, > to notify other devices waiting on the fence. If there are no sw > waiters, this can be skipped to avoid waking the CPU unnecessarily. Can this be done inside interrupt context? I could insert some semaphores into intel that would block execution, but I would save a context switch if intel could release the command blocking from inside irq context. > The intention is to provide a userspace interface (presumably via eventfd) > later, to be used in conjunction with dma-buf's mmap support for sw access > to buffers (or for userspace apps that would prefer to do their own > synchronization). I'll have to look at this more in the morning but I see no barrier for this being used with dmabufmgr right now. The fence lock should probably not be static but shared with the dmabufmgr code, with _locked variants. Oh and in your example code I noticed inconsistent use of spin_lock and spin_lock_irqsave, do you intend it to be used in hardirq context? ~Maarten ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 25/81] drm: remove the list_head from drm_mode_set
It's unused. At it confused me quite a bit until I've discovered that. Cc: dri-devel at lists.freedesktop.org Signed-Off-by: Daniel Vetter --- include/drm/drm_crtc.h |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index bac55c2..a1a0386 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -676,8 +676,6 @@ struct drm_plane { * This is used to set modes. */ struct drm_mode_set { - struct list_head head; - struct drm_framebuffer *fb; struct drm_crtc *crtc; struct drm_display_mode *mode; -- 1.7.7.6
[PATCH 24/81] drm/fb helper: don't call drm_crtc_helper_set_config
Go through the interface vtable instead, because not everyone might be using the crtc helper code. Cc: dri-devel at lists.freedesktop.org Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5683b7f..bf97c0a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -228,7 +228,7 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) int i, ret; for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; - ret = drm_crtc_helper_set_config(mode_set); + ret = mode_set->crtc->funcs->set_config(mode_set); if (ret) error = true; } -- 1.7.7.6
Re: [RFC] dma-fence: dma-buf synchronization
oh, btw, this should be an [RFC] On Wed, Jul 11, 2012 at 5:29 PM, Rob Clark wrote: > From: Rob Clark > > A dma-fence can be attached to a buffer which is being filled or consumed > by hw, to allow userspace to pass the buffer without waiting to another > device. For example, userspace can call page_flip ioctl to display the > next frame of graphics after kicking the GPU but while the GPU is still > rendering. The display device sharing the buffer with the GPU would > attach a callback to get notified when the GPU's rendering-complete IRQ > fires, to update the scan-out address of the display, without having to > wake up userspace. > > A dma-fence is transient, one-shot deal. It is allocated and attached > to dma-buf's list of fences. When the one that attached it is done, > with the pending operation, it can signal the fence removing it from the > dma-buf's list of fences: > > + dma_buf_attach_fence() > + dma_fence_signal() > > Other drivers can access the current fence on the dma-buf (if any), > which increment's the fences refcnt: > > + dma_buf_get_fence() > + dma_fence_put() > > The one pending on the fence can add an async callback (and optionally > cancel it.. for example, to recover from GPU hangs): > > + dma_fence_add_callback() > + dma_fence_cancel_callback() > > Or wait synchronously (optionally with timeout or from atomic context): > > + dma_fence_wait() > > A default software-only implementation is provided, which can be used > by drivers attaching a fence to a buffer when they have no other means > for hw sync. But a memory backed fence is also envisioned, because it > is common that GPU's can write to, or poll on some memory location for > synchronization. For example: > > fence = dma_buf_get_fence(dmabuf); > if (fence->ops == &mem_dma_fence_ops) { > dma_buf *fence_buf; > mem_dma_fence_get_buf(fence, &fence_buf, &offset); > ... tell the hw the memory location to wait on ... > } else { > /* fall-back to sw sync * / > dma_fence_add_callback(fence, my_cb); > } > > The memory location is itself backed by dma-buf, to simplify mapping > to the device's address space, an idea borrowed from Maarten Lankhorst. > > NOTE: the memory location fence is not implemented yet, the above is > just for explaining how it would work. > > On SoC platforms, if some other hw mechanism is provided for synchronizing > between IP blocks, it could be supported as an alternate implementation > with it's own fence ops in a similar way. > > The other non-sw implementations would wrap the add/cancel_callback and > wait fence ops, so that they can keep track if a device not supporting > hw sync is waiting on the fence, and in this case should arrange to > call dma_fence_signal() at some point after the condition has changed, > to notify other devices waiting on the fence. If there are no sw > waiters, this can be skipped to avoid waking the CPU unnecessarily. > > The intention is to provide a userspace interface (presumably via eventfd) > later, to be used in conjunction with dma-buf's mmap support for sw access > to buffers (or for userspace apps that would prefer to do their own > synchronization). > --- > drivers/base/Makefile |2 +- > drivers/base/dma-buf.c|3 + > drivers/base/dma-fence.c | 325 > + > include/linux/dma-buf.h |3 + > include/linux/dma-fence.h | 118 > 5 files changed, 450 insertions(+), 1 deletion(-) > create mode 100644 drivers/base/dma-fence.c > create mode 100644 include/linux/dma-fence.h > > diff --git a/drivers/base/Makefile b/drivers/base/Makefile > index 5aa2d70..6e9f217 100644 > --- a/drivers/base/Makefile > +++ b/drivers/base/Makefile > @@ -10,7 +10,7 @@ obj-$(CONFIG_CMA) += dma-contiguous.o > obj-y += power/ > obj-$(CONFIG_HAS_DMA) += dma-mapping.o > obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o > -obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o > +obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o dma-fence.o > obj-$(CONFIG_ISA) += isa.o > obj-$(CONFIG_FW_LOADER)+= firmware_class.o > obj-$(CONFIG_NUMA) += node.o > diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c > index 24e88fe..b053236 100644 > --- a/drivers/base/dma-buf.c > +++ b/drivers/base/dma-buf.c > @@ -39,6 +39,8 @@ static int dma_buf_release(struct inode *inode, struct file > *file) > > dmabuf = file->private_data; > > + WARN_ON(!list_empty(&dmabuf->fence_list)); > + > dmabuf->ops->release(dmabuf); > kfree(dmabuf); > return 0; > @@ -119,6 +121,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct > dma_buf_ops *ops, > > mutex_init(&dmabuf->lock); > INIT_LIST_HEAD(&dmabuf->attachments); > + INIT_LIST_HEAD(&dmabuf->fence_list); > > return dmabuf; > } > diff --git a/drivers/base/dma-fence.c b/drivers/base/dma-fence.c > new file mode 100644 > index 000..a94ed01 > --
[PATCH] dma-fence: dma-buf synchronization
From: Rob Clark A dma-fence can be attached to a buffer which is being filled or consumed by hw, to allow userspace to pass the buffer without waiting to another device. For example, userspace can call page_flip ioctl to display the next frame of graphics after kicking the GPU but while the GPU is still rendering. The display device sharing the buffer with the GPU would attach a callback to get notified when the GPU's rendering-complete IRQ fires, to update the scan-out address of the display, without having to wake up userspace. A dma-fence is transient, one-shot deal. It is allocated and attached to dma-buf's list of fences. When the one that attached it is done, with the pending operation, it can signal the fence removing it from the dma-buf's list of fences: + dma_buf_attach_fence() + dma_fence_signal() Other drivers can access the current fence on the dma-buf (if any), which increment's the fences refcnt: + dma_buf_get_fence() + dma_fence_put() The one pending on the fence can add an async callback (and optionally cancel it.. for example, to recover from GPU hangs): + dma_fence_add_callback() + dma_fence_cancel_callback() Or wait synchronously (optionally with timeout or from atomic context): + dma_fence_wait() A default software-only implementation is provided, which can be used by drivers attaching a fence to a buffer when they have no other means for hw sync. But a memory backed fence is also envisioned, because it is common that GPU's can write to, or poll on some memory location for synchronization. For example: fence = dma_buf_get_fence(dmabuf); if (fence->ops == &mem_dma_fence_ops) { dma_buf *fence_buf; mem_dma_fence_get_buf(fence, &fence_buf, &offset); ... tell the hw the memory location to wait on ... } else { /* fall-back to sw sync * / dma_fence_add_callback(fence, my_cb); } The memory location is itself backed by dma-buf, to simplify mapping to the device's address space, an idea borrowed from Maarten Lankhorst. NOTE: the memory location fence is not implemented yet, the above is just for explaining how it would work. On SoC platforms, if some other hw mechanism is provided for synchronizing between IP blocks, it could be supported as an alternate implementation with it's own fence ops in a similar way. The other non-sw implementations would wrap the add/cancel_callback and wait fence ops, so that they can keep track if a device not supporting hw sync is waiting on the fence, and in this case should arrange to call dma_fence_signal() at some point after the condition has changed, to notify other devices waiting on the fence. If there are no sw waiters, this can be skipped to avoid waking the CPU unnecessarily. The intention is to provide a userspace interface (presumably via eventfd) later, to be used in conjunction with dma-buf's mmap support for sw access to buffers (or for userspace apps that would prefer to do their own synchronization). --- drivers/base/Makefile |2 +- drivers/base/dma-buf.c|3 + drivers/base/dma-fence.c | 325 + include/linux/dma-buf.h |3 + include/linux/dma-fence.h | 118 5 files changed, 450 insertions(+), 1 deletion(-) create mode 100644 drivers/base/dma-fence.c create mode 100644 include/linux/dma-fence.h diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 5aa2d70..6e9f217 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_CMA) += dma-contiguous.o obj-y += power/ obj-$(CONFIG_HAS_DMA) += dma-mapping.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o -obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o +obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o dma-fence.o obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER)+= firmware_class.o obj-$(CONFIG_NUMA) += node.o diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 24e88fe..b053236 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -39,6 +39,8 @@ static int dma_buf_release(struct inode *inode, struct file *file) dmabuf = file->private_data; + WARN_ON(!list_empty(&dmabuf->fence_list)); + dmabuf->ops->release(dmabuf); kfree(dmabuf); return 0; @@ -119,6 +121,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, mutex_init(&dmabuf->lock); INIT_LIST_HEAD(&dmabuf->attachments); + INIT_LIST_HEAD(&dmabuf->fence_list); return dmabuf; } diff --git a/drivers/base/dma-fence.c b/drivers/base/dma-fence.c new file mode 100644 index 000..a94ed01 --- /dev/null +++ b/drivers/base/dma-fence.c @@ -0,0 +1,325 @@ +/* + * Fence mechanism for dma-buf to allow for asynchronous dma access + * + * Copyright (C) 2012 Texas Instruments + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of th
[Bug 15844] Failed to load firmware "radeon/RV770_pfp.bin"
https://bugzilla.kernel.org/show_bug.cgi?id=15844 Alan changed: What|Removed |Added Status|NEW |RESOLVED CC||alan at lxorguk.ukuu.org.uk Resolution||DOCUMENTED -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[PATCH 7/7] drm/exynos: Add IOMMU support for mapping gem object
A gem object is created using dma_alloc_writecombine. Currently, this buffer is assumed to be contiguous. If a IOMMU mapping is created for DRM, this buffer would be non-contig so the map functions are modified to call dma_mmap_writecombine. This works for both contig and non-contig buffers. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 35 ++ 1 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 5c8b683..59240f7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -162,17 +162,22 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, { struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - unsigned long pfn; if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { + unsigned long pfn; if (!buf->pages) return -EINTR; pfn = page_to_pfn(buf->pages[page_offset++]); - } else - pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; - - return vm_insert_mixed(vma, f_vaddr, pfn); + return vm_insert_mixed(vma, f_vaddr, pfn); + } else { + int ret; + ret = dma_mmap_writecombine(obj->dev->dev, vma, buf->kvaddr, + buf->dma_addr, buf->size); + if (ret) + DRM_ERROR("dma_mmap_writecombine failed\n"); + return ret; + } } static int exynos_drm_gem_get_pages(struct drm_gem_object *obj) @@ -503,7 +508,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, struct drm_gem_object *obj = filp->private_data; struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct exynos_drm_gem_buf *buffer; - unsigned long pfn, vm_size, usize, uaddr = vma->vm_start; + unsigned long vm_size, usize, uaddr = vma->vm_start; int ret; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -543,19 +548,11 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, usize -= PAGE_SIZE; } while (usize > 0); } else { - /* -* get page frame number to physical memory to be mapped -* to user space. -*/ - pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> - PAGE_SHIFT; - - DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); - - if (remap_pfn_range(vma, vma->vm_start, pfn, vm_size, - vma->vm_page_prot)) { - DRM_ERROR("failed to remap pfn range.\n"); - return -EAGAIN; + ret = dma_mmap_writecombine(obj->dev->dev, vma, buffer->kvaddr, + buffer->dma_addr, buffer->size); + if (ret) { + DRM_ERROR("dma_mmap_writecombine failed\n"); + return ret; } } -- 1.7.0.4
[PATCH 6/7] drm/exynos: Add exynos drm specific fb_mmap function
This patch adds a exynos drm specific implementation of fb_mmap which supports mapping a non-contiguous buffer to user space. This new function does not assume that the frame buffer is contiguous and calls dma_mmap_writecombine for mapping the buffer to user space. dma_mmap_writecombine will be able to map a contiguous buffer as well as non-contig buffer depending on whether an IOMMU mapping is created for drm or not. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 16 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d5586cc..b53e638 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -46,8 +46,24 @@ struct exynos_drm_fbdev { struct exynos_drm_gem_obj *exynos_gem_obj; }; +static int exynos_drm_fb_mmap(struct fb_info *info, + struct vm_area_struct *vma) +{ + if ((vma->vm_end - vma->vm_start) > info->fix.smem_len) + return -EINVAL; + + vma->vm_pgoff = 0; + vma->vm_flags |= VM_IO | VM_RESERVED; + if (dma_mmap_writecombine(info->device, vma, info->screen_base, + info->fix.smem_start, vma->vm_end - vma->vm_start)) + return -EAGAIN; + + return 0; +} + static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, + .fb_mmap= exynos_drm_fb_mmap, .fb_fillrect= cfb_fillrect, .fb_copyarea= cfb_copyarea, .fb_imageblit = cfb_imageblit, -- 1.7.0.4
[PATCH 5/7] drm/exynos: attach drm device with common drm mapping
This patch sets the common mapping created during drm init, to the drm device's archdata. The dma_ops of drm device is set as arm_iommu_ops. The common mapping is shared across all the drm devices which ensures that any buffer allocated with drm is accessible by drm-fimd or drm-hdmi or both. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_drv.c |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index c3ad87e..2e40ca8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -276,6 +276,15 @@ static struct drm_driver exynos_drm_driver = { static int exynos_drm_platform_probe(struct platform_device *pdev) { +#ifdef CONFIG_EXYNOS_IOMMU + struct device *dev = &pdev->dev; + + kref_get(&exynos_drm_common_mapping->kref); + dev->archdata.mapping = exynos_drm_common_mapping; + set_dma_ops(dev, &arm_iommu_ops); + + DRM_INFO("drm common mapping set to drm device.\n"); +#endif DRM_DEBUG_DRIVER("%s\n", __FILE__); exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); -- 1.7.0.4
[PATCH 4/7] ARM: dma-mapping: rename and export iommu_ops
This patch renames the dma_ops structure for arm from iommu_ops to arm_iommu_ops. This structure is also exported and declared extern so that it can be set as any device's dma ops directly. Signed-off-by: Prathyush K --- arch/arm/include/asm/dma-mapping.h |1 + arch/arm/mm/dma-mapping.c |5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index bbef15d..5957357 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -13,6 +13,7 @@ #define DMA_ERROR_CODE (~0) extern struct dma_map_ops arm_dma_ops; +extern struct dma_map_ops arm_iommu_ops; static inline struct dma_map_ops *get_dma_ops(struct device *dev) { diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 0f9358b..cff13ac 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1567,7 +1567,7 @@ static void arm_iommu_sync_single_for_device(struct device *dev, __dma_page_cpu_to_dev(page, offset, size, dir); } -struct dma_map_ops iommu_ops = { +struct dma_map_ops arm_iommu_ops = { .alloc = arm_iommu_alloc_attrs, .free = arm_iommu_free_attrs, .mmap = arm_iommu_mmap_attrs, @@ -1582,6 +1582,7 @@ struct dma_map_ops iommu_ops = { .sync_sg_for_cpu= arm_iommu_sync_sg_for_cpu, .sync_sg_for_device = arm_iommu_sync_sg_for_device, }; +EXPORT_SYMBOL(arm_iommu_ops); /** * arm_iommu_create_mapping @@ -1674,7 +1675,7 @@ int arm_iommu_attach_device(struct device *dev, kref_get(&mapping->kref); dev->archdata.mapping = mapping; - set_dma_ops(dev, &iommu_ops); + set_dma_ops(dev, &arm_iommu_ops); pr_info("Attached IOMMU controller to %s device.\n", dev_name(dev)); return 0; -- 1.7.0.4
[PATCH 3/7] drm/exynos: add IOMMU support to drm fimd
This patch adds device tree based IOMMU support to DRM FIMD. During probe, the driver searches for a 'sysmmu' field in the device node. The sysmmu field points to the corresponding sysmmu device of fimd. This sysmmu device is retrieved and set as fimd's sysmmu. The common IOMMU mapping created during DRM init is then attached to drm fimd. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 54 +- 1 files changed, 53 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 15b5286..6d4048a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -19,7 +19,7 @@ #include #include #include - +#include #include #include @@ -790,12 +790,56 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable) } #ifdef CONFIG_OF + +#ifdef CONFIG_EXYNOS_IOMMU +static int iommu_init(struct device *dev) +{ + struct platform_device *pds; + struct device_node *dn, *dns; + const __be32 *parp; + int ret; + + dn = dev->of_node; + parp = of_get_property(dn, "sysmmu", NULL); + if (parp == NULL) { + dev_err(dev, "failed to find sysmmu property\n"); + return -EINVAL; + } + dns = of_find_node_by_phandle(be32_to_cpup(parp)); + if (dns == NULL) { + dev_err(dev, "failed to find sysmmu node\n"); + return -EINVAL; + } + pds = of_find_device_by_node(dns); + if (pds == NULL) { + dev_err(dev, "failed to find sysmmu platform device\n"); + return -EINVAL; + } + + platform_set_sysmmu(&pds->dev, dev); + dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL); + if (!dev->dma_parms) { + dev_err(dev, "failed to allocate dma parms\n"); + return -ENOMEM; + } + dma_set_max_seg_size(dev, 0xu); + + ret = arm_iommu_attach_device(dev, exynos_drm_common_mapping); + if (ret) { + dev_err(dev, "failed to attach device\n"); + return ret; + } + return 0; +} +#endif + static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) { struct device_node *np = dev->of_node; struct device_node *disp_np; struct exynos_drm_fimd_pdata *pd; u32 data[4]; + int ret; pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { @@ -803,6 +847,14 @@ static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) return ERR_PTR(-ENOMEM); } +#ifdef CONFIG_EXYNOS_IOMMU + ret = iommu_init(dev); + if (ret) { + dev_err(dev, "failed to initialize iommu\n"); + return ERR_PTR(ret); + } +#endif + if (of_get_property(np, "samsung,fimd-vidout-rgb", NULL)) pd->vidcon0 |= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB; if (of_get_property(np, "samsung,fimd-vidout-tv", NULL)) -- 1.7.0.4
[PATCH 2/7] ARM: EXYNOS5: add sysmmu field to fimd device node
This patch adds the sysmmu field to the fimd device node in the exynos5250 device tree. This field is used to link the parent device and its sysmmu device in the device tree. Signed-off-by: Prathyush K --- arch/arm/boot/dts/exynos5250.dtsi |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 3e85b2b..2c7ce61 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -461,6 +461,7 @@ interrupt-parent = <&combiner>; reg = <0x1440 0x4>; interrupts = <18 5>, <18 4>, <18 6>; + sysmmu = <&sysmmu_11>; }; mipi { -- 1.7.0.4
[PATCH 1/7] drm/exynos: create common IOMMU mapping for DRM
This patch creates an IOMMU mapping during drm init. This is used by all the drm devices including the exynos drm virtual device. This ensures that when drm creates a buffer using the dma-mapping framework, this buffer is accessible by all the drm devices like hdmi/fimd. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_core.c |3 +++ drivers/gpu/drm/exynos/exynos_drm_drv.c | 21 + drivers/gpu/drm/exynos/exynos_drm_drv.h | 10 ++ 3 files changed, 34 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index eaf630d..13ecca6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -34,6 +34,9 @@ static LIST_HEAD(exynos_drm_subdrv_list); static struct drm_device *drm_dev; +#ifdef CONFIG_EXYNOS_IOMMU +struct dma_iommu_mapping *exynos_drm_common_mapping; +#endif static int exynos_drm_subdrv_probe(struct drm_device *dev, struct exynos_drm_subdrv *subdrv) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index d6de2e0..c3ad87e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -307,6 +307,18 @@ static int __init exynos_drm_init(void) DRM_DEBUG_DRIVER("%s\n", __FILE__); +#ifdef CONFIG_EXYNOS_IOMMU + exynos_drm_common_mapping = arm_iommu_create_mapping(&platform_bus_type, + EXYNOS_DRM_DMA_ADDR, + EXYNOS_DRM_IOMMU_SIZE, + EXYNOS_DRM_IOMMU_ORDER); + if (IS_ERR_OR_NULL(exynos_drm_common_mapping)) { + DRM_ERROR("failed to created IOMMU mapping\n"); + ret = PTR_ERR(exynos_drm_common_mapping); + goto out_iommu; + } +#endif + #ifdef CONFIG_DRM_EXYNOS_FIMD ret = platform_driver_register(&fimd_driver); if (ret < 0) @@ -367,6 +379,11 @@ out_hdmi: platform_driver_unregister(&fimd_driver); out_fimd: #endif +#ifdef CONFIG_EXYNOS_IOMMU + arm_iommu_release_mapping(exynos_drm_common_mapping); + exynos_drm_common_mapping = NULL; +out_iommu: +#endif return ret; } @@ -393,6 +410,10 @@ static void __exit exynos_drm_exit(void) #ifdef CONFIG_DRM_EXYNOS_FIMD platform_driver_unregister(&fimd_driver); #endif +#ifdef CONFIG_EXYNOS_IOMMU + arm_iommu_release_mapping(exynos_drm_common_mapping); + exynos_drm_common_mapping = NULL; +#endif } module_init(exynos_drm_init); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index c82c90c..bd12ee2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -31,11 +31,18 @@ #include #include "drm.h" +#ifdef CONFIG_EXYNOS_IOMMU +#include +#include +#endif #define MAX_CRTC 3 #define MAX_PLANE 5 #define MAX_FB_BUFFER 4 #define DEFAULT_ZPOS -1 +#define EXYNOS_DRM_DMA_ADDR0x2000 +#define EXYNOS_DRM_IOMMU_SIZE SZ_128M +#define EXYNOS_DRM_IOMMU_ORDER 4 struct drm_device; struct exynos_drm_overlay; @@ -304,4 +311,7 @@ extern struct platform_driver mixer_driver; extern struct platform_driver exynos_drm_common_hdmi_driver; extern struct platform_driver vidi_driver; extern struct platform_driver g2d_driver; +#ifdef CONFIG_EXYNOS_IOMMU +extern struct dma_iommu_mapping *exynos_drm_common_mapping; +#endif #endif -- 1.7.0.4
[PATCH 0/7] [RFC] drm/exynos: Add IOMMU support to DRM
The dma-mapping framework needs a IOMMU mapping to be created for the device which allocates/maps/frees the non-contig buffer. In the DRM framework, a gem buffer is created by the DRM virtual device and not directly by any of the physical devices (FIMD, HDMI etc). Each gem object can be set as a framebuffer to one or many of the drm devices. So a gem object cannot be allocated for any one device. All the DRM devices should be able to access this buffer. The proposed method is to create a common IOMMU mapping during drm init. This mapping is then attached to all of the drm devices including the drm device. [PATCH 1/7] drm/exynos: create common IOMMU mapping for DRM During the probe of drm fimd, the driver retrieves a 'sysmmu' field in the device node for fimd. If such a field exists, the driver retrieves the platform device of the sysmmu device. This sysmmu is set as the sysmmu for fimd. The common mapping created is then attached to fimd. This needs to be done for all the other devices (hdmi, vidi etc). [PATCH 2/7] ARM: EXYNOS5: add sysmmu field to fimd device node [PATCH 3/7] drm/exynos: add IOMMU support to drm fimd During DRM's probe which happens last, the common mapping is set to its archdata and iommu ops are set as its dma ops. This requires a modification in the dma-mapping framework so that the iommu ops can be visible to all drivers. [PATCH 4/7] ARM: dma-mapping: rename and export iommu_ops [PATCH 5/7] drm/exynos: attach drm device with common drm mapping Currently allocation and free use the iommu framework by calling dma_alloc_writecombine and dma_free_writecombine respectively. For mapping the buffers to user space, the mmap functions assume that the buffer is contiguous. This is modified by calling dma_mmap_writecombine. [PATCH 6/7] drm/exynos: Add exynos drm specific fb_mmap function [PATCH 7/7] Add IOMMU support for mapping gem object The device tree based patches are based on Leela's patch which was posted last week for adding DT support to DRM FIMD. The patch to add sysmmu field is for reference only and will be posted to the device tree mailing list. Same with the rename and export iommu_ops patch. These patches are tested on Exynos5250 SMDK board and tested with modetest from libdrm tests. Prathyush K (7): drm/exynos: create common IOMMU mapping for DRM ARM: EXYNOS5: add sysmmu field to fimd device node drm/exynos: add IOMMU support to drm fimd ARM: dma-mapping: rename and export iommu_ops drm/exynos: attach drm device with common drm mapping drm/exynos: Add exynos drm specific fb_mmap function drm/exynos: Add IOMMU support for mapping gem object arch/arm/boot/dts/exynos5250.dtsi |1 + arch/arm/include/asm/dma-mapping.h|1 + arch/arm/mm/dma-mapping.c |5 ++- drivers/gpu/drm/exynos/exynos_drm_core.c |3 ++ drivers/gpu/drm/exynos/exynos_drm_drv.c | 30 drivers/gpu/drm/exynos/exynos_drm_drv.h | 10 + drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 16 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 54 - drivers/gpu/drm/exynos/exynos_drm_gem.c | 35 -- 9 files changed, 133 insertions(+), 22 deletions(-)
[Bug 15748] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
https://bugzilla.kernel.org/show_bug.cgi?id=15748 Alan changed: What|Removed |Added Status|NEW |RESOLVED CC||alan at lxorguk.ukuu.org.uk Resolution||OBSOLETE --- Comment #2 from Alan 2012-07-11 15:08:31 --- Closing as this code has changed hugely since the reported version -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[Bug 15738] VGA output of Radeon HD3450 displays too bright colors with KMS radeon driver
https://bugzilla.kernel.org/show_bug.cgi?id=15738 Alan changed: What|Removed |Added Status|NEW |RESOLVED CC||alan at lxorguk.ukuu.org.uk Resolution||CODE_FIX -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[PATCH V2 2/2] drm/exynos: Modifying exynos drm fimd to support exynos5
From: Prathyush K The name of the exynos drm fimd device is renamed to exynos-drm-fimd and two ids are created from exynos4-fb and exynos5-fb. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 13 - 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 6f06260..0a28a55 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1089,6 +1089,16 @@ static const struct of_device_id drm_fimd_dt_match[] = { MODULE_DEVICE_TABLE(of, drm_fimd_dt_match); #endif +static struct platform_device_id exynos_drm_driver_ids[] = { + { + .name = "exynos4-fb", + }, { + .name = "exynos5-fb", + }, + {}, +}; +MODULE_DEVICE_TABLE(platform, exynos_drm_driver_ids); + static const struct dev_pm_ops fimd_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) @@ -1097,8 +1107,9 @@ static const struct dev_pm_ops fimd_pm_ops = { struct platform_driver fimd_driver = { .probe = fimd_probe, .remove = __devexit_p(fimd_remove), + .id_table = exynos_drm_driver_ids, .driver = { - .name = "exynos4-fb", + .name = "exynos-drm-fimd", .owner = THIS_MODULE, .pm = &fimd_pm_ops, .of_match_table = of_match_ptr(drm_fimd_dt_match), -- 1.7.0.4
[PATCH V2 1/2] video: drm: exynos: Add device tree support
Add device tree based discovery support for DRM-FIMD driver. Signed-off-by: Leela Krishna Amudala --- Documentation/devicetree/bindings/fb/drm-fimd.txt | 73 + drivers/gpu/drm/exynos/exynos_drm_fimd.c | 88 - 2 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/fb/drm-fimd.txt diff --git a/Documentation/devicetree/bindings/fb/drm-fimd.txt b/Documentation/devicetree/bindings/fb/drm-fimd.txt new file mode 100644 index 000..9a52ddb --- /dev/null +++ b/Documentation/devicetree/bindings/fb/drm-fimd.txt @@ -0,0 +1,73 @@ +* Samsung Display Controller using DRM frame work + +The display controller is used to transfer image data from memory to an +external LCD driver interface. It supports various color formats such as +rgb and yuv. + +Required properties: + - compatible: Should be "samsung,exynos5-drm" for fimd using DRM frame work. + - reg: physical base address of the controller and length of memory + mapped region. + - interrupts: Three interrupts should be specified. The interrupts should be + specified in the following order. + - VSYNC interrupt + - FIFO level interrupt + - FIMD System Interrupt + + - samsung,fimd-display: This property should specify the phandle of the + display device node which holds the video interface timing with the + below mentioned properties. + + - lcd-htiming: Specifies the horizontal timing for the overlay. The + horizontal timing includes four parameters in the following order. + + - horizontal back porch (in number of lcd clocks) + - horizontal front porch (in number of lcd clocks) + - hsync pulse width (in number of lcd clocks) + - Display panels X resolution. + + - lcd-vtiming: Specifies the vertical timing for the overlay. The + vertical timing includes four parameters in the following order. + + - vertical back porch (in number of lcd lines) + - vertical front porch (in number of lcd lines) + - vsync pulse width (in number of lcd clocks) + - Display panels Y resolution. + + + - samsung,default-window: Specifies the default window number of the fimd controller. + + - samsung,fimd-win-bpp: Specifies the bits per pixel. + +Optional properties: + - supports-mipi-panel: Specifies the lcd is mipi panel type + - samsung,fimd-vidout-rgb: Video output format is RGB. + - samsung,fimd-inv-vclk: invert video clock polarity. + - samsung,fimd-frame-rate: Number of video frames per second. + +Example: + + The following is an example for the fimd controller is split into + two portions. The SoC specific portion can be specified in the SoC + specific dts file. The board specific portion can be specified in the + board specific dts file. + + - SoC Specific portion + + lcd_fimd0: lcd_panel0 { + lcd-htiming = <4 4 4 480>; + lcd-vtiming = <4 4 4 320>; + supports-mipi-panel; + }; + + - Board Specific portion + + fimd { + samsung,fimd-display = <&lcd_fimd0>; + samsung,fimd-vidout-rgb; + samsung,fimd-inv-vclk; + samsung,fimd-frame-rate = <60>; + samsung,default-window = <0>; + samsung,fimd-win-bpp = <32>; + }; + diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 29fdbfe..6f06260 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -788,12 +789,82 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable) return 0; } +#ifdef CONFIG_OF +static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct device_node *disp_np; + struct exynos_drm_fimd_pdata *pd; + u32 data[4]; + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + dev_err(dev, "memory allocation for pdata failed\n"); + return ERR_PTR(-ENOMEM); + } + + if (of_get_property(np, "samsung,fimd-vidout-rgb", NULL)) + pd->vidcon0 |= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB; + if (of_get_property(np, "samsung,fimd-vidout-tv", NULL)) + pd->vidcon0 |= VIDCON0_VIDOUT_TV; + if (of_get_property(np, "samsung,fimd-inv-hsync", NULL)) + pd->vidcon1 |= VIDCON1_INV_HSYNC; + if (of_get_property(np, "samsung,fimd-inv-vsync", NULL)) + pd->vidcon1 |= VIDCON1_INV_VSYNC; + if (of_get_property(np, "samsung,fimd-inv-vclk", NULL)) + pd->vidcon1 |= VIDCON1_INV_VCLK; + if (of_get_property(np, "samsung,fimd-inv-vden", NULL)) + pd->vidcon1 |= VIDCON1_INV_VDEN; + + disp_np = of_parse_phandle(np, "samsung,fimd-display", 0); + if
[PATCH V2 0/2] video: drm: Add Device tree support to DRM-FIMD
This patch set adds device tree support for DRM-FIMD for Samsung's Exynos5250. It includes parsing platform data from dts file. This patchset is based and tested on top of v3.5-rc6 Changes since V1: - Corrected typo errors and changed compatibility string Leela Krishna Amudala (1): video: drm: exynos: Add device tree support Prathyush K (1): drm/exynos: Modifying exynos drm fimd to support exynos5 Documentation/devicetree/bindings/fb/drm-fimd.txt | 73 +++ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 101 - 2 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/fb/drm-fimd.txt
3.5-rc5: radeon acceleration regression on Transmeta system
> > It's actually more complicated than that. Old kernel images started > > misbehaving from around 2.6.35-rc5 and any kernel older than that was > > OK. When I recompiled the older kernels with squeeze gcc (migh have been > > lenny gcc before, or different answers to make oldconfig), anything from > > current git down to 2.6.33 is broken with radeon.modeset=1 and works (I > > What releases of GCC were those? I'm chasing an issue where compiling > with 4.7.[01] breaks but 4.6.2 is OK, wondering if we're chasing the same > thing. I do not remember when I upgraded from lenny to squeeze. It the previous gcc was lenny's, it was gcc version 4.3.2 (Debian 4.3.2-1.1). The gcc in current stable (squeeze) is gcc version 4.4.5 (Debian 4.4.5-8). Since the old laptop is somewhat slow for following unstable, I have not tried any newer gcc version on that machine, and it has been compiling its own kernels for stress-testing purposes. So it's probably not related to gcc 4.6->4.7 changes. -- Meelis Roos (mroos at linux.ee)
Re: [PATCH v2] of: Add videomode helper
On Wed, 11 Jul 2012, Sascha Hauer wrote: > Hi Guennadi, > > On Wed, Jul 11, 2012 at 10:34:54AM +0200, Guennadi Liakhovetski wrote: > > Hi Sascha > > > > > + > > > +Optional properties: > > > + - width-mm, height-mm: Display dimensions in mm > > > + - hsync-active-high (bool): Hsync pulse is active high > > > + - vsync-active-high (bool): Vsync pulse is active high > > > > How about > > > > + - hsync-active: Hsync pulse polarity: 1 for high, 0 for low > > I am unsure if it's good to mix this with the other bool flags like: > > > > > > + - interlaced (bool): This is an interlaced mode > > > + - doublescan (bool): This is a doublescan mode > > Which behave differently. 'interlaced' will be evaluated as true if > the property is present, no matter which value it has. This might > lead to confusion. I don't feel strongly either way either. I don't think it'd be confusing - you have integer properties there too, and the logic in this case is not "active high - yes or now," but rather "active level - logical 1 (high) or 0 (low)." But as I said - that was just an idea, unless someone has strong arguments either way - you're the original author, it's your call:-) Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
general protection fault on ttm_init()
On Sat, Jul 07, 2012 at 11:31:42PM +0800, Fengguang Wu wrote: > On Sat, Jul 07, 2012 at 10:08:47AM +0800, Fengguang Wu wrote: > > On Fri, Jul 06, 2012 at 06:09:20PM +0100, Dave Airlie wrote: > > > On Fri, Jul 6, 2012 at 5:49 PM, Dave Airlie wrote: > > > > On Fri, Jul 6, 2012 at 3:48 PM, Fengguang Wu > > > intel.com> wrote: > > > >> ... The missed kconfig. > > > >> > > > >> On Fri, Jul 06, 2012 at 10:46:22PM +0800, Fengguang Wu wrote: > > > >>> Hi Thomas, > > > > > > > > Wierd, I'm sorta tempted to just depend drm on CONFIG_PROC_FS, but it > > > > looks like the error path is failing to dtrt. > > > > > > I've attached a patch that should fix it, let me know if it works. > > > > It does not work.. The dmesg (attached) remains the same. > > I got more interesting back traces in a clean kernel: Another trace shows that ttm_init tries to register with an empty name: [2.919061] WARNING: at /c/kernel-tests/tip/lib/kobject.c:166 kobject_add_internal+0x1a3/0x210() [2.917489] device: 'ttm': device_add [2.918179] [ cut here ] [2.919061] WARNING: at /c/kernel-tests/tip/lib/kobject.c:166 kobject_add_internal+0x1a3/0x210() ==>[2.920704] kobject: (8826ecc0): attempted to be registered with empty name! [2.922129] Pid: 1, comm: swapper Not tainted 3.5.0-rc2+ #28 [2.923172] Call Trace: [2.923638] [] ? kobject_add_internal+0x1a3/0x210 [2.924827] [] warn_slowpath_common+0x66/0x90 [2.925993] [] ? drm_core_init+0xca/0xca [2.927028] [] warn_slowpath_fmt+0x41/0x50 [2.928093] [] kobject_add_internal+0x1a3/0x210 [2.929261] [] ? drm_core_init+0xca/0xca [2.930327] [] ? drm_core_init+0xca/0xca [2.931473] [] kobject_add+0x67/0xc0 [2.932589] [] ? get_device_parent+0x118/0x1b7 [2.933790] [] get_device_parent+0x161/0x1b7 [2.934895] [] device_add+0x151/0x5f0 [2.935907] [] ? drm_core_init+0xca/0xca [2.936940] [] ? __raw_spin_lock_init+0x38/0x70 [2.938099] [] ? drm_core_init+0xca/0xca [2.939132] [] device_register+0x19/0x20 [2.940254] [] drm_class_device_register+0x17/0x20 [2.941437] [] ttm_init+0x37/0x62 [2.942360] [] do_one_initcall+0x78/0x136 [2.943413] [] kernel_init+0x122/0x1a6 [2.944415] [] ? loglevel+0x31/0x31 [2.945402] [] kernel_thread_helper+0x4/0x10 [2.946506] [] ? retint_restore_args+0x13/0x13 [2.947635] [] ? do_one_initcall+0x136/0x136 [2.948739] [] ? gs_change+0x13/0x13 Thanks, Fengguang > device class 'drm': registering > kobject: 'drm' (88000f07f050): kobject_add_internal: parent: 'class', > set: 'class' > kobject: 'drm' (88000f07f050): kobject_uevent_env > kobject: 'drm' (88000f07f050): fill_kobj_path: path = '/class/drm' > [drm:drm_core_init] *ERROR* Cannot create /proc/dri > device class 'drm': unregistering > kobject: 'drm' (88000f07f050): kobject_cleanup > kobject: 'drm' (88000f07f050): auto cleanup 'remove' event > kobject: 'drm' (88000f07f050): kobject_uevent_env > kobject: 'drm' (88000f07f050): fill_kobj_path: path = '/class/drm' > kobject: 'drm' (88000f07f050): auto cleanup kobject_del > kobject: 'drm' (88000f07f050): calling ktype release > class 'drm': release. > class_create_release called for drm > kobject: 'drm': free name > kobject: 'drm' (88000f080070): kobject_cleanup > kobject: 'drm' (88000f080070): calling ktype release > kobject: 'drm': free name > device: 'ttm': device_add > kobject: '(null)' (88000f080230): kobject_add_internal: parent: > 'virtual', set: '(null)' > kobject: 'ttm' (824709b0): kobject_add_internal: parent: '(null)', > set: 'devices' > general protection fault: [#1] SMP > CPU 1 > Pid: 1, comm: swapper/0 Not tainted 3.5.0-rc5-bisect #207 > RIP: 0010:[] [] > sysfs_do_create_link+0x59/0x1c0 > RSP: 0018:88107db0 EFLAGS: 00010206 > RAX: 8810 RBX: 00cc RCX: dad9 > RDX: d9d9 RSI: RDI: 8243b320 > RBP: 88107e00 R08: 88100580 R09: fe80 > R10: 8810 R11: 0200 R12: 821622db > R13: 88000f080150 R14: 0001 R15: 88000f080308 > FS: () GS:88000df0() knlGS: > CS: 0010 DS: ES: CR0: 8005003b > CR2: CR3: 02411000 CR4: 06a0 > DR0: DR1: DR2: > DR3: DR6: 0ff0 DR7: 0400 > Process swapper/0 (pid: 1, threadinfo 88106000, task 8810) > Stack: > 88000f080308 824709b0 02ec > fff
Re: [PATCH v2] of: Add videomode helper
Hi Guennadi, On Wed, Jul 11, 2012 at 10:34:54AM +0200, Guennadi Liakhovetski wrote: > Hi Sascha > > > + > > +Optional properties: > > + - width-mm, height-mm: Display dimensions in mm > > + - hsync-active-high (bool): Hsync pulse is active high > > + - vsync-active-high (bool): Vsync pulse is active high > > How about > > + - hsync-active: Hsync pulse polarity: 1 for high, 0 for low I am unsure if it's good to mix this with the other bool flags like: > > > + - interlaced (bool): This is an interlaced mode > > + - doublescan (bool): This is a doublescan mode Which behave differently. 'interlaced' will be evaluated as true if the property is present, no matter which value it has. This might lead to confusion. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3] DRM: Add DRM kms/fb cma helper
On Mon, Jul 02, 2012 at 04:37:47PM +0200, Lars-Peter Clausen wrote: > This patchset introduces a set of helper function for implementing the KMS > framebuffer layer for drivers which use the drm gem CMA helper function. > > Signed-off-by: Lars-Peter Clausen > > --- > Note: This patch depends on Sascha's "DRM: add drm gem CMA helper" patch > > Changes since v2: > * Adapt to changes in the GEM CMA helper > * Add basic buffer size checking in drm_fb_cma_create > Changes since v1: > * Some spelling fixes > * Add missing kfree in drm_fb_cma_alloc error path > * Add multi-plane support > --- > drivers/gpu/drm/Kconfig | 10 + > drivers/gpu/drm/Makefile|1 + > drivers/gpu/drm/drm_fb_cma_helper.c | 393 > +++ > include/drm/drm_fb_cma_helper.h | 27 +++ > 4 files changed, 431 insertions(+) > create mode 100644 drivers/gpu/drm/drm_fb_cma_helper.c > create mode 100644 include/drm/drm_fb_cma_helper.h Tested-by: Sascha Hauer Would be good if this could go into the next merge window. Sascha > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 41bbd95..e511c9a 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -41,6 +41,16 @@ config DRM_GEM_CMA_HELPER > help > Choose this if you need the GEM CMA helper functions > > +config DRM_KMS_CMA_HELPER > + tristate > + select DRM_GEM_CMA_HELPER > + select DRM_KMS_HELPER > + select FB_SYS_FILLRECT > + select FB_SYS_COPYAREA > + select FB_SYS_IMAGEBLIT > + help > + Choose this if you need the KMS cma helper functions > + > config DRM_TDFX > tristate "3dfx Banshee/Voodoo3+" > depends on DRM && PCI > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 6e9e948..5dcb1a5 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -18,6 +18,7 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o > drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o > > drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o > +drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o > > obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o > > diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c > b/drivers/gpu/drm/drm_fb_cma_helper.c > new file mode 100644 > index 000..9042233 > --- /dev/null > +++ b/drivers/gpu/drm/drm_fb_cma_helper.c > @@ -0,0 +1,393 @@ > +/* > + * drm kms/fb cma (contiguous memory allocator) helper functions > + * > + * Copyright (C) 2012 Analog Device Inc. > + * Author: Lars-Peter Clausen > + * > + * Based on udl_fbdev.c > + * Copyright (C) 2012 Red Hat > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct drm_fb_cma { > + struct drm_framebuffer fb; > + struct drm_gem_cma_object *obj[4]; > +}; > + > +struct drm_fbdev_cma { > + struct drm_fb_helperfb_helper; > + struct drm_fb_cma *fb; > +}; > + > +static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper > *helper) > +{ > + return container_of(helper, struct drm_fbdev_cma, fb_helper); > +} > + > +static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb) > +{ > + return container_of(fb, struct drm_fb_cma, fb); > +} > + > +static void drm_fb_cma_destroy(struct drm_framebuffer *fb) > +{ > + struct drm_fb_cma *fb_cma = to_fb_cma(fb); > + int i; > + > + for (i = 0; i < 4; i++) { > + if (fb_cma->obj[i]) > + > drm_gem_object_unreference_unlocked(&fb_cma->obj[i]->base); > + } > + > + drm_framebuffer_cleanup(fb); > + kfree(fb_cma); > +} > + > +static int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > + struct drm_file *file_priv, unsigned int *handle) > +{ > + struct drm_fb_cma *fb_cma = to_fb_cma(fb); > + > + return drm_gem_handle_create(file_priv, > + &fb_cma->obj[0]->base, handle); > +} > + > +static struct drm_framebuffer_funcs drm_fb_cma_funcs = { > + .destroy= drm_fb_cma_destroy, > + .create_handle = drm_fb_cma_create_handle, > +}; > + > +static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, > + struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj, > + unsigned int num_planes) > +{ > + struct drm_fb_cma *fb_cma; > + int ret; > + int i; > + > +
[PATCH v2] of: Add videomode helper
Hi Sascha On Wed, 4 Jul 2012, Sascha Hauer wrote: > This patch adds a helper function for parsing videomodes from the devicetree. > The videomode can be either converted to a struct drm_display_mode or a > struct fb_videomode. > > Signed-off-by: Sascha Hauer > --- > > changes since v1: > - use hyphens instead of underscores for property names > > .../devicetree/bindings/video/displaymode | 40 > drivers/of/Kconfig |5 + > drivers/of/Makefile|1 + > drivers/of/of_videomode.c | 108 > > include/linux/of_videomode.h | 19 > 5 files changed, 173 insertions(+) > create mode 100644 Documentation/devicetree/bindings/video/displaymode > create mode 100644 drivers/of/of_videomode.c > create mode 100644 include/linux/of_videomode.h > > diff --git a/Documentation/devicetree/bindings/video/displaymode > b/Documentation/devicetree/bindings/video/displaymode > new file mode 100644 > index 000..43cc17d > --- /dev/null > +++ b/Documentation/devicetree/bindings/video/displaymode > @@ -0,0 +1,40 @@ > +videomode bindings > +== > + > +Required properties: > + - xres, yres: Display resolution > + - left-margin, right-margin, hsync-len: Horizontal Display timing parameters > + in pixels > + upper-margin, lower-margin, vsync-len: Vertical display timing parameters > in > + lines > + - clock: displayclock in Hz > + > +Optional properties: > + - width-mm, height-mm: Display dimensions in mm > + - hsync-active-high (bool): Hsync pulse is active high > + - vsync-active-high (bool): Vsync pulse is active high How about + - hsync-active: Hsync pulse polarity: 1 for high, 0 for low and similar for vsync-active? Which would then become > + - interlaced (bool): This is an interlaced mode > + - doublescan (bool): This is a doublescan mode > + > +There are different ways of describing a display mode. The devicetree > representation > +corresponds to the one used by the Linux Framebuffer framework described > here in > +Documentation/fb/framebuffer.txt. This representation has been chosen > because it's > +the only format which does not allow for inconsistent parameters.Unlike the > Framebuffer > +framework the devicetree has the clock in Hz instead of ps. > + > +Example: > + > + display at 0 { > + /* 1920x1080p24 */ > + clock = <5200>; > + xres = <1920>; > + yres = <1080>; > + left-margin = <25>; > + right-margin = <25>; > + hsync-len = <25>; > + lower-margin = <2>; > + upper-margin = <2>; > + vsync-len = <2>; > + hsync-active-high; + hsync-active = <1>; > + }; > + Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/
[PATCH 14/15] drm/radeon: record what is next valid wptr for each ring v2
On 10.07.2012 18:56, Jerome Glisse wrote: > On Tue, Jul 10, 2012 at 8:51 AM, Christian K?nig > wrote: >> Before emitting any indirect buffer, emit the offset of the next >> valid ring content if any. This allow code that want to resume >> ring to resume ring right after ib that caused GPU lockup. >> >> v2: use scratch registers instead of storing it into memory >> > Why using scratch register ? To minimize bus activities ? No, but that also seems like a valid argument. If we want to reduce bus activity we should also disable writeback for the scratch registers . My main intention was that a register write seems to be more failsafe than a memory write. For a memory write there are just more things that can go terribly wrong, just think of old AGP cards. Also not all rings can write to memory, but it seems like that everybody can do a simple register write. Reading that register once in case of a lockup isn't such a big overhead compared what needs to be done for a complete reset. >> Signed-off-by: Jerome Glisse >> Signed-off-by: Christian K?nig >> --- >> drivers/gpu/drm/radeon/evergreen.c |8 +++- >> drivers/gpu/drm/radeon/ni.c | 11 ++- >> drivers/gpu/drm/radeon/r600.c| 18 -- >> drivers/gpu/drm/radeon/radeon.h |1 + >> drivers/gpu/drm/radeon/radeon_ring.c |4 >> drivers/gpu/drm/radeon/rv770.c |4 +++- >> drivers/gpu/drm/radeon/si.c | 22 +++--- >> 7 files changed, 60 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/evergreen.c >> b/drivers/gpu/drm/radeon/evergreen.c >> index f39b900..40de347 100644 >> --- a/drivers/gpu/drm/radeon/evergreen.c >> +++ b/drivers/gpu/drm/radeon/evergreen.c >> @@ -1368,7 +1368,13 @@ void evergreen_ring_ib_execute(struct radeon_device >> *rdev, struct radeon_ib *ib) >> /* set to DX10/11 mode */ >> radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); >> radeon_ring_write(ring, 1); >> - /* FIXME: implement */ >> + >> + if (ring->rptr_save_reg) { >> + uint32_t next_rptr = ring->wptr + 2 + 4; >> + radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0)); >> + radeon_ring_write(ring, next_rptr); >> + } >> + >> radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); >> radeon_ring_write(ring, >> #ifdef __BIG_ENDIAN >> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c >> index f2afefb..6e3d448 100644 >> --- a/drivers/gpu/drm/radeon/ni.c >> +++ b/drivers/gpu/drm/radeon/ni.c >> @@ -855,6 +855,13 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, >> struct radeon_ib *ib) >> /* set to DX10/11 mode */ >> radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); >> radeon_ring_write(ring, 1); >> + >> + if (ring->rptr_save_reg) { >> + uint32_t next_rptr = ring->wptr + 2 + 4; > I would rather also skip the surface sync so add another + 8 Akk, going to change that. > >> + radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0)); >> + radeon_ring_write(ring, next_rptr); >> + } >> + >> radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); >> radeon_ring_write(ring, >> #ifdef __BIG_ENDIAN >> @@ -981,8 +988,10 @@ static int cayman_cp_start(struct radeon_device *rdev) >> >> static void cayman_cp_fini(struct radeon_device *rdev) >> { >> + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; >> cayman_cp_enable(rdev, false); >> - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); >> + radeon_ring_fini(rdev, ring); >> + radeon_scratch_free(rdev, ring->rptr_save_reg); >> } >> >> int cayman_cp_resume(struct radeon_device *rdev) >> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c >> index c808fa9..74fca15 100644 >> --- a/drivers/gpu/drm/radeon/r600.c >> +++ b/drivers/gpu/drm/radeon/r600.c >> @@ -2155,18 +2155,27 @@ int r600_cp_resume(struct radeon_device *rdev) >> void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, >> unsigned ring_size) >> { >> u32 rb_bufsz; >> + int r; >> >> /* Align ring size */ >> rb_bufsz = drm_order(ring_size / 8); >> ring_size = (1 << (rb_bufsz + 1)) * 4; >> ring->ring_size = ring_size; >> ring->align_mask = 16 - 1; >> + >> + r = radeon_scratch_get(rdev, &ring->rptr_save_reg); >> + if (r) { >> + DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", >> r); >> + ring->rptr_save_reg = 0; >> + } >> } >> >> void r600_cp_fini(struct radeon_device *rdev) >> { >> + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; >> r600_cp_stop(rdev); >> - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
[PATCH 25/81] drm: remove the list_head from drm_mode_set
It's unused. At it confused me quite a bit until I've discovered that. Cc: dri-devel@lists.freedesktop.org Signed-Off-by: Daniel Vetter --- include/drm/drm_crtc.h |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index bac55c2..a1a0386 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -676,8 +676,6 @@ struct drm_plane { * This is used to set modes. */ struct drm_mode_set { - struct list_head head; - struct drm_framebuffer *fb; struct drm_crtc *crtc; struct drm_display_mode *mode; -- 1.7.7.6 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 24/81] drm/fb helper: don't call drm_crtc_helper_set_config
Go through the interface vtable instead, because not everyone might be using the crtc helper code. Cc: dri-devel@lists.freedesktop.org Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5683b7f..bf97c0a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -228,7 +228,7 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) int i, ret; for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; - ret = drm_crtc_helper_set_config(mode_set); + ret = mode_set->crtc->funcs->set_config(mode_set); if (ret) error = true; } -- 1.7.7.6 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 15844] Failed to load firmware "radeon/RV770_pfp.bin"
https://bugzilla.kernel.org/show_bug.cgi?id=15844 Alan changed: What|Removed |Added Status|NEW |RESOLVED CC||a...@lxorguk.ukuu.org.uk Resolution||DOCUMENTED -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 15748] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
https://bugzilla.kernel.org/show_bug.cgi?id=15748 Alan changed: What|Removed |Added Status|NEW |RESOLVED CC||a...@lxorguk.ukuu.org.uk Resolution||OBSOLETE --- Comment #2 from Alan 2012-07-11 15:08:31 --- Closing as this code has changed hugely since the reported version -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 15738] VGA output of Radeon HD3450 displays too bright colors with KMS radeon driver
https://bugzilla.kernel.org/show_bug.cgi?id=15738 Alan changed: What|Removed |Added Status|NEW |RESOLVED CC||a...@lxorguk.ukuu.org.uk Resolution||CODE_FIX -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: 3.5-rc5: radeon acceleration regression on Transmeta system
> > It's actually more complicated than that. Old kernel images started > > misbehaving from around 2.6.35-rc5 and any kernel older than that was > > OK. When I recompiled the older kernels with squeeze gcc (migh have been > > lenny gcc before, or different answers to make oldconfig), anything from > > current git down to 2.6.33 is broken with radeon.modeset=1 and works (I > > What releases of GCC were those? I'm chasing an issue where compiling > with 4.7.[01] breaks but 4.6.2 is OK, wondering if we're chasing the same > thing. I do not remember when I upgraded from lenny to squeeze. It the previous gcc was lenny's, it was gcc version 4.3.2 (Debian 4.3.2-1.1). The gcc in current stable (squeeze) is gcc version 4.4.5 (Debian 4.4.5-8). Since the old laptop is somewhat slow for following unstable, I have not tried any newer gcc version on that machine, and it has been compiling its own kernels for stress-testing purposes. So it's probably not related to gcc 4.6->4.7 changes. -- Meelis Roos (mr...@linux.ee) ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 7/7] drm/exynos: Add IOMMU support for mapping gem object
A gem object is created using dma_alloc_writecombine. Currently, this buffer is assumed to be contiguous. If a IOMMU mapping is created for DRM, this buffer would be non-contig so the map functions are modified to call dma_mmap_writecombine. This works for both contig and non-contig buffers. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 35 ++ 1 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 5c8b683..59240f7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -162,17 +162,22 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, { struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - unsigned long pfn; if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { + unsigned long pfn; if (!buf->pages) return -EINTR; pfn = page_to_pfn(buf->pages[page_offset++]); - } else - pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; - - return vm_insert_mixed(vma, f_vaddr, pfn); + return vm_insert_mixed(vma, f_vaddr, pfn); + } else { + int ret; + ret = dma_mmap_writecombine(obj->dev->dev, vma, buf->kvaddr, + buf->dma_addr, buf->size); + if (ret) + DRM_ERROR("dma_mmap_writecombine failed\n"); + return ret; + } } static int exynos_drm_gem_get_pages(struct drm_gem_object *obj) @@ -503,7 +508,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, struct drm_gem_object *obj = filp->private_data; struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct exynos_drm_gem_buf *buffer; - unsigned long pfn, vm_size, usize, uaddr = vma->vm_start; + unsigned long vm_size, usize, uaddr = vma->vm_start; int ret; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -543,19 +548,11 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, usize -= PAGE_SIZE; } while (usize > 0); } else { - /* -* get page frame number to physical memory to be mapped -* to user space. -*/ - pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> - PAGE_SHIFT; - - DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); - - if (remap_pfn_range(vma, vma->vm_start, pfn, vm_size, - vma->vm_page_prot)) { - DRM_ERROR("failed to remap pfn range.\n"); - return -EAGAIN; + ret = dma_mmap_writecombine(obj->dev->dev, vma, buffer->kvaddr, + buffer->dma_addr, buffer->size); + if (ret) { + DRM_ERROR("dma_mmap_writecombine failed\n"); + return ret; } } -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 6/7] drm/exynos: Add exynos drm specific fb_mmap function
This patch adds a exynos drm specific implementation of fb_mmap which supports mapping a non-contiguous buffer to user space. This new function does not assume that the frame buffer is contiguous and calls dma_mmap_writecombine for mapping the buffer to user space. dma_mmap_writecombine will be able to map a contiguous buffer as well as non-contig buffer depending on whether an IOMMU mapping is created for drm or not. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 16 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d5586cc..b53e638 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -46,8 +46,24 @@ struct exynos_drm_fbdev { struct exynos_drm_gem_obj *exynos_gem_obj; }; +static int exynos_drm_fb_mmap(struct fb_info *info, + struct vm_area_struct *vma) +{ + if ((vma->vm_end - vma->vm_start) > info->fix.smem_len) + return -EINVAL; + + vma->vm_pgoff = 0; + vma->vm_flags |= VM_IO | VM_RESERVED; + if (dma_mmap_writecombine(info->device, vma, info->screen_base, + info->fix.smem_start, vma->vm_end - vma->vm_start)) + return -EAGAIN; + + return 0; +} + static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, + .fb_mmap= exynos_drm_fb_mmap, .fb_fillrect= cfb_fillrect, .fb_copyarea= cfb_copyarea, .fb_imageblit = cfb_imageblit, -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/7] ARM: dma-mapping: rename and export iommu_ops
This patch renames the dma_ops structure for arm from iommu_ops to arm_iommu_ops. This structure is also exported and declared extern so that it can be set as any device's dma ops directly. Signed-off-by: Prathyush K --- arch/arm/include/asm/dma-mapping.h |1 + arch/arm/mm/dma-mapping.c |5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index bbef15d..5957357 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -13,6 +13,7 @@ #define DMA_ERROR_CODE (~0) extern struct dma_map_ops arm_dma_ops; +extern struct dma_map_ops arm_iommu_ops; static inline struct dma_map_ops *get_dma_ops(struct device *dev) { diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 0f9358b..cff13ac 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1567,7 +1567,7 @@ static void arm_iommu_sync_single_for_device(struct device *dev, __dma_page_cpu_to_dev(page, offset, size, dir); } -struct dma_map_ops iommu_ops = { +struct dma_map_ops arm_iommu_ops = { .alloc = arm_iommu_alloc_attrs, .free = arm_iommu_free_attrs, .mmap = arm_iommu_mmap_attrs, @@ -1582,6 +1582,7 @@ struct dma_map_ops iommu_ops = { .sync_sg_for_cpu= arm_iommu_sync_sg_for_cpu, .sync_sg_for_device = arm_iommu_sync_sg_for_device, }; +EXPORT_SYMBOL(arm_iommu_ops); /** * arm_iommu_create_mapping @@ -1674,7 +1675,7 @@ int arm_iommu_attach_device(struct device *dev, kref_get(&mapping->kref); dev->archdata.mapping = mapping; - set_dma_ops(dev, &iommu_ops); + set_dma_ops(dev, &arm_iommu_ops); pr_info("Attached IOMMU controller to %s device.\n", dev_name(dev)); return 0; -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/7] drm/exynos: attach drm device with common drm mapping
This patch sets the common mapping created during drm init, to the drm device's archdata. The dma_ops of drm device is set as arm_iommu_ops. The common mapping is shared across all the drm devices which ensures that any buffer allocated with drm is accessible by drm-fimd or drm-hdmi or both. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_drv.c |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index c3ad87e..2e40ca8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -276,6 +276,15 @@ static struct drm_driver exynos_drm_driver = { static int exynos_drm_platform_probe(struct platform_device *pdev) { +#ifdef CONFIG_EXYNOS_IOMMU + struct device *dev = &pdev->dev; + + kref_get(&exynos_drm_common_mapping->kref); + dev->archdata.mapping = exynos_drm_common_mapping; + set_dma_ops(dev, &arm_iommu_ops); + + DRM_INFO("drm common mapping set to drm device.\n"); +#endif DRM_DEBUG_DRIVER("%s\n", __FILE__); exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/7] drm/exynos: add IOMMU support to drm fimd
This patch adds device tree based IOMMU support to DRM FIMD. During probe, the driver searches for a 'sysmmu' field in the device node. The sysmmu field points to the corresponding sysmmu device of fimd. This sysmmu device is retrieved and set as fimd's sysmmu. The common IOMMU mapping created during DRM init is then attached to drm fimd. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 54 +- 1 files changed, 53 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 15b5286..6d4048a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -19,7 +19,7 @@ #include #include #include - +#include #include #include @@ -790,12 +790,56 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable) } #ifdef CONFIG_OF + +#ifdef CONFIG_EXYNOS_IOMMU +static int iommu_init(struct device *dev) +{ + struct platform_device *pds; + struct device_node *dn, *dns; + const __be32 *parp; + int ret; + + dn = dev->of_node; + parp = of_get_property(dn, "sysmmu", NULL); + if (parp == NULL) { + dev_err(dev, "failed to find sysmmu property\n"); + return -EINVAL; + } + dns = of_find_node_by_phandle(be32_to_cpup(parp)); + if (dns == NULL) { + dev_err(dev, "failed to find sysmmu node\n"); + return -EINVAL; + } + pds = of_find_device_by_node(dns); + if (pds == NULL) { + dev_err(dev, "failed to find sysmmu platform device\n"); + return -EINVAL; + } + + platform_set_sysmmu(&pds->dev, dev); + dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL); + if (!dev->dma_parms) { + dev_err(dev, "failed to allocate dma parms\n"); + return -ENOMEM; + } + dma_set_max_seg_size(dev, 0xu); + + ret = arm_iommu_attach_device(dev, exynos_drm_common_mapping); + if (ret) { + dev_err(dev, "failed to attach device\n"); + return ret; + } + return 0; +} +#endif + static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) { struct device_node *np = dev->of_node; struct device_node *disp_np; struct exynos_drm_fimd_pdata *pd; u32 data[4]; + int ret; pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { @@ -803,6 +847,14 @@ static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) return ERR_PTR(-ENOMEM); } +#ifdef CONFIG_EXYNOS_IOMMU + ret = iommu_init(dev); + if (ret) { + dev_err(dev, "failed to initialize iommu\n"); + return ERR_PTR(ret); + } +#endif + if (of_get_property(np, "samsung,fimd-vidout-rgb", NULL)) pd->vidcon0 |= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB; if (of_get_property(np, "samsung,fimd-vidout-tv", NULL)) -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/7] ARM: EXYNOS5: add sysmmu field to fimd device node
This patch adds the sysmmu field to the fimd device node in the exynos5250 device tree. This field is used to link the parent device and its sysmmu device in the device tree. Signed-off-by: Prathyush K --- arch/arm/boot/dts/exynos5250.dtsi |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 3e85b2b..2c7ce61 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -461,6 +461,7 @@ interrupt-parent = <&combiner>; reg = <0x1440 0x4>; interrupts = <18 5>, <18 4>, <18 6>; + sysmmu = <&sysmmu_11>; }; mipi { -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/7] drm/exynos: create common IOMMU mapping for DRM
This patch creates an IOMMU mapping during drm init. This is used by all the drm devices including the exynos drm virtual device. This ensures that when drm creates a buffer using the dma-mapping framework, this buffer is accessible by all the drm devices like hdmi/fimd. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_core.c |3 +++ drivers/gpu/drm/exynos/exynos_drm_drv.c | 21 + drivers/gpu/drm/exynos/exynos_drm_drv.h | 10 ++ 3 files changed, 34 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index eaf630d..13ecca6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -34,6 +34,9 @@ static LIST_HEAD(exynos_drm_subdrv_list); static struct drm_device *drm_dev; +#ifdef CONFIG_EXYNOS_IOMMU +struct dma_iommu_mapping *exynos_drm_common_mapping; +#endif static int exynos_drm_subdrv_probe(struct drm_device *dev, struct exynos_drm_subdrv *subdrv) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index d6de2e0..c3ad87e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -307,6 +307,18 @@ static int __init exynos_drm_init(void) DRM_DEBUG_DRIVER("%s\n", __FILE__); +#ifdef CONFIG_EXYNOS_IOMMU + exynos_drm_common_mapping = arm_iommu_create_mapping(&platform_bus_type, + EXYNOS_DRM_DMA_ADDR, + EXYNOS_DRM_IOMMU_SIZE, + EXYNOS_DRM_IOMMU_ORDER); + if (IS_ERR_OR_NULL(exynos_drm_common_mapping)) { + DRM_ERROR("failed to created IOMMU mapping\n"); + ret = PTR_ERR(exynos_drm_common_mapping); + goto out_iommu; + } +#endif + #ifdef CONFIG_DRM_EXYNOS_FIMD ret = platform_driver_register(&fimd_driver); if (ret < 0) @@ -367,6 +379,11 @@ out_hdmi: platform_driver_unregister(&fimd_driver); out_fimd: #endif +#ifdef CONFIG_EXYNOS_IOMMU + arm_iommu_release_mapping(exynos_drm_common_mapping); + exynos_drm_common_mapping = NULL; +out_iommu: +#endif return ret; } @@ -393,6 +410,10 @@ static void __exit exynos_drm_exit(void) #ifdef CONFIG_DRM_EXYNOS_FIMD platform_driver_unregister(&fimd_driver); #endif +#ifdef CONFIG_EXYNOS_IOMMU + arm_iommu_release_mapping(exynos_drm_common_mapping); + exynos_drm_common_mapping = NULL; +#endif } module_init(exynos_drm_init); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index c82c90c..bd12ee2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -31,11 +31,18 @@ #include #include "drm.h" +#ifdef CONFIG_EXYNOS_IOMMU +#include +#include +#endif #define MAX_CRTC 3 #define MAX_PLANE 5 #define MAX_FB_BUFFER 4 #define DEFAULT_ZPOS -1 +#define EXYNOS_DRM_DMA_ADDR0x2000 +#define EXYNOS_DRM_IOMMU_SIZE SZ_128M +#define EXYNOS_DRM_IOMMU_ORDER 4 struct drm_device; struct exynos_drm_overlay; @@ -304,4 +311,7 @@ extern struct platform_driver mixer_driver; extern struct platform_driver exynos_drm_common_hdmi_driver; extern struct platform_driver vidi_driver; extern struct platform_driver g2d_driver; +#ifdef CONFIG_EXYNOS_IOMMU +extern struct dma_iommu_mapping *exynos_drm_common_mapping; +#endif #endif -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/7] [RFC] drm/exynos: Add IOMMU support to DRM
The dma-mapping framework needs a IOMMU mapping to be created for the device which allocates/maps/frees the non-contig buffer. In the DRM framework, a gem buffer is created by the DRM virtual device and not directly by any of the physical devices (FIMD, HDMI etc). Each gem object can be set as a framebuffer to one or many of the drm devices. So a gem object cannot be allocated for any one device. All the DRM devices should be able to access this buffer. The proposed method is to create a common IOMMU mapping during drm init. This mapping is then attached to all of the drm devices including the drm device. [PATCH 1/7] drm/exynos: create common IOMMU mapping for DRM During the probe of drm fimd, the driver retrieves a 'sysmmu' field in the device node for fimd. If such a field exists, the driver retrieves the platform device of the sysmmu device. This sysmmu is set as the sysmmu for fimd. The common mapping created is then attached to fimd. This needs to be done for all the other devices (hdmi, vidi etc). [PATCH 2/7] ARM: EXYNOS5: add sysmmu field to fimd device node [PATCH 3/7] drm/exynos: add IOMMU support to drm fimd During DRM's probe which happens last, the common mapping is set to its archdata and iommu ops are set as its dma ops. This requires a modification in the dma-mapping framework so that the iommu ops can be visible to all drivers. [PATCH 4/7] ARM: dma-mapping: rename and export iommu_ops [PATCH 5/7] drm/exynos: attach drm device with common drm mapping Currently allocation and free use the iommu framework by calling dma_alloc_writecombine and dma_free_writecombine respectively. For mapping the buffers to user space, the mmap functions assume that the buffer is contiguous. This is modified by calling dma_mmap_writecombine. [PATCH 6/7] drm/exynos: Add exynos drm specific fb_mmap function [PATCH 7/7] Add IOMMU support for mapping gem object The device tree based patches are based on Leela's patch which was posted last week for adding DT support to DRM FIMD. The patch to add sysmmu field is for reference only and will be posted to the device tree mailing list. Same with the rename and export iommu_ops patch. These patches are tested on Exynos5250 SMDK board and tested with modetest from libdrm tests. Prathyush K (7): drm/exynos: create common IOMMU mapping for DRM ARM: EXYNOS5: add sysmmu field to fimd device node drm/exynos: add IOMMU support to drm fimd ARM: dma-mapping: rename and export iommu_ops drm/exynos: attach drm device with common drm mapping drm/exynos: Add exynos drm specific fb_mmap function drm/exynos: Add IOMMU support for mapping gem object arch/arm/boot/dts/exynos5250.dtsi |1 + arch/arm/include/asm/dma-mapping.h|1 + arch/arm/mm/dma-mapping.c |5 ++- drivers/gpu/drm/exynos/exynos_drm_core.c |3 ++ drivers/gpu/drm/exynos/exynos_drm_drv.c | 30 drivers/gpu/drm/exynos/exynos_drm_drv.h | 10 + drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 16 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 54 - drivers/gpu/drm/exynos/exynos_drm_gem.c | 35 -- 9 files changed, 133 insertions(+), 22 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH V2 2/2] drm/exynos: Modifying exynos drm fimd to support exynos5
From: Prathyush K The name of the exynos drm fimd device is renamed to exynos-drm-fimd and two ids are created from exynos4-fb and exynos5-fb. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 13 - 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 6f06260..0a28a55 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1089,6 +1089,16 @@ static const struct of_device_id drm_fimd_dt_match[] = { MODULE_DEVICE_TABLE(of, drm_fimd_dt_match); #endif +static struct platform_device_id exynos_drm_driver_ids[] = { + { + .name = "exynos4-fb", + }, { + .name = "exynos5-fb", + }, + {}, +}; +MODULE_DEVICE_TABLE(platform, exynos_drm_driver_ids); + static const struct dev_pm_ops fimd_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) @@ -1097,8 +1107,9 @@ static const struct dev_pm_ops fimd_pm_ops = { struct platform_driver fimd_driver = { .probe = fimd_probe, .remove = __devexit_p(fimd_remove), + .id_table = exynos_drm_driver_ids, .driver = { - .name = "exynos4-fb", + .name = "exynos-drm-fimd", .owner = THIS_MODULE, .pm = &fimd_pm_ops, .of_match_table = of_match_ptr(drm_fimd_dt_match), -- 1.7.0.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH V2 1/2] video: drm: exynos: Add device tree support
Add device tree based discovery support for DRM-FIMD driver. Signed-off-by: Leela Krishna Amudala --- Documentation/devicetree/bindings/fb/drm-fimd.txt | 73 + drivers/gpu/drm/exynos/exynos_drm_fimd.c | 88 - 2 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/fb/drm-fimd.txt diff --git a/Documentation/devicetree/bindings/fb/drm-fimd.txt b/Documentation/devicetree/bindings/fb/drm-fimd.txt new file mode 100644 index 000..9a52ddb --- /dev/null +++ b/Documentation/devicetree/bindings/fb/drm-fimd.txt @@ -0,0 +1,73 @@ +* Samsung Display Controller using DRM frame work + +The display controller is used to transfer image data from memory to an +external LCD driver interface. It supports various color formats such as +rgb and yuv. + +Required properties: + - compatible: Should be "samsung,exynos5-drm" for fimd using DRM frame work. + - reg: physical base address of the controller and length of memory + mapped region. + - interrupts: Three interrupts should be specified. The interrupts should be + specified in the following order. + - VSYNC interrupt + - FIFO level interrupt + - FIMD System Interrupt + + - samsung,fimd-display: This property should specify the phandle of the + display device node which holds the video interface timing with the + below mentioned properties. + + - lcd-htiming: Specifies the horizontal timing for the overlay. The + horizontal timing includes four parameters in the following order. + + - horizontal back porch (in number of lcd clocks) + - horizontal front porch (in number of lcd clocks) + - hsync pulse width (in number of lcd clocks) + - Display panels X resolution. + + - lcd-vtiming: Specifies the vertical timing for the overlay. The + vertical timing includes four parameters in the following order. + + - vertical back porch (in number of lcd lines) + - vertical front porch (in number of lcd lines) + - vsync pulse width (in number of lcd clocks) + - Display panels Y resolution. + + + - samsung,default-window: Specifies the default window number of the fimd controller. + + - samsung,fimd-win-bpp: Specifies the bits per pixel. + +Optional properties: + - supports-mipi-panel: Specifies the lcd is mipi panel type + - samsung,fimd-vidout-rgb: Video output format is RGB. + - samsung,fimd-inv-vclk: invert video clock polarity. + - samsung,fimd-frame-rate: Number of video frames per second. + +Example: + + The following is an example for the fimd controller is split into + two portions. The SoC specific portion can be specified in the SoC + specific dts file. The board specific portion can be specified in the + board specific dts file. + + - SoC Specific portion + + lcd_fimd0: lcd_panel0 { + lcd-htiming = <4 4 4 480>; + lcd-vtiming = <4 4 4 320>; + supports-mipi-panel; + }; + + - Board Specific portion + + fimd { + samsung,fimd-display = <&lcd_fimd0>; + samsung,fimd-vidout-rgb; + samsung,fimd-inv-vclk; + samsung,fimd-frame-rate = <60>; + samsung,default-window = <0>; + samsung,fimd-win-bpp = <32>; + }; + diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 29fdbfe..6f06260 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -788,12 +789,82 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable) return 0; } +#ifdef CONFIG_OF +static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct device_node *disp_np; + struct exynos_drm_fimd_pdata *pd; + u32 data[4]; + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + dev_err(dev, "memory allocation for pdata failed\n"); + return ERR_PTR(-ENOMEM); + } + + if (of_get_property(np, "samsung,fimd-vidout-rgb", NULL)) + pd->vidcon0 |= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB; + if (of_get_property(np, "samsung,fimd-vidout-tv", NULL)) + pd->vidcon0 |= VIDCON0_VIDOUT_TV; + if (of_get_property(np, "samsung,fimd-inv-hsync", NULL)) + pd->vidcon1 |= VIDCON1_INV_HSYNC; + if (of_get_property(np, "samsung,fimd-inv-vsync", NULL)) + pd->vidcon1 |= VIDCON1_INV_VSYNC; + if (of_get_property(np, "samsung,fimd-inv-vclk", NULL)) + pd->vidcon1 |= VIDCON1_INV_VCLK; + if (of_get_property(np, "samsung,fimd-inv-vden", NULL)) + pd->vidcon1 |= VIDCON1_INV_VDEN; + + disp_np = of_parse_phandle(np, "samsung,fimd-display", 0); +
[PATCH V2 0/2] video: drm: Add Device tree support to DRM-FIMD
This patch set adds device tree support for DRM-FIMD for Samsung's Exynos5250. It includes parsing platform data from dts file. This patchset is based and tested on top of v3.5-rc6 Changes since V1: - Corrected typo errors and changed compatibility string Leela Krishna Amudala (1): video: drm: exynos: Add device tree support Prathyush K (1): drm/exynos: Modifying exynos drm fimd to support exynos5 Documentation/devicetree/bindings/fb/drm-fimd.txt | 73 +++ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 101 - 2 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/fb/drm-fimd.txt ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] of: Add videomode helper
Hi Sascha On Wed, 4 Jul 2012, Sascha Hauer wrote: > This patch adds a helper function for parsing videomodes from the devicetree. > The videomode can be either converted to a struct drm_display_mode or a > struct fb_videomode. > > Signed-off-by: Sascha Hauer > --- > > changes since v1: > - use hyphens instead of underscores for property names > > .../devicetree/bindings/video/displaymode | 40 > drivers/of/Kconfig |5 + > drivers/of/Makefile|1 + > drivers/of/of_videomode.c | 108 > > include/linux/of_videomode.h | 19 > 5 files changed, 173 insertions(+) > create mode 100644 Documentation/devicetree/bindings/video/displaymode > create mode 100644 drivers/of/of_videomode.c > create mode 100644 include/linux/of_videomode.h > > diff --git a/Documentation/devicetree/bindings/video/displaymode > b/Documentation/devicetree/bindings/video/displaymode > new file mode 100644 > index 000..43cc17d > --- /dev/null > +++ b/Documentation/devicetree/bindings/video/displaymode > @@ -0,0 +1,40 @@ > +videomode bindings > +== > + > +Required properties: > + - xres, yres: Display resolution > + - left-margin, right-margin, hsync-len: Horizontal Display timing parameters > + in pixels > + upper-margin, lower-margin, vsync-len: Vertical display timing parameters > in > + lines > + - clock: displayclock in Hz > + > +Optional properties: > + - width-mm, height-mm: Display dimensions in mm > + - hsync-active-high (bool): Hsync pulse is active high > + - vsync-active-high (bool): Vsync pulse is active high How about + - hsync-active: Hsync pulse polarity: 1 for high, 0 for low and similar for vsync-active? Which would then become > + - interlaced (bool): This is an interlaced mode > + - doublescan (bool): This is a doublescan mode > + > +There are different ways of describing a display mode. The devicetree > representation > +corresponds to the one used by the Linux Framebuffer framework described > here in > +Documentation/fb/framebuffer.txt. This representation has been chosen > because it's > +the only format which does not allow for inconsistent parameters.Unlike the > Framebuffer > +framework the devicetree has the clock in Hz instead of ps. > + > +Example: > + > + display@0 { > + /* 1920x1080p24 */ > + clock = <5200>; > + xres = <1920>; > + yres = <1080>; > + left-margin = <25>; > + right-margin = <25>; > + hsync-len = <25>; > + lower-margin = <2>; > + upper-margin = <2>; > + vsync-len = <2>; > + hsync-active-high; + hsync-active = <1>; > + }; > + Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 14/15] drm/radeon: record what is next valid wptr for each ring v2
On 10.07.2012 18:56, Jerome Glisse wrote: On Tue, Jul 10, 2012 at 8:51 AM, Christian König wrote: Before emitting any indirect buffer, emit the offset of the next valid ring content if any. This allow code that want to resume ring to resume ring right after ib that caused GPU lockup. v2: use scratch registers instead of storing it into memory Why using scratch register ? To minimize bus activities ? No, but that also seems like a valid argument. If we want to reduce bus activity we should also disable writeback for the scratch registers . My main intention was that a register write seems to be more failsafe than a memory write. For a memory write there are just more things that can go terribly wrong, just think of old AGP cards. Also not all rings can write to memory, but it seems like that everybody can do a simple register write. Reading that register once in case of a lockup isn't such a big overhead compared what needs to be done for a complete reset. Signed-off-by: Jerome Glisse Signed-off-by: Christian König --- drivers/gpu/drm/radeon/evergreen.c |8 +++- drivers/gpu/drm/radeon/ni.c | 11 ++- drivers/gpu/drm/radeon/r600.c| 18 -- drivers/gpu/drm/radeon/radeon.h |1 + drivers/gpu/drm/radeon/radeon_ring.c |4 drivers/gpu/drm/radeon/rv770.c |4 +++- drivers/gpu/drm/radeon/si.c | 22 +++--- 7 files changed, 60 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f39b900..40de347 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1368,7 +1368,13 @@ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) /* set to DX10/11 mode */ radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); radeon_ring_write(ring, 1); - /* FIXME: implement */ + + if (ring->rptr_save_reg) { + uint32_t next_rptr = ring->wptr + 2 + 4; + radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0)); + radeon_ring_write(ring, next_rptr); + } + radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); radeon_ring_write(ring, #ifdef __BIG_ENDIAN diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index f2afefb..6e3d448 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -855,6 +855,13 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) /* set to DX10/11 mode */ radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); radeon_ring_write(ring, 1); + + if (ring->rptr_save_reg) { + uint32_t next_rptr = ring->wptr + 2 + 4; I would rather also skip the surface sync so add another + 8 Akk, going to change that. + radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0)); + radeon_ring_write(ring, next_rptr); + } + radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); radeon_ring_write(ring, #ifdef __BIG_ENDIAN @@ -981,8 +988,10 @@ static int cayman_cp_start(struct radeon_device *rdev) static void cayman_cp_fini(struct radeon_device *rdev) { + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; cayman_cp_enable(rdev, false); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_fini(rdev, ring); + radeon_scratch_free(rdev, ring->rptr_save_reg); } int cayman_cp_resume(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c808fa9..74fca15 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2155,18 +2155,27 @@ int r600_cp_resume(struct radeon_device *rdev) void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) { u32 rb_bufsz; + int r; /* Align ring size */ rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; ring->ring_size = ring_size; ring->align_mask = 16 - 1; + + r = radeon_scratch_get(rdev, &ring->rptr_save_reg); + if (r) { + DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); + ring->rptr_save_reg = 0; + } } void r600_cp_fini(struct radeon_device *rdev) { + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; r600_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_fini(rdev, ring); + radeon_scratch_free(rdev, ring->rptr_save_reg); } @@ -2568,7 +2577,12 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; - /* FIXME: implement