Re: [PATCH] drm: simple_kms_helper: Fix .mode_valid() documentation

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 11:11:09AM +0100, Linus Walleij wrote:
> This fixes up the .mode_valid() vtable entry documentation
> by copyediting the documentation from the .mode_valid()
> documentation in the drm_modeset_helper_vtables.h file.
> 
> Fixes: 40275dc4edb4 ("drm: simple_kms_helper: Add mode_valid() callback 
> support")
> Suggested-by: Daniel Vetter 
> Signed-off-by: Linus Walleij 

Reviewed-by: Daniel Vetter 

> ---
>  include/drm/drm_simple_kms_helper.h | 27 ---
>  1 file changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/include/drm/drm_simple_kms_helper.h 
> b/include/drm/drm_simple_kms_helper.h
> index d9e4c3c3f009..0d700a869cc8 100644
> --- a/include/drm/drm_simple_kms_helper.h
> +++ b/include/drm/drm_simple_kms_helper.h
> @@ -24,9 +24,30 @@ struct drm_simple_display_pipe_funcs {
>   /**
>* @mode_valid:
>*
> -  * This function is called to filter out valid modes from the
> -  * suggestions suggested by the bridge or display. This optional
> -  * hook is passed in when initializing the pipeline.
> +  * This callback is used to check if a specific mode is valid in the
> +  * crtc used in this simple display pipe. This should be implemented
> +  * if the display pipe has some sort of restriction in the modes
> +  * it can display. For example, a given display pipe may be responsible
> +  * to set a clock value. If the clock can not produce all the values
> +  * for the available modes then this callback can be used to restrict
> +  * the number of modes to only the ones that can be displayed. Another
> +  * reason can be bandwidth mitigation: the memory port on the display
> +  * controller can have bandwidth limitations not allowing pixel data
> +  * to be fetched at any rate.
> +  *
> +  * This hook is used by the probe helpers to filter the mode list in
> +  * drm_helper_probe_single_connector_modes(), and it is used by the
> +  * atomic helpers to validate modes supplied by userspace in
> +  * drm_atomic_helper_check_modeset().
> +  *
> +  * This function is optional.
> +  *
> +  * NOTE:
> +  *
> +  * Since this function is both called from the check phase of an atomic
> +  * commit, and the mode validation in the probe paths it is not allowed
> +  * to look at anything else but the passed-in mode, and validate it
> +  * against configuration-invariant hardware constraints.
>*
>* RETURNS:
>*
> -- 
> 2.14.3
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] dma-buf/reservation: should keep the new fence in add_shared_inplace

2018-03-06 Thread Christian König

NAK, the newly added fence must always be newer than the existing one.

Christian.

Am 06.03.2018 um 04:09 schrieb Monk Liu:

Change-Id: If6a979ba9fd6c923b82212f35f07a9ff31c86767
Signed-off-by: Monk Liu 
---
  drivers/dma-buf/reservation.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 314eb10..29b7e45 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -118,7 +118,7 @@ reservation_object_add_shared_inplace(struct 
reservation_object *obj,
old_fence = rcu_dereference_protected(fobj->shared[i],
reservation_object_held(obj));
  
-		if (old_fence->context == fence->context) {

+   if (dma_fence_is_later(fence, old_fence)) {
/* memory barrier is added by write_seqcount_begin */
RCU_INIT_POINTER(fobj->shared[i], fence);
write_seqcount_end(&obj->seq);


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 198883] amdgpu: carrizo: Screen stalls after starting X

2018-03-06 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=198883

--- Comment #31 from Ricardo Ribalda (ricardo.riba...@gmail.com) ---
Hi Andrey

I mean a stall, sorry about that.

root@qt5122:~# ps aux | grep Xorg
root   520  0.0  0.0  15936   900 ?S07:59   0:00 xinit
/etc/X11/Xsession -- /usr/bin/Xorg :0 -br -pn
root   541  0.2  1.3 859896 47412 ?Shttp://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-poky-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 541
[New LWP 614]
[New LWP 615]
[New LWP 616]
[New LWP 617]
[New LWP 618]
[New LWP 619]
[New LWP 620]
[New LWP 625]
[New LWP 636]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
0x00321c4ee1a6 in __GI_epoll_pwait (epfd=3,
events=events@entry=0x7ffc92802560, 
maxevents=maxevents@entry=256, timeout=474326, set=set@entry=0x0)
at
/usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/epoll_pwait.c:42
42return SYSCALL_CANCEL (epoll_pwait, epfd, events, maxevents,

(gdb) thread apply all bt

Thread 10 (Thread 0x7fb4d31cd700 (LWP 636)):
#0  0x00321c4ee1a6 in __GI_epoll_pwait (epfd=24,
events=events@entry=0x7fb4d31cc0d0, 
maxevents=maxevents@entry=256, timeout=timeout@entry=-1, set=set@entry=0x0)
at
/usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/epoll_pwait.c:42
#1  0x00321c4ee318 in epoll_wait (epfd=,
events=events@entry=0x7fb4d31cc0d0, 
maxevents=maxevents@entry=256, timeout=timeout@entry=-1)
at /usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/epoll_wait.c:30
#2  0x0056ff24 in ospoll_wait (ospoll=0xea8b50,
timeout=timeout@entry=-1)
at
/usr/src/debug/xserver-xorg/2_1.19.3-r0/xorg-server-1.19.3/os/ospoll.c:397
#3  0x0056d9b6 in InputThreadDoWork (arg=)
at
/usr/src/debug/xserver-xorg/2_1.19.3-r0/xorg-server-1.19.3/os/inputthread.c:367
#4  0x00321c807385 in start_thread (arg=0x7fb4d31cd700)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_create.c:465
#5  0x00321c4ee03f in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 9 (Thread 0x7fb4d3fff700 (LWP 625)):
#0  0x00321c80d2a5 in futex_wait_cancelable (private=,
expected=0, 
futex_word=0xd390f4)
at
/usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0xd390a0, cond=0xd390c8)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0xd390c8, mutex=0xd390a0)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_cond_wait.c:655
#3  0x7fb4e40e5243 in ?? () from /usr/lib/dri/radeonsi_dri.so
#4  0x7fb4e40e5188 in ?? () from /usr/lib/dri/radeonsi_dri.so
#5  0x00321c807385 in start_thread (arg=0x7fb4d3fff700)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_create.c:465
#6  0x00321c4ee03f in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 8 (Thread 0x7fb4d93d8700 (LWP 620)):
#0  0x00321c80d2a5 in futex_wait_cancelable (private=,
expected=0, 
futex_word=0xc655f8)
at
/usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0xc655a8, cond=0xc655d0)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0xc655d0, mutex=0xc655a8)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_cond_wait.c:655
#3  0x7fb4e40e5243 in ?? () from /usr/lib/dri/radeonsi_dri.so
#4  0x7fb4e40e5188 in ?? () from /usr/lib/dri/radeonsi_dri.so
#5  0x00321c807385 in start_thread (arg=0x7fb4d93d8700)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_create.c:465
#6  0x00321c4ee03f in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 7 (Thread 0x7fb4d9bd9700 (LWP 619)):
#0  0x00321c80d2a5 in futex_wait_cancelable (private=,
expected=0, 
futex_word=0xc655f8)
at
/usr/src/debug/glibc/2.26-r0/git/sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0xc655a8, cond=0xc655d0)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0xc655d0, mutex=0xc655a8)
at /usr/src/debug/glibc/2.26-r0/git/nptl/pthread_cond_wait.c:655
#3  0x7fb4e40e5243 in ?? () from /usr/lib/dri/radeonsi_dri.so
#4  0x7fb4e40e5188 in ?? () from /usr/lib/dri/radeonsi_dri.so
---Type  to continue, or q  to quit---
#5  0x00321c807385 in start_thread (arg=0x7fb4d9bd9700)
at /usr/src/d

Re: [PATCH] dma-buf/reservation: should keep later one in add fence(v3)

2018-03-06 Thread Christian König
And still a NAK, the prerequisite for adding a shared fence is that it 
is later than any existing fence in that context.


In other words reservation_object_add_shared_fence() is always called 
with a new fence, never with some old one.


So the whole checking here is completely superfluous,
Christian.

Am 06.03.2018 um 08:00 schrieb Monk Liu:

v2:
still check context first to avoid warning from dma_fence_is_later
apply this fix in add_shared_replace as well

v3:
use a bool falg to indict if fence is need to insert to new slot
and ignore it if it is an eld fence compared with the one with
the same context in old->shared

Change-Id: If6a979ba9fd6c923b82212f35f07a9ff31c86767
Signed-off-by: Monk Liu 
---
  drivers/dma-buf/reservation.c | 28 ++--
  1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 314eb10..a7d0598 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -118,7 +118,8 @@ reservation_object_add_shared_inplace(struct 
reservation_object *obj,
old_fence = rcu_dereference_protected(fobj->shared[i],
reservation_object_held(obj));
  
-		if (old_fence->context == fence->context) {

+   if (old_fence->context == fence->context &&
+   dma_fence_is_later(fence, old_fence)) {
/* memory barrier is added by write_seqcount_begin */
RCU_INIT_POINTER(fobj->shared[i], fence);
write_seqcount_end(&obj->seq);
@@ -158,6 +159,7 @@ reservation_object_add_shared_replace(struct 
reservation_object *obj,
  struct dma_fence *fence)
  {
unsigned i, j, k;
+   bool wrong_fence = false;
  
  	dma_fence_get(fence);
  
@@ -179,15 +181,29 @@ reservation_object_add_shared_replace(struct reservation_object *obj,

check = rcu_dereference_protected(old->shared[i],
reservation_object_held(obj));
  
-		if (check->context == fence->context ||

-   dma_fence_is_signaled(check))
+   if (dma_fence_is_signaled(check)) {
+   /* put check to tail of fobj if signaled */
RCU_INIT_POINTER(fobj->shared[--k], check);
-   else
+   } else if (check->context == fence->context) {
+   if (dma_fence_is_later(fence, check)) {
+   /* put check to tail of fobj if it is 
deprecated */
+   RCU_INIT_POINTER(fobj->shared[--k], check);
+   } else {
+   /* this is a wrong operation that add an eld 
fence */
+   wrong_fence = true;
+   RCU_INIT_POINTER(fobj->shared[j++], check);
+   }
+   } else {
+   /* add fence to new slot */
RCU_INIT_POINTER(fobj->shared[j++], check);
+   }
}
+
fobj->shared_count = j;
-   RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
-   fobj->shared_count++;
+   if (!wrong_fence) {
+   RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
+   fobj->shared_count++;
+   }
  
  done:

preempt_disable();


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 198883] amdgpu: carrizo: Screen stalls after starting X

2018-03-06 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=198883

--- Comment #32 from Ricardo Ribalda (ricardo.riba...@gmail.com) ---
Created attachment 274579
  --> https://bugzilla.kernel.org/attachment.cgi?id=274579&action=edit
sudo umr -O many,bits  -r *.gfx80.mmGRBM_STATUS &> stall  sudo umr -O many,bits
 -r *.gfx80.HEADER_DUMP &>>stall sudo umr -O many,bits  -r *.gfx80.CP_EOP
&>>stall

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm: of: simplify component probe code

2018-03-06 Thread Philipp Zabel
On Thu, 2018-02-22 at 21:22 +0200, Baruch Siach wrote:
> Use positive logic for better readability. This also eliminates one
> of_node_put() call, making the code shorter.
> 
> Signed-off-by: Baruch Siach 

Reviewed-by: Philipp Zabel 
Tested-by: Philipp Zabel 

regards
Philipp

> ---
>  drivers/gpu/drm/drm_of.c | 8 +++-
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index 4c191c050e7d..fa354d14127b 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -122,12 +122,10 @@ int drm_of_component_probe(struct device *dev,
>   if (!port)
>   break;
>  
> - if (!of_device_is_available(port->parent)) {
> - of_node_put(port);
> - continue;
> - }
> + if (of_device_is_available(port->parent))
> + drm_of_component_match_add(dev, &match, compare_of,
> + port);
>  
> - drm_of_component_match_add(dev, &match, compare_of, port);
>   of_node_put(port);
>   }
>  
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105021] suspend / rx550 / extremely slow after 2nd thaw

2018-03-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105021

--- Comment #28 from arne_woer...@yahoo.com ---
linux kernel 4.15.7-1-MANJARO
with mesa 17.3.6-1
still does not like 20180119-2 polaris12 firmware...
-arne

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 198883] amdgpu: carrizo: Screen stalls after starting X

2018-03-06 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=198883

--- Comment #33 from Ricardo Ribalda (ricardo.riba...@gmail.com) ---
Last dump belongs to a stall after running dmesg. (similar to yesterdays dump
1).

The next one happens after running Xorg. This time, gdb also stalls when trying
to get a dump:

root@qt5122:~# ps aux | grep Xorg
root   519  0.0  0.0  15936   900 ?S08:19   0:00 xinit
/etc/X11/Xsession -- /usr/bin/Xorg :0 -br -pn
root   540  0.3  1.3 857220 47812 ?Shttp://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-poky-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 540
[New LWP 617]
[New LWP 618]
[New LWP 619]
[New LWP 620]
[New LWP 621]
[New LWP 622]
[New LWP 623]
[New LWP 624]
[New LWP 635]

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 198883] amdgpu: carrizo: Screen stalls after starting X

2018-03-06 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=198883

--- Comment #34 from Ricardo Ribalda (ricardo.riba...@gmail.com) ---
Created attachment 274581
  --> https://bugzilla.kernel.org/attachment.cgi?id=274581&action=edit
Stalled after starting X. Gdb also stalls

sudo umr -O many,bits  -r *.gfx80.mmGRBM_STATUS &> stall 
sudo umr -O many,bits  -r *.gfx80.HEADER_DUMP &>>stall
sudo umr -O many,bits  -r *.gfx80.CP_EOP &>>stall

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] dma-buf/reservation: should keep later one in add fence(v2)

2018-03-06 Thread Chris Wilson
Quoting Monk Liu (2018-03-06 03:53:10)
> v2:
> still check context first to avoid warning from dma_fence_is_later
> apply this fix in add_shared_replace as well
> 
> Change-Id: If6a979ba9fd6c923b82212f35f07a9ff31c86767
> Signed-off-by: Monk Liu 
> ---
>  drivers/dma-buf/reservation.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> index 314eb10..c6e3c86 100644
> --- a/drivers/dma-buf/reservation.c
> +++ b/drivers/dma-buf/reservation.c
> @@ -118,7 +118,8 @@ reservation_object_add_shared_inplace(struct 
> reservation_object *obj,
> old_fence = rcu_dereference_protected(fobj->shared[i],
> reservation_object_held(obj));
>  
> -   if (old_fence->context == fence->context) {
> +   if (old_fence->context == fence->context &&
> +   dma_fence_is_later(fence, old_fence)) {

This should be true by construction. Adding an older fence on the same
context is a programming bug, imo. Between different callers the resv
should have been locked and the fenced operations serialised, from the
same caller, you shouldn't be handling more than one output fence?
-Chris
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC v3 02/12] drm/file: Don't set master on in-kernel clients

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:43PM +0100, Noralf Trønnes wrote:
> It only makes sense for userspace clients.
> 
> Signed-off-by: Noralf Trønnes 

I think we might be able to reuse some of the master stuff to better
handle hand-over between in-kernel clients and userspace masters for kms.
But this definitely makes sense.

Reviewed-by: Daniel Vetter 

> ---
>  drivers/gpu/drm/drm_file.c | 18 +-
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> index d4588d33f91c..55505378df47 100644
> --- a/drivers/gpu/drm/drm_file.c
> +++ b/drivers/gpu/drm/drm_file.c
> @@ -155,17 +155,8 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
>   goto out_prime_destroy;
>   }
>  
> - if (drm_is_primary_client(file)) {
> - ret = drm_master_open(file);
> - if (ret)
> - goto out_close;
> - }
> -
>   return file;
>  
> -out_close:
> - if (dev->driver->postclose)
> - dev->driver->postclose(dev, file);
>  out_prime_destroy:
>   if (drm_core_check_feature(dev, DRIVER_PRIME))
>   drm_prime_destroy_file_private(&file->prime);
> @@ -365,6 +356,7 @@ static int drm_open_helper(struct file *filp, struct 
> drm_minor *minor)
>  {
>   struct drm_device *dev = minor->dev;
>   struct drm_file *priv;
> + int ret;
>  
>   if (filp->f_flags & O_EXCL)
>   return -EBUSY;  /* No exclusive opens */
> @@ -379,6 +371,14 @@ static int drm_open_helper(struct file *filp, struct 
> drm_minor *minor)
>   if (IS_ERR(priv))
>   return PTR_ERR(priv);
>  
> + if (drm_is_primary_client(priv)) {
> + ret = drm_master_open(priv);
> + if (ret) {
> + drm_file_free(priv);
> + return ret;
> + }
> + }
> +
>   filp->private_data = priv;
>   priv->filp = filp;
>  
> -- 
> 2.15.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/atomic: Add new reverse iterator over all plane state (V2)

2018-03-06 Thread Jani Nikula
On Mon, 05 Mar 2018, Harry Wentland  wrote:
>   make DOCBOOKS="" htmldocs

DOCBOOKS is no more. Simply 'make htmldocs' will do the same.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Technology Center
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 32/38] drm/rockchip: Disable PSR on input events

2018-03-06 Thread Enric Balletbo i Serra
From: "Kristian H. Kristensen" 

To improve PSR exit latency, we speculatively start exiting when we
receive input events. Occasionally, this may lead to false positives,
but most of the time we get a head start on coming out of PSR. Depending
on how userspace takes to produce a new frame in response to the event,
this can completely hide the exit latency. In case of Chrome OS, we
typically get the input notifier 50ms or more before the dirty_fb
triggered exit.

Signed-off-by: Kristian H. Kristensen 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 134 
 1 file changed, 134 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 9376f4396b6b..a107845ba97c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -12,6 +12,8 @@
  * GNU General Public License for more details.
  */
 
+#include 
+
 #include 
 #include 
 
@@ -35,6 +37,9 @@ struct psr_drv {
enum psr_state  state;
 
struct delayed_work flush_work;
+   struct work_struct  disable_work;
+
+   struct input_handlerinput_handler;
 
int (*set)(struct drm_encoder *encoder, bool enable);
 };
@@ -133,6 +138,18 @@ static void psr_flush_handler(struct work_struct *work)
mutex_unlock(&psr->lock);
 }
 
+static void psr_disable_handler(struct work_struct *work)
+{
+   struct psr_drv *psr = container_of(work, struct psr_drv, disable_work);
+
+   /* If the state has changed since we initiated the flush, do nothing */
+   mutex_lock(&psr->lock);
+   if (psr->state == PSR_ENABLE)
+   psr_set_state_locked(psr, PSR_FLUSH);
+   mutex_unlock(&psr->lock);
+   mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS);
+}
+
 /**
  * rockchip_drm_psr_activate - activate PSR on the given pipe
  * @encoder: encoder to obtain the PSR encoder
@@ -173,6 +190,7 @@ int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
psr->active = false;
mutex_unlock(&psr->lock);
cancel_delayed_work_sync(&psr->flush_work);
+   cancel_work_sync(&psr->disable_work);
 
return 0;
 }
@@ -226,6 +244,95 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev)
 }
 EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
 
+static void psr_input_event(struct input_handle *handle,
+   unsigned int type, unsigned int code,
+   int value)
+{
+   struct psr_drv *psr = handle->handler->private;
+
+   schedule_work(&psr->disable_work);
+}
+
+static int psr_input_connect(struct input_handler *handler,
+struct input_dev *dev,
+const struct input_device_id *id)
+{
+   struct input_handle *handle;
+   int error;
+
+   handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+   if (!handle)
+   return -ENOMEM;
+
+   handle->dev = dev;
+   handle->handler = handler;
+   handle->name = "rockchip-psr";
+
+   error = input_register_handle(handle);
+   if (error)
+   goto err2;
+
+   error = input_open_device(handle);
+   if (error)
+   goto err1;
+
+   return 0;
+
+err1:
+   input_unregister_handle(handle);
+err2:
+   kfree(handle);
+   return error;
+}
+
+static void psr_input_disconnect(struct input_handle *handle)
+{
+   input_close_device(handle);
+   input_unregister_handle(handle);
+   kfree(handle);
+}
+
+/* Same device ids as cpu-boost */
+static const struct input_device_id psr_ids[] = {
+   {
+   .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+INPUT_DEVICE_ID_MATCH_ABSBIT,
+   .evbit = { BIT_MASK(EV_ABS) },
+   .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
+   BIT_MASK(ABS_MT_POSITION_X) |
+   BIT_MASK(ABS_MT_POSITION_Y) },
+   }, /* multi-touch touchscreen */
+   {
+   .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+   .evbit = { BIT_MASK(EV_ABS) },
+   .absbit = { [BIT_WORD(ABS_X)] = BIT_MASK(ABS_X) }
+
+   }, /* stylus or joystick device */
+   {
+   .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+   .evbit = { BIT_MASK(EV_KEY) },
+   .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
+   }, /* pointer (e.g. trackpad, mouse) */
+   {
+   .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+   .evbit = { BIT_MASK(EV_KEY) },
+   .keybit = { [BIT_WORD(KEY_ESC)] = BIT_MASK(KEY_ESC) },
+   }, /* keyboard */
+   {
+   .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+   INPUT_DEVICE_ID_MATCH_KEYBIT,
+   .evbit = { BIT_MASK(EV_KEY) },
+   .keybit = {[BIT_WORD(BTN_JOYSTICK)] 

[PATCH v4 04/38] drm/rockchip: Remove analogix psr worker

2018-03-06 Thread Enric Balletbo i Serra
From: Sean Paul 

Now that the spinlocks and timers are gone, we can remove the psr
worker located in rockchip's analogix driver and do the enable/disable
directly. This should simplify the code and remove races on disable.

Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 31 ++---
 1 file changed, 2 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 7d76ff47028d..36334839a3f8 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -71,10 +71,6 @@ struct rockchip_dp_device {
struct regmap*grf;
struct reset_control *rst;
 
-   struct work_struct   psr_work;
-   struct mutex psr_lock;
-   unsigned int psr_state;
-
const struct rockchip_dp_chip_data *data;
 
struct analogix_dp_device *adp;
@@ -84,28 +80,13 @@ struct rockchip_dp_device {
 static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
 {
struct rockchip_dp_device *dp = to_dp(encoder);
+   int ret;
 
if (!analogix_dp_psr_supported(dp->adp))
return;
 
DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
 
-   mutex_lock(&dp->psr_lock);
-   if (enabled)
-   dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE;
-   else
-   dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
-
-   schedule_work(&dp->psr_work);
-   mutex_unlock(&dp->psr_lock);
-}
-
-static void analogix_dp_psr_work(struct work_struct *work)
-{
-   struct rockchip_dp_device *dp =
-   container_of(work, typeof(*dp), psr_work);
-   int ret;
-
ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
@@ -113,12 +94,10 @@ static void analogix_dp_psr_work(struct work_struct *work)
return;
}
 
-   mutex_lock(&dp->psr_lock);
-   if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
+   if (enabled)
analogix_dp_enable_psr(dp->adp);
else
analogix_dp_disable_psr(dp->adp);
-   mutex_unlock(&dp->psr_lock);
 }
 
 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
@@ -135,8 +114,6 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data 
*plat_data)
struct rockchip_dp_device *dp = to_dp(plat_data);
int ret;
 
-   cancel_work_sync(&dp->psr_work);
-
ret = clk_prepare_enable(dp->pclk);
if (ret < 0) {
DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
@@ -355,10 +332,6 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
dp->plat_data.power_off = rockchip_dp_powerdown;
dp->plat_data.get_modes = rockchip_dp_get_modes;
 
-   mutex_init(&dp->psr_lock);
-   dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
-   INIT_WORK(&dp->psr_work, analogix_dp_psr_work);
-
ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set);
if (ret < 0)
goto err_cleanup_encoder;
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 27/38] drm/bridge: analogix_dp: Properly log AUX CH errors

2018-03-06 Thread Enric Balletbo i Serra
From: Douglas Anderson 

The code in analogix_dp_transfer() that was supposed to print out:
  AUX CH error happened

Was actually dead code. That's because the previous check (whether
the interrupt status indicated any errors) would have hit for all
errors anyway.

Let's combine the two error checks so we can actually see AUX CH
errors.  We'll also downgrade the message to a warning since some of
these types of errors might be expected for some displays.  If this
gets too noisy we can downgrade again to debug.

Cc: 征增 王 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 4eae206ec31b..58e8a28e99aa 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1105,6 +1105,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 struct drm_dp_aux_msg *msg)
 {
u32 reg;
+   u32 status_reg;
u8 *buffer = msg->buffer;
unsigned int i;
int num_transferred = 0;
@@ -1193,16 +1194,12 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 
/* Clear interrupt source for AUX CH access error */
reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   if (reg & AUX_ERR) {
+   status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
+   if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
-   goto aux_error;
-   }
 
-   /* Check AUX CH error access status */
-   reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
-   if ((reg & AUX_STATUS_MASK)) {
-   dev_err(dp->dev, "AUX CH error happened: %d\n\n",
-   reg & AUX_STATUS_MASK);
+   dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
+status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
goto aux_error;
}
 
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 35/38] drm/rockchip: psr: Sanitize semantics of allow/disallow API

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

Currently both rockchip_drm_psr_activate() and _deactivate() only set the
boolean "active" flag without actually making sure that hardware state
complies with it.

Since we are going to extend the usage of this API to properly lock PSR
for the duration of atomic commits, we change the semantics in following
way:
 - a counter is used to track the number of disallow requests,
 - PSR is actually disabled in hardware on first disallow request,
 - PSR enable work is scheduled on last disallow request.

The above allows using the API as a way to deterministically synchronize
PSR state changes with other DRM events, i.e. atomic commits and cursor
updates. As a nice side effect, the naming is sorted out and we have
"inhibit" for stopping the software logic and "enable" for hardware
state.

Signed-off-by: Tomasz Figa 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 57 ++---
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h |  4 +-
 3 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 6d45d62466b3..080f05352195 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -134,7 +134,7 @@ static int rockchip_dp_poweron_end(struct 
analogix_dp_plat_data *plat_data)
 {
struct rockchip_dp_device *dp = to_dp(plat_data);
 
-   return rockchip_drm_psr_activate(&dp->encoder);
+   return rockchip_drm_psr_inhibit_put(&dp->encoder);
 }
 
 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
@@ -142,7 +142,7 @@ static int rockchip_dp_powerdown(struct 
analogix_dp_plat_data *plat_data)
struct rockchip_dp_device *dp = to_dp(plat_data);
int ret;
 
-   ret = rockchip_drm_psr_deactivate(&dp->encoder);
+   ret = rockchip_drm_psr_inhibit_get(&dp->encoder);
if (ret != 0)
return ret;
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 448c5fde241c..e7e16d92d5a1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -27,7 +27,7 @@ struct psr_drv {
struct drm_encoder  *encoder;
 
struct mutexlock;
-   boolactive;
+   int inhibit_count;
boolenabled;
 
struct delayed_work flush_work;
@@ -76,7 +76,7 @@ static int psr_set_state_locked(struct psr_drv *psr, bool 
enable)
 {
int ret;
 
-   if (!psr->active)
+   if (psr->inhibit_count > 0)
return -EINVAL;
 
if (enable == psr->enabled)
@@ -101,13 +101,18 @@ static void psr_flush_handler(struct work_struct *work)
 }
 
 /**
- * rockchip_drm_psr_activate - activate PSR on the given pipe
+ * rockchip_drm_psr_inhibit_put - release PSR inhibit on given encoder
  * @encoder: encoder to obtain the PSR encoder
  *
+ * Decrements PSR inhibit count on given encoder. Should be called only
+ * for a PSR inhibit count increment done before. If PSR inhibit counter
+ * reaches zero, PSR flush work is scheduled to make the hardware enter
+ * PSR mode in PSR_FLUSH_TIMEOUT_MS.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_activate(struct drm_encoder *encoder)
+int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder)
 {
struct psr_drv *psr = find_psr_by_encoder(encoder);
 
@@ -115,21 +120,29 @@ int rockchip_drm_psr_activate(struct drm_encoder *encoder)
return PTR_ERR(psr);
 
mutex_lock(&psr->lock);
-   psr->active = true;
+   --psr->inhibit_count;
+   if (!psr->inhibit_count)
+   mod_delayed_work(system_wq, &psr->flush_work,
+PSR_FLUSH_TIMEOUT_MS);
mutex_unlock(&psr->lock);
 
return 0;
 }
-EXPORT_SYMBOL(rockchip_drm_psr_activate);
+EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put);
 
 /**
- * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe
+ * rockchip_drm_psr_inhibit_get - acquire PSR inhibit on given encoder
  * @encoder: encoder to obtain the PSR encoder
  *
+ * Increments PSR inhibit count on given encoder. This function guarantees
+ * that after it returns PSR is turned off on given encoder and no PSR-related
+ * hardware state change occurs at least until a matching call to
+ * rockchip_drm_psr_inhibit_put() is done.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
+int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder)
 {
struct psr_drv *psr = find_psr_by_encoder(encoder);
 
@@ -137,15 +150,15 @@ int rockchip_drm_psr_deactivate(struct drm_encoder 
*encoder)

Re: [PATCH] drm/simple_kms_helper: Fix NULL pointer dereference with no active CRTC

2018-03-06 Thread Oleksandr Andrushchenko

On 03/05/2018 10:52 AM, Daniel Vetter wrote:

On Tue, Feb 20, 2018 at 03:29:07PM +0200, Oleksandr Andrushchenko wrote:

On 02/20/2018 02:53 PM, Oleksandr Andrushchenko wrote:

On 02/20/2018 02:49 PM, Daniel Vetter wrote:

On Tue, Feb 20, 2018 at 02:36:05PM +0200, Oleksandr Andrushchenko wrote:

On 02/20/2018 01:17 PM, Daniel Vetter wrote:

On Mon, Feb 19, 2018 at 04:58:43PM +0200, Oleksandr
Andrushchenko wrote:

On 02/19/2018 04:30 PM, Daniel Vetter wrote:

On Tue, Feb 13, 2018 at 10:44:16AM +0200, Oleksandr
Andrushchenko wrote:

From: Oleksandr Andrushchenko 

It is possible that drm_simple_kms_plane_atomic_check called
with no CRTC set, e.g. when user-space
application sets CRTC_ID/FB_ID
to 0 before doing any actual drawing. This leads to NULL pointer
dereference because in this case new CRTC state is NULL and must be
checked before accessing.

Signed-off-by: Oleksandr Andrushchenko

---
     drivers/gpu/drm/drm_simple_kms_helper.c | 6 --
     1 file changed, 4 insertions(+), 2 deletions(-)

diff --git
a/drivers/gpu/drm/drm_simple_kms_helper.c
b/drivers/gpu/drm/drm_simple_kms_helper.c
index 9ca8a4a59b74..a05eca9cec8b 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -121,8 +121,10 @@ static int
drm_simple_kms_plane_atomic_check(struct
drm_plane *plane,
     pipe = container_of(plane, struct
drm_simple_display_pipe, plane);
     crtc_state =
drm_atomic_get_new_crtc_state(plane_state->state,
    &pipe->crtc);
-    if (!crtc_state->enable)
-    return 0; /* nothing to check when
disabling or disabled */
+
+    if (!crtc_state || !crtc_state->enable)
+    /* nothing to check when disabling or
disabled or no CRTC set */
+    return 0;
     if (crtc_state->enable)
drm_mode_get_hv_timing(&crtc_state->mode,

Hm, this is a bit annoying, since the can_position =
false parameter to
drm_atomic_helper_check_plane_state is supposed to
catch all this. Would
moving all the checks after the call to that helper,
and gating them on
plane_state->visible also work?

Yes, it does work if this is what you mean:

I wasn't sure, thanks for figuring this out!


diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c
b/drivers/gpu/drm/drm_simple_kms_helper.c
index a05eca9cec8b..c48858bb2823 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -122,14 +122,6 @@ static int
drm_simple_kms_plane_atomic_check(struct
drm_plane *plane,
       crtc_state =
drm_atomic_get_new_crtc_state(plane_state->state,
&pipe->crtc);

-   if (!crtc_state || !crtc_state->enable)
-   /* nothing to check when disabling or
disabled or no CRTC
set */
-   return 0;
-
-   if (crtc_state->enable)
- drm_mode_get_hv_timing(&crtc_state->mode,
-  &clip.x2, &clip.y2);
-
       ret =
drm_atomic_helper_check_plane_state(plane_state,
crtc_state,
&clip,
DRM_PLANE_HELPER_NO_SCALING,
@@ -138,6 +130,13 @@ static int
drm_simple_kms_plane_atomic_check(struct
drm_plane *plane,
       if (ret)
       return ret;

+   if (!plane_state->visible || !crtc_state->enable)
+   return 0; /* nothing to check when
disabling or disabled */

if (!plane_state->visible) {
 WARN_ON(crtc_state->enabled);
 return 0;
}

The helper call above should guarantee this.

Yes, but I still see cases when crtc_state is NULL, thus
making crtc_state->enable to fail

Right, when the plane is completely off there's no CRTC state. Correct
check should be

 WARN_ON(crtc_state && crtc_state->enabled);

ok, will update with this additional check

huh, this indeed solves the NULL pointer dereference, but floods a lot
with every page flip I have, e.g. !plane_state->visible == true
and crtc_state is not NULL and crtc_state->enable == true,
thus firing WARN_ON.
Is this something wrong with my use-case/driver or it is still legal
to have such a configuration and leave it without WARN_ON and just
return 0?

1 week of vacation later I have to admit that this WARN_ON is completely
bogus :-)

np ;)

Sorry for all the confusion, pls leave it out.
-Daniel


+
+   if (plane_state->visible && crtc_state->enable)

Similar here.


+ drm_mode_get_hv_timing(&crtc_state->mode,
+  &clip.x2, &clip.y2);
+
       if (!plane_state->visible)
       return -EINVAL;

This can now be removed, the plane helper takes care of checking for
plane_state->visible != crtc_state->enable. Please also remove.


We'd need to add a guarantee to
drm_atomic_helper_check_plane_state that
it can cope with crtc_state == NULL, but I think that's a good idea
anyway. Atm it shouldn't end up looking at the
crtc_state pointer in that
case.

It doesn't look at it at the moment

Otherwise we'll just go with your fix, but it feels
all a bit too fragile,
hence why I want to explore more robust options a bit.

At list with the change above 

[PATCH v4 07/38] drm/bridge: analogix_dp: add fast link train for eDP

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

We would meet a short black screen when exit PSR with the full link
training, In this case, we should use fast link train instead of full
link training.

Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 142 -
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   3 +
 2 files changed, 114 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ee00d3d920e0..806c3878b3d6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -10,17 +10,18 @@
 * option) any later version.
 */
 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
+#include 
+#include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-#include 
-#include 
 #include 
+#include 
 
 #include 
 #include 
@@ -35,6 +36,8 @@
 
 #define to_dp(nm)  container_of(nm, struct analogix_dp_device, nm)
 
+static const bool verify_fast_training;
+
 struct bridge_init {
struct i2c_client *client;
struct device_node *node;
@@ -528,7 +531,7 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
 {
int lane, lane_count, retval;
u32 reg;
-   u8 link_align, link_status[2], adjust_request[2];
+   u8 link_align, link_status[2], adjust_request[2], spread;
 
usleep_range(400, 401);
 
@@ -571,6 +574,20 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
 
+   retval = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD,
+  &spread);
+   if (retval != 1) {
+   dev_err(dp->dev, "failed to read downspread %d\n",
+   retval);
+   dp->fast_train_support = false;
+   } else {
+   dp->fast_train_support =
+   (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
+   true : false;
+   }
+   dev_dbg(dp->dev, "fast link training %s\n",
+   dp->fast_train_support ? "supported" : "unsupported");
+
/* set enhanced mode if available */
analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;
@@ -627,10 +644,12 @@ static void analogix_dp_get_max_rx_lane_count(struct 
analogix_dp_device *dp,
*lane_count = DPCD_MAX_LANE_COUNT(data);
 }
 
-static void analogix_dp_init_training(struct analogix_dp_device *dp,
- enum link_lane_count_type max_lane,
- int max_rate)
+static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
+  u32 max_lanes, u32 max_rate)
 {
+   int retval = 0;
+   bool training_finished = false;
+
/*
 * MACRO_RST must be applied after the PLL_LOCK to avoid
 * the DP inter pair skew issue for at least 10 us
@@ -656,18 +675,13 @@ static void analogix_dp_init_training(struct 
analogix_dp_device *dp,
}
 
/* Setup TX lane count & rate */
-   if (dp->link_train.lane_count > max_lane)
-   dp->link_train.lane_count = max_lane;
+   if (dp->link_train.lane_count > max_lanes)
+   dp->link_train.lane_count = max_lanes;
if (dp->link_train.link_rate > max_rate)
dp->link_train.link_rate = max_rate;
 
/* All DP analog module power up */
analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
-}
-
-static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
-{
-   int retval = 0, training_finished = 0;
 
dp->link_train.lt_state = START;
 
@@ -702,22 +716,88 @@ static int analogix_dp_sw_link_training(struct 
analogix_dp_device *dp)
return retval;
 }
 
-static int analogix_dp_set_link_train(struct analogix_dp_device *dp,
- u32 count, u32 bwtype)
+static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
 {
-   int i;
-   int retval;
+   int i, ret;
+   u8 link_align, link_status[2];
+   enum pll_status status;
 
-   for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
-   analogix_dp_init_training(dp, count, bwtype);
-   retval = analogix_dp_sw_link_training(dp);
-   if (retval == 0)
-   break;
+   analogix_dp_reset_macro(dp);
+
+   analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
+   analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
 
-   usleep_range(100,

Re: [linux-sunxi] [PATCH v3 15/16] ARM: dts: sun8i: h3: Enable HDMI output on H3 boards

2018-03-06 Thread Jernej Škrabec
Hi!

Dne ponedeljek, 05. marec 2018 ob 16:27:00 CET je Joonas Kylmälä napisal(a):
> Jernej Skrabec:
> > +&hdmi_out {
> > +   hdmi_out_con: endpoint {
> > +   remote-endpoint = <&hdmi_con_in>;
> > +   };
> > +};
> 
> This node is added to all the DTS files you enabled HDMI on. Is it
> something that could be instead put to the DTSI file?

I guess that would mean also including connector node (hdmi_con_in) in DTSI, 
since it is referenced inside. However, not all boards have HDMI connector, so 
I didn't include it in DTSI.

Best regards,
Jernej


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 09/38] drm/bridge: analogix_dp: Move enable video into config_video()

2018-03-06 Thread Enric Balletbo i Serra
From: Lin Huang 

We need to enable video before analogix_dp_is_video_stream_on(), so
we can get the right video stream status.

Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5a2e35dc41e3..f9661b410cb9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -819,11 +819,10 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0)
break;
if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "Timeout of video streamclk ok\n");
+   dev_err(dp->dev, "Timeout of slave video streamclk 
ok\n");
return -ETIMEDOUT;
}
-
-   usleep_range(1, 2);
+   usleep_range(1000, 1001);
}
 
/* Set to use the register calculated M/N video */
@@ -838,6 +837,9 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
/* Configure video slave mode */
analogix_dp_enable_video_master(dp, 0);
 
+   /* Enable video */
+   analogix_dp_start_video(dp);
+
timeout_loop = 0;
 
for (;;) {
@@ -948,9 +950,6 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
DRM_ERROR("failed to enable the panel\n");
}
 
-   /* Enable video */
-   analogix_dp_start_video(dp);
-
dp->psr_enable = analogix_dp_detect_sink_psr(dp);
if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 9/9] drm/xen-front: Implement communication with backend

2018-03-06 Thread Oleksandr Andrushchenko

On 03/05/2018 11:25 AM, Daniel Vetter wrote:

On Wed, Feb 21, 2018 at 10:03:42AM +0200, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Handle communication with the backend:
  - send requests and wait for the responses according
to the displif protocol
  - serialize access to the communication channel
  - time-out used for backend communication is set to 3000 ms
  - manage display buffers shared with the backend

Signed-off-by: Oleksandr Andrushchenko 

After the demidlayering it probably makes sense to merge this with the
overall kms/basic-drm-driver patch. Up to you really.

The reason for such partitioning here and before was that
I can have Xen/DRM parts separate, so those are easier for
review by Xen/DRM communities. So, I would prefer to have it
as it is

-Daniel

---
  drivers/gpu/drm/xen/xen_drm_front.c | 327 +++-
  drivers/gpu/drm/xen/xen_drm_front.h |   5 +
  2 files changed, 327 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front.c 
b/drivers/gpu/drm/xen/xen_drm_front.c
index 8de88e359d5e..5ad546231d30 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -31,12 +31,146 @@
  #include "xen_drm_front_evtchnl.h"
  #include "xen_drm_front_shbuf.h"
  
+/* timeout in ms to wait for backend to respond */

+#define VDRM_WAIT_BACK_MS  3000
+
+struct xen_drm_front_dbuf {
+   struct list_head list;
+   uint64_t dbuf_cookie;
+   uint64_t fb_cookie;
+   struct xen_drm_front_shbuf *shbuf;
+};
+
+static int dbuf_add_to_list(struct xen_drm_front_info *front_info,
+   struct xen_drm_front_shbuf *shbuf, uint64_t dbuf_cookie)
+{
+   struct xen_drm_front_dbuf *dbuf;
+
+   dbuf = kzalloc(sizeof(*dbuf), GFP_KERNEL);
+   if (!dbuf)
+   return -ENOMEM;
+
+   dbuf->dbuf_cookie = dbuf_cookie;
+   dbuf->shbuf = shbuf;
+   list_add(&dbuf->list, &front_info->dbuf_list);
+   return 0;
+}
+
+static struct xen_drm_front_dbuf *dbuf_get(struct list_head *dbuf_list,
+   uint64_t dbuf_cookie)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list)
+   if (buf->dbuf_cookie == dbuf_cookie)
+   return buf;
+
+   return NULL;
+}
+
+static void dbuf_flush_fb(struct list_head *dbuf_list, uint64_t fb_cookie)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list)
+   if (buf->fb_cookie == fb_cookie)
+   xen_drm_front_shbuf_flush(buf->shbuf);
+}
+
+static void dbuf_free(struct list_head *dbuf_list, uint64_t dbuf_cookie)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list)
+   if (buf->dbuf_cookie == dbuf_cookie) {
+   list_del(&buf->list);
+   xen_drm_front_shbuf_unmap(buf->shbuf);
+   xen_drm_front_shbuf_free(buf->shbuf);
+   kfree(buf);
+   break;
+   }
+}
+
+static void dbuf_free_all(struct list_head *dbuf_list)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list) {
+   list_del(&buf->list);
+   xen_drm_front_shbuf_unmap(buf->shbuf);
+   xen_drm_front_shbuf_free(buf->shbuf);
+   kfree(buf);
+   }
+}
+
+static struct xendispl_req *be_prepare_req(
+   struct xen_drm_front_evtchnl *evtchnl, uint8_t operation)
+{
+   struct xendispl_req *req;
+
+   req = RING_GET_REQUEST(&evtchnl->u.req.ring,
+   evtchnl->u.req.ring.req_prod_pvt);
+   req->operation = operation;
+   req->id = evtchnl->evt_next_id++;
+   evtchnl->evt_id = req->id;
+   return req;
+}
+
+static int be_stream_do_io(struct xen_drm_front_evtchnl *evtchnl,
+   struct xendispl_req *req)
+{
+   reinit_completion(&evtchnl->u.req.completion);
+   if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED))
+   return -EIO;
+
+   xen_drm_front_evtchnl_flush(evtchnl);
+   return 0;
+}
+
+static int be_stream_wait_io(struct xen_drm_front_evtchnl *evtchnl)
+{
+   if (wait_for_completion_timeout(&evtchnl->u.req.completion,
+   msecs_to_jiffies(VDRM_WAIT_BACK_MS)) <= 0)
+   return -ETIMEDOUT;
+
+   return evtchnl->u.req.resp_status;
+}
+
  static int be_mode_set(struct xen_drm_front_drm_pipeline *pipeline, uint32_t 
x,
uint32_t y, uint32_t width, uint32_t height, uint32_t bpp,
uint64_t fb_cookie)
  
  {

-   return 0;
+   struct xen_drm_front_evtchnl *evtchnl;
+   struct xen_drm_front_info *front_info;
+   struct xendispl_req *req;
+   unsigned long flags;
+   int ret;
+
+   front_info = pipeline->drm_info->front_info;
+   evtchnl = &front_info->evt_pa

[PATCH v4 20/38] drm/bridge: analogix_dp: Reset aux channel if an error occurred

2018-03-06 Thread Enric Balletbo i Serra
From: Lin Huang 

AUX errors are caused by many different reasons. We may not know what
happened in aux channel on failure, so let's reset aux channel if some
errors occurred.

Cc: 征增 王 
Cc: Douglas Anderson 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index dee1ba109b5f..7b7fd227e1f9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -466,6 +466,10 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
reg = RPLY_RECEIV | AUX_ERR;
writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
 
+   analogix_dp_set_analog_power_down(dp, AUX_BLOCK, true);
+   usleep_range(10, 11);
+   analogix_dp_set_analog_power_down(dp, AUX_BLOCK, false);
+
analogix_dp_reset_aux(dp);
 
/* Disable AUX transaction H/W retry */
@@ -1159,7 +1163,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 reg, !(reg & AUX_EN), 25, 500 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH enable timeout!\n");
-   return -ETIMEDOUT;
+   goto aux_error;
}
 
/* TODO: Wait for an interrupt instead of looping? */
@@ -1168,7 +1172,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 reg, reg & RPLY_RECEIV, 10, 20 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
-   return -ETIMEDOUT;
+   goto aux_error;
}
 
/* Clear interrupt source for AUX CH command reply */
@@ -1178,7 +1182,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
if (reg & AUX_ERR) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
-   return -EREMOTEIO;
+   goto aux_error;
}
 
/* Check AUX CH error access status */
@@ -1186,7 +1190,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
if ((reg & AUX_STATUS_MASK)) {
dev_err(dp->dev, "AUX CH error happened: %d\n\n",
reg & AUX_STATUS_MASK);
-   return -EREMOTEIO;
+   goto aux_error;
}
 
if (msg->request & DP_AUX_I2C_READ) {
@@ -1212,4 +1216,10 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
 
return num_transferred > 0 ? num_transferred : -EBUSY;
+
+aux_error:
+   /* if aux err happen, reset aux */
+   analogix_dp_init_aux(dp);
+
+   return -EREMOTEIO;
 }
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 23/38] drm/bridge: analogix_dp: Fix timeout of video streamclk config

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

The STRM_VALID bit in register ANALOGIX_DP_SYS_CTL_3 may be unstable,
so we may hit the error log "Timeout of video streamclk ok" since
checked this unstable bit.
In fact, we can go continue and the streamclk is ok if we wait enough time,
it does no effect on display.
Let's change this error to warn.

Cc: Douglas Anderson 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c93a0d125b87..2493a580e655 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -921,8 +921,9 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
done_count = 0;
}
if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "Timeout of video streamclk ok\n");
-   return -ETIMEDOUT;
+   dev_warn(dp->dev,
+"Ignoring timeout of video streamclk ok\n");
+   break;
}
 
usleep_range(1000, 1001);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Overlay sugar syntax (was: Re: [PATCH v6 3/4] drm: rcar-du: Fix legacy DT to create LVDS encoder nodes)

2018-03-06 Thread David Gibson
On Fri, Feb 23, 2018 at 09:05:24AM +0100, Geert Uytterhoeven wrote:
> Hi Frank,
> 
> On Fri, Feb 23, 2018 at 3:38 AM, Frank Rowand  wrote:
> > I was hoping to be able to convert the .dts files to use sugar syntax
> > instead of hand coding the fragment nodes, but for this specific set
> > of files I failed, since the labels that would have been required do
> > not already exist in the base .dts files that that overlays would be
> > applied against.
> 
> Indeed, hence the fixup overlays use "target-path".
> 
> BTW, is there any specific reason there is no sugar syntax support in dtc
> for absolute target paths? I guess to prevent adding stuff to a random
> existing node, and to encourage people to use a "connector" API defined in
> term of labels?

Only because it hasn't been implemented.  Using &{/whatever} should
IMO generate a target-path and the fact it doesn't is a bug.

> I'm also in the process of converting my collection of DT overlays to sugar
> syntax, and lack of support for "target-path" is the sole thing that holds
> me back from completing this. So for now I use a mix of sugar and
> traditional overlay syntax.
> 
> In particular, I need "target-path" for two things:
>   1. To refer to the root node, for adding devices that should live at
>  (a board subnode of) the root node, like:
>- devices connected to GPIO controllers provided by other base or
>  overlay devices (e.g. LEDs, displays, buttons, ...),
>- clock providers for other overlays devices (e.g. fixed-clock).
>   2. To refer to the aliases node, for adding mandatory serialX aliases.
> 
> The former is the real blocker for me.
> 
> The latter doesn't work with plain upstream (hacky patches available), so
> I'm working on getting rid of the serialX requirement in the serial driver.

Below is draft patch adding target-path support.  The pretty minimal
test examples do include a case using &{/}

From 8f1b35f88395adea01ce1100c5faa27dacbc8410 Mon Sep 17 00:00:00 2001
From: David Gibson 
Date: Tue, 6 Mar 2018 13:27:53 +1100
Subject: [PATCH] Correct overlay syntactic sugar for generating target-path
 fragments

We've recently added "syntactic sugar" support to generate runtime dtb
overlays using similar syntax to the compile time overlays we've had for
a while.  This worked with the &label { ... } syntax, adjusting an existing
labelled node, but would fail with the &{/path} { ... } syntax attempting
to adjust an existing node referenced by its path.

The previous code would always try to use the "target" property in the
output overlay, which needs to be fixed up, and __fixups__ can only encode
symbols, not paths, so the result could never work properly.

This adds support for the &{/path} syntax for overlays, translating it into
the "target-path" encoding in the output.  It also changes existing
behaviour a little because we now unconditionally one fragment for each
overlay section in the source.  Previously we would only create a fragment
if we couldn't locally resolve the node referenced.  We need this for
path references, because the path is supposed to be referencing something
in the (not yet known) base tree, rather than the overlay tree we are
working with now.  In particular one useful case for path based overlays
is using &{/} - but the constructed overlay tree will always have a root
node, meaning that without the change that would attempt to resolve the
fragment locally, which is not what we want.

Signed-off-by: David Gibson 
---
 dtc-parser.y | 22 +-
 livetree.c   | 12 +++---
 tests/overlay_overlay_bypath.dts | 48 
 tests/run_tests.sh   | 12 ++
 4 files changed, 80 insertions(+), 14 deletions(-)
 create mode 100644 tests/overlay_overlay_bypath.dts

diff --git a/dtc-parser.y b/dtc-parser.y
index 44af170..25e92d6 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -190,18 +190,18 @@ devicetree:
}
| devicetree DT_REF nodedef
{
-   struct node *target = get_node_by_ref($1, $2);
-
-   if (target) {
-   merge_nodes(target, $3);
+   /*
+* We rely on the rule being always:
+*   versioninfo plugindecl memreserves devicetree
+* so $-1 is what we want (plugindecl)
+*/
+   if ($-1 & DTSF_PLUGIN) {
+   add_orphan_node($1, $3, $2);
} else {
-   /*
-* We rely on the rule being always:
-*   versioninfo plugindecl memreserves 
devicetree
-* so $-1 is what we want (plugindecl)
-*/
-   if ($-1 & DTSF_PLUGIN)
- 

[PATCH v4 26/38] drm/bridge: analogix_dp: Reorder plat_data->power_off to happen sooner

2018-03-06 Thread Enric Balletbo i Serra
From: Douglas Anderson 

The current user of the analogix power_off is "analogix_dp-rockchip".
That driver does this:
- deactivate PSR
- turn off a clock

Both of these things (especially deactive PSR) should be done before
we turn the PHY power off and turn off analog power.  Let's move the
callback up.

Note that without this patch (and with
https://patchwork.kernel.org/patch/9553349/ [seanpaul: this patch was
not applied, but it seems like the race can still occur]), I experienced
an error in reboot testing where one thread was at:

  rockchip_drm_psr_deactivate
  rockchip_dp_powerdown
  analogix_dp_bridge_disable
  drm_bridge_disable

...and the other thread was at:

  analogix_dp_send_psr_spd
  analogix_dp_enable_psr
  analogix_dp_psr_set
  psr_flush_handler

The flush handler thread was finding AUX channel errors and eventually
reported "Failed to apply PSR", where I had a kgdb breakpoint. Presumably
the device would have eventually given up and shut down anyway, but it
seems better to fix the order to be more correct.

Cc: Kristian H. Kristensen 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e0f96ad4c700..edaca650e6d2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1337,12 +1337,13 @@ static void analogix_dp_bridge_disable(struct 
drm_bridge *bridge)
}
 
disable_irq(dp->irq);
-   phy_power_off(dp->phy);
-   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
 
if (dp->plat_data->power_off)
dp->plat_data->power_off(dp->plat_data);
 
+   phy_power_off(dp->phy);
+   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
+
clk_disable_unprepare(dp->clock);
 
pm_runtime_put_sync(dp->dev);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 22/38] drm/bridge: analogix_dp: Don't use ANALOGIX_DP_PLL_CTL to control pll

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

There is no register named ANALOGIX_DP_PLL_CTL in Rockchip edp phy reg
list.  We should use BIT_4 in ANALOGIX_DP_PD to control the pll power
instead of ANALOGIX_DP_PLL_CTL.

Cc: Douglas Anderson 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 7b7fd227e1f9..02ab1aaa9993 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -230,16 +230,20 @@ enum pll_status analogix_dp_get_pll_lock_status(struct 
analogix_dp_device *dp)
 void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
 {
u32 reg;
+   u32 mask = DP_PLL_PD;
+   u32 pd_addr = ANALOGIX_DP_PLL_CTL;
 
-   if (enable) {
-   reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   reg |= DP_PLL_PD;
-   writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   } else {
-   reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   reg &= ~DP_PLL_PD;
-   writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+   pd_addr = ANALOGIX_DP_PD;
+   mask = RK_PLL_PD;
}
+
+   reg = readl(dp->reg_base + pd_addr);
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + pd_addr);
 }
 
 void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/bridge/synopsys: dw-hdmi: Fix memleak in __dw_hdmi_remove

2018-03-06 Thread Russell King - ARM Linux
On Mon, Mar 05, 2018 at 03:45:55PM +0800, Jeffy Chen wrote:
> The platform_device_register_full() will allocate dma_mask for
> hdmi->audio, so we should free before platform_device_unregister().
> 
> Reported by kmemleak:
> unreferenced object 0xffc0ef70ff00 (size 128):
>   comm "kworker/4:1", pid 123, jiffies 4294670080 (age 189.604s)
>   hex dump (first 32 bytes):
> ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00  
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
>   backtrace:
> [<21946f44>] kmemleak_alloc+0x58/0x8c
> [<9c43890d>] kmem_cache_alloc_memcg_trace+0x18c/0x25c
> [<0e17cd06>] platform_device_register_full+0x64/0x108
> [<418a0882>] __dw_hdmi_probe+0xb9c/0xcc0
> [] dw_hdmi_bind+0x30/0x88
> [<9af347f6>] dw_hdmi_rockchip_bind+0x260/0x2e8
> 
> Signed-off-by: Jeffy Chen 
> ---
> 
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index f9802399cc0d..d9afdc59d4f4 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2567,8 +2567,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  
>  static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
> - if (hdmi->audio && !IS_ERR(hdmi->audio))
> + if (hdmi->audio && !IS_ERR(hdmi->audio)) {
> + kfree(hdmi->audio->dev.dma_mask);
>   platform_device_unregister(hdmi->audio);
> + }
>   if (!IS_ERR(hdmi->cec))
>   platform_device_unregister(hdmi->cec);

NAK.  This is a hack, plain and simple.

The audio device is created by platform_device_register_full(), and
the lifetime of that is managed by the driver model.  When it's time
to clean that up, it's handled by the platform support code in
drivers/base/platform.c.  It is not the driver's responsibility to
clean this up.

There's two issues here:
- Since you're kfree()ing it _before_ unregistering the device, the
  memory you're freeing may still be accessed by the DMA API on
  behalf of the device driver, so you're introducing a use-after-free
  bug.
- kfree()ing it _after_ unregistering the device means that you're then
  potentially accessing memory that has been kfree()'d (the underlying
  struct device) unless you save a pointer to it before unregistering
  and kfree() it after.

However, see the comment in platform_device_register_full() - if this
gets fixed at the core platform level (since every driver using
platform_device_register_full() with a DMA mask will suffer this
same problem, that's the place to fix it) adding a workaround at driver
level will introduce a non-obvious double-free bug.

I suspect the best solution to this is to arrange for struct
platform_device to also contain a DMA mask which
platform_device_register_full() can use, which means the DMA mask will
be freed automatically along with the rest of the platform device,
rather than separately allocating this.  There may be some resistance
to adding 64 bits to platform devices, but if we have lots of these
separately kmalloc'd DMA masks, we're actually wasting a lot more memory
not doing this (since kmalloc has a minimum size of the L1 cacheline
size.)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 00/38] DRM Rockchip rk3399 (Kevin)

2018-03-06 Thread Enric Balletbo i Serra
Hi,

This patchset includes cleanups, improvements, and bug fixes for
Rockchip DRM driver and PSR support.

This new version is the same as before but rebased on top of
drm-misc-next plus the Marek patches that fixes Chromebook2 Peach-Pit [1]
and the latest series of Rockchip rk3399 eDP support [2].

[1] https://www.spinics.net/lists/dri-devel/msg167804.html
[2] https://www.spinics.net/lists/dri-devel/msg167770.html

Regards,
 Enric

Changes in v4:
- Rebased all on top of drm-misc-next
- Removed the following patches as are already applied.
  [PATCH v3 01/43] drm/rockchip: Get rid of unnecessary struct fields
  [PATCH v3 02/43] drm/rockchip: support prime import sg table
  [PATCH v3 03/43] drm/rockchip: Respect page offset for PRIME mmap
  calls
- Removed the following patches as now are part of another patchset
  [PATCH v3 05/43] drm/bridge: analogix_dp: Don't power bridge in
  analogix_dp_bind
  [PATCH v3 33/43] drm/panel: simple: Change mode for Sharp lq123p1jx31

Changes in v3:
- Addressed some of the comments from Sean on the v2

Changes in v2:
- A few patches have been replaced by newer and cleaner versions from
  the ChromeOS kernel gerrit, especially about disallowing PSR for the
  whole atomic commit.


Douglas Anderson (4):
  drm/bridge: analogix_dp: Reorder plat_data->power_off to happen sooner
  drm/bridge: analogix_dp: Properly log AUX CH errors
  drm/bridge: analogix_dp: Properly disable aux chan retries on rockchip
  drm/bridge: analogix_dp: Split the platform-specific poweron in two
parts

Kristian H. Kristensen (1):
  drm/rockchip: Disable PSR on input events

Lin Huang (6):
  drm/bridge: analogix_dp: Move enable video into config_video()
  drm/bridge: analogix_dp: Check AUX_EN status when doing AUX transfer
  drm/bridge: analogix_dp: Ensure edp is disabled when shutting down the
panel
  drm/bridge: analogix_dp: Extend hpd check time to 100ms
  drm/bridge: analogix_dp: Check dpcd write/read status
  drm/bridge: analogix_dp: Reset aux channel if an error occurred

Mark Yao (1):
  drm/rockchip: pre dither down when output bpc is 8bit

Sean Paul (2):
  drm/rockchip: Don't use atomic constructs for psr
  drm/rockchip: Remove analogix psr worker

Tomasz Figa (7):
  drm/rockchip: analogix_dp: Do not call Analogix code before bind
  drm/rockchip: Cancel PSR enable work before changing the state
  drm/rockchip: psr: Avoid redundant calls to .set() callback
  drm/rockchip: psr: Sanitize semantics of allow/disallow API
  drm/rockchip: Disable PSR from reboot notifier
  drm/rockchip: Disallow PSR for the whole atomic commit
  drm/rockchip: psr: Remove flush by CRTC

Yakir Yang (1):
  drm/bridge: analogix_dp: detect Sink PSR state after configuring the
PSR

zain wang (16):
  drm/bridge: analogix_dp: set psr activate/deactivate when
enable/disable bridge
  drm/bridge: analogix_dp: Don't change psr while bridge is disabled
  drm/rockchip: add mutex vop lock
  drm/bridge: analogix_dp: add fast link train for eDP
  drm/rockchip: Only wait for panel ACK on PSR entry
  drm/bridge: analogix_dp: Don't use fast link training when panel just
powered up
  drm/bridge: analogix_dp: Retry bridge enable when it failed
  drm/bridge: analogix_dp: Wait for HPD signal before configuring link
  drm/bridge: analogix_dp: Set PD_INC_BG first when powering up edp phy
  drm/bridge: analogix_dp: Fix incorrect usage of enhanced mode
  drm/bridge: analogix_dp: Fix AUX_PD bit for Rockchip
  drm/rockchip: Restore psr->state when enable/disable psr failed
  drm/bridge: analogix_dp: Don't use ANALOGIX_DP_PLL_CTL to control pll
  drm/bridge: analogix_dp: Fix timeout of video streamclk config
  drm/bridge: analogix_dp: Fix incorrect operations with register
ANALOGIX_DP_FUNC_EN_1
  drm/bridge: analogix_dp: Move fast link training detect to set_bridge

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 452 -
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  14 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 274 -
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h  |   7 +
 drivers/gpu/drm/exynos/exynos_dp.c |   2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  73 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c|   2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h|   3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  61 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 361 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h|   7 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  47 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h|   1 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c|   1 +
 include/drm/bridge/analogix_dp.h   |   5 +-
 15 files changed, 915 insertions(+), 395 deletions(-)

-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-d

[PATCH v4 00/38] DRM Rockchip rk3399 (Kevin)

2018-03-06 Thread Enric Balletbo i Serra
Hi,

This patchset includes cleanups, improvements, and bug fixes for
Rockchip DRM driver and PSR support.

This new version is the same as before but rebased on top of
drm-misc-next plus the Marek patches that fixes Chromebook2 Peach-Pit [1]
and the latest series of Rockchip rk3399 eDP support [2].

[1] https://www.spinics.net/lists/dri-devel/msg167804.html
[2] https://www.spinics.net/lists/dri-devel/msg167770.html

Regards,
 Enric

Changes in v4:
- Rebased all on top of drm-misc-next
- Removed the following patches as are already applied.
  [PATCH v3 01/43] drm/rockchip: Get rid of unnecessary struct fields
  [PATCH v3 02/43] drm/rockchip: support prime import sg table
  [PATCH v3 03/43] drm/rockchip: Respect page offset for PRIME mmap
  calls
- Removed the following patches as now are part of another patchset
  [PATCH v3 05/43] drm/bridge: analogix_dp: Don't power bridge in
  analogix_dp_bind
  [PATCH v3 33/43] drm/panel: simple: Change mode for Sharp lq123p1jx31

Changes in v3:
- Addressed some of the comments from Sean on the v2

Changes in v2:
- A few patches have been replaced by newer and cleaner versions from
  the ChromeOS kernel gerrit, especially about disallowing PSR for the
  whole atomic commit.


Douglas Anderson (4):
  drm/bridge: analogix_dp: Reorder plat_data->power_off to happen sooner
  drm/bridge: analogix_dp: Properly log AUX CH errors
  drm/bridge: analogix_dp: Properly disable aux chan retries on rockchip
  drm/bridge: analogix_dp: Split the platform-specific poweron in two
parts

Kristian H. Kristensen (1):
  drm/rockchip: Disable PSR on input events

Lin Huang (6):
  drm/bridge: analogix_dp: Move enable video into config_video()
  drm/bridge: analogix_dp: Check AUX_EN status when doing AUX transfer
  drm/bridge: analogix_dp: Ensure edp is disabled when shutting down the
panel
  drm/bridge: analogix_dp: Extend hpd check time to 100ms
  drm/bridge: analogix_dp: Check dpcd write/read status
  drm/bridge: analogix_dp: Reset aux channel if an error occurred

Mark Yao (1):
  drm/rockchip: pre dither down when output bpc is 8bit

Sean Paul (2):
  drm/rockchip: Don't use atomic constructs for psr
  drm/rockchip: Remove analogix psr worker

Tomasz Figa (7):
  drm/rockchip: analogix_dp: Do not call Analogix code before bind
  drm/rockchip: Cancel PSR enable work before changing the state
  drm/rockchip: psr: Avoid redundant calls to .set() callback
  drm/rockchip: psr: Sanitize semantics of allow/disallow API
  drm/rockchip: Disable PSR from reboot notifier
  drm/rockchip: Disallow PSR for the whole atomic commit
  drm/rockchip: psr: Remove flush by CRTC

Yakir Yang (1):
  drm/bridge: analogix_dp: detect Sink PSR state after configuring the
PSR

zain wang (16):
  drm/bridge: analogix_dp: set psr activate/deactivate when
enable/disable bridge
  drm/bridge: analogix_dp: Don't change psr while bridge is disabled
  drm/rockchip: add mutex vop lock
  drm/bridge: analogix_dp: add fast link train for eDP
  drm/rockchip: Only wait for panel ACK on PSR entry
  drm/bridge: analogix_dp: Don't use fast link training when panel just
powered up
  drm/bridge: analogix_dp: Retry bridge enable when it failed
  drm/bridge: analogix_dp: Wait for HPD signal before configuring link
  drm/bridge: analogix_dp: Set PD_INC_BG first when powering up edp phy
  drm/bridge: analogix_dp: Fix incorrect usage of enhanced mode
  drm/bridge: analogix_dp: Fix AUX_PD bit for Rockchip
  drm/rockchip: Restore psr->state when enable/disable psr failed
  drm/bridge: analogix_dp: Don't use ANALOGIX_DP_PLL_CTL to control pll
  drm/bridge: analogix_dp: Fix timeout of video streamclk config
  drm/bridge: analogix_dp: Fix incorrect operations with register
ANALOGIX_DP_FUNC_EN_1
  drm/bridge: analogix_dp: Move fast link training detect to set_bridge

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 452 -
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  14 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 274 -
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h  |   7 +
 drivers/gpu/drm/exynos/exynos_dp.c |   2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  73 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c|   2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h|   3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  61 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 361 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h|   7 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  47 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h|   1 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c|   1 +
 include/drm/bridge/analogix_dp.h   |   5 +-
 15 files changed, 915 insertions(+), 395 deletions(-)

-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-d

[PATCH v4 11/38] drm/bridge: analogix_dp: Don't use fast link training when panel just powered up

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

Panel would reset its setting when it powers down. It would forget the last
succeeded link training setting. So we can't use the last successful link
training setting to do fast link training. Let's reset fast_train_enable in
analogix_dp_bridge_disable();

Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index f9661b410cb9..ea7a80a989c6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -579,14 +579,14 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
if (retval != 1) {
dev_err(dp->dev, "failed to read downspread %d\n",
retval);
-   dp->fast_train_support = false;
+   dp->fast_train_enable = false;
} else {
-   dp->fast_train_support =
+   dp->fast_train_enable =
(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
true : false;
}
dev_dbg(dp->dev, "fast link training %s\n",
-   dp->fast_train_support ? "supported" : "unsupported");
+   dp->fast_train_enable ? "supported" : "unsupported");
 
/* set enhanced mode if available */
analogix_dp_set_enhanced_mode(dp);
@@ -793,7 +793,7 @@ static int analogix_dp_fast_link_train(struct 
analogix_dp_device *dp)
 
 static int analogix_dp_train_link(struct analogix_dp_device *dp)
 {
-   if (dp->fast_train_support)
+   if (dp->fast_train_enable)
return analogix_dp_fast_link_train(dp);
 
return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count,
@@ -1197,6 +1197,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
 
dp->psr_enable = false;
+   dp->fast_train_enable = false;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 6a96ef7e6934..403ff853464b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -173,7 +173,7 @@ struct analogix_dp_device {
int hpd_gpio;
boolforce_hpd;
boolpsr_enable;
-   boolfast_train_support;
+   boolfast_train_enable;
 
struct mutexpanel_lock;
boolpanel_is_modeset;
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 16/38] drm/bridge: analogix_dp: Extend hpd check time to 100ms

2018-03-06 Thread Enric Balletbo i Serra
From: Lin Huang 

There was a 1ms delay to detect the hpd signal, which is too short to
detect a short pulse. This patch extends this delay to 100ms.

Cc: Stéphane Marchesin 
Cc: 征增 王 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 9b7d530ad24c..0ff151f741a3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -76,7 +76,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 
timeout_loop++;
-   usleep_range(10, 11);
+   usleep_range(1000, 1100);
}
 
/*
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [linux-sunxi] [PATCH v3 15/16] ARM: dts: sun8i: h3: Enable HDMI output on H3 boards

2018-03-06 Thread Joonas Kylmälä
Jernej Skrabec:
> +&hdmi_out {
> + hdmi_out_con: endpoint {
> + remote-endpoint = <&hdmi_con_in>;
> + };
> +};

This node is added to all the DTS files you enabled HDMI on. Is it
something that could be instead put to the DTSI file?

Joonas
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 02/38] drm/rockchip: Don't use atomic constructs for psr

2018-03-06 Thread Enric Balletbo i Serra
From: Sean Paul 

Instead of using timer and spinlocks, use delayed_work and
mutexes for rockchip psr. This allows us to make blocking
calls when enabling/disabling psr (which is sort of important
given we're talking over dpcd to the display).

Cc: Caesar Wang 
Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 68 -
 3 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 1920334dbdaa..f814d37b1db2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -134,7 +134,7 @@ static int rockchip_drm_bind(struct device *dev)
drm_dev->dev_private = private;
 
INIT_LIST_HEAD(&private->psr_list);
-   spin_lock_init(&private->psr_list_lock);
+   mutex_init(&private->psr_list_lock);
 
ret = rockchip_drm_init_iommu(drm_dev);
if (ret)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 498dfbc52cec..9c064a40458b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -55,7 +55,7 @@ struct rockchip_drm_private {
struct mutex mm_lock;
struct drm_mm mm;
struct list_head psr_list;
-   spinlock_t psr_list_lock;
+   struct mutex psr_list_lock;
 };
 
 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index b3fb99c5b1fd..b339ca943139 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -18,7 +18,7 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_psr.h"
 
-#define PSR_FLUSH_TIMEOUT  msecs_to_jiffies(100)
+#define PSR_FLUSH_TIMEOUT_MS   100
 
 enum psr_state {
PSR_FLUSH,
@@ -30,11 +30,11 @@ struct psr_drv {
struct list_headlist;
struct drm_encoder  *encoder;
 
-   spinlock_t  lock;
+   struct mutexlock;
boolactive;
enum psr_state  state;
 
-   struct timer_list   flush_timer;
+   struct delayed_work flush_work;
 
void (*set)(struct drm_encoder *encoder, bool enable);
 };
@@ -43,9 +43,8 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
 {
struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;
struct psr_drv *psr;
-   unsigned long flags;
 
-   spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
+   mutex_lock(&drm_drv->psr_list_lock);
list_for_each_entry(psr, &drm_drv->psr_list, list) {
if (psr->encoder->crtc == crtc)
goto out;
@@ -53,7 +52,7 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
psr = ERR_PTR(-ENODEV);
 
 out:
-   spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
+   mutex_unlock(&drm_drv->psr_list_lock);
return psr;
 }
 
@@ -61,9 +60,8 @@ static struct psr_drv *find_psr_by_encoder(struct drm_encoder 
*encoder)
 {
struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
struct psr_drv *psr;
-   unsigned long flags;
 
-   spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
+   mutex_lock(&drm_drv->psr_list_lock);
list_for_each_entry(psr, &drm_drv->psr_list, list) {
if (psr->encoder == encoder)
goto out;
@@ -71,7 +69,7 @@ static struct psr_drv *find_psr_by_encoder(struct drm_encoder 
*encoder)
psr = ERR_PTR(-ENODEV);
 
 out:
-   spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
+   mutex_unlock(&drm_drv->psr_list_lock);
return psr;
 }
 
@@ -112,23 +110,21 @@ static void psr_set_state_locked(struct psr_drv *psr, 
enum psr_state state)
 
 static void psr_set_state(struct psr_drv *psr, enum psr_state state)
 {
-   unsigned long flags;
-
-   spin_lock_irqsave(&psr->lock, flags);
+   mutex_lock(&psr->lock);
psr_set_state_locked(psr, state);
-   spin_unlock_irqrestore(&psr->lock, flags);
+   mutex_unlock(&psr->lock);
 }
 
-static void psr_flush_handler(struct timer_list *t)
+static void psr_flush_handler(struct work_struct *work)
 {
-   struct psr_drv *psr = from_timer(psr, t, flush_timer);
-   unsigned long flags;
+   struct psr_drv *psr = container_of(to_delayed_work(work),
+  struct psr_drv, flush_work);
 
/* If the state has changed since we initiated the flush, do nothing */
-   spin_lock_irqsave(&psr->lock, flags);
+   mutex_lock(&psr->lock);
if (ps

[PATCH v4 03/38] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR

2018-03-06 Thread Enric Balletbo i Serra
From: Yakir Yang 

Make sure the request PSR state takes effect in analogix_dp_send_psr_spd()
function, or print the sink PSR error state if we failed to apply the
requested PSR setting.

Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Yakir Yang 
[seanpaul changed timeout loop to a readx poll]
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  6 ++--
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  6 ++--
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 35 +++---
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a693ab3078f0..e738aa6de1af 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -122,8 +122,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
 
-   analogix_dp_send_psr_spd(dp, &psr_vsc);
-   return 0;
+   return analogix_dp_send_psr_spd(dp, &psr_vsc);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
@@ -149,8 +148,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
if (ret != 1)
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
 
-   analogix_dp_send_psr_spd(dp, &psr_vsc);
-   return 0;
+   return analogix_dp_send_psr_spd(dp, &psr_vsc);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 5c6a28806129..b039b28d8fcc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -20,6 +20,8 @@
 #define MAX_CR_LOOP 5
 #define MAX_EQ_LOOP 5
 
+#define DP_TIMEOUT_PSR_LOOP_MS 300
+
 /* DP_MAX_LANE_COUNT */
 #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
 #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
@@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct 
analogix_dp_device *dp);
 void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
 void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
-void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
- struct edp_vsc_psr *vsc);
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc);
 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
 struct drm_dp_aux_msg *msg);
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 303083ad28e3..005a3f7005d2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -10,10 +10,11 @@
  * option) any later version.
  */
 
-#include 
-#include 
 #include 
+#include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -992,10 +993,25 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device 
*dp)
writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
 }
 
-void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
- struct edp_vsc_psr *vsc)
+static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
+{
+   ssize_t val;
+   u8 status;
+
+   val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
+   if (val < 0) {
+   dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
+   return val;
+   }
+   return status;
+}
+
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc)
 {
unsigned int val;
+   int ret;
+   ssize_t psr_status;
 
/* don't send info frame */
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1052,17 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
val |= IF_EN;
writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
+
+   ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
+   psr_status >= 0 &&
+   ((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
+   (!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
+   DP_TIMEOUT_PSR_LOOP_MS * 1000);
+   if (ret) {
+   dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
+   return ret;
+   }
+   return 0;
 }
 
 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
-- 
2.16.1

___
dri-devel mailing list
dri-devel@l

[PATCH v4 15/38] drm/bridge: analogix_dp: Ensure edp is disabled when shutting down the panel

2018-03-06 Thread Enric Balletbo i Serra
From: Lin Huang 

When panel is shut down, we should make sure edp can be disabled to avoid
undefined behavior.

Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 92fb9a072cb6..9b7d530ad24c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1160,6 +1160,12 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
 
pm_runtime_get_sync(dp->dev);
 
+   ret = clk_prepare_enable(dp->clock);
+   if (ret < 0) {
+   DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
+   goto out_dp_clk_pre;
+   }
+
if (dp->plat_data->power_on)
dp->plat_data->power_on(dp->plat_data);
 
@@ -1191,6 +1197,8 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
phy_power_off(dp->phy);
if (dp->plat_data->power_off)
dp->plat_data->power_off(dp->plat_data);
+   clk_disable_unprepare(dp->clock);
+out_dp_clk_pre:
pm_runtime_put_sync(dp->dev);
 
return ret;
@@ -1234,10 +1242,13 @@ static void analogix_dp_bridge_disable(struct 
drm_bridge *bridge)
 
disable_irq(dp->irq);
phy_power_off(dp->phy);
+   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
 
if (dp->plat_data->power_off)
dp->plat_data->power_off(dp->plat_data);
 
+   clk_disable_unprepare(dp->clock);
+
pm_runtime_put_sync(dp->dev);
 
ret = analogix_dp_prepare_panel(dp, false, true);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 12/38] drm/bridge: analogix_dp: Retry bridge enable when it failed

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

When we enable bridge failed, we have to retry it, otherwise we would get
the abnormal display.

Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 65 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  3 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  5 +-
 3 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ea7a80a989c6..c81733b8185e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -43,8 +43,10 @@ struct bridge_init {
struct device_node *node;
 };
 
-static void analogix_dp_init_dp(struct analogix_dp_device *dp)
+static int analogix_dp_init_dp(struct analogix_dp_device *dp)
 {
+   int ret;
+
analogix_dp_reset(dp);
 
analogix_dp_swreset(dp);
@@ -56,10 +58,13 @@ static void analogix_dp_init_dp(struct analogix_dp_device 
*dp)
analogix_dp_enable_sw_function(dp);
 
analogix_dp_config_interrupt(dp);
-   analogix_dp_init_analog_func(dp);
+   ret = analogix_dp_init_analog_func(dp);
+   if (ret)
+   return ret;
 
analogix_dp_init_hpd(dp);
analogix_dp_init_aux(dp);
+   return 0;
 }
 
 static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
@@ -918,7 +923,7 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
 }
 
-static void analogix_dp_commit(struct analogix_dp_device *dp)
+static int analogix_dp_commit(struct analogix_dp_device *dp)
 {
int ret;
 
@@ -928,11 +933,10 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
DRM_ERROR("failed to disable the panel\n");
}
 
-   ret = readx_poll_timeout(analogix_dp_train_link, dp, ret, !ret, 100,
-DP_TIMEOUT_TRAINING_US * 5);
+   ret = analogix_dp_train_link(dp);
if (ret) {
dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
-   return;
+   return ret;
}
 
analogix_dp_enable_scramble(dp, 1);
@@ -953,6 +957,7 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
dp->psr_enable = analogix_dp_detect_sink_psr(dp);
if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
+   return 0;
 }
 
 /*
@@ -1149,12 +1154,9 @@ static void analogix_dp_bridge_pre_enable(struct 
drm_bridge *bridge)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
 }
 
-static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
+static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
 {
-   struct analogix_dp_device *dp = bridge->driver_private;
-
-   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
-   return;
+   int ret;
 
pm_runtime_get_sync(dp->dev);
 
@@ -1162,11 +1164,46 @@ static void analogix_dp_bridge_enable(struct drm_bridge 
*bridge)
dp->plat_data->power_on(dp->plat_data);
 
phy_power_on(dp->phy);
-   analogix_dp_init_dp(dp);
+
+   ret = analogix_dp_init_dp(dp);
+   if (ret)
+   goto out_dp_init;
+
+   ret = analogix_dp_commit(dp);
+   if (ret)
+   goto out_dp_init;
+
enable_irq(dp->irq);
-   analogix_dp_commit(dp);
+   return 0;
 
-   dp->dpms_mode = DRM_MODE_DPMS_ON;
+out_dp_init:
+   phy_power_off(dp->phy);
+   if (dp->plat_data->power_off)
+   dp->plat_data->power_off(dp->plat_data);
+   pm_runtime_put_sync(dp->dev);
+
+   return ret;
+}
+
+static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
+{
+   struct analogix_dp_device *dp = bridge->driver_private;
+   int timeout_loop = 0;
+
+   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
+   return;
+
+   while (timeout_loop < MAX_PLL_LOCK_LOOP) {
+   if (analogix_dp_set_bridge(dp) == 0) {
+   dp->dpms_mode = DRM_MODE_DPMS_ON;
+   return;
+   }
+   dev_err(dp->dev, "failed to set bridge, retry: %d\n",
+   timeout_loop);
+   timeout_loop++;
+   usleep_range(10, 11);
+   }
+   dev_err(dp->dev, "too many times retry set bridge, give it up\n");
 }
 
 static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 403ff853464b..769255dc6e99 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -19,6 +19,7 @@
 #define DP_TIMEOUT_LOOP_COUNT 100
 #define MAX_CR_LOOP 

[PATCH v4 01/38] drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

There's a race between when bridge_disable and when vop_crtc_disable
are called. If the flush timer triggers a new psr work between these,
we will operate eDP without power shutdowned by bridge_disable. In this
case, moving activate/deactivate to enable/disable bridge to avoid it.

Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Caesar Wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  7 +-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 30 -
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h |  4 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  4 
 4 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index eb88c52336a7..7d76ff47028d 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -150,12 +150,17 @@ static int rockchip_dp_poweron(struct 
analogix_dp_plat_data *plat_data)
return ret;
}
 
-   return 0;
+   return rockchip_drm_psr_activate(&dp->encoder);
 }
 
 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
 {
struct rockchip_dp_device *dp = to_dp(plat_data);
+   int ret;
+
+   ret = rockchip_drm_psr_deactivate(&dp->encoder);
+   if (ret != 0)
+   return ret;
 
clk_disable_unprepare(dp->pclk);
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 3acfd576b7df..b3fb99c5b1fd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -57,6 +57,24 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc 
*crtc)
return psr;
 }
 
+static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder)
+{
+   struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
+   struct psr_drv *psr;
+   unsigned long flags;
+
+   spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
+   list_for_each_entry(psr, &drm_drv->psr_list, list) {
+   if (psr->encoder == encoder)
+   goto out;
+   }
+   psr = ERR_PTR(-ENODEV);
+
+out:
+   spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
+   return psr;
+}
+
 static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state)
 {
/*
@@ -115,14 +133,14 @@ static void psr_flush_handler(struct timer_list *t)
 
 /**
  * rockchip_drm_psr_activate - activate PSR on the given pipe
- * @crtc: CRTC to obtain the PSR encoder
+ * @encoder: encoder to obtain the PSR encoder
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_activate(struct drm_crtc *crtc)
+int rockchip_drm_psr_activate(struct drm_encoder *encoder)
 {
-   struct psr_drv *psr = find_psr_by_crtc(crtc);
+   struct psr_drv *psr = find_psr_by_encoder(encoder);
unsigned long flags;
 
if (IS_ERR(psr))
@@ -138,14 +156,14 @@ EXPORT_SYMBOL(rockchip_drm_psr_activate);
 
 /**
  * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe
- * @crtc: CRTC to obtain the PSR encoder
+ * @encoder: encoder to obtain the PSR encoder
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_deactivate(struct drm_crtc *crtc)
+int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
 {
-   struct psr_drv *psr = find_psr_by_crtc(crtc);
+   struct psr_drv *psr = find_psr_by_encoder(encoder);
unsigned long flags;
 
if (IS_ERR(psr))
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index b420cf1bf902..b1ea0155e57c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -18,8 +18,8 @@
 void rockchip_drm_psr_flush_all(struct drm_device *dev);
 int rockchip_drm_psr_flush(struct drm_crtc *crtc);
 
-int rockchip_drm_psr_activate(struct drm_crtc *crtc);
-int rockchip_drm_psr_deactivate(struct drm_crtc *crtc);
+int rockchip_drm_psr_activate(struct drm_encoder *encoder);
+int rockchip_drm_psr_deactivate(struct drm_encoder *encoder);
 
 int rockchip_drm_psr_register(struct drm_encoder *encoder,
void (*psr_set)(struct drm_encoder *, bool enable));
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9f72762532bf..63fbe789a5dd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -569,8 +569,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
 
WARN_ON(vop->event);
 
-   rockchip_drm_psr_deactivate(&vop->crtc);
-
drm_crtc_vblank_off(crtc);
 
/*
@@ -942,8 +940,6 @@ static void vop_crtc_atomic_en

[PATCH v4 25/38] drm/bridge: analogix_dp: Move fast link training detect to set_bridge

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

It's too early to detect fast link training, if other step after it
failed, we will set fast_link flag to 1, and retry set_bridge again. In
this case we will power down and power up panel power supply, and we
will do fast link training since we have set fast_link flag to 1. In
fact, we should do full link training now, not the fast link training.
So we should move the fast link detection at the end of set_bridge.

Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 42 +-
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 2493a580e655..e0f96ad4c700 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -601,7 +601,7 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
 {
int lane, lane_count, retval;
u32 reg;
-   u8 link_align, link_status[2], adjust_request[2], spread;
+   u8 link_align, link_status[2], adjust_request[2];
 
usleep_range(400, 401);
 
@@ -645,20 +645,6 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
 
-   retval = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD,
-  &spread);
-   if (retval != 1) {
-   dev_err(dp->dev, "failed to read downspread %d\n",
-   retval);
-   dp->fast_train_enable = false;
-   } else {
-   dp->fast_train_enable =
-   (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
-   true : false;
-   }
-   dev_dbg(dp->dev, "fast link training %s\n",
-   dp->fast_train_enable ? "supported" : "unsupported");
-
dp->link_train.lt_state = FINISHED;
 
return 0;
@@ -996,6 +982,22 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
 }
 
+static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *dp)
+{
+   int ret;
+   u8 spread;
+
+   ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &spread);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to read downspread %d\n", ret);
+   return ret;
+   }
+   dp->fast_train_enable = !!(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
+   dev_dbg(dp->dev, "fast link training %s\n",
+   dp->fast_train_enable ? "supported" : "unsupported");
+   return 0;
+}
+
 static int analogix_dp_commit(struct analogix_dp_device *dp)
 {
int ret;
@@ -1038,8 +1040,16 @@ static int analogix_dp_commit(struct analogix_dp_device 
*dp)
if (ret)
return ret;
 
-   if (dp->psr_enable)
+   if (dp->psr_enable) {
ret = analogix_dp_enable_sink_psr(dp);
+   if (ret)
+   return ret;
+   }
+
+   /* Check whether panel supports fast training */
+   ret =  analogix_dp_fast_link_train_detection(dp);
+   if (ret)
+   dp->psr_enable = false;
 
return ret;
 }
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 17/38] drm/bridge: analogix_dp: Fix incorrect usage of enhanced mode

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

Enhanced mode is required by the eDP 1.2 specification, and not doing it
early could result in a period of time where we have a link transmitting
idle packets without it. Since there is no reason to disable it, we just
enable it at the beginning of link training and then keep it on all the
time.

Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 0ff151f741a3..5489570ef010 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -281,6 +281,8 @@ static int analogix_dp_link_start(struct analogix_dp_device 
*dp)
retval = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, 2);
if (retval < 0)
return retval;
+   /* set enhanced mode if available */
+   analogix_dp_set_enhanced_mode(dp);
 
/* Set TX pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
@@ -593,8 +595,6 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
dev_dbg(dp->dev, "fast link training %s\n",
dp->fast_train_enable ? "supported" : "unsupported");
 
-   /* set enhanced mode if available */
-   analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;
 
return 0;
@@ -940,8 +940,6 @@ static int analogix_dp_commit(struct analogix_dp_device *dp)
}
 
analogix_dp_enable_scramble(dp, 1);
-   analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
-   analogix_dp_enable_enhanced_mode(dp, 1);
 
analogix_dp_init_video(dp);
ret = analogix_dp_config_video(dp);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 08/38] drm/rockchip: Only wait for panel ACK on PSR entry

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

We currently wait for the panel to mirror our intended PSR state
before continuing on both PSR enter and PSR exit. This is really
only important to do when we're entering PSR, since we want to
be sure the last frame we pushed is being served from the panel's
internal fb before shutting down the soc blocks (vop/analogix).

This patch changes the behavior such that we only wait for the
panel to complete the PSR transition when we're entering PSR, and
to skip verification when we're exiting.

Cc: Stéphane Marchesin 
Cc: Sonny Rao 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++--
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 5 -
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 806c3878b3d6..5a2e35dc41e3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -125,7 +125,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
 
-   return analogix_dp_send_psr_spd(dp, &psr_vsc);
+   return analogix_dp_send_psr_spd(dp, &psr_vsc, true);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
 
@@ -151,7 +151,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
if (ret != 1)
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
 
-   return analogix_dp_send_psr_spd(dp, &psr_vsc);
+   return analogix_dp_send_psr_spd(dp, &psr_vsc, false);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 920607d7eb3e..6a96ef7e6934 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -253,7 +253,7 @@ void analogix_dp_enable_scrambling(struct 
analogix_dp_device *dp);
 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
 void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
 int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
-struct edp_vsc_psr *vsc);
+struct edp_vsc_psr *vsc, bool blocking);
 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
 struct drm_dp_aux_msg *msg);
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 005a3f7005d2..9df2f3ef000c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1007,7 +1007,7 @@ static ssize_t analogix_dp_get_psr_status(struct 
analogix_dp_device *dp)
 }
 
 int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
-struct edp_vsc_psr *vsc)
+struct edp_vsc_psr *vsc, bool blocking)
 {
unsigned int val;
int ret;
@@ -1053,6 +1053,9 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
val |= IF_EN;
writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 
+   if (!blocking)
+   return 0;
+
ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
psr_status >= 0 &&
((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v5 1/6] dt-bindings: add bindings for USB physical connector

2018-03-06 Thread Heikki Krogerus
On Mon, Mar 05, 2018 at 09:18:10AM +0100, Andrzej Hajda wrote:
> On 02.03.2018 14:13, Heikki Krogerus wrote:
> > Hi,
> >
> > On Tue, Feb 27, 2018 at 08:11:29AM +0100, Andrzej Hajda wrote:
> >> +2. USB-C connector attached to CC controller (s2mm005), HS lines routed
> >> +to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort.
> >> +DisplayPort video lines are routed to the connector via SS mux in USB3 
> >> PHY.
> >> +
> >> +ccic: s2mm005@33 {
> >> +  ...
> >> +  usb_con: connector {
> >> +  compatible = "usb-c-connector";
> >> +  label = "USB-C";
> > Is this child node really necessary? There will never be more then
> > one connector per CC line.
> 
> But there can be more connectors/cc-lines per IC, for example EZ-PD CCG5[1].

OK, in that case the child node is of course needed.

> [1]:
> http://www.cypress.com/products/ez-pd-ccg5-two-port-usb-type-c-and-power-delivery
> 
> >
> > We should prefer device_graph* functions over of_graph* and
> I guess you mean fwnode_graph* functions.

Yes.

> > acpi_graph* functions in the drivers so we don't have to handle the
> > same thing multiple times with separate APIs. Is it still possible if
> > there is that connector child node?
> 
> Bindings proposed here are OF bindings, I suppose the most important is
> to follow OF specification and guidelines and these bindings tries to
> follow it.
> It looks like it should not be a problem for fwnode framework to handle
> such bindings, but it is just my guess. I have not seen any fwnode*
> specification I am not sure what is the real purpose of this framework,
> but it seems to be just in-kernel abstraction for different firmware
> standards (OF, ACPI), so even if it lacks at the moment some
> functionality it should not be a barrier for OF bindings.

Sure thing.


Thanks,

-- 
heikki
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 13/38] drm/bridge: analogix_dp: Wait for HPD signal before configuring link

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

According to DP spec v1.3 chap 3.5.1.2 Link Training, Link Policy Maker
must first detect that the HPD signal is asserted high by the Downstream
Device before establishing a link with it.

Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c81733b8185e..92fb9a072cb6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1169,6 +1169,17 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
if (ret)
goto out_dp_init;
 
+   /*
+* According to DP spec v1.3 chap 3.5.1.2 Link Training,
+* We should first make sure the HPD signal is asserted high by device
+* when we want to establish a link with it.
+*/
+   ret = analogix_dp_detect_hpd(dp);
+   if (ret) {
+   DRM_ERROR("failed to get hpd single ret = %d\n", ret);
+   goto out_dp_init;
+   }
+
ret = analogix_dp_commit(dp);
if (ret)
goto out_dp_init;
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 05/38] drm/bridge: analogix_dp: Don't change psr while bridge is disabled

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

There is a race between AUX CH bring-up and enabling bridge which will
cause link training to fail. To avoid hitting it, don't change psr state
while enabling the bridge.

Cc: Tomeu Vizoso 
Cc: Sean Paul 
Signed-off-by: zain wang 
Signed-off-by: Caesar Wang 
[seanpaul fixed up the commit message a bit and renamed *_supported to 
*_enabled]
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 15 ---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  2 +-
 include/drm/bridge/analogix_dp.h   |  2 +-
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e738aa6de1af..ee00d3d920e0 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,18 +98,18 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }
 
-int analogix_dp_psr_supported(struct analogix_dp_device *dp)
+int analogix_dp_psr_enabled(struct analogix_dp_device *dp)
 {
 
-   return dp->psr_support;
+   return dp->psr_enable;
 }
-EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
+EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled);
 
 int analogix_dp_enable_psr(struct analogix_dp_device *dp)
 {
struct edp_vsc_psr psr_vsc;
 
-   if (!dp->psr_support)
+   if (!dp->psr_enable)
return 0;
 
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
@@ -131,7 +131,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
struct edp_vsc_psr psr_vsc;
int ret;
 
-   if (!dp->psr_support)
+   if (!dp->psr_enable)
return 0;
 
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
@@ -871,8 +871,8 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
/* Enable video */
analogix_dp_start_video(dp);
 
-   dp->psr_support = analogix_dp_detect_sink_psr(dp);
-   if (dp->psr_support)
+   dp->psr_enable = analogix_dp_detect_sink_psr(dp);
+   if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
 }
 
@@ -1117,6 +1117,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
if (ret)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
 
+   dp->psr_enable = false;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index b039b28d8fcc..e135a42cb19e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -170,7 +170,7 @@ struct analogix_dp_device {
int dpms_mode;
int hpd_gpio;
boolforce_hpd;
-   boolpsr_support;
+   boolpsr_enable;
 
struct mutexpanel_lock;
boolpanel_is_modeset;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 36334839a3f8..3e8bf79bea58 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -82,7 +82,7 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, 
bool enabled)
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;
 
-   if (!analogix_dp_psr_supported(dp->adp))
+   if (!analogix_dp_psr_enabled(dp->adp))
return;
 
DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 711fff9b6803..e9a1116d2f8e 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -41,7 +41,7 @@ struct analogix_dp_plat_data {
 struct drm_connector *);
 };
 
-int analogix_dp_psr_supported(struct analogix_dp_device *dp);
+int analogix_dp_psr_enabled(struct analogix_dp_device *dp);
 int analogix_dp_enable_psr(struct analogix_dp_device *dp);
 int analogix_dp_disable_psr(struct analogix_dp_device *dp);
 
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 21/38] drm/rockchip: Restore psr->state when enable/disable psr failed

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

If we failed disable psr, it would hang the display until next psr
cycle coming. So we should restore psr->state when it failed.

Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 +++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 10 +-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 20 +---
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h|  2 +-
 4 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 2d49ee6fd2f3..c93a0d125b87 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -153,8 +153,10 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
psr_vsc.DB1 = 0;
 
ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
-   if (ret != 1)
+   if (ret != 1) {
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
+   return ret;
+   }
 
return analogix_dp_send_psr_spd(dp, &psr_vsc, false);
 }
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 3e8bf79bea58..8c884f9ce713 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -77,13 +77,13 @@ struct rockchip_dp_device {
struct analogix_dp_plat_data plat_data;
 };
 
-static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
+static int analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
 {
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;
 
if (!analogix_dp_psr_enabled(dp->adp))
-   return;
+   return 0;
 
DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
 
@@ -91,13 +91,13 @@ static void analogix_dp_psr_set(struct drm_encoder 
*encoder, bool enabled)
 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n");
-   return;
+   return -ETIMEDOUT;
}
 
if (enabled)
-   analogix_dp_enable_psr(dp->adp);
+   return analogix_dp_enable_psr(dp->adp);
else
-   analogix_dp_disable_psr(dp->adp);
+   return analogix_dp_disable_psr(dp->adp);
 }
 
 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index b339ca943139..9376f4396b6b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -36,7 +36,7 @@ struct psr_drv {
 
struct delayed_work flush_work;
 
-   void (*set)(struct drm_encoder *encoder, bool enable);
+   int (*set)(struct drm_encoder *encoder, bool enable);
 };
 
 static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
@@ -93,19 +93,25 @@ static void psr_set_state_locked(struct psr_drv *psr, enum 
psr_state state)
return;
}
 
-   psr->state = state;
-
/* Actually commit the state change to hardware */
-   switch (psr->state) {
+   switch (state) {
case PSR_ENABLE:
-   psr->set(psr->encoder, true);
+   if (psr->set(psr->encoder, true))
+   return;
break;
 
case PSR_DISABLE:
case PSR_FLUSH:
-   psr->set(psr->encoder, false);
+   if (psr->set(psr->encoder, false))
+   return;
break;
+
+   default:
+   pr_err("%s: Unknown state %d\n", __func__, state);
+   return;
}
+
+   psr->state = state;
 }
 
 static void psr_set_state(struct psr_drv *psr, enum psr_state state)
@@ -229,7 +235,7 @@ EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
  * Zero on success, negative errno on failure.
  */
 int rockchip_drm_psr_register(struct drm_encoder *encoder,
-   void (*psr_set)(struct drm_encoder *, bool enable))
+   int (*psr_set)(struct drm_encoder *, bool enable))
 {
struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
struct psr_drv *psr;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index b1ea0155e57c..06537ee27565 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -22,7 +22,7 @@ int rockchip_drm_psr_activate(struct drm_encoder *encoder);
 int rockchip_drm_psr_deactivate(struct drm_encoder *encoder);
 
 int rockchip_drm_psr_register

Re: [PATCH 2/2] arm64: dts: sdm845: Support GPU/GMU

2018-03-06 Thread Viresh Kumar
On 05-03-18, 08:28, Jordan Crouse wrote:
> I'm glad you brought this up - I was trying to find a place in the 
> documentation
> to put it, but since target specific nodes would be a new trick for OPP I 
> didn't
> quite know how to go about doing it. Do we just list them as Optional: or
> should we add a target specific section to the documentation and list them out
> there instead?

Something like this and you need to have your own compatible string as
well:

Documentation/devicetree/bindings/opp/ti-omap5-opp-supply.txt

But first, what's the purpose of this field? Just to check if it can
be handled by current bindings.

-- 
viresh
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [linux-sunxi] [PATCH v3 15/16] ARM: dts: sun8i: h3: Enable HDMI output on H3 boards

2018-03-06 Thread Joonas Kylmälä
Jernej Škrabec:
> I guess that would mean also including connector node (hdmi_con_in) in DTSI, 
> since it is referenced inside. However, not all boards have HDMI connector, 
> so 
> I didn't include it in DTSI.

You're absolutely right on this. I wish there was someway to get rid of
this duplication but that's a whole different problem to discuss.

Great work by the way!

Joonas
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 06/38] drm/rockchip: add mutex vop lock

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

Add a lock to vop to avoid disabling the crtc while waiting for a line
flag while enabling psr. If we disable in the middle of waiting for the
line flag, we'll end up timing out or worse.

Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 30 +++--
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 63fbe789a5dd..184f980679af 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -117,6 +117,8 @@ struct vop {
spinlock_t reg_lock;
/* lock vop irq reg */
spinlock_t irq_lock;
+   /* protects crtc enable/disable */
+   struct mutex vop_lock;
 
unsigned int irq;
 
@@ -569,6 +571,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
 
WARN_ON(vop->event);
 
+   mutex_lock(&vop->vop_lock);
drm_crtc_vblank_off(crtc);
 
/*
@@ -604,6 +607,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable(vop->aclk);
clk_disable(vop->hclk);
pm_runtime_put(vop->dev);
+   mutex_unlock(&vop->vop_lock);
 
if (crtc->state->event && !crtc->state->active) {
spin_lock_irq(&crtc->dev->event_lock);
@@ -873,10 +877,13 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
uint32_t pin_pol, val;
int ret;
 
+   mutex_lock(&vop->vop_lock);
+
WARN_ON(vop->event);
 
ret = vop_enable(crtc);
if (ret) {
+   mutex_unlock(&vop->vop_lock);
DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
return;
}
@@ -940,6 +947,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 
VOP_REG_SET(vop, common, standby, 0);
+   mutex_unlock(&vop->vop_lock);
 }
 
 static bool vop_fs_irq_is_pending(struct vop *vop)
@@ -1478,15 +1486,21 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, 
unsigned int mstimeout)
 {
struct vop *vop = to_vop(crtc);
unsigned long jiffies_left;
+   int ret = 0;
 
if (!crtc || !vop->is_enabled)
return -ENODEV;
 
-   if (mstimeout <= 0)
-   return -EINVAL;
+   mutex_lock(&vop->vop_lock);
+   if (mstimeout <= 0) {
+   ret = -EINVAL;
+   goto out;
+   }
 
-   if (vop_line_flag_irq_is_enabled(vop))
-   return -EBUSY;
+   if (vop_line_flag_irq_is_enabled(vop)) {
+   ret = -EBUSY;
+   goto out;
+   }
 
reinit_completion(&vop->line_flag_completion);
vop_line_flag_irq_enable(vop);
@@ -1497,10 +1511,13 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, 
unsigned int mstimeout)
 
if (jiffies_left == 0) {
DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
-   return -ETIMEDOUT;
+   ret = -ETIMEDOUT;
+   goto out;
}
 
-   return 0;
+out:
+   mutex_unlock(&vop->vop_lock);
+   return ret;
 }
 EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
 
@@ -1550,6 +1567,7 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
 
spin_lock_init(&vop->reg_lock);
spin_lock_init(&vop->irq_lock);
+   mutex_init(&vop->vop_lock);
 
ret = devm_request_irq(dev, vop->irq, vop_isr,
   IRQF_SHARED, dev_name(dev), vop);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 38/38] drm/rockchip: psr: Remove flush by CRTC

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

It is not used anymore after last changes and it was not even correct to
begin with as it assumed a 1:1 relation between a CRTC and encoder,
while in fact a CRTC can be attached to multiple encoders.

Signed-off-by: Tomasz Figa 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 35 -
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h |  1 -
 2 files changed, 36 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 1bf5cba9a64d..b1988ac758d5 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -40,23 +40,6 @@ struct psr_drv {
int (*set)(struct drm_encoder *encoder, bool enable);
 };
 
-static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
-{
-   struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;
-   struct psr_drv *psr;
-
-   mutex_lock(&drm_drv->psr_list_lock);
-   list_for_each_entry(psr, &drm_drv->psr_list, list) {
-   if (psr->encoder->crtc == crtc)
-   goto out;
-   }
-   psr = ERR_PTR(-ENODEV);
-
-out:
-   mutex_unlock(&drm_drv->psr_list_lock);
-   return psr;
-}
-
 static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder)
 {
struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
@@ -173,24 +156,6 @@ static void rockchip_drm_do_flush(struct psr_drv *psr)
mutex_unlock(&psr->lock);
 }
 
-/**
- * rockchip_drm_psr_flush - flush a single pipe
- * @crtc: CRTC of the pipe to flush
- *
- * Returns:
- * 0 on success, -errno on fail
- */
-int rockchip_drm_psr_flush(struct drm_crtc *crtc)
-{
-   struct psr_drv *psr = find_psr_by_crtc(crtc);
-   if (IS_ERR(psr))
-   return PTR_ERR(psr);
-
-   rockchip_drm_do_flush(psr);
-   return 0;
-}
-EXPORT_SYMBOL(rockchip_drm_psr_flush);
-
 /**
  * rockchip_drm_psr_flush_all - force to flush all registered PSR encoders
  * @dev: drm device
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index 40e026c14168..860c62494496 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -16,7 +16,6 @@
 #define __ROCKCHIP_DRM_PSR___
 
 void rockchip_drm_psr_flush_all(struct drm_device *dev);
-int rockchip_drm_psr_flush(struct drm_crtc *crtc);
 
 int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder);
 int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 14/38] drm/bridge: analogix_dp: Set PD_INC_BG first when powering up edp phy

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

Following the correct power up sequence:
dp_pd=ff => dp_pd=7f => wait 10us => dp_pd=00

Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 10 --
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |  3 +++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index b47c5af43560..bb72f8b0e603 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -321,10 +321,16 @@ void analogix_dp_set_analog_power_down(struct 
analogix_dp_device *dp,
break;
case POWER_ALL:
if (enable) {
-   reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
-   CH1_PD | CH0_PD;
+   reg = DP_ALL_PD;
writel(reg, dp->reg_base + phy_pd_addr);
} else {
+   reg = DP_ALL_PD;
+   writel(reg, dp->reg_base + phy_pd_addr);
+   usleep_range(10, 15);
+   reg &= ~DP_INC_BG;
+   writel(reg, dp->reg_base + phy_pd_addr);
+   usleep_range(10, 15);
+
writel(0x00, dp->reg_base + phy_pd_addr);
}
break;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index 40200c652533..9602668669f4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -342,12 +342,15 @@
 #define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
 
 /* ANALOGIX_DP_PHY_PD */
+#define DP_INC_BG  (0x1 << 7)
+#define DP_EXP_BG  (0x1 << 6)
 #define DP_PHY_PD  (0x1 << 5)
 #define AUX_PD (0x1 << 4)
 #define CH3_PD (0x1 << 3)
 #define CH2_PD (0x1 << 2)
 #define CH1_PD (0x1 << 1)
 #define CH0_PD (0x1 << 0)
+#define DP_ALL_PD  (0xff)
 
 /* ANALOGIX_DP_PHY_TEST */
 #define MACRO_RST  (0x1 << 5)
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 18/38] drm/bridge: analogix_dp: Check dpcd write/read status

2018-03-06 Thread Enric Balletbo i Serra
From: Lin Huang 

We need to check the dpcd write/read return value to see whether the
write/read was successful

Cc: Kristian H. Kristensen 
Signed-off-by: Lin Huang 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 169 -
 1 file changed, 127 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5489570ef010..2d49ee6fd2f3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -160,80 +160,137 @@ int analogix_dp_disable_psr(struct analogix_dp_device 
*dp)
 }
 EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
 
-static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
+static int analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
 {
unsigned char psr_version;
+   int ret;
+
+   ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to get PSR version, disable it\n");
+   return ret;
+   }
 
-   drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version);
 
-   return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;
+   dp->psr_enable = (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;
+
+   return 0;
 }
 
-static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)
+static int analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)
 {
unsigned char psr_en;
+   int ret;
 
/* Disable psr function */
-   drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en);
+   ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to get psr config\n");
+   goto end;
+   }
+
psr_en &= ~DP_PSR_ENABLE;
-   drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to disable panel psr\n");
+   goto end;
+   }
 
/* Main-Link transmitter remains active during PSR active states */
psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
-   drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to set panel psr\n");
+   goto end;
+   }
 
/* Enable psr function */
psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
 DP_PSR_CRC_VERIFICATION;
-   drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to set panel psr\n");
+   goto end;
+   }
 
analogix_dp_enable_psr_crc(dp);
+
+   return 0;
+end:
+   dev_err(dp->dev, "enable psr fail, force to disable psr\n");
+   dp->psr_enable = false;
+
+   return ret;
 }
 
-static void
+static int
 analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp,
   bool enable)
 {
u8 data;
+   int ret;
 
-   drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data);
+   ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data);
+   if (ret != 1)
+   return ret;
 
if (enable)
-   drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
-  DP_LANE_COUNT_ENHANCED_FRAME_EN |
-   DPCD_LANE_COUNT_SET(data));
+   ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
+DP_LANE_COUNT_ENHANCED_FRAME_EN |
+DPCD_LANE_COUNT_SET(data));
else
-   drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
-  DPCD_LANE_COUNT_SET(data));
+   ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
+DPCD_LANE_COUNT_SET(data));
+
+   return ret < 0 ? ret : 0;
 }
 
-static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device 
*dp)
+static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device 
*dp,
+ u8 *enhanced_mode_support)
 {
u8 data;
-   int retval;
+   int ret;
 
-   drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
-   retval = DPCD_ENHANCED_FRAME_CAP(data);
+   ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data);
+   if (ret != 1) {

[PATCH v4 36/38] drm/rockchip: Disable PSR from reboot notifier

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

It looks like the driver subsystem detaches devices from power domains
at shutdown without consent of the drivers. This means that we might have
our power domain turned off behind our back and the only way to avoid
problems is to stop doing any hardware programming at some point before
the power is cut. A reboot notifier, despite being a misnomer and
handling shutdowns as well, is a good place to do it.

Signed-off-by: Tomasz Figa 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index e7e16d92d5a1..1bf5cba9a64d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -13,6 +13,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -33,6 +34,7 @@ struct psr_drv {
struct delayed_work flush_work;
struct work_struct  disable_work;
 
+   struct notifier_block   reboot_nb;
struct input_handlerinput_handler;
 
int (*set)(struct drm_encoder *encoder, bool enable);
@@ -309,6 +311,24 @@ static const struct input_device_id psr_ids[] = {
{ },
 };
 
+static int rockchip_drm_psr_reboot_notifier(struct notifier_block *nb,
+   unsigned long action, void *data)
+{
+   struct psr_drv *psr = container_of(nb, struct psr_drv, reboot_nb);
+
+   /*
+* It looks like the driver subsystem detaches devices from power
+* domains at shutdown without consent of the drivers. This means
+* that we might have our power domain turned off behind our back
+* and the only way to avoid problems is to stop doing any hardware
+* programming after this point, which is achieved by the unbalanced
+* call below.
+*/
+   rockchip_drm_psr_inhibit_get(psr->encoder);
+
+   return 0;
+}
+
 /**
  * rockchip_drm_psr_register - register encoder to psr driver
  * @encoder: encoder that obtain the PSR function
@@ -361,6 +381,9 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
if (error)
goto err1;
 
+   psr->reboot_nb.notifier_call = rockchip_drm_psr_reboot_notifier;
+   register_reboot_notifier(&psr->reboot_nb);
+
mutex_lock(&drm_drv->psr_list_lock);
list_add_tail(&psr->list, &drm_drv->psr_list);
mutex_unlock(&drm_drv->psr_list_lock);
@@ -403,6 +426,7 @@ void rockchip_drm_psr_unregister(struct drm_encoder 
*encoder)
WARN_ON(psr->inhibit_count != 1);
 
list_del(&psr->list);
+   unregister_reboot_notifier(&psr->reboot_nb);
input_unregister_handler(&psr->input_handler);
kfree(psr->input_handler.name);
kfree(psr);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 34/38] drm/rockchip: psr: Avoid redundant calls to .set() callback

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

The first time after we call rockchip_drm_do_flush() after
rockchip_drm_psr_register(), we go from PSR_DISABLE to PSR_FLUSH. The
difference between PSR_DISABLE and PSR_FLUSH is whether or not we have a
delayed work pending - PSR is off in either state.  However
psr_set_state() only catches the transition from PSR_FLUSH to
PSR_DISABLE (which never happens), while going from PSR_DISABLE to
PSR_FLUSH triggers a call to psr->set() to disable PSR while it's
already disabled. This triggers the eDP PHY power-on sequence without
being shut down first and this seems to occasionally leave the encoder
unable to later enable PSR. Let's just simplify the state machine and
simply consider PSR_DISABLE and PSR_FLUSH the same state. This lets us
represent the hardware state by a simple boolean called "enabled" and,
while at it, rename the misleading "active" boolean to "inhibit", which
represents the purpose much better.

Also, userspace can (and does) trigger the rockchip_drm_do_flush() path
from drmModeDirtyFB() at any time, whether or the encoder is active. If
no mode is set, we call into analogix_dp_psr_set() which returns -EINVAL
because encoder->crtc is NULL. Avoid this by starting out with
psr->allowed set to false.

Signed-off-by: Kristian H. Kristensen 
Signed-off-by: Tomasz Figa 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 79 +
 1 file changed, 23 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index c8655e625ba2..448c5fde241c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -22,19 +22,13 @@
 
 #define PSR_FLUSH_TIMEOUT_MS   100
 
-enum psr_state {
-   PSR_FLUSH,
-   PSR_ENABLE,
-   PSR_DISABLE,
-};
-
 struct psr_drv {
struct list_headlist;
struct drm_encoder  *encoder;
 
struct mutexlock;
boolactive;
-   enum psr_state  state;
+   boolenabled;
 
struct delayed_work flush_work;
struct work_struct  disable_work;
@@ -78,52 +72,22 @@ static struct psr_drv *find_psr_by_encoder(struct 
drm_encoder *encoder)
return psr;
 }
 
-static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state)
+static int psr_set_state_locked(struct psr_drv *psr, bool enable)
 {
-   /*
-* Allowed finite state machine:
-*
-*   PSR_ENABLE  < = = = = = >  PSR_FLUSH
-*   | ^|
-*   | ||
-*   v ||
-*   PSR_DISABLE < - - - - - - - - -
-*/
-   if (state == psr->state || !psr->active)
-   return;
-
-   /* Already disabled in flush, change the state, but not the hardware */
-   if (state == PSR_DISABLE && psr->state == PSR_FLUSH) {
-   psr->state = state;
-   return;
-   }
+   int ret;
 
-   /* Actually commit the state change to hardware */
-   switch (state) {
-   case PSR_ENABLE:
-   if (psr->set(psr->encoder, true))
-   return;
-   break;
-
-   case PSR_DISABLE:
-   case PSR_FLUSH:
-   if (psr->set(psr->encoder, false))
-   return;
-   break;
-
-   default:
-   pr_err("%s: Unknown state %d\n", __func__, state);
-   return;
-   }
+   if (!psr->active)
+   return -EINVAL;
 
-   psr->state = state;
-}
+   if (enable == psr->enabled)
+   return 0;
 
-static void psr_set_state(struct psr_drv *psr, enum psr_state state)
-{
-   mutex_lock(&psr->lock);
-   psr_set_state_locked(psr, state);
-   mutex_unlock(&psr->lock);
+   ret = psr->set(psr->encoder, enable);
+   if (ret)
+   return ret;
+
+   psr->enabled = enable;
+   return 0;
 }
 
 static void psr_flush_handler(struct work_struct *work)
@@ -131,10 +95,8 @@ static void psr_flush_handler(struct work_struct *work)
struct psr_drv *psr = container_of(to_delayed_work(work),
   struct psr_drv, flush_work);
 
-   /* If the state has changed since we initiated the flush, do nothing */
mutex_lock(&psr->lock);
-   if (psr->state == PSR_FLUSH)
-   psr_set_state_locked(psr, PSR_ENABLE);
+   psr_set_state_locked(psr, true);
mutex_unlock(&psr->lock);
 }
 
@@ -176,6 +138,7 @@ int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
 
mutex_lock(&psr->lock);
psr->active = false;
+   psr->enabled = false;
mutex_unlock(&psr->lock);
cancel_delayed_work_sync(&psr->flush_work);
cancel_work_sync(&psr->disable_work);
@@ -187,8 +150,12 @@ 

[PATCH v4 24/38] drm/bridge: analogix_dp: Fix incorrect operations with register ANALOGIX_DP_FUNC_EN_1

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

Register ANALOGIX_DP_FUNC_EN_1(offset 0x18), Rockchip is different to
Exynos:

on Exynos edp phy,
BIT 7   MASTER_VID_FUNC_EN_N
BIT 6   reserved
BIT 5   SLAVE_VID_FUNC_EN_N

on Rockchip edp phy,
BIT 7   reserved
BIT 6   RK_VID_CAP_FUNC_EN_N
BIT 5   RK_VID_FIFO_FUNC_EN_N

So, we should do some private operations to Rockchip.

Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 19 ++-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |  2 ++
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 02ab1aaa9993..4eae206ec31b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -126,9 +126,14 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
analogix_dp_stop_video(dp);
analogix_dp_enable_video_mute(dp, 0);
 
-   reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
-   AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
-   HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+   reg = RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N |
+   SW_FUNC_EN_N;
+   else
+   reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+   AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+   HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 
reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
@@ -971,8 +976,12 @@ void analogix_dp_config_video_slave_mode(struct 
analogix_dp_device *dp)
u32 reg;
 
reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
-   reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
-   reg |= MASTER_VID_FUNC_EN_N;
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+   reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
+   } else {
+   reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
+   reg |= MASTER_VID_FUNC_EN_N;
+   }
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 
reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index b633a4a5082a..0cf27c731727 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -127,7 +127,9 @@
 
 /* ANALOGIX_DP_FUNC_EN_1 */
 #define MASTER_VID_FUNC_EN_N   (0x1 << 7)
+#define RK_VID_CAP_FUNC_EN_N   (0x1 << 6)
 #define SLAVE_VID_FUNC_EN_N(0x1 << 5)
+#define RK_VID_FIFO_FUNC_EN_N  (0x1 << 5)
 #define AUD_FIFO_FUNC_EN_N (0x1 << 4)
 #define AUD_FUNC_EN_N  (0x1 << 3)
 #define HDCP_FUNC_EN_N (0x1 << 2)
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 33/38] drm/rockchip: Cancel PSR enable work before changing the state

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

If we change the state first and reschedule later, we might have the
work executed according to previous scheduled time and end up with PSR
re-enabled instantly. Let's cancel the work before changing the state.

While at it, consolidate psr_disable_handler() to just call
rockchip_drm_do_flush(), as they are both supposed to do the same.

Signed-off-by: Tomasz Figa 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index a107845ba97c..c8655e625ba2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -138,18 +138,6 @@ static void psr_flush_handler(struct work_struct *work)
mutex_unlock(&psr->lock);
 }
 
-static void psr_disable_handler(struct work_struct *work)
-{
-   struct psr_drv *psr = container_of(work, struct psr_drv, disable_work);
-
-   /* If the state has changed since we initiated the flush, do nothing */
-   mutex_lock(&psr->lock);
-   if (psr->state == PSR_ENABLE)
-   psr_set_state_locked(psr, PSR_FLUSH);
-   mutex_unlock(&psr->lock);
-   mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS);
-}
-
 /**
  * rockchip_drm_psr_activate - activate PSR on the given pipe
  * @encoder: encoder to obtain the PSR encoder
@@ -198,6 +186,7 @@ EXPORT_SYMBOL(rockchip_drm_psr_deactivate);
 
 static void rockchip_drm_do_flush(struct psr_drv *psr)
 {
+   cancel_delayed_work_sync(&psr->flush_work);
psr_set_state(psr, PSR_FLUSH);
mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS);
 }
@@ -244,6 +233,13 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev)
 }
 EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
 
+static void psr_disable_handler(struct work_struct *work)
+{
+   struct psr_drv *psr = container_of(work, struct psr_drv, disable_work);
+
+   rockchip_drm_do_flush(psr);
+}
+
 static void psr_input_event(struct input_handle *handle,
unsigned int type, unsigned int code,
int value)
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 29/38] drm/rockchip: pre dither down when output bpc is 8bit

2018-03-06 Thread Enric Balletbo i Serra
From: Mark Yao 

Some encoder have a crc verification check, crc check fail if
input and output data is not equal.

That means encoder input and output need use same color depth,
vop can output 10bit data to encoder, but some panel only support
8bit depth, that would make crc check die.

So pre dither down vop data to 8bit if panel's bpc is 8.

Signed-off-by: Mark Yao 
[seanpaul resolved conflict in rockchip_drm_vop.c]
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 2 ++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 +
 5 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 8c884f9ce713..b3f46ed24cdc 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -218,6 +218,7 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
  struct drm_connector_state *conn_state)
 {
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+   struct drm_display_info *di = &conn_state->connector->display_info;
 
/*
 * The hardware IC designed that VOP must output the RGB10 video
@@ -229,6 +230,7 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
 
s->output_mode = ROCKCHIP_OUT_MODE_;
s->output_type = DRM_MODE_CONNECTOR_eDP;
+   s->output_bpc = di->bpc;
 
return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 9c064a40458b..3a6ebfc26036 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -36,6 +36,7 @@ struct rockchip_crtc_state {
struct drm_crtc_state base;
int output_type;
int output_mode;
+   int output_bpc;
 };
 #define to_rockchip_crtc_state(s) \
container_of(s, struct rockchip_crtc_state, base)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 184f980679af..42562ab04bde 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -928,6 +928,12 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
if (s->output_mode == ROCKCHIP_OUT_MODE_ &&
!(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
s->output_mode = ROCKCHIP_OUT_MODE_P888;
+
+   if (s->output_mode == ROCKCHIP_OUT_MODE_ && s->output_bpc == 8)
+   VOP_REG_SET(vop, common, pre_dither_down, 1);
+   else
+   VOP_REG_SET(vop, common, pre_dither_down, 0);
+
VOP_REG_SET(vop, common, out_mode, s->output_mode);
 
VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 56bbd2e2a8ef..084acdd0019a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -67,6 +67,7 @@ struct vop_common {
struct vop_reg cfg_done;
struct vop_reg dsp_blank;
struct vop_reg data_blank;
+   struct vop_reg pre_dither_down;
struct vop_reg dither_down;
struct vop_reg dither_up;
struct vop_reg gate_en;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 2e4eea3459fe..08023d3ecb76 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -264,6 +264,7 @@ static const struct vop_common rk3288_common = {
.standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
+   .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
.dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 19/38] drm/bridge: analogix_dp: Fix AUX_PD bit for Rockchip

2018-03-06 Thread Enric Balletbo i Serra
From: zain wang 

There are some different bits between Rockchip and Exynos in register
"AUX_PD". This patch fixes the incorrect operations about it.

Cc: Douglas Anderson 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 117 --
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |   2 +
 2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index bb72f8b0e603..dee1ba109b5f 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -248,76 +248,85 @@ void analogix_dp_set_analog_power_down(struct 
analogix_dp_device *dp,
 {
u32 reg;
u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+   u32 mask;
 
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
phy_pd_addr = ANALOGIX_DP_PD;
 
switch (block) {
case AUX_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= AUX_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~AUX_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+   mask = RK_AUX_PD;
+   else
+   mask = AUX_PD;
+
+   reg = readl(dp->reg_base + phy_pd_addr);
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH0_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH0_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH0_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH0_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH1_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH1_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH1_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH1_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH2_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH2_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH2_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH2_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH3_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH3_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH3_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH3_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case ANALOG_TOTAL:
-   if (enable) {
-   reg = readl(dp

[PATCH v4 10/38] drm/bridge: analogix_dp: Check AUX_EN status when doing AUX transfer

2018-03-06 Thread Enric Balletbo i Serra
From: Lin Huang 

We should check AUX_EN bit to confirm the AUX CH operation is completed.

Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 +--
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 9df2f3ef000c..e78c861b9e06 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1073,9 +1073,9 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 {
u32 reg;
u8 *buffer = msg->buffer;
-   int timeout_loop = 0;
unsigned int i;
int num_transferred = 0;
+   int ret;
 
/* Buffer size of AUX CH is 16 bytes */
if (WARN_ON(msg->size > 16))
@@ -1139,17 +1139,20 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 
writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
 
-   /* Is AUX CH command reply received? */
+   ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
+reg, !(reg & AUX_EN), 25, 500 * 1000);
+   if (ret) {
+   dev_err(dp->dev, "AUX CH enable timeout!\n");
+   return -ETIMEDOUT;
+   }
+
/* TODO: Wait for an interrupt instead of looping? */
-   reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   while (!(reg & RPLY_RECEIV)) {
-   timeout_loop++;
-   if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "AUX CH command reply failed!\n");
-   return -ETIMEDOUT;
-   }
-   reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   usleep_range(10, 11);
+   /* Is AUX CH command reply received? */
+   ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
+reg, reg & RPLY_RECEIV, 10, 20 * 1000);
+   if (ret) {
+   dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
+   return -ETIMEDOUT;
}
 
/* Clear interrupt source for AUX CH command reply */
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 37/38] drm/rockchip: Disallow PSR for the whole atomic commit

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

Currently PSR flush is triggered from CRTC's .atomic_begin() callback,
which is executed after modeset disables and enables and before plane
updates are committed. Since PSR flush and re-enable can be triggered
asynchronously by external sources (input event, delayed work), it can
race with hardware programming done in the aforementioned stages.

This patch blocks the PSR completely before hardware programming part
begins and unblock after it ends. This relies on reference counted PSR
disable introduced with previous patch.

Cc: Kristian H. Kristensen 
Signed-off-by: Tomasz Figa 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 61 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  7 
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index e266539e04e5..d4f4118b482d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -167,8 +167,67 @@ rockchip_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
return ERR_PTR(ret);
 }
 
+static void
+rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   struct drm_encoder *encoder;
+   u32 encoder_mask = 0;
+   int i;
+
+   for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
+   encoder_mask |= crtc_state->encoder_mask;
+   encoder_mask |= crtc->state->encoder_mask;
+   }
+
+   drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
+   rockchip_drm_psr_inhibit_get(encoder);
+}
+
+static void
+rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   struct drm_encoder *encoder;
+   u32 encoder_mask = 0;
+   int i;
+
+   for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
+   encoder_mask |= crtc_state->encoder_mask;
+   encoder_mask |= crtc->state->encoder_mask;
+   }
+
+   drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
+   rockchip_drm_psr_inhibit_put(encoder);
+}
+
+static void
+rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
+{
+   struct drm_device *dev = old_state->dev;
+
+   rockchip_drm_psr_inhibit_get_state(old_state);
+
+   drm_atomic_helper_commit_modeset_disables(dev, old_state);
+
+   drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+   drm_atomic_helper_commit_planes(dev, old_state,
+   DRM_PLANE_COMMIT_ACTIVE_ONLY);
+
+   rockchip_drm_psr_inhibit_put_state(old_state);
+
+   drm_atomic_helper_commit_hw_done(old_state);
+
+   drm_atomic_helper_wait_for_vblanks(dev, old_state);
+
+   drm_atomic_helper_cleanup_planes(dev, old_state);
+}
+
 static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers 
= {
-   .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+   .atomic_commit_tail = rockchip_atomic_helper_commit_tail_rpm,
 };
 
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 42562ab04bde..12ebaec740c6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1032,16 +1032,9 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
}
 }
 
-static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
-{
-   rockchip_drm_psr_flush(crtc);
-}
-
 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
.mode_fixup = vop_crtc_mode_fixup,
.atomic_flush = vop_crtc_atomic_flush,
-   .atomic_begin = vop_crtc_atomic_begin,
.atomic_enable = vop_crtc_atomic_enable,
.atomic_disable = vop_crtc_atomic_disable,
 };
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 30/38] drm/bridge: analogix_dp: Split the platform-specific poweron in two parts

2018-03-06 Thread Enric Balletbo i Serra
From: Douglas Anderson 

Some of the platform-specific stuff in rockchip_dp_poweron() needs to
happen before the generic code.  Some needs to happen after.  Let's
split the callback in two.

Specifically we can't start doing PSR work until _after_ the whole
controller is up, so don't set the enable until the end.

Cc: Kristian H. Kristensen 
Signed-off-by: Douglas Anderson 
[seanpaul added exynos change]
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  7 +--
 drivers/gpu/drm/exynos/exynos_dp.c |  2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 12 ++--
 include/drm/bridge/analogix_dp.h   |  3 ++-
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index edaca650e6d2..8703c3cc5ff8 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1260,8 +1260,8 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
goto out_dp_clk_pre;
}
 
-   if (dp->plat_data->power_on)
-   dp->plat_data->power_on(dp->plat_data);
+   if (dp->plat_data->power_on_start)
+   dp->plat_data->power_on_start(dp->plat_data);
 
phy_power_on(dp->phy);
 
@@ -1286,6 +1286,9 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
goto out_dp_init;
}
 
+   if (dp->plat_data->power_on_end)
+   dp->plat_data->power_on_end(dp->plat_data);
+
enable_irq(dp->irq);
return 0;
 
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
b/drivers/gpu/drm/exynos/exynos_dp.c
index 964831dab102..86330f396784 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -162,7 +162,7 @@ static int exynos_dp_bind(struct device *dev, struct device 
*master, void *data)
dp->drm_dev = drm_dev;
 
dp->plat_data.dev_type = EXYNOS_DP;
-   dp->plat_data.power_on = exynos_dp_poweron;
+   dp->plat_data.power_on_start = exynos_dp_poweron;
dp->plat_data.power_off = exynos_dp_poweroff;
dp->plat_data.attach = exynos_dp_bridge_attach;
dp->plat_data.get_modes = exynos_dp_get_modes;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index b3f46ed24cdc..23317a2269e1 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -109,7 +109,7 @@ static int rockchip_dp_pre_init(struct rockchip_dp_device 
*dp)
return 0;
 }
 
-static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
+static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data)
 {
struct rockchip_dp_device *dp = to_dp(plat_data);
int ret;
@@ -127,6 +127,13 @@ static int rockchip_dp_poweron(struct 
analogix_dp_plat_data *plat_data)
return ret;
}
 
+   return ret;
+}
+
+static int rockchip_dp_poweron_end(struct analogix_dp_plat_data *plat_data)
+{
+   struct rockchip_dp_device *dp = to_dp(plat_data);
+
return rockchip_drm_psr_activate(&dp->encoder);
 }
 
@@ -330,7 +337,8 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
dp->plat_data.encoder = &dp->encoder;
 
dp->plat_data.dev_type = dp->data->chip_type;
-   dp->plat_data.power_on = rockchip_dp_poweron;
+   dp->plat_data.power_on_start = rockchip_dp_poweron_start;
+   dp->plat_data.power_on_end = rockchip_dp_poweron_end;
dp->plat_data.power_off = rockchip_dp_powerdown;
dp->plat_data.get_modes = rockchip_dp_get_modes;
 
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index e9a1116d2f8e..475b706b49de 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -33,7 +33,8 @@ struct analogix_dp_plat_data {
struct drm_connector *connector;
bool skip_connector;
 
-   int (*power_on)(struct analogix_dp_plat_data *);
+   int (*power_on_start)(struct analogix_dp_plat_data *);
+   int (*power_on_end)(struct analogix_dp_plat_data *);
int (*power_off)(struct analogix_dp_plat_data *);
int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *,
  struct drm_connector *);
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC v3 04/12] drm: Make ioctls available for in-kernel clients part 2

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:45PM +0100, Noralf Trønnes wrote:
> This is part 2 of making ioctls useable for in-kernel clients.
> Make an ioctl wrapper function that calls a function that can be used by
> in-kernel clients.
> 
> It adjusts the signature of the following functions:
> - drm_mode_getcrtc()
> - drm_mode_create_dumb_ioctl()
> - drm_mode_destroy_dumb_ioctl()
> - drm_mode_getencoder()
> - drm_mode_addfb2()
> - drm_mode_rmfb()
> - drm_mode_obj_set_property_ioctl()
> - drm_mode_page_flip_ioctl()
> - drm_prime_handle_to_fd_ioctl()
> - drm_wait_vblank_ioctl()
> 
> drm_mode_addfb2() also gets the ability to override the debug name.
> 
> There is no functional change from the userspace side.
> 
> Signed-off-by: Noralf Trønnes 

Do we really need all of these? For in-kernel KMS users I think it would
be much better to keep using the in-kernel KMS interfaces directly (like
the current fbdev emulation code does). Doing all the marshalling and
demarshalling for the generic KMS ioctls looks like lots of fragile code.

I think the only ioctl we really absolutely need are:
- dumb_create/mmap_offset/destroy
- addfb2

As soon as we've called addfb2 we can use the idr lookup to go from the id
to the drm_framebuffer * (including a full reference), and once we have
the drm_framebuffer we don't need any of the other ioctls. Or am I missing
something? Maybe the addfb wrapper for internal clients could even
directly convert to the drm_framebuffer * and never expose the KMS ID.
-Daniel


> ---
>  drivers/gpu/drm/drm_crtc.c  | 15 +++
>  drivers/gpu/drm/drm_crtc_internal.h | 37 +--
>  drivers/gpu/drm/drm_dumb_buffers.c  | 33 
>  drivers/gpu/drm/drm_encoder.c   | 10 ++--
>  drivers/gpu/drm/drm_framebuffer.c   | 50 
> -
>  drivers/gpu/drm/drm_internal.h  |  5 
>  drivers/gpu/drm/drm_ioc32.c |  2 +-
>  drivers/gpu/drm/drm_ioctl.c |  8 +++---
>  drivers/gpu/drm/drm_mode_object.c   | 12 ++---
>  drivers/gpu/drm/drm_plane.c | 12 ++---
>  drivers/gpu/drm/drm_prime.c | 13 +++---
>  drivers/gpu/drm/drm_vblank.c| 11 +---
>  12 files changed, 147 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index c9ab1cc6b412..61a6a90fae7e 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -387,8 +387,8 @@ EXPORT_SYMBOL(drm_crtc_cleanup);
>  /**
>   * drm_mode_getcrtc - get CRTC configuration
>   * @dev: drm device for the ioctl
> - * @data: data pointer for the ioctl
> - * @file_priv: drm file for the ioctl call
> + * @crtc_resp: pointer to crtc request structure
> + * @file_priv: drm file
>   *
>   * Construct a CRTC configuration structure to return to the user.
>   *
> @@ -397,10 +397,9 @@ EXPORT_SYMBOL(drm_crtc_cleanup);
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
> -int drm_mode_getcrtc(struct drm_device *dev,
> -  void *data, struct drm_file *file_priv)
> +int drm_mode_getcrtc(struct drm_device *dev, struct drm_mode_crtc *crtc_resp,
> +  struct drm_file *file_priv)
>  {
> - struct drm_mode_crtc *crtc_resp = data;
>   struct drm_crtc *crtc;
>  
>   if (!drm_core_check_feature(dev, DRIVER_MODESET))
> @@ -451,6 +450,12 @@ int drm_mode_getcrtc(struct drm_device *dev,
>   return 0;
>  }
>  
> +int drm_mode_getcrtc_ioctl(struct drm_device *dev,
> +void *data, struct drm_file *file_priv)
> +{
> + return drm_mode_getcrtc(dev, data, file_priv);
> +}
> +
>  static int __drm_mode_set_config_internal(struct drm_mode_set *set,
> struct drm_modeset_acquire_ctx *ctx)
>  {
> diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
> b/drivers/gpu/drm/drm_crtc_internal.h
> index 29c59ce7e56e..45713af5a015 100644
> --- a/drivers/gpu/drm/drm_crtc_internal.h
> +++ b/drivers/gpu/drm/drm_crtc_internal.h
> @@ -45,12 +45,14 @@ void drm_crtc_unregister_all(struct drm_device *dev);
>  
>  struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
>  
> +int drm_mode_getcrtc(struct drm_device *dev, struct drm_mode_crtc *crtc_resp,
> +  struct drm_file *file_priv);
>  int drm_mode_setcrtc(struct drm_device *dev, struct drm_mode_crtc *crtc_req,
>struct drm_file *file_priv, bool user);
>  
>  /* IOCTLs */
> -int drm_mode_getcrtc(struct drm_device *dev,
> -  void *data, struct drm_file *file_priv);
> +int drm_mode_getcrtc_ioctl(struct drm_device *dev,
> +void *data, struct drm_file *file_priv);
>  int drm_mode_setcrtc_ioctl(struct drm_device *dev,
>  void *data, struct drm_file *file_priv);
>  
> @@ -68,6 +70,12 @@ int drm_mode_getresources_ioctl(struct drm_device *dev, 
> void *data,
>  
>  
>  /* drm_dumb_buffers.c */
> +int drm_mode_create_dumb(struct drm_device *dev,
>

[PATCH v4 28/38] drm/bridge: analogix_dp: Properly disable aux chan retries on rockchip

2018-03-06 Thread Enric Balletbo i Serra
From: Douglas Anderson 

The comments in analogix_dp_init_aux() claim that we're disabling aux
channel retries, but then right below it for Rockchip it sets them to
3.  If we actually need 3 retries for Rockchip then we could adjust
the comment, but it seems more likely that we want the same retry
behavior across all platforms.

Cc: Stéphane Marchesin 
Cc: 征增 王 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 58e8a28e99aa..a5f2763d72e4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -481,15 +481,16 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
 
analogix_dp_reset_aux(dp);
 
-   /* Disable AUX transaction H/W retry */
+   /* AUX_BIT_PERIOD_EXPECTED_DELAY doesn't apply to Rockchip IP */
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
-   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
- AUX_HW_RETRY_COUNT_SEL(3) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+   reg = 0;
else
-   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
- AUX_HW_RETRY_COUNT_SEL(0) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3);
+
+   /* Disable AUX transaction H/W retry */
+   reg |= AUX_HW_RETRY_COUNT_SEL(0) |
+  AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+
writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
 
/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 31/38] drm/rockchip: analogix_dp: Do not call Analogix code before bind

2018-03-06 Thread Enric Balletbo i Serra
From: Tomasz Figa 

Driver callbacks, such as system suspend or resume can be called any
time, specifically they can be called before the component bind
callback. Let's use dp->adp pointer as a safeguard and skip calling
Analogix entry points if it is an ERR_PTR().

Signed-off-by: Tomasz Figa 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 23317a2269e1..6d45d62466b3 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -368,6 +368,8 @@ static void rockchip_dp_unbind(struct device *dev, struct 
device *master,
analogix_dp_unbind(dp->adp);
rockchip_drm_psr_unregister(&dp->encoder);
dp->encoder.funcs->destroy(&dp->encoder);
+
+   dp->adp = ERR_PTR(-ENODEV);
 }
 
 static const struct component_ops rockchip_dp_component_ops = {
@@ -391,6 +393,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
return -ENOMEM;
 
dp->dev = dev;
+   dp->adp = ERR_PTR(-ENODEV);
dp->plat_data.panel = panel;
 
ret = rockchip_dp_of_probe(dp);
@@ -414,6 +417,9 @@ static int rockchip_dp_suspend(struct device *dev)
 {
struct rockchip_dp_device *dp = dev_get_drvdata(dev);
 
+   if (IS_ERR(dp->adp))
+   return 0;
+
return analogix_dp_suspend(dp->adp);
 }
 
@@ -421,6 +427,9 @@ static int rockchip_dp_resume(struct device *dev)
 {
struct rockchip_dp_device *dp = dev_get_drvdata(dev);
 
+   if (IS_ERR(dp->adp))
+   return 0;
+
return analogix_dp_resume(dp->adp);
 }
 #endif
-- 
2.16.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC v3 07/12] drm/modes: Add drm_umode_equal()

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:48PM +0100, Noralf Trønnes wrote:
> Add a way to check if userspace modes are equal. Useful for in-kernel
> clients. Also export drm_mode_convert_umode().
> 
> Signed-off-by: Noralf Trønnes 

Assuming we don't use the KMS ioctls for in-kernel clients I guess we
don't need this here either?
-Daniel

> ---
>  drivers/gpu/drm/drm_modes.c | 50 
> +
>  include/drm/drm_modes.h |  2 ++
>  2 files changed, 52 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 5a8033fda4e3..0e39164f15aa 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1631,6 +1631,56 @@ int drm_mode_convert_umode(struct drm_device *dev,
>  out:
>   return ret;
>  }
> +EXPORT_SYMBOL(drm_mode_convert_umode);
> +
> +/**
> + * drm_umode_equal - test modeinfo modes for equality
> + * @mode1: first mode
> + * @mode2: second mode
> + *
> + * Check to see if @mode1 and @mode2 are equivalent.
> + *
> + * Returns:
> + * True if the modes are equal, false otherwise.
> + */
> +bool drm_umode_equal(const struct drm_mode_modeinfo *mode1,
> +  const struct drm_mode_modeinfo *mode2)
> +{
> + if (!mode1 && !mode2)
> + return true;
> +
> + if (!mode1 || !mode2)
> + return false;
> +
> + /* do clock check convert to PICOS so fb modes get matched the same */
> + if (mode1->clock && mode2->clock) {
> + if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock))
> + return false;
> + } else if (mode1->clock != mode2->clock) {
> + return false;
> + }
> +
> + if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) !=
> + (mode2->flags & DRM_MODE_FLAG_3D_MASK))
> + return false;
> +
> + if (mode1->hdisplay == mode2->hdisplay &&
> + mode1->hsync_start == mode2->hsync_start &&
> + mode1->hsync_end == mode2->hsync_end &&
> + mode1->htotal == mode2->htotal &&
> + mode1->hskew == mode2->hskew &&
> + mode1->vdisplay == mode2->vdisplay &&
> + mode1->vsync_start == mode2->vsync_start &&
> + mode1->vsync_end == mode2->vsync_end &&
> + mode1->vtotal == mode2->vtotal &&
> + mode1->vscan == mode2->vscan &&
> + (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
> +  (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
> + return true;
> +
> + return false;
> +}
> +EXPORT_SYMBOL(drm_umode_equal);
>  
>  /**
>   * drm_mode_is_420_only - if a given videomode can be only supported in 
> YCBCR420
> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
> index 0d310beae6af..05e73ca4f2ae 100644
> --- a/include/drm/drm_modes.h
> +++ b/include/drm/drm_modes.h
> @@ -447,6 +447,8 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo 
> *out,
>  int drm_mode_convert_umode(struct drm_device *dev,
>  struct drm_display_mode *out,
>  const struct drm_mode_modeinfo *in);
> +bool drm_umode_equal(const struct drm_mode_modeinfo *mode1,
> +  const struct drm_mode_modeinfo *mode2);
>  void drm_mode_probed_add(struct drm_connector *connector, struct 
> drm_display_mode *mode);
>  void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
>  bool drm_mode_is_420_only(const struct drm_display_info *display,
> -- 
> 2.15.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC v3 08/12] drm/framebuffer: Add drm_mode_can_dirtyfb()

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:49PM +0100, Noralf Trønnes wrote:
> Add a function so the generic fbdev client can check if the framebuffer
> does flushing. This is needed to set up deferred I/O.
> 
> Signed-off-by: Noralf Trønnes 

Again I guess not needed if we use drm_framebuffer * internally for
in-kernel clients.

For a high-level design I think the only place where we have to use the
abstract (drm_file, id) pair is for backing storage buffers, because not
every driver is using drm_gem_object for that. But otherwise I don't think
there's a need, and not using the abstract IDs makes for more cumbersome
code I think. Real userspace compositors also recreate their own mirroring
objects as the first thing, since the IDs are all a bit unwiedling to
manage.
-Daniel

> ---
>  drivers/gpu/drm/drm_framebuffer.c | 31 +++
>  include/drm/drm_framebuffer.h |  2 ++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_framebuffer.c 
> b/drivers/gpu/drm/drm_framebuffer.c
> index ad8f7d308656..a659cff45844 100644
> --- a/drivers/gpu/drm/drm_framebuffer.c
> +++ b/drivers/gpu/drm/drm_framebuffer.c
> @@ -600,6 +600,37 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
>   return drm_mode_dirtyfb(dev, data, file_priv, true);
>  }
>  
> +/**
> + * drm_mode_can_dirtyfb - check if the FB does flushing
> + * @dev: drm device
> + * @fb_id: Framebuffer id
> + * @file_priv: drm file
> + *
> + * Returns:
> + * True if the framebuffer does flushing, false otherwise.
> + */
> +bool drm_mode_can_dirtyfb(struct drm_device *dev, u32 fb_id,
> +   struct drm_file *file_priv)
> +{
> + struct drm_framebuffer *fb;
> + bool ret = false;
> +
> + if (!drm_core_check_feature(dev, DRIVER_MODESET))
> + return false;
> +
> + fb = drm_framebuffer_lookup(dev, file_priv, fb_id);
> + if (!fb)
> + return false;
> +
> + if (fb->funcs->dirty)
> + ret = true;
> +
> + drm_framebuffer_put(fb);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(drm_mode_can_dirtyfb);
> +
>  /**
>   * drm_fb_release - remove and free the FBs on this file
>   * @priv: drm file for the ioctl
> diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
> index c50502c656e5..05d170f4e215 100644
> --- a/include/drm/drm_framebuffer.h
> +++ b/include/drm/drm_framebuffer.h
> @@ -216,6 +216,8 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct 
> drm_device *dev,
>  void drm_framebuffer_remove(struct drm_framebuffer *fb);
>  void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
>  void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
> +bool drm_mode_can_dirtyfb(struct drm_device *dev, u32 fb_id,
> +   struct drm_file *file_priv);
>  
>  /**
>   * drm_framebuffer_get - acquire a framebuffer reference
> -- 
> 2.15.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 198985] BUG: KASAN: use-after-free in amdgpu_job_free_cb+0x26/0xb0 [amdgpu]

2018-03-06 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=198985

Christian König (christian.koe...@amd.com) changed:

   What|Removed |Added

 CC||christian.koe...@amd.com

--- Comment #2 from Christian König (christian.koe...@amd.com) ---
That is fixed by:

commit d1f6dc1a9a106a73510181cfad9b4a7a0b140990
Author: Andrey Grodzovsky 
Date:   Thu Oct 19 14:29:46 2017 -0400

drm/amdgpu: Avoid accessing job->entity after the job is scheduled.

Bug: amdgpu_job_free_cb was accessing s_job->s_entity when the allocated
amdgpu_ctx (and the entity inside it) were already deallocated from
amdgpu_cs_parser_fini.

Fix: Save job's priority on it's creation instead of accessing it from
s_entity later on.

Signed-off-by: Andrey Grodzovsky 
Reviewed-by: Andres Rodriguez 
Signed-off-by: Alex Deucher 


Not sure why that didn't ended up in 4.15.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] dma-buf/reservation: should keep the new fence in add_shared_inplace

2018-03-06 Thread Liu, Monk
why? is there a design doc mentioned for this on reservation ?


From: Christian K?nig 
Sent: Tuesday, March 6, 2018 4:03:39 PM
To: Liu, Monk; dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] dma-buf/reservation: should keep the new fence in 
add_shared_inplace

NAK, the newly added fence must always be newer than the existing one.

Christian.

Am 06.03.2018 um 04:09 schrieb Monk Liu:
> Change-Id: If6a979ba9fd6c923b82212f35f07a9ff31c86767
> Signed-off-by: Monk Liu 
> ---
>   drivers/dma-buf/reservation.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
> index 314eb10..29b7e45 100644
> --- a/drivers/dma-buf/reservation.c
> +++ b/drivers/dma-buf/reservation.c
> @@ -118,7 +118,7 @@ reservation_object_add_shared_inplace(struct 
> reservation_object *obj,
>old_fence = rcu_dereference_protected(fobj->shared[i],
>reservation_object_held(obj));
>
> - if (old_fence->context == fence->context) {
> + if (dma_fence_is_later(fence, old_fence)) {
>/* memory barrier is added by write_seqcount_begin */
>RCU_INIT_POINTER(fobj->shared[i], fence);
>write_seqcount_end(&obj->seq);

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm: of: simplify component probe code

2018-03-06 Thread Archit Taneja



On Tuesday 06 March 2018 01:46 PM, Philipp Zabel wrote:

On Thu, 2018-02-22 at 21:22 +0200, Baruch Siach wrote:

Use positive logic for better readability. This also eliminates one
of_node_put() call, making the code shorter.

Signed-off-by: Baruch Siach 


Reviewed-by: Philipp Zabel 
Tested-by: Philipp Zabel 



queued to drm-misc-next after fixing a minor checkpatch
warning.

Thanks,
Archit


regards
Philipp


---
  drivers/gpu/drm/drm_of.c | 8 +++-
  1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 4c191c050e7d..fa354d14127b 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -122,12 +122,10 @@ int drm_of_component_probe(struct device *dev,
if (!port)
break;
  
-		if (!of_device_is_available(port->parent)) {

-   of_node_put(port);
-   continue;
-   }
+   if (of_device_is_available(port->parent))
+   drm_of_component_match_add(dev, &match, compare_of,
+   port);
  
-		drm_of_component_match_add(dev, &match, compare_of, port);

of_node_put(port);
}
  

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC v3 09/12] drm: Add API for in-kernel clients

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:50PM +0100, Noralf Trønnes wrote:
> This adds an API for writing in-kernel clients.
> 
> TODO:
> - Flesh out and complete documentation.
> - Cloned displays is not tested.
> - Complete tiled display support and test it.
> - Test plug/unplug different monitors.
> - A runtime knob to prevent clients from attaching for debugging purposes.
> - Maybe a way to unbind individual client instances.
> - Maybe take the sysrq support in drm_fb_helper and move it here somehow.
> - Add suspend/resume callbacks.
>   Does anyone know why fbdev requires suspend/resume?
> 
> Signed-off-by: Noralf Trønnes 

The core client api I like. Some of the opens I'm seeing:

- If we go with using the internal kms api directly instead of IOCTL
  wrappers then a huge pile of the functions you have here aren't needed
  (e.g. all the event stuff we can just directly use vblank events instead
  of all the wrapping). I'm leaning ever more into that direction, since
  much less code to add.

- The register/unregister model needs more thought. Allowing both clients
  to register whenever they want to, and drm_device instances to come and
  go is what fbcon has done, and the resulting locking is a horror show.

  I think if we require that all in-kernel drm_clients are registers when
  loading drm.ko (and enabled/disabled only per module options and
  Kconfig), then we can throw out all the locking. That avoids a lot of
  the headaches.

  2nd, if the list of clients is static over the lifetime of drm.ko, we
  also don't need to iterate existing drivers. Which avoids me having to
  review the iterator patch (that's the other aspect where fbcon totally
  falls over and essentially just ignores a bunch of races).

> ---
>  drivers/gpu/drm/Kconfig |2 +
>  drivers/gpu/drm/Makefile|3 +-
>  drivers/gpu/drm/client/Kconfig  |4 +
>  drivers/gpu/drm/client/Makefile |1 +
>  drivers/gpu/drm/client/drm_client.c | 1612 
> +++

I'd move this into main drm/ directory, it's fairly core stuff.

>  drivers/gpu/drm/drm_drv.c   |6 +
>  drivers/gpu/drm/drm_file.c  |3 +
>  drivers/gpu/drm/drm_probe_helper.c  |3 +
>  include/drm/drm_client.h|  192 +
>  include/drm/drm_device.h|1 +
>  include/drm/drm_file.h  |7 +
>  11 files changed, 1833 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/client/Kconfig
>  create mode 100644 drivers/gpu/drm/client/Makefile
>  create mode 100644 drivers/gpu/drm/client/drm_client.c
>  create mode 100644 include/drm/drm_client.h
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index deeefa7a1773..d4ae15f9ee9f 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -154,6 +154,8 @@ config DRM_SCHED
>   tristate
>   depends on DRM
>  
> +source "drivers/gpu/drm/client/Kconfig"
> +
>  source "drivers/gpu/drm/i2c/Kconfig"
>  
>  source "drivers/gpu/drm/arm/Kconfig"
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 50093ff4479b..8e06dc7eeca1 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -18,7 +18,7 @@ drm-y   :=  drm_auth.o drm_bufs.o drm_cache.o \
>   drm_encoder.o drm_mode_object.o drm_property.o \
>   drm_plane.o drm_color_mgmt.o drm_print.o \
>   drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
> - drm_syncobj.o drm_lease.o
> + drm_syncobj.o drm_lease.o client/drm_client.o
>  
>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
>  drm-$(CONFIG_DRM_VM) += drm_vm.o
> @@ -103,3 +103,4 @@ obj-$(CONFIG_DRM_MXSFB)   += mxsfb/
>  obj-$(CONFIG_DRM_TINYDRM) += tinydrm/
>  obj-$(CONFIG_DRM_PL111) += pl111/
>  obj-$(CONFIG_DRM_TVE200) += tve200/
> +obj-y+= client/
> diff --git a/drivers/gpu/drm/client/Kconfig b/drivers/gpu/drm/client/Kconfig
> new file mode 100644
> index ..4bb8e4655ff7
> --- /dev/null
> +++ b/drivers/gpu/drm/client/Kconfig
> @@ -0,0 +1,4 @@
> +menu "DRM Clients"
> + depends on DRM
> +
> +endmenu
> diff --git a/drivers/gpu/drm/client/Makefile b/drivers/gpu/drm/client/Makefile
> new file mode 100644
> index ..f66554cd5c45
> --- /dev/null
> +++ b/drivers/gpu/drm/client/Makefile
> @@ -0,0 +1 @@
> +# SPDX-License-Identifier: GPL-2.0
> diff --git a/drivers/gpu/drm/client/drm_client.c 
> b/drivers/gpu/drm/client/drm_client.c
> new file mode 100644
> index ..a633bf747316
> --- /dev/null
> +++ b/drivers/gpu/drm/client/drm_client.c
> @@ -0,0 +1,1612 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright 2018 Noralf Trønnes
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "drm_crtc_internal.h"
> +#include "drm_internal.h"
> +
> +struct drm_client_funcs_entry {
> + struct list_head list

[Bug 105353] Textures flickering in Civilizations VI

2018-03-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105353

Michel Dänzer  changed:

   What|Removed |Added

   Assignee|mesa-dev@lists.freedesktop. |dri-devel@lists.freedesktop
   |org |.org
  Component|Other   |Drivers/Gallium/radeonsi
 QA Contact|mesa-dev@lists.freedesktop. |dri-devel@lists.freedesktop
   |org |.org

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105352] [r600g] OpenGL ES fails to start on RV730

2018-03-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105352

--- Comment #1 from Michel Dänzer  ---
Does it run if you set the environment variable allow_rgb10_configs=false for
it? If so, it's probably a kwin bug, not handling 10 bit per component colour
format configs correctly.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC v3 10/12] drm/client: Add fbdev emulation client

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:51PM +0100, Noralf Trønnes wrote:
> This adds generic fbdev emulation for drivers that support the
> dumb buffer API. No fbdev code is necessary in the driver.
> 
> Differences from drm_fb_helper:
> - The backing buffer is created when the first fd is opened.
> - Supports changing the mode from userspace.
> - Doesn't restore on lastclose if there is no fd/fbcon open.
> - Supports changing the buffer size (yres_virtual) from userspace before
>   the fd is opened (double/trippel/... buffering).
> - Panning is only supported as page flipping, so no partial offset.
> - Supports real page flipping with FBIO_WAITFORVSYNC waiting on the
>   actual flip.
> - Supports framebuffer flushing for fbcon on buffers that doesn't support
>   fbdev deferred I/O (shmem). mmap doesn't work but fbcon does.
> 
> TODO:
> - suspend/resume
> - sysrq
> - Look more into plane format selection/support.
> - Need a way for the driver to say that it wants generic fbdev emulation.
>   The client .new hook is run in drm_dev_register() which is before
>   drivers set up fbdev themselves. So the client can't look at
>   drm_device->fb_helper to find out.

For fbdev I think the better option (given where we are right now) is to
integrate the generic buffer allocation support into the existing fbdev
helpers, as a default fb_probe implementation that allocates a suitable
buffer.

This has a bunch of upsides:
- integrates with existing s/r support
- integrates with existing driver load sequence, avoiding bugs and stuff
- integrates with existing module options and similar to disable fbdev
  (although they're all now generic and should be using the one Kconfig
  option we have for that).

Furthermore this gives drivers more flexibility of still overwriting parts
of the fbdev helpers. This is useful for drivers with a dirtyfb hook:
Because of the rather nasty nature of the defio tracking required by fbdev
mmap semantics it's better to disable dirtyfb for fbdev emulation (if
possible by the hardware), even if that costs some performance/incrases
power consumption. This is e.g. what we do for i915 - we simply disable
manual upload when switching to fbdev.

Of course for your panels you always need manual upload, so not a concern.

Reusing the existing fbdev code also means better continuity and
bisectability, which is Always Good (tm) in kernel land :-)

The only downside is that there's a bit more layering and it will take us
a bit longer until we reach the perfectly clean world for most drivers,
but that's just the usual price to pay.

For the other/new clients (bootsplash) I think using your ->new hooks
makes perfect sense.

> - Do we need to support FB_VISUAL_PSEUDOCOLOR?
> 
> TROUBLE:
> - fbcon can't handle fb_open returning an error, it just heads on. This
>   results in a NULL deref in fbcon_init(). fbcon/vt is awful when it
>   comes to error handling. It doesn't look to be easily fixed, so I guess
>   a buffer has to be pre-allocated to ensure health and safety.

Yup, we need to stick to the exact same logic as the current fbdev helpers
of allocating at init time, and then reusing the same buffer for
everything. The mmap stuff should all still work.
-Daniel

> 
> Signed-off-by: Noralf Trønnes 
> ---
>  drivers/gpu/drm/client/Kconfig |  16 +
>  drivers/gpu/drm/client/Makefile|   2 +
>  drivers/gpu/drm/client/drm_fbdev.c | 997 
> +
>  3 files changed, 1015 insertions(+)
>  create mode 100644 drivers/gpu/drm/client/drm_fbdev.c
> 
> diff --git a/drivers/gpu/drm/client/Kconfig b/drivers/gpu/drm/client/Kconfig
> index 4bb8e4655ff7..73902ab44c75 100644
> --- a/drivers/gpu/drm/client/Kconfig
> +++ b/drivers/gpu/drm/client/Kconfig
> @@ -1,4 +1,20 @@
>  menu "DRM Clients"
>   depends on DRM
>  
> +config DRM_CLIENT_FBDEV
> + tristate "Generic fbdev emulation"
> + depends on DRM
> + select FB
> + select FRAMEBUFFER_CONSOLE if !EXPERT
> + select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
> + select FB_SYS_FOPS
> + select FB_SYS_FILLRECT
> + select FB_SYS_COPYAREA
> + select FB_SYS_IMAGEBLIT
> + select FB_DEFERRED_IO
> + select FB_MODE_HELPERS
> + select VIDEOMODE_HELPERS
> + help
> +   Generic fbdev emulation
> +
>  endmenu
> diff --git a/drivers/gpu/drm/client/Makefile b/drivers/gpu/drm/client/Makefile
> index f66554cd5c45..3ff694429dec 100644
> --- a/drivers/gpu/drm/client/Makefile
> +++ b/drivers/gpu/drm/client/Makefile
> @@ -1 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_DRM_CLIENT_FBDEV) += drm_fbdev.o
> diff --git a/drivers/gpu/drm/client/drm_fbdev.c 
> b/drivers/gpu/drm/client/drm_fbdev.c
> new file mode 100644
> index ..e28416d72de1
> --- /dev/null
> +++ b/drivers/gpu/drm/client/drm_fbdev.c
> @@ -0,0 +1,997 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright 2018 Noralf Trønnes
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

Re: [PATCH 3/5] drm/ttm: move ttm_tt defines into ttm_tt.h

2018-03-06 Thread Christian König

Hi Michel & Thomas,

any more comments on this? Or can I commit it?

Thanks,
Christian.

Am 27.02.2018 um 12:49 schrieb Christian König:

Let's stop mangling everything in a single header and create one header
per object instead.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/ttm/ttm_tt.c|   6 -
  include/drm/ttm/ttm_bo_driver.h | 237 +-
  include/drm/ttm/ttm_tt.h| 272 
  3 files changed, 273 insertions(+), 242 deletions(-)
  create mode 100644 include/drm/ttm/ttm_tt.h

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 0ee3b8f11605..8e0b525cda00 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -31,17 +31,11 @@
  #define pr_fmt(fmt) "[TTM] " fmt
  
  #include 

-#include 
  #include 
  #include 
  #include 
-#include 
-#include 
-#include 
  #include 
-#include 
  #include 
-#include 
  #include 
  #ifdef CONFIG_X86
  #include 
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 4312b5326f0b..f8e2515b401f 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -42,111 +42,10 @@
  #include "ttm_memory.h"
  #include "ttm_module.h"
  #include "ttm_placement.h"
+#include "ttm_tt.h"
  
  #define TTM_MAX_BO_PRIORITY	4U
  
-struct ttm_backend_func {

-   /**
-* struct ttm_backend_func member bind
-*
-* @ttm: Pointer to a struct ttm_tt.
-* @bo_mem: Pointer to a struct ttm_mem_reg describing the
-* memory type and location for binding.
-*
-* Bind the backend pages into the aperture in the location
-* indicated by @bo_mem. This function should be able to handle
-* differences between aperture and system page sizes.
-*/
-   int (*bind) (struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
-
-   /**
-* struct ttm_backend_func member unbind
-*
-* @ttm: Pointer to a struct ttm_tt.
-*
-* Unbind previously bound backend pages. This function should be
-* able to handle differences between aperture and system page sizes.
-*/
-   int (*unbind) (struct ttm_tt *ttm);
-
-   /**
-* struct ttm_backend_func member destroy
-*
-* @ttm: Pointer to a struct ttm_tt.
-*
-* Destroy the backend. This will be call back from ttm_tt_destroy so
-* don't call ttm_tt_destroy from the callback or infinite loop.
-*/
-   void (*destroy) (struct ttm_tt *ttm);
-};
-
-#define TTM_PAGE_FLAG_WRITE   (1 << 3)
-#define TTM_PAGE_FLAG_SWAPPED (1 << 4)
-#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5)
-#define TTM_PAGE_FLAG_ZERO_ALLOC  (1 << 6)
-#define TTM_PAGE_FLAG_DMA32   (1 << 7)
-#define TTM_PAGE_FLAG_SG  (1 << 8)
-#define TTM_PAGE_FLAG_NO_RETRY   (1 << 9)
-
-enum ttm_caching_state {
-   tt_uncached,
-   tt_wc,
-   tt_cached
-};
-
-/**
- * struct ttm_tt
- *
- * @bdev: Pointer to a struct ttm_bo_device.
- * @func: Pointer to a struct ttm_backend_func that describes
- * the backend methods.
- * pointer.
- * @pages: Array of pages backing the data.
- * @num_pages: Number of pages in the page array.
- * @bdev: Pointer to the current struct ttm_bo_device.
- * @be: Pointer to the ttm backend.
- * @swap_storage: Pointer to shmem struct file for swap storage.
- * @caching_state: The current caching state of the pages.
- * @state: The current binding state of the pages.
- *
- * This is a structure holding the pages, caching- and aperture binding
- * status for a buffer object that isn't backed by fixed (VRAM / AGP)
- * memory.
- */
-
-struct ttm_tt {
-   struct ttm_bo_device *bdev;
-   struct ttm_backend_func *func;
-   struct page **pages;
-   uint32_t page_flags;
-   unsigned long num_pages;
-   struct sg_table *sg; /* for SG objects via dma-buf */
-   struct file *swap_storage;
-   enum ttm_caching_state caching_state;
-   enum {
-   tt_bound,
-   tt_unbound,
-   tt_unpopulated,
-   } state;
-};
-
-/**
- * struct ttm_dma_tt
- *
- * @ttm: Base ttm_tt struct.
- * @dma_address: The DMA (bus) addresses of the pages
- * @pages_list: used by some page allocation backend
- *
- * This is a structure holding the pages, caching- and aperture binding
- * status for a buffer object that isn't backed by fixed (VRAM / AGP)
- * memory.
- */
-struct ttm_dma_tt {
-   struct ttm_tt ttm;
-   dma_addr_t *dma_address;
-   struct list_head pages_list;
-};
-
  #define TTM_MEMTYPE_FLAG_FIXED (1 << 0) /* Fixed (on-card) PCI memory 
*/
  #define TTM_MEMTYPE_FLAG_MAPPABLE  (1 << 1) /* Memory mappable */
  #define TTM_MEMTYPE_FLAG_CMA   (1 << 3) /* Can't map aperture */
@@ -610,117 +509,6 @@ ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t 
mask)
return *old;
  }
  
-/**

- * ttm_tt_create
- *
-

Re: [RFC v3 11/12] drm/client: Add bootsplash client

2018-03-06 Thread Daniel Vetter
On Thu, Feb 22, 2018 at 09:06:52PM +0100, Noralf Trønnes wrote:
> Just a hack to test the client API.
> 
> Signed-off-by: Noralf Trønnes 

Adding the suse folks who submitted the bootsplash a while ago, would be
great if they could pick this up and run with it.

> ---
>  drivers/gpu/drm/client/Kconfig  |   5 +
>  drivers/gpu/drm/client/Makefile |   1 +
>  drivers/gpu/drm/client/drm_bootsplash.c | 205 
> 
>  3 files changed, 211 insertions(+)
>  create mode 100644 drivers/gpu/drm/client/drm_bootsplash.c
> 
> diff --git a/drivers/gpu/drm/client/Kconfig b/drivers/gpu/drm/client/Kconfig
> index 73902ab44c75..16cf1e14620a 100644
> --- a/drivers/gpu/drm/client/Kconfig
> +++ b/drivers/gpu/drm/client/Kconfig
> @@ -17,4 +17,9 @@ config DRM_CLIENT_FBDEV
>   help
> Generic fbdev emulation
>  
> +config DRM_CLIENT_BOOTSPLASH
> + tristate "DRM Bootsplash"
> + help
> +   DRM Bootsplash
> +
>  endmenu
> diff --git a/drivers/gpu/drm/client/Makefile b/drivers/gpu/drm/client/Makefile
> index 3ff694429dec..8660530e4646 100644
> --- a/drivers/gpu/drm/client/Makefile
> +++ b/drivers/gpu/drm/client/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
>  obj-$(CONFIG_DRM_CLIENT_FBDEV) += drm_fbdev.o
> +obj-$(CONFIG_DRM_CLIENT_BOOTSPLASH) += drm_bootsplash.o
> diff --git a/drivers/gpu/drm/client/drm_bootsplash.c 
> b/drivers/gpu/drm/client/drm_bootsplash.c
> new file mode 100644
> index ..43c703606e74
> --- /dev/null
> +++ b/drivers/gpu/drm/client/drm_bootsplash.c
> @@ -0,0 +1,205 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct drm_bootsplash {
> + struct drm_client_dev *client;
> + struct drm_client_display *display;
> + struct drm_client_buffer *buffer[2];
> + struct work_struct worker;
> + bool stop;
> +};
> +
> +static u32 drm_bootsplash_color_table[3] = {
> + 0x00ff, 0xff00, 0x00ff,
> +};
> +
> +/* Draw a box with changing colors */
> +static void
> +drm_bootsplash_draw(struct drm_client_buffer *buffer, unsigned int sequence)
> +{
> + unsigned int x, y;
> + u32 *pix;
> +
> + pix = buffer->vaddr;
> + pix += ((buffer->height / 2) - 50) * buffer->width;
> + pix += (buffer->width / 2) - 50;
> +
> + for (y = 0; y < 100; y++) {
> + for (x = 0; x < 100; x++)
> + *pix++ = drm_bootsplash_color_table[sequence];
> + pix += buffer->width - 100;
> + }
> +}
> +
> +static void drm_bootsplash_worker(struct work_struct *work)
> +{
> + struct drm_bootsplash *splash = container_of(work, struct 
> drm_bootsplash,
> +  worker);
> + struct drm_event *event;
> + unsigned int i = 0, sequence = 0, fb_id;
> + int ret;
> +
> + while (!splash->stop) {
> + /* Are we still in charge? */
> + fb_id = drm_client_display_current_fb(splash->display);
> + if (fb_id != splash->buffer[i]->fb_ids[0])
> + break;
> +
> + /*
> +  * We can race with userspace here between checking and doing
> +  * the page flip, so double buffering isn't such a good idea.
> +  * Tearing probably isn't a problem on a presumably small splash
> +  * animation. I've kept it to test the page flip code.
> +  */

I think a much cleaner way to solve all this is to tie it into our master
tracking. If there is a master (even if it's not displaying anything),
then none of the in-kernel clients should display anything.

If there is not, then we grab a temporary/weak master reference which
blocks other masters for the time being, but only until we've complete our
drawing operation. Then the in-kernel client drops that weak reference
again. A very simply solution would be to simply hold the device's master
lock (but I'm not sure whether that would result in deadlocks).

That would mean something like

if (!drm_master_try_internal_acquire())
/* someone else is master */
break;

here instead of your fb id check.
> +
> + i = !i;
> + drm_bootsplash_draw(splash->buffer[i], sequence++);
> + if (sequence == 3)
> + sequence = 0;
> +
> + ret = drm_client_display_page_flip(splash->display,
> +splash->buffer[i]->fb_ids[0],
> +true);
> + if (!ret) {
> + event = drm_client_read_event(splash->client, true);
> + if (!IS_ERR(event))
> + kfree(event);
> + }

And
drm_master_interal_relase()

here before we sleep again. Similar for all the fbdev i

Re: [PATCH 1/5] drm/prime: fix potential race in drm_gem_map_detach

2018-03-06 Thread Daniel Vetter
On Wed, Feb 28, 2018 at 11:25:59AM +0100, Christian König wrote:
> Am 28.02.2018 um 10:48 schrieb Lucas Stach:
> > Hi Christian,
> > 
> > Am Dienstag, den 27.02.2018, 12:49 +0100 schrieb Christian König:
> > > Unpin the GEM object only after freeing the sg table.
> > What is the race that is being fixed here? The SG table is private to
> > the importer and the importer should hopefully only call map_detach if
> > it is done with all operations using the SG table. Thus it shouldn't
> > matter that the SG table might point to moved pages during execution of
> > this function.
> 
> Exactly, it shouldn't matter. This is just a precaution.
> 
> When the device driver is buggy I want proper error messages from IOMMU and
> not accessing pages which might already be reused for something else.

Please add this to the commit message, rather crucial to understand the
motivation. With that fixed you can have my

Reviewed-by: Daniel Vetter 

And pls push to drm-misc.
-Daniel

> 
> Regards,
> Christian.
> 
> > 
> > Regards,
> > Lucas
> > 
> > > Signed-off-by: Christian König 
> > > ---
> > >   drivers/gpu/drm/drm_prime.c | 32 
> > >   1 file changed, 16 insertions(+), 16 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_prime.c
> > > b/drivers/gpu/drm/drm_prime.c
> > > index e82a976f0fba..c38dacda6119 100644
> > > --- a/drivers/gpu/drm/drm_prime.c
> > > +++ b/drivers/gpu/drm/drm_prime.c
> > > @@ -230,26 +230,26 @@ void drm_gem_map_detach(struct dma_buf
> > > *dma_buf,
> > >   struct drm_prime_attachment *prime_attach = attach->priv;
> > >   struct drm_gem_object *obj = dma_buf->priv;
> > >   struct drm_device *dev = obj->dev;
> > > - struct sg_table *sgt;
> > > - if (dev->driver->gem_prime_unpin)
> > > - dev->driver->gem_prime_unpin(obj);
> > > + if (prime_attach) {
> > > + struct sg_table *sgt = prime_attach->sgt;
> > > - if (!prime_attach)
> > > - return;
> > > -
> > > - sgt = prime_attach->sgt;
> > > - if (sgt) {
> > > - if (prime_attach->dir != DMA_NONE)
> > > - dma_unmap_sg_attrs(attach->dev, sgt->sgl,
> > > sgt->nents,
> > > -prime_attach->dir,
> > > -DMA_ATTR_SKIP_CPU_SYNC);
> > > - sg_free_table(sgt);
> > > + if (sgt) {
> > > + if (prime_attach->dir != DMA_NONE)
> > > + dma_unmap_sg_attrs(attach->dev, sgt-
> > > > sgl,
> > > +sgt->nents,
> > > +prime_attach-
> > > > dir,
> > > +DMA_ATTR_SKIP_CPU
> > > _SYNC);
> > > + sg_free_table(sgt);
> > > + }
> > > +
> > > + kfree(sgt);
> > > + kfree(prime_attach);
> > > + attach->priv = NULL;
> > >   }
> > > - kfree(sgt);
> > > - kfree(prime_attach);
> > > - attach->priv = NULL;
> > > + if (dev->driver->gem_prime_unpin)
> > > + dev->driver->gem_prime_unpin(obj);
> > >   }
> > >   EXPORT_SYMBOL(drm_gem_map_detach);
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Nouveau] [PATCH 4/5] drm/ttm: add ttm_sg_tt_init

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 01:07:06PM +0100, Christian König wrote:
> Hi guys,
> 
> at least on amdgpu and radeon the page array allocated by ttm_dma_tt_init is
> completely unused in the case of DMA-buf sharing. So I'm trying to get rid
> of that by only allocating the DMA address array.
> 
> Now the only other user of DMA-buf together with ttm_dma_tt_init is Nouveau.
> So my question is are you guys using the page array anywhere in your kernel
> driver in case of a DMA-buf sharing?
> 
> If no then I could just make this the default behavior for all drivers and
> save quite a bit of memory for everybody.

+1 on teaching ttm to no longer look at the struct page * in the dma-buf
sgt, but only the dma_buf address.

If there's still some need for in-kernel cpu or userspace mmap access then
imo ttm needs to be fixed to delegate all that to the right dma-buf
interfaces. The ttm abstraction is already there, it's just not passed
through.

I don't pretend to now enough of the details to review this stuff :-)
-Daniel

> 
> Thanks,
> Christian.
> 
> Am 27.02.2018 um 12:49 schrieb Christian König:
> > This allows drivers to only allocate dma addresses, but not a page
> > array.
> > 
> > Signed-off-by: Christian König 
> > ---
> >   drivers/gpu/drm/ttm/ttm_tt.c | 54 
> > 
> >   include/drm/ttm/ttm_tt.h |  2 ++
> >   2 files changed, 47 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
> > index 8e0b525cda00..971133106ec2 100644
> > --- a/drivers/gpu/drm/ttm/ttm_tt.c
> > +++ b/drivers/gpu/drm/ttm/ttm_tt.c
> > @@ -108,6 +108,16 @@ static int ttm_dma_tt_alloc_page_directory(struct 
> > ttm_dma_tt *ttm)
> > return 0;
> >   }
> > +static int ttm_sg_tt_alloc_page_directory(struct ttm_dma_tt *ttm)
> > +{
> > +   ttm->dma_address = kvmalloc_array(ttm->ttm.num_pages,
> > + sizeof(*ttm->dma_address),
> > + GFP_KERNEL | __GFP_ZERO);
> > +   if (!ttm->dma_address)
> > +   return -ENOMEM;
> > +   return 0;
> > +}
> > +
> >   #ifdef CONFIG_X86
> >   static inline int ttm_tt_set_page_caching(struct page *p,
> >   enum ttm_caching_state c_old,
> > @@ -227,8 +237,8 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
> > ttm->func->destroy(ttm);
> >   }
> > -int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
> > -   unsigned long size, uint32_t page_flags)
> > +void ttm_tt_init_fields(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
> > +   unsigned long size, uint32_t page_flags)
> >   {
> > ttm->bdev = bdev;
> > ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> > @@ -236,6 +246,12 @@ int ttm_tt_init(struct ttm_tt *ttm, struct 
> > ttm_bo_device *bdev,
> > ttm->page_flags = page_flags;
> > ttm->state = tt_unpopulated;
> > ttm->swap_storage = NULL;
> > +}
> > +
> > +int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev,
> > +   unsigned long size, uint32_t page_flags)
> > +{
> > +   ttm_tt_init_fields(ttm, bdev, size, page_flags);
> > if (ttm_tt_alloc_page_directory(ttm)) {
> > ttm_tt_destroy(ttm);
> > @@ -258,12 +274,7 @@ int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct 
> > ttm_bo_device *bdev,
> >   {
> > struct ttm_tt *ttm = &ttm_dma->ttm;
> > -   ttm->bdev = bdev;
> > -   ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> > -   ttm->caching_state = tt_cached;
> > -   ttm->page_flags = page_flags;
> > -   ttm->state = tt_unpopulated;
> > -   ttm->swap_storage = NULL;
> > +   ttm_tt_init_fields(ttm, bdev, size, page_flags);
> > INIT_LIST_HEAD(&ttm_dma->pages_list);
> > if (ttm_dma_tt_alloc_page_directory(ttm_dma)) {
> > @@ -275,11 +286,36 @@ int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, 
> > struct ttm_bo_device *bdev,
> >   }
> >   EXPORT_SYMBOL(ttm_dma_tt_init);
> > +int ttm_sg_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_bo_device *bdev,
> > +  unsigned long size, uint32_t page_flags)
> > +{
> > +   struct ttm_tt *ttm = &ttm_dma->ttm;
> > +   int ret;
> > +
> > +   ttm_tt_init_fields(ttm, bdev, size, page_flags);
> > +
> > +   INIT_LIST_HEAD(&ttm_dma->pages_list);
> > +   if (page_flags & TTM_PAGE_FLAG_SG)
> > +   ret = ttm_sg_tt_alloc_page_directory(ttm_dma);
> > +   else
> > +   ret = ttm_dma_tt_alloc_page_directory(ttm_dma);
> > +   if (ret) {
> > +   ttm_tt_destroy(ttm);
> > +   pr_err("Failed allocating page table\n");
> > +   return -ENOMEM;
> > +   }
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL(ttm_sg_tt_init);
> > +
> >   void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma)
> >   {
> > struct ttm_tt *ttm = &ttm_dma->ttm;
> > -   kvfree(ttm->pages);
> > +   if (ttm->pages)
> > +   kvfree(ttm->pages);
> > +   else
> > +   kvfree(ttm_dma->dma_address);
> > ttm->pages = NULL;
> > ttm_dma->dma_address = NULL;
> >

Re: [PATCH 2/5] drm/prime: make the pages array optional for drm_prime_sg_to_page_addr_arrays

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 12:49:57PM +0100, Christian König wrote:
> Most of the time we only need the dma addresses.
> 
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/drm_prime.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> index c38dacda6119..7856a9b3f8a8 100644
> --- a/drivers/gpu/drm/drm_prime.c
> +++ b/drivers/gpu/drm/drm_prime.c
> @@ -922,40 +922,40 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
>  /**
>   * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
>   * @sgt: scatter-gather table to convert
> - * @pages: array of page pointers to store the page array in
> + * @pages: optional array of page pointers to store the page array in
>   * @addrs: optional array to store the dma bus address of each page
> - * @max_pages: size of both the passed-in arrays
> + * @max_entries: size of both the passed-in arrays
>   *
>   * Exports an sg table into an array of pages and addresses. This is 
> currently
>   * required by the TTM driver in order to do correct fault handling.
>   */

Can't we just teach ttm to use sgts wherever needed, and deprecate
exporting dma-bufs to page arrays (which really breaks the abstraction
entirely and was just a quick hack to get things going that stuck around
for years). Last time I looked into ttm the only thing it did is convert
it back to sgts again (after calling dma_map once more, which the exporter
should have done already for you).
-Daniel

>  int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page 
> **pages,
> -  dma_addr_t *addrs, int max_pages)
> +  dma_addr_t *addrs, int max_entries)
>  {
>   unsigned count;
>   struct scatterlist *sg;
>   struct page *page;
> - u32 len;
> - int pg_index;
> + u32 len, index;
>   dma_addr_t addr;
>  
> - pg_index = 0;
> + index = 0;
>   for_each_sg(sgt->sgl, sg, sgt->nents, count) {
>   len = sg->length;
>   page = sg_page(sg);
>   addr = sg_dma_address(sg);
>  
>   while (len > 0) {
> - if (WARN_ON(pg_index >= max_pages))
> + if (WARN_ON(index >= max_entries))
>   return -1;
> - pages[pg_index] = page;
> + if (pages)
> + pages[index] = page;
>   if (addrs)
> - addrs[pg_index] = addr;
> + addrs[index] = addr;
>  
>   page++;
>   addr += PAGE_SIZE;
>   len -= PAGE_SIZE;
> - pg_index++;
> + index++;
>   }
>   }
>   return 0;
> -- 
> 2.14.1
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 105359] kms_frontbuffer_tracking - FBC disabled

2018-03-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=105359

Marta Löfstedt  changed:

   What|Removed |Added

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

--- Comment #3 from Marta Löfstedt  ---
Sent up an igt patch that will skip the test if FBC was disabled by previous
error.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/5] drm/prime: make the pages array optional for drm_prime_sg_to_page_addr_arrays

2018-03-06 Thread Christian König

Am 06.03.2018 um 10:21 schrieb Daniel Vetter:

On Tue, Feb 27, 2018 at 12:49:57PM +0100, Christian König wrote:

Most of the time we only need the dma addresses.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/drm_prime.c | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index c38dacda6119..7856a9b3f8a8 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -922,40 +922,40 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
  /**
   * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
   * @sgt: scatter-gather table to convert
- * @pages: array of page pointers to store the page array in
+ * @pages: optional array of page pointers to store the page array in
   * @addrs: optional array to store the dma bus address of each page
- * @max_pages: size of both the passed-in arrays
+ * @max_entries: size of both the passed-in arrays
   *
   * Exports an sg table into an array of pages and addresses. This is currently
   * required by the TTM driver in order to do correct fault handling.
   */

Can't we just teach ttm to use sgts wherever needed, and deprecate
exporting dma-bufs to page arrays (which really breaks the abstraction
entirely and was just a quick hack to get things going that stuck around
for years). Last time I looked into ttm the only thing it did is convert
it back to sgts again (after calling dma_map once more, which the exporter
should have done already for you).


Thought about that as well, but the problem here isn't TTM.

We need to be able to access the SGT by an index in amdgpu to be able to 
build up the VM page tables and that is not possible because the SGT is 
potentially chained.


We could add a new sg_table access helper function to work around that 
thought.


BTW: TTM isn't mapping anything in that case, we just fill in the arrays 
from the SGT.


Christian.


-Daniel


  int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page 
**pages,
-dma_addr_t *addrs, int max_pages)
+dma_addr_t *addrs, int max_entries)
  {
unsigned count;
struct scatterlist *sg;
struct page *page;
-   u32 len;
-   int pg_index;
+   u32 len, index;
dma_addr_t addr;
  
-	pg_index = 0;

+   index = 0;
for_each_sg(sgt->sgl, sg, sgt->nents, count) {
len = sg->length;
page = sg_page(sg);
addr = sg_dma_address(sg);
  
  		while (len > 0) {

-   if (WARN_ON(pg_index >= max_pages))
+   if (WARN_ON(index >= max_entries))
return -1;
-   pages[pg_index] = page;
+   if (pages)
+   pages[index] = page;
if (addrs)
-   addrs[pg_index] = addr;
+   addrs[index] = addr;
  
  			page++;

addr += PAGE_SIZE;
len -= PAGE_SIZE;
-   pg_index++;
+   index++;
}
}
return 0;
--
2.14.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 9/9] drm/xen-front: Implement communication with backend

2018-03-06 Thread Daniel Vetter
On Mon, Mar 05, 2018 at 11:30:35AM +0200, Oleksandr Andrushchenko wrote:
> On 03/05/2018 11:25 AM, Daniel Vetter wrote:
> > On Wed, Feb 21, 2018 at 10:03:42AM +0200, Oleksandr Andrushchenko wrote:
> > > From: Oleksandr Andrushchenko 
> > > 
> > > Handle communication with the backend:
> > >   - send requests and wait for the responses according
> > > to the displif protocol
> > >   - serialize access to the communication channel
> > >   - time-out used for backend communication is set to 3000 ms
> > >   - manage display buffers shared with the backend
> > > 
> > > Signed-off-by: Oleksandr Andrushchenko 
> > After the demidlayering it probably makes sense to merge this with the
> > overall kms/basic-drm-driver patch. Up to you really.
> The reason for such partitioning here and before was that
> I can have Xen/DRM parts separate, so those are easier for
> review by Xen/DRM communities. So, I would prefer to have it
> as it is

Well for reviewing the kms parts I need to check what the xen parts are
doing (at least sometimes), since semantics of what you're doing matter,
and there's a few cases which new drivers tend to get wrong. So for me,
this splitting makes stuff actually harder to review.

And I guess for the xen folks it won't hurt if they see a bit clearer how
it's used on the drm side (even if they might not really understand what's
going on). If we have some superficial abstraction in between each of the
subsystem maintainers might make assumptions about what the other side of
the code is doing which turn out to be wrong, and that's not good.

Just explaining my motivation for why I don't like abstractions and
splitting stuff up into patches that don't make much sense on their own
(because the code is just hanging out there without being wired up
anywhere).
-Daniel
> > -Daniel
> > > ---
> > >   drivers/gpu/drm/xen/xen_drm_front.c | 327 
> > > +++-
> > >   drivers/gpu/drm/xen/xen_drm_front.h |   5 +
> > >   2 files changed, 327 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/xen/xen_drm_front.c 
> > > b/drivers/gpu/drm/xen/xen_drm_front.c
> > > index 8de88e359d5e..5ad546231d30 100644
> > > --- a/drivers/gpu/drm/xen/xen_drm_front.c
> > > +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> > > @@ -31,12 +31,146 @@
> > >   #include "xen_drm_front_evtchnl.h"
> > >   #include "xen_drm_front_shbuf.h"
> > > +/* timeout in ms to wait for backend to respond */
> > > +#define VDRM_WAIT_BACK_MS3000
> > > +
> > > +struct xen_drm_front_dbuf {
> > > + struct list_head list;
> > > + uint64_t dbuf_cookie;
> > > + uint64_t fb_cookie;
> > > + struct xen_drm_front_shbuf *shbuf;
> > > +};
> > > +
> > > +static int dbuf_add_to_list(struct xen_drm_front_info *front_info,
> > > + struct xen_drm_front_shbuf *shbuf, uint64_t dbuf_cookie)
> > > +{
> > > + struct xen_drm_front_dbuf *dbuf;
> > > +
> > > + dbuf = kzalloc(sizeof(*dbuf), GFP_KERNEL);
> > > + if (!dbuf)
> > > + return -ENOMEM;
> > > +
> > > + dbuf->dbuf_cookie = dbuf_cookie;
> > > + dbuf->shbuf = shbuf;
> > > + list_add(&dbuf->list, &front_info->dbuf_list);
> > > + return 0;
> > > +}
> > > +
> > > +static struct xen_drm_front_dbuf *dbuf_get(struct list_head *dbuf_list,
> > > + uint64_t dbuf_cookie)
> > > +{
> > > + struct xen_drm_front_dbuf *buf, *q;
> > > +
> > > + list_for_each_entry_safe(buf, q, dbuf_list, list)
> > > + if (buf->dbuf_cookie == dbuf_cookie)
> > > + return buf;
> > > +
> > > + return NULL;
> > > +}
> > > +
> > > +static void dbuf_flush_fb(struct list_head *dbuf_list, uint64_t 
> > > fb_cookie)
> > > +{
> > > + struct xen_drm_front_dbuf *buf, *q;
> > > +
> > > + list_for_each_entry_safe(buf, q, dbuf_list, list)
> > > + if (buf->fb_cookie == fb_cookie)
> > > + xen_drm_front_shbuf_flush(buf->shbuf);
> > > +}
> > > +
> > > +static void dbuf_free(struct list_head *dbuf_list, uint64_t dbuf_cookie)
> > > +{
> > > + struct xen_drm_front_dbuf *buf, *q;
> > > +
> > > + list_for_each_entry_safe(buf, q, dbuf_list, list)
> > > + if (buf->dbuf_cookie == dbuf_cookie) {
> > > + list_del(&buf->list);
> > > + xen_drm_front_shbuf_unmap(buf->shbuf);
> > > + xen_drm_front_shbuf_free(buf->shbuf);
> > > + kfree(buf);
> > > + break;
> > > + }
> > > +}
> > > +
> > > +static void dbuf_free_all(struct list_head *dbuf_list)
> > > +{
> > > + struct xen_drm_front_dbuf *buf, *q;
> > > +
> > > + list_for_each_entry_safe(buf, q, dbuf_list, list) {
> > > + list_del(&buf->list);
> > > + xen_drm_front_shbuf_unmap(buf->shbuf);
> > > + xen_drm_front_shbuf_free(buf->shbuf);
> > > + kfree(buf);
> > > + }
> > > +}
> > > +
> > > +static struct xendispl_req *be_prepare_req(
> > > + struct xen_drm_front_evtchnl *evtchnl, uint8_t operation)
> > > +{
> > > + struct xendispl_req *req;
> > > +
> > > + req = RING_GET_REQUEST(&evtchn

[Bug 104064] (DC 4.15-rc2) WARNING: CPU: 4 PID: 75 at drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:601 dm_suspend+0x4e/0x60 [amdgpu]

2018-03-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=104064

--- Comment #25 from taij...@posteo.de ---
Created attachment 137816
  --> https://bugs.freedesktop.org/attachment.cgi?id=137816&action=edit
dmesg with 4.17-wip-7f462340284582c0180384c046ddd6dda03888b1 and dc=1

I have rebuilt with the latest commits to 4.17-wip (up to  
7f462340284582c0180384c046ddd6dda03888b1) and lo and behold: I was able to run
my usual DRI_PRIME=1 glxgears *without* the system crashing afterwards. So that
is quite a bit of progress. PM also seems to work, as battery drain is around
11W while composing this message, and noticeably higher only when explicitly
invoking the dGPU. Will test with dc=0 soon.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/5] drm/prime: fix potential race in drm_gem_map_detach

2018-03-06 Thread Christian König

Am 06.03.2018 um 10:15 schrieb Daniel Vetter:

On Wed, Feb 28, 2018 at 11:25:59AM +0100, Christian König wrote:

Am 28.02.2018 um 10:48 schrieb Lucas Stach:

Hi Christian,

Am Dienstag, den 27.02.2018, 12:49 +0100 schrieb Christian König:

Unpin the GEM object only after freeing the sg table.

What is the race that is being fixed here? The SG table is private to
the importer and the importer should hopefully only call map_detach if
it is done with all operations using the SG table. Thus it shouldn't
matter that the SG table might point to moved pages during execution of
this function.

Exactly, it shouldn't matter. This is just a precaution.

When the device driver is buggy I want proper error messages from IOMMU and
not accessing pages which might already be reused for something else.

Please add this to the commit message, rather crucial to understand the
motivation. With that fixed you can have my

Reviewed-by: Daniel Vetter 

And pls push to drm-misc.


Can I use standard git for that now? I really don't want to mess with 
dim in my environment.


Christian.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 11/11] drm: Sprinkle lockdep asserts for edid/display_info

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:57:00PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> edid and display_info are protected by mode_config.mutex. Add lockdep
> asserts to make sure we're not accessing things w/o the lock.
> 
> FIXME: pretty sure this will blow up with amdgpu as they seem
> to be doing edid updates even from the modeset path. Need to figure
> out what to do about that. Maybe protect the edid/display info with
> with connection_mutex instead of mode_config.mutex?

Imo not doing EDID udpates from the modeset path is the right fix. I can't
think of any reasonable reason to do that at least. Can you point me at
the relevant amdgpu code pls (I'm lazy, sry)?

Otherwise I think this is a real good patch.

Thanks, Daniel

> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Cc: Harry Wentland 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/drm_connector.c| 4 
>  drivers/gpu/drm/drm_edid.c | 2 ++
>  drivers/gpu/drm/drm_probe_helper.c | 2 +-
>  3 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 122060792b6f..a9f3536f4e94 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1374,6 +1374,8 @@ int drm_mode_connector_update_edid_property(struct 
> drm_connector *connector,
>   size_t size = 0;
>   int ret;
>  
> + lockdep_assert_held(&dev->mode_config.mutex);
> +
>   /* ignore requests to set edid when overridden */
>   if (connector->override_edid)
>   return 0;
> @@ -1770,6 +1772,8 @@ void drm_connector_reset_display_info(struct 
> drm_connector *connector)
>  {
>   struct drm_display_info *info = &connector->display_info;
>  
> + lockdep_assert_held(&connector->dev->mode_config.mutex);
> +
>   memset(info, 0, sizeof(*info));
>  }
>  EXPORT_SYMBOL_GPL(drm_connector_reset_display_info);
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 618093c4a039..7f9e9236114b 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4440,6 +4440,8 @@ u32 drm_add_display_info(struct drm_connector 
> *connector, const struct edid *edi
>   struct drm_display_info *info = &connector->display_info;
>   u32 quirks = edid_get_quirks(edid);
>  
> + lockdep_assert_held(&connector->dev->mode_config.mutex);
> +
>   info->width_mm = edid->width_cm * 10;
>   info->height_mm = edid->height_cm * 10;
>  
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 7dc7e635d7e4..2a2afcf72788 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -400,7 +400,7 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
>   enum drm_connector_status old_status;
>   struct drm_modeset_acquire_ctx ctx;
>  
> - WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
> + lockdep_assert_held(&dev->mode_config.mutex);
>  
>   drm_modeset_acquire_init(&ctx, 0);
>  
> -- 
> 2.13.6
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 05/11] drm/edid: Clear display info fully

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:54PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Now that we have split the display info into static and dynamic parts,
> we can just zero out the entire dynamic part with memset(). Previously
> we were just clearing parts of it, leaving stale data in other parts
> (eg. HDMI SCDC capabilities).
> 
> Also when the edid is NULL drm_add_edid_modes() bails out early skipping
> the call to drm_add_display_info(). Thus we would again leave stale
> data behind. To avoid that let's clear out the display info at the
> very start of drm_add_edid_modes().
> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Cc: Shashank Sharma 
> Signed-off-by: Ville Syrjälä 

I like the idea of this, but I think we need to refine it a bit. What
about only doing this for external screens, but not panels? That would
avoid a lot of surprises (there's really no need to reset the display info
for fixed panels ever), and also avoid the need for the first 3 patches in
your series.
-Daniel

> ---
>  drivers/gpu/drm/drm_connector.c |  3 +--
>  drivers/gpu/drm/drm_edid.c  | 23 +++
>  2 files changed, 4 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index d73e97ed7dff..ddd7d978f462 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1389,10 +1389,9 @@ int drm_mode_connector_update_edid_property(struct 
> drm_connector *connector,
>* duplicate it rather than attempt to ensure some arbitrary
>* ordering of calls.
>*/
> + drm_reset_display_info(connector);
>   if (edid)
>   drm_add_display_info(connector, edid);
> - else
> - drm_reset_display_info(connector);
>  
>   drm_object_property_set_value(&connector->base,
> dev->mode_config.non_desktop_property,
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 788fee4b4bf9..78c1f37be3db 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4443,37 +4443,18 @@ drm_reset_display_info(struct drm_connector 
> *connector)
>  {
>   struct drm_display_info *info = &connector->display_info;
>  
> - info->width_mm = 0;
> - info->height_mm = 0;
> -
> - info->bpc = 0;
> - info->color_formats = 0;
> - info->cea_rev = 0;
> - info->max_tmds_clock = 0;
> - info->dvi_dual = false;
> - info->has_hdmi_infoframe = false;
> -
> - info->non_desktop = 0;
> + memset(info, 0, sizeof(*info));
>  }
>  EXPORT_SYMBOL_GPL(drm_reset_display_info);
>  
>  u32 drm_add_display_info(struct drm_connector *connector, const struct edid 
> *edid)
>  {
>   struct drm_display_info *info = &connector->display_info;
> -
>   u32 quirks = edid_get_quirks(edid);
>  
>   info->width_mm = edid->width_cm * 10;
>   info->height_mm = edid->height_cm * 10;
>  
> - /* driver figures it out in this case */
> - info->bpc = 0;
> - info->color_formats = 0;
> - info->cea_rev = 0;
> - info->max_tmds_clock = 0;
> - info->dvi_dual = false;
> - info->has_hdmi_infoframe = false;
> -
>   info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
>  
>   DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
> @@ -4684,6 +4665,8 @@ int drm_add_edid_modes(struct drm_connector *connector, 
> struct edid *edid)
>   int num_modes = 0;
>   u32 quirks;
>  
> + drm_reset_display_info(connector);
> +
>   if (edid == NULL) {
>   clear_eld(connector);
>   return 0;
> -- 
> 2.13.6
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 104064] (DC 4.15-rc2) WARNING: CPU: 4 PID: 75 at drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:601 dm_suspend+0x4e/0x60 [amdgpu]

2018-03-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=104064

taij...@posteo.de changed:

   What|Removed |Added

 Attachment #137816|0   |1
is obsolete||

--- Comment #26 from taij...@posteo.de ---
Created attachment 137817
  --> https://bugs.freedesktop.org/attachment.cgi?id=137817&action=edit
dmesg with 4.17-wip-7f462340284582c0180384c046ddd6dda03888b1 and dc=1

OK, so maybe my enthusiasm was premature. I decided to do a second invocation
of the dGPU within the same session and this time it did crash shortly
thereafter. But, I was able to get some dmesg output first. Notice that on the
second invocation there are a bunch of snd_hda_intel bug messages, maybe those
have something to do with it?

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/5] drm/prime: make the pages array optional for drm_prime_sg_to_page_addr_arrays

2018-03-06 Thread Daniel Vetter
On Tue, Mar 06, 2018 at 10:25:03AM +0100, Christian König wrote:
> Am 06.03.2018 um 10:21 schrieb Daniel Vetter:
> > On Tue, Feb 27, 2018 at 12:49:57PM +0100, Christian König wrote:
> > > Most of the time we only need the dma addresses.
> > > 
> > > Signed-off-by: Christian König 
> > > ---
> > >   drivers/gpu/drm/drm_prime.c | 20 ++--
> > >   1 file changed, 10 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> > > index c38dacda6119..7856a9b3f8a8 100644
> > > --- a/drivers/gpu/drm/drm_prime.c
> > > +++ b/drivers/gpu/drm/drm_prime.c
> > > @@ -922,40 +922,40 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
> > >   /**
> > >* drm_prime_sg_to_page_addr_arrays - convert an sg table into a page 
> > > array
> > >* @sgt: scatter-gather table to convert
> > > - * @pages: array of page pointers to store the page array in
> > > + * @pages: optional array of page pointers to store the page array in
> > >* @addrs: optional array to store the dma bus address of each page
> > > - * @max_pages: size of both the passed-in arrays
> > > + * @max_entries: size of both the passed-in arrays
> > >*
> > >* Exports an sg table into an array of pages and addresses. This is 
> > > currently
> > >* required by the TTM driver in order to do correct fault handling.
> > >*/
> > Can't we just teach ttm to use sgts wherever needed, and deprecate
> > exporting dma-bufs to page arrays (which really breaks the abstraction
> > entirely and was just a quick hack to get things going that stuck around
> > for years). Last time I looked into ttm the only thing it did is convert
> > it back to sgts again (after calling dma_map once more, which the exporter
> > should have done already for you).
> 
> Thought about that as well, but the problem here isn't TTM.
> 
> We need to be able to access the SGT by an index in amdgpu to be able to
> build up the VM page tables and that is not possible because the SGT is
> potentially chained.
> 
> We could add a new sg_table access helper function to work around that
> thought.

There's some neat per-page sgt iter functions that we've build for i915.
See i915_gem_gtt.c. But yeah that's probably a pile more work, but imo
from the i915 code shuffling the end result looks fairly neat.
-Daniel
> 
> BTW: TTM isn't mapping anything in that case, we just fill in the arrays
> from the SGT.
> 
> Christian.
> 
> > -Daniel
> > 
> > >   int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page 
> > > **pages,
> > > -  dma_addr_t *addrs, int max_pages)
> > > +  dma_addr_t *addrs, int max_entries)
> > >   {
> > >   unsigned count;
> > >   struct scatterlist *sg;
> > >   struct page *page;
> > > - u32 len;
> > > - int pg_index;
> > > + u32 len, index;
> > >   dma_addr_t addr;
> > > - pg_index = 0;
> > > + index = 0;
> > >   for_each_sg(sgt->sgl, sg, sgt->nents, count) {
> > >   len = sg->length;
> > >   page = sg_page(sg);
> > >   addr = sg_dma_address(sg);
> > >   while (len > 0) {
> > > - if (WARN_ON(pg_index >= max_pages))
> > > + if (WARN_ON(index >= max_entries))
> > >   return -1;
> > > - pages[pg_index] = page;
> > > + if (pages)
> > > + pages[index] = page;
> > >   if (addrs)
> > > - addrs[pg_index] = addr;
> > > + addrs[index] = addr;
> > >   page++;
> > >   addr += PAGE_SIZE;
> > >   len -= PAGE_SIZE;
> > > - pg_index++;
> > > + index++;
> > >   }
> > >   }
> > >   return 0;
> > > -- 
> > > 2.14.1
> > > 
> > > ___
> > > dri-devel mailing list
> > > dri-devel@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/5] drm/prime: fix potential race in drm_gem_map_detach

2018-03-06 Thread Daniel Vetter
On Tue, Mar 06, 2018 at 10:30:56AM +0100, Christian König wrote:
> Am 06.03.2018 um 10:15 schrieb Daniel Vetter:
> > On Wed, Feb 28, 2018 at 11:25:59AM +0100, Christian König wrote:
> > > Am 28.02.2018 um 10:48 schrieb Lucas Stach:
> > > > Hi Christian,
> > > > 
> > > > Am Dienstag, den 27.02.2018, 12:49 +0100 schrieb Christian König:
> > > > > Unpin the GEM object only after freeing the sg table.
> > > > What is the race that is being fixed here? The SG table is private to
> > > > the importer and the importer should hopefully only call map_detach if
> > > > it is done with all operations using the SG table. Thus it shouldn't
> > > > matter that the SG table might point to moved pages during execution of
> > > > this function.
> > > Exactly, it shouldn't matter. This is just a precaution.
> > > 
> > > When the device driver is buggy I want proper error messages from IOMMU 
> > > and
> > > not accessing pages which might already be reused for something else.
> > Please add this to the commit message, rather crucial to understand the
> > motivation. With that fixed you can have my
> > 
> > Reviewed-by: Daniel Vetter 
> > 
> > And pls push to drm-misc.
> 
> Can I use standard git for that now? I really don't want to mess with dim in
> my environment.

Ping Alex to run it for you please. In an ideal world we'd run all that
stuff server-side, but that's not happening anytime soon.

Also if you have any specific issues about dim stomping over your setup,
we'll be happy to fix it. If you set the (relative) paths correctly you
can hide the various additional checkouts it needs rather well.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 04/11] drm: Split the display info into static and dynamic parts

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:53PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Currently we have a mix of static and dynamic information stored in
> the display info structure. That makes it rather difficult to repopulate
> the dynamic parts when a new EDID appears. Let's make life easier by
> splitting the structure up into static and dynamic parts.
> 
> The static part will consist of subpixel_order, panel_orientation,
> and bus_formats.
> 
> Actually I'm not sure where bus_formats & co. fit in all this. For some
> drivers those seem to be static, even though they might fill them out
> from .get_modes(). For other drivers this stuff even gets frobbed at
> runtime, making it more some kind of a bastard encoder/connector state.
> I'll just stick it into the static side so that the behaviour doesn't
> change when I start clear out the entire dynamic state with memset().

If we go with my suggestion for the next patch to not reset display info
for panels, then this problem disappears. Because all the stuff you
identified as static is relevant for panels, and for panels _everything_
is static.

I think with the next patch changed per my suggestion you could drop this
one here outright, and still retain all the benefits of your cleanup.
-Daniel
> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Cc: Hans de Goede 
> Cc: Shashank Sharma 
> Cc: Stefan Agner 
> Cc: Thierry Reding 
> Cc: Boris Brezillon 
> Cc: Philipp Zabel 
> Cc: Laurent Pinchart 
> Cc: Manfred Schlaegl 
> Cc: Marek Vasut 
> Cc: Archit Taneja 
> Cc: Andrzej Hajda 
> Cc: Alison Wang 
> Cc: Eric Anholt 
> Cc: Linus Walleij 
> Cc: linux-renesas-...@vger.kernel.org
> Cc: Maxime Ripard 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |   2 +-
>  drivers/gpu/drm/amd/amdgpu/dce_virtual.c   |   2 +-
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c |   2 +-
>  drivers/gpu/drm/bridge/sii902x.c   |   2 +-
>  drivers/gpu/drm/bridge/tc358767.c  |   2 +-
>  drivers/gpu/drm/drm_connector.c|  12 +-
>  drivers/gpu/drm/drm_fb_helper.c|   2 +-
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c |   2 +-
>  drivers/gpu/drm/gma500/cdv_intel_hdmi.c|   2 +-
>  drivers/gpu/drm/gma500/cdv_intel_lvds.c|   2 +-
>  drivers/gpu/drm/gma500/mdfld_dsi_output.c  |   2 +-
>  drivers/gpu/drm/gma500/oaktrail_hdmi.c |   2 +-
>  drivers/gpu/drm/gma500/oaktrail_lvds.c |   2 +-
>  drivers/gpu/drm/gma500/psb_intel_lvds.c|   2 +-
>  drivers/gpu/drm/gma500/psb_intel_sdvo.c|   2 +-
>  drivers/gpu/drm/i915/i915_debugfs.c|   2 +-
>  drivers/gpu/drm/i915/intel_dsi.c   |   4 +-
>  drivers/gpu/drm/i915/intel_dvo.c   |   2 +-
>  drivers/gpu/drm/i915/intel_lvds.c  |   2 +-
>  drivers/gpu/drm/i915/intel_sdvo.c  |   2 +-
>  drivers/gpu/drm/imx/imx-ldb.c  |   4 +-
>  drivers/gpu/drm/imx/parallel-display.c |   2 +-
>  drivers/gpu/drm/mxsfb/mxsfb_crtc.c |   6 +-
>  drivers/gpu/drm/panel/panel-arm-versatile.c|   2 +-
>  drivers/gpu/drm/panel/panel-ilitek-ili9322.c   |   8 +-
>  drivers/gpu/drm/panel/panel-lvds.c |   4 +-
>  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  |   2 +-
>  drivers/gpu/drm/panel/panel-seiko-43wvf1g.c|   4 +-
>  drivers/gpu/drm/panel/panel-simple.c   |   4 +-
>  drivers/gpu/drm/pl111/pl111_display.c  |   4 +-
>  drivers/gpu/drm/radeon/radeon_connectors.c |   4 +-
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.c  |   2 +-
>  drivers/gpu/drm/sun4i/sun4i_tcon.c |   4 +-
>  drivers/gpu/drm/tve200/tve200_display.c|   2 +-
>  drivers/gpu/drm/vc4/vc4_dpi.c  |   4 +-
>  include/drm/drm_connector.h| 123 
> -
>  36 files changed, 125 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> index 74d2efaec52f..1ba72dc2a85b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> @@ -1927,7 +1927,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
>   } else
>   connector->polled = DRM_CONNECTOR_POLL_HPD;
>  
> - connector->display_info.subpixel_order = subpixel_order;
> + connector->static_display_info.subpixel_order = subpixel_order;
>   drm_connector_register(connector);
>  
>   if (has_aux)
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c 
> b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> index 120dd3b26fc2..7e9f7f1ab1b1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> @@ -639,7 +639,7 @@ static int dce_virtual_connector_encoder_init(s

Re: [RFC][PATCH 05/11] drm/edid: Clear display info fully

2018-03-06 Thread Daniel Vetter
On Tue, Mar 06, 2018 at 10:33:31AM +0100, Daniel Vetter wrote:
> On Tue, Feb 27, 2018 at 02:56:54PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > Now that we have split the display info into static and dynamic parts,
> > we can just zero out the entire dynamic part with memset(). Previously
> > we were just clearing parts of it, leaving stale data in other parts
> > (eg. HDMI SCDC capabilities).
> > 
> > Also when the edid is NULL drm_add_edid_modes() bails out early skipping
> > the call to drm_add_display_info(). Thus we would again leave stale
> > data behind. To avoid that let's clear out the display info at the
> > very start of drm_add_edid_modes().
> > 
> > Cc: Keith Packard 
> > Cc: Daniel Vetter 
> > Cc: Shashank Sharma 
> > Signed-off-by: Ville Syrjälä 
> 
> I like the idea of this, but I think we need to refine it a bit. What
> about only doing this for external screens, but not panels? That would
> avoid a lot of surprises (there's really no need to reset the display info
> for fixed panels ever), and also avoid the need for the first 3 patches in
> your series.

Probably best to extract a drm_connector_is_panel function into
drm_connector.c for that, and also use it in
drm_helper_move_panel_connectors_to_head. Just to make sure we only have 1
definition of  what a panel is.
-Daniel

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/drm_connector.c |  3 +--
> >  drivers/gpu/drm/drm_edid.c  | 23 +++
> >  2 files changed, 4 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_connector.c 
> > b/drivers/gpu/drm/drm_connector.c
> > index d73e97ed7dff..ddd7d978f462 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1389,10 +1389,9 @@ int drm_mode_connector_update_edid_property(struct 
> > drm_connector *connector,
> >  * duplicate it rather than attempt to ensure some arbitrary
> >  * ordering of calls.
> >  */
> > +   drm_reset_display_info(connector);
> > if (edid)
> > drm_add_display_info(connector, edid);
> > -   else
> > -   drm_reset_display_info(connector);
> >  
> > drm_object_property_set_value(&connector->base,
> >   dev->mode_config.non_desktop_property,
> > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> > index 788fee4b4bf9..78c1f37be3db 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4443,37 +4443,18 @@ drm_reset_display_info(struct drm_connector 
> > *connector)
> >  {
> > struct drm_display_info *info = &connector->display_info;
> >  
> > -   info->width_mm = 0;
> > -   info->height_mm = 0;
> > -
> > -   info->bpc = 0;
> > -   info->color_formats = 0;
> > -   info->cea_rev = 0;
> > -   info->max_tmds_clock = 0;
> > -   info->dvi_dual = false;
> > -   info->has_hdmi_infoframe = false;
> > -
> > -   info->non_desktop = 0;
> > +   memset(info, 0, sizeof(*info));
> >  }
> >  EXPORT_SYMBOL_GPL(drm_reset_display_info);
> >  
> >  u32 drm_add_display_info(struct drm_connector *connector, const struct 
> > edid *edid)
> >  {
> > struct drm_display_info *info = &connector->display_info;
> > -
> > u32 quirks = edid_get_quirks(edid);
> >  
> > info->width_mm = edid->width_cm * 10;
> > info->height_mm = edid->height_cm * 10;
> >  
> > -   /* driver figures it out in this case */
> > -   info->bpc = 0;
> > -   info->color_formats = 0;
> > -   info->cea_rev = 0;
> > -   info->max_tmds_clock = 0;
> > -   info->dvi_dual = false;
> > -   info->has_hdmi_infoframe = false;
> > -
> > info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
> >  
> > DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
> > @@ -4684,6 +4665,8 @@ int drm_add_edid_modes(struct drm_connector 
> > *connector, struct edid *edid)
> > int num_modes = 0;
> > u32 quirks;
> >  
> > +   drm_reset_display_info(connector);
> > +
> > if (edid == NULL) {
> > clear_eld(connector);
> > return 0;
> > -- 
> > 2.13.6
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


reservation questions

2018-03-06 Thread Liu, Monk
Hi Christian & Chris

two question regarding resv:

1) considering below sequence:

call reservation_object_add_shared_fence,
now assume old->shared_count is now 3
call reservation_object_add_shared_fence,
now assume old->shared_count is now 4,

call reservation_object_reserve_shared,
now obj->staged is new allocated, and its shared_max = 8, but not
used by far.

call reservation_object_add_excl_fence,
it set obj->fence->shared_count to 0, and put all shared fence from obj->fence 
without waiting signaling.
(this action looks inappropriate, I think at least before put all those shared 
fences
we should dma_wait_fence() on them to make sure they are signaled)

call reservation_object_reserve_shared,
this time obj->staged isn't NULL, and it is freed (nothing bad now
since obj->fence points to other place),
and obj->staged set to NULL,

call reservation_object_add_shared_fence,
this time should going through reservation_object_add_shared_inplace,
But BUG_ON(old->shared_count >= old->shared_max) will hit !

This looks a design flaw in reservation object, shouldn't we fix it ?


2) in add_excl_fence(), it simply set old->shared_count to 0, and put all 
shared fences of old
is that correct? if excl fence is really exclusively used, why we still 
consider both shared fence and
excl fence on wait_timeout_rcu() routine, see blew description of this routine


/**
* reservation_object_wait_timeout_rcu - Wait on reservation's objects
* shared and/or exclusive fences.
* @obj: the reservation object
* @wait_all: if true, wait on all fences, else wait on just exclusive fence
* @intr: if true, do interruptible wait
* @timeout: timeout value in jiffies or zero to return immediately
*
* RETURNS
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
* greater than zer on success.
*/
long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
 bool wait_all, bool intr,
 unsigned long timeout)


thanks
/Monk




___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 9/9] drm/xen-front: Implement communication with backend

2018-03-06 Thread Oleksandr Andrushchenko

On 03/06/2018 11:26 AM, Daniel Vetter wrote:

On Mon, Mar 05, 2018 at 11:30:35AM +0200, Oleksandr Andrushchenko wrote:

On 03/05/2018 11:25 AM, Daniel Vetter wrote:

On Wed, Feb 21, 2018 at 10:03:42AM +0200, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Handle communication with the backend:
   - send requests and wait for the responses according
 to the displif protocol
   - serialize access to the communication channel
   - time-out used for backend communication is set to 3000 ms
   - manage display buffers shared with the backend

Signed-off-by: Oleksandr Andrushchenko 

After the demidlayering it probably makes sense to merge this with the
overall kms/basic-drm-driver patch. Up to you really.

The reason for such partitioning here and before was that
I can have Xen/DRM parts separate, so those are easier for
review by Xen/DRM communities. So, I would prefer to have it
as it is

Well for reviewing the kms parts I need to check what the xen parts are
doing (at least sometimes), since semantics of what you're doing matter,
and there's a few cases which new drivers tend to get wrong. So for me,
this splitting makes stuff actually harder to review.

And I guess for the xen folks it won't hurt if they see a bit clearer how
it's used on the drm side (even if they might not really understand what's
going on). If we have some superficial abstraction in between each of the
subsystem maintainers might make assumptions about what the other side of
the code is doing which turn out to be wrong, and that's not good.

Just explaining my motivation for why I don't like abstractions and
splitting stuff up into patches that don't make much sense on their own
(because the code is just hanging out there without being wired up
anywhere).

Ok, no problem here. Will squash relevant patches then

-Daniel

-Daniel

---
   drivers/gpu/drm/xen/xen_drm_front.c | 327 
+++-
   drivers/gpu/drm/xen/xen_drm_front.h |   5 +
   2 files changed, 327 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front.c 
b/drivers/gpu/drm/xen/xen_drm_front.c
index 8de88e359d5e..5ad546231d30 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -31,12 +31,146 @@
   #include "xen_drm_front_evtchnl.h"
   #include "xen_drm_front_shbuf.h"
+/* timeout in ms to wait for backend to respond */
+#define VDRM_WAIT_BACK_MS  3000
+
+struct xen_drm_front_dbuf {
+   struct list_head list;
+   uint64_t dbuf_cookie;
+   uint64_t fb_cookie;
+   struct xen_drm_front_shbuf *shbuf;
+};
+
+static int dbuf_add_to_list(struct xen_drm_front_info *front_info,
+   struct xen_drm_front_shbuf *shbuf, uint64_t dbuf_cookie)
+{
+   struct xen_drm_front_dbuf *dbuf;
+
+   dbuf = kzalloc(sizeof(*dbuf), GFP_KERNEL);
+   if (!dbuf)
+   return -ENOMEM;
+
+   dbuf->dbuf_cookie = dbuf_cookie;
+   dbuf->shbuf = shbuf;
+   list_add(&dbuf->list, &front_info->dbuf_list);
+   return 0;
+}
+
+static struct xen_drm_front_dbuf *dbuf_get(struct list_head *dbuf_list,
+   uint64_t dbuf_cookie)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list)
+   if (buf->dbuf_cookie == dbuf_cookie)
+   return buf;
+
+   return NULL;
+}
+
+static void dbuf_flush_fb(struct list_head *dbuf_list, uint64_t fb_cookie)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list)
+   if (buf->fb_cookie == fb_cookie)
+   xen_drm_front_shbuf_flush(buf->shbuf);
+}
+
+static void dbuf_free(struct list_head *dbuf_list, uint64_t dbuf_cookie)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list)
+   if (buf->dbuf_cookie == dbuf_cookie) {
+   list_del(&buf->list);
+   xen_drm_front_shbuf_unmap(buf->shbuf);
+   xen_drm_front_shbuf_free(buf->shbuf);
+   kfree(buf);
+   break;
+   }
+}
+
+static void dbuf_free_all(struct list_head *dbuf_list)
+{
+   struct xen_drm_front_dbuf *buf, *q;
+
+   list_for_each_entry_safe(buf, q, dbuf_list, list) {
+   list_del(&buf->list);
+   xen_drm_front_shbuf_unmap(buf->shbuf);
+   xen_drm_front_shbuf_free(buf->shbuf);
+   kfree(buf);
+   }
+}
+
+static struct xendispl_req *be_prepare_req(
+   struct xen_drm_front_evtchnl *evtchnl, uint8_t operation)
+{
+   struct xendispl_req *req;
+
+   req = RING_GET_REQUEST(&evtchnl->u.req.ring,
+   evtchnl->u.req.ring.req_prod_pvt);
+   req->operation = operation;
+   req->id = evtchnl->evt_next_id++;
+   evtchnl->evt_id = req->id;
+   return req;
+}
+
+static int be_stream_do_io(struct xen_drm_front_evtchnl *evtc

Re: [RFC][PATCH 06/11] drm/edid: Don't call drm_add_display_info() with an invalid EDID

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:55PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> drm_mode_connector_update_edid_property() will call
> drm_add_display_info() if an invalid edid is passed in.
> This differs from the behaviour of drm_add_edid_modes() which
> doesn't try to populate the display info from an invalid edid.
> Adjust drm_mode_connector_update_edid_property() to match that
> behaviour.
> 
> Unfortunately we have to pass the edid as non-const to
> drm_mode_connector_update_edid_property() because drm_edid_is_valid()
> may need to modify it :( Would be nice to one day fix up the EDID code
> to not do crazy things like that.

I guess we could put the EDID validation into the EDID reading helpers and
just pray that any fixed EDID (from vbt or wherever) is actually valid?

Meanwhile this makes sense to me.

Reviewed-by: Daniel Vetter 

> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/drm_connector.c | 4 ++--
>  include/drm/drm_connector.h | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index ddd7d978f462..d8c3ef4f17da 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1368,7 +1368,7 @@ EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
>   * Zero on success, negative errno on failure.
>   */
>  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> - const struct edid *edid)
> + struct edid *edid)
>  {
>   struct drm_device *dev = connector->dev;
>   size_t size = 0;
> @@ -1390,7 +1390,7 @@ int drm_mode_connector_update_edid_property(struct 
> drm_connector *connector,
>* ordering of calls.
>*/
>   drm_reset_display_info(connector);
> - if (edid)
> + if (edid && drm_edid_is_valid(edid))
>   drm_add_display_info(connector, edid);
>  
>   drm_object_property_set_value(&connector->base,
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index aad3258facf2..8815ef1ce429 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -1119,7 +1119,7 @@ int drm_mode_connector_set_path_property(struct 
> drm_connector *connector,
>const char *path);
>  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> - const struct edid *edid);
> + struct edid *edid);
>  void drm_mode_connector_set_link_status_property(struct drm_connector 
> *connector,
>uint64_t link_status);
>  int drm_connector_init_panel_orientation_property(
> -- 
> 2.13.6
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 07/11] drm/probe-helper: Avoid iterating the list twice on ww backoff

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:56PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> If we have to backoff there's no point in going over the mode list again
> to mark all the modes as stale. We can defer that until we're ready to
> refresh the mode list. Avoids multiple list walks if we have to do the
> locking backoff.
> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Signed-off-by: Ville Syrjälä 

Some drivers add modes from their ->detect callbacks I think, won't this
break them? At least I'm never sure about what different drivers are
supposed to do in each case.

Otoh the kerneldoc is fairly clear, and this patch is easy to revert, and
it might help in forcing drivers to be more consistent.

If you add a note about my concerns (as a hint in case we bisect a
regression to this patch), then this is:

Reviewed-by: Daniel Vetter 


> ---
>  drivers/gpu/drm/drm_probe_helper.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c 
> b/drivers/gpu/drm/drm_probe_helper.c
> index 527743394150..7dc7e635d7e4 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -415,10 +415,6 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
>   } else
>   WARN_ON(ret < 0);
>  
> - /* set all old modes to the stale state */
> - list_for_each_entry(mode, &connector->modes, head)
> - mode->status = MODE_STALE;
> -
>   old_status = connector->status;
>  
>   if (connector->force) {
> @@ -472,6 +468,10 @@ int drm_helper_probe_single_connector_modes(struct 
> drm_connector *connector,
>  
>   dev->mode_config.poll_running = drm_kms_helper_poll;
>  
> + /* set all old modes to the stale state */
> + list_for_each_entry(mode, &connector->modes, head)
> + mode->status = MODE_STALE;
> +
>   if (connector->status == connector_status_disconnected) {
>   DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
>   connector->base.id, connector->name);
> -- 
> 2.13.6
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 05/11] drm/edid: Clear display info fully

2018-03-06 Thread Daniel Vetter
On Tue, Mar 06, 2018 at 10:33:31AM +0100, Daniel Vetter wrote:
> On Tue, Feb 27, 2018 at 02:56:54PM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > Now that we have split the display info into static and dynamic parts,
> > we can just zero out the entire dynamic part with memset(). Previously
> > we were just clearing parts of it, leaving stale data in other parts
> > (eg. HDMI SCDC capabilities).
> > 
> > Also when the edid is NULL drm_add_edid_modes() bails out early skipping
> > the call to drm_add_display_info(). Thus we would again leave stale
> > data behind. To avoid that let's clear out the display info at the
> > very start of drm_add_edid_modes().
> > 
> > Cc: Keith Packard 
> > Cc: Daniel Vetter 
> > Cc: Shashank Sharma 
> > Signed-off-by: Ville Syrjälä 
> 
> I like the idea of this, but I think we need to refine it a bit. What
> about only doing this for external screens, but not panels? That would
> avoid a lot of surprises (there's really no need to reset the display info
> for fixed panels ever), and also avoid the need for the first 3 patches in
> your series.

Just realized I replied to the wrong patch, this was meant for the forced
clearing of all display_info data in one of the later patches. But it is
also somewhat relevant here ...
-Daniel

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/drm_connector.c |  3 +--
> >  drivers/gpu/drm/drm_edid.c  | 23 +++
> >  2 files changed, 4 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_connector.c 
> > b/drivers/gpu/drm/drm_connector.c
> > index d73e97ed7dff..ddd7d978f462 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1389,10 +1389,9 @@ int drm_mode_connector_update_edid_property(struct 
> > drm_connector *connector,
> >  * duplicate it rather than attempt to ensure some arbitrary
> >  * ordering of calls.
> >  */
> > +   drm_reset_display_info(connector);
> > if (edid)
> > drm_add_display_info(connector, edid);
> > -   else
> > -   drm_reset_display_info(connector);
> >  
> > drm_object_property_set_value(&connector->base,
> >   dev->mode_config.non_desktop_property,
> > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> > index 788fee4b4bf9..78c1f37be3db 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4443,37 +4443,18 @@ drm_reset_display_info(struct drm_connector 
> > *connector)
> >  {
> > struct drm_display_info *info = &connector->display_info;
> >  
> > -   info->width_mm = 0;
> > -   info->height_mm = 0;
> > -
> > -   info->bpc = 0;
> > -   info->color_formats = 0;
> > -   info->cea_rev = 0;
> > -   info->max_tmds_clock = 0;
> > -   info->dvi_dual = false;
> > -   info->has_hdmi_infoframe = false;
> > -
> > -   info->non_desktop = 0;
> > +   memset(info, 0, sizeof(*info));
> >  }
> >  EXPORT_SYMBOL_GPL(drm_reset_display_info);
> >  
> >  u32 drm_add_display_info(struct drm_connector *connector, const struct 
> > edid *edid)
> >  {
> > struct drm_display_info *info = &connector->display_info;
> > -
> > u32 quirks = edid_get_quirks(edid);
> >  
> > info->width_mm = edid->width_cm * 10;
> > info->height_mm = edid->height_cm * 10;
> >  
> > -   /* driver figures it out in this case */
> > -   info->bpc = 0;
> > -   info->color_formats = 0;
> > -   info->cea_rev = 0;
> > -   info->max_tmds_clock = 0;
> > -   info->dvi_dual = false;
> > -   info->has_hdmi_infoframe = false;
> > -
> > info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
> >  
> > DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
> > @@ -4684,6 +4665,8 @@ int drm_add_edid_modes(struct drm_connector 
> > *connector, struct edid *edid)
> > int num_modes = 0;
> > u32 quirks;
> >  
> > +   drm_reset_display_info(connector);
> > +
> > if (edid == NULL) {
> > clear_eld(connector);
> > return 0;
> > -- 
> > 2.13.6
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic Meson GX SoCs

2018-03-06 Thread Neil Armstrong
Hi Architt,

On 23/02/2018 12:44, Neil Armstrong wrote:
> The Amlogic Meson GX SoCs, embedded the v2.01a controller, has been also
> identified needing this workaround.
> This patch adds the corresponding version to enable a single iteration for
> this specific version.
> 
> Fixes: be41fc55f1aa ("drm: bridge: dw-hdmi: Handle overflow workaround based 
> on device version")
> Signed-off-by: Neil Armstrong 
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index a38db40..f5018f9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1637,6 +1637,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
>* (and possibly on the platform). So far only i.MX6Q (v1.30a) and
>* i.MX6DL (v1.31a) have been identified as needing the workaround, with
>* 4 and 1 iterations respectively.
> +  * The Amlogic Meson GX SoCs (v2.01a) have been identifies as needing
> +  * the workaround with a single iteration.
>*/
>  
>   switch (hdmi->version) {
> @@ -1644,6 +1646,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
>   count = 4;
>   break;
>   case 0x131a:
> + case 0x201a:
>   count = 1;
>   break;
>   default:
> 

This fixes a long time issue on Amlogic SoCs, is it ok for you ?

Thanks,
Neil
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 09/11] drm: Fix getconnector locking

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:58PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> The edid is protected by mode_config.mutex so extend the locking to
> protect the property readout part as well.
> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Signed-off-by: Ville Syrjälä 

Ehrm no, properties have their own locking and are safe.
drm_connector->edid is indeed protected by the mode_config.mutex, but
that's not the thing we're looking at here. Maybe we need to patch up the
struct drm_connector locking comments a bit to clarify this more?
-Daniel

> ---
>  drivers/gpu/drm/drm_connector.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 2bf19a37dbac..122060792b6f 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1624,15 +1624,12 @@ int drm_mode_getconnector(struct drm_device *dev, 
> void *data,
>   if (copy_to_user(mode_ptr + copied,
>&u_mode, sizeof(u_mode))) {
>   ret = -EFAULT;
> - mutex_unlock(&dev->mode_config.mutex);
> -
>   goto out;
>   }
>   copied++;
>   }
>   }
>   out_resp->count_modes = mode_count;
> - mutex_unlock(&dev->mode_config.mutex);
>  
>   drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
>   encoder = drm_connector_get_encoder(connector);
> @@ -1650,6 +1647,8 @@ int drm_mode_getconnector(struct drm_device *dev, void 
> *data,
>   drm_modeset_unlock(&dev->mode_config.connection_mutex);
>  
>  out:
> + mutex_unlock(&dev->mode_config.mutex);
> +
>   drm_connector_put(connector);
>  
>   return ret;
> -- 
> 2.13.6
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 3/5] drm/ttm: move ttm_tt defines into ttm_tt.h

2018-03-06 Thread Michel Dänzer
On 2018-03-06 10:13 AM, Christian König wrote:
> Hi Michel & Thomas,
> 
> any more comments on this? Or can I commit it?

Acked-by: Michel Dänzer 


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: reservation questions

2018-03-06 Thread Liu, Monk

sorry, I have some mistake in previous thread, correct it as followings.

1) considering below sequence:

call reservation_object_add_shared_fence,
now assume old->shared_count is now 3
call reservation_object_add_shared_fence,
now assume old->shared_count is now 4,

call reservation_object_reserve_shared,
now obj->staged is new allocated, and its shared_max = 8, but not
used by far.

call reservation_object_add_excl_fence,
it set obj->fence->shared_count to 0, and put all shared fence from obj->fence 
without waiting signaling.
(this action looks inappropriate, I think at least before put all those shared 
fences
we should dma_wait_fence() on them to make sure they are signaled)

call reservation_object_reserve_shared,
this time obj->staged isn't NULL, and it is freed (nothing bad now
since obj->fence points to other place),
and obj->staged set to NULL,

call reservation_object_add_shared_fence,
this time should going through reservation_object_add_shared_inplace,
since old->shared_count is 1 now, during reservation_object_add_shared_inplace()
it would go through the shared list, but the fence in shared list is now wild 
pointer:
for (i = 0; i < fobj->shared_count; ++i) {
struct dma_fence *old_fence;

old_fence = rcu_dereference_protected(fobj->shared[i],
reservation_object_held(obj));

if (old_fence->context == fence->context &&
dma_fence_is_later(fence, old_fence)) {
/* memory barrier is added by write_seqcount_begin */
RCU_INIT_POINTER(fobj->shared[i], fence);
write_seqcount_end(&obj->seq);
preempt_enable();

dma_fence_put(old_fence);
return;
}

if (!signaled && dma_fence_is_signaled(old_fence)) {
signaled = old_fence;
signaled_idx = i;
}
}

see that old_fence is get from fobj, and fobj is from 
reservation_object_get_list(obj)
in outside, which is obj->fence, and in add_excl_fence, all dma_fence in
obj->fence is already put.

/Monk




From: Liu, Monk
Sent: Tuesday, March 6, 2018 5:45:19 PM
To: dri-devel@lists.freedesktop.org; Chris Wilson; Koenig, Christian
Subject: reservation questions


Hi Christian & Chris

two question regarding resv:

1) considering below sequence:

call reservation_object_add_shared_fence,
now assume old->shared_count is now 3
call reservation_object_add_shared_fence,
now assume old->shared_count is now 4,

call reservation_object_reserve_shared,
now obj->staged is new allocated, and its shared_max = 8, but not
used by far.

call reservation_object_add_excl_fence,
it set obj->fence->shared_count to 0, and put all shared fence from obj->fence 
without waiting signaling.
(this action looks inappropriate, I think at least before put all those shared 
fences
we should dma_wait_fence() on them to make sure they are signaled)

call reservation_object_reserve_shared,
this time obj->staged isn't NULL, and it is freed (nothing bad now
since obj->fence points to other place),
and obj->staged set to NULL,

call reservation_object_add_shared_fence,
this time should going through reservation_object_add_shared_inplace,
But BUG_ON(old->shared_count >= old->shared_max) will hit !

This looks a design flaw in reservation object, shouldn't we fix it ?


2) in add_excl_fence(), it simply set old->shared_count to 0, and put all 
shared fences of old
is that correct? if excl fence is really exclusively used, why we still 
consider both shared fence and
excl fence on wait_timeout_rcu() routine, see blew description of this routine


/**
* reservation_object_wait_timeout_rcu - Wait on reservation's objects
* shared and/or exclusive fences.
* @obj: the reservation object
* @wait_all: if true, wait on all fences, else wait on just exclusive fence
* @intr: if true, do interruptible wait
* @timeout: timeout value in jiffies or zero to return immediately
*
* RETURNS
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
* greater than zer on success.
*/
long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
 bool wait_all, bool intr,
 unsigned long timeout)


thanks
/Monk




___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 10/11] drm: Fix debugfs edid_override locking

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:59PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> The edid is protected by mode_config.mutex. Grab the lock when frobbing
> the debugfs edid_override thing.
> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Signed-off-by: Ville Syrjälä 

Yup, this looks correct. A kerneldoc patch to update the locking rules
would be great.

Reviewed-by: Daniel Vetter 

> ---
>  drivers/gpu/drm/drm_debugfs.c | 12 +++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index b2482818fee8..caac17145629 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -275,11 +275,17 @@ static ssize_t connector_write(struct file *file, const 
> char __user *ubuf,
>  static int edid_show(struct seq_file *m, void *data)
>  {
>   struct drm_connector *connector = m->private;
> - struct drm_property_blob *edid = connector->edid_blob_ptr;
> + struct drm_property_blob *edid;
> +
> + mutex_lock(&connector->dev->mode_config.mutex);
> +
> + edid = connector->edid_blob_ptr;
>  
>   if (connector->override_edid && edid)
>   seq_write(m, edid->data, edid->length);
>  
> + mutex_unlock(&connector->dev->mode_config.mutex);
> +
>   return 0;
>  }
>  
> @@ -305,6 +311,8 @@ static ssize_t edid_write(struct file *file, const char 
> __user *ubuf,
>  
>   edid = (struct edid *) buf;
>  
> + mutex_lock(&connector->dev->mode_config.mutex);
> +
>   if (len == 5 && !strncmp(buf, "reset", 5)) {
>   connector->override_edid = false;
>   ret = drm_mode_connector_update_edid_property(connector, NULL);
> @@ -318,6 +326,8 @@ static ssize_t edid_write(struct file *file, const char 
> __user *ubuf,
>   connector->override_edid = true;
>   }
>  
> + mutex_unlock(&connector->dev->mode_config.mutex);
> +
>   kfree(buf);
>  
>   return (ret) ? ret : len;
> -- 
> 2.13.6
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC][PATCH 08/11] drm: Add drm_connector_fill_modes()

2018-03-06 Thread Daniel Vetter
On Tue, Feb 27, 2018 at 02:56:57PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Wrap the ->fill_modes() call in a small helper that first clears out the
> stale data from connector->display_info. This should guarantee that we
> get consistent display_info whether or not the drivers use the EDID
> based stuff to clear and fill it.
> 
> TODO: what about just after init, before anyone has called
> ->fill_modes()? In that case userspace could see stale data if they do
> the cheap getconnector ioctl. Not sure if that's a valid concern though.
> 
> Cc: Keith Packard 
> Cc: Daniel Vetter 
> Signed-off-by: Ville Syrjälä 

Some thoughts:
- I think unconditionally resetting for panels is the wrong thing to do.
- We're not resetting in even more places, can't we just condense them all
  down to 1?
- I'm undecided on whether this should be in the core, or in the helpers.
  Atm the core is the one that implements the "just give me the current
  mode list, don't reprobe" logic, but then we punt everything else to
  ->fill_modes (including setting all modes to stale and all that stuff).
  I'm slightly leaning towards doing this in the helper code, not the core
  code. Any reasons for doing this in core?

Cheers, Daniel
> ---
>  drivers/gpu/drm/drm_connector.c | 44 
> +
>  drivers/gpu/drm/drm_edid.c  | 14 +
>  drivers/gpu/drm/drm_fb_helper.c |  2 +-
>  drivers/gpu/drm/drm_sysfs.c |  6 +++---
>  include/drm/drm_connector.h |  3 +++
>  include/drm/drm_edid.h  |  1 -
>  6 files changed, 48 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index d8c3ef4f17da..2bf19a37dbac 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1389,7 +1389,7 @@ int drm_mode_connector_update_edid_property(struct 
> drm_connector *connector,
>* duplicate it rather than attempt to ensure some arbitrary
>* ordering of calls.
>*/
> - drm_reset_display_info(connector);
> + drm_connector_reset_display_info(connector);
>   if (edid && drm_edid_is_valid(edid))
>   drm_add_display_info(connector, edid);
>  
> @@ -1594,9 +1594,9 @@ int drm_mode_getconnector(struct drm_device *dev, void 
> *data,
>  
>   mutex_lock(&dev->mode_config.mutex);
>   if (out_resp->count_modes == 0) {
> - connector->funcs->fill_modes(connector,
> -  dev->mode_config.max_width,
> -  dev->mode_config.max_height);
> + drm_connector_fill_modes(connector,
> +  dev->mode_config.max_width,
> +  dev->mode_config.max_height);
>   }
>  
>   out_resp->mm_width = connector->display_info.width_mm;
> @@ -1759,3 +1759,39 @@ struct drm_tile_group 
> *drm_mode_create_tile_group(struct drm_device *dev,
>   return tg;
>  }
>  EXPORT_SYMBOL(drm_mode_create_tile_group);
> +
> +/**
> + * drm_connector_reset_display_info - reset the connector's display info
> + * @connector: DRM connector
> + *
> + * Clear the old display info for @connector allowing the driver to
> + * repopulate it based on fresh data.
> + */
> +void drm_connector_reset_display_info(struct drm_connector *connector)
> +{
> + struct drm_display_info *info = &connector->display_info;
> +
> + memset(info, 0, sizeof(*info));
> +}
> +EXPORT_SYMBOL_GPL(drm_connector_reset_display_info);
> +
> +/**
> + * drm_connector_fill_modes - fill connector mode list and dynamic display 
> info
> + * @connector: DRM connector
> + * @max_width: max width for modes
> + * @max_height: max height for modes
> + *
> + * Reset the display info and calls &drm_connector_funcs.fill_modes() vfunc
> + * repopulate it and and the mode list.
> + *
> + * RETURNS:
> + * The number of modes found on @connector.
> + */
> +int drm_connector_fill_modes(struct drm_connector *connector,
> +  unsigned int max_width, unsigned int max_height)
> +{
> + drm_connector_reset_display_info(connector);
> +
> + return connector->funcs->fill_modes(connector, max_width, max_height);
> +}
> +EXPORT_SYMBOL(drm_connector_fill_modes);
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 78c1f37be3db..618093c4a039 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4435,18 +4435,6 @@ static void drm_parse_cea_ext(struct drm_connector 
> *connector,
>   }
>  }
>  
> -/* A connector has no EDID information, so we've got no EDID to compute 
> quirks from. Reset
> - * all of the values which would have been set from EDID
> - */
> -void
> -drm_reset_display_info(struct drm_connector *connector)
> -{
> - struct drm_display_info *info = &connector->display_info;
> -
> - memset(info, 0, sizeof(*info));
> -}
> -EXPORT_SYMBOL_GPL(drm_reset_display_info);
> -
>  u32 drm_a

Re: [PATCH 3/5] drm/ttm: move ttm_tt defines into ttm_tt.h

2018-03-06 Thread Thomas Hellstrom

Acked-by: Thomas Hellstrom 

On 03/06/2018 10:13 AM, Christian König wrote:

Hi Michel & Thomas,

any more comments on this? Or can I commit it?

Thanks,
Christian.

Am 27.02.2018 um 12:49 schrieb Christian König:

Let's stop mangling everything in a single header and create one header
per object instead.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/ttm/ttm_tt.c    |   6 -
  include/drm/ttm/ttm_bo_driver.h | 237 
+-
  include/drm/ttm/ttm_tt.h    | 272 


  3 files changed, 273 insertions(+), 242 deletions(-)
  create mode 100644 include/drm/ttm/ttm_tt.h

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 0ee3b8f11605..8e0b525cda00 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -31,17 +31,11 @@
  #define pr_fmt(fmt) "[TTM] " fmt
    #include 
-#include 
  #include 
  #include 
  #include 
-#include 
-#include 
-#include 
  #include 
-#include 
  #include 
-#include 
  #include 
  #ifdef CONFIG_X86
  #include 
diff --git a/include/drm/ttm/ttm_bo_driver.h 
b/include/drm/ttm/ttm_bo_driver.h

index 4312b5326f0b..f8e2515b401f 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -42,111 +42,10 @@
  #include "ttm_memory.h"
  #include "ttm_module.h"
  #include "ttm_placement.h"
+#include "ttm_tt.h"
    #define TTM_MAX_BO_PRIORITY    4U
  -struct ttm_backend_func {
-    /**
- * struct ttm_backend_func member bind
- *
- * @ttm: Pointer to a struct ttm_tt.
- * @bo_mem: Pointer to a struct ttm_mem_reg describing the
- * memory type and location for binding.
- *
- * Bind the backend pages into the aperture in the location
- * indicated by @bo_mem. This function should be able to handle
- * differences between aperture and system page sizes.
- */
-    int (*bind) (struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
-
-    /**
- * struct ttm_backend_func member unbind
- *
- * @ttm: Pointer to a struct ttm_tt.
- *
- * Unbind previously bound backend pages. This function should be
- * able to handle differences between aperture and system page 
sizes.

- */
-    int (*unbind) (struct ttm_tt *ttm);
-
-    /**
- * struct ttm_backend_func member destroy
- *
- * @ttm: Pointer to a struct ttm_tt.
- *
- * Destroy the backend. This will be call back from 
ttm_tt_destroy so

- * don't call ttm_tt_destroy from the callback or infinite loop.
- */
-    void (*destroy) (struct ttm_tt *ttm);
-};
-
-#define TTM_PAGE_FLAG_WRITE   (1 << 3)
-#define TTM_PAGE_FLAG_SWAPPED (1 << 4)
-#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5)
-#define TTM_PAGE_FLAG_ZERO_ALLOC  (1 << 6)
-#define TTM_PAGE_FLAG_DMA32   (1 << 7)
-#define TTM_PAGE_FLAG_SG  (1 << 8)
-#define TTM_PAGE_FLAG_NO_RETRY  (1 << 9)
-
-enum ttm_caching_state {
-    tt_uncached,
-    tt_wc,
-    tt_cached
-};
-
-/**
- * struct ttm_tt
- *
- * @bdev: Pointer to a struct ttm_bo_device.
- * @func: Pointer to a struct ttm_backend_func that describes
- * the backend methods.
- * pointer.
- * @pages: Array of pages backing the data.
- * @num_pages: Number of pages in the page array.
- * @bdev: Pointer to the current struct ttm_bo_device.
- * @be: Pointer to the ttm backend.
- * @swap_storage: Pointer to shmem struct file for swap storage.
- * @caching_state: The current caching state of the pages.
- * @state: The current binding state of the pages.
- *
- * This is a structure holding the pages, caching- and aperture binding
- * status for a buffer object that isn't backed by fixed (VRAM / AGP)
- * memory.
- */
-
-struct ttm_tt {
-    struct ttm_bo_device *bdev;
-    struct ttm_backend_func *func;
-    struct page **pages;
-    uint32_t page_flags;
-    unsigned long num_pages;
-    struct sg_table *sg; /* for SG objects via dma-buf */
-    struct file *swap_storage;
-    enum ttm_caching_state caching_state;
-    enum {
-    tt_bound,
-    tt_unbound,
-    tt_unpopulated,
-    } state;
-};
-
-/**
- * struct ttm_dma_tt
- *
- * @ttm: Base ttm_tt struct.
- * @dma_address: The DMA (bus) addresses of the pages
- * @pages_list: used by some page allocation backend
- *
- * This is a structure holding the pages, caching- and aperture binding
- * status for a buffer object that isn't backed by fixed (VRAM / AGP)
- * memory.
- */
-struct ttm_dma_tt {
-    struct ttm_tt ttm;
-    dma_addr_t *dma_address;
-    struct list_head pages_list;
-};
-
  #define TTM_MEMTYPE_FLAG_FIXED (1 << 0)    /* Fixed 
(on-card) PCI memory */
  #define TTM_MEMTYPE_FLAG_MAPPABLE  (1 << 1)    /* Memory 
mappable */
  #define TTM_MEMTYPE_FLAG_CMA   (1 << 3)    /* Can't map 
aperture */
@@ -610,117 +509,6 @@ ttm_flag_masked(uint32_t *old, uint32_t new, 
uint32_t mask)

  return *old;
  }
  -/**
- * ttm_tt_create
- *
- * @bo: pointer to a struct ttm_buffer_object
- * @zero_alloc: t

  1   2   3   4   >