-next slippages

2015-06-04 Thread Dave Airlie
Hey,

so remember aim for rc5?

Can we get a bit more on target shooting here,

I don't think I've seen,
exynos, msm or nouveau this cycle, and I've probably forgotten some of
the others.

though I know I'd prefer exynos atomic to land at all than hang on
another cycle,

Otherwise I know amdgpu is coming and virtgpu is here so I think that
should be all I have.

Dave.


[PATCH 01/25] drm: add generic lock-free queue implementation

2015-06-04 Thread Jammy Zhou
Signed-off-by: Jammy Zhou 
Signed-off-by: Shaoyun Liu 
Reviewed-by: Christian K?nig 
---
 drivers/gpu/drm/Makefile|   3 +-
 drivers/gpu/drm/drm_queue.c | 208 
 include/drm/drm_queue.h |  47 ++
 3 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_queue.c
 create mode 100644 include/drm/drm_queue.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 20f81fd..173d2b6 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -14,7 +14,8 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \
drm_trace_points.o drm_global.o drm_prime.o \
drm_rect.o drm_vma_manager.o drm_flip_work.o \
-   drm_modeset_lock.o drm_atomic.o drm_bridge.o
+   drm_modeset_lock.o drm_atomic.o drm_bridge.o \
+   drm_queue.o

 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/drm_queue.c b/drivers/gpu/drm/drm_queue.c
new file mode 100644
index 000..00cd649
--- /dev/null
+++ b/drivers/gpu/drm/drm_queue.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * This file implement a generic circular array queue.
+ * It's lock free for single producer and single consumer.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define QUEUE_IDX(_X_)  ((_X_)&(queue->size-1))
+
+/**
+ * drm_queue_create - create the queue
+ *
+ * @size  total number of elements for this queue
+ * @element_size the memory size of each element entry
+ *
+ * return pointer to the drm_queue structure if succeed, NULL if failed
+ */
+struct drm_queue * drm_queue_create(uint32_t size, uint32_t element_size)
+{
+   struct drm_queue *queue;
+
+   /* check whether the size is power of 2*/
+   BUG_ON(size & (size - 1));
+
+   queue = kzalloc(sizeof(struct drm_queue), GFP_KERNEL);
+   if (!queue)
+   return NULL;
+
+   queue->size = size;
+   queue->element_size = element_size;
+   atomic_set(&queue->count, 0);
+   mutex_init(&queue->lock);
+   queue->data = kzalloc(size * element_size, GFP_KERNEL);
+   if (!queue->data) {
+   kfree(queue);
+   return NULL;
+   }
+
+   return queue;
+}
+
+EXPORT_SYMBOL(drm_queue_create);
+
+/**
+ * drm_queue_free - free the queue storage
+ *
+ * @queue pointer to the queue need to be destroied
+ *
+ * return 0 if succeed. -1 if failed.
+ */
+int drm_queue_free(struct drm_queue *queue)
+{
+   BUG_ON(queue == NULL);
+
+   kfree(queue->data);
+   kfree(queue);
+
+   return 0;
+}
+
+EXPORT_SYMBOL(drm_queue_free);
+
+/**
+ * drm_queue_get_count - Get active count of elements in the queue
+ *
+ * @queue pointer to the queue.
+ *
+ * return current occuptied count of the queue.
+ *
+ */
+int drm_queue_get_count(struct drm_queue *queue)
+{
+   BUG_ON(queue == NULL);
+   return atomic_read(&queue->count);
+}
+
+EXPORT_SYMBOL(drm_queue_get_count);
+
+/**
+ * drm_queue_push - push one element into the queue
+ *
+ * @queue pointer to the queue
+ * @data  pointer to the element.
+ *
+ * return 0 if succeed.
+ *-EINVAL if the queue is not valid
+ *-ENOSPC if the queue is full.
+ *
+ * Only one producer is allowed.
+ */
+int drm_queue_push(struct drm_queue *queue, void *data)
+{
+   uint32_t index;
+
+   if (!(queue && queue->data))
+   return -EINVAL;
+
+   if (atomic_read(&queue->count) >= queue->size)
+   return -ENOSPC;
+
+   index = QUEUE_IDX(queue->w_idx++);
+   memcpy(queue->data + index * queue->element_size,
+  data, queue->element_size);
+   barrier();
+   atomic_inc(&queue->count);
+   return 0;
+}
+
+EX

[PATCH] Add device enumeration interface (v3)

2015-06-04 Thread Zhou, Jammy
> Does the above cover all the things that you have planned for the interface 
> to provide ?
Yes, exactly. That can cover what we need. Thanks.

Regards,
Jammy

-Original Message-
From: Emil Velikov [mailto:emil.l.veli...@gmail.com] 
Sent: Thursday, June 04, 2015 12:04 AM
To: Zhou, Jammy
Cc: Alex Deucher; Deucher, Alexander; Min, Frank; dri-devel at 
lists.freedesktop.org
Subject: Re: [PATCH] Add device enumeration interface (v3)

Hello Jammy,

On 1 June 2015 at 03:12, Zhou, Jammy  wrote:
>> Jammy or Frank might be able to provide some pseudo code in the interim.
>
> I think the requirement here is quite simple. We would like to have some 
> interface to enumerate the GPU devices on the system, and select some 
> specific device for different purposes (i.e, rendering, computing, 
> displaying, etc). Current libdrm interfaces are just for single device, and 
> there is no good consideration for multiple GPUs yet.
>
I believe I've read the same quote earlier, although still explains the goal, 
rather than the requirements :'-( Can you elaborate on what exactly the 
interface should provide - I can think of the following:
 - Number of devices.
 - ^^ + masked by vendor id/module name. This one seem like an overkill imho..
 - Flags indicating if the device has primary/control/render node.
 - Location (bus info) for the device(s)
 - PCI/platform device information.

Does the above cover all the things that you have planned for the interface to 
provide ?

Thanks
Emil


[Bug 71789] [r300g] Visuals not found in (default) depth = 24

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=71789

herminio.hernandezjr at gmail.com changed:

   What|Removed |Added

 OS|OpenBSD |Linux (All)

--- Comment #3 from herminio.hernandezjr at gmail.com ---
I am seeing the same thing in Debian Testing. Those patches woorked all the way
up to mesa 10.5.5 then they began to fail.

-- 
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/20150604/451a7f62/attachment.html>


[Bug 71789] [r300g] Visuals not found in (default) depth = 24

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=71789

--- Comment #4 from herminio.hernandezjr at gmail.com ---
Created attachment 116274
  --> https://bugs.freedesktop.org/attachment.cgi?id=116274&action=edit
glxinfo output

-- 
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/20150604/4bd605f2/attachment.html>


Help on drmModeSetPlane

2015-06-04 Thread Xie, William
Hi
Does anyone know what the result value of "-34" means returned by 
drmModeSetPlane?

William
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150604/da4153da/attachment.html>


[Linaro-mm-sig] [RFCv3 2/2] dma-buf: add helpers for sharing attacher constraints with dma-parms

2015-06-04 Thread Sumit Semwal
On 3 June 2015 at 15:07, Hans Verkuil  wrote:
> On 06/03/15 10:41, Russell King - ARM Linux wrote:
>> On Wed, Jun 03, 2015 at 08:39:55AM +0200, Hans Verkuil wrote:
>>> Hi Sumit,
>>>
>>> On 05/05/2015 04:41 PM, Sumit Semwal wrote:
 Hi Russell, everyone,

 First up, sincere apologies for being awol for sometime; had some
 personal / medical things to take care of, and then I thought I'd wait
 for the merge window to get over before beginning to discuss this
 again.

 On 11 February 2015 at 21:53, Russell King - ARM Linux
  wrote:
> On Wed, Feb 11, 2015 at 01:20:24PM +0100, Marek Szyprowski wrote:
>> Hello,
>>
>> On 2015-02-11 12:12, Russell King - ARM Linux wrote:
>>> Which is a damn good reason to NAK it - by that admission, it's a 
>>> half-baked
>>> idea.
>>>
>>> If all we want to know is whether the importer can accept only 
>>> contiguous
>>> memory or not, make a flag to do that, and allow the exporter to test 
>>> this
>>> flag.  Don't over-engineer this to make it _seem_ like it can do 
>>> something
>>> that it actually totally fails with.
>>>
>>> As I've already pointed out, there's a major problem if you have already
>>> had a less restrictive attachment which has an active mapping, and a new
>>> more restrictive attachment comes along later.
>>>
>>> It seems from Rob's descriptions that we also need another flag in the
>>> importer to indicate whether it wants to have a valid struct page in the
>>> scatter list, or whether it (correctly) uses the DMA accessors on the
>>> scatter list - so that exporters can reject importers which are buggy.
>>
>> Okay, but flag-based approach also have limitations.
>
> Yes, the flag-based approach doesn't let you describe in detail what
> the importer can accept - which, given the issues that I've raised
> is a *good* thing.  We won't be misleading anyone into thinking that
> we can do something that's really half-baked, and which we have no
> present requirement for.
>
> This is precisely what Linus talks about when he says "don't over-
> engineer" - if we over-engineer this, we end up with something that
> sort-of works, and that's a bad thing.
>
> The Keep It Simple approach here makes total sense - what are our
> current requirements - to be able to say that an importer can only accept:
>   - contiguous memory rather than a scatterlist
>   - scatterlists with struct page pointers
>
> Does solving that need us to compare all the constraints of each and
> every importer, possibly ending up with constraints which can't be
> satisfied?  No.  Does the flag approach satisfy the requirements?  Yes.
>

 So, for basic constraint-sharing, we'll just go with the flag based
 approach, with a flag (best place for it is still dev->dma_params I
 suppose) for denoting contiguous or scatterlist. Is that agreed, then?
 Also, with this idea, of course, there won't be any helpers for trying
 to calculate constraints; it would be totally the exporter's
 responsibility to handle it via the attach() dma_buf_op if it wishes
 to.
>>>
>>> What's wrong with the proposed max_segment_count? Many media devices do
>>> have a limited max_segment_count and that should be taken into account.
>>
>> So what happens if you have a dma_buf exporter, and several dma_buf
>> importers.  One dma_buf importer attaches to the exporter, and asks
>> for the buffer, and starts making use of the buffer.  This export has
>> many scatterlist segments.
>>
>> Another dma_buf importer attaches to the same buffer, and now asks for
>> the buffer, but the number of scatterlist segments exceeds it
>> requirement.

So, in the midst of all the various directions this discussion has
taken, I seem to have missed to reiterate the base premise for this
suggestion [1] - that we can use this information to help implement a
deferred allocation logic - so that all the importers can attach
first, and the exporter can do the actual allocation on the first
map() call.
This is also inline with the prescribed usage of dma_buf_attach() /
dma_buf_map_attachment() sequence - ideally speaking, all
participating 'importers' of dma_buf should only attach first, and
then map() at a 'later' time, which is usually right before using the
buffer actually.
Note: at present, both DRI and V4L subsystems don't do that; while
proposing this RFC I had deliberately kept that separate, as it is a
related but orthogonal problem to solve. I guess I should address that
in parallel.
>>
>> You can't reallocate the buffer because it's in-use by another importer.
>> There is no way to revoke the buffer from the other importer.  So there
>> is no way to satisfy this importer's requirements.
>>
You're right; but in a deferred allocation mechanism, this
constraint-sharing can atleast help decide on the most rest

[PATCH] drm/exynos: dsi: check whether dsi is enabled before sending data

2015-06-04 Thread Hyungwon Hwang
exynos_dsi_host_transfer() can be called through a panel driver while
DSI is turning down. It is possible because the function checks only
whether DSI is initialized or not, and there is a moment which DSI is
set by uninitialized, but DSI is still turning down. To prevent it,
DSI must be set by disabled before starting to be turned down, and
exynos_dsi_host_transfer() must check whether DSI is enabled or not.

Kernel dump:
[ 4721.351448] Unhandled fault: synchronous external abort (0x96000210) at 
0xff800015e018
[ 4721.351809] Internal error: : 96000210 [#1] PREEMPT SMP
[ 4721.352031] Modules linked in:
[ 4721.352173] CPU: 2 PID: 300 Comm: deviced Tainted: GW   
4.0.4-01017-g7964a87 #1
[ 4721.353989] Hardware name: Samsung DRACO board (DT)
[ 4721.358852] task: ffc0a0b7 ti: ffc0a00ec000 task.ti: 
ffc0a00ec000
[ 4721.366327] PC is at exynos_dsi_enable_lane+0x14/0x5c
[ 4721.371353] LR is at exynos_dsi_host_transfer+0x834/0x8d8
[ 4721.376731] pc : [] lr : [] pstate: 
6145
[ 4721.384107] sp : ffc0a00efbe0
[ 4721.387405] x29: ffc0a00efbe0 x28: ffc0a00ec000
[ 4721.392699] x27: ffc000968000 x26: 0040
[ 4721.397994] x25: ffc000f74dc0 x24: ffc0a00efec8
[ 4721.403290] x23: ffc0a4815400 x22: ffc0009f2729
[ 4721.408584] x21: ffc0a00efcc8 x20: ffc0a4a2a848
[ 4721.413879] x19: ffc0a4a2a818 x18: 0004
[ 4721.419173] x17: 007faa5cddf0 x16: ffc0001a40a8
[ 4721.424469] x15: 0009 x14: 000d
[ 4721.429762] x13: 6e6e6f63206b726f x12: 0010
[ 4721.435058] x11: 0101010101010101 x10: 
[ 4721.440353] x9 : 000a x8 : 8386838282818381
[ 4721.445648] x7 : ffc0a201efe8 x6 : 
[ 4721.450943] x5 : fffa x4 : ffc0a201f170
[ 4721.456237] x3 : ff800015e000 x2 : ff800015e018
[ 4721.461531] x1 : 000f x0 : ffc0a4a2a818
[ 4721.466826]
[ 4721.468305] Process deviced (pid: 300, stack limit = 0xffc0a00ec028)
[ 4721.474989] Stack: (0xffc0a00efbe0 to 0xffc0a00f)
[ 4721.480720] fbe0: a00efca0 ffc0 0042c944 ffc0 a0f2d680 ffc0 
0024 
[ 4721.488895] fc00: a4b6d000 ffc0 009f2729 ffc0 a4815400 ffc0 
a00efec8 ffc0

Signed-off-by: Hyungwon Hwang 
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 1cfc4be07..6413339 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1408,6 +1408,9 @@ static ssize_t exynos_dsi_host_transfer(struct 
mipi_dsi_host *host,
struct exynos_dsi_transfer xfer;
int ret;

+   if (!(dsi->state & DSIM_STATE_ENABLED))
+   return -EINVAL;
+
if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
ret = exynos_dsi_init(dsi);
if (ret)
@@ -1551,9 +1554,10 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi)
drm_panel_disable(dsi->panel);
exynos_dsi_set_display_enable(dsi, false);
drm_panel_unprepare(dsi->panel);
-   exynos_dsi_poweroff(dsi);

dsi->state &= ~DSIM_STATE_ENABLED;
+
+   exynos_dsi_poweroff(dsi);
 }

 static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)
-- 
1.9.1



[PATCH 00/21] On-demand device registration

2015-06-04 Thread Tomeu Vizoso
On 3 June 2015 at 21:57, Grygorii.Strashko at linaro.org
 wrote:
> Hi Tomeu,
>
> On 05/28/2015 07:33 AM, Rob Herring wrote:
>> On Mon, May 25, 2015 at 9:53 AM, Tomeu Vizoso > collabora.com> wrote:
>>> I have a problem with the panel on my Tegra Chromebook taking longer than
>>> expected to be ready during boot (Stéphane Marchesin reported what is
>>> basically the same issue in [0]), and have looked into ordered probing as a
>>> better way of solving this than moving nodes around in the DT or playing 
>>> with
>>> initcall levels.
>>>
>>> While reading the thread [1] that Alexander Holler started with his series 
>>> to
>>> make probing order deterministic, it occurred to me that it should be 
>>> possible
>>> to achieve the same by registering devices as they are referenced by other
>>> devices.
>>
>> I like the concept and novel approach.
>>
>>> This basically reuses the information that is already implicit in the 
>>> probe()
>>> implementations, saving us from refactoring existing drivers or adding
>>> information to DTBs.
>>>
>>> Something I'm not completely happy with is that I have had to move the call 
>>> to
>>> of_platform_populate after all platform drivers have been registered.
>>> Otherwise I don't see how I could register drivers on demand as we don't 
>>> have
>>> yet each driver's compatible strings.
>>
>> Yeah, this is the opposite of what we'd really like. Ideally, we would
>> have a solution that works for modules too. However, we're no worse
>> off. We pretty much build-in dependencies to avoid module ordering
>> problems.
>>
>> Perhaps we need to make the probing on-demand rather than simply on
>> device<->driver match occurring.
>>
>>> For machs that don't move of_platform_populate() to a later point, these
>>> patches shouldn't cause any problems but it's not guaranteed that we'll 
>>> avoid
>>> all the deferred probes as some drivers may not be registered yet.
>>
>> Ideally, of_platform_populate is not explicitly called by each
>> platform. So I think we need to make this work for the default case.
>>
>>> I have tested this on boards with Tegra, iMX.6 and Exynos SoCs, and these
>>> patches were enough to eliminate all the deferred probes.
>>>
>>> With this series I get the kernel to output to the panel in 0.5s, instead 
>>> of 2.8s.
>>
>> That's certainly compelling.
>
> I've found your idea about moving device registration later during System boot
> very interesting so I've decided to try it on dra7-evem (TI) :).
> It's good to know time during Kernel boot when we can assume that all drivers 
> are
> ready for probing, so there are more ways to control probing order.

Thanks, though right now I'm following Rob's suggestion and only delay
probing, not registration. The patch is really simple (applies on
linux-next, with async probing):

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 8da8e07..7e6b1e1 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -407,6 +407,11 @@ int driver_probe_device(struct device_driver
*drv, struct device *dev)
if (!device_is_registered(dev))
return -ENODEV;

+   if (!driver_deferred_probe_enable) {
+   driver_deferred_probe_add(dev);
+   return 0;
+   }
+
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
 drv->bus->name, __func__, dev_name(dev), drv->name);

@@ -585,7 +590,7 @@ EXPORT_SYMBOL_GPL(device_attach);

 void device_initial_probe(struct device *dev)
 {
-   __device_attach(dev, true);
+   __device_attach(dev, driver_deferred_probe_enable);
 }

 static int __driver_attach(struct device *dev, void *data)

> Pls, Note here that TI OMAP2+ mach is not pure DT mach - it's combination of
> DT and not DT devices/drivers.
>
> Ok. So What was done...
>
> LKML Linux 4.1-rc3 (a simple case)
> 1) use your patches 3/4 as reference (only these two patches :)
> 2) move of_platform_populate later at device_initcall_sync time
> Boot time reduction ~0.4 sec

I'm a bit surprised at such a big improvement. May I ask how you are
measuring it?

> TI Android Kernel 3.14 (NOT a simple case)
> 1) use your patches 3/4 as reference (only these two patches :)
> 2) move of_platform_populate later at device_initcall_sync time
> 3) make it to boot (not sure I've fixed all issues, but those which
>break the System boot):
>  - split non-DT and DT devices registration in platform code;
>  - keep non-DT devices registration from .init_machine() [arch_initcall]
>  - move DT-devices registration at device_initcall_sync time
>  - fix drivers which use platform_driver_probe().
>Note. Now there are at about ~190 occurrences of this macro in Kernel.
>  - re-order few devices in DT (4 devices)
>  - fix one driver which uses of_find_device_by_node() wrongly
>Note. This API is used some times with assumption that
>requested dev has been probed already.
> Boot time reduction ~0.3 sec. Probing of some devices are still deferred.

I got no deferred probes on a pan

[Bug 90704] Desktop will black when sliding mouse in touchpad after switching tty in my skylake machine

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=90704

--- Comment #6 from vivianhu  ---
Created attachment 116279
  --> https://bugs.freedesktop.org/attachment.cgi?id=116279&action=edit
dmesg

-- 
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/20150604/25ee9f79/attachment.html>


[Bug 90704] Desktop will black when sliding mouse in touchpad after switching tty in my skylake machine

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=90704

--- Comment #7 from vivianhu  ---
Hi jani, sorry to trouble you. ^-^ But we meet a new problem when we use
drm-intel-nightly branch,it will report an error and many crash info in dmesg,
please refer to attachment.
What is i915/skl_dmc_ver4.bin and where to get it? And Does it will cause any
problem if skl_dmc_ver4.bin is not loaded?  what is the cut info?


for example:
[5.076518] i915 :00:02.0: Direct firmware load for
i915/skl_dmc_ver4.bin failed with error -2
[5.076562] [drm:i915_firmware_load_error_print [i915]] *ERROR* failed to
load firmware i915/skl_dmc_ver4.bin (0)

[ cut here ]
[6.127802] WARNING: CPU: 0 PID: 92 at drivers/gpu/drm/i915/intel_csr.c:462
assert_csr_loaded+0xa7/0x100 [i915]()
[6.127803] CSR is not loaded.
[6.127811] Modules linked in: i915(+) i2c_algo_bit video drm_kms_helper drm
i2c_core
[6.127816] CPU: 0 PID: 92 Comm: kworker/u16:3 Not tainted
4.1.0-50.5.1.lp22.x86_64 #1
[6.127818] Hardware name: LENOVO INVALID/VIUU4, BIOS D5CN07WW(T006)
02/11/2015
[6.127826] Workqueue: events_unbound async_run_entry_fn
[6.127831]  a0186ff8 88026f6ef738 8176889d
08ae08ae
[6.127835]  88026f6ef788 88026f6ef778 8107c32a
88026f6ef768
[6.127838]  88026f18 88026f1802b0 0002
300f
[6.127839] Call Trace:
[6.127848]  [] dump_stack+0x45/0x57
[6.127853]  [] warn_slowpath_common+0x8a/0xc0
[6.127857]  [] warn_slowpath_fmt+0x46/0x50
[6.127921]  [] ? gen9_read32+0x6e/0x2f0 [i915]
[6.127971]  [] assert_csr_loaded+0xa7/0x100 [i915]
[6.128015]  [] skl_set_power_well+0x743/0xac0 [i915]
[6.128057]  [] skl_power_well_enable+0x13/0x20 [i915]
[6.128099]  [] intel_display_power_get+0xa6/0x100 [i915]
[6.128169]  [] intel_hdmi_set_edid+0x3c/0x100 [i915]
[6.128236]  [] intel_hdmi_detect+0x55/0xb0 [i915]
[6.128246]  []
drm_helper_probe_single_connector_modes_merge_bits+0x300/0x4c0 [drm_kms_helper]
[6.128255]  []
drm_helper_probe_single_connector_modes+0x13/0x20 [drm_kms_helper]
[6.128266]  []
drm_fb_helper_probe_connector_modes.isra.3+0x50/0x70 [drm_kms_helper]
[6.128277]  [] drm_fb_helper_hotplug_event+0x5e/0xe0
[drm_kms_helper]
[6.128287]  []
drm_fb_helper_restore_fbdev_mode_unlocked+0x4c/0x80 [drm_kms_helper]
[6.128295]  [] drm_fb_helper_set_par+0x22/0x50
[drm_kms_helper]
[6.128359]  [] intel_fbdev_set_par+0x1a/0x60 [i915]
[6.128364]  [] fbcon_init+0x4f4/0x580
[6.128369]  [] visual_init+0xbc/0x120
[6.128373]  [] do_bind_con_driver+0x163/0x330
[6.128378]  [] do_take_over_console+0x11c/0x1c0
[6.128384]  [] do_fbcon_takeover+0x63/0xd0
[6.128387]  [] fbcon_event_notify+0x68d/0x7e0
[6.128394]  [] notifier_call_chain+0x4e/0x80
[6.128399]  [] __blocking_notifier_call_chain+0x4d/0x70
[6.128402]  [] ? pm_vt_switch_required+0x76/0xa0
[6.128408]  [] blocking_notifier_call_chain+0x16/0x20
[6.128413]  [] fb_notifier_call_chain+0x1b/0x20
[6.128417]  [] register_framebuffer+0x1e6/0x320
[6.128429]  [] drm_fb_helper_initial_config+0x274/0x3d0
[drm_kms_helper]
[6.128492]  [] intel_fbdev_initial_config+0x1b/0x20
[i915]
[6.128496]  [] async_run_entry_fn+0x4a/0x140
[6.128500]  [] process_one_work+0x142/0x3f0
[6.128503]  [] worker_thread+0x11b/0x460
[6.128507]  [] ? process_one_work+0x3f0/0x3f0
[6.128512]  [] kthread+0xd2/0xf0
[6.128517]  [] ? kthread_create_on_node+0x170/0x170
[6.128522]  [] ret_from_fork+0x42/0x70
[6.128526]  [] ? kthread_create_on_node+0x170/0x170
[6.128529] ---[ end trace d595c73cdcde54bc ]---

-- 
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/20150604/74b1412a/attachment-0001.html>


[Bug 90704] Desktop will black when sliding mouse in touchpad after switching tty in my skylake machine

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=90704

--- Comment #8 from Jani Nikula  ---
(In reply to vivianhu from comment #7)
> Hi jani, sorry to trouble you. ^-^ But we meet a new problem when we use
> drm-intel-nightly branch,it will report an error and many crash info in
> dmesg, please refer to attachment.
> What is i915/skl_dmc_ver4.bin and where to get it? And Does it will cause
> any problem if skl_dmc_ver4.bin is not loaded?  what is the cut info?

One bug per report please, file new ones for new bugs.

You need the firmware. You can get it from
https://01.org/linuxgraphics/downloads. Hopefully it will be included in
linux-firmware sometime soon.

There's been some back and forth between the naming, see e.g.
http://mid.gmane.org/1433375419-13266-1-git-send-email-rodrigo.vivi at 
intel.com,
I'm not sure which name is currently used in the download page.

-- 
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/20150604/a1c38582/attachment.html>


[PATCHv2 08/45] drm: omapdrm: Turn vblank on/off when enabling/disabling CRTC

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The DRM core vblank handling mechanism requires drivers to forcefully
turn vblank reporting off when disabling the CRTC, and to restore the
vblank reporting status when enabling the CRTC.

Implement this using the drm_crtc_vblank_on/off helpers. When disabling
vblank we must first wait for page flips to complete, so implement page
flip completion wait as well.

Finally, drm_crtc_vblank_off() must be called at startup to synchronize
the state of the vblank core code with the hardware, which is initially
disabled. An interesting side effect is that the .disable_vblank()
operation will now be called for the first time with the CRTC disabled
and the DISPC runtime suspended. The dispc_runtime_get() call in
.disable_vblank() is supposed to take care of that, but the operation is
called with a spinlock held, which prevents it from sleeping.

To fix that move DISPC runtime PM handling out of the vblank operations
to the CRTC code, ensuring that the display controller will always be
powered when enabling or disabling vblank interrupts.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 78 +++--
 drivers/gpu/drm/omapdrm/omap_drv.c  |  5 +++
 drivers/gpu/drm/omapdrm/omap_irq.c  |  4 --
 3 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index c086f72e488d..1076bc0a7f78 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -76,6 +76,7 @@ struct omap_crtc {
 */
enum omap_page_flip_state flip_state;
struct drm_pending_vblank_event *flip_event;
+   wait_queue_head_t flip_wait;
struct work_struct flip_work;

struct completion completion;
@@ -309,6 +310,61 @@ static void omap_crtc_complete_page_flip(struct drm_crtc 
*crtc,
}

omap_crtc->flip_state = state;
+
+   if (state == OMAP_PAGE_FLIP_IDLE)
+   wake_up(&omap_crtc->flip_wait);
+}
+
+static bool omap_crtc_page_flip_pending(struct drm_crtc *crtc)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct drm_device *dev = crtc->dev;
+   unsigned long flags;
+   bool pending;
+
+   spin_lock_irqsave(&dev->event_lock, flags);
+   pending = omap_crtc->flip_state != OMAP_PAGE_FLIP_IDLE;
+   spin_unlock_irqrestore(&dev->event_lock, flags);
+
+   return pending;
+}
+
+static void omap_crtc_wait_page_flip(struct drm_crtc *crtc)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct drm_device *dev = crtc->dev;
+   bool cancelled = false;
+   unsigned long flags;
+
+   /*
+* If we're still waiting for the GEM async operation to complete just
+* cancel the page flip, as we're holding the CRTC mutex preventing the
+* page flip work handler from queueing the page flip.
+*
+* We can't release the reference to the frame buffer here as the async
+* operation doesn't keep its own reference to the buffer. We'll just
+* let the page flip work queue handle that.
+*/
+   spin_lock_irqsave(&dev->event_lock, flags);
+   if (omap_crtc->flip_state == OMAP_PAGE_FLIP_WAIT) {
+   omap_crtc_complete_page_flip(crtc, OMAP_PAGE_FLIP_CANCELLED);
+   cancelled = true;
+   }
+   spin_unlock_irqrestore(&dev->event_lock, flags);
+
+   if (cancelled)
+   return;
+
+   if (wait_event_timeout(omap_crtc->flip_wait,
+  !omap_crtc_page_flip_pending(crtc),
+  msecs_to_jiffies(50)))
+   return;
+
+   dev_warn(crtc->dev->dev, "page flip timeout!\n");
+
+   spin_lock_irqsave(&dev->event_lock, flags);
+   omap_crtc_complete_page_flip(crtc, OMAP_PAGE_FLIP_IDLE);
+   spin_unlock_irqrestore(&dev->event_lock, flags);
 }

 static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -455,26 +511,39 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int 
mode)
 {
struct omap_drm_private *priv = crtc->dev->dev_private;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   bool enabled = (mode == DRM_MODE_DPMS_ON);
+   bool enable = (mode == DRM_MODE_DPMS_ON);
int i;

DBG("%s: %d", omap_crtc->name, mode);

-   if (enabled == omap_crtc->enabled)
+   if (enable == omap_crtc->enabled)
return;

+   if (!enable) {
+   omap_crtc_wait_page_flip(crtc);
+   dispc_runtime_get();
+   drm_crtc_vblank_off(crtc);
+   dispc_runtime_put();
+   }
+
/* Enable/disable all planes associated with the CRTC. */
for (i = 0; i < priv->num_planes; i++) {
struct drm_plane *plane = priv->planes[i];

if (plane->crtc == crtc)
-   WARN_ON(omap_plane_set_enable

[PATCHv2 12/45] drm: omapdrm: Rework CRTC enable/disable for atomic updates

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

When using atomic updates the CRTC .enable() and .disable() helper
operations are preferred over the (then legacy) .prepare() and .commit()
operations. Implement .enable() and rework .disable() to not depend on
DPMS, easing DPMS removal later on.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 83 ++---
 1 file changed, 59 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 94c1bb8448be..0359a67f8f8d 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -509,50 +509,70 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
kfree(omap_crtc);
 }

-static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
+static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
+   const struct drm_display_mode *mode,
+   struct drm_display_mode *adjusted_mode)
+{
+   return true;
+}
+
+static void omap_crtc_enable(struct drm_crtc *crtc)
 {
struct omap_drm_private *priv = crtc->dev->dev_private;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   bool enable = (mode == DRM_MODE_DPMS_ON);
-   int i;
+   unsigned int i;

-   DBG("%s: %d", omap_crtc->name, mode);
+   DBG("%s", omap_crtc->name);

-   if (enable == omap_crtc->enabled)
+   if (omap_crtc->enabled)
return;

-   if (!enable) {
-   omap_crtc_wait_page_flip(crtc);
-   dispc_runtime_get();
-   drm_crtc_vblank_off(crtc);
-   dispc_runtime_put();
-   }
-
-   /* Enable/disable all planes associated with the CRTC. */
+   /* Enable all planes associated with the CRTC. */
for (i = 0; i < priv->num_planes; i++) {
struct drm_plane *plane = priv->planes[i];

if (plane->crtc == crtc)
-   WARN_ON(omap_plane_set_enable(plane, enable));
+   WARN_ON(omap_plane_set_enable(plane, true));
}

-   omap_crtc->enabled = enable;
+   omap_crtc->enabled = true;

omap_crtc_setup(crtc);
omap_crtc_flush(crtc);

-   if (enable) {
-   dispc_runtime_get();
-   drm_crtc_vblank_on(crtc);
-   dispc_runtime_put();
-   }
+   dispc_runtime_get();
+   drm_crtc_vblank_on(crtc);
+   dispc_runtime_put();
 }

-static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+static void omap_crtc_disable(struct drm_crtc *crtc)
 {
-   return true;
+   struct omap_drm_private *priv = crtc->dev->dev_private;
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   unsigned int i;
+
+   DBG("%s", omap_crtc->name);
+
+   if (!omap_crtc->enabled)
+   return;
+
+   omap_crtc_wait_page_flip(crtc);
+   dispc_runtime_get();
+   drm_crtc_vblank_off(crtc);
+   dispc_runtime_put();
+
+   /* Disable all planes associated with the CRTC. */
+   for (i = 0; i < priv->num_planes; i++) {
+   struct drm_plane *plane = priv->planes[i];
+
+   if (plane->crtc == crtc)
+   WARN_ON(omap_plane_set_enable(plane, false));
+   }
+
+   omap_crtc->enabled = false;
+
+   omap_crtc_setup(crtc);
+   omap_crtc_flush(crtc);
 }

 static int omap_crtc_mode_set(struct drm_crtc *crtc,
@@ -587,6 +607,19 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc,
   x, y, mode->hdisplay, mode->vdisplay);
 }

+static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   bool enable = (mode == DRM_MODE_DPMS_ON);
+
+   DBG("%s: %d", omap_crtc->name, mode);
+
+   if (enable)
+   omap_crtc_enable(crtc);
+   else
+   omap_crtc_disable(crtc);
+}
+
 static void omap_crtc_prepare(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -751,6 +784,8 @@ static const struct drm_crtc_helper_funcs 
omap_crtc_helper_funcs = {
.prepare = omap_crtc_prepare,
.commit = omap_crtc_commit,
.mode_set_base = omap_crtc_mode_set_base,
+   .disable = omap_crtc_disable,
+   .enable = omap_crtc_enable,
 };

 /* 
-
-- 
2.1.4



[PATCHv2 19/45] drm: omapdrm: Switch connector DPMS to atomic helpers

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The atomic connector DPMS helper implements the connector DPMS operation
using atomic commit, removing the need for DPMS helper operations on
CRTCs and encoders.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_connector.c |  2 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 14 --
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 26 +-
 3 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index d170f0cb1aa9..83f2a9177c14 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -260,7 +260,7 @@ struct drm_encoder *omap_connector_attached_encoder(
 }

 static const struct drm_connector_funcs omap_connector_funcs = {
-   .dpms = drm_helper_connector_dpms,
+   .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = omap_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 68bf38bd0ce2..5216fb07b534 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -592,19 +592,6 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
copy_timings_drm_to_omap(&omap_crtc->timings, mode);
 }

-static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   bool enable = (mode == DRM_MODE_DPMS_ON);
-
-   DBG("%s: %d", omap_crtc->name, mode);
-
-   if (enable)
-   omap_crtc_enable(crtc);
-   else
-   omap_crtc_disable(crtc);
-}
-
 static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
 {
dispc_runtime_get();
@@ -749,7 +736,6 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
 };

 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
-   .dpms = omap_crtc_dpms,
.mode_fixup = omap_crtc_mode_fixup,
.mode_set_nofb = omap_crtc_mode_set_nofb,
.disable = omap_crtc_disable,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 96459f709147..2aeb41f0881a 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -62,22 +62,6 @@ static const struct drm_encoder_funcs omap_encoder_funcs = {
.destroy = omap_encoder_destroy,
 };

-/*
- * The CRTC drm_crtc_helper_set_mode() doesn't really give us the right
- * order.. the easiest way to work around this for now is to make all
- * the encoder-helper's no-op's and have the omap_crtc code take care
- * of the sequencing and call us in the right points.
- *
- * Eventually to handle connecting CRTCs to different encoders properly,
- * either the CRTC helpers need to change or we need to replace
- * drm_crtc_helper_set_mode(), but lets wait until atomic-modeset for
- * that.
- */
-
-static void omap_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-}
-
 static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
  const struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode)
@@ -116,6 +100,15 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
}
 }

+/*
+ * The CRTC drm_crtc_helper_set_mode() didn't really give us the right order.
+ * The easiest way to work around this was to make all the encoder-helper's
+ * no-op's and have the omap_crtc code take care of the sequencing and call
+ * us in the right points.
+ *
+ * FIXME: Revisit this after switching to atomic updates completely.
+ */
+
 static void omap_encoder_disable(struct drm_encoder *encoder)
 {
 }
@@ -125,7 +118,6 @@ static void omap_encoder_enable(struct drm_encoder *encoder)
 }

 static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
-   .dpms = omap_encoder_dpms,
.mode_fixup = omap_encoder_mode_fixup,
.mode_set = omap_encoder_mode_set,
.disable = omap_encoder_disable,
-- 
2.1.4



[PATCHv2 33/45] drm: omapdrm: Remove nested PM get/sync when configuring encoders

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The omap_crtc_encoder_setup() function is always called with the DSS
enabled. Remove the dispc_runtime_get() and dispc_runtime_put() calls.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index aa719ebfe787..16f9c07dc4f6 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -374,8 +374,6 @@ static void omap_crtc_encoder_setup(struct drm_crtc *crtc, 
bool enable)

DBG("%s: enable=%d", omap_crtc->name, enable);

-   dispc_runtime_get();
-
for (i = 0; i < priv->num_encoders; i++) {
if (priv->encoders[i]->crtc == crtc) {
encoder = priv->encoders[i];
@@ -396,8 +394,6 @@ static void omap_crtc_encoder_setup(struct drm_crtc *crtc, 
bool enable)
omap_encoder_set_enabled(encoder, true);
}
}
-
-   dispc_runtime_put();
 }

 /* 
-
-- 
2.1.4



[PATCHv2 38/45] drm: omapdrm: omap_plane_setup() cannot fail, use WARN

2015-06-04 Thread Tomi Valkeinen
With atomic modesetting, omap_plane_setup()'s return value is ignored as
the functions using it cannot fail. dispc_ovl_setup(), called by
omap_plane_setup(), can fail (but shouldn't).

Instead of returning an error from omap_plane_setup() which gets
ignored, return void and use WARN if dispc_ovl_setup() fails.

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 448707669690..a8e617f9f2af 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -58,12 +58,11 @@ to_omap_plane_state(struct drm_plane_state *state)
return container_of(state, struct omap_plane_state, base);
 }

-static int omap_plane_setup(struct drm_plane *plane)
+static void omap_plane_setup(struct drm_plane *plane)
 {
struct omap_plane *omap_plane = to_omap_plane(plane);
struct drm_plane_state *state = plane->state;
struct omap_plane_state *omap_state = to_omap_plane_state(state);
-   struct drm_device *dev = plane->dev;
struct omap_overlay_info info;
struct omap_drm_window win;
int ret;
@@ -72,7 +71,7 @@ static int omap_plane_setup(struct drm_plane *plane)

if (!state->crtc) {
dispc_ovl_enable(omap_plane->id, false);
-   return 0;
+   return;
}

memset(&info, 0, sizeof(info));
@@ -123,14 +122,10 @@ static int omap_plane_setup(struct drm_plane *plane)
/* and finally, update omapdss: */
ret = dispc_ovl_setup(omap_plane->id, &info, false,
  omap_crtc_timings(state->crtc), false);
-   if (ret) {
-   dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret);
-   return ret;
-   }
+   if (WARN_ON(ret))
+   return;

dispc_ovl_enable(omap_plane->id, true);
-
-   return 0;
 }

 static int omap_plane_prepare_fb(struct drm_plane *plane,
-- 
2.1.4



[PATCHv2 45/45] drm: omapdrm: add lock for fb pinning

2015-06-04 Thread Tomi Valkeinen
Before atomic modesetting omap_framebuffer_pin() and
omap_framebuffer_unpin() were always called with modesetting locks
taken. With atomic modesetting support this is no longer the case, and
we need locking to protect the pin_count and the paddr, as multiple
threads may pin the same fb concurrently.

This patch adds a mutex to struct omap_framebuffer, and uses it in
omap_framebuffer_pin() and omap_framebuffer_unpin().

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_fb.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c 
b/drivers/gpu/drm/omapdrm/omap_fb.c
index e505140a8782..0b967e76df1a 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -89,6 +89,8 @@ struct omap_framebuffer {
int pin_count;
const struct format *format;
struct plane planes[4];
+   /* lock for pinning (pin_count and planes.paddr) */
+   struct mutex lock;
 };

 static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -250,8 +252,11 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format);

+   mutex_lock(&omap_fb->lock);
+
if (omap_fb->pin_count > 0) {
omap_fb->pin_count++;
+   mutex_unlock(&omap_fb->lock);
return 0;
}

@@ -265,6 +270,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)

omap_fb->pin_count++;

+   mutex_unlock(&omap_fb->lock);
+
return 0;

 fail:
@@ -274,6 +281,8 @@ fail:
plane->paddr = 0;
}

+   mutex_unlock(&omap_fb->lock);
+
return ret;
 }

@@ -283,10 +292,14 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format);

+   mutex_lock(&omap_fb->lock);
+
omap_fb->pin_count--;

-   if (omap_fb->pin_count > 0)
+   if (omap_fb->pin_count > 0) {
+   mutex_unlock(&omap_fb->lock);
return 0;
+   }

for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i];
@@ -296,9 +309,12 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
plane->paddr = 0;
}

+   mutex_unlock(&omap_fb->lock);
+
return 0;

 fail:
+   mutex_unlock(&omap_fb->lock);
return ret;
 }

@@ -411,6 +427,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct 
drm_device *dev,

fb = &omap_fb->base;
omap_fb->format = format;
+   mutex_init(&omap_fb->lock);

for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i];
-- 
2.1.4



[PATCHv2 34/45] drm: omapdrm: Simplify DSS power management

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Instead of sprinkling dispc_runtime_get() and dispc_runtime_put() calls
in various CRTC operations, move all power management code to the atomic
commit function.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 11 ---
 drivers/gpu/drm/omapdrm/omap_drv.c  |  4 
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 16f9c07dc4f6..3a5e68a06af3 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -429,8 +429,6 @@ static void omap_crtc_enable(struct drm_crtc *crtc)

DBG("%s", omap_crtc->name);

-   dispc_runtime_get();
-
/* Enable all planes associated with the CRTC. */
for (i = 0; i < priv->num_planes; i++) {
struct drm_plane *plane = priv->planes[i];
@@ -443,8 +441,6 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
omap_crtc_flush(crtc);

drm_crtc_vblank_on(crtc);
-
-   dispc_runtime_put();
 }

 static void omap_crtc_disable(struct drm_crtc *crtc)
@@ -456,7 +452,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
DBG("%s", omap_crtc->name);

omap_crtc_wait_page_flip(crtc);
-   dispc_runtime_get();
drm_crtc_vblank_off(crtc);

/* Disable all planes associated with the CRTC. */
@@ -469,8 +464,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)

omap_crtc_encoder_setup(crtc, false);
omap_crtc_flush(crtc);
-
-   dispc_runtime_put();
 }

 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
@@ -495,8 +488,6 @@ static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
unsigned long flags;

-   dispc_runtime_get();
-
if (event) {
WARN_ON(omap_crtc->event);
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
@@ -511,8 +502,6 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
 {
omap_crtc_flush(crtc);

-   dispc_runtime_put();
-
crtc->invert_dimensions = !!(crtc->primary->state->rotation &
(BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270)));
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 2e7706355eb6..50f30e55 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -73,6 +73,8 @@ static void omap_atomic_complete(struct 
omap_atomic_state_commit *commit)
struct drm_atomic_state *old_state = commit->state;

/* Apply the atomic update. */
+   dispc_runtime_get();
+
drm_atomic_helper_commit_modeset_disables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state);
drm_atomic_helper_commit_modeset_enables(dev, old_state);
@@ -81,6 +83,8 @@ static void omap_atomic_complete(struct 
omap_atomic_state_commit *commit)

drm_atomic_helper_cleanup_planes(dev, old_state);

+   dispc_runtime_put();
+
drm_atomic_state_free(old_state);

/* Complete the commit, wake up any waiter. */
-- 
2.1.4



[PATCHv2 28/45] drm: omapdrm: Remove omap_plane enabled field

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The field tracks the plane state to avoid double-enable or -disable.
This isn't required anymore, as

- the DRM atomic core guarantees that the plane atomic_update and
  atomic_disable functions will never be called on an enabled/disabled
  plane

- the CRTC enable/disable operations that enable/disable the plane are
  already guarded against double enable/disable

We can thus remove the enabled field completely. The
omap_plane_set_enable() function then becomes a wrapper around
omap_plane_setup() which can be called directly.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 11 +
 drivers/gpu/drm/omapdrm/omap_drv.h   |  2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c | 45 +++-
 3 files changed, 16 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index e93ed34dea33..82d03ed92576 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -452,19 +452,21 @@ static void omap_crtc_enable(struct drm_crtc *crtc)

DBG("%s", omap_crtc->name);

+   dispc_runtime_get();
+
/* Enable all planes associated with the CRTC. */
for (i = 0; i < priv->num_planes; i++) {
struct drm_plane *plane = priv->planes[i];

if (plane->crtc == crtc)
-   WARN_ON(omap_plane_set_enable(plane, true));
+   WARN_ON(omap_plane_setup(plane));
}

omap_crtc_encoder_setup(crtc, true);
omap_crtc_flush(crtc);

-   dispc_runtime_get();
drm_crtc_vblank_on(crtc);
+
dispc_runtime_put();
 }

@@ -479,18 +481,19 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
omap_crtc_wait_page_flip(crtc);
dispc_runtime_get();
drm_crtc_vblank_off(crtc);
-   dispc_runtime_put();

/* Disable all planes associated with the CRTC. */
for (i = 0; i < priv->num_planes; i++) {
struct drm_plane *plane = priv->planes[i];

if (plane->crtc == crtc)
-   WARN_ON(omap_plane_set_enable(plane, false));
+   WARN_ON(omap_plane_setup(plane));
}

omap_crtc_encoder_setup(crtc, false);
omap_crtc_flush(crtc);
+
+   dispc_runtime_put();
 }

 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index f5209412fae6..7f815552fe7e 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -151,7 +151,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,

 struct drm_plane *omap_plane_init(struct drm_device *dev,
int id, enum drm_plane_type type);
-int omap_plane_set_enable(struct drm_plane *plane, bool enable);
+int omap_plane_setup(struct drm_plane *plane);
 void omap_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj);

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 465fd9cafd7b..d18fe106e256 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -40,8 +40,6 @@ struct omap_plane {
int id;  /* TODO rename omap_plane -> omap_plane_id in omapdss so I can 
use the enum */
const char *name;

-   bool enabled;
-
uint32_t nformats;
uint32_t formats[32];

@@ -60,18 +58,19 @@ to_omap_plane_state(struct drm_plane_state *state)
return container_of(state, struct omap_plane_state, base);
 }

-static int omap_plane_setup(struct omap_plane *omap_plane)
+int omap_plane_setup(struct drm_plane *plane)
 {
-   struct drm_plane_state *state = omap_plane->base.state;
+   struct omap_plane *omap_plane = to_omap_plane(plane);
+   struct drm_plane_state *state = plane->state;
struct omap_plane_state *omap_state = to_omap_plane_state(state);
-   struct drm_device *dev = omap_plane->base.dev;
+   struct drm_device *dev = plane->dev;
struct omap_overlay_info info;
struct omap_drm_window win;
int ret;

-   DBG("%s, enabled=%d", omap_plane->name, omap_plane->enabled);
+   DBG("%s, crtc=%p fb=%p", omap_plane->name, state->crtc, state->fb);

-   if (!omap_plane->enabled) {
+   if (!state->crtc) {
dispc_ovl_enable(omap_plane->id, false);
return 0;
}
@@ -134,23 +133,6 @@ static int omap_plane_setup(struct omap_plane *omap_plane)
return 0;
 }

-int omap_plane_set_enable(struct drm_plane *plane, bool enable)
-{
-   struct omap_plane *omap_plane = to_omap_plane(plane);
-   int ret;
-
-   if (enable == omap_plane->enabled)
-   return 0;
-
-   omap_plane->enabled = enable;
-
-   dispc_runtime_get();
-   ret = omap_plane_setup(omap_plane);
-   dispc_runtim

[PATCHv2 04/45] drm: omapdrm: Rename omap_crtc page flip-related fields

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The old_fb field is only used to indicate whether a page flip is
pending. Turn it into a bool named flip_pending. Rename event and
page_flip_work to flip_event and flip_work for consistency.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 47 -
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 7ef9147bde73..85129d56cf4c 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -54,19 +54,22 @@ struct omap_crtc {
/* list of framebuffers to unpin */
struct list_head pending_unpins;

-   /* if there is a pending flip, these will be non-null: */
-   struct drm_pending_vblank_event *event;
-   struct drm_framebuffer *old_fb;
+   /*
+* The flip_pending flag indicates if a page flip has been queued and
+* hasn't completed yet. The flip event, if any, is stored in
+* flip_event.
+*
+* The flip_work work queue handles page flip requests without caring
+* about what context the GEM async callback is called from. Possibly we
+* should just make omap_gem always call the cb from the worker so we
+* don't have to care about this.
+*/
+   bool flip_pending;
+   struct drm_pending_vblank_event *flip_event;
+   struct work_struct flip_work;

struct completion completion;

-   /* for handling page flips without caring about what
-* the callback is called from.  Possibly we should just
-* make omap_gem always call the cb from the worker so
-* we don't have to care about this..
-*/
-   struct work_struct page_flip_work;
-
bool ignore_digit_sync_lost;
 };

@@ -293,11 +296,12 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq 
*irq, uint32_t irqstatus)
spin_lock_irqsave(&dev->event_lock, flags);

/* wakeup userspace */
-   if (omap_crtc->event)
-   drm_send_vblank_event(dev, omap_crtc->pipe, omap_crtc->event);
+   if (omap_crtc->flip_event)
+   drm_send_vblank_event(dev, omap_crtc->pipe,
+ omap_crtc->flip_event);

-   omap_crtc->event = NULL;
-   omap_crtc->old_fb = NULL;
+   omap_crtc->flip_event = NULL;
+   omap_crtc->flip_pending = false;

spin_unlock_irqrestore(&dev->event_lock, flags);

@@ -507,7 +511,7 @@ static int omap_crtc_mode_set_base(struct drm_crtc *crtc, 
int x, int y,
 static void page_flip_worker(struct work_struct *work)
 {
struct omap_crtc *omap_crtc =
-   container_of(work, struct omap_crtc, page_flip_work);
+   container_of(work, struct omap_crtc, flip_work);
struct drm_crtc *crtc = &omap_crtc->base;
struct drm_display_mode *mode = &crtc->mode;
struct drm_gem_object *bo;
@@ -531,7 +535,7 @@ static void page_flip_cb(void *arg)
struct omap_drm_private *priv = crtc->dev->dev_private;

/* avoid assumptions about what ctxt we are called from: */
-   queue_work(priv->wq, &omap_crtc->page_flip_work);
+   queue_work(priv->wq, &omap_crtc->flip_work);
 }

 static int omap_crtc_page_flip(struct drm_crtc *crtc,
@@ -550,15 +554,16 @@ static int omap_crtc_page_flip(struct drm_crtc *crtc,

spin_lock_irqsave(&dev->event_lock, flags);

-   if (omap_crtc->old_fb) {
+   if (omap_crtc->flip_pending) {
spin_unlock_irqrestore(&dev->event_lock, flags);
dev_err(dev->dev, "already a pending flip\n");
return -EBUSY;
}

-   omap_crtc->event = event;
-   omap_crtc->old_fb = primary->fb = fb;
-   drm_framebuffer_reference(omap_crtc->old_fb);
+   omap_crtc->flip_event = event;
+   omap_crtc->flip_pending = true;
+   primary->fb = fb;
+   drm_framebuffer_reference(fb);

spin_unlock_irqrestore(&dev->event_lock, flags);

@@ -640,7 +645,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,

crtc = &omap_crtc->base;

-   INIT_WORK(&omap_crtc->page_flip_work, page_flip_worker);
+   INIT_WORK(&omap_crtc->flip_work, page_flip_worker);

INIT_LIST_HEAD(&omap_crtc->pending_unpins);

-- 
2.1.4



[PATCHv2 06/45] drm: omapdrm: Cancel pending page flips when closing device

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Pending page flips must be cancelled when closing the device, otherwise
their completion at next vblank will result in nasty effects, including
possible oopses due to resources required to complete the page flip
being freed.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 21 -
 drivers/gpu/drm/omapdrm/omap_drv.c  |  6 ++
 drivers/gpu/drm/omapdrm/omap_drv.h  |  1 +
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 85129d56cf4c..a60f4e49b55f 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -263,9 +263,28 @@ static const struct dss_mgr_ops mgr_ops = {
 };

 /* 
-
- * Setup and Flush
+ * Setup, Flush and Page Flip
  */

+void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct drm_device *dev = crtc->dev;
+   unsigned long flags;
+
+   spin_lock_irqsave(&dev->event_lock, flags);
+
+   /* Only complete events queued for our file handle. */
+   if (omap_crtc->flip_event &&
+   file == omap_crtc->flip_event->base.file_priv) {
+   drm_send_vblank_event(dev, omap_crtc->pipe,
+ omap_crtc->flip_event);
+   omap_crtc->flip_event = NULL;
+   }
+
+   spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 {
struct omap_crtc *omap_crtc =
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 47fb99b3a375..cf1b37e5374b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -630,7 +630,13 @@ static void dev_lastclose(struct drm_device *dev)

 static void dev_preclose(struct drm_device *dev, struct drm_file *file)
 {
+   struct omap_drm_private *priv = dev->dev_private;
+   unsigned int i;
+
DBG("preclose: dev=%p", dev);
+
+   for (i = 0; i < priv->num_crtcs; ++i)
+   omap_crtc_cancel_page_flip(priv->crtcs[i], file);
 }

 static void dev_postclose(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index f1005b46a193..774b9f6ab2d6 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -136,6 +136,7 @@ const struct omap_video_timings *omap_crtc_timings(struct 
drm_crtc *crtc);
 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
 int omap_crtc_flush(struct drm_crtc *crtc);
 int omap_crtc_queue_unpin(struct drm_crtc *crtc, struct drm_framebuffer *fb);
+void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
 void omap_crtc_pre_init(void);
 void omap_crtc_pre_uninit(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
-- 
2.1.4



[PATCHv2 11/45] drm: omapdrm: Rename CRTC DSS operations with an omap_crtc_dss_ prefix

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The omap_crtc_enable() and omap_crtc_disable() DSS operations functions
will clash with the new CRTC enable and disable helpers. Rename them to
omap_crtc_dss_*, as well as the other DSS operations for consistency.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 6840ed5c45a7..94c1bb8448be 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -131,7 +131,7 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
 static struct omap_crtc *omap_crtcs[8];

 /* we can probably ignore these until we support command-mode panels: */
-static int omap_crtc_connect(struct omap_overlay_manager *mgr,
+static int omap_crtc_dss_connect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
 {
if (mgr->output)
@@ -146,14 +146,14 @@ static int omap_crtc_connect(struct omap_overlay_manager 
*mgr,
return 0;
 }

-static void omap_crtc_disconnect(struct omap_overlay_manager *mgr,
+static void omap_crtc_dss_disconnect(struct omap_overlay_manager *mgr,
struct omap_dss_device *dst)
 {
mgr->output->manager = NULL;
mgr->output = NULL;
 }

-static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
+static void omap_crtc_dss_start_update(struct omap_overlay_manager *mgr)
 {
 }

@@ -215,7 +215,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, 
bool enable)
 }


-static int omap_crtc_enable(struct omap_overlay_manager *mgr)
+static int omap_crtc_dss_enable(struct omap_overlay_manager *mgr)
 {
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];

@@ -227,14 +227,14 @@ static int omap_crtc_enable(struct omap_overlay_manager 
*mgr)
return 0;
 }

-static void omap_crtc_disable(struct omap_overlay_manager *mgr)
+static void omap_crtc_dss_disable(struct omap_overlay_manager *mgr)
 {
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];

omap_crtc_set_enabled(&omap_crtc->base, false);
 }

-static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
+static void omap_crtc_dss_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings)
 {
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
@@ -242,7 +242,7 @@ static void omap_crtc_set_timings(struct 
omap_overlay_manager *mgr,
omap_crtc->timings = *timings;
 }

-static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr,
+static void omap_crtc_dss_set_lcd_config(struct omap_overlay_manager *mgr,
const struct dss_lcd_mgr_config *config)
 {
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
@@ -250,29 +250,29 @@ static void omap_crtc_set_lcd_config(struct 
omap_overlay_manager *mgr,
dispc_mgr_set_lcd_config(omap_crtc->channel, config);
 }

-static int omap_crtc_register_framedone_handler(
+static int omap_crtc_dss_register_framedone(
struct omap_overlay_manager *mgr,
void (*handler)(void *), void *data)
 {
return 0;
 }

-static void omap_crtc_unregister_framedone_handler(
+static void omap_crtc_dss_unregister_framedone(
struct omap_overlay_manager *mgr,
void (*handler)(void *), void *data)
 {
 }

 static const struct dss_mgr_ops mgr_ops = {
-   .connect = omap_crtc_connect,
-   .disconnect = omap_crtc_disconnect,
-   .start_update = omap_crtc_start_update,
-   .enable = omap_crtc_enable,
-   .disable = omap_crtc_disable,
-   .set_timings = omap_crtc_set_timings,
-   .set_lcd_config = omap_crtc_set_lcd_config,
-   .register_framedone_handler = omap_crtc_register_framedone_handler,
-   .unregister_framedone_handler = omap_crtc_unregister_framedone_handler,
+   .connect = omap_crtc_dss_connect,
+   .disconnect = omap_crtc_dss_disconnect,
+   .start_update = omap_crtc_dss_start_update,
+   .enable = omap_crtc_dss_enable,
+   .disable = omap_crtc_dss_disable,
+   .set_timings = omap_crtc_dss_set_timings,
+   .set_lcd_config = omap_crtc_dss_set_lcd_config,
+   .register_framedone_handler = omap_crtc_dss_register_framedone,
+   .unregister_framedone_handler = omap_crtc_dss_unregister_framedone,
 };

 /* 
-
-- 
2.1.4



[PATCHv2 22/45] drm: omapdrm: Switch page flip to atomic helpers

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The atomic page flip helper implements the page flip operation using
asynchronous commits.

As the legacy page flip was the last caller of omap_plane_mode_set(),
remove the function.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 224 +++
 drivers/gpu/drm/omapdrm/omap_drv.h   |   6 -
 drivers/gpu/drm/omapdrm/omap_plane.c |  23 
 3 files changed, 41 insertions(+), 212 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 5216fb07b534..a87ec26a883b 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -30,18 +30,10 @@

 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)

-enum omap_page_flip_state {
-   OMAP_PAGE_FLIP_IDLE,
-   OMAP_PAGE_FLIP_WAIT,
-   OMAP_PAGE_FLIP_QUEUED,
-   OMAP_PAGE_FLIP_CANCELLED,
-};
-
 struct omap_crtc {
struct drm_crtc base;

const char *name;
-   int pipe;
enum omap_channel channel;
struct omap_overlay_manager_info info;
struct drm_encoder *current_encoder;
@@ -63,25 +55,9 @@ struct omap_crtc {
/* list of framebuffers to unpin */
struct list_head pending_unpins;

-   /*
-* flip_state flag indicates the current page flap state: IDLE if no
-* page queue has been submitted, WAIT when waiting for GEM async
-* completion, QUEUED when the page flip has been queued to the hardware
-* or CANCELLED when the CRTC is turned off before the flip gets queued
-* to the hardware. The flip event, if any, is stored in flip_event, and
-* the framebuffer queued for page flip is stored in flip_fb. The
-* flip_wait wait queue is used to wait for page flip completion.
-*
-* The flip_work work queue handles page flip requests without caring
-* about what context the GEM async callback is called from. Possibly we
-* should just make omap_gem always call the cb from the worker so we
-* don't have to care about this.
-*/
-   enum omap_page_flip_state flip_state;
-   struct drm_pending_vblank_event *flip_event;
-   struct drm_framebuffer *flip_fb;
+   /* pending event */
+   struct drm_pending_vblank_event *event;
wait_queue_head_t flip_wait;
-   struct work_struct flip_work;

struct completion completion;

@@ -284,39 +260,46 @@ static const struct dss_mgr_ops mgr_ops = {
 void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct drm_pending_vblank_event *event;
struct drm_device *dev = crtc->dev;
unsigned long flags;

+   /* Destroy the pending vertical blanking event associated with the
+* pending page flip, if any, and disable vertical blanking interrupts.
+*/
+
spin_lock_irqsave(&dev->event_lock, flags);

-   /* Only complete events queued for our file handle. */
-   if (omap_crtc->flip_event &&
-   file == omap_crtc->flip_event->base.file_priv) {
-   drm_send_vblank_event(dev, omap_crtc->pipe,
- omap_crtc->flip_event);
-   omap_crtc->flip_event = NULL;
+   event = omap_crtc->event;
+   omap_crtc->event = NULL;
+
+   if (event && event->base.file_priv == file) {
+   event->base.destroy(&event->base);
+   drm_crtc_vblank_put(crtc);
}

spin_unlock_irqrestore(&dev->event_lock, flags);
 }

-/* Must be called with dev->event_lock locked. */
-static void omap_crtc_complete_page_flip(struct drm_crtc *crtc,
-enum omap_page_flip_state state)
+static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct drm_pending_vblank_event *event;
struct drm_device *dev = crtc->dev;
+   unsigned long flags;

-   if (omap_crtc->flip_event) {
-   drm_send_vblank_event(dev, omap_crtc->pipe,
- omap_crtc->flip_event);
-   omap_crtc->flip_event = NULL;
-   }
+   spin_lock_irqsave(&dev->event_lock, flags);

-   omap_crtc->flip_state = state;
+   event = omap_crtc->event;
+   omap_crtc->event = NULL;

-   if (state == OMAP_PAGE_FLIP_IDLE)
+   if (event) {
+   drm_crtc_send_vblank_event(crtc, event);
wake_up(&omap_crtc->flip_wait);
+   drm_crtc_vblank_put(crtc);
+   }
+
+   spin_unlock_irqrestore(&dev->event_lock, flags);
 }

 static bool omap_crtc_page_flip_pending(struct drm_crtc *crtc)
@@ -327,7 +310,7 @@ static bool omap_crtc_page_flip_pending(struct drm_crtc 
*crtc)
bool pending;

spin_lock_irqsave(&dev->event_lock, flags);
-   pending =

[PATCHv2 23/45] drm: omapdrm: Drop manual framebuffer pin handling

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Since the removal of omap_plane_mode_set(), framebuffers are now pinned
exclusively through the plane .prepare_fb() and .cleanup_fb() operations
as the remaining callers of omap_plane_setup() don't modify the
framebuffer. Remove the manual pin/unpin infrastructure.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 35 --
 drivers/gpu/drm/omapdrm/omap_drv.h   |  1 -
 drivers/gpu/drm/omapdrm/omap_plane.c | 41 
 3 files changed, 77 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index a87ec26a883b..646563e47562 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -52,9 +52,6 @@ struct omap_crtc {
struct omap_drm_irq vblank_irq;
struct omap_drm_irq error_irq;

-   /* list of framebuffers to unpin */
-   struct list_head pending_unpins;
-
/* pending event */
struct drm_pending_vblank_event *event;
wait_queue_head_t flip_wait;
@@ -64,11 +61,6 @@ struct omap_crtc {
bool ignore_digit_sync_lost;
 };

-struct omap_framebuffer_unpin {
-   struct list_head list;
-   struct drm_framebuffer *fb;
-};
-
 /* 
-
  * Helper Functions
  */
@@ -365,7 +357,6 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, 
uint32_t irqstatus)
 int omap_crtc_flush(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   struct omap_framebuffer_unpin *fb, *next;

DBG("%s: GO", omap_crtc->name);

@@ -385,29 +376,6 @@ int omap_crtc_flush(struct drm_crtc *crtc)

dispc_runtime_put();

-   /* Unpin and unreference pending framebuffers. */
-   list_for_each_entry_safe(fb, next, &omap_crtc->pending_unpins, list) {
-   omap_framebuffer_unpin(fb->fb);
-   drm_framebuffer_unreference(fb->fb);
-   list_del(&fb->list);
-   kfree(fb);
-   }
-
-   return 0;
-}
-
-int omap_crtc_queue_unpin(struct drm_crtc *crtc, struct drm_framebuffer *fb)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   struct omap_framebuffer_unpin *unpin;
-
-   unpin = kzalloc(sizeof(*unpin), GFP_KERNEL);
-   if (!unpin)
-   return -ENOMEM;
-
-   unpin->fb = fb;
-   list_add_tail(&unpin->list, &omap_crtc->pending_unpins);
-
return 0;
 }

@@ -643,9 +611,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
crtc = &omap_crtc->base;

init_waitqueue_head(&omap_crtc->flip_wait);
-
-   INIT_LIST_HEAD(&omap_crtc->pending_unpins);
-
init_completion(&omap_crtc->completion);

omap_crtc->channel = channel;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 0231f81dfb9b..580fe10184d7 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -143,7 +143,6 @@ void omap_fbdev_free(struct drm_device *dev);
 const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
 int omap_crtc_flush(struct drm_crtc *crtc);
-int omap_crtc_queue_unpin(struct drm_crtc *crtc, struct drm_framebuffer *fb);
 void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
 void omap_crtc_pre_init(void);
 void omap_crtc_pre_uninit(void);
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 117fa37534b6..7813e48b6896 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -45,49 +45,12 @@ struct omap_plane {
struct omap_drm_window win;
bool enabled;

-   /* last fb that we pinned: */
-   struct drm_framebuffer *pinned_fb;
-
uint32_t nformats;
uint32_t formats[32];

struct omap_drm_irq error_irq;
 };

-/* update which fb (if any) is pinned for scanout */
-static int omap_plane_update_pin(struct drm_plane *plane)
-{
-   struct omap_plane *omap_plane = to_omap_plane(plane);
-   struct drm_framebuffer *pinned_fb = omap_plane->pinned_fb;
-   struct drm_framebuffer *fb = omap_plane->enabled ? plane->fb : NULL;
-   int ret = 0;
-
-   if (pinned_fb == fb)
-   return 0;
-
-   DBG("%p -> %p", pinned_fb, fb);
-
-   if (fb) {
-   drm_framebuffer_reference(fb);
-   ret = omap_framebuffer_pin(fb);
-   }
-
-   if (pinned_fb)
-   omap_crtc_queue_unpin(plane->crtc, pinned_fb);
-
-   if (ret) {
-   dev_err(plane->dev->dev, "could not swap %p -> %p\n",
-   omap_plane->pinned_fb, fb);
-   drm_framebuffer_unreference(fb);
-   omap_plane->pinned_fb = NULL;
-   return ret;
-   }
-
-   omap_plan

[PATCHv2 30/45] drm: omapdrm: Don't get/put dispc in omap_crtc_flush()

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The omap_crtc_flush() function is always called with a reference to the
dispc held. Remove unnecessary calls to dispc_runtime_get() and
dispc_runtime_put().

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 96ba21509607..993bd15ecfbd 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -368,8 +368,6 @@ static int omap_crtc_flush(struct drm_crtc *crtc)
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
WARN_ON(omap_crtc->vblank_irq.registered);

-   dispc_runtime_get();
-
if (dispc_mgr_is_enabled(omap_crtc->channel)) {
dispc_mgr_go(omap_crtc->channel);
omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
@@ -379,8 +377,6 @@ static int omap_crtc_flush(struct drm_crtc *crtc)
reinit_completion(&omap_crtc->completion);
}

-   dispc_runtime_put();
-
return 0;
 }

-- 
2.1.4



[PATCHv2 05/45] drm: omapdrm: Simplify IRQ registration

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The omapdrm can't use drm_irq_install() and drm_irq_uninstall() as it
delegates IRQ handling to the omapdss driver. However, the code still
declares IRQ-related operations used by the DRM IRQ helpers, and calls
them indirectly.

Simplify the implementation by calling the functions directly or
inlining them. The irq_enabled checks can then also be simplified as
the call stacks guarantees that omap_drm_irq_install() and
omap_drm_irq_uninstall() will never run concurrently.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_drv.c |   7 +--
 drivers/gpu/drm/omapdrm/omap_drv.h |   6 +--
 drivers/gpu/drm/omapdrm/omap_irq.c | 102 +
 3 files changed, 25 insertions(+), 90 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index bf02121d9ce8..47fb99b3a375 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -656,8 +656,7 @@ static const struct file_operations omapdriver_fops = {
 };

 static struct drm_driver omap_drm_driver = {
-   .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM
-| DRIVER_PRIME,
+   .driver_features = DRIVER_MODESET | DRIVER_GEM  | DRIVER_PRIME,
.load = dev_load,
.unload = dev_unload,
.open = dev_open,
@@ -668,10 +667,6 @@ static struct drm_driver omap_drm_driver = {
.get_vblank_counter = drm_vblank_count,
.enable_vblank = omap_irq_enable_vblank,
.disable_vblank = omap_irq_disable_vblank,
-   .irq_preinstall = omap_irq_preinstall,
-   .irq_postinstall = omap_irq_postinstall,
-   .irq_uninstall = omap_irq_uninstall,
-   .irq_handler = omap_irq_handler,
 #ifdef CONFIG_DEBUG_FS
.debugfs_init = omap_debugfs_init,
.debugfs_cleanup = omap_debugfs_cleanup,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 6c0cb463b9dc..f1005b46a193 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -122,15 +122,11 @@ int omap_gem_resume(struct device *dev);

 int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id);
 void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id);
-irqreturn_t omap_irq_handler(int irq, void *arg);
-void omap_irq_preinstall(struct drm_device *dev);
-int omap_irq_postinstall(struct drm_device *dev);
-void omap_irq_uninstall(struct drm_device *dev);
 void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
 void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
 void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
 void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
-int omap_drm_irq_uninstall(struct drm_device *dev);
+void omap_drm_irq_uninstall(struct drm_device *dev);
 int omap_drm_irq_install(struct drm_device *dev);

 struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c 
b/drivers/gpu/drm/omapdrm/omap_irq.c
index 3eb097efc488..803aff0db768 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -187,7 +187,7 @@ void omap_irq_disable_vblank(struct drm_device *dev, int 
crtc_id)
dispc_runtime_put();
 }

-irqreturn_t omap_irq_handler(int irq, void *arg)
+static irqreturn_t omap_irq_handler(int irq, void *arg)
 {
struct drm_device *dev = (struct drm_device *) arg;
struct omap_drm_private *priv = dev->dev_private;
@@ -222,23 +222,29 @@ irqreturn_t omap_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
 }

-void omap_irq_preinstall(struct drm_device *dev)
-{
-   DBG("dev=%p", dev);
-   dispc_runtime_get();
-   dispc_clear_irqstatus(0x);
-   dispc_runtime_put();
-}
+/*
+ * We need a special version, instead of just using drm_irq_install(),
+ * because we need to register the irq via omapdss.  Once omapdss and
+ * omapdrm are merged together we can assign the dispc hwmod data to
+ * ourselves and drop these and just use drm_irq_{install,uninstall}()
+ */

-int omap_irq_postinstall(struct drm_device *dev)
+int omap_drm_irq_install(struct drm_device *dev)
 {
struct omap_drm_private *priv = dev->dev_private;
struct omap_drm_irq *error_handler = &priv->error_handler;
-
-   DBG("dev=%p", dev);
+   int ret;

INIT_LIST_HEAD(&priv->irq_list);

+   dispc_runtime_get();
+   dispc_clear_irqstatus(0x);
+   dispc_runtime_put();
+
+   ret = dispc_request_irq(omap_irq_handler, dev);
+   if (ret < 0)
+   return ret;
+
error_handler->irq = omap_irq_error_handler;
error_handler->irqmask = DISPC_IRQ_OCP_ERR;

@@ -249,76 +255,22 @@ int omap_irq_postinstall(struct drm_device *dev)

omap_irq_register(dev, error_handler);

-   return 0;
-}
-
-void omap_irq_uninstall(struct d

[PATCHv2 01/45] drm: omapdrm: Store the rotation property in dev->mode_config

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Rotation is a standard property, store it in
dev->mode_config.rotation_property. While at it, extract the properties
initialization code to a separate function instead of running it for
every plane.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  |  4 +---
 drivers/gpu/drm/omapdrm/omap_drv.c   | 31 ---
 drivers/gpu/drm/omapdrm/omap_drv.h   |  1 -
 drivers/gpu/drm/omapdrm/omap_plane.c | 27 ---
 4 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index f456544bf300..7a64765d0537 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -646,9 +646,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 static int omap_crtc_set_property(struct drm_crtc *crtc,
struct drm_property *property, uint64_t val)
 {
-   struct omap_drm_private *priv = crtc->dev->dev_private;
-
-   if (property == priv->rotation_prop) {
+   if (property == crtc->dev->mode_config.rotation_property) {
crtc->invert_dimensions =
!!(val & ((1LL << DRM_ROTATE_90) | (1LL << 
DRM_ROTATE_270)));
}
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 94920d47e3b6..ce6a255d277a 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -151,6 +151,27 @@ static int omap_modeset_create_crtc(struct drm_device 
*dev, int id,
return 0;
 }

+static int omap_modeset_init_properties(struct drm_device *dev)
+{
+   struct omap_drm_private *priv = dev->dev_private;
+
+   if (priv->has_dmm) {
+   dev->mode_config.rotation_property =
+   drm_mode_create_rotation_property(dev,
+   BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) |
+   BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) |
+   BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
+   if (!dev->mode_config.rotation_property)
+   return -ENOMEM;
+   }
+
+   priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0, 3);
+   if (!priv->zorder_prop)
+   return -ENOMEM;
+
+   return 0;
+}
+
 static int omap_modeset_init(struct drm_device *dev)
 {
struct omap_drm_private *priv = dev->dev_private;
@@ -165,6 +186,10 @@ static int omap_modeset_init(struct drm_device *dev)

omap_drm_irq_install(dev);

+   ret = omap_modeset_init_properties(dev);
+   if (ret < 0)
+   return ret;
+
/*
 * We usually don't want to create a CRTC for each manager, at least
 * not until we have a way to expose private planes to userspace.
@@ -583,7 +608,7 @@ static void dev_lastclose(struct drm_device *dev)

DBG("lastclose: dev=%p", dev);

-   if (priv->rotation_prop) {
+   if (dev->mode_config.rotation_property) {
/* need to restore default rotation state.. not sure
 * if there is a cleaner way to restore properties to
 * default state?  Maybe a flag that properties should
@@ -592,12 +617,12 @@ static void dev_lastclose(struct drm_device *dev)
 */
for (i = 0; i < priv->num_crtcs; i++) {
drm_object_property_set_value(&priv->crtcs[i]->base,
-   priv->rotation_prop, 0);
+   dev->mode_config.rotation_property, 0);
}

for (i = 0; i < priv->num_planes; i++) {
drm_object_property_set_value(&priv->planes[i]->base,
-   priv->rotation_prop, 0);
+   dev->mode_config.rotation_property, 0);
}
}

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index b31c79f15aed..a42a11c62106 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -114,7 +114,6 @@ struct omap_drm_private {
bool has_dmm;

/* properties: */
-   struct drm_property *rotation_prop;
struct drm_property *zorder_prop;

/* irq handling: */
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 1c6b63f39474..a1c9c08db345 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -297,33 +297,14 @@ void omap_plane_install_properties(struct drm_plane 
*plane,
 {
struct drm_device *dev = plane->dev;
struct omap_drm_private *priv = dev->dev_private;
-   struct drm_property *prop;

if (priv->has_dmm) {
-   prop = priv->rotation_prop;
-   if (!prop) {
-   p

[PATCHv2 02/45] drm: omapdrm: Apply settings synchronously

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The omapdrm driver implements a mechanism to apply new settings (due to
plane update, plane disable, plane property set, CRTC mode set or CRTC
DPMS) asynchronously. While this improves performance, it adds a level
of complexity that makes transition to the atomic update API close to
impossible. Furthermore the atomic update API requires part of the apply
operations to be synchronous (such as pinning the framebuffers), so the
current implementation needs to be changed.

Simplify the CRTC and plane code by making updates synchronous to
prepare for the switch to the atomic update API. Asynchronous update
will be implemented in a second step.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 269 +--
 drivers/gpu/drm/omapdrm/omap_drv.c   |   5 -
 drivers/gpu/drm/omapdrm/omap_drv.h   |  23 +--
 drivers/gpu/drm/omapdrm/omap_plane.c | 211 +++
 4 files changed, 183 insertions(+), 325 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 7a64765d0537..e5fb8c6e25e6 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -17,6 +17,8 @@
  * this program.  If not, see .
  */

+#include 
+
 #include "omap_drv.h"

 #include 
@@ -46,36 +48,33 @@ struct omap_crtc {
struct omap_video_timings timings;
bool enabled;

-   struct omap_drm_apply apply;
-
-   struct omap_drm_irq apply_irq;
+   struct omap_drm_irq vblank_irq;
struct omap_drm_irq error_irq;

-   /* list of in-progress apply's: */
-   struct list_head pending_applies;
-
-   /* list of queued apply's: */
-   struct list_head queued_applies;
-
-   /* for handling queued and in-progress applies: */
-   struct work_struct apply_work;
+   /* list of framebuffers to unpin */
+   struct list_head pending_unpins;

/* if there is a pending flip, these will be non-null: */
struct drm_pending_vblank_event *event;
struct drm_framebuffer *old_fb;

+   struct completion completion;
+
/* for handling page flips without caring about what
 * the callback is called from.  Possibly we should just
 * make omap_gem always call the cb from the worker so
 * we don't have to care about this..
-*
-* XXX maybe fold into apply_work??
 */
struct work_struct page_flip_work;

bool ignore_digit_sync_lost;
 };

+struct omap_framebuffer_unpin {
+   struct list_head list;
+   struct drm_framebuffer *fb;
+};
+
 /* 
-
  * Helper Functions
  */
@@ -142,7 +141,7 @@ static void omap_crtc_start_update(struct 
omap_overlay_manager *mgr)
 {
 }

-/* Called only from CRTC pre_apply and suspend/resume handlers. */
+/* Called only from omap_crtc_setup and suspend/resume handlers. */
 static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 {
struct drm_device *dev = crtc->dev;
@@ -261,7 +260,7 @@ static const struct dss_mgr_ops mgr_ops = {
 };

 /* 
-
- * Apply Logic
+ * Setup and Flush
  */

 static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -278,121 +277,93 @@ static void omap_crtc_error_irq(struct omap_drm_irq 
*irq, uint32_t irqstatus)
DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
 }

-static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
+static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 {
struct omap_crtc *omap_crtc =
-   container_of(irq, struct omap_crtc, apply_irq);
-   struct drm_crtc *crtc = &omap_crtc->base;
+   container_of(irq, struct omap_crtc, vblank_irq);
+   struct drm_device *dev = omap_crtc->base.dev;
+   unsigned long flags;

-   if (!dispc_mgr_go_busy(omap_crtc->channel)) {
-   struct omap_drm_private *priv =
-   crtc->dev->dev_private;
-   DBG("%s: apply done", omap_crtc->name);
-   __omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq);
-   queue_work(priv->wq, &omap_crtc->apply_work);
-   }
+   if (dispc_mgr_go_busy(omap_crtc->channel))
+   return;
+
+   DBG("%s: apply done", omap_crtc->name);
+   __omap_irq_unregister(dev, &omap_crtc->vblank_irq);
+
+   spin_lock_irqsave(&dev->event_lock, flags);
+
+   /* wakeup userspace */
+   if (omap_crtc->event)
+   drm_send_vblank_event(dev, omap_crtc->pipe, omap_crtc->event);
+
+   omap_crtc->event = NULL;
+   omap_crtc->old_fb = NULL;
+
+   spin_unlock_irqrestore(&dev->event_lock, flags);
+
+   complete(&omap_crtc->complet

[PATCHv2 03/45] drm: omapdrm: Rename omap_crtc_page_flip_locked to omap_crtc_page_flip

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The operation is called page_flip, rename its implementation
accordingly.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index e5fb8c6e25e6..7ef9147bde73 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -534,10 +534,10 @@ static void page_flip_cb(void *arg)
queue_work(priv->wq, &omap_crtc->page_flip_work);
 }

-static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
-struct drm_framebuffer *fb,
-struct drm_pending_vblank_event *event,
-uint32_t page_flip_flags)
+static int omap_crtc_page_flip(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t page_flip_flags)
 {
struct drm_device *dev = crtc->dev;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -589,7 +589,7 @@ static int omap_crtc_set_property(struct drm_crtc *crtc,
 static const struct drm_crtc_funcs omap_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.destroy = omap_crtc_destroy,
-   .page_flip = omap_crtc_page_flip_locked,
+   .page_flip = omap_crtc_page_flip,
.set_property = omap_crtc_set_property,
 };

-- 
2.1.4



[PATCHv2 10/45] drm: omapdrm: Clean up #include's

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Use the <...> include style instead of "..." for DRM headers and sort
the headers alphabetically to ease detection of duplicates.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_connector.c  |  6 +++---
 drivers/gpu/drm/omapdrm/omap_crtc.c   |  8 
 drivers/gpu/drm/omapdrm/omap_debugfs.c|  6 +++---
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c  | 19 ++-
 drivers/gpu/drm/omapdrm/omap_drv.c|  6 +++---
 drivers/gpu/drm/omapdrm/omap_drv.h|  8 
 drivers/gpu/drm/omapdrm/omap_encoder.c| 10 --
 drivers/gpu/drm/omapdrm/omap_fb.c |  8 
 drivers/gpu/drm/omapdrm/omap_fbdev.c  |  6 +++---
 drivers/gpu/drm/omapdrm/omap_gem.c|  4 ++--
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c |  4 ++--
 drivers/gpu/drm/omapdrm/omap_plane.c  |  2 +-
 12 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 17739737dcf6..cd1b10d660ac 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -17,10 +17,10 @@
  * this program.  If not, see .
  */

-#include "omap_drv.h"
+#include 
+#include 

-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+#include "omap_drv.h"

 /*
  * connector funcs
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 68abc4d7fa0d..6840ed5c45a7 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -19,12 +19,12 @@

 #include 

-#include "omap_drv.h"
-
+#include 
+#include 
 #include 
 #include 
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+
+#include "omap_drv.h"

 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)

diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c 
b/drivers/gpu/drm/omapdrm/omap_debugfs.c
index d4c04d69fc4d..ee91a25127f9 100644
--- a/drivers/gpu/drm/omapdrm/omap_debugfs.c
+++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c
@@ -17,12 +17,12 @@
  * this program.  If not, see .
  */

+#include 
+#include 
+
 #include "omap_drv.h"
 #include "omap_dmm_tiler.h"

-#include "drm_fb_helper.h"
-
-
 #ifdef CONFIG_DEBUG_FS

 static int gem_show(struct seq_file *m, void *arg)
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c 
b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 042038e8a662..f2daad8c3d96 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -15,21 +15,22 @@
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+
+#include 
+#include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include  /* platform_device() */
-#include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
+#include 
+#include 

 #include "omap_dmm_tiler.h"
 #include "omap_dmm_priv.h"
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index e81fbc07ea9b..dbd304691281 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -17,11 +17,11 @@
  * this program.  If not, see .
  */

-#include "omap_drv.h"
+#include 
+#include 

-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
 #include "omap_dmm_tiler.h"
+#include "omap_drv.h"

 #define DRIVER_NAMEMODULE_NAME
 #define DRIVER_DESC"OMAP DRM"
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 774b9f6ab2d6..6448fa809215 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -20,15 +20,15 @@
 #ifndef __OMAP_DRV_H__
 #define __OMAP_DRV_H__

-#include 
 #include 
+#include 
 #include 
+#include 
+
 #include 
 #include 
-#include 
 #include 
-#include 
-
+#include 

 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 7445fb1491ae..ab6ed49f37ab 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -17,16 +17,14 @@
  * this program.  If not, see .
  */

+#include 
+
+#include 
+#include 
 #include 

 #include "omap_drv.h"

-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-
-#include 
-
-
 /*
  * encoder funcs
  */
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c 
b/drivers/gpu/drm/omapdrm/omap_fb.c
index b2c1a29cc12b..e505140a8782 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -17,11 +17,11 @@
  * this program.  If not, see .
  */

-#include "omap_drv.h"
-#include "omap_dm

[PATCHv2 13/45] drm: omapdrm: Implement encoder .disable() and .enable() operations

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The operations are required by the atomic helpers, implement them.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_encoder.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index ab6ed49f37ab..0734527808d5 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -124,12 +124,22 @@ static void omap_encoder_commit(struct drm_encoder 
*encoder)
 {
 }

+static void omap_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static void omap_encoder_enable(struct drm_encoder *encoder)
+{
+}
+
 static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
.dpms = omap_encoder_dpms,
.mode_fixup = omap_encoder_mode_fixup,
.mode_set = omap_encoder_mode_set,
.prepare = omap_encoder_prepare,
.commit = omap_encoder_commit,
+   .disable = omap_encoder_disable,
+   .enable = omap_encoder_enable,
 };

 /*
-- 
2.1.4



[PATCHv2 15/45] drm: omapdrm: Implement planes atomic operations

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Implement the CRTC .atomic_begin() and .atomic_flush() operations, the
plane .atomic_check(), .atomic_update() and operations, and use the
transitional atomic helpers to implement the plane update and disable
operations on top of the new atomic operations.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  |  14 
 drivers/gpu/drm/omapdrm/omap_plane.c | 127 ++-
 2 files changed, 93 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 5f4f5ad93345..277cad1dacf7 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -652,6 +652,18 @@ static int omap_crtc_mode_set_base(struct drm_crtc *crtc, 
int x, int y,
return omap_crtc_flush(crtc);
 }

+static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
+{
+   dispc_runtime_get();
+}
+
+static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
+{
+   omap_crtc_flush(crtc);
+
+   dispc_runtime_put();
+}
+
 static void page_flip_worker(struct work_struct *work)
 {
struct omap_crtc *omap_crtc =
@@ -792,6 +804,8 @@ static const struct drm_crtc_helper_funcs 
omap_crtc_helper_funcs = {
.mode_set_base = omap_crtc_mode_set_base,
.disable = omap_crtc_disable,
.enable = omap_crtc_enable,
+   .atomic_begin = omap_crtc_atomic_begin,
+   .atomic_flush = omap_crtc_atomic_flush,
 };

 /* 
-
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 533dcc15f03c..7587bac1b222 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -18,6 +18,7 @@
  */

 #include 
+#include 

 #include "omap_dmm_tiler.h"
 #include "omap_drv.h"
@@ -87,30 +88,23 @@ static int omap_plane_update_pin(struct drm_plane *plane)
return 0;
 }

-static int omap_plane_setup(struct omap_plane *omap_plane)
+static int __omap_plane_setup(struct omap_plane *omap_plane,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb)
 {
struct omap_overlay_info *info = &omap_plane->info;
-   struct drm_plane *plane = &omap_plane->base;
-   struct drm_device *dev = plane->dev;
-   struct drm_crtc *crtc = plane->crtc;
+   struct drm_device *dev = omap_plane->base.dev;
int ret;

DBG("%s, enabled=%d", omap_plane->name, omap_plane->enabled);

-   /* if fb has changed, pin new fb: */
-   ret = omap_plane_update_pin(plane);
-   if (ret)
-   return ret;
-
-   dispc_runtime_get();
-
if (!omap_plane->enabled) {
dispc_ovl_enable(omap_plane->id, false);
-   goto done;
+   return 0;
}

/* update scanout: */
-   omap_framebuffer_update_scanout(plane->fb, &omap_plane->win, info);
+   omap_framebuffer_update_scanout(fb, &omap_plane->win, info);

DBG("%dx%d -> %dx%d (%d)", info->width, info->height,
info->out_width, info->out_height,
@@ -126,13 +120,27 @@ static int omap_plane_setup(struct omap_plane *omap_plane)
  omap_crtc_timings(crtc), false);
if (ret) {
dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret);
-   goto done;
+   return ret;
}

dispc_ovl_enable(omap_plane->id, true);

-done:
+   return 0;
+}
+
+static int omap_plane_setup(struct omap_plane *omap_plane)
+{
+   struct drm_plane *plane = &omap_plane->base;
+   int ret;
+
+   ret = omap_plane_update_pin(plane);
+   if (ret < 0)
+   return ret;
+
+   dispc_runtime_get();
+   ret = __omap_plane_setup(omap_plane, plane->crtc, plane->fb);
dispc_runtime_put();
+
return ret;
 }

@@ -170,45 +178,62 @@ int omap_plane_set_enable(struct drm_plane *plane, bool 
enable)
return omap_plane_setup(omap_plane);
 }

-static int omap_plane_update(struct drm_plane *plane,
-   struct drm_crtc *crtc, struct drm_framebuffer *fb,
-   int crtc_x, int crtc_y,
-   unsigned int crtc_w, unsigned int crtc_h,
-   uint32_t src_x, uint32_t src_y,
-   uint32_t src_w, uint32_t src_h)
+static int omap_plane_prepare_fb(struct drm_plane *plane,
+struct drm_framebuffer *fb,
+const struct drm_plane_state *new_state)
+{
+   return omap_framebuffer_pin(fb);
+}
+
+static void omap_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb,
+ const struct drm_plane_state *old_state)
+{
+   omap_framebuffer_unpin(fb);
+}
+
+static void omap_plane_atomic_update(struct drm_plane *plane,
+   

[PATCHv2 17/45] drm: omapdrm: Switch plane update to atomic helpers

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

This removes the legacy plane update code. Wire up the default atomic
check and atomic commit mode config helpers as needed by the plane
update atomic helpers.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_drv.c   | 3 +++
 drivers/gpu/drm/omapdrm/omap_plane.c | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 5bf4b2b71126..ec0ae4220e72 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -17,6 +17,7 @@
  * this program.  If not, see .
  */

+#include 
 #include 
 #include 

@@ -58,6 +59,8 @@ static void omap_fb_output_poll_changed(struct drm_device 
*dev)
 static const struct drm_mode_config_funcs omap_mode_config_funcs = {
.fb_create = omap_framebuffer_create,
.output_poll_changed = omap_fb_output_poll_changed,
+   .atomic_check = drm_atomic_helper_check,
+   .atomic_commit = drm_atomic_helper_commit,
 };

 static int get_connector_type(struct omap_dss_device *dssdev)
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 7587bac1b222..fcc5d9603292 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -316,8 +316,8 @@ int omap_plane_set_property(struct drm_plane *plane,
 }

 static const struct drm_plane_funcs omap_plane_funcs = {
-   .update_plane = drm_plane_helper_update,
-   .disable_plane = drm_plane_helper_disable,
+   .update_plane = drm_atomic_helper_update_plane,
+   .disable_plane = drm_atomic_helper_disable_plane,
.reset = drm_atomic_helper_plane_reset,
.destroy = omap_plane_destroy,
.set_property = omap_plane_set_property,
-- 
2.1.4



[PATCHv2 18/45] drm: omapdrm: Switch mode config to atomic helpers

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

This removes the legacy mode config code. The CRTC and encoder prepare
and commit operations are not used anymore, remove them.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c| 37 +-
 drivers/gpu/drm/omapdrm/omap_encoder.c | 10 -
 2 files changed, 1 insertion(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 31d50533d538..68bf38bd0ce2 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -571,23 +571,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
WARN_ON(omap_plane_set_enable(plane, false));
}

-   /*
-* HACK: Unpin the primary plane frame buffer if we're disabled without
-* going through full mode set.
-* HACK: The legacy set config helper drm_crtc_helper_set_config() that
-* we still use calls the .disable() operation directly when called with
-* a NULL frame buffer (for instance from drm_fb_release()). As a result
-* the CRTC is disabled without going through a full mode set, and the
-* primary plane' framebuffer is kept pin. Unpin it manually here until
-* we switch to the atomic set config helper.
-*/
-   if (crtc->primary->fb) {
-   const struct drm_plane_helper_funcs *funcs;
-
-   funcs = crtc->primary->helper_private;
-   funcs->cleanup_fb(crtc->primary, crtc->primary->fb, NULL);
-   }
-
omap_crtc->enabled = false;

omap_crtc_setup(crtc);
@@ -622,20 +605,6 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
omap_crtc_disable(crtc);
 }

-static void omap_crtc_prepare(struct drm_crtc *crtc)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   DBG("%s", omap_crtc->name);
-   omap_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void omap_crtc_commit(struct drm_crtc *crtc)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   DBG("%s", omap_crtc->name);
-   omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
 static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
 {
dispc_runtime_get();
@@ -771,7 +740,7 @@ static int omap_crtc_set_property(struct drm_crtc *crtc,

 static const struct drm_crtc_funcs omap_crtc_funcs = {
.reset = drm_atomic_helper_crtc_reset,
-   .set_config = drm_crtc_helper_set_config,
+   .set_config = drm_atomic_helper_set_config,
.destroy = omap_crtc_destroy,
.page_flip = omap_crtc_page_flip,
.set_property = omap_crtc_set_property,
@@ -782,11 +751,7 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
.dpms = omap_crtc_dpms,
.mode_fixup = omap_crtc_mode_fixup,
-   .mode_set = drm_helper_crtc_mode_set,
-   .prepare = omap_crtc_prepare,
-   .commit = omap_crtc_commit,
.mode_set_nofb = omap_crtc_mode_set_nofb,
-   .mode_set_base = drm_helper_crtc_mode_set_base,
.disable = omap_crtc_disable,
.enable = omap_crtc_enable,
.atomic_begin = omap_crtc_atomic_begin,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 0734527808d5..96459f709147 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -116,14 +116,6 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
}
 }

-static void omap_encoder_prepare(struct drm_encoder *encoder)
-{
-}
-
-static void omap_encoder_commit(struct drm_encoder *encoder)
-{
-}
-
 static void omap_encoder_disable(struct drm_encoder *encoder)
 {
 }
@@ -136,8 +128,6 @@ static const struct drm_encoder_helper_funcs 
omap_encoder_helper_funcs = {
.dpms = omap_encoder_dpms,
.mode_fixup = omap_encoder_mode_fixup,
.mode_set = omap_encoder_mode_set,
-   .prepare = omap_encoder_prepare,
-   .commit = omap_encoder_commit,
.disable = omap_encoder_disable,
.enable = omap_encoder_enable,
 };
-- 
2.1.4



[PATCHv2 20/45] drm: omapdrm: Replace encoder mode_fixup with atomic_check

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The encoder .mode_fixup() operation is legacy, atomic updates uses the
new .atomic_check() operation. Convert the encoder driver.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_encoder.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 2aeb41f0881a..54847ed089ef 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -62,13 +62,6 @@ static const struct drm_encoder_funcs omap_encoder_funcs = {
.destroy = omap_encoder_destroy,
 };

-static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
-   return true;
-}
-
 static void omap_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -117,11 +110,18 @@ static void omap_encoder_enable(struct drm_encoder 
*encoder)
 {
 }

+static int omap_encoder_atomic_check(struct drm_encoder *encoder,
+struct drm_crtc_state *crtc_state,
+struct drm_connector_state *conn_state)
+{
+   return 0;
+}
+
 static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
-   .mode_fixup = omap_encoder_mode_fixup,
.mode_set = omap_encoder_mode_set,
.disable = omap_encoder_disable,
.enable = omap_encoder_enable,
+   .atomic_check = omap_encoder_atomic_check,
 };

 /*
-- 
2.1.4



[PATCHv2 24/45] drm: omapdrm: Switch crtc and plane set_property to atomic helpers

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Allow setting up plane properties atomically using the plane
set_property atomic helper. The properties are now stored in the plane
state (requiring subclassing it) and applied when updating the planes.

The CRTC exposes the properties of its primary plane for legacy reason.
We can't get rid of that API, so simply delegate it to the primary
plane.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  |  45 +++--
 drivers/gpu/drm/omapdrm/omap_drv.h   |   2 -
 drivers/gpu/drm/omapdrm/omap_plane.c | 180 +++
 3 files changed, 156 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 646563e47562..b32a6fb05338 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -540,17 +540,44 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
omap_crtc_flush(crtc);

dispc_runtime_put();
+
+   crtc->invert_dimensions = !!(crtc->primary->state->rotation &
+   (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270)));
 }

-static int omap_crtc_set_property(struct drm_crtc *crtc,
-   struct drm_property *property, uint64_t val)
+static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
+struct drm_crtc_state *state,
+struct drm_property *property,
+uint64_t val)
 {
-   if (property == crtc->dev->mode_config.rotation_property) {
-   crtc->invert_dimensions =
-   !!(val & ((1LL << DRM_ROTATE_90) | (1LL << 
DRM_ROTATE_270)));
-   }
+   struct drm_plane_state *plane_state;
+   struct drm_plane *plane = crtc->primary;
+
+   /*
+* Delegate property set to the primary plane. Get the plane state and
+* set the property directly.
+*/
+
+   plane_state = drm_atomic_get_plane_state(state->state, plane);
+   if (!plane_state)
+   return -EINVAL;
+
+   return drm_atomic_plane_set_property(plane, plane_state, property, val);
+}

-   return omap_plane_set_property(crtc->primary, property, val);
+static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
+const struct drm_crtc_state *state,
+struct drm_property *property,
+uint64_t *val)
+{
+   /*
+* Delegate property get to the primary plane. The
+* drm_atomic_plane_get_property() function isn't exported, but can be
+* called through drm_object_property_get_value() as that will call
+* drm_atomic_get_property() for atomic drivers.
+*/
+   return drm_object_property_get_value(&crtc->primary->base, property,
+val);
 }

 static const struct drm_crtc_funcs omap_crtc_funcs = {
@@ -558,9 +585,11 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = omap_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
-   .set_property = omap_crtc_set_property,
+   .set_property = drm_atomic_helper_crtc_set_property,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+   .atomic_set_property = omap_crtc_atomic_set_property,
+   .atomic_get_property = omap_crtc_atomic_get_property,
 };

 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 580fe10184d7..f5209412fae6 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -154,8 +154,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 int omap_plane_set_enable(struct drm_plane *plane, bool enable);
 void omap_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj);
-int omap_plane_set_property(struct drm_plane *plane,
-   struct drm_property *property, uint64_t val);

 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_dss_device *dssdev);
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 7813e48b6896..7011cb23d3eb 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -51,10 +51,22 @@ struct omap_plane {
struct omap_drm_irq error_irq;
 };

-static int __omap_plane_setup(struct omap_plane *omap_plane,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb)
+struct omap_plane_state {
+   struct drm_plane_state base;
+
+   unsigned int zorder;
+};
+
+s

[PATCHv2 26/45] drm: omapdrm: Move crtc info out of the crtc structure

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The crtc info structure is only used to setup the crtc through the DSS
API. Move it from the crtc structure to local variables in
omap_crtc_dss_enable().

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index b32a6fb05338..430bf64521f0 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -35,7 +35,6 @@ struct omap_crtc {

const char *name;
enum omap_channel channel;
-   struct omap_overlay_manager_info info;
struct drm_encoder *current_encoder;

/*
@@ -188,8 +187,15 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, 
bool enable)
 static int omap_crtc_dss_enable(struct omap_overlay_manager *mgr)
 {
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+   struct omap_overlay_manager_info info;

-   dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
+   memset(&info, 0, sizeof(info));
+   info.default_color = 0x;
+   info.trans_key = 0x;
+   info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
+   info.trans_enabled = false;
+
+   dispc_mgr_setup(omap_crtc->channel, &info);
dispc_mgr_set_timings(omap_crtc->channel,
&omap_crtc->timings);
omap_crtc_set_enabled(&omap_crtc->base, true);
@@ -628,7 +634,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 {
struct drm_crtc *crtc = NULL;
struct omap_crtc *omap_crtc;
-   struct omap_overlay_manager_info *info;
int ret;

DBG("%s", channel_names[channel]);
@@ -656,13 +661,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
/* temporary: */
omap_crtc->mgr = omap_dss_get_overlay_manager(channel);

-   /* TODO: fix hard-coded setup.. add properties! */
-   info = &omap_crtc->info;
-   info->default_color = 0x;
-   info->trans_key = 0x;
-   info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
-   info->trans_enabled = false;
-
ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
&omap_crtc_funcs);
if (ret < 0) {
-- 
2.1.4



[PATCHv2 27/45] drm: omapdrm: Remove omap_crtc enabled field

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The field tracks the CRTC state to avoid double-enable or -disable. As
the DRM atomic core guarantees that the CRTC enable and disable
functions won't be called on an already enabled or disabled CRTC, such
tracking isn't needed. Remove the enabled field.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 32 +---
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 430bf64521f0..e93ed34dea33 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -46,7 +46,6 @@ struct omap_crtc {
struct omap_overlay_manager *mgr;

struct omap_video_timings timings;
-   bool enabled;

struct omap_drm_irq vblank_irq;
struct omap_drm_irq error_irq;
@@ -126,7 +125,7 @@ static void omap_crtc_dss_start_update(struct 
omap_overlay_manager *mgr)
 {
 }

-/* Called only from omap_crtc_setup and suspend/resume handlers. */
+/* Called only from omap_crtc_encoder_setup and suspend/resume handlers. */
 static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 {
struct drm_device *dev = crtc->dev;
@@ -385,14 +384,14 @@ int omap_crtc_flush(struct drm_crtc *crtc)
return 0;
 }

-static void omap_crtc_setup(struct drm_crtc *crtc)
+static void omap_crtc_encoder_setup(struct drm_crtc *crtc, bool enable)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
struct omap_drm_private *priv = crtc->dev->dev_private;
struct drm_encoder *encoder = NULL;
unsigned int i;

-   DBG("%s: enabled=%d", omap_crtc->name, omap_crtc->enabled);
+   DBG("%s: enable=%d", omap_crtc->name, enable);

dispc_runtime_get();

@@ -408,14 +407,11 @@ static void omap_crtc_setup(struct drm_crtc *crtc)

omap_crtc->current_encoder = encoder;

-   if (!omap_crtc->enabled) {
-   if (encoder)
-   omap_encoder_set_enabled(encoder, false);
-   } else {
-   if (encoder) {
-   omap_encoder_set_enabled(encoder, false);
+   if (encoder) {
+   omap_encoder_set_enabled(encoder, false);
+   if (enable) {
omap_encoder_update(encoder, omap_crtc->mgr,
-   &omap_crtc->timings);
+   &omap_crtc->timings);
omap_encoder_set_enabled(encoder, true);
}
}
@@ -456,9 +452,6 @@ static void omap_crtc_enable(struct drm_crtc *crtc)

DBG("%s", omap_crtc->name);

-   if (omap_crtc->enabled)
-   return;
-
/* Enable all planes associated with the CRTC. */
for (i = 0; i < priv->num_planes; i++) {
struct drm_plane *plane = priv->planes[i];
@@ -467,9 +460,7 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
WARN_ON(omap_plane_set_enable(plane, true));
}

-   omap_crtc->enabled = true;
-
-   omap_crtc_setup(crtc);
+   omap_crtc_encoder_setup(crtc, true);
omap_crtc_flush(crtc);

dispc_runtime_get();
@@ -485,9 +476,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)

DBG("%s", omap_crtc->name);

-   if (!omap_crtc->enabled)
-   return;
-
omap_crtc_wait_page_flip(crtc);
dispc_runtime_get();
drm_crtc_vblank_off(crtc);
@@ -501,9 +489,7 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
WARN_ON(omap_plane_set_enable(plane, false));
}

-   omap_crtc->enabled = false;
-
-   omap_crtc_setup(crtc);
+   omap_crtc_encoder_setup(crtc, false);
omap_crtc_flush(crtc);
 }

-- 
2.1.4



[PATCHv2 29/45] drm: omapdrm: Make the omap_crtc_flush function static

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The function isn't used outside of its compilation unit, make it static.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +-
 drivers/gpu/drm/omapdrm/omap_drv.h  | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 82d03ed92576..96ba21509607 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -359,7 +359,7 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, 
uint32_t irqstatus)
complete(&omap_crtc->completion);
 }

-int omap_crtc_flush(struct drm_crtc *crtc)
+static int omap_crtc_flush(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 7f815552fe7e..c7ef4d8977ec 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -142,7 +142,6 @@ void omap_fbdev_free(struct drm_device *dev);

 const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
-int omap_crtc_flush(struct drm_crtc *crtc);
 void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
 void omap_crtc_pre_init(void);
 void omap_crtc_pre_uninit(void);
-- 
2.1.4



[PATCHv2 31/45] drm: omapdrm: omap_crtc_flush() isn't called with modeset locked

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

When performing asynchronous atomic updates the modeset lock isn't taken
around the callers of omap_crtc_flush(). This isn't an issue though, as
access to the CRTC is properly serialized. Just drop the warning.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 993bd15ecfbd..8cbac72a1015 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -365,7 +365,6 @@ static int omap_crtc_flush(struct drm_crtc *crtc)

DBG("%s: GO", omap_crtc->name);

-   WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
WARN_ON(omap_crtc->vblank_irq.registered);

if (dispc_mgr_is_enabled(omap_crtc->channel)) {
-- 
2.1.4



[PATCHv2 36/45] drm: omapdrm: Don't flush CRTC when enabling or disabling it

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The omap_crtc_flush() call in omap_crtc_enable() and omap_crtc_disable()
is a no-op, as the display manager is always disabled at this point. Just
remove the function call.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 2236f52f8bc3..701406e1f0ee 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -405,8 +405,6 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
WARN_ON(omap_plane_setup(plane));
}

-   omap_crtc_flush(crtc);
-
drm_crtc_vblank_on(crtc);
 }

@@ -428,8 +426,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
if (plane->crtc == crtc)
WARN_ON(omap_plane_setup(plane));
}
-
-   omap_crtc_flush(crtc);
 }

 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
-- 
2.1.4



[PATCHv2 37/45] drm: omapdrm: Don't setup planes manually from CRTC .enable()/.disable()

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Planes setup is handled by the DRM core through the atomic helpers,
there's no need to duplicate the code in the CRTC .enable() and
.disable() operations.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 20 
 drivers/gpu/drm/omapdrm/omap_drv.h   |  1 -
 drivers/gpu/drm/omapdrm/omap_plane.c |  2 +-
 3 files changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 701406e1f0ee..abfafd1600b8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -391,41 +391,21 @@ static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,

 static void omap_crtc_enable(struct drm_crtc *crtc)
 {
-   struct omap_drm_private *priv = crtc->dev->dev_private;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   unsigned int i;

DBG("%s", omap_crtc->name);

-   /* Enable all planes associated with the CRTC. */
-   for (i = 0; i < priv->num_planes; i++) {
-   struct drm_plane *plane = priv->planes[i];
-
-   if (plane->crtc == crtc)
-   WARN_ON(omap_plane_setup(plane));
-   }
-
drm_crtc_vblank_on(crtc);
 }

 static void omap_crtc_disable(struct drm_crtc *crtc)
 {
-   struct omap_drm_private *priv = crtc->dev->dev_private;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   unsigned int i;

DBG("%s", omap_crtc->name);

omap_crtc_wait_page_flip(crtc);
drm_crtc_vblank_off(crtc);
-
-   /* Disable all planes associated with the CRTC. */
-   for (i = 0; i < priv->num_planes; i++) {
-   struct drm_plane *plane = priv->planes[i];
-
-   if (plane->crtc == crtc)
-   WARN_ON(omap_plane_setup(plane));
-   }
 }

 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index bdd54162698f..0b7a055bf007 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -150,7 +150,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,

 struct drm_plane *omap_plane_init(struct drm_device *dev,
int id, enum drm_plane_type type);
-int omap_plane_setup(struct drm_plane *plane);
 void omap_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj);

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index d18fe106e256..448707669690 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -58,7 +58,7 @@ to_omap_plane_state(struct drm_plane_state *state)
return container_of(state, struct omap_plane_state, base);
 }

-int omap_plane_setup(struct drm_plane *plane)
+static int omap_plane_setup(struct drm_plane *plane)
 {
struct omap_plane *omap_plane = to_omap_plane(plane);
struct drm_plane_state *state = plane->state;
-- 
2.1.4



[PATCHv2 39/45] drm: omapdrm: inline omap_plane_setup into update/disable

2015-06-04 Thread Tomi Valkeinen
At the moment we have omap_plane_setup() function which handles both
enabling (and configuring) and disabling the plane. With atomic
modesetting we have separate hooks for plane enable/config and disable.

This patch moves the code from omap_plane_setup() to
omap_plane_atomic_update() and omap_plane_atomic_disable().

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 44 ++--
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index a8e617f9f2af..b13fb2fd4a9a 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -58,7 +58,22 @@ to_omap_plane_state(struct drm_plane_state *state)
return container_of(state, struct omap_plane_state, base);
 }

-static void omap_plane_setup(struct drm_plane *plane)
+static int omap_plane_prepare_fb(struct drm_plane *plane,
+struct drm_framebuffer *fb,
+const struct drm_plane_state *new_state)
+{
+   return omap_framebuffer_pin(fb);
+}
+
+static void omap_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb,
+ const struct drm_plane_state *old_state)
+{
+   omap_framebuffer_unpin(fb);
+}
+
+static void omap_plane_atomic_update(struct drm_plane *plane,
+struct drm_plane_state *old_state)
 {
struct omap_plane *omap_plane = to_omap_plane(plane);
struct drm_plane_state *state = plane->state;
@@ -69,11 +84,6 @@ static void omap_plane_setup(struct drm_plane *plane)

DBG("%s, crtc=%p fb=%p", omap_plane->name, state->crtc, state->fb);

-   if (!state->crtc) {
-   dispc_ovl_enable(omap_plane->id, false);
-   return;
-   }
-
memset(&info, 0, sizeof(info));
info.rotation_type = OMAP_DSS_ROT_DMA;
info.rotation = OMAP_DSS_ROT_0;
@@ -128,26 +138,6 @@ static void omap_plane_setup(struct drm_plane *plane)
dispc_ovl_enable(omap_plane->id, true);
 }

-static int omap_plane_prepare_fb(struct drm_plane *plane,
-struct drm_framebuffer *fb,
-const struct drm_plane_state *new_state)
-{
-   return omap_framebuffer_pin(fb);
-}
-
-static void omap_plane_cleanup_fb(struct drm_plane *plane,
- struct drm_framebuffer *fb,
- const struct drm_plane_state *old_state)
-{
-   omap_framebuffer_unpin(fb);
-}
-
-static void omap_plane_atomic_update(struct drm_plane *plane,
-struct drm_plane_state *old_state)
-{
-   omap_plane_setup(plane);
-}
-
 static void omap_plane_atomic_disable(struct drm_plane *plane,
  struct drm_plane_state *old_state)
 {
@@ -158,7 +148,7 @@ static void omap_plane_atomic_disable(struct drm_plane 
*plane,
omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY
   ? 0 : omap_plane->id;

-   omap_plane_setup(plane);
+   dispc_ovl_enable(omap_plane->id, false);
 }

 static const struct drm_plane_helper_funcs omap_plane_helper_funcs = {
-- 
2.1.4



[PATCHv2 40/45] drm: omapdrm: if omap_plane_atomic_update fails, disable plane

2015-06-04 Thread Tomi Valkeinen
omap_plane_atomic_update() calls dispc_ovl_setup(), which can fail (but
shouldn't). To make the code a bit more robust, make sure the plane gets
disabled if dispc_ovl_setup() fails, as otherwise we might get illegal
HW configuration leading to error interrupts.

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index b13fb2fd4a9a..cfa8276c4deb 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -132,8 +132,10 @@ static void omap_plane_atomic_update(struct drm_plane 
*plane,
/* and finally, update omapdss: */
ret = dispc_ovl_setup(omap_plane->id, &info, false,
  omap_crtc_timings(state->crtc), false);
-   if (WARN_ON(ret))
+   if (WARN_ON(ret)) {
+   dispc_ovl_enable(omap_plane->id, false);
return;
+   }

dispc_ovl_enable(omap_plane->id, true);
 }
-- 
2.1.4



[PATCHv2 42/45] drm: omapdrm: add omap_atomic_wait_for_gos()

2015-06-04 Thread Tomi Valkeinen
omap_atomic_complete() uses drm_atomic_helper_wait_for_vblanks() to wait
for all operations to finish. That works, but can easily cause waits for
vblanks when no wait is actually necessary.

This patch adds omap_atomic_wait_for_gos() and uses it instead.
omap_atomic_wait_for_gos() waits for the GO bit to get unset for all
relevant crtcs.

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c |  7 +++
 drivers/gpu/drm/omapdrm/omap_drv.c  | 31 ++-
 drivers/gpu/drm/omapdrm/omap_drv.h  |  1 +
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 2c0d91a67418..8f905d2c8074 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -80,6 +80,13 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
return omap_crtc->channel;
 }

+bool omap_crtc_needs_wait(struct drm_crtc *crtc)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+   return dispc_mgr_go_busy(omap_crtc->channel);
+}
+
 /* 
-
  * DSS Manager Functions
  */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 50f30e55..c03405593f9f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -66,6 +66,35 @@ struct omap_atomic_state_commit {
u32 crtcs;
 };

+static void omap_atomic_wait_for_gos(struct drm_device *dev,
+struct drm_atomic_state *old_state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *old_crtc_state;
+   int i, ret;
+
+   for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+   if (!crtc->state->enable)
+   continue;
+
+   if (!omap_crtc_needs_wait(crtc))
+   continue;
+
+   ret = drm_crtc_vblank_get(crtc);
+   if (ret != 0)
+   continue;
+
+   ret = wait_event_timeout(dev->vblank[i].queue,
+!omap_crtc_needs_wait(crtc),
+msecs_to_jiffies(50));
+   if (!ret)
+   dev_warn(dev->dev,
+"atomic flush timeout (pipe %u)!\n", i);
+
+   drm_crtc_vblank_put(crtc);
+   }
+}
+
 static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
 {
struct drm_device *dev = commit->dev;
@@ -79,7 +108,7 @@ static void omap_atomic_complete(struct 
omap_atomic_state_commit *commit)
drm_atomic_helper_commit_planes(dev, old_state);
drm_atomic_helper_commit_modeset_enables(dev, old_state);

-   drm_atomic_helper_wait_for_vblanks(dev, old_state);
+   omap_atomic_wait_for_gos(dev, old_state);

drm_atomic_helper_cleanup_planes(dev, old_state);

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 0b7a055bf007..27bbf7c4d76e 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -147,6 +147,7 @@ void omap_crtc_pre_init(void);
 void omap_crtc_pre_uninit(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id);
+bool omap_crtc_needs_wait(struct drm_crtc *crtc);

 struct drm_plane *omap_plane_init(struct drm_device *dev,
int id, enum drm_plane_type type);
-- 
2.1.4



[PATCHv2 43/45] drm: omapdrm: don't wait in crtc_atomic_flush

2015-06-04 Thread Tomi Valkeinen
omap_crtc_atomic_flush() sets the GO bit and waits for it to get unset,
which tells us the HW has taken the new configuration into use.

This is unnecessary as omap_atomic_complete() waits for all the GO bits
to get unset. In fact, waiting is wrong, as with multiple CRTCs we would
not get the the changes to all the CRTCs as soon as possible, but only
one after another.

This patch removes the wait.

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 8f905d2c8074..2ec34dc0c66c 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -17,8 +17,6 @@
  * this program.  If not, see .
  */

-#include 
-
 #include 
 #include 
 #include 
@@ -52,8 +50,6 @@ struct omap_crtc {
/* pending event */
struct drm_pending_vblank_event *event;

-   struct completion completion;
-
bool ignore_digit_sync_lost;
 };

@@ -317,8 +313,6 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, 
uint32_t irqstatus)

/* wakeup userspace */
omap_crtc_complete_page_flip(&omap_crtc->base);
-
-   complete(&omap_crtc->completion);
 }

 static int omap_crtc_flush(struct drm_crtc *crtc)
@@ -332,10 +326,6 @@ static int omap_crtc_flush(struct drm_crtc *crtc)
if (dispc_mgr_is_enabled(omap_crtc->channel)) {
dispc_mgr_go(omap_crtc->channel);
omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
-
-   WARN_ON(!wait_for_completion_timeout(&omap_crtc->completion,
-msecs_to_jiffies(100)));
-   reinit_completion(&omap_crtc->completion);
}

return 0;
@@ -517,8 +507,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,

crtc = &omap_crtc->base;

-   init_completion(&omap_crtc->completion);
-
omap_crtc->channel = channel;
omap_crtc->name = channel_names[channel];

-- 
2.1.4



[PATCHv2 44/45] drm: omapdrm: merge omap_crtc_flush and omap_crtc_atomic_flush

2015-06-04 Thread Tomi Valkeinen
omap_crtc_atomic_flush() is the only user of omap_crtc_flush(), so just
move the code from omap_crtc_flush() to omap_crtc_atomic_flush().

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 27 ++-
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 2ec34dc0c66c..b7df689cdb4c 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -315,22 +315,6 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, 
uint32_t irqstatus)
omap_crtc_complete_page_flip(&omap_crtc->base);
 }

-static int omap_crtc_flush(struct drm_crtc *crtc)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-
-   DBG("%s: GO", omap_crtc->name);
-
-   WARN_ON(omap_crtc->vblank_irq.registered);
-
-   if (dispc_mgr_is_enabled(omap_crtc->channel)) {
-   dispc_mgr_go(omap_crtc->channel);
-   omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
-   }
-
-   return 0;
-}
-
 /* 
-
  * CRTC Functions
  */
@@ -408,7 +392,16 @@ static void omap_crtc_atomic_begin(struct drm_crtc *crtc)

 static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
 {
-   omap_crtc_flush(crtc);
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+   if (dispc_mgr_is_enabled(omap_crtc->channel)) {
+   WARN_ON(omap_crtc->vblank_irq.registered);
+
+   DBG("%s: GO", omap_crtc->name);
+
+   dispc_mgr_go(omap_crtc->channel);
+   omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
+   }

crtc->invert_dimensions = !!(crtc->primary->state->rotation &
(BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270)));
-- 
2.1.4



[PATCHv2 41/45] drm: omapdrm: remove omap_crtc_wait_page_flip

2015-06-04 Thread Tomi Valkeinen
omap_crtc_disable() waits for pending page flips to finish. However,
omap_crtc_disable() is always called via omap_atomic_complete() and we
never have page flips going on at that time.

So remove the omap_crtc_wait_page_flip() and related code.

Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 32 
 1 file changed, 32 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index abfafd1600b8..2c0d91a67418 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -51,7 +51,6 @@ struct omap_crtc {

/* pending event */
struct drm_pending_vblank_event *event;
-   wait_queue_head_t flip_wait;

struct completion completion;

@@ -277,41 +276,12 @@ static void omap_crtc_complete_page_flip(struct drm_crtc 
*crtc)
else
event->base.destroy(&event->base);

-   wake_up(&omap_crtc->flip_wait);
drm_crtc_vblank_put(crtc);
}

spin_unlock_irqrestore(&dev->event_lock, flags);
 }

-static bool omap_crtc_page_flip_pending(struct drm_crtc *crtc)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   struct drm_device *dev = crtc->dev;
-   unsigned long flags;
-   bool pending;
-
-   spin_lock_irqsave(&dev->event_lock, flags);
-   pending = omap_crtc->event != NULL;
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-
-   return pending;
-}
-
-static void omap_crtc_wait_page_flip(struct drm_crtc *crtc)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-
-   if (wait_event_timeout(omap_crtc->flip_wait,
-  !omap_crtc_page_flip_pending(crtc),
-  msecs_to_jiffies(50)))
-   return;
-
-   dev_warn(crtc->dev->dev, "page flip timeout!\n");
-
-   omap_crtc_complete_page_flip(crtc);
-}
-
 static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 {
struct omap_crtc *omap_crtc =
@@ -404,7 +374,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)

DBG("%s", omap_crtc->name);

-   omap_crtc_wait_page_flip(crtc);
drm_crtc_vblank_off(crtc);
 }

@@ -541,7 +510,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,

crtc = &omap_crtc->base;

-   init_waitqueue_head(&omap_crtc->flip_wait);
init_completion(&omap_crtc->completion);

omap_crtc->channel = channel;
-- 
2.1.4



[PATCHv2 14/45] drm: omapdrm: Wire up atomic state object scaffolding

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Hook up the default .reset(), .atomic_duplicate_state() and
.atomic_free_state() helpers to ensure that state objects are properly
created and destroyed, and call drm_mode_config_reset() at init time to
create the initial state objects.

Framebuffer reference count also gets maintained automatically by the
transitional helpers except for the legacy page flip operation. Maintain
it explicitly there.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 4 
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 6 ++
 drivers/gpu/drm/omapdrm/omap_drv.c   | 2 ++
 drivers/gpu/drm/omapdrm/omap_plane.c | 5 +
 4 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index cd1b10d660ac..d170f0cb1aa9 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -17,6 +17,7 @@
  * this program.  If not, see .
  */

+#include 
 #include 
 #include 

@@ -260,9 +261,12 @@ struct drm_encoder *omap_connector_attached_encoder(

 static const struct drm_connector_funcs omap_connector_funcs = {
.dpms = drm_helper_connector_dpms,
+   .reset = drm_atomic_helper_connector_reset,
.detect = omap_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = omap_connector_destroy,
+   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };

 static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 0359a67f8f8d..5f4f5ad93345 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -19,6 +19,8 @@

 #include 

+#include 
+#include 
 #include 
 #include 
 #include 
@@ -742,6 +744,7 @@ static int omap_crtc_page_flip(struct drm_crtc *crtc,
omap_crtc->flip_event = event;
omap_crtc->flip_state = OMAP_PAGE_FLIP_WAIT;

+   drm_atomic_set_fb_for_plane(primary->state, fb);
primary->fb = fb;

spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -771,10 +774,13 @@ static int omap_crtc_set_property(struct drm_crtc *crtc,
 }

 static const struct drm_crtc_funcs omap_crtc_funcs = {
+   .reset = drm_atomic_helper_crtc_reset,
.set_config = drm_crtc_helper_set_config,
.destroy = omap_crtc_destroy,
.page_flip = omap_crtc_page_flip,
.set_property = omap_crtc_set_property,
+   .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };

 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index dbd304691281..5bf4b2b71126 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -350,6 +350,8 @@ static int omap_modeset_init(struct drm_device *dev)

dev->mode_config.funcs = &omap_mode_config_funcs;

+   drm_mode_config_reset(dev);
+
return 0;
 }

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 57d5b035d078..533dcc15f03c 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -17,6 +17,8 @@
  * this program.  If not, see .
  */

+#include 
+
 #include "omap_dmm_tiler.h"
 #include "omap_drv.h"

@@ -287,8 +289,11 @@ int omap_plane_set_property(struct drm_plane *plane,
 static const struct drm_plane_funcs omap_plane_funcs = {
.update_plane = omap_plane_update,
.disable_plane = omap_plane_disable,
+   .reset = drm_atomic_helper_plane_reset,
.destroy = omap_plane_destroy,
.set_property = omap_plane_set_property,
+   .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };

 static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
-- 
2.1.4



[PATCHv2 25/45] drm: omapdrm: Move plane info and win out of the plane structure

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

The plane info and win structures are only used to setup the plane
through the DSS API. Move them from the plane structure to local
variables in omap_plane_setup().

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 92 
 1 file changed, 41 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c 
b/drivers/gpu/drm/omapdrm/omap_plane.c
index 7011cb23d3eb..465fd9cafd7b 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -39,10 +39,7 @@ struct omap_plane {
struct drm_plane base;
int id;  /* TODO rename omap_plane -> omap_plane_id in omapdss so I can 
use the enum */
const char *name;
-   struct omap_overlay_info info;

-   /* position/orientation of scanout within the fb: */
-   struct omap_drm_window win;
bool enabled;

uint32_t nformats;
@@ -67,8 +64,9 @@ static int omap_plane_setup(struct omap_plane *omap_plane)
 {
struct drm_plane_state *state = omap_plane->base.state;
struct omap_plane_state *omap_state = to_omap_plane_state(state);
-   struct omap_overlay_info *info = &omap_plane->info;
struct drm_device *dev = omap_plane->base.dev;
+   struct omap_overlay_info info;
+   struct omap_drm_window win;
int ret;

DBG("%s, enabled=%d", omap_plane->name, omap_plane->enabled);
@@ -78,22 +76,53 @@ static int omap_plane_setup(struct omap_plane *omap_plane)
return 0;
}

-   info->zorder = omap_state->zorder;
+   memset(&info, 0, sizeof(info));
+   info.rotation_type = OMAP_DSS_ROT_DMA;
+   info.rotation = OMAP_DSS_ROT_0;
+   info.global_alpha = 0xff;
+   info.mirror = 0;
+   info.zorder = omap_state->zorder;
+
+   memset(&win, 0, sizeof(win));
+   win.rotation = state->rotation;
+   win.crtc_x = state->crtc_x;
+   win.crtc_y = state->crtc_y;
+   win.crtc_w = state->crtc_w;
+   win.crtc_h = state->crtc_h;
+
+   /*
+* src values are in Q16 fixed point, convert to integer.
+* omap_framebuffer_update_scanout() takes adjusted src.
+*/
+   win.src_x = state->src_x >> 16;
+   win.src_y = state->src_y >> 16;
+
+   switch (state->rotation & 0xf) {
+   case BIT(DRM_ROTATE_90):
+   case BIT(DRM_ROTATE_270):
+   win.src_w = state->src_h >> 16;
+   win.src_h = state->src_w >> 16;
+   break;
+   default:
+   win.src_w = state->src_w >> 16;
+   win.src_h = state->src_h >> 16;
+   break;
+   }

/* update scanout: */
-   omap_framebuffer_update_scanout(state->fb, &omap_plane->win, info);
+   omap_framebuffer_update_scanout(state->fb, &win, &info);

-   DBG("%dx%d -> %dx%d (%d)", info->width, info->height,
-   info->out_width, info->out_height,
-   info->screen_width);
-   DBG("%d,%d %pad %pad", info->pos_x, info->pos_y,
-   &info->paddr, &info->p_uv_addr);
+   DBG("%dx%d -> %dx%d (%d)", info.width, info.height,
+   info.out_width, info.out_height,
+   info.screen_width);
+   DBG("%d,%d %pad %pad", info.pos_x, info.pos_y,
+   &info.paddr, &info.p_uv_addr);

dispc_ovl_set_channel_out(omap_plane->id,
  omap_crtc_channel(state->crtc));

/* and finally, update omapdss: */
-   ret = dispc_ovl_setup(omap_plane->id, info, false,
+   ret = dispc_ovl_setup(omap_plane->id, &info, false,
  omap_crtc_timings(state->crtc), false);
if (ret) {
dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret);
@@ -140,40 +169,11 @@ static void omap_plane_atomic_update(struct drm_plane 
*plane,
 struct drm_plane_state *old_state)
 {
struct omap_plane *omap_plane = to_omap_plane(plane);
-   struct omap_drm_window *win = &omap_plane->win;
struct drm_plane_state *state = plane->state;
-   uint32_t src_w;
-   uint32_t src_h;

if (!state->fb || !state->crtc)
return;

-   win->rotation = state->rotation;
-
-   /* omap_framebuffer_update_scanout() takes adjusted src */
-   switch (state->rotation & 0xf) {
-   case BIT(DRM_ROTATE_90):
-   case BIT(DRM_ROTATE_270):
-   src_w = state->src_h;
-   src_h = state->src_w;
-   break;
-   default:
-   src_w = state->src_w;
-   src_h = state->src_h;
-   break;
-   }
-
-   /* src values are in Q16 fixed point, convert to integer. */
-   win->crtc_x = state->crtc_x;
-   win->crtc_y = state->crtc_y;
-   win->crtc_w = state->crtc_w;
-   win->crtc_h = state->crtc_h;
-
-   win->src_x

[PATCHv2 21/45] drm: omapdrm: Implement asynchronous commit support

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Implement a custom .atomic_commit() handler that supports asynchronous
commits using a work queue. This can be used for userspace-driven
asynchronous commits, as well as for an atomic page flip implementation.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 113 -
 drivers/gpu/drm/omapdrm/omap_drv.h |   8 +++
 2 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index ec0ae4220e72..72a5a88a6419 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -17,6 +17,9 @@
  * this program.  If not, see .
  */

+#include 
+
+#include 
 #include 
 #include 
 #include 
@@ -56,11 +59,117 @@ static void omap_fb_output_poll_changed(struct drm_device 
*dev)
drm_fb_helper_hotplug_event(priv->fbdev);
 }

+struct omap_atomic_state_commit {
+   struct work_struct work;
+   struct drm_device *dev;
+   struct drm_atomic_state *state;
+   u32 crtcs;
+};
+
+static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
+{
+   struct drm_device *dev = commit->dev;
+   struct omap_drm_private *priv = dev->dev_private;
+   struct drm_atomic_state *old_state = commit->state;
+
+   /* Apply the atomic update. */
+   drm_atomic_helper_commit_modeset_disables(dev, old_state);
+   drm_atomic_helper_commit_planes(dev, old_state);
+   drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+   drm_atomic_helper_wait_for_vblanks(dev, old_state);
+
+   drm_atomic_helper_cleanup_planes(dev, old_state);
+
+   drm_atomic_state_free(old_state);
+
+   /* Complete the commit, wake up any waiter. */
+   spin_lock(&priv->commit.lock);
+   priv->commit.pending &= ~commit->crtcs;
+   spin_unlock(&priv->commit.lock);
+
+   wake_up_all(&priv->commit.wait);
+
+   kfree(commit);
+}
+
+static void omap_atomic_work(struct work_struct *work)
+{
+   struct omap_atomic_state_commit *commit =
+   container_of(work, struct omap_atomic_state_commit, work);
+
+   omap_atomic_complete(commit);
+}
+
+static bool omap_atomic_is_pending(struct omap_drm_private *priv,
+  struct omap_atomic_state_commit *commit)
+{
+   bool pending;
+
+   spin_lock(&priv->commit.lock);
+   pending = priv->commit.pending & commit->crtcs;
+   spin_unlock(&priv->commit.lock);
+
+   return pending;
+}
+
+static int omap_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state, bool async)
+{
+   struct omap_drm_private *priv = dev->dev_private;
+   struct omap_atomic_state_commit *commit;
+   unsigned int i;
+   int ret;
+
+   ret = drm_atomic_helper_prepare_planes(dev, state);
+   if (ret)
+   return ret;
+
+   /* Allocate the commit object. */
+   commit = kzalloc(sizeof(*commit), GFP_KERNEL);
+   if (commit == NULL) {
+   ret = -ENOMEM;
+   goto error;
+   }
+
+   INIT_WORK(&commit->work, omap_atomic_work);
+   commit->dev = dev;
+   commit->state = state;
+
+   /* Wait until all affected CRTCs have completed previous commits and
+* mark them as pending.
+*/
+   for (i = 0; i < dev->mode_config.num_crtc; ++i) {
+   if (state->crtcs[i])
+   commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
+   }
+
+   wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
+
+   spin_lock(&priv->commit.lock);
+   priv->commit.pending |= commit->crtcs;
+   spin_unlock(&priv->commit.lock);
+
+   /* Swap the state, this is the point of no return. */
+   drm_atomic_helper_swap_state(dev, state);
+
+   if (async)
+   schedule_work(&commit->work);
+   else
+   omap_atomic_complete(commit);
+
+   return 0;
+
+error:
+   drm_atomic_helper_cleanup_planes(dev, state);
+   return ret;
+}
+
 static const struct drm_mode_config_funcs omap_mode_config_funcs = {
.fb_create = omap_framebuffer_create,
.output_poll_changed = omap_fb_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
-   .atomic_commit = drm_atomic_helper_commit,
+   .atomic_commit = omap_atomic_commit,
 };

 static int get_connector_type(struct omap_dss_device *dssdev)
@@ -521,6 +630,8 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
dev->dev_private = priv;

priv->wq = alloc_ordered_workqueue("omapdrm", 0);
+   init_waitqueue_head(&priv->commit.wait);
+   spin_lock_init(&priv->commit.lock);

spin_lock_init(&priv->list_lock);
INIT_LIST_HEAD(&priv->obj_list);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_dr

[PATCHv2 07/45] drm: omapdrm: Rework page flip handling

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

To implement proper vblank control the driver will need to wait for page
flip completion before disabling the vblank interrupt. This is made
complex by the page flip implementation which queues and submits page
flips to the hardware in two separate steps between which DRM locks are
released. We thus need to avoid waiting on a page flip that has been
queued but not submitted as submission and wait are covered by the same
lock.

Rework page flip handling as a first step by splitting the flip_pending
boolean variable into an enumerated state and moving between states
based on flip queue, submission and completion. The CANCELLED state will
be used in a second step.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 84 -
 1 file changed, 64 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index a60f4e49b55f..c086f72e488d 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -28,6 +28,13 @@

 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)

+enum omap_page_flip_state {
+   OMAP_PAGE_FLIP_IDLE,
+   OMAP_PAGE_FLIP_WAIT,
+   OMAP_PAGE_FLIP_QUEUED,
+   OMAP_PAGE_FLIP_CANCELLED,
+};
+
 struct omap_crtc {
struct drm_crtc base;

@@ -55,16 +62,19 @@ struct omap_crtc {
struct list_head pending_unpins;

/*
-* The flip_pending flag indicates if a page flip has been queued and
-* hasn't completed yet. The flip event, if any, is stored in
-* flip_event.
+* flip_state flag indicates the current page flap state: IDLE if no
+* page queue has been submitted, WAIT when waiting for GEM async
+* completion, QUEUED when the page flip has been queued to the hardware
+* or CANCELLED when the CRTC is turned off before the flip gets queued
+* to the hardware. The flip event, if any, is stored in flip_event. The
+* flip_wait wait queue is used to wait for page flip completion.
 *
 * The flip_work work queue handles page flip requests without caring
 * about what context the GEM async callback is called from. Possibly we
 * should just make omap_gem always call the cb from the worker so we
 * don't have to care about this.
 */
-   bool flip_pending;
+   enum omap_page_flip_state flip_state;
struct drm_pending_vblank_event *flip_event;
struct work_struct flip_work;

@@ -285,6 +295,22 @@ void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, 
struct drm_file *file)
spin_unlock_irqrestore(&dev->event_lock, flags);
 }

+/* Must be called with dev->event_lock locked. */
+static void omap_crtc_complete_page_flip(struct drm_crtc *crtc,
+enum omap_page_flip_state state)
+{
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct drm_device *dev = crtc->dev;
+
+   if (omap_crtc->flip_event) {
+   drm_send_vblank_event(dev, omap_crtc->pipe,
+ omap_crtc->flip_event);
+   omap_crtc->flip_event = NULL;
+   }
+
+   omap_crtc->flip_state = state;
+}
+
 static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 {
struct omap_crtc *omap_crtc =
@@ -312,16 +338,9 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, 
uint32_t irqstatus)
DBG("%s: apply done", omap_crtc->name);
__omap_irq_unregister(dev, &omap_crtc->vblank_irq);

-   spin_lock_irqsave(&dev->event_lock, flags);
-
/* wakeup userspace */
-   if (omap_crtc->flip_event)
-   drm_send_vblank_event(dev, omap_crtc->pipe,
- omap_crtc->flip_event);
-
-   omap_crtc->flip_event = NULL;
-   omap_crtc->flip_pending = false;
-
+   spin_lock_irqsave(&dev->event_lock, flags);
+   omap_crtc_complete_page_flip(&omap_crtc->base, OMAP_PAGE_FLIP_IDLE);
spin_unlock_irqrestore(&dev->event_lock, flags);

complete(&omap_crtc->completion);
@@ -533,16 +552,41 @@ static void page_flip_worker(struct work_struct *work)
container_of(work, struct omap_crtc, flip_work);
struct drm_crtc *crtc = &omap_crtc->base;
struct drm_display_mode *mode = &crtc->mode;
+   struct drm_device *dev = crtc->dev;
+   struct drm_framebuffer *fb;
struct drm_gem_object *bo;
+   unsigned long flags;
+   bool queue_flip;

drm_modeset_lock(&crtc->mutex, NULL);
-   omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
-   0, 0, mode->hdisplay, mode->vdisplay,
-   crtc->x, crtc->y, mode->hdisplay, mode->vdisplay);
-   omap_crtc_flush(crtc);
+
+   spin_lock_irqsave(&dev->event_lock, flags);
+   /*
+* The pag

[PATCHv2 32/45] drm: omapdrm: Support unlinking page flip events prematurely

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

DRM page flip vblank events requested by page flips or atomic commits
are created by the DRM core and then passed to driver through CRTC
states (for atomic commit) or directly to the page flip handler (for
legacy page flips). The events are then kept aside until the page flip
completes, at which point drivers queue them for delivery with a call to
drm_send_vblank_event().

When a DRM file handle is closed events pending for delivery are cleaned
up automatically by the DRM core. Events that have been passed to the
driver but haven't completed yet, however, are not handled by the DRM
core. Drivers are responsible for destroying them and must not attempt
to queue them for delivery. This is usually handled by drivers'
preclose() handlers that cancel and destroy page flip events that
reference the file handle being closed.

With asynchronous atomic updates the story becomes more complex. Several
asynchronous atomic updates can be pending, each of them carrying
per-CRTC events. As the atomic_commit() operation doesn't receive a file
handle context, drivers can't know which file handle a pending update
refers to, making it difficult to cancel or wait for completion of
updates related to the file handle being closed.

It should be noted that cancelling page flips or waiting for atomic
updates completion isn't required by the DRM core when closing a file
handle. The only requirement is that no event gets queued for delivery
after the preclose() operation returns. This can easily be achieved by
storing events for atomic commits in a list, unlinking events from the
file handle being closed by setting the file_priv field to NULL, and
skipping delivery of unlinked events.

This logic replaces the page flip cancellation completely.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 36 +++-
 drivers/gpu/drm/omapdrm/omap_drv.c  | 30 +++---
 drivers/gpu/drm/omapdrm/omap_drv.h  |  2 +-
 3 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 8cbac72a1015..aa719ebfe787 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -254,30 +254,6 @@ static const struct dss_mgr_ops mgr_ops = {
  * Setup, Flush and Page Flip
  */

-void omap_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   struct drm_pending_vblank_event *event;
-   struct drm_device *dev = crtc->dev;
-   unsigned long flags;
-
-   /* Destroy the pending vertical blanking event associated with the
-* pending page flip, if any, and disable vertical blanking interrupts.
-*/
-
-   spin_lock_irqsave(&dev->event_lock, flags);
-
-   event = omap_crtc->event;
-   omap_crtc->event = NULL;
-
-   if (event && event->base.file_priv == file) {
-   event->base.destroy(&event->base);
-   drm_crtc_vblank_put(crtc);
-   }
-
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -291,7 +267,17 @@ static void omap_crtc_complete_page_flip(struct drm_crtc 
*crtc)
omap_crtc->event = NULL;

if (event) {
-   drm_crtc_send_vblank_event(crtc, event);
+   list_del(&event->base.link);
+
+   /*
+* Queue the event for delivery if it's still linked to a file
+* handle, otherwise just destroy it.
+*/
+   if (event->base.file_priv)
+   drm_crtc_send_vblank_event(crtc, event);
+   else
+   event->base.destroy(&event->base);
+
wake_up(&omap_crtc->flip_wait);
drm_crtc_vblank_put(crtc);
}
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 72a5a88a6419..2e7706355eb6 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -118,6 +118,7 @@ static int omap_atomic_commit(struct drm_device *dev,
 {
struct omap_drm_private *priv = dev->dev_private;
struct omap_atomic_state_commit *commit;
+   unsigned long flags;
unsigned int i;
int ret;

@@ -150,6 +151,17 @@ static int omap_atomic_commit(struct drm_device *dev,
priv->commit.pending |= commit->crtcs;
spin_unlock(&priv->commit.lock);

+   /* Keep track of all CRTC events to unlink them in preclose(). */
+   spin_lock_irqsave(&dev->event_lock, flags);
+   for (i = 0; i < dev->mode_config.num_crtc; ++i) {
+   struct drm_crtc_state *cstate = state->crtc_states[i];
+
+   if (cstate && cstate->event)
+   list_add_tail(&cstate->event-

[PATCHv2 00/45] Convert omapdrm to the atomic updates API

2015-06-04 Thread Tomi Valkeinen
Hi,

This is v2 of the atomic modesetting series for omapdrm. Laurent was not able
to finish the work before having to leave abroad, so I continued the work on
the series, fixing up the remaining issues and doing some additional cleanups.

It is a bit late in the kernel development cycle, but I'm hoping we could get
this into v4.2 for two reasons: 

* After these patches some long remaining issues in omapdrm are gone. We
  finally get tear-free page flipping.
* After these patches the driver is so, SO much cleaner, that fixing any new
  bugs found will be considerably easier.

There is some going back-and-forth in these patches, but that's expected with
such a big change. The kernel should compile after each patch, but omapdrm will
not function perfectly after each patch. The issues shouldn't be huge, though,
but things like fps dropping into half do happen in the middle of the series.

The series is based on the latest drm/next branch and depends on the pending
"drm: omapdrm: Store the rotation property in dev->mode_config" patch by
Daniel Vetter.

The omapdrm loses support for its custom fences in the process. This isn't
deemed to be an issue, as the custom fences API is used by the SGX driver
only, which requires out-of-tree patches anyway. Fences support will be
reimplemented at a later point on top of the atomic updates conversion using
the mainline fence API.

I have been testing this with Pandaboard, using single and dual outputs,
without any issues.

These patches can also be found from:

git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git omapdrm-atomic

 Tomi

Cc: Daniel Vetter 
Cc: Rob Clark 
Cc: Thierry Reding 
Cc: Benjamin Gaignard 

Laurent Pinchart (37):
  drm: omapdrm: Store the rotation property in dev->mode_config
  drm: omapdrm: Apply settings synchronously
  drm: omapdrm: Rename omap_crtc_page_flip_locked to omap_crtc_page_flip
  drm: omapdrm: Rename omap_crtc page flip-related fields
  drm: omapdrm: Simplify IRQ registration
  drm: omapdrm: Cancel pending page flips when closing device
  drm: omapdrm: Rework page flip handling
  drm: omapdrm: Turn vblank on/off when enabling/disabling CRTC
  drm: omapdrm: Fix page flip race with CRTC disable
  drm: omapdrm: Clean up #include's
  drm: omapdrm: Rename CRTC DSS operations with an omap_crtc_dss_ prefix
  drm: omapdrm: Rework CRTC enable/disable for atomic updates
  drm: omapdrm: Implement encoder .disable() and .enable() operations
  drm: omapdrm: Wire up atomic state object scaffolding
  drm: omapdrm: Implement planes atomic operations
  drm: omapdrm: Handle primary plane config through atomic plane ops
  drm: omapdrm: Switch plane update to atomic helpers
  drm: omapdrm: Switch mode config to atomic helpers
  drm: omapdrm: Switch connector DPMS to atomic helpers
  drm: omapdrm: Replace encoder mode_fixup with atomic_check
  drm: omapdrm: Implement asynchronous commit support
  drm: omapdrm: Switch page flip to atomic helpers
  drm: omapdrm: Drop manual framebuffer pin handling
  drm: omapdrm: Switch crtc and plane set_property to atomic helpers
  drm: omapdrm: Move plane info and win out of the plane structure
  drm: omapdrm: Move crtc info out of the crtc structure
  drm: omapdrm: Remove omap_crtc enabled field
  drm: omapdrm: Remove omap_plane enabled field
  drm: omapdrm: Make the omap_crtc_flush function static
  drm: omapdrm: Don't get/put dispc in omap_crtc_flush()
  drm: omapdrm: omap_crtc_flush() isn't called with modeset locked
  drm: omapdrm: Support unlinking page flip events prematurely
  drm: omapdrm: Remove nested PM get/sync when configuring encoders
  drm: omapdrm: Simplify DSS power management
  drm: omapdrm: Move encoder setup to encoder operations
  drm: omapdrm: Don't flush CRTC when enabling or disabling it
  drm: omapdrm: Don't setup planes manually from CRTC
.enable()/.disable()

Tomi Valkeinen (8):
  drm: omapdrm: omap_plane_setup() cannot fail, use WARN
  drm: omapdrm: inline omap_plane_setup into update/disable
  drm: omapdrm: if omap_plane_atomic_update fails, disable plane
  drm: omapdrm: remove omap_crtc_wait_page_flip
  drm: omapdrm: add omap_atomic_wait_for_gos()
  drm: omapdrm: don't wait in crtc_atomic_flush
  drm: omapdrm: merge omap_crtc_flush and omap_crtc_atomic_flush
  drm: omapdrm: add lock for fb pinning

 drivers/gpu/drm/omapdrm/omap_connector.c  |  12 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c   | 539 +-
 drivers/gpu/drm/omapdrm/omap_debugfs.c|   6 +-
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c  |  19 +-
 drivers/gpu/drm/omapdrm/omap_drv.c| 233 -
 drivers/gpu/drm/omapdrm/omap_drv.h|  59 +---
 drivers/gpu/drm/omapdrm/omap_encoder.c|  99 ++
 drivers/gpu/drm/omapdrm/omap_fb.c |  27 +-
 drivers/gpu/drm/omapdrm/omap_fbdev.c  |   6 +-
 drivers/gpu/drm/omapdrm/omap_gem.c|   4 +-
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c |   4 +-
 drivers/gpu/drm/omapdrm/omap_irq.c| 106 ++
 drivers/gpu/drm/om

[PATCHv2 09/45] drm: omapdrm: Fix page flip race with CRTC disable

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

We can't rely on crtc->primary->fb in the page flip worker, as a racing
CRTC disable (due for instance to an explicit framebuffer deletion from
userspace) would set that field to NULL before the worker gets a change
to run. Store the framebuffer queued for page flip in a new field of
omap_crtc instead, and hold a reference to it.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 1076bc0a7f78..68abc4d7fa0d 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -66,7 +66,8 @@ struct omap_crtc {
 * page queue has been submitted, WAIT when waiting for GEM async
 * completion, QUEUED when the page flip has been queued to the hardware
 * or CANCELLED when the CRTC is turned off before the flip gets queued
-* to the hardware. The flip event, if any, is stored in flip_event. The
+* to the hardware. The flip event, if any, is stored in flip_event, and
+* the framebuffer queued for page flip is stored in flip_fb. The
 * flip_wait wait queue is used to wait for page flip completion.
 *
 * The flip_work work queue handles page flip requests without caring
@@ -76,6 +77,7 @@ struct omap_crtc {
 */
enum omap_page_flip_state flip_state;
struct drm_pending_vblank_event *flip_event;
+   struct drm_framebuffer *flip_fb;
wait_queue_head_t flip_wait;
struct work_struct flip_work;

@@ -630,6 +632,7 @@ static void page_flip_worker(struct work_struct *work)
drm_modeset_lock(&crtc->mutex, NULL);

spin_lock_irqsave(&dev->event_lock, flags);
+
/*
 * The page flip could have been cancelled while waiting for the GEM
 * async operation to complete. Don't queue the flip in that case.
@@ -641,9 +644,11 @@ static void page_flip_worker(struct work_struct *work)
omap_crtc->flip_state = OMAP_PAGE_FLIP_IDLE;
queue_flip = false;
}
-   spin_unlock_irqrestore(&dev->event_lock, flags);

-   fb = crtc->primary->fb;
+   fb = omap_crtc->flip_fb;
+   omap_crtc->flip_fb = NULL;
+
+   spin_unlock_irqrestore(&dev->event_lock, flags);

if (queue_flip) {
omap_plane_mode_set(crtc->primary, crtc, fb,
@@ -657,7 +662,7 @@ static void page_flip_worker(struct work_struct *work)

bo = omap_framebuffer_bo(fb, 0);
drm_gem_object_unreference_unlocked(bo);
-   drm_framebuffer_unreference(crtc->primary->fb);
+   drm_framebuffer_unreference(fb);
 }

 static void page_flip_cb(void *arg)
@@ -692,10 +697,19 @@ static int omap_crtc_page_flip(struct drm_crtc *crtc,
return -EBUSY;
}

+   /*
+* Store a reference to the framebuffer queued for page flip in the CRTC
+* private structure. We can't rely on crtc->primary->fb in the page
+* flip worker, as a racing CRTC disable (due for instance to an
+* explicit framebuffer deletion from userspace) would set that field to
+* NULL before the worker gets a change to run.
+*/
+   drm_framebuffer_reference(fb);
+   omap_crtc->flip_fb = fb;
omap_crtc->flip_event = event;
omap_crtc->flip_state = OMAP_PAGE_FLIP_WAIT;
+
primary->fb = fb;
-   drm_framebuffer_reference(fb);

spin_unlock_irqrestore(&dev->event_lock, flags);

-- 
2.1.4



[PATCHv2 16/45] drm: omapdrm: Handle primary plane config through atomic plane ops

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Use the new CRTC atomic transitional helpers drm_helper_crtc_mode_set()
and drm_helper_crtc_mode_set_base() to implement the CRTC .mode_set and
.mode_set_base operations. This delegates primary plane configuration to
the plane .atomic_update and .atomic_disable operations, removing
duplicate code from the CRTC implementation.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 69 +++--
 1 file changed, 27 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 277cad1dacf7..31d50533d538 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -571,42 +571,42 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
WARN_ON(omap_plane_set_enable(plane, false));
}

+   /*
+* HACK: Unpin the primary plane frame buffer if we're disabled without
+* going through full mode set.
+* HACK: The legacy set config helper drm_crtc_helper_set_config() that
+* we still use calls the .disable() operation directly when called with
+* a NULL frame buffer (for instance from drm_fb_release()). As a result
+* the CRTC is disabled without going through a full mode set, and the
+* primary plane' framebuffer is kept pin. Unpin it manually here until
+* we switch to the atomic set config helper.
+*/
+   if (crtc->primary->fb) {
+   const struct drm_plane_helper_funcs *funcs;
+
+   funcs = crtc->primary->helper_private;
+   funcs->cleanup_fb(crtc->primary, crtc->primary->fb, NULL);
+   }
+
omap_crtc->enabled = false;

omap_crtc_setup(crtc);
omap_crtc_flush(crtc);
 }

-static int omap_crtc_mode_set(struct drm_crtc *crtc,
-   struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode,
-   int x, int y,
-   struct drm_framebuffer *old_fb)
+static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-
-   mode = adjusted_mode;
+   struct drm_display_mode *mode = &crtc->state->adjusted_mode;

DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
-   omap_crtc->name, mode->base.id, mode->name,
-   mode->vrefresh, mode->clock,
-   mode->hdisplay, mode->hsync_start,
-   mode->hsync_end, mode->htotal,
-   mode->vdisplay, mode->vsync_start,
-   mode->vsync_end, mode->vtotal,
-   mode->type, mode->flags);
+   omap_crtc->name, mode->base.id, mode->name,
+   mode->vrefresh, mode->clock,
+   mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
+   mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
+   mode->type, mode->flags);

copy_timings_drm_to_omap(&omap_crtc->timings, mode);
-
-   /*
-* The primary plane CRTC can be reset if the plane is disabled directly
-* through the universal plane API. Set it again here.
-*/
-   crtc->primary->crtc = crtc;
-
-   return omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
-  0, 0, mode->hdisplay, mode->vdisplay,
-  x, y, mode->hdisplay, mode->vdisplay);
 }

 static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -636,22 +636,6 @@ static void omap_crtc_commit(struct drm_crtc *crtc)
omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 }

-static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-   struct drm_framebuffer *old_fb)
-{
-   struct drm_plane *plane = crtc->primary;
-   struct drm_display_mode *mode = &crtc->mode;
-   int ret;
-
-   ret = omap_plane_mode_set(plane, crtc, crtc->primary->fb,
- 0, 0, mode->hdisplay, mode->vdisplay,
- x, y, mode->hdisplay, mode->vdisplay);
-   if (ret < 0)
-   return ret;
-
-   return omap_crtc_flush(crtc);
-}
-
 static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
 {
dispc_runtime_get();
@@ -798,10 +782,11 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
 static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
.dpms = omap_crtc_dpms,
.mode_fixup = omap_crtc_mode_fixup,
-   .mode_set = omap_crtc_mode_set,
+   .mode_set = drm_helper_crtc_mode_set,
.prepare = omap_crtc_prepare,
.commit = omap_crtc_commit,
-   .mode_set_base = omap_crtc_mode_set_base,
+   .mode_set_nofb = omap_crtc_mode_set_nofb,
+   .mode_set_base = drm_helper_crtc_mode_set_base,
.disable = omap_crtc_disable,
.enab

[PATCHv2 35/45] drm: omapdrm: Move encoder setup to encoder operations

2015-06-04 Thread Tomi Valkeinen
From: Laurent Pinchart 

Now that the driver is fully converted to atomic operations, and that
the atomic helpers call the operations in the right order, we can move
encoder setup to where it belongs, in the encoder operations.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c| 38 +---
 drivers/gpu/drm/omapdrm/omap_drv.h |  6 +--
 drivers/gpu/drm/omapdrm/omap_encoder.c | 79 +-
 3 files changed, 34 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 3a5e68a06af3..2236f52f8bc3 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -35,7 +35,6 @@ struct omap_crtc {

const char *name;
enum omap_channel channel;
-   struct drm_encoder *current_encoder;

/*
 * Temporary: eventually this will go away, but it is needed
@@ -70,7 +69,7 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
return dispc_mgr_get_vsync_irq(omap_crtc->channel);
 }

-const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc)
+struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
return &omap_crtc->timings;
@@ -125,7 +124,7 @@ static void omap_crtc_dss_start_update(struct 
omap_overlay_manager *mgr)
 {
 }

-/* Called only from omap_crtc_encoder_setup and suspend/resume handlers. */
+/* Called only from the encoder enable/disable and suspend/resume handlers. */
 static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 {
struct drm_device *dev = crtc->dev;
@@ -365,37 +364,6 @@ static int omap_crtc_flush(struct drm_crtc *crtc)
return 0;
 }

-static void omap_crtc_encoder_setup(struct drm_crtc *crtc, bool enable)
-{
-   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-   struct omap_drm_private *priv = crtc->dev->dev_private;
-   struct drm_encoder *encoder = NULL;
-   unsigned int i;
-
-   DBG("%s: enable=%d", omap_crtc->name, enable);
-
-   for (i = 0; i < priv->num_encoders; i++) {
-   if (priv->encoders[i]->crtc == crtc) {
-   encoder = priv->encoders[i];
-   break;
-   }
-   }
-
-   if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
-   omap_encoder_set_enabled(omap_crtc->current_encoder, false);
-
-   omap_crtc->current_encoder = encoder;
-
-   if (encoder) {
-   omap_encoder_set_enabled(encoder, false);
-   if (enable) {
-   omap_encoder_update(encoder, omap_crtc->mgr,
-   &omap_crtc->timings);
-   omap_encoder_set_enabled(encoder, true);
-   }
-   }
-}
-
 /* 
-
  * CRTC Functions
  */
@@ -437,7 +405,6 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
WARN_ON(omap_plane_setup(plane));
}

-   omap_crtc_encoder_setup(crtc, true);
omap_crtc_flush(crtc);

drm_crtc_vblank_on(crtc);
@@ -462,7 +429,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
WARN_ON(omap_plane_setup(plane));
}

-   omap_crtc_encoder_setup(crtc, false);
omap_crtc_flush(crtc);
 }

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 81c60284bfb0..bdd54162698f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -141,7 +141,7 @@ int omap_drm_irq_install(struct drm_device *dev);
 struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
 void omap_fbdev_free(struct drm_device *dev);

-const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
+struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
 void omap_crtc_pre_init(void);
 void omap_crtc_pre_uninit(void);
@@ -156,10 +156,6 @@ void omap_plane_install_properties(struct drm_plane *plane,

 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_dss_device *dssdev);
-int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled);
-int omap_encoder_update(struct drm_encoder *encoder,
-   struct omap_overlay_manager *mgr,
-   struct omap_video_timings *timings);

 struct drm_connector *omap_connector_init(struct drm_device *dev,
int connector_type, struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 54847ed089ef..7d9b32a0eb43 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -52,8 +52,6 @@ static void omap_encoder_destroy(struct drm

[PATCH 09/98] via_drm.h: include linux/types.h instead of non-existing via_drmclient.h

2015-06-04 Thread Emil Velikov
On 3 June 2015 at 18:16, Emil Velikov  wrote:
> Hi Mikko,
>
> On 30 May 2015 at 16:38, Mikko Rapeli  wrote:
>> Fixes compiler error:
>>
>> drm/via_drm.h:36:27: fatal error: via_drmclient.h: No such file or directory
>>
>> Signed-off-by: Mikko Rapeli 
>> ---
>>  include/uapi/drm/via_drm.h | 4 +---
>>  1 file changed, 1 insertion(+), 3 deletions(-)
>>
>> diff --git a/include/uapi/drm/via_drm.h b/include/uapi/drm/via_drm.h
>> index 8b0533c..791531e 100644
>> --- a/include/uapi/drm/via_drm.h
>> +++ b/include/uapi/drm/via_drm.h
>> @@ -24,6 +24,7 @@
>>  #ifndef _VIA_DRM_H_
>>  #define _VIA_DRM_H_
>>
>> +#include 
> As mentioned elsewhere one could avoid this, and just use drm.h to
> manage the approapriate types (uint32_t vs __u32 and so on).
>
>>  #include 
>>
>>  /* WARNING: These defines must be the same as what the Xserver uses.
>> @@ -33,9 +34,6 @@
>>  #ifndef _VIA_DEFINES_
>>  #define _VIA_DEFINES_
>>
>> -#ifndef __KERNEL__
>> -#include "via_drmclient.h"
>> -#endif
>>
> I fear that this one is a particular example of a nasty legacy from
> the UMS days. The file is available/provided in very old mesa versions
> and at the very same time mesa requires via_drm.h. So I would kindly
> ask that you:
>
>  - Grab the libdrm userspace package, and apply a similar change.
>  - Rebuild/install the above.
>  - Fetch mesa 7.11, and try building the via dri module. Ideally
> things will continue to build, alternatively we might need to add
> another/additional guard for this include.
>
So the situation is "funnier" than expected:
 - There are at least two users of via_drm.h (mesa and xf86-video-via)
with each providing different via_drmclient.h.
 - Neither of the two projects includes the latter header, despite
that it uses the macros defined within.
 - via_drm.h is included via multiple headers, so adding extra ifdef
guards sounds like a bad idea.
 - While new version of the ddx can be released, a mesa one is
unlikely - 7.11.2 was released ~4 years ago.
 - Even if we cover the above two project, other projects (how many,
where are they hosted, etc.) may need the same treatment.

With the above said I'd suspect that we're safer leaving the include
as is ? Yes, it is busted if one tries to use the standalone header,
jet (most/all?) official users rely on that behaviour :-\

Cheers
Emil


dri-devel Digest, Vol 63, Issue 41

2015-06-04 Thread vinay simha
hi,

where is the kernel.git for dri-devel ? so that i can git clone the
kernel sources?

Regards,
vinay simha


On Thu, Jun 4, 2015 at 4:36 PM,
 wrote:
> Send dri-devel mailing list submissions to
> dri-devel at lists.freedesktop.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> or, via email, send a message with subject or body 'help' to
> dri-devel-request at lists.freedesktop.org
>
> You can reach the person managing the list at
> dri-devel-owner at lists.freedesktop.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of dri-devel digest..."
>
>
> Today's Topics:
>
>1. [PATCHv2 20/45] drm: omapdrm: Replace encoder mode_fixup with
>   atomic_check (Tomi Valkeinen)
>2. [PATCHv2 27/45] drm: omapdrm: Remove omap_crtc enabled field
>   (Tomi Valkeinen)
>3. [PATCHv2 36/45] drm: omapdrm: Don't flush CRTC when enabling
>   or disabling it (Tomi Valkeinen)
>4. [PATCHv2 40/45] drm: omapdrm: if omap_plane_atomic_update
>   fails, disable plane (Tomi Valkeinen)
>5. [PATCHv2 14/45] drm: omapdrm: Wire up atomic state object
>   scaffolding (Tomi Valkeinen)
>6. [PATCHv2 17/45] drm: omapdrm: Switch plane update to atomic
>   helpers (Tomi Valkeinen)
>7. [PATCHv2 18/45] drm: omapdrm: Switch mode config to atomic
>   helpers (Tomi Valkeinen)
>
>
> --
>
> Message: 1
> Date: Thu, 4 Jun 2015 12:02:37 +0300
> From: Tomi Valkeinen 
> To: , Laurent Pinchart
> 
> Cc: Tomi Valkeinen 
> Subject: [PATCHv2 20/45] drm: omapdrm: Replace encoder mode_fixup with
> atomic_check
> Message-ID: <1433408582-9828-21-git-send-email-tomi.valkeinen at ti.com>
> Content-Type: text/plain
>
> From: Laurent Pinchart 
>
> The encoder .mode_fixup() operation is legacy, atomic updates uses the
> new .atomic_check() operation. Convert the encoder driver.
>
> Signed-off-by: Laurent Pinchart 
> Signed-off-by: Tomi Valkeinen 
> ---
>  drivers/gpu/drm/omapdrm/omap_encoder.c | 16 
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
> b/drivers/gpu/drm/omapdrm/omap_encoder.c
> index 2aeb41f0881a..54847ed089ef 100644
> --- a/drivers/gpu/drm/omapdrm/omap_encoder.c
> +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
> @@ -62,13 +62,6 @@ static const struct drm_encoder_funcs omap_encoder_funcs = 
> {
> .destroy = omap_encoder_destroy,
>  };
>
> -static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
> - const struct drm_display_mode *mode,
> - struct drm_display_mode *adjusted_mode)
> -{
> -   return true;
> -}
> -
>  static void omap_encoder_mode_set(struct drm_encoder *encoder,
> struct drm_display_mode *mode,
> struct drm_display_mode *adjusted_mode)
> @@ -117,11 +110,18 @@ static void omap_encoder_enable(struct drm_encoder 
> *encoder)
>  {
>  }
>
> +static int omap_encoder_atomic_check(struct drm_encoder *encoder,
> +struct drm_crtc_state *crtc_state,
> +struct drm_connector_state *conn_state)
> +{
> +   return 0;
> +}
> +
>  static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
> -   .mode_fixup = omap_encoder_mode_fixup,
> .mode_set = omap_encoder_mode_set,
> .disable = omap_encoder_disable,
> .enable = omap_encoder_enable,
> +   .atomic_check = omap_encoder_atomic_check,
>  };
>
>  /*
> --
> 2.1.4
>
>
>
> --
>
> Message: 2
> Date: Thu, 4 Jun 2015 12:02:44 +0300
> From: Tomi Valkeinen 
> To: , Laurent Pinchart
> 
> Cc: Tomi Valkeinen 
> Subject: [PATCHv2 27/45] drm: omapdrm: Remove omap_crtc enabled field
> Message-ID: <1433408582-9828-28-git-send-email-tomi.valkeinen at ti.com>
> Content-Type: text/plain
>
> From: Laurent Pinchart 
>
> The field tracks the CRTC state to avoid double-enable or -disable. As
> the DRM atomic core guarantees that the CRTC enable and disable
> functions won't be called on an already enabled or disabled CRTC, such
> tracking isn't needed. Remove the enabled field.
>
> Signed-off-by: Laurent Pinchart 
> Signed-off-by: Tomi Valkeinen 
> ---
>  drivers/gpu/drm/omapdrm/omap_crtc.c | 32 +---
>  1 file changed, 9 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
> b/drivers/gpu/drm/omapdrm/omap_crtc.c
> index 430bf64521f0..e93ed34dea33 100644
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -46,7 +46,6 @@ struct omap_crtc {
> struct omap_overlay_manager *mgr;
>
> struct omap_video_timings timings;
> -   bool enabled;
>
> struct omap_drm_

[PATCH] drm/tegra: Support kernel mappings with IOMMU

2015-06-04 Thread Arto Merilainen
Host1x command buffer patching requires that the buffer object can be
mapped into kernel address space, however, the recent addition of
IOMMU did not account to this requirement. Therefore Host1x engines
cannot be used if IOMMU is enabled.

This patch implements kmap, kunmap, mmap and munmap functions to
host1x bo objects.

Signed-off-by: Arto Merilainen 
---
 drivers/gpu/drm/tegra/gem.c | 34 +++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 1217272a51f2..89ca8d35f555 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -2,7 +2,7 @@
  * NVIDIA Tegra DRM GEM helper functions
  *
  * Copyright (C) 2012 Sascha Hauer, Pengutronix
- * Copyright (C) 2013 NVIDIA CORPORATION, All rights reserved.
+ * Copyright (C) 2013-2015 NVIDIA CORPORATION, All rights reserved.
  *
  * Based on the GEM/CMA helpers
  *
@@ -50,23 +50,51 @@ static void *tegra_bo_mmap(struct host1x_bo *bo)
 {
struct tegra_bo *obj = host1x_to_tegra_bo(bo);

-   return obj->vaddr;
+   if (obj->vaddr)
+   return obj->vaddr;
+   else if (obj->gem.import_attach)
+   return dma_buf_vmap(obj->gem.import_attach->dmabuf);
+   else
+   return vmap(obj->pages, obj->num_pages, VM_MAP,
+   pgprot_writecombine(PAGE_KERNEL));
 }

 static void tegra_bo_munmap(struct host1x_bo *bo, void *addr)
 {
+   struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+
+   if (obj->vaddr)
+   return;
+   else if (obj->gem.import_attach)
+   dma_buf_vunmap(obj->gem.import_attach->dmabuf, addr);
+   else
+   vunmap(addr);
 }

 static void *tegra_bo_kmap(struct host1x_bo *bo, unsigned int page)
 {
struct tegra_bo *obj = host1x_to_tegra_bo(bo);

-   return obj->vaddr + page * PAGE_SIZE;
+   if (obj->vaddr)
+   return obj->vaddr + page * PAGE_SIZE;
+   else if (obj->gem.import_attach)
+   return dma_buf_kmap(obj->gem.import_attach->dmabuf, page);
+   else
+   return vmap(obj->pages + page, 1, VM_MAP,
+   pgprot_writecombine(PAGE_KERNEL));
 }

 static void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page,
void *addr)
 {
+   struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+
+   if (obj->vaddr)
+   return;
+   else if (obj->gem.import_attach)
+   dma_buf_kunmap(obj->gem.import_attach->dmabuf, page, addr);
+   else
+   vunmap(addr);
 }

 static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
-- 
1.8.1.5



[Bug 87649] After archlinux system update switching on both of internal and external graphics card does not work anymore (vgaswitcheroo)

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=87649

Ander Conselvan de Oliveira  changed:

   What|Removed |Added

  Component|DRM/Intel   |DRM/Radeon
   Assignee|intel-gfx-bugs at lists.freede |dri-devel at 
lists.freedesktop
   |sktop.org   |.org
 QA Contact|intel-gfx-bugs at lists.freede |
   |sktop.org   |

-- 
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/20150604/0712c457/attachment.html>


[Bug 87649] After archlinux system update switching on both of internal and external graphics card does not work anymore (vgaswitcheroo)

2015-06-04 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=87649

--- Comment #13 from Alex Deucher  ---
(In reply to gofabian from comment #11)
> Created attachment 112056 [details]
> dmesg_v3.19rc2_without_switch_refuse

It's a radeon GPU hang.  Is there something specific that you were doing to
trigger it?  E.g., running some app?

-- 
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/20150604/490d9a21/attachment.html>


drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Oded Gabbay
Hi Valentin,
Thanks for catching that.
I would be grateful if you could fix this yourself.

Oded

On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg 
wrote:

> Hi Yair,
>
> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
> module support") has shown up in today's linux-next tree (i.e.,
> next-20150604).  The commit adds the following lines of code to
> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>
> +/* CONFIG reg space definition */
> +enum {
> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
> +   CONFIG_REG_END = 0x2B00,
> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
> +};
>
> There is a problem with the 'CONFIG_' prefix of those entries.  This
> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
> so that static analysis tools (and readers of the code) may mistakenly
> assume that the symbol is defined somewhere in a Kconfig file.
>
> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
> mind renaming those entries to something without the 'CONFIG_' prefix?
>  I can also take care of it if you wish to.
>
> Kind regards,
>  Valentin
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20150604/d46183d9/attachment.html>


drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Alex Deucher
On Thu, Jun 4, 2015 at 9:48 AM, Oded Gabbay  wrote:
> Hi Valentin,
> Thanks for catching that.
> I would be grateful if you could fix this yourself.

Please try and keep CONFIG in the name since this range of registers
are called CONFIG registers.

Alex

>
> Oded
>
> On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg
>  wrote:
>>
>> Hi Yair,
>>
>> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
>> module support") has shown up in today's linux-next tree (i.e.,
>> next-20150604).  The commit adds the following lines of code to
>> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>>
>> +/* CONFIG reg space definition */
>> +enum {
>> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
>> +   CONFIG_REG_END = 0x2B00,
>> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
>> +};
>>
>> There is a problem with the 'CONFIG_' prefix of those entries.  This
>> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
>> so that static analysis tools (and readers of the code) may mistakenly
>> assume that the symbol is defined somewhere in a Kconfig file.
>>
>> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
>> mind renaming those entries to something without the 'CONFIG_' prefix?
>>  I can also take care of it if you wish to.
>>
>> Kind regards,
>>  Valentin
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>


[PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers

2015-06-04 Thread Emil Velikov
Hi Daniel,
On 22/05/15 12:36, Daniel Stone wrote:
> Signed-off-by: Daniel Stone 

There is a trivial suggestion inline, although I must say thank you !
Thank you for keeping the impl. details of struct
_drmModeAtomicReqItem/_drmModeAtomicReq out of the public headers.

> --- a/xf86drmMode.c
> +++ b/xf86drmMode.c
> @@ -1333,3 +1333,34 @@ out:
>  
>   return ret;
>  }
> +
> +int
> +drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t 
> *id)
> +{
> + struct drm_mode_create_blob create;
Please explicitly zero the struct - most places use memclear()

> + int ret;
> +
> + if (length >= 0x)
> + return -ERANGE;
> +
> + create.length = length;
> + create.data = (uintptr_t) data;
> + create.blob_id = 0;
> + *id = 0;
> +
> + ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
> + if (ret != 0)
> + return ret;
> +
> + *id = create.blob_id;
> + return 0;
> +}
> +
> +int
> +drmModeDestroyPropertyBlob(int fd, uint32_t id)
> +{
> + struct drm_mode_destroy_blob destroy;
Ditto.

Thanks
Emil



drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Alex Deucher
On Thu, Jun 4, 2015 at 10:04 AM, Valentin Rothberg
 wrote:
> Hi Alex,
>
> On Thu, Jun 4, 2015 at 4:01 PM, Alex Deucher  wrote:
>> On Thu, Jun 4, 2015 at 9:48 AM, Oded Gabbay  wrote:
>>> Hi Valentin,
>>> Thanks for catching that.
>>> I would be grateful if you could fix this yourself.
>>
>> Please try and keep CONFIG in the name since this range of registers
>> are called CONFIG registers.
>
> I cannot force changing those symbols, but point out that it's
> violating naming conventions.  I would suggest to s/CONFIG_/CONF_/ to
> make clear that it's config registers.  Would you be fine with that?

What about something like AMD_CONFIG_REG?

>
> Kind regards,
>  Valentin
>
>> Alex
>>
>>>
>>> Oded
>>>
>>> On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg
>>>  wrote:
>>>>
>>>> Hi Yair,
>>>>
>>>> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
>>>> module support") has shown up in today's linux-next tree (i.e.,
>>>> next-20150604).  The commit adds the following lines of code to
>>>> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>>>>
>>>> +/* CONFIG reg space definition */
>>>> +enum {
>>>> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
>>>> +   CONFIG_REG_END = 0x2B00,
>>>> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
>>>> +};
>>>>
>>>> There is a problem with the 'CONFIG_' prefix of those entries.  This
>>>> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
>>>> so that static analysis tools (and readers of the code) may mistakenly
>>>> assume that the symbol is defined somewhere in a Kconfig file.
>>>>
>>>> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
>>>> mind renaming those entries to something without the 'CONFIG_' prefix?
>>>>  I can also take care of it if you wish to.
>>>>
>>>> Kind regards,
>>>>  Valentin
>>>
>>>
>>> ___
>>> dri-devel mailing list
>>> dri-devel at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>


drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Christian König
On 04.06.2015 17:09, Alex Deucher wrote:
> On Thu, Jun 4, 2015 at 10:04 AM, Valentin Rothberg
>  wrote:
>> Hi Alex,
>>
>> On Thu, Jun 4, 2015 at 4:01 PM, Alex Deucher  
>> wrote:
>>> On Thu, Jun 4, 2015 at 9:48 AM, Oded Gabbay  
>>> wrote:
>>>> Hi Valentin,
>>>> Thanks for catching that.
>>>> I would be grateful if you could fix this yourself.
>>> Please try and keep CONFIG in the name since this range of registers
>>> are called CONFIG registers.
>> I cannot force changing those symbols, but point out that it's
>> violating naming conventions.  I would suggest to s/CONFIG_/CONF_/ to
>> make clear that it's config registers.  Would you be fine with that?
> What about something like AMD_CONFIG_REG?

For the background: The register headers will be auto generated in the 
future and if the hardware designer named the register CONFIG_* the name 
will show up in our headers as such.

Prefixing it with AMD_ sounds like a good solution to me, too.

Regards,
Christian.

>
>> Kind regards,
>>   Valentin
>>
>>> Alex
>>>
>>>> Oded
>>>>
>>>> On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg
>>>>  wrote:
>>>>> Hi Yair,
>>>>>
>>>>> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
>>>>> module support") has shown up in today's linux-next tree (i.e.,
>>>>> next-20150604).  The commit adds the following lines of code to
>>>>> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>>>>>
>>>>> +/* CONFIG reg space definition */
>>>>> +enum {
>>>>> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
>>>>> +   CONFIG_REG_END = 0x2B00,
>>>>> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
>>>>> +};
>>>>>
>>>>> There is a problem with the 'CONFIG_' prefix of those entries.  This
>>>>> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
>>>>> so that static analysis tools (and readers of the code) may mistakenly
>>>>> assume that the symbol is defined somewhere in a Kconfig file.
>>>>>
>>>>> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
>>>>> mind renaming those entries to something without the 'CONFIG_' prefix?
>>>>>   I can also take care of it if you wish to.
>>>>>
>>>>> Kind regards,
>>>>>   Valentin
>>>>
>>>> ___
>>>> dri-devel mailing list
>>>> dri-devel at lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Valentin Rothberg
Hi Oded,

On Thu, Jun 4, 2015 at 3:48 PM, Oded Gabbay  wrote:
> Hi Valentin,
> Thanks for catching that.
> I would be grateful if you could fix this yourself.

With pleasure,  I am happy if I can help.  Do you have any preference
to change the prefix to something else?  As there are three other
symbols SH_REG_{BASE,SIZE,END}, I would rename CONFIG_ to CONF_ to
avoid mix-ups.

Kind regards,
 Valentin

> Oded
>
> On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg
>  wrote:
>>
>> Hi Yair,
>>
>> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
>> module support") has shown up in today's linux-next tree (i.e.,
>> next-20150604).  The commit adds the following lines of code to
>> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>>
>> +/* CONFIG reg space definition */
>> +enum {
>> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
>> +   CONFIG_REG_END = 0x2B00,
>> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
>> +};
>>
>> There is a problem with the 'CONFIG_' prefix of those entries.  This
>> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
>> so that static analysis tools (and readers of the code) may mistakenly
>> assume that the symbol is defined somewhere in a Kconfig file.
>>
>> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
>> mind renaming those entries to something without the 'CONFIG_' prefix?
>>  I can also take care of it if you wish to.
>>
>> Kind regards,
>>  Valentin


drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Valentin Rothberg
Hi Alex,

On Thu, Jun 4, 2015 at 4:01 PM, Alex Deucher  wrote:
> On Thu, Jun 4, 2015 at 9:48 AM, Oded Gabbay  wrote:
>> Hi Valentin,
>> Thanks for catching that.
>> I would be grateful if you could fix this yourself.
>
> Please try and keep CONFIG in the name since this range of registers
> are called CONFIG registers.

I cannot force changing those symbols, but point out that it's
violating naming conventions.  I would suggest to s/CONFIG_/CONF_/ to
make clear that it's config registers.  Would you be fine with that?

Kind regards,
 Valentin

> Alex
>
>>
>> Oded
>>
>> On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg
>>  wrote:
>>>
>>> Hi Yair,
>>>
>>> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
>>> module support") has shown up in today's linux-next tree (i.e.,
>>> next-20150604).  The commit adds the following lines of code to
>>> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>>>
>>> +/* CONFIG reg space definition */
>>> +enum {
>>> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
>>> +   CONFIG_REG_END = 0x2B00,
>>> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
>>> +};
>>>
>>> There is a problem with the 'CONFIG_' prefix of those entries.  This
>>> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
>>> so that static analysis tools (and readers of the code) may mistakenly
>>> assume that the symbol is defined somewhere in a Kconfig file.
>>>
>>> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
>>> mind renaming those entries to something without the 'CONFIG_' prefix?
>>>  I can also take care of it if you wish to.
>>>
>>> Kind regards,
>>>  Valentin
>>
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>


[PATCH 2/3] asus-wmi: Use acpi_video_unregister_backlight instead of acpi_video_unregister

2015-06-04 Thread Corentin Chary
On Mon, Jun 1, 2015 at 10:25 AM, Hans de Goede  wrote:
> acpi_video_unregister() not only unregisters the acpi-video backlight
> interface but also unregisters the acpi video bus event listener, causing
> e.g. brightness hotkey presses to no longer generate keypress events.
>
> The unregistering of the acpi video bus event listener usually is
> undesirable, which by itself is a good reason to switch to
> acpi_video_unregister_backlight().
>
> Another problem with using acpi_video_unregister() rather then using
> acpi_video_unregister_backlight() is that on systems with an intel video
> opregion (most systems) and a wmi_backlight_power quirk, whether or not
> the acpi video bus event listener actually gets unregistered depends on
> module load ordering:
>
> Scenario a:
> 1) acpi/video.ko gets loaded (*), does not do acpi_video_register as there
>is an intel opregion.
> 2) intel.ko gets loaded, calls acpi_video_register() which registers both
>the listener and the acpi backlight interface
> 3) asus-wmi.ko gets loaded, calls acpi_video_unregister() causing both
>the listener and the acpi backlight interface to unregister
>
> Scenario b:
> 1) acpi/video.ko gets loaded (*), does not do acpi_video_register as there
>is an intel opregion.
> 2) asus-wmi.ko gets loaded, calls acpi_video_dmi_promote_vendor(),
>calls acpi_video_unregister(), which is a nop since acpi_video_register
>has not yet been called
> 2) intel.ko gets loaded, calls acpi_video_register() which registers
>the listener, but does not register the acpi backlight interface due to
>the call to the preciding call to acpi_video_dmi_promote_vendor()
>
> *) acpi/video.ko always loads first as both other modules depend on it.
>
> So we end up with or without an acpi video bus event listener depending
> on module load ordering, not good.
>
> Switching to using acpi_video_unregister_backlight() means that independ
> of ordering we will always have an acpi video bus event listener fixing
> this.
>
> Note that this commit means that systems without an intel video opregion,
> and systems which were hitting scenario a wrt module load ordering, are
> now getting an acpi video bus event listener while before they were not!
>
> On some systems this may cause the brightness hotkeys to start generating
> keypresses while before they were not (good), while on other systems this
> may cause the brightness hotkeys to generate multiple keypress events for
> a single press (not so good). Since on most systems the acpi video bus is
> the canonical source for brightness events I believe that the latter case
> will needs to be handled on a case by case basis by filtering out the
> duplicate keypresses at the other source for them.
>
> Cc: Corentin Chary 
> Cc: acpi4asus-user at lists.sourceforge.net
> Signed-off-by: Hans de Goede 
> ---
>  drivers/platform/x86/asus-wmi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 7543a56..945145d 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -1777,7 +1777,7 @@ static int asus_wmi_add(struct platform_device *pdev)
> acpi_video_dmi_promote_vendor();
> if (!acpi_video_backlight_support()) {
> pr_info("Disabling ACPI video driver\n");
> -   acpi_video_unregister();
> +   acpi_video_unregister_backlight();
> err = asus_wmi_backlight_init(asus);
> if (err && err != -ENODEV)
> goto fail_backlight;
> --
> 2.4.2
>

Acked-by: Corentin Chary http://xf.iksaif.net


[PATCH 3/3] samsung-laptop: Use acpi_video_unregister_backlight instead of acpi_video_unregister

2015-06-04 Thread Corentin Chary
On Mon, Jun 1, 2015 at 10:25 AM, Hans de Goede  wrote:
> acpi_video_unregister() not only unregisters the acpi-video backlight
> interface but also unregisters the acpi video bus event listener, causing
> e.g. brightness hotkey presses to no longer generate keypress events.
>
> The unregistering of the acpi video bus event listener usually is
> undesirable, which by itself is a good reason to switch to
> acpi_video_unregister_backlight().
>
> Another problem with using acpi_video_unregister() rather then using
> acpi_video_unregister_backlight() is that on systems with an intel video
> opregion (most systems) and a broken_acpi_video quirk, whether or not
> the acpi video bus event listener actually gets unregistered depends on
> module load ordering:
>
> Scenario a:
> 1) acpi/video.ko gets loaded (*), does not do acpi_video_register as there
>is an intel opregion.
> 2) intel.ko gets loaded, calls acpi_video_register() which registers both
>the listener and the acpi backlight interface
> 3) samsung-laptop.ko gets loaded, calls acpi_video_unregister() causing
>both the listener and the acpi backlight interface to unregister
>
> Scenario b:
> 1) acpi/video.ko gets loaded (*), does not do acpi_video_register as there
>is an intel opregion.
> 2) samsung-laptop.ko gets loaded, calls acpi_video_dmi_promote_vendor(),
>calls acpi_video_unregister(), which is a nop since acpi_video_register
>has not yet been called
> 2) intel.ko gets loaded, calls acpi_video_register() which registers
>the listener, but does not register the acpi backlight interface due to
>the call to the preciding call to acpi_video_dmi_promote_vendor()
>
> *) acpi/video.ko always loads first as both other modules depend on it.
>
> So we end up with or without an acpi video bus event listener depending
> on module load ordering, not good.
>
> Switching to using acpi_video_unregister_backlight() means that independ
> of ordering we will always have an acpi video bus event listener fixing
> this.
>
> Note that this commit means that systems without an intel video opregion,
> and systems which were hitting scenario a wrt module load ordering, are
> now getting an acpi video bus event listener while before they were not!
>
> On some systems this may cause the brightness hotkeys to start generating
> keypresses while before they were not (good), while on other systems this
> may cause the brightness hotkeys to generate multiple keypress events for
> a single press (not so good). Since on most systems the acpi video bus is
> the canonical source for brightness events I believe that the latter case
> will needs to be handled on a case by case basis by filtering out the
> duplicate keypresses at the other source for them.
>
> Cc: Corentin Chary 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/platform/x86/samsung-laptop.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/platform/x86/samsung-laptop.c 
> b/drivers/platform/x86/samsung-laptop.c
> index 9e701b2..0df03e2 100644
> --- a/drivers/platform/x86/samsung-laptop.c
> +++ b/drivers/platform/x86/samsung-laptop.c
> @@ -1730,14 +1730,14 @@ static int __init samsung_init(void)
> samsung->handle_backlight = false;
> } else if (samsung->quirks->broken_acpi_video) {
> pr_info("Disabling ACPI video driver\n");
> -   acpi_video_unregister();
> +   acpi_video_unregister_backlight();
> }
>
> if (samsung->quirks->use_native_backlight) {
> pr_info("Using native backlight driver\n");
> /* Tell acpi-video to not handle the backlight */
> acpi_video_dmi_promote_vendor();
> -   acpi_video_unregister();
> +   acpi_video_unregister_backlight();
> /* And also do not handle it ourselves */
> samsung->handle_backlight = false;
> }
> --
> 2.4.2
>

Acked-by: Corentin Chary http://xf.iksaif.net


drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Valentin Rothberg
Hi Christian,

On Thu, Jun 4, 2015 at 6:47 PM, Christian König  
wrote:
> On 04.06.2015 17:09, Alex Deucher wrote:
>>
>> On Thu, Jun 4, 2015 at 10:04 AM, Valentin Rothberg
>>  wrote:
>>>
>>> Hi Alex,
>>>
>>> On Thu, Jun 4, 2015 at 4:01 PM, Alex Deucher 
>>> wrote:
>>>>
>>>> On Thu, Jun 4, 2015 at 9:48 AM, Oded Gabbay 
>>>> wrote:
>>>>>
>>>>> Hi Valentin,
>>>>> Thanks for catching that.
>>>>> I would be grateful if you could fix this yourself.
>>>>
>>>> Please try and keep CONFIG in the name since this range of registers
>>>> are called CONFIG registers.
>>>
>>> I cannot force changing those symbols, but point out that it's
>>> violating naming conventions.  I would suggest to s/CONFIG_/CONF_/ to
>>> make clear that it's config registers.  Would you be fine with that?
>>
>> What about something like AMD_CONFIG_REG?
>
>
> For the background: The register headers will be auto generated in the
> future and if the hardware designer named the register CONFIG_* the name
> will show up in our headers as such.
>
> Prefixing it with AMD_ sounds like a good solution to me, too.

Okay.  I will prepare and send a patch tomorrow.

Kind regards,
 Valentin

> Regards,
> Christian.
>
>
>>
>>> Kind regards,
>>>   Valentin
>>>
>>>> Alex
>>>>
>>>>> Oded
>>>>>
>>>>> On Thu, Jun 4, 2015 at 4:45 PM Valentin Rothberg
>>>>>  wrote:
>>>>>>
>>>>>> Hi Yair,
>>>>>>
>>>>>> your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
>>>>>> module support") has shown up in today's linux-next tree (i.e.,
>>>>>> next-20150604).  The commit adds the following lines of code to
>>>>>> drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:
>>>>>>
>>>>>> +/* CONFIG reg space definition */
>>>>>> +enum {
>>>>>> +   CONFIG_REG_BASE = 0x2000,   /* in dwords */
>>>>>> +   CONFIG_REG_END = 0x2B00,
>>>>>> +   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
>>>>>> +};
>>>>>>
>>>>>> There is a problem with the 'CONFIG_' prefix of those entries.  This
>>>>>> prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
>>>>>> so that static analysis tools (and readers of the code) may mistakenly
>>>>>> assume that the symbol is defined somewhere in a Kconfig file.
>>>>>>
>>>>>> I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
>>>>>> mind renaming those entries to something without the 'CONFIG_' prefix?
>>>>>>   I can also take care of it if you wish to.
>>>>>>
>>>>>> Kind regards,
>>>>>>   Valentin
>>>>>
>>>>>
>>>>> ___
>>>>> dri-devel mailing list
>>>>> dri-devel at lists.freedesktop.org
>>>>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
>


On Thu, Jun 4, 2015 at 6:47 PM, Christian König  
wrote:
> On 04.06.2015 17:09, Alex Deucher wrote:
>>
>> On Thu, Jun 4, 2015 at 10:04 AM, Valentin Rothberg
>>  wrote:
>>>
>>> Hi Alex,
>>>
>>> On Thu, Jun 4, 2015 at 4:01 PM, Alex Deucher 
>>> wrote:
>>>>
>>>> On Thu, Jun 4, 2015 at 9:48 AM, Oded Gabbay 
>>>> wrote:
>>>>>
>>>>> Hi Valentin,
>>>>> Thanks for catching that.
>>>>> I would be grateful if you could fix this yourself.
>>>>
>>>> Please try and keep CONFIG in the name since this range of registers
>>>> are called CONFIG registers.
>>>
>>> I cannot force changing those symbols, but point out that it's
>>> violating naming conventions.  I would suggest to s/CONFIG_/CONF_/ to
>>> make clear that it's config registers.  Would you be fine with that?
>>
>> What about something like AMD_CONFIG_REG?
>
>
> For the background: The register headers w

[PATCH] treewide: Fix typo compatability -> compatibility

2015-06-04 Thread Stanislav Yakovlev
On 27 May 2015 at 16:05, Laurent Pinchart
 wrote:
> Even though 'compatability' has a dedicated entry in the Wiktionary,
> it's listed as 'Mispelling of compatibility'. Fix it.
>
> Signed-off-by: Laurent Pinchart 
> ---
>  drivers/net/wireless/ipw2x00/ipw2100.h   | 2 +-
>

Acked-by: Stanislav Yakovlev 

for ipw2100 part.

Stanislav.


drm/amdkfd: bad CONFIG_ prefix for enum entries

2015-06-04 Thread Valentin Rothberg
Hi Yair,

your commit fbeb661bfa89 ("drm/amdkfd: Add skeleton H/W debugger
module support") has shown up in today's linux-next tree (i.e.,
next-20150604).  The commit adds the following lines of code to
drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h:

+/* CONFIG reg space definition */
+enum {
+   CONFIG_REG_BASE = 0x2000,   /* in dwords */
+   CONFIG_REG_END = 0x2B00,
+   CONFIG_REG_SIZE = CONFIG_REG_END - CONFIG_REG_BASE
+};

There is a problem with the 'CONFIG_' prefix of those entries.  This
prefix is reserved for Kconfig options in Make/Kbuild and CPP syntax,
so that static analysis tools (and readers of the code) may mistakenly
assume that the symbol is defined somewhere in a Kconfig file.

I detected the issue with ./scripts/checkkconfigsymbols.py.  Would you
mind renaming those entries to something without the 'CONFIG_' prefix?
 I can also take care of it if you wish to.

Kind regards,
 Valentin


[PATCH 00/21] On-demand device registration

2015-06-04 Thread grygorii.stras...@linaro.org
On 06/04/2015 11:39 AM, Tomeu Vizoso wrote:
> On 3 June 2015 at 21:57, Grygorii.Strashko at linaro.org
>  wrote:
>> On 05/28/2015 07:33 AM, Rob Herring wrote:
>>> On Mon, May 25, 2015 at 9:53 AM, Tomeu Vizoso >> collabora.com> wrote:
 I have a problem with the panel on my Tegra Chromebook taking longer than
 expected to be ready during boot (Stéphane Marchesin reported what is
 basically the same issue in [0]), and have looked into ordered probing as a
 better way of solving this than moving nodes around in the DT or playing 
 with
 initcall levels.

 While reading the thread [1] that Alexander Holler started with his series 
 to
 make probing order deterministic, it occurred to me that it should be 
 possible
 to achieve the same by registering devices as they are referenced by other
 devices.
>>>
>>> I like the concept and novel approach.
>>>
 This basically reuses the information that is already implicit in the 
 probe()
 implementations, saving us from refactoring existing drivers or adding
 information to DTBs.

 Something I'm not completely happy with is that I have had to move the 
 call to
 of_platform_populate after all platform drivers have been registered.
 Otherwise I don't see how I could register drivers on demand as we don't 
 have
 yet each driver's compatible strings.
>>>
>>> Yeah, this is the opposite of what we'd really like. Ideally, we would
>>> have a solution that works for modules too. However, we're no worse
>>> off. We pretty much build-in dependencies to avoid module ordering
>>> problems.
>>>
>>> Perhaps we need to make the probing on-demand rather than simply on
>>> device<->driver match occurring.
>>>
 For machs that don't move of_platform_populate() to a later point, these
 patches shouldn't cause any problems but it's not guaranteed that we'll 
 avoid
 all the deferred probes as some drivers may not be registered yet.
>>>
>>> Ideally, of_platform_populate is not explicitly called by each
>>> platform. So I think we need to make this work for the default case.
>>>
 I have tested this on boards with Tegra, iMX.6 and Exynos SoCs, and these
 patches were enough to eliminate all the deferred probes.

 With this series I get the kernel to output to the panel in 0.5s, instead 
 of 2.8s.
>>>
>>> That's certainly compelling.
>>
>> I've found your idea about moving device registration later during System 
>> boot
>> very interesting so I've decided to try it on dra7-evem (TI) :).
>> It's good to know time during Kernel boot when we can assume that all 
>> drivers are
>> ready for probing, so there are more ways to control probing order.
> 
> Thanks, though right now I'm following Rob's suggestion and only delay
> probing, not registration. The patch is really simple (applies on
> linux-next, with async probing):
> 
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 8da8e07..7e6b1e1 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -407,6 +407,11 @@ int driver_probe_device(struct device_driver
> *drv, struct device *dev)
>  if (!device_is_registered(dev))
>  return -ENODEV;
> 
> +   if (!driver_deferred_probe_enable) {
> +   driver_deferred_probe_add(dev);
> +   return 0;
> +   }
> +
>  pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
>   drv->bus->name, __func__, dev_name(dev), drv->name);
> 
> @@ -585,7 +590,7 @@ EXPORT_SYMBOL_GPL(device_attach);
> 
>   void device_initial_probe(struct device *dev)
>   {
> -   __device_attach(dev, true);
> +   __device_attach(dev, driver_deferred_probe_enable);
>   }
> 
>   static int __driver_attach(struct device *dev, void *data)

Can't boot my 3.14 kernel with this change :( Most probably,
the problem is related to platform_driver_probe() usage :(
Have no time to play with it now :(, but recommend you to check also
earlyprintk, last log message I can see:
[1.435522] bootconsole [earlycon0] disabled

But, nice try ;) Seems -EPROBE_DEFER is reality of life which
has to be accepted as is.

> 
>> Pls, Note here that TI OMAP2+ mach is not pure DT mach - it's combination of
>> DT and not DT devices/drivers.
>>
>> Ok. So What was done...
>>
>> LKML Linux 4.1-rc3 (a simple case)
>> 1) use your patches 3/4 as reference (only these two patches :)
>> 2) move of_platform_populate later at device_initcall_sync time
>> Boot time reduction ~0.4 sec
> 
> I'm a bit surprised at such a big improvement. May I ask how you are
> measuring it?

Ah. My measurements are not precise. I've just tracking time of message
"[4.110756] Freeing unused kernel memory: 344K (c0994000 - c09ea000)"

> 
>> TI Android Kernel 3.14 (NOT a simple case)
>> 1) use your patches 3/4 as reference (only these two patches :)
>> 2) move of_platform_populate later at device_initcall_sync time
>> 3) make it to boot (not sure I've fixed a

[PATCH v3 0/2] drm/msm/hdmi: Use pinctrl in HDMI driver

2015-06-04 Thread Stephane Viau
Pinctrl support for HDMI needs a small fix before the actual implementation...

Stephane Viau (2):
  drm/msm/hdmi: Point to the right struct device
  drm/msm/hdmi: Use pinctrl in HDMI driver

 Documentation/devicetree/bindings/drm/msm/hdmi.txt |  6 +++
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c  | 43 ++
 2 files changed, 33 insertions(+), 16 deletions(-)

-- 
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a 
Linux Foundation Collaborative Project



[PATCH v3 1/2] drm/msm/hdmi: Point to the right struct device

2015-06-04 Thread Stephane Viau
DRM device's dev (hdmi->dev->dev) points to the mdss_mdp device
handle. Instead, we should get a reference to the mdss_hdmi
handle.

Signed-off-by: Stephane Viau 
---
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 32 +++
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index 914bf95..e29b62a 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -78,14 +78,14 @@ static void hdmi_phy_reset(struct hdmi *hdmi)

 static int gpio_config(struct hdmi *hdmi, bool on)
 {
-   struct drm_device *dev = hdmi->dev;
+   struct device *dev = &hdmi->pdev->dev;
const struct hdmi_platform_config *config = hdmi->config;
int ret;

if (on) {
ret = gpio_request(config->ddc_clk_gpio, "HDMI_DDC_CLK");
if (ret) {
-   dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+   dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
"HDMI_DDC_CLK", config->ddc_clk_gpio, ret);
goto error1;
}
@@ -93,7 +93,7 @@ static int gpio_config(struct hdmi *hdmi, bool on)

ret = gpio_request(config->ddc_data_gpio, "HDMI_DDC_DATA");
if (ret) {
-   dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+   dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
"HDMI_DDC_DATA", config->ddc_data_gpio, ret);
goto error2;
}
@@ -101,7 +101,7 @@ static int gpio_config(struct hdmi *hdmi, bool on)

ret = gpio_request(config->hpd_gpio, "HDMI_HPD");
if (ret) {
-   dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+   dev_err(dev, "'%s'(%d) gpio_request failed: %d\n",
"HDMI_HPD", config->hpd_gpio, ret);
goto error3;
}
@@ -111,7 +111,7 @@ static int gpio_config(struct hdmi *hdmi, bool on)
if (config->mux_en_gpio != -1) {
ret = gpio_request(config->mux_en_gpio, "HDMI_MUX_EN");
if (ret) {
-   dev_err(dev->dev, "'%s'(%d) gpio_request 
failed: %d\n",
+   dev_err(dev, "'%s'(%d) gpio_request failed: 
%d\n",
"HDMI_MUX_EN", config->mux_en_gpio, 
ret);
goto error4;
}
@@ -121,7 +121,7 @@ static int gpio_config(struct hdmi *hdmi, bool on)
if (config->mux_sel_gpio != -1) {
ret = gpio_request(config->mux_sel_gpio, 
"HDMI_MUX_SEL");
if (ret) {
-   dev_err(dev->dev, "'%s'(%d) gpio_request 
failed: %d\n",
+   dev_err(dev, "'%s'(%d) gpio_request failed: 
%d\n",
"HDMI_MUX_SEL", config->mux_sel_gpio, 
ret);
goto error5;
}
@@ -132,7 +132,7 @@ static int gpio_config(struct hdmi *hdmi, bool on)
ret = gpio_request(config->mux_lpm_gpio,
"HDMI_MUX_LPM");
if (ret) {
-   dev_err(dev->dev,
+   dev_err(dev,
"'%s'(%d) gpio_request failed: %d\n",
"HDMI_MUX_LPM",
config->mux_lpm_gpio, ret);
@@ -185,7 +185,7 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
 {
struct hdmi *hdmi = hdmi_connector->hdmi;
const struct hdmi_platform_config *config = hdmi->config;
-   struct drm_device *dev = hdmi_connector->base.dev;
+   struct device *dev = &hdmi->pdev->dev;
struct hdmi_phy *phy = hdmi->phy;
uint32_t hpd_ctrl;
int i, ret;
@@ -193,7 +193,7 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
for (i = 0; i < config->hpd_reg_cnt; i++) {
ret = regulator_enable(hdmi->hpd_regs[i]);
if (ret) {
-   dev_err(dev->dev, "failed to enable hpd regulator: %s 
(%d)\n",
+   dev_err(dev, "failed to enable hpd regulator: %s 
(%d)\n",
config->hpd_reg_names[i], ret);
goto fail;
}
@@ -201,7 +201,7 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)

ret = gpio_config(hdmi, true);
if (ret) {
-   dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret);
+   dev_err(dev, "failed to configure GPIOs: %d\n", ret);
go

[PATCH v3 2/2] drm/msm/hdmi: Use pinctrl in HDMI driver

2015-06-04 Thread Stephane Viau
Some targets (eg: msm8994) use the pinctrl framework to configure
interface pins. This change adds support for initialization and
pinctrl active/sleep state control for the HDMI driver.

Signed-off-by: Stephane Viau 
---
v3:
- Use pins binding handled in driver really_probe()  [Ivan]

v2:
- Add devicetree binding documentation for pinctrl property  [Ivan]
- Use pinctrl framework's PINCTRL_STATE_DEFAULT/SLEEP states [Ivan]

 Documentation/devicetree/bindings/drm/msm/hdmi.txt |  6 ++
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c  | 11 +++
 2 files changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/drm/msm/hdmi.txt 
b/Documentation/devicetree/bindings/drm/msm/hdmi.txt
index a29a55f..c43aa53 100644
--- a/Documentation/devicetree/bindings/drm/msm/hdmi.txt
+++ b/Documentation/devicetree/bindings/drm/msm/hdmi.txt
@@ -20,6 +20,9 @@ Required properties:
 Optional properties:
 - qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin
 - qcom,hdmi-tx-mux-sel-gpio: hdmi mux select pin
+- pinctrl-names: the pin control state names; should contain "default"
+- pinctrl-0: the default pinctrl state (active)
+- pinctrl-1: the "sleep" pinctrl state

 Example:

@@ -44,5 +47,8 @@ Example:
qcom,hdmi-tx-hpd = <&msmgpio 72 GPIO_ACTIVE_HIGH>;
core-vdda-supply = <&pm8921_hdmi_mvs>;
hdmi-mux-supply = <&ext_3p3v>;
+   pinctrl-names = "default", "sleep";
+   pinctrl-0 = <&hpd_active  &ddc_active  &cec_active>;
+   pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>;
};
 };
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index e29b62a..ece572d 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -16,6 +16,7 @@
  */

 #include 
+#include 

 #include "msm_kms.h"
 #include "hdmi.h"
@@ -199,6 +200,12 @@ static int hpd_enable(struct hdmi_connector 
*hdmi_connector)
}
}

+   ret = pinctrl_pm_select_default_state(dev);
+   if (ret) {
+   dev_err(dev, "pinctrl state chg failed: %d\n", ret);
+   goto fail;
+   }
+
ret = gpio_config(hdmi, true);
if (ret) {
dev_err(dev, "failed to configure GPIOs: %d\n", ret);
@@ -268,6 +275,10 @@ static void hdp_disable(struct hdmi_connector 
*hdmi_connector)
if (ret)
dev_warn(dev, "failed to unconfigure GPIOs: %d\n", ret);

+   ret = pinctrl_pm_select_sleep_state(dev);
+   if (ret)
+   dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
+
for (i = 0; i < config->hpd_reg_cnt; i++) {
ret = regulator_disable(hdmi->hpd_regs[i]);
if (ret)
-- 
Qualcomm Innovation Center, Inc.

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a 
Linux Foundation Collaborative Project



[Intel-gfx] [RFC PATCH 00/11] drm/i915: Expose OA metrics via perf PMU

2015-06-04 Thread Robert Bragg
On Wed, May 27, 2015 at 4:39 PM, <> wrote:
> On Thu, May 21, 2015 at 12:17:48AM +0100, Robert Bragg wrote:
>> >
>> > So for me the 'natural' way to represent this in perf would be through
>> > event groups. Create a perf event for every single event -- yes this is
>> > 53 events.
>>
>> So when I was first looking at this work I had considered the
>> possibility of separate events, and these are some of the things that
>> in the end made me forward the hardware's raw report data via a single
>> event instead...
>>
>> There are 100s of possible B counters depending on the MUX
>> configuration + fixed-function logic in addition to the A counters.
>
> There's only 8 B counters, what there is 100s of is configurations, and
> that's no different from any other PMU. There's 100s of events to select
> on the CPU side as well - yet only 4 (general purpose) counters (8 if
> you disable HT on recent machines) per CPU.

To clarify one thing here; In the PRM you'll see a reference to
'Reserved' slots in the report layouts and these effectively
correspond to a further 8 configurable counters. These further
counters get referred to as 'C' counters for 'custom' and similar to
the B counters they are defined based on the MUX configuration except
they skip the boolean logic pipeline.

Thanks for the comparison with the CPU.

My main thought here is to beware of considering these configurable
counters as 'general purpose' if that might also imply orthogonality.
All our configurable counters build on top of a common/shared MUX
configuration so I'd tend to think of them more like a 'general
purpose counter set'.

>
> Of course, you could create more than 8 events at any one time, and then
> perf will round-robin the configuration for you.

This hardware really isn't designed to allow round-robin
reconfiguration. If we change the metric set then we will loose the
aggregate value of our B counters. Besides writing the large MUX
config + boolean logic state we would also need to save the current
aggregated counter values only maintained by the OA unit so they could
be restored later as well as any internal state that's simply not
accessible to us. If we reconfigure to try and round-robin between
sets of counters each reconfiguration will trash state that we have no
way of restoring. The counters have to no longer be in use if there's
no going back once we reconfigure.

>
>> A
>> choice would need to be made about whether to expose events for the
>> configurable counters that aren't inherently associated with any
>> semantics, or instead defining events for counters with specific
>> semantics (with 100s of possible counters to define). The later would
>> seem more complex for userspace and the kernel if they both now have
>> to understand the constraints on what counters can be used together.
>
> Again, no different from existing PMUs. The most 'interesting' part of
> any PMU driver is event scheduling.
>
> The explicit design of perf was to put event scheduling _in_ the kernel
> and not allow userspace direct access to the hardware (as previous PMU
> models did).

I'm thinking your 'event scheduling' here refers to the kernel being
able to handle multiple concurrent users of the same pmu, but then we
may be talking cross purposes...

I was describing how (if we exposed events for counters with well
defined semantics - as opposed to just 16 events for the B/C counters)
the driver would need to do some kind of matching based on the events
added to a group to deduce which MUX configuration should be used and
saying that in this case userspace would need to be very aware of
which events belong to a specific MUX configuration.

I don't think we have the hardware flexibility to support scheduling
in terms of multiple concurrent users, unless they happen to want
exactly the same configuration.

I also don't think we have a use case for accessing gpu metrics where
concurrent access is really important. It's possible to think of cases
where it might be nice, except they are unlikely to involve the same
configuration so given the current OA unit design I haven't had plans
to try and support concurrent access and haven't had any requests for
it so far.

>
>> I
>> guess with either approach we would also need to have some form of
>> dedicated group leader event accepting attributes for configuring the
>> state that affects the group as a whole, such as the counter
>> configuration (3D vs GPGPU vs media etc).
>
> That depends a bit on how flexible you want to switch between these
> modes; with the cost being in the 100s of MMIO register writes, it might
> just not make sense to make this too dynamic.
>
> An option might be to select the mode through the PMU driver's sysfs
> files. Another option might be to expose the B counters 3 times and have
> each set be mutually exclusive. That is, as soon as you've created a 3D
> event, you can no longer create GPGPU/Media events.

Hmm, interesting idea to have global/pmu state be controlled via sysfs.

[PATCH 00/21] On-demand device registration

2015-06-04 Thread Alexander Holler
Am 03.06.2015 um 21:57 schrieb Grygorii.Strashko at linaro.org:

...

> So few comments from above:
> - registering devices later during the System boot may improve boot time.
>   But resolving of all deferred probes may NOT improve boot time ;) 
>   Have you seen smth like this?

If someone is out for boot time reduction, I think one of the best ways
would by making driver initialization parallel. Keep in mind that all
linked in drivers currently are initialized in series.

As it seems to have been forgotten or overread, I've mentioned in my
series of patches last year that, with a few changes, it's possible to
let the algorithm I've used (dfs) to spit out all drivers which can be
initialized in parallel.

But as I'm not paid for the work I've done and just did it out of
curiosity, interest or how ever you want name it, I haven't spend any
more time into that topic, especially as I'm missing the necessary
connections to get patches into the kernel. ;)

But, as said, it's easy (at least if aren't getting panic when it comes
to a bit of algorithm theory) to get a list drivers you can start in
parallel if you have such a complete list of dependencies as DT already
offers. Just look at the pictures generate by dtc (using my patches),
you will see, they already show which drivers can be initialized in
parallel.

So it would be easy to use e.g. all cores already very early at boot to
initialize drivers, not just after init got started. Besides that the
würgaround of defered init (which, btw. leads devs to supress error
messages, which is especially bad if you are searching a problem) isn't
needed anymore if you have a list of dependecies (however you get it,
I've used DT because the dependencies already are all there).

Regards,

Alexander Holler


[PATCH] drm: bridge/dw_hdmi: Return num_modes in dw_hdmi_connector_get_modes

2015-06-04 Thread Doug Anderson
The dw_hdmi_connector_get_modes() function accidentally forgets to
return the number of modes it added, although it has this information
stored in a local variable.  Let's fix that.

Without this fix, drm_helper_probe_single_connector_modes_merge_bits()
could get confused and always call drm_add_modes_noedid().  That's not
right.

Signed-off-by: Doug Anderson 
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 594f84c..816d104 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1395,7 +1395,7 @@ static int dw_hdmi_connector_get_modes(struct 
drm_connector *connector)
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 connector);
struct edid *edid;
-   int ret;
+   int ret = 0;

if (!hdmi->ddc)
return 0;
@@ -1412,7 +1412,7 @@ static int dw_hdmi_connector_get_modes(struct 
drm_connector *connector)
dev_dbg(hdmi->dev, "failed to get edid\n");
}

-   return 0;
+   return ret;
 }

 static enum drm_mode_status
-- 
2.2.0.rc0.207.ga3a616c



[PATCH v2 1/2] clk: change clk_ops' ->round_rate() prototype

2015-06-04 Thread Paul Walmsley
Hi folks

just a brief comment on this one:

On Thu, 30 Apr 2015, Boris Brezillon wrote:

> Clock rates are stored in an unsigned long field, but ->round_rate()
> (which returns a rounded rate from a requested one) returns a long
> value (errors are reported using negative error codes), which can lead
> to long overflow if the clock rate exceed 2Ghz.
> 
> Change ->round_rate() prototype to return 0 or an error code, and pass the
> requested rate as a pointer so that it can be adjusted depending on
> hardware capabilities.

...

> diff --git a/Documentation/clk.txt b/Documentation/clk.txt
> index 0e4f90a..fca8b7a 100644
> --- a/Documentation/clk.txt
> +++ b/Documentation/clk.txt
> @@ -68,8 +68,8 @@ the operations defined in clk.h:
>   int (*is_enabled)(struct clk_hw *hw);
>   unsigned long   (*recalc_rate)(struct clk_hw *hw,
>   unsigned long parent_rate);
> - long(*round_rate)(struct clk_hw *hw,
> - unsigned long rate,
> + int (*round_rate)(struct clk_hw *hw,
> + unsigned long *rate,
>   unsigned long *parent_rate);
>   long(*determine_rate)(struct clk_hw *hw,
>   unsigned long rate,

I'd suggest that we should probably go straight to 64-bit rates.  There 
are already plenty of clock sources that can generate rates higher than 
4GiHz.


- Paul


[PATCH 00/21] On-demand device registration

2015-06-04 Thread Alexander Holler
Am 03.06.2015 um 23:12 schrieb Rob Clark:
> On Mon, May 25, 2015 at 10:53 AM, Tomeu Vizoso
>  wrote:
>> Hello,
>>
>> I have a problem with the panel on my Tegra Chromebook taking longer than
>> expected to be ready during boot (Stéphane Marchesin reported what is
>> basically the same issue in [0]), and have looked into ordered probing as a
>> better way of solving this than moving nodes around in the DT or playing with
>> initcall levels.
>>
>> While reading the thread [1] that Alexander Holler started with his series to
>> make probing order deterministic, it occurred to me that it should be 
>> possible
>> to achieve the same by registering devices as they are referenced by other
>> devices.
>>
>> This basically reuses the information that is already implicit in the probe()
>> implementations, saving us from refactoring existing drivers or adding
>> information to DTBs.
>>
>> Something I'm not completely happy with is that I have had to move the call 
>> to
>> of_platform_populate after all platform drivers have been registered.
>> Otherwise I don't see how I could register drivers on demand as we don't have
>> yet each driver's compatible strings.
>>
>> For machs that don't move of_platform_populate() to a later point, these
>> patches shouldn't cause any problems but it's not guaranteed that we'll avoid
>> all the deferred probes as some drivers may not be registered yet.
>>
>> I have tested this on boards with Tegra, iMX.6 and Exynos SoCs, and these
>> patches were enough to eliminate all the deferred probes.
>>
>> With this series I get the kernel to output to the panel in 0.5s, instead of 
>> 2.8s.
> 
> So, complete drive-by comment (and I won't claim to be a DT expert,
> etc, etc, so take this with a few grains of salt), but why not push
> the problem to the DT compiler (or a pre-process step that could be
> run on existing DT blobs), which generates an optional DT node that is
> the recommended probe order?  That seems like it avoids adding
> complexity into the early boot code (which seems like a good thing)..

I've played with that approach too (as my patches for dtc do contain the
same code I've put into the kernel, but decided that it doesn't make
much sense. The sort algorithm is really small (some dozen lines), very
fast (around 3-5ms on a omap) and might be later used to sort necessary
module loading too. So there would be no advantage to put a sorted list
into the DT. And having the sort algorithm in the kernel, would make it
possible to use it for acpi or something else too, if they manage it to
provide the necessary dependencies.

Regards,

Alexander Holler