Re: [PATCH] drm/amdgpu/dc: Stop dma_resv_lock inversion in commit_tail

2020-07-27 Thread Christian König

Am 27.07.20 um 23:30 schrieb Daniel Vetter:

Trying to grab dma_resv_lock while in commit_tail before we've done
all the code that leads to the eventual signalling of the vblank event
(which can be a dma_fence) is deadlock-y. Don't do that.

Here the solution is easy because just grabbing locks to read
something races anyway. We don't need to bother, READ_ONCE is
equivalent. And avoids the locking issue.

v2: Also take into account tmz_surface boolean, plus just delete the
old code.

Cc: linux-me...@vger.kernel.org
Cc: linaro-mm-...@lists.linaro.org
Cc: linux-r...@vger.kernel.org
Cc: amd-...@lists.freedesktop.org
Cc: intel-...@lists.freedesktop.org
Cc: Chris Wilson 
Cc: Maarten Lankhorst 
Cc: Christian König 
Signed-off-by: Daniel Vetter 
---
DC-folks, I think this split out patch from my series here

https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fdri-devel%2F20200707201229.472834-1-daniel.vetter%40ffwll.ch%2F&data=02%7C01%7Cchristian.koenig%40amd.com%7C8a4f5736682a4b5c943e08d832747ab1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637314823145521840&sdata=qd7Nrox62Lr%2FXWbJJFVskg9RYL4%2FoRVCFjR6rUDMA5E%3D&reserved=0

should be ready for review/merging. I fixed it up a bit so that it's not
just a gross hack :-)

Cheers, Daniel


---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 ++-
  1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 21ec64fe5527..a20b62b1f2ef 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6959,20 +6959,13 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
DRM_ERROR("Waiting for fences timed out!");
  
  		/*

-* TODO This might fail and hence better not used, wait
-* explicitly on fences instead
-* and in general should be called for
-* blocking commit to as per framework helpers
+* We cannot reserve buffers here, which means the normal flag
+* access functions don't work. Paper over this with READ_ONCE,
+* but maybe the flags are invariant enough that not even that
+* would be needed.
 */
-   r = amdgpu_bo_reserve(abo, true);
-   if (unlikely(r != 0))
-   DRM_ERROR("failed to reserve buffer before flip\n");
-
-   amdgpu_bo_get_tiling_flags(abo, &tiling_flags);
-
-   tmz_surface = amdgpu_bo_encrypted(abo);
-
-   amdgpu_bo_unreserve(abo);
+   tiling_flags = READ_ONCE(abo->tiling_flags);
+   tmz_surface = READ_ONCE(abo->flags) & 
AMDGPU_GEM_CREATE_ENCRYPTED;


Yeah, the abo->flags are mostly fixed after creation, especially the 
encrypted flag can't change or we corrupt page table tables. So that 
should work fine.


Anybody who picks this up feel free to add an Reviewed-by: Christian 
König .


Regards,
Christian.

  
  		fill_dc_plane_info_and_addr(

dm->adev, new_plane_state, tiling_flags,


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


[PATCH] drm/ttm/nouveau: consolidate slowpath reserve

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

The WARN_ON in the non-underscore path is off questionable value
(can we drop it from the non-slowpath?). At least for nouveau
where it's just looked up the gem object we know the ttm object
has a reference always so we can skip the check.

It's probably nouveau could use execbut utils here at some point
but for now align the code between them to always call the __
versions, and remove the non underscored version.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_gem.c  |  6 ++---
 drivers/gpu/drm/ttm/ttm_execbuf_util.c | 10 +
 include/drm/ttm/ttm_bo_driver.h| 31 +++---
 3 files changed, 17 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c 
b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 81f111ad3f4f..d2d535d2ece1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -422,15 +422,15 @@ validate_init(struct nouveau_channel *chan, struct 
drm_file *file_priv,
break;
}
 
-   ret = ttm_bo_reserve(&nvbo->bo, true, false, &op->ticket);
+   ret = __ttm_bo_reserve(&nvbo->bo, true, false, &op->ticket);
if (ret) {
list_splice_tail_init(&vram_list, &op->list);
list_splice_tail_init(&gart_list, &op->list);
list_splice_tail_init(&both_list, &op->list);
validate_fini_no_ticket(op, chan, NULL, NULL);
if (unlikely(ret == -EDEADLK)) {
-   ret = ttm_bo_reserve_slowpath(&nvbo->bo, true,
- &op->ticket);
+   ret = __ttm_bo_reserve_slowpath(&nvbo->bo, true,
+   &op->ticket);
if (!ret)
res_bo = nvbo;
}
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c 
b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index 1797f04c0534..a24f13bc90fb 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -119,13 +119,7 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
ttm_eu_backoff_reservation_reverse(list, entry);
 
if (ret == -EDEADLK) {
-   if (intr) {
-   ret = 
dma_resv_lock_slow_interruptible(bo->base.resv,
-   
 ticket);
-   } else {
-   dma_resv_lock_slow(bo->base.resv, ticket);
-   ret = 0;
-   }
+   ret = __ttm_bo_reserve_slowpath(bo, intr, ticket);
}
 
if (!ret && entry->num_shared)
@@ -133,8 +127,6 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,

entry->num_shared);
 
if (unlikely(ret != 0)) {
-   if (ret == -EINTR)
-   ret = -ERESTARTSYS;
if (ticket) {
ww_acquire_done(ticket);
ww_acquire_fini(ticket);
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 5a37f1cc057e..563b970949a1 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -695,7 +695,7 @@ static inline int ttm_bo_reserve(struct ttm_buffer_object 
*bo,
 }
 
 /**
- * ttm_bo_reserve_slowpath:
+ * __ttm_bo_reserve_slowpath:
  * @bo: A pointer to a struct ttm_buffer_object.
  * @interruptible: Sleep interruptible if waiting.
  * @sequence: Set (@bo)->sequence to this value after lock
@@ -704,24 +704,19 @@ static inline int ttm_bo_reserve(struct ttm_buffer_object 
*bo,
  * from all our other reservations. Because there are no other reservations
  * held by us, this function cannot deadlock any more.
  */
-static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
- bool interruptible,
- struct ww_acquire_ctx *ticket)
+static inline int __ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
+   bool interruptible,
+   struct ww_acquire_ctx *ticket)
 {
-   int ret = 0;
-
-   WARN_ON(!kref_read(&bo->kref));
-
-   if (interruptible)
-   ret = dma_resv_lock_slow_interruptible(bo->base.resv,
-ticket);
-   else
-   dma_resv_lock_slow(bo->base.resv, ticket);
-
-   if (ret == -EINTR)
-   ret = -ERESTARTSYS;
-
-   return ret;
+   if (interruptible) {

[PATCH] drm/ttm: drop unusued function declaration

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

This was removed in
f5a9a9383f279de9da63296cb623a6418a66196b drm/ttm: remove TTM_MEMTYPE_FLAG_CMA

but the the declaration was left dangling.

Signed-off-by: Dave Airlie 
---
 include/drm/ttm/ttm_bo_driver.h | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 71b195e78c7c..5a37f1cc057e 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -525,17 +525,6 @@ ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask)
  * ttm_bo.c
  */
 
-/**
- * ttm_mem_reg_is_pci
- *
- * @bdev: Pointer to a struct ttm_bo_device.
- * @mem: A valid struct ttm_mem_reg.
- *
- * Returns true if the memory described by @mem is PCI memory,
- * false otherwise.
- */
-bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem);
-
 /**
  * ttm_bo_mem_space
  *
-- 
2.26.2

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


[PATCH] drm/ttm/nouveau: don't call tt destroy callback on alloc failure.

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

This is confusing, and from my reading of all the drivers only
nouveau got this right.

Just make the API act under driver control of it's own allocation
failing, and don't call destroy, if the page table fails to
create there is nothing to cleanup here.

(I'm willing to believe I've missed something here, so please
review deeply).

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_sgdma.c | 9 +++--
 drivers/gpu/drm/ttm/ttm_tt.c| 3 ---
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 20b6d0b3de5c..c3ccf661b7a6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -95,12 +95,9 @@ nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo, 
uint32_t page_flags)
else
nvbe->ttm.ttm.func = &nv50_sgdma_backend;
 
-   if (ttm_dma_tt_init(&nvbe->ttm, bo, page_flags))
-   /*
-* A failing ttm_dma_tt_init() will call ttm_tt_destroy()
-* and thus our nouveau_sgdma_destroy() hook, so we don't need
-* to free nvbe here.
-*/
+   if (ttm_dma_tt_init(&nvbe->ttm, bo, page_flags)) {
+   kfree(nvbe);
return NULL;
+   }
return &nvbe->ttm.ttm;
 }
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index bab67873cfd4..9d1c7177384c 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -244,7 +244,6 @@ int ttm_tt_init(struct ttm_tt *ttm, struct 
ttm_buffer_object *bo,
ttm_tt_init_fields(ttm, bo, page_flags);
 
if (ttm_tt_alloc_page_directory(ttm)) {
-   ttm_tt_destroy(ttm);
pr_err("Failed allocating page table\n");
return -ENOMEM;
}
@@ -268,7 +267,6 @@ int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct 
ttm_buffer_object *bo,
 
INIT_LIST_HEAD(&ttm_dma->pages_list);
if (ttm_dma_tt_alloc_page_directory(ttm_dma)) {
-   ttm_tt_destroy(ttm);
pr_err("Failed allocating page table\n");
return -ENOMEM;
}
@@ -290,7 +288,6 @@ int ttm_sg_tt_init(struct ttm_dma_tt *ttm_dma, struct 
ttm_buffer_object *bo,
else
ret = ttm_dma_tt_alloc_page_directory(ttm_dma);
if (ret) {
-   ttm_tt_destroy(ttm);
pr_err("Failed allocating page table\n");
return -ENOMEM;
}
-- 
2.26.2

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


[PATCH] drm/ttm: make ttm_tt unbind function return void.

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

The return value just led to BUG_ON, I think if a driver wants
to BUG_ON here it can do it itself. (don't BUG_ON).

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c| 5 ++---
 drivers/gpu/drm/nouveau/nouveau_sgdma.c| 3 +--
 drivers/gpu/drm/qxl/qxl_ttm.c  | 3 +--
 drivers/gpu/drm/radeon/radeon_ttm.c| 4 +---
 drivers/gpu/drm/ttm/ttm_agp_backend.c  | 9 +
 drivers/gpu/drm/ttm/ttm_tt.c   | 5 +
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 4 +---
 include/drm/ttm/ttm_tt.h   | 2 +-
 8 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index fcff5671f6f8..e11c5d69843d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1292,7 +1292,7 @@ int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
  * Called by ttm_tt_unbind() on behalf of ttm_bo_move_ttm() and
  * ttm_tt_destroy().
  */
-static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm)
+static void amdgpu_ttm_backend_unbind(struct ttm_tt *ttm)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -1303,14 +1303,13 @@ static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm)
amdgpu_ttm_tt_unpin_userptr(ttm);
 
if (gtt->offset == AMDGPU_BO_INVALID_OFFSET)
-   return 0;
+   return;
 
/* unbind shouldn't be done for GDS/GWS/OA in ttm_bo_clean_mm */
r = amdgpu_gart_unbind(adev, gtt->offset, ttm->num_pages);
if (r)
DRM_ERROR("failed to unbind %lu pages at 0x%08llX\n",
  gtt->ttm.ttm.num_pages, gtt->offset);
-   return r;
 }
 
 static void amdgpu_ttm_backend_destroy(struct ttm_tt *ttm)
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index feaac908efed..20b6d0b3de5c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -46,12 +46,11 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *reg)
return 0;
 }
 
-static int
+static void
 nv04_sgdma_unbind(struct ttm_tt *ttm)
 {
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
nouveau_mem_fini(nvbe->mem);
-   return 0;
 }
 
 static struct ttm_backend_func nv04_sgdma_backend = {
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index 1d8e07b8b19e..bf9dc451583a 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -149,10 +149,9 @@ static int qxl_ttm_backend_bind(struct ttm_tt *ttm,
return -1;
 }
 
-static int qxl_ttm_backend_unbind(struct ttm_tt *ttm)
+static void qxl_ttm_backend_unbind(struct ttm_tt *ttm)
 {
/* Not implemented */
-   return -1;
 }
 
 static void qxl_ttm_backend_destroy(struct ttm_tt *ttm)
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index 54af06df865b..004344dce140 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -591,7 +591,7 @@ static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
return 0;
 }
 
-static int radeon_ttm_backend_unbind(struct ttm_tt *ttm)
+static void radeon_ttm_backend_unbind(struct ttm_tt *ttm)
 {
struct radeon_ttm_tt *gtt = (void *)ttm;
 
@@ -599,8 +599,6 @@ static int radeon_ttm_backend_unbind(struct ttm_tt *ttm)
 
if (gtt->userptr)
radeon_ttm_tt_unpin_userptr(ttm);
-
-   return 0;
 }
 
 static void radeon_ttm_backend_destroy(struct ttm_tt *ttm)
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c 
b/drivers/gpu/drm/ttm/ttm_agp_backend.c
index 6050dc846894..38f1351140e2 100644
--- a/drivers/gpu/drm/ttm/ttm_agp_backend.c
+++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c
@@ -82,17 +82,18 @@ static int ttm_agp_bind(struct ttm_tt *ttm, struct 
ttm_mem_reg *bo_mem)
return ret;
 }
 
-static int ttm_agp_unbind(struct ttm_tt *ttm)
+static void ttm_agp_unbind(struct ttm_tt *ttm)
 {
struct ttm_agp_backend *agp_be = container_of(ttm, struct 
ttm_agp_backend, ttm);
 
if (agp_be->mem) {
-   if (agp_be->mem->is_bound)
-   return agp_unbind_memory(agp_be->mem);
+   if (agp_be->mem->is_bound) {
+   agp_unbind_memory(agp_be->mem);
+   return;
+   }
agp_free_memory(agp_be->mem);
agp_be->mem = NULL;
}
-   return 0;
 }
 
 static void ttm_agp_destroy(struct ttm_tt *ttm)
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index e25d4097aa16..bab67873cfd4 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -313,11 +313,8 @@ EXPORT_SYMBOL(ttm_dma_tt_fini);
 
 void ttm_tt_unbind(struct ttm_tt *ttm)
 {
-   int ret;
-
if (tt

[PATCH] ttm: ttm_bo_swapout_all doesn't use it's argument.

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

Just drop the argument from this.

This does ask the question if this is the function vmwgfx
should be using or should it be doing an evict all like
the other drivers.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/ttm/ttm_bo.c| 2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +-
 include/drm/ttm/ttm_bo_api.h| 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index b03747717ec7..f297fd5e02d4 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1838,7 +1838,7 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct 
ttm_operation_ctx *ctx)
 }
 EXPORT_SYMBOL(ttm_bo_swapout);
 
-void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
+void ttm_bo_swapout_all(void)
 {
struct ttm_operation_ctx ctx = {
.interruptible = false,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 470428387878..fb39826f72c1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1352,7 +1352,7 @@ static int vmw_pm_freeze(struct device *kdev)
vmw_execbuf_release_pinned_bo(dev_priv);
vmw_resource_evict_all(dev_priv);
vmw_release_device_early(dev_priv);
-   ttm_bo_swapout_all(&dev_priv->bdev);
+   ttm_bo_swapout_all();
if (dev_priv->enable_fb)
vmw_fifo_resource_dec(dev_priv);
if (atomic_read(&dev_priv->num_fifo_resources) != 0) {
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index b1c705a93517..a9e13b252820 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -692,7 +692,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file 
*filp,
 
 int ttm_bo_swapout(struct ttm_bo_global *glob,
struct ttm_operation_ctx *ctx);
-void ttm_bo_swapout_all(struct ttm_bo_device *bdev);
+void ttm_bo_swapout_all(void);
 
 /**
  * ttm_bo_uses_embedded_gem_object - check if the given bo uses the
-- 
2.26.2

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


linux-next: manual merge of the drm tree with the drm-misc-fixes tree

2020-07-27 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the drm tree got a conflict in:

  drivers/gpu/drm/drm_gem.c

between commit:

  8490d6a7e0a0 ("drm: hold gem reference until object is no longer accessed")

from the drm-misc-fixes tree and commit:

  be6ee102341b ("drm: remove _unlocked suffix in drm_gem_object_put_unlocked")

from the drm tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc drivers/gpu/drm/drm_gem.c
index ee2058ad482c,a57f5379fc08..
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@@ -901,9 -913,7 +909,9 @@@ drm_gem_open_ioctl(struct drm_device *d
args->handle = handle;
args->size = obj->size;
  
 -  return 0;
 +err:
-   drm_gem_object_put_unlocked(obj);
++  drm_gem_object_put(obj);
 +  return ret;
  }
  
  /**


pgpng9x56_UUo.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 207383] [Regression] 5.7 amdgpu/polaris11 gpf: amdgpu_atomic_commit_tail

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207383

--- Comment #104 from mn...@protonmail.com ---
(In reply to mnrzk from comment #103)
> (In reply to Nicholas Kazlauskas from comment #95)
> > Created attachment 290583 [details]
> > 0001-drm-amd-display-Force-add-all-CRTCs-to-state-when-us.patch
> > 
> > So the sequence looks like the following:
> > 
> > 1. Non-blocking commit #1 requested, checked, swaps state and deferred to
> > work queue.
> > 
> > 2. Non-blocking commit #2 requested, checked, swaps state and deferred to
> > work queue.
> > 
> > Commits #1 and #2 don't touch any of the same core DRM objects (CRTCs,
> > Planes, Connectors) so Commit #2 does not stall for Commit #1. DRM Private
> > Objects have always been avoided in stall checks, so we have no safety from
> > DRM core in this regard.
> > 
> > 3. Due to system load commit #2 executes first and finishes its commit tail
> > work. At the end of commit tail, as part of DRM core, it calls
> > drm_atomic_state_put().
> > 
> > Since this was the pageflip IOCTL we likely already dropped the reference
> on
> > the state held by the IOCTL itself. So it's going to actually free at this
> > point.
> > 
> > This eventually calls drm_atomic_state_clear() which does the following:
> > 
> > obj->funcs->atomic_destroy_state(obj, state->private_objs[i].state);
> > 
> > Note that it clears "state" here. Commit sets "state" to the following:
> > 
> > state->private_objs[i].state = old_obj_state;
> > obj->state = new_obj_state;
> > 
> > Since Commit #1 swapped first this means Commit #2 actually does free
> Commit
> > #1's private object.
> > 
> > 4. Commit #1 then executes and we get a use after free.
> > 
> > Same bug, it's just this was never corrupted before by the slab changes.
> > It's been sitting dormant for 5.0~5.8.
> > 
> > Attached is a patch that might help resolve this.
> 
> So I just got around to testing this patch and so far, not very promising.
> 
> Right now I can't comment on if the bug in question was resolved but this
> just introduced some new critical bugs for me.
> 
> I first tried this on my bare metal system w/ my RX 480 and it boots into
> lightdm just fine. As soon as I log in and start up XFCE however, one of my
> two monitors goes black (monitor reports being asleep) but my cursor seems
> to drift into the other monitor just fine. So after that, I check the
> display settings and both monitors are detected. So I tried re-enabling the
> off monitor and then both monitors work fine.
> 
> After that, another bug: I now have two cursors, one only works on my right
> monitor and the other only stays in one position.
> 
> At this point, I recompiled and remade the initramfs, and sure enough, same
> issues. This time, however, changing the display settings didn't "fix" the
> issue with one monitor being blank; the off monitor activated, but the
> previously working one just froze.
> 
> I also tried this on my VM passing through my GPU w/ vfio-pci; similar
> issues. Lightdm worked fine but when I started KDE Plasma, it started
> flashing white and one of my monitors just became blank. This time, I
> couldn't enable the blank display from the settings, it just didn't show
> up. Xrandr only showed one output as well; switching HDMI outputs still
> only lets me use the monitor on the "working" HDMI port.
> 
> I don't exactly know how I would go about debugging this since there's just
> too many bugs to count. I also don't know if it would be worth it at all.
> 
> Do you have any idea why this would occur? This patch only seems to force
> synchronisation, I don't quite know why it would break my system so much.

This just gets even weirder the more I test it out. Swapping the two
monitors (i.e. swapping the HDMI ports used for each monitor) seems to fix
the issue completely on my VM (at least from 1 minute of testing), but on
the host it fixes some of the issues (my cursor still disappears on one of
my monitors).

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


Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Mazin Rezk
On Monday, July 27, 2020 9:26 AM, Kazlauskas, Nicholas 
 wrote:

> On 2020-07-27 1:40 a.m., Mazin Rezk wrote:
> > This patch fixes a race condition that causes a use-after-free during
> > amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking commits
> > are requested and the second one finishes before the first. Essentially,
> > this bug occurs when the following sequence of events happens:
> >
> > 1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
> > deferred to the workqueue.
> >
> > 2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
> > deferred to the workqueue.
> >
> > 3. Commit #2 starts before commit #1, dm_state #1 is used in the
> > commit_tail and commit #2 completes, freeing dm_state #1.
> >
> > 4. Commit #1 starts after commit #2 completes, uses the freed dm_state
> > 1 and dereferences a freelist pointer while setting the context.
> >
> > Since this bug has only been spotted with fast commits, this patch fixes
> > the bug by clearing the dm_state instead of using the old dc_state for
> > fast updates. In addition, since dm_state is only used for its dc_state
> > and amdgpu_dm_atomic_commit_tail will retain the dc_state if none is found,
> > removing the dm_state should not have any consequences in fast updates.
> >
> > This use-after-free bug has existed for a while now, but only caused a
> > noticeable issue starting from 5.7-rc1 due to 3202fa62f ("slub: relocate
> > freelist pointer to middle of object") moving the freelist pointer from
> > dm_state->base (which was unused) to dm_state->context (which is
> > dereferenced).
> >
> > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=207383
> > Fixes: bd200d190f45 ("drm/amd/display: Don't replace the dc_state for fast 
> > updates")
> > Reported-by: Duncan <1i5t5.dun...@cox.net>
> > Signed-off-by: Mazin Rezk 
> > ---
> >   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 ++-
> >   1 file changed, 27 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index 86ffa0c2880f..710edc70e37e 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -8717,20 +8717,38 @@ static int amdgpu_dm_atomic_check(struct drm_device 
> > *dev,
> >  * the same resource. If we have a new DC context as part of
> >  * the DM atomic state from validation we need to free it and
> >  * retain the existing one instead.
> > +*
> > +* Furthermore, since the DM atomic state only contains the DC
> > +* context and can safely be annulled, we can free the state
> > +* and clear the associated private object now to free
> > +* some memory and avoid a possible use-after-free later.
> >  */
> > -   struct dm_atomic_state *new_dm_state, *old_dm_state;
> >
> > -   new_dm_state = dm_atomic_get_new_state(state);
> > -   old_dm_state = dm_atomic_get_old_state(state);
> > +   for (i = 0; i < state->num_private_objs; i++) {
> > +   struct drm_private_obj *obj = 
> > state->private_objs[i].ptr;
> >
> > -   if (new_dm_state && old_dm_state) {
> > -   if (new_dm_state->context)
> > -   dc_release_state(new_dm_state->context);
> > +   if (obj->funcs == adev->dm.atomic_obj.funcs) {
> > +   int j = state->num_private_objs-1;
> >
> > -   new_dm_state->context = old_dm_state->context;
> > +   dm_atomic_destroy_state(obj,
> > +   state->private_objs[i].state);
> > +
> > +   /* If i is not at the end of the array then the
> > +* last element needs to be moved to where i was
> > +* before the array can safely be truncated.
> > +*/
> > +   if (i != j)
> > +   state->private_objs[i] =
> > +   state->private_objs[j];
> >
> > -   if (old_dm_state->context)
> > -   dc_retain_state(old_dm_state->context);
> > +   state->private_objs[j].ptr = NULL;
> > +   state->private_objs[j].state = NULL;
> > +   state->private_objs[j].old_state = NULL;
> > +   state->private_objs[j].new_state = NULL;
> > +
> > +   state->num_private_objs = j;
> > +   break;
> > +   }
>
> In the bug report itself I mentioned that I don't really like hacking
> around the DRM core for resolving this patch but to go into more
> specifics, it's really two issues of code maintenanc

Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Mazin Rezk
On Monday, July 27, 2020 4:29 PM, Daniel Vetter  wrote:

> On Mon, Jul 27, 2020 at 9:28 PM Christian König
>  wrote:
> >
> > Am 27.07.20 um 16:05 schrieb Kazlauskas, Nicholas:
> > > On 2020-07-27 9:39 a.m., Christian König wrote:
> > >> Am 27.07.20 um 07:40 schrieb Mazin Rezk:
> > >>> This patch fixes a race condition that causes a use-after-free during
> > >>> amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking
> > >>> commits
> > >>> are requested and the second one finishes before the first.
> > >>> Essentially,
> > >>> this bug occurs when the following sequence of events happens:
> > >>>
> > >>> 1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
> > >>> deferred to the workqueue.
> > >>>
> > >>> 2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
> > >>> deferred to the workqueue.
> > >>>
> > >>> 3. Commit #2 starts before commit #1, dm_state #1 is used in the
> > >>> commit_tail and commit #2 completes, freeing dm_state #1.
> > >>>
> > >>> 4. Commit #1 starts after commit #2 completes, uses the freed dm_state
> > >>> 1 and dereferences a freelist pointer while setting the context.
> > >>
> > >> Well I only have a one mile high view on this, but why don't you let
> > >> the work items execute in order?
> > >>
> > >> That would be better anyway cause this way we don't trigger a cache
> > >> line ping pong between CPUs.
> > >>
> > >> Christian.
> > >
> > > We use the DRM helpers for managing drm_atomic_commit_state and those
> > > helpers internally push non-blocking commit work into the system
> > > unbound work queue.
> >
> > Mhm, well if you send those helper atomic commits in the order A,B and
> > they execute it in the order B,A I would call that a bug :)
>
> The way it works is it pushes all commits into unbound work queue, but
> then forces serialization as needed. We do _not_ want e.g. updates on
> different CRTC to be serialized, that would result in lots of judder.
> And hw is funny enough that there's all kinds of dependencies.
>
> The way you force synchronization is by adding other CRTC state
> objects. So if DC is busted and can only handle a single update per
> work item, then I guess you always need all CRTC states and everything
> will be run in order. But that also totally kills modern multi-screen
> compositors. Xorg isn't modern, just in case that's not clear :-)
>
> Lucking at the code it seems like you indeed have only a single dm
> state, so yeah global sync is what you'll need as immediate fix, and
> then maybe fix up DM to not be quite so silly ... or at least only do
> the dm state stuff when really needed.
>
> We could also sprinkle the drm_crtc_commit structure around a bit
> (it's the glue that provides the synchronization across commits), but
> since your dm state is global just grabbing all crtc states
> unconditionally as part of that is probably best.
>
> > > While we could duplicate a copy of that code with nothing but the
> > > workqueue changed that isn't something I'd really like to maintain
> > > going forward.
> >
> > I'm not talking about duplicating the code, I'm talking about fixing the
> > helpers. I don't know that code well, but from the outside it sounds
> > like a bug there.
> >
> > And executing work items in the order they are submitted is trivial.
> >
> > Had anybody pinged Daniel or other people familiar with the helper code
> > about it?
>
> Yeah something is wrong here, and the fix looks horrible :-)
>
> Aside, I've also seen some recent discussion flare up about
> drm_atomic_state_get/put used to paper over some other use-after-free,
> but this time related to interrupt handlers. Maybe a few rules about
> that:
> - dont
> - especially not when it's interrupt handlers, because you can't call
> drm_atomic_state_put from interrupt handlers.
>
> Instead have an spin_lock_irq to protect the shared date with your
> interrupt handler, and _copy_ the date over. This is e.g. what
> drm_crtc_arm_vblank_event does.

Nicholas wrote a patch that attempted to resolve the issue by adding every
CRTC into the commit to use use the stall checks. [1] While this forces
synchronisation on commits, it's kind of a hacky method that may take a
toll on performance.

Is it possible to have a DRM helper that forces synchronisation on some
commits without having to add every CRTC into the commit?

Also, is synchronisation really necessary for fast updates in amdgpu?
I'll admit, the idea of eliminating the use-after-free bug by eliminating
the use entirely doesn't seem ideal; but is forcing synchronisation on
these updates that much better?

[1] https://bugzilla.kernel.org/show_bug.cgi?id=207383#c96

Thanks,
Mazin Rezk

>
> Cheers, Daniel
>
> >
> > Regards,
> > Christian.
> >
> > >
> > > Regards,
> > > Nicholas Kazlauskas
> > >
> > >>
> > >>>
> > >>> Since this bug has only been spotted with fast commits, this patch
> > >>> fixes
> > >>> the bug by clearing the dm_state instead of using the old dc_state for
> > >>> fast updates. In add

[PATCH] nouveau: use ttm populate mapping functions. (v2)

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

Instead of rolling driver copies of them.

v2: cleanup return handling (Ben)
Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c | 38 ++--
 1 file changed, 2 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7806278dce57..6ef5085c9a91 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1231,8 +1231,6 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct 
ttm_operation_ctx *ctx)
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
struct device *dev;
-   unsigned i;
-   int r;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
if (ttm->state != tt_unpopulated)
@@ -1260,31 +1258,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct 
ttm_operation_ctx *ctx)
return ttm_dma_populate((void *)ttm, dev, ctx);
}
 #endif
-
-   r = ttm_pool_populate(ttm, ctx);
-   if (r) {
-   return r;
-   }
-
-   for (i = 0; i < ttm->num_pages; i++) {
-   dma_addr_t addr;
-
-   addr = dma_map_page(dev, ttm->pages[i], 0, PAGE_SIZE,
-   DMA_BIDIRECTIONAL);
-
-   if (dma_mapping_error(dev, addr)) {
-   while (i--) {
-   dma_unmap_page(dev, ttm_dma->dma_address[i],
-  PAGE_SIZE, DMA_BIDIRECTIONAL);
-   ttm_dma->dma_address[i] = 0;
-   }
-   ttm_pool_unpopulate(ttm);
-   return -EFAULT;
-   }
-
-   ttm_dma->dma_address[i] = addr;
-   }
-   return 0;
+   return ttm_populate_and_map_pages(dev, ttm_dma, ctx);
 }
 
 static void
@@ -1293,7 +1267,6 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
struct device *dev;
-   unsigned i;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
if (slave)
@@ -1316,14 +1289,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
}
 #endif
 
-   for (i = 0; i < ttm->num_pages; i++) {
-   if (ttm_dma->dma_address[i]) {
-   dma_unmap_page(dev, ttm_dma->dma_address[i], PAGE_SIZE,
-  DMA_BIDIRECTIONAL);
-   }
-   }
-
-   ttm_pool_unpopulate(ttm);
+   ttm_unmap_and_unpopulate_pages(dev, ttm_dma);
 }
 
 void
-- 
2.26.2

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


ttm_tt_set_placement_caching on vram->ram transfers

2020-07-27 Thread Dave Airlie
Hi Christian + Ben,

Just been reviewing around driver TTM code, and found an inconsistency,

amdgpu + radeon both call the above before binding the ttm and going
gpu vram->ram copies, but I don't see nouveau doing it Not sure if it
could cause any issues, but it does look inconsistent.

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


[Bug 207383] [Regression] 5.7 amdgpu/polaris11 gpf: amdgpu_atomic_commit_tail

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207383

--- Comment #103 from mn...@protonmail.com ---
(In reply to Nicholas Kazlauskas from comment #95)
> Created attachment 290583 [details]
> 0001-drm-amd-display-Force-add-all-CRTCs-to-state-when-us.patch
> 
> So the sequence looks like the following:
> 
> 1. Non-blocking commit #1 requested, checked, swaps state and deferred to
> work queue.
> 
> 2. Non-blocking commit #2 requested, checked, swaps state and deferred to
> work queue.
> 
> Commits #1 and #2 don't touch any of the same core DRM objects (CRTCs,
> Planes, Connectors) so Commit #2 does not stall for Commit #1. DRM Private
> Objects have always been avoided in stall checks, so we have no safety from
> DRM core in this regard.
> 
> 3. Due to system load commit #2 executes first and finishes its commit tail
> work. At the end of commit tail, as part of DRM core, it calls
> drm_atomic_state_put().
> 
> Since this was the pageflip IOCTL we likely already dropped the reference on
> the state held by the IOCTL itself. So it's going to actually free at this
> point.
> 
> This eventually calls drm_atomic_state_clear() which does the following:
> 
> obj->funcs->atomic_destroy_state(obj, state->private_objs[i].state);
> 
> Note that it clears "state" here. Commit sets "state" to the following:
> 
> state->private_objs[i].state = old_obj_state;
> obj->state = new_obj_state;
> 
> Since Commit #1 swapped first this means Commit #2 actually does free Commit
> #1's private object.
> 
> 4. Commit #1 then executes and we get a use after free.
> 
> Same bug, it's just this was never corrupted before by the slab changes.
> It's been sitting dormant for 5.0~5.8.
> 
> Attached is a patch that might help resolve this.

So I just got around to testing this patch and so far, not very promising.

Right now I can't comment on if the bug in question was resolved but this
just introduced some new critical bugs for me.

I first tried this on my bare metal system w/ my RX 480 and it boots into
lightdm just fine. As soon as I log in and start up XFCE however, one of my
two monitors goes black (monitor reports being asleep) but my cursor seems
to drift into the other monitor just fine. So after that, I check the
display settings and both monitors are detected. So I tried re-enabling the
off monitor and then both monitors work fine.

After that, another bug: I now have two cursors, one only works on my right
monitor and the other only stays in one position.

At this point, I recompiled and remade the initramfs, and sure enough, same
issues. This time, however, changing the display settings didn't "fix" the
issue with one monitor being blank; the off monitor activated, but the
previously working one just froze.

I also tried this on my VM passing through my GPU w/ vfio-pci; similar
issues. Lightdm worked fine but when I started KDE Plasma, it started
flashing white and one of my monitors just became blank. This time, I
couldn't enable the blank display from the settings, it just didn't show
up. Xrandr only showed one output as well; switching HDMI outputs still
only lets me use the monitor on the "working" HDMI port.

I don't exactly know how I would go about debugging this since there's just
too many bugs to count. I also don't know if it would be worth it at all.

Do you have any idea why this would occur? This patch only seems to force
synchronisation, I don't quite know why it would break my system so much.

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


[PATCH] drm/vmwgfx: drop bo map/unmap dma functions.

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

The map one was used once, just inline it, and drop them both.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h|  2 -
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 46 +++---
 2 files changed, 6 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index b7c763713b4c..65c414f119c0 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1019,8 +1019,6 @@ extern struct ttm_placement vmw_mob_placement;
 extern struct ttm_placement vmw_mob_ne_placement;
 extern struct ttm_placement vmw_nonfixed_placement;
 extern struct ttm_bo_driver vmw_bo_driver;
-extern int vmw_bo_map_dma(struct ttm_buffer_object *bo);
-extern void vmw_bo_unmap_dma(struct ttm_buffer_object *bo);
 extern const struct vmw_sg_table *
 vmw_bo_sg_table(struct ttm_buffer_object *bo);
 extern int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index d051b84aaeb5..0f0f9600ea46 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -519,43 +519,6 @@ static void vmw_ttm_unmap_dma(struct vmw_ttm_tt *vmw_tt)
vmw_tt->mapped = false;
 }
 
-
-/**
- * vmw_bo_map_dma - Make sure buffer object pages are visible to the device
- *
- * @bo: Pointer to a struct ttm_buffer_object
- *
- * Wrapper around vmw_ttm_map_dma, that takes a TTM buffer object pointer
- * instead of a pointer to a struct vmw_ttm_backend as argument.
- * Note that the buffer object must be either pinned or reserved before
- * calling this function.
- */
-int vmw_bo_map_dma(struct ttm_buffer_object *bo)
-{
-   struct vmw_ttm_tt *vmw_tt =
-   container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm.ttm);
-
-   return vmw_ttm_map_dma(vmw_tt);
-}
-
-
-/**
- * vmw_bo_unmap_dma - Make sure buffer object pages are visible to the device
- *
- * @bo: Pointer to a struct ttm_buffer_object
- *
- * Wrapper around vmw_ttm_unmap_dma, that takes a TTM buffer object pointer
- * instead of a pointer to a struct vmw_ttm_backend as argument.
- */
-void vmw_bo_unmap_dma(struct ttm_buffer_object *bo)
-{
-   struct vmw_ttm_tt *vmw_tt =
-   container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm.ttm);
-
-   vmw_ttm_unmap_dma(vmw_tt);
-}
-
-
 /**
  * vmw_bo_sg_table - Return a struct vmw_sg_table object for a
  * TTM buffer object
@@ -876,9 +839,12 @@ int vmw_bo_create_and_populate(struct vmw_private 
*dev_priv,
 
ret = ttm_bo_reserve(bo, false, true, NULL);
BUG_ON(ret != 0);
-   ret = vmw_bo_driver.ttm_tt_populate(bo->ttm, &ctx);
-   if (likely(ret == 0))
-   ret = vmw_bo_map_dma(bo);
+   ret = vmw_ttm_populate(bo->ttm, &ctx);
+   if (likely(ret == 0)) {
+   struct vmw_ttm_tt *vmw_tt =
+   container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm.ttm);
+   ret = vmw_ttm_map_dma(vmw_tt);
+   }
 
ttm_bo_unreserve(bo);
 
-- 
2.26.2

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


[PATCH] drm/vmwgfx: consolidate ttm object creation and populate

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

These two functions has the same code in them, create a common
helper function instead.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h|  4 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_mob.c| 60 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 32 
 3 files changed, 39 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 3596f3923ea3..b7c763713b4c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1023,6 +1023,10 @@ extern int vmw_bo_map_dma(struct ttm_buffer_object *bo);
 extern void vmw_bo_unmap_dma(struct ttm_buffer_object *bo);
 extern const struct vmw_sg_table *
 vmw_bo_sg_table(struct ttm_buffer_object *bo);
+extern int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
+ unsigned long bo_size,
+ struct ttm_buffer_object **bo_p);
+
 extern void vmw_piter_start(struct vmw_piter *viter,
const struct vmw_sg_table *vsgt,
unsigned long p_offs);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
index e8eb42933ca2..7f95ed6aa224 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
@@ -238,10 +238,6 @@ static int vmw_otable_batch_setup(struct vmw_private 
*dev_priv,
unsigned long offset;
unsigned long bo_size;
struct vmw_otable *otables = batch->otables;
-   struct ttm_operation_ctx ctx = {
-   .interruptible = false,
-   .no_wait_gpu = false
-   };
SVGAOTableType i;
int ret;
 
@@ -255,24 +251,9 @@ static int vmw_otable_batch_setup(struct vmw_private 
*dev_priv,
bo_size += otables[i].size;
}
 
-   ret = ttm_bo_create(&dev_priv->bdev, bo_size,
-   ttm_bo_type_device,
-   &vmw_sys_ne_placement,
-   0, false, &batch->otable_bo);
-
-   if (unlikely(ret != 0))
-   goto out_no_bo;
-
-   ret = ttm_bo_reserve(batch->otable_bo, false, true, NULL);
-   BUG_ON(ret != 0);
-   ret = vmw_bo_driver.ttm_tt_populate(batch->otable_bo->ttm, &ctx);
-   if (unlikely(ret != 0))
-   goto out_unreserve;
-   ret = vmw_bo_map_dma(batch->otable_bo);
+   ret = vmw_bo_create_and_populate(dev_priv, bo_size, &batch->otable_bo);
if (unlikely(ret != 0))
-   goto out_unreserve;
-
-   ttm_bo_unreserve(batch->otable_bo);
+   return ret;
 
offset = 0;
for (i = 0; i < batch->num_otables; ++i) {
@@ -289,8 +270,6 @@ static int vmw_otable_batch_setup(struct vmw_private 
*dev_priv,
 
return 0;
 
-out_unreserve:
-   ttm_bo_unreserve(batch->otable_bo);
 out_no_setup:
for (i = 0; i < batch->num_otables; ++i) {
if (batch->otables[i].enabled)
@@ -300,7 +279,6 @@ static int vmw_otable_batch_setup(struct vmw_private 
*dev_priv,
 
ttm_bo_put(batch->otable_bo);
batch->otable_bo = NULL;
-out_no_bo:
return ret;
 }
 
@@ -432,41 +410,9 @@ struct vmw_mob *vmw_mob_create(unsigned long data_pages)
 static int vmw_mob_pt_populate(struct vmw_private *dev_priv,
   struct vmw_mob *mob)
 {
-   int ret;
-   struct ttm_operation_ctx ctx = {
-   .interruptible = false,
-   .no_wait_gpu = false
-   };
-
BUG_ON(mob->pt_bo != NULL);
 
-   ret = ttm_bo_create(&dev_priv->bdev, mob->num_pages * PAGE_SIZE,
-   ttm_bo_type_device,
-   &vmw_sys_ne_placement,
-   0, false, &mob->pt_bo);
-   if (unlikely(ret != 0))
-   return ret;
-
-   ret = ttm_bo_reserve(mob->pt_bo, false, true, NULL);
-
-   BUG_ON(ret != 0);
-   ret = vmw_bo_driver.ttm_tt_populate(mob->pt_bo->ttm, &ctx);
-   if (unlikely(ret != 0))
-   goto out_unreserve;
-   ret = vmw_bo_map_dma(mob->pt_bo);
-   if (unlikely(ret != 0))
-   goto out_unreserve;
-
-   ttm_bo_unreserve(mob->pt_bo);
-
-   return 0;
-
-out_unreserve:
-   ttm_bo_unreserve(mob->pt_bo);
-   ttm_bo_put(mob->pt_bo);
-   mob->pt_bo = NULL;
-
-   return ret;
+   return vmw_bo_create_and_populate(dev_priv, mob->num_pages * PAGE_SIZE, 
&mob->pt_bo);
 }
 
 /**
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index 1d78187eaba6..d051b84aaeb5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -854,3 +854,35 @@ struct ttm_bo_driver vmw_bo_driver = {
.swap_notify = vmw_swap_notify,
.io_mem_reserve = &vmw_ttm_io_mem_reserve,
 };
+
+int vmw_bo_create_and_populate(struct vmw_private 

Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Kazlauskas, Nicholas

On 2020-07-27 5:32 p.m., Daniel Vetter wrote:

On Mon, Jul 27, 2020 at 11:11 PM Mazin Rezk  wrote:


On Monday, July 27, 2020 4:29 PM, Daniel Vetter  wrote:


On Mon, Jul 27, 2020 at 9:28 PM Christian König
 wrote:


Am 27.07.20 um 16:05 schrieb Kazlauskas, Nicholas:

On 2020-07-27 9:39 a.m., Christian König wrote:

Am 27.07.20 um 07:40 schrieb Mazin Rezk:

This patch fixes a race condition that causes a use-after-free during
amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking
commits
are requested and the second one finishes before the first.
Essentially,
this bug occurs when the following sequence of events happens:

1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
deferred to the workqueue.

2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
deferred to the workqueue.

3. Commit #2 starts before commit #1, dm_state #1 is used in the
commit_tail and commit #2 completes, freeing dm_state #1.

4. Commit #1 starts after commit #2 completes, uses the freed dm_state
1 and dereferences a freelist pointer while setting the context.


Well I only have a one mile high view on this, but why don't you let
the work items execute in order?

That would be better anyway cause this way we don't trigger a cache
line ping pong between CPUs.

Christian.


We use the DRM helpers for managing drm_atomic_commit_state and those
helpers internally push non-blocking commit work into the system
unbound work queue.


Mhm, well if you send those helper atomic commits in the order A,B and
they execute it in the order B,A I would call that a bug :)


The way it works is it pushes all commits into unbound work queue, but
then forces serialization as needed. We do _not_ want e.g. updates on
different CRTC to be serialized, that would result in lots of judder.
And hw is funny enough that there's all kinds of dependencies.

The way you force synchronization is by adding other CRTC state
objects. So if DC is busted and can only handle a single update per
work item, then I guess you always need all CRTC states and everything
will be run in order. But that also totally kills modern multi-screen
compositors. Xorg isn't modern, just in case that's not clear :-)

Lucking at the code it seems like you indeed have only a single dm
state, so yeah global sync is what you'll need as immediate fix, and
then maybe fix up DM to not be quite so silly ... or at least only do
the dm state stuff when really needed.

We could also sprinkle the drm_crtc_commit structure around a bit
(it's the glue that provides the synchronization across commits), but
since your dm state is global just grabbing all crtc states
unconditionally as part of that is probably best.


While we could duplicate a copy of that code with nothing but the
workqueue changed that isn't something I'd really like to maintain
going forward.


I'm not talking about duplicating the code, I'm talking about fixing the
helpers. I don't know that code well, but from the outside it sounds
like a bug there.

And executing work items in the order they are submitted is trivial.

Had anybody pinged Daniel or other people familiar with the helper code
about it?


Yeah something is wrong here, and the fix looks horrible :-)

Aside, I've also seen some recent discussion flare up about
drm_atomic_state_get/put used to paper over some other use-after-free,
but this time related to interrupt handlers. Maybe a few rules about
that:
- dont
- especially not when it's interrupt handlers, because you can't call
drm_atomic_state_put from interrupt handlers.

Instead have an spin_lock_irq to protect the shared date with your
interrupt handler, and _copy_ the date over. This is e.g. what
drm_crtc_arm_vblank_event does.


Nicholas wrote a patch that attempted to resolve the issue by adding every
CRTC into the commit to use use the stall checks. [1] While this forces
synchronisation on commits, it's kind of a hacky method that may take a
toll on performance.

Is it possible to have a DRM helper that forces synchronisation on some
commits without having to add every CRTC into the commit?

Also, is synchronisation really necessary for fast updates in amdgpu?
I'll admit, the idea of eliminating the use-after-free bug by eliminating
the use entirely doesn't seem ideal; but is forcing synchronisation on
these updates that much better?


Well clearing the dc_state pointer here and then allocating another
one in atomic_commit_tail also looks fishy. The proper fix is probably
a lot more involved, but yeah interim fix is to grab all crtc states
iff you also grabbed the dm_atomic_state structure. Real fix is to
only do this when necessary, which pretty much means the dc_state
needs to be somehow split up, or there needs to be some guarantees
about when it's necessary and when not. Otherwise parallel commits on
different CRTC are not possible with the current dc backend code.


Thanks for spending some time to help take a look at this as well.

The DRM documentation (at least at th

[PATCH] nouveau: use ttm populate mapping functions.

2020-07-27 Thread Dave Airlie
From: Dave Airlie 

Instead of rolling driver copies of them.

Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c | 32 ++--
 1 file changed, 2 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7806278dce57..fe773737b662 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1231,7 +1231,6 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct 
ttm_operation_ctx *ctx)
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
struct device *dev;
-   unsigned i;
int r;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
@@ -1261,29 +1260,10 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct 
ttm_operation_ctx *ctx)
}
 #endif
 
-   r = ttm_pool_populate(ttm, ctx);
+   r = ttm_populate_and_map_pages(dev, ttm_dma, ctx);
if (r) {
return r;
}
-
-   for (i = 0; i < ttm->num_pages; i++) {
-   dma_addr_t addr;
-
-   addr = dma_map_page(dev, ttm->pages[i], 0, PAGE_SIZE,
-   DMA_BIDIRECTIONAL);
-
-   if (dma_mapping_error(dev, addr)) {
-   while (i--) {
-   dma_unmap_page(dev, ttm_dma->dma_address[i],
-  PAGE_SIZE, DMA_BIDIRECTIONAL);
-   ttm_dma->dma_address[i] = 0;
-   }
-   ttm_pool_unpopulate(ttm);
-   return -EFAULT;
-   }
-
-   ttm_dma->dma_address[i] = addr;
-   }
return 0;
 }
 
@@ -1293,7 +1273,6 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
struct device *dev;
-   unsigned i;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
if (slave)
@@ -1316,14 +1295,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
}
 #endif
 
-   for (i = 0; i < ttm->num_pages; i++) {
-   if (ttm_dma->dma_address[i]) {
-   dma_unmap_page(dev, ttm_dma->dma_address[i], PAGE_SIZE,
-  DMA_BIDIRECTIONAL);
-   }
-   }
-
-   ttm_pool_unpopulate(ttm);
+   ttm_unmap_and_unpopulate_pages(dev, ttm_dma);
 }
 
 void
-- 
2.26.2

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


[Bug 207383] [Regression] 5.7 amdgpu/polaris11 gpf: amdgpu_atomic_commit_tail

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207383

--- Comment #102 from Duncan (1i5t5.dun...@cox.net) ---
(In reply to Duncan from comment #101)
> (In reply to Nicholas Kazlauskas from comment #95)
> > 0001-drm-amd-display-Force-add-all-CRTCs-to-state-when-us.patch
> 
> Just booted to 5.8-rc7 with this patched in locally (and the g320+ reverts
> /not/ patched in).  So testing, but noting again that the bug can take a
> couple days to trigger on my hardware, so while verifying bug-still-there
> /might/ be fast, verifying that it's /not/ there will take awhile.

So far building system updates so heavy cpu load while playing only moderate
FHD video.  No freezes but I have seen a bit of the predicted judder.

I suspect the synchronization is preventing the freezes, and the judder hasn't
been /bad/.  But with different-refresh monitors (mine are both 60 Hz 4k
bigscreen TVs so same refresh), or trying 4k video, particularly 4k60 which my
system already struggles with, or possibly even both say 120 Hz monitors, the
judder would be noticeably worse.  The 4k30 and 4k60 youtube tests will
probably have to wait for tomorrow, tho, as I've been up near 24 now...

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


[PATCH 5/6] i915: fail atomic commit when muxed away

2020-07-27 Thread Daniel Dadap
Attempting to commit a modeset while mux-switched away can cause
problems due to DisplayPort links being unavailable while they are
physically disconnected. In order to avoid this, bail out of atomic
commit early if attempted while a display mux is switched away.

Signed-off-by: Daniel Dadap 
---
 drivers/gpu/drm/i915/display/intel_display.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 346846609f45..4ad799e4b024 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -15736,6 +15737,12 @@ static int intel_atomic_commit(struct drm_device *dev,
struct drm_i915_private *dev_priv = to_i915(dev);
int ret = 0;
 
+   if (!vga_switcheroo_is_client_active(to_pci_dev(dev->dev))) {
+   drm_dbg_atomic(&dev_priv->drm,
+   "Atomic commit attempted while muxed away.\n");
+   return -EINVAL;
+   }
+
state->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
 
drm_atomic_state_get(&state->base);
-- 
2.18.4

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


[PATCH 4/6] drm/panel: Add panel driver for NewVision NV3052C based LCDs

2020-07-27 Thread Paul Cercueil
This driver supports the NewVision NV3052C based LCDs. Right now, it
only supports the LeadTek LTK035C5444T 2.4" 640x480 TFT LCD panel, which
can be found in the Anbernic RG-350M handheld console.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-newvision-nv3052c.c   | 523 ++
 3 files changed, 533 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-newvision-nv3052c.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index de2f2a452be5..6a8a51a702d8 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -198,6 +198,15 @@ config DRM_PANEL_NEC_NL8048HL11
  panel (found on the Zoom2/3/3630 SDP boards). To compile this driver
  as a module, choose M here.
 
+config DRM_PANEL_NEWVISION_NV3052C
+   tristate "NewVision NV3052C DSI/SPI RGB panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for the panels built
+ around the NewVision NV3052C display controller.
+
 config DRM_PANEL_NOVATEK_NT35510
tristate "Novatek NT35510 RGB panel driver"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index e45ceac6286f..a0516ced87db 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += 
panel-leadtek-ltk500hd1829.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
+obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
 obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c 
b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
new file mode 100644
index ..2feabef6dc3c
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NevVision NV3052C IPS LCD panel driver
+ *
+ * Copyright (C) 2020, Paul Cercueil 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+struct nv3052c_panel_info {
+   const struct drm_display_mode *display_modes;
+   unsigned int num_modes;
+   unsigned int bus_type;
+   u16 width_mm, height_mm;
+   u32 bus_format, bus_flags;
+};
+
+struct nv3052c_reg {
+   u8 cmd;
+   u8 value;
+};
+
+struct nv3052c {
+   struct drm_panel drm_panel;
+   struct mipi_dsi_device *dsi;
+   struct device *dev;
+
+   struct regulator *supply;
+   const struct nv3052c_panel_info *panel_info;
+
+   struct gpio_desc *reset_gpio;
+
+   struct backlight_device *backlight;
+};
+
+static const struct nv3052c_reg nv3052c_regs[] = {
+   { 0xff, 0x30 },
+   { 0xff, 0x52 },
+   { 0xff, 0x01 },
+   { 0xe3, 0x00 },
+   { 0x40, 0x00 },
+   { 0x03, 0x40 },
+   { 0x04, 0x00 },
+   { 0x05, 0x03 },
+   { 0x08, 0x00 },
+   { 0x09, 0x07 },
+   { 0x0a, 0x01 },
+   { 0x0b, 0x32 },
+   { 0x0c, 0x32 },
+   { 0x0d, 0x0b },
+   { 0x0e, 0x00 },
+   { 0x23, 0xa0 },
+
+   { 0x24, 0x0c },
+   { 0x25, 0x06 },
+   { 0x26, 0x14 },
+   { 0x27, 0x14 },
+
+   { 0x38, 0xcc },
+   { 0x39, 0xd7 },
+   { 0x3a, 0x4a },
+
+   { 0x28, 0x40 },
+   { 0x29, 0x01 },
+   { 0x2a, 0xdf },
+   { 0x49, 0x3c },
+   { 0x91, 0x77 },
+   { 0x92, 0x77 },
+   { 0xa0, 0x55 },
+   { 0xa1, 0x50 },
+   { 0xa4, 0x9c },
+   { 0xa7, 0x02 },
+   { 0xa8, 0x01 },
+   { 0xa9, 0x01 },
+   { 0xaa, 0xfc },
+   { 0xab, 0x28 },
+   { 0xac, 0x06 },
+   { 0xad, 0x06 },
+   { 0xae, 0x06 },
+   { 0xaf, 0x03 },
+   { 0xb0, 0x08 },
+   { 0xb1, 0x26 },
+   { 0xb2, 0x28 },
+   { 0xb3, 0x28 },
+   { 0xb4, 0x33 },
+   { 0xb5, 0x08 },
+   { 0xb6, 0x26 },
+   { 0xb7, 0x08 },
+   { 0xb8, 0x26 },
+   { 0xf0, 0x00 },
+   { 0xf6, 0xc0 },
+
+   { 0xff, 0x30 },
+   { 0xff, 0x52 },
+   { 0xff, 0x02 },
+   { 0xb0, 0x0b },
+   { 0xb1, 0x16 },
+   { 0xb2, 0x17 },
+   { 0xb3, 0x2c },
+   { 0xb4, 0x32 },
+   { 0xb5, 0x3b },
+   { 0xb6, 0x29 },
+   { 0xb7, 0x40 },
+   { 0xb8, 0x0d },
+   { 0xb9, 0x05 },
+   { 0xba, 0x12 },
+   { 0xbb, 0x10 },
+   { 0xbc, 0x12 },
+   { 0xbd, 0x15 },
+   { 0xbe, 0x19 },
+   { 0xbf, 0x0e },
+   { 0xc0, 0x16 },
+   { 0xc1, 0x0a },
+  

[PATCH 3/6] vga-switcheroo: notify clients of pending/completed switch events

2020-07-27 Thread Daniel Dadap
Add a new vga-switcheroo client callback to allow clients to register
for receiving notifications when a mux switch is pending, completed,
or failed. This allows individual client drivers to prepare for or
respond to mux switches to and from the registered client device.

Signed-off-by: Daniel Dadap 
---
 drivers/gpu/vga/vga_switcheroo.c | 29 -
 include/linux/vga_switcheroo.h   | 18 ++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index a4fc78c4bf4f..6392dc92696b 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -756,14 +756,41 @@ static int vga_switchto_stage2(struct 
vga_switcheroo_client *new_client,
if (new_client->fb_info)
fbcon_remap_all(new_client->fb_info);
 
+   if (active->ops->notify)
+   active->ops->notify(active->pdev,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_AWAY,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_PENDING);
+   if (new_client->ops->notify)
+   new_client->ops->notify(new_client->pdev,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_TO,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_PENDING);
+
active->switched = false;
mutex_lock(&vgasr_priv.mux_hw_lock);
ret = vgasr_priv.handler->switchto(new_client->id);
mutex_unlock(&vgasr_priv.mux_hw_lock);
-   if (ret)
+   if (ret) {
+   if (active->ops->notify)
+   active->ops->notify(active->pdev,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_AWAY,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_FAILED);
+   if (new_client->ops->notify)
+   new_client->ops->notify(new_client->pdev,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_TO,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_FAILED);
return ret;
+   }
new_client->switched = true;
 
+   if (active->ops->notify)
+   active->ops->notify(active->pdev,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_AWAY,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_COMPLETE);
+   if (new_client->ops->notify)
+   new_client->ops->notify(new_client->pdev,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_TO,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_COMPLETE);
+
if (new_client->ops->reprobe)
new_client->ops->reprobe(new_client->pdev);
 
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 63e6d6e5786e..2dc8ebc84fd4 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -90,6 +90,17 @@ enum vga_switcheroo_client_id {
VGA_SWITCHEROO_MAX_CLIENTS,
 };
 
+enum vga_switcheroo_notify_direction {
+   VGA_SWITCHEROO_NOTIFY_SWITCH_TO,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_AWAY,
+};
+
+enum vga_switcheroo_notify_action {
+   VGA_SWITCHEROO_NOTIFY_SWITCH_PENDING,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_COMPLETE,
+   VGA_SWITCHEROO_NOTIFY_SWITCH_FAILED,
+};
+
 /**
  * struct vga_switcheroo_handler - handler callbacks
  * @init: initialize handler.
@@ -134,6 +145,10 @@ struct vga_switcheroo_handler {
  * Mandatory. The client should return false if a user space process
  * has one of its device files open
  * @gpu_bound: notify the client id to audio client when the GPU is bound.
+ * @notify: notify clients of pending and completed switches
+ * Optional. This gets called for both active and inactive clients,
+ * before a switch begins, and after a switch successfully completes
+ * or fails.
  *
  * Client callbacks. A client can be either a GPU or an audio device on a GPU.
  * The @set_gpu_state and @can_switch methods are mandatory, @reprobe may be
@@ -145,6 +160,9 @@ struct vga_switcheroo_client_ops {
void (*reprobe)(struct pci_dev *dev);
bool (*can_switch)(struct pci_dev *dev);
void (*gpu_bound)(struct pci_dev *dev, enum vga_switcheroo_client_id);
+   void (*notify)(struct pci_dev *dev,
+  enum vga_switcheroo_notify_direction,
+  enum vga_switcheroo_notify_action);
 };
 
 #if defined(CONFIG_VGA_SWITCHEROO)
-- 
2.18.4

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


Re: [v7, PATCH 7/7] drm/mediatek: add support for mediatek SOC MT8183

2020-07-27 Thread Yongqiang Niu
On Sat, 2020-07-25 at 07:24 +0800, Chun-Kuang Hu wrote:
> Hi Yongqiang:
> 
> Yongqiang Niu  於 2020年7月23日 週四 上午10:15寫道:
> >
> > This patch add support for mediatek SOC MT8183
> > 1.ovl_2l share driver with ovl
> 
> I think this is done in [1], [2], [3], this patch just add the support
> of mt8183-ovl and mt8183-ovl-2l.
> 
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/gpu/drm/mediatek?h=v5.8-rc6&id=132c6e250ed745443973cada8db17cdbaebdf551
> [2] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/gpu/drm/mediatek?h=v5.8-rc6&id=318462d1a568634ba09263cc730cb0fb1d56c2b3
> [3] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/gpu/drm/mediatek?h=v5.8-rc6&id=57148baac8b78461e394953cfd5317bde8f795ab
> 
> > 2.rdma1 share drive with rdma0, but fifo size is different
> 
> I think this is done in [4], this patch just add the support of mt8183-rdma.
> 
> [4] https://patchwork.kernel.org/patch/11679549/
> 
> > 3.add mt8183 mutex private data, and mmsys private data
> > 4.add mt8183 main and external path module for crtc create
> 
> The fourth item is the mmsys private data in third item, so you need
> not to repeat it.
> 
> >
> > Signed-off-by: Yongqiang Niu 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 18 
> >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp.c   | 47 
> > 
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 43 +
> >  4 files changed, 114 insertions(+)
> >
> 
> [snip]
> 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> > index 014c1bb..60788c1 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
> > @@ -15,6 +15,8 @@
> >
> >  #define MT2701_DISP_MUTEX0_MOD00x2c
> >  #define MT2701_DISP_MUTEX0_SOF00x30
> > +#define MT8183_DISP_MUTEX0_MOD00x30
> > +#define MT8183_DISP_MUTEX0_SOF00x2c
> >
> >  #define DISP_REG_MUTEX_EN(n)   (0x20 + 0x20 * (n))
> >  #define DISP_REG_MUTEX(n)  (0x24 + 0x20 * (n))
> > @@ -25,6 +27,18 @@
> >
> >  #define INT_MUTEX  BIT(1)
> >
> > +#define MT8183_MUTEX_MOD_DISP_RDMA00
> > +#define MT8183_MUTEX_MOD_DISP_RDMA11
> > +#define MT8183_MUTEX_MOD_DISP_OVL0 9
> > +#define MT8183_MUTEX_MOD_DISP_OVL0_2L  10
> > +#define MT8183_MUTEX_MOD_DISP_OVL1_2L  11
> > +#define MT8183_MUTEX_MOD_DISP_WDMA012
> > +#define MT8183_MUTEX_MOD_DISP_COLOR0   13
> > +#define MT8183_MUTEX_MOD_DISP_CCORR0   14
> > +#define MT8183_MUTEX_MOD_DISP_AAL0 15
> > +#define MT8183_MUTEX_MOD_DISP_GAMMA0   16
> > +#define MT8183_MUTEX_MOD_DISP_DITHER0  17
> > +
> >  #define MT8173_MUTEX_MOD_DISP_OVL0 11
> >  #define MT8173_MUTEX_MOD_DISP_OVL1 12
> >  #define MT8173_MUTEX_MOD_DISP_RDMA013
> > @@ -74,6 +88,10 @@
> >  #define MUTEX_SOF_DSI2 5
> >  #define MUTEX_SOF_DSI3 6
> >
> > +#define MT8183_MUTEX_SOF_DPI0  2
> > +#define MT8183_MUTEX_EOF_DSI0  (MUTEX_SOF_DSI0 << 6)
> > +#define MT8183_MUTEX_EOF_DPI0  (MT8183_MUTEX_SOF_DPI0 << 6)
> > +
> >
> >  struct mtk_disp_mutex {
> > int id;
> > @@ -153,6 +171,20 @@ struct mtk_ddp {
> > [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
> >  };
> >
> > +static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> > +   [DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
> > +   [DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
> > +   [DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
> > +   [DDP_COMPONENT_DITHER] = MT8183_MUTEX_MOD_DISP_DITHER0,
> > +   [DDP_COMPONENT_GAMMA] = MT8183_MUTEX_MOD_DISP_GAMMA0,
> > +   [DDP_COMPONENT_OVL0] = MT8183_MUTEX_MOD_DISP_OVL0,
> > +   [DDP_COMPONENT_OVL_2L0] = MT8183_MUTEX_MOD_DISP_OVL0_2L,
> > +   [DDP_COMPONENT_OVL_2L1] = MT8183_MUTEX_MOD_DISP_OVL1_2L,
> > +   [DDP_COMPONENT_RDMA0] = MT8183_MUTEX_MOD_DISP_RDMA0,
> > +   [DDP_COMPONENT_RDMA1] = MT8183_MUTEX_MOD_DISP_RDMA1,
> > +   [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
> > +};
> > +
> >  static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = {
> > [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> > [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
> > @@ -163,6 +195,12 @@ struct mtk_ddp {
> > [DDP_MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
> >  };
> >
> > +static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = {
> > +   [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> > +   [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
> 

Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Duncan
On Mon, 27 Jul 2020 10:05:01 -0400
"Kazlauskas, Nicholas"  wrote:

> On 2020-07-27 9:39 a.m., Christian König wrote:
> > Am 27.07.20 um 07:40 schrieb Mazin Rezk:
> >> This patch fixes a race condition that causes a use-after-free
> >> during amdgpu_dm_atomic_commit_tail. This can occur when 2
> >> non-blocking commits are requested and the second one finishes
> >> before the first. Essentially, this bug occurs when the following
> >> sequence of events happens:
> >>
> >> 1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
> >> deferred to the workqueue.
> >>
> >> 2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
> >> deferred to the workqueue.
> >>
> >> 3. Commit #2 starts before commit #1, dm_state #1 is used in the
> >> commit_tail and commit #2 completes, freeing dm_state #1.
> >>
> >> 4. Commit #1 starts after commit #2 completes, uses the freed
> >> dm_state 1 and dereferences a freelist pointer while setting the
> >> context.
> > 
> > Well I only have a one mile high view on this, but why don't you
> > let the work items execute in order?
> > 
> > That would be better anyway cause this way we don't trigger a cache
> > line ping pong between CPUs.
> > 
> > Christian.
> 
> We use the DRM helpers for managing drm_atomic_commit_state and those 
> helpers internally push non-blocking commit work into the system
> unbound work queue.
> 
> While we could duplicate a copy of that code with nothing but the 
> workqueue changed that isn't something I'd really like to maintain
> going forward.
> 
> Regards,
> Nicholas Kazlauskas

Additionally, I don't see mentioned on-thread (it's on the bug and now
in the details below) that we're talking multi-monitor, not
single-monitor. Presumably that goes some way toward answering the "why
not force order?" question, considering the outputs may be running at
different refresh frequencies, etc...

All the reports on the bug seem to be multi-monitor (after seeing
multi-monitor/output in several reports I asked if anyone was seeing it
with only one monitor and no answers), and as you commented on the bug
for your proposed patch but seems missing from this one here (different
author/proposal) ...

Commits #1 and #2 don't touch any of the same core DRM objects (CRTCs,
Planes, Connectors) so Commit #2 does not stall for Commit #1. DRM
Private Objects have always been avoided in stall checks, so we have no
safety from DRM core in this regard.

> >>
> >> Since this bug has only been spotted with fast commits, this patch
> >> fixes the bug by clearing the dm_state instead of using the old
> >> dc_state for fast updates. In addition, since dm_state is only
> >> used for its dc_state and amdgpu_dm_atomic_commit_tail will retain
> >> the dc_state if none is found,
> >> removing the dm_state should not have any consequences in fast
> >> updates.
> >>
> >> This use-after-free bug has existed for a while now, but only
> >> caused a noticeable issue starting from 5.7-rc1 due to 3202fa62f
> >> ("slub: relocate freelist pointer to middle of object") moving the
> >> freelist pointer from dm_state->base (which was unused) to
> >> dm_state->context (which is dereferenced).
> >>
> >> Bugzilla: 
> >> https://bugzilla.kernel.org/show_bug.cgi?id=207383 
> >>
> >> Fixes: bd200d190f45 ("drm/amd/display: Don't replace the dc_state
> >> for fast updates")
> >> Reported-by: Duncan <1i5t5.dun...@cox.net>
> >> Signed-off-by: Mazin Rezk 
> >> ---
> >>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36
> >> ++- 1 file changed, 27 insertions(+), 9
> >> deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> >> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> index 86ffa0c2880f..710edc70e37e 100644
> >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> @@ -8717,20 +8717,38 @@ static int amdgpu_dm_atomic_check(struct 
> >> drm_device *dev,
> >>    * the same resource. If we have a new DC context as
> >> part of
> >>    * the DM atomic state from validation we need to free
> >> it and
> >>    * retain the existing one instead.
> >> + *
> >> + * Furthermore, since the DM atomic state only contains
> >> the DC
> >> + * context and can safely be annulled, we can free the
> >> state
> >> + * and clear the associated private object now to free
> >> + * some memory and avoid a possible use-after-free later.
> >>    */
> >> -    struct dm_atomic_state *new_dm_state, *old_dm_state;
> >>
> >> -    new_dm_state = dm_atomic_get_new_state(state);
> >> -    old_dm_state = dm_atomic_get_old_state(state);
> >> +    for (i = 0; i < state->num_private_objs; i++) {
> >> +    struct drm_private_obj *obj =
> >> state->private_objs[i].ptr;
> >>
> >> -    if (new_dm_state && old_dm_state) {
> >> -    if (new_dm_state->context)
> >> -    dc_release_state

[PATCH 1/2] drm/radeon: switch from 'pci_' to 'dma_' API

2020-07-27 Thread Christophe JAILLET
The wrappers in include/linux/pci-dma-compat.h should go away.

The patch has been generated with the coccinelle script below and has been
hand modified to replace GFP_ with a correct flag.
It has been compile tested.

When memory is allocated in 'radeon_gart_table_ram_alloc()' GFP_KERNEL
can be used because its callers already use this flag.

Both 'r100_pci_gart_init()' (r100.c) and 'rs400_gart_init()' (rs400.c)
call 'radeon_gart_init()'.
This function uses 'vmalloc'.


@@
@@
-PCI_DMA_BIDIRECTIONAL
+DMA_BIDIRECTIONAL

@@
@@
-PCI_DMA_TODEVICE
+DMA_TO_DEVICE

@@
@@
-PCI_DMA_FROMDEVICE
+DMA_FROM_DEVICE

@@
@@
-PCI_DMA_NONE
+DMA_NONE

@@
expression e1, e2, e3;
@@
-pci_alloc_consistent(e1, e2, e3)
+dma_alloc_coherent(&e1->dev, e2, e3, GFP_)

@@
expression e1, e2, e3;
@@
-pci_zalloc_consistent(e1, e2, e3)
+dma_alloc_coherent(&e1->dev, e2, e3, GFP_)

@@
expression e1, e2, e3, e4;
@@
-pci_free_consistent(e1, e2, e3, e4)
+dma_free_coherent(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_map_single(e1, e2, e3, e4)
+dma_map_single(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_unmap_single(e1, e2, e3, e4)
+dma_unmap_single(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4, e5;
@@
-pci_map_page(e1, e2, e3, e4, e5)
+dma_map_page(&e1->dev, e2, e3, e4, e5)

@@
expression e1, e2, e3, e4;
@@
-pci_unmap_page(e1, e2, e3, e4)
+dma_unmap_page(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_map_sg(e1, e2, e3, e4)
+dma_map_sg(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_unmap_sg(e1, e2, e3, e4)
+dma_unmap_sg(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_dma_sync_single_for_cpu(e1, e2, e3, e4)
+dma_sync_single_for_cpu(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_dma_sync_single_for_device(e1, e2, e3, e4)
+dma_sync_single_for_device(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_dma_sync_sg_for_cpu(e1, e2, e3, e4)
+dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-pci_dma_sync_sg_for_device(e1, e2, e3, e4)
+dma_sync_sg_for_device(&e1->dev, e2, e3, e4)

@@
expression e1, e2;
@@
-pci_dma_mapping_error(e1, e2)
+dma_mapping_error(&e1->dev, e2)

@@
expression e1, e2;
@@
-pci_set_dma_mask(e1, e2)
+dma_set_mask(&e1->dev, e2)

@@
expression e1, e2;
@@
-pci_set_consistent_dma_mask(e1, e2)
+dma_set_coherent_mask(&e1->dev, e2)

Signed-off-by: Christophe JAILLET 
---
If needed, see post from Christoph Hellwig on the kernel-janitors ML:
   https://marc.info/?l=kernel-janitors&m=158745678307186&w=4
---
 drivers/gpu/drm/radeon/radeon_gart.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index f178ba321715..b7ce254e5663 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -72,8 +72,8 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev)
 {
void *ptr;
 
-   ptr = pci_alloc_consistent(rdev->pdev, rdev->gart.table_size,
-  &rdev->gart.table_addr);
+   ptr = dma_alloc_coherent(&rdev->pdev->dev, rdev->gart.table_size,
+&rdev->gart.table_addr, GFP_KERNEL);
if (ptr == NULL) {
return -ENOMEM;
}
@@ -110,9 +110,8 @@ void radeon_gart_table_ram_free(struct radeon_device *rdev)
  rdev->gart.table_size >> PAGE_SHIFT);
}
 #endif
-   pci_free_consistent(rdev->pdev, rdev->gart.table_size,
-   (void *)rdev->gart.ptr,
-   rdev->gart.table_addr);
+   dma_free_coherent(&rdev->pdev->dev, rdev->gart.table_size,
+ (void *)rdev->gart.ptr, rdev->gart.table_addr);
rdev->gart.ptr = NULL;
rdev->gart.table_addr = 0;
 }
-- 
2.25.1

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


[PATCH 4/6] i915: implement vga-switcheroo reprobe() callback

2020-07-27 Thread Daniel Dadap
Add a vga-switcheroo callback for reprobing displays. Use this new
callback to retrain the link on all DP encoders after a mux switch.

Signed-off-by: Daniel Dadap 
---
 drivers/gpu/drm/i915/i915_switcheroo.c | 27 +-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c 
b/drivers/gpu/drm/i915/i915_switcheroo.c
index ed69b5d4a375..fa388de03cf6 100644
--- a/drivers/gpu/drm/i915/i915_switcheroo.c
+++ b/drivers/gpu/drm/i915/i915_switcheroo.c
@@ -7,6 +7,8 @@
 
 #include "i915_drv.h"
 #include "i915_switcheroo.h"
+#include "display/intel_display_types.h"
+#include "display/intel_dp.h"
 
 static void i915_switcheroo_set_state(struct pci_dev *pdev,
  enum vga_switcheroo_state state)
@@ -46,9 +48,32 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
return i915 && atomic_read(&i915->drm.open_count) == 0;
 }
 
+static void i915_switcheroo_reprobe(struct pci_dev *pdev)
+{
+   struct drm_i915_private *i915 = pdev_to_i915(pdev);
+   struct intel_encoder *encoder;
+
+   for_each_intel_dp(&i915->drm, encoder) {
+   int ret = -EDEADLK;
+   struct drm_modeset_acquire_ctx ctx;
+
+   drm_modeset_acquire_init(&ctx, 0);
+
+   while (ret == -EDEADLK) {
+   ret = intel_dp_retrain_link(encoder, &ctx);
+
+   if (ret == -EDEADLK)
+   drm_modeset_backoff(&ctx);
+   }
+
+   drm_modeset_drop_locks(&ctx);
+   drm_modeset_acquire_fini(&ctx);
+   }
+}
+
 static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
.set_gpu_state = i915_switcheroo_set_state,
-   .reprobe = NULL,
+   .reprobe = i915_switcheroo_reprobe,
.can_switch = i915_switcheroo_can_switch,
 };
 
-- 
2.18.4

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


[PATCH 3/6] drm/bridge: Add SPI DBI host driver

2020-07-27 Thread Paul Cercueil
This driver will register a DBI host driver for panels connected over
SPI.

DBI types c1 and c3 are supported. C1 is a SPI protocol with 9 bits per
word, with the data/command information in the 9th (MSB) bit. C3 is a
SPI protocol with 8 bits per word, with the data/command information
carried by a separate GPIO.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/bridge/Kconfig   |   8 +
 drivers/gpu/drm/bridge/Makefile  |   1 +
 drivers/gpu/drm/bridge/dbi-spi.c | 261 +++
 3 files changed, 270 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/dbi-spi.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index c7f0dacfb57a..ed38366847c1 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -219,6 +219,14 @@ config DRM_TI_TPD12S015
  Texas Instruments TPD12S015 HDMI level shifter and ESD protection
  driver.
 
+config DRM_MIPI_DBI_SPI
+   tristate "SPI host support for MIPI DBI"
+   depends on OF && SPI
+   select DRM_MIPI_DSI
+   select DRM_MIPI_DBI
+   help
+ Driver to support DBI over SPI.
+
 source "drivers/gpu/drm/bridge/analogix/Kconfig"
 
 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 7d7c123a95e4..c2c522c2774f 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
 obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
 obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
 obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
+obj-$(CONFIG_DRM_MIPI_DBI_SPI) += dbi-spi.o
 obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
 
 obj-y += analogix/
diff --git a/drivers/gpu/drm/bridge/dbi-spi.c b/drivers/gpu/drm/bridge/dbi-spi.c
new file mode 100644
index ..1060b8f95fba
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dbi-spi.c
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MIPI Display Bus Interface (DBI) SPI support
+ *
+ * Copyright 2016 Noralf Trønnes
+ * Copyright 2020 Paul Cercueil 
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+
+struct dbi_spi {
+   struct mipi_dsi_host host;
+   struct mipi_dsi_host_ops host_ops;
+
+   struct spi_device *spi;
+   struct gpio_desc *dc;
+   struct mutex cmdlock;
+
+   unsigned int current_bus_type;
+
+   /**
+* @tx_buf9: Buffer used for Option 1 9-bit conversion
+*/
+   void *tx_buf9;
+
+   /**
+* @tx_buf9_len: Size of tx_buf9.
+*/
+   size_t tx_buf9_len;
+};
+
+static inline struct dbi_spi *host_to_dbi_spi(struct mipi_dsi_host *host)
+{
+   return container_of(host, struct dbi_spi, host);
+}
+
+static ssize_t dbi_spi1_transfer(struct mipi_dsi_host *host,
+const struct mipi_dsi_msg *msg)
+{
+   struct dbi_spi *dbi = host_to_dbi_spi(host);
+   struct spi_device *spi = dbi->spi;
+   struct spi_transfer tr = {
+   .bits_per_word = 9,
+   };
+   const u8 *src8 = msg->tx_buf;
+   struct spi_message m;
+   size_t max_chunk, chunk;
+   size_t len = msg->tx_len;
+   bool cmd_byte = true;
+   unsigned int i;
+   u16 *dst16;
+   int ret;
+
+   tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len);
+   dst16 = dbi->tx_buf9;
+
+   max_chunk = min(dbi->tx_buf9_len / 2, len);
+
+   spi_message_init_with_transfers(&m, &tr, 1);
+   tr.tx_buf = dst16;
+
+   while (len) {
+   chunk = min(len, max_chunk);
+
+   for (i = 0; i < chunk; i++) {
+   dst16[i] = *src8++;
+
+   /* Bit 9: 0 means command, 1 means data */
+   if (!cmd_byte)
+   dst16[i] |= BIT(9);
+
+   cmd_byte = false;
+   }
+
+   tr.len = chunk * 2;
+   len -= chunk;
+
+   ret = spi_sync(spi, &m);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static ssize_t dbi_spi3_transfer(struct mipi_dsi_host *host,
+const struct mipi_dsi_msg *msg)
+{
+   struct dbi_spi *dbi = host_to_dbi_spi(host);
+   struct spi_device *spi = dbi->spi;
+   const u8 *buf = msg->tx_buf;
+   unsigned int bpw = 8;
+   u32 speed_hz;
+   ssize_t ret;
+
+   /* for now we only support sending messages, not receiving */
+   if (msg->rx_len)
+   return -EINVAL;
+
+   gpiod_set_value_cansleep(dbi->dc, 0);
+
+   speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
+   ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, buf, 1);
+   if (ret || msg->tx_len == 1)
+   return ret;
+
+   if (buf[0] == MIPI_DCS_WRITE_MEMORY_START)
+   bpw = 16;
+
+   gpiod_set_value_cansleep(dbi->dc, 1);
+   speed_hz = mipi_d

[PATCH 2/6] vga-switcheroo: Add a way to test for the active client

2020-07-27 Thread Daniel Dadap
vga-switcheroo clients may wish to know whether they are currently
active, i.e., whether the mux is currently switched to the client
in question. Add an in-kernel API to test whether a vga-switcheroo
client, as identified by PCI device, is actively switched.

Signed-off-by: Daniel Dadap 
---
 drivers/gpu/vga/vga_switcheroo.c | 38 +++-
 include/linux/vga_switcheroo.h   |  2 ++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index cf3c7024dafa..a4fc78c4bf4f 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -99,7 +99,13 @@
  * @id: client identifier. Determining the id requires the handler,
  * so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID
  * and later given their true id in vga_switcheroo_enable()
- * @active: whether the outputs are currently switched to this client
+ * @active: whether the client is currently active: this is unset for the
+ * currently active client before preparing for a mux switch, and set
+ * for the newly active client after completing all post-switch actions.
+ * @switched: whether the outputs are physically switched to the client:
+ * this is unset for the currently switched client immediately before
+ * switching the mux, and set for the newly switched client immediately
+ * after switching the mux.
  * @driver_power_control: whether power state is controlled by the driver's
  * runtime pm. If true, writing ON and OFF to the vga_switcheroo debugfs
  * interface is a no-op so as not to interfere with runtime pm
@@ -117,6 +123,7 @@ struct vga_switcheroo_client {
const struct vga_switcheroo_client_ops *ops;
enum vga_switcheroo_client_id id;
bool active;
+   bool switched;
bool driver_power_control;
struct list_head list;
struct pci_dev *vga_dev;
@@ -306,6 +313,7 @@ static int register_client(struct pci_dev *pdev,
client->ops = ops;
client->id = id;
client->active = active;
+   client->switched = active;
client->driver_power_control = driver_power_control;
client->vga_dev = vga_dev;
 
@@ -748,11 +756,13 @@ static int vga_switchto_stage2(struct 
vga_switcheroo_client *new_client,
if (new_client->fb_info)
fbcon_remap_all(new_client->fb_info);
 
+   active->switched = false;
mutex_lock(&vgasr_priv.mux_hw_lock);
ret = vgasr_priv.handler->switchto(new_client->id);
mutex_unlock(&vgasr_priv.mux_hw_lock);
if (ret)
return ret;
+   new_client->switched = true;
 
if (new_client->ops->reprobe)
new_client->ops->reprobe(new_client->pdev);
@@ -,3 +1121,29 @@ void vga_switcheroo_fini_domain_pm_ops(struct device 
*dev)
dev_pm_domain_set(dev, NULL);
 }
 EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
+
+/**
+ * vga_switcheroo_is_client_active() - test if a device is the active client
+ * @pdev: vga client device
+ *
+ * Check whether the mux is switched to the switcheroo client associated with
+ * the given PCI device. Assumes that mux is always switched to the device in
+ * question when switcheroo is inactive, and that the mux is switched away if
+ * no matching client is registered.
+ */
+bool vga_switcheroo_is_client_active(struct pci_dev *pdev)
+{
+   if (vgasr_priv.active) {
+   struct vga_switcheroo_client *client;
+
+   client = find_client_from_pci(&vgasr_priv.clients, pdev);
+
+   if (client)
+   return client->switched;
+   else
+   return false;
+   } else {
+   return true;
+   }
+}
+EXPORT_SYMBOL(vga_switcheroo_is_client_active);
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 7e6ac0114d55..63e6d6e5786e 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -173,6 +173,7 @@ enum vga_switcheroo_state 
vga_switcheroo_get_client_state(struct pci_dev *dev);
 
 int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain 
*domain);
 void vga_switcheroo_fini_domain_pm_ops(struct device *dev);
+bool vga_switcheroo_is_client_active(struct pci_dev *pdev);
 #else
 
 static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
@@ -194,6 +195,7 @@ static inline enum vga_switcheroo_state 
vga_switcheroo_get_client_state(struct p
 
 static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct 
dev_pm_domain *domain) { return -EINVAL; }
 static inline void vga_switcheroo_fini_domain_pm_ops(struct device *dev) {}
+static inline bool vga_switcheroo_is_client_active(struct pci_dev *pdev) { 
return true; }
 
 #endif
 #endif /* _LINUX_VGA_SWITCHEROO_H_ */
-- 
2.18.4

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

[PATCH 2/6] drm: dsi: Let host and device specify supported bus

2020-07-27 Thread Paul Cercueil
The current MIPI DSI framework can very well be used to support MIPI DBI
panels. In order to add support for the various bus types supported by
DBI, the DRM panel drivers should specify the bus type they will use,
and the DSI host drivers should specify the bus types they are
compatible with.

The DSI host driver can then use the information provided by the DBI/DSI
device driver, such as the bus type and the number of lanes, to
configure its hardware properly.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/drm_mipi_dsi.c |  9 +
 include/drm/drm_mipi_dsi.h | 12 
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 5dd475e82995..11ef885de765 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -281,6 +281,9 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
struct device_node *node;
 
+   if (WARN_ON_ONCE(!host->bus_types))
+   host->bus_types = MIPI_DEVICE_TYPE_DSI;
+
for_each_available_child_of_node(host->dev->of_node, node) {
/* skip nodes without reg property */
if (!of_find_property(node, "reg", NULL))
@@ -323,6 +326,12 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi)
 {
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
 
+   if (WARN_ON_ONCE(!dsi->bus_type))
+   dsi->bus_type = MIPI_DEVICE_TYPE_DSI;
+
+   if (!(dsi->bus_type & dsi->host->bus_types))
+   return -EINVAL;
+
if (!ops || !ops->attach)
return -ENOSYS;
 
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 360e6377e84b..65d2961fc054 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -63,6 +63,14 @@ struct mipi_dsi_packet {
 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
   const struct mipi_dsi_msg *msg);
 
+/* MIPI bus types */
+#define MIPI_DEVICE_TYPE_DSI   BIT(0)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE1 BIT(1)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE2 BIT(2)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE3 BIT(3)
+#define MIPI_DEVICE_TYPE_DBI_M6800 BIT(4)
+#define MIPI_DEVICE_TYPE_DBI_I8080 BIT(5)
+
 /**
  * struct mipi_dsi_host_ops - DSI bus operations
  * @attach: attach DSI device to DSI host
@@ -94,11 +102,13 @@ struct mipi_dsi_host_ops {
  * struct mipi_dsi_host - DSI host device
  * @dev: driver model device node for this DSI host
  * @ops: DSI host operations
+ * @bus_types: Bitmask of supported MIPI bus types
  * @list: list management
  */
 struct mipi_dsi_host {
struct device *dev;
const struct mipi_dsi_host_ops *ops;
+   unsigned int bus_types;
struct list_head list;
 };
 
@@ -162,6 +172,7 @@ struct mipi_dsi_device_info {
  * @host: DSI host for this peripheral
  * @dev: driver model device node for this peripheral
  * @name: DSI peripheral chip type
+ * @bus_type: MIPI bus type (MIPI_DEVICE_TYPE_DSI/...)
  * @channel: virtual channel assigned to the peripheral
  * @format: pixel format for video mode
  * @lanes: number of active data lanes
@@ -178,6 +189,7 @@ struct mipi_dsi_device {
struct device dev;
 
char name[DSI_DEV_NAME_SIZE];
+   unsigned int bus_type;
unsigned int channel;
unsigned int lanes;
enum mipi_dsi_pixel_format format;
-- 
2.27.0

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


[PATCH 6/6] i915: bail out of eDP link training while mux-switched away

2020-07-27 Thread Daniel Dadap
It is not possible to train a Displayport link while the lanes are
physically disconnected by a display mux. In order to prevent problems
associated with attempting to train a disconnected link, abort eDP
link training if the i915 GPU is not an active vga-switcheroo client.
This short circuit is eDP-specific, as normal DP (e.g. for external
displays) should be able to detect that the link is not physically
connected, while eDP is usually assumed to be always connected.

Signed-off-by: Daniel Dadap 
---
 drivers/gpu/drm/i915/display/intel_dp_link_training.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index a7defb37ab00..a1c61db8a228 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -24,6 +24,7 @@
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
+#include "linux/vga_switcheroo.h"
 
 static void
 intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE])
@@ -371,6 +372,14 @@ void
 intel_dp_start_link_train(struct intel_dp *intel_dp)
 {
struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct device *dev = dp_to_dig_port(intel_dp)->base.base.dev->dev;
+
+   if (intel_dp_is_edp(intel_dp) &&
+   !vga_switcheroo_is_client_active(to_pci_dev(dev))) {
+   drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
+   "eDP link training not allowed when muxed away.");
+   return;
+   }
 
if (!intel_dp_link_training_clock_recovery(intel_dp))
goto failure_handling;
-- 
2.18.4

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


[PATCH 6/6] drm/panel: Add Ilitek ILI9341 DBI panel driver

2020-07-27 Thread Paul Cercueil
This driver is for the Ilitek ILI9341 based YX240QV29-T 2.4" 240x320 TFT
LCD panel from Adafruit.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/panel/Kconfig|   9 +
 drivers/gpu/drm/panel/Makefile   |   1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 345 +++
 3 files changed, 355 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 6a8a51a702d8..132a42a81895 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -105,6 +105,15 @@ config DRM_PANEL_ILITEK_IL9322
  Say Y here if you want to enable support for Ilitek IL9322
  QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
 
+config DRM_PANEL_ILITEK_ILI9341
+   tristate "Ilitek ILI9341 320x240 QVGA panels"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for Ilitek IL9341
+ QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
+
 config DRM_PANEL_ILITEK_ILI9881C
tristate "Ilitek ILI9881C-based panels"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index a0516ced87db..ad5e6089c3ef 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
 obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
 obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += 
panel-feiyang-fy07024di26a30d.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
new file mode 100644
index ..3af6628639d6
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * DRM driver for Ilitek ILI9341 panels
+ *
+ * Copyright 2018 David Lechner 
+ * Copyright 2020 Paul Cercueil 
+ *
+ * Based on mi0283qt.c:
+ * Copyright 2016 Noralf Trønnes
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define ILI9341_FRMCTR10xb1
+#define ILI9341_DISCTRL0xb6
+#define ILI9341_ETMOD  0xb7
+
+#define ILI9341_PWCTRL10xc0
+#define ILI9341_PWCTRL20xc1
+#define ILI9341_VMCTRL10xc5
+#define ILI9341_VMCTRL20xc7
+#define ILI9341_PWCTRLA0xcb
+#define ILI9341_PWCTRLB0xcf
+
+#define ILI9341_PGAMCTRL   0xe0
+#define ILI9341_NGAMCTRL   0xe1
+#define ILI9341_DTCTRLA0xe8
+#define ILI9341_DTCTRLB0xea
+#define ILI9341_PWRSEQ 0xed
+
+#define ILI9341_EN3GAM 0xf2
+#define ILI9341_PUMPCTRL   0xf7
+
+#define ILI9341_MADCTL_BGR BIT(3)
+#define ILI9341_MADCTL_MV  BIT(5)
+#define ILI9341_MADCTL_MX  BIT(6)
+#define ILI9341_MADCTL_MY  BIT(7)
+
+struct ili9341_pdata {
+   struct drm_display_mode mode;
+   unsigned int width_mm;
+   unsigned int height_mm;
+   unsigned int bus_type;
+   unsigned int lanes;
+};
+
+struct ili9341 {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   const struct ili9341_pdata *pdata;
+
+   struct gpio_desc*reset_gpiod;
+   struct backlight_device *backlight;
+   u32 rotation;
+};
+
+#define mipi_dcs_command(dsi, cmd, seq...) \
+({ \
+   u8 d[] = { seq }; \
+   mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \
+})
+
+static inline struct ili9341 *panel_to_ili9341(struct drm_panel *panel)
+{
+   return container_of(panel, struct ili9341, panel);
+}
+
+static int ili9341_prepare(struct drm_panel *panel)
+{
+   struct ili9341 *priv = panel_to_ili9341(panel);
+   struct mipi_dsi_device *dsi = priv->dsi;
+   u8 addr_mode;
+   int ret;
+
+   gpiod_set_value_cansleep(priv->reset_gpiod, 0);
+   usleep_range(20, 1000);
+   gpiod_set_value_cansleep(priv->reset_gpiod, 1);
+   msleep(120);
+
+   ret = mipi_dcs_command(dsi, MIPI_DCS_SOFT_RESET);
+   if (ret) {
+   dev_err(panel->dev, "Failed to send reset command: %d\n", ret);
+   return ret;
+   }
+
+   /* Wait 5ms after soft reset per MIPI DCS spec */
+   usleep_range(5000, 2);
+
+   mipi_dcs_command(dsi, MIPI_DCS_SET_DISPLAY_OFF);
+
+   mipi_dcs_command(dsi, ILI9341_PWCTRLB, 0x00, 0xc1, 0x30);
+   mipi_dcs_command(dsi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12,

[PATCH 1/6] vga-switcheroo: add new "immediate" switch event type

2020-07-27 Thread Daniel Dadap
vga-switcheroo supports the following types of mux switch events:

* standard: checks the clients' can_switch() callbacks and switches
  the mux if the client drivers report that they are prepared for a
  switch. Also uses client and handler callbacks to manage power on
  the GPUs and reprobe display outputs.
* deferred: registers the intent to perform a mux switch and defers
  it until the client drivers no longer have any active modesetting
  clients. Performs the equivalent of a standard switch when clients
  are ready.
* mux-only: switches the mux immediately without testing can_switch
  first and without calling any of the client or handler callbacks
  for power management and reprobing.

In order to support additional use cases involving dynamic switching
of display muxes, add a new type of "immediate" switch event which
skips the can_switch test and power management hooks, but still calls
the reprobe hook. This switch event type uses 'I' as a prefix for its
commands, similar to the existing 'D' pefix for the deferred commands
and 'M' for the mux-only commands.

Signed-off-by: Daniel Dadap 
---
 drivers/gpu/vga/vga_switcheroo.c | 86 +---
 1 file changed, 58 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 087304b1a5d7..cf3c7024dafa 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -631,16 +631,23 @@ EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
  * * DDIS: Delayed switch to the discrete graphics device.
  * * MIGD: Mux-only switch to the integrated graphics device.
  *   Does not remap console or change the power state of either gpu.
+ *   Does not call into any client-supplied callbacks, e.g. reprobe.
  *   If the integrated GPU is currently off, the screen will turn black.
  *   If it is on, the screen will show whatever happens to be in VRAM.
  *   Either way, the user has to blindly enter the command to switch back.
  * * MDIS: Mux-only switch to the discrete graphics device.
+ * * IIGD: Immediate switch to the integrated graphics device.
+ *   Does not test for active user space processes utilizing the device
+ *   files of the GPU or audio device. Does not change the power state of
+ *   either gpu. The console is remapped and client-provided callbacks
+ *   such as reprobe are called.
+ *  * IDIS: Immediate switch to the discrete graphics device.
  *
  * For GPUs whose power state is controlled by the driver's runtime pm,
  * the ON and OFF commands are a no-op (see next section).
  *
- * For muxless machines, the IGD/DIS, DIGD/DDIS and MIGD/MDIS commands
- * should not be used.
+ * For muxless machines, the IGD/DIS, DIGD/DDIS, MIGD/MDIS and IIGD/IDIS
+ * commands should not be used.
  */
 
 static int vga_switcheroo_show(struct seq_file *m, void *v)
@@ -704,7 +711,8 @@ static void set_audio_state(enum vga_switcheroo_client_id 
id,
 }
 
 /* stage one happens before delay */
-static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
+static int vga_switchto_stage1(struct vga_switcheroo_client *new_client,
+  bool power_control)
 {
struct vga_switcheroo_client *active;
 
@@ -712,7 +720,8 @@ static int vga_switchto_stage1(struct vga_switcheroo_client 
*new_client)
if (!active)
return 0;
 
-   if (vga_switcheroo_pwr_state(new_client) == VGA_SWITCHEROO_OFF)
+   if (power_control &&
+   vga_switcheroo_pwr_state(new_client) == VGA_SWITCHEROO_OFF)
vga_switchon(new_client);
 
vga_set_default_device(new_client->pdev);
@@ -720,7 +729,8 @@ static int vga_switchto_stage1(struct vga_switcheroo_client 
*new_client)
 }
 
 /* post delay */
-static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
+static int vga_switchto_stage2(struct vga_switcheroo_client *new_client,
+  bool power_control)
 {
int ret;
struct vga_switcheroo_client *active;
@@ -747,7 +757,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client 
*new_client)
if (new_client->ops->reprobe)
new_client->ops->reprobe(new_client->pdev);
 
-   if (vga_switcheroo_pwr_state(active) == VGA_SWITCHEROO_ON)
+   if (power_control &&
+   vga_switcheroo_pwr_state(active) == VGA_SWITCHEROO_ON)
vga_switchoff(active);
 
/* let HDA controller autoresume if GPU uses driver power control */
@@ -779,6 +790,7 @@ vga_switcheroo_debugfs_write(struct file *filp, const char 
__user *ubuf,
int ret;
bool delay = false, can_switch;
bool just_mux = false;
+   bool immediate_switch = false;
enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
struct vga_switcheroo_client *client = NULL;
 
@@ -822,30 +834,48 @@ vga_switcheroo_debugfs_write(struct file *filp, const 
char __user *ubuf,
goto out;
}
 
-   /* request a dela

Re: [PATCH 1/6] dt-bindings: display: Document NewVision NV3052C DT node

2020-07-27 Thread Maarten ter Huurne
On Monday, 27 July 2020 21:10:52 CEST Sam Ravnborg wrote:
> > +description: |
> > +  This is a driver for 320x240 TFT panels,
> 
> The binding describes the HW, not the driver. So please re-phrase this
> part.
> 
> This datasheet:
> https://www.phoenixdisplay.com/wp-content/uploads/2019/05/NV3052C-Dat
> asheet-V0.2.pdf tells that the driver supports additional resoltions.
> I guess the 320x240 resolution is limited to the leadtek panel.

The word "driver" is overloaded ;)

I guess "driver IC" would make it clearer.

Bye,
Maarten



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


Re: [PATCH 1/9] clk: qcom: gcc-sdm660: Add missing modem reset

2020-07-27 Thread Konrad Dybcio
Fixes: f2a76a2955c0 (clk: qcom: Add Global Clock controller (GCC)
driver for SDM660)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 3/6] drm/bridge: Add SPI DBI host driver

2020-07-27 Thread Paul Cercueil

Hi Laurent,

Le lun. 27 juil. 2020 à 20:06, Laurent Pinchart 
 a écrit :

Hi Paul,

Thank you for the patch.

On Mon, Jul 27, 2020 at 06:46:10PM +0200, Paul Cercueil wrote:
 This driver will register a DBI host driver for panels connected 
over

 SPI.

 DBI types c1 and c3 are supported. C1 is a SPI protocol with 9 bits 
per
 word, with the data/command information in the 9th (MSB) bit. C3 is 
a

 SPI protocol with 8 bits per word, with the data/command information
 carried by a separate GPIO.

 Signed-off-by: Paul Cercueil 
 ---
  drivers/gpu/drm/bridge/Kconfig   |   8 +
  drivers/gpu/drm/bridge/Makefile  |   1 +
  drivers/gpu/drm/bridge/dbi-spi.c | 261 
+++

  3 files changed, 270 insertions(+)
  create mode 100644 drivers/gpu/drm/bridge/dbi-spi.c

 diff --git a/drivers/gpu/drm/bridge/Kconfig 
b/drivers/gpu/drm/bridge/Kconfig

 index c7f0dacfb57a..ed38366847c1 100644
 --- a/drivers/gpu/drm/bridge/Kconfig
 +++ b/drivers/gpu/drm/bridge/Kconfig
 @@ -219,6 +219,14 @@ config DRM_TI_TPD12S015
  	  Texas Instruments TPD12S015 HDMI level shifter and ESD 
protection

  driver.

 +config DRM_MIPI_DBI_SPI
 +  tristate "SPI host support for MIPI DBI"
 +  depends on OF && SPI
 +  select DRM_MIPI_DSI
 +  select DRM_MIPI_DBI
 +  help
 +Driver to support DBI over SPI.
 +
  source "drivers/gpu/drm/bridge/analogix/Kconfig"

  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
 diff --git a/drivers/gpu/drm/bridge/Makefile 
b/drivers/gpu/drm/bridge/Makefile

 index 7d7c123a95e4..c2c522c2774f 100644
 --- a/drivers/gpu/drm/bridge/Makefile
 +++ b/drivers/gpu/drm/bridge/Makefile
 @@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
  obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
  obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 +obj-$(CONFIG_DRM_MIPI_DBI_SPI) += dbi-spi.o
  obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o

  obj-y += analogix/
 diff --git a/drivers/gpu/drm/bridge/dbi-spi.c 
b/drivers/gpu/drm/bridge/dbi-spi.c

 new file mode 100644
 index ..1060b8f95fba
 --- /dev/null
 +++ b/drivers/gpu/drm/bridge/dbi-spi.c
 @@ -0,0 +1,261 @@
 +// SPDX-License-Identifier: GPL-2.0-or-later
 +/*
 + * MIPI Display Bus Interface (DBI) SPI support
 + *
 + * Copyright 2016 Noralf Trønnes
 + * Copyright 2020 Paul Cercueil 
 + */
 +
 +#include 
 +#include 
 +#include 
 +
 +#include 
 +#include 
 +
 +#include 
 +
 +struct dbi_spi {
 +  struct mipi_dsi_host host;
 +  struct mipi_dsi_host_ops host_ops;
 +
 +  struct spi_device *spi;
 +  struct gpio_desc *dc;
 +  struct mutex cmdlock;
 +
 +  unsigned int current_bus_type;
 +
 +  /**
 +   * @tx_buf9: Buffer used for Option 1 9-bit conversion
 +   */
 +  void *tx_buf9;
 +
 +  /**
 +   * @tx_buf9_len: Size of tx_buf9.
 +   */
 +  size_t tx_buf9_len;
 +};
 +
 +static inline struct dbi_spi *host_to_dbi_spi(struct mipi_dsi_host 
*host)

 +{
 +  return container_of(host, struct dbi_spi, host);
 +}
 +
 +static ssize_t dbi_spi1_transfer(struct mipi_dsi_host *host,
 +   const struct mipi_dsi_msg *msg)
 +{
 +  struct dbi_spi *dbi = host_to_dbi_spi(host);
 +  struct spi_device *spi = dbi->spi;
 +  struct spi_transfer tr = {
 +  .bits_per_word = 9,
 +  };
 +  const u8 *src8 = msg->tx_buf;
 +  struct spi_message m;
 +  size_t max_chunk, chunk;
 +  size_t len = msg->tx_len;
 +  bool cmd_byte = true;
 +  unsigned int i;
 +  u16 *dst16;
 +  int ret;
 +
 +  tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len);
 +  dst16 = dbi->tx_buf9;
 +
 +  max_chunk = min(dbi->tx_buf9_len / 2, len);
 +
 +  spi_message_init_with_transfers(&m, &tr, 1);
 +  tr.tx_buf = dst16;
 +
 +  while (len) {
 +  chunk = min(len, max_chunk);
 +
 +  for (i = 0; i < chunk; i++) {
 +  dst16[i] = *src8++;
 +
 +  /* Bit 9: 0 means command, 1 means data */
 +  if (!cmd_byte)
 +  dst16[i] |= BIT(9);
 +
 +  cmd_byte = false;
 +  }
 +
 +  tr.len = chunk * 2;
 +  len -= chunk;
 +
 +  ret = spi_sync(spi, &m);
 +  if (ret)
 +  return ret;
 +  }
 +
 +  return 0;
 +}
 +
 +static ssize_t dbi_spi3_transfer(struct mipi_dsi_host *host,
 +   const struct mipi_dsi_msg *msg)
 +{
 +  struct dbi_spi *dbi = host_to_dbi_spi(host);
 +  struct spi_device *spi = dbi->spi;
 +  const u8 *buf = msg->tx_buf;
 +  unsigned int bpw = 8;
 +  u32 speed_hz;
 +  ssize_t ret;
 +
 +  /* for now we only support sending messages, not receiving */
 +  if (msg->rx_len)
 +  return -EINVAL;
 +
 +  gpiod_set_value_cansleep(dbi->dc, 0);
 +
 +  speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
 +  ret

Re: [Freedreno] [PATCH V2] drm: hold gem reference until object is no longer accessed

2020-07-27 Thread cohens

On 2020-07-27 16:11, dan...@ffwll.ch wrote:

On Mon, Jul 27, 2020 at 09:55:07PM +0200, Greg KH wrote:

On Mon, Jul 20, 2020 at 06:30:50PM -0400, Steve Cohen wrote:
> A use-after-free in drm_gem_open_ioctl can happen if the
> GEM object handle is closed between the idr lookup and
> retrieving the size from said object since a local reference
> is not being held at that point. Hold the local reference
> while the object can still be accessed to fix this and
> plug the potential security hole.
>
> Signed-off-by: Steve Cohen 
> ---
>  drivers/gpu/drm/drm_gem.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 7bf628e..ee2058a 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -871,9 +871,6 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
>   * @file_priv: drm file-private structure
>   *
>   * Open an object using the global name, returning a handle and the size.
> - *
> - * This handle (of course) holds a reference to the object, so the object
> - * will not go away until the handle is deleted.
>   */
>  int
>  drm_gem_open_ioctl(struct drm_device *dev, void *data,
> @@ -898,14 +895,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
>
>/* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
>ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
> -  drm_gem_object_put_unlocked(obj);
>if (ret)
> -  return ret;
> +  goto err;
>
>args->handle = handle;
>args->size = obj->size;
>
> -  return 0;
> +err:
> +  drm_gem_object_put_unlocked(obj);
> +  return ret;
>  }
>
>  /**

As this seems to fix an important issue, any reason it wasn't cc: 
stable

on it so that it gets backported properly?

How about a "Fixes:" tag so that we know what commit id it fixes so we
know how far back to backport things?

And a hint to the maintainers that "this is an issue that needs to get
into 5.8-final, it shouldn't wait around longer please" would have 
also

been nice to see :)

And what chagned from v1, aren't you supposed to list that somewhere 
in

the changelog or below the --- line (never remember what DRM drivers
want here...)

Care to send a v3?


Don't worry, I'm pushing this to drm-misc-fixes now, should still make 
it
to 5.8. Plus cc: stable. I didn't bother with Fixes: since I think the 
bug
is rather old. Also, worst case you leak 32bit of some kernel memory 
that
got reused already (but yeah I know that's often enough to get the foot 
in

somewhere nasty and crack the door open).

I think it fell through cracks because Sam said he'll apply, guess that
didn't happen.


Sam added his Reviewed-By on V1 with a comment to rename the goto label,
but in V2 I also updated the API documentation and the commit text for
a more complete change and thought he would re-add the tag.


Also yes a changelog, somewhere, for next time around.


Apologies, it won't happen again. Should I still submit a V3?
It looks like you've got Greg's concerns covered.

-Steve


-Daniel




thanks,

greg k-h

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


Re: [PATCH] drm/sun4i: mixer: Enable register value caching

2020-07-27 Thread Maxime Ripard
Hi,

On Fri, Jul 24, 2020 at 10:35:49PM +0200, Jernej Skrabec wrote:
> It was discovered in the past by Ondrej Jirman that mixer register read
> may occasionally return wrong value, most likely zero. It turns out
> that all mixer units are affected by this issue. This becomes especially
> obvious with applications like video player. After a few minutes of a
> playback visual glitches appeared but not always in the same way. After
> register inspection it was clear that some bits are not set even when
> they should be.

There was a similar issue on the earlier backend stuff, and it turned
out to be because we were accessing registers while the registers
"commit" wasn't completed yet.

It looks that in the DE2, it's the register GLB_DBUFFER that controls it
(offset 0x08). It would be worth looking into whether it happens only
when the bit 0 is still high.

I ended up writing a small program using devmem back then to write a
known value in known to be faulty register and checking it in a tight
loop (and then with a poll on that bit) to see if that fixed it or not.

> Best solution would be to shuffle the code a bit to avoid
> read-modify-write operations and use only register writes. However,
> quicker solution is to enable caching support in regmap which is also
> used here. Such fix is also easier to backport in stable kernels.

It only partially fixes the issue though. None of the volatile registers
would be covered, and this includes GLB_CTL too at least.

Maxime


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


[PATCH 0/6] DBI/DSI, panel drivers, and tinyDRM compat

2020-07-27 Thread Paul Cercueil
Hi,

Here's a follow-up on the previous discussion about the current state of
DSI/DBI panel drivers, TinyDRM, and the need of a cleanup.

For the record, here is a small sum-up of the current situation:

- the current MIPI DBI code (drivers/gpu/drm/drm_mipi_dbi.c) is lagging
  way behind the MIPI DSI code (drivers/gpu/drm/drm_mipi_dsi.c). While
  the DSI code adds a proper bus support, with support for host drivers
  and client devices, there is no such thing with the DBI code. As such,
  it is currently impossible to write a standard DRM panel driver for a
  DBI panel.

- Even if the MIPI DBI code was updated with a proper bus, many panels
  and MIPI controllers support both DSI and DBI, so it would be a pain
  to support them without resolving to duplicating each driver.

- The panel drivers written against the DBI code are all "tinyDRM"
  drivers, which means that they will register a full yet simple DRM
  driver, and cannot be used as regular DRM panels for a different DRM
  driver.

- These "tinyDRM" drivers all use SPI directly, even though the panels
  they're driving can work on other interfaces (e.g. i8080 bus). Which
  means that one driver written for e.g. a ILI9341 would not work if
  the control interface is not SPI.

- The "tinyDRM" common code is entangled with DBI and there is no clear
  separation between the two. It could very well be moved to a single
  "tinyDRM" driver that works with a DRM panel obtained from devicetree,
  because the only requirement is that the panel supports a few given
  DCS commands.

This patchset introduces the following:

* Patch [2/6] slightly tweaks the MIPI DSI code so that it now also
  supports MIPI DBI over various hardware buses. Because if you think
  about it, DSI is just the same as DBI just on a different hardware
  bus. The DSI host drivers, now DSI/DBI host drivers, set compatibility
  bits for the hardware buses they support (DSI, DBI/i8080, DBI/SPI9,
  DBI/SPI+GPIO), which is matched against the hardware bus that panel
  drivers request.

* For the DBI panels connected over SPI, a new DSI/DBI host driver is
  added in patch [3/6]. It allows MIPI DBI panel drivers to be written
  with the DSI/DBI framework, even if they are connected over SPI,
  instead of registering as SPI device drivers. Since most of these
  panels can be connected over various buses, it permits to reuse the
  same driver independently of the bus used.

* Patch [4/6] adds a panel driver for NewVision NV3052C based panels.
  This has been successfully tested on the Anbernic RG350M handheld
  console, along with the dbi-spi bridge and the ingenic-drm driver.

* A TinyDRM driver for DSI/DBI panels, once again independent of the bus
  used; the only dependency (currently) being that the panel must
  understand DCS commands.

* A DRM panel driver to test the stack. This driver controls Ilitek
  ILI9341 based DBI panels, like the Adafruit YX240QV29-T 320x240 2.4"
  TFT LCD panel. This panel was converted from
  drivers/gpu/drm/tiny/ili9341.c.

Patches [1-4] were successfully tested on hardware.
Patches [5-6] were compile-tested and runtime-tested but without
hardware connected, so I'd want a Tested-by on these two.

Another thing to note, is that it does not break Device Tree ABI. The
display node stays the same:

spi {
...

display@0 {
compatible = "adafruit,yx240qv29", "ilitek,ili9341";
reg = <0>;
spi-max-frequency = <3200>;
dc-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
rotation = <270>;
backlight = <&backlight>;
};
};

The reason it works, is that the "adafruit,yx240qv29" device is probed
on the SPI bus, so it will match with the SPI/DBI host driver. This will
in turn register the very same node with the DSI bus, and the ILI9341
DRM panel driver will probe. The driver will detect that no controller
is linked to the panel, and eventually register the DBI/DSI TinyDRM
driver.

One drawback of this approach, is that the "adafruit,yx240qv29" must be
added to the dbi-spi bridge driver (unless a custom rule is added for a
"dbi-spi" fallback compatible string). I still think that it's a small
price to pay to avoid breaking the Device Tree bindings.

Feedback welcome.

Cheers,
-Paul

Paul Cercueil (6):
  dt-bindings: display: Document NewVision NV3052C DT node
  drm: dsi: Let host and device specify supported bus
  drm/bridge: Add SPI DBI host driver
  drm/panel: Add panel driver for NewVision NV3052C based LCDs
  drm/tiny: Add TinyDRM for DSI/DBI panels
  drm/panel: Add Ilitek ILI9341 DBI panel driver

 .../display/panel/newvision,nv3052c.yaml  |  69 +++
 drivers/gpu/drm/bridge/Kconfig|   8 +
 drivers/gpu/drm/bridge/Makefile   |   1 +
 drivers/gpu/drm/bridge/dbi-spi.c  | 262 +
 drivers/gpu/drm/drm_mipi_dsi.c|   9 +
 drivers/gpu/drm/panel/Kconfig  

[PATCH 5/6] drm/tiny: Add TinyDRM for DSI/DBI panels

2020-07-27 Thread Paul Cercueil
The new API function mipi_dsi_maybe_register_tiny_driver() is supposed
to be called by DSI/DBI panel drivers at the end of their probe.

If it is detected that the panel is not connected to any controller,
because it has no port #0 node in Device Tree that points back to it,
then a TinyDRM driver is registered with it.

This TinyDRM driver expects that a DCS-compliant protocol is used by the
DSI/DBI panel and can only be used with these.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/tiny/Kconfig|   8 +
 drivers/gpu/drm/tiny/Makefile   |   1 +
 drivers/gpu/drm/tiny/tiny-dsi.c | 266 
 include/drm/drm_mipi_dsi.h  |  19 +++
 4 files changed, 294 insertions(+)
 create mode 100644 drivers/gpu/drm/tiny/tiny-dsi.c

diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
index 2b6414f0fa75..b62427b88dfe 100644
--- a/drivers/gpu/drm/tiny/Kconfig
+++ b/drivers/gpu/drm/tiny/Kconfig
@@ -28,6 +28,14 @@ config DRM_GM12U320
 This is a KMS driver for projectors which use the GM12U320 chipset
 for video transfer over USB2/3, such as the Acer C120 mini projector.
 
+config TINYDRM_DSI
+   tristate "DRM support for generic DBI/DSI display panels"
+   depends on DRM && DRM_MIPI_DSI
+   select DRM_MIPI_DBI
+   select DRM_KMS_CMA_HELPER
+   help
+ DRM driver for generic DBI/DSI display panels
+
 config TINYDRM_HX8357D
tristate "DRM support for HX8357D display panels"
depends on DRM && SPI
diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile
index 6ae4e9e5a35f..2bfee13347a5 100644
--- a/drivers/gpu/drm/tiny/Makefile
+++ b/drivers/gpu/drm/tiny/Makefile
@@ -2,6 +2,7 @@
 
 obj-$(CONFIG_DRM_CIRRUS_QEMU)  += cirrus.o
 obj-$(CONFIG_DRM_GM12U320) += gm12u320.o
+obj-$(CONFIG_TINYDRM_DSI)  += tiny-dsi.o
 obj-$(CONFIG_TINYDRM_HX8357D)  += hx8357d.o
 obj-$(CONFIG_TINYDRM_ILI9225)  += ili9225.o
 obj-$(CONFIG_TINYDRM_ILI9341)  += ili9341.o
diff --git a/drivers/gpu/drm/tiny/tiny-dsi.c b/drivers/gpu/drm/tiny/tiny-dsi.c
new file mode 100644
index ..b24d49836125
--- /dev/null
+++ b/drivers/gpu/drm/tiny/tiny-dsi.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * TinyDRM driver for standard DSI/DBI panels
+ *
+ * Copyright 2020 Paul Cercueil 
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct tiny_dsi {
+   struct drm_device drm;
+   struct drm_connector connector;
+   struct drm_simple_display_pipe pipe;
+
+   struct mipi_dsi_device *dsi;
+   struct drm_panel *panel;
+};
+
+#define mipi_dcs_command(dsi, cmd, seq...) \
+({ \
+   u8 d[] = { seq }; \
+   mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \
+})
+
+static inline struct tiny_dsi *drm_to_tiny_dsi(struct drm_device *drm)
+{
+   return container_of(drm, struct tiny_dsi, drm);
+}
+
+static void tiny_dsi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect 
*rect)
+{
+   struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+   struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem);
+   struct tiny_dsi *priv = drm_to_tiny_dsi(fb->dev);
+   unsigned int height = rect->y2 - rect->y1;
+   unsigned int width = rect->x2 - rect->x1;
+   bool fb_convert;
+   int idx, ret;
+   void *tr;
+
+   if (!drm_dev_enter(fb->dev, &idx))
+   return;
+
+   DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, 
DRM_RECT_ARG(rect));
+
+   fb_convert = width != fb->width || height != fb->height
+   || fb->format->format == DRM_FORMAT_XRGB;
+   if (fb_convert) {
+   tr = kzalloc(width * height * 2, GFP_KERNEL);
+
+   /* TODO: swap pixels if needed */
+   ret = mipi_dbi_buf_copy(tr, fb, rect, false);
+   if (ret)
+   goto err_msg;
+   } else {
+   tr = cma_obj->vaddr;
+   }
+
+   mipi_dcs_command(priv->dsi, MIPI_DCS_SET_COLUMN_ADDRESS,
+(rect->x1 >> 8) & 0xff, rect->x1 & 0xff,
+(rect->x2 >> 8) & 0xff, rect->x2 & 0xff);
+   mipi_dcs_command(priv->dsi, MIPI_DCS_SET_PAGE_ADDRESS,
+(rect->y1 >> 8) & 0xff, rect->y1 & 0xff,
+(rect->y2 >> 8) & 0xff, rect->y2 & 0xff);
+
+   ret = mipi_dsi_dcs_write(priv->dsi, MIPI_DCS_WRITE_MEMORY_START,
+tr, width * height * 2);
+err_msg:
+   if (ret)
+   dev_err_once(fb->dev->dev, "Failed to update display %d\n", 
ret);
+
+   if (fb_convert)
+   kfree(tr);
+   drm_dev_exit(idx);
+}
+
+static void tiny_dsi_enable(struct drm_simple_display_pipe *pipe,
+   struct drm_crtc_state *crtc_state,
+   stru

Re: [PATCH 3/6] drm/bridge: Add SPI DBI host driver

2020-07-27 Thread Paul Cercueil

Hi Sam,

Le lun. 27 juil. 2020 à 22:31, Sam Ravnborg  a 
écrit :

Hi Paul.

On Mon, Jul 27, 2020 at 06:46:10PM +0200, Paul Cercueil wrote:
 This driver will register a DBI host driver for panels connected 
over

 SPI.

So this is actually a MIPI DBI host driver.

I personally would love to have added mipi_ in the names - to make it
all more explicit.
But maybe that just because I get confused on all the acronyms.


I can rename the driver and move it out of drm/bridge/, no problem.

Some details in the following. Will try to find some more time so I 
can

grasp the full picture. The following was just my low-level notes for
now.

Sam


 DBI types c1 and c3 are supported. C1 is a SPI protocol with 9 bits 
per
 word, with the data/command information in the 9th (MSB) bit. C3 is 
a

 SPI protocol with 8 bits per word, with the data/command information
 carried by a separate GPIO.


We did not have any define to distingush between DBI_C1 and DBI_c3:
+/* MIPI bus types */
+#define MIPI_DEVICE_TYPE_DSI   BIT(0)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE1 BIT(1)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE2 BIT(2)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE3 BIT(3)
+#define MIPI_DEVICE_TYPE_DBI_M6800 BIT(4)
+#define MIPI_DEVICE_TYPE_DBI_I8080 BIT(5)

Is this on purpose?


I understand the confusion. Here SPI_MODE1/3 actually mean SPI_C1/3. I 
will rename them.


I had assumed the host should tell what it supports and the device 
should

tell what it wanted.
So if the host did not support DBI_C3 and device wants it - then we
could give up early.


Well that's exactly what's done here - just with badly named macros :)



 Signed-off-by: Paul Cercueil 
 ---
  drivers/gpu/drm/bridge/Kconfig   |   8 +
  drivers/gpu/drm/bridge/Makefile  |   1 +
  drivers/gpu/drm/bridge/dbi-spi.c | 261 
+++

This is no bridge driver - so does not belong in the bridge
directory.
gpu/drm/drm_mipi_dbi_spi.c?


  3 files changed, 270 insertions(+)
  create mode 100644 drivers/gpu/drm/bridge/dbi-spi.c

 diff --git a/drivers/gpu/drm/bridge/Kconfig 
b/drivers/gpu/drm/bridge/Kconfig

 index c7f0dacfb57a..ed38366847c1 100644
 --- a/drivers/gpu/drm/bridge/Kconfig
 +++ b/drivers/gpu/drm/bridge/Kconfig
 @@ -219,6 +219,14 @@ config DRM_TI_TPD12S015
  	  Texas Instruments TPD12S015 HDMI level shifter and ESD 
protection

  driver.

 +config DRM_MIPI_DBI_SPI
 +  tristate "SPI host support for MIPI DBI"
 +  depends on OF && SPI
 +  select DRM_MIPI_DSI
 +  select DRM_MIPI_DBI
 +  help
 +Driver to support DBI over SPI.
 +
  source "drivers/gpu/drm/bridge/analogix/Kconfig"

  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
 diff --git a/drivers/gpu/drm/bridge/Makefile 
b/drivers/gpu/drm/bridge/Makefile

 index 7d7c123a95e4..c2c522c2774f 100644
 --- a/drivers/gpu/drm/bridge/Makefile
 +++ b/drivers/gpu/drm/bridge/Makefile
 @@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
  obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
  obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 +obj-$(CONFIG_DRM_MIPI_DBI_SPI) += dbi-spi.o

mipi_dbi_spi.o would be nice...


  obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o

  obj-y += analogix/
 diff --git a/drivers/gpu/drm/bridge/dbi-spi.c 
b/drivers/gpu/drm/bridge/dbi-spi.c

 new file mode 100644
 index ..1060b8f95fba
 --- /dev/null
 +++ b/drivers/gpu/drm/bridge/dbi-spi.c
 @@ -0,0 +1,261 @@
 +// SPDX-License-Identifier: GPL-2.0-or-later
 +/*
 + * MIPI Display Bus Interface (DBI) SPI support
 + *
 + * Copyright 2016 Noralf Trønnes
 + * Copyright 2020 Paul Cercueil 
 + */
 +
 +#include 
 +#include 
 +#include 
 +
 +#include 
 +#include 
 +
 +#include 
 +
 +struct dbi_spi {
 +  struct mipi_dsi_host host;

It is very confusing that the mipi_dbi_spi driver uses a dsi_host.
It clashes in my head - and then reviewing it not easy.


From now on read all "mipi_dsi_*" as a MIPI DSI/DBI API. Renaming the 
API means a treewide patchset that touches many many files...





 +  struct mipi_dsi_host_ops host_ops;

const?

 +
 +  struct spi_device *spi;
 +  struct gpio_desc *dc;
 +  struct mutex cmdlock;
 +
 +  unsigned int current_bus_type;
 +
 +  /**
 +   * @tx_buf9: Buffer used for Option 1 9-bit conversion
 +   */
 +  void *tx_buf9;
 +
 +  /**
 +   * @tx_buf9_len: Size of tx_buf9.
 +   */
 +  size_t tx_buf9_len;
 +};
 +
 +static inline struct dbi_spi *host_to_dbi_spi(struct mipi_dsi_host 
*host)

 +{
 +  return container_of(host, struct dbi_spi, host);
 +}
 +
 +static ssize_t dbi_spi1_transfer(struct mipi_dsi_host *host,
 +   const struct mipi_dsi_msg *msg)
 +{
 +  struct dbi_spi *dbi = host_to_dbi_spi(host);
 +  struct spi_device *spi = dbi->spi;
 +  struct spi_transfer tr = {
 +  .bits_per_word = 9,
 +  };
 +  const u8 *src8 = msg->tx_buf;
 +  struct spi_message m;
 +  size_t m

[PATCH 2/2] drm/radeon: avoid a useless memset

2020-07-27 Thread Christophe JAILLET
Avoid a memset after a call to 'dma_alloc_coherent()'.
This is useless since
commit 518a2f1925c3 ("dma-mapping: zero memory returned from dma_alloc_*")

Signed-off-by: Christophe JAILLET 
---
 drivers/gpu/drm/radeon/radeon_gart.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index b7ce254e5663..3808a753127b 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -85,7 +85,6 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev)
}
 #endif
rdev->gart.ptr = ptr;
-   memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size);
return 0;
 }
 
-- 
2.25.1

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


Re: [PATCH v2 4/4] xen: add helpers to allocate unpopulated memory

2020-07-27 Thread Roger Pau Monné
On Fri, Jul 24, 2020 at 12:36:33PM -0400, Boris Ostrovsky wrote:
> On 7/24/20 10:34 AM, David Hildenbrand wrote:
> > CCing Dan
> >
> > On 24.07.20 14:42, Roger Pau Monne wrote:
> >> +
> >> +#include 
> >> +#include 
> >> +#include 
> >> +#include 
> >> +#include 
> >> +#include 
> >> +
> >> +#include 
> >> +
> >> +#include 
> >> +#include 
> >> +
> >> +static DEFINE_MUTEX(lock);
> >> +static LIST_HEAD(list);
> >> +static unsigned int count;
> >> +
> >> +static int fill(unsigned int nr_pages)
> 
> 
> Less generic names? How about  list_lock, pg_list, pg_count,
> fill_pglist()? (But these are bad too, so maybe you can come up with
> something better)

OK, I have to admit I like using such short names when the code allows
to, for example this code is so simple that it didn't seem to warrant
using longer names. Will rename on next version.

> >> +{
> >> +  struct dev_pagemap *pgmap;
> >> +  void *vaddr;
> >> +  unsigned int i, alloc_pages = round_up(nr_pages, PAGES_PER_SECTION);
> >> +  int nid, ret;
> >> +
> >> +  pgmap = kzalloc(sizeof(*pgmap), GFP_KERNEL);
> >> +  if (!pgmap)
> >> +  return -ENOMEM;
> >> +
> >> +  pgmap->type = MEMORY_DEVICE_DEVDAX;
> >> +  pgmap->res.name = "XEN SCRATCH";
> 
> 
> Typically iomem resources only capitalize first letters.
> 
> 
> >> +  pgmap->res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
> >> +
> >> +  ret = allocate_resource(&iomem_resource, &pgmap->res,
> >> +  alloc_pages * PAGE_SIZE, 0, -1,
> >> +  PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL);
> 
> 
> Are we not going to end up with a whole bunch of "Xen scratch" resource
> ranges for each miss in the page list? Or do we expect them to get merged?

PAGES_PER_SECTION is IMO big enough to prevent ending up with a lot of
separated ranges. I think the value is 32 or 64MiB on x86, so while we
are likely to end up with more than one resource added, I don't think
it's going to be massive.

> 
> >> +  if (ret < 0) {
> >> +  pr_err("Cannot allocate new IOMEM resource\n");
> >> +  kfree(pgmap);
> >> +  return ret;
> >> +  }
> >> +
> >> +  nid = memory_add_physaddr_to_nid(pgmap->res.start);
> 
> 
> Should we consider page range crossing node boundaries?

I'm not sure whether this is possible (I would think allocate_resource
should return a range from a single node), but then it would greatly
complicate the code to perform the memremap_pages, as we would have to
split the region into multiple dev_pagemap structs.

FWIW the current code in the balloon driver does exactly the same
(which doesn't mean it's correct, but that's where I got the logic
from).

> >> +
> >> +#ifdef CONFIG_XEN_HAVE_PVMMU
> >> +  /*
> >> +   * We don't support PV MMU when Linux and Xen is using
> >> +   * different page granularity.
> >> +   */
> >> +  BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
> >> +
> >> +/*
> >> + * memremap will build page tables for the new memory so
> >> + * the p2m must contain invalid entries so the correct
> >> + * non-present PTEs will be written.
> >> + *
> >> + * If a failure occurs, the original (identity) p2m entries
> >> + * are not restored since this region is now known not to
> >> + * conflict with any devices.
> >> + */
> >> +  if (!xen_feature(XENFEAT_auto_translated_physmap)) {
> >> +  xen_pfn_t pfn = PFN_DOWN(pgmap->res.start);
> >> +
> >> +  for (i = 0; i < alloc_pages; i++) {
> >> +  if (!set_phys_to_machine(pfn + i, INVALID_P2M_ENTRY)) {
> >> +  pr_warn("set_phys_to_machine() failed, no 
> >> memory added\n");
> >> +  release_resource(&pgmap->res);
> >> +  kfree(pgmap);
> >> +  return -ENOMEM;
> >> +  }
> >> +}
> >> +  }
> >> +#endif
> >> +
> >> +  vaddr = memremap_pages(pgmap, nid);
> >> +  if (IS_ERR(vaddr)) {
> >> +  pr_err("Cannot remap memory range\n");
> >> +  release_resource(&pgmap->res);
> >> +  kfree(pgmap);
> >> +  return PTR_ERR(vaddr);
> >> +  }
> >> +
> >> +  for (i = 0; i < alloc_pages; i++) {
> >> +  struct page *pg = virt_to_page(vaddr + PAGE_SIZE * i);
> >> +
> >> +  BUG_ON(!virt_addr_valid(vaddr + PAGE_SIZE * i));
> >> +  list_add(&pg->lru, &list);
> >> +  count++;
> >> +  }
> >> +
> >> +  return 0;
> >> +}
> >> +
> >> +/**
> >> + * xen_alloc_unpopulated_pages - alloc unpopulated pages
> >> + * @nr_pages: Number of pages
> >> + * @pages: pages returned
> >> + * @return 0 on success, error otherwise
> >> + */
> >> +int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page 
> >> **pages)
> >> +{
> >> +  unsigned int i;
> >> +  int ret = 0;
> >> +
> >> +  mutex_lock(&lock);
> >> +  if (count < nr_pages) {
> >> +  ret = fill(nr_pages);
> 
> 
> (nr_pages - count) ?

Yup, already fixed as Juergen also pointed it out.

> >> +

Re: [PATCH 2/6] drm: dsi: Let host and device specify supported bus

2020-07-27 Thread Paul Cercueil

Hi Laurent,

Le lun. 27 juil. 2020 à 20:02, Laurent Pinchart 
 a écrit :

Hi Paul,

Thank you for the patch.

On Mon, Jul 27, 2020 at 06:46:09PM +0200, Paul Cercueil wrote:
 The current MIPI DSI framework can very well be used to support 
MIPI DBI
 panels. In order to add support for the various bus types supported 
by
 DBI, the DRM panel drivers should specify the bus type they will 
use,

 and the DSI host drivers should specify the bus types they are
 compatible with.

 The DSI host driver can then use the information provided by the 
DBI/DSI

 device driver, such as the bus type and the number of lanes, to
 configure its hardware properly.

 Signed-off-by: Paul Cercueil 
 ---
  drivers/gpu/drm/drm_mipi_dsi.c |  9 +
  include/drm/drm_mipi_dsi.h | 12 


Use the mipi_dsi_* API for DBI panels will be very confusing to say 
the

least. Can we consider a global name refactoring to clarify all this ?


I was thinking that this could be done when the code is cleaned up and 
drivers/gpu/drm/drm_mipi_dbi.c is removed. I'm scared of tree-wide 
patchsets.


-Paul




  2 files changed, 21 insertions(+)

 diff --git a/drivers/gpu/drm/drm_mipi_dsi.c 
b/drivers/gpu/drm/drm_mipi_dsi.c

 index 5dd475e82995..11ef885de765 100644
 --- a/drivers/gpu/drm/drm_mipi_dsi.c
 +++ b/drivers/gpu/drm/drm_mipi_dsi.c
 @@ -281,6 +281,9 @@ int mipi_dsi_host_register(struct mipi_dsi_host 
*host)

  {
struct device_node *node;

 +  if (WARN_ON_ONCE(!host->bus_types))
 +  host->bus_types = MIPI_DEVICE_TYPE_DSI;
 +
for_each_available_child_of_node(host->dev->of_node, node) {
/* skip nodes without reg property */
if (!of_find_property(node, "reg", NULL))
 @@ -323,6 +326,12 @@ int mipi_dsi_attach(struct mipi_dsi_device 
*dsi)

  {
const struct mipi_dsi_host_ops *ops = dsi->host->ops;

 +  if (WARN_ON_ONCE(!dsi->bus_type))
 +  dsi->bus_type = MIPI_DEVICE_TYPE_DSI;
 +
 +  if (!(dsi->bus_type & dsi->host->bus_types))
 +  return -EINVAL;
 +
if (!ops || !ops->attach)
return -ENOSYS;

 diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
 index 360e6377e84b..65d2961fc054 100644
 --- a/include/drm/drm_mipi_dsi.h
 +++ b/include/drm/drm_mipi_dsi.h
 @@ -63,6 +63,14 @@ struct mipi_dsi_packet {
  int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
   const struct mipi_dsi_msg *msg);

 +/* MIPI bus types */
 +#define MIPI_DEVICE_TYPE_DSI  BIT(0)
 +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE1BIT(1)
 +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE2BIT(2)
 +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE3BIT(3)
 +#define MIPI_DEVICE_TYPE_DBI_M6800BIT(4)
 +#define MIPI_DEVICE_TYPE_DBI_I8080BIT(5)
 +
  /**
   * struct mipi_dsi_host_ops - DSI bus operations
   * @attach: attach DSI device to DSI host
 @@ -94,11 +102,13 @@ struct mipi_dsi_host_ops {
   * struct mipi_dsi_host - DSI host device
   * @dev: driver model device node for this DSI host
   * @ops: DSI host operations
 + * @bus_types: Bitmask of supported MIPI bus types
   * @list: list management
   */
  struct mipi_dsi_host {
struct device *dev;
const struct mipi_dsi_host_ops *ops;
 +  unsigned int bus_types;
struct list_head list;
  };

 @@ -162,6 +172,7 @@ struct mipi_dsi_device_info {
   * @host: DSI host for this peripheral
   * @dev: driver model device node for this peripheral
   * @name: DSI peripheral chip type
 + * @bus_type: MIPI bus type (MIPI_DEVICE_TYPE_DSI/...)
   * @channel: virtual channel assigned to the peripheral
   * @format: pixel format for video mode
   * @lanes: number of active data lanes
 @@ -178,6 +189,7 @@ struct mipi_dsi_device {
struct device dev;

char name[DSI_DEV_NAME_SIZE];
 +  unsigned int bus_type;
unsigned int channel;
unsigned int lanes;
enum mipi_dsi_pixel_format format;


--
Regards,

Laurent Pinchart



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


Re: [PATCH 8/9] clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk

2020-07-27 Thread Konrad Dybcio
>Fixes tag?

Can I add it here? I supose I can.

Fixes: f2a76a2955c0 (clk: qcom: Add Global Clock controller (GCC)
driver for SDM660)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 0/6] vga-switcheroo: initial dynamic mux switch support

2020-07-27 Thread Daniel Dadap
Changes to allow vga-switcheroo to switch the mux while modesetting
clients remain active. There is existing support for switching the
mux without checking can_switch; however, this support also does not
reprobe after the mux switch is complete. This patch series adds a new
type of switch event which switches immediately while still calling
client driver callbacks, and updates the i915 DRM-KMS driver to reprobe
eDP outputs after switching the mux to an i915-driven GPU, and to avoid
using eDP links (which i915 always assumes to be connected) while the
mux is switched away.

Daniel Dadap (6):
  vga-switcheroo: add new "immediate" switch event type
  vga-switcheroo: Add a way to test for the active client
  vga-switcheroo: notify clients of pending/completed switch events
  i915: implement vga-switcheroo reprobe() callback
  i915: fail atomic commit when muxed away
  i915: bail out of eDP link training while mux-switched away

 drivers/gpu/drm/i915/display/intel_display.c  |   7 +
 .../drm/i915/display/intel_dp_link_training.c |   9 ++
 drivers/gpu/drm/i915/i915_switcheroo.c|  27 +++-
 drivers/gpu/vga/vga_switcheroo.c  | 153 ++
 include/linux/vga_switcheroo.h|  20 +++
 5 files changed, 185 insertions(+), 31 deletions(-)

-- 
2.18.4

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


[PATCH v3 4/4] xen: add helpers to allocate unpopulated memory

2020-07-27 Thread Roger Pau Monne
To be used in order to create foreign mappings. This is based on the
ZONE_DEVICE facility which is used by persistent memory devices in
order to create struct pages and kernel virtual mappings for the IOMEM
areas of such devices. Note that on kernels without support for
ZONE_DEVICE Xen will fallback to use ballooned pages in order to
create foreign mappings.

The newly added helpers use the same parameters as the existing
{alloc/free}_xenballooned_pages functions, which allows for in-place
replacement of the callers. Once a memory region has been added to be
used as scratch mapping space it will no longer be released, and pages
returned are kept in a linked list. This allows to have a buffer of
pages and prevents resorting to frequent additions and removals of
regions.

If enabled (because ZONE_DEVICE is supported) the usage of the new
functionality untangles Xen balloon and RAM hotplug from the usage of
unpopulated physical memory ranges to map foreign pages, which is the
correct thing to do in order to avoid mappings of foreign pages depend
on memory hotplug.

Signed-off-by: Roger Pau Monné 
---
I've not added a new memory_type type and just used
MEMORY_DEVICE_DEVDAX which seems to be what we want for such memory
regions. I'm unsure whether abusing this type is fine, or if I should
instead add a specific type, maybe MEMORY_DEVICE_GENERIC? I don't
think we should be using a specific Xen type at all.
---
Cc: Oleksandr Andrushchenko 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Boris Ostrovsky 
Cc: Juergen Gross 
Cc: Stefano Stabellini 
Cc: Dan Carpenter 
Cc: Roger Pau Monne 
Cc: Wei Liu 
Cc: Yan Yankovskyi 
Cc: dri-devel@lists.freedesktop.org
Cc: xen-de...@lists.xenproject.org
Cc: linux...@kvack.org
Cc: David Hildenbrand 
Cc: Michal Hocko 
Cc: Dan Williams 
---
Changes since v2:
 - Drop BUILD_BUG_ON regarding PVMMU page sizes.
 - Use a SPDX license identifier.
 - Call fill with only the minimum required number of pages.
 - Include xen.h header in xen_drm_front_gem.c.
 - Use less generic function names.
 - Exit early from the init function if not a PV guest.
 - Don't use all caps for region name.
---
 drivers/gpu/drm/xen/xen_drm_front_gem.c |   9 +-
 drivers/xen/Makefile|   1 +
 drivers/xen/balloon.c   |   4 +-
 drivers/xen/grant-table.c   |   4 +-
 drivers/xen/privcmd.c   |   4 +-
 drivers/xen/unpopulated-alloc.c | 185 
 drivers/xen/xenbus/xenbus_client.c  |   6 +-
 drivers/xen/xlate_mmu.c |   4 +-
 include/xen/xen.h   |   9 ++
 9 files changed, 211 insertions(+), 15 deletions(-)
 create mode 100644 drivers/xen/unpopulated-alloc.c

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c 
b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e094111..270e1bd3e4da 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -18,6 +18,7 @@
 #include 
 
 #include 
+#include 
 
 #include "xen_drm_front.h"
 #include "xen_drm_front_gem.h"
@@ -99,8 +100,8 @@ static struct xen_gem_object *gem_create(struct drm_device 
*dev, size_t size)
 * allocate ballooned pages which will be used to map
 * grant references provided by the backend
 */
-   ret = alloc_xenballooned_pages(xen_obj->num_pages,
-  xen_obj->pages);
+   ret = xen_alloc_unpopulated_pages(xen_obj->num_pages,
+ xen_obj->pages);
if (ret < 0) {
DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",
  xen_obj->num_pages, ret);
@@ -152,8 +153,8 @@ void xen_drm_front_gem_free_object_unlocked(struct 
drm_gem_object *gem_obj)
} else {
if (xen_obj->pages) {
if (xen_obj->be_alloc) {
-   free_xenballooned_pages(xen_obj->num_pages,
-   xen_obj->pages);
+   xen_free_unpopulated_pages(xen_obj->num_pages,
+  xen_obj->pages);
gem_free_pages_array(xen_obj);
} else {
drm_gem_put_pages(&xen_obj->base,
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0d322f3d90cd..788a5d9c8ef0 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -42,3 +42,4 @@ xen-gntdev-$(CONFIG_XEN_GNTDEV_DMABUF)+= 
gntdev-dmabuf.o
 xen-gntalloc-y := gntalloc.o
 xen-privcmd-y  := privcmd.o privcmd-buf.o
 obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF)+= xen-front-pgdir-shbuf.o
+obj-$(CONFIG_ZONE_DEVICE)  += unpopulated-alloc.o
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index b1d8b028bf80..815ef10eb2ff 100644
--- a/dr

Re: divide error in fbcon_switch

2020-07-27 Thread syzbot
syzbot suspects this issue was fixed by commit:

commit ce684552a266cb1c7cc2f7e623f38567adec6653
Author: Tetsuo Handa 
Date:   Sun Jul 12 11:10:12 2020 +

vt: Reject zero-sized screen buffer size.

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=155549c490
start commit:   76bb8b05 Merge tag 'kbuild-v5.5' of git://git.kernel.org/p..
git tree:   upstream
kernel config:  https://syzkaller.appspot.com/x/.config?x=dd226651cb0f364b
dashboard link: https://syzkaller.appspot.com/bug?extid=13013adc4a234406c29e
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=17d69aeae0
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=13fdcc2ae0

If the result looks correct, please mark the issue as fixed by replying with:

#syz fix: vt: Reject zero-sized screen buffer size.

For information about bisection process see: https://goo.gl/tpsmEJ#bisection
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/6] dt-bindings: display: Document NewVision NV3052C DT node

2020-07-27 Thread Paul Cercueil
Add documentation for the Device Tree node for LCD panels based on the
NewVision NV3052C controller.

Signed-off-by: Paul Cercueil 
---
 .../display/panel/newvision,nv3052c.yaml  | 69 +++
 1 file changed, 69 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml 
b/Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml
new file mode 100644
index ..751a28800fc2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/newvision,nv3052c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NewVision NV3052C TFT LCD panel driver with SPI control bus
+
+maintainers:
+  - Paul Cercueil 
+
+description: |
+  This is a driver for 320x240 TFT panels, accepting a variety of input
+  streams that get adapted and scaled to the panel. The panel output has
+  960 TFT source driver pins and 240 TFT gate driver pins, VCOM, VCOML and
+  VCOMH outputs.
+
+  The panel must obey the rules for a SPI slave device as specified in
+  spi/spi-controller.yaml
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+items:
+  - enum:
+- leadtek,ltk035c5444t-spi
+
+  - const: newvision,nv3052c
+
+  reg:
+maxItems: 1
+
+  reset-gpios: true
+  port: true
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+spi {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  display@0 {
+compatible = "leadtek,ltk035c5444t-spi", "newvision,nv3052c";
+reg = <0>;
+
+spi-max-frequency = <1500>;
+spi-3wire;
+reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>;
+backlight = <&backlight>;
+power-supply = <&vcc>;
+
+port {
+  panel_input: endpoint {
+  remote-endpoint = <&panel_output>;
+  };
+};
+  };
+};
+
+...
-- 
2.27.0

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


Re: [PATCH 8/9] clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk

2020-07-27 Thread Stephen Boyd
Quoting Konrad Dybcio (2020-07-26 04:12:05)
> Add missing halt_check, hwcg_reg and hwcg_bit properties.
> These were likely omitted when porting the driver upstream.
> 
> Signed-off-by: Konrad Dybcio 
> ---

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


Re: [PATCH 1/9] clk: qcom: gcc-sdm660: Add missing modem reset

2020-07-27 Thread Stephen Boyd
Quoting Konrad Dybcio (2020-07-26 04:11:58)
> This will be required in order to support the
> modem upstream.
> 
> Signed-off-by: Konrad Dybcio 
> ---

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


Re: [PATCH v5 1/5] drm/i915: Add enable/disable flip done and flip done handler

2020-07-27 Thread Daniel Vetter
On Mon, Jul 27, 2020 at 2:27 PM Michel Dänzer  wrote:
>
> On 2020-07-25 1:26 a.m., Paulo Zanoni wrote:
> > Em seg, 2020-07-20 às 17:01 +0530, Karthik B S escreveu:
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_irq.c 
> >> b/drivers/gpu/drm/i915/i915_irq.c
> >> index 1fa67700d8f4..95953b393941 100644
> >> --- a/drivers/gpu/drm/i915/i915_irq.c
> >> +++ b/drivers/gpu/drm/i915/i915_irq.c
> >> @@ -697,14 +697,24 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
> >>  return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xff;
> >>  }
> >>
> >> +static u32 g4x_get_flip_counter(struct drm_crtc *crtc)
> >> +{
> >> +struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> >> +enum pipe pipe = to_intel_crtc(crtc)->pipe;
> >> +
> >> +return I915_READ(PIPE_FLIPCOUNT_G4X(pipe));
> >> +}
> >> +
> >>  u32 g4x_get_vblank_counter(struct drm_crtc *crtc)
> >>  {
> >>  struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> >>  enum pipe pipe = to_intel_crtc(crtc)->pipe;
> >>
> >> +if (crtc->state->async_flip)
> >> +return g4x_get_flip_counter(crtc);
> >> +
> >>  return I915_READ(PIPE_FRMCOUNT_G4X(pipe));
> >
> > I don't understand the intention behind this, can you please clarify?
> > This goes back to my reply of the cover letter. It seems that here
> > we're going to alternate between two different counters in our vblank
> > count. So if user space alternates between sometimes using async flips
> > and sometimes using normal flip it's going to get some very weird
> > deltas, isn't it? At least this is what I remember from when I played
> > with these registers: FLIPCOUNT drifts away from FRMCOUNT when we start
> > using async flips.
>
> This definitely looks wrong. The counter value returned by the
> get_vblank_counter hook is supposed to increment when a vertical blank
> period occurs; page flips are not supposed to affect this in any way.

Also you just flat out can't access crtc->state from interrupt
context. Anything you need in there needs to be protected by the right
irq-type spin_lock, updates correctly synchronized against both the
interrupt handler and atomic updates, and data copied over, not
pointers. Otherwise just crash&burn.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Daniel Vetter
On Mon, Jul 27, 2020 at 11:11 PM Mazin Rezk  wrote:
>
> On Monday, July 27, 2020 4:29 PM, Daniel Vetter  wrote:
>
> > On Mon, Jul 27, 2020 at 9:28 PM Christian König
> >  wrote:
> > >
> > > Am 27.07.20 um 16:05 schrieb Kazlauskas, Nicholas:
> > > > On 2020-07-27 9:39 a.m., Christian König wrote:
> > > >> Am 27.07.20 um 07:40 schrieb Mazin Rezk:
> > > >>> This patch fixes a race condition that causes a use-after-free during
> > > >>> amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking
> > > >>> commits
> > > >>> are requested and the second one finishes before the first.
> > > >>> Essentially,
> > > >>> this bug occurs when the following sequence of events happens:
> > > >>>
> > > >>> 1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
> > > >>> deferred to the workqueue.
> > > >>>
> > > >>> 2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
> > > >>> deferred to the workqueue.
> > > >>>
> > > >>> 3. Commit #2 starts before commit #1, dm_state #1 is used in the
> > > >>> commit_tail and commit #2 completes, freeing dm_state #1.
> > > >>>
> > > >>> 4. Commit #1 starts after commit #2 completes, uses the freed dm_state
> > > >>> 1 and dereferences a freelist pointer while setting the context.
> > > >>
> > > >> Well I only have a one mile high view on this, but why don't you let
> > > >> the work items execute in order?
> > > >>
> > > >> That would be better anyway cause this way we don't trigger a cache
> > > >> line ping pong between CPUs.
> > > >>
> > > >> Christian.
> > > >
> > > > We use the DRM helpers for managing drm_atomic_commit_state and those
> > > > helpers internally push non-blocking commit work into the system
> > > > unbound work queue.
> > >
> > > Mhm, well if you send those helper atomic commits in the order A,B and
> > > they execute it in the order B,A I would call that a bug :)
> >
> > The way it works is it pushes all commits into unbound work queue, but
> > then forces serialization as needed. We do _not_ want e.g. updates on
> > different CRTC to be serialized, that would result in lots of judder.
> > And hw is funny enough that there's all kinds of dependencies.
> >
> > The way you force synchronization is by adding other CRTC state
> > objects. So if DC is busted and can only handle a single update per
> > work item, then I guess you always need all CRTC states and everything
> > will be run in order. But that also totally kills modern multi-screen
> > compositors. Xorg isn't modern, just in case that's not clear :-)
> >
> > Lucking at the code it seems like you indeed have only a single dm
> > state, so yeah global sync is what you'll need as immediate fix, and
> > then maybe fix up DM to not be quite so silly ... or at least only do
> > the dm state stuff when really needed.
> >
> > We could also sprinkle the drm_crtc_commit structure around a bit
> > (it's the glue that provides the synchronization across commits), but
> > since your dm state is global just grabbing all crtc states
> > unconditionally as part of that is probably best.
> >
> > > > While we could duplicate a copy of that code with nothing but the
> > > > workqueue changed that isn't something I'd really like to maintain
> > > > going forward.
> > >
> > > I'm not talking about duplicating the code, I'm talking about fixing the
> > > helpers. I don't know that code well, but from the outside it sounds
> > > like a bug there.
> > >
> > > And executing work items in the order they are submitted is trivial.
> > >
> > > Had anybody pinged Daniel or other people familiar with the helper code
> > > about it?
> >
> > Yeah something is wrong here, and the fix looks horrible :-)
> >
> > Aside, I've also seen some recent discussion flare up about
> > drm_atomic_state_get/put used to paper over some other use-after-free,
> > but this time related to interrupt handlers. Maybe a few rules about
> > that:
> > - dont
> > - especially not when it's interrupt handlers, because you can't call
> > drm_atomic_state_put from interrupt handlers.
> >
> > Instead have an spin_lock_irq to protect the shared date with your
> > interrupt handler, and _copy_ the date over. This is e.g. what
> > drm_crtc_arm_vblank_event does.
>
> Nicholas wrote a patch that attempted to resolve the issue by adding every
> CRTC into the commit to use use the stall checks. [1] While this forces
> synchronisation on commits, it's kind of a hacky method that may take a
> toll on performance.
>
> Is it possible to have a DRM helper that forces synchronisation on some
> commits without having to add every CRTC into the commit?
>
> Also, is synchronisation really necessary for fast updates in amdgpu?
> I'll admit, the idea of eliminating the use-after-free bug by eliminating
> the use entirely doesn't seem ideal; but is forcing synchronisation on
> these updates that much better?

Well clearing the dc_state pointer here and then allocating another
one in atomic_commit_tail also looks fishy. The proper fix is probably
a lot mo

[PATCH] drm/amdgpu/dc: Stop dma_resv_lock inversion in commit_tail

2020-07-27 Thread Daniel Vetter
Trying to grab dma_resv_lock while in commit_tail before we've done
all the code that leads to the eventual signalling of the vblank event
(which can be a dma_fence) is deadlock-y. Don't do that.

Here the solution is easy because just grabbing locks to read
something races anyway. We don't need to bother, READ_ONCE is
equivalent. And avoids the locking issue.

v2: Also take into account tmz_surface boolean, plus just delete the
old code.

Cc: linux-me...@vger.kernel.org
Cc: linaro-mm-...@lists.linaro.org
Cc: linux-r...@vger.kernel.org
Cc: amd-...@lists.freedesktop.org
Cc: intel-...@lists.freedesktop.org
Cc: Chris Wilson 
Cc: Maarten Lankhorst 
Cc: Christian König 
Signed-off-by: Daniel Vetter 
---
DC-folks, I think this split out patch from my series here

https://lore.kernel.org/dri-devel/20200707201229.472834-1-daniel.vet...@ffwll.ch/

should be ready for review/merging. I fixed it up a bit so that it's not
just a gross hack :-)

Cheers, Daniel


---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 21ec64fe5527..a20b62b1f2ef 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6959,20 +6959,13 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
DRM_ERROR("Waiting for fences timed out!");
 
/*
-* TODO This might fail and hence better not used, wait
-* explicitly on fences instead
-* and in general should be called for
-* blocking commit to as per framework helpers
+* We cannot reserve buffers here, which means the normal flag
+* access functions don't work. Paper over this with READ_ONCE,
+* but maybe the flags are invariant enough that not even that
+* would be needed.
 */
-   r = amdgpu_bo_reserve(abo, true);
-   if (unlikely(r != 0))
-   DRM_ERROR("failed to reserve buffer before flip\n");
-
-   amdgpu_bo_get_tiling_flags(abo, &tiling_flags);
-
-   tmz_surface = amdgpu_bo_encrypted(abo);
-
-   amdgpu_bo_unreserve(abo);
+   tiling_flags = READ_ONCE(abo->tiling_flags);
+   tmz_surface = READ_ONCE(abo->flags) & 
AMDGPU_GEM_CREATE_ENCRYPTED;
 
fill_dc_plane_info_and_addr(
dm->adev, new_plane_state, tiling_flags,
-- 
2.27.0

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


Re: [PATCH 1/3] drm: Restore driver.preclose() for all to use

2020-07-27 Thread Sasha Levin
Hi

[This is an automated email]

This commit has been processed because it contains a -stable tag.
The stable tag indicates that it's relevant for the following trees: 4.12+

The bot has tested the following trees: v5.7.10, v5.4.53, v4.19.134, v4.14.189.

v5.7.10: Build OK!
v5.4.53: Build OK!
v4.19.134: Build OK!
v4.14.189: Failed to apply! Possible dependencies:
112ed2d31a46 ("drm/i915: Move GraphicsTechnology files under gt/")
1572042a4ab2 ("drm: provide management functions for drm_file")
7a2c65dd32b1 ("drm: Release filp before global lock")
7e13ad896484 ("drm: Avoid drm_global_mutex for simple inc/dec of 
dev->open_count")
b46a33e271ed ("drm/i915/pmu: Expose a PMU interface for perf queries")
c2400ec3b6d1 ("drm/i915: add Makefile magic for testing headers are 
self-contained")
cc662126b413 ("drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET")
e7af3116836f ("drm/i915: Introduce a preempt context")
f0e4a0639752 ("drm/i915: Move GEM domain management to its own file")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

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


Re: [PATCH 3/3] drm/i915/gem: Serialise debugfs i915_gem_objects with ctx->mutex

2020-07-27 Thread Sasha Levin
Hi

[This is an automated email]

This commit has been processed because it contains a -stable tag.
The stable tag indicates that it's relevant for the following trees: all

The bot has tested the following trees: v5.7.10, v5.4.53, v4.19.134, v4.14.189, 
v4.9.231, v4.4.231.

v5.7.10: Build OK!
v5.4.53: Failed to apply! Possible dependencies:
061489c65ff5 ("drm/i915/dsb: single register write function for DSB.")
11988e393813 ("drm/i915/execlists: Try rearranging breadcrumb flush")
2850748ef876 ("drm/i915: Pull i915_vma_pin under the vm->mutex")
5a90606df7cb ("drm/i915: Replace obj->pin_global with obj->frontbuffer")
67f3b58f3bac ("drm/i915/dsb: DSB context creation.")
8a9a982767b7 ("drm/i915: use a separate context for gpu relocs")
a4e7ccdac38e ("drm/i915: Move context management under GEM")
b27a96ad72fd ("drm/i915/dsb: Indexed register write function for DSB.")
bb120e1171a9 ("drm/i915: Show the logical context ring state on dumping")
c210e85b8f33 ("drm/i915/tgl: Extend MI_SEMAPHORE_WAIT")
d19d71fc2b15 ("drm/i915: Mark i915_request.timeline as a volatile, rcu 
pointer")
e8f6b4952ec5 ("drm/i915/execlists: Flush the post-sync breadcrumb write 
harder")

v4.19.134: Failed to apply! Possible dependencies:
0258404f9d38 ("drm/i915: start moving runtime device info to a separate 
struct")
026844460743 ("drm/i915: Remove intel_context.active_link")
07d805721938 ("drm/i915: Introduce intel_runtime_pm_disable to pair 
intel_runtime_pm_enable")
13f1bfd3b332 ("drm/i915: Make object/vma allocation caches global")
1c71bc565cdb ("drm/i915/perf: simplify configure all context function")
2cc8376fd350 ("drm/i915: rename dev_priv info to __info to avoid usage")
2cd9a689e97b ("drm/i915: Refactor intel_display_set_init_power() logic")
37d7c9cc2eb6 ("drm/i915: Check engine->default_state mapping on module 
load")
55ac5a1614f9 ("drm/i915: Attach the pci match data to the device upon 
creation")
666424abfb86 ("drm/i915/execlists: Use coherent writes into the context 
image")
6dfc4a8f134f ("drm/i915: Verify power domains after enabling them")
722f3de39e03 ("i915/oa: Simplify updating contexts")
900ccf30f9e1 ("drm/i915: Only force GGTT coherency w/a on required 
chipsets")
c4d52feb2c46 ("drm/i915: Move over to intel_context_lookup()")
f6e8aa387171 ("drm/i915: Report the number of closed vma held by each 
context in debugfs")
fa9f668141f4 ("drm/i915: Export intel_context_instance()")

v4.14.189: Failed to apply! Possible dependencies:
3bd4073524fa ("drm/i915: Consolidate get_fence with pin_fence")
465c403cb508 ("drm/i915: introduce simple gemfs")
66df1014efba ("drm/i915: Keep a small stash of preallocated WC pages")
67b48040255b ("drm/i915: Assert that the handle->vma lut is empty on object 
close")
73ebd503034c ("drm/i915: make mappable struct resource centric")
7789422665f5 ("drm/i915: make dsm struct resource centric")
82ad6443a55e ("drm/i915/gtt: Rename i915_hw_ppgtt base member")
969b0950a188 ("drm/i915: Add interface to reserve fence registers for vGPU")
a65adaf8a834 ("drm/i915: Track user GTT faulting per-vma")
b4563f595ed4 ("drm/i915: Pin fence for iomap")
e91ef99b9543 ("drm/i915/selftests: Remember to create the fake preempt 
context")
f6e8aa387171 ("drm/i915: Report the number of closed vma held by each 
context in debugfs")
f773568b6ff8 ("drm/i915: nuke the duplicated stolen discovery")

v4.9.231: Failed to apply! Possible dependencies:
0e70447605f4 ("drm/i915: Move common code out of i915_gpu_error.c")
1b36595ffb35 ("drm/i915: Show RING registers through debugfs")
28a60dee2ce6 ("drm/i915/gvt: vGPU HW resource management")
3b3f1650b1ca ("drm/i915: Allocate intel_engine_cs structure only for the 
enabled engines")
82ad6443a55e ("drm/i915/gtt: Rename i915_hw_ppgtt base member")
85fd4f58d7ef ("drm/i915: Mark all non-vma being inserted into the address 
spaces")
9c870d03674f ("drm/i915: Use RPM as the barrier for controlling user mmap 
access")
bb6dc8d96b68 ("drm/i915: Implement pread without struct-mutex")
d636951ec01b ("drm/i915: Cleanup instdone collection")
e007b19d7ba7 ("drm/i915: Use the MRU stack search after evicting")
f6e8aa387171 ("drm/i915: Report the number of closed vma held by each 
context in debugfs")
f9e613728090 ("drm/i915: Try to print INSTDONE bits for all slice/subslice")

v4.4.231: Failed to apply! Possible dependencies:
1b683729e7ac ("drm/i915: Remove redundant check in i915_gem_obj_to_vma")
1c7f4bca5a6f ("drm/i915: Rename vma->*_list to *_link for consistency")
3272db53136f ("drm/i915: Combine all i915_vma bitfields into a single set 
of flags")
596c5923197b ("drm/i915: Reduce the pointer dance of i915_is_ggtt()")
c1a415e261aa ("drm/i915: Disable shrinker for non-swapped backed objects")
d0710abbcd88 ("drm/i915: Set the map-and-fenceable flag for preallocated 
objects")
 

Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Daniel Vetter
On Mon, Jul 27, 2020 at 10:29 PM Daniel Vetter  wrote:
>
> On Mon, Jul 27, 2020 at 9:28 PM Christian König
>  wrote:
> >
> > Am 27.07.20 um 16:05 schrieb Kazlauskas, Nicholas:
> > > On 2020-07-27 9:39 a.m., Christian König wrote:
> > >> Am 27.07.20 um 07:40 schrieb Mazin Rezk:
> > >>> This patch fixes a race condition that causes a use-after-free during
> > >>> amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking
> > >>> commits
> > >>> are requested and the second one finishes before the first.
> > >>> Essentially,
> > >>> this bug occurs when the following sequence of events happens:
> > >>>
> > >>> 1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
> > >>> deferred to the workqueue.
> > >>>
> > >>> 2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
> > >>> deferred to the workqueue.
> > >>>
> > >>> 3. Commit #2 starts before commit #1, dm_state #1 is used in the
> > >>> commit_tail and commit #2 completes, freeing dm_state #1.
> > >>>
> > >>> 4. Commit #1 starts after commit #2 completes, uses the freed dm_state
> > >>> 1 and dereferences a freelist pointer while setting the context.
> > >>
> > >> Well I only have a one mile high view on this, but why don't you let
> > >> the work items execute in order?
> > >>
> > >> That would be better anyway cause this way we don't trigger a cache
> > >> line ping pong between CPUs.
> > >>
> > >> Christian.
> > >
> > > We use the DRM helpers for managing drm_atomic_commit_state and those
> > > helpers internally push non-blocking commit work into the system
> > > unbound work queue.
> >
> > Mhm, well if you send those helper atomic commits in the order A,B and
> > they execute it in the order B,A I would call that a bug :)
>
> The way it works is it pushes all commits into unbound work queue, but
> then forces serialization as needed. We do _not_ want e.g. updates on
> different CRTC to be serialized, that would result in lots of judder.
> And hw is funny enough that there's all kinds of dependencies.
>
> The way you force synchronization is by adding other CRTC state
> objects. So if DC is busted and can only handle a single update per
> work item, then I guess you always need all CRTC states and everything
> will be run in order. But that also totally kills modern multi-screen
> compositors. Xorg isn't modern, just in case that's not clear :-)
>
> Lucking at the code it seems like you indeed have only a single dm
> state, so yeah global sync is what you'll need as immediate fix, and
> then maybe fix up DM to not be quite so silly ... or at least only do
> the dm state stuff when really needed.

Just looked a bit more at this struct dc_state, and that looks a lot
like an atomic side-wagon. I don't think that works as a private
state, this should probably be embedded into a subclass of
drm_atomic_state.

And probably a lot of these pointers moved to other places I think, or
I'm not entirely clear on what exactly this stuff is needed for ...

dc_state is also refcounted, which is definitely rather funny for a
state structure.

Feels like this entire thing (how the overall dc state machinery is
glued into atomic) isn't quite thought thru just yet :-/
-Daniel

> We could also sprinkle the drm_crtc_commit structure around a bit
> (it's the glue that provides the synchronization across commits), but
> since your dm state is global just grabbing all crtc states
> unconditionally as part of that is probably best.
>
> > > While we could duplicate a copy of that code with nothing but the
> > > workqueue changed that isn't something I'd really like to maintain
> > > going forward.
> >
> > I'm not talking about duplicating the code, I'm talking about fixing the
> > helpers. I don't know that code well, but from the outside it sounds
> > like a bug there.
> >
> > And executing work items in the order they are submitted is trivial.
> >
> > Had anybody pinged Daniel or other people familiar with the helper code
> > about it?
>
> Yeah something is wrong here, and the fix looks horrible :-)
>
> Aside, I've also seen some recent discussion flare up about
> drm_atomic_state_get/put used to paper over some other use-after-free,
> but this time related to interrupt handlers. Maybe a few rules about
> that:
> - dont
> - especially not when it's interrupt handlers, because you can't call
> drm_atomic_state_put from interrupt handlers.
>
> Instead have an spin_lock_irq to protect the shared date with your
> interrupt handler, and _copy_ the date over. This is e.g. what
> drm_crtc_arm_vblank_event does.
>
> Cheers, Daniel
>
> >
> > Regards,
> > Christian.
> >
> > >
> > > Regards,
> > > Nicholas Kazlauskas
> > >
> > >>
> > >>>
> > >>> Since this bug has only been spotted with fast commits, this patch
> > >>> fixes
> > >>> the bug by clearing the dm_state instead of using the old dc_state for
> > >>> fast updates. In addition, since dm_state is only used for its dc_state
> > >>> and amdgpu_dm_atomic_commit_tail will retain the dc_state if none is
>

Re: [PATCH v3 1/2] dt-bindings: display: panel: Add bindings for Tianma nt36672a panel

2020-07-27 Thread Rob Herring
On Mon, 27 Jul 2020 13:13:47 +0530, Sumit Semwal wrote:
> The nt36672a panel from Tianma is a FHD+ panel with a resolution of
> 1080x2246 and 6.18 inches size. It is found in some of the Poco F1
> phones.
> 
> Signed-off-by: Sumit Semwal 
> 
> ---
> v2: remove ports node, making port@0 directly under panel@0 node.
> v3: updated to replace port@0 to just 'port'.
> ---
>  .../display/panel/tianma,nt36672a.yaml| 95 +++
>  1 file changed, 95 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/panel/tianma,nt36672a.yaml
> 

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


Re: [PATCH 3/6] drm/bridge: Add SPI DBI host driver

2020-07-27 Thread Sam Ravnborg
Hi Paul.

On Mon, Jul 27, 2020 at 06:46:10PM +0200, Paul Cercueil wrote:
> This driver will register a DBI host driver for panels connected over
> SPI.
So this is actually a MIPI DBI host driver.

I personally would love to have added mipi_ in the names - to make it
all more explicit.
But maybe that just because I get confused on all the acronyms.


Some details in the following. Will try to find some more time so I can
grasp the full picture. The following was just my low-level notes for
now.

Sam
> 
> DBI types c1 and c3 are supported. C1 is a SPI protocol with 9 bits per
> word, with the data/command information in the 9th (MSB) bit. C3 is a
> SPI protocol with 8 bits per word, with the data/command information
> carried by a separate GPIO.

We did not have any define to distingush between DBI_C1 and DBI_c3:
+/* MIPI bus types */
+#define MIPI_DEVICE_TYPE_DSI   BIT(0)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE1 BIT(1)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE2 BIT(2)
+#define MIPI_DEVICE_TYPE_DBI_SPI_MODE3 BIT(3)
+#define MIPI_DEVICE_TYPE_DBI_M6800 BIT(4)
+#define MIPI_DEVICE_TYPE_DBI_I8080 BIT(5)

Is this on purpose?
I had assumed the host should tell what it supports and the device should
tell what it wanted.
So if the host did not support DBI_C3 and device wants it - then we
could give up early.

> 
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/bridge/Kconfig   |   8 +
>  drivers/gpu/drm/bridge/Makefile  |   1 +
>  drivers/gpu/drm/bridge/dbi-spi.c | 261 +++
This is no bridge driver - so does not belong in the bridge
directory.
gpu/drm/drm_mipi_dbi_spi.c?

>  3 files changed, 270 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/dbi-spi.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index c7f0dacfb57a..ed38366847c1 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -219,6 +219,14 @@ config DRM_TI_TPD12S015
> Texas Instruments TPD12S015 HDMI level shifter and ESD protection
> driver.
>  
> +config DRM_MIPI_DBI_SPI
> + tristate "SPI host support for MIPI DBI"
> + depends on OF && SPI
> + select DRM_MIPI_DSI
> + select DRM_MIPI_DBI
> + help
> +   Driver to support DBI over SPI.
> +
>  source "drivers/gpu/drm/bridge/analogix/Kconfig"
>  
>  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 7d7c123a95e4..c2c522c2774f 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
>  obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
>  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
>  obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
> +obj-$(CONFIG_DRM_MIPI_DBI_SPI) += dbi-spi.o
mipi_dbi_spi.o would be nice...

>  obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
>  
>  obj-y += analogix/
> diff --git a/drivers/gpu/drm/bridge/dbi-spi.c 
> b/drivers/gpu/drm/bridge/dbi-spi.c
> new file mode 100644
> index ..1060b8f95fba
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dbi-spi.c
> @@ -0,0 +1,261 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * MIPI Display Bus Interface (DBI) SPI support
> + *
> + * Copyright 2016 Noralf Trønnes
> + * Copyright 2020 Paul Cercueil 
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +struct dbi_spi {
> + struct mipi_dsi_host host;
It is very confusing that the mipi_dbi_spi driver uses a dsi_host.
It clashes in my head - and then reviewing it not easy.

> + struct mipi_dsi_host_ops host_ops;
const?
> +
> + struct spi_device *spi;
> + struct gpio_desc *dc;
> + struct mutex cmdlock;
> +
> + unsigned int current_bus_type;
> +
> + /**
> +  * @tx_buf9: Buffer used for Option 1 9-bit conversion
> +  */
> + void *tx_buf9;
> +
> + /**
> +  * @tx_buf9_len: Size of tx_buf9.
> +  */
> + size_t tx_buf9_len;
> +};
> +
> +static inline struct dbi_spi *host_to_dbi_spi(struct mipi_dsi_host *host)
> +{
> + return container_of(host, struct dbi_spi, host);
> +}
> +
> +static ssize_t dbi_spi1_transfer(struct mipi_dsi_host *host,
> +  const struct mipi_dsi_msg *msg)
> +{
> + struct dbi_spi *dbi = host_to_dbi_spi(host);
> + struct spi_device *spi = dbi->spi;
> + struct spi_transfer tr = {
> + .bits_per_word = 9,
> + };
> + const u8 *src8 = msg->tx_buf;
> + struct spi_message m;
> + size_t max_chunk, chunk;
> + size_t len = msg->tx_len;
> + bool cmd_byte = true;
> + unsigned int i;
> + u16 *dst16;
> + int ret;
> +
> + tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len);
> + dst16 = dbi->tx_buf9;
> +
> + max_chunk = min(dbi->tx_buf9_len / 2, len);
Hmm, this looks not right. We limit the max_chunk to 8K here.
We learned the other day th

Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Daniel Vetter
On Mon, Jul 27, 2020 at 9:28 PM Christian König
 wrote:
>
> Am 27.07.20 um 16:05 schrieb Kazlauskas, Nicholas:
> > On 2020-07-27 9:39 a.m., Christian König wrote:
> >> Am 27.07.20 um 07:40 schrieb Mazin Rezk:
> >>> This patch fixes a race condition that causes a use-after-free during
> >>> amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking
> >>> commits
> >>> are requested and the second one finishes before the first.
> >>> Essentially,
> >>> this bug occurs when the following sequence of events happens:
> >>>
> >>> 1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
> >>> deferred to the workqueue.
> >>>
> >>> 2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
> >>> deferred to the workqueue.
> >>>
> >>> 3. Commit #2 starts before commit #1, dm_state #1 is used in the
> >>> commit_tail and commit #2 completes, freeing dm_state #1.
> >>>
> >>> 4. Commit #1 starts after commit #2 completes, uses the freed dm_state
> >>> 1 and dereferences a freelist pointer while setting the context.
> >>
> >> Well I only have a one mile high view on this, but why don't you let
> >> the work items execute in order?
> >>
> >> That would be better anyway cause this way we don't trigger a cache
> >> line ping pong between CPUs.
> >>
> >> Christian.
> >
> > We use the DRM helpers for managing drm_atomic_commit_state and those
> > helpers internally push non-blocking commit work into the system
> > unbound work queue.
>
> Mhm, well if you send those helper atomic commits in the order A,B and
> they execute it in the order B,A I would call that a bug :)

The way it works is it pushes all commits into unbound work queue, but
then forces serialization as needed. We do _not_ want e.g. updates on
different CRTC to be serialized, that would result in lots of judder.
And hw is funny enough that there's all kinds of dependencies.

The way you force synchronization is by adding other CRTC state
objects. So if DC is busted and can only handle a single update per
work item, then I guess you always need all CRTC states and everything
will be run in order. But that also totally kills modern multi-screen
compositors. Xorg isn't modern, just in case that's not clear :-)

Lucking at the code it seems like you indeed have only a single dm
state, so yeah global sync is what you'll need as immediate fix, and
then maybe fix up DM to not be quite so silly ... or at least only do
the dm state stuff when really needed.

We could also sprinkle the drm_crtc_commit structure around a bit
(it's the glue that provides the synchronization across commits), but
since your dm state is global just grabbing all crtc states
unconditionally as part of that is probably best.

> > While we could duplicate a copy of that code with nothing but the
> > workqueue changed that isn't something I'd really like to maintain
> > going forward.
>
> I'm not talking about duplicating the code, I'm talking about fixing the
> helpers. I don't know that code well, but from the outside it sounds
> like a bug there.
>
> And executing work items in the order they are submitted is trivial.
>
> Had anybody pinged Daniel or other people familiar with the helper code
> about it?

Yeah something is wrong here, and the fix looks horrible :-)

Aside, I've also seen some recent discussion flare up about
drm_atomic_state_get/put used to paper over some other use-after-free,
but this time related to interrupt handlers. Maybe a few rules about
that:
- dont
- especially not when it's interrupt handlers, because you can't call
drm_atomic_state_put from interrupt handlers.

Instead have an spin_lock_irq to protect the shared date with your
interrupt handler, and _copy_ the date over. This is e.g. what
drm_crtc_arm_vblank_event does.

Cheers, Daniel

>
> Regards,
> Christian.
>
> >
> > Regards,
> > Nicholas Kazlauskas
> >
> >>
> >>>
> >>> Since this bug has only been spotted with fast commits, this patch
> >>> fixes
> >>> the bug by clearing the dm_state instead of using the old dc_state for
> >>> fast updates. In addition, since dm_state is only used for its dc_state
> >>> and amdgpu_dm_atomic_commit_tail will retain the dc_state if none is
> >>> found,
> >>> removing the dm_state should not have any consequences in fast updates.
> >>>
> >>> This use-after-free bug has existed for a while now, but only caused a
> >>> noticeable issue starting from 5.7-rc1 due to 3202fa62f ("slub:
> >>> relocate
> >>> freelist pointer to middle of object") moving the freelist pointer from
> >>> dm_state->base (which was unused) to dm_state->context (which is
> >>> dereferenced).
> >>>
> >>> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=207383
> >>> Fixes: bd200d190f45 ("drm/amd/display: Don't replace the dc_state
> >>> for fast updates")
> >>> Reported-by: Duncan <1i5t5.dun...@cox.net>
> >>> Signed-off-by: Mazin Rezk 
> >>> ---
> >>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36
> >>> ++-
> >>>   1 file changed, 27 insertions(+), 9 deletions

Re: [PATCH V2] drm: hold gem reference until object is no longer accessed

2020-07-27 Thread daniel
On Mon, Jul 27, 2020 at 09:55:07PM +0200, Greg KH wrote:
> On Mon, Jul 20, 2020 at 06:30:50PM -0400, Steve Cohen wrote:
> > A use-after-free in drm_gem_open_ioctl can happen if the
> > GEM object handle is closed between the idr lookup and
> > retrieving the size from said object since a local reference
> > is not being held at that point. Hold the local reference
> > while the object can still be accessed to fix this and
> > plug the potential security hole.
> > 
> > Signed-off-by: Steve Cohen 
> > ---
> >  drivers/gpu/drm/drm_gem.c | 10 --
> >  1 file changed, 4 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> > index 7bf628e..ee2058a 100644
> > --- a/drivers/gpu/drm/drm_gem.c
> > +++ b/drivers/gpu/drm/drm_gem.c
> > @@ -871,9 +871,6 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
> >   * @file_priv: drm file-private structure
> >   *
> >   * Open an object using the global name, returning a handle and the size.
> > - *
> > - * This handle (of course) holds a reference to the object, so the object
> > - * will not go away until the handle is deleted.
> >   */
> >  int
> >  drm_gem_open_ioctl(struct drm_device *dev, void *data,
> > @@ -898,14 +895,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
> >  
> > /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
> > ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
> > -   drm_gem_object_put_unlocked(obj);
> > if (ret)
> > -   return ret;
> > +   goto err;
> >  
> > args->handle = handle;
> > args->size = obj->size;
> >  
> > -   return 0;
> > +err:
> > +   drm_gem_object_put_unlocked(obj);
> > +   return ret;
> >  }
> >  
> >  /**
> 
> As this seems to fix an important issue, any reason it wasn't cc: stable
> on it so that it gets backported properly?
> 
> How about a "Fixes:" tag so that we know what commit id it fixes so we
> know how far back to backport things?
> 
> And a hint to the maintainers that "this is an issue that needs to get
> into 5.8-final, it shouldn't wait around longer please" would have also
> been nice to see :)
> 
> And what chagned from v1, aren't you supposed to list that somewhere in
> the changelog or below the --- line (never remember what DRM drivers
> want here...)
> 
> Care to send a v3?

Don't worry, I'm pushing this to drm-misc-fixes now, should still make it
to 5.8. Plus cc: stable. I didn't bother with Fixes: since I think the bug
is rather old. Also, worst case you leak 32bit of some kernel memory that
got reused already (but yeah I know that's often enough to get the foot in
somewhere nasty and crack the door open).

I think it fell through cracks because Sam said he'll apply, guess that
didn't happen.

Also yes a changelog, somewhere, for next time around.
-Daniel


> 
> thanks,
> 
> greg k-h

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


RE: [PATCH 1/3] drm: Restore driver.preclose() for all to use

2020-07-27 Thread Tang, CQ



> -Original Message-
> From: Daniel Vetter 
> Sent: Monday, July 27, 2020 12:33 PM
> To: Chris Wilson ; Dave Airlie 
> Cc: intel-gfx ; stable
> ; Gustavo Padovan
> ; Tang, CQ ; dri-
> devel ; Vetter, Daniel
> 
> Subject: Re: [PATCH 1/3] drm: Restore driver.preclose() for all to use
> 
> On Thu, Jul 23, 2020 at 7:21 PM Chris Wilson 
> wrote:
> >
> > An unfortunate sequence of events, but it turns out there is a valid
> > usecase for being able to free/decouple the driver objects before they
> > are freed by the DRM core. In particular, if we have a pointer into a
> > drm core object from inside a driver object, that pointer needs to be
> > nerfed *before* it is freed so that concurrent access (e.g. debugfs)
> > does not following the dangling pointer.
> >
> > The legacy marker was adding in the code movement from drp_fops.c to
> > drm_file.c
> 
> I might fumble a lot, but not this one:
> 
> commit 45c3d213a400c952ab7119f394c5293bb6877e6b
> Author: Daniel Vetter 
> Date:   Mon May 8 10:26:33 2017 +0200
> 
> drm: Nerf the preclose callback for modern drivers
> 
> Also looking at the debugfs hook that has some rather adventurous stuff
> going on I think, feels a bit like a kitchensink with batteries included. If 
> that's
> really all needed I'd say iterate the contexts by first going over files, 
> then the
> ctx (which arent shared anyway) and the problem should also be gone.

Debugfs code can jump in after drm_gem_release() (where file->object_idr is 
destroyed), but before postclose(). At this window, everything is fine for 
debugfs context accessing except the file->object_idr.

--CQ

> -Daniel
> 
> > References: 9acdac68bcdc ("drm: rename drm_fops.c to drm_file.c")
> > Signed-off-by: Chris Wilson 
> > Cc: Daniel Vetter 
> > Cc: Gustavo Padovan 
> > Cc: CQ Tang 
> > Cc:  # v4.12+
> > ---
> >  drivers/gpu/drm/drm_file.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> > index 0ac4566ae3f4..7b4258d6f7cc 100644
> > --- a/drivers/gpu/drm/drm_file.c
> > +++ b/drivers/gpu/drm/drm_file.c
> > @@ -258,8 +258,7 @@ void drm_file_free(struct drm_file *file)
> >   (long)old_encode_dev(file->minor->kdev->devt),
> >   atomic_read(&dev->open_count));
> >
> > -   if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
> > -   dev->driver->preclose)
> > +   if (dev->driver->preclose)
> > dev->driver->preclose(dev, file);
> >
> > if (drm_core_check_feature(dev, DRIVER_LEGACY))
> > --
> > 2.20.1
> >
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/6] drm: dsi: Let host and device specify supported bus

2020-07-27 Thread Sam Ravnborg
Hi Paul.

On Mon, Jul 27, 2020 at 06:46:09PM +0200, Paul Cercueil wrote:
> The current MIPI DSI framework can very well be used to support MIPI DBI
> panels. In order to add support for the various bus types supported by
> DBI, the DRM panel drivers should specify the bus type they will use,
> and the DSI host drivers should specify the bus types they are
> compatible with.
> 
> The DSI host driver can then use the information provided by the DBI/DSI
> device driver, such as the bus type and the number of lanes, to
> configure its hardware properly.
> 
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c |  9 +
>  include/drm/drm_mipi_dsi.h | 12 
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 5dd475e82995..11ef885de765 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -281,6 +281,9 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  {
>   struct device_node *node;
>  
> + if (WARN_ON_ONCE(!host->bus_types))
> + host->bus_types = MIPI_DEVICE_TYPE_DSI;
> +
So all 14 users need to specify bus_types.
Seems doable.

>   for_each_available_child_of_node(host->dev->of_node, node) {
>   /* skip nodes without reg property */
>   if (!of_find_property(node, "reg", NULL))
> @@ -323,6 +326,12 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi)
>  {
>   const struct mipi_dsi_host_ops *ops = dsi->host->ops;
>  
> + if (WARN_ON_ONCE(!dsi->bus_type))
> + dsi->bus_type = MIPI_DEVICE_TYPE_DSI;
We have ~50 users of mipi_dsi_attach() - doable. But a bit more work.

> +
> + if (!(dsi->bus_type & dsi->host->bus_types))
> + return -EINVAL;
> +
>   if (!ops || !ops->attach)
>   return -ENOSYS;
>  
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 360e6377e84b..65d2961fc054 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -63,6 +63,14 @@ struct mipi_dsi_packet {
>  int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
>  const struct mipi_dsi_msg *msg);
>  
> +/* MIPI bus types */
If you define this as an enum then kernel-doc syntax will be picked up.
See for example: enum drm_driver_feature

> +#define MIPI_DEVICE_TYPE_DSI BIT(0)
> +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE1   BIT(1)
> +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE2   BIT(2)
> +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE3   BIT(3)
> +#define MIPI_DEVICE_TYPE_DBI_M6800   BIT(4)
> +#define MIPI_DEVICE_TYPE_DBI_I8080   BIT(5)
> +
>  /**
>   * struct mipi_dsi_host_ops - DSI bus operations
>   * @attach: attach DSI device to DSI host
> @@ -94,11 +102,13 @@ struct mipi_dsi_host_ops {
>   * struct mipi_dsi_host - DSI host device
>   * @dev: driver model device node for this DSI host
>   * @ops: DSI host operations
> + * @bus_types: Bitmask of supported MIPI bus types
Please add some kind of reference to MIPI_DEVICE_TYPE_* - so the reader
knows for sure this is the bits used here.

>   * @list: list management
>   */
>  struct mipi_dsi_host {
>   struct device *dev;
>   const struct mipi_dsi_host_ops *ops;
> + unsigned int bus_types;
Use u32. Shorter and we know this is 32 bits wide.

>   struct list_head list;
>  };
>  
> @@ -162,6 +172,7 @@ struct mipi_dsi_device_info {
>   * @host: DSI host for this peripheral
>   * @dev: driver model device node for this peripheral
>   * @name: DSI peripheral chip type
> + * @bus_type: MIPI bus type (MIPI_DEVICE_TYPE_DSI/...)
>   * @channel: virtual channel assigned to the peripheral
>   * @format: pixel format for video mode
>   * @lanes: number of active data lanes
> @@ -178,6 +189,7 @@ struct mipi_dsi_device {
>   struct device dev;
>  
>   char name[DSI_DEV_NAME_SIZE];
> + unsigned int bus_type;
Use u32.

>   unsigned int channel;
>   unsigned int lanes;
>   enum mipi_dsi_pixel_format format;
> -- 
> 2.27.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH V2] drm: hold gem reference until object is no longer accessed

2020-07-27 Thread Greg KH
On Mon, Jul 20, 2020 at 06:30:50PM -0400, Steve Cohen wrote:
> A use-after-free in drm_gem_open_ioctl can happen if the
> GEM object handle is closed between the idr lookup and
> retrieving the size from said object since a local reference
> is not being held at that point. Hold the local reference
> while the object can still be accessed to fix this and
> plug the potential security hole.
> 
> Signed-off-by: Steve Cohen 
> ---
>  drivers/gpu/drm/drm_gem.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 7bf628e..ee2058a 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -871,9 +871,6 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
>   * @file_priv: drm file-private structure
>   *
>   * Open an object using the global name, returning a handle and the size.
> - *
> - * This handle (of course) holds a reference to the object, so the object
> - * will not go away until the handle is deleted.
>   */
>  int
>  drm_gem_open_ioctl(struct drm_device *dev, void *data,
> @@ -898,14 +895,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
>  
>   /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
>   ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
> - drm_gem_object_put_unlocked(obj);
>   if (ret)
> - return ret;
> + goto err;
>  
>   args->handle = handle;
>   args->size = obj->size;
>  
> - return 0;
> +err:
> + drm_gem_object_put_unlocked(obj);
> + return ret;
>  }
>  
>  /**

As this seems to fix an important issue, any reason it wasn't cc: stable
on it so that it gets backported properly?

How about a "Fixes:" tag so that we know what commit id it fixes so we
know how far back to backport things?

And a hint to the maintainers that "this is an issue that needs to get
into 5.8-final, it shouldn't wait around longer please" would have also
been nice to see :)

And what chagned from v1, aren't you supposed to list that somewhere in
the changelog or below the --- line (never remember what DRM drivers
want here...)

Care to send a v3?

thanks,

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


Re: [PATCH 1/9] clk: qcom: gcc-sdm660: Add missing modem reset

2020-07-27 Thread Stephen Boyd
Quoting Konrad Dybcio (2020-07-26 04:11:58)
> This will be required in order to support the
> modem upstream.
> 
> Signed-off-by: Konrad Dybcio 
> ---

Should have a fixes tag too.

>  drivers/clk/qcom/gcc-sdm660.c   | 1 +
>  include/dt-bindings/clock/qcom,gcc-sdm660.h | 1 +
>  2 files changed, 2 insertions(+)
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [v6] dt-bindings: msm: disp: add yaml schemas for DPU and DSI bindings

2020-07-27 Thread Rob Herring
On Thu, Jul 16, 2020 at 08:15:28PM +0530, Krishna Manikandan wrote:
> MSM Mobile Display Subsytem (MDSS) encapsulates sub-blocks
> like DPU display controller, DSI etc. Add YAML schema
> for the device tree bindings for the same.
> 
> Signed-off-by: Krishna Manikandan 
> 
> Changes in v2:
> - Changed dpu to DPU (Sam Ravnborg)
> - Fixed indentation issues (Sam Ravnborg)
> - Added empty line between different properties (Sam Ravnborg)
> - Replaced reference txt files with  their corresponding
>   yaml files (Sam Ravnborg)
> - Modified the file to use "|" only when it is
>   necessary (Sam Ravnborg)
> 
> Changes in v3:
> - Corrected the license used (Rob Herring)
> - Added maxItems for properties (Rob Herring)
> - Dropped generic descriptions (Rob Herring)
> - Added ranges property (Rob Herring)
> - Corrected the indendation (Rob Herring)
> - Added additionalProperties (Rob Herring)
> - Split dsi file into two, one for dsi controller
>   and another one for dsi phy per target (Rob Herring)
> - Corrected description for pinctrl-names (Rob Herring)
> - Corrected the examples used in yaml file (Rob Herring)
> - Delete dsi.txt and dpu.txt (Rob Herring)
> 
> Changes in v4:
> - Move schema up by one level (Rob Herring)
> - Add patternProperties for mdp node (Rob Herring)
> - Corrected description of some properties (Rob Herring)
> 
> Changes in v5:
> - Correct the indentation (Rob Herring)
> - Remove unnecessary description from properties (Rob Herring)
> - Correct the number of interconnect entries (Rob Herring)
> - Add interconnect names for sc7180 (Rob Herring)
> - Add description for ports (Rob Herring)
> - Remove common properties (Rob Herring)
> - Add unevalutatedProperties (Rob Herring)
> - Reference existing dsi controller yaml in the common
>   dsi controller file (Rob Herring)
> - Correct the description of clock names to include only the
>   clocks that are required (Rob Herring)
> - Remove properties which are already covered under the common
>   binding (Rob Herring)
> - Add dsi phy supply nodes which are required for sc7180 and
>   sdm845 targets (Rob Herring)
> - Add type ref for syscon-sfpb (Rob Herring)
> 
> Changes in v6:
> - Fixed errors during dt_binding_check (Rob Herring)
> - Add maxItems for phys and phys-names (Rob Herring)
> - Use unevaluatedProperties wherever required (Rob Herring)
> - Removed interrupt controller from required properties for
>   dsi controller (Rob Herring)
> - Add constraints for dsi-phy reg-names based on the compatible
>   phy version (Rob Herring)
> - Add constraints for dsi-phy supply nodes based on the
>   compatible phy version (Rob Herring)
> ---
>  .../bindings/display/msm/dpu-sc7180.yaml   | 236 
>  .../bindings/display/msm/dpu-sdm845.yaml   | 216 ++
>  .../devicetree/bindings/display/msm/dpu.txt| 141 
>  .../display/msm/dsi-common-controller.yaml | 180 +++
>  .../display/msm/dsi-controller-sc7180.yaml | 120 ++
>  .../display/msm/dsi-controller-sdm845.yaml | 120 ++
>  .../bindings/display/msm/dsi-phy-sc7180.yaml   |  80 +++
>  .../bindings/display/msm/dsi-phy-sdm845.yaml   |  82 +++
>  .../devicetree/bindings/display/msm/dsi-phy.yaml   | 126 +++
>  .../devicetree/bindings/display/msm/dsi.txt| 246 
> -
>  10 files changed, 1160 insertions(+), 387 deletions(-)
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml
>  delete mode 100644 Documentation/devicetree/bindings/display/msm/dpu.txt
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dsi-common-controller.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dsi-controller-sc7180.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dsi-controller-sdm845.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dsi-phy-sc7180.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/dsi-phy-sdm845.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/msm/dsi-phy.yaml
>  delete mode 100644 Documentation/devicetree/bindings/display/msm/dsi.txt
> 
> diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml 
> b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
> new file mode 100644
> index 000..df70393
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml
> @@ -0,0 +1,236 @@
> +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/msm/dpu-sc7180.yaml#
> +$schema: http://devicetree.org/meta-schemas

Re: [PATCH 8/9] clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk

2020-07-27 Thread Stephen Boyd
Quoting Konrad Dybcio (2020-07-26 04:12:05)
> Add missing halt_check, hwcg_reg and hwcg_bit properties.
> These were likely omitted when porting the driver upstream.
> 
> Signed-off-by: Konrad Dybcio 
> ---

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


Re: [PATCH 1/3] drm: Restore driver.preclose() for all to use

2020-07-27 Thread Daniel Vetter
On Thu, Jul 23, 2020 at 7:21 PM Chris Wilson  wrote:
>
> An unfortunate sequence of events, but it turns out there is a valid
> usecase for being able to free/decouple the driver objects before they
> are freed by the DRM core. In particular, if we have a pointer into a
> drm core object from inside a driver object, that pointer needs to be
> nerfed *before* it is freed so that concurrent access (e.g. debugfs)
> does not following the dangling pointer.
>
> The legacy marker was adding in the code movement from drp_fops.c to
> drm_file.c

I might fumble a lot, but not this one:

commit 45c3d213a400c952ab7119f394c5293bb6877e6b
Author: Daniel Vetter 
Date:   Mon May 8 10:26:33 2017 +0200

drm: Nerf the preclose callback for modern drivers

Also looking at the debugfs hook that has some rather adventurous
stuff going on I think, feels a bit like a kitchensink with batteries
included. If that's really all needed I'd say iterate the contexts by
first going over files, then the ctx (which arent shared anyway) and
the problem should also be gone.
-Daniel

> References: 9acdac68bcdc ("drm: rename drm_fops.c to drm_file.c")
> Signed-off-by: Chris Wilson 
> Cc: Daniel Vetter 
> Cc: Gustavo Padovan 
> Cc: CQ Tang 
> Cc:  # v4.12+
> ---
>  drivers/gpu/drm/drm_file.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> index 0ac4566ae3f4..7b4258d6f7cc 100644
> --- a/drivers/gpu/drm/drm_file.c
> +++ b/drivers/gpu/drm/drm_file.c
> @@ -258,8 +258,7 @@ void drm_file_free(struct drm_file *file)
>   (long)old_encode_dev(file->minor->kdev->devt),
>   atomic_read(&dev->open_count));
>
> -   if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
> -   dev->driver->preclose)
> +   if (dev->driver->preclose)
> dev->driver->preclose(dev, file);
>
> if (drm_core_check_feature(dev, DRIVER_LEGACY))
> --
> 2.20.1
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



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


Re: [PATCH] drm/amd/display: Clear dm_state for fast updates

2020-07-27 Thread Christian König

Am 27.07.20 um 16:05 schrieb Kazlauskas, Nicholas:

On 2020-07-27 9:39 a.m., Christian König wrote:

Am 27.07.20 um 07:40 schrieb Mazin Rezk:

This patch fixes a race condition that causes a use-after-free during
amdgpu_dm_atomic_commit_tail. This can occur when 2 non-blocking 
commits
are requested and the second one finishes before the first. 
Essentially,

this bug occurs when the following sequence of events happens:

1. Non-blocking commit #1 is requested w/ a new dm_state #1 and is
deferred to the workqueue.

2. Non-blocking commit #2 is requested w/ a new dm_state #2 and is
deferred to the workqueue.

3. Commit #2 starts before commit #1, dm_state #1 is used in the
commit_tail and commit #2 completes, freeing dm_state #1.

4. Commit #1 starts after commit #2 completes, uses the freed dm_state
1 and dereferences a freelist pointer while setting the context.


Well I only have a one mile high view on this, but why don't you let 
the work items execute in order?


That would be better anyway cause this way we don't trigger a cache 
line ping pong between CPUs.


Christian.


We use the DRM helpers for managing drm_atomic_commit_state and those 
helpers internally push non-blocking commit work into the system 
unbound work queue.


Mhm, well if you send those helper atomic commits in the order A,B and 
they execute it in the order B,A I would call that a bug :)


While we could duplicate a copy of that code with nothing but the 
workqueue changed that isn't something I'd really like to maintain 
going forward.


I'm not talking about duplicating the code, I'm talking about fixing the 
helpers. I don't know that code well, but from the outside it sounds 
like a bug there.


And executing work items in the order they are submitted is trivial.

Had anybody pinged Daniel or other people familiar with the helper code 
about it?


Regards,
Christian.



Regards,
Nicholas Kazlauskas





Since this bug has only been spotted with fast commits, this patch 
fixes

the bug by clearing the dm_state instead of using the old dc_state for
fast updates. In addition, since dm_state is only used for its dc_state
and amdgpu_dm_atomic_commit_tail will retain the dc_state if none is 
found,

removing the dm_state should not have any consequences in fast updates.

This use-after-free bug has existed for a while now, but only caused a
noticeable issue starting from 5.7-rc1 due to 3202fa62f ("slub: 
relocate

freelist pointer to middle of object") moving the freelist pointer from
dm_state->base (which was unused) to dm_state->context (which is
dereferenced).

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=207383
Fixes: bd200d190f45 ("drm/amd/display: Don't replace the dc_state 
for fast updates")

Reported-by: Duncan <1i5t5.dun...@cox.net>
Signed-off-by: Mazin Rezk 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 
++-

  1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 86ffa0c2880f..710edc70e37e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8717,20 +8717,38 @@ static int amdgpu_dm_atomic_check(struct 
drm_device *dev,

   * the same resource. If we have a new DC context as part of
   * the DM atomic state from validation we need to free it and
   * retain the existing one instead.
+ *
+ * Furthermore, since the DM atomic state only contains the DC
+ * context and can safely be annulled, we can free the state
+ * and clear the associated private object now to free
+ * some memory and avoid a possible use-after-free later.
   */
-    struct dm_atomic_state *new_dm_state, *old_dm_state;

-    new_dm_state = dm_atomic_get_new_state(state);
-    old_dm_state = dm_atomic_get_old_state(state);
+    for (i = 0; i < state->num_private_objs; i++) {
+    struct drm_private_obj *obj = state->private_objs[i].ptr;

-    if (new_dm_state && old_dm_state) {
-    if (new_dm_state->context)
-    dc_release_state(new_dm_state->context);
+    if (obj->funcs == adev->dm.atomic_obj.funcs) {
+    int j = state->num_private_objs-1;

-    new_dm_state->context = old_dm_state->context;
+    dm_atomic_destroy_state(obj,
+    state->private_objs[i].state);
+
+    /* If i is not at the end of the array then the
+ * last element needs to be moved to where i was
+ * before the array can safely be truncated.
+ */
+    if (i != j)
+    state->private_objs[i] =
+    state->private_objs[j];

-    if (old_dm_state->context)
-    dc_retain_state(old_dm_state->context);
+    state->private_objs[j].ptr = NULL;
+  

Re: [PATCH 1/6] dt-bindings: display: Document NewVision NV3052C DT node

2020-07-27 Thread Sam Ravnborg
Hi Paul.

On Mon, Jul 27, 2020 at 06:46:08PM +0200, Paul Cercueil wrote:
> Add documentation for the Device Tree node for LCD panels based on the
> NewVision NV3052C controller.
> 
> Signed-off-by: Paul Cercueil 

Very happy to see work on RG-350 :-)
Some feedback below.

Sam

> ---
>  .../display/panel/newvision,nv3052c.yaml  | 69 +++
>  1 file changed, 69 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml 
> b/Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml
> new file mode 100644
> index ..751a28800fc2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/newvision,nv3052c.yaml
> @@ -0,0 +1,69 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/newvision,nv3052c.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NewVision NV3052C TFT LCD panel driver with SPI control bus
> +
> +maintainers:
> +  - Paul Cercueil 
> +
> +description: |
> +  This is a driver for 320x240 TFT panels,
The binding describes the HW, not the driver. So please re-phrase this
part.

This datasheet: 
https://www.phoenixdisplay.com/wp-content/uploads/2019/05/NV3052C-Datasheet-V0.2.pdf
tells that the driver supports additional resoltions.
I guess the 320x240 resolution is limited to the leadtek panel.

> +  accepting a variety of input
> +  streams that get adapted and scaled to the panel. The panel output has
> +  960 TFT source driver pins and 240 TFT gate driver pins, VCOM, VCOML and
> +  VCOMH outputs.
> +
> +  The panel must obey the rules for a SPI slave device as specified in
> +  spi/spi-controller.yaml
> +
> +allOf:
> +  - $ref: panel-common.yaml#
> +
> +properties:
> +  compatible:
> +items:
> +  - enum:
> +- leadtek,ltk035c5444t-spi
> +
> +  - const: newvision,nv3052c
> +
> +  reg:
> +maxItems: 1
> +
> +  reset-gpios: true
> +  port: true
> +
> +required:
> +  - compatible
> +  - reg
> +
> +unevaluatedProperties: false
> +
Do the panel need any power?
I had expected to see a power-supply node as mandatory.

> +examples:
> +  - |
> +#include 
> +spi {
> +  #address-cells = <1>;
> +  #size-cells = <0>;
> +
> +  display@0 {
> +compatible = "leadtek,ltk035c5444t-spi", "newvision,nv3052c";
> +reg = <0>;
> +
> +spi-max-frequency = <1500>;
> +spi-3wire;
> +reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>;


> +backlight = <&backlight>;
> +power-supply = <&vcc>;
These would fail later due to "unevaluatedProperties: false".
Add them above like
  backlight: true
  power-supply: true

as done for reset-gpios for example.

> +
> +port {
> +  panel_input: endpoint {
> +  remote-endpoint = <&panel_output>;
> +  };
> +};
> +  };
> +};
Personally I prefer 4 space indent. But there is no fixed rule (yet)
what to use.

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


Re: [Nouveau] [PATCH v2] drm/nouveau: Accept 'legacy' format modifiers

2020-07-27 Thread James Jones

On 7/23/20 9:06 PM, Ben Skeggs wrote:

On Sat, 18 Jul 2020 at 13:34, James Jones  wrote:


Accept the DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK()
family of modifiers to handle broken userspace
Xorg modesetting and Mesa drivers. Existing Mesa
drivers are still aware of only these older
format modifiers which do not differentiate
between different variations of the block linear
layout. When the format modifier support flag was
flipped in the nouveau kernel driver, the X.org
modesetting driver began attempting to use its
format modifier-enabled framebuffer path. Because
the set of format modifiers advertised by the
kernel prior to this change do not intersect with
the set of format modifiers advertised by Mesa,
allocating GBM buffers using format modifiers
fails and the modesetting driver falls back to
non-modifier allocation. However, it still later
queries the modifier of the GBM buffer when
creating its DRM-KMS framebuffer object, receives
the old-format modifier from Mesa, and attempts
to create a framebuffer with it. Since the kernel
is still not aware of these formats, this fails.

Userspace should not be attempting to query format
modifiers of GBM buffers allocated with a non-
format-modifier-aware allocation path, but to
avoid breaking existing userspace behavior, this
change accepts the old-style format modifiers when
creating framebuffers and applying them to planes
by translating them to the equivalent new-style
modifier. To accomplish this, some layout
parameters must be assumed to match properties of
the device targeted by the relevant ioctls. To
avoid perpetuating misuse of the old-style
modifiers, this change does not advertise support
for them. Doing so would imply compatibility
between devices with incompatible memory layouts.

Tested with Xorg 1.20 modesetting driver,
weston@c46c70dac84a4b3030cd05b380f9f410536690fc,
gnome & KDE wayland desktops from Ubuntu 18.04,
and sway 1.5

Reported-by: Kirill A. Shutemov 
Fixes: fa4f4c213f5f ("drm/nouveau/kms: Support NVIDIA format modifiers")
Link: https://lkml.org/lkml/2020/6/30/1251
Signed-off-by: James Jones 
---
  drivers/gpu/drm/nouveau/nouveau_display.c | 26 +--
  1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index 496c4621cc78..31543086254b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -191,8 +191,14 @@ nouveau_decode_mod(struct nouveau_drm *drm,
uint32_t *tile_mode,
uint8_t *kind)
  {
+   struct nouveau_display *disp = nouveau_display(drm->dev);
 BUG_ON(!tile_mode || !kind);

+   if ((modifier & (0xffull << 12)) == 0ull) {
+   /* Legacy modifier.  Translate to this device's 'kind.' */
+   modifier |= disp->format_modifiers[0] & (0xffull << 12);
+   }

I believe this should be moved into the != MOD_LINEAR case.


Yes, of course, thanks.  I need to re-evaluate my testing yet again to 
make sure I hit that case too.  Preparing a v3...


Thanks,
-James


+
 if (modifier == DRM_FORMAT_MOD_LINEAR) {
 /* tile_mode will not be used in this case */
 *tile_mode = 0;
@@ -227,6 +233,16 @@ nouveau_framebuffer_get_layout(struct drm_framebuffer *fb,
 }
  }

+static const u64 legacy_modifiers[] = {
+   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0),
+   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1),
+   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2),
+   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3),
+   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4),
+   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5),
+   DRM_FORMAT_MOD_INVALID
+};
+
  static int
  nouveau_validate_decode_mod(struct nouveau_drm *drm,
 uint64_t modifier,
@@ -247,8 +263,14 @@ nouveau_validate_decode_mod(struct nouveau_drm *drm,
  (disp->format_modifiers[mod] != modifier);
  mod++);

-   if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID)
-   return -EINVAL;
+   if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID) {
+   for (mod = 0;
+(legacy_modifiers[mod] != DRM_FORMAT_MOD_INVALID) &&
+(legacy_modifiers[mod] != modifier);
+mod++);
+   if (legacy_modifiers[mod] == DRM_FORMAT_MOD_INVALID)
+   return -EINVAL;
+   }

 nouveau_decode_mod(drm, modifier, tile_mode, kind);

--
2.17.1

___
Nouveau mailing list
nouv...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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


Re: [PATCH] drm/dbi: Fix SPI Type 1 (9-bit) transfer

2020-07-27 Thread Sam Ravnborg
Hi Paul.

On Fri, Jul 03, 2020 at 04:23:57PM +0200, Sam Ravnborg wrote:
> On Fri, Jul 03, 2020 at 04:13:41PM +0200, Paul Cercueil wrote:
> > The function mipi_dbi_spi1_transfer() will transfer its payload as 9-bit
> > data, the 9th (MSB) bit being the data/command bit. In order to do that,
> > it unpacks the 8-bit values into 16-bit values, then sets the 9th bit if
> > the byte corresponds to data, clears it otherwise. The 7 MSB are
> > padding. The array of now 16-bit values is then passed to the SPI core
> > for transfer.
> > 
> > This function was broken since its introduction, as the length of the
> > SPI transfer was set to the payload size before its conversion, but the
> > payload doubled in size due to the 8-bit -> 16-bit conversion.
> > 
> > Fixes: 02dd95fe3169 ("drm/tinydrm: Add MIPI DBI support")
> > Cc:  # 4.10
> > Signed-off-by: Paul Cercueil 
> 
> As discussed on irc this looks correct to me too.
> 
> Reviewed-by: Sam Ravnborg 
> 
> 
> I will apply later, but let's wait and see if Noralf or others
> have any feedback first.
I finally went back to this patch, I missed it yesterday.
Applied to drm-misc-fixes with a stable 5.4+ tag.

Sam

> > ---
> >  drivers/gpu/drm/drm_mipi_dbi.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
> > index bb27c82757f1..bf7888ad9ad4 100644
> > --- a/drivers/gpu/drm/drm_mipi_dbi.c
> > +++ b/drivers/gpu/drm/drm_mipi_dbi.c
> > @@ -923,7 +923,7 @@ static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, 
> > int dc,
> > }
> > }
> >  
> > -   tr.len = chunk;
> > +   tr.len = chunk * 2;
> > len -= chunk;
> >  
> > ret = spi_sync(spi, &m);
> > -- 
> > 2.27.0
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/3] drm/ast: Store image size in HW cursor info

2020-07-27 Thread Daniel Vetter
On Mon, Jul 27, 2020 at 1:37 PM Thomas Zimmermann  wrote:
>
> Hi
>
> Am 27.07.20 um 12:42 schrieb dan...@ffwll.ch:
> > On Mon, Jul 27, 2020 at 09:37:06AM +0200, Thomas Zimmermann wrote:
> >> Store the image size as part of the HW cursor info, so that the
> >> cursor show function doesn't require the information from the
> >> caller. No functional changes.
> >
> > Uh just pass the state structure and done? All these "store random stuff
> > in private structures" (they're not even atomic state structures, it's the
> > driver private thing even!) is very non-atomic. And I see zero reasons why
> > you have to do this, the cursor stays around.
>
> It's not random stuff. Ast cannot use ARGB for cursors. Anything in
> ast_private.cursor represents cursor hardware state (not DRM state);
> duplicated for double buffering.
>
>  * gbo: two perma-pinned GEM objects at the end of VRAM. It's the HW
> cursor buffer in ARGB format. The userspace's cursor image is
> converted to ARGB and copied into the current backbuffer.
>
>  * vaddr: A mapping of the gbo's into kernel address space. We don't
> want to map the gbo on each update, so they are mapped once and the
> kernel address is stored in vaddr.
>
>  * size: the size of each HW buffer. We could use the value in the fb,
> but storing this as well makes the cursor code self-contained.

Yeah, but this kind of stuff should be in the ast_plane_state. Not in
ast_private, that latter option is very non-atomic and results in all
kinds of coordination fun.
-Daniel

>
> Best regards
> Thomas
>
> > -Daniel
> >
> >>
> >> Signed-off-by: Thomas Zimmermann 
> >> Fixes: 4961eb60f145 ("drm/ast: Enable atomic modesetting")
> >> Cc: Thomas Zimmermann 
> >> Cc: Gerd Hoffmann 
> >> Cc: Dave Airlie 
> >> Cc: Daniel Vetter 
> >> Cc: Sam Ravnborg 
> >> Cc: Emil Velikov 
> >> Cc: "Y.C. Chen" 
> >> Cc:  # v5.6+
> >> ---
> >>  drivers/gpu/drm/ast/ast_cursor.c | 13 +++--
> >>  drivers/gpu/drm/ast/ast_drv.h|  7 +--
> >>  drivers/gpu/drm/ast/ast_mode.c   |  8 +---
> >>  3 files changed, 17 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/ast/ast_cursor.c 
> >> b/drivers/gpu/drm/ast/ast_cursor.c
> >> index acf0d23514e8..8642a0ce9da6 100644
> >> --- a/drivers/gpu/drm/ast/ast_cursor.c
> >> +++ b/drivers/gpu/drm/ast/ast_cursor.c
> >> @@ -87,6 +87,8 @@ int ast_cursor_init(struct ast_private *ast)
> >>
> >>  ast->cursor.gbo[i] = gbo;
> >>  ast->cursor.vaddr[i] = vaddr;
> >> +ast->cursor.size[i].width = 0;
> >> +ast->cursor.size[i].height = 0;
> >>  }
> >>
> >>  return drmm_add_action_or_reset(dev, ast_cursor_release, NULL);
> >> @@ -194,6 +196,9 @@ int ast_cursor_blit(struct ast_private *ast, struct 
> >> drm_framebuffer *fb)
> >>  /* do data transfer to cursor BO */
> >>  update_cursor_image(dst, src, fb->width, fb->height);
> >>
> >> +ast->cursor.size[ast->cursor.next_index].width = fb->width;
> >> +ast->cursor.size[ast->cursor.next_index].height = fb->height;
> >> +
> >>  drm_gem_vram_vunmap(gbo, src);
> >>  drm_gem_vram_unpin(gbo);
> >>
> >> @@ -249,14 +254,18 @@ static void ast_cursor_set_location(struct 
> >> ast_private *ast, u16 x, u16 y,
> >>  ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
> >>  }
> >>
> >> -void ast_cursor_show(struct ast_private *ast, int x, int y,
> >> - unsigned int offset_x, unsigned int offset_y)
> >> +void ast_cursor_show(struct ast_private *ast, int x, int y)
> >>  {
> >> +unsigned int offset_x, offset_y;
> >>  u8 x_offset, y_offset;
> >>  u8 __iomem *dst, __iomem *sig;
> >>  u8 jreg;
> >>
> >>  dst = ast->cursor.vaddr[ast->cursor.next_index];
> >> +offset_x = AST_MAX_HWC_WIDTH -
> >> +   ast->cursor.size[ast->cursor.next_index].width;
> >> +offset_y = AST_MAX_HWC_HEIGHT -
> >> +   ast->cursor.size[ast->cursor.next_index].height;
> >>
> >>  sig = dst + AST_HWC_SIZE;
> >>  writel(x, sig + AST_HWC_SIGNATURE_X);
> >> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
> >> index e3a264ac7ee2..57414b429db3 100644
> >> --- a/drivers/gpu/drm/ast/ast_drv.h
> >> +++ b/drivers/gpu/drm/ast/ast_drv.h
> >> @@ -116,6 +116,10 @@ struct ast_private {
> >>  struct {
> >>  struct drm_gem_vram_object *gbo[AST_DEFAULT_HWC_NUM];
> >>  void __iomem *vaddr[AST_DEFAULT_HWC_NUM];
> >> +struct {
> >> +unsigned int width;
> >> +unsigned int height;
> >> +} size[AST_DEFAULT_HWC_NUM];
> >>  unsigned int next_index;
> >>  } cursor;
> >>
> >> @@ -311,8 +315,7 @@ void ast_release_firmware(struct drm_device *dev);
> >>  int ast_cursor_init(struct ast_private *ast);
> >>  int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb);
> >>  void ast_cursor_page_flip(struct ast_private *ast);
> >> -void ast_cursor_show(struct ast_private *ast, int x, i

Re: [PATCH 1/3] drm/ast: Do full modeset if the primary plane's format changes

2020-07-27 Thread Daniel Vetter
On Mon, Jul 27, 2020 at 1:24 PM Thomas Zimmermann  wrote:
>
> Hi
>
> Am 27.07.20 um 12:40 schrieb dan...@ffwll.ch:
> > On Mon, Jul 27, 2020 at 09:37:05AM +0200, Thomas Zimmermann wrote:
> >> The atomic modesetting code tried to distinguish format changes from
> >> full modesetting operations. In practice, this was buggy and the format
> >> registers were often updated even for simple pageflips.
> >
> > Nah it's not buggy, it's intentional. Most hw can update formats in a flip
> > withouth having to shut down the hw to do so.
>
> Admittedly it was intentional when I write it, but it never really
> worked. I think it might have even updated these color registers on each
> frame.
>
> >
> >
> >> Instead do a full modeset if the primary plane changes formats. It's
> >> just as rare as an actual mode change, so there will be no performance
> >> penalty.
> >>
> >> The patch also replaces a reference to drm_crtc_state.allow_modeset with
> >> the correct call to drm_atomic_crtc_needs_modeset().
> >>
> >> Signed-off-by: Thomas Zimmermann 
> >> Fixes: 4961eb60f145 ("drm/ast: Enable atomic modesetting")
> >> Cc: Thomas Zimmermann 
> >> Cc: Gerd Hoffmann 
> >> Cc: Dave Airlie 
> >> Cc: Daniel Vetter 
> >> Cc: Sam Ravnborg 
> >> Cc: Emil Velikov 
> >> Cc: "Y.C. Chen" 
> >> Cc:  # v5.6+
> >> ---
> >>  drivers/gpu/drm/ast/ast_mode.c | 23 ---
> >>  1 file changed, 16 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/ast/ast_mode.c 
> >> b/drivers/gpu/drm/ast/ast_mode.c
> >> index 154cd877d9d1..3680a000b812 100644
> >> --- a/drivers/gpu/drm/ast/ast_mode.c
> >> +++ b/drivers/gpu/drm/ast/ast_mode.c
> >> @@ -527,8 +527,8 @@ static const uint32_t ast_primary_plane_formats[] = {
> >>  static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
> >>   struct drm_plane_state 
> >> *state)
> >>  {
> >> -struct drm_crtc_state *crtc_state;
> >> -struct ast_crtc_state *ast_crtc_state;
> >> +struct drm_crtc_state *crtc_state, *old_crtc_state;
> >> +struct ast_crtc_state *ast_crtc_state, *old_ast_crtc_state;
> >>  int ret;
> >>
> >>  if (!state->crtc)
> >> @@ -550,6 +550,15 @@ static int 
> >> ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
> >>
> >>  ast_crtc_state->format = state->fb->format;
> >>
> >> +old_crtc_state = drm_atomic_get_old_crtc_state(state->state, 
> >> state->crtc);
> >> +if (!old_crtc_state)
> >> +return 0;
> >> +old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
> >> +if (!old_ast_crtc_state)
> >
> > The above two if checks should never fail, I'd wrap them in a WARN_ON.
>
> Really? But what's the old state when the first mode is being programmed?

Uh, atomic _always_ has a state. That's why you need to call
drm_mode_config_reset, to get this entire machinery started. Also, the
sw state is supposed to always match the hw state (at least once all
the nonblocking commit workers have caught up).

> >
> >> +return 0;
> >> +if (ast_crtc_state->format != old_ast_crtc_state->format)
> >> +crtc_state->mode_changed = true;
> >> +
> >>  return 0;
> >>  }
> >>
> >> @@ -775,18 +784,18 @@ static void ast_crtc_helper_atomic_flush(struct 
> >> drm_crtc *crtc,
> >>
> >>  ast_state = to_ast_crtc_state(crtc->state);
> >>
> >> -format = ast_state->format;
> >> -if (!format)
> >> +if (!drm_atomic_crtc_needs_modeset(crtc->state))
> >>  return;
> >>
> >> +format = ast_state->format;
> >> +if (drm_WARN_ON_ONCE(dev, !format))
> >> +return; /* BUG: We didn't set format in primary check(). */
> >
> > Hm that entire ast_state->format machinery looks kinda strange, can't you
> > just look up the primary plane state everywhere and that's it?
> > drm_framebuffer are fully invariant and refcounted to the state, so there
> > really shouldn't be any need to copy format around.
>
> ast_state->format is the format that has to be programmed in
> atomic_flush(). If it's NULL, the current format was used. Updating the
> primary plane's format also requires the vbios info, which depends on
> CRTC state. So it's collected in the CRTC's atomic_check().
>
> It felt natural to use the various atomic_check() functions to collect
> and store and store away these structures, and later use them in
> atomic_flush().
>
> I'd prefer to keep the current design. It's the one that worked best
> while writing the atomic-modesetting support for ast.

So if you have actual checks in atomic_check for validation, then this
makes sense - it avoids computing stuff twice and getting in wrong in
one case.

But from reading ast code all you do is store the temporary lookup in
there, and that's really just confusing. You can just look up the
atomic state, at least in atomic_check (in the commit side it's mildly
more annoying, we need to fix a few things). But it's also not totally
horrible ofc, just would be nice to improve this.
-

Re: [PATCH 1/2] drm/radeon: switch from 'pci_' to 'dma_' API

2020-07-27 Thread Alex Deucher
Applied.  Thanks!

Alex

On Mon, Jul 27, 2020 at 9:42 AM Christian König
 wrote:
>
> Am 27.07.20 um 12:34 schrieb Christophe JAILLET:
> > The wrappers in include/linux/pci-dma-compat.h should go away.
> >
> > The patch has been generated with the coccinelle script below and has been
> > hand modified to replace GFP_ with a correct flag.
> > It has been compile tested.
> >
> > When memory is allocated in 'radeon_gart_table_ram_alloc()' GFP_KERNEL
> > can be used because its callers already use this flag.
> >
> > Both 'r100_pci_gart_init()' (r100.c) and 'rs400_gart_init()' (rs400.c)
> > call 'radeon_gart_init()'.
> > This function uses 'vmalloc'.
> >
> >
> > @@
> > @@
> > -PCI_DMA_BIDIRECTIONAL
> > +DMA_BIDIRECTIONAL
> >
> > @@
> > @@
> > -PCI_DMA_TODEVICE
> > +DMA_TO_DEVICE
> >
> > @@
> > @@
> > -PCI_DMA_FROMDEVICE
> > +DMA_FROM_DEVICE
> >
> > @@
> > @@
> > -PCI_DMA_NONE
> > +DMA_NONE
> >
> > @@
> > expression e1, e2, e3;
> > @@
> > -pci_alloc_consistent(e1, e2, e3)
> > +dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
> >
> > @@
> > expression e1, e2, e3;
> > @@
> > -pci_zalloc_consistent(e1, e2, e3)
> > +dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_free_consistent(e1, e2, e3, e4)
> > +dma_free_coherent(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_map_single(e1, e2, e3, e4)
> > +dma_map_single(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_unmap_single(e1, e2, e3, e4)
> > +dma_unmap_single(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4, e5;
> > @@
> > -pci_map_page(e1, e2, e3, e4, e5)
> > +dma_map_page(&e1->dev, e2, e3, e4, e5)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_unmap_page(e1, e2, e3, e4)
> > +dma_unmap_page(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_map_sg(e1, e2, e3, e4)
> > +dma_map_sg(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_unmap_sg(e1, e2, e3, e4)
> > +dma_unmap_sg(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_dma_sync_single_for_cpu(e1, e2, e3, e4)
> > +dma_sync_single_for_cpu(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_dma_sync_single_for_device(e1, e2, e3, e4)
> > +dma_sync_single_for_device(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_dma_sync_sg_for_cpu(e1, e2, e3, e4)
> > +dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2, e3, e4;
> > @@
> > -pci_dma_sync_sg_for_device(e1, e2, e3, e4)
> > +dma_sync_sg_for_device(&e1->dev, e2, e3, e4)
> >
> > @@
> > expression e1, e2;
> > @@
> > -pci_dma_mapping_error(e1, e2)
> > +dma_mapping_error(&e1->dev, e2)
> >
> > @@
> > expression e1, e2;
> > @@
> > -pci_set_dma_mask(e1, e2)
> > +dma_set_mask(&e1->dev, e2)
> >
> > @@
> > expression e1, e2;
> > @@
> > -pci_set_consistent_dma_mask(e1, e2)
> > +dma_set_coherent_mask(&e1->dev, e2)
> >
> > Signed-off-by: Christophe JAILLET 
>
> Reviewed-by: Christian König 
>
> > ---
> > If needed, see post from Christoph Hellwig on the kernel-janitors ML:
> > https://marc.info/?l=kernel-janitors&m=158745678307186&w=4
> > ---
> >   drivers/gpu/drm/radeon/radeon_gart.c | 9 -
> >   1 file changed, 4 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
> > b/drivers/gpu/drm/radeon/radeon_gart.c
> > index f178ba321715..b7ce254e5663 100644
> > --- a/drivers/gpu/drm/radeon/radeon_gart.c
> > +++ b/drivers/gpu/drm/radeon/radeon_gart.c
> > @@ -72,8 +72,8 @@ int radeon_gart_table_ram_alloc(struct radeon_device 
> > *rdev)
> >   {
> >   void *ptr;
> >
> > - ptr = pci_alloc_consistent(rdev->pdev, rdev->gart.table_size,
> > -&rdev->gart.table_addr);
> > + ptr = dma_alloc_coherent(&rdev->pdev->dev, rdev->gart.table_size,
> > +  &rdev->gart.table_addr, GFP_KERNEL);
> >   if (ptr == NULL) {
> >   return -ENOMEM;
> >   }
> > @@ -110,9 +110,8 @@ void radeon_gart_table_ram_free(struct radeon_device 
> > *rdev)
> > rdev->gart.table_size >> PAGE_SHIFT);
> >   }
> >   #endif
> > - pci_free_consistent(rdev->pdev, rdev->gart.table_size,
> > - (void *)rdev->gart.ptr,
> > - rdev->gart.table_addr);
> > + dma_free_coherent(&rdev->pdev->dev, rdev->gart.table_size,
> > +   (void *)rdev->gart.ptr, rdev->gart.table_addr);
> >   rdev->gart.ptr = NULL;
> >   rdev->gart.table_addr = 0;
> >   }
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_

Re: [PATCH 9/9] soc/qcom: Add REVID driver

2020-07-27 Thread Rob Herring
On Sun, Jul 26, 2020 at 01:12:06PM +0200, Konrad Dybcio wrote:
> From: Xiaozhe Shi 
> 
> Add the REVID device driver. The REVID driver will print out the PMIC
> revision at probe time.
> 
> Signed-off-by: Xiaozhe Shi 
> [konradyb...@gmail.com: Fast-forward the driver from kernel 4.14 to 5.8,
> convert binding to yaml]
> Signed-off-by: Konrad Dybcio 
> ---
>  .../bindings/soc/qcom/qcom,qpnp-revid.yaml|  38 ++

Bindings should be a separate patch. checkpatch.pl will tell you this.

>  drivers/soc/qcom/Kconfig  |   9 +
>  drivers/soc/qcom/Makefile |   1 +
>  drivers/soc/qcom/qpnp-revid.c | 288 ++
>  include/linux/qpnp/qpnp-revid.h   | 369 ++
>  5 files changed, 705 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml
>  create mode 100644 drivers/soc/qcom/qpnp-revid.c
>  create mode 100644 include/linux/qpnp/qpnp-revid.h
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 9/9] soc/qcom: Add REVID driver

2020-07-27 Thread Rob Herring
On Sun, 26 Jul 2020 13:12:06 +0200, Konrad Dybcio wrote:
> From: Xiaozhe Shi 
> 
> Add the REVID device driver. The REVID driver will print out the PMIC
> revision at probe time.
> 
> Signed-off-by: Xiaozhe Shi 
> [konradyb...@gmail.com: Fast-forward the driver from kernel 4.14 to 5.8,
> convert binding to yaml]
> Signed-off-by: Konrad Dybcio 
> ---
>  .../bindings/soc/qcom/qcom,qpnp-revid.yaml|  38 ++
>  drivers/soc/qcom/Kconfig  |   9 +
>  drivers/soc/qcom/Makefile |   1 +
>  drivers/soc/qcom/qpnp-revid.c | 288 ++
>  include/linux/qpnp/qpnp-revid.h   | 369 ++
>  5 files changed, 705 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml
>  create mode 100644 drivers/soc/qcom/qpnp-revid.c
>  create mode 100644 include/linux/qpnp/qpnp-revid.h
> 


My bot found errors running 'make dt_binding_check' on your patch:

Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml:  while 
scanning a block scalar
  in "", line 22, column 18
found a tab character where an indentation space is expected
  in "", line 24, column 1
Documentation/devicetree/bindings/Makefile:20: recipe for target 
'Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.example.dts' failed
make[1]: *** 
[Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.example.dts] Error 1
make[1]: *** Waiting for unfinished jobs
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml:
 ignoring, error parsing file
warning: no schema found in file: 
./Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml:
 ignoring, error parsing file
warning: no schema found in file: 
./Documentation/devicetree/bindings/soc/qcom/qcom,qpnp-revid.yaml
Makefile:1347: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2


See https://patchwork.ozlabs.org/patch/1336467

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure dt-schema is up to date:

pip3 install git+https://github.com/devicetree-org/dt-schema.git@master 
--upgrade

Please check and re-submit.

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


Re: [PATCH 2/2] drm/radeon: avoid a useless memset

2020-07-27 Thread Alex Deucher
Applied.  Thanks!

Alex

On Mon, Jul 27, 2020 at 9:41 AM Christian König
 wrote:
>
> Am 27.07.20 um 12:34 schrieb Christophe JAILLET:
> > Avoid a memset after a call to 'dma_alloc_coherent()'.
> > This is useless since
> > commit 518a2f1925c3 ("dma-mapping: zero memory returned from dma_alloc_*")
> >
> > Signed-off-by: Christophe JAILLET 
>
> Reviewed-by: Christian König 
>
> > ---
> >   drivers/gpu/drm/radeon/radeon_gart.c | 1 -
> >   1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
> > b/drivers/gpu/drm/radeon/radeon_gart.c
> > index b7ce254e5663..3808a753127b 100644
> > --- a/drivers/gpu/drm/radeon/radeon_gart.c
> > +++ b/drivers/gpu/drm/radeon/radeon_gart.c
> > @@ -85,7 +85,6 @@ int radeon_gart_table_ram_alloc(struct radeon_device 
> > *rdev)
> >   }
> >   #endif
> >   rdev->gart.ptr = ptr;
> > - memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size);
> >   return 0;
> >   }
> >
>
> ___
> amd-gfx mailing list
> amd-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/3] dt-bindings: Add DT bindings for Powertip PH800480T013

2020-07-27 Thread Rob Herring
On Sat, 25 Jul 2020 23:13:34 +0200, Marek Vasut wrote:
> Add DT bindings for Powertip PH800480T013 800x480 parallel LCD,
> this one is used in the Raspberry Pi 7" touchscreen display unit.
> 
> Signed-off-by: Marek Vasut 
> To: dri-devel@lists.freedesktop.org
> Cc: Eric Anholt 
> Cc: Rob Herring 
> Cc: Sam Ravnborg 
> Cc: devicet...@vger.kernel.org
> ---
>  .../panel/powertip,ph800480t013-idf02.yaml| 28 +++
>  1 file changed, 28 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml
> 


My bot found errors running 'make dt_binding_check' on your patch:

/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml:
 $id: 
'http://devicetree.org/schemas/display/panel/powertip,ph800480t013-idf02#' does 
not match 'http://devicetree.org/schemas/.*\\.yaml#'
Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml:
 $id: relative path/filename doesn't match actual path or filename
expected: 
http://devicetree.org/schemas/display/panel/powertip,ph800480t013-idf02.yaml#
Documentation/devicetree/bindings/Makefile:20: recipe for target 
'Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.example.dts'
 failed
make[1]: *** 
[Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.example.dts]
 Error 1
make[1]: *** Waiting for unfinished jobs
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml:
 ignoring, error in schema: $id
warning: no schema found in file: 
./Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml:
 ignoring, error in schema: $id
warning: no schema found in file: 
./Documentation/devicetree/bindings/display/panel/powertip,ph800480t013-idf02.yaml
Makefile:1347: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2


See https://patchwork.ozlabs.org/patch/1336335

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure dt-schema is up to date:

pip3 install git+https://github.com/devicetree-org/dt-schema.git@master 
--upgrade

Please check and re-submit.

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


Re: [PATCH 1/2] dt-bindings: Add DT bindings for Toshiba TC358762 DSI-to-DPI bridge

2020-07-27 Thread Rob Herring
On Sat, 25 Jul 2020 23:14:56 +0200, Marek Vasut wrote:
> Add DT bindings for Toshiba TC358762 DSI-to-DPI bridge, this
> one is used in the Raspberry Pi 7" touchscreen display unit.
> 
> Signed-off-by: Marek Vasut 
> To: dri-devel@lists.freedesktop.org
> Cc: Eric Anholt 
> Cc: Rob Herring 
> Cc: Sam Ravnborg 
> Cc: devicet...@vger.kernel.org
> ---
>  .../display/bridge/toshiba,tc358762.yaml  | 116 ++
>  1 file changed, 116 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml
> 


My bot found errors running 'make dt_binding_check' on your patch:

Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dts:20.13-23:
 Warning (reg_format): /example-0/bridge@0:reg: property has invalid length (4 
bytes) (#address-cells == 1, #size-cells == 1)
Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 Warning (pci_device_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 Warning (simple_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 Warning (spi_bus_reg): Failed prerequisite 'reg_format'
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 example-0: bridge@0:reg:0: [0] is too short
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 bridge@0: '#address-cells', '#size-cells', 'port@0', 'port@1' do not match any 
of the regexes: 'pinctrl-[0-9]+'
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.example.dt.yaml:
 bridge@0: 'ports' is a required property


See https://patchwork.ozlabs.org/patch/1336337

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure dt-schema is up to date:

pip3 install git+https://github.com/devicetree-org/dt-schema.git@master 
--upgrade

Please check and re-submit.

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


Re: [PATCH -next] crc:Fix build errors

2020-07-27 Thread Lyude Paul
Hi, I actually already sent a patch for this:

https://patchwork.freedesktop.org/patch/378202/

I'm guessing it hasn't gotten picked up upstream yet?

On Mon, 2020-07-27 at 12:00 +0800, Peng Wu wrote:
> If CONFIG_DRM_NOUVEAU=y,the following errors
> are seen while building crc.h.
> 
> In file included from
> /scratch/linux/drivers/gpu/drm/nouveau/nouveau_display.c:47:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h: In function
> ‘nv50_head_crc_late_register’:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:109:47: error:
> parameter name omitted
>  static inline int nv50_head_crc_late_register(struct nv50_head *) {}
>^~
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:109:54: warning: no
> return statement in function returning non-void [-Wreturn-type]
>  static inline int nv50_head_crc_late_register(struct nv50_head *) {}
>   ^
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h: In function
> ‘nv50_crc_handle_vblank’:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:111:57: warning:
> ‘return’ with a value, in function returning void
>  nv50_crc_handle_vblank(struct nv50_head *head) { return 0; }
>  ^
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:111:1: note: declared
> here
>  nv50_crc_handle_vblank(struct nv50_head *head) { return 0; }
>  ^~
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h: In function
> ‘nv50_crc_atomic_check_head’:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:114:28: error:
> parameter name omitted
>  nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
> ^~
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:114:48: error:
> parameter name omitted
>  nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
> ^~~
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:115:7: error:
> parameter name omitted
>struct nv50_head_atom *) {}
>^~~
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:115:14: warning: no
> return statement in function returning non-void [-Wreturn-type]
>struct nv50_head_atom *) {}
>   ^~
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h: In function
> ‘nv50_crc_atomic_stop_reporting’:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:118:32: error:
> parameter name omitted
>  nv50_crc_atomic_stop_reporting(struct drm_atomic_state *) {}
> ^
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h: In function
> ‘nv50_crc_atomic_init_notifier_contexts’:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:120:40: error:
> parameter name omitted
>  nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *) {}
> ^
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h: In function
> ‘nv50_crc_atomic_release_notifier_contexts’:
> /scratch/linux/drivers/gpu/drm/nouveau/dispnv50/crc.h:122:43: error:
> parameter name omitted
> 
> Signed-off-by: Peng Wu 
> ---
>  drivers/gpu/drm/nouveau/dispnv50/crc.h | 44 +
> -
>  1 file changed, 22 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.h
> b/drivers/gpu/drm/nouveau/dispnv50/crc.h
> index 4bc59e7..3da16cd 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/crc.h
> +++ b/drivers/gpu/drm/nouveau/dispnv50/crc.h
> @@ -76,22 +76,22 @@ struct nv50_crc {
>  };
>  
>  void nv50_crc_init(struct drm_device *dev);
> -int nv50_head_crc_late_register(struct nv50_head *);
> +int nv50_head_crc_late_register(struct nv50_head *head);
>  void nv50_crc_handle_vblank(struct nv50_head *head);
>  
> -int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *);
> -const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *);
> -int nv50_crc_set_source(struct drm_crtc *, const char *);
> +int nv50_crc_verify_source(struct drm_crtc *crtc, const char *source_name,
> size_t *values_cnt);
> +const char *const *nv50_crc_get_sources(struct drm_crtc *crtc, size_t
> *count);
> +int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str);
>  
> -int nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
> -struct nv50_head_atom *);
> +int nv50_crc_atomic_check_head(struct nv50_head *head, struct
> nv50_head_atom *asyh,
> +struct nv50_head_atom *armh);
>  void nv50_crc_atomic_check_outp(struct nv50_atom *atom);
> -void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *);
> -void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *);
> -void nv50_crc_atomic_relea

Re: [PATCH v5 0/5] drm/bridge: Update tc358767 and nxp-ptn3460 to support chained bridges

2020-07-27 Thread Sam Ravnborg
Hi all.

On Mon, Jul 27, 2020 at 07:03:15PM +0200, Sam Ravnborg wrote:
> This patch-set aims to make connector creation optional
> and prepare the bridge drivers for use in a chained setup.
> 
> The objective is that all bridge drivers shall support a chained setup
> connector creation is moved to the display drivers.
> This is just one step on this path.
> 
> The general approach for the bridge drivers:
> - Introduce bridge operations
> - Introduce use of panel bridge and make connector creation optional
> 
> v5:
>   - Applied reviewed patches, so we went from 15 to 5
>   - Fixed bug in connector creation in both drivers
> 
> v4:
>   - Dropped patch for ti-sn65dsi86. Await full conversion
>   - Dropped patch for ti-tpd12s015. It was wrong (Laurent)
>   - Drop boe,hv070wsa-100 patch, it was applied
>   - Combined a few patches to fix connector created twice (Laurent)
>   - Fix memory leak in get_edid (Laurent)
>   - Added patch to validate panel descriptions in panel-simple
>   - Set bridge.type in relevant drivers
>  
> v3:
>   - Rebase on top of drm-misc-next
>   - Address kbuild test robot feedback
>  
> v2:
>   - Updated bus_flags for boe,hv070wsa-100
>   - Collected r-b, but did not apply patches yet
>   - On the panel side the panel-simple driver gained a default
> connector type for all the dumb panels that do not
> include so in their description.
> With this change panels always provide a connector type,
> and we have the potential to drop most uses of
> devm_drm_panel_bridge_add_typed().
>   - Added conversion of a few more bridge drivers
> 
> Patches can build but no run-time testing.
> So both test and review feedback appreciated!
> 
>   Sam
> 
> 
> Sam Ravnborg (5):
>   drm/bridge: tc358767: add detect bridge operation
>   drm/bridge: tc358767: add get_edid bridge operation
>   drm/bridge: tc358767: add drm_panel_bridge support
>   drm/bridge: nxp-ptn3460: add get_edid bridge operation
>   drm/bridge: nxp-ptn3460: add drm_panel_bridge support

Fixed up per Laurent's suggestion and applied to drm-misc-next.

Sam


> 
>  drivers/gpu/drm/bridge/nxp-ptn3460.c | 103 +---
>  drivers/gpu/drm/bridge/tc358767.c| 126 
> +++
>  2 files changed, 114 insertions(+), 115 deletions(-)
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v5 5/5] drm/bridge: nxp-ptn3460: add drm_panel_bridge support

2020-07-27 Thread Laurent Pinchart
Hi Sam,

Thank you for the patch.

On Mon, Jul 27, 2020 at 07:03:20PM +0200, Sam Ravnborg wrote:
> Prepare the bridge driver for use in a chained setup.
> 
> - Replacing direct use of drm_panel with drm_panel_bridge support.
> - Make the connector creation optional
> 
> Note: the bridge panel will use the connector type from the panel.
> 
> v3:
>   - Fix wrong logic in connector creation (Laurent)
> 
> v2:
>   - Use panel_bridge for local variable name to align with other drivers
>   - Fix that connector was created twice (Laurent)
>   - Set bridge.type to DRM_MODE_CONNECTOR_LVDS.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Andrzej Hajda 
> Cc: Neil Armstrong 
> Cc: Laurent Pinchart 
> Cc: Jonas Karlman 
> Cc: Jernej Skrabec 
> ---
>  drivers/gpu/drm/bridge/nxp-ptn3460.c | 60 ++--
>  1 file changed, 20 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c 
> b/drivers/gpu/drm/bridge/nxp-ptn3460.c
> index 2805c8938f98..391c1f66f60f 100644
> --- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
> +++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
> @@ -29,7 +29,7 @@ struct ptn3460_bridge {
>   struct drm_connector connector;
>   struct i2c_client *client;
>   struct drm_bridge bridge;
> - struct drm_panel *panel;
> + struct drm_bridge *panel_bridge;
>   struct gpio_desc *gpio_pd_n;
>   struct gpio_desc *gpio_rst_n;
>   u32 edid_emulation;
> @@ -126,11 +126,6 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
>   usleep_range(10, 20);
>   gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
>  
> - if (drm_panel_prepare(ptn_bridge->panel)) {
> - DRM_ERROR("failed to prepare panel\n");
> - return;
> - }
> -
>   /*
>* There's a bug in the PTN chip where it falsely asserts hotplug before
>* it is fully functional. We're forced to wait for the maximum start up
> @@ -145,16 +140,6 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
>   ptn_bridge->enabled = true;
>  }
>  
> -static void ptn3460_enable(struct drm_bridge *bridge)
> -{
> - struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
> -
> - if (drm_panel_enable(ptn_bridge->panel)) {
> - DRM_ERROR("failed to enable panel\n");
> - return;
> - }
> -}
> -
>  static void ptn3460_disable(struct drm_bridge *bridge)
>  {
>   struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
> @@ -164,24 +149,10 @@ static void ptn3460_disable(struct drm_bridge *bridge)
>  
>   ptn_bridge->enabled = false;
>  
> - if (drm_panel_disable(ptn_bridge->panel)) {
> - DRM_ERROR("failed to disable panel\n");
> - return;
> - }
> -
>   gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
>   gpiod_set_value(ptn_bridge->gpio_pd_n, 0);
>  }
>  
> -static void ptn3460_post_disable(struct drm_bridge *bridge)
> -{
> - struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
> -
> - if (drm_panel_unprepare(ptn_bridge->panel)) {
> - DRM_ERROR("failed to unprepare panel\n");
> - return;
> - }
> -}
>  
>  static struct edid *ptn3460_get_edid(struct drm_bridge *bridge,
>struct drm_connector *connector)
> @@ -245,12 +216,18 @@ static int ptn3460_bridge_attach(struct drm_bridge 
> *bridge,
>enum drm_bridge_attach_flags flags)
>  {
>   struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
> + enum drm_bridge_attach_flags panel_flags;
>   int ret;
>  
> - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> - DRM_ERROR("Fix bridge driver to make connector optional!");
> - return -EINVAL;
> - }
> + /* Let this driver create connector if requested */
> + panel_flags = flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR;
> + ret = drm_bridge_attach(bridge->encoder, ptn_bridge->panel_bridge,
> + bridge, panel_flags);

Same here, you could write

flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);

Reviewed-by: Laurent Pinchart 

> + if (ret < 0)
> + return ret;
> +
> + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> + return 0;
>  
>   if (!bridge->encoder) {
>   DRM_ERROR("Parent encoder object not found");
> @@ -270,9 +247,6 @@ static int ptn3460_bridge_attach(struct drm_bridge 
> *bridge,
>   drm_connector_attach_encoder(&ptn_bridge->connector,
>   bridge->encoder);
>  
> - if (ptn_bridge->panel)
> - drm_panel_attach(ptn_bridge->panel, &ptn_bridge->connector);
> -
>   drm_helper_hpd_irq_event(ptn_bridge->connector.dev);
>  
>   return ret;
> @@ -280,9 +254,7 @@ static int ptn3460_bridge_attach(struct drm_bridge 
> *bridge,
>  
>  static const struct drm_bridge_funcs ptn3460_bridge_funcs = {
>   .pre_enable = ptn3460_pre_enable,
> - .enable = p

Re: [PATCH v5 3/5] drm/bridge: tc358767: add drm_panel_bridge support

2020-07-27 Thread Laurent Pinchart
Hi Sam,

Thank you for the patch.

On Mon, Jul 27, 2020 at 07:03:18PM +0200, Sam Ravnborg wrote:
> With the bridge operations implemented the last step to prepare
> this driver for a chained setup is the use of the bridge panel driver.
> 
> The bridge panel driver is only used when a port@2 is present in
> the DT. So when the display driver requests a connector
> support both situations:
> - connector created by bridge panel driver
> - connector created by this driver
> 
> And on top, support that the display driver creates the connector,
> which is the preferred setup.
> 
> Note: the bridge panel will use the connector type from the panel.
> 
> v3:
>   - Fix wrong logic in connector creation (Laurent)
> 
> v2:
>   - Merge connector and drm_panel_bridge patches
> and fix so we do not create two connectors (Laurent)
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Laurent Pinchart 
> Cc: Andrzej Hajda 
> Cc: Neil Armstrong 
> Cc: Jonas Karlman 
> Cc: Jernej Skrabec 
> ---
>  drivers/gpu/drm/bridge/tc358767.c | 70 +++
>  1 file changed, 35 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/tc358767.c 
> b/drivers/gpu/drm/bridge/tc358767.c
> index b26c669f3e91..cbad2607ab43 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -244,8 +244,8 @@ struct tc_data {
>   struct drm_dp_aux   aux;
>  
>   struct drm_bridge   bridge;
> + struct drm_bridge   *panel_bridge;
>   struct drm_connectorconnector;
> - struct drm_panel*panel;
>  
>   /* link settings */
>   struct tc_edp_link  link;
> @@ -1234,13 +1234,6 @@ static int tc_stream_disable(struct tc_data *tc)
>   return 0;
>  }
>  
> -static void tc_bridge_pre_enable(struct drm_bridge *bridge)
> -{
> - struct tc_data *tc = bridge_to_tc(bridge);
> -
> - drm_panel_prepare(tc->panel);
> -}
> -
>  static void tc_bridge_enable(struct drm_bridge *bridge)
>  {
>   struct tc_data *tc = bridge_to_tc(bridge);
> @@ -1264,8 +1257,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
>   tc_main_link_disable(tc);
>   return;
>   }
> -
> - drm_panel_enable(tc->panel);
>  }
>  
>  static void tc_bridge_disable(struct drm_bridge *bridge)
> @@ -1273,8 +1264,6 @@ static void tc_bridge_disable(struct drm_bridge *bridge)
>   struct tc_data *tc = bridge_to_tc(bridge);
>   int ret;
>  
> - drm_panel_disable(tc->panel);
> -
>   ret = tc_stream_disable(tc);
>   if (ret < 0)
>   dev_err(tc->dev, "main link stream stop error: %d\n", ret);
> @@ -1284,13 +1273,6 @@ static void tc_bridge_disable(struct drm_bridge 
> *bridge)
>   dev_err(tc->dev, "main link disable error: %d\n", ret);
>  }
>  
> -static void tc_bridge_post_disable(struct drm_bridge *bridge)
> -{
> - struct tc_data *tc = bridge_to_tc(bridge);
> -
> - drm_panel_unprepare(tc->panel);
> -}
> -
>  static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
>const struct drm_display_mode *mode,
>struct drm_display_mode *adj)
> @@ -1354,9 +1336,11 @@ static int tc_connector_get_modes(struct drm_connector 
> *connector)
>   return 0;
>   }
>  
> - num_modes = drm_panel_get_modes(tc->panel, connector);
> - if (num_modes > 0)
> - return num_modes;
> + if (tc->panel_bridge) {
> + num_modes = drm_bridge_get_modes(tc->panel_bridge, connector);
> + if (num_modes > 0)
> + return num_modes;
> + }
>  
>   edid = tc_get_edid(&tc->bridge, connector);
>   num_modes = drm_add_edid_modes(connector, edid);
> @@ -1396,7 +1380,7 @@ tc_connector_detect(struct drm_connector *connector, 
> bool force)
>   if (tc->hpd_pin >= 0)
>   return tc_bridge_detect(&tc->bridge);
>  
> - if (tc->panel)
> + if (tc->panel_bridge)
>   return connector_status_connected;
>   else
>   return connector_status_unknown;
> @@ -1419,16 +1403,23 @@ static int tc_bridge_attach(struct drm_bridge *bridge,
>   struct drm_device *drm = bridge->dev;
>   int ret;
>  
> - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> - DRM_ERROR("Fix bridge driver to make connector optional!");
> - return -EINVAL;
> + if (tc->panel_bridge) {
> + enum drm_bridge_attach_flags panel_flags;
> +
> + /* If a connector is required then this driver shall create it 
> */
> + panel_flags = flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR;
> + ret = drm_bridge_attach(tc->bridge.encoder, tc->panel_bridge,
> + &tc->bridge, panel_flags);

You could write this

flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);

and drop the panel_flags variable.

Reviewed-by: Laurent Pinchart 

> + if (ret)
> +

Re: [PATCH 3/6] drm/bridge: Add SPI DBI host driver

2020-07-27 Thread Laurent Pinchart
Hi Paul,

Thank you for the patch.

On Mon, Jul 27, 2020 at 06:46:10PM +0200, Paul Cercueil wrote:
> This driver will register a DBI host driver for panels connected over
> SPI.
> 
> DBI types c1 and c3 are supported. C1 is a SPI protocol with 9 bits per
> word, with the data/command information in the 9th (MSB) bit. C3 is a
> SPI protocol with 8 bits per word, with the data/command information
> carried by a separate GPIO.
> 
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/bridge/Kconfig   |   8 +
>  drivers/gpu/drm/bridge/Makefile  |   1 +
>  drivers/gpu/drm/bridge/dbi-spi.c | 261 +++
>  3 files changed, 270 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/dbi-spi.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index c7f0dacfb57a..ed38366847c1 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -219,6 +219,14 @@ config DRM_TI_TPD12S015
> Texas Instruments TPD12S015 HDMI level shifter and ESD protection
> driver.
>  
> +config DRM_MIPI_DBI_SPI
> + tristate "SPI host support for MIPI DBI"
> + depends on OF && SPI
> + select DRM_MIPI_DSI
> + select DRM_MIPI_DBI
> + help
> +   Driver to support DBI over SPI.
> +
>  source "drivers/gpu/drm/bridge/analogix/Kconfig"
>  
>  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 7d7c123a95e4..c2c522c2774f 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
>  obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
>  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
>  obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
> +obj-$(CONFIG_DRM_MIPI_DBI_SPI) += dbi-spi.o
>  obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
>  
>  obj-y += analogix/
> diff --git a/drivers/gpu/drm/bridge/dbi-spi.c 
> b/drivers/gpu/drm/bridge/dbi-spi.c
> new file mode 100644
> index ..1060b8f95fba
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dbi-spi.c
> @@ -0,0 +1,261 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * MIPI Display Bus Interface (DBI) SPI support
> + *
> + * Copyright 2016 Noralf Trønnes
> + * Copyright 2020 Paul Cercueil 
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +struct dbi_spi {
> + struct mipi_dsi_host host;
> + struct mipi_dsi_host_ops host_ops;
> +
> + struct spi_device *spi;
> + struct gpio_desc *dc;
> + struct mutex cmdlock;
> +
> + unsigned int current_bus_type;
> +
> + /**
> +  * @tx_buf9: Buffer used for Option 1 9-bit conversion
> +  */
> + void *tx_buf9;
> +
> + /**
> +  * @tx_buf9_len: Size of tx_buf9.
> +  */
> + size_t tx_buf9_len;
> +};
> +
> +static inline struct dbi_spi *host_to_dbi_spi(struct mipi_dsi_host *host)
> +{
> + return container_of(host, struct dbi_spi, host);
> +}
> +
> +static ssize_t dbi_spi1_transfer(struct mipi_dsi_host *host,
> +  const struct mipi_dsi_msg *msg)
> +{
> + struct dbi_spi *dbi = host_to_dbi_spi(host);
> + struct spi_device *spi = dbi->spi;
> + struct spi_transfer tr = {
> + .bits_per_word = 9,
> + };
> + const u8 *src8 = msg->tx_buf;
> + struct spi_message m;
> + size_t max_chunk, chunk;
> + size_t len = msg->tx_len;
> + bool cmd_byte = true;
> + unsigned int i;
> + u16 *dst16;
> + int ret;
> +
> + tr.speed_hz = mipi_dbi_spi_cmd_max_speed(spi, len);
> + dst16 = dbi->tx_buf9;
> +
> + max_chunk = min(dbi->tx_buf9_len / 2, len);
> +
> + spi_message_init_with_transfers(&m, &tr, 1);
> + tr.tx_buf = dst16;
> +
> + while (len) {
> + chunk = min(len, max_chunk);
> +
> + for (i = 0; i < chunk; i++) {
> + dst16[i] = *src8++;
> +
> + /* Bit 9: 0 means command, 1 means data */
> + if (!cmd_byte)
> + dst16[i] |= BIT(9);
> +
> + cmd_byte = false;
> + }
> +
> + tr.len = chunk * 2;
> + len -= chunk;
> +
> + ret = spi_sync(spi, &m);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static ssize_t dbi_spi3_transfer(struct mipi_dsi_host *host,
> +  const struct mipi_dsi_msg *msg)
> +{
> + struct dbi_spi *dbi = host_to_dbi_spi(host);
> + struct spi_device *spi = dbi->spi;
> + const u8 *buf = msg->tx_buf;
> + unsigned int bpw = 8;
> + u32 speed_hz;
> + ssize_t ret;
> +
> + /* for now we only support sending messages, not receiving */
> + if (msg->rx_len)
> + return -EINVAL;
> +
> + gpiod_set_value_cansleep(dbi->dc, 0);
> +
> + speed_hz = mipi_dbi_spi_cmd_max_speed(spi

[PATCH v5 2/5] drm/bridge: tc358767: add get_edid bridge operation

2020-07-27 Thread Sam Ravnborg
Prepare for chained bridge with the addition of
get_edid support.

v2:
  - Fixed handling of edid storage (Laurent)

Signed-off-by: Sam Ravnborg 
Reviewed-by: Laurent Pinchart 
Cc: Andrzej Hajda 
Cc: Neil Armstrong 
Cc: Laurent Pinchart 
Cc: Jonas Karlman 
Cc: Jernej Skrabec 
---
 drivers/gpu/drm/bridge/tc358767.c | 34 ---
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c 
b/drivers/gpu/drm/bridge/tc358767.c
index bde89e213882..b26c669f3e91 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -250,8 +250,6 @@ struct tc_data {
/* link settings */
struct tc_edp_link  link;
 
-   /* display edid */
-   struct edid *edid;
/* current mode */
struct drm_display_mode mode;
 
@@ -1335,11 +1333,19 @@ static void tc_bridge_mode_set(struct drm_bridge 
*bridge,
tc->mode = *mode;
 }
 
+static struct edid *tc_get_edid(struct drm_bridge *bridge,
+   struct drm_connector *connector)
+{
+   struct tc_data *tc = bridge_to_tc(bridge);
+
+   return drm_get_edid(connector, &tc->aux.ddc);
+}
+
 static int tc_connector_get_modes(struct drm_connector *connector)
 {
struct tc_data *tc = connector_to_tc(connector);
+   int num_modes;
struct edid *edid;
-   int count;
int ret;
 
ret = tc_get_display_props(tc);
@@ -1348,21 +1354,15 @@ static int tc_connector_get_modes(struct drm_connector 
*connector)
return 0;
}
 
-   count = drm_panel_get_modes(tc->panel, connector);
-   if (count > 0)
-   return count;
-
-   edid = drm_get_edid(connector, &tc->aux.ddc);
-
-   kfree(tc->edid);
-   tc->edid = edid;
-   if (!edid)
-   return 0;
+   num_modes = drm_panel_get_modes(tc->panel, connector);
+   if (num_modes > 0)
+   return num_modes;
 
-   drm_connector_update_edid_property(connector, edid);
-   count = drm_add_edid_modes(connector, edid);
+   edid = tc_get_edid(&tc->bridge, connector);
+   num_modes = drm_add_edid_modes(connector, edid);
+   kfree(edid);
 
-   return count;
+   return num_modes;
 }
 
 static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
@@ -1465,6 +1465,7 @@ static const struct drm_bridge_funcs tc_bridge_funcs = {
.post_disable = tc_bridge_post_disable,
.mode_fixup = tc_bridge_mode_fixup,
.detect = tc_bridge_detect,
+   .get_edid = tc_get_edid,
 };
 
 static bool tc_readable_reg(struct device *dev, unsigned int reg)
@@ -1689,6 +1690,7 @@ static int tc_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
tc->bridge.funcs = &tc_bridge_funcs;
if (tc->hpd_pin >= 0)
tc->bridge.ops |= DRM_BRIDGE_OP_DETECT;
+   tc->bridge.ops |= DRM_BRIDGE_OP_EDID;
 
tc->bridge.of_node = dev->of_node;
drm_bridge_add(&tc->bridge);
-- 
2.25.1

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


[PATCH v5 0/5] drm/bridge: Update tc358767 and nxp-ptn3460 to support chained bridges

2020-07-27 Thread Sam Ravnborg
This patch-set aims to make connector creation optional
and prepare the bridge drivers for use in a chained setup.

The objective is that all bridge drivers shall support a chained setup
connector creation is moved to the display drivers.
This is just one step on this path.

The general approach for the bridge drivers:
- Introduce bridge operations
- Introduce use of panel bridge and make connector creation optional

v5:
  - Applied reviewed patches, so we went from 15 to 5
  - Fixed bug in connector creation in both drivers

v4:
  - Dropped patch for ti-sn65dsi86. Await full conversion
  - Dropped patch for ti-tpd12s015. It was wrong (Laurent)
  - Drop boe,hv070wsa-100 patch, it was applied
  - Combined a few patches to fix connector created twice (Laurent)
  - Fix memory leak in get_edid (Laurent)
  - Added patch to validate panel descriptions in panel-simple
  - Set bridge.type in relevant drivers
 
v3:
  - Rebase on top of drm-misc-next
  - Address kbuild test robot feedback
 
v2:
  - Updated bus_flags for boe,hv070wsa-100
  - Collected r-b, but did not apply patches yet
  - On the panel side the panel-simple driver gained a default
connector type for all the dumb panels that do not
include so in their description.
With this change panels always provide a connector type,
and we have the potential to drop most uses of
devm_drm_panel_bridge_add_typed().
  - Added conversion of a few more bridge drivers

Patches can build but no run-time testing.
So both test and review feedback appreciated!

Sam


Sam Ravnborg (5):
  drm/bridge: tc358767: add detect bridge operation
  drm/bridge: tc358767: add get_edid bridge operation
  drm/bridge: tc358767: add drm_panel_bridge support
  drm/bridge: nxp-ptn3460: add get_edid bridge operation
  drm/bridge: nxp-ptn3460: add drm_panel_bridge support

 drivers/gpu/drm/bridge/nxp-ptn3460.c | 103 +---
 drivers/gpu/drm/bridge/tc358767.c| 126 +++
 2 files changed, 114 insertions(+), 115 deletions(-)


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


[PATCH v5 5/5] drm/bridge: nxp-ptn3460: add drm_panel_bridge support

2020-07-27 Thread Sam Ravnborg
Prepare the bridge driver for use in a chained setup.

- Replacing direct use of drm_panel with drm_panel_bridge support.
- Make the connector creation optional

Note: the bridge panel will use the connector type from the panel.

v3:
  - Fix wrong logic in connector creation (Laurent)

v2:
  - Use panel_bridge for local variable name to align with other drivers
  - Fix that connector was created twice (Laurent)
  - Set bridge.type to DRM_MODE_CONNECTOR_LVDS.

Signed-off-by: Sam Ravnborg 
Cc: Andrzej Hajda 
Cc: Neil Armstrong 
Cc: Laurent Pinchart 
Cc: Jonas Karlman 
Cc: Jernej Skrabec 
---
 drivers/gpu/drm/bridge/nxp-ptn3460.c | 60 ++--
 1 file changed, 20 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c 
b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index 2805c8938f98..391c1f66f60f 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -29,7 +29,7 @@ struct ptn3460_bridge {
struct drm_connector connector;
struct i2c_client *client;
struct drm_bridge bridge;
-   struct drm_panel *panel;
+   struct drm_bridge *panel_bridge;
struct gpio_desc *gpio_pd_n;
struct gpio_desc *gpio_rst_n;
u32 edid_emulation;
@@ -126,11 +126,6 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
usleep_range(10, 20);
gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
 
-   if (drm_panel_prepare(ptn_bridge->panel)) {
-   DRM_ERROR("failed to prepare panel\n");
-   return;
-   }
-
/*
 * There's a bug in the PTN chip where it falsely asserts hotplug before
 * it is fully functional. We're forced to wait for the maximum start up
@@ -145,16 +140,6 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
ptn_bridge->enabled = true;
 }
 
-static void ptn3460_enable(struct drm_bridge *bridge)
-{
-   struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
-
-   if (drm_panel_enable(ptn_bridge->panel)) {
-   DRM_ERROR("failed to enable panel\n");
-   return;
-   }
-}
-
 static void ptn3460_disable(struct drm_bridge *bridge)
 {
struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
@@ -164,24 +149,10 @@ static void ptn3460_disable(struct drm_bridge *bridge)
 
ptn_bridge->enabled = false;
 
-   if (drm_panel_disable(ptn_bridge->panel)) {
-   DRM_ERROR("failed to disable panel\n");
-   return;
-   }
-
gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
gpiod_set_value(ptn_bridge->gpio_pd_n, 0);
 }
 
-static void ptn3460_post_disable(struct drm_bridge *bridge)
-{
-   struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
-
-   if (drm_panel_unprepare(ptn_bridge->panel)) {
-   DRM_ERROR("failed to unprepare panel\n");
-   return;
-   }
-}
 
 static struct edid *ptn3460_get_edid(struct drm_bridge *bridge,
 struct drm_connector *connector)
@@ -245,12 +216,18 @@ static int ptn3460_bridge_attach(struct drm_bridge 
*bridge,
 enum drm_bridge_attach_flags flags)
 {
struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
+   enum drm_bridge_attach_flags panel_flags;
int ret;
 
-   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-   DRM_ERROR("Fix bridge driver to make connector optional!");
-   return -EINVAL;
-   }
+   /* Let this driver create connector if requested */
+   panel_flags = flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR;
+   ret = drm_bridge_attach(bridge->encoder, ptn_bridge->panel_bridge,
+   bridge, panel_flags);
+   if (ret < 0)
+   return ret;
+
+   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+   return 0;
 
if (!bridge->encoder) {
DRM_ERROR("Parent encoder object not found");
@@ -270,9 +247,6 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge,
drm_connector_attach_encoder(&ptn_bridge->connector,
bridge->encoder);
 
-   if (ptn_bridge->panel)
-   drm_panel_attach(ptn_bridge->panel, &ptn_bridge->connector);
-
drm_helper_hpd_irq_event(ptn_bridge->connector.dev);
 
return ret;
@@ -280,9 +254,7 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge,
 
 static const struct drm_bridge_funcs ptn3460_bridge_funcs = {
.pre_enable = ptn3460_pre_enable,
-   .enable = ptn3460_enable,
.disable = ptn3460_disable,
-   .post_disable = ptn3460_post_disable,
.attach = ptn3460_bridge_attach,
.get_edid = ptn3460_get_edid,
 };
@@ -292,6 +264,8 @@ static int ptn3460_probe(struct i2c_client *client,
 {
struct device *dev = &client->dev;
struct ptn3460_bridge *ptn_bridge;
+   struct drm_bridge *panel_br

[PATCH v5 3/5] drm/bridge: tc358767: add drm_panel_bridge support

2020-07-27 Thread Sam Ravnborg
With the bridge operations implemented the last step to prepare
this driver for a chained setup is the use of the bridge panel driver.

The bridge panel driver is only used when a port@2 is present in
the DT. So when the display driver requests a connector
support both situations:
- connector created by bridge panel driver
- connector created by this driver

And on top, support that the display driver creates the connector,
which is the preferred setup.

Note: the bridge panel will use the connector type from the panel.

v3:
  - Fix wrong logic in connector creation (Laurent)

v2:
  - Merge connector and drm_panel_bridge patches
and fix so we do not create two connectors (Laurent)

Signed-off-by: Sam Ravnborg 
Cc: Laurent Pinchart 
Cc: Andrzej Hajda 
Cc: Neil Armstrong 
Cc: Jonas Karlman 
Cc: Jernej Skrabec 
---
 drivers/gpu/drm/bridge/tc358767.c | 70 +++
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c 
b/drivers/gpu/drm/bridge/tc358767.c
index b26c669f3e91..cbad2607ab43 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -244,8 +244,8 @@ struct tc_data {
struct drm_dp_aux   aux;
 
struct drm_bridge   bridge;
+   struct drm_bridge   *panel_bridge;
struct drm_connectorconnector;
-   struct drm_panel*panel;
 
/* link settings */
struct tc_edp_link  link;
@@ -1234,13 +1234,6 @@ static int tc_stream_disable(struct tc_data *tc)
return 0;
 }
 
-static void tc_bridge_pre_enable(struct drm_bridge *bridge)
-{
-   struct tc_data *tc = bridge_to_tc(bridge);
-
-   drm_panel_prepare(tc->panel);
-}
-
 static void tc_bridge_enable(struct drm_bridge *bridge)
 {
struct tc_data *tc = bridge_to_tc(bridge);
@@ -1264,8 +1257,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
tc_main_link_disable(tc);
return;
}
-
-   drm_panel_enable(tc->panel);
 }
 
 static void tc_bridge_disable(struct drm_bridge *bridge)
@@ -1273,8 +1264,6 @@ static void tc_bridge_disable(struct drm_bridge *bridge)
struct tc_data *tc = bridge_to_tc(bridge);
int ret;
 
-   drm_panel_disable(tc->panel);
-
ret = tc_stream_disable(tc);
if (ret < 0)
dev_err(tc->dev, "main link stream stop error: %d\n", ret);
@@ -1284,13 +1273,6 @@ static void tc_bridge_disable(struct drm_bridge *bridge)
dev_err(tc->dev, "main link disable error: %d\n", ret);
 }
 
-static void tc_bridge_post_disable(struct drm_bridge *bridge)
-{
-   struct tc_data *tc = bridge_to_tc(bridge);
-
-   drm_panel_unprepare(tc->panel);
-}
-
 static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
 const struct drm_display_mode *mode,
 struct drm_display_mode *adj)
@@ -1354,9 +1336,11 @@ static int tc_connector_get_modes(struct drm_connector 
*connector)
return 0;
}
 
-   num_modes = drm_panel_get_modes(tc->panel, connector);
-   if (num_modes > 0)
-   return num_modes;
+   if (tc->panel_bridge) {
+   num_modes = drm_bridge_get_modes(tc->panel_bridge, connector);
+   if (num_modes > 0)
+   return num_modes;
+   }
 
edid = tc_get_edid(&tc->bridge, connector);
num_modes = drm_add_edid_modes(connector, edid);
@@ -1396,7 +1380,7 @@ tc_connector_detect(struct drm_connector *connector, bool 
force)
if (tc->hpd_pin >= 0)
return tc_bridge_detect(&tc->bridge);
 
-   if (tc->panel)
+   if (tc->panel_bridge)
return connector_status_connected;
else
return connector_status_unknown;
@@ -1419,16 +1403,23 @@ static int tc_bridge_attach(struct drm_bridge *bridge,
struct drm_device *drm = bridge->dev;
int ret;
 
-   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-   DRM_ERROR("Fix bridge driver to make connector optional!");
-   return -EINVAL;
+   if (tc->panel_bridge) {
+   enum drm_bridge_attach_flags panel_flags;
+
+   /* If a connector is required then this driver shall create it 
*/
+   panel_flags = flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR;
+   ret = drm_bridge_attach(tc->bridge.encoder, tc->panel_bridge,
+   &tc->bridge, panel_flags);
+   if (ret)
+   return ret;
}
 
+   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+   return 0;
+
/* Create DP/eDP connector */
drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs);
-   ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs,
-tc->panel ? DRM_MODE_CONNECTOR_eDP :
-DRM_MODE_CONNECTOR_Displ

[PATCH v5 1/5] drm/bridge: tc358767: add detect bridge operation

2020-07-27 Thread Sam Ravnborg
Prepare the bridge driver for chained operation by adding
support for the detect operation.

v3:
  - Fix code to make it readable (Laurent)

v2:
  - Do not announce detect operation if there is no hpd pin (Laurent)

Signed-off-by: Sam Ravnborg 
Reviewed-by: Laurent Pinchart 
Cc: Andrzej Hajda 
Cc: Neil Armstrong 
Cc: Laurent Pinchart 
Cc: Jonas Karlman 
Cc: Jernej Skrabec 
---
 drivers/gpu/drm/bridge/tc358767.c | 30 --
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c 
b/drivers/gpu/drm/bridge/tc358767.c
index c2777b226c75..bde89e213882 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1369,21 +1369,13 @@ static const struct drm_connector_helper_funcs 
tc_connector_helper_funcs = {
.get_modes = tc_connector_get_modes,
 };
 
-static enum drm_connector_status tc_connector_detect(struct drm_connector 
*connector,
-bool force)
+static enum drm_connector_status tc_bridge_detect(struct drm_bridge *bridge)
 {
-   struct tc_data *tc = connector_to_tc(connector);
+   struct tc_data *tc = bridge_to_tc(bridge);
bool conn;
u32 val;
int ret;
 
-   if (tc->hpd_pin < 0) {
-   if (tc->panel)
-   return connector_status_connected;
-   else
-   return connector_status_unknown;
-   }
-
ret = regmap_read(tc->regmap, GPIOI, &val);
if (ret)
return connector_status_unknown;
@@ -1396,6 +1388,20 @@ static enum drm_connector_status 
tc_connector_detect(struct drm_connector *conne
return connector_status_disconnected;
 }
 
+static enum drm_connector_status
+tc_connector_detect(struct drm_connector *connector, bool force)
+{
+   struct tc_data *tc = connector_to_tc(connector);
+
+   if (tc->hpd_pin >= 0)
+   return tc_bridge_detect(&tc->bridge);
+
+   if (tc->panel)
+   return connector_status_connected;
+   else
+   return connector_status_unknown;
+}
+
 static const struct drm_connector_funcs tc_connector_funcs = {
.detect = tc_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1458,6 +1464,7 @@ static const struct drm_bridge_funcs tc_bridge_funcs = {
.disable = tc_bridge_disable,
.post_disable = tc_bridge_post_disable,
.mode_fixup = tc_bridge_mode_fixup,
+   .detect = tc_bridge_detect,
 };
 
 static bool tc_readable_reg(struct device *dev, unsigned int reg)
@@ -1680,6 +1687,9 @@ static int tc_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
return ret;
 
tc->bridge.funcs = &tc_bridge_funcs;
+   if (tc->hpd_pin >= 0)
+   tc->bridge.ops |= DRM_BRIDGE_OP_DETECT;
+
tc->bridge.of_node = dev->of_node;
drm_bridge_add(&tc->bridge);
 
-- 
2.25.1

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


[PATCH v5 4/5] drm/bridge: nxp-ptn3460: add get_edid bridge operation

2020-07-27 Thread Sam Ravnborg
Add the get_edid() bridge operation to prepare for
use as a chained bridge.
Add helper function that is also used by the connector.

v2:
  - Fix memory leak (Laurent)
  - Do not save a copy of edid, read it when needed

Signed-off-by: Sam Ravnborg 
Reviewed-by: Laurent Pinchart 
Cc: Andrzej Hajda 
Cc: Neil Armstrong 
Cc: Laurent Pinchart 
Cc: Jonas Karlman 
Cc: Jernej Skrabec 
---
 drivers/gpu/drm/bridge/nxp-ptn3460.c | 43 
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c 
b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index 438e566ce0a4..2805c8938f98 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -29,7 +29,6 @@ struct ptn3460_bridge {
struct drm_connector connector;
struct i2c_client *client;
struct drm_bridge bridge;
-   struct edid *edid;
struct drm_panel *panel;
struct gpio_desc *gpio_pd_n;
struct gpio_desc *gpio_rst_n;
@@ -184,17 +183,13 @@ static void ptn3460_post_disable(struct drm_bridge 
*bridge)
}
 }
 
-static int ptn3460_get_modes(struct drm_connector *connector)
+static struct edid *ptn3460_get_edid(struct drm_bridge *bridge,
+struct drm_connector *connector)
 {
-   struct ptn3460_bridge *ptn_bridge;
-   u8 *edid;
-   int ret, num_modes = 0;
+   struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
bool power_off;
-
-   ptn_bridge = connector_to_ptn3460(connector);
-
-   if (ptn_bridge->edid)
-   return drm_add_edid_modes(connector, ptn_bridge->edid);
+   u8 *edid;
+   int ret;
 
power_off = !ptn_bridge->enabled;
ptn3460_pre_enable(&ptn_bridge->bridge);
@@ -202,30 +197,40 @@ static int ptn3460_get_modes(struct drm_connector 
*connector)
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
if (!edid) {
DRM_ERROR("Failed to allocate EDID\n");
-   return 0;
+   goto out;
}
 
ret = ptn3460_read_bytes(ptn_bridge, PTN3460_EDID_ADDR, edid,
-   EDID_LENGTH);
+EDID_LENGTH);
if (ret) {
kfree(edid);
+   edid = NULL;
goto out;
}
 
-   ptn_bridge->edid = (struct edid *)edid;
-   drm_connector_update_edid_property(connector, ptn_bridge->edid);
-
-   num_modes = drm_add_edid_modes(connector, ptn_bridge->edid);
-
 out:
if (power_off)
ptn3460_disable(&ptn_bridge->bridge);
 
+   return (struct edid *)edid;
+}
+
+static int ptn3460_connector_get_modes(struct drm_connector *connector)
+{
+   struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector);
+   struct edid *edid;
+   int num_modes;
+
+   edid = ptn3460_get_edid(&ptn_bridge->bridge, connector);
+   drm_connector_update_edid_property(connector, edid);
+   num_modes = drm_add_edid_modes(connector, edid);
+   kfree(edid);
+
return num_modes;
 }
 
 static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs 
= {
-   .get_modes = ptn3460_get_modes,
+   .get_modes = ptn3460_connector_get_modes,
 };
 
 static const struct drm_connector_funcs ptn3460_connector_funcs = {
@@ -279,6 +284,7 @@ static const struct drm_bridge_funcs ptn3460_bridge_funcs = 
{
.disable = ptn3460_disable,
.post_disable = ptn3460_post_disable,
.attach = ptn3460_bridge_attach,
+   .get_edid = ptn3460_get_edid,
 };
 
 static int ptn3460_probe(struct i2c_client *client,
@@ -327,6 +333,7 @@ static int ptn3460_probe(struct i2c_client *client,
}
 
ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
+   ptn_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
ptn_bridge->bridge.of_node = dev->of_node;
drm_bridge_add(&ptn_bridge->bridge);
 
-- 
2.25.1

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


Re: [PATCH 2/6] drm: dsi: Let host and device specify supported bus

2020-07-27 Thread Laurent Pinchart
Hi Paul,

Thank you for the patch.

On Mon, Jul 27, 2020 at 06:46:09PM +0200, Paul Cercueil wrote:
> The current MIPI DSI framework can very well be used to support MIPI DBI
> panels. In order to add support for the various bus types supported by
> DBI, the DRM panel drivers should specify the bus type they will use,
> and the DSI host drivers should specify the bus types they are
> compatible with.
> 
> The DSI host driver can then use the information provided by the DBI/DSI
> device driver, such as the bus type and the number of lanes, to
> configure its hardware properly.
> 
> Signed-off-by: Paul Cercueil 
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c |  9 +
>  include/drm/drm_mipi_dsi.h | 12 

Use the mipi_dsi_* API for DBI panels will be very confusing to say the
least. Can we consider a global name refactoring to clarify all this ?

>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index 5dd475e82995..11ef885de765 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -281,6 +281,9 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host)
>  {
>   struct device_node *node;
>  
> + if (WARN_ON_ONCE(!host->bus_types))
> + host->bus_types = MIPI_DEVICE_TYPE_DSI;
> +
>   for_each_available_child_of_node(host->dev->of_node, node) {
>   /* skip nodes without reg property */
>   if (!of_find_property(node, "reg", NULL))
> @@ -323,6 +326,12 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi)
>  {
>   const struct mipi_dsi_host_ops *ops = dsi->host->ops;
>  
> + if (WARN_ON_ONCE(!dsi->bus_type))
> + dsi->bus_type = MIPI_DEVICE_TYPE_DSI;
> +
> + if (!(dsi->bus_type & dsi->host->bus_types))
> + return -EINVAL;
> +
>   if (!ops || !ops->attach)
>   return -ENOSYS;
>  
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 360e6377e84b..65d2961fc054 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -63,6 +63,14 @@ struct mipi_dsi_packet {
>  int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
>  const struct mipi_dsi_msg *msg);
>  
> +/* MIPI bus types */
> +#define MIPI_DEVICE_TYPE_DSI BIT(0)
> +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE1   BIT(1)
> +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE2   BIT(2)
> +#define MIPI_DEVICE_TYPE_DBI_SPI_MODE3   BIT(3)
> +#define MIPI_DEVICE_TYPE_DBI_M6800   BIT(4)
> +#define MIPI_DEVICE_TYPE_DBI_I8080   BIT(5)
> +
>  /**
>   * struct mipi_dsi_host_ops - DSI bus operations
>   * @attach: attach DSI device to DSI host
> @@ -94,11 +102,13 @@ struct mipi_dsi_host_ops {
>   * struct mipi_dsi_host - DSI host device
>   * @dev: driver model device node for this DSI host
>   * @ops: DSI host operations
> + * @bus_types: Bitmask of supported MIPI bus types
>   * @list: list management
>   */
>  struct mipi_dsi_host {
>   struct device *dev;
>   const struct mipi_dsi_host_ops *ops;
> + unsigned int bus_types;
>   struct list_head list;
>  };
>  
> @@ -162,6 +172,7 @@ struct mipi_dsi_device_info {
>   * @host: DSI host for this peripheral
>   * @dev: driver model device node for this peripheral
>   * @name: DSI peripheral chip type
> + * @bus_type: MIPI bus type (MIPI_DEVICE_TYPE_DSI/...)
>   * @channel: virtual channel assigned to the peripheral
>   * @format: pixel format for video mode
>   * @lanes: number of active data lanes
> @@ -178,6 +189,7 @@ struct mipi_dsi_device {
>   struct device dev;
>  
>   char name[DSI_DEV_NAME_SIZE];
> + unsigned int bus_type;
>   unsigned int channel;
>   unsigned int lanes;
>   enum mipi_dsi_pixel_format format;

-- 
Regards,

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


Re: [PATCH v4 0/15] drm/bridge: support chained bridges + panel updates

2020-07-27 Thread Sam Ravnborg
Hi Laurent/all.

On Sun, Jul 26, 2020 at 10:33:09PM +0200, Sam Ravnborg wrote:
> The objective is that all bridge drivers shall support a chained setup
> connector creation is moved to the display drivers.
> This is just one step on this path.
> 
> The general approach for the bridge drivers:
> - Introduce bridge operations
> - Introduce use of panel bridge and make connector creation optional
> 
> v4:
>   - Dropped patch for ti-sn65dsi86. Await full conversion.
>   - Dropped patch for ti-tpd12s015. It was wrong (Laurent)
>   - Drop boe,hv070wsa-100 patch, it was applied
>   - Combined a few patches to fix connector created twice (Laurent)
>   - Fix memory leak in get_edid in several drivers (Laurent)
>   - Added patch to validate panel descriptions in panel-simple
>   - Set bridge.type in relevant drivers
>  
> v3:
>   - Rebase on top of drm-misc-next
>   - Address kbuild test robot feedback
>  
> v2:
>   - Updated bus_flags for boe,hv070wsa-100
>   - Collected r-b, but did not apply patches yet
>   - On the panel side the panel-simple driver gained a default
> connector type for all the dumb panels that do not
> include so in their description.
> With this change panels always provide a connector type,
> and we have the potential to drop most uses of
> devm_drm_panel_bridge_add_typed().
>   - Added conversion of a few more bridge drivers
> 
> Patches can build but no run-time testing.
> So both test and review feedback appreciated!
> 
>   Sam
> 
> Sam Ravnborg (15):
>   drm/panel: panel-simple: validate panel description
>   drm/panel: panel-simple: add default connector_type
>   drm/bridge: tc358764: drop drm_connector_(un)register
>   drm/bridge: tc358764: add drm_panel_bridge support
>   drm/bridge: tc358767: add detect bridge operation
>   drm/bridge: tc358767: add get_edid bridge operation
>   drm/bridge: tc358767: add drm_panel_bridge support
>   drm/bridge: parade-ps8622: add drm_panel_bridge support
>   drm/bridge: megachips: add helper to create connector
>   drm/bridge: megachips: get drm_device from bridge
>   drm/bridge: megachips: enable detect bridge operation
>   drm/bridge: megachips: add get_edid bridge operation
>   drm/bridge: megachips: make connector creation optional
>   drm/bridge: nxp-ptn3460: add get_edid bridge operation
>   drm/bridge: nxp-ptn3460: add drm_panel_bridge support

Laurent reviewed the full series - thanks!
I went ahead and applied the patches for drivers where all
patches was reviewed.

I will send a v5 soon for tc358767 and nxp-ptn3460 where I have fixed
my brown paper bag bugs
.
I am very happy Laurent spotted these before we applied the patches.
This also gives a good indication of the quality of the review.

Sam

> 
>  .../drm/bridge/megachips-stdp-ge-b850v3-fw.c   |  97 +---
>  drivers/gpu/drm/bridge/nxp-ptn3460.c   | 103 -
>  drivers/gpu/drm/bridge/parade-ps8622.c | 100 +++-
>  drivers/gpu/drm/bridge/tc358764.c  | 110 +++---
>  drivers/gpu/drm/bridge/tc358767.c  | 126 
> +++--
>  drivers/gpu/drm/panel/panel-simple.c   |  48 +++-
>  6 files changed, 242 insertions(+), 342 deletions(-)
> 
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 207383] [Regression] 5.7 amdgpu/polaris11 gpf: amdgpu_atomic_commit_tail

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207383

--- Comment #101 from Duncan (1i5t5.dun...@cox.net) ---
(In reply to Nicholas Kazlauskas from comment #95)
> Created attachment 290583 [details]
> 0001-drm-amd-display-Force-add-all-CRTCs-to-state-when-us.patch

Just booted to 5.8-rc7 with this patched in locally (and the g320+ reverts
/not/ patched in).  So testing, but noting again that the bug can take a couple
days to trigger on my hardware, so while verifying bug-still-there /might/ be
fast, verifying that it's /not/ there will take awhile.

If this still bugs on me (and barring other developments first) I'll try
mnrzk's patch in place of this one.  Even if it's not permanent, getting it
into 5.8 as a temporary fix and doing something better for 5.9 would buy us
some time to develop and test the more permanent fix.

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


[Bug 204241] amdgpu fails to resume from suspend

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=204241

--- Comment #64 from felipejfc (fjfcavalca...@gmail.com) ---
(In reply to felipejfc from comment #63)
> I'm having the same issue with an AMD RX5700 and kernel version 5.7.9-1 on
> manjaro linux.
> 
> for me adding kernel params 'amd_iommu=on iommu=pt' didn't solve the
> problem. graphics won't turn on so monitor just keeps blinking

complementing my last answer, the "fix" that worked for me was to disable IOMMU
on BIOS

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


[Bug 204241] amdgpu fails to resume from suspend

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=204241

felipejfc (fjfcavalca...@gmail.com) changed:

   What|Removed |Added

 CC||fjfcavalca...@gmail.com

--- Comment #63 from felipejfc (fjfcavalca...@gmail.com) ---
I'm having the same issue with an AMD RX5700 and kernel version 5.7.9-1 on
manjaro linux.

for me adding kernel params 'amd_iommu=on iommu=pt' didn't solve the problem.
graphics won't turn on so monitor just keeps blinking

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


[Bug 207901] Nouveau: In a 4 monitor setup, 1-2 displays remains black after boot

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207901

--- Comment #27 from Ilia Mirkin (imir...@alum.mit.edu) ---
DP -> HDMI is, most likely, just passive, so the displays are being driven as
HDMI rather than as DP. DP is the problematic protocol...

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


[Bug 207901] Nouveau: In a 4 monitor setup, 1-2 displays remains black after boot

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207901

--- Comment #26 from Maurice Gale (mauricega...@gmail.com) ---
Sorry for the delay and the mistake. It loaded the 5.3 kernel by default. I
recreated the log using 5.7-rc5 with the i2c timeout patch. I also added the
new grub options. The file size is much larger than the old one, so it should
be correct this time.

I noticed that I have more luck getting all monitors displayed when I do not
have the Display->MiniDisplay connected (Swap it out for Display->HDMI). It
seems as though mini display is causing some issues.

Again, thank you so much for your help, and please let me know if you need
anything else.

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


Re: [PATCH v4 08/15] drm/bridge: parade-ps8622: add drm_panel_bridge support

2020-07-27 Thread Sam Ravnborg
Hi Laurent.

On Mon, Jul 27, 2020 at 12:54:08AM +0300, Laurent Pinchart wrote:
> Hi Sam,
> 
> Thank you for the patch.
> 
> On Sun, Jul 26, 2020 at 10:33:17PM +0200, Sam Ravnborg wrote:
> > Prepare the bridge driver for use in a chained setup by
> > replacing direct use of drm_panel with drm_panel_bridge support.
> > 
> > The connecter is now either created by the panel bridge or the display
> > driver. So all code for connector creation in this driver is no longer
> > relevant and thus dropped.
> > 
> > The connector code had some special polling handling:
> > connector.polled = DRM_CONNECTOR_POLL_HPD;
> > drm_helper_hpd_irq_event(ps8622->bridge.dev);
> > 
> > This code was most likely added to speed up detection of the connector.
> > If really needed then this functionality belongs somewhere else.
> > 
> > Note: the bridge panel will use the connector type from the panel.
> > 
> > v2:
> >   - Fix to avoid creating connector twice (Laurent)
> >   - Drop all connector code - defer to bridge panel
> >   - Use panel_bridge for local variable to align with other drivers
> >   - Set bridge.type to DRM_MODE_CONNECTOR_LVDS;
> > 
> > Signed-off-by: Sam Ravnborg 
> > Cc: Andrzej Hajda 
> > Cc: Neil Armstrong 
> > Cc: Laurent Pinchart 
> > Cc: Jonas Karlman 
> > Cc: Jernej Skrabec 
> > ---
> >  drivers/gpu/drm/bridge/parade-ps8622.c | 100 -
> >  1 file changed, 13 insertions(+), 87 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c 
> > b/drivers/gpu/drm/bridge/parade-ps8622.c
> > index d789ea2a7fb9..614b19f0f1b7 100644
> > --- a/drivers/gpu/drm/bridge/parade-ps8622.c
> > +++ b/drivers/gpu/drm/bridge/parade-ps8622.c
> > @@ -42,10 +42,9 @@
> >  #endif
> >  
> >  struct ps8622_bridge {
> > -   struct drm_connector connector;
> > struct i2c_client *client;
> > struct drm_bridge bridge;
> > -   struct drm_panel *panel;
> > +   struct drm_bridge *panel_bridge;
> > struct regulator *v12;
> > struct backlight_device *bl;
> >  
> > @@ -64,12 +63,6 @@ static inline struct ps8622_bridge *
> > return container_of(bridge, struct ps8622_bridge, bridge);
> >  }
> >  
> > -static inline struct ps8622_bridge *
> > -   connector_to_ps8622(struct drm_connector *connector)
> > -{
> > -   return container_of(connector, struct ps8622_bridge, connector);
> > -}
> > -
> >  static int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val)
> >  {
> > int ret;
> > @@ -365,11 +358,6 @@ static void ps8622_pre_enable(struct drm_bridge 
> > *bridge)
> > DRM_ERROR("fails to enable ps8622->v12");
> > }
> >  
> > -   if (drm_panel_prepare(ps8622->panel)) {
> > -   DRM_ERROR("failed to prepare panel\n");
> > -   return;
> > -   }
> > -
> > gpiod_set_value(ps8622->gpio_slp, 1);
> >  
> > /*
> > @@ -399,24 +387,9 @@ static void ps8622_pre_enable(struct drm_bridge 
> > *bridge)
> > ps8622->enabled = true;
> >  }
> >  
> > -static void ps8622_enable(struct drm_bridge *bridge)
> > -{
> > -   struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge);
> > -
> > -   if (drm_panel_enable(ps8622->panel)) {
> > -   DRM_ERROR("failed to enable panel\n");
> > -   return;
> > -   }
> > -}
> > -
> >  static void ps8622_disable(struct drm_bridge *bridge)
> >  {
> > -   struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge);
> > -
> > -   if (drm_panel_disable(ps8622->panel)) {
> > -   DRM_ERROR("failed to disable panel\n");
> > -   return;
> > -   }
> > +   /* Delay after panel is disabled */
> > msleep(PS8622_PWMO_END_T12_MS);
> 
> I really don't understand why a delay would be needed here.
>
Neither do I. I was there in the original code and I have kept it.

> Reviewed-by: Laurent Pinchart 
Thanks.

Sam

> 
> >  }
> >  
> > @@ -436,11 +409,6 @@ static void ps8622_post_disable(struct drm_bridge 
> > *bridge)
> >  */
> > gpiod_set_value(ps8622->gpio_slp, 0);
> >  
> > -   if (drm_panel_unprepare(ps8622->panel)) {
> > -   DRM_ERROR("failed to unprepare panel\n");
> > -   return;
> > -   }
> > -
> > if (ps8622->v12)
> > regulator_disable(ps8622->v12);
> >  
> > @@ -455,67 +423,17 @@ static void ps8622_post_disable(struct drm_bridge 
> > *bridge)
> > msleep(PS8622_POWER_OFF_T17_MS);
> >  }
> >  
> > -static int ps8622_get_modes(struct drm_connector *connector)
> > -{
> > -   struct ps8622_bridge *ps8622;
> > -
> > -   ps8622 = connector_to_ps8622(connector);
> > -
> > -   return drm_panel_get_modes(ps8622->panel, connector);
> > -}
> > -
> > -static const struct drm_connector_helper_funcs 
> > ps8622_connector_helper_funcs = {
> > -   .get_modes = ps8622_get_modes,
> > -};
> > -
> > -static const struct drm_connector_funcs ps8622_connector_funcs = {
> > -   .fill_modes = drm_helper_probe_single_connector_modes,
> > -   .destroy = drm_connector_cleanup,
> > -   .reset = drm_atomic_helper_connector_reset,
> > -   .atomic_duplicate_state = 

[Bug 208661] Backlight doesn't work with both nv_backlight and acpi_video

2020-07-27 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=208661

--- Comment #7 from Shannon Gaines (iknstu...@protonmail.com) ---
Created attachment 290619
  --> https://bugzilla.kernel.org/attachment.cgi?id=290619&action=edit
Patch to add NvForceGpioReset config option

I created a patch that allows users to force a GPIO reset everytime the GPU is
initialized as a work-around for this bug. I've attached it.

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


Re: [PATCH v3 4/4] xen: add helpers to allocate unpopulated memory

2020-07-27 Thread Jürgen Groß

On 27.07.20 11:13, Roger Pau Monne wrote:

To be used in order to create foreign mappings. This is based on the
ZONE_DEVICE facility which is used by persistent memory devices in
order to create struct pages and kernel virtual mappings for the IOMEM
areas of such devices. Note that on kernels without support for
ZONE_DEVICE Xen will fallback to use ballooned pages in order to
create foreign mappings.

The newly added helpers use the same parameters as the existing
{alloc/free}_xenballooned_pages functions, which allows for in-place
replacement of the callers. Once a memory region has been added to be
used as scratch mapping space it will no longer be released, and pages
returned are kept in a linked list. This allows to have a buffer of
pages and prevents resorting to frequent additions and removals of
regions.

If enabled (because ZONE_DEVICE is supported) the usage of the new
functionality untangles Xen balloon and RAM hotplug from the usage of
unpopulated physical memory ranges to map foreign pages, which is the
correct thing to do in order to avoid mappings of foreign pages depend
on memory hotplug.

Signed-off-by: Roger Pau Monné 
---
I've not added a new memory_type type and just used
MEMORY_DEVICE_DEVDAX which seems to be what we want for such memory
regions. I'm unsure whether abusing this type is fine, or if I should
instead add a specific type, maybe MEMORY_DEVICE_GENERIC? I don't
think we should be using a specific Xen type at all.


What about introducing MEMORY_DEVICE_VIRT? The comment for
MEMORY_DEVICE_DEVDAX doesn't really fit, as there is no character device
involved.

In the end its the memory management maintainers to decide that.

Other than that you can have my

Reviewed-by: Juergen Gross 


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


Re: [PATCH v2] drm/drm_fb_helper: fix fbdev with sparc64

2020-07-27 Thread Sam Ravnborg
Hi Daniel

On Mon, Jul 27, 2020 at 11:20:13AM +0200, Daniel Vetter wrote:
> On Sat, Jul 25, 2020 at 9:10 PM Sam Ravnborg  wrote:
> >
> > From 1323a7433691aee112a9b2df8041b5024895a77e Mon Sep 17 00:00:00 2001
> > From: Sam Ravnborg 
> > Date: Thu, 9 Jul 2020 21:30:16 +0200
> > Subject: [PATCH v2 1/1] drm/drm_fb_helper: fix fbdev with sparc64
> >
> > Recent kernels have been reported to panic using the bochs_drm framebuffer 
> > under
> > qemu-system-sparc64 which was bisected to commit 7a0483ac4ffc "drm/bochs: 
> > switch to
> > generic drm fbdev emulation". The backtrace indicates that the shadow 
> > framebuffer
> > copy in drm_fb_helper_dirty_blit_real() is trying to access the real 
> > framebuffer
> > using a virtual address rather than use an IO access typically implemented 
> > using a
> > physical (ASI_PHYS) access on SPARC.
> >
> > The fix is to replace the memcpy with memcpy_toio() from io.h.
> >
> > memcpy_toio() uses writeb() where the original fbdev code
> > used sbus_memcpy_toio(). The latter uses sbus_writeb().
> >
> > The difference between writeb() and sbus_memcpy_toio() is
> > that writeb() writes bytes in little-endian, where sbus_writeb() writes
> > bytes in big-endian. As endian does not matter for byte writes they are
> > the same. So we can safely use memcpy_toio() here.
> >
> > For many architectures memcpy_toio() is a simple memcpy().
> > One side-effect that is unknown is if this has any impact on other
> > architectures.
> > So far the analysis tells that this change is OK for other arch's.
> > but testing would be good.
> 
> The rules are that officially we have to use the io functions for
> __mmio pointers. We just drop these sparse annotations on the floor.
> I'd replace this with something like:
> 
> "Note that this only fixes bochs, in general fbdev helpers still have
> issues with mixing up system memory and mmio space. Fixing that will
> require a lot more work."
OK, done.

> 
> > v2:
> >   - Added missing __iomem cast (kernel test robot)
> >   - Made changelog readable and fix typos (Mark)
> >   - Add flag to select iomem - and set it in the bochs driver
> >
> > Signed-off-by: Sam Ravnborg 
> > Reported-by: Mark Cave-Ayland 
> > Reported-by: kernel test robot 
> > Tested-by: Mark Cave-Ayland 
> > Cc: Mark Cave-Ayland 
> > Cc: Thomas Zimmermann 
> > Cc: Gerd Hoffmann 
> > Cc: "David S. Miller" 
> > Cc: sparcli...@vger.kernel.org
> > Link: 
> > https://patchwork.freedesktop.org/patch/msgid/20200709193016.291267-1-...@ravnborg.org
> > ---
> >
> > This fix introducing a flag in mode_config is at best a band-aid
> > solution until we have a proper fix.
> > We need to propagate the info about iomem so it is not a driver flag
> > thing.
> >
> > There is also the issue with sys* versus cfb* functions, where cfb*
> > functions are used for iomem.
> > I did not manage to make the bochs driver work with the cfb* functions,
> > for some unknown reason booting would be stuck waiting for the console
> > mutex when usign the cfb* functions.
> >
> > I consider this fix OK to get the kernel working for sparc64 with the
> > bochs driver for now. And with the fbdev_uses_iomem flag no other
> > drivers will see any changes.
> >
> > Sam
> >
> >  drivers/gpu/drm/bochs/bochs_kms.c | 1 +
> >  drivers/gpu/drm/drm_fb_helper.c   | 6 +-
> >  include/drm/drm_mode_config.h | 9 +
> >  3 files changed, 15 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
> > b/drivers/gpu/drm/bochs/bochs_kms.c
> > index 05d8373888e8..079f46f5cdb6 100644
> > --- a/drivers/gpu/drm/bochs/bochs_kms.c
> > +++ b/drivers/gpu/drm/bochs/bochs_kms.c
> > @@ -146,6 +146,7 @@ int bochs_kms_init(struct bochs_device *bochs)
> > bochs->dev->mode_config.preferred_depth = 24;
> > bochs->dev->mode_config.prefer_shadow = 0;
> > bochs->dev->mode_config.prefer_shadow_fbdev = 1;
> > +   bochs->dev->mode_config.fbdev_use_iomem = true;
> > bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
> >
> > bochs->dev->mode_config.funcs = &bochs_mode_funcs;
> > diff --git a/drivers/gpu/drm/drm_fb_helper.c 
> > b/drivers/gpu/drm/drm_fb_helper.c
> > index 5609e164805f..89cfd68ef400 100644
> > --- a/drivers/gpu/drm/drm_fb_helper.c
> > +++ b/drivers/gpu/drm/drm_fb_helper.c
> > @@ -399,7 +399,11 @@ static void drm_fb_helper_dirty_blit_real(struct 
> > drm_fb_helper *fb_helper,
> > unsigned int y;
> >
> > for (y = clip->y1; y < clip->y2; y++) {
> > -   memcpy(dst, src, len);
> > +   if (!fb_helper->dev->mode_config.fbdev_use_iomem)
> > +   memcpy(dst, src, len);
> > +   else
> > +   memcpy_toio((void __iomem *)dst, src, len);
> > +
> > src += fb->pitches[0];
> > dst += fb->pitches[0];
> > }
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index 6c3ef49b46b3..c24c066bdd9c 100644
> >

  1   2   >