[Bug 120591] BUG() in dmesg after loading nouveau module

2016-06-24 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=120591

Dmitrii Tcvetkov  changed:

   What|Removed |Added

 Status|RESOLVED|CLOSED

--- Comment #8 from Dmitrii Tcvetkov  ---
commit 52dfcc5ccfbb6697ac3cac7f7ff1e712760e1216
Author: Dmitrii Tcvetkov 
Date:   Mon Jun 20 13:52:14 2016 +0300

drm/nouveau: fix for disabled fbdev emulation

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


[PATCH 1/2] drm/ttm: fix stupid parameter inversion in the pipeline code

2016-06-24 Thread Christian König
From: Christian König 

We want to keep the newest fence, not the oldest one.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c 
b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 0c389a5..4da0e78 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -753,7 +753,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,
 */

spin_lock(>move_lock);
-   if (!from->move || fence_is_later(from->move, fence)) {
+   if (!from->move || fence_is_later(fence, from->move)) {
fence_put(from->move);
from->move = fence_get(fence);
}
-- 
2.5.0



[Bug 96622] [radeonsi,apitrace] "Dreamfall Chapters: The longest Journey" shows visual corruption

2016-06-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=96622

Kai  changed:

   What|Removed |Added

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

--- Comment #4 from Kai  ---
Resolving as „not our bug“ since the changelog for DFC 5.2.0
(<http://steamcommunity.com/games/237850/announcements/detail/814405200397204382>)
mentions fixes for pixel errors (even though the changelog seems to restrict
this to Mac OS X, but since both use OpenGL...).

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


[PATCH v2 6/6] drm: Separate DRIVER_MODESET and DRIVER_LEGACY

2016-06-24 Thread Frank Binns
Support non-legacy drivers without mode-setting functionality by using
the new DRIVER_LEGACY feature to separate out legacy code, rather than
relying on DRIVER_MODESET not being advertised.

Signed-off-by: Thierry Reding 

v2:
- Rebase
- Change a few more places to check against DRIVER_LEGACY
- Move a core check

Signed-off-by: Frank Binns 
---
 drivers/gpu/drm/drm_bufs.c| 22 +++---
 drivers/gpu/drm/drm_context.c | 24 
 drivers/gpu/drm/drm_dma.c |  4 ++--
 drivers/gpu/drm/drm_fops.c| 10 ++
 drivers/gpu/drm/drm_ioctl.c   |  4 ++--
 drivers/gpu/drm/drm_irq.c | 14 +++---
 drivers/gpu/drm/drm_lock.c|  4 ++--
 drivers/gpu/drm/drm_pci.c | 10 +-
 drivers/gpu/drm/drm_scatter.c |  6 +++---
 9 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index c3a12cd..3219151 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -397,7 +397,7 @@ int drm_legacy_addmap_ioctl(struct drm_device *dev, void 
*data,
return -EPERM;

if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

err = drm_addmap_core(dev, map->offset, map->size, map->type,
@@ -443,7 +443,7 @@ int drm_legacy_getmap_ioctl(struct drm_device *dev, void 
*data,
int i;

if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

idx = map->offset;
@@ -545,7 +545,7 @@ EXPORT_SYMBOL(drm_legacy_rmmap_locked);
 void drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
 {
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return;

mutex_lock(>struct_mutex);
@@ -558,7 +558,7 @@ void drm_legacy_master_rmmaps(struct drm_device *dev, 
struct drm_master *master)
 {
struct drm_map_list *r_list, *list_temp;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return;

mutex_lock(>struct_mutex);
@@ -595,7 +595,7 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void 
*data,
int ret;

if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
-   drm_core_check_feature(dev, DRIVER_MODESET))
+   !drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

mutex_lock(>struct_mutex);
@@ -1220,7 +1220,7 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data,
struct drm_buf_desc *request = data;
int ret;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1266,7 +1266,7 @@ int drm_legacy_infobufs(struct drm_device *dev, void 
*data,
int i;
int count;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1347,7 +1347,7 @@ int drm_legacy_markbufs(struct drm_device *dev, void 
*data,
int order;
struct drm_buf_entry *entry;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1395,7 +1395,7 @@ int drm_legacy_freebufs(struct drm_device *dev, void 
*data,
int idx;
struct drm_buf *buf;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1450,7 +1450,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data,
struct drm_buf_map *request = data;
int i;

-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
@@ -1530,7 +1530,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data,
 int drm_legacy_dma_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv)
 {
-   if (drm_core_check_feature(dev, DRIVER_MODESET))
+   if (!drm_core_check_feature(dev, DRIVER_LEGACY))
return -EINVAL;

if (dev->driver->dma_ioctl)
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 192a5f9..3c4000f 100644

[PATCH v2 5/6] drm: Introduce DRIVER_LEGACY feature

2016-06-24 Thread Frank Binns
From: Thierry Reding 

Currently drivers that set the DRIVER_MODESET feature are considered to
be non-legacy drivers. At the same time DRIVER_MODESET implies that the
mode-setting IOCTLs are available. It is therefore not possible to
distinguish between a non-legacy driver with full mode-setting support
and a non-legacy driver without mode-setting functionality.

To separate the meaning of "legacy" and "modeset", a new driver feature
is introduced: DRIVER_LEGACY. The meaning of DRIVER_MODESET can then be
changed to apply to the mode-setting functionality only, irrespective
of whether it is legacy or not.

Mark all legacy drivers appropriately.

Signed-off-by: Thierry Reding 

v2:
- Rebase
- Add legacy flag to r128
- Don't add legacy flag to radeon
- Build fix for tdfx (use the correct field name)
- Add documentation to drm-internals

Signed-off-by: Frank Binns 
---
I wasn't totally sure what to do with regards to authorship and sign-off
as I'd like to give credit where it's due. Feel free to tell me if I got
it wrong :)

 Documentation/gpu/drm-internals.rst | 9 ++---
 drivers/gpu/drm/i810/i810_drv.c | 3 ++-
 drivers/gpu/drm/mga/mga_drv.c   | 3 ++-
 drivers/gpu/drm/r128/r128_drv.c | 3 ++-
 drivers/gpu/drm/savage/savage_drv.c | 2 +-
 drivers/gpu/drm/sis/sis_drv.c   | 2 +-
 drivers/gpu/drm/tdfx/tdfx_drv.c | 1 +
 drivers/gpu/drm/via/via_drv.c   | 2 +-
 include/drm/drmP.h  | 1 +
 9 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/Documentation/gpu/drm-internals.rst 
b/Documentation/gpu/drm-internals.rst
index 4f71765..97b458e 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -95,6 +95,9 @@ DRIVER_ATOMIC
 implement appropriate obj->atomic_get_property() vfuncs for any
 modeset objects with driver specific properties.

+DRIVER_LEGACY
+Driver supports user mode setting interfaces (UMS). Deprecated.
+
 Major, Minor and Patchlevel
 ~~~

@@ -337,9 +340,9 @@ how the ioctl is allowed to be called.
device

 -  DRM_UNLOCKED - The ioctl handler will be called without locking the
-   DRM global mutex. This is the enforced default for kms drivers (i.e.
-   using the DRIVER_MODESET flag) and hence shouldn't be used any more
-   for new drivers.
+   DRM global mutex. This is the enforced default for drivers that don't
+   support UMS (i.e. using the DRIVER_LEGACY flag) and hence shouldn't
+   be used any more for new drivers.

 .. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:export:
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index 44f4a13..8c3c04a 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -58,7 +58,8 @@ static const struct file_operations i810_driver_fops = {
 static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP |
-   DRIVER_HAVE_DMA,
+   DRIVER_HAVE_DMA |
+   DRIVER_LEGACY,
.dev_priv_size = sizeof(drm_i810_buf_priv_t),
.load = i810_driver_load,
.lastclose = i810_driver_lastclose,
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 5e2f131..06aafdc 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -59,7 +59,8 @@ static const struct file_operations mga_driver_fops = {
 static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_PCI_DMA |
-   DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+   DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+   DRIVER_LEGACY,
.dev_priv_size = sizeof(drm_mga_buf_priv_t),
.load = mga_driver_load,
.unload = mga_driver_unload,
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index c57b4de..5a63425 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -57,7 +57,8 @@ static const struct file_operations r128_driver_fops = {
 static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
-   DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+   DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+   DRIVER_LEGACY,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
.load = r128_driver_load,
.preclose = r128_driver_preclose,
diff --git a/drivers/gpu/drm/savage/savage_drv.c 
b/drivers/gpu/drm/savage/savage_drv.c
index 21aed1f..3b80713 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -50,7 +50,7 @@ static const struct file_operations savage_driver_fops = {

 static struct drm_driver driver = {
.driver_features =
-   DRIVER_USE_AGP | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
+   DRIVER_USE_AGP | DRIVER_HAVE_DMA | DRIVER_PCI_DMA | DRIVER_LEGACY,
.dev_priv_size = 

[PATCH 4/6] drm/qxl: Remove dead code

2016-06-24 Thread Frank Binns
From: Thierry Reding 

The QXL driver sets DRIVER_MODESET unconditionally, so testing for the
absence of the feature will always fail.

Signed-off-by: Thierry Reding 
---
 drivers/gpu/drm/qxl/qxl_kms.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 2319800..12b8dff 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -310,10 +310,6 @@ int qxl_driver_load(struct drm_device *dev, unsigned long 
flags)
struct qxl_device *qdev;
int r;

-   /* require kms */
-   if (!drm_core_check_feature(dev, DRIVER_MODESET))
-   return -ENODEV;
-
qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL);
if (qdev == NULL)
return -ENOMEM;
-- 
2.7.4



[PATCH 3/6] drm/amd/amdgpu: Set DRIVER_MODESET feature flag at build time

2016-06-24 Thread Frank Binns
This flag was being set unconditionally at runtime so just set it at
compile time instead.

Signed-off-by: Frank Binns 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f888c01..7fe7f3c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -515,7 +515,7 @@ static struct drm_driver kms_driver = {
.driver_features =
DRIVER_USE_AGP |
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
-   DRIVER_PRIME | DRIVER_RENDER,
+   DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,
.dev_priv_size = 0,
.load = amdgpu_driver_load_kms,
.open = amdgpu_driver_open_kms,
@@ -590,7 +590,6 @@ static int __init amdgpu_init(void)
DRM_INFO("amdgpu kernel modesetting enabled.\n");
driver = _driver;
pdriver = _kms_pci_driver;
-   driver->driver_features |= DRIVER_MODESET;
driver->num_ioctls = amdgpu_max_kms_ioctl;
amdgpu_register_atpx_handler();
/* let modprobe override vga console setting */
-- 
2.7.4



[PATCH 2/6] drm: Rename DRM_MINOR_LEGACY to DRM_MINOR_PRIMARY

2016-06-24 Thread Frank Binns
This brings the minor type name into line with how the actual minor,
using this type, is referenced throughout the rest of drm.

Signed-off-by: Frank Binns 
---
 drivers/gpu/drm/drm_drv.c | 16 
 include/drm/drmP.h|  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index aead9ff..7775c8b 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -112,7 +112,7 @@ static struct drm_minor **drm_minor_get_slot(struct 
drm_device *dev,
 unsigned int type)
 {
switch (type) {
-   case DRM_MINOR_LEGACY:
+   case DRM_MINOR_PRIMARY:
return >primary;
case DRM_MINOR_RENDER:
return >render;
@@ -362,7 +362,7 @@ EXPORT_SYMBOL(drm_put_dev);
 void drm_unplug_dev(struct drm_device *dev)
 {
/* for a USB device */
-   drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+   drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
drm_minor_unregister(dev, DRM_MINOR_CONTROL);

@@ -514,7 +514,7 @@ int drm_dev_init(struct drm_device *dev,
goto err_minors;
}

-   ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
+   ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
if (ret)
goto err_minors;

@@ -547,7 +547,7 @@ err_ctxbitmap:
drm_legacy_ctxbitmap_cleanup(dev);
drm_ht_remove(>map_hash);
 err_minors:
-   drm_minor_free(dev, DRM_MINOR_LEGACY);
+   drm_minor_free(dev, DRM_MINOR_PRIMARY);
drm_minor_free(dev, DRM_MINOR_RENDER);
drm_minor_free(dev, DRM_MINOR_CONTROL);
drm_fs_inode_free(dev->anon_inode);
@@ -610,7 +610,7 @@ static void drm_dev_release(struct kref *ref)
drm_ht_remove(>map_hash);
drm_fs_inode_free(dev->anon_inode);

-   drm_minor_free(dev, DRM_MINOR_LEGACY);
+   drm_minor_free(dev, DRM_MINOR_PRIMARY);
drm_minor_free(dev, DRM_MINOR_RENDER);
drm_minor_free(dev, DRM_MINOR_CONTROL);

@@ -686,7 +686,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
if (ret)
goto err_minors;

-   ret = drm_minor_register(dev, DRM_MINOR_LEGACY);
+   ret = drm_minor_register(dev, DRM_MINOR_PRIMARY);
if (ret)
goto err_minors;

@@ -703,7 +703,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
goto out_unlock;

 err_minors:
-   drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+   drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
drm_minor_unregister(dev, DRM_MINOR_CONTROL);
 out_unlock:
@@ -743,7 +743,7 @@ void drm_dev_unregister(struct drm_device *dev)
list_for_each_entry_safe(r_list, list_temp, >maplist, head)
drm_legacy_rmmap(dev, r_list->map);

-   drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+   drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
drm_minor_unregister(dev, DRM_MINOR_CONTROL);
 }
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index cf918e3e..1d39988 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -642,7 +642,7 @@ struct drm_driver {
 };

 enum drm_minor_type {
-   DRM_MINOR_LEGACY,
+   DRM_MINOR_PRIMARY,
DRM_MINOR_CONTROL,
DRM_MINOR_RENDER,
DRM_MINOR_CNT,
@@ -883,7 +883,7 @@ static inline bool drm_is_control_client(const struct 
drm_file *file_priv)

 static inline bool drm_is_primary_client(const struct drm_file *file_priv)
 {
-   return file_priv->minor->type == DRM_MINOR_LEGACY;
+   return file_priv->minor->type == DRM_MINOR_PRIMARY;
 }

 /**/
-- 
2.7.4



[PATCH 1/6] drm/vmwgfx: Stop checking minor type directly

2016-06-24 Thread Frank Binns
Use the appropriate drm minor type helper instead.

Cc: Sinclair Yeh 
Cc: Thomas Hellstrom 
Signed-off-by: Frank Binns 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 6064664..5d5c951 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1041,8 +1041,7 @@ static struct vmw_master *vmw_master_check(struct 
drm_device *dev,
struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
struct vmw_master *vmaster;

-   if (file_priv->minor->type != DRM_MINOR_LEGACY ||
-   !(flags & DRM_AUTH))
+   if (!drm_is_primary_client(file_priv) || !(flags & DRM_AUTH))
return NULL;

ret = mutex_lock_interruptible(>master_mutex);
-- 
2.7.4



[PATCH v2 0/6] Support render only drivers

2016-06-24 Thread Frank Binns
This series resurrects work originally done by Thierry Reding (hence
the v2) but without taking things quite as far as the original [1].

The motivation for this series is to remove the dual meaning of
the DRIVER_MODESET feature flag, whereby it means "support kernel
modesetting" and "don't expose pre-KMS legacy behaviour". Without
this, it's necessary for render only drivers, such as etnaviv, to
choose between falsely advertising themselves as modesetting drivers
or exposing legacy behaviour. Unlike the original series, it doesn't
restrict the card-node to drivers that set DRIVER_MODESET.

As a couple of years have now passed, a number of the patches from the
original series have now either been merged (mainly clean up), are no
longer relevant or have no code changes in common with the originals.
It also means that some new patches are needed. Those patches that have
been rebased are marked as v2.

[1] https://lwn.net/Articles/588016/

Frank Binns (4):
  drm/vmwgfx: Stop checking minor type directly
  drm: Rename DRM_MINOR_LEGACY to DRM_MINOR_PRIMARY
  drm/amd/amdgpu: Set DRIVER_MODESET feature flag at build time
  drm: Separate DRIVER_MODESET and DRIVER_LEGACY

Thierry Reding (2):
  drm/qxl: Remove dead code
  drm: Introduce DRIVER_LEGACY feature

 Documentation/gpu/drm-internals.rst |  9 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 +--
 drivers/gpu/drm/drm_bufs.c  | 22 +++---
 drivers/gpu/drm/drm_context.c   | 24 
 drivers/gpu/drm/drm_dma.c   |  4 ++--
 drivers/gpu/drm/drm_drv.c   | 16 
 drivers/gpu/drm/drm_fops.c  | 10 ++
 drivers/gpu/drm/drm_ioctl.c |  4 ++--
 drivers/gpu/drm/drm_irq.c   | 14 +++---
 drivers/gpu/drm/drm_lock.c  |  4 ++--
 drivers/gpu/drm/drm_pci.c   | 10 +-
 drivers/gpu/drm/drm_scatter.c   |  6 +++---
 drivers/gpu/drm/i810/i810_drv.c |  3 ++-
 drivers/gpu/drm/mga/mga_drv.c   |  3 ++-
 drivers/gpu/drm/qxl/qxl_kms.c   |  4 
 drivers/gpu/drm/r128/r128_drv.c |  3 ++-
 drivers/gpu/drm/savage/savage_drv.c |  2 +-
 drivers/gpu/drm/sis/sis_drv.c   |  2 +-
 drivers/gpu/drm/tdfx/tdfx_drv.c |  1 +
 drivers/gpu/drm/via/via_drv.c   |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |  3 +--
 include/drm/drmP.h  |  5 +++--
 22 files changed, 79 insertions(+), 75 deletions(-)

-- 
2.7.4



[PATCH 3/6] drm/amd/amdgpu: Set DRIVER_MODESET feature flag at build time

2016-06-24 Thread Alex Deucher
On Fri, Jun 24, 2016 at 1:15 PM, Frank Binns  wrote:
> This flag was being set unconditionally at runtime so just set it at
> compile time instead.
>
> Signed-off-by: Frank Binns 

Reviewed-by: Alex Deucher 

Do you want to take this as part of the patch set, or should I apply
this to my tree?

Alex

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index f888c01..7fe7f3c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -515,7 +515,7 @@ static struct drm_driver kms_driver = {
> .driver_features =
> DRIVER_USE_AGP |
> DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
> -   DRIVER_PRIME | DRIVER_RENDER,
> +   DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,
> .dev_priv_size = 0,
> .load = amdgpu_driver_load_kms,
> .open = amdgpu_driver_open_kms,
> @@ -590,7 +590,6 @@ static int __init amdgpu_init(void)
> DRM_INFO("amdgpu kernel modesetting enabled.\n");
> driver = _driver;
> pdriver = _kms_pci_driver;
> -   driver->driver_features |= DRIVER_MODESET;
> driver->num_ioctls = amdgpu_max_kms_ioctl;
> amdgpu_register_atpx_handler();
> /* let modprobe override vga console setting */
> --
> 2.7.4
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/2 RESEND] drm/amdgpu: Poll for both connect/disconnect on analog connectors

2016-06-24 Thread Lyude
DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
disconnections. Because of this, we end up losing hotplug polling for
analog connectors once they get connected.

Easy way to reproduce:
 - Grab a machine with an AMD GPU and a VGA port
 - Plug a monitor into the VGA port, wait for it to update the connector
   from disconnected to connected
 - Disconnect the monitor on VGA, a hotplug event is never sent for the
   removal of the connector.

Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good
idea since doing VGA polling can sometimes result in having to mess with
the DAC voltages to figure out whether or not there's actually something
there since VGA doesn't have HPD. Doing this would have the potential of
showing visible artifacts on the screen every time we ran a poll while a
VGA display was connected. Luckily, amdgpu_vga_detect() only resorts to
this sort of polling if the poll is forced, and DRM's polling helper
doesn't force it's polls.

Additionally, this removes some assignments to connector->polled that
weren't actually doing anything.

Cc: stable at vger.kernel.org
Signed-off-by: Lyude 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index cb07da4..ff0b55a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -1690,7 +1690,6 @@ amdgpu_connector_add(struct amdgpu_device *adev,
   DRM_MODE_SCALE_NONE);
/* no HPD on analog connectors */
amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -1893,8 +1892,10 @@ amdgpu_connector_add(struct amdgpu_device *adev,
}

if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) {
-   if (i2c_bus->valid)
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+   if (i2c_bus->valid) {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;

-- 
2.7.4



[PATCH 1/2 RESEND] drm/radeon: Poll for both connect/disconnect on analog connectors

2016-06-24 Thread Lyude
DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
disconnections. Because of this, we end up losing hotplug polling for
analog connectors once they get connected.

Easy way to reproduce:
 - Grab a machine with a radeon GPU and a VGA port
 - Plug a monitor into the VGA port, wait for it to update the connector
   from disconnected to connected
 - Disconnect the monitor on VGA, a hotplug event is never sent for the
   removal of the connector.

Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good
idea since doing VGA polling can sometimes result in having to mess with
the DAC voltages to figure out whether or not there's actually something
there since VGA doesn't have HPD. Doing this would have the potential of
showing visible artifacts on the screen every time we ran a poll while a
VGA display was connected. Luckily, radeon_vga_detect() only resorts to
this sort of polling if the poll is forced, and DRM's polling helper
doesn't force it's polls.

Additionally, this removes some assignments to connector->polled that
weren't actually doing anything.

Cc: stable at vger.kernel.org
Signed-off-by: Lyude 
---
 drivers/gpu/drm/radeon/radeon_connectors.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c 
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 81a63d7..b79f3b0 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -2064,7 +2064,6 @@ radeon_add_atom_connector(struct drm_device *dev,
   
RADEON_OUTPUT_CSC_BYPASS);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -2314,8 +2313,10 @@ radeon_add_atom_connector(struct drm_device *dev,
}

if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-   if (i2c_bus->valid)
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+   if (i2c_bus->valid) {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;

@@ -2391,7 +2392,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
  1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -2476,10 +2476,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
}

if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-   if (i2c_bus->valid)
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+   if (i2c_bus->valid) {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;
+
connector->display_info.subpixel_order = subpixel_order;
drm_connector_register(connector);
 }
-- 
2.7.4



[PATCH 1/2] drm/radeon: Poll for both connect/disconnect on analog connectors

2016-06-24 Thread Lyude
Whoops, very sorry about this! I ran git send-email, and it looks like
I had forgotten to remove some other patches in my patches/ folder.
Going to resend this to avoid confusing anyone trying to review this.

On Fri, 2016-06-24 at 17:45 -0400, Lyude wrote:
> DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
> disconnections. Because of this, we end up losing hotplug polling for
> analog connectors once they get connected.
> 
> Easy way to reproduce:
>  - Grab a machine with a radeon GPU and a VGA port
>  - Plug a monitor into the VGA port, wait for it to update the
> connector
>    from disconnected to connected
>  - Disconnect the monitor on VGA, a hotplug event is never sent for
> the
>    removal of the connector.
> 
> Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a
> good
> idea since doing VGA polling can sometimes result in having to mess
> with
> the DAC voltages to figure out whether or not there's actually
> something
> there since VGA doesn't have HPD. Doing this would have the potential
> of
> showing visible artifacts on the screen every time we ran a poll
> while a
> VGA display was connected. Luckily, radeon_vga_detect() only resorts
> to
> this sort of polling if the poll is forced, and DRM's polling helper
> doesn't force it's polls.
> 
> Additionally, this removes some assignments to connector->polled that
> weren't actually doing anything.
> 
> Cc: stable at vger.kernel.org
> Signed-off-by: Lyude 
> ---
>  drivers/gpu/drm/radeon/radeon_connectors.c | 15 +--
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
> b/drivers/gpu/drm/radeon/radeon_connectors.c
> index 81a63d7..b79f3b0 100644
> --- a/drivers/gpu/drm/radeon/radeon_connectors.c
> +++ b/drivers/gpu/drm/radeon/radeon_connectors.c
> @@ -2064,7 +2064,6 @@ radeon_add_atom_connector(struct drm_device
> *dev,
>     RADEON_OU
> TPUT_CSC_BYPASS);
>  /* no HPD on analog connectors */
>  radeon_connector->hpd.hpd = RADEON_HPD_NONE;
> - connector->polled =
> DRM_CONNECTOR_POLL_CONNECT;
>  connector->interlace_allowed = true;
>  connector->doublescan_allowed = true;
>  break;
> @@ -2314,8 +2313,10 @@ radeon_add_atom_connector(struct drm_device
> *dev,
>  }
>  
>  if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
> - if (i2c_bus->valid)
> - connector->polled =
> DRM_CONNECTOR_POLL_CONNECT;
> + if (i2c_bus->valid) {
> + connector->polled =
> DRM_CONNECTOR_POLL_CONNECT |
> +                     
> DRM_CONNECTOR_POLL_DISCO
> NNECT;
> + }
>  } else
>  connector->polled = DRM_CONNECTOR_POLL_HPD;
>  
> @@ -2391,7 +2392,6 @@ radeon_add_legacy_connector(struct drm_device
> *dev,
>        1);
>  /* no HPD on analog connectors */
>  radeon_connector->hpd.hpd = RADEON_HPD_NONE;
> - connector->polled = DRM_CONNECTOR_POLL_CONNECT;
>  connector->interlace_allowed = true;
>  connector->doublescan_allowed = true;
>  break;
> @@ -2476,10 +2476,13 @@ radeon_add_legacy_connector(struct drm_device
> *dev,
>  }
>  
>  if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
> - if (i2c_bus->valid)
> - connector->polled =
> DRM_CONNECTOR_POLL_CONNECT;
> + if (i2c_bus->valid) {
> + connector->polled =
> DRM_CONNECTOR_POLL_CONNECT |
> +                     
> DRM_CONNECTOR_POLL_DISCO
> NNECT;
> + }
>  } else
>  connector->polled = DRM_CONNECTOR_POLL_HPD;
> +
>  connector->display_info.subpixel_order = subpixel_order;
>  drm_connector_register(connector);
>  }
-- 

Cheers,
Lyude


[PATCH v6 2/4] drm/i915/vlv: Reset the ADPA in vlv_display_power_well_init()

2016-06-24 Thread Lyude
While VGA hotplugging worked(ish) before, it looks like that was mainly
because we'd unintentionally enable it in
valleyview_crt_detect_hotplug() when we did a force trigger. This
doesn't work reliably enough because whenever the display powerwell on
vlv gets disabled, the values set in VLV_ADPA get cleared and
consequently VGA hotplugging gets disabled. This causes bugs such as one
we found on an Intel NUC, where doing the following sequence of
hotplugs:

  - Disconnect all monitors
  - Connect VGA
  - Disconnect VGA
  - Connect HDMI

Would result in VGA hotplugging becoming disabled, due to the powerwells
getting toggled in the process of connecting HDMI.

Changes since v3:
 - Expose intel_crt_reset() through intel_drv.h and call that in
   vlv_display_power_well_init() instead of
   encoder->base.funcs->reset(>base);

Changes since v2:
 - Use intel_encoder structs instead of drm_encoder structs

Changes since v1:
 - Instead of handling the register writes ourself, we just reuse
   intel_crt_detect()
 - Instead of resetting the ADPA during display IRQ installation, we now
   reset them in vlv_display_power_well_init()

Cc: stable at vger.kernel.org
Acked-by: Daniel Vetter 
Signed-off-by: Lyude 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_crt.c| 2 +-
 drivers/gpu/drm/i915/intel_drv.h| 2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 7 +++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index dfcd718..220be7a 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -713,7 +713,7 @@ static int intel_crt_set_property(struct drm_connector 
*connector,
return 0;
 }

-static void intel_crt_reset(struct drm_encoder *encoder)
+void intel_crt_reset(struct drm_encoder *encoder)
 {
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 496c962..dcbfdde 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1075,7 +1075,7 @@ void gen8_irq_power_well_pre_disable(struct 
drm_i915_private *dev_priv,

 /* intel_crt.c */
 void intel_crt_init(struct drm_device *dev);
-
+void intel_crt_reset(struct drm_encoder *encoder);

 /* intel_ddi.c */
 void intel_ddi_clk_select(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index e856d49..f88ef76 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1065,6 +1065,7 @@ static void vlv_init_display_clock_gating(struct 
drm_i915_private *dev_priv)

 static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
 {
+   struct intel_encoder *encoder;
enum pipe pipe;

/*
@@ -1100,6 +1101,12 @@ static void vlv_display_power_well_init(struct 
drm_i915_private *dev_priv)

intel_hpd_init(dev_priv);

+   /* Re-enable the ADPA, if we have one */
+   for_each_intel_encoder(dev_priv->dev, encoder) {
+   if (encoder->type == INTEL_OUTPUT_ANALOG)
+   intel_crt_reset(>base);
+   }
+
i915_redisable_vga_power_on(dev_priv->dev);
 }

-- 
2.5.5



[PATCH v6 1/4] drm/i915/vlv: Make intel_crt_reset() per-encoder

2016-06-24 Thread Lyude
This lets call intel_crt_reset() in contexts where IRQs are disabled and
as such, can't hold the locks required to work with the connectors.

Cc: stable at vger.kernel.org
Cc: Ville Syrjälä 
Acked-by: Daniel Vetter 
Signed-off-by: Lyude 
---
 drivers/gpu/drm/i915/intel_crt.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index e115bcc..dfcd718 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -713,11 +713,11 @@ static int intel_crt_set_property(struct drm_connector 
*connector,
return 0;
 }

-static void intel_crt_reset(struct drm_connector *connector)
+static void intel_crt_reset(struct drm_encoder *encoder)
 {
-   struct drm_device *dev = connector->dev;
+   struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
-   struct intel_crt *crt = intel_attached_crt(connector);
+   struct intel_crt *crt = intel_encoder_to_crt(to_intel_encoder(encoder));

if (INTEL_INFO(dev)->gen >= 5) {
u32 adpa;
@@ -739,7 +739,6 @@ static void intel_crt_reset(struct drm_connector *connector)
  */

 static const struct drm_connector_funcs intel_crt_connector_funcs = {
-   .reset = intel_crt_reset,
.dpms = drm_atomic_helper_connector_dpms,
.detect = intel_crt_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -757,6 +756,7 @@ static const struct drm_connector_helper_funcs 
intel_crt_connector_helper_funcs
 };

 static const struct drm_encoder_funcs intel_crt_enc_funcs = {
+   .reset = intel_crt_reset,
.destroy = intel_encoder_destroy,
 };

@@ -901,5 +901,5 @@ void intel_crt_init(struct drm_device *dev)
dev_priv->fdi_rx_config = I915_READ(FDI_RX_CTL(PIPE_A)) & 
fdi_config;
}

-   intel_crt_reset(connector);
+   intel_crt_reset(>base.base);
 }
-- 
2.5.5



[PATCH v6 0/4] Fixes for HPD

2016-06-24 Thread Lyude
Latest version of:

https://lists.freedesktop.org/archives/intel-gfx/2016-June/098787.html

The only patch that's changed here is 4/4, the rest are just being sent so that
they can be in one thread to make things easier for reviewers

Lyude (4):
  drm/i915/vlv: Make intel_crt_reset() per-encoder
  drm/i915/vlv: Reset the ADPA in vlv_display_power_well_init()
  drm/i915/vlv: Disable HPD in valleyview_crt_detect_hotplug()
  drm/i915: Enable polling when we don't have hpd

 drivers/gpu/drm/i915/i915_drv.c |   3 +
 drivers/gpu/drm/i915/i915_drv.h |   5 ++
 drivers/gpu/drm/i915/intel_crt.c|  28 ++--
 drivers/gpu/drm/i915/intel_drv.h|   4 +-
 drivers/gpu/drm/i915/intel_hotplug.c| 117 
 drivers/gpu/drm/i915/intel_runtime_pm.c |   9 +++
 6 files changed, 148 insertions(+), 18 deletions(-)

-- 
2.5.5



[PATCH 2/2] drm/amdgpu: Poll for both connect/disconnect on analog connectors

2016-06-24 Thread Lyude
DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
disconnections. Because of this, we end up losing hotplug polling for
analog connectors once they get connected.

Easy way to reproduce:
 - Grab a machine with an AMD GPU and a VGA port
 - Plug a monitor into the VGA port, wait for it to update the connector
   from disconnected to connected
 - Disconnect the monitor on VGA, a hotplug event is never sent for the
   removal of the connector.

Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good
idea since doing VGA polling can sometimes result in having to mess with
the DAC voltages to figure out whether or not there's actually something
there since VGA doesn't have HPD. Doing this would have the potential of
showing visible artifacts on the screen every time we ran a poll while a
VGA display was connected. Luckily, amdgpu_vga_detect() only resorts to
this sort of polling if the poll is forced, and DRM's polling helper
doesn't force it's polls.

Additionally, this removes some assignments to connector->polled that
weren't actually doing anything.

Cc: stable at vger.kernel.org
Signed-off-by: Lyude 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index cb07da4..ff0b55a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -1690,7 +1690,6 @@ amdgpu_connector_add(struct amdgpu_device *adev,
   DRM_MODE_SCALE_NONE);
/* no HPD on analog connectors */
amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -1893,8 +1892,10 @@ amdgpu_connector_add(struct amdgpu_device *adev,
}

if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) {
-   if (i2c_bus->valid)
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+   if (i2c_bus->valid) {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;

-- 
2.7.4



[PATCH 1/2] drm/radeon: Poll for both connect/disconnect on analog connectors

2016-06-24 Thread Lyude
DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
disconnections. Because of this, we end up losing hotplug polling for
analog connectors once they get connected.

Easy way to reproduce:
 - Grab a machine with a radeon GPU and a VGA port
 - Plug a monitor into the VGA port, wait for it to update the connector
   from disconnected to connected
 - Disconnect the monitor on VGA, a hotplug event is never sent for the
   removal of the connector.

Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good
idea since doing VGA polling can sometimes result in having to mess with
the DAC voltages to figure out whether or not there's actually something
there since VGA doesn't have HPD. Doing this would have the potential of
showing visible artifacts on the screen every time we ran a poll while a
VGA display was connected. Luckily, radeon_vga_detect() only resorts to
this sort of polling if the poll is forced, and DRM's polling helper
doesn't force it's polls.

Additionally, this removes some assignments to connector->polled that
weren't actually doing anything.

Cc: stable at vger.kernel.org
Signed-off-by: Lyude 
---
 drivers/gpu/drm/radeon/radeon_connectors.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c 
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 81a63d7..b79f3b0 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -2064,7 +2064,6 @@ radeon_add_atom_connector(struct drm_device *dev,
   
RADEON_OUTPUT_CSC_BYPASS);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -2314,8 +2313,10 @@ radeon_add_atom_connector(struct drm_device *dev,
}

if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-   if (i2c_bus->valid)
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+   if (i2c_bus->valid) {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;

@@ -2391,7 +2392,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
  1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -2476,10 +2476,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
}

if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
-   if (i2c_bus->valid)
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+   if (i2c_bus->valid) {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;
+
connector->display_info.subpixel_order = subpixel_order;
drm_connector_register(connector);
 }
-- 
2.7.4



[RFC 0/5] rework fences on struct sync_file

2016-06-24 Thread Christian König
Am 24.06.2016 um 16:59 schrieb Gustavo Padovan:
> 2016-06-24 Christian König :
>
>> Am 24.06.2016 um 15:17 schrieb Gustavo Padovan:
>>> Hi Christian,
>>>
>>> 2016-06-24 Christian König :
>>>
 Am 23.06.2016 um 17:29 schrieb Gustavo Padovan:
> From: Gustavo Padovan 
>
> Hi all,
>
> This is an attempt to improve fence support on Sync File. The basic idea
> is to have only sync_file->fence and store all fences there, either as
> normal fences or fence_arrays. That way we can remove some potential
> duplication when using fence_array with sync_file: the duplication of the 
> array
> of fences and the duplication of fence_add_callback() for all fences.
>
> Now when creating a new sync_file during the merge process 
> sync_file_set_fence()
> will set sync_file->fence based on the number of fences for that 
> sync_file. If
> there is more than one fence a fence_array is created. One important 
> advantage
> approach is that we only add one fence callback now, no matter how many 
> fences
> there are in a sync_file - the individual callbacks are added by 
> fence_array.
>
> Two fence ops had to be created to help abstract the difference between 
> handling
> fences and fences_arrays: .teardown() and .get_fences(). The former run 
> needed
> on fence_array, and the latter just return a copy of all fences in the 
> fence.
> I'm not so sure about adding those two, speacially .get_fences(). What do 
> you
> think?
 Clearly not a good idea to add this a fence ops, cause those are 
 specialized
 functions for only a certain fence implementation (the fence_array).
>>> Are you refering only to .get_fences()?
>> That comment was only for the get_fences() operation, but the teardown()
>> callback looks very suspicious to me as well.
>>
>> Can you explain once more why that should be necessary?
> When the sync_file owner exits we need to clean up it and that means releasing
> the fence too, however with fence_array we can't just call fence_put()
> as a extra reference to array->base for each fence is held when enabling
> signalling. Thus we need a prior step, that I called teardown(), to
> remove the callback for not signaled fences and put the extra
> references.
>
> Another way to do this would be:
>
>   if (fence_is_array(sync_file->fence))
>   fence_array_destroy(to_fence_array(sync_file->fence));
>   else
>   fence_put(sync_file_fence);
>
> This would avoid the extra ops, maybe we should go this way.

NAK on both approaches. The fence array grabs another reference on 
itself for each callback it registers, so this isn't necessary:

> for (i = 0; i < array->num_fences; ++i) {
> cb[i].array = array;
> /*
>  * As we may report that the fence is signaled before all
>  * callbacks are complete, we need to take an additional
>  * reference count on the array so that we do not free 
> it too
>  * early. The core fence handling will only hold the 
> reference
>  * until we signal the array as complete (but that is now
>  * insufficient).
>  */
> fence_get(>base);
> if (fence_add_callback(array->fences[i], [i].cb,
>fence_array_cb_func)) {
> fence_put(>base);
> if (atomic_dec_and_test(>num_pending))
> return false;
> }
> }

So you can just use fence_remove_callback() and then fence_put() without 
worrying about the reference.

Regards,
Christian.

>
>   Gustavo



[PATCH 2/2] drm:fsl-dcu: add support for drm bridge

2016-06-24 Thread Meng Yi
The current output code only supports connection to drm panels.
Add codes to support drm bridge, to supports connection to
external connectors.

Signed-off-by: Meng Yi 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index 57a030b..f19e9b1 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -189,6 +189,7 @@ err_cleanup:
 static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev,
const struct of_endpoint *ep)
 {
+   struct drm_bridge *bridge;
struct device_node *np;
int ret;

@@ -200,8 +201,21 @@ static int fsl_dcu_attach_endpoint(struct 
fsl_dcu_drm_device *fsl_dev,
ret = fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
if (ret)
return -EPROBE_DEFER;
+   return 0;
}

+   bridge = of_drm_find_bridge(np);
+   of_node_put(np);
+   if (!bridge)
+   return -ENODEV;
+
+   fsl_dev->encoder.bridge = bridge;
+   bridge->encoder = _dev->encoder;
+
+   ret = drm_bridge_attach(fsl_dev->drm, bridge);
+   if (ret)
+   return -EPROBE_DEFER;
+
return 0;
 }

-- 
2.1.0.27.g96db324



[PATCH 1/2] drm:fsl-dcu: rework codes to support of_graph dt binding for panel

2016-06-24 Thread Meng Yi
This patch rework the output code to add of_graph dt binding support
for panel device and also keeps the backward compatibility

Signed-off-by: Meng Yi 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c|  2 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h |  3 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c| 76 
 3 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
index c564ec6..b48ffa7 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
@@ -43,7 +43,7 @@ int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device 
*fsl_dev)
if (ret)
goto fail_encoder;

-   ret = fsl_dcu_drm_connector_create(fsl_dev, _dev->encoder);
+   ret = fsl_dcu_create_outputs(fsl_dev);
if (ret)
goto fail_connector;

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
index 7093109..5a7b88e 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
@@ -25,9 +25,8 @@ to_fsl_dcu_connector(struct drm_connector *con)
 : NULL;
 }

-int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
-struct drm_encoder *encoder);
 int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
   struct drm_crtc *crtc);
+int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev);

 #endif /* __FSL_DCU_DRM_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index 98c998d..57a030b 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "fsl_dcu_drm_drv.h"
 #include "fsl_tcon.h"
@@ -141,15 +142,15 @@ static const struct drm_connector_helper_funcs 
connector_helper_funcs = {
.mode_valid = fsl_dcu_drm_connector_mode_valid,
 };

-int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
-struct drm_encoder *encoder)
+static int fsl_dcu_attach_panel(struct fsl_dcu_drm_device  *fsl_dev,
+   struct drm_panel *panel)
 {
+   struct drm_encoder *encoder = _dev->encoder;
struct drm_connector *connector = _dev->connector.base;
struct drm_mode_config *mode_config = _dev->drm->mode_config;
-   struct device_node *panel_node;
int ret;

-   fsl_dev->connector.encoder = encoder;
+   fsl_dev->connector.encoder = _dev->encoder;

ret = drm_connector_init(fsl_dev->drm, connector,
 _dcu_drm_connector_funcs,
@@ -170,21 +171,7 @@ int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device 
*fsl_dev,
  mode_config->dpms_property,
  DRM_MODE_DPMS_OFF);

-   panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0);
-   if (!panel_node) {
-   dev_err(fsl_dev->dev, "fsl,panel property not found\n");
-   ret = -ENODEV;
-   goto err_sysfs;
-   }
-
-   fsl_dev->connector.panel = of_drm_find_panel(panel_node);
-   if (!fsl_dev->connector.panel) {
-   ret = -EPROBE_DEFER;
-   goto err_panel;
-   }
-   of_node_put(panel_node);
-
-   ret = drm_panel_attach(fsl_dev->connector.panel, connector);
+   ret = drm_panel_attach(panel, connector);
if (ret) {
dev_err(fsl_dev->dev, "failed to attach panel\n");
goto err_sysfs;
@@ -192,11 +179,58 @@ int fsl_dcu_drm_connector_create(struct 
fsl_dcu_drm_device *fsl_dev,

return 0;

-err_panel:
-   of_node_put(panel_node);
 err_sysfs:
drm_connector_unregister(connector);
 err_cleanup:
drm_connector_cleanup(connector);
return ret;
 }
+
+static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev,
+   const struct of_endpoint *ep)
+{
+   struct device_node *np;
+   int ret;
+
+   np = of_graph_get_remote_port_parent(ep->local_node);
+
+   fsl_dev->connector.panel = of_drm_find_panel(np);
+   if (fsl_dev->connector.panel) {
+   of_node_put(np);
+   ret = fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
+   if (ret)
+   return -EPROBE_DEFER;
+   }
+
+   return 0;
+}
+
+int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev)
+{
+   struct of_endpoint ep;
+   struct device_node *ep_node, *panel_node;
+   int ret;
+   struct device_node *parent = fsl_dev->dev->of_node;
+
+   /*This is for the backward compatibility*/
+   panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0);
+   if 

[PATCH] drm: Only handle _DRM_VBLANK_NEXTONMISS once

2016-06-24 Thread Michel Dänzer
From: Michel Dänzer 

Consolidate the _DRM_VBLANK_NEXTONMISS handling between drm_wait_vblank
and drm_queue_vblank_event.

This is a cleanup spotted while working on other changes.

(The way it was previously handled could also theoretically result in
drm_queue_vblank_event unnecessarily bumping vblwait->request.sequence,
if the vblank counter happened to increment between the
drm_vblank_count(_and_time) calls in each function, but that's unlikely)

Signed-off-by: Michel Dänzer 
---
 drivers/gpu/drm/drm_irq.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 3c1a6f1..39ea4fc 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1685,12 +1685,6 @@ static int drm_queue_vblank_event(struct drm_device 
*dev, unsigned int pipe,

seq = drm_vblank_count_and_time(dev, pipe, );

-   if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
-   (seq - vblwait->request.sequence) <= (1 << 23)) {
-   vblwait->request.sequence = seq + 1;
-   vblwait->reply.sequence = vblwait->request.sequence;
-   }
-
DRM_DEBUG("event on vblank count %d, current %d, crtc %u\n",
  vblwait->request.sequence, seq, pipe);

@@ -1787,6 +1781,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
goto done;
}

+   if ((flags & _DRM_VBLANK_NEXTONMISS) &&
+   (seq - vblwait->request.sequence) <= (1 << 23)) {
+   vblwait->request.sequence = seq + 1;
+   }
+
if (flags & _DRM_VBLANK_EVENT) {
/* must hold on to the vblank ref until the event fires
 * drm_vblank_put will be called asynchronously
@@ -1794,11 +1793,6 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
return drm_queue_vblank_event(dev, pipe, vblwait, file_priv);
}

-   if ((flags & _DRM_VBLANK_NEXTONMISS) &&
-   (seq - vblwait->request.sequence) <= (1<<23)) {
-   vblwait->request.sequence = seq + 1;
-   }
-
DRM_DEBUG("waiting on vblank count %d, crtc %u\n",
  vblwait->request.sequence, pipe);
vblank->last_wait = vblwait->request.sequence;
-- 
2.8.1



[RFC 0/5] rework fences on struct sync_file

2016-06-24 Thread Christian König
Am 24.06.2016 um 15:17 schrieb Gustavo Padovan:
> Hi Christian,
>
> 2016-06-24 Christian König :
>
>> Am 23.06.2016 um 17:29 schrieb Gustavo Padovan:
>>> From: Gustavo Padovan 
>>>
>>> Hi all,
>>>
>>> This is an attempt to improve fence support on Sync File. The basic idea
>>> is to have only sync_file->fence and store all fences there, either as
>>> normal fences or fence_arrays. That way we can remove some potential
>>> duplication when using fence_array with sync_file: the duplication of the 
>>> array
>>> of fences and the duplication of fence_add_callback() for all fences.
>>>
>>> Now when creating a new sync_file during the merge process 
>>> sync_file_set_fence()
>>> will set sync_file->fence based on the number of fences for that sync_file. 
>>> If
>>> there is more than one fence a fence_array is created. One important 
>>> advantage
>>> approach is that we only add one fence callback now, no matter how many 
>>> fences
>>> there are in a sync_file - the individual callbacks are added by 
>>> fence_array.
>>>
>>> Two fence ops had to be created to help abstract the difference between 
>>> handling
>>> fences and fences_arrays: .teardown() and .get_fences(). The former run 
>>> needed
>>> on fence_array, and the latter just return a copy of all fences in the 
>>> fence.
>>> I'm not so sure about adding those two, speacially .get_fences(). What do 
>>> you
>>> think?
>> Clearly not a good idea to add this a fence ops, cause those are specialized
>> functions for only a certain fence implementation (the fence_array).
> Are you refering only to .get_fences()?

That comment was only for the get_fences() operation, but the teardown() 
callback looks very suspicious to me as well.

Can you explain once more why that should be necessary?

Regards,
Christian.

>
>> What you should do is try to cast the fence in your sync file using
>> to_fence_array() and then you can access the fences in the array.
> Yes, that seems a better idea I think. The initial idea was to abstract
> the difference as much as possible, but it doesn't seem really worth
> for .get_fences().
>
>   Gustavo
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



[PATCH 4/5] drm/imx: drop deprecated load/unload drm_driver ops

2016-06-24 Thread Ying Liu
On Fri, Jun 17, 2016 at 8:48 PM, Daniel Vetter  wrote:
> On Fri, Jun 17, 2016 at 12:13:41PM +0200, Lucas Stach wrote:
>> Drop the load/unload driver ops, as they are deprecated because of their
>> inherent races, with devices being visible to userspace before they are
>> fully initialized.
>>
>> Move this code into the driver bind/unbind routines bracketed by the
>> proper drm_dev_alloc/register and drm_dev_unregister/unref calls.
>>
>> Signed-off-by: Lucas Stach 
>> ---
>>  drivers/gpu/drm/imx/imx-drm-core.c | 247 
>> ++---
>>  1 file changed, 121 insertions(+), 126 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c 
>> b/drivers/gpu/drm/imx/imx-drm-core.c
>> index c63378661e11..799a68976590 100644
>> --- a/drivers/gpu/drm/imx/imx-drm-core.c
>> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
>> @@ -78,25 +78,6 @@ static void imx_drm_driver_lastclose(struct drm_device 
>> *drm)
>>   }
>>  }
>>
>> -static int imx_drm_driver_unload(struct drm_device *drm)
>> -{
>> - struct imx_drm_device *imxdrm = drm->dev_private;
>> -
>> - drm_kms_helper_poll_fini(drm);
>> -
>> - if (imxdrm->fbhelper)
>> - drm_fbdev_cma_fini(imxdrm->fbhelper);
>> -
>> - component_unbind_all(drm->dev, drm);
>> -
>> - drm_vblank_cleanup(drm);
>> - drm_mode_config_cleanup(drm);
>> -
>> - platform_set_drvdata(drm->platformdev, NULL);
>> -
>> - return 0;
>> -}
>> -
>>  static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
>>  {
>>   struct imx_drm_device *imxdrm = crtc->dev->dev_private;
>> @@ -223,109 +204,6 @@ static const struct drm_mode_config_funcs 
>> imx_drm_mode_config_funcs = {
>>  };
>>
>>  /*
>> - * Main DRM initialisation. This binds, initialises and registers
>> - * with DRM the subcomponents of the driver.
>> - */
>> -static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
>> -{
>> - struct imx_drm_device *imxdrm;
>> - struct drm_connector *connector;
>> - int ret;
>> -
>> - imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
>> - if (!imxdrm)
>> - return -ENOMEM;
>> -
>> - imxdrm->drm = drm;
>> -
>> - drm->dev_private = imxdrm;
>> -
>> - /*
>> -  * enable drm irq mode.
>> -  * - with irq_enabled = true, we can use the vblank feature.
>> -  *
>> -  * P.S. note that we wouldn't use drm irq handler but
>> -  *  just specific driver own one instead because
>> -  *  drm framework supports only one irq handler and
>> -  *  drivers can well take care of their interrupts
>> -  */
>> - drm->irq_enabled = true;
>> -
>> - /*
>> -  * set max width and height as default value(4096x4096).
>> -  * this value would be used to check framebuffer size limitation
>> -  * at drm_mode_addfb().
>> -  */
>> - drm->mode_config.min_width = 64;
>> - drm->mode_config.min_height = 64;
>> - drm->mode_config.max_width = 4096;
>> - drm->mode_config.max_height = 4096;
>> - drm->mode_config.funcs = _drm_mode_config_funcs;
>> -
>> - drm_mode_config_init(drm);
>> -
>> - ret = drm_vblank_init(drm, MAX_CRTC);
>> - if (ret)
>> - goto err_kms;
>> -
>> - platform_set_drvdata(drm->platformdev, drm);
>> -
>> - /* Now try and bind all our sub-components */
>> - ret = component_bind_all(drm->dev, drm);
>> - if (ret)
>> - goto err_vblank;
>> -
>> - /*
>> -  * All components are now added, we can publish the connector sysfs
>> -  * entries to userspace.  This will generate hotplug events and so
>> -  * userspace will expect to be able to access DRM at this point.
>> -  */
>> - list_for_each_entry(connector, >mode_config.connector_list, head) 
>> {
>> - ret = drm_connector_register(connector);
>> - if (ret) {
>> - dev_err(drm->dev,
>> - "[CONNECTOR:%d:%s] drm_connector_register 
>> failed: %d\n",
>> - connector->base.id,
>> - connector->name, ret);
>> - goto err_unbind;
>> - }
>> - }
>> -
>> - /*
>> -  * All components are now initialised, so setup the fb helper.
>> -  * The fb helper takes copies of key hardware information, so the
>> -  * crtcs/connectors/encoders must not change after this point.
>> -  */
>> -#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
>> - if (legacyfb_depth != 16 && legacyfb_depth != 32) {
>> - dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 
>> 16bpp\n");
>> - legacyfb_depth = 16;
>> - }
>> - drm_helper_disable_unused_functions(drm);
>> - imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
>> - drm->mode_config.num_crtc, MAX_CRTC);
>> - if (IS_ERR(imxdrm->fbhelper)) {
>> - ret = PTR_ERR(imxdrm->fbhelper);
>> - 

[PATCH 1/6] drm/vmwgfx: Stop checking minor type directly

2016-06-24 Thread Sinclair Yeh
Thanks!

Reviewed-by: Sinclair Yeh 


On Fri, Jun 24, 2016 at 06:15:15PM +0100, Frank Binns wrote:
> Use the appropriate drm minor type helper instead.
> 
> Cc: Sinclair Yeh 
> Cc: Thomas Hellstrom 
> Signed-off-by: Frank Binns 
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index 6064664..5d5c951 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -1041,8 +1041,7 @@ static struct vmw_master *vmw_master_check(struct 
> drm_device *dev,
>   struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
>   struct vmw_master *vmaster;
>  
> - if (file_priv->minor->type != DRM_MINOR_LEGACY ||
> - !(flags & DRM_AUTH))
> + if (!drm_is_primary_client(file_priv) || !(flags & DRM_AUTH))
>   return NULL;
>  
>   ret = mutex_lock_interruptible(>master_mutex);
> -- 
> 2.7.4
> 


[Bug 50325] Glyphy bad render on r600g (software render is fine) - too many registers?

2016-06-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=50325

--- Comment #6 from Vedran Miletić  ---
(In reply to cyberkm from comment #5)
> Bump

Have you confirmed it happens with latest Mesa git? What hardware did you try
it on?

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


[PATCH 5/5] drm: Unexport drm_connector_unregister_all()

2016-06-24 Thread Chris Wilson
This has now been removed from all drivers as it is performed centrally
as a part of device unregistration for modesetting drivers. With the last
user gone, we can unexport it from the DRM module. That requires us to
move the code slightly to avoid the need for a forward declaration.

Signed-off-by: Chris Wilson 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_crtc.c | 29 +
 include/drm/drm_crtc.h |  3 ---
 2 files changed, 9 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index c660ea28cf26..3ed866b02cbf 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1109,6 +1109,15 @@ void drm_connector_unregister(struct drm_connector 
*connector)
 }
 EXPORT_SYMBOL(drm_connector_unregister);

+static void drm_connector_unregister_all(struct drm_device *dev)
+{
+   struct drm_connector *connector;
+
+   /* FIXME: taking the mode config mutex ends up in a clash with sysfs */
+   list_for_each_entry(connector, >mode_config.connector_list, head)
+   drm_connector_unregister(connector);
+}
+
 static int drm_connector_register_all(struct drm_device *dev)
 {
struct drm_connector *connector;
@@ -1132,26 +1141,6 @@ err:
return ret;
 }

-/**
- * drm_connector_unregister_all - unregister connector userspace interfaces
- * @dev: drm device
- *
- * This functions unregisters all connectors from sysfs and other places so
- * that userspace can no longer access them. Drivers should call this as the
- * first step tearing down the device instace, or when the underlying
- * physical device disappeared (e.g. USB unplug), right before calling
- * drm_dev_unregister().
- */
-void drm_connector_unregister_all(struct drm_device *dev)
-{
-   struct drm_connector *connector;
-
-   /* FIXME: taking the mode config mutex ends up in a clash with sysfs */
-   list_for_each_entry(connector, >mode_config.connector_list, head)
-   drm_connector_unregister(connector);
-}
-EXPORT_SYMBOL(drm_connector_unregister_all);
-
 static int drm_encoder_register_all(struct drm_device *dev)
 {
struct drm_encoder *encoder;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index ddaa7243af55..b1e72322ebd6 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -2588,9 +2588,6 @@ static inline unsigned drm_connector_index(struct 
drm_connector *connector)
return connector->connector_id;
 }

-/* helpers to {un}register all connectors from sysfs for device */
-extern void drm_connector_unregister_all(struct drm_device *dev);
-
 extern __printf(5, 6)
 int drm_encoder_init(struct drm_device *dev,
 struct drm_encoder *encoder,
-- 
2.8.1



[PATCH 4/5] drm/udl: Unplugging a device now unregisters it

2016-06-24 Thread Chris Wilson
Rather than manually perform our unregistration actions before shutting
down the device, move them to drm_unplug_dev().

Signed-off-by: Chris Wilson 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Laurent Pinchart 
Cc: Alexey Brodkin 
Cc: Amitoj Kaur Chawla 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/udl/udl_drv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index c20408940cd0..17d34e0edbdd 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -94,7 +94,6 @@ static void udl_usb_disconnect(struct usb_interface 
*interface)
struct drm_device *dev = usb_get_intfdata(interface);

drm_kms_helper_poll_disable(dev);
-   drm_connector_unregister_all(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
drm_unplug_dev(dev);
-- 
2.8.1



[PATCH 3/5] drm: Do a full device unregister when unplugging

2016-06-24 Thread Chris Wilson
Rather than do a partial unregister of just the minors, unregister the
device (drm_dev_unregister(), and so remove all userspace interfaces,
when the device is unplugged (drm_unplug_dev()).

Signed-off-by: Chris Wilson 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Laurent Pinchart 
Cc: Alexey Brodkin 
Cc: Amitoj Kaur Chawla 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_drv.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index aead9ffcbe29..be27ed36f56e 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -362,9 +362,7 @@ EXPORT_SYMBOL(drm_put_dev);
 void drm_unplug_dev(struct drm_device *dev)
 {
/* for a USB device */
-   drm_minor_unregister(dev, DRM_MINOR_LEGACY);
-   drm_minor_unregister(dev, DRM_MINOR_RENDER);
-   drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+   drm_dev_unregister(dev);

mutex_lock(_global_mutex);

-- 
2.8.1



[PATCH 2/5] drm/sun4i: Remove redundant call to drm_connector_unregister_all()

2016-06-24 Thread Chris Wilson
drm_connector_unregister_all() is automatically called by
drm_dev_unregister() and so the manual call can be dropped.

Signed-off-by: Chris Wilson 
Cc: Daniel Vetter 
Cc: Maxime Ripard 
Cc: David Airlie 
Cc: Chen-Yu Tsai 
Cc: dri-devel at lists.freedesktop.org
Cc: linux-arm-kernel at lists.infradead.org
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c 
b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 5b89940edcb1..b22acc68d3b2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -185,7 +185,6 @@ static void sun4i_drv_unbind(struct device *dev)
 {
struct drm_device *drm = dev_get_drvdata(dev);

-   drm_connector_unregister_all(drm);
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
sun4i_framebuffer_free(drm);
-- 
2.8.1



[PATCH 1/5] drm: Unexport drm_connector_register_all()

2016-06-24 Thread Chris Wilson
This has now been removed from all drivers as it is performed centrally
as a part of device registration for modesetting drivers. With the last
user gone, we can unexport it from the DRM module.

Signed-off-by: Chris Wilson 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/drm_crtc.c | 19 +--
 include/drm/drm_crtc.h |  1 -
 2 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1190638a3d53..c660ea28cf26 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1109,23 +1109,7 @@ void drm_connector_unregister(struct drm_connector 
*connector)
 }
 EXPORT_SYMBOL(drm_connector_unregister);

-/**
- * drm_connector_register_all - register all connectors
- * @dev: drm device
- *
- * This function registers all connectors in sysfs and other places so that
- * userspace can start to access them. drm_connector_register_all() is called
- * automatically from drm_dev_register() to complete the device registration,
- * if they don't call drm_connector_register() on each connector individually.
- *
- * When a device is unplugged and should be removed from userspace access,
- * call drm_connector_unregister_all(), which is the inverse of this
- * function.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_connector_register_all(struct drm_device *dev)
+static int drm_connector_register_all(struct drm_device *dev)
 {
struct drm_connector *connector;
int ret;
@@ -1147,7 +1131,6 @@ err:
drm_connector_unregister_all(dev);
return ret;
 }
-EXPORT_SYMBOL(drm_connector_register_all);

 /**
  * drm_connector_unregister_all - unregister connector userspace interfaces
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index e6ed7018e290..ddaa7243af55 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -2589,7 +2589,6 @@ static inline unsigned drm_connector_index(struct 
drm_connector *connector)
 }

 /* helpers to {un}register all connectors from sysfs for device */
-extern int drm_connector_register_all(struct drm_device *dev);
 extern void drm_connector_unregister_all(struct drm_device *dev);

 extern __printf(5, 6)
-- 
2.8.1



[GIT PULL] drm/mediatek: MT8173 gamma & dither support

2016-06-24 Thread Bibby Hsieh
Hi Dave,

Please consider merging this tag, which contains the v2 MT8173 gamma & dither 
function patches I sent on 2016-06-17, rebased onto v4.7-rc1. There have been 
no further comments.

Thanks
Bibby

The following changes since commit 1a695a905c18548062509178b98bc91e67510864:

  Linux 4.7-rc1 (2016-05-29 16:29:24 GMT)

are available in the git repository at:

  git at github.com:BibbyHsieh/linux4.7-rc1.git

for you to fetch changes up to dd0eb773bc125f5e6bca735d19c08500dc3730f9:

  drm/mediatek: Add gamma correction

-
This is MT8173 gamma & dither support PATCH v2, based on 4.7-rc1.

Changes since v1:
 -According to the suggestion from Daniel,
  we used the new atomic color management.
 -Applied gamma function at GAMMA engine (path 2).
 -Made dithering function support hardware mirroring well.
 -Removed the bpc variable from mtk_drm_crtc struct.
-

Bibby Hsieh (2):
  drm/mediatek: Add gamma correction
  drm/mediatek: set mt8173 dithering function

 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |3 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|3 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |   26 -
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |1 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  147 ++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   16 ++-
 6 files changed, 184 insertions(+), 12 deletions(-)

-- 
1.7.9.5



[PATCH 09/12] dt-bindings: Add bindings for Tegra DPAUX pinctrl driver

2016-06-24 Thread Rob Herring
On Thu, Jun 23, 2016 at 04:59:02PM +0100, Jon Hunter wrote:
> On Tegra124, Tegra132 and Tegra210 devices the pads used by the Display
> Port Auxiliary (DPAUX) channel are multiplexed such that they can also
> be used by one of the internal I2C controllers. Note that this is
> different from I2C-over-AUX supported by the DPAUX controller. The
> register that configures these pads is part of the DPAUX controllers
> register set and so a pinctrl driver is being added for the DPAUX device
> to share these pads. Add the device-tree binding documentation for the
> DPAUX pad controller.
> 
> Although there is only one group of pads associated with the DPAUX that
> can be multiplexed, the group still needs to be described by the binding.
> If the 'groups' property is not present in the binding, then the pads
> will not be allocated by the pinctrl core for a client and this would
> allow another client to re-configure the same pads that may already be
> in-use.
> 
> Please note that although the "off" function for the DPAUX pads is not
> technically a pin-mux setting but more of a pin-conf setting it is
> simpler to expose these as a function so that the user can simply select
> either "aux", "i2c" or "off" as the current function/mode.
> 
> Update the main DPAUX binding documentation to reference the DPAUX pad
> controller binding document and add the 'i2c-bus' subnode. The 'i2c-bus'
> subnode is used for populating I2C slaves for the DPAUX device so that
> the I2C driver core does not attempt to add the DPAUX pad controller
> nodes as I2C slaves.
> 
> Signed-off-by: Jon Hunter 
> ---
>  .../display/tegra/nvidia,tegra20-host1x.txt|  6 +++
>  .../pinctrl/nvidia,tegra124-dpaux-padctl.txt   | 60 
> ++
>  2 files changed, 66 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt 
> b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
> index 275f45680892..d0f1dc62550a 100644
> --- 
> a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
> +++ 
> b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
> @@ -241,6 +241,12 @@ of the following host1x client modules:
>- reset-names: Must include the following entries:
>  - dpaux
>- vdd-supply: phandle of a supply that powers the DisplayPort link
> +  - i2c-bus: Subnode where I2C slave devices are listed. This subnode
> +must be always present. If there are no I2C slave devices, an empty
> +node should be added. See ../../i2c/i2c.txt for more information.
> +
> +  See ../pinctrl/nvidia,tegra124-dpaux-padctl.txt for information
> +  regarding the DPAUX pad controller bindings.
>  
>  Example:
>  
> diff --git 
> a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt 
> b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
> new file mode 100644
> index ..656e0a04be8f
> --- /dev/null
> +++ 
> b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt
> @@ -0,0 +1,60 @@
> +Device tree binding for NVIDIA Tegra DPAUX pad controller
> +
> +
> +The Tegra Display Port Auxiliary (DPAUX) pad controller manages two pins
> +which can be assigned to either the DPAUX channel or to an I2C
> +controller.
> +
> +This document defines the device-specific binding for the DPAUX pad
> +controller. Refer to pinctrl-bindings.txt in this directory for generic
> +information about pin controller device tree bindings. Please refer to
> +the binding document ../display/tegra/nvidia,tegra20-host1x.txt for more
> +details on the DPAUX binding.
> +
> +Pin muxing:
> +---
> +
> +Child nodes contain the pinmux configurations following the conventions
> +from the pinctrl-bindings.txt document.
> +
> +Since only three configurations are possible, only three child nodes are
> +needed to describe the pin mux'ing options for the DPAUX pads.
> +Furthermore, given that the pad functions are only applicable to a
> +single set of pads, the child nodes only need to describe the pad group
> +the functions are being applied to rather than the individual pads.
> +
> +Required properties:
> +- groups: Must be "dpaux-io"
> +- function: Must be either "aux", "i2c" or "off".
> +
> +Example:
> +
> +
> + dpaux at 545c {
> + ...
> +
> + state_dpaux_aux: pinmux_aux {

Use '-' for node names. With that:

Acked-by: Rob Herring 

> + groups = "dpaux-io";
> + function = "aux";
> + };
> +
> + state_dpaux_i2c: pinmux_i2c {
> + groups = "dpaux-io";
> + function = "i2c";
> + };
> +
> + state_dpaux_off: pinmux_off {
> + groups = "dpaux-io";
> + 

[PATCH 07/12] dt-bindings: i2c: Add support for 'i2c-bus' subnode

2016-06-24 Thread Rob Herring
On Thu, Jun 23, 2016 at 04:59:00PM +0100, Jon Hunter wrote:
> The I2C driver core for boards using device-tree assumes any subnode of
> an I2C adapter in the device-tree blob as being a I2C slave device.
> Although this makes complete sense, some I2C adapters may have subnodes
> which are not I2C slaves but subnodes presenting other features. For
> example some Tegra devices have an I2C interface which may share its
> pins with other devices and to share these pins subnodes for
> representing these pins so they have be shared via the pinctrl framework
> are needed.
> 
> To allow I2C adapters to have non-I2C specific subnodes in device-tree
> that are not parsed by the I2C driver core by adding support for a
> 'i2c-bus' subnode where I2C slaves can be placed. If the 'i2c-bus'
> subnode is present then all I2C slaves must be placed under this subnode.
> 
> Signed-off-by: Jon Hunter 
> Acked-by: Thierry Reding 
> ---
>  Documentation/devicetree/bindings/i2c/i2c.txt | 8 
>  1 file changed, 8 insertions(+)

Acked-by: Rob Herring 


[PATCH 04/12] dt-bindings: display: Update Tegra DPAUX documentation

2016-06-24 Thread Rob Herring
On Thu, Jun 23, 2016 at 04:58:57PM +0100, Jon Hunter wrote:
> Update the DPAUX compatibility string information for Tegra124, Tegra132
> and Tegra210.
> 
> Signed-off-by: Jon Hunter 
> ---
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt | 6 
> +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Acked-by: Rob Herring 


[v3 PATCH 4/5] Documentation: bindings: add dt documentation for cdn DP controller

2016-06-24 Thread Rob Herring
On Thu, Jun 23, 2016 at 08:51:03PM +0800, Chris Zhong wrote:
> This patch adds a binding that describes the cdn DP controller for
> rk3399.
> 
> Signed-off-by: Chris Zhong 
> 
> ---
> 
> Changes in v3:
> - add SoC specific compatible string
> - remove reg = <1>;
> 
> Changes in v2: None
> Changes in v1:
> - add extcon node description
> - add #sound-dai-cells description
> 
>  .../bindings/display/rockchip/cdn-dp-rockchip.txt  | 61 
> ++
>  1 file changed, 61 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/rockchip/cdn-dp-rockchip.txt

Acked-by: Rob Herring 


[PATCH 2/2] drm/tegra: sor: Use sor1_src clock to set parent for HDMI

2016-06-24 Thread Rob Herring
On Thu, Jun 23, 2016 at 12:27:59PM +0200, Thierry Reding wrote:
> From: Thierry Reding 
> 
> When running in HDMI mode, the sor1 IP block needs to use the sor1_src
> as parent clock, and in turn configure the sor1_src to use pll_d2_out0
> as its parent.
> 
> Signed-off-by: Thierry Reding 
> ---
>  drivers/gpu/drm/tegra/sor.c | 14 +-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
> index 6887e52318e2..7405c39f6db3 100644
> --- a/drivers/gpu/drm/tegra/sor.c
> +++ b/drivers/gpu/drm/tegra/sor.c
> @@ -172,6 +172,7 @@ struct tegra_sor {
>   struct clk *clk_parent;
>   struct clk *clk_brick;
>   struct clk *clk_safe;
> + struct clk *clk_src;
>   struct clk *clk_dp;
>   struct clk *clk;
>  
> @@ -2140,7 +2141,11 @@ static void tegra_sor_hdmi_enable(struct drm_encoder 
> *encoder)
>   tegra_sor_writel(sor, 0x, SOR_XBAR_POL);
>  
>   /* switch to parent clock */
> - err = tegra_sor_set_parent_clock(clk, sor->clk_parent);
> + err = clk_set_parent(sor->clk_src, sor->clk_parent);
> + if (err < 0)
> + dev_err(sor->dev, "failed to set source clock: %d\n", err);
> +
> + err = tegra_sor_set_parent_clock(sor, sor->clk_src);
>   if (err < 0)
>   dev_err(sor->dev, "failed to set parent clock: %d\n", err);
>  
> @@ -2645,6 +2650,13 @@ static int tegra_sor_probe(struct platform_device 
> *pdev)
>   goto remove;
>   }
>  
> + sor->clk_src = devm_clk_get(>dev, "source");
> + if (IS_ERR(sor->clk_src)) {
> + err = PTR_ERR(sor->clk_src);
> + dev_err(>dev, "failed to get source clock: %d\n", err);
> + goto remove;

Shouldn't this fallback to current behavior without this clock?

> + }
> +
>   sor->clk_parent = devm_clk_get(>dev, "parent");
>   if (IS_ERR(sor->clk_parent)) {
>   err = PTR_ERR(sor->clk_parent);
> -- 
> 2.8.3
> 


[PATCH] drm/exynos: make fbdev support really optional

2016-06-24 Thread Tobias Jakobi
Currently enabling Exynos DRM support automatically pulls in
lots of fbdev dependencies. However these deps are
unnecessary since DRM core already enables them when
needed.

Signed-off-by: Tobias Jakobi 
---
 drivers/gpu/drm/exynos/Kconfig | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index baddf33..590559c 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -2,10 +2,6 @@ config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || 
ARCH_MULTIPLATFORM)
select DRM_KMS_HELPER
-   select DRM_KMS_FB_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
select VIDEOMODE_HELPERS
help
  Choose this option if you have a Samsung SoC EXYNOS chipset.
-- 
2.7.3



[Intel-gfx] Bad flicker on skylake HQD due to code in the 4.7 merge window

2016-06-24 Thread Chris Wilson
On Fri, Jun 24, 2016 at 12:48:17PM +0100, Steven Newbury wrote:
> On Fri, 2016-06-24 at 11:59 +0100, Chris Wilson wrote:
> > On Thu, Jun 23, 2016 at 02:14:12PM +0100, Steven Newbury wrote:
> > > On Thu, 2016-06-23 at 15:59 +0300, Jani Nikula wrote:
> > > > On Thu, 23 Jun 2016, Steven Newbury 
> > > > wrote:
> > > > > I'm seeing this on my IvyBridge.  I'll try reverting the commit
> > > > > here
> > > > > too, to see if it's the same issue.
> > > > 
> > > > IvyBridge doesn't have low vswing for eDP. If reverting helps,
> > > > it's a
> > > > different failure mode.
> > > > 
> > > It must be something else then.  Actually, in my case linus/master
> > > is
> > > okay.  I saw the subject and though it must be the same issue.  I'm
> > > seeing it with drm-intel nightly/next branches.  Shall I try to
> > > bisect
> > > it?  Symptoms are similar, although I would describe it more like
> > > flashes of a different buffer across parts of the screen.
> > 
> > Try reverting ee042aa40b66d18d465206845b0752c6a617ba3f instead.
> > -Chris
> > 
> 
> Yes, thanks, that "fixed" it.  So atomic commits not working properly
> on IVB?

Not yet it seems. Something seems to be off in the timing, but has so
far eluded capture.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[Bug 48472] GPU Lockup while running demo (rzr - the scene is dead) in wine

2016-06-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=48472

--- Comment #6 from cyberkm at gmail.com ---
There are many different problems with this solution now.

examples
https://bugs.freedesktop.org/show_bug.cgi?id=84292
https://bugs.freedesktop.org/show_bug.cgi?id=50325
https://bugs.freedesktop.org/show_bug.cgi?id=93936
https://bugs.freedesktop.org/show_bug.cgi?id=68901

Maybe its the time to remove this temporary fix and solve the root problem.
As more and more games / apps come to linux and they simply don't work with
mesa.

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


[Bug 50325] Glyphy bad render on r600g (software render is fine) - too many registers?

2016-06-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=50325

--- Comment #5 from cyberkm at gmail.com ---
Bump

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


[Bug 93936] Snail shadertoy displays black quad

2016-06-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=93936

--- Comment #4 from cyberkm at gmail.com ---
Same problem here, i see in logs ->
also i saw that the hardcoded value for registers is 124, any reason for such
small number?

r600_shader.c:3662 r600_shader_from_tgsi - GPR limit exceeded - shader requires
230 registers

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


[Intel-gfx] Bad flicker on skylake HQD due to code in the 4.7 merge window

2016-06-24 Thread Steven Newbury
On Fri, 2016-06-24 at 11:59 +0100, Chris Wilson wrote:
> On Thu, Jun 23, 2016 at 02:14:12PM +0100, Steven Newbury wrote:
> > On Thu, 2016-06-23 at 15:59 +0300, Jani Nikula wrote:
> > > On Thu, 23 Jun 2016, Steven Newbury 
> > > wrote:
> > > > I'm seeing this on my IvyBridge.  I'll try reverting the commit
> > > > here
> > > > too, to see if it's the same issue.
> > > 
> > > IvyBridge doesn't have low vswing for eDP. If reverting helps,
> > > it's a
> > > different failure mode.
> > > 
> > It must be something else then.  Actually, in my case linus/master
> > is
> > okay.  I saw the subject and though it must be the same issue.  I'm
> > seeing it with drm-intel nightly/next branches.  Shall I try to
> > bisect
> > it?  Symptoms are similar, although I would describe it more like
> > flashes of a different buffer across parts of the screen.
> 
> Try reverting ee042aa40b66d18d465206845b0752c6a617ba3f instead.
> -Chris
> 

Yes, thanks, that "fixed" it.  So atomic commits not working properly
on IVB?
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: This is a digitally signed message part
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160624/3537ed86/attachment.sig>


[RFC 0/5] rework fences on struct sync_file

2016-06-24 Thread Gustavo Padovan
2016-06-24 Christian König :

> Am 24.06.2016 um 16:59 schrieb Gustavo Padovan:
> > 2016-06-24 Christian König :
> > 
> > > Am 24.06.2016 um 15:17 schrieb Gustavo Padovan:
> > > > Hi Christian,
> > > > 
> > > > 2016-06-24 Christian König :
> > > > 
> > > > > Am 23.06.2016 um 17:29 schrieb Gustavo Padovan:
> > > > > > From: Gustavo Padovan 
> > > > > > 
> > > > > > Hi all,
> > > > > > 
> > > > > > This is an attempt to improve fence support on Sync File. The basic 
> > > > > > idea
> > > > > > is to have only sync_file->fence and store all fences there, either 
> > > > > > as
> > > > > > normal fences or fence_arrays. That way we can remove some potential
> > > > > > duplication when using fence_array with sync_file: the duplication 
> > > > > > of the array
> > > > > > of fences and the duplication of fence_add_callback() for all 
> > > > > > fences.
> > > > > > 
> > > > > > Now when creating a new sync_file during the merge process 
> > > > > > sync_file_set_fence()
> > > > > > will set sync_file->fence based on the number of fences for that 
> > > > > > sync_file. If
> > > > > > there is more than one fence a fence_array is created. One 
> > > > > > important advantage
> > > > > > approach is that we only add one fence callback now, no matter how 
> > > > > > many fences
> > > > > > there are in a sync_file - the individual callbacks are added by 
> > > > > > fence_array.
> > > > > > 
> > > > > > Two fence ops had to be created to help abstract the difference 
> > > > > > between handling
> > > > > > fences and fences_arrays: .teardown() and .get_fences(). The former 
> > > > > > run needed
> > > > > > on fence_array, and the latter just return a copy of all fences in 
> > > > > > the fence.
> > > > > > I'm not so sure about adding those two, speacially .get_fences(). 
> > > > > > What do you
> > > > > > think?
> > > > > Clearly not a good idea to add this a fence ops, cause those are 
> > > > > specialized
> > > > > functions for only a certain fence implementation (the fence_array).
> > > > Are you refering only to .get_fences()?
> > > That comment was only for the get_fences() operation, but the teardown()
> > > callback looks very suspicious to me as well.
> > > 
> > > Can you explain once more why that should be necessary?
> > When the sync_file owner exits we need to clean up it and that means 
> > releasing
> > the fence too, however with fence_array we can't just call fence_put()
> > as a extra reference to array->base for each fence is held when enabling
> > signalling. Thus we need a prior step, that I called teardown(), to
> > remove the callback for not signaled fences and put the extra
> > references.
> > 
> > Another way to do this would be:
> > 
> > if (fence_is_array(sync_file->fence))
> > fence_array_destroy(to_fence_array(sync_file->fence));
> > else
> > fence_put(sync_file_fence);
> > 
> > This would avoid the extra ops, maybe we should go this way.
> 
> NAK on both approaches. The fence array grabs another reference on itself
> for each callback it registers, so this isn't necessary:
> 
> > for (i = 0; i < array->num_fences; ++i) {
> > cb[i].array = array;
> > /*
> >  * As we may report that the fence is signaled before all
> >  * callbacks are complete, we need to take an additional
> >  * reference count on the array so that we do not free
> > it too
> >  * early. The core fence handling will only hold the
> > reference
> >  * until we signal the array as complete (but that is now
> >  * insufficient).
> >  */
> > fence_get(>base);
> > if (fence_add_callback(array->fences[i], [i].cb,
> >fence_array_cb_func)) {
> > fence_put(>base);
> > if (atomic_dec_and_test(>num_pending))
> > return false;
> > }
> > }
> 
> So you can just use fence_remove_callback() and then fence_put() without
> worrying about the reference.

Yes. That is what I have in mind for fence_array_destroy() in the
snippet of code in the last e-mail. That plus the last fence_put() to
release the fence_array().

Gustavo


[RFC 0/5] rework fences on struct sync_file

2016-06-24 Thread Gustavo Padovan
2016-06-24 Christian König :

> Am 24.06.2016 um 15:17 schrieb Gustavo Padovan:
> > Hi Christian,
> > 
> > 2016-06-24 Christian König :
> > 
> > > Am 23.06.2016 um 17:29 schrieb Gustavo Padovan:
> > > > From: Gustavo Padovan 
> > > > 
> > > > Hi all,
> > > > 
> > > > This is an attempt to improve fence support on Sync File. The basic idea
> > > > is to have only sync_file->fence and store all fences there, either as
> > > > normal fences or fence_arrays. That way we can remove some potential
> > > > duplication when using fence_array with sync_file: the duplication of 
> > > > the array
> > > > of fences and the duplication of fence_add_callback() for all fences.
> > > > 
> > > > Now when creating a new sync_file during the merge process 
> > > > sync_file_set_fence()
> > > > will set sync_file->fence based on the number of fences for that 
> > > > sync_file. If
> > > > there is more than one fence a fence_array is created. One important 
> > > > advantage
> > > > approach is that we only add one fence callback now, no matter how many 
> > > > fences
> > > > there are in a sync_file - the individual callbacks are added by 
> > > > fence_array.
> > > > 
> > > > Two fence ops had to be created to help abstract the difference between 
> > > > handling
> > > > fences and fences_arrays: .teardown() and .get_fences(). The former run 
> > > > needed
> > > > on fence_array, and the latter just return a copy of all fences in the 
> > > > fence.
> > > > I'm not so sure about adding those two, speacially .get_fences(). What 
> > > > do you
> > > > think?
> > > Clearly not a good idea to add this a fence ops, cause those are 
> > > specialized
> > > functions for only a certain fence implementation (the fence_array).
> > Are you refering only to .get_fences()?
> 
> That comment was only for the get_fences() operation, but the teardown()
> callback looks very suspicious to me as well.
> 
> Can you explain once more why that should be necessary?

When the sync_file owner exits we need to clean up it and that means releasing
the fence too, however with fence_array we can't just call fence_put()
as a extra reference to array->base for each fence is held when enabling
signalling. Thus we need a prior step, that I called teardown(), to
remove the callback for not signaled fences and put the extra
references.

Another way to do this would be:

if (fence_is_array(sync_file->fence))
fence_array_destroy(to_fence_array(sync_file->fence));
else
fence_put(sync_file_fence);

This would avoid the extra ops, maybe we should go this way.

Gustavo


[Intel-gfx] Bad flicker on skylake HQD due to code in the 4.7 merge window

2016-06-24 Thread Chris Wilson
On Thu, Jun 23, 2016 at 02:14:12PM +0100, Steven Newbury wrote:
> On Thu, 2016-06-23 at 15:59 +0300, Jani Nikula wrote:
> > On Thu, 23 Jun 2016, Steven Newbury  wrote:
> > > I'm seeing this on my IvyBridge.  I'll try reverting the commit
> > > here
> > > too, to see if it's the same issue.
> > 
> > IvyBridge doesn't have low vswing for eDP. If reverting helps, it's a
> > different failure mode.
> > 
> It must be something else then.  Actually, in my case linus/master is
> okay.  I saw the subject and though it must be the same issue.  I'm
> seeing it with drm-intel nightly/next branches.  Shall I try to bisect
> it?  Symptoms are similar, although I would describe it more like
> flashes of a different buffer across parts of the screen.

Try reverting ee042aa40b66d18d465206845b0752c6a617ba3f instead.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[Intel-gfx] [PATCH] drm/i915: Fix misleading driver debug message

2016-06-24 Thread Chris Wilson
On Fri, Jun 24, 2016 at 11:23:56AM +0100, Frank Binns wrote:
> Stop claiming that UMS support is disabled when it's not actually
> supported anymore.
> 
> Signed-off-by: Frank Binns 

But not technically untrue!
Reviewed-by: Chris Wilson 

Since I have a series touching this code, I'll pull it into that.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/3] drm: bridge: add DesignWare HDMI I2S audio support

2016-06-24 Thread Kuninori Morimoto

From: Kuninori Morimoto 

Current dw-hdmi is supporting sound via AHB bus, but it has
I2S audio feature too. This patch adds I2S audio support to dw-hdmi.
This HDMI I2S is supported by using ALSA SoC common HDMI encoder
driver.

Signed-off-by: Kuninori Morimoto 
---
 drivers/gpu/drm/bridge/Kconfig |   8 ++
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/dw-hdmi-audio.h |   7 ++
 drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 123 +
 drivers/gpu/drm/bridge/dw-hdmi.c   |  22 +-
 drivers/gpu/drm/bridge/dw-hdmi.h   |  21 +
 6 files changed, 180 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 8f7423f..8e2a22d 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -32,6 +32,14 @@ config DRM_DW_HDMI_AHB_AUDIO
  Designware HDMI block.  This is used in conjunction with
  the i.MX6 HDMI driver.

+config DRM_DW_HDMI_I2S_AUDIO
+   tristate "Synopsis Designware I2S Audio interface"
+   depends on DRM_DW_HDMI
+   select SND_SOC_HDMI_CODEC
+   help
+ Support the I2S Audio interface which is part of the Synopsis
+ Designware HDMI block.
+
 config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 96b13b3..1af92ad 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -3,6 +3,7 @@ ccflags-y := -Iinclude/drm
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h 
b/drivers/gpu/drm/bridge/dw-hdmi-audio.h
index 91f631b..fd1f745 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi-audio.h
+++ b/drivers/gpu/drm/bridge/dw-hdmi-audio.h
@@ -11,4 +11,11 @@ struct dw_hdmi_audio_data {
u8 *eld;
 };

+struct dw_hdmi_i2s_audio_data {
+   struct dw_hdmi *hdmi;
+
+   void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+   u8 (*read)(struct dw_hdmi *hdmi, int offset);
+};
+
 #endif
diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c 
b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c
new file mode 100644
index 000..df1519c
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c
@@ -0,0 +1,123 @@
+/*
+ * dw-hdmi-i2s-audio.c
+ *
+ * Copyright (c) 2016 Kuninori Morimoto 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include 
+
+#include 
+
+#include "dw-hdmi.h"
+#include "dw-hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-i2s-audio"
+
+static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, u8 val, 
int offset)
+{
+   struct dw_hdmi *hdmi = audio->hdmi;
+
+   audio->write(hdmi, val, offset);
+}
+
+static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset)
+{
+   struct dw_hdmi *hdmi = audio->hdmi;
+
+   return audio->read(hdmi, offset);
+}
+
+static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
+struct hdmi_codec_daifmt *fmt,
+struct hdmi_codec_params *hparms)
+{
+   struct dw_hdmi_i2s_audio_data *audio = data;
+   struct dw_hdmi *hdmi = audio->hdmi;
+   u8 conf0 = 0;
+   u8 conf1 = 0;
+   u8 inputclkfs = 0;
+
+   /* it cares I2S only */
+   if ((fmt->fmt != HDMI_I2S) ||
+   (fmt->bit_clk_master | fmt->frame_clk_master)) {
+   dev_err(dev, "unsupported format/settings\n");
+   return -EINVAL;
+   }
+
+   inputclkfs  = HDMI_AUD_INPUTCLKFS_64FS;
+   conf0   = HDMI_AUD_CONF0_I2S_ALL_ENABLE;
+
+   switch(hparms->sample_width) {
+   case 16:
+   conf1 = HDMI_AUD_CONF1_WIDTH_16;
+   break;
+   case 24:
+   case 32:
+   conf1 = HDMI_AUD_CONF1_WIDTH_24;
+   break;
+   }
+
+   dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
+
+   hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS);
+   hdmi_write(audio, conf0, HDMI_AUD_CONF0);
+   hdmi_write(audio, conf1, HDMI_AUD_CONF1);
+
+   dw_hdmi_audio_enable(hdmi);
+
+   return 0;
+}
+
+static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data)
+{
+   struct dw_hdmi_i2s_audio_data *audio = data;
+   struct dw_hdmi *hdmi = audio->hdmi;
+
+   dw_hdmi_audio_disable(hdmi);
+
+   

[RFC 0/5] rework fences on struct sync_file

2016-06-24 Thread Christian König
Am 23.06.2016 um 17:29 schrieb Gustavo Padovan:
> From: Gustavo Padovan 
>
> Hi all,
>
> This is an attempt to improve fence support on Sync File. The basic idea
> is to have only sync_file->fence and store all fences there, either as
> normal fences or fence_arrays. That way we can remove some potential
> duplication when using fence_array with sync_file: the duplication of the 
> array
> of fences and the duplication of fence_add_callback() for all fences.
>
> Now when creating a new sync_file during the merge process 
> sync_file_set_fence()
> will set sync_file->fence based on the number of fences for that sync_file. If
> there is more than one fence a fence_array is created. One important advantage
> approach is that we only add one fence callback now, no matter how many fences
> there are in a sync_file - the individual callbacks are added by fence_array.
>
> Two fence ops had to be created to help abstract the difference between 
> handling
> fences and fences_arrays: .teardown() and .get_fences(). The former run needed
> on fence_array, and the latter just return a copy of all fences in the fence.
> I'm not so sure about adding those two, speacially .get_fences(). What do you
> think?

Clearly not a good idea to add this a fence ops, cause those are 
specialized functions for only a certain fence implementation (the 
fence_array).

What you should do is try to cast the fence in your sync file using 
to_fence_array() and then you can access the fences in the array.

Regards,
Christian.

>
> Please comment! Thanks.
>
>   Gustavo
> ---
>
> Gustavo Padovan (5):
>dma-buf/fence: add .teardown() ops
>dma-buf/fence-array: add fence_array_teardown()
>dma-buf/fence: add .get_fences() ops
>dma-buf/fence-array: add fence_array_get_fences()
>dma-buf/sync_file: rework fence storage in struct file
>
>   drivers/dma-buf/fence-array.c|  30 
>   drivers/dma-buf/fence.c  |  21 ++
>   drivers/dma-buf/sync_file.c  | 129 
> +--
>   drivers/staging/android/sync_debug.c |   5 +-
>   include/linux/fence.h|  10 +++
>   include/linux/sync_file.h|  12 ++--
>   6 files changed, 161 insertions(+), 46 deletions(-)
>



[drm:intel_set_cpu_fifo_underrun_reporting]

2016-06-24 Thread Petko Manolov
On 16-06-13 15:35:51, Petko Manolov wrote:
> On 16-06-13 13:29:46, Petko Manolov wrote:
> > Hello guys,
> > 
> > Running xorg on my Lenovo Yoga 2 Pro (MY2013) on recent kernels turn into a 
> > major PITA.  After a couple of minutes the screen starts to flicker and 
> > only 
> > killing xorg or reboot fixes the problem.  This is what i typically see in 
> > dmesg:
> > 
> > 
> > [0.00] microcode: microcode updated early to revision 0x1d, date = 
> > 2015-08-13
> > [0.00] Linux version 4.7.0-rc3 (petkan at yoga) (gcc version 6.1.1 
> > 20160519 (Debian 6.1.1-4) ) #5 SMP Mon Jun 13 12:41:31 EEST 2016
> > [0.00] Command line: BOOT_IMAGE=/boot/vmlinuz-4.7.0-rc3 
> > root=/dev/sda1 ro quiet
> > ...
> > [0.104213] smpboot: CPU0: Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz 
> > (family: 0x6, model: 0x45, stepping: 0x1)
> > ...
> > [1.033691] [drm] Initialized drm 1.1.0 20060810
> > [1.034106] [drm] Memory usable by graphics device = 2048M
> > [1.034108] [drm] Replacing VGA console driver
> > [1.040787] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> > [1.040788] [drm] Driver supports precise vblank timestamp query.
> > [1.066820] [drm] Initialized i915 1.6.0 20160425 for :00:02.0 on 
> > minor 0
> > [1.231007] fbcon: inteldrmfb (fb0) is primary device
> > [2.524538] i915 :00:02.0: fb0: inteldrmfb frame buffer device
> > ...
> > [   92.825302] [drm:intel_set_cpu_fifo_underrun_reporting] *ERROR* 
> > uncleared fifo underrun on pipe A
> > [   92.825312] [drm:ironlake_irq_handler] *ERROR* CPU pipe A FIFO underrun
> > 
> > 
> > This is going on for all v4.6 kernel releases as well as v4.7-rcX.  Older, 
> > v4.4 and v4.5, kernels are running fine.  I'm using Debian testing updated 
> > to 
> > 2016-06-13.
> > 
> > I'd be happy to help with testing so please let me know if there's anything 
> > i 
> > can do for you.
> 
> It seems that James (Bottomley) has similar problem and it was suggested to 
> him 
> to try drm-intel-nightly.  Which i did, but it didn't help much.  Admittedly, 
> the flicker issue showed up after about an hour instead of a couple of 
> minutes.
> 
> The 'dmesg' output seems very much like what i posted above.

It does not look like you guys care, but just for completeness and in case 
anybody is reading the thread: i915.enable_psr=0 did the trick for me.


Petko


[PATCH] drm/i915: Fix misleading driver debug message

2016-06-24 Thread Frank Binns
Stop claiming that UMS support is disabled when it's not actually
supported anymore.

Signed-off-by: Frank Binns 
---
 drivers/gpu/drm/i915/i915_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3eb47fb..22ded6b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1807,7 +1807,7 @@ static int __init i915_init(void)

if (!(driver.driver_features & DRIVER_MODESET)) {
/* Silently fail loading to not upset userspace. */
-   DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
+   DRM_DEBUG_DRIVER("KMS disabled.\n");
return 0;
}

-- 
2.7.4



[PATCH] drm: fix some spelling mistakes

2016-06-24 Thread Frank Binns
Signed-off-by: Frank Binns 
---
 drivers/gpu/drm/drm_irq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 8ca3d2b..149453c 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -532,7 +532,7 @@ int drm_irq_uninstall(struct drm_device *dev)

/*
 * Wake up any waiters so they don't hang. This is just to paper over
-* isssues for UMS drivers which aren't in full control of their
+* issues for UMS drivers which aren't in full control of their
 * vblank/irq handling. KMS drivers must ensure that vblanks are all
 * disabled when uninstalling the irq handler.
 */
@@ -594,7 +594,7 @@ int drm_control(struct drm_device *dev, void *data,
return 0;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;
-   /* UMS was only ever support on pci devices. */
+   /* UMS was only ever supported on pci devices. */
if (WARN_ON(!dev->pdev))
return -EINVAL;

-- 
2.7.4



[PATCH v2 18/25] drm/msm/dsi: Don't get DSI index from DT

2016-06-24 Thread Archit Taneja


On 06/23/2016 08:15 PM, Rob Herring wrote:
> On Thu, Jun 23, 2016 at 9:13 AM, Archit Taneja  
> wrote:
>> The DSI host and PHY driver currently expects the DT bindings to provide
>> custom properties "qcom,dsi-host-index" and "qcom,dsi-phy-index" so that
>> the driver can identify which DSI instance it is.
>>
>> The binding isn't acceptable, but the driver still needs to figure out
>> what its instance id. This is now done by storing the mmio starting
>> addresses for each DSI instance in every SoC version in the driver. The
>> driver then identifies the index number by trying to match the stored
>> address with comparing the resource start address we get from DT.
>
> I looked a bit more at this. It seems at least one reason you need to
> know which DSI instance is which is when ganging the instances
> together and needing to define the clock master. You could define a
> property for the clock master for example.

The ganging of instances itself has two parts to it: 1) routing the
external clocks feeding to the DSI hosts. That can be managed by
assigned clocks without the need of having a clock-master property.
I've shared an example at the end showing how that can be done. 2)
Programming certain PHY register fields telling it which 'DSI index
number' it's getting its clocks from.

For (2), just having a 'clock-master' property in one of the instances
property isn't sufficient to program the register field. We need to
know that DSI0 is 0, and DSI1 is 1. That's why we need to derive it in
the driver itself if we don't have a property for it in DT.

It would have been nicer if the register interface had let us say
"I am the master" or "other instance is the master", but I guess that
wouldn't have worked if a SoC had, say, 3 DSI instances.

I guess we can derive the instance number from the driver internally
as done in this patch, use assigned clocks to set up the routing of
the external clocks, and have a "qcom,dsi-clock-master" property
only needed for Dual DSI usecases.

Does this sound good?

Thanks,
Archit

In the example bindings below, DSI0 PLL outputs are used to drive both
the DSIs, i.e, DSI0 instance is the clock master:

dsi_phy0 {
/* DSI0 PLL clock provider */
};

dsi_phy1 {
/* DSI1 PLL clock provider */
};

dsi0 {
...

assigned-clocks =
< BYTE0_CLK_SRC>,
< PCLK0_CLK_SRC>;
assigned-clock-parents =
<_phy0 0>,
<_phy0 1>;
...

};

dsi1 {
...
assigned-clocks =
< BYTE1_CLK_SRC>,
< PCLK1_CLK_SRC>;
assigned-clock-parents =
<_phy0 0>,
<_phy0 1>;
...
};


>
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


[RFC 5/5] dma-buf/sync_file: rework fence storage in struct file

2016-06-24 Thread Gustavo Padovan
2016-06-23 Chris Wilson :

> On Thu, Jun 23, 2016 at 12:29:50PM -0300, Gustavo Padovan wrote:
> > -static void sync_file_add_pt(struct sync_file *sync_file, int *i,
> > +static int sync_file_set_fence(struct sync_file *sync_file,
> > +  struct fence **fences)
> > +{
> > +   struct fence_array *array;
> > +
> > +   if (sync_file->num_fences == 1) {
> > +   sync_file->fence = fences[0];
> 
> Straightforward pointer assignment.
> 
> > +   } else {
> > +   array = fence_array_create(sync_file->num_fences, fences,
> > +  fence_context_alloc(1), 1, false);
> > +   if (!array)
> > +   return -ENOMEM;
> > +
> > +   sync_file->fence = >base;
> 
> New reference.
> 
> Imbalance will promptly go bang after we release the single fence[0].
> 
> Would fence_array_create(1, fence) returning fence_get(fence) be too
> much of a hack?
> 
> I would suggest dropping the exported fence_get_fences() and use a local
> instead that could avoid the copy, e.g.
> 
> static struct fence *get_fences(struct fence **fence,
>   unsigned int *num_fences)
> {
>   if (fence_is_array(*fence)) {
>   struct fence_array *array = to_fence_array(*fence);
>   *num_fences = array->num_fences;
>   return array->fences;
>   } else {
>   *num_fences = 1;
>   return fence;
>   }
> }
> 
> sync_file_merge() {
>   int num_fences, num_a_fences, num_b_fences;
>   struct fence **fences, **a_fences, **b_fences;
> 
>   a_fences = get_fences(, _a_fences);
>   b_fences = get_fences(, _b_fences);
> 
>   num_fences = num_a_fences + num_b_fences;


Yes. That is much cleaner solution. I did this initially but then tried
to come up with .get_fences(), but that was the wrong road.

> 
> >  static void sync_file_free(struct kref *kref)
> >  {
> > struct sync_file *sync_file = container_of(kref, struct sync_file,
> >  kref);
> > -   int i;
> > -
> > -   for (i = 0; i < sync_file->num_fences; ++i) {
> > -   fence_remove_callback(sync_file->cbs[i].fence,
> > - _file->cbs[i].cb);
> > -   fence_put(sync_file->cbs[i].fence);
> > -   }
> >  
> > +   fence_remove_callback(sync_file->fence, _file->cb);
> > +   fence_teardown(sync_file->fence);
> 
> Hmm. Could we detect the removal of the last callback and propagate that
> to the fence_array? (Rather then introduce a manual call to
> fence_teardown.)

Maybe. I'll look into ways to identify that. What I did during the
development of this patch was to have a fence_array_destroy(), but then
I moved to .teardown() in the hope to abstract the diff between fences
and fence_arrays.

Gustavo


Reported regressions for 4.7 as of Sunday, 2016-06-19

2016-06-24 Thread George Spelvin
Here's a regression you might add.  I only reported it to dri-devel,
since it's DRI-specific, but since there's been thunderous silence
for a few weeks, I'm trying to be a squeakier wheel.

Given that I bisected it to a single, small, revertable commit, I'd
hoped it would be easy to deal with.

[BISECTED: 0955c1250e] 4.7-rc1 oops at drm_connector_cleanup+0x5c/0x1d0 

E-mail report at
https://marc.info/?l=dri-devel=146577898611849

Bugzilla report at
https://bugs.freedesktop.org/show_bug.cgi?id=96532


[RFC 1/5] dma-buf/fence: add .teardown() ops

2016-06-24 Thread Gustavo Padovan
2016-06-23 Chris Wilson :

> On Thu, Jun 23, 2016 at 12:29:46PM -0300, Gustavo Padovan wrote:
> > From: Gustavo Padovan 
> > 
> > fence_array requires a function to clean up its state before we
> > are able to call fence_put() and release it.
> 
> An explanation along the lines of:
> 
> As the array of fence callbacks held by an active struct fence_array
> each has a reference to the struct fence_array, when the owner of the
> fence_array is freed it must dispose of the callback references before
> it can free the fence_array. This can not happen simply during
> fence_release() because of the extra references and so we need a new
> function to run before the final fence_put().
> 
> would help, it is not until you use it in 5/5 that it becomes apparent
> why it is needed.

That is much better explanation. Thanks!

Gustavo


[RFC 0/5] rework fences on struct sync_file

2016-06-24 Thread Gustavo Padovan
Hi Christian,

2016-06-24 Christian König :

> Am 23.06.2016 um 17:29 schrieb Gustavo Padovan:
> > From: Gustavo Padovan 
> > 
> > Hi all,
> > 
> > This is an attempt to improve fence support on Sync File. The basic idea
> > is to have only sync_file->fence and store all fences there, either as
> > normal fences or fence_arrays. That way we can remove some potential
> > duplication when using fence_array with sync_file: the duplication of the 
> > array
> > of fences and the duplication of fence_add_callback() for all fences.
> > 
> > Now when creating a new sync_file during the merge process 
> > sync_file_set_fence()
> > will set sync_file->fence based on the number of fences for that sync_file. 
> > If
> > there is more than one fence a fence_array is created. One important 
> > advantage
> > approach is that we only add one fence callback now, no matter how many 
> > fences
> > there are in a sync_file - the individual callbacks are added by 
> > fence_array.
> > 
> > Two fence ops had to be created to help abstract the difference between 
> > handling
> > fences and fences_arrays: .teardown() and .get_fences(). The former run 
> > needed
> > on fence_array, and the latter just return a copy of all fences in the 
> > fence.
> > I'm not so sure about adding those two, speacially .get_fences(). What do 
> > you
> > think?
> 
> Clearly not a good idea to add this a fence ops, cause those are specialized
> functions for only a certain fence implementation (the fence_array).

Are you refering only to .get_fences()?

> 
> What you should do is try to cast the fence in your sync file using
> to_fence_array() and then you can access the fences in the array.

Yes, that seems a better idea I think. The initial idea was to abstract 
the difference as much as possible, but it doesn't seem really worth
for .get_fences().

Gustavo


[PATCH v5 8/8] iommu/rockchip: Enable Rockchip IOMMU on ARM64

2016-06-24 Thread Shunqian Zheng
From: Simon Xue 

This patch makes it possible to compile the rockchip-iommu driver on
ARM64, so that it can be used with 64-bit SoCs equipped with this type
of IOMMU.

Signed-off-by: Simon Xue 
Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
---
 drivers/iommu/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index ad08603..5572621 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -218,7 +218,7 @@ config OMAP_IOMMU_DEBUG

 config ROCKCHIP_IOMMU
bool "Rockchip IOMMU Support"
-   depends on ARM
+   depends on ARM || ARM64
depends on ARCH_ROCKCHIP || COMPILE_TEST
select IOMMU_API
select ARM_DMA_USE_IOMMU
-- 
1.9.1



[PATCH v5 7/8] drm/rockchip: Use common IOMMU API to attach devices

2016-06-24 Thread Shunqian Zheng
Rockchip DRM used the arm special API, arm_iommu_*(), to attach
iommu for ARM32 SoCs. This patch convert to common iommu API
so it would support ARM64 like RK3399.

Since previous patch added support for direct IOMMU address space
management, there is no need to use DMA API anymore and this patch wires
things to use the new method.

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 100 +++-
 1 file changed, 53 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 8b96c69..ca9624f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -14,18 +14,18 @@
  * GNU General Public License for more details.
  */

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

 #include 

@@ -51,28 +51,31 @@ static struct drm_driver rockchip_drm_driver;
 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
   struct device *dev)
 {
-   struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
+   struct rockchip_drm_private *private = drm_dev->dev_private;
int ret;

if (!is_support_iommu)
return 0;

-   ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
-   if (ret)
+   ret = iommu_attach_device(private->domain, dev);
+   if (ret) {
+   dev_err(dev, "Failed to attach iommu device\n");
return ret;
+   }

-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   return arm_iommu_attach_device(dev, mapping);
+   return 0;
 }

 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev)
 {
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain *domain = private->domain;
+
if (!is_support_iommu)
return;

-   arm_iommu_detach_device(dev);
+   iommu_detach_device(domain, dev);
 }

 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
@@ -137,11 +140,45 @@ static void rockchip_drm_crtc_disable_vblank(struct 
drm_device *dev,
priv->crtc_funcs[pipe]->disable_vblank(crtc);
 }

+static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+   struct iommu_domain_geometry *geometry;
+   u64 start, end;
+
+   if (!is_support_iommu)
+   return 0;
+
+   private->domain = iommu_domain_alloc(_bus_type);
+   if (!private->domain)
+   return -ENOMEM;
+
+   geometry = >domain->geometry;
+   start = geometry->aperture_start;
+   end = geometry->aperture_end;
+
+   DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
+ start, end);
+   drm_mm_init(>mm, start, end - start + 1);
+
+   return 0;
+}
+
+static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
+{
+   struct rockchip_drm_private *private = drm_dev->dev_private;
+
+   if (!is_support_iommu)
+   return;
+
+   drm_mm_takedown(>mm);
+   iommu_domain_free(private->domain);
+}
+
 static int rockchip_drm_bind(struct device *dev)
 {
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
-   struct dma_iommu_mapping *mapping = NULL;
int ret;

drm_dev = drm_dev_alloc(_drm_driver, dev);
@@ -162,38 +199,14 @@ static int rockchip_drm_bind(struct device *dev)

rockchip_drm_mode_config_init(drm_dev);

-   dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
- GFP_KERNEL);
-   if (!dev->dma_parms) {
-   ret = -ENOMEM;
+   ret = rockchip_drm_init_iommu(drm_dev);
+   if (ret)
goto err_config_cleanup;
-   }
-
-   if (is_support_iommu) {
-   /* TODO(djkurtz): fetch the mapping start/size from somewhere */
-   mapping = arm_iommu_create_mapping(_bus_type,
-  0x,
-  SZ_2G);
-   if (IS_ERR(mapping)) {
-   ret = PTR_ERR(mapping);
-   goto err_config_cleanup;
-   }
-
-   ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-   if (ret)
-   goto err_release_mapping;
-
-   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
-   ret = arm_iommu_attach_device(dev, mapping);
-   if (ret)
-   goto err_release_mapping;
-   }

/* Try to bind all sub drivers. */
ret = component_bind_all(dev, drm_dev);
if (ret)
-   goto err_detach_device;
+  

[PATCH v5 6/8] drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

2016-06-24 Thread Shunqian Zheng
From: Tomasz Figa 

The API is not suitable for subsystems consisting of multiple devices
and requires severe hacks to use it. To mitigate this, this patch
implements allocation and address space management locally by using
helpers provided by DRM framework, like other DRM drivers do, e.g.
Tegra.

This patch should not introduce any functional changes until the driver
is made to attach subdevices into an IOMMU domain with the generic IOMMU
API, which will happen in following patch. Based heavily on GEM
implementation of Tegra DRM driver.

Signed-off-by: Tomasz Figa 
Signed-off-by: Shunqian Zheng 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   3 +
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 221 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   9 ++
 3 files changed, 222 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..5ab1223 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@

 struct drm_device;
 struct drm_connector;
+struct iommu_domain;

 /*
  * Rockchip drm private crtc funcs.
@@ -61,6 +62,8 @@ struct rockchip_drm_private {
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
+   struct iommu_domain *domain;
+   struct drm_mm mm;
 };

 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 394f92b..e7cd93d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -19,11 +19,135 @@
 #include 

 #include 
+#include 

 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"

-static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
+static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+   int prot = IOMMU_READ | IOMMU_WRITE;
+   ssize_t ret;
+
+   ret = drm_mm_insert_node_generic(>mm, _obj->mm,
+rk_obj->base.size, PAGE_SIZE,
+0, 0, 0);
+   if (ret < 0) {
+   DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
+   return ret;
+   }
+
+   rk_obj->dma_addr = rk_obj->mm.start;
+
+   ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
+  rk_obj->sgt->nents, prot);
+   if (ret < 0) {
+   DRM_ERROR("failed to map buffer: %zd\n", ret);
+   goto err_remove_node;
+   }
+
+   rk_obj->size = ret;
+
+   return 0;
+
+err_remove_node:
+   drm_mm_remove_node(_obj->mm);
+
+   return ret;
+}
+
+static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   struct rockchip_drm_private *private = drm->dev_private;
+
+   iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
+   drm_mm_remove_node(_obj->mm);
+
+   return 0;
+}
+
+static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
+{
+   struct drm_device *drm = rk_obj->base.dev;
+   int ret, i;
+   struct scatterlist *s;
+
+   rk_obj->pages = drm_gem_get_pages(_obj->base);
+   if (IS_ERR(rk_obj->pages))
+   return PTR_ERR(rk_obj->pages);
+
+   rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
+
+   rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages);
+   if (IS_ERR(rk_obj->sgt)) {
+   ret = PTR_ERR(rk_obj->sgt);
+   goto err_put_pages;
+   }
+
+   /*
+* Fake up the SG table so that dma_sync_sg_for_device() can be used
+* to flush the pages associated with it.
+*
+* TODO: Replace this by drm_clflush_sg() once it can be implemented
+* without relying on symbols that are not exported.
+*/
+   for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
+  DMA_TO_DEVICE);
+
+   return 0;
+
+err_put_pages:
+   drm_gem_put_pages(_obj->base, rk_obj->pages, false, false);
+   return ret;
+}
+
+static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj)
+{
+   sg_free_table(rk_obj->sgt);
+   kfree(rk_obj->sgt);
+   drm_gem_put_pages(_obj->base, rk_obj->pages, false, false);
+}
+
+static int rockchip_gem_alloc_iommu(struct rockchip_gem_object *rk_obj,
+   bool alloc_kmap)
+{
+   int ret;
+
+   ret = rockchip_gem_get_pages(rk_obj);
+   if 

[PATCH v5 5/8] iommu/rockchip: Prepare to support generic DMA mapping

2016-06-24 Thread Shunqian Zheng
Set geometry for allocated domains and fix .domain_alloc() callback to
work with IOMMU_DOMAIN_DMA domain type, which is used for implicit
domains on ARM64.

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
---
 drivers/iommu/rockchip-iommu.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 712ed75..9afcbf7 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -889,7 +889,7 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned 
type)
struct platform_device *pdev;
struct device *iommu_dev;

-   if (type != IOMMU_DOMAIN_UNMANAGED)
+   if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
return NULL;

/* Register a pdev per domain, so DMA API can base on this *dev
@@ -906,8 +906,8 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned 
type)

rk_domain->pdev = pdev;

-   /* To init the iovad which is required by iommu_dma_init_domain() */
-   if (iommu_get_dma_cookie(_domain->domain))
+   if (type == IOMMU_DOMAIN_DMA &&
+   iommu_get_dma_cookie(_domain->domain))
goto err_unreg_pdev;

/*
@@ -933,12 +933,17 @@ static struct iommu_domain 
*rk_iommu_domain_alloc(unsigned type)
spin_lock_init(_domain->dt_lock);
INIT_LIST_HEAD(_domain->iommus);

+   rk_domain->domain.geometry.aperture_start = 0;
+   rk_domain->domain.geometry.aperture_end   = DMA_BIT_MASK(32);
+   rk_domain->domain.geometry.force_aperture = true;
+
return _domain->domain;

 err_free_dt:
free_page((unsigned long)rk_domain->dt);
 err_put_cookie:
-   iommu_put_dma_cookie(_domain->domain);
+   if (type == IOMMU_DOMAIN_DMA)
+   iommu_put_dma_cookie(_domain->domain);
 err_unreg_pdev:
platform_device_unregister(pdev);

@@ -967,7 +972,8 @@ static void rk_iommu_domain_free(struct iommu_domain 
*domain)
 SPAGE_SIZE, DMA_TO_DEVICE);
free_page((unsigned long)rk_domain->dt);

-   iommu_put_dma_cookie(_domain->domain);
+   if (domain->type == IOMMU_DOMAIN_DMA)
+   iommu_put_dma_cookie(_domain->domain);

platform_device_unregister(rk_domain->pdev);
 }
-- 
1.9.1



[PATCH v5 4/8] iommu/rockchip: Use DMA API to manage coherency

2016-06-24 Thread Shunqian Zheng
Use DMA API instead of architecture internal functions like
__cpuc_flush_dcache_area() etc.

The biggest difficulty here is that dma_map and _sync calls require some
struct device, while there is no real 1:1 relation between an IOMMU
domain and some device. To overcome this, a simple platform device is
registered for each allocated IOMMU domain.

With this patch, this driver can be used on both ARM and ARM64
platforms, such as RK3288 and RK3399 respectively.

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
---
 drivers/iommu/rockchip-iommu.c | 162 +++--
 1 file changed, 123 insertions(+), 39 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 8a5bac7..712ed75 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -4,11 +4,10 @@
  * published by the Free Software Foundation.
  */

-#include 
-#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -77,7 +76,9 @@

 struct rk_iommu_domain {
struct list_head iommus;
+   struct platform_device *pdev;
u32 *dt; /* page directory table */
+   dma_addr_t dt_dma;
spinlock_t iommus_lock; /* lock for iommus list */
spinlock_t dt_lock; /* lock for modifying page directory table */

@@ -93,14 +94,12 @@ struct rk_iommu {
struct iommu_domain *domain; /* domain to which iommu is attached */
 };

-static inline void rk_table_flush(u32 *va, unsigned int count)
+static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma,
+ unsigned int count)
 {
-   phys_addr_t pa_start = virt_to_phys(va);
-   phys_addr_t pa_end = virt_to_phys(va + count);
-   size_t size = pa_end - pa_start;
+   size_t size = count * sizeof(u32); /* count of u32 entry */

-   __cpuc_flush_dcache_area(va, size);
-   outer_flush_range(pa_start, pa_end);
+   dma_sync_single_for_device(>pdev->dev, dma, size, DMA_TO_DEVICE);
 }

 static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
@@ -183,10 +182,9 @@ static inline bool rk_dte_is_pt_valid(u32 dte)
return dte & RK_DTE_PT_VALID;
 }

-static u32 rk_mk_dte(u32 *pt)
+static inline u32 rk_mk_dte(dma_addr_t pt_dma)
 {
-   phys_addr_t pt_phys = virt_to_phys(pt);
-   return (pt_phys & RK_DTE_PT_ADDRESS_MASK) | RK_DTE_PT_VALID;
+   return (pt_dma & RK_DTE_PT_ADDRESS_MASK) | RK_DTE_PT_VALID;
 }

 /*
@@ -603,13 +601,16 @@ static void rk_iommu_zap_iova_first_last(struct 
rk_iommu_domain *rk_domain,
 static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
  dma_addr_t iova)
 {
+   struct device *dev = _domain->pdev->dev;
u32 *page_table, *dte_addr;
-   u32 dte;
+   u32 dte_index, dte;
phys_addr_t pt_phys;
+   dma_addr_t pt_dma;

assert_spin_locked(_domain->dt_lock);

-   dte_addr = _domain->dt[rk_iova_dte_index(iova)];
+   dte_index = rk_iova_dte_index(iova);
+   dte_addr = _domain->dt[dte_index];
dte = *dte_addr;
if (rk_dte_is_pt_valid(dte))
goto done;
@@ -618,19 +619,27 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain 
*rk_domain,
if (!page_table)
return ERR_PTR(-ENOMEM);

-   dte = rk_mk_dte(page_table);
-   *dte_addr = dte;
+   pt_dma = dma_map_single(dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, pt_dma)) {
+   dev_err(dev, "DMA mapping error while allocating page table\n");
+   free_page((unsigned long)page_table);
+   return ERR_PTR(-ENOMEM);
+   }

-   rk_table_flush(page_table, NUM_PT_ENTRIES);
-   rk_table_flush(dte_addr, 1);
+   dte = rk_mk_dte(pt_dma);
+   *dte_addr = dte;

+   rk_table_flush(rk_domain, pt_dma, NUM_PT_ENTRIES);
+   rk_table_flush(rk_domain,
+  rk_domain->dt_dma + dte_index * sizeof(u32), 1);
 done:
pt_phys = rk_dte_pt_address(dte);
return (u32 *)phys_to_virt(pt_phys);
 }

 static size_t rk_iommu_unmap_iova(struct rk_iommu_domain *rk_domain,
- u32 *pte_addr, dma_addr_t iova, size_t size)
+ u32 *pte_addr, dma_addr_t pte_dma,
+ size_t size)
 {
unsigned int pte_count;
unsigned int pte_total = size / SPAGE_SIZE;
@@ -645,14 +654,14 @@ static size_t rk_iommu_unmap_iova(struct rk_iommu_domain 
*rk_domain,
pte_addr[pte_count] = rk_mk_pte_invalid(pte);
}

-   rk_table_flush(pte_addr, pte_count);
+   rk_table_flush(rk_domain, pte_dma, pte_count);

return pte_count * SPAGE_SIZE;
 }

 static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
-dma_addr_t iova, phys_addr_t paddr, size_t size,
-int prot)
+ 

[PATCH v5 3/8] iommu/rockchip: Fix allocation of bases array in driver probe

2016-06-24 Thread Shunqian Zheng
In .probe(), devm_kzalloc() is called with size == 0 and works only
by luck, due to internal behavior of the allocator and the fact
that the proper allocation size is small. Let's use proper value for
calculating the size.

Fixes: cd6438c5f844 ("iommu/rockchip: Reconstruct to support multi slaves")

Signed-off-by: Shunqian Zheng 
Signed-off-by: Tomasz Figa 
Reviewed-by: Douglas Anderson 
---
 drivers/iommu/rockchip-iommu.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 53fa0d9..8a5bac7 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1034,6 +1034,7 @@ static int rk_iommu_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct rk_iommu *iommu;
struct resource *res;
+   int num_res = pdev->num_resources;
int i;

iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
@@ -1043,12 +1044,13 @@ static int rk_iommu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, iommu);
iommu->dev = dev;
iommu->num_mmu = 0;
-   iommu->bases = devm_kzalloc(dev, sizeof(*iommu->bases) * iommu->num_mmu,
+
+   iommu->bases = devm_kzalloc(dev, sizeof(*iommu->bases) * num_res,
GFP_KERNEL);
if (!iommu->bases)
return -ENOMEM;

-   for (i = 0; i < pdev->num_resources; i++) {
+   for (i = 0; i < num_res; i++) {
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res)
continue;
-- 
1.9.1



[PATCH v5 2/8] iommu/rockchip: Add map_sg callback for rk_iommu_ops

2016-06-24 Thread Shunqian Zheng
From: Simon Xue 

The iommu_dma_alloc() in iommu/dma-iommu.c calls iommu_map_sg()
that requires the callback iommu_ops .map_sg(). Adding the
default_iommu_map_sg() to Rockchip IOMMU accordingly.

Signed-off-by: Simon Xue 
Signed-off-by: Shunqian Zheng 
Reviewed-by: Douglas Anderson 
Signed-off-by: Tomasz Figa 
---
 drivers/iommu/rockchip-iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 5a9659a..53fa0d9 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1022,6 +1022,7 @@ static const struct iommu_ops rk_iommu_ops = {
.detach_dev = rk_iommu_detach_device,
.map = rk_iommu_map,
.unmap = rk_iommu_unmap,
+   .map_sg = default_iommu_map_sg,
.add_device = rk_iommu_add_device,
.remove_device = rk_iommu_remove_device,
.iova_to_phys = rk_iommu_iova_to_phys,
-- 
1.9.1



[PATCH v5 1/8] iommu/rockchip: Fix devm_{request,free}_irq parameter

2016-06-24 Thread Shunqian Zheng
From: Simon Xue 

Even though the IOMMU shares IRQ with its master, the struct device
passed to {request,free}_irq is supposed to represent the device that is
signalling the interrupt. This patch makes the driver use IOMMU device
instead of master's device to make things clear.

Signed-off-by: Simon Xue 
Signed-off-by: Shunqian Zheng 
Reviewed-by: Douglas Anderson 
Signed-off-by: Tomasz Figa 
---
 drivers/iommu/rockchip-iommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 25b4627..5a9659a 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -807,7 +807,7 @@ static int rk_iommu_attach_device(struct iommu_domain 
*domain,

iommu->domain = domain;

-   ret = devm_request_irq(dev, iommu->irq, rk_iommu_irq,
+   ret = devm_request_irq(iommu->dev, iommu->irq, rk_iommu_irq,
   IRQF_SHARED, dev_name(dev), iommu);
if (ret)
return ret;
@@ -860,7 +860,7 @@ static void rk_iommu_detach_device(struct iommu_domain 
*domain,
}
rk_iommu_disable_stall(iommu);

-   devm_free_irq(dev, iommu->irq, iommu);
+   devm_free_irq(iommu->dev, iommu->irq, iommu);

iommu->domain = NULL;

-- 
1.9.1



iommu/rockchip: Fix bugs and enable on ARM64

2016-06-24 Thread Shunqian Zheng
This series intends mostly to enable support for ARM64 architecture
in the rockchip-iommu driver. On the way to do so, some bugs are also
fixed.

The most important changes here are:
 - making the Rockchip IOMMU driver use DMA API for managing cache
   coherency of page tables,
 - making the Rockchip DRM driver not use DMA API on behalf of a virtual
   device (behind a virtual IOMMU) to allocate and map buffers, but
   instead proper DRM helpers and IOMMU API directly.

Changes since v4:
 - Address some coding style comments on:
- https://chromium-review.googlesource.com/#/c/346328/38
- https://chromium-review.googlesource.com/#/c/353591/10
Changes since v3:
 - Drop the idea of virtual IOMMU. Instead replace hacky allocation code
   in DRM driver, with proper management of IOMMU domain.
 - Add one more fix for allocation of IOMMU register base addresses.
Changes since v2:
 - Instead of registering virtual IOMMU from DTS, create it when
   attaching.
 - Fix some bugs found in internal review.

Shunqian Zheng (4):
  iommu/rockchip: Fix allocation of bases array in driver probe
  iommu/rockchip: Use DMA API to manage coherency
  iommu/rockchip: Prepare to support generic DMA mapping
  drm/rockchip: Use common IOMMU API to attach devices

Simon Xue (3):
  iommu/rockchip: Fix devm_{request,free}_irq parameter
  iommu/rockchip: Add map_sg callback for rk_iommu_ops
  iommu/rockchip: Enable Rockchip IOMMU on ARM64

Tomasz Figa (1):
  drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 100 +++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   3 +
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 221 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.h |   9 ++
 drivers/iommu/Kconfig   |   2 +-
 drivers/iommu/rockchip-iommu.c  | 181 +--
 6 files changed, 413 insertions(+), 103 deletions(-)

-- 
1.9.1



[PATCH 9/9] async: Introduce a dependency resolver for parallel execution

2016-06-24 Thread Chris Wilson
A challenge in driver initialisation is the coordination of many small
sometimes independent, sometimes interdependent tasks. We would like to
schedule the independent tasks for execution in parallel across as many
cores as possible for rapid initialisation, and then schedule all the
dependent tasks once they have completed, again running as many of those
in parallel as is possible.

Resolving the interdependencies by hand is time consuming and error
prone. Instead, we want to declare what dependencies a particular task
has, and what that task provides, and let a runtime dependency solver
work out what tasks to run and when, and which in parallel. To this end,
we introduce the struct async_dependency_graph building upon the kfence
and async_work from the previous patches to allow for the runtime
computation of the topological task ordering.

The graph is constructed with async_dependency_graph_build(), which
takes the task, its dependencies and what it provides, and builds the
graph of kfences required for ordering. Additional kfences can be
inserted through async_dependency_depends() and
async_dependency_provides() for manual control of the execution order,
and async_dependency_get() retrieves a kfence for inspection or waiting
upon.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/async.h  |  37 +++
 kernel/async.c | 250 
 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   1 +
 lib/test-async-dependency-graph.c  | 317 +
 .../selftests/lib/async-dependency-graph.sh|  10 +
 6 files changed, 627 insertions(+)
 create mode 100644 lib/test-async-dependency-graph.c
 create mode 100755 tools/testing/selftests/lib/async-dependency-graph.sh

diff --git a/include/linux/async.h b/include/linux/async.h
index 64a090e3f24f..c9cadb383813 100644
--- a/include/linux/async.h
+++ b/include/linux/async.h
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 

 typedef u64 async_cookie_t;
 typedef void (*async_func_t) (void *data, async_cookie_t cookie);
@@ -101,4 +102,40 @@ extern async_cookie_t queue_async_work(struct async_domain 
*domain,
   gfp_t gfp);
 extern async_cookie_t schedule_async_work(struct async_work *work);

+/* Build a graph of work based on dependencies generated by keywords.
+ * The graph must be acyclic. Can be used to both generate a topological
+ * ordering of tasks, and to execute independent chains of tasks in
+ * parallel.
+ */
+
+struct async_dependency_graph {
+   struct rb_root root;
+   struct list_head list;
+};
+
+#define ASYNC_DEPENDENCY_GRAPH_INIT(_name) {   \
+   .root = RB_ROOT,\
+   .list = LIST_HEAD_INIT(_name.list), \
+}
+#define ASYNC_DEPENDENCY_GRAPH(_name) \
+   struct async_dependency_graph _name = ASYNC_DEPENDENCY_GRAPH_INIT(_name)
+
+extern int async_dependency_graph_build(struct async_dependency_graph *adg,
+   async_func_t fn, void *data,
+   const char *depends,
+   const char *provides);
+
+extern int async_dependency_depends(struct async_dependency_graph *adg,
+   struct kfence *fence,
+   const char *depends);
+
+extern int async_dependency_provides(struct async_dependency_graph *adg,
+struct kfence *fence,
+const char *provides);
+
+extern struct kfence *async_dependency_get(struct async_dependency_graph *adg,
+  const char *name);
+
+extern void async_dependency_graph_execute(struct async_dependency_graph *adg);
+
 #endif
diff --git a/kernel/async.c b/kernel/async.c
index a22945f4b4c4..8330d719074b 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -1005,3 +1005,253 @@ void init_async_domain(struct async_domain *domain, 
bool registered)
domain->registered = registered;
 }
 EXPORT_SYMBOL_GPL(init_async_domain);
+
+struct async_dependency {
+   struct kfence fence;
+   struct rb_node node;
+   struct list_head link;
+   char name[0];
+};
+
+static struct async_dependency *

[PATCH 8/9] async: Add execution barriers

2016-06-24 Thread Chris Wilson
A frequent mode of operation is fanning out N tasks to execute in
parallel, collating results, fanning out M tasks, rinse and repeat. This
is also common to the notion of the async/sync kernel domain split.
A barrier provides a mechanism by which all work queued after the
barrier must wait (i.e. not be scheduled) until all work queued before the
barrier is completed.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/async.h |  4 
 kernel/async.c| 60 +++
 2 files changed, 64 insertions(+)

diff --git a/include/linux/async.h b/include/linux/async.h
index 45d6c8323b60..64a090e3f24f 100644
--- a/include/linux/async.h
+++ b/include/linux/async.h
@@ -26,6 +26,7 @@ struct async_work {

 struct async_domain {
struct list_head pending;
+   struct kfence *barrier;
unsigned registered:1;
 };

@@ -59,6 +60,9 @@ extern void async_synchronize_cookie(async_cookie_t cookie);
 extern void async_synchronize_cookie_domain(async_cookie_t cookie,
struct async_domain *domain);

+extern void async_barrier(void);
+extern void async_barrier_domain(struct async_domain *domain);
+
 extern bool current_is_async(void);

 extern struct async_work *
diff --git a/kernel/async.c b/kernel/async.c
index 83007c39a113..a22945f4b4c4 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -724,6 +724,12 @@ struct async_work *async_work_create(async_func_t func, 
void *data, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(async_work_create);

+static void async_barrier_delete(struct async_domain *domain)
+{
+   kfence_put(domain->barrier);
+   domain->barrier = NULL;
+}
+
 async_cookie_t queue_async_work(struct async_domain *domain,
struct async_work *work,
gfp_t gfp)
@@ -744,6 +750,9 @@ async_cookie_t queue_async_work(struct async_domain *domain,
async_pending_count++;
spin_unlock_irqrestore(_lock, flags);

+   if (!kfence_add(>base.fence, domain->barrier, gfp))
+   async_barrier_delete(domain);
+
/* mark that this task has queued an async job, used by module init */
current->flags |= PF_USED_ASYNC;

@@ -811,6 +820,55 @@ async_cookie_t async_schedule_domain(async_func_t func, 
void *data,
 }
 EXPORT_SYMBOL_GPL(async_schedule_domain);

+static struct kfence * __async_barrier_create(struct async_domain *domain)
+{
+   struct kfence *fence;
+   struct async_entry *entry;
+   unsigned long flags;
+   int ret;
+
+   fence = kfence_create(GFP_KERNEL);
+   if (!fence)
+   goto out_sync;
+
+   ret = 0;
+   spin_lock_irqsave(_lock, flags);
+   list_for_each_entry(entry, >pending, pending_link[0]) {
+   ret |= kfence_add(fence, >base.fence, GFP_ATOMIC);
+   if (ret < 0)
+   break;
+   }
+   spin_unlock_irqrestore(_lock, flags);
+   if (ret <= 0)
+   goto out_put;
+
+   kfence_add(fence, domain->barrier, GFP_KERNEL);
+   kfence_signal(fence);
+   return fence;
+
+out_put:
+   kfence_signal(fence);
+   kfence_put(fence);
+out_sync:
+   async_synchronize_full_domain(domain);
+   return NULL;
+}
+
+void async_barrier(void)
+{
+   async_barrier_domain(_dfl_domain);
+}
+EXPORT_SYMBOL_GPL(async_barrier);
+
+void async_barrier_domain(struct async_domain *domain)
+{
+   struct kfence *barrier = __async_barrier_create(domain);
+
+   kfence_put(domain->barrier);
+   domain->barrier = barrier;
+}
+EXPORT_SYMBOL_GPL(async_barrier_domain);
+
 /**
  * async_synchronize_full - synchronize all asynchronous function calls
  *
@@ -834,6 +892,8 @@ EXPORT_SYMBOL_GPL(async_synchronize_full);
 void async_unregister_domain(struct async_domain *domain)
 {
WARN_ON(!list_empty(>pending));
+
+   async_barrier_delete(domain);
domain->registered = 0;
 }
 EXPORT_SYMBOL_GPL(async_unregister_domain);
-- 
2.8.1



[PATCH 7/9] async: Add support for explicit fine-grained barriers

2016-06-24 Thread Chris Wilson
The current async-domain model supports running a multitude of
independent tasks with a coarse synchronisation point. This is
sufficient for its original purpose of allowing independent drivers to
run concurrently during various phases (booting, early resume, late
resume etc), and keep the asynchronous domain out of the synchronous
kernel domains. However, for greater exploitation, drivers themselves
want to schedule multiple tasks within a phase (or between phases) and
control the order of execution within those tasks relative to each
other. To enable this, we extend the synchronisation scheme based upon
kfences and back every task with one. Any task may now wait upon the
kfence before being scheduled, and equally the kfence may be used to
wait on the task itself (rather than waiting on the cookie for all
previous tasks to be completed).

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/async.h   |  60 +-
 kernel/async.c  | 244 +
 lib/test-async-domain.c | 311 +++-
 3 files changed, 505 insertions(+), 110 deletions(-)

diff --git a/include/linux/async.h b/include/linux/async.h
index 6b0226bdaadc..45d6c8323b60 100644
--- a/include/linux/async.h
+++ b/include/linux/async.h
@@ -13,38 +13,88 @@
 #define __ASYNC_H__

 #include 
+#include 
 #include 

 typedef u64 async_cookie_t;
 typedef void (*async_func_t) (void *data, async_cookie_t cookie);
+
+struct async_work {
+   struct kfence fence;
+   /* private */
+};
+
 struct async_domain {
struct list_head pending;
unsigned registered:1;
 };

+#define ASYNC_DOMAIN_INIT(_name, _r) { \
+   .pending = LIST_HEAD_INIT(_name.pending),   \
+   .registered = _r\
+}
+
 /*
  * domain participates in global async_synchronize_full
  */
 #define ASYNC_DOMAIN(_name) \
-   struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), 
\
- .registered = 1 }
+   struct async_domain _name = ASYNC_DOMAIN_INIT(_name, 1)

 /*
  * domain is free to go out of scope as soon as all pending work is
  * complete, this domain does not participate in async_synchronize_full
  */
 #define ASYNC_DOMAIN_EXCLUSIVE(_name) \
-   struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), 
\
- .registered = 0 }
+   struct async_domain _name = ASYNC_DOMAIN_INIT(_name, 0)
+
+extern void init_async_domain(struct async_domain *domain, bool registered);

 extern async_cookie_t async_schedule(async_func_t func, void *data);
 extern async_cookie_t async_schedule_domain(async_func_t func, void *data,
struct async_domain *domain);
-void async_unregister_domain(struct async_domain *domain);
+extern void async_unregister_domain(struct async_domain *domain);
 extern void async_synchronize_full(void);
 extern void async_synchronize_full_domain(struct async_domain *domain);
 extern void async_synchronize_cookie(async_cookie_t cookie);
 extern void async_synchronize_cookie_domain(async_cookie_t cookie,
struct async_domain *domain);
+
 extern bool current_is_async(void);
+
+extern struct async_work *
+async_work_create(async_func_t func, void *data, gfp_t gfp);
+
+static inline struct async_work *async_work_get(struct async_work *work)
+{
+   kfence_get(>fence);
+   return work;
+}
+
+static inline int
+async_work_after(struct async_work *work, struct kfence *fence)
+{
+   return kfence_add(>fence, fence, GFP_KERNEL);
+}
+
+static inline int
+async_work_before(struct async_work *work, struct kfence *fence)
+{
+   return kfence_add(fence, >fence, GFP_KERNEL);
+}
+
+static inline void async_work_wait(struct async_work *work)
+{
+   kfence_wait(>fence);
+}
+
+static inline void async_work_put(struct async_work *work)
+{
+   kfence_put(>fence);
+}
+
+extern async_cookie_t queue_async_work(struct async_domain *domain,
+  struct async_work *work,
+  gfp_t gfp);
+extern async_cookie_t schedule_async_work(struct async_work *work);
+
 #endif
diff --git a/kernel/async.c b/kernel/async.c
index 1fa1f39b5a74..83007c39a113 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -2,6 +2,7 @@
  * async.c: 

[PATCH 6/9] async: Add a convenience wrapper for waiting on implicit dma-buf

2016-06-24 Thread Chris Wilson
dma-buf implicitly track their (DMA) rendering using a
reservation_object, which tracks ether the last write (in an exclusive
fence) or the current renders (with a set of shared fences). To wait
upon a reservation object in conjunction with other sources,
kfence_add_reservation() extracts the DMA fences from the object and
adds the individual waits for the kfence.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/kfence.h |  5 
 kernel/async.c | 65 ++
 2 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 1abec5e6b23c..2f01eb052e4d 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -17,6 +17,7 @@
 struct completion;
 struct fence;
 enum hrtimer_mode;
+struct reservation_object;

 struct kfence {
wait_queue_head_t wait;
@@ -34,6 +35,10 @@ extern int kfence_add_completion(struct kfence *fence,
 extern int kfence_add_dma(struct kfence *fence,
  struct fence *dma,
  gfp_t gfp);
+extern int kfence_add_reservation(struct kfence *fence,
+ struct reservation_object *resv,
+ bool write,
+ gfp_t gfp);
 extern int kfence_add_delay(struct kfence *fence,
clockid_t clock, enum hrtimer_mode mode,
ktime_t delay, u64 slack,
diff --git a/kernel/async.c b/kernel/async.c
index 5d02445e36b7..1fa1f39b5a74 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -54,9 +54,10 @@ asynchronous and synchronous parts of the kernel.
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
+#include 
 #include 

 #include "workqueue_internal.h"
@@ -123,11 +124,17 @@ static atomic_t entry_count;
  * allowing multiple pending / signals to be sent before the kfence is
  * complete.
  *
- * kfence_add() / kfence_add_completion() / kfence_add_dma()
+ * kfence_add() / kfence_add_completion()
+ * / kfence_add_dma()
+ *
+ * sets the kfence to wait upon another fence or completion respectively. To
+ * wait upon DMA activity, either use
  *
- * sets the kfence to wait upon another fence, completion, or DMA fence
- * respectively. To set the fence to wait for at least a certain period of
- * time, or until after a certain point in time, use
+ * kfence_add_dma() or kfence_add_reservation()
+ *
+ * depending on the manner of DMA activity tracking.  To set the fence to wait
+ * for at least a certain period of time, or until after a certain point in
+ * time, use
  *
  * kfence_add_timer()
  *
@@ -547,6 +554,54 @@ int kfence_add_dma(struct kfence *fence, struct fence 
*dma, gfp_t gfp)
 EXPORT_SYMBOL_GPL(kfence_add_dma);

 /**
+ * kfence_add_reservation - set the fence to wait upon a reservation_object
+ * @fence: this kfence
+ * @resv: target reservation_object (collection of DMA fences) to wait upon
+ * @write: Wait for read or read/write access
+ * @gfp: the allowed allocation type
+ *
+ * kfence_add_reservation() causes the @fence to wait upon completion of the
+ * reservation object (a collection of DMA fences), either for read access
+ * or for read/write access.
+ *
+ * Returns 1 if the @fence was successfully to the waitqueues of @resv, 0
+ * if @resev was already signaled (and so not added), or a negative error code.
+ */
+int kfence_add_reservation(struct kfence *fence,
+  struct reservation_object *resv,
+  bool write,
+  gfp_t gfp)
+{
+   struct fence *excl, **shared;
+   unsigned count, i;
+   int ret;
+
+   ret = reservation_object_get_fences_rcu(resv, , , );
+   if (ret)
+   return ret;
+
+   if (write) {
+   for (i = 0; i < count; i++) {
+   ret |= kfence_add_dma(fence, shared[i], gfp);
+   if (ret < 0)
+   goto out;
+   }
+   }
+
+   if (excl)
+   ret |= kfence_add_dma(fence, excl, gfp);
+
+out:
+   fence_put(excl);
+   for (i = 0; i < count; i++)
+   fence_put(shared[i]);
+   kfree(shared);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(kfence_add_reservation);
+
+/**
  * kfence_add_delay - set the fence to wait for a period of time
  * @fence: this kfence
  * @clock: which clock to program
-- 

[PATCH 5/9] async: Wrap hrtimer to provide a time source for a kfence

2016-06-24 Thread Chris Wilson
kfence_add_delay() is a convenience wrapper around
hrtimer_start_range_ns() to provide a time source for a kfence graph.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/kfence.h |  5 +
 kernel/async.c | 60 +-
 lib/test-kfence.c  | 44 
 3 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index d71f30c626ae..1abec5e6b23c 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -16,6 +16,7 @@

 struct completion;
 struct fence;
+enum hrtimer_mode;

 struct kfence {
wait_queue_head_t wait;
@@ -33,6 +34,10 @@ extern int kfence_add_completion(struct kfence *fence,
 extern int kfence_add_dma(struct kfence *fence,
  struct fence *dma,
  gfp_t gfp);
+extern int kfence_add_delay(struct kfence *fence,
+   clockid_t clock, enum hrtimer_mode mode,
+   ktime_t delay, u64 slack,
+   gfp_t gfp);
 extern void kfence_pending(struct kfence *fence);
 extern void kfence_signal(struct kfence *fence);
 extern void kfence_wait(struct kfence *fence);
diff --git a/kernel/async.c b/kernel/async.c
index 01552d23a916..5d02445e36b7 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -126,7 +126,10 @@ static atomic_t entry_count;
  * kfence_add() / kfence_add_completion() / kfence_add_dma()
  *
  * sets the kfence to wait upon another fence, completion, or DMA fence
- * respectively.
+ * respectively. To set the fence to wait for at least a certain period of
+ * time, or until after a certain point in time, use
+ *
+ * kfence_add_timer()
  *
  * Unlike completions, kfences are expected to live inside more complex graphs
  * and form the basis for parallel execution of interdependent and so are
@@ -543,6 +546,61 @@ int kfence_add_dma(struct kfence *fence, struct fence 
*dma, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(kfence_add_dma);

+/**
+ * kfence_add_delay - set the fence to wait for a period of time
+ * @fence: this kfence
+ * @clock: which clock to program
+ * @mode: delay given as relative or absolute
+ * @delay: how long or until what time to wait
+ * @slack: how much slack that may be applied to the delay
+ *
+ * kfence_add_delay() causes the @fence to wait for a a period of time, or
+ * until a certain point in time. It is a convenience wrapper around
+ * hrtimer_start_range_ns(). For more details on @clock, @mode, @delay and
+ * @slack please consult the hrtimer documentation.
+ *
+ * Returns 1 if the delay was sucessfuly added to the @fence, or a negative
+ * error code on failure.
+ */
+struct timer_cb {
+   struct hrtimer timer;
+   struct kfence *fence;
+};
+
+static enum hrtimer_restart
+timer_kfence_wake(struct hrtimer *timer)
+{
+   struct timer_cb *cb = container_of(timer, typeof(*cb), timer);
+
+   kfence_signal(cb->fence);
+   kfence_put(cb->fence);
+   kfree(cb);
+
+   return HRTIMER_NORESTART;
+}
+
+int kfence_add_delay(struct kfence *fence,
+clockid_t clock, enum hrtimer_mode mode,
+ktime_t delay, u64 slack,
+gfp_t gfp)
+{
+   struct timer_cb *cb;
+
+   cb = kmalloc(sizeof(*cb), gfp);
+   if (!cb)
+   return -ENOMEM;
+
+   cb->fence = kfence_get(fence);
+   kfence_pending(fence);
+
+   hrtimer_init(>timer, clock, mode);
+   cb->timer.function = timer_kfence_wake;
+
+   hrtimer_start_range_ns(>timer, delay, slack, mode);
+   return 1;
+}
+EXPORT_SYMBOL_GPL(kfence_add_delay);
+
 static async_cookie_t lowest_in_progress(struct async_domain *domain)
 {
struct list_head *pending;
diff --git a/lib/test-kfence.c b/lib/test-kfence.c
index 0604a27f68b2..782a2cca19c5 100644
--- a/lib/test-kfence.c
+++ b/lib/test-kfence.c
@@ -341,6 +341,44 @@ static int __init test_completion(void)
return 0;
 }

+static int __init test_delay(void)
+{
+   struct kfence *fence;
+   ktime_t delay;
+   int ret;
+
+   /* Test use of a hrtimer as an event source for kfences */
+   pr_debug("%s\n", __func__);
+
+   fence = kfence_create(GFP_KERNEL);
+   if (!fence)
+   return -ENOMEM;
+
+   delay = ktime_get();
+
+   ret = kfence_add_delay(fence, CLOCK_MONOTONIC, HRTIMER_MODE_REL,
+  ms_to_ktime(1), 1 << 

[PATCH 4/9] async: Extend kfences for listening on DMA fences

2016-06-24 Thread Chris Wilson
dma-buf provides an interfaces for receiving notifications from DMA
hardware. kfence provides a useful interface for collecting such fences
and combining them with other events.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/kfence.h |  4 
 kernel/async.c | 63 --
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 82096bfafaa1..d71f30c626ae 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -15,6 +15,7 @@
 #include 

 struct completion;
+struct fence;

 struct kfence {
wait_queue_head_t wait;
@@ -29,6 +30,9 @@ extern int kfence_add(struct kfence *fence, struct kfence 
*after, gfp_t gfp);
 extern int kfence_add_completion(struct kfence *fence,
 struct completion *x,
 gfp_t gfp);
+extern int kfence_add_dma(struct kfence *fence,
+ struct fence *dma,
+ gfp_t gfp);
 extern void kfence_pending(struct kfence *fence);
 extern void kfence_signal(struct kfence *fence);
 extern void kfence_wait(struct kfence *fence);
diff --git a/kernel/async.c b/kernel/async.c
index db22b890711e..01552d23a916 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -50,6 +50,7 @@ asynchronous and synchronous parts of the kernel.

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -122,9 +123,10 @@ static atomic_t entry_count;
  * allowing multiple pending / signals to be sent before the kfence is
  * complete.
  *
- * kfence_add() / kfence_add_completion()
+ * kfence_add() / kfence_add_completion() / kfence_add_dma()
  *
- * sets the kfence to wait upon another fence, or completion respectively.
+ * sets the kfence to wait upon another fence, completion, or DMA fence
+ * respectively.
  *
  * Unlike completions, kfences are expected to live inside more complex graphs
  * and form the basis for parallel execution of interdependent and so are
@@ -484,6 +486,63 @@ int kfence_add_completion(struct kfence *fence, struct 
completion *x, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(kfence_add_completion);

+struct dma_fence_cb {
+   struct fence_cb base;
+   struct kfence *fence;
+};
+
+static void dma_kfence_wake(struct fence *dma, struct fence_cb *data)
+{
+   struct dma_fence_cb *cb = container_of(data, typeof(*cb), base);
+   kfence_signal(cb->fence);
+   kfence_put(cb->fence);
+   kfree(cb);
+}
+
+/**
+ * kfence_add_dma - set the fence to wait upon a DMA fence
+ * @fence: this kfence
+ * @dma: target DMA fence to wait upon
+ * @gfp: the allowed allocation type
+ *
+ * kfence_add_dma() causes the @fence to wait upon completion of a DMA fence.
+ *
+ * Returns 1 if the @fence was successfully to the waitqueue of @dma, 0
+ * if @dma was already signaled (and so not added), or a negative error code.
+ */
+int kfence_add_dma(struct kfence *fence, struct fence *dma, gfp_t gfp)
+{
+   struct dma_fence_cb *cb;
+   int ret;
+
+   if (!dma || fence_is_signaled(dma))
+   return 0;
+
+   cb = kmalloc(sizeof(*cb), gfp);
+   if (!cb) {
+   if (!gfpflags_allow_blocking(gfp))
+   return -ENOMEM;
+
+   return fence_wait(dma, false);
+   }
+
+   cb->fence = kfence_get(fence);
+   kfence_pending(fence);
+
+   ret = fence_add_callback(dma, >base, dma_kfence_wake);
+   if (ret == 0) {
+   /* signal fence add and is pending */
+   ret = 1;
+   } else {
+   dma_kfence_wake(dma, >base);
+   if (ret == -ENOENT) /* fence already signaled */
+   ret = 0;
+   }
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(kfence_add_dma);
+
 static async_cookie_t lowest_in_progress(struct async_domain *domain)
 {
struct list_head *pending;
-- 
2.8.1



[PATCH 3/9] async: Extend kfence to allow struct embedding

2016-06-24 Thread Chris Wilson
Provide a kfence_init() function for use for embedding the kfence into a
parent structure. kfence_init() takes an optional function pointer argument
should the caller wish to be notified when the kfence is complete. This is
useful for allowing the kfences to drive other state machinery.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/kfence.h |  5 
 kernel/async.c | 52 
 lib/test-kfence.c  | 64 +++---
 3 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 82eba8aacd02..82096bfafaa1 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -38,4 +38,9 @@ static inline bool kfence_complete(struct kfence *fence)
 }
 extern void kfence_put(struct kfence *fence);

+typedef void (*kfence_notify_t)(struct kfence *);
+#define __kfence_call __attribute__((aligned(4)))
+
+extern void kfence_init(struct kfence *fence, kfence_notify_t fn);
+
 #endif /* _KFENCE_H_ */
diff --git a/kernel/async.c b/kernel/async.c
index d0bcb7cc4884..db22b890711e 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -134,7 +134,17 @@ static atomic_t entry_count;
  *
  * The fence starts off pending a single signal. Once you have finished
  * setting up the fence, use kfence_signal() to allow it to wait upon
- * its event sources.
+ * its event sources. To embed a kfence within another struct, use
+ *
+ * kfence_init()
+ *
+ * This can also be used to receive a callback when the kfence is completed
+ * (pending signal count hits 0).  The callback is also called when the fence
+ * is released (the reference count hits 0, and the fence will be complete).
+ * Note that since the kfence is embedded inside another, its initial reference
+ * must not be dropped unless a callback is provided, or the kfence is the
+ * first member in the parent, and the parent was allocated by kmalloc (i.e.
+ * valid to be freed by kfree()).
  *
  * Use
  *
@@ -151,7 +161,11 @@ static void kfence_free(struct kref *kref)

WARN_ON(atomic_read(>pending) > 0);

-   kfree(fence);
+   if (fence->flags) {
+   kfence_notify_t fn = (kfence_notify_t)fence->flags;
+   fn(fence);
+   } else
+   kfree(fence);
 }

 /**
@@ -203,6 +217,11 @@ static void __kfence_signal(struct kfence *fence,
if (!atomic_dec_and_test(>pending))
return;

+   if (fence->flags) {
+   kfence_notify_t fn = (kfence_notify_t)fence->flags;
+   fn(fence);
+   }
+
atomic_dec(>pending);
__kfence_wake_up_all(fence, continuation);
 }
@@ -240,7 +259,7 @@ void kfence_wait(struct kfence *fence)
 }
 EXPORT_SYMBOL_GPL(kfence_wait);

-static void kfence_init(struct kfence *fence)
+static void __kfence_init(struct kfence *fence)
 {
init_waitqueue_head(>wait);
kref_init(>kref);
@@ -266,11 +285,36 @@ struct kfence *kfence_create(gfp_t gfp)
if (!fence)
return NULL;

-   kfence_init(fence);
+   __kfence_init(fence);
return fence;
 }
 EXPORT_SYMBOL_GPL(kfence_create);

+/**
+ * kfence_init - initialize a fence for use embedded within a struct
+ * @fence: this kfence
+ * @fn: a callback function for when the fence is complete, and when the
+ * fence is released
+ *
+ * This function initialises the @fence for use embedded within a parent
+ * structure. The optional @fn hook is called when the fence is completed
+ * (when all of its events sources have signaled their completion, i.e.
+ * pending signal count hits 0, fence_complete() however reports false as the
+ * fence is not considered complete until after the callback returns) and when
+ * the fence is subsequently released (the reference count hits 0,
+ * fence_complete() is then true). Note carefully that @fn will be called from
+ * atomic context. Also the lower 2 bits of the function pointer are used for
+ * storing flags, so the function must be aligned to at least 4 bytes - use
+ * __kfence_call as a function attribute to ensure correct alignment.
+ */
+void kfence_init(struct kfence *fence, kfence_notify_t fn)
+{
+   __kfence_init(fence);
+   BUG_ON((unsigned long)fn & KFENCE_CHECKED_BIT);
+   fence->flags = (unsigned long)fn;
+}
+EXPORT_SYMBOL_GPL(kfence_init);
+
 static int kfence_wake(wait_queue_t *wq, unsigned mode, int flags, void *key)
 {

[PATCH 2/9] async: Introduce kfence, a N:M completion mechanism

2016-06-24 Thread Chris Wilson
Completions are a simple synchronization mechanism, suitable for 1:M
barriers where many waiters maybe waiting for a single event. In
situations where a single waiter needs to wait for multiple events they
could wait on a list of individual completions. If many waiters need the
same set of completion events, they each need to wait upon their own list.
The kfence abstracts this by itself being able to wait upon many events
before signaling its own completion. A kfence may wait upon completions
or other kfences, so long as there are no cycles in the dependency graph.

The kfence is a one-shot flag, signaling that work has progressed passed
a certain point and the waiters may proceed. Unlike completions, kfences
are expected to live inside more complex graphs and form the basis for
parallel execution of interdependent tasks and so are referenced counted.

kfences provide both signaling and waiting routines:

kfence_pending()

indicates that the kfence should itself wait for another signal. A
kfence created by kfence_create() starts in the pending state.

kfence_signal()

undoes the earlier pending notification and allows the fence to complete
if all pending events have then been signaled.

kfence_wait()

allows the caller to sleep (uninterruptibly) until the fence is complete.

This interface is very similar to completions, with the exception of
allowing multiple pending / signals to be sent before the kfence is
complete.

kfence_add() / kfence_add_completion()

sets the kfence to wait upon another fence, or completion respectively.

Signed-off-by: Chris Wilson 
Cc: Sumit Semwal 
Cc: Shuah Khan 
Cc: Tejun Heo 
Cc: Daniel Vetter 
Cc: Andrew Morton 
Cc: Ingo Molnar 
Cc: Kees Cook 
Cc: Thomas Gleixner 
Cc: "Paul E. McKenney" 
Cc: Dan Williams 
Cc: Andrey Ryabinin 
Cc: Davidlohr Bueso 
Cc: Nikolay Aleksandrov 
Cc: "David S. Miller" 
Cc: "Peter Zijlstra (Intel)" 
Cc: Rasmus Villemoes 
Cc: Andy Shevchenko 
Cc: Dmitry Vyukov 
Cc: Alexander Potapenko 
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linaro-mm-sig at lists.linaro.org
---
 include/linux/kfence.h|  41 +++
 kernel/async.c| 358 +
 lib/Kconfig.debug |  23 ++
 lib/Makefile  |   1 +
 lib/test-kfence.c | 475 ++
 tools/testing/selftests/lib/kfence.sh |  10 +
 6 files changed, 908 insertions(+)
 create mode 100644 include/linux/kfence.h
 create mode 100644 lib/test-kfence.c
 create mode 100755 tools/testing/selftests/lib/kfence.sh

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
new file mode 100644
index ..82eba8aacd02
--- /dev/null
+++ b/include/linux/kfence.h
@@ -0,0 +1,41 @@
+/*
+ * kfence.h - library routines for N:M synchronisation points
+ *
+ * Copyright (C) 2016 Intel Corporation
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#ifndef _KFENCE_H_
+#define _KFENCE_H_
+
+#include 
+#include 
+#include 
+
+struct completion;
+
+struct kfence {
+   wait_queue_head_t wait;
+   unsigned long flags;
+   struct kref kref;
+   atomic_t pending;
+};
+
+extern struct kfence *kfence_create(gfp_t gfp);
+extern struct kfence *kfence_get(struct kfence *fence);
+extern int kfence_add(struct kfence *fence, struct kfence *after, gfp_t gfp);
+extern int kfence_add_completion(struct kfence *fence,
+struct completion *x,
+gfp_t gfp);
+extern void kfence_pending(struct kfence *fence);
+extern void kfence_signal(struct kfence *fence);
+extern void kfence_wait(struct kfence *fence);
+static inline bool kfence_complete(struct kfence *fence)
+{
+   return atomic_read(>pending) < 0;
+}
+extern void kfence_put(struct kfence *fence);
+
+#endif /* _KFENCE_H_ */
diff --git a/kernel/async.c b/kernel/async.c
index d2edd6efec56..d0bcb7cc4884 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -50,6 +50,7 @@ asynchronous and synchronous parts of the kernel.

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -82,6 +83,363 @@ static DECLARE_WAIT_QUEUE_HEAD(async_done);

 static atomic_t entry_count;

+/**
+ * DOC: kfence overview
+ *
+ * kfences provide synchronisation barriers between multiple processes.
+ * They are very similar to completions, or a pthread_barrier. Where
+ * kfence differs from completions is their ability to track multiple
+ * event sources rather than being a singular "completion event". Similar
+ * to completions, multiple processes or other kfences can listen or wait
+ * upon a kfence to signal its completion.
+ *
+ * The kfence is a one-shot flag, signaling that work has progressed passed
+ * a certain point (as measured by completion of all events the kfence is
+ * listening for) and the waiters upon kfence may proceed.
+ *
+ * kfences provide both signaling and waiting 

[PATCH] drm: Only handle _DRM_VBLANK_NEXTONMISS once

2016-06-24 Thread Chris Wilson
On Fri, Jun 24, 2016 at 04:59:47PM +0900, Michel Dänzer wrote:
> From: Michel Dänzer 
> 
> Consolidate the _DRM_VBLANK_NEXTONMISS handling between drm_wait_vblank
> and drm_queue_vblank_event.
> 
> This is a cleanup spotted while working on other changes.
> 
> (The way it was previously handled could also theoretically result in
> drm_queue_vblank_event unnecessarily bumping vblwait->request.sequence,
> if the vblank counter happened to increment between the
> drm_vblank_count(_and_time) calls in each function, but that's unlikely)
> 
> Signed-off-by: Michel Dänzer 
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH] drm: fix some spelling mistakes

2016-06-24 Thread Alex Deucher
On Fri, Jun 24, 2016 at 6:15 AM, Frank Binns  wrote:
> Signed-off-by: Frank Binns 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/drm_irq.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 8ca3d2b..149453c 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -532,7 +532,7 @@ int drm_irq_uninstall(struct drm_device *dev)
>
> /*
>  * Wake up any waiters so they don't hang. This is just to paper over
> -* isssues for UMS drivers which aren't in full control of their
> +* issues for UMS drivers which aren't in full control of their
>  * vblank/irq handling. KMS drivers must ensure that vblanks are all
>  * disabled when uninstalling the irq handler.
>  */
> @@ -594,7 +594,7 @@ int drm_control(struct drm_device *dev, void *data,
> return 0;
> if (drm_core_check_feature(dev, DRIVER_MODESET))
> return 0;
> -   /* UMS was only ever support on pci devices. */
> +   /* UMS was only ever supported on pci devices. */
> if (WARN_ON(!dev->pdev))
> return -EINVAL;
>
> --
> 2.7.4
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/3] RFC: drm: Restrict vblank ioctl to master

2016-06-24 Thread Daniel Stone
Hi Rainer,

On 24 June 2016 at 05:54, Rainer Hochecker  wrote:
> I spent some time reading and investigating on this. Bear with me, I am
> doing Kodi development in my spare time and may not be up-to-date on all
> platforms. Seems Wayland is much better suited to serve as reference
> platform as X11 does. Is that correct? If so I don't request
> OML_sync_control for EGL. Don't waste resources and let the old crap die.

I certainly think so, for a number of reasons. I don't believe X11
will ever be as accurate or as efficient as Wayland can be.

Cheers,
Daniel


[git pull] drm fixes

2016-06-24 Thread Dave Airlie

Hi Linus,

This is the drm fixes tree for 4.7-rc5. It's a bit larger than normal,
due to fixes for production AMD Polaris GPUs. We only merged support for
these in 4.7-rc1 so it would be good if we got all the fixes into final.
The changes don't hit any other hardware.

Other than the amdgpu Polaris changes:

A single fix for atomic modesetting WARN.
Nouveau fix for when fbdev is disabled.
i915 fixes for FBC on Haswell and displayport regression.
Exynos fix for a display panel regression and some other minor changes
Atmel fixes for scaling and OF graph interaction
Allwiinner build, warning and probing fixes
AMD GPU non-polaris fix for num_rbs and some minor fixes.

Also I've just moved house, and my new place is Internet challenged
due to incompetent incumbent ISPs, hopefully sorted out in a couple of
weeks, so I might not be too responsive over the next while. It also
helps Daniel is on holidays for those couple of weeks as well.

Dave.

The following changes since commit 33688abb2802ff3a230bd2441f765477b94cc89e:

  Linux 4.7-rc4 (2016-06-19 21:30:02 -0700)

are available in the git repository at:

  git://people.freedesktop.org/~airlied/linux tags/drm-fixes-for-v4.7-rc5

for you to fetch changes up to 81e257e964268d050f8e9188becd44d50f241d72:

  drm/atomic: Make drm_atomic_legacy_backoff reset crtc->acquire_ctx 
(2016-06-24 11:10:36 +1000)


Alex Deucher (1):
  drm/amdgpu: fix num_rbs exposed to userspace (v2)

Arnd Bergmann (3):
  drm/sun4i: add COMMON_CLK dependency
  drm: sun4i: print DMA address correctly
  drm: sun4i: fix probe error handling

Boris Brezillon (2):
  drm: atmel-hlcdc: actually disable scaling when no scaling is required
  drm: atmel-hlcdc: Fix OF graph parsing

Chen-Yu Tsai (1):
  drm: sun4i: do cleanup if RGB output init fails

Dan Carpenter (2):
  drm/amdgpu: missing bounds check in amdgpu_set_pp_force_state()
  drm/amdgpu: precedence bug in amdgpu_device_init()

Dave Airlie (6):
  Merge branch 'linux-4.7' of git://github.com/skeggsb/linux into drm-fixes
  Merge tag 'drm-intel-fixes-2016-06-22' of 
git://anongit.freedesktop.org/drm-intel into drm-fixes
  Merge tag 'sunxi-drm-fixes-for-4.7' of 
https://git.kernel.org/.../mripard/linux into drm-fixes
  Merge tag 'drm-atmel-hlcdc-fixes/for-4.7-rc5' of 
github.com:bbrezillon/linux-at91 into drm-fixes
  Merge branch 'exynos-drm-fixes' of 
git://git.kernel.org/.../daeinki/drm-exynos into drm-fixes
  Merge branch 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/linux 
into drm-fixes

Dmitrii Tcvetkov (1):
  drm/nouveau: fix for disabled fbdev emulation

Javier Martinez Canillas (2):
  drm/exynos: fimd: don't set .has_hw_trigger in s3c6400 driver data
  drm/exynos: don't use HW trigger for Exynos5420/5422/5800

Lyude (1):
  drm/i915/fbc: Disable on HSW by default for now

Maarten Lankhorst (1):
  drm/atomic: Make drm_atomic_legacy_backoff reset crtc->acquire_ctx

Maxime Ripard (6):
  drm/sun4i: request exact rates to our parents
  drm/sun4i: rgb: Validate the clock rate
  drm/sun4i: defer only if we didn't find our panel
  drm/sun4i: rgb: panel is an error pointer
  drm/sun4i: remove simplefb at probe
  drm/sun4i: Convert to connector register helpers

Mika Kahola (1):
  drm/i915: Revert DisplayPort fast link training feature

Nicolas Iooss (1):
  drm/amdgpu: initialize amdgpu_cgs_acpi_eval_object result value

Rex Zhu (12):
  drm/amd/powerplay: fix logic error.
  drm/amd/powerplay: fix bug that function parameter was incorect.
  drm/amd/powerplay: need to notify system bios pcie device ready
  drm/amd/powerplay: enable PowerContainment feature for polaris10/11.
  drm/amd/powerplay: initialize variables which were missed.
  drm/amd/powerplay: disable UVD SMU handshake for MCLK.
  drm/amd/powrplay: enable stutter_mode for polaris.
  drm/amd/powerplay: add avfs related define for polaris
  drm/amdgpu/atombios: add avfs struct for Polaris10/11
  drm/amd/powerplay: enable avfs feature for polaris
  drm/amdgpu/gfx8: update golden setting for polaris10
  drm/amd/powerplay: enable clock stretch feature for polaris

Tobias Jakobi (3):
  drm/exynos: g2d: drop the _REG postfix from the stride defines
  drm/exynos: remove superfluous inclusions of fbdev header
  drm/exynos: use logical AND in exynos_drm_plane_check_size()

Yakir Yang (1):
  drm/exynos: dp: Fix NULL pointer dereference due uninitialized connector

 drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c|   3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c |  28 ++-
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c  |   3 +-
 drivers/gpu/drm/amd/include/atombios.h |  72 +++
 

[PATCH 3/3] ASoC: hdmi-codec: enable multi probe for same device

2016-06-24 Thread Kuninori Morimoto

From: Kuninori Morimoto 

hdmi-codec driver is common HDMI sound driver,
but it doesn't care about multi sound ports.
For example, hdmi-codec driver is supporting 1 I2S and 1 SPDIF ports,
so, we can't use this driver if HDMI has 2 or more I2S ports.

And we would like to use multi detection.
For example, DesignWare HDMI driver is providing dw_hdmi_bind() to
DRM/KMS driver, and it will setups HDMI video/sound.
Note is that it will be called under for_each loop of ports.

int dw_hdmi_bind(xxx)
{
/* register hdmi-codec driver here */
}

static int xxx_probe(struct platform_device *pdev)
{
for_each_xxx(xx) {
...
dw_hdmi_bind(xxx);
...
}
}

This case, dw_hdmi_bind() would like to use hdmi-codec,
and it will be called multiple times for each ports.

Here, ASoC's CPU/Codec/Card bind will checks each "of_node" on DT,
and hdmi-codec driver is assuming its parent device for it.
But it doesn't care about case.
Thus, ASoC never detect correct sound card in this case.

To solve this issue, this patch checks each parent device,
and names "hdmi-hifi.x" in order to each ports.
And uses struct snd_soc_component_driver :: of_xlate_dai_name
for snd_soc_get_dai_name().

Signed-off-by: Kuninori Morimoto 
---
 sound/soc/codecs/hdmi-codec.c | 66 +--
 1 file changed, 63 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f27d115..fe155bc 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -24,6 +24,15 @@

 #include  /* This is only to get MAX_ELD_BYTES */

+struct hdmi_device {
+   struct device *dev;
+   struct list_head list;
+   int cnt;
+};
+#define pos_to_hdmi_device(pos)container_of((pos), struct hdmi_device, 
list)
+LIST_HEAD(hdmi_device_list);
+
+#define DAI_NAME_SIZE 16
 struct hdmi_codec_priv {
struct hdmi_codec_pdata hcd;
struct snd_soc_dai_driver *daidrv;
@@ -320,7 +329,6 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)

 static struct snd_soc_dai_driver hdmi_i2s_dai = {
-   .name = "i2s-hifi",
.id = DAI_ID_I2S,
.playback = {
.stream_name = "Playback",
@@ -334,7 +342,6 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = {
 };

 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
-   .name = "spdif-hifi",
.id = DAI_ID_SPDIF,
.playback = {
.stream_name = "Playback",
@@ -346,6 +353,27 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.ops = _dai_ops,
 };

+static char hdmi_dai_name[][DAI_NAME_SIZE] = {
+   "hdmi-hifi.0",
+   "hdmi-hifi.1",
+   "hdmi-hifi.2",
+   "hdmi-hifi.3",
+};
+
+static int hdmi_of_xlate_dai_name(struct snd_soc_component *component,
+ struct of_phandle_args *args,
+ const char **dai_name)
+{
+   int id = args->args[0];
+
+   if (id < ARRAY_SIZE(hdmi_dai_name)) {
+   *dai_name = hdmi_dai_name[id];
+   return 0;
+   }
+
+   return -EAGAIN;
+}
+
 static struct snd_soc_codec_driver hdmi_codec = {
.controls = hdmi_controls,
.num_controls = ARRAY_SIZE(hdmi_controls),
@@ -353,6 +381,9 @@ static struct snd_soc_codec_driver hdmi_codec = {
.num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
.dapm_routes = hdmi_routes,
.num_dapm_routes = ARRAY_SIZE(hdmi_routes),
+   .component_driver = {
+   .of_xlate_dai_name  = hdmi_of_xlate_dai_name,
+   },
 };

 static int hdmi_codec_probe(struct platform_device *pdev)
@@ -360,6 +391,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
struct device *dev = >dev;
struct hdmi_codec_priv *hcp;
+   struct hdmi_device *hd;
+   struct list_head *pos;
int dai_count, i = 0;
int ret;

@@ -381,6 +414,30 @@ static int hdmi_codec_probe(struct platform_device *pdev)
if (!hcp)
return -ENOMEM;

+   hd = NULL;
+   list_for_each(pos, _device_list) {
+   struct hdmi_device *tmp = pos_to_hdmi_device(pos);
+   if (tmp->dev == dev->parent) {
+   hd = tmp;
+   break;
+   }
+   }
+
+   if (!hd) {
+   hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL);
+   if (!hd)
+   return -ENOMEM;
+
+   hd->dev = dev->parent;
+
+   list_add_tail(>list, _device_list);
+   }
+
+   if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) {
+   dev_err(dev, "too many hdmi codec are deteced\n");
+   return -EINVAL;
+   }
+
hcp->hcd = *hcd;

[PATCH 2/3] ASoC: hdmi-codec: callback function will be called with private data

2016-06-24 Thread Kuninori Morimoto
From: Kuninori Morimoto 

Current hdmi-codec driver is assuming that it will be registered
from HDMI driver. Because of this assumption, each callback function
has struct device pointer which is parent device (= HDMI).
Then, it can use dev_get_drvdata() to get private data.

OTOH, on some SoC/HDMI case, SoC has VIDEO/SOUND and HDMI IPs.
This case, it needs SoC VIDEO, SoC SOUND and HDMI video, HDMI codec
driver. In DesignWare HDMI IP case, SoC VIDEO (= DRM/KMS) driver tries
to bind DesignWare HDMI video driver, and HDMI codec driver
(= hdmi-codec). This case, above "parent device" of HDMI codec driver
is DRM/KMS driver and its "device" already has private data.

And, from DT and ASoC CPU/Codec/Card binding point of view, HDMI codec
(= hdmi-codec) needs to have "parent device" (= DRM/KMS), otherwise,
it never detect sound card.

Because of these reasons, some driver can't use dev_get_drvdata() to
get private data on hdmi-codec driver. This patch add new void pointer
on hdmi_codec_pdata for private data, and callback function will be
called with it.

Signed-off-by: Kuninori Morimoto 
---
 include/sound/hdmi-codec.h| 13 -
 sound/soc/codecs/hdmi-codec.c | 15 ---
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index fc3a481..530c57b 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -53,18 +53,19 @@ struct hdmi_codec_params {
int channels;
 };

+struct hdmi_codec_pdata;
 struct hdmi_codec_ops {
/*
 * Called when ASoC starts an audio stream setup.
 * Optional
 */
-   int (*audio_startup)(struct device *dev);
+   int (*audio_startup)(struct device *dev, void *data);

/*
 * Configures HDMI-encoder for audio stream.
 * Mandatory
 */
-   int (*hw_params)(struct device *dev,
+   int (*hw_params)(struct device *dev, void *data,
 struct hdmi_codec_daifmt *fmt,
 struct hdmi_codec_params *hparms);

@@ -72,19 +73,20 @@ struct hdmi_codec_ops {
 * Shuts down the audio stream.
 * Mandatory
 */
-   void (*audio_shutdown)(struct device *dev);
+   void (*audio_shutdown)(struct device *dev, void *data);

/*
 * Mute/unmute HDMI audio stream.
 * Optional
 */
-   int (*digital_mute)(struct device *dev, bool enable);
+   int (*digital_mute)(struct device *dev, void *data, bool enable);

/*
 * Provides EDID-Like-Data from connected HDMI device.
 * Optional
 */
-   int (*get_eld)(struct device *dev, uint8_t *buf, size_t len);
+   int (*get_eld)(struct device *dev, void *data,
+  uint8_t *buf, size_t len);
 };

 /* HDMI codec initalization data */
@@ -93,6 +95,7 @@ struct hdmi_codec_pdata {
uint i2s:1;
uint spdif:1;
int max_i2s_channels;
+   void *data;
 };

 #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 8e36e88..f27d115 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -112,7 +112,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream 
*substream,
return ret;

if (hcp->hcd.ops->audio_startup) {
-   ret = hcp->hcd.ops->audio_startup(dai->dev->parent);
+   ret = hcp->hcd.ops->audio_startup(dai->dev->parent, 
hcp->hcd.data);
if (ret) {
mutex_lock(>current_stream_lock);
hcp->current_stream = NULL;
@@ -122,8 +122,8 @@ static int hdmi_codec_startup(struct snd_pcm_substream 
*substream,
}

if (hcp->hcd.ops->get_eld) {
-   ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->eld,
-   sizeof(hcp->eld));
+   ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
+   hcp->eld, sizeof(hcp->eld));

if (!ret) {
ret = snd_pcm_hw_constraint_eld(substream->runtime,
@@ -144,7 +144,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream 
*substream,

WARN_ON(hcp->current_stream != substream);

-   hcp->hcd.ops->audio_shutdown(dai->dev->parent);
+   hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);

mutex_lock(>current_stream_lock);
hcp->current_stream = NULL;
@@ -195,8 +195,8 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream 
*substream,
hp.sample_rate = params_rate(params);
hp.channels = params_channels(params);

-   return hcp->hcd.ops->hw_params(dai->dev->parent, >daifmt[dai->id],
-  );
+   return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
+  

[PATCH 0/3] DesignWare HDMI I2S suport

2016-06-24 Thread Kuninori Morimoto

Hi Mark, Thierry, Russell

These are DesignWare HDMI I2S support patches.
It will use ALSA SoC hdmi-codec driver, but we can't use it as-is.
So, 2), 3) patches modify hdmi-codec style.

Kuninori Morimoto (3):
  1) drm: bridge: add DesignWare HDMI I2S audio support
  2) ASoC: hdmi-codec: callback function will be called with private data
  3) ASoC: hdmi-codec: enable multi probe for same device

 drivers/gpu/drm/bridge/Kconfig |   8 ++
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/dw-hdmi-audio.h |   7 ++
 drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 123 +
 drivers/gpu/drm/bridge/dw-hdmi.c   |  22 +-
 drivers/gpu/drm/bridge/dw-hdmi.h   |  21 +
 include/sound/hdmi-codec.h |  13 +--
 sound/soc/codecs/hdmi-codec.c  |  81 ---
 8 files changed, 259 insertions(+), 17 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c

-- 
1.9.1



[PATCH 02/23] ARM: dts: n950: add display support

2016-06-24 Thread Sebastian Reichel
Hi Tony,

On Tue, Jun 21, 2016 at 04:01:03AM -0700, Tony Lindgren wrote:
> * Tony Lindgren  [160412 13:53]:
> > * Sebastian Reichel  [160324 17:16]:
> > > On Thu, Mar 24, 2016 at 05:11:15PM +0200, Jani Nikula wrote:
> > > > > I _think_, that your HW team decided to cover the first and the
> > > > > last few pixels of the 864 display with plastic. So technically
> > > > > it's a 864 display, but effectively it's 854.
> > 
> > Sebastian, should I apply this dts patch as is or are changes
> > still needed?
> 
> Well please repost when ready, I'll untag this old thread here..

Sounds fine to me. DTS changes should be merged once the driver
changes are accepted and they need at least one more cycle.

-- Sebastian
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160624/eef21cde/attachment-0001.sig>