[Intel-gfx] [PATCH v2 2/2] drm/debugfs: add an "edid_override" file per connector

2014-06-18 Thread Daniel Vetter
On Wed, Jun 18, 2014 at 03:37:30PM -0400, Alex Deucher wrote:
> On Wed, Jun 18, 2014 at 12:52 PM, Thomas Wood  
> wrote:
> > +static ssize_t edid_write(struct file *file, const char __user *ubuf,
> > + size_t len, loff_t *offp)
> > +{
> > +   struct seq_file *m = file->private_data;
> > +   struct drm_connector *connector = m->private;
> > +   char *buf;
> > +   struct edid *edid;
> > +   int ret;
> > +
> > +   buf = memdup_user(ubuf, len);
> > +   if (IS_ERR(buf))
> > +   return PTR_ERR(buf);
> > +
> > +   edid = (struct edid *) buf;
> > +
> > +   if (len == 5 && !strncmp(buf, "reset", 5)) {
> > +   connector->override_edid = false;
> > +   ret = drm_mode_connector_update_edid_property(connector, 
> > NULL);
> > +   } else if (len < EDID_LENGTH ||
> > +  EDID_LENGTH * (1 + edid->extensions) > len)
> > +   ret = -EINVAL;
> > +   else {
> > +   connector->override_edid = false;
> 
> Might be worth doing some minimal validation of the EDID (e.g., make
> sure it has a valid header).

Actually we also have plans to abuse this for a bit of nasty EDID
injection to exercise our parser. So at most we should do just enough
checking to make sure the claimed edid length field agrees with the edid
itself (which we have), but beyond that any kind of garbage should be
allowed imo.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH] drm/nouveau: avoid memory leak

2014-06-18 Thread Heinrich Schuchardt
If ttm_dma_tt_init fails memory is leaked.

Signed-off-by: Heinrich Schuchardt 
---
 drivers/gpu/drm/nouveau/nouveau_sgdma.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index a4d22e5..23d880b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -109,7 +109,9 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
else
nvbe->ttm.ttm.func = _sgdma_backend;

-   if (ttm_dma_tt_init(>ttm, bdev, size, page_flags, 
dummy_read_page))
+   if (ttm_dma_tt_init(>ttm, bdev, size, page_flags, 
dummy_read_page)) {
+   kfree(nvbe);
return NULL;
+   }
return >ttm.ttm;
 }
-- 
2.0.0



[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Greg KH
On Thu, Jun 19, 2014 at 09:57:35AM +0530, Sumit Semwal wrote:
> Hi Greg,
> 
> On 19 June 2014 06:55, Rob Clark  wrote:
> > On Wed, Jun 18, 2014 at 9:16 PM, Greg KH  
> > wrote:
> >> On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
> >>> A 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 driver must allocate a fence context for each execution ring that can
> >>> run in parallel. The function for this takes an argument with how many
> >>> contexts to allocate:
> >>>   + fence_context_alloc()
> >>>
> >>> A fence is transient, one-shot deal.  It is allocated and attached
> >>> to one or more dma-buf's.  When the one that attached it is done, with
> >>> the pending operation, it can signal the fence:
> >>>   + fence_signal()
> >>>
> >>> To have a rough approximation whether a fence is fired, call:
> >>>   + fence_is_signaled()
> >>>
> >>> The dma-buf-mgr handles tracking, and waiting on, the fences associated
> >>> with a dma-buf.
> >>>
> >>> The one pending on the fence can add an async callback:
> >>>   + fence_add_callback()
> >>>
> >>> The callback can optionally be cancelled with:
> >>>   + fence_remove_callback()
> >>>
> >>> To wait synchronously, optionally with a timeout:
> >>>   + fence_wait()
> >>>   + fence_wait_timeout()
> >>>
> >>> When emitting a fence, call:
> >>>   + trace_fence_emit()
> >>>
> >>> To annotate that a fence is blocking on another fence, call:
> >>>   + trace_fence_annotate_wait_on(fence, on_fence)
> >>>
> >>> 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 = custom_get_fence(...);
> >>>   if ((seqno_fence = to_seqno_fence(fence)) != NULL) {
> >>> dma_buf *fence_buf = seqno_fence->sync_buf;
> >>> get_dma_buf(fence_buf);
> >>>
> >>> ... tell the hw the memory location to wait ...
> >>> custom_wait_on(fence_buf, seqno_fence->seqno_ofs, fence->seqno);
> >>>   } else {
> >>> /* fall-back to sw sync * /
> >>> fence_add_callback(fence, my_cb);
> >>>   }
> >>>
> >>> 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.
> >>>
> >>> enable_signaling callback is used to provide sw signaling in case a cpu
> >>> waiter is requested or no compatible hardware signaling could be used.
> >>>
> >>> 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).
> >>>
> >>> v1: Original
> >>> v2: After discussion w/ danvet and mlankhorst on #dri-devel, we decided
> >>> that dma-fence didn't need to care about the sw->hw signaling path
> >>> (it can be handled same as sw->sw case), and therefore the fence->ops
> >>> can be simplified and more handled in the core.  So remove the signal,
> >>> add_callback, cancel_callback, and wait ops, and replace with a simple
> >>> enable_signaling() op which can be used to inform a fence supporting
> >>> hw->hw signaling that one or more devices which do not support hw
> >>> signaling are waiting (and therefore it should enable an irq or do
> >>> whatever is necessary in order that the CPU is notified when the
> >>> fence is passed).
> >>> v3: Fix locking fail in attach_fence() and get_fence()
> >>> v4: Remove tie-in w/ dma-buf..  after discussion w/ danvet and mlankorst
> >>> we decided that we need to be able to attach one fence to N dma-buf's,
> >>> so using the list_head in dma-fence struct would be problematic.
> >>> v5: [ Maarten Lankhorst ] Updated for dma-bikeshed-fence and 
> >>> dma-buf-manager.
> >>> v6: [ Maarten Lankhorst ] I removed dma_fence_cancel_callback and some 
> >>> comments
> >>> about checking if fence fired or not. This is broken by design.
> >>> waitqueue_active during destruction is now fatal, since the signaller
> >>> should be holding a reference in enable_signalling until it signalled
> >>> the fence. Pass the original dma_fence_cb along, and call 
> >>> __remove_wait
> >>> in the 

[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Rob Clark
On Wed, Jun 18, 2014 at 9:16 PM, Greg KH  wrote:
> On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
>> A 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 driver must allocate a fence context for each execution ring that can
>> run in parallel. The function for this takes an argument with how many
>> contexts to allocate:
>>   + fence_context_alloc()
>>
>> A fence is transient, one-shot deal.  It is allocated and attached
>> to one or more dma-buf's.  When the one that attached it is done, with
>> the pending operation, it can signal the fence:
>>   + fence_signal()
>>
>> To have a rough approximation whether a fence is fired, call:
>>   + fence_is_signaled()
>>
>> The dma-buf-mgr handles tracking, and waiting on, the fences associated
>> with a dma-buf.
>>
>> The one pending on the fence can add an async callback:
>>   + fence_add_callback()
>>
>> The callback can optionally be cancelled with:
>>   + fence_remove_callback()
>>
>> To wait synchronously, optionally with a timeout:
>>   + fence_wait()
>>   + fence_wait_timeout()
>>
>> When emitting a fence, call:
>>   + trace_fence_emit()
>>
>> To annotate that a fence is blocking on another fence, call:
>>   + trace_fence_annotate_wait_on(fence, on_fence)
>>
>> 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 = custom_get_fence(...);
>>   if ((seqno_fence = to_seqno_fence(fence)) != NULL) {
>> dma_buf *fence_buf = seqno_fence->sync_buf;
>> get_dma_buf(fence_buf);
>>
>> ... tell the hw the memory location to wait ...
>> custom_wait_on(fence_buf, seqno_fence->seqno_ofs, fence->seqno);
>>   } else {
>> /* fall-back to sw sync * /
>> fence_add_callback(fence, my_cb);
>>   }
>>
>> 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.
>>
>> enable_signaling callback is used to provide sw signaling in case a cpu
>> waiter is requested or no compatible hardware signaling could be used.
>>
>> 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).
>>
>> v1: Original
>> v2: After discussion w/ danvet and mlankhorst on #dri-devel, we decided
>> that dma-fence didn't need to care about the sw->hw signaling path
>> (it can be handled same as sw->sw case), and therefore the fence->ops
>> can be simplified and more handled in the core.  So remove the signal,
>> add_callback, cancel_callback, and wait ops, and replace with a simple
>> enable_signaling() op which can be used to inform a fence supporting
>> hw->hw signaling that one or more devices which do not support hw
>> signaling are waiting (and therefore it should enable an irq or do
>> whatever is necessary in order that the CPU is notified when the
>> fence is passed).
>> v3: Fix locking fail in attach_fence() and get_fence()
>> v4: Remove tie-in w/ dma-buf..  after discussion w/ danvet and mlankorst
>> we decided that we need to be able to attach one fence to N dma-buf's,
>> so using the list_head in dma-fence struct would be problematic.
>> v5: [ Maarten Lankhorst ] Updated for dma-bikeshed-fence and dma-buf-manager.
>> v6: [ Maarten Lankhorst ] I removed dma_fence_cancel_callback and some 
>> comments
>> about checking if fence fired or not. This is broken by design.
>> waitqueue_active during destruction is now fatal, since the signaller
>> should be holding a reference in enable_signalling until it signalled
>> the fence. Pass the original dma_fence_cb along, and call __remove_wait
>> in the dma_fence_callback handler, so that no cleanup needs to be
>> performed.
>> v7: [ Maarten Lankhorst ] Set cb->func and only enable sw signaling if
>> fence wasn't signaled yet, for example for hardware fences that may
>> choose to signal blindly.
>> v8: [ Maarten Lankhorst ] Tons of tiny fixes, moved __dma_fence_init to
>> header and fixed include mess. dma-fence.h now includes dma-buf.h
>> All members 

[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Rob Clark
On Wed, Jun 18, 2014 at 9:13 PM, Greg KH  wrote:
> On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
>> +#define CREATE_TRACE_POINTS
>> +#include 
>> +
>> +EXPORT_TRACEPOINT_SYMBOL(fence_annotate_wait_on);
>> +EXPORT_TRACEPOINT_SYMBOL(fence_emit);
>
> Are you really willing to live with these as tracepoints for forever?
> What is the use of them in debugging?  Was it just for debugging the
> fence code, or for something else?

fwiw, the goal is something like this:

http://people.freedesktop.org/~robclark/perf-supertuxkart.svg

but without needing to make perf understand each driver's custom trace events

(from: 
http://bloggingthemonkey.blogspot.com/2013/09/freedreno-update-moar-fps.html
)

BR,
-R


>> +/**
>> + * fence_context_alloc - allocate an array of fence contexts
>> + * @num: [in]amount of contexts to allocate
>> + *
>> + * This function will return the first index of the number of fences 
>> allocated.
>> + * The fence context is used for setting fence->context to a unique number.
>> + */
>> +unsigned fence_context_alloc(unsigned num)
>> +{
>> + BUG_ON(!num);
>> + return atomic_add_return(num, _context_counter) - num;
>> +}
>> +EXPORT_SYMBOL(fence_context_alloc);
>
> EXPORT_SYMBOL_GPL()?  Same goes for all of the exports in here.
> Traditionally all of the driver core exports have been with this
> marking, any objection to making that change here as well?
>
>> +int __fence_signal(struct fence *fence)
>> +{
>> + struct fence_cb *cur, *tmp;
>> + int ret = 0;
>> +
>> + if (WARN_ON(!fence))
>> + return -EINVAL;
>> +
>> + if (!ktime_to_ns(fence->timestamp)) {
>> + fence->timestamp = ktime_get();
>> + smp_mb__before_atomic();
>> + }
>> +
>> + if (test_and_set_bit(FENCE_FLAG_SIGNALED_BIT, >flags)) {
>> + ret = -EINVAL;
>> +
>> + /*
>> +  * we might have raced with the unlocked fence_signal,
>> +  * still run through all callbacks
>> +  */
>> + } else
>> + trace_fence_signaled(fence);
>> +
>> + list_for_each_entry_safe(cur, tmp, >cb_list, node) {
>> + list_del_init(>node);
>> + cur->func(fence, cur);
>> + }
>> + return ret;
>> +}
>> +EXPORT_SYMBOL(__fence_signal);
>
> Don't export a function with __ in front of it, you are saying that an
> internal function is somehow "valid" for everyone else to call?  Why?
> You aren't even documenting the function, so who knows how to use it?
>
>> +/**
>> + * fence_signal - signal completion of a fence
>> + * @fence: the fence to signal
>> + *
>> + * Signal completion for software callbacks on a fence, this will unblock
>> + * fence_wait() calls and run all the callbacks added with
>> + * fence_add_callback(). Can be called multiple times, but since a fence
>> + * can only go from unsignaled to signaled state, it will only be effective
>> + * the first time.
>> + */
>> +int fence_signal(struct fence *fence)
>> +{
>> + unsigned long flags;
>> +
>> + if (!fence)
>> + return -EINVAL;
>> +
>> + if (!ktime_to_ns(fence->timestamp)) {
>> + fence->timestamp = ktime_get();
>> + smp_mb__before_atomic();
>> + }
>> +
>> + if (test_and_set_bit(FENCE_FLAG_SIGNALED_BIT, >flags))
>> + return -EINVAL;
>> +
>> + trace_fence_signaled(fence);
>> +
>> + if (test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, >flags)) {
>> + struct fence_cb *cur, *tmp;
>> +
>> + spin_lock_irqsave(fence->lock, flags);
>> + list_for_each_entry_safe(cur, tmp, >cb_list, node) {
>> + list_del_init(>node);
>> + cur->func(fence, cur);
>> + }
>> + spin_unlock_irqrestore(fence->lock, flags);
>> + }
>> + return 0;
>> +}
>> +EXPORT_SYMBOL(fence_signal);
>
> So, why should I use this over __fence_signal?  What is the difference?
> Am I missing some documentation somewhere?
>
>> +void release_fence(struct kref *kref)
>> +{
>> + struct fence *fence =
>> + container_of(kref, struct fence, refcount);
>> +
>> + trace_fence_destroy(fence);
>> +
>> + BUG_ON(!list_empty(>cb_list));
>> +
>> + if (fence->ops->release)
>> + fence->ops->release(fence);
>> + else
>> + kfree(fence);
>> +}
>> +EXPORT_SYMBOL(release_fence);
>
> fence_release() makes it more unified with the other functions in this
> file, right?
>
>> +/**
>> + * fence_default_wait - default sleep until the fence gets signaled
>> + * or until timeout elapses
>> + * @fence:   [in]the fence to wait on
>> + * @intr:[in]if true, do an interruptible wait
>> + * @timeout: [in]timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
>> + *
>> + * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
>> + * remaining timeout in jiffies on success.
>> + */
>> +long
>
> Shouldn't this be signed to be explicit?
>
>> 

[Bug 79980] Random radeonsi crashes

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=79980

--- Comment #18 from Alex Deucher  ---
If it's the same problem Marek is seeing it's probably this:
6d2f294 - drm/radeon: use normal BOs for the page tables v4

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/fedc1140/attachment.html>


[Bug 76223] [radeonsi] luxmark segfault

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=76223

--- Comment #11 from joshua.r.marshall.1991 at gmail.com ---
Exact same back trace with and without luxrays.  This also working off of this
morning's mesa-git build.

sorry I can't be of more help.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/204632e6/attachment.html>


[Bug 76223] [radeonsi] luxmark segfault

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=76223

--- Comment #10 from joshua.r.marshall.1991 at gmail.com ---
this was obtained by "gdb luxmark" and then entering "run" at the prompt.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/d1a844a6/attachment-0001.html>


[Bug 76223] [radeonsi] luxmark segfault

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=76223

--- Comment #9 from joshua.r.marshall.1991 at gmail.com ---
Currently, I am using the luxmark packaged in arch linux's repo's.  I'm not
seeing exactly what you are, so I'll include a BT:

Program received signal SIGSEGV, Segmentation fault.
0x004c1630 in slg::PathOCLRenderEngine::StopLockLess() ()
(gdb) bt
#0  0x004c1630 in slg::PathOCLRenderEngine::StopLockLess() ()
#1  0x0047ccb6 in slg::RenderEngine::Stop() ()
#2  0x00477c9b in slg::RenderSession::~RenderSession() ()
#3  0x0046441c in LuxMarkApp::Stop() ()
#4  0x004644c3 in LuxMarkApp::InitRendering(LuxMarkAppMode, char
const*) ()
#5  0x0046b3e7 in MainWindow::event(QEvent*) ()
#6  0x770dbf0c in QApplicationPrivate::notify_helper(QObject*, QEvent*)
()
   from /usr/lib/libQtGui.so.4
#7  0x770e248d in QApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/libQtGui.so.4
#8  0x76bad58d in QCoreApplication::notifyInternal(QObject*, QEvent*)
()
   from /usr/lib/libQtCore.so.4
#9  0x76bb06dd in QCoreApplicationPrivate::sendPostedEvents(QObject*,
int, QThreadData*) () from /usr/lib/libQtCore.so.4
#10 0x76bda9e3 in ?? () from /usr/lib/libQtCore.so.4
#11 0x74023b84 in g_main_context_dispatch () from
/usr/lib/libglib-2.0.so.0
#12 0x74023dc8 in ?? () from /usr/lib/libglib-2.0.so.0
#13 0x74023e6c in g_main_context_iteration () from
/usr/lib/libglib-2.0.so.0
#14 0x76bda2a5 in
QEventDispatcherGlib::processEvents(QFlags) ()
from /usr/lib/libQtCore.so.4
#15 0x77178fb6 in ?? () from /usr/lib/libQtGui.so.4
#16 0x76bac15f in
QEventLoop::processEvents(QFlags) ()
   from /usr/lib/libQtCore.so.4
#17 0x76bac455 in
QEventLoop::exec(QFlags) ()
   from /usr/lib/libQtCore.so.4
#18 0x76bb1719 in QCoreApplication::exec() () from
/usr/lib/libQtCore.so.4
#19 0x0045a144 in main ()

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/c1732036/attachment.html>


[PATCH] drm/msm: Implement msm drm fb_mmap callback function

2014-06-18 Thread Rob Clark
On Wed, Jun 18, 2014 at 4:55 PM, Hai Li  wrote:
> This change implements msm drm specific fb_mmap function for fb device
> to properly map the fb address to userspace.
>

thanks, queued up on msm-next

BR,
-R

> Signed-off-by: Hai Li 
> Signed-off-by: Stephane Viau 
> ---
>  drivers/gpu/drm/msm/msm_fbdev.c | 37 -
>  1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
> index 4f4e7b4..2522f51 100644
> --- a/drivers/gpu/drm/msm/msm_fbdev.c
> +++ b/drivers/gpu/drm/msm/msm_fbdev.c
> @@ -19,6 +19,11 @@
>
>  #include "drm_crtc.h"
>  #include "drm_fb_helper.h"
> +#include "msm_gem.h"
> +
> +extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
> +   struct vm_area_struct *vma);
> +static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma);
>
>  /*
>   * fbdev funcs, to implement legacy fbdev interface on top of drm driver
> @@ -43,6 +48,7 @@ static struct fb_ops msm_fb_ops = {
> .fb_fillrect = sys_fillrect,
> .fb_copyarea = sys_copyarea,
> .fb_imageblit = sys_imageblit,
> +   .fb_mmap = msm_fbdev_mmap,
>
> .fb_check_var = drm_fb_helper_check_var,
> .fb_set_par = drm_fb_helper_set_par,
> @@ -51,6 +57,31 @@ static struct fb_ops msm_fb_ops = {
> .fb_setcmap = drm_fb_helper_setcmap,
>  };
>
> +static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
> +{
> +   struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
> +   struct msm_fbdev *fbdev = to_msm_fbdev(helper);
> +   struct drm_gem_object *drm_obj = fbdev->bo;
> +   struct drm_device *dev = helper->dev;
> +   int ret = 0;
> +
> +   if (drm_device_is_unplugged(dev))
> +   return -ENODEV;
> +
> +   mutex_lock(>struct_mutex);
> +
> +   ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
> +
> +   mutex_unlock(>struct_mutex);
> +
> +   if (ret) {
> +   pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
> +   return ret;
> +   }
> +
> +   return msm_gem_mmap_obj(drm_obj, vma);
> +}
> +
>  static int msm_fbdev_create(struct drm_fb_helper *helper,
> struct drm_fb_helper_surface_size *sizes)
>  {
> @@ -108,7 +139,11 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
> mutex_lock(>struct_mutex);
>
> /* TODO implement our own fb_mmap so we don't need this: */
> -   msm_gem_get_iova_locked(fbdev->bo, 0, );
> +   ret = msm_gem_get_iova_locked(fbdev->bo, 0, );
> +   if (ret) {
> +   dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret);
> +   goto fail;
> +   }
>
> fbi = framebuffer_alloc(0, dev->dev);
> if (!fbi) {
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
>


[Bug 80162] center and lfe channels screwed up on suspend

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=80162

Alex Deucher  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |NOTOURBUG

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/d534808c/attachment.html>


[Bug 80162] center and lfe channels screwed up on suspend

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=80162

--- Comment #2 from Pierre Ossman  ---
Thanks. Going through the vendor verbs revealed the issue. Multichannel mode
was getting reset on suspend, and was not properly reinitialised by the driver
on resume.

Will prepare a patch for the ALSA folks. I guess you can close this bug entry
as invalid.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/d5993286/attachment.html>


[Bug 79980] Random radeonsi crashes

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=79980

--- Comment #17 from Alex Deucher  ---
(In reply to comment #15)
> This bug is caused by TAHITI_mc2.bin firmware. The old firmware works good.

Did you test a new kernel with the old firmware or an old kernel without the
new firmware patch?  It could be some other change if you did the latter.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/f5cca296/attachment.html>


[PATCH] drm/nouveau: avoid memory leak

2014-06-18 Thread Ben Skeggs
- Original Message -
> From: "Heinrich Schuchardt" 
> To: "David Airlie" 
> Cc: "Ben Skeggs" , dri-devel at lists.freedesktop.org, 
> linux-kernel at vger.kernel.org, "Heinrich
> Schuchardt" 
> Sent: Thursday, 19 June, 2014 5:57:47 AM
> Subject: [PATCH] drm/nouveau: avoid memory leak
> 
> If ttm_dma_tt_init fails memory is leaked.
No, it's not.  TTM calls the destroy function itself on failure.

Thanks,
Ben.
> 
> Signed-off-by: Heinrich Schuchardt 
> ---
>  drivers/gpu/drm/nouveau/nouveau_sgdma.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
> b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
> index a4d22e5..23d880b 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
> @@ -109,7 +109,9 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
>   else
>   nvbe->ttm.ttm.func = _sgdma_backend;
>  
> - if (ttm_dma_tt_init(>ttm, bdev, size, page_flags, 
> dummy_read_page))
> + if (ttm_dma_tt_init(>ttm, bdev, size, page_flags, 
> dummy_read_page)) {
> + kfree(nvbe);
>   return NULL;
> + }
>   return >ttm.ttm;
>  }
> --
> 2.0.0
> 
> 


[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Tomeu Vizoso
On 06/17/2014 06:15 PM, Stephen Warren wrote:
> On 06/17/2014 06:16 AM, Tomeu Vizoso wrote:
>> On 06/16/2014 10:02 PM, Stephen Warren wrote:
>>> On 06/16/2014 07:35 AM, Tomeu Vizoso wrote:
 +#ifdef CONFIG_TEGRA124_EMC
 +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
 long rate);
 +void tegra124_emc_set_floor(unsigned long freq);
 +void tegra124_emc_set_ceiling(unsigned long freq);
 +#else
 +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
 long rate)
 +{ return -ENODEV; }
 +void tegra124_emc_set_floor(unsigned long freq)
 +{ return; }
 +void tegra124_emc_set_ceiling(unsigned long freq)
 +{ return; }
 +#endif
>>>
>>> I'll repeat what I said off-list so that we can have the whole
>>> conversation on the list:
>>>
>>> That looks like a custom Tegra-specific API. I think it'd be much better
>>> to integrate this into the common clock framework as a standard clock
>>> constraints API. There are other use-cases for clock constraints besides
>>> EMC scaling (e.g. some in audio on Tegra, and I'm sure many on other
>>> SoCs too).
>>
>> Yes, I wrote a bit in the cover letter about our requirements and how
>> they map to the CCF. Could you please comment on that?
>
> My comments remain the same. I believe this is something that belongs in
> the clock driver, or at the least, some API that takes a struct clock as
> its parameter, so that drivers can use the existing DT clock lookup
> mechanism.

Ok, let me put this strawman here to see if I have gotten close to what 
you have in mind:

* add per-client accounting (Rabin's patches referenced before)

* add clk_set_floor, to be used by cpufreq, load stats, etc.

* add clk_set_ceiling, to be used by battery drivers, thermal, etc.

* an EMC driver would collect bandwidth and latency requests from 
consumers and call clk_set_floor on the EMC clock.

* the EMC driver would also register for rate change notifications in 
the EMC clock and would update the latency allowance registers at that 
point.

How does it sound?

Regards,

Tomeu


[Bug 79980] Random radeonsi crashes

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=79980

--- Comment #16 from Andy Furniss  ---
(In reply to comment #15)
> This bug is caused by TAHITI_mc2.bin firmware. The old firmware works good.

Well I haven't tried without it, but I have so far failed to reproduce this bug
on a slightly older 3.15 drm fixes also using TAHITI_mc2.bin.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/4a6f5d70/attachment.html>


[PATCH] drm/exynos: defer hdmi probe when fail to get regulators

2014-06-18 Thread Rahul Sharma
HDMI probe proceeds with dummy regulators when the regulators
are not provided in DT node or regulator provider has not get
probed or failed to register the regulators.

This patch modify hdmi driver to defer the probe in case the
regulators are not available.

Signed-off-by: Rahul Sharma 
---
Based on exynos-drm-fixes branch in Inki dae's tree.
 drivers/gpu/drm/exynos/exynos_hdmi.c |   69 --
 1 file changed, 50 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index aa259b0..3f24c49 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -83,7 +83,7 @@ struct hdmi_resources {
struct clk  *sclk_pixel;
struct clk  *sclk_hdmiphy;
struct clk  *mout_hdmi;
-   struct regulator_bulk_data  *regul_bulk;
+   struct regulator**regulators;
int regul_count;
 };

@@ -2022,6 +2022,36 @@ static void hdmi_commit(struct exynos_drm_display 
*display)
hdmi_conf_apply(hdata);
 }

+int hdmi_regulator_enable(struct hdmi_context *hdata)
+{
+   struct hdmi_resources *res = >res;
+   int i, ret;
+
+   for (i = 0; i < res->regul_count; ++i) {
+   ret = regulator_enable(res->regulators[i]);
+   if (ret < 0) {
+   DRM_ERROR("fail to enable regulators.\n");
+   return ret;
+   }
+   }
+   return 0;
+}
+
+int hdmi_regulator_disable(struct hdmi_context *hdata)
+{
+   struct hdmi_resources *res = >res;
+   int i, ret;
+
+   for (i = 0; i < res->regul_count; ++i) {
+   ret = regulator_disable(res->regulators[i]);
+   if (ret < 0) {
+   DRM_ERROR("fail to disable regulators.\n");
+   return ret;
+   }
+   }
+   return 0;
+}
+
 static void hdmi_poweron(struct exynos_drm_display *display)
 {
struct hdmi_context *hdata = display->ctx;
@@ -2039,8 +2069,8 @@ static void hdmi_poweron(struct exynos_drm_display 
*display)

pm_runtime_get_sync(hdata->dev);

-   if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
-   DRM_DEBUG_KMS("failed to enable regulator bulk\n");
+   if (hdmi_regulator_enable(hdata))
+   DRM_DEBUG_KMS("failed to enable regulators\n");

/* set pmu hdmiphy control bit to enable hdmiphy */
regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
@@ -2077,7 +2107,8 @@ static void hdmi_poweroff(struct exynos_drm_display 
*display)
regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
PMU_HDMI_PHY_ENABLE_BIT, 0);

-   regulator_bulk_disable(res->regul_count, res->regul_bulk);
+   if (hdmi_regulator_disable(hdata))
+   DRM_DEBUG_KMS("failed to disable regulators\n");

pm_runtime_put_sync(hdata->dev);

@@ -2211,24 +2242,24 @@ static int hdmi_resources_init(struct hdmi_context 
*hdata)

clk_set_parent(res->mout_hdmi, res->sclk_pixel);

-   res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
-   sizeof(res->regul_bulk[0]), GFP_KERNEL);
-   if (!res->regul_bulk) {
-   ret = -ENOMEM;
-   goto fail;
-   }
+   res->regul_count = ARRAY_SIZE(supply);
+
+   res->regulators = devm_kzalloc(dev, res->regul_count *
+   sizeof(res->regulators[0]), GFP_KERNEL);
+   if (!res->regulators)
+   return -ENOMEM;
+
for (i = 0; i < ARRAY_SIZE(supply); ++i) {
-   res->regul_bulk[i].supply = supply[i];
-   res->regul_bulk[i].consumer = NULL;
-   }
-   ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
-   if (ret) {
-   DRM_ERROR("failed to get regulators\n");
-   return ret;
+   res->regulators[i] =
+   devm_regulator_get_optional(dev, supply[i]);
+   if (IS_ERR(res->regulators[i])) {
+   DRM_ERROR("fail to get regulator: %s.\n",
+   supply[i]);
+   return -EPROBE_DEFER;
+   }
}
-   res->regul_count = ARRAY_SIZE(supply);

-   return ret;
+   return 0;
 fail:
DRM_ERROR("HDMI resource init - failed\n");
return ret;
-- 
1.7.9.5



[PATCH] drm/radeon: fix race condition in radeon_crtc_page_flip

2014-06-18 Thread Christian König
From: Christian K?nig 

radeon_crtc_handle_flip can be called concurrently and if
we set the unpin_work to early try to flip an unpinned BO or
worse.

Signed-off-by: Christian K?nig 
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/radeon/radeon_display.c | 31 ---
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_display.c 
b/drivers/gpu/drm/radeon/radeon_display.c
index 356b733..cf22741 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -393,17 +393,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,

INIT_WORK(>work, radeon_unpin_work_func);

-   /* We borrow the event spin lock for protecting unpin_work */
-   spin_lock_irqsave(>event_lock, flags);
-   if (radeon_crtc->unpin_work) {
-   DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
-   r = -EBUSY;
-   goto unlock_free;
-   }
-   radeon_crtc->unpin_work = work;
-   radeon_crtc->deferred_flip_completion = 0;
-   spin_unlock_irqrestore(>event_lock, flags);
-
/* pin the new buffer */
DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n",
 work->old_rbo, rbo);
@@ -461,10 +450,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
base &= ~7;
}

-   spin_lock_irqsave(>event_lock, flags);
-   work->new_crtc_base = base;
-   spin_unlock_irqrestore(>event_lock, flags);
-
/* update crtc fb */
crtc->primary->fb = fb;

@@ -477,6 +462,22 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
/* set the proper interrupt */
radeon_pre_page_flip(rdev, radeon_crtc->crtc_id);

+   /* We borrow the event spin lock for protecting unpin_work */
+   spin_lock_irqsave(>event_lock, flags);
+   if (radeon_crtc->unpin_work) {
+   spin_unlock_irqrestore(>event_lock, flags);
+   radeon_post_page_flip(rdev, radeon_crtc->crtc_id);
+   drm_vblank_put(dev, radeon_crtc->crtc_id);
+
+   DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+   r = -EBUSY;
+   goto pflip_cleanup1;
+   }
+   radeon_crtc->unpin_work = work;
+   radeon_crtc->deferred_flip_completion = 0;
+   work->new_crtc_base = base;
+   spin_unlock_irqrestore(>event_lock, flags);
+
return 0;

 pflip_cleanup1:
-- 
1.9.1



[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Greg KH
On Wed, Jun 18, 2014 at 09:23:06PM -0400, Rob Clark wrote:
> On Wed, Jun 18, 2014 at 9:13 PM, Greg KH  
> wrote:
> > On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
> >> +#define CREATE_TRACE_POINTS
> >> +#include 
> >> +
> >> +EXPORT_TRACEPOINT_SYMBOL(fence_annotate_wait_on);
> >> +EXPORT_TRACEPOINT_SYMBOL(fence_emit);
> >
> > Are you really willing to live with these as tracepoints for forever?
> > What is the use of them in debugging?  Was it just for debugging the
> > fence code, or for something else?
> 
> fwiw, the goal is something like this:
> 
> http://people.freedesktop.org/~robclark/perf-supertuxkart.svg
> 
> but without needing to make perf understand each driver's custom trace events
> 
> (from: 
> http://bloggingthemonkey.blogspot.com/2013/09/freedreno-update-moar-fps.html
> )

Will these tracepoints provide something like that?  If so, great, but I
want to make sure as these now become a user/kernel ABI that you can not
break.

thanks,

greg k-h


[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Greg KH
On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
> A 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 driver must allocate a fence context for each execution ring that can
> run in parallel. The function for this takes an argument with how many
> contexts to allocate:
>   + fence_context_alloc()
> 
> A fence is transient, one-shot deal.  It is allocated and attached
> to one or more dma-buf's.  When the one that attached it is done, with
> the pending operation, it can signal the fence:
>   + fence_signal()
> 
> To have a rough approximation whether a fence is fired, call:
>   + fence_is_signaled()
> 
> The dma-buf-mgr handles tracking, and waiting on, the fences associated
> with a dma-buf.
> 
> The one pending on the fence can add an async callback:
>   + fence_add_callback()
> 
> The callback can optionally be cancelled with:
>   + fence_remove_callback()
> 
> To wait synchronously, optionally with a timeout:
>   + fence_wait()
>   + fence_wait_timeout()
> 
> When emitting a fence, call:
>   + trace_fence_emit()
> 
> To annotate that a fence is blocking on another fence, call:
>   + trace_fence_annotate_wait_on(fence, on_fence)
> 
> 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 = custom_get_fence(...);
>   if ((seqno_fence = to_seqno_fence(fence)) != NULL) {
> dma_buf *fence_buf = seqno_fence->sync_buf;
> get_dma_buf(fence_buf);
> 
> ... tell the hw the memory location to wait ...
> custom_wait_on(fence_buf, seqno_fence->seqno_ofs, fence->seqno);
>   } else {
> /* fall-back to sw sync * /
> fence_add_callback(fence, my_cb);
>   }
> 
> 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.
> 
> enable_signaling callback is used to provide sw signaling in case a cpu
> waiter is requested or no compatible hardware signaling could be used.
> 
> 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).
> 
> v1: Original
> v2: After discussion w/ danvet and mlankhorst on #dri-devel, we decided
> that dma-fence didn't need to care about the sw->hw signaling path
> (it can be handled same as sw->sw case), and therefore the fence->ops
> can be simplified and more handled in the core.  So remove the signal,
> add_callback, cancel_callback, and wait ops, and replace with a simple
> enable_signaling() op which can be used to inform a fence supporting
> hw->hw signaling that one or more devices which do not support hw
> signaling are waiting (and therefore it should enable an irq or do
> whatever is necessary in order that the CPU is notified when the
> fence is passed).
> v3: Fix locking fail in attach_fence() and get_fence()
> v4: Remove tie-in w/ dma-buf..  after discussion w/ danvet and mlankorst
> we decided that we need to be able to attach one fence to N dma-buf's,
> so using the list_head in dma-fence struct would be problematic.
> v5: [ Maarten Lankhorst ] Updated for dma-bikeshed-fence and dma-buf-manager.
> v6: [ Maarten Lankhorst ] I removed dma_fence_cancel_callback and some 
> comments
> about checking if fence fired or not. This is broken by design.
> waitqueue_active during destruction is now fatal, since the signaller
> should be holding a reference in enable_signalling until it signalled
> the fence. Pass the original dma_fence_cb along, and call __remove_wait
> in the dma_fence_callback handler, so that no cleanup needs to be
> performed.
> v7: [ Maarten Lankhorst ] Set cb->func and only enable sw signaling if
> fence wasn't signaled yet, for example for hardware fences that may
> choose to signal blindly.
> v8: [ Maarten Lankhorst ] Tons of tiny fixes, moved __dma_fence_init to
> header and fixed include mess. dma-fence.h now includes dma-buf.h
> All members are now initialized, so kmalloc can be used for
> allocating a dma-fence. More documentation added.
> v9: Change compiler bitfields to 

[REPOST PATCH 4/8] android: convert sync to fence api, v5

2014-06-18 Thread Greg KH
On Wed, Jun 18, 2014 at 12:37:11PM +0200, Maarten Lankhorst wrote:
> Just to show it's easy.
> 
> Android syncpoints can be mapped to a timeline. This removes the need
> to maintain a separate api for synchronization. I've left the android
> trace events in place, but the core fence events should already be
> sufficient for debugging.
> 
> v2:
> - Call fence_remove_callback in sync_fence_free if not all fences have fired.
> v3:
> - Merge Colin Cross' bugfixes, and the android fence merge optimization.
> v4:
> - Merge with the upstream fixes.
> v5:
> - Fix small style issues pointed out by Thomas Hellstrom.
> 
> Signed-off-by: Maarten Lankhorst 
> Acked-by: John Stultz 
> ---
>  drivers/staging/android/Kconfig  |1 
>  drivers/staging/android/Makefile |2 
>  drivers/staging/android/sw_sync.c|6 
>  drivers/staging/android/sync.c   |  913 
> +++---
>  drivers/staging/android/sync.h   |   79 ++-
>  drivers/staging/android/sync_debug.c |  247 +
>  drivers/staging/android/trace/sync.h |   12 
>  7 files changed, 609 insertions(+), 651 deletions(-)
>  create mode 100644 drivers/staging/android/sync_debug.c

With these changes, can we pull the android sync logic out of
drivers/staging/ now?

thanks,

greg k-h


[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Greg KH
On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
> + * 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.

I don't like this paragraph in all of the files, but if you insist that
some lawyer wants it there, I'll live with it...

> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .

That's just not needed at all and is fluff.  Please remove.


[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Greg KH
On Wed, Jun 18, 2014 at 12:36:54PM +0200, Maarten Lankhorst wrote:
> +#define CREATE_TRACE_POINTS
> +#include 
> +
> +EXPORT_TRACEPOINT_SYMBOL(fence_annotate_wait_on);
> +EXPORT_TRACEPOINT_SYMBOL(fence_emit);

Are you really willing to live with these as tracepoints for forever?
What is the use of them in debugging?  Was it just for debugging the
fence code, or for something else?

> +/**
> + * fence_context_alloc - allocate an array of fence contexts
> + * @num: [in]amount of contexts to allocate
> + *
> + * This function will return the first index of the number of fences 
> allocated.
> + * The fence context is used for setting fence->context to a unique number.
> + */
> +unsigned fence_context_alloc(unsigned num)
> +{
> + BUG_ON(!num);
> + return atomic_add_return(num, _context_counter) - num;
> +}
> +EXPORT_SYMBOL(fence_context_alloc);

EXPORT_SYMBOL_GPL()?  Same goes for all of the exports in here.
Traditionally all of the driver core exports have been with this
marking, any objection to making that change here as well?

> +int __fence_signal(struct fence *fence)
> +{
> + struct fence_cb *cur, *tmp;
> + int ret = 0;
> +
> + if (WARN_ON(!fence))
> + return -EINVAL;
> +
> + if (!ktime_to_ns(fence->timestamp)) {
> + fence->timestamp = ktime_get();
> + smp_mb__before_atomic();
> + }
> +
> + if (test_and_set_bit(FENCE_FLAG_SIGNALED_BIT, >flags)) {
> + ret = -EINVAL;
> +
> + /*
> +  * we might have raced with the unlocked fence_signal,
> +  * still run through all callbacks
> +  */
> + } else
> + trace_fence_signaled(fence);
> +
> + list_for_each_entry_safe(cur, tmp, >cb_list, node) {
> + list_del_init(>node);
> + cur->func(fence, cur);
> + }
> + return ret;
> +}
> +EXPORT_SYMBOL(__fence_signal);

Don't export a function with __ in front of it, you are saying that an
internal function is somehow "valid" for everyone else to call?  Why?
You aren't even documenting the function, so who knows how to use it?

> +/**
> + * fence_signal - signal completion of a fence
> + * @fence: the fence to signal
> + *
> + * Signal completion for software callbacks on a fence, this will unblock
> + * fence_wait() calls and run all the callbacks added with
> + * fence_add_callback(). Can be called multiple times, but since a fence
> + * can only go from unsignaled to signaled state, it will only be effective
> + * the first time.
> + */
> +int fence_signal(struct fence *fence)
> +{
> + unsigned long flags;
> +
> + if (!fence)
> + return -EINVAL;
> +
> + if (!ktime_to_ns(fence->timestamp)) {
> + fence->timestamp = ktime_get();
> + smp_mb__before_atomic();
> + }
> +
> + if (test_and_set_bit(FENCE_FLAG_SIGNALED_BIT, >flags))
> + return -EINVAL;
> +
> + trace_fence_signaled(fence);
> +
> + if (test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, >flags)) {
> + struct fence_cb *cur, *tmp;
> +
> + spin_lock_irqsave(fence->lock, flags);
> + list_for_each_entry_safe(cur, tmp, >cb_list, node) {
> + list_del_init(>node);
> + cur->func(fence, cur);
> + }
> + spin_unlock_irqrestore(fence->lock, flags);
> + }
> + return 0;
> +}
> +EXPORT_SYMBOL(fence_signal);

So, why should I use this over __fence_signal?  What is the difference?
Am I missing some documentation somewhere?

> +void release_fence(struct kref *kref)
> +{
> + struct fence *fence =
> + container_of(kref, struct fence, refcount);
> +
> + trace_fence_destroy(fence);
> +
> + BUG_ON(!list_empty(>cb_list));
> +
> + if (fence->ops->release)
> + fence->ops->release(fence);
> + else
> + kfree(fence);
> +}
> +EXPORT_SYMBOL(release_fence);

fence_release() makes it more unified with the other functions in this
file, right?

> +/**
> + * fence_default_wait - default sleep until the fence gets signaled
> + * or until timeout elapses
> + * @fence:   [in]the fence to wait on
> + * @intr:[in]if true, do an interruptible wait
> + * @timeout: [in]timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
> + *
> + * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
> + * remaining timeout in jiffies on success.
> + */
> +long

Shouldn't this be signed to be explicit?

> +fence_default_wait(struct fence *fence, bool intr, signed long timeout)
> +{
> + struct default_wait_cb cb;
> + unsigned long flags;
> + long ret = timeout;
> + bool was_set;
> +
> + if (test_bit(FENCE_FLAG_SIGNALED_BIT, >flags))
> + return timeout;
> +
> + spin_lock_irqsave(fence->lock, flags);
> +
> + if (intr && signal_pending(current)) {
> + ret = -ERESTARTSYS;
> + goto out;
> + }
> +
> + was_set = 

[PATCH v2 2/2] drm/debugfs: add an "edid_override" file per connector

2014-06-18 Thread Thomas Wood
Add a file to debugfs for each connector to allow the EDID to be
overridden.

v2: Copy ubuf before accessing it and reject invalid length data. (David
Herrmann)
Ensure override_edid is reset when a new EDID value is written.
(David Herrmann)
Fix the debugfs file permissions. (David Herrmann)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c |  4 +++
 drivers/gpu/drm/drm_debugfs.c  | 68 ++
 drivers/gpu/drm/drm_probe_helper.c |  9 -
 include/drm/drm_crtc.h |  1 +
 4 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fdb69f7..4b3bbc4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3916,6 +3916,10 @@ int drm_mode_connector_update_edid_property(struct 
drm_connector *connector,
struct drm_device *dev = connector->dev;
int ret, size;

+   /* ignore requests to set edid when overridden */
+   if (connector->override_edid)
+   return 0;
+
if (connector->edid_blob_ptr)
drm_property_destroy_blob(dev, connector->edid_blob_ptr);

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 8ab3f3e..13bd429 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 

 #if defined(CONFIG_DEBUG_FS)

@@ -304,6 +305,67 @@ static ssize_t connector_write(struct file *file, const 
char __user *ubuf,
return len;
 }

+static int edid_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   struct drm_property_blob *edid = connector->edid_blob_ptr;
+
+   if (connector->override_edid && edid)
+   seq_write(m, edid->data, edid->length);
+
+   return 0;
+}
+
+static int edid_open(struct inode *inode, struct file *file)
+{
+   struct drm_connector *dev = inode->i_private;
+
+   return single_open(file, edid_show, dev);
+}
+
+static ssize_t edid_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_connector *connector = m->private;
+   char *buf;
+   struct edid *edid;
+   int ret;
+
+   buf = memdup_user(ubuf, len);
+   if (IS_ERR(buf))
+   return PTR_ERR(buf);
+
+   edid = (struct edid *) buf;
+
+   if (len == 5 && !strncmp(buf, "reset", 5)) {
+   connector->override_edid = false;
+   ret = drm_mode_connector_update_edid_property(connector, NULL);
+   } else if (len < EDID_LENGTH ||
+  EDID_LENGTH * (1 + edid->extensions) > len)
+   ret = -EINVAL;
+   else {
+   connector->override_edid = false;
+   ret = drm_mode_connector_update_edid_property(connector, edid);
+   if (!ret)
+   connector->override_edid = true;
+   }
+
+   kfree(buf);
+
+   return (ret) ? ret : len;
+}
+
+static const struct file_operations drm_edid_fops = {
+   .owner = THIS_MODULE,
+   .open = edid_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = edid_write
+};
+
+
 static const struct file_operations drm_connector_fops = {
.owner = THIS_MODULE,
.open = connector_open,
@@ -333,6 +395,12 @@ int drm_debugfs_connector_add(struct drm_connector 
*connector)
if (!ent)
goto error;

+   /* edid */
+   ent = debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root,
+ connector, _edid_fops);
+   if (!ent)
+   goto error;
+
return 0;

 error:
diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index d22676b..db7d250 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -130,7 +130,14 @@ static int 
drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
count = drm_load_edid_firmware(connector);
if (count == 0)
 #endif
-   count = (*connector_funcs->get_modes)(connector);
+   {
+   if (connector->override_edid) {
+   struct edid *edid = (struct edid *) 
connector->edid_blob_ptr->data;
+
+   count = drm_add_edid_modes(connector, edid);
+   } else
+   count = (*connector_funcs->get_modes)(connector);
+   }

if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 67a33bc..d09b471 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -537,6 +537,7 @@ struct drm_connector {

/* forced on connector */
enum 

[PATCH v2 1/2] drm/debugfs: add a "force" file per connector

2014-06-18 Thread Thomas Wood
Add a file to debugfs for each connector to enable modification of the
"force" connector attribute. This allows connectors to be enabled or
disabled for testing and debugging purposes.

v2: Add stricter value checking and clean up debugfs_entry if file
creation fails in drm_debugfs_connector_add. (David Herrmann)

Signed-off-by: Thomas Wood 
---
 drivers/gpu/drm/drm_crtc.c|  17 ++-
 drivers/gpu/drm/drm_debugfs.c | 114 ++
 include/drm/drmP.h|  11 
 include/drm/drm_crtc.h|   2 +
 4 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 365e2c0..fdb69f7 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -888,6 +888,8 @@ int drm_connector_init(struct drm_device *dev,
drm_object_attach_property(>base,
  dev->mode_config.dpms_property, 0);

+   connector->debugfs_entry = NULL;
+
 out_put:
if (ret)
drm_mode_object_put(dev, >base);
@@ -938,7 +940,19 @@ EXPORT_SYMBOL(drm_connector_cleanup);
  */
 int drm_connector_register(struct drm_connector *connector)
 {
-   return drm_sysfs_connector_add(connector);
+   int ret;
+
+   ret = drm_sysfs_connector_add(connector);
+   if (ret)
+   return ret;
+
+   ret = drm_debugfs_connector_add(connector);
+   if (ret) {
+   drm_sysfs_connector_remove(connector);
+   return ret;
+   }
+
+   return 0;
 }
 EXPORT_SYMBOL(drm_connector_register);

@@ -951,6 +965,7 @@ EXPORT_SYMBOL(drm_connector_register);
 void drm_connector_unregister(struct drm_connector *connector)
 {
drm_sysfs_connector_remove(connector);
+   drm_debugfs_connector_remove(connector);
 }
 EXPORT_SYMBOL(drm_connector_unregister);

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b4b51d4..8ab3f3e 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -237,5 +237,119 @@ int drm_debugfs_cleanup(struct drm_minor *minor)
return 0;
 }

+static int connector_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   const char *status;
+
+   switch (connector->force) {
+   case DRM_FORCE_ON:
+   status = "on\n";
+   break;
+
+   case DRM_FORCE_ON_DIGITAL:
+   status = "digital\n";
+   break;
+
+   case DRM_FORCE_OFF:
+   status = "off\n";
+   break;
+
+   case DRM_FORCE_UNSPECIFIED:
+   status = "unspecified\n";
+   break;
+
+   default:
+   return 0;
+   }
+
+   seq_puts(m, status);
+
+   return 0;
+}
+
+static int connector_open(struct inode *inode, struct file *file)
+{
+   struct drm_connector *dev = inode->i_private;
+
+   return single_open(file, connector_show, dev);
+}
+
+static ssize_t connector_write(struct file *file, const char __user *ubuf,
+  size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_connector *connector = m->private;
+   char buf[12];
+
+   if (len > sizeof(buf) - 1)
+   return -EINVAL;
+
+   if (copy_from_user(buf, ubuf, len))
+   return -EFAULT;
+
+   buf[len] = '\0';
+
+   if (!strcmp(buf, "on"))
+   connector->force = DRM_FORCE_ON;
+   else if (!strcmp(buf, "digital"))
+   connector->force = DRM_FORCE_ON_DIGITAL;
+   else if (!strcmp(buf, "off"))
+   connector->force = DRM_FORCE_OFF;
+   else if (!strcmp(buf, "unspecified"))
+   connector->force = DRM_FORCE_UNSPECIFIED;
+   else
+   return -EINVAL;
+
+   return len;
+}
+
+static const struct file_operations drm_connector_fops = {
+   .owner = THIS_MODULE,
+   .open = connector_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = connector_write
+};
+
+int drm_debugfs_connector_add(struct drm_connector *connector)
+{
+   struct drm_minor *minor = connector->dev->primary;
+   struct dentry *root, *ent;
+
+   if (!minor->debugfs_root)
+   return -1;
+
+   root = debugfs_create_dir(connector->name, minor->debugfs_root);
+   if (!root)
+   return -ENOMEM;
+
+   connector->debugfs_entry = root;
+
+   /* force */
+   ent = debugfs_create_file("force", S_IRUGO | S_IWUSR, root, connector,
+ _connector_fops);
+   if (!ent)
+   goto error;
+
+   return 0;
+
+error:
+   debugfs_remove_recursive(connector->debugfs_entry);
+   connector->debugfs_entry = NULL;
+   return -ENOMEM;
+}
+
+void drm_debugfs_connector_remove(struct drm_connector *connector)
+{
+   if (!connector->debugfs_entry)
+   

[PATCH v2 0/2] connector debugfs properties

2014-06-18 Thread Thomas Wood
The following patches update the last two patches in the original series with
the suggested changes from David Herrmann.

Thomas Wood (2):
  drm/debugfs: add a "force" file per connector
  drm/debugfs: add an "edid_override" file per connector

 drivers/gpu/drm/drm_crtc.c |  21 -
 drivers/gpu/drm/drm_debugfs.c  | 182 +
 drivers/gpu/drm/drm_probe_helper.c |   9 +-
 include/drm/drmP.h |  11 +++
 include/drm/drm_crtc.h |   3 +
 5 files changed, 224 insertions(+), 2 deletions(-)

-- 
1.9.3


[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Stephen Warren
On 06/18/2014 05:14 PM, Thierry Reding wrote:
> On Wed, Jun 18, 2014 at 04:09:06PM -0600, Stephen Warren wrote:
>> On 06/18/2014 04:03 PM, Thierry Reding wrote:
...
>>> From what I remember, Mike was fairly strongly opposing the idea of
>>> virtual clocks, but what you're proposing here sounds like it would
>>> assume the existence of virtual clocks. clk_set_rate() per client
>>> doesn't work with the current API as I understand it.
>>>
>>> Or perhaps what you're proposing isn't about the individual clocks at
>>> all but rather about a mechanism to express constraints for a set of
>>> clocks?
>>
>> This doesn't have anything to do with virtual clocks. As you mention,
>> it's just about constraints.
>>
>> One user of clock "cpu" wants min rate 216MHz. Another wants max rate
>> 1GHz. cpufreq will request some rate between the 2, or be capped to
>> those limits. These set of imposed constraints would need to be stored
>> per client of the clock, not per HW clock, since many clients could set
>> different max rates (e.g. thermal throttle 1.5GHz due to temperature,
>> CPU policy 1GHz due to the user selecting low CPU power, etc.)
>>
>> Similarly for audio, of there are N clients of 1 clock/PLL, and they
>> each want the PLL to run at a different rate, something needs to detect
>> that and deny it.
> 
> I'm wondering how this should work with the current API. Could the clock
> core be modified to return a per-client struct clk * that references the
> hardware clock internally? Or do we need to add a new API?

I would assume the we can just change struct clk and hide the details
from any driver. Hopefully only clock-core and clock-drivers would need
any changes.

-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/e86187fa/attachment.sig>


[PATCH 5/5] drm/exynos: enable vsync interrupt while waiting for vblank

2014-06-18 Thread Rahul Sharma
mixer_wait_for_vblank function expects that the upcoming
vsync interrupt handler routine will clear the
wait_vsync_event atomic variable.

For this to happen, interrupts should be enabled and
disabled properly.

Signed-off-by: Rahul Sharma 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 6f18581..7927f2e 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1019,6 +1019,8 @@ static void mixer_wait_for_vblank(struct 
exynos_drm_manager *mgr)
}
mutex_unlock(_ctx->mixer_mutex);

+   mixer_enable_vblank(mgr);
+
atomic_set(_ctx->wait_vsync_event, 1);

/*
@@ -1029,6 +1031,8 @@ static void mixer_wait_for_vblank(struct 
exynos_drm_manager *mgr)
!atomic_read(_ctx->wait_vsync_event),
HZ/20))
DRM_DEBUG_KMS("vblank wait timed out.\n");
+
+   mixer_disable_vblank(mgr);
 }

 static void mixer_window_suspend(struct exynos_drm_manager *mgr)
-- 
1.7.9.5



[PATCH 4/5] drm/exynos: soft reset mixer before reconfigure after power-on

2014-06-18 Thread Rahul Sharma
Mixer soft reset is a recommended step before reconfiguring
the mixer after power on. Mixer looses the previous state of
DMAs if soft reset. This is the recommendation from the
hardware team.

Signed-off-by: Rahul Sharma 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 6773b03..6f18581 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1085,6 +1085,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
ctx->powered = true;
mutex_unlock(>mixer_mutex);

+   mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
+
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
mixer_win_reset(ctx);

-- 
1.7.9.5



[PATCH 3/5] drm/exynos: allow mulitple layer updates per vsync for mixer

2014-06-18 Thread Rahul Sharma
Allowing only one layer update per vsync can cause issues
while there are update available for both layers. There is
a good amount of possibility to loose updates if we allow
single update per vsync.

Signed-off-by: Rahul Sharma 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index d359501..6773b03 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -511,13 +511,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int 
win)
 static void mixer_layer_update(struct mixer_context *ctx)
 {
struct mixer_resources *res = >mixer_res;
-   u32 val;
-
-   val = mixer_reg_read(res, MXR_CFG);

-   /* allow one update per vsync only */
-   if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
-   mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
+   mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
 }

 static void mixer_graph_buffer(struct mixer_context *ctx, int win)
-- 
1.7.9.5



[PATCH 2/5] drm/exynos: stop mixer before gating clocks during poweroff

2014-06-18 Thread Rahul Sharma
Mixer should be power gated only after it is gracefully stopped.
The recommended sequence is to Stop the mixer and wait till
it enters to IDLE state before gating the clocks and power to
the mixer.

Signed-off-by: Rahul Sharma 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |   15 +++
 drivers/gpu/drm/exynos/regs-mixer.h   |1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index c00abbe..d359501 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -377,6 +377,20 @@ static void mixer_run(struct mixer_context *ctx)
mixer_regs_dump(ctx);
 }

+static void mixer_stop(struct mixer_context *ctx)
+{
+   struct mixer_resources *res = >mixer_res;
+   int timeout = 20;
+
+   mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
+
+   while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
+   --timeout)
+   usleep_range(1, 12000);
+
+   mixer_regs_dump(ctx);
+}
+
 static void vp_video_buffer(struct mixer_context *ctx, int win)
 {
struct mixer_resources *res = >mixer_res;
@@ -1094,6 +1108,7 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
}
mutex_unlock(>mixer_mutex);

+   mixer_stop(ctx);
mixer_window_suspend(mgr);

ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h 
b/drivers/gpu/drm/exynos/regs-mixer.h
index 4537026..5f32e1a 100644
--- a/drivers/gpu/drm/exynos/regs-mixer.h
+++ b/drivers/gpu/drm/exynos/regs-mixer.h
@@ -78,6 +78,7 @@
 #define MXR_STATUS_BIG_ENDIAN  (1 << 3)
 #define MXR_STATUS_ENDIAN_MASK (1 << 3)
 #define MXR_STATUS_SYNC_ENABLE (1 << 2)
+#define MXR_STATUS_REG_IDLE(1 << 1)
 #define MXR_STATUS_REG_RUN (1 << 0)

 /* bits for MXR_CFG */
-- 
1.7.9.5



[PATCH 1/5] drm/exynos: set power state variable after enabling clocks and power

2014-06-18 Thread Rahul Sharma
Power state variable holds the state of the mixer device.
Power on and power off functions are toggling these variable
at wrong place.

State variable should be changed to true only after Runtime
PM and clocks are enabled. Else it may result to a situation
where mixer registers are accessed with device power enabled.
Similar logic for poweroff sequence.

Signed-off-by: Rahul Sharma 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |   22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 4c5aed7..c00abbe 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1061,7 +1061,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
mutex_unlock(>mixer_mutex);
return;
}
-   ctx->powered = true;
+
mutex_unlock(>mixer_mutex);

pm_runtime_get_sync(ctx->dev);
@@ -1072,6 +1072,10 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
clk_prepare_enable(res->sclk_mixer);
}

+   mutex_lock(>mixer_mutex);
+   ctx->powered = true;
+   mutex_unlock(>mixer_mutex);
+
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
mixer_win_reset(ctx);

@@ -1084,14 +1088,20 @@ static void mixer_poweroff(struct exynos_drm_manager 
*mgr)
struct mixer_resources *res = >mixer_res;

mutex_lock(>mixer_mutex);
-   if (!ctx->powered)
-   goto out;
+   if (!ctx->powered) {
+   mutex_unlock(>mixer_mutex);
+   return;
+   }
mutex_unlock(>mixer_mutex);

mixer_window_suspend(mgr);

ctx->int_en = mixer_reg_read(res, MXR_INT_EN);

+   mutex_lock(>mixer_mutex);
+   ctx->powered = false;
+   mutex_unlock(>mixer_mutex);
+
clk_disable_unprepare(res->mixer);
if (ctx->vp_enabled) {
clk_disable_unprepare(res->vp);
@@ -1099,12 +1109,6 @@ static void mixer_poweroff(struct exynos_drm_manager 
*mgr)
}

pm_runtime_put_sync(ctx->dev);
-
-   mutex_lock(>mixer_mutex);
-   ctx->powered = false;
-
-out:
-   mutex_unlock(>mixer_mutex);
 }

 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
-- 
1.7.9.5



[PATCH 0/5] drm/exynos: fix for misc issues related to exynos mixer

2014-06-18 Thread Rahul Sharma
Fixes for various issues which are to Power On/Off sequence,
Layer update, waiting for vblank in exynos mixer driver.

This series is based on exynos-drm-fixes branch in Inki dae's tree.

Rahul Sharma (5):
  drm/exynos: set power state variable after enabling clocks and power
  drm/exynos: stop mixer before gating clocks during poweroff
  drm/exynos: allow mulitple layer updates per vsync for mixer
  drm/exynos: soft reset mixer before reconfigure after power-on
  drm/exynos: enable vsync interrupt while waiting for vblank

 drivers/gpu/drm/exynos/exynos_mixer.c |   50 +++--
 drivers/gpu/drm/exynos/regs-mixer.h   |1 +
 2 files changed, 36 insertions(+), 15 deletions(-)

-- 
1.7.9.5



[pull] radeon drm-fixes-3.16

2014-06-18 Thread Alex Deucher
Hi Dave,

Some fixes for radeon mode validation, deep color support, and pageflipping.

The following changes since commit 571366284b50c93ba4ba5f13fad3f2430024c613:

  Merge branch 'drm-nouveau-next' of 
git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next (2014-06-18 
15:50:58 +1000)

are available in the git repository at:


  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.16

for you to fetch changes up to 46889d9568b90ae9032a4e84a7b404bb5f96f9a3:

  drm/radeon: Fix radeon_irq_kms_pflip_irq_get/put() imbalance (2014-06-18 
16:30:50 -0400)


Alex Deucher (2):
  drm/radeon: update mode_valid testing for DP
  drm/radeon: improve dvi_mode_valid

Mario Kleiner (1):
  drm/radeon: Use dce5/6 hdmi deep color clock setup also on dce8+

Michel D?nzer (2):
  Revert "drm/radeon: remove drm_vblank_get|put from pflip handling"
  drm/radeon: Fix radeon_irq_kms_pflip_irq_get/put() imbalance

 drivers/gpu/drm/radeon/atombios_crtc.c |  2 +-
 drivers/gpu/drm/radeon/radeon_connectors.c | 35 +++---
 drivers/gpu/drm/radeon/radeon_display.c| 19 +++-
 3 files changed, 41 insertions(+), 15 deletions(-)


[PATCH] drm/msm: Implement msm drm fb_mmap callback function

2014-06-18 Thread Hai Li
This change implements msm drm specific fb_mmap function for fb device
to properly map the fb address to userspace.

Signed-off-by: Hai Li 
Signed-off-by: Stephane Viau 
---
 drivers/gpu/drm/msm/msm_fbdev.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 4f4e7b4..2522f51 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -19,6 +19,11 @@

 #include "drm_crtc.h"
 #include "drm_fb_helper.h"
+#include "msm_gem.h"
+
+extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
+   struct vm_area_struct *vma);
+static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma);

 /*
  * fbdev funcs, to implement legacy fbdev interface on top of drm driver
@@ -43,6 +48,7 @@ static struct fb_ops msm_fb_ops = {
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
+   .fb_mmap = msm_fbdev_mmap,

.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
@@ -51,6 +57,31 @@ static struct fb_ops msm_fb_ops = {
.fb_setcmap = drm_fb_helper_setcmap,
 };

+static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+   struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
+   struct msm_fbdev *fbdev = to_msm_fbdev(helper);
+   struct drm_gem_object *drm_obj = fbdev->bo;
+   struct drm_device *dev = helper->dev;
+   int ret = 0;
+
+   if (drm_device_is_unplugged(dev))
+   return -ENODEV;
+
+   mutex_lock(>struct_mutex);
+
+   ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
+
+   mutex_unlock(>struct_mutex);
+
+   if (ret) {
+   pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
+   return ret;
+   }
+
+   return msm_gem_mmap_obj(drm_obj, vma);
+}
+
 static int msm_fbdev_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
 {
@@ -108,7 +139,11 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(>struct_mutex);

/* TODO implement our own fb_mmap so we don't need this: */
-   msm_gem_get_iova_locked(fbdev->bo, 0, );
+   ret = msm_gem_get_iova_locked(fbdev->bo, 0, );
+   if (ret) {
+   dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret);
+   goto fail;
+   }

fbi = framebuffer_alloc(0, dev->dev);
if (!fbi) {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Stephen Warren
On 06/18/2014 04:19 PM, St?phane Marchesin wrote:
> On Wed, Jun 18, 2014 at 3:00 PM, Thierry Reding
>  wrote:
>> On Wed, Jun 18, 2014 at 07:23:47PM +0200, Tomeu Vizoso wrote:
>>> On 06/17/2014 06:15 PM, Stephen Warren wrote:
 On 06/17/2014 06:16 AM, Tomeu Vizoso wrote:
> On 06/16/2014 10:02 PM, Stephen Warren wrote:
>> On 06/16/2014 07:35 AM, Tomeu Vizoso wrote:
>>> +#ifdef CONFIG_TEGRA124_EMC
>>> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
>>> long rate);
>>> +void tegra124_emc_set_floor(unsigned long freq);
>>> +void tegra124_emc_set_ceiling(unsigned long freq);
>>> +#else
>>> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
>>> long rate)
>>> +{ return -ENODEV; }
>>> +void tegra124_emc_set_floor(unsigned long freq)
>>> +{ return; }
>>> +void tegra124_emc_set_ceiling(unsigned long freq)
>>> +{ return; }
>>> +#endif
>>
>> I'll repeat what I said off-list so that we can have the whole
>> conversation on the list:
>>
>> That looks like a custom Tegra-specific API. I think it'd be much better
>> to integrate this into the common clock framework as a standard clock
>> constraints API. There are other use-cases for clock constraints besides
>> EMC scaling (e.g. some in audio on Tegra, and I'm sure many on other
>> SoCs too).
>
> Yes, I wrote a bit in the cover letter about our requirements and how
> they map to the CCF. Could you please comment on that?

 My comments remain the same. I believe this is something that belongs in
 the clock driver, or at the least, some API that takes a struct clock as
 its parameter, so that drivers can use the existing DT clock lookup
 mechanism.
>>>
>>> Ok, let me put this strawman here to see if I have gotten close to what you
>>> have in mind:
>>>
>>> * add per-client accounting (Rabin's patches referenced before)
>>>
>>> * add clk_set_floor, to be used by cpufreq, load stats, etc.
>>>
>>> * add clk_set_ceiling, to be used by battery drivers, thermal, etc.
>>>
>>> * an EMC driver would collect bandwidth and latency requests from consumers
>>> and call clk_set_floor on the EMC clock.
>>>
>>> * the EMC driver would also register for rate change notifications in the
>>> EMC clock and would update the latency allowance registers at that point.
>>
>> Latency allowance registers are part of the MC rather than the EMC. So I
>> think we have two options: a) have a unified driver for MC and EMC or b)
>> provide two parts of the API in two drivers.
>>
>> Or perhaps c), create a generic framework that both MC and EMC can
>> register with (bandwidth for EMC, latency for MC).
> 
> Is there any motivation for keeping MC and EMC separate? In my mind,
> the solution was always to handle those together.

Well, they are documented as being separate HW modules in the TRM.

I know there's an interlock in HW so that when the EMC clock is changed,
the EMC registers can flip atomically to a new configuration.

I'm not aware of any similar HW interlock between MC and EMC registers.
That would imply that very tight co-ordination shouldn't be required.

Do the MC latency allowance registers /really/ need to be *very tightly*
managed whenever the EMC clock is changed, or is it just a matter of it
being a good idea to update EMC clock and MC latency allowance registers
at roughly the same time? Even if there's some co-ordination required,
maybe it can be handled rather like cpufreq notifications; use clock
pre-rate change notifications to set MC up in a way that'll work at both
old/new EMC clocks, and then clock post-rate notifications to the final
MC configuration?


[Bug 79980] Random radeonsi crashes

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=79980

--- Comment #15 from agapito  ---
This bug is caused by TAHITI_mc2.bin firmware. The old firmware works good.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/2a1b0cda/attachment.html>


[PATCH 3/3] drm/radeon: enable bapm by default on desktop TN/RL boards

2014-06-18 Thread Alex Deucher
bapm enabled the GPU and CPU to share TDP headroom.  It was
disabled by default since some laptops hung when it was enabled
in conjunction with dpm.  It seems to be stable on desktop
boards and fixes hangs on boot with dpm enabled on certain
boards, so enable it by default on desktop boards.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=72921

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/trinity_dpm.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c 
b/drivers/gpu/drm/radeon/trinity_dpm.c
index 2a2822c..20da6ff 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1874,7 +1874,15 @@ int trinity_dpm_init(struct radeon_device *rdev)
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
pi->at[i] = TRINITY_AT_DFLT;

-   pi->enable_bapm = false;
+   /* There are stability issues reported on latops with
+* bapm installed when switching between AC and battery
+* power.  At the same time, some desktop boards hang
+* if it's not enabled and dpm is enabled.
+*/
+   if (rdev->flags & RADEON_IS_MOBILITY)
+   pi->enable_bapm = false;
+   else
+   pi->enable_bapm = true;
pi->enable_nbps_policy = true;
pi->enable_sclk_ds = true;
pi->enable_gfx_power_gating = true;
-- 
1.8.3.1



[PATCH 2/3] drm/radeon: enable bapm by default on KV/KB

2014-06-18 Thread Alex Deucher
bapm allows the GPU and CPU to share TDP.  This allows
for additional performance out of the GPU and CPU when
the headroom is available.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/kv_dpm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index 3f6e817..9ef8c38 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -2726,7 +2726,7 @@ int kv_dpm_init(struct radeon_device *rdev)
pi->caps_sclk_ds = true;
pi->enable_auto_thermal_throttling = true;
pi->disable_nb_ps3_in_battery = false;
-   pi->bapm_enable = false;
+   pi->bapm_enable = true;
pi->voltage_drop_t = 0;
pi->caps_sclk_throttle_low_notification = false;
pi->caps_fps = false; /* true? */
-- 
1.8.3.1



[PATCH 1/3] drm/radeon: only apply bapm changes for AC power on ARUBA

2014-06-18 Thread Alex Deucher
Never asics shouldn't need any manual adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_pm.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 12c663e..e447e39 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -73,8 +73,10 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev)
rdev->pm.dpm.ac_power = true;
else
rdev->pm.dpm.ac_power = false;
-   if (rdev->asic->dpm.enable_bapm)
-   radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power);
+   if (rdev->family == CHIP_ARUBA) {
+   if (rdev->asic->dpm.enable_bapm)
+   radeon_dpm_enable_bapm(rdev, 
rdev->pm.dpm.ac_power);
+   }
mutex_unlock(>pm.mutex);
 } else if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
if (rdev->pm.profile == PM_PROFILE_AUTO) {
-- 
1.8.3.1



[PATCH] drm/radeon: adjust default dispclk on DCE6 (v2)

2014-06-18 Thread Alex Deucher
Set the default to 600Mhz if it's not set in the bios,
and bump the default to 600Mhz if it's lower than that.

This fixes display issues with certain 4k DP monitors when
using 5.4 Ghz DP clocks.

v2: fix typo.

Signed-off-by: Alex Deucher 
---

Send out the wrong version before.

 drivers/gpu/drm/radeon/radeon_atombios.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index 3084481..173f378 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1227,11 +1227,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
rdev->clock.default_dispclk =

le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
if (rdev->clock.default_dispclk == 0) {
-   if (ASIC_IS_DCE5(rdev))
+   if (ASIC_IS_DCE6(rdev))
+   rdev->clock.default_dispclk = 6; /* 
600 Mhz */
+   else if (ASIC_IS_DCE5(rdev))
rdev->clock.default_dispclk = 54000; /* 
540 Mhz */
else
rdev->clock.default_dispclk = 6; /* 
600 Mhz */
}
+   /* set a reasonable default for DP */
+   if (ASIC_IS_DCE6(rdev) && (rdev->clock.default_dispclk 
< 53900)) {
+   DRM_INFO("Changing default dispclk from %dMhz 
to 600Mhz\n",
+rdev->clock.default_dispclk / 100);
+   rdev->clock.default_dispclk = 6;
+   }
rdev->clock.dp_extclk =

le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
rdev->clock.current_dispclk = 
rdev->clock.default_dispclk;
-- 
1.8.3.1



[PATCH V2] drm/tegra: add MODULE_DEVICE_TABLEs

2014-06-18 Thread Stephen Warren
From: Stephen Warren 

When tegra-drm.ko is built as a module, these MODULE_DEVICE_TABLEs allow
the module to be auto-loaded since the module will match the devices
instantiated from device tree.

(Notes for stable: in 3.14+, just git rm any conflicting file, since they
are added in later kernels. For 3.13 and below, manual merging will be
needed)

Cc: 
Signed-off-by: Stephen Warren 
---
v2: Remove change to drm.c, since the match table there isn't used for
probing.
---
 drivers/gpu/drm/tegra/dc.c| 1 +
 drivers/gpu/drm/tegra/dpaux.c | 1 +
 drivers/gpu/drm/tegra/dsi.c   | 1 +
 drivers/gpu/drm/tegra/gr2d.c  | 1 +
 drivers/gpu/drm/tegra/gr3d.c  | 1 +
 drivers/gpu/drm/tegra/hdmi.c  | 1 +
 drivers/gpu/drm/tegra/sor.c   | 1 +
 7 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ef40381f3909..48c3bc460eef 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1303,6 +1303,7 @@ static const struct of_device_id tegra_dc_of_match[] = {
/* sentinel */
}
 };
+MODULE_DEVICE_TABLE(of, tegra_dc_of_match);

 static int tegra_dc_parse_dt(struct tegra_dc *dc)
 {
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 3f132e356e9c..708f783ead47 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -382,6 +382,7 @@ static const struct of_device_id tegra_dpaux_of_match[] = {
{ .compatible = "nvidia,tegra124-dpaux", },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);

 struct platform_driver tegra_dpaux_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index bd56f2affa78..97c409f10456 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -982,6 +982,7 @@ static const struct of_device_id tegra_dsi_of_match[] = {
{ .compatible = "nvidia,tegra114-dsi", },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);

 struct platform_driver tegra_dsi_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index 7c53941f2a9e..02cd3e37a6ec 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -121,6 +121,7 @@ static const struct of_device_id gr2d_match[] = {
{ .compatible = "nvidia,tegra20-gr2d" },
{ },
 };
+MODULE_DEVICE_TABLE(of, gr2d_match);

 static const u32 gr2d_addr_regs[] = {
GR2D_UA_BASE_ADDR,
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index 30f5ba9bd6d0..2bea2b2d204e 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -130,6 +130,7 @@ static const struct of_device_id tegra_gr3d_match[] = {
{ .compatible = "nvidia,tegra20-gr3d" },
{ }
 };
+MODULE_DEVICE_TABLE(of, tegra_gr3d_match);

 static const u32 gr3d_addr_regs[] = {
GR3D_IDX_ATTRIBUTE( 0),
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index a0b8d8539d07..84ea0c8b47f7 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -1370,6 +1370,7 @@ static const struct of_device_id tegra_hdmi_of_match[] = {
{ .compatible = "nvidia,tegra20-hdmi", .data = _hdmi_config },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match);

 static int tegra_hdmi_probe(struct platform_device *pdev)
 {
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 27c979b50111..061a5c501124 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -1455,6 +1455,7 @@ static const struct of_device_id tegra_sor_of_match[] = {
{ .compatible = "nvidia,tegra124-sor", },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_sor_of_match);

 struct platform_driver tegra_sor_driver = {
.driver = {
-- 
1.8.1.5



[PATCH] drm/tegra: add MODULE_DEVICE_TABLEs

2014-06-18 Thread Stephen Warren
On 06/18/2014 03:51 PM, Thierry Reding wrote:
> On Wed, Jun 18, 2014 at 03:19:15PM -0600, Stephen Warren wrote:
>> From: Stephen Warren 
>>
>> When tegra-drm.ko is built as a module, these MODULE_DEVICE_TABLEs allow
>> the module to be auto-loaded since the module will match the devices
>> instantiated from device tree.
> 
> I vaguely remember doing something like this a while back and getting a
> bunch of link-time errors. But I assume that you've tested this, so I
> must be remembering wrongly.

Were the problems due to:

a) Simply building the tegradrm driver as modules.

I vaguely recall some runtime issues with tegradrm as a module, but I'm
not sure about build issues. I don't think this patch could make this
any worse.

b) Building as modules works, but adding MODULE_DEVICE_TABLE broke that.

This seems unlikely since *many* module in the kernel have a
MODULE_DEVICE_TABLE...

Certainly, with this patch applied, building tegradrm as a module in
next-20140611 works out just fine, and the code runs fine too. Building
tegra_defconfig (which has tegradrm builtin) on Linus' master with this
patch applied also works out fine.

I'll post v2 with the issue you mentioned addressed.

-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/12b77b6c/attachment.sig>


[PATCH] drm/radeon: adjust default dispclk on DCE6

2014-06-18 Thread Alex Deucher
Set the default to 600Mhz if it's not set in the bios,
and bump the default to 600Mhz if it's lower than that.

This fixes display issues with certain 4k DP monitors when
using 5.4 Ghz DP clocks.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_atombios.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index 3084481..c08629e 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1227,11 +1227,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
rdev->clock.default_dispclk =

le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
if (rdev->clock.default_dispclk == 0) {
-   if (ASIC_IS_DCE5(rdev))
+   if (ASIC_IS_DCE6(rdev))
+   rdev->clock.default_dispclk = 6; /* 
600 Mhz */
+   else if (ASIC_IS_DCE5(rdev))
rdev->clock.default_dispclk = 54000; /* 
540 Mhz */
else
rdev->clock.default_dispclk = 6; /* 
600 Mhz */
}
+   /* set a reasonable default for DP */
+   if (ASIC_IS_DCE6(rdev) && (rdev->clock.default_dispclk 
< 53900)) {
+   DRM_INFO("Changing default dispclk from %dMhz 
to 600Mhz\n",
+rdev->clock.default_dispclk);
+   rdev->clock.default_dispclk = 6;
+   }
rdev->clock.dp_extclk =

le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
rdev->clock.current_dispclk = 
rdev->clock.default_dispclk;
-- 
1.8.3.1



[PATCH v2 1/2] drm/debugfs: add a "force" file per connector

2014-06-18 Thread Alex Deucher
On Wed, Jun 18, 2014 at 12:52 PM, Thomas Wood  wrote:
> Add a file to debugfs for each connector to enable modification of the
> "force" connector attribute. This allows connectors to be enabled or
> disabled for testing and debugging purposes.
>
> v2: Add stricter value checking and clean up debugfs_entry if file
> creation fails in drm_debugfs_connector_add. (David Herrmann)
>
> Signed-off-by: Thomas Wood 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/drm_crtc.c|  17 ++-
>  drivers/gpu/drm/drm_debugfs.c | 114 
> ++
>  include/drm/drmP.h|  11 
>  include/drm/drm_crtc.h|   2 +
>  4 files changed, 143 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 365e2c0..fdb69f7 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -888,6 +888,8 @@ int drm_connector_init(struct drm_device *dev,
> drm_object_attach_property(>base,
>   dev->mode_config.dpms_property, 0);
>
> +   connector->debugfs_entry = NULL;
> +
>  out_put:
> if (ret)
> drm_mode_object_put(dev, >base);
> @@ -938,7 +940,19 @@ EXPORT_SYMBOL(drm_connector_cleanup);
>   */
>  int drm_connector_register(struct drm_connector *connector)
>  {
> -   return drm_sysfs_connector_add(connector);
> +   int ret;
> +
> +   ret = drm_sysfs_connector_add(connector);
> +   if (ret)
> +   return ret;
> +
> +   ret = drm_debugfs_connector_add(connector);
> +   if (ret) {
> +   drm_sysfs_connector_remove(connector);
> +   return ret;
> +   }
> +
> +   return 0;
>  }
>  EXPORT_SYMBOL(drm_connector_register);
>
> @@ -951,6 +965,7 @@ EXPORT_SYMBOL(drm_connector_register);
>  void drm_connector_unregister(struct drm_connector *connector)
>  {
> drm_sysfs_connector_remove(connector);
> +   drm_debugfs_connector_remove(connector);
>  }
>  EXPORT_SYMBOL(drm_connector_unregister);
>
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index b4b51d4..8ab3f3e 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -237,5 +237,119 @@ int drm_debugfs_cleanup(struct drm_minor *minor)
> return 0;
>  }
>
> +static int connector_show(struct seq_file *m, void *data)
> +{
> +   struct drm_connector *connector = m->private;
> +   const char *status;
> +
> +   switch (connector->force) {
> +   case DRM_FORCE_ON:
> +   status = "on\n";
> +   break;
> +
> +   case DRM_FORCE_ON_DIGITAL:
> +   status = "digital\n";
> +   break;
> +
> +   case DRM_FORCE_OFF:
> +   status = "off\n";
> +   break;
> +
> +   case DRM_FORCE_UNSPECIFIED:
> +   status = "unspecified\n";
> +   break;
> +
> +   default:
> +   return 0;
> +   }
> +
> +   seq_puts(m, status);
> +
> +   return 0;
> +}
> +
> +static int connector_open(struct inode *inode, struct file *file)
> +{
> +   struct drm_connector *dev = inode->i_private;
> +
> +   return single_open(file, connector_show, dev);
> +}
> +
> +static ssize_t connector_write(struct file *file, const char __user *ubuf,
> +  size_t len, loff_t *offp)
> +{
> +   struct seq_file *m = file->private_data;
> +   struct drm_connector *connector = m->private;
> +   char buf[12];
> +
> +   if (len > sizeof(buf) - 1)
> +   return -EINVAL;
> +
> +   if (copy_from_user(buf, ubuf, len))
> +   return -EFAULT;
> +
> +   buf[len] = '\0';
> +
> +   if (!strcmp(buf, "on"))
> +   connector->force = DRM_FORCE_ON;
> +   else if (!strcmp(buf, "digital"))
> +   connector->force = DRM_FORCE_ON_DIGITAL;
> +   else if (!strcmp(buf, "off"))
> +   connector->force = DRM_FORCE_OFF;
> +   else if (!strcmp(buf, "unspecified"))
> +   connector->force = DRM_FORCE_UNSPECIFIED;
> +   else
> +   return -EINVAL;
> +
> +   return len;
> +}
> +
> +static const struct file_operations drm_connector_fops = {
> +   .owner = THIS_MODULE,
> +   .open = connector_open,
> +   .read = seq_read,
> +   .llseek = seq_lseek,
> +   .release = single_release,
> +   .write = connector_write
> +};
> +
> +int drm_debugfs_connector_add(struct drm_connector *connector)
> +{
> +   struct drm_minor *minor = connector->dev->primary;
> +   struct dentry *root, *ent;
> +
> +   if (!minor->debugfs_root)
> +   return -1;
> +
> +   root = debugfs_create_dir(connector->name, minor->debugfs_root);
> +   if (!root)
> +   return -ENOMEM;
> +
> +   connector->debugfs_entry = root;
> +
> +   /* force */
> +   ent = debugfs_create_file("force", S_IRUGO | S_IWUSR, root, 

[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Stephen Warren
On 06/18/2014 04:03 PM, Thierry Reding wrote:
> On Wed, Jun 18, 2014 at 11:46:49AM -0600, Stephen Warren wrote:
>> On 06/18/2014 11:23 AM, Tomeu Vizoso wrote:
>>> On 06/17/2014 06:15 PM, Stephen Warren wrote:
>>>> On 06/17/2014 06:16 AM, Tomeu Vizoso wrote:
>>>>> On 06/16/2014 10:02 PM, Stephen Warren wrote:
>>>>>> On 06/16/2014 07:35 AM, Tomeu Vizoso wrote:
>>>>>>> +#ifdef CONFIG_TEGRA124_EMC
>>>>>>> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
>>>>>>> long rate);
>>>>>>> +void tegra124_emc_set_floor(unsigned long freq);
>>>>>>> +void tegra124_emc_set_ceiling(unsigned long freq);
>>>>>>> +#else
>>>>>>> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
>>>>>>> long rate)
>>>>>>> +{ return -ENODEV; }
>>>>>>> +void tegra124_emc_set_floor(unsigned long freq)
>>>>>>> +{ return; }
>>>>>>> +void tegra124_emc_set_ceiling(unsigned long freq)
>>>>>>> +{ return; }
>>>>>>> +#endif
>>>>>>
>>>>>> I'll repeat what I said off-list so that we can have the whole
>>>>>> conversation on the list:
>>>>>>
>>>>>> That looks like a custom Tegra-specific API. I think it'd be much
>>>>>> better
>>>>>> to integrate this into the common clock framework as a standard clock
>>>>>> constraints API. There are other use-cases for clock constraints
>>>>>> besides
>>>>>> EMC scaling (e.g. some in audio on Tegra, and I'm sure many on other
>>>>>> SoCs too).
>>>>>
>>>>> Yes, I wrote a bit in the cover letter about our requirements and how
>>>>> they map to the CCF. Could you please comment on that?
>>>>
>>>> My comments remain the same. I believe this is something that belongs in
>>>> the clock driver, or at the least, some API that takes a struct clock as
>>>> its parameter, so that drivers can use the existing DT clock lookup
>>>> mechanism.
>>>
>>> Ok, let me put this strawman here to see if I have gotten close to what
>>> you have in mind:
>>>
>>> * add per-client accounting (Rabin's patches referenced before)
>>>
>>> * add clk_set_floor, to be used by cpufreq, load stats, etc.
>>>
>>> * add clk_set_ceiling, to be used by battery drivers, thermal, etc.
>>
>> Yes. I'd expect those to be maintained per-client, and so the clock core
>> (or whatever higher level code implements clk_set_floor/ceiling)
>> performs the logic that "blends" together all the different requests
>> from different clients.
>>
>> As an aside, for audio usage, I would expect clk_set_rate to be a
>> per-client (rather than per HW clock) operation too, and to error out if
>> one client says it wants to set pll_a to the rate needed for
>> 44.1KHz-based audio and a different client wants the rate for
>> 48KHz-based audio.
> 
> From what I remember, Mike was fairly strongly opposing the idea of
> virtual clocks, but what you're proposing here sounds like it would
> assume the existence of virtual clocks. clk_set_rate() per client
> doesn't work with the current API as I understand it.
> 
> Or perhaps what you're proposing isn't about the individual clocks at
> all but rather about a mechanism to express constraints for a set of
> clocks?

This doesn't have anything to do with virtual clocks. As you mention,
it's just about constraints.

One user of clock "cpu" wants min rate 216MHz. Another wants max rate
1GHz. cpufreq will request some rate between the 2, or be capped to
those limits. These set of imposed constraints would need to be stored
per client of the clock, not per HW clock, since many clients could set
different max rates (e.g. thermal throttle 1.5GHz due to temperature,
CPU policy 1GHz due to the user selecting low CPU power, etc.)

Similarly for audio, of there are N clients of 1 clock/PLL, and they
each want the PLL to run at a different rate, something needs to detect
that and deny it.


-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/c955e82b/attachment.sig>


[PATCH v2 2/2] drm/debugfs: add an "edid_override" file per connector

2014-06-18 Thread Alex Deucher
On Wed, Jun 18, 2014 at 12:52 PM, Thomas Wood  wrote:
> Add a file to debugfs for each connector to allow the EDID to be
> overridden.
>
> v2: Copy ubuf before accessing it and reject invalid length data. (David
> Herrmann)
> Ensure override_edid is reset when a new EDID value is written.
> (David Herrmann)
> Fix the debugfs file permissions. (David Herrmann)
>
> Signed-off-by: Thomas Wood 

One minor nit below, but either way:

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/drm_crtc.c |  4 +++
>  drivers/gpu/drm/drm_debugfs.c  | 68 
> ++
>  drivers/gpu/drm/drm_probe_helper.c |  9 -
>  include/drm/drm_crtc.h |  1 +
>  4 files changed, 81 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index fdb69f7..4b3bbc4 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -3916,6 +3916,10 @@ int drm_mode_connector_update_edid_property(struct 
> drm_connector *connector,
> struct drm_device *dev = connector->dev;
> int ret, size;
>
> +   /* ignore requests to set edid when overridden */
> +   if (connector->override_edid)
> +   return 0;
> +
> if (connector->edid_blob_ptr)
> drm_property_destroy_blob(dev, connector->edid_blob_ptr);
>
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index 8ab3f3e..13bd429 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -35,6 +35,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #if defined(CONFIG_DEBUG_FS)
>
> @@ -304,6 +305,67 @@ static ssize_t connector_write(struct file *file, const 
> char __user *ubuf,
> return len;
>  }
>
> +static int edid_show(struct seq_file *m, void *data)
> +{
> +   struct drm_connector *connector = m->private;
> +   struct drm_property_blob *edid = connector->edid_blob_ptr;
> +
> +   if (connector->override_edid && edid)
> +   seq_write(m, edid->data, edid->length);
> +
> +   return 0;
> +}
> +
> +static int edid_open(struct inode *inode, struct file *file)
> +{
> +   struct drm_connector *dev = inode->i_private;
> +
> +   return single_open(file, edid_show, dev);
> +}
> +
> +static ssize_t edid_write(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> +   struct seq_file *m = file->private_data;
> +   struct drm_connector *connector = m->private;
> +   char *buf;
> +   struct edid *edid;
> +   int ret;
> +
> +   buf = memdup_user(ubuf, len);
> +   if (IS_ERR(buf))
> +   return PTR_ERR(buf);
> +
> +   edid = (struct edid *) buf;
> +
> +   if (len == 5 && !strncmp(buf, "reset", 5)) {
> +   connector->override_edid = false;
> +   ret = drm_mode_connector_update_edid_property(connector, 
> NULL);
> +   } else if (len < EDID_LENGTH ||
> +  EDID_LENGTH * (1 + edid->extensions) > len)
> +   ret = -EINVAL;
> +   else {
> +   connector->override_edid = false;

Might be worth doing some minimal validation of the EDID (e.g., make
sure it has a valid header).

Alex

> +   ret = drm_mode_connector_update_edid_property(connector, 
> edid);
> +   if (!ret)
> +   connector->override_edid = true;
> +   }
> +
> +   kfree(buf);
> +
> +   return (ret) ? ret : len;
> +}
> +
> +static const struct file_operations drm_edid_fops = {
> +   .owner = THIS_MODULE,
> +   .open = edid_open,
> +   .read = seq_read,
> +   .llseek = seq_lseek,
> +   .release = single_release,
> +   .write = edid_write
> +};
> +
> +
>  static const struct file_operations drm_connector_fops = {
> .owner = THIS_MODULE,
> .open = connector_open,
> @@ -333,6 +395,12 @@ int drm_debugfs_connector_add(struct drm_connector 
> *connector)
> if (!ent)
> goto error;
>
> +   /* edid */
> +   ent = debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root,
> + connector, _edid_fops);
> +   if (!ent)
> +   goto error;
> +
> return 0;
>
>  error:
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index d22676b..db7d250 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -130,7 +130,14 @@ static int 
> drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
> count = drm_load_edid_firmware(connector);
> if (count == 0)
>  #endif
> -   count = (*connector_funcs->get_modes)(connector);
> +   {
> +   if (connector->override_edid) {
> +   struct edid *edid = (struct edid *) 
> connector->edid_blob_ptr->data;
> +
> +   count = 

[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Stéphane Marchesin
On Wed, Jun 18, 2014 at 3:00 PM, Thierry Reding
 wrote:
> On Wed, Jun 18, 2014 at 07:23:47PM +0200, Tomeu Vizoso wrote:
>> On 06/17/2014 06:15 PM, Stephen Warren wrote:
>> >On 06/17/2014 06:16 AM, Tomeu Vizoso wrote:
>> >>On 06/16/2014 10:02 PM, Stephen Warren wrote:
>> >>>On 06/16/2014 07:35 AM, Tomeu Vizoso wrote:
>> +#ifdef CONFIG_TEGRA124_EMC
>> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
>> long rate);
>> +void tegra124_emc_set_floor(unsigned long freq);
>> +void tegra124_emc_set_ceiling(unsigned long freq);
>> +#else
>> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
>> long rate)
>> +{ return -ENODEV; }
>> +void tegra124_emc_set_floor(unsigned long freq)
>> +{ return; }
>> +void tegra124_emc_set_ceiling(unsigned long freq)
>> +{ return; }
>> +#endif
>> >>>
>> >>>I'll repeat what I said off-list so that we can have the whole
>> >>>conversation on the list:
>> >>>
>> >>>That looks like a custom Tegra-specific API. I think it'd be much better
>> >>>to integrate this into the common clock framework as a standard clock
>> >>>constraints API. There are other use-cases for clock constraints besides
>> >>>EMC scaling (e.g. some in audio on Tegra, and I'm sure many on other
>> >>>SoCs too).
>> >>
>> >>Yes, I wrote a bit in the cover letter about our requirements and how
>> >>they map to the CCF. Could you please comment on that?
>> >
>> >My comments remain the same. I believe this is something that belongs in
>> >the clock driver, or at the least, some API that takes a struct clock as
>> >its parameter, so that drivers can use the existing DT clock lookup
>> >mechanism.
>>
>> Ok, let me put this strawman here to see if I have gotten close to what you
>> have in mind:
>>
>> * add per-client accounting (Rabin's patches referenced before)
>>
>> * add clk_set_floor, to be used by cpufreq, load stats, etc.
>>
>> * add clk_set_ceiling, to be used by battery drivers, thermal, etc.
>>
>> * an EMC driver would collect bandwidth and latency requests from consumers
>> and call clk_set_floor on the EMC clock.
>>
>> * the EMC driver would also register for rate change notifications in the
>> EMC clock and would update the latency allowance registers at that point.
>
> Latency allowance registers are part of the MC rather than the EMC. So I
> think we have two options: a) have a unified driver for MC and EMC or b)
> provide two parts of the API in two drivers.
>
> Or perhaps c), create a generic framework that both MC and EMC can
> register with (bandwidth for EMC, latency for MC).

Is there any motivation for keeping MC and EMC separate? In my mind,
the solution was always to handle those together.

St?phane


[PATCH] drm/tegra: add MODULE_DEVICE_TABLEs

2014-06-18 Thread Stephen Warren
From: Stephen Warren 

When tegra-drm.ko is built as a module, these MODULE_DEVICE_TABLEs allow
the module to be auto-loaded since the module will match the devices
instantiated from device tree.

(Notes for stable: in 3.14+, just git rm any conflicting file, since they
are added in later kernels. For 3.13 and below, manual merging will be
needed)

Cc: 
Signed-off-by: Stephen Warren 
---
 drivers/gpu/drm/tegra/dc.c| 1 +
 drivers/gpu/drm/tegra/dpaux.c | 1 +
 drivers/gpu/drm/tegra/drm.c   | 1 +
 drivers/gpu/drm/tegra/dsi.c   | 1 +
 drivers/gpu/drm/tegra/gr2d.c  | 1 +
 drivers/gpu/drm/tegra/gr3d.c  | 1 +
 drivers/gpu/drm/tegra/hdmi.c  | 1 +
 drivers/gpu/drm/tegra/sor.c   | 1 +
 8 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ef40381f3909..48c3bc460eef 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1303,6 +1303,7 @@ static const struct of_device_id tegra_dc_of_match[] = {
/* sentinel */
}
 };
+MODULE_DEVICE_TABLE(of, tegra_dc_of_match);

 static int tegra_dc_parse_dt(struct tegra_dc *dc)
 {
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 3f132e356e9c..708f783ead47 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -382,6 +382,7 @@ static const struct of_device_id tegra_dpaux_of_match[] = {
{ .compatible = "nvidia,tegra124-dpaux", },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);

 struct platform_driver tegra_dpaux_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 3396f9f6a9f7..a1f9b06a75d5 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -694,6 +694,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra124-hdmi", },
{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, host1x_drm_subdevs);

 static struct host1x_driver host1x_drm_driver = {
.name = "drm",
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index bd56f2affa78..97c409f10456 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -982,6 +982,7 @@ static const struct of_device_id tegra_dsi_of_match[] = {
{ .compatible = "nvidia,tegra114-dsi", },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);

 struct platform_driver tegra_dsi_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index 7c53941f2a9e..02cd3e37a6ec 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -121,6 +121,7 @@ static const struct of_device_id gr2d_match[] = {
{ .compatible = "nvidia,tegra20-gr2d" },
{ },
 };
+MODULE_DEVICE_TABLE(of, gr2d_match);

 static const u32 gr2d_addr_regs[] = {
GR2D_UA_BASE_ADDR,
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index 30f5ba9bd6d0..2bea2b2d204e 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -130,6 +130,7 @@ static const struct of_device_id tegra_gr3d_match[] = {
{ .compatible = "nvidia,tegra20-gr3d" },
{ }
 };
+MODULE_DEVICE_TABLE(of, tegra_gr3d_match);

 static const u32 gr3d_addr_regs[] = {
GR3D_IDX_ATTRIBUTE( 0),
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index ba067bb767e3..ffe26547328d 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -1450,6 +1450,7 @@ static const struct of_device_id tegra_hdmi_of_match[] = {
{ .compatible = "nvidia,tegra20-hdmi", .data = _hdmi_config },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match);

 static int tegra_hdmi_probe(struct platform_device *pdev)
 {
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 27c979b50111..061a5c501124 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -1455,6 +1455,7 @@ static const struct of_device_id tegra_sor_of_match[] = {
{ .compatible = "nvidia,tegra124-sor", },
{ },
 };
+MODULE_DEVICE_TABLE(of, tegra_sor_of_match);

 struct platform_driver tegra_sor_driver = {
.driver = {
-- 
1.8.1.5



[Bug 78221] 3.16 RC1: AMD R9 270 GPU locks up on some heavy 2D activity - GPU VM fault occurs. (possibly DMA copying issue strikes back?)

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=78221

Alex Deucher  changed:

   What|Removed |Added

 CC||alexdeucher at gmail.com

--- Comment #2 from Alex Deucher  ---
This is more likely a bug in the mesa 3D driver than a kernel bug.  The 3D
driver is used for both 2D and 3D acceleration.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 74751] resume from suspend broken with 3.15-rc1 and rc2 kernels

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=74751

Daniel Vetter  changed:

   What|Removed |Added

 Status|NEEDINFO|RESOLVED
 Resolution|--- |CODE_FIX

--- Comment #27 from Daniel Vetter  ---
Patch is merged upstream, thanks for the report and testing.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[PATCH 1/2] Revert "drm/radeon: remove drm_vblank_get|put from pflip handling"

2014-06-18 Thread Michel Dänzer
On 17.06.2014 20:41, Christian K?nig wrote:
> Am 17.06.2014 12:12, schrieb Michel D?nzer:
>> From: Michel D?nzer 
>>
>> This reverts commit 75f36d861957cb05b7889af24c8cd4a789398304.
>>
>> drm_vblank_get() is necessary to ensure the DRM vblank counter value is
>> up to date in drm_send_vblank_event().
>>
>> Seems to fix weston hangs waiting for page flips to complete.
>>
>> Signed-off-by: Michel D?nzer 
> 
> Both patches are: Reviewed-by: Christian K?nig 

Thank you.


Looking into these issues has got me thinking about the use of the page
flip interrupt: If the page flip interrupt arrives before the corresponding
vertical blank interrupt, the DRM vblank counter will be lower than
expected by 1 in drm_send_vblank_event(). I suspect this is the cause of

 (WW) RADEON(0): radeon_dri2_flip_event_handler: Pageflip completion event has 
impossible msc [x-1] < target_msc [x]

messages in the X log file which have been popping up in bug reports lately.
This also results in 0s being returned to the client for the MSC and
timestamp of the swap completion, which could cause all kinds of bad
behaviour.

The easy way to avoid that would be to stop using the page flip interrupt
for this again. Could there be another solution for the issues you
addressed by using it?


If not, another issue I encountered in 3.15 is that
radeon_crtc_handle_flip() is called unconditionally when a page flip
interrupt arrives. If the flip was already handled (presumably from the
vertical blank interrupt), the BUG_ON() in drm_vblank_put() triggers a
panic. This happened to me with weston.

This is presumably not an issue in 3.16 because radeon_crtc_handle_flip()
now bails early if radeon_crtc->flip_work == NULL.


-- 
Earthling Michel D?nzer|  http://www.amd.com
Libre software enthusiast  |Mesa and X developer


[PATCH] drm: fix NULL pointer access by wrong ioctl

2014-06-18 Thread Zhaowei Yuan
If user uses wrong ioctl command with _IOC_NONE and argument size
greater than 0, it can cause NULL pointer access from memset of line
463. If _IOC_NONE, don't memset to 0 for kdata.

Signed-off-by: Zhaowei Yuan 
---
 drivers/gpu/drm/drm_drv.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 drivers/gpu/drm/drm_drv.c

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
old mode 100644
new mode 100755
index 2ab782c..1a92bcb
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -459,8 +459,9 @@ long drm_ioctl(struct file *filp,
retcode = -EFAULT;
goto err_i1;
}
-   } else
+   } else if (cmd & IOC_OUT) {
memset(kdata, 0, usize);
+   }

if (ioctl->flags & DRM_UNLOCKED)
retcode = func(dev, kdata, file_priv);
--
1.7.9.5



[PATCH] drm: fix NULL pointer access by wrong ioctl

2014-06-18 Thread y...@samsung.com
From: Zhaowei Yuan 

If user uses wrong ioctl command with _IOC_NONE and argument size
greater than 0, it can cause NULL pointer access from memset of line
463. If _IOC_NONE, don't memset to 0 for kdata.

Signed-off-by: Zhaowei Yuan 
---
 drivers/gpu/drm/drm_drv.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 drivers/gpu/drm/drm_drv.c

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
old mode 100644
new mode 100755
index 2ab782c..1a92bcb
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -459,8 +459,9 @@ long drm_ioctl(struct file *filp,
retcode = -EFAULT;
goto err_i1;
}
-   } else
+   } else if (cmd & IOC_OUT) {
memset(kdata, 0, usize);
+   }

if (ioctl->flags & DRM_UNLOCKED)
retcode = func(dev, kdata, file_priv);
--
1.7.9.5



[PATCH 1/1] drm/exynos: Fix de-registration ordering

2014-06-18 Thread Inki Dae
On 2014? 06? 17? 20:38, Sachin Kamat wrote:
> 'exynos_drm_pdev' was not getting unregistered if platform_driver_register()
> failed. Fix the ordering to allow this. This also fixes the below warning by
> moving the #endif macro. While at it also fix the ordering in the exit 
> function
> so that de-registration happens in opposite order of registration.
> drivers/gpu/drm/exynos/exynos_drm_drv.c:768:1: warning: label 
> ?err_unregister_pd? defined but not used [-Wunused-label]

Above line doesn't conform to UTF-8 so I just fixed it. :)
Applied.

Thanks,
Inki Dae

> Signed-off-by: Sachin Kamat 
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c |8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
> b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 5d225dd5..f72ca0c 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -765,24 +765,24 @@ static int exynos_drm_init(void)
>  
>   return 0;
>  
> -err_unregister_pd:
> - platform_device_unregister(exynos_drm_pdev);
> -
>  err_remove_vidi:
>  #ifdef CONFIG_DRM_EXYNOS_VIDI
>   exynos_drm_remove_vidi();
> +
> +err_unregister_pd:
>  #endif
> + platform_device_unregister(exynos_drm_pdev);
>  
>   return ret;
>  }
>  
>  static void exynos_drm_exit(void)
>  {
> + platform_driver_unregister(_drm_platform_driver);
>  #ifdef CONFIG_DRM_EXYNOS_VIDI
>   exynos_drm_remove_vidi();
>  #endif
>   platform_device_unregister(exynos_drm_pdev);
> - platform_driver_unregister(_drm_platform_driver);
>  }
>  
>  module_init(exynos_drm_init);
> 



[PATCH] drm: fix uninitialized acquire_ctx fields (v2)

2014-06-18 Thread Ville Syrjälä
On Sat, Jun 07, 2014 at 10:55:39AM -0400, Rob Clark wrote:
> The acquire ctx will typically be declared on the stack, which means we
> could have garbage values for any uninitialized field.  In this case, it
> was triggering WARN_ON()s because 'contended' had garbage value.
> 
> Go ahead and use memset() to be more future-proof.
> 
> v2: now with extra brown paper bag
> 
> Reported-by: Ville Syrj?l? 
> Signed-off-by: Rob Clark 

I thought I already gave these. Well here they are again:
Reviewed-by: Ville Syrj?l? 
Tested-by: Ville Syrj?l? 

> ---
>  drivers/gpu/drm/drm_modeset_lock.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/drm_modeset_lock.c 
> b/drivers/gpu/drm/drm_modeset_lock.c
> index 7c2497d..0dc57d5 100644
> --- a/drivers/gpu/drm/drm_modeset_lock.c
> +++ b/drivers/gpu/drm/drm_modeset_lock.c
> @@ -64,6 +64,7 @@
>  void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx,
>   uint32_t flags)
>  {
> + memset(ctx, 0, sizeof(*ctx));
>   ww_acquire_init(>ww_ctx, _ww_class);
>   INIT_LIST_HEAD(>locked);
>  }
> -- 
> 1.9.3

-- 
Ville Syrj?l?
Intel OTC


[PATCH] drm/exynos: dpi: Fix NULL pointer dereference with legacy bindings

2014-06-18 Thread Inki Dae
On 2014? 06? 18? 09:09, Tomasz Figa wrote:
> On 10.06.2014 22:57, Tomasz Figa wrote:
>> If there is no panel node in DT and instead display timings are provided
>> directly in FIMD node, there is no panel object created and ctx->panel
>> becomes NULL. However during Exynos DRM initialization
>> drm_helper_hpd_irq_event() is called, which in turns calls
>> exynos_dpi_detect(), which dereferences ctx->panel without a check,
>> causing a NULL pointer derefrence.
>>
>> This patch fixes the issue by adding necessary NULL pointer check.
>>
>> Signed-off-by: Tomasz Figa 
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_dpi.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c 
>> b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
>> index f1b8587..f44bd90 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
>> @@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool 
>> force)
>>  {
>>  struct exynos_dpi *ctx = connector_to_dpi(connector);
>>  
>> -if (!ctx->panel->connector)
>> +if (ctx->panel && !ctx->panel->connector)
>>  drm_panel_attach(ctx->panel, >connector);
>>  
>>  return connector_status_connected;
>>
> 
> Ping.

Applied.

Thanks,
Inki Dae

> 
> Best regards,
> Tomasz
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
> in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



[REPOST PATCH 8/8] reservation: add suppport for read-only access using rcu

2014-06-18 Thread Maarten Lankhorst
This adds 4 more functions to deal with rcu.

reservation_object_get_fences_rcu() will obtain the list of shared
and exclusive fences without obtaining the ww_mutex.

reservation_object_wait_timeout_rcu() will wait on all fences of the
reservation_object, without obtaining the ww_mutex.

reservation_object_test_signaled_rcu() will test if all fences of the
reservation_object are signaled without using the ww_mutex.

reservation_object_get_excl() is added because touching the fence_excl
member directly will trigger a sparse warning.

Signed-off-by: Maarten Lankhorst 
Reviewed-By: Thomas Hellstrom 
---
 drivers/base/dma-buf.c  |   47 +-
 drivers/base/reservation.c  |  336 ---
 include/linux/fence.h   |   20 ++-
 include/linux/reservation.h |   52 +--
 4 files changed, 400 insertions(+), 55 deletions(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index cb8379dfeed5..f3014c448e1e 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -137,7 +137,7 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
struct reservation_object_list *fobj;
struct fence *fence_excl;
unsigned long events;
-   unsigned shared_count;
+   unsigned shared_count, seq;

dmabuf = file->private_data;
if (!dmabuf || !dmabuf->resv)
@@ -151,14 +151,20 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
if (!events)
return 0;

-   ww_mutex_lock(>lock, NULL);
+retry:
+   seq = read_seqcount_begin(>seq);
+   rcu_read_lock();

-   fobj = resv->fence;
-   if (!fobj)
-   goto out;
-
-   shared_count = fobj->shared_count;
-   fence_excl = resv->fence_excl;
+   fobj = rcu_dereference(resv->fence);
+   if (fobj)
+   shared_count = fobj->shared_count;
+   else
+   shared_count = 0;
+   fence_excl = rcu_dereference(resv->fence_excl);
+   if (read_seqcount_retry(>seq, seq)) {
+   rcu_read_unlock();
+   goto retry;
+   }

if (fence_excl && (!(events & POLLOUT) || shared_count == 0)) {
struct dma_buf_poll_cb_t *dcb = >cb_excl;
@@ -176,14 +182,20 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
spin_unlock_irq(>poll.lock);

if (events & pevents) {
-   if (!fence_add_callback(fence_excl, >cb,
+   if (!fence_get_rcu(fence_excl)) {
+   /* force a recheck */
+   events &= ~pevents;
+   dma_buf_poll_cb(NULL, >cb);
+   } else if (!fence_add_callback(fence_excl, >cb,
   dma_buf_poll_cb)) {
events &= ~pevents;
+   fence_put(fence_excl);
} else {
/*
 * No callback queued, wake up any additional
 * waiters.
 */
+   fence_put(fence_excl);
dma_buf_poll_cb(NULL, >cb);
}
}
@@ -205,13 +217,26 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
goto out;

for (i = 0; i < shared_count; ++i) {
-   struct fence *fence = fobj->shared[i];
+   struct fence *fence = rcu_dereference(fobj->shared[i]);

+   if (!fence_get_rcu(fence)) {
+   /*
+* fence refcount dropped to zero, this means
+* that fobj has been freed
+*
+* call dma_buf_poll_cb and force a recheck!
+*/
+   events &= ~POLLOUT;
+   dma_buf_poll_cb(NULL, >cb);
+   break;
+   }
if (!fence_add_callback(fence, >cb,
dma_buf_poll_cb)) {
+   fence_put(fence);
events &= ~POLLOUT;
break;
}
+   fence_put(fence);
}

/* No callback queued, wake up any additional waiters. */
@@ -220,7 +245,7 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
}

 out:
-   ww_mutex_unlock(>lock);
+   rcu_read_unlock();
return events;
 }

diff --git a/drivers/base/reservation.c b/drivers/base/reservation.c
index e6166723a9ae..3c97c8fa8d02 100644
--- a/drivers/base/reservation.c

[REPOST PATCH 7/8] reservation: update api and add some helpers

2014-06-18 Thread Maarten Lankhorst
Move the list of shared fences to a struct, and return it in
reservation_object_get_list().
Add reservation_object_get_excl to get the exclusive fence.

Add reservation_object_reserve_shared(), which reserves space
in the reservation_object for 1 more shared fence.

reservation_object_add_shared_fence() and
reservation_object_add_excl_fence() are used to assign a new
fence to a reservation_object pointer, to complete a reservation.

Signed-off-by: Maarten Lankhorst 

Changes since v1:
- Add reservation_object_get_excl, reorder code a bit.
---
 drivers/base/dma-buf.c  |   35 +++---
 drivers/base/fence.c|4 +
 drivers/base/reservation.c  |  156 +++
 include/linux/fence.h   |6 ++
 include/linux/reservation.h |   56 ++-
 5 files changed, 236 insertions(+), 21 deletions(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 25e8c4165936..cb8379dfeed5 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -134,7 +134,10 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
 {
struct dma_buf *dmabuf;
struct reservation_object *resv;
+   struct reservation_object_list *fobj;
+   struct fence *fence_excl;
unsigned long events;
+   unsigned shared_count;

dmabuf = file->private_data;
if (!dmabuf || !dmabuf->resv)
@@ -150,12 +153,18 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)

ww_mutex_lock(>lock, NULL);

-   if (resv->fence_excl && (!(events & POLLOUT) ||
-resv->fence_shared_count == 0)) {
+   fobj = resv->fence;
+   if (!fobj)
+   goto out;
+
+   shared_count = fobj->shared_count;
+   fence_excl = resv->fence_excl;
+
+   if (fence_excl && (!(events & POLLOUT) || shared_count == 0)) {
struct dma_buf_poll_cb_t *dcb = >cb_excl;
unsigned long pevents = POLLIN;

-   if (resv->fence_shared_count == 0)
+   if (shared_count == 0)
pevents |= POLLOUT;

spin_lock_irq(>poll.lock);
@@ -167,19 +176,20 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
spin_unlock_irq(>poll.lock);

if (events & pevents) {
-   if (!fence_add_callback(resv->fence_excl,
-   >cb, dma_buf_poll_cb))
+   if (!fence_add_callback(fence_excl, >cb,
+  dma_buf_poll_cb)) {
events &= ~pevents;
-   else
+   } else {
/*
 * No callback queued, wake up any additional
 * waiters.
 */
dma_buf_poll_cb(NULL, >cb);
+   }
}
}

-   if ((events & POLLOUT) && resv->fence_shared_count > 0) {
+   if ((events & POLLOUT) && shared_count > 0) {
struct dma_buf_poll_cb_t *dcb = >cb_shared;
int i;

@@ -194,15 +204,18 @@ static unsigned int dma_buf_poll(struct file *file, 
poll_table *poll)
if (!(events & POLLOUT))
goto out;

-   for (i = 0; i < resv->fence_shared_count; ++i)
-   if (!fence_add_callback(resv->fence_shared[i],
-   >cb, dma_buf_poll_cb)) {
+   for (i = 0; i < shared_count; ++i) {
+   struct fence *fence = fobj->shared[i];
+
+   if (!fence_add_callback(fence, >cb,
+   dma_buf_poll_cb)) {
events &= ~POLLOUT;
break;
}
+   }

/* No callback queued, wake up any additional waiters. */
-   if (i == resv->fence_shared_count)
+   if (i == shared_count)
dma_buf_poll_cb(NULL, >cb);
}

diff --git a/drivers/base/fence.c b/drivers/base/fence.c
index 752a2dfa505f..74d1f7bcb467 100644
--- a/drivers/base/fence.c
+++ b/drivers/base/fence.c
@@ -170,7 +170,7 @@ void release_fence(struct kref *kref)
if (fence->ops->release)
fence->ops->release(fence);
else
-   kfree(fence);
+   free_fence(fence);
 }
 EXPORT_SYMBOL(release_fence);

@@ -448,7 +448,7 @@ static void seqno_release(struct fence *fence)
if (f->ops->release)
f->ops->release(fence);
else
-   kfree(f);
+   free_fence(fence);
 }

 static long seqno_wait(struct fence *fence, bool intr, signed long timeout)
diff --git a/drivers/base/reservation.c b/drivers/base/reservation.c

[REPOST PATCH 6/8] dma-buf: add poll support, v3

2014-06-18 Thread Maarten Lankhorst
Thanks to Fengguang Wu for spotting a missing static cast.

v2:
- Kill unused variable need_shared.
v3:
- Clarify the BUG() in dma_buf_release some more. (Rob Clark)

Signed-off-by: Maarten Lankhorst 
---
 drivers/base/dma-buf.c  |  108 +++
 include/linux/dma-buf.h |   12 +
 2 files changed, 120 insertions(+)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index cd40ca22911f..25e8c4165936 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 

 static inline int is_dma_buf_file(struct file *);
@@ -52,6 +53,16 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)

BUG_ON(dmabuf->vmapping_counter);

+   /*
+* Any fences that a dma-buf poll can wait on should be signaled
+* before releasing dma-buf. This is the responsibility of each
+* driver that uses the reservation objects.
+*
+* If you hit this BUG() it means someone dropped their ref to the
+* dma-buf while still having pending operation to the buffer.
+*/
+   BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
+
dmabuf->ops->release(dmabuf);

mutex_lock(_list.lock);
@@ -108,10 +119,103 @@ static loff_t dma_buf_llseek(struct file *file, loff_t 
offset, int whence)
return base + offset;
 }

+static void dma_buf_poll_cb(struct fence *fence, struct fence_cb *cb)
+{
+   struct dma_buf_poll_cb_t *dcb = (struct dma_buf_poll_cb_t *)cb;
+   unsigned long flags;
+
+   spin_lock_irqsave(>poll->lock, flags);
+   wake_up_locked_poll(dcb->poll, dcb->active);
+   dcb->active = 0;
+   spin_unlock_irqrestore(>poll->lock, flags);
+}
+
+static unsigned int dma_buf_poll(struct file *file, poll_table *poll)
+{
+   struct dma_buf *dmabuf;
+   struct reservation_object *resv;
+   unsigned long events;
+
+   dmabuf = file->private_data;
+   if (!dmabuf || !dmabuf->resv)
+   return POLLERR;
+
+   resv = dmabuf->resv;
+
+   poll_wait(file, >poll, poll);
+
+   events = poll_requested_events(poll) & (POLLIN | POLLOUT);
+   if (!events)
+   return 0;
+
+   ww_mutex_lock(>lock, NULL);
+
+   if (resv->fence_excl && (!(events & POLLOUT) ||
+resv->fence_shared_count == 0)) {
+   struct dma_buf_poll_cb_t *dcb = >cb_excl;
+   unsigned long pevents = POLLIN;
+
+   if (resv->fence_shared_count == 0)
+   pevents |= POLLOUT;
+
+   spin_lock_irq(>poll.lock);
+   if (dcb->active) {
+   dcb->active |= pevents;
+   events &= ~pevents;
+   } else
+   dcb->active = pevents;
+   spin_unlock_irq(>poll.lock);
+
+   if (events & pevents) {
+   if (!fence_add_callback(resv->fence_excl,
+   >cb, dma_buf_poll_cb))
+   events &= ~pevents;
+   else
+   /*
+* No callback queued, wake up any additional
+* waiters.
+*/
+   dma_buf_poll_cb(NULL, >cb);
+   }
+   }
+
+   if ((events & POLLOUT) && resv->fence_shared_count > 0) {
+   struct dma_buf_poll_cb_t *dcb = >cb_shared;
+   int i;
+
+   /* Only queue a new callback if no event has fired yet */
+   spin_lock_irq(>poll.lock);
+   if (dcb->active)
+   events &= ~POLLOUT;
+   else
+   dcb->active = POLLOUT;
+   spin_unlock_irq(>poll.lock);
+
+   if (!(events & POLLOUT))
+   goto out;
+
+   for (i = 0; i < resv->fence_shared_count; ++i)
+   if (!fence_add_callback(resv->fence_shared[i],
+   >cb, dma_buf_poll_cb)) {
+   events &= ~POLLOUT;
+   break;
+   }
+
+   /* No callback queued, wake up any additional waiters. */
+   if (i == resv->fence_shared_count)
+   dma_buf_poll_cb(NULL, >cb);
+   }
+
+out:
+   ww_mutex_unlock(>lock);
+   return events;
+}
+
 static const struct file_operations dma_buf_fops = {
.release= dma_buf_release,
.mmap   = dma_buf_mmap_internal,
.llseek = dma_buf_llseek,
+   .poll   = dma_buf_poll,
 };

 /*
@@ -171,6 +275,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
dmabuf->ops = ops;
dmabuf->size = size;
dmabuf->exp_name = 

[REPOST PATCH 5/8] reservation: add support for fences to enable cross-device synchronisation

2014-06-18 Thread Maarten Lankhorst
Signed-off-by: Maarten Lankhorst 
Reviewed-by: Rob Clark 
---
 include/linux/reservation.h |   20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/include/linux/reservation.h b/include/linux/reservation.h
index 813dae960ebd..f3f57460a205 100644
--- a/include/linux/reservation.h
+++ b/include/linux/reservation.h
@@ -6,7 +6,7 @@
  * Copyright (C) 2012 Texas Instruments
  *
  * Authors:
- * Rob Clark 
+ * Rob Clark 
  * Maarten Lankhorst 
  * Thomas Hellstrom 
  *
@@ -40,22 +40,40 @@
 #define _LINUX_RESERVATION_H

 #include 
+#include 
+#include 

 extern struct ww_class reservation_ww_class;

 struct reservation_object {
struct ww_mutex lock;
+
+   struct fence *fence_excl;
+   struct fence **fence_shared;
+   u32 fence_shared_count, fence_shared_max;
 };

 static inline void
 reservation_object_init(struct reservation_object *obj)
 {
ww_mutex_init(>lock, _ww_class);
+
+   obj->fence_shared_count = obj->fence_shared_max = 0;
+   obj->fence_shared = NULL;
+   obj->fence_excl = NULL;
 }

 static inline void
 reservation_object_fini(struct reservation_object *obj)
 {
+   int i;
+
+   if (obj->fence_excl)
+   fence_put(obj->fence_excl);
+   for (i = 0; i < obj->fence_shared_count; ++i)
+   fence_put(obj->fence_shared[i]);
+   kfree(obj->fence_shared);
+
ww_mutex_destroy(>lock);
 }




[REPOST PATCH 4/8] android: convert sync to fence api, v5

2014-06-18 Thread Maarten Lankhorst
Just to show it's easy.

Android syncpoints can be mapped to a timeline. This removes the need
to maintain a separate api for synchronization. I've left the android
trace events in place, but the core fence events should already be
sufficient for debugging.

v2:
- Call fence_remove_callback in sync_fence_free if not all fences have fired.
v3:
- Merge Colin Cross' bugfixes, and the android fence merge optimization.
v4:
- Merge with the upstream fixes.
v5:
- Fix small style issues pointed out by Thomas Hellstrom.

Signed-off-by: Maarten Lankhorst 
Acked-by: John Stultz 
---
 drivers/staging/android/Kconfig  |1 
 drivers/staging/android/Makefile |2 
 drivers/staging/android/sw_sync.c|6 
 drivers/staging/android/sync.c   |  913 +++---
 drivers/staging/android/sync.h   |   79 ++-
 drivers/staging/android/sync_debug.c |  247 +
 drivers/staging/android/trace/sync.h |   12 
 7 files changed, 609 insertions(+), 651 deletions(-)
 create mode 100644 drivers/staging/android/sync_debug.c

diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 99e484f845f2..51607e9aa049 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -88,6 +88,7 @@ config SYNC
bool "Synchronization framework"
default n
select ANON_INODES
+   select DMA_SHARED_BUFFER
---help---
  This option enables the framework for synchronization between multiple
  drivers.  Sync implementations can take advantage of hardware
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 0a01e1914905..517ad5ffa429 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -9,5 +9,5 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT)  += timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)   += timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)+= lowmemorykiller.o
 obj-$(CONFIG_ANDROID_INTF_ALARM_DEV)   += alarm-dev.o
-obj-$(CONFIG_SYNC) += sync.o
+obj-$(CONFIG_SYNC) += sync.o sync_debug.o
 obj-$(CONFIG_SW_SYNC)  += sw_sync.o
diff --git a/drivers/staging/android/sw_sync.c 
b/drivers/staging/android/sw_sync.c
index 12a136ec1cec..a76db3ff87cb 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/staging/android/sw_sync.c
@@ -50,7 +50,7 @@ static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt)
 {
struct sw_sync_pt *pt = (struct sw_sync_pt *) sync_pt;
struct sw_sync_timeline *obj =
-   (struct sw_sync_timeline *)sync_pt->parent;
+   (struct sw_sync_timeline *)sync_pt_parent(sync_pt);

return (struct sync_pt *) sw_sync_pt_create(obj, pt->value);
 }
@@ -59,7 +59,7 @@ static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt)
 {
struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
struct sw_sync_timeline *obj =
-   (struct sw_sync_timeline *)sync_pt->parent;
+   (struct sw_sync_timeline *)sync_pt_parent(sync_pt);

return sw_sync_cmp(obj->value, pt->value) >= 0;
 }
@@ -97,7 +97,6 @@ static void sw_sync_pt_value_str(struct sync_pt *sync_pt,
   char *str, int size)
 {
struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
-
snprintf(str, size, "%d", pt->value);
 }

@@ -157,7 +156,6 @@ static int sw_sync_open(struct inode *inode, struct file 
*file)
 static int sw_sync_release(struct inode *inode, struct file *file)
 {
struct sw_sync_timeline *obj = file->private_data;
-
sync_timeline_destroy(>obj);
return 0;
 }
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 18174f7c871c..70b09b5001ba 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -31,22 +31,13 @@
 #define CREATE_TRACE_POINTS
 #include "trace/sync.h"

-static void sync_fence_signal_pt(struct sync_pt *pt);
-static int _sync_pt_has_signaled(struct sync_pt *pt);
-static void sync_fence_free(struct kref *kref);
-static void sync_dump(void);
-
-static LIST_HEAD(sync_timeline_list_head);
-static DEFINE_SPINLOCK(sync_timeline_list_lock);
-
-static LIST_HEAD(sync_fence_list_head);
-static DEFINE_SPINLOCK(sync_fence_list_lock);
+static const struct fence_ops android_fence_ops;
+static const struct file_operations sync_fence_fops;

 struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
   int size, const char *name)
 {
struct sync_timeline *obj;
-   unsigned long flags;

if (size < sizeof(struct sync_timeline))
return NULL;
@@ -57,17 +48,14 @@ struct sync_timeline *sync_timeline_create(const struct 
sync_timeline_ops *ops,

kref_init(>kref);
obj->ops = ops;
+   obj->context = fence_context_alloc(1);
strlcpy(obj->name, name, sizeof(obj->name));


[REPOST PATCH 3/8] dma-buf: use reservation objects

2014-06-18 Thread Maarten Lankhorst
This allows reservation objects to be used in dma-buf. it's required
for implementing polling support on the fences that belong to a dma-buf.

Signed-off-by: Maarten Lankhorst 
Acked-by: Mauro Carvalho Chehab  
#drivers/media/v4l2-core/
Acked-by: Thomas Hellstrom  #drivers/gpu/drm/ttm
Signed-off-by: Vincent Stehl?  
#drivers/gpu/drm/armada/
---
 drivers/base/dma-buf.c |   22 --
 drivers/gpu/drm/armada/armada_gem.c|2 +-
 drivers/gpu/drm/drm_prime.c|8 +++-
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c |2 +-
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |3 ++-
 drivers/gpu/drm/nouveau/nouveau_drm.c  |1 +
 drivers/gpu/drm/nouveau/nouveau_gem.h  |1 +
 drivers/gpu/drm/nouveau/nouveau_prime.c|7 +++
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c  |2 +-
 drivers/gpu/drm/radeon/radeon_drv.c|2 ++
 drivers/gpu/drm/radeon/radeon_prime.c  |8 
 drivers/gpu/drm/tegra/gem.c|2 +-
 drivers/gpu/drm/ttm/ttm_object.c   |2 +-
 drivers/media/v4l2-core/videobuf2-dma-contig.c |2 +-
 drivers/staging/android/ion/ion.c  |3 ++-
 include/drm/drmP.h |3 +++
 include/linux/dma-buf.h|9 ++---
 17 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 840c7fa80983..cd40ca22911f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -25,10 +25,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 

 static inline int is_dma_buf_file(struct file *);

@@ -56,6 +58,9 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
list_del(>list_node);
mutex_unlock(_list.lock);

+   if (dmabuf->resv == (struct reservation_object *)[1])
+   reservation_object_fini(dmabuf->resv);
+
kfree(dmabuf);
return 0;
 }
@@ -128,6 +133,7 @@ static inline int is_dma_buf_file(struct file *file)
  * @size:  [in]Size of the buffer
  * @flags: [in]mode flags for the file.
  * @exp_name:  [in]name of the exporting module - useful for debugging.
+ * @resv:  [in]reservation-object, NULL to allocate default one.
  *
  * Returns, on success, a newly created dma_buf object, which wraps the
  * supplied private data and operations for dma_buf_ops. On either missing
@@ -135,10 +141,17 @@ static inline int is_dma_buf_file(struct file *file)
  *
  */
 struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
-   size_t size, int flags, const char *exp_name)
+   size_t size, int flags, const char *exp_name,
+   struct reservation_object *resv)
 {
struct dma_buf *dmabuf;
struct file *file;
+   size_t alloc_size = sizeof(struct dma_buf);
+   if (!resv)
+   alloc_size += sizeof(struct reservation_object);
+   else
+   /* prevent _buf[1] == dma_buf->resv */
+   alloc_size += 1;

if (WARN_ON(!priv || !ops
  || !ops->map_dma_buf
@@ -150,7 +163,7 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
return ERR_PTR(-EINVAL);
}

-   dmabuf = kzalloc(sizeof(struct dma_buf), GFP_KERNEL);
+   dmabuf = kzalloc(alloc_size, GFP_KERNEL);
if (dmabuf == NULL)
return ERR_PTR(-ENOMEM);

@@ -158,6 +171,11 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
dmabuf->ops = ops;
dmabuf->size = size;
dmabuf->exp_name = exp_name;
+   if (!resv) {
+   resv = (struct reservation_object *)[1];
+   reservation_object_init(resv);
+   }
+   dmabuf->resv = resv;

file = anon_inode_getfile("dmabuf", _buf_fops, dmabuf, flags);
if (IS_ERR(file)) {
diff --git a/drivers/gpu/drm/armada/armada_gem.c 
b/drivers/gpu/drm/armada/armada_gem.c
index bb9b642d8485..7496f55611a5 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -539,7 +539,7 @@ armada_gem_prime_export(struct drm_device *dev, struct 
drm_gem_object *obj,
int flags)
 {
return dma_buf_export(obj, _gem_prime_dmabuf_ops, obj->size,
- O_RDWR);
+ O_RDWR, NULL);
 }

 struct drm_gem_object *
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 304ca8cacbc4..99d578bad17e 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -336,7 +336,13 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = 
 {
 struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
 struct 

[REPOST PATCH 2/8] seqno-fence: Hardware dma-buf implementation of fencing (v5)

2014-06-18 Thread Maarten Lankhorst
This type of fence can be used with hardware synchronization for simple
hardware that can block execution until the condition
(dma_buf[offset] - value) >= 0 has been met when WAIT_GEQUAL is used,
or (dma_buf[offset] != 0) has been met when WAIT_NONZERO is set.

A software fallback still has to be provided in case the fence is used
with a device that doesn't support this mechanism. It is useful to expose
this for graphics cards that have an op to support this.

Some cards like i915 can export those, but don't have an option to wait,
so they need the software fallback.

I extended the original patch by Rob Clark.

v1: Original
v2: Renamed from bikeshed to seqno, moved into dma-fence.c since
not much was left of the file. Lots of documentation added.
v3: Use fence_ops instead of custom callbacks. Moved to own file
to avoid circular dependency between dma-buf.h and fence.h
v4: Add spinlock pointer to seqno_fence_init
v5: Add condition member to allow wait for != 0.
Fix small style errors pointed out by checkpatch.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Rob Clark  #v4
---
 Documentation/DocBook/device-drivers.tmpl |1 
 drivers/base/fence.c  |   52 +
 include/linux/seqno-fence.h   |  119 +
 3 files changed, 172 insertions(+)
 create mode 100644 include/linux/seqno-fence.h

diff --git a/Documentation/DocBook/device-drivers.tmpl 
b/Documentation/DocBook/device-drivers.tmpl
index 7eef81069d1b..6ca7a11fb893 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -131,6 +131,7 @@ X!Edrivers/base/interface.c
 !Edrivers/base/dma-buf.c
 !Edrivers/base/fence.c
 !Iinclude/linux/fence.h
+!Iinclude/linux/seqno-fence.h
 !Edrivers/base/reservation.c
 !Iinclude/linux/reservation.h
 !Edrivers/base/dma-coherent.c
diff --git a/drivers/base/fence.c b/drivers/base/fence.c
index 1da7f4d6542a..752a2dfa505f 100644
--- a/drivers/base/fence.c
+++ b/drivers/base/fence.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 

 #define CREATE_TRACE_POINTS
 #include 
@@ -414,3 +415,54 @@ __fence_init(struct fence *fence, const struct fence_ops 
*ops,
trace_fence_init(fence);
 }
 EXPORT_SYMBOL(__fence_init);
+
+static const char *seqno_fence_get_driver_name(struct fence *fence)
+{
+   struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+   return seqno_fence->ops->get_driver_name(fence);
+}
+
+static const char *seqno_fence_get_timeline_name(struct fence *fence)
+{
+   struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+   return seqno_fence->ops->get_timeline_name(fence);
+}
+
+static bool seqno_enable_signaling(struct fence *fence)
+{
+   struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+   return seqno_fence->ops->enable_signaling(fence);
+}
+
+static bool seqno_signaled(struct fence *fence)
+{
+   struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+   return seqno_fence->ops->signaled && seqno_fence->ops->signaled(fence);
+}
+
+static void seqno_release(struct fence *fence)
+{
+   struct seqno_fence *f = to_seqno_fence(fence);
+
+   dma_buf_put(f->sync_buf);
+   if (f->ops->release)
+   f->ops->release(fence);
+   else
+   kfree(f);
+}
+
+static long seqno_wait(struct fence *fence, bool intr, signed long timeout)
+{
+   struct seqno_fence *f = to_seqno_fence(fence);
+   return f->ops->wait(fence, intr, timeout);
+}
+
+const struct fence_ops seqno_fence_ops = {
+   .get_driver_name = seqno_fence_get_driver_name,
+   .get_timeline_name = seqno_fence_get_timeline_name,
+   .enable_signaling = seqno_enable_signaling,
+   .signaled = seqno_signaled,
+   .wait = seqno_wait,
+   .release = seqno_release,
+};
+EXPORT_SYMBOL(seqno_fence_ops);
diff --git a/include/linux/seqno-fence.h b/include/linux/seqno-fence.h
new file mode 100644
index ..b4d4aad3cadc
--- /dev/null
+++ b/include/linux/seqno-fence.h
@@ -0,0 +1,119 @@
+/*
+ * seqno-fence, using a dma-buf to synchronize fencing
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Copyright (C) 2012 Canonical Ltd
+ * Authors:
+ * Rob Clark 
+ *   Maarten Lankhorst 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef __LINUX_SEQNO_FENCE_H
+#define __LINUX_SEQNO_FENCE_H
+
+#include 
+#include 
+
+enum seqno_fence_condition {
+   SEQNO_FENCE_WAIT_GEQUAL,

[REPOST PATCH 1/8] fence: dma-buf cross-device synchronization (v17)

2014-06-18 Thread Maarten Lankhorst
A 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 driver must allocate a fence context for each execution ring that can
run in parallel. The function for this takes an argument with how many
contexts to allocate:
  + fence_context_alloc()

A fence is transient, one-shot deal.  It is allocated and attached
to one or more dma-buf's.  When the one that attached it is done, with
the pending operation, it can signal the fence:
  + fence_signal()

To have a rough approximation whether a fence is fired, call:
  + fence_is_signaled()

The dma-buf-mgr handles tracking, and waiting on, the fences associated
with a dma-buf.

The one pending on the fence can add an async callback:
  + fence_add_callback()

The callback can optionally be cancelled with:
  + fence_remove_callback()

To wait synchronously, optionally with a timeout:
  + fence_wait()
  + fence_wait_timeout()

When emitting a fence, call:
  + trace_fence_emit()

To annotate that a fence is blocking on another fence, call:
  + trace_fence_annotate_wait_on(fence, on_fence)

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 = custom_get_fence(...);
  if ((seqno_fence = to_seqno_fence(fence)) != NULL) {
dma_buf *fence_buf = seqno_fence->sync_buf;
get_dma_buf(fence_buf);

... tell the hw the memory location to wait ...
custom_wait_on(fence_buf, seqno_fence->seqno_ofs, fence->seqno);
  } else {
/* fall-back to sw sync * /
fence_add_callback(fence, my_cb);
  }

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.

enable_signaling callback is used to provide sw signaling in case a cpu
waiter is requested or no compatible hardware signaling could be used.

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).

v1: Original
v2: After discussion w/ danvet and mlankhorst on #dri-devel, we decided
that dma-fence didn't need to care about the sw->hw signaling path
(it can be handled same as sw->sw case), and therefore the fence->ops
can be simplified and more handled in the core.  So remove the signal,
add_callback, cancel_callback, and wait ops, and replace with a simple
enable_signaling() op which can be used to inform a fence supporting
hw->hw signaling that one or more devices which do not support hw
signaling are waiting (and therefore it should enable an irq or do
whatever is necessary in order that the CPU is notified when the
fence is passed).
v3: Fix locking fail in attach_fence() and get_fence()
v4: Remove tie-in w/ dma-buf..  after discussion w/ danvet and mlankorst
we decided that we need to be able to attach one fence to N dma-buf's,
so using the list_head in dma-fence struct would be problematic.
v5: [ Maarten Lankhorst ] Updated for dma-bikeshed-fence and dma-buf-manager.
v6: [ Maarten Lankhorst ] I removed dma_fence_cancel_callback and some comments
about checking if fence fired or not. This is broken by design.
waitqueue_active during destruction is now fatal, since the signaller
should be holding a reference in enable_signalling until it signalled
the fence. Pass the original dma_fence_cb along, and call __remove_wait
in the dma_fence_callback handler, so that no cleanup needs to be
performed.
v7: [ Maarten Lankhorst ] Set cb->func and only enable sw signaling if
fence wasn't signaled yet, for example for hardware fences that may
choose to signal blindly.
v8: [ Maarten Lankhorst ] Tons of tiny fixes, moved __dma_fence_init to
header and fixed include mess. dma-fence.h now includes dma-buf.h
All members are now initialized, so kmalloc can be used for
allocating a dma-fence. More documentation added.
v9: Change compiler bitfields to flags, change return type of
enable_signaling to bool. Rework dma_fence_wait. Added
dma_fence_is_signaled and dma_fence_wait_timeout.
s/dma// and change exports to non GPL. Added fence_is_signaled and
fence_enable_sw_signaling calls, add ability to override 

[REPOST PATCH 0/8] fence synchronization patches

2014-06-18 Thread Maarten Lankhorst
The following series implements fence and converts dma-buf and
android sync to use it. Patch 5 and 6 add support for polling
to dma-buf, blocking until all fences are signaled.
Patch 7 and 8 provide some helpers, and allow use of RCU in the
reservation api. The helpers make it easier to convert ttm, and
make dealing with rcu less painful.

Patches slightly updated to fix compilation with armada and
new atomic primitives, but otherwise identical.

---

Maarten Lankhorst (8):
  fence: dma-buf cross-device synchronization (v17)
  seqno-fence: Hardware dma-buf implementation of fencing (v5)
  dma-buf: use reservation objects
  android: convert sync to fence api, v5
  reservation: add support for fences to enable cross-device synchronisation
  dma-buf: add poll support, v3
  reservation: update api and add some helpers
  reservation: add suppport for read-only access using rcu


 Documentation/DocBook/device-drivers.tmpl  |3 
 drivers/base/Kconfig   |9 
 drivers/base/Makefile  |2 
 drivers/base/dma-buf.c |  168 
 drivers/base/fence.c   |  468 
 drivers/base/reservation.c |  440 
 drivers/gpu/drm/armada/armada_gem.c|2 
 drivers/gpu/drm/drm_prime.c|8 
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c |2 
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |3 
 drivers/gpu/drm/nouveau/nouveau_drm.c  |1 
 drivers/gpu/drm/nouveau/nouveau_gem.h  |1 
 drivers/gpu/drm/nouveau/nouveau_prime.c|7 
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c  |2 
 drivers/gpu/drm/radeon/radeon_drv.c|2 
 drivers/gpu/drm/radeon/radeon_prime.c  |8 
 drivers/gpu/drm/tegra/gem.c|2 
 drivers/gpu/drm/ttm/ttm_object.c   |2 
 drivers/media/v4l2-core/videobuf2-dma-contig.c |2 
 drivers/staging/android/Kconfig|1 
 drivers/staging/android/Makefile   |2 
 drivers/staging/android/ion/ion.c  |3 
 drivers/staging/android/sw_sync.c  |6 
 drivers/staging/android/sync.c |  913 
 drivers/staging/android/sync.h |   79 +-
 drivers/staging/android/sync_debug.c   |  247 ++
 drivers/staging/android/trace/sync.h   |   12 
 include/drm/drmP.h |3 
 include/linux/dma-buf.h|   21 -
 include/linux/fence.h  |  355 +
 include/linux/reservation.h|   82 ++
 include/linux/seqno-fence.h|  119 +++
 include/trace/events/fence.h   |  128 +++
 33 files changed, 2435 insertions(+), 668 deletions(-)
 create mode 100644 drivers/base/fence.c
 create mode 100644 drivers/staging/android/sync_debug.c
 create mode 100644 include/linux/fence.h
 create mode 100644 include/linux/seqno-fence.h
 create mode 100644 include/trace/events/fence.h

-- 
Signature


[PATCH 1/4] clk: propagate parent change up one level

2014-06-18 Thread Tomasz Stanislawski
Hi Mike,
Do you have any comments about this patch?
The patch is needed to provide a clean fix for recently
broken support for HDMI on Exynos4210 SoC in mainline.

Regards,
Tomasz Stanislawski


On 05/01/2014 12:19 AM, Tomasz Figa wrote:
> Mike,
> 
> On 08.04.2014 17:45, Tomasz Figa wrote:
>> Hi,
>>
>> On 04.04.2014 16:53, Tomasz Stanislawski wrote:
>>> This patch adds support for propagation of setup of clock's parent one
>>> level
>>> up.
>>>
>>> This feature is helpful when a driver changes topology of its clocks
>>> using
>>> clk_set_parent().  The problem occurs when on one platform/SoC
>>> driver's clock
>>> is located at MUX output but on the other platform/SoC there is a
>>> gated proxy
>>> clock between the MUX and driver's clock.  In such a case, driver's
>>> code has to
>>> be modified to use one clock for enabling and the other clock for
>>> setup of a
>>> parent.
>>>
>>> The code updates are avoided by propagating setup of a parent up one
>>> level.
>>>
>>> Additionally, this patch adds CLK_SET_PARENT_PARENT (sorry for naming)
>>> flag to
>>> inform clk-core that clk_set_parent() should be propagated.
>>>
>>> Signed-off-by: Tomasz Stanislawski 
>>> ---
>>>   drivers/clk/clk.c|6 ++
>>>   include/linux/clk-provider.h |1 +
>>>   2 files changed, 7 insertions(+)
>>>
>>> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
>>> index dff0373..53bbfda 100644
>>> --- a/drivers/clk/clk.c
>>> +++ b/drivers/clk/clk.c
>>> @@ -1737,6 +1737,12 @@ int clk_set_parent(struct clk *clk, struct clk
>>> *parent)
>>>
>>>   /* try finding the new parent index */
>>>   if (parent) {
>>> +if ((clk->flags & CLK_SET_PARENT_PARENT)
>>> +&& clk->num_parents == 1) {
>>> +ret = clk_set_parent(clk->parent, parent);
>>> +goto out;
>>> +}
>>> +
>>>   p_index = clk_fetch_parent_index(clk, parent);
>>>   p_rate = parent->rate;
>>>   if (p_index < 0) {
>>> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
>>> index 5119174..daa0b03 100644
>>> --- a/include/linux/clk-provider.h
>>> +++ b/include/linux/clk-provider.h
>>> @@ -30,6 +30,7 @@
>>>   #define CLK_GET_RATE_NOCACHEBIT(6) /* do not use the cached clk
>>> rate */
>>>   #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate
>>> change */
>>>   #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk
>>> accuracy */
>>> +#define CLK_SET_PARENT_PARENTBIT(9) /* propagate parent change up
>>> one level */
>>>
>>>   struct clk_hw;
>>>   struct dentry;
>>>
>>
>> This would be very useful, at least on Exynos platforms, with
>> mux-div-gate clock paths. PARENT_PARENT sounds a bit funny, though.
>>
>> Reviewed-by: Tomasz Figa 
> 
> Your opinion on this would be greatly appreciated.
> 
> Best regards,
> Tomasz



[Bug 66452] JUNIPER UVD accelerated playback of WMV3 streams does not work

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=66452

Christian K?nig  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #9 from Christian K?nig  ---
Well that's actually not really a bug. The hardware just doesn't support WMV3,
it only support VC-1 in the advanced profile. So depending on what stream you
got it might work or not.

Anyway I've just pushed a patch stopping advertising VC-1 simple and main
profile (which are essentially WMV3) support on JUNIPER as well.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/48b62508/attachment.html>


[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Peter De Schrijver
On Wed, Jun 18, 2014 at 12:35:27AM +0200, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Tue, Jun 17, 2014 at 02:16:06PM +0200, Tomeu Vizoso wrote:
> > On 06/16/2014 10:02 PM, Stephen Warren wrote:
> > >On 06/16/2014 07:35 AM, Tomeu Vizoso wrote:
> > >>+
> > >>+Child device nodes describe the memory settings for different 
> > >>configurations and
> > >>+clock rates.
> > >
> > >How do the child nodes do that? The binding needs to specify the format
> > >of the child node.
> > 
> > Sorry, that file was sent before I had finished removing the bits from
> > downstream that aren't needed yet. There's no current need for any child
> > nodes.
> > 
> > >This binding looks quite anaemic vs.
> > >Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt; I
> > >would expect that this binding needs all the EMC register data from the
> > >tegra20-emc binding too. Can the two bindings be identical?
> > 
> > There's even less stuff needed right now, as all what ultimately the EMC
> > driver does is call clk_set_rate on the EMC clock. As the T124 EMC driver
> > gains more features, they should get more similar.
> > 
> > >Can you explain what the nvidia,mc and nvidia,pmc references are needed
> > >for? Hopefully, this driver isn't going to reach into those devices and
> > >touch their registers directly.
> > 
> > Not really needed, see above.
> 
> I've been working on a prototype driver for the memory controller. Part
> of what I've added is programming of the latency allowance registers (it
> doesn't yet expose an API to do so yet, though). I think that needs to
> eventually take into account the EMC frequency (and needs to be notified
> of changes to the same).
> 
> Without having thought this through very thoroughly, I suspect that
> rather than referencing the MC from the EMC it might be better to have
> the MC register with the EMC for notifications.
> 
> But perhaps there are other services from MC that EMC needs to work?
> 

If the emc frequency change is modelled as a clock, you could use CCF
notifications for this?

Cheers,

Peter.


Radeon drivers on PowerPC (e500)

2014-06-18 Thread Benjamin Herrenschmidt
On Wed, 2014-06-18 at 11:05 +1000, Dave Airlie wrote:
> 
> I don't think we ever ioremap GART, it should kmap GART pages, ioremap
> should only happen for VRAM areas AFAIK,
> 
> This isn't some 32-bit vs 36-bit BAR or something, I seem to remember BenH
> mentioning something like that before.

Yes, it's a recurring problem in the DRM with physical addresses that are
bigger than 32-bit on 32-bit systems. There have been patches done to
fix that but afaik never quite "completed". I can dig internally if
I can put my hand onto something.

If possible at all, can you try to configure your SoC to bring the MMIO
space of the PCIe within the bottom 32-bit of the chip address space ?

(Or use a 64-bit e5500 based chip ? :-)

Cheers,
Ben.




[RFC PATCH 1/4] memory: tegra124-emc: Add EMC driver

2014-06-18 Thread Stephen Warren
On 06/18/2014 11:23 AM, Tomeu Vizoso wrote:
> On 06/17/2014 06:15 PM, Stephen Warren wrote:
>> On 06/17/2014 06:16 AM, Tomeu Vizoso wrote:
>>> On 06/16/2014 10:02 PM, Stephen Warren wrote:
 On 06/16/2014 07:35 AM, Tomeu Vizoso wrote:
> +#ifdef CONFIG_TEGRA124_EMC
> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
> long rate);
> +void tegra124_emc_set_floor(unsigned long freq);
> +void tegra124_emc_set_ceiling(unsigned long freq);
> +#else
> +int tegra124_emc_reserve_bandwidth(unsigned int consumer, unsigned
> long rate)
> +{ return -ENODEV; }
> +void tegra124_emc_set_floor(unsigned long freq)
> +{ return; }
> +void tegra124_emc_set_ceiling(unsigned long freq)
> +{ return; }
> +#endif

 I'll repeat what I said off-list so that we can have the whole
 conversation on the list:

 That looks like a custom Tegra-specific API. I think it'd be much
 better
 to integrate this into the common clock framework as a standard clock
 constraints API. There are other use-cases for clock constraints
 besides
 EMC scaling (e.g. some in audio on Tegra, and I'm sure many on other
 SoCs too).
>>>
>>> Yes, I wrote a bit in the cover letter about our requirements and how
>>> they map to the CCF. Could you please comment on that?
>>
>> My comments remain the same. I believe this is something that belongs in
>> the clock driver, or at the least, some API that takes a struct clock as
>> its parameter, so that drivers can use the existing DT clock lookup
>> mechanism.
> 
> Ok, let me put this strawman here to see if I have gotten close to what
> you have in mind:
> 
> * add per-client accounting (Rabin's patches referenced before)
> 
> * add clk_set_floor, to be used by cpufreq, load stats, etc.
> 
> * add clk_set_ceiling, to be used by battery drivers, thermal, etc.

Yes. I'd expect those to be maintained per-client, and so the clock core
(or whatever higher level code implements clk_set_floor/ceiling)
performs the logic that "blends" together all the different requests
from different clients.

As an aside, for audio usage, I would expect clk_set_rate to be a
per-client (rather than per HW clock) operation too, and to error out if
one client says it wants to set pll_a to the rate needed for
44.1KHz-based audio and a different client wants the rate for
48KHz-based audio.

> * an EMC driver would collect bandwidth and latency requests from
> consumers and call clk_set_floor on the EMC clock.
> 
> * the EMC driver would also register for rate change notifications in
> the EMC clock and would update the latency allowance registers at that
> point.
> 
> How does it sound?

At a high level, yes this sounds about right to me.



[PATCH 2/2] drm/i915: rework digital port IRQ handling (v2)

2014-06-18 Thread Dave Airlie
From: Dave Airlie 

The digital ports from Ironlake and up have the ability to distinguish
between long and short HPD pulses. Displayport 1.1 only uses the short
form to request link retraining usually, so we haven't really needed
support for it until now.

However with DP 1.2 MST we need to handle the short irqs on their
own outside the modesetting locking the long hpd's involve. This
patch adds the framework to distinguish between short/long to the
current code base, to lay the basis for future DP 1.2 MST work.

This should mean we get better bisectability in case of regression
due to the new irq handling.

v2: add GM45 support (untested, due to lack of hw)

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/i915/i915_drv.h  |   5 ++
 drivers/gpu/drm/i915/i915_irq.c  | 160 +--
 drivers/gpu/drm/i915/intel_ddi.c |   3 +
 drivers/gpu/drm/i915/intel_dp.c  |  20 +
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 5 files changed, 182 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8f68678..5fd5bf3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1551,6 +1551,11 @@ struct drm_i915_private {

struct i915_runtime_pm pm;

+   struct intel_digital_port *hpd_irq_port[I915_MAX_PORTS];
+   u32 long_hpd_port_mask;
+   u32 short_hpd_port_mask;
+   struct work_struct dig_port_work;
+
/* Old dri1 support infrastructure, beware the dragons ya fools entering
 * here! */
struct i915_dri1_state dri1;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index cbf31cb..9913c08 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1096,6 +1096,53 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
return true;
 }

+static void i915_digport_work_func(struct work_struct *work)
+{
+   struct drm_i915_private *dev_priv =
+   container_of(work, struct drm_i915_private, dig_port_work);
+   unsigned long irqflags;
+   u32 long_port_mask, short_port_mask;
+   struct intel_digital_port *intel_dig_port;
+   int i, ret;
+   u32 old_bits = 0;
+
+   spin_lock_irqsave(_priv->irq_lock, irqflags);
+   long_port_mask = dev_priv->long_hpd_port_mask;
+   dev_priv->long_hpd_port_mask = 0;
+   short_port_mask = dev_priv->short_hpd_port_mask;
+   dev_priv->short_hpd_port_mask = 0;
+   spin_unlock_irqrestore(_priv->irq_lock, irqflags);
+
+   for (i = 0; i < I915_MAX_PORTS; i++) {
+   bool valid = false;
+   bool long_hpd = false;
+   intel_dig_port = dev_priv->hpd_irq_port[i];
+   if (!intel_dig_port || !intel_dig_port->hpd_pulse)
+   continue;
+
+   if (long_port_mask & (1 << i))  {
+   valid = true;
+   long_hpd = true;
+   } else if (short_port_mask & (1 << i))
+   valid = true;
+
+   if (valid) {
+   ret = intel_dig_port->hpd_pulse(intel_dig_port, 
long_hpd);
+   if (ret == true) {
+   /* if we get true fallback to old school hpd */
+   old_bits |= (1 << intel_dig_port->base.hpd_pin);
+   }
+   }
+   }
+
+   if (old_bits) {
+   spin_lock_irqsave(_priv->irq_lock, irqflags);
+   dev_priv->hpd_event_bits |= old_bits;
+   spin_unlock_irqrestore(_priv->irq_lock, irqflags);
+   schedule_work(_priv->hotplug_work);
+   }
+}
+
 /*
  * Handle hotplug events outside the interrupt handler proper.
  */
@@ -1520,23 +1567,104 @@ static irqreturn_t gen8_gt_irq_handler(struct 
drm_device *dev,
 #define HPD_STORM_DETECT_PERIOD 1000
 #define HPD_STORM_THRESHOLD 5

+static int ilk_port_to_hotplug_shift(enum port port)
+{
+   switch (port) {
+   case PORT_A:
+   case PORT_E:
+   default:
+   return -1;
+   case PORT_B:
+   return 0;
+   case PORT_C:
+   return 8;
+   case PORT_D:
+   return 16;
+   }
+}
+
+static int g4x_port_to_hotplug_shift(enum port port)
+{
+   switch (port) {
+   case PORT_A:
+   case PORT_E:
+   default:
+   return -1;
+   case PORT_B:
+   return 17;
+   case PORT_C:
+   return 19;
+   case PORT_D:
+   return 21;
+   }
+}
+
+static inline enum port get_port_from_pin(enum hpd_pin pin)
+{
+   switch (pin) {
+   case HPD_PORT_B:
+   return PORT_B;
+   case HPD_PORT_C:
+   return PORT_C;
+   case HPD_PORT_D:
+   return PORT_D;
+   default:
+   return PORT_A; /* no hpd */
+   }
+}
+
 static inline void intel_hpd_irq_handler(struct 

[PATCH 1/2] drm/i915: Add #defines for short/long pulse on gmch platforms

2014-06-18 Thread Dave Airlie
From: Daniel Vetter 

For no reason at all the public docs lack them, and Dave needs them
for his hpd interrupt rework.

Cc: Dave Airlie 
Signed-off-by: Daniel Vetter 
Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/i915/i915_reg.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5122254..5d8ba0c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2526,8 +2526,14 @@ enum punit_power_well {
 #define   PORTC_HOTPLUG_LIVE_STATUS_VLV(1 << 28)
 #define   PORTB_HOTPLUG_LIVE_STATUS_VLV(1 << 29)
 #define   PORTD_HOTPLUG_INT_STATUS (3 << 21)
+#define   PORTD_HOTPLUG_INT_LONG_PULSE (2 << 21)
+#define   PORTD_HOTPLUG_INT_SHORT_PULSE(1 << 21)
 #define   PORTC_HOTPLUG_INT_STATUS (3 << 19)
+#define   PORTC_HOTPLUG_INT_LONG_PULSE (2 << 19)
+#define   PORTC_HOTPLUG_INT_SHORT_PULSE(1 << 19)
 #define   PORTB_HOTPLUG_INT_STATUS (3 << 17)
+#define   PORTB_HOTPLUG_INT_LONG_PULSE (2 << 17)
+#define   PORTB_HOTPLUG_INT_SHORT_PLUSE(1 << 17)
 /* CRT/TV common between gen3+ */
 #define   CRT_HOTPLUG_INT_STATUS   (1 << 11)
 #define   TV_HOTPLUG_INT_STATUS(1 << 10)
-- 
1.9.3



i915 hpd irq rework

2014-06-18 Thread Dave Airlie
Can we get these merged or even looked at?, they are blocking the whole MST 
progress,
and I don't have any insight to secret Intel review process. :-)

Dave.



[PATCH 1/2] Revert "drm/radeon: remove drm_vblank_get|put from pflip handling"

2014-06-18 Thread Christian König
Am 18.06.2014 07:53, schrieb Michel D?nzer:
> On 17.06.2014 20:41, Christian K?nig wrote:
>> Am 17.06.2014 12:12, schrieb Michel D?nzer:
>>> From: Michel D?nzer 
>>>
>>> This reverts commit 75f36d861957cb05b7889af24c8cd4a789398304.
>>>
>>> drm_vblank_get() is necessary to ensure the DRM vblank counter value is
>>> up to date in drm_send_vblank_event().
>>>
>>> Seems to fix weston hangs waiting for page flips to complete.
>>>
>>> Signed-off-by: Michel D?nzer 
>> Both patches are: Reviewed-by: Christian K?nig 
> Thank you.
>
>
> Looking into these issues has got me thinking about the use of the page
> flip interrupt: If the page flip interrupt arrives before the corresponding
> vertical blank interrupt, the DRM vblank counter will be lower than
> expected by 1 in drm_send_vblank_event(). I suspect this is the cause of
>
>   (WW) RADEON(0): radeon_dri2_flip_event_handler: Pageflip completion event 
> has impossible msc [x-1] < target_msc [x]
>
> messages in the X log file which have been popping up in bug reports lately.
> This also results in 0s being returned to the client for the MSC and
> timestamp of the swap completion, which could cause all kinds of bad
> behaviour.
First of all thanks for looking into it. Are you getting this on 3.16 or 
3.15?

I don't think that the pflip irq is thrown earlier than the vblank, but 
on 3.16 it might actually be that we program the flip so fast into the 
hardware that we do it one frame earlier than planned.

> The easy way to avoid that would be to stop using the page flip interrupt
> for this again. Could there be another solution for the issues you
> addressed by using it?
The original problem was that programming the flip in the vblank event 
actually doesn't work reliable because of the underlying hardware double 
buffering. We just can't tell if the flip will complete in this frame or 
if the vblank interrupt was processed so late that it will happen in the 
next frame.

We could just busy loop until either the pending bit or the bit for the 
update period becomes null, but even busy waiting for the pending bit to 
go up in an interrupt handler like we did before is quite questionable.

Additional to that using the pflip interrupt enables us to sync to the 
hblank as well or just not at all with just changing a few register 
bits. And it's also a prerequisite of switching to a non constant sync 
rate. So I would like to keep it and try to fix the issues we are seeing 
instead.

> If not, another issue I encountered in 3.15 is that
> radeon_crtc_handle_flip() is called unconditionally when a page flip
> interrupt arrives. If the flip was already handled (presumably from the
> vertical blank interrupt), the BUG_ON() in drm_vblank_put() triggers a
> panic. This happened to me with weston.
Calling radeon_crtc_handle_flip multiple times shouldn't be a problem, 
that can happen with the old code as well. Setting unpin_work to NULL 
under a spin lock protects us from that case.

But take a look at the 3.15 version of radeon_crtc_page_flip instead!!! 
We first set "unpin_work", release the spin lock and *then* reserve and 
pin the BO. If I'm not completely wrong there is a race condition here 
that when the vblank interrupt happens before the rest of the function 
all kind of bad things can happen.

The only thing preventing us from that is that the vblank interrupt is 
turned on only at the end of the function, but the vblank interrupt can 
be turned on before by other reasons as well.

> This is presumably not an issue in 3.16 because radeon_crtc_handle_flip()
> now bails early if radeon_crtc->flip_work == NULL.


Thanks,
Christian.


Radeon drivers on PowerPC (e500)

2014-06-18 Thread Dave Airlie
On 18 June 2014 05:14, Martyn Welch  wrote:
> Hi,
>
> I've been asked to try and get a r600 based (E6460) graphics card running on
> a machine powered by a Freescale p4080 (e500 core). I've run into a bit of a
> problem.
>
> I have the driver built into the kernel at this point. When I boot the card
> is detected and it seems to be finding the fimware (I'm also building in the
> required firmware blobs), but I get the following messages:
>
> [drm] Initialized drm 1.1.0 20060810
> [drm] radeon defaulting to kernel modesetting.
> [drm] radeon kernel modesetting enabled.
> [drm] initializing kernel modesetting (CAICOS 0x1002:0x6763 0x1775:0xC6A7).
> [drm] register mmio base: 0x1000
> [drm] register mmio size: 131072
> ATOM BIOS: GE
> [drm] GPU not posted. posting now...
> radeon :04:00.0: VRAM: 512M 0x - 0x1FFF
> (512M used)
> radeon :04:00.0: GTT: 512M 0x2000 - 0x3FFF
> [drm] Detected VRAM RAM=512M, BAR=256M
> [drm] RAM width 64bits DDR
> [TTM] Zone  kernel: Available graphics memory: 338754 kiB
> [TTM] Zone highmem: Available graphics memory: 994110 kiB
> [TTM] Initializing pool allocator
> [TTM] Initializing DMA pool allocator
> [drm] radeon: 512M of VRAM memory ready
> [drm] radeon: 512M of GTT memory ready.
> [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
> [drm] Driver supports precise vblank timestamp query.
> radeon :04:00.0: radeon: using MSI.
> [drm] radeon: irq initialized.
> [drm] GART: num cpu pages 131072, num gpu pages 131072
> [drm] probing gen 2 caps for device 111d:808a = 2/0
> [drm] enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0
> [drm] Loading CAICOS Microcode
> __ioremap_caller(14, 4096, 4194304, c02eab20)__ioremap(): phys addr
> 0x14 is RAM lr ttm_bo_kmap
> radeon :04:00.0: disabling GPU acceleration
> radeon :04:00.0: e957e400 unpin not necessary
> radeon :04:00.0: e957e400 unpin not necessary
> [drm] Radeon Display Connectors
> [drm] Connector 0:
> [drm]   DP-1
> [drm]   HPD2
> [drm]   HPD3
> [drm]   DDC: 0x6450 0x6450 0x6454 0x6454 0x6458 0x6458 0x645c 0x645c
> [drm]   Encoders:
> [drm] DFP2: INTERNAL_UNIPHY1
> [drm] Connector 2:
> [drm]   DVI-I-1
> [drm]   HPD1
> [drm]   DDC: 0x6430 0x6430 0x6434 0x6434 0x6438 0x6438 0x643c 0x643c
> [drm]   Encoders:
> [drm] DFP3: INTERNAL_UNIPHY
> [drm] CRT1: INTERNAL_KLDSCP_DAC1
> [drm] Internal thermal controller with fan control
> [drm] radeon: power management initialized
> __ioremap_caller(141000, 5242880, 4194304, c02eab20)__ioremap(): phys addr
> 0x141000 is RAM lr ttm_bo_kmap
> [drm:radeonfb_create] *ERROR* failed to create fbcon object -12
> [drm] Initialized radeon 2.29.0 20080528 for :04:00.0 on minor 0
>
> There are failed attempts to ioremap RAM, initially as part of
> r600_vram_scratch_init() and again I guess mapping the GART?
>
> On the e500, overlapping TLBs are not allowed and there is an explict check
> in arch/powerpc/mm/pgtable_32.c __ioremap_caller() to protect against
> ioremapping RAM that's already got TLB entries which is resulting in the
> error messages.

I don't think we ever ioremap GART, it should kmap GART pages, ioremap
should only happen for VRAM areas AFAIK,

This isn't some 32-bit vs 36-bit BAR or something, I seem to remember BenH
mentioning something like that before.

Dave.


[PATCH 1/1] drm/exynos: Fix de-registration ordering

2014-06-18 Thread Sachin Kamat
On Wed, Jun 18, 2014 at 10:53 AM, Inki Dae  wrote:
> On 2014? 06? 17? 20:38, Sachin Kamat wrote:
>> 'exynos_drm_pdev' was not getting unregistered if platform_driver_register()
>> failed. Fix the ordering to allow this. This also fixes the below warning by
>> moving the #endif macro. While at it also fix the ordering in the exit 
>> function
>> so that de-registration happens in opposite order of registration.
>> drivers/gpu/drm/exynos/exynos_drm_drv.c:768:1: warning: label 
>> ?err_unregister_pd? defined but not used [-Wunused-label]
>
> Above line doesn't conform to UTF-8 so I just fixed it. :)
> Applied.

Thanks Inki :)

Regards,
Sachin


[PATCH v5 11/11] drm: sti: Add DRM driver itself

2014-06-18 Thread Benjamin Gaignard
Make the link between all the hardware drivers and DRM/KMS interface.
Create the driver itself and make it register all the sub-components.
Use GEM CMA helpers for buffer allocation.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Kconfig  |   8 +
 drivers/gpu/drm/sti/Makefile |   6 +-
 drivers/gpu/drm/sti/sti_compositor.c |  16 +-
 drivers/gpu/drm/sti/sti_drm_crtc.c   | 419 +++
 drivers/gpu/drm/sti/sti_drm_crtc.h   |  21 ++
 drivers/gpu/drm/sti/sti_drm_drv.c| 244 
 drivers/gpu/drm/sti/sti_drm_drv.h|  29 +++
 drivers/gpu/drm/sti/sti_drm_plane.c  | 192 
 drivers/gpu/drm/sti/sti_drm_plane.h  |  17 ++
 9 files changed, 949 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/sti/sti_drm_crtc.c
 create mode 100644 drivers/gpu/drm/sti/sti_drm_crtc.h
 create mode 100644 drivers/gpu/drm/sti/sti_drm_drv.c
 create mode 100644 drivers/gpu/drm/sti/sti_drm_drv.h
 create mode 100644 drivers/gpu/drm/sti/sti_drm_plane.c
 create mode 100644 drivers/gpu/drm/sti/sti_drm_plane.h

diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
index 1013570..bb48696 100644
--- a/drivers/gpu/drm/sti/Kconfig
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -1,6 +1,14 @@
 config DRM_STI
bool "DRM Support for STMicroelectronics SoC stiH41x Series"
depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
+   select DRM_KMS_HELPER
+   select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
help
  Choose this option to enable DRM on STM stiH41x chipset
+
+config DRM_STI_FBDEV
+   bool "DRM frame buffer device for STMicroelectronics SoC stiH41x Serie"
+   depends on DRM_STI
+   help
+ Choose this option to enable FBDEV on top of DRM for STM stiH41x 
chipset
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index a0612cc..d104551 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -7,7 +7,11 @@ obj-$(CONFIG_DRM_STI) += \
sti_hdmi_tx3g4c28phy.o \
sti_hda.o \
sti_tvout.o \
+   sti_drm_crtc.o \
+   sti_drm_plane.o \
+   sti_hda.o \
sti_layer.o \
sti_mixer.o \
sti_gdp.o \
-   sti_vid.o
\ No newline at end of file
+   sti_vid.o \
+   sti_drm_drv.o
diff --git a/drivers/gpu/drm/sti/sti_compositor.c 
b/drivers/gpu/drm/sti/sti_compositor.c
index 46c224d..dade64f 100644
--- a/drivers/gpu/drm/sti/sti_compositor.c
+++ b/drivers/gpu/drm/sti/sti_compositor.c
@@ -14,6 +14,9 @@
 #include 

 #include "sti_compositor.h"
+#include "sti_drm_crtc.h"
+#include "sti_drm_drv.h"
+#include "sti_drm_plane.h"
 #include "sti_gdp.h"
 #include "sti_vtg.h"

@@ -87,10 +90,15 @@ static int sti_compositor_bind(struct device *dev, struct 
device *master,
struct sti_compositor *compo = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
unsigned int i, crtc = 0, plane = 0;
+   struct sti_drm_private *dev_priv = drm_dev->dev_private;
+
+   dev_priv->compo = compo;

for (i = 0; i < compo->nb_mixers; i++) {
-   if (compo->mixer[i])
+   if (compo->mixer[i]) {
+   sti_drm_crtc_init(drm_dev, compo->mixer[i]);
crtc++;
+   }
}
if (crtc == 0) {
DRM_ERROR("No CRTC available\n");
@@ -108,8 +116,11 @@ static int sti_compositor_bind(struct device *dev, struct 
device *master,
enum sti_layer_desc desc = compo->layer[i]->desc;
enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK;

-   if ((type == STI_GDP) && (desc != STI_GDP_0))
+   if ((type == STI_GDP) && (desc != STI_GDP_0)) {
+   sti_drm_plane_init(drm_dev, compo->layer[i],
+   (1 << crtc) - 1);
plane++;
+   }
}
}

@@ -159,6 +170,7 @@ static int sti_compositor_probe(struct platform_device 
*pdev)
return -ENOMEM;
}
compo->dev = dev;
+   compo->vtg_vblank_nb.notifier_call = sti_drm_crtc_vblank_cb;

/* populate data structure depending on compatibility */
BUG_ON(!of_match_node(compositor_of_match, np)->data);
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c 
b/drivers/gpu/drm/sti/sti_drm_crtc.c
new file mode 100644
index 000..a1c617b
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_crtc.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard 
+ *  Fabien Dessenne 
+ *  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+
+#include 
+#include 
+
+#include "sti_compositor.h"
+#include "sti_drm_drv.h"
+#include "sti_drm_crtc.h"
+#include "sti_vtg.h"
+
+static void 

[PATCH v5 10/11] drm: sti: add Compositor

2014-06-18 Thread Benjamin Gaignard
Compositor control all the input sub-device (VID, GDP)
and the mixer(s).
It is the main entry point for composition.
Layer interface is used to control the abstracted layers.

Add debug in mixer and GDP

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Kconfig  |   1 +
 drivers/gpu/drm/sti/Makefile |   2 +
 drivers/gpu/drm/sti/sti_compositor.c | 252 +++
 drivers/gpu/drm/sti/sti_compositor.h |  90 +
 drivers/gpu/drm/sti/sti_gdp.c|  33 +
 drivers/gpu/drm/sti/sti_layer.c  | 206 
 drivers/gpu/drm/sti/sti_mixer.c  |   6 +
 7 files changed, 590 insertions(+)
 create mode 100644 drivers/gpu/drm/sti/sti_compositor.c
 create mode 100644 drivers/gpu/drm/sti/sti_compositor.h
 create mode 100644 drivers/gpu/drm/sti/sti_layer.c

diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
index cbd664b..1013570 100644
--- a/drivers/gpu/drm/sti/Kconfig
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -1,5 +1,6 @@
 config DRM_STI
bool "DRM Support for STMicroelectronics SoC stiH41x Series"
depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
+   select DRM_KMS_CMA_HELPER
help
  Choose this option to enable DRM on STM stiH41x chipset
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index ce03e15..a0612cc 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -1,11 +1,13 @@
 obj-$(CONFIG_DRM_STI) += \
sti_vtg.o \
sti_vtac.o \
+   sti_compositor.o \
sti_hdmi.o \
sti_hdmi_tx3g0c55phy.o \
sti_hdmi_tx3g4c28phy.o \
sti_hda.o \
sti_tvout.o \
+   sti_layer.o \
sti_mixer.o \
sti_gdp.o \
sti_vid.o
\ No newline at end of file
diff --git a/drivers/gpu/drm/sti/sti_compositor.c 
b/drivers/gpu/drm/sti/sti_compositor.c
new file mode 100644
index 000..46c224d
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_compositor.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard 
+ *  Fabien Dessenne 
+ *  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "sti_compositor.h"
+#include "sti_gdp.h"
+#include "sti_vtg.h"
+
+/*
+ * stiH407 compositor properties
+ */
+struct sti_compositor_data stih407_compositor_data = {
+   .nb_subdev = 6,
+   .subdev_desc = {
+   {STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100},
+   {STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
+   {STI_GPD_SUBDEV, (int)STI_GDP_2, 0x300},
+   {STI_GPD_SUBDEV, (int)STI_GDP_3, 0x400},
+   {STI_VID_SUBDEV, (int)STI_VID_0, 0x700},
+   {STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}
+   },
+};
+
+/*
+ * stiH416 compositor properties
+ * Note:
+ * on stih416 MIXER_AUX has a different base address from MIXER_MAIN
+ * Moreover, GDPx is different for Main and Aux Mixer. So this subdev map does
+ * not fit for stiH416 if we want to enable the MIXER_AUX.
+ */
+struct sti_compositor_data stih416_compositor_data = {
+   .nb_subdev = 3,
+   .subdev_desc = {
+   {STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100},
+   {STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
+   {STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}
+   },
+};
+
+static int sti_compositor_init_subdev(struct sti_compositor *compo,
+   struct sti_compositor_subdev_descriptor *desc,
+   unsigned int array_size)
+{
+   unsigned int i, mixer_id = 0, layer_id = 0;
+
+   for (i = 0; i < array_size; i++) {
+   switch (desc[i].type) {
+   case STI_MIXER_MAIN_SUBDEV:
+   case STI_MIXER_AUX_SUBDEV:
+   compo->mixer[mixer_id++] =
+   sti_mixer_create(compo->dev, desc[i].id,
+compo->regs + desc[i].offset);
+   break;
+   case STI_GPD_SUBDEV:
+   case STI_VID_SUBDEV:
+   compo->layer[layer_id++] =
+   sti_layer_create(compo->dev, desc[i].id,
+compo->regs + desc[i].offset);
+   break;
+   /* case STI_CURSOR_SUBDEV : TODO */
+   default:
+   DRM_ERROR("Unknow subdev compoment type\n");
+   return 1;
+   }
+
+   }
+   compo->nb_mixers = mixer_id;
+   compo->nb_layers = layer_id;
+
+   return 0;
+}
+
+static int sti_compositor_bind(struct device *dev, struct device *master,
+   void *data)
+{
+   struct sti_compositor *compo = dev_get_drvdata(dev);
+   struct drm_device *drm_dev = data;
+   

[PATCH v5 09/11] drm: sti: add Mixer

2014-06-18 Thread Benjamin Gaignard
Mixer hardware IP is responsible of mixing the different inputs layers.
Z-order is managed by the mixer.
We could 2 mixers: one for main path and one for auxillary path

Mixers are part of Compositor hardware block

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile|   1 +
 drivers/gpu/drm/sti/sti_mixer.c | 243 
 drivers/gpu/drm/sti/sti_mixer.h |  54 +
 3 files changed, 298 insertions(+)
 create mode 100644 drivers/gpu/drm/sti/sti_mixer.c
 create mode 100644 drivers/gpu/drm/sti/sti_mixer.h

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index bb0f6b3..ce03e15 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_DRM_STI) += \
sti_hdmi_tx3g4c28phy.o \
sti_hda.o \
sti_tvout.o \
+   sti_mixer.o \
sti_gdp.o \
sti_vid.o
\ No newline at end of file
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c
new file mode 100644
index 000..5fa6dc5
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_mixer.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard 
+ *  Fabien Dessenne 
+ *  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include "sti_mixer.h"
+#include "sti_vtg.h"
+
+/* Identity: G=Y , B=Cb , R=Cr */
+static const u32 mixerColorSpaceMatIdentity[] = {
+   0x1000, 0x, 0x1000, 0x1000,
+   0x, 0x, 0x, 0x
+};
+
+/* regs offset */
+#define GAM_MIXER_CTL  0x00
+#define GAM_MIXER_BKC  0x04
+#define GAM_MIXER_BCO  0x0C
+#define GAM_MIXER_BCS  0x10
+#define GAM_MIXER_AVO  0x28
+#define GAM_MIXER_AVS  0x2C
+#define GAM_MIXER_CRB  0x34
+#define GAM_MIXER_ACT  0x38
+#define GAM_MIXER_MBP  0x3C
+#define GAM_MIXER_MX0  0x80
+
+/* id for depth of CRB reg */
+#define GAM_DEPTH_VID0_ID  1
+#define GAM_DEPTH_VID1_ID  2
+#define GAM_DEPTH_GDP0_ID  3
+#define GAM_DEPTH_GDP1_ID  4
+#define GAM_DEPTH_GDP2_ID  5
+#define GAM_DEPTH_GDP3_ID  6
+#define GAM_DEPTH_MASK_ID  7
+
+/* mask in CTL reg */
+#define GAM_CTL_BACK_MASK  BIT(0)
+#define GAM_CTL_VID0_MASK  BIT(1)
+#define GAM_CTL_VID1_MASK  BIT(2)
+#define GAM_CTL_GDP0_MASK  BIT(3)
+#define GAM_CTL_GDP1_MASK  BIT(4)
+#define GAM_CTL_GDP2_MASK  BIT(5)
+#define GAM_CTL_GDP3_MASK  BIT(6)
+
+const char *sti_mixer_to_str(struct sti_mixer *mixer)
+{
+   switch (mixer->id) {
+   case STI_MIXER_MAIN:
+   return "MAIN_MIXER";
+   case STI_MIXER_AUX:
+   return "AUX_MIXER";
+   default:
+   return "";
+   }
+}
+
+static inline u32 sti_mixer_reg_read(struct sti_mixer *mixer, u32 reg_id)
+{
+   return readl(mixer->regs + reg_id);
+}
+
+static inline void sti_mixer_reg_write(struct sti_mixer *mixer,
+  u32 reg_id, u32 val)
+{
+   writel(val, mixer->regs + reg_id);
+}
+
+void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable)
+{
+   u32 val = sti_mixer_reg_read(mixer, GAM_MIXER_CTL);
+
+   val &= ~GAM_CTL_BACK_MASK;
+   val |= enable;
+   sti_mixer_reg_write(mixer, GAM_MIXER_CTL, val);
+}
+
+static void sti_mixer_set_background_color(struct sti_mixer *mixer,
+  u8 red, u8 green, u8 blue)
+{
+   u32 val = (red << 16) | (green << 8) | blue;
+
+   sti_mixer_reg_write(mixer, GAM_MIXER_BKC, val);
+}
+
+static void sti_mixer_set_background_area(struct sti_mixer *mixer,
+ struct drm_display_mode *mode)
+{
+   u32 ydo, xdo, yds, xds;
+
+   ydo = sti_vtg_get_line_number(*mode, 0);
+   yds = sti_vtg_get_line_number(*mode, mode->vdisplay - 1);
+   xdo = sti_vtg_get_pixel_number(*mode, 0);
+   xds = sti_vtg_get_pixel_number(*mode, mode->hdisplay - 1);
+
+   sti_mixer_reg_write(mixer, GAM_MIXER_BCO, ydo << 16 | xdo);
+   sti_mixer_reg_write(mixer, GAM_MIXER_BCS, yds << 16 | xds);
+}
+
+int sti_mixer_set_layer_depth(struct sti_mixer *mixer, struct sti_layer *layer)
+{
+   int layer_id = 0, depth = layer->zorder;
+   u32 mask, val;
+
+   if (depth >= GAM_MIXER_NB_DEPTH_LEVEL)
+   return 1;
+
+   switch (layer->desc) {
+   case STI_GDP_0:
+   layer_id = GAM_DEPTH_GDP0_ID;
+   break;
+   case STI_GDP_1:
+   layer_id = GAM_DEPTH_GDP1_ID;
+   break;
+   case STI_GDP_2:
+   layer_id = GAM_DEPTH_GDP2_ID;
+   break;
+   case STI_GDP_3:
+   layer_id = GAM_DEPTH_GDP3_ID;
+   break;
+   case STI_VID_0:
+   layer_id = GAM_DEPTH_VID0_ID;
+   break;
+   case STI_VID_1:
+   layer_id = GAM_DEPTH_VID1_ID;
+   break;
+   default:
+   DRM_ERROR("Unknown 

[PATCH v5 08/11] drm: sti: add VID layer

2014-06-18 Thread Benjamin Gaignard
VIDeo plug are one of the compositor input sub-devices.
VID are dedicated to video inputs like YUV plans.

Like GDP, VID are part of Compositor hardware block
and use sti_layer structure to provide an abstraction for
Compositor calls.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile  |   3 +-
 drivers/gpu/drm/sti/sti_vid.c | 138 ++
 drivers/gpu/drm/sti/sti_vid.h |  12 
 3 files changed, 152 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sti/sti_vid.c
 create mode 100644 drivers/gpu/drm/sti/sti_vid.h

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index 1745697..bb0f6b3 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_DRM_STI) += \
sti_hdmi_tx3g4c28phy.o \
sti_hda.o \
sti_tvout.o \
-   sti_gdp.o
\ No newline at end of file
+   sti_gdp.o \
+   sti_vid.o
\ No newline at end of file
diff --git a/drivers/gpu/drm/sti/sti_vid.c b/drivers/gpu/drm/sti/sti_vid.c
new file mode 100644
index 000..10ced6a
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vid.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Fabien Dessenne  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+
+#include "sti_layer.h"
+#include "sti_vid.h"
+#include "sti_vtg.h"
+
+/* Registers */
+#define VID_CTL 0x00
+#define VID_ALP 0x04
+#define VID_CLF 0x08
+#define VID_VPO 0x0C
+#define VID_VPS 0x10
+#define VID_KEY10x28
+#define VID_KEY20x2C
+#define VID_MPR00x30
+#define VID_MPR10x34
+#define VID_MPR20x38
+#define VID_MPR30x3C
+#define VID_MST 0x68
+#define VID_BC  0x70
+#define VID_TINT0x74
+#define VID_CSAT0x78
+
+/* Registers values */
+#define VID_CTL_IGNORE  (BIT(31) | BIT(30))
+#define VID_CTL_PSI_ENABLE  (BIT(2) | BIT(1) | BIT(0))
+#define VID_ALP_OPAQUE  0x0080
+#define VID_BC_DFLT 0x8000
+#define VID_TINT_DFLT   0x
+#define VID_CSAT_DFLT   0x0080
+/* YCbCr to RGB BT709:
+ * R = Y+1.5391Cr
+ * G = Y-0.4590Cr-0.1826Cb
+ * B = Y+1.8125Cb */
+#define VID_MPR0_BT709  0x0A80
+#define VID_MPR1_BT709  0x0AC5
+#define VID_MPR2_BT709  0x07150545
+#define VID_MPR3_BT709  0x0AE8
+
+static int sti_vid_prepare_layer(struct sti_layer *vid, bool first_prepare)
+{
+   u32 val;
+
+   /* Unmask */
+   val = readl(vid->regs + VID_CTL);
+   val &= ~VID_CTL_IGNORE;
+   writel(val, vid->regs + VID_CTL);
+
+   return 0;
+}
+
+static int sti_vid_commit_layer(struct sti_layer *vid)
+{
+   struct drm_display_mode *mode = vid->mode;
+   u32 ydo, xdo, yds, xds;
+
+   ydo = sti_vtg_get_line_number(*mode, vid->dst_y);
+   yds = sti_vtg_get_line_number(*mode, vid->dst_y + vid->dst_h - 1);
+   xdo = sti_vtg_get_pixel_number(*mode, vid->dst_x);
+   xds = sti_vtg_get_pixel_number(*mode, vid->dst_x + vid->dst_w - 1);
+
+   writel((ydo << 16) | xdo, vid->regs + VID_VPO);
+   writel((yds << 16) | xds, vid->regs + VID_VPS);
+
+   return 0;
+}
+
+static int sti_vid_disable_layer(struct sti_layer *vid)
+{
+   u32 val;
+
+   /* Mask */
+   val = readl(vid->regs + VID_CTL);
+   val |= VID_CTL_IGNORE;
+   writel(val, vid->regs + VID_CTL);
+
+   return 0;
+}
+
+static const uint32_t *sti_vid_get_formats(struct sti_layer *layer)
+{
+   return NULL;
+}
+
+static unsigned int sti_vid_get_nb_formats(struct sti_layer *layer)
+{
+   return 0;
+}
+
+static void sti_vid_init(struct sti_layer *vid)
+{
+   /* Enable PSI, Mask layer */
+   writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL);
+
+   /* Opaque */
+   writel(VID_ALP_OPAQUE, vid->regs + VID_ALP);
+
+   /* Color conversion parameters */
+   writel(VID_MPR0_BT709, vid->regs + VID_MPR0);
+   writel(VID_MPR1_BT709, vid->regs + VID_MPR1);
+   writel(VID_MPR2_BT709, vid->regs + VID_MPR2);
+   writel(VID_MPR3_BT709, vid->regs + VID_MPR3);
+
+   /* Brightness, contrast, tint, saturation */
+   writel(VID_BC_DFLT, vid->regs + VID_BC);
+   writel(VID_TINT_DFLT, vid->regs + VID_TINT);
+   writel(VID_CSAT_DFLT, vid->regs + VID_CSAT);
+}
+
+static const struct sti_layer_funcs vid_ops = {
+   .get_formats = sti_vid_get_formats,
+   .get_nb_formats = sti_vid_get_nb_formats,
+   .init = sti_vid_init,
+   .prepare = sti_vid_prepare_layer,
+   .commit = sti_vid_commit_layer,
+   .disable = sti_vid_disable_layer,
+};
+
+struct sti_layer *sti_vid_create(struct device *dev)
+{
+   struct sti_layer *vid;
+
+   vid = devm_kzalloc(dev, 

[PATCH v5 07/11] drm: sti: add GDP layer

2014-06-18 Thread Benjamin Gaignard
Generic Display Pipeline are one of the compositor input sub-devices.
GDP are dedicated to graphic input like RGB plans.
GDP is part of Compositor hardware block which will be introduce later.

A sti_layer structure is used to abstract GDP calls from Compositor.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile|   3 +-
 drivers/gpu/drm/sti/sti_gdp.c   | 516 
 drivers/gpu/drm/sti/sti_gdp.h   |  16 ++
 drivers/gpu/drm/sti/sti_layer.h | 125 ++
 4 files changed, 659 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sti/sti_gdp.c
 create mode 100644 drivers/gpu/drm/sti/sti_gdp.h
 create mode 100644 drivers/gpu/drm/sti/sti_layer.h

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index dcc9568..1745697 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_DRM_STI) += \
sti_hdmi_tx3g0c55phy.o \
sti_hdmi_tx3g4c28phy.o \
sti_hda.o \
-   sti_tvout.o
\ No newline at end of file
+   sti_tvout.o \
+   sti_gdp.o
\ No newline at end of file
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
new file mode 100644
index 000..7f55767
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard 
+ *  Fabien Dessenne 
+ *  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+
+#include "sti_gdp.h"
+#include "sti_layer.h"
+#include "sti_vtg.h"
+
+#define ENA_COLOR_FILL  BIT(8)
+#define WAIT_NEXT_VSYNC BIT(31)
+
+/* GDP color formats */
+#define GDP_RGB565  0x00
+#define GDP_RGB888  0x01
+#define GDP_RGB888_32   0x02
+#define GDP_ARGB85650x04
+#define GDP_ARGB0x05
+#define GDP_ARGB15550x06
+#define GDP_ARGB0x07
+#define GDP_CLUT8   0x0B
+#define GDP_YCBR888 0x10
+#define GDP_YCBR422R0x12
+#define GDP_AYCBR   0x15
+
+#define GAM_GDP_CTL_OFFSET  0x00
+#define GAM_GDP_AGC_OFFSET  0x04
+#define GAM_GDP_VPO_OFFSET  0x0C
+#define GAM_GDP_VPS_OFFSET  0x10
+#define GAM_GDP_PML_OFFSET  0x14
+#define GAM_GDP_PMP_OFFSET  0x18
+#define GAM_GDP_SIZE_OFFSET 0x1C
+#define GAM_GDP_NVN_OFFSET  0x24
+#define GAM_GDP_KEY1_OFFSET 0x28
+#define GAM_GDP_KEY2_OFFSET 0x2C
+#define GAM_GDP_PPT_OFFSET  0x34
+#define GAM_GDP_CML_OFFSET  0x3C
+#define GAM_GDP_MST_OFFSET  0x68
+
+#define GAM_GDP_ALPHARANGE_255  BIT(5)
+#define GAM_GDP_AGC_FULL_RANGE  0x00808080
+#define GAM_GDP_PPT_IGNORE  (BIT(1) | BIT(0))
+#define GAM_GDP_SIZE_MAX0x7FF
+
+#define GDP_NODE_NB_BANK   2
+#define GDP_NODE_PER_FIELD 2
+
+struct sti_gdp_node {
+   u32 gam_gdp_ctl;
+   u32 gam_gdp_agc;
+   u32 reserved1;
+   u32 gam_gdp_vpo;
+   u32 gam_gdp_vps;
+   u32 gam_gdp_pml;
+   u32 gam_gdp_pmp;
+   u32 gam_gdp_size;
+   u32 reserved2;
+   u32 gam_gdp_nvn;
+   u32 gam_gdp_key1;
+   u32 gam_gdp_key2;
+   u32 reserved3;
+   u32 gam_gdp_ppt;
+   u32 reserved4;
+   u32 gam_gdp_cml;
+};
+
+struct sti_gdp_node_list {
+   struct sti_gdp_node *top_field;
+   struct sti_gdp_node *btm_field;
+};
+
+/**
+ * STI GDP structure
+ *
+ * @layer: layer structure
+ * @clk_pix:pixel clock for the current gdp
+ * @vtg_field_nb:   callback for VTG FIELD (top or bottom) notification
+ * @is_curr_top:true if the current node processed is the top field
+ * @node_list: array of node list
+ */
+struct sti_gdp {
+   struct sti_layer layer;
+   struct clk *clk_pix;
+   struct notifier_block vtg_field_nb;
+   bool is_curr_top;
+   struct sti_gdp_node_list node_list[GDP_NODE_NB_BANK];
+};
+
+#define to_sti_gdp(x) container_of(x, struct sti_gdp, layer)
+
+static const uint32_t gdp_supported_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_AYUV,
+   DRM_FORMAT_YUV444,
+   DRM_FORMAT_VYUY,
+   DRM_FORMAT_C8,
+};
+
+static const uint32_t *sti_gdp_get_formats(struct sti_layer *layer)
+{
+   return gdp_supported_formats;
+}
+
+static unsigned int sti_gdp_get_nb_formats(struct sti_layer *layer)
+{
+   return ARRAY_SIZE(gdp_supported_formats);
+}
+
+static int sti_gdp_fourcc2format(int fourcc)
+{
+   switch (fourcc) {
+   case DRM_FORMAT_XRGB:
+   return GDP_RGB888_32;
+   case DRM_FORMAT_ARGB:
+   return GDP_ARGB;
+   case DRM_FORMAT_ARGB:
+   return GDP_ARGB;
+   case DRM_FORMAT_ARGB1555:
+   return GDP_ARGB1555;
+   case DRM_FORMAT_RGB565:
+   return GDP_RGB565;
+   case DRM_FORMAT_RGB888:
+   

[PATCH v5 06/11] drm: sti: add TVOut driver

2014-06-18 Thread Benjamin Gaignard
TVout hardware block is responsible to dispatch the data flow coming
from compositor block to any of the output (HDMI or Analog TV).
It control when output are start/stop and configure according the
require flow path.

TVout is the parent of HDMI and HDA drivers and bind them at runtime.

Tvout is mapped on drm_encoder structure.
One encoder is created for each of the sub-devices and link to their
connector/bridge

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile|   3 +-
 drivers/gpu/drm/sti/sti_tvout.c | 657 
 2 files changed, 659 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sti/sti_tvout.c

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index df47171..dcc9568 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_DRM_STI) += \
sti_hdmi.o \
sti_hdmi_tx3g0c55phy.o \
sti_hdmi_tx3g4c28phy.o \
-   sti_hda.o
+   sti_hda.o \
+   sti_tvout.o
\ No newline at end of file
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
new file mode 100644
index 000..11008d9
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard 
+ *  Vincent Abriou 
+ *  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/* glue registers */
+#define TVO_CSC_MAIN_M0  0x000
+#define TVO_CSC_MAIN_M1  0x004
+#define TVO_CSC_MAIN_M2  0x008
+#define TVO_CSC_MAIN_M3  0x00c
+#define TVO_CSC_MAIN_M4  0x010
+#define TVO_CSC_MAIN_M5  0x014
+#define TVO_CSC_MAIN_M6  0x018
+#define TVO_CSC_MAIN_M7  0x01c
+#define TVO_MAIN_IN_VID_FORMAT   0x030
+#define TVO_CSC_AUX_M0   0x100
+#define TVO_CSC_AUX_M1   0x104
+#define TVO_CSC_AUX_M2   0x108
+#define TVO_CSC_AUX_M3   0x10c
+#define TVO_CSC_AUX_M4   0x110
+#define TVO_CSC_AUX_M5   0x114
+#define TVO_CSC_AUX_M6   0x118
+#define TVO_CSC_AUX_M7   0x11c
+#define TVO_AUX_IN_VID_FORMAT0x130
+#define TVO_VIP_HDF  0x400
+#define TVO_HD_SYNC_SEL  0x418
+#define TVO_HD_DAC_CFG_OFF   0x420
+#define TVO_VIP_HDMI 0x500
+#define TVO_HDMI_FORCE_COLOR_0   0x504
+#define TVO_HDMI_FORCE_COLOR_1   0x508
+#define TVO_HDMI_CLIP_VALUE_B_CB 0x50c
+#define TVO_HDMI_CLIP_VALUE_Y_G  0x510
+#define TVO_HDMI_CLIP_VALUE_R_CR 0x514
+#define TVO_HDMI_SYNC_SEL0x518
+#define TVO_HDMI_DFV_OBS 0x540
+
+#define TVO_IN_FMT_SIGNEDBIT(0)
+#define TVO_SYNC_EXT BIT(4)
+
+#define TVO_VIP_REORDER_R_SHIFT  24
+#define TVO_VIP_REORDER_G_SHIFT  20
+#define TVO_VIP_REORDER_B_SHIFT  16
+#define TVO_VIP_REORDER_MASK 0x3
+#define TVO_VIP_REORDER_Y_G_SEL  0
+#define TVO_VIP_REORDER_CB_B_SEL 1
+#define TVO_VIP_REORDER_CR_R_SEL 2
+
+#define TVO_VIP_CLIP_SHIFT   8
+#define TVO_VIP_CLIP_MASK0x7
+#define TVO_VIP_CLIP_DISABLED0
+#define TVO_VIP_CLIP_EAV_SAV 1
+#define TVO_VIP_CLIP_LIMITED_RANGE_RGB_Y 2
+#define TVO_VIP_CLIP_LIMITED_RANGE_CB_CR 3
+#define TVO_VIP_CLIP_PROG_RANGE  4
+
+#define TVO_VIP_RND_SHIFT4
+#define TVO_VIP_RND_MASK 0x3
+#define TVO_VIP_RND_8BIT_ROUNDED 0
+#define TVO_VIP_RND_10BIT_ROUNDED1
+#define TVO_VIP_RND_12BIT_ROUNDED2
+
+#define TVO_VIP_SEL_INPUT_MASK   0xf
+#define TVO_VIP_SEL_INPUT_MAIN   0x0
+#define TVO_VIP_SEL_INPUT_AUX0x8
+#define TVO_VIP_SEL_INPUT_FORCE_COLOR0xf
+#define TVO_VIP_SEL_INPUT_BYPASS_MASK0x1
+#define TVO_VIP_SEL_INPUT_BYPASSED   1
+
+#define TVO_SYNC_MAIN_VTG_SET_REF0x00
+#define TVO_SYNC_MAIN_VTG_SET_1  0x01
+#define TVO_SYNC_MAIN_VTG_SET_2  0x02
+#define TVO_SYNC_MAIN_VTG_SET_3  0x03
+#define TVO_SYNC_MAIN_VTG_SET_4  0x04
+#define TVO_SYNC_MAIN_VTG_SET_5  0x05
+#define TVO_SYNC_MAIN_VTG_SET_6  0x06
+#define TVO_SYNC_AUX_VTG_SET_REF 0x10
+#define TVO_SYNC_AUX_VTG_SET_1   0x11
+#define TVO_SYNC_AUX_VTG_SET_2   0x12
+#define TVO_SYNC_AUX_VTG_SET_3   0x13
+#define TVO_SYNC_AUX_VTG_SET_4   0x14
+#define TVO_SYNC_AUX_VTG_SET_5   0x15
+#define TVO_SYNC_AUX_VTG_SET_6   0x16
+
+#define TVO_SYNC_HD_DCS_SHIFT8
+
+#define ENCODER_MAIN_CRTC_MASK   BIT(0)
+
+/* enum listing the 

[PATCH v5 05/11] drm: sti: add HDA driver

2014-06-18 Thread Benjamin Gaignard
Add driver to support analog TV ouput.

HDA driver is mapped on drm_bridge and drm_connector structures.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile  |   3 +-
 drivers/gpu/drm/sti/sti_hda.c | 790 ++
 2 files changed, 792 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sti/sti_hda.c

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index 5521a85..df47171 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_DRM_STI) += \
sti_vtac.o \
sti_hdmi.o \
sti_hdmi_tx3g0c55phy.o \
-   sti_hdmi_tx3g4c28phy.o
\ No newline at end of file
+   sti_hdmi_tx3g4c28phy.o \
+   sti_hda.o
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
new file mode 100644
index 000..ff8cd6f
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -0,0 +1,790 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Fabien Dessenne  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/* HDformatter registers */
+#define HDA_ANA_CFG 0x
+#define HDA_ANA_SCALE_CTRL_Y0x0004
+#define HDA_ANA_SCALE_CTRL_CB   0x0008
+#define HDA_ANA_SCALE_CTRL_CR   0x000C
+#define HDA_ANA_ANC_CTRL0x0010
+#define HDA_ANA_SRC_Y_CFG   0x0014
+#define HDA_COEFF_Y_PH1_TAP123  0x0018
+#define HDA_COEFF_Y_PH1_TAP456  0x001C
+#define HDA_COEFF_Y_PH2_TAP123  0x0020
+#define HDA_COEFF_Y_PH2_TAP456  0x0024
+#define HDA_COEFF_Y_PH3_TAP123  0x0028
+#define HDA_COEFF_Y_PH3_TAP456  0x002C
+#define HDA_COEFF_Y_PH4_TAP123  0x0030
+#define HDA_COEFF_Y_PH4_TAP456  0x0034
+#define HDA_ANA_SRC_C_CFG   0x0040
+#define HDA_COEFF_C_PH1_TAP123  0x0044
+#define HDA_COEFF_C_PH1_TAP456  0x0048
+#define HDA_COEFF_C_PH2_TAP123  0x004C
+#define HDA_COEFF_C_PH2_TAP456  0x0050
+#define HDA_COEFF_C_PH3_TAP123  0x0054
+#define HDA_COEFF_C_PH3_TAP456  0x0058
+#define HDA_COEFF_C_PH4_TAP123  0x005C
+#define HDA_COEFF_C_PH4_TAP456  0x0060
+#define HDA_SYNC_AWGI   0x0300
+
+/* HDA_ANA_CFG */
+#define CFG_AWG_ASYNC_ENBIT(0)
+#define CFG_AWG_ASYNC_HSYNC_MTD BIT(1)
+#define CFG_AWG_ASYNC_VSYNC_MTD BIT(2)
+#define CFG_AWG_SYNC_DELBIT(3)
+#define CFG_AWG_FLTR_MODE_SHIFT 4
+#define CFG_AWG_FLTR_MODE_MASK  (0xF << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_AWG_FLTR_MODE_SD(0 << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_AWG_FLTR_MODE_ED(1 << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_AWG_FLTR_MODE_HD(2 << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_SYNC_ON_PBPR_MASK   BIT(8)
+#define CFG_PREFILTER_EN_MASK   BIT(9)
+#define CFG_PBPR_SYNC_OFF_SHIFT 16
+#define CFG_PBPR_SYNC_OFF_MASK  (0x7FF << CFG_PBPR_SYNC_OFF_SHIFT)
+#define CFG_PBPR_SYNC_OFF_VAL   0x117 /* Voltage dependent. stiH416 */
+
+/* Default scaling values */
+#define SCALE_CTRL_Y_DFLT   0x00C50256
+#define SCALE_CTRL_CB_DFLT  0x00DB0249
+#define SCALE_CTRL_CR_DFLT  0x00DB0249
+
+/* Video DACs control */
+#define VIDEO_DACS_CONTROL_MASK 0x0FFF
+#define VIDEO_DACS_CONTROL_SYSCFG2535   0x085C /* for stih416 */
+#define DAC_CFG_HD_OFF_SHIFT5
+#define DAC_CFG_HD_OFF_MASK (0x7 << DAC_CFG_HD_OFF_SHIFT)
+#define VIDEO_DACS_CONTROL_SYSCFG5072   0x0120 /* for stih407 */
+#define DAC_CFG_HD_HZUVW_OFF_MASK   BIT(1)
+
+
+/* Upsampler values for the alternative 2X Filter */
+#define SAMPLER_COEF_NB 8
+#define HDA_ANA_SRC_Y_CFG_ALT_2X0x0113
+static u32 coef_y_alt_2x[] = {
+   0x00FE83FB, 0x1F900401, 0x, 0x,
+   0x00F408F9, 0x055F7C25, 0x, 0x
+};
+
+#define HDA_ANA_SRC_C_CFG_ALT_2X0x01750004
+static u32 coef_c_alt_2x[] = {
+   0x001305F7, 0x05274BD0, 0x, 0x,
+   0x0004907C, 0x09C80B9D, 0x, 0x
+};
+
+/* Upsampler values for the 4X Filter */
+#define HDA_ANA_SRC_Y_CFG_4X0x01ED0005
+#define HDA_ANA_SRC_C_CFG_4X0x01ED0004
+static u32 coef_yc_4x[] = {
+   0x00FC827F, 0x008FE20B, 0x00F684FC, 0x050F7C24,
+   0x00F4857C, 0x0A1F402E, 0x00FA027F, 0x0E076E1D
+};
+
+/* AWG instructions for some video modes */
+#define AWG_MAX_INST64
+
+/* 720p at 50 */
+static u32 AWGi_720p_50[] = {
+   0x0971, 0x0C26, 0x013B, 0x0CDA,
+   0x0104, 0x0E7E, 0x0E7F, 0x013B,
+   0x0D8E, 0x0104, 0x1804, 0x0971,
+   0x0C26, 0x003B, 0x0FB4, 0x0FB5,
+   0x0104, 0x1AE8
+};
+
+#define NN_720p_50 

[PATCH v5 04/11] drm: sti: add HDMI driver

2014-06-18 Thread Benjamin Gaignard
Add driver for HDMI output.
HDMI PHY registers are mixed into HDMI device registers
and their is only one IRQ for all this hardware block.
That is why PHYs aren't using phy framework but only a
thin hdmi_phy_ops structure with start and stop functions.

HDMI driver is mapped on drm_bridge and drm_connector structures.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile   |   5 +-
 drivers/gpu/drm/sti/sti_hdmi.c | 808 +
 drivers/gpu/drm/sti/sti_hdmi.h |  88 
 drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.c | 336 
 drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.h |  14 +
 drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.c | 211 
 drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.h |  14 +
 7 files changed, 1475 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sti/sti_hdmi.c
 create mode 100644 drivers/gpu/drm/sti/sti_hdmi.h
 create mode 100644 drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.c
 create mode 100644 drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.h
 create mode 100644 drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.c
 create mode 100644 drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.h

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index 52e2e80..5521a85 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -1,3 +1,6 @@
 obj-$(CONFIG_DRM_STI) += \
sti_vtg.o \
-   sti_vtac.o
+   sti_vtac.o \
+   sti_hdmi.o \
+   sti_hdmi_tx3g0c55phy.o \
+   sti_hdmi_tx3g4c28phy.o
\ No newline at end of file
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
new file mode 100644
index 000..004c686
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -0,0 +1,808 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "sti_hdmi.h"
+#include "sti_hdmi_tx3g4c28phy.h"
+#include "sti_hdmi_tx3g0c55phy.h"
+#include "sti_vtg.h"
+
+#define HDMI_CFG0x
+#define HDMI_INT_EN 0x0004
+#define HDMI_INT_STA0x0008
+#define HDMI_INT_CLR0x000C
+#define HDMI_STA0x0010
+#define HDMI_ACTIVE_VID_XMIN0x0100
+#define HDMI_ACTIVE_VID_XMAX0x0104
+#define HDMI_ACTIVE_VID_YMIN0x0108
+#define HDMI_ACTIVE_VID_YMAX0x010C
+#define HDMI_DFLT_CHL0_DAT  0x0110
+#define HDMI_DFLT_CHL1_DAT  0x0114
+#define HDMI_DFLT_CHL2_DAT  0x0118
+#define HDMI_SW_DI_1_HEAD_WORD  0x0210
+#define HDMI_SW_DI_1_PKT_WORD0  0x0214
+#define HDMI_SW_DI_1_PKT_WORD1  0x0218
+#define HDMI_SW_DI_1_PKT_WORD2  0x021C
+#define HDMI_SW_DI_1_PKT_WORD3  0x0220
+#define HDMI_SW_DI_1_PKT_WORD4  0x0224
+#define HDMI_SW_DI_1_PKT_WORD5  0x0228
+#define HDMI_SW_DI_1_PKT_WORD6  0x022C
+#define HDMI_SW_DI_CFG  0x0230
+
+#define HDMI_IFRAME_SLOT_AVI1
+
+#define  XCAT(prefix, x, suffix)prefix ## x ## suffix
+#define  HDMI_SW_DI_N_HEAD_WORD(x)  XCAT(HDMI_SW_DI_, x, _HEAD_WORD)
+#define  HDMI_SW_DI_N_PKT_WORD0(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD0)
+#define  HDMI_SW_DI_N_PKT_WORD1(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD1)
+#define  HDMI_SW_DI_N_PKT_WORD2(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD2)
+#define  HDMI_SW_DI_N_PKT_WORD3(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD3)
+#define  HDMI_SW_DI_N_PKT_WORD4(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD4)
+#define  HDMI_SW_DI_N_PKT_WORD5(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD5)
+#define  HDMI_SW_DI_N_PKT_WORD6(x)  XCAT(HDMI_SW_DI_, x, _PKT_WORD6)
+
+#define HDMI_IFRAME_DISABLED0x0
+#define HDMI_IFRAME_SINGLE_SHOT 0x1
+#define HDMI_IFRAME_FIELD   0x2
+#define HDMI_IFRAME_FRAME   0x3
+#define HDMI_IFRAME_MASK0x3
+#define HDMI_IFRAME_CFG_DI_N(x, n)   ((x) << ((n-1)*4)) /* n from 1 to 6 */
+
+#define HDMI_CFG_DEVICE_EN  BIT(0)
+#define HDMI_CFG_HDMI_NOT_DVI   BIT(1)
+#define HDMI_CFG_HDCP_ENBIT(2)
+#define HDMI_CFG_ESS_NOT_OESS   BIT(3)
+#define HDMI_CFG_H_SYNC_POL_NEG BIT(4)
+#define HDMI_CFG_SINK_TERM_DET_EN   BIT(5)
+#define HDMI_CFG_V_SYNC_POL_NEG BIT(6)
+#define HDMI_CFG_422_EN BIT(8)
+#define HDMI_CFG_FIFO_OVERRUN_CLR   BIT(12)
+#define HDMI_CFG_FIFO_UNDERRUN_CLR  BIT(13)
+#define HDMI_CFG_SW_RST_EN  BIT(31)
+
+#define HDMI_INT_GLOBAL BIT(0)
+#define HDMI_INT_SW_RST BIT(1)
+#define HDMI_INT_PIX_CAPBIT(3)
+#define HDMI_INT_HOT_PLUG   BIT(4)
+#define HDMI_INT_DLL_LCKBIT(5)
+#define HDMI_INT_NEW_FRAME  

[PATCH v5 03/11] drm: sti: add VTAC drivers

2014-06-18 Thread Benjamin Gaignard
Video Traffic Advance Communication Rx and Tx drivers are designed
for inter-die communication.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/sti/Makefile   |   3 +-
 drivers/gpu/drm/sti/sti_vtac.c | 211 +
 2 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sti/sti_vtac.c

diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index 3658a13e..52e2e80 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_DRM_STI) += \
-   sti_vtg.o
+   sti_vtg.o \
+   sti_vtac.o
diff --git a/drivers/gpu/drm/sti/sti_vtac.c b/drivers/gpu/drm/sti/sti_vtac.c
new file mode 100644
index 000..5226a04
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vtac.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard  for 
STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+/* registers offset */
+#define VTAC_CONFIG 0x00
+#define VTAC_RX_FIFO_CONFIG 0x04
+#define VTAC_FIFO_CONFIG_VAL0x04
+
+#define VTAC_SYS_CFG85210x824
+#define VTAC_SYS_CFG85220x828
+
+/* Number of phyts per pixel */
+#define VTAC_2_5_PPP0x0005
+#define VTAC_3_PPP  0x0006
+#define VTAC_4_PPP  0x0008
+#define VTAC_5_PPP  0x000A
+#define VTAC_6_PPP  0x000C
+#define VTAC_13_PPP 0x001A
+#define VTAC_14_PPP 0x001C
+#define VTAC_15_PPP 0x001E
+#define VTAC_16_PPP 0x0020
+#define VTAC_17_PPP 0x0022
+#define VTAC_18_PPP 0x0024
+
+/* enable bits */
+#define VTAC_ENABLE 0x3003
+
+#define VTAC_TX_PHY_ENABLE_CLK_PHY  BIT(0)
+#define VTAC_TX_PHY_ENABLE_CLK_DLL  BIT(1)
+#define VTAC_TX_PHY_PLL_NOT_OSC_MODEBIT(3)
+#define VTAC_TX_PHY_RST_N_DLL_SWITCHBIT(4)
+#define VTAC_TX_PHY_PROG_N3 BIT(9)
+
+
+/**
+ * VTAC mode structure
+ *
+ * @vid_in_width: Video Data Resolution
+ * @phyts_width: Width of phyt buses(phyt low and phyt high).
+ * @phyts_per_pixel: Number of phyts sent per pixel
+ */
+struct sti_vtac_mode {
+   u32 vid_in_width;
+   u32 phyts_width;
+   u32 phyts_per_pixel;
+};
+
+static const struct sti_vtac_mode vtac_mode_main = {0x2, 0x2, VTAC_5_PPP};
+static const struct sti_vtac_mode vtac_mode_aux = {0x1, 0x0, VTAC_17_PPP};
+
+/**
+ * VTAC structure
+ *
+ * @dev: pointer to device structure
+ * @regs: ioremapped registers for RX and TX devices
+ * @phy_regs: phy registers for TX device
+ * @clk: clock
+ * @mode: main or auxillary configuration mode
+ */
+struct sti_vtac {
+   struct device *dev;
+   void __iomem *regs;
+   void __iomem *phy_regs;
+   struct clk *clk;
+   const struct sti_vtac_mode *mode;
+};
+
+static void sti_vtac_rx_set_config(struct sti_vtac *vtac)
+{
+   u32 config;
+
+   /* Enable VTAC clock */
+   if (clk_prepare_enable(vtac->clk))
+   DRM_ERROR("Failed to prepare/enable vtac_rx clock.\n");
+
+   writel(VTAC_FIFO_CONFIG_VAL, vtac->regs + VTAC_RX_FIFO_CONFIG);
+
+   config = VTAC_ENABLE;
+   config |= vtac->mode->vid_in_width << 4;
+   config |= vtac->mode->phyts_width << 16;
+   config |= vtac->mode->phyts_per_pixel << 23;
+   writel(config, vtac->regs + VTAC_CONFIG);
+}
+
+static void sti_vtac_tx_set_config(struct sti_vtac *vtac)
+{
+   u32 phy_config;
+   u32 config;
+
+   /* Enable VTAC clock */
+   if (clk_prepare_enable(vtac->clk))
+   DRM_ERROR("Failed to prepare/enable vtac_tx clock.\n");
+
+   /* Configure vtac phy */
+   phy_config = 0x;
+   writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8522);
+   phy_config = VTAC_TX_PHY_ENABLE_CLK_PHY;
+   writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config |= VTAC_TX_PHY_PROG_N3;
+   writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config |= VTAC_TX_PHY_ENABLE_CLK_DLL;
+   writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config |= VTAC_TX_PHY_RST_N_DLL_SWITCH;
+   writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+   phy_config |= VTAC_TX_PHY_PLL_NOT_OSC_MODE;
+   writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+
+   /* Configure vtac tx */
+   config = VTAC_ENABLE;
+   config |= vtac->mode->vid_in_width << 4;
+   config |= vtac->mode->phyts_width << 16;
+   config |= 

[PATCH v5 02/11] drm: sti: add VTG driver

2014-06-18 Thread Benjamin Gaignard
Video Time Generator drivers are used to synchronize the compositor
and tvout hardware IPs by providing line count, sample count,
synchronization signals (HSYNC, VSYNC) and top and bottom fields
indication.
VTG are used by pair for each data path (main or auxiliary)
one for master and one for slave.

Signed-off-by: Benjamin Gaignard 
---
 drivers/gpu/drm/Kconfig   |   2 +
 drivers/gpu/drm/Makefile  |   1 +
 drivers/gpu/drm/sti/Kconfig   |   5 +
 drivers/gpu/drm/sti/Makefile  |   2 +
 drivers/gpu/drm/sti/sti_vtg.c | 356 ++
 drivers/gpu/drm/sti/sti_vtg.h |  28 
 6 files changed, 394 insertions(+)
 create mode 100644 drivers/gpu/drm/sti/Kconfig
 create mode 100644 drivers/gpu/drm/sti/Makefile
 create mode 100644 drivers/gpu/drm/sti/sti_vtg.c
 create mode 100644 drivers/gpu/drm/sti/sti_vtg.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index d1cc2f6..0e30029 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -201,3 +201,5 @@ source "drivers/gpu/drm/tegra/Kconfig"
 source "drivers/gpu/drm/panel/Kconfig"

 source "drivers/gpu/drm/bridge/Kconfig"
+
+source "drivers/gpu/drm/sti/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 5e792b0..44f7b17 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_DRM_QXL) += qxl/
 obj-$(CONFIG_DRM_BOCHS) += bochs/
 obj-$(CONFIG_DRM_MSM) += msm/
 obj-$(CONFIG_DRM_TEGRA) += tegra/
+obj-$(CONFIG_DRM_STI) += sti/
 obj-y  += i2c/
 obj-y  += panel/
 obj-y  += bridge/
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
new file mode 100644
index 000..cbd664b
--- /dev/null
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -0,0 +1,5 @@
+config DRM_STI
+   bool "DRM Support for STMicroelectronics SoC stiH41x Series"
+   depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
+   help
+ Choose this option to enable DRM on STM stiH41x chipset
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
new file mode 100644
index 000..3658a13e
--- /dev/null
+++ b/drivers/gpu/drm/sti/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_DRM_STI) += \
+   sti_vtg.o
diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c
new file mode 100644
index 000..49f95d4
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vtg.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard 
+ *  Fabien Dessenne 
+ *  Vincent Abriou 
+ *  for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "sti_vtg.h"
+
+#define VTG_TYPE_MASTER 0
+#define VTG_TYPE_SLAVE_BY_EXT0  1
+
+/* registers offset */
+#define VTG_MODE0x
+#define VTG_CLKLN   0x0008
+#define VTG_HLFLN   0x000C
+#define VTG_DRST_AUTOC  0x0010
+#define VTG_VID_TFO 0x0040
+#define VTG_VID_TFS 0x0044
+#define VTG_VID_BFO 0x0048
+#define VTG_VID_BFS 0x004C
+
+#define VTG_HOST_ITS0x0078
+#define VTG_HOST_ITS_BCLR   0x007C
+#define VTG_HOST_ITM_BCLR   0x0088
+#define VTG_HOST_ITM_BSET   0x008C
+
+#define VTG_H_HD_1  0x00C0
+#define VTG_TOP_V_VD_1  0x00C4
+#define VTG_BOT_V_VD_1  0x00C8
+#define VTG_TOP_V_HD_1  0x00CC
+#define VTG_BOT_V_HD_1  0x00D0
+
+#define VTG_H_HD_2  0x00E0
+#define VTG_TOP_V_VD_2  0x00E4
+#define VTG_BOT_V_VD_2  0x00E8
+#define VTG_TOP_V_HD_2  0x00EC
+#define VTG_BOT_V_HD_2  0x00F0
+
+#define VTG_H_HD_3  0x0100
+#define VTG_TOP_V_VD_3  0x0104
+#define VTG_BOT_V_VD_3  0x0108
+#define VTG_TOP_V_HD_3  0x010C
+#define VTG_BOT_V_HD_3  0x0110
+
+#define VTG_IRQ_BOTTOM  BIT(0)
+#define VTG_IRQ_TOP BIT(1)
+#define VTG_IRQ_MASK(VTG_IRQ_TOP | VTG_IRQ_BOTTOM)
+
+/* delay introduced by the Arbitrary Waveform Generator in nb of pixels */
+#define AWG_DELAY_HD(-9)
+#define AWG_DELAY_ED(-8)
+#define AWG_DELAY_SD(-7)
+
+LIST_HEAD(vtg_lookup);
+
+/**
+ * STI VTG structure
+ *
+ * @dev: pointer to device driver
+ * @data: data associated to the device
+ * @irq: VTG irq
+ * @type: VTG type (main or aux)
+ * @notifier_list: notifier callback
+ * @crtc_id: the crtc id for vblank event
+ * @slave: slave vtg
+ * @link: List node to link the structure in lookup list
+ */
+struct sti_vtg {
+   struct device *dev;
+   struct device_node *np;
+   void __iomem *regs;
+   int irq;
+   u32 irq_status;
+   struct raw_notifier_head notifier_list;
+   int crtc_id;
+   struct sti_vtg *slave;
+   struct list_head link;
+};
+
+static void vtg_register(struct sti_vtg *vtg)
+{
+   list_add_tail(>link, _lookup);
+}
+
+struct sti_vtg *of_vtg_find(struct device_node *np)
+{
+   struct sti_vtg *vtg;
+
+   

[PATCH v5 01/11] drm: sti: add bindings for DRM driver

2014-06-18 Thread Benjamin Gaignard
Add DRM/KMS driver bindings documentation.
Describe the required properties for each of the hardware IPs drivers.

Signed-off-by: Benjamin Gaignard 
---
 .../devicetree/bindings/gpu/st,stih4xx.txt | 189 +
 drivers/gpu/drm/sti/NOTES  |  58 +++
 2 files changed, 247 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/st,stih4xx.txt
 create mode 100644 drivers/gpu/drm/sti/NOTES

diff --git a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt 
b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
new file mode 100644
index 000..59a59a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
@@ -0,0 +1,189 @@
+STMicroelectronics stih4xx platforms
+
+- sti-vtg: video timing generator
+  Required properties:
+  - compatible: "st,vtg"
+  - reg: Physical base address of the IP registers and length of memory mapped 
region.
+  Optional properties:
+  - interrupts : VTG interrupt number to the CPU.
+  - st,slave: phandle on a slave vtg
+
+- sti-vtac: video timing advanced inter dye communication Rx and TX
+  Required properties:
+  - compatible: "st,vtac-main" or "st,vtac-aux"
+  - reg: Physical base address of the IP registers and length of memory mapped 
region.
+  - clocks: from common clock binding: handle hardware IP needed clocks, the
+number of clocks may depend of the SoC type.
+See ../clocks/clock-bindings.txt for details.
+  - clock-names: names of the clocks listed in clocks property in the same
+order.
+
+- sti-display-subsystem: Master device for DRM sub-components
+  This device must be the parent of all the sub-components and is responsible
+  of bind them.
+  Required properties:
+  - compatible: "st,sti-display-subsystem"
+  - ranges: to allow probing of subdevices
+
+- sti-compositor: frame compositor engine
+  must be a child of sti-display-subsystem
+  Required properties:
+  - compatible: "st,stih-compositor"
+  - reg: Physical base address of the IP registers and length of memory mapped 
region.
+  - clocks: from common clock binding: handle hardware IP needed clocks, the
+number of clocks may depend of the SoC type.
+See ../clocks/clock-bindings.txt for details.
+  - clock-names: names of the clocks listed in clocks property in the same
+order.
+  - resets: resets to be used by the device
+See ../reset/reset.txt for details.
+  - reset-names: names of the resets listed in resets property in the same
+order.
+  - st,vtg: phandle(s) on vtg device (main and aux) nodes.
+
+- sti-tvout: video out hardware block
+  must be a child of sti-display-subsystem
+  Required properties:
+  - compatible: "st,stih-tvout"
+  - reg: Physical base address of the IP registers and length of memory mapped 
region.
+  - reg-names: names of the mapped memory regions listed in regs property in
+the same order.
+  - resets: resets to be used by the device
+See ../reset/reset.txt for details.
+  - reset-names: names of the resets listed in resets property in the same
+order.
+  - ranges: to allow probing of subdevices
+
+- sti-hdmi: hdmi output block
+  must be a child of sti-tvout
+  Required properties:
+  - compatible: "st,stih-hdmi";
+  - reg: Physical base address of the IP registers and length of memory mapped 
region.
+  - reg-names: names of the mapped memory regions listed in regs property in
+the same order.
+  - interrupts : HDMI interrupt number to the CPU.
+  - interrupt-names: name of the interrupts listed in interrupts property in
+the same order
+  - clocks: from common clock binding: handle hardware IP needed clocks, the
+number of clocks may depend of the SoC type.
+  - clock-names: names of the clocks listed in clocks property in the same
+order.
+  - hdmi,hpd-gpio: gpio id to detect if an hdmi cable is plugged or not.
+
+sti-hda:
+  Required properties:
+  must be a child of sti-tvout
+  - compatible: "st,stih-hda"
+  - reg: Physical base address of the IP registers and length of memory mapped 
region.
+  - reg-names: names of the mapped memory regions listed in regs property in
+the same order.
+  - clocks: from common clock binding: handle hardware IP needed clocks, the
+number of clocks may depend of the SoC type.
+See ../clocks/clock-bindings.txt for details.
+  - clock-names: names of the clocks listed in clocks property in the same
+order.
+
+Example:
+
+/ {
+   ...
+
+   vtg_main_slave: sti-vtg-main-slave at fe85A800 {
+   compatible  = "st,vtg";
+   reg = <0xfe85A800 0x300>;
+   interrupts  = ;
+   };
+
+   vtg_main: sti-vtg-main-master at fd348000 {
+   compatible  = "st,vtg";
+   reg = <0xfd348000 0x400>;
+   st,slave= <_main_slave>;
+   };
+
+   vtg_aux_slave: sti-vtg-aux-slave at fd348400 {
+   compatible  = "st,vtg";
+   reg = <0xfe858200 

[PATCH v5 00/11] Add DRM for stih4xx platforms

2014-06-18 Thread Benjamin Gaignard
This series of patches add the support of DRM/KMS drivers for STMicroelectronics
chipsets stih416 and stih407.

version 5:
- Rework sti_drm_drv probes functions to support deferred probe.
  This allow hdmi to delayed framebuffer creation until I2C is 
available.
- Add ops functsions in sti_layer structure to simpify GDP and VID code.
- Add NOTES file to describe how the DRM concepts are mapped on 
hardware.

patches could be found here: 
git://git.linaro.org/people/benjamin.gaignard/kernel.git
on branch: drm_kms_for_next-v5

version 4:
- Remove depency between TVout it subdevices HDMI and HDA
- Rework and simplify VTG and VTAC code
- Fix numbers of typo and indentation
- Remove debug (will be push in separate patches)
- Fix remarks done in previous patcheset

patches could be found here: 
git://git.linaro.org/people/benjamin.gaignard/kernel.git
on branch: drm_kms_for_next-v4

version 3:
- Correctly split code between probe and bind funtions
- Squash some commits
- remove HQ-VDP device code to have a smaller patcheset,
  we will introduce it later.

patches could be found here: 
git://git.linaro.org/people/benjamin.gaignard/kernel.git
on branch: drm_kms_for_next-v3

version 2:
- Use componentized device instead of register sub-devices in master
driver probe function
- Fix Makefile and Kconfig to only allow built-in compilation

patches could be found here: 
git://git.linaro.org/people/benjamin.gaignard/kernel.git
on branch: drm_kms_for_next-v2

version 1:
- First path submission

Hardware is split in two main blocks: Compositor and TVout. Each of them
includes specific hardware IPs and the display timing are controlled by a 
specific
Video Timing Generator hardware IP (VTG).

Compositor is made of the follow hardware IPs:
 - GDP (Generic Display Pipeline) which is an entry point for graphic (RGB)
   buffers
 - VDP (Video Diplay Pipeline) which is an entry point for video (YUV) buffers
 - HQVDP (High Quality Video Display Processor) that supports scaling,
   deinterlacing and some miscellaneous image quality improvements.
   It fetches the Video decoded buffers from memory, processes them and pushes
   them to the Compositor through a HW dedicated bus.
 - Mixer is responsible of mixing all the entries depending of their
   respective z-order and layout

TVout is divided in 3 parts:
 - HDMI to generate HDMI signals, depending of chipset version HDMI phy can
   change.
 - HDA to generate signals for HD analog TV
 - VIP to control/switch data path coming from Compositor

On stih416 compositor and Tvout are on different dies so a Video Trafic Advance
inter-die Communication mechanism (VTAC) is needed.

+-+   
++
| +---+   ++  |   |  ++   
+--+ |
| |   |   ||  |   |  ||   |  +-+
 ++  | |
| | ++  +--+  |   ||  |   |  ||   |  | VIP 
|>|HDMI|  | |
| | |GPD +->|  |  |   ||  |   |  ||   |  | |
 ++  | |
| | ++  |Mixer |--|-->||  |   |  ||---|->| switcher|
 | |
| | |  |  |   ||  |   |  ||   |  | |
 ++  | |
| | |  |  |   ||  |   |  ||   |  | 
|>|HDA |  | |
| | +--+  |   |VTAC|>|VTAC|   |  +-+
 ++  | |
| |   |   ||  |   |  ||   | 
 | |
| | Compositor|   ||  |   |  ||   |   TVout 
 | |
| +---+   ||  |   |  ||   
+--+ |
|  ^  ||  |   |  || ^   
   |
|  |  ||  |   |  || |   
   |
|   +--+  ||  |   |  ||  
+-+   |
|   | VTG (master) |->||  |   |  ||->| VTG (slave) 
|   |
|   +--+  ++  |   |  ++  
+-+   |
|Digital die  |   | 
 Analog Die|
+-+   
++

On stih407 Compositor and Tvout are on the same die

+-+
| +---+  +--+ |
| |   |  |  +-+ ++  | |
| | ++  +--+  |  |  | VIP |>|HDMI|  | |
| | |GPD +->|  |  |  |  |  

[PATCH] drm/exynos: dpi: Fix NULL pointer dereference with legacy bindings

2014-06-18 Thread Jingoo Han
On Wednesday, June 11, 2014 5:58 AM, Tomasz Figa wrote:
> 
> If there is no panel node in DT and instead display timings are provided
> directly in FIMD node, there is no panel object created and ctx->panel
> becomes NULL. However during Exynos DRM initialization
> drm_helper_hpd_irq_event() is called, which in turns calls
> exynos_dpi_detect(), which dereferences ctx->panel without a check,
> causing a NULL pointer derefrence.
> 
> This patch fixes the issue by adding necessary NULL pointer check.
> 
> Signed-off-by: Tomasz Figa 

(+cc Inki Dae)

Reviewed-by: Jingoo Han 

Best regards,
Jingoo Han

> ---
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c 
> b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> index f1b8587..f44bd90 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> @@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool 
> force)
>  {
>   struct exynos_dpi *ctx = connector_to_dpi(connector);
> 
> - if (!ctx->panel->connector)
> + if (ctx->panel && !ctx->panel->connector)
>   drm_panel_attach(ctx->panel, >connector);
> 
>   return connector_status_connected;
> --



Radeon drivers on PowerPC (e500)

2014-06-18 Thread Martyn Welch


On 18/06/14 02:48, Benjamin Herrenschmidt wrote:
> On Wed, 2014-06-18 at 11:05 +1000, Dave Airlie wrote:
>>
>> I don't think we ever ioremap GART, it should kmap GART pages, ioremap
>> should only happen for VRAM areas AFAIK,
>>
>> This isn't some 32-bit vs 36-bit BAR or something, I seem to remember BenH
>> mentioning something like that before.
>
> Yes, it's a recurring problem in the DRM with physical addresses that are
> bigger than 32-bit on 32-bit systems. There have been patches done to
> fix that but afaik never quite "completed". I can dig internally if
> I can put my hand onto something.
>

Thanks Ben, that would be much appreciated.

> If possible at all, can you try to configure your SoC to bring the MMIO
> space of the PCIe within the bottom 32-bit of the chip address space ?
>

Will give it a try.

Thanks again,

Martyn

-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms   | (3828642) at 100 Barbirolli Square
T +44(0)1327322748 | Manchester, M2 3AB
E martyn.welch at ge.com  | VAT:GB 927559189


Radeon drivers on PowerPC (e500)

2014-06-18 Thread Martyn Welch


On 18/06/14 02:05, Dave Airlie wrote:
> On 18 June 2014 05:14, Martyn Welch  wrote:
>> Hi,
>>
>> I've been asked to try and get a r600 based (E6460) graphics card running on
>> a machine powered by a Freescale p4080 (e500 core). I've run into a bit of a
>> problem.
>>
>> I have the driver built into the kernel at this point. When I boot the card
>> is detected and it seems to be finding the fimware (I'm also building in the
>> required firmware blobs), but I get the following messages:
>>
>> [drm] Initialized drm 1.1.0 20060810
>> [drm] radeon defaulting to kernel modesetting.
>> [drm] radeon kernel modesetting enabled.
>> [drm] initializing kernel modesetting (CAICOS 0x1002:0x6763 0x1775:0xC6A7).
>> [drm] register mmio base: 0x1000
>> [drm] register mmio size: 131072
>> ATOM BIOS: GE
>> [drm] GPU not posted. posting now...
>> radeon :04:00.0: VRAM: 512M 0x - 0x1FFF
>> (512M used)
>> radeon :04:00.0: GTT: 512M 0x2000 - 0x3FFF
>> [drm] Detected VRAM RAM=512M, BAR=256M
>> [drm] RAM width 64bits DDR
>> [TTM] Zone  kernel: Available graphics memory: 338754 kiB
>> [TTM] Zone highmem: Available graphics memory: 994110 kiB
>> [TTM] Initializing pool allocator
>> [TTM] Initializing DMA pool allocator
>> [drm] radeon: 512M of VRAM memory ready
>> [drm] radeon: 512M of GTT memory ready.
>> [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
>> [drm] Driver supports precise vblank timestamp query.
>> radeon :04:00.0: radeon: using MSI.
>> [drm] radeon: irq initialized.
>> [drm] GART: num cpu pages 131072, num gpu pages 131072
>> [drm] probing gen 2 caps for device 111d:808a = 2/0
>> [drm] enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0
>> [drm] Loading CAICOS Microcode
>> __ioremap_caller(14, 4096, 4194304, c02eab20)__ioremap(): phys addr
>> 0x14 is RAM lr ttm_bo_kmap
>> radeon :04:00.0: disabling GPU acceleration
>> radeon :04:00.0: e957e400 unpin not necessary
>> radeon :04:00.0: e957e400 unpin not necessary
>> [drm] Radeon Display Connectors
>> [drm] Connector 0:
>> [drm]   DP-1
>> [drm]   HPD2
>> [drm]   HPD3
>> [drm]   DDC: 0x6450 0x6450 0x6454 0x6454 0x6458 0x6458 0x645c 0x645c
>> [drm]   Encoders:
>> [drm] DFP2: INTERNAL_UNIPHY1
>> [drm] Connector 2:
>> [drm]   DVI-I-1
>> [drm]   HPD1
>> [drm]   DDC: 0x6430 0x6430 0x6434 0x6434 0x6438 0x6438 0x643c 0x643c
>> [drm]   Encoders:
>> [drm] DFP3: INTERNAL_UNIPHY
>> [drm] CRT1: INTERNAL_KLDSCP_DAC1
>> [drm] Internal thermal controller with fan control
>> [drm] radeon: power management initialized
>> __ioremap_caller(141000, 5242880, 4194304, c02eab20)__ioremap(): phys addr
>> 0x141000 is RAM lr ttm_bo_kmap
>> [drm:radeonfb_create] *ERROR* failed to create fbcon object -12
>> [drm] Initialized radeon 2.29.0 20080528 for :04:00.0 on minor 0
>>
>> There are failed attempts to ioremap RAM, initially as part of
>> r600_vram_scratch_init() and again I guess mapping the GART?
>>
>> On the e500, overlapping TLBs are not allowed and there is an explict check
>> in arch/powerpc/mm/pgtable_32.c __ioremap_caller() to protect against
>> ioremapping RAM that's already got TLB entries which is resulting in the
>> error messages.
>
> I don't think we ever ioremap GART, it should kmap GART pages, ioremap
> should only happen for VRAM areas AFAIK,
>

Ah, quite possibly, I hadn't looked in any depth further than the 
initial failure with r600_vram_scratch_init() as that was going to be a 
bit of a blocker.

> This isn't some 32-bit vs 36-bit BAR or something, I seem to remember BenH
> mentioning something like that before.
>

Thanks Dave.

Martyn

-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms   | (3828642) at 100 Barbirolli Square
T +44(0)1327322748 | Manchester, M2 3AB
E martyn.welch at ge.com  | VAT:GB 927559189


[REGRESSION] drm/g94/i2c: add aux channel interrupt driver

2014-06-18 Thread Ben Skeggs
On Wed, Jun 18, 2014 at 12:38 AM, Maarten Lankhorst
 wrote:
> Hey,
>
> This patch causes a regression on my display-less nvd7.
> Commenting out the aux, aux_stat and aux_mask members in nvd0_i2c_oclass 
> fixes boot, and makes things work normally again.
>
Hey Maarten,

Yeah that probably makes sense that those regs aren't there, no idea
how it breaks gr though :P  I'll push a fix, sorry for that.

Ben.

> broken dmesg:
>
> [   40.314470] ACPI Warning: \_SB_.PCI0.GFX0._DSM: Argument #4 type mismatch 
> - Found [Buffer], ACPI requires [Package] (20140424/nsarguments-95)
> [   40.314729] ACPI Warning: \_SB_.PCI0.GFX0._DSM: Argument #4 type mismatch 
> - Found [Buffer], ACPI requires [Package] (20140424/nsarguments-95)
> [   40.314963] i915 :00:02.0: optimus capabilities: enabled, status 
> dynamic power,
> [   40.315001] ACPI Warning: \_SB_.PCI0.PEG0.PEGP._DSM: Argument #4 type 
> mismatch - Found [Buffer], ACPI requires [Package] (20140424/nsarguments-95)
> [   40.315198] ACPI Warning: \_SB_.PCI0.PEG0.PEGP._DSM: Argument #4 type 
> mismatch - Found [Buffer], ACPI requires [Package] (20140424/nsarguments-95)
> [   40.315386] pci :01:00.0: optimus capabilities: enabled, status 
> dynamic power,
> [   40.315392] VGA switcheroo: detected Optimus DSM method 
> \_SB_.PCI0.PEG0.PEGP handle
> [   40.315652] nouveau D[ DRM] hdmi device not found 1 0 1
> [   40.315695] nouveau  [  DEVICE][:01:00.0] BOOT0  : 0x0d7000a2
> [   40.315698] nouveau  [  DEVICE][:01:00.0] Chipset: GF117 (NVD7)
> [   40.315700] nouveau  [  DEVICE][:01:00.0] Family : NVD0
> [   40.315703] nouveau D[  DEVICE][:01:00.0] crystal freq: 27000KHz
> [   40.315724] nouveau  [   VBIOS][:01:00.0] checking PRAMIN for image...
> [   40.315728] nouveau  [   VBIOS][:01:00.0] ... signature not found
> [   40.315730] nouveau  [   VBIOS][:01:00.0] checking PROM for image...
> [   40.315787] nouveau  [   VBIOS][:01:00.0] ... signature not found
> [   40.315788] nouveau  [   VBIOS][:01:00.0] checking ACPI for image...
> [   40.361066] init: Failed to obtain startpar-bridge instance: Unknown 
> parameter: INSTANCE
> [   40.505222] ieee80211 phy0: Selected rate control algorithm 'iwl-agn-rs'
> [   41.547821] snd_hda_intel :00:1b.0: irq 47 for MSI/MSI-X
> [   41.695435] nouveau  [   VBIOS][:01:00.0] ... appears to be valid
> [   41.695441] nouveau  [   VBIOS][:01:00.0] using image from ACPI
> [   41.695539] nouveau  [   VBIOS][:01:00.0] BIT signature found
> [   41.695543] nouveau  [   VBIOS][:01:00.0] version 75.17.53.00.12
> [   41.695746] nouveau D[   VBIOS][:01:00.0] reset
> [   41.695751] nouveau D[ DEVINIT][:01:00.0] reset
> [   41.695753] nouveau  [   VBIOS][:01:00.0] running init tables
> [   41.695884] nouveau D[ I2C][:01:00.0] PAD:X:03: -> PORT:03
> [   41.697027] nouveau D[ I2C][:01:00.0] PAD:X:03: -> NULL
> [   41.697030] nouveau D[ I2C][:01:00.0] PAD:X:03: -> PORT:03
> [   41.698124] nouveau D[ I2C][:01:00.0] PAD:X:03: -> NULL
> [   41.698126] nouveau D[ I2C][:01:00.0] PAD:X:03: -> PORT:03
> [   41.699239] nouveau D[ I2C][:01:00.0] PAD:X:03: -> NULL
> [   41.699242] nouveau D[ I2C][:01:00.0] PAD:X:03: -> PORT:03
> [   41.700337] nouveau D[ I2C][:01:00.0] PAD:X:03: -> NULL
> [   41.704845] sound hdaudioC0D0: autoconfig: line_outs=1 
> (0x14/0x0/0x0/0x0/0x0) type:speaker
> [   41.704848] sound hdaudioC0D0:speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
> [   41.704850] sound hdaudioC0D0:hp_outs=1 (0x15/0x0/0x0/0x0/0x0)
> [   41.704851] sound hdaudioC0D0:mono: mono_out=0x0
> [   41.704852] sound hdaudioC0D0:inputs:
> [   41.704854] sound hdaudioC0D0:  Mic=0x1a
> [   41.704856] sound hdaudioC0D0:  Internal Mic=0x19
> [   41.783610] nouveau D[GPIO][:01:00.0] reset
> [   41.783616] nouveau D[ I2C][:01:00.0] PAD:X:03: -> NULL
> [   41.783618] nouveau D[ I2C][:01:00.0] PAD:X:05: -> NULL
> [   41.784591] nouveau D[ I2C][:01:00.0] reset
> [   41.784596] nouveau D[ MXM][:01:00.0] no VBIOS data, nothing to do
> [   41.784599] nouveau D[ MXM][:01:00.0] reset
> [   41.784619] nouveau :01:00.0: irq 48 for MSI/MSI-X
> [   41.784634] nouveau  [ PMC][:01:00.0] MSI interrupts enabled
> [   41.784655] nouveau D[ PMC][:01:00.0] reset
> [   41.784658] nouveau D[PBUS][:01:00.0] reset
> [   41.784660] nouveau D[  PTIMER][:01:00.0] reset
> [   41.784662] nouveau D[  PTIMER][:01:00.0] input frequency : 27000Hz
> [   41.784663] nouveau D[  PTIMER][:01:00.0] input multiplier: 3
> [   41.784665] nouveau D[  PTIMER][:01:00.0] numerator   : 0x0144
> [   41.784666] nouveau D[  PTIMER][:01:00.0] denominator : 0x007d
> [   41.784668] nouveau D[  PTIMER][:01:00.0] timer frequency : 31250Hz
> [   41.784669] nouveau D[  PTIMER][:01:00.0] time low: 0x
> [   41.784670] nouveau D[  PTIMER][:01:00.0] 

[PATCH 1/2] x86, ia64: Move EFI_FB vga_default_device() initialization to pci_vga_fixup()

2014-06-18 Thread Bruno Prémont
On Tue, 17 Jun 2014 16:35:42 -0600 Bjorn Helgaas wrote:
> On Mon, Jun 02, 2014 at 08:19:26PM +0200, Bruno Pr?mont wrote:
> > With commit b4aa0163056b ("efifb: Implement vga_default_device() (v2)")
> > Matthew Garrett introduced a efifb vga_default_device() so that EFI
> > systems that do not load shadow VBIOS or setup VGA get proper value for
> > boot_vga PCI sysfs attribute on the corresponding PCI device.
> > 
> > Xorg is refusing to detect devices when boot_vga=0 which is the case on
> > some EFI system (e.g. MacBookAir2,1). Xorg detects the GPU and finds
> > the dri device but then bails out with "no devices detected".
> > 
> > Note: When vga_default_device() is set boot_vga PCI sysfs attribute
> > reflects its state. When unset this attribute is 1 whenever
> > IORESOURCE_ROM_SHADOW flag is set.
> > 
> > With introduction of sysfb/simplefb/simpledrm efifb is getting obsolete
> > while having native drivers for the GPU also makes selecting
> > sysfb/efifb optional.
> > 
> > Remove the efifb implementation of vga_default_device() and initialize
> > vgaarb's vga_default_device() with the PCI GPU that matches boot
> > screen_info in pci_fixup_video().
> > 
> > Signed-off-by: Bruno Pr?mont 
> > ---
> >  arch/ia64/pci/fixup.c   | 21 +
> >  arch/x86/include/asm/vga.h  |  6 --
> >  arch/x86/pci/fixup.c| 21 +
> >  drivers/video/fbdev/efifb.c | 38 --
> >  4 files changed, 42 insertions(+), 44 deletions(-)
> 
> Something went wrong here.  It seems like the [2/2] patch should have
> been [1/2], and this one should be [2/2].  And this one modifies both
> arch/ia64/pci/fixup.c and arch/x86/pci/fixup.c, but the other patch
> mostly combines them, so I don't see how this one applies.

I ordered both patches the other way around from your explicit ordering
proposal following the stable kernel suggestion following it.

My patch 1/2 fixes the encountered issue and is the one that may go
stable while my patch 2/2 performs unification of common code.
The unification will need to be placed somewhere else than in vgaarb.c
if one wants to keep current fixup working with CONFIG_VGA_ARB=n.

> And there were unrelated (trivial) changes to these files, so they
> need to be rebased to v3.16-rc1.  I'd take care of the rebase, but
> I don't understand the other stuff I mentioned.

Ok

Bruno

> Bjorn
> 
> > diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
> > index eee069a..9ed5bef 100644
> > --- a/arch/ia64/pci/fixup.c
> > +++ b/arch/ia64/pci/fixup.c
> > @@ -37,6 +37,27 @@ static void pci_fixup_video(struct pci_dev *pdev)
> > return;
> > /* Maybe, this machine supports legacy memory map. */
> >  
> > +   if (!vga_default_device()) {
> > +   resource_size_t start, end;
> > +   int i;
> > +
> > +   /* Does firmware framebuffer belong to us? */
> > +   for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
> > +   if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
> > +   continue;
> > +
> > +   start = pci_resource_start(pdev, i);
> > +   end  = pci_resource_end(pdev, i);
> > +
> > +   if (!start || !end)
> > +   continue;
> > +
> > +   if (screen_info.lfb_base >= start &&
> > +   (screen_info.lfb_base + screen_info.lfb_size) < 
> > end)
> > +   vga_set_default_device(pdev);
> > +   }
> > +   }
> > +
> > /* Is VGA routed to us? */
> > bus = pdev->bus;
> > while (bus) {
> > diff --git a/arch/x86/include/asm/vga.h b/arch/x86/include/asm/vga.h
> > index 44282fb..c4b9dc2 100644
> > --- a/arch/x86/include/asm/vga.h
> > +++ b/arch/x86/include/asm/vga.h
> > @@ -17,10 +17,4 @@
> >  #define vga_readb(x) (*(x))
> >  #define vga_writeb(x, y) (*(y) = (x))
> >  
> > -#ifdef CONFIG_FB_EFI
> > -#define __ARCH_HAS_VGA_DEFAULT_DEVICE
> > -extern struct pci_dev *vga_default_device(void);
> > -extern void vga_set_default_device(struct pci_dev *pdev);
> > -#endif
> > -
> >  #endif /* _ASM_X86_VGA_H */
> > diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
> > index 94ae9ae..7246cf2 100644
> > --- a/arch/x86/pci/fixup.c
> > +++ b/arch/x86/pci/fixup.c
> > @@ -325,6 +325,27 @@ static void pci_fixup_video(struct pci_dev *pdev)
> > struct pci_bus *bus;
> > u16 config;
> >  
> > +   if (!vga_default_device()) {
> > +   resource_size_t start, end;
> > +   int i;
> > +
> > +   /* Does firmware framebuffer belong to us? */
> > +   for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
> > +   if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
> > +   continue;
> > +
> > +   start = pci_resource_start(pdev, i);
> > +   end  = pci_resource_end(pdev, i);
> > +
> > +   if (!start || !end)
> > +

[Bug 78111] APU turbo core boost not working when radeon.dpm=1

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=78111

--- Comment #9 from Marko Srebre  ---
I've been using enable_bapm for a day now, here are my observations:

* There are no issues regarding lockups. Not even when plugging/unplugging AC
adapter or sleeping/resuming.

* Boost state is active on boot regardless of AC begin plugged or not. However,
boost will get deactivated if at a later time AC is deplugged, and get
activated again on plugging. While this may make sense in some situations, I
prefer boost being always active, so for the time being I just changed the
relevant code so it's always on. I guess it would make sense for it to be an
option that could be tuned.

* There is some strange behaviour associated with this particular APU
(A6-1450). This is probably not Linux specific as I've seen reports on it for
Windows too. After boot turbo would only work for a single core and up to
1.3Ghz. But after doing a sleep/resume cycle turbo works for all 4 cores and up
to full 1.4Ghz (the difference is also quite audible since the fans go wild).
As if available TDP would somehow get much bigger after sleep/resume.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 80172] Rendering an application with discrete card makes X crash with segfault

2014-06-18 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=80172

Michel D?nzer  changed:

   What|Removed |Added

   Assignee|dri-devel at lists.freedesktop |chris at chris-wilson.co.uk
   |.org|
 QA Contact||intel-gfx-bugs at lists.freede
   ||sktop.org
Product|Mesa|xorg
  Component|Drivers/Gallium/radeonsi|Driver/intel

--- Comment #2 from Michel D?nzer  ---
The backtrace in the log file looks like an intel driver crash.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140618/0ebfe61e/attachment.html>


[Bug 78211] GPU lockup

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=78211

t3st3r at mail.ru changed:

   What|Removed |Added

 Status|RESOLVED|CLOSED

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 78221] 3.16 RC1: AMD R9 270 GPU locks up on some heavy 2D activity - GPU VM fault occurs. (possibly DMA copying issue strikes back?)

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=78221

--- Comment #1 from t3st3r at mail.ru ---
*** Bug 78211 has been marked as a duplicate of this bug. ***

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 78211] GPU lockup

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=78211

t3st3r at mail.ru changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |DUPLICATE
   Severity|high|low

--- Comment #1 from t3st3r at mail.ru ---
Bug escaped prematurely - duplicate of Bug 78221

*** This bug has been marked as a duplicate of bug 78221 ***

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[Bug 78221] New: 3.16 RC1: AMD R9 270 GPU locks up on some heavy 2D activity - GPU VM fault occurs. (possibly DMA copying issue strikes back?)

2014-06-18 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=78221

Bug ID: 78221
   Summary: 3.16 RC1: AMD R9 270 GPU locks up on some heavy 2D
activity - GPU VM fault occurs. (possibly DMA copying
issue strikes back?)
   Product: Drivers
   Version: 2.5
Kernel Version: 3.16-rc1
  Hardware: x86-64
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: high
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-dri at kernel-bugs.osdl.org
  Reporter: t3st3r at mail.ru
Regression: No

Configuration:
 AMD R9 270 with 3.16-rc1 kernel.
 Ubuntu 14.04 + oibaf PPA used as recent opensource graphics stack (MESA 10.3
git).
 XFCE used as DE, compositing is off.

To reproduce:
 Intermittent bug. R9 270 GPU can sometimes lock up on some heavy 2D-based
loads. 
 Known way to toggle bug is to install Battle for Wesnoth game from ubuntu
repos and allow game to display some map with many units/heavy animations when
running in windowed mode (BfW is SDL-based, 2D-only game, it does not makes GL
calls, etc). In random intervals, usually in range of 30 minutes, GPU could
lose stability and could lock up.

Special considerations:
 1) GPU recovery often succeeds in this case. Yet its bad to have 20 seconds of
black screen and sometimes it can fail to recover after multiple GPU crashes.
 2) Kernels prior 3.15 had similar issue. Kernel 3.15 (release version but not
-RCs) has been rock solid and never crashed GPU to the best of my knowledge, no
matter what I attempted. Now 3.16-rc1 crashes again.
 3) Taking 2) into account and such verioning I suspect it could have something
to do with commit b5be1a839a33634393394e4782edaa37a4bc1a1e or somewhere around.
Possibly its what reintroduced lockups in 3.16 again. Maybe underlying reasons
of deadlocks were not fixed for R9 270?
 4) GPU seems to be stable under 3D loads I've attempted - it does not crashes
even after hours of quite demanding 3D loads like games, etc. Only some
specific 2D loads can cause such issues.

Crash details are looking like this:
===CUT===
Jun 18 03:10:01 localhost kernel: [26125.102351] radeon :01:00.0: ring 0
stalled for more than 10263msec
Jun 18 03:10:01 localhost kernel: [26125.102362] radeon :01:00.0: GPU
lockup (waiting for 0x00445274 last fence id 0x00445273 on ring
0)
Jun 18 03:10:01 localhost kernel: [26125.102370] radeon :01:00.0: failed to
get a new IB (-35)
Jun 18 03:10:01 localhost kernel: [26125.671219] AMD-Vi: Event logged
[IO_PAGE_FAULT device=01:00.0 domain=0x0018 address=0x803dae00
flags=0x]
Jun 18 03:10:01 localhost kernel: [26125.671232] AMD-Vi: Event logged [
Jun 18 03:10:01 localhost kernel: [26125.671232] radeon :01:00.0: Saved
23200 dwords of commands on ring 0.
Jun 18 03:10:01 localhost kernel: [26125.671240] IO_PAGE_FAULT device=01:00.0
domain=0x0018 address=0x803dae30 flags=0x0020]
Jun 18 03:10:01 localhost kernel: [26125.671243] AMD-Vi: Event logged
[IO_PAGE_FAULT device=01:00.0 domain=0x0018 address=0x8100
flags=0x0020]
Jun 18 03:10:01 localhost kernel: [26125.671248] AMD-Vi: Event logged
[IO_PAGE_FAULT device=01:00.0 domain=0x0018 address=0x803dad00
flags=0x]
Jun 18 03:10:01 localhost kernel: [26125.671361] radeon :01:00.0: GPU
softreset: 0x006C
Jun 18 03:10:01 localhost kernel: [26125.671365] radeon :01:00.0:  
GRBM_STATUS   = 0xA0003028
Jun 18 03:10:01 localhost kernel: [26125.671367] radeon :01:00.0:  
GRBM_STATUS_SE0   = 0x0006
Jun 18 03:10:01 localhost kernel: [26125.671370] radeon :01:00.0:  
GRBM_STATUS_SE1   = 0x0006
Jun 18 03:10:01 localhost kernel: [26125.671372] radeon :01:00.0:  
SRBM_STATUS   = 0x20C0
Jun 18 03:10:01 localhost kernel: [26125.671483] radeon :01:00.0:  
SRBM_STATUS2  = 0x
Jun 18 03:10:01 localhost kernel: [26125.671485] radeon :01:00.0:  
R_008674_CP_STALLED_STAT1 = 0x
Jun 18 03:10:01 localhost kernel: [26125.671487] radeon :01:00.0:  
R_008678_CP_STALLED_STAT2 = 0x0001
Jun 18 03:10:01 localhost kernel: [26125.671489] radeon :01:00.0:  
R_00867C_CP_BUSY_STAT = 0x0002
Jun 18 03:10:01 localhost kernel: [26125.671492] radeon :01:00.0:  
R_008680_CP_STAT  = 0x80010243
Jun 18 03:10:01 localhost kernel: [26125.671494] radeon :01:00.0:  
R_00D034_DMA_STATUS_REG   = 0x44483146
Jun 18 03:10:01 localhost kernel: [26125.671496] radeon :01:00.0:  
R_00D834_DMA_STATUS_REG   = 0x44C84246
Jun 18 03:10:01 localhost kernel: [26125.671499] radeon :01:00.0:  
VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x
Jun 18 03:10:01 localhost kernel: [26125.671501] radeon :01:00.0:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x
Jun 18 03:10:02 localhost kernel: [26126.218193] radeon :01:00.0:
GRBM_SOFT_RESET=0xDDFF
Jun 18 

  1   2   >