[PATCH 0/3] Prepare error capture for asynchronous migration

2021-10-26 Thread Thomas Hellström
This patch series prepares error capture for asynchronous migration,
where the vma pages may not reflect the pages the GPU is currently
executing from but may be several migrations ahead.

The first patch deals with refcounting sg-list so that they don't
disappear under the capture code, which typically otherwise happens at
put_pages() time.

The second patch introduces vma state snapshots that record the vma state
at request submission time. It also updates the memory allocation mode to
reflect that error capture may and will happen in the dma-fence signalling
critical path, and finally takes additional measures to make sure that
the capture list and request is not disappearing from under us while
capturing. The latter may otherwise happen if a heartbeat triggered parallel
capture is running during a manual reset which retires the request.

Finally the last patch is more of a POC patch and not strictly needed yet,
but will be (or at least something very similar) soon for async unbinding.
It will make sure that unbinding doesn't complete or signal completion
before capture is done. Async reuse of memory can't happen until unbinding
signals complete and without waiting for capture done, we might capture
contents of reused memory.
Before the last patch the vma active is instead still keeping the vma alive,
but that will not work with async unbinding anymore, and also it is still
not clear how we guarantee keeping the vma alive long enough to even
grab an active reference during capture.

Thomas Hellström (3):
  drm/i915: Introduce refcounted sg-tables
  drm/i915: Update error capture code to avoid using the current vma
state
  drm/i915: Initial introduction of vma resources

 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 143 ++---
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   4 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   3 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c |  16 +-
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   | 188 ++---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   8 +-
 .../drm/i915/gt/intel_execlists_submission.c  |   2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c | 180 +++-
 drivers/gpu/drm/i915/i915_request.c   |  63 --
 drivers/gpu/drm/i915/i915_request.h   |  18 +-
 drivers/gpu/drm/i915/i915_scatterlist.c   |  62 --
 drivers/gpu/drm/i915/i915_scatterlist.h   |  76 ++-
 drivers/gpu/drm/i915/i915_vma.c   | 192 +-
 drivers/gpu/drm/i915/i915_vma.h   |  15 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.c  | 131 
 drivers/gpu/drm/i915/i915_vma_snapshot.h  | 112 ++
 drivers/gpu/drm/i915/i915_vma_types.h |   5 +
 drivers/gpu/drm/i915/intel_region_ttm.c   |  15 +-
 drivers/gpu/drm/i915/intel_region_ttm.h   |   5 +-
 drivers/gpu/drm/i915/selftests/mock_region.c  |  12 +-
 21 files changed, 1026 insertions(+), 225 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.c
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.h

-- 
2.31.1



[PATCH 2/3] drm/i915: Update error capture code to avoid using the current vma state

2021-10-26 Thread Thomas Hellström
With asynchronous migrations, the vma state may be several migrations
ahead of the state that matches the request we're capturing.
Address that by introducing an i915_vma_snapshot structure that
can be used to snapshot relevant state at request submission.
In order to make sure we access the correct memory, the snapshots take
references on relevant sg-tables and memory regions.

Also move the capture list allocation out of the fence signaling
critical path and use the CONFIG_DRM_I915_CAPTURE_ERROR define to
avoid compiling in members and functions used for error capture
when they're not used.

Finally, correct lockdep annotation would reveal that error capture is
typically done in the fence signalling critical path. Alter the
error capture memory allocation mode accordingly.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 135 ++---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   8 +-
 .../drm/i915/gt/intel_execlists_submission.c  |   2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c | 180 +-
 drivers/gpu/drm/i915/i915_request.c   |  63 --
 drivers/gpu/drm/i915/i915_request.h   |  18 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.c  | 137 +
 drivers/gpu/drm/i915/i915_vma_snapshot.h  | 112 +++
 9 files changed, 558 insertions(+), 98 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.c
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 467872cca027..2424c19cd0bc 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -173,6 +173,7 @@ i915-y += \
  i915_trace_points.o \
  i915_ttm_buddy_manager.o \
  i915_vma.o \
+ i915_vma_snapshot.o \
  intel_wopcm.o
 
 # general-purpose microcontroller (GuC) support
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 9c323666bd7c..9338cdb0ed56 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -29,6 +29,7 @@
 #include "i915_gem_ioctls.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
+#include "i915_vma_snapshot.h"
 
 struct eb_vma {
struct i915_vma *vma;
@@ -307,11 +308,15 @@ struct i915_execbuffer {
 
struct eb_fence *fences;
unsigned long num_fences;
+#ifdef CONFIG_DRM_I915_CAPTURE_ERROR
+   struct i915_capture_list *capture_lists[MAX_ENGINE_INSTANCE + 1];
+#endif
 };
 
 static int eb_parse(struct i915_execbuffer *eb);
 static int eb_pin_engine(struct i915_execbuffer *eb, bool throttle);
 static void eb_unpin_engine(struct i915_execbuffer *eb);
+static void eb_capture_release(struct i915_execbuffer *eb);
 
 static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
 {
@@ -1054,6 +1059,7 @@ static void eb_release_vmas(struct i915_execbuffer *eb, 
bool final)
i915_vma_put(vma);
}
 
+   eb_capture_release(eb);
eb_unpin_engine(eb);
 }
 
@@ -1891,36 +1897,113 @@ eb_find_first_request_added(struct i915_execbuffer *eb)
return NULL;
 }
 
-static int eb_move_to_gpu(struct i915_execbuffer *eb)
+#ifdef CONFIG_DRM_I915_CAPTURE_ERROR
+
+/* Stage with GFP_KERNEL allocations before we enter the signaling critical 
path */
+static void eb_capture_stage(struct i915_execbuffer *eb)
 {
const unsigned int count = eb->buffer_count;
-   unsigned int i = count;
-   int err = 0, j;
+   unsigned int i = count, j;
+   struct i915_vma_snapshot *vsnap;
 
while (i--) {
struct eb_vma *ev = &eb->vma[i];
struct i915_vma *vma = ev->vma;
unsigned int flags = ev->flags;
-   struct drm_i915_gem_object *obj = vma->obj;
 
-   assert_vma_held(vma);
+   if (!(flags & EXEC_OBJECT_CAPTURE))
+   continue;
 
-   if (flags & EXEC_OBJECT_CAPTURE) {
+   vsnap = i915_vma_snapshot_alloc(GFP_KERNEL);
+   if (!vsnap)
+   continue;
+
+   i915_vma_snapshot_init(vsnap, vma, "user");
+   for_each_batch_create_order(eb, j) {
struct i915_capture_list *capture;
 
-   for_each_batch_create_order(eb, j) {
-   if (!eb->requests[j])
-   break;
+   capture = kmalloc(sizeof(*capture), GFP_KERNEL);
+   if (!capture)
+   continue;
 
-   capture = kmalloc(sizeof(*capture), GFP_KERNEL);
-   if (capture) {
-   capture->next =
-   eb->requests[j]->captur

[PATCH 1/3] drm/i915: Introduce refcounted sg-tables

2021-10-26 Thread Thomas Hellström
As we start to introduce asynchronous failsafe object migration,
where we update the object state and then submit asynchronous
commands we need to record what memory resources are actually used
by various part of the command stream. Initially for three purposes:

1) Error capture.
2) Asynchronous migration error recovery.
3) Asynchronous vma bind.

At the time where these happens, the object state may have been updated
to be several migrations ahead and object sg-tables discarded.

In order to make it possible to keep sg-tables with memory resource
information for these operations, introduce refcounted sg-tables that
aren't freed until the last user is done with them.

The alternative would be to either copy sg-tables when needed or
reference information sitting on the corresponding ttm_resources which
typically have the same lifetime as these refcountes sg_tables, but
that leads to other awkward constructs: Due to the design direction chosen
for ttm resource managers that would lead to diamond-style inheritance,
the LMEM resources may sometimes be prematurely freed, and finally the
subclassed struct ttm_resource would have to bleed into the asynchronous
vma bind code.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   4 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   3 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c |  16 +-
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   | 188 +++---
 drivers/gpu/drm/i915/i915_scatterlist.c   |  62 --
 drivers/gpu/drm/i915/i915_scatterlist.h   |  76 ++-
 drivers/gpu/drm/i915/intel_region_ttm.c   |  15 +-
 drivers/gpu/drm/i915/intel_region_ttm.h   |   5 +-
 drivers/gpu/drm/i915/selftests/mock_region.c  |  12 +-
 9 files changed, 262 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index a5479ac7a4ad..c5ab364d4311 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -624,8 +624,8 @@ struct sg_table *shmem_alloc_st(struct drm_i915_private 
*i915,
size_t size, struct intel_memory_region *mr,
struct address_space *mapping,
unsigned int max_segment);
-void shmem_free_st(struct sg_table *st, struct address_space *mapping,
-  bool dirty, bool backup);
+void shmem_free_st_table(struct sg_table *st, struct address_space *mapping,
+bool dirty, bool backup);
 void __shmem_writeback(size_t size, struct address_space *mapping);
 
 #ifdef CONFIG_MMU_NOTIFIER
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index a4b69a43b898..604ed5ad77f5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -544,6 +544,7 @@ struct drm_i915_gem_object {
 */
struct list_head region_link;
 
+   struct i915_refct_sgt *rsgt;
struct sg_table *pages;
void *mapping;
 
@@ -597,7 +598,7 @@ struct drm_i915_gem_object {
} mm;
 
struct {
-   struct sg_table *cached_io_st;
+   struct i915_refct_sgt *cached_io_rsgt;
struct i915_gem_object_page_iter get_io_page;
struct drm_i915_gem_object *backup;
bool created:1;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 01f332d8dbde..67c6bee695c7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -25,8 +25,8 @@ static void check_release_pagevec(struct pagevec *pvec)
cond_resched();
 }
 
-void shmem_free_st(struct sg_table *st, struct address_space *mapping,
-  bool dirty, bool backup)
+void shmem_free_st_table(struct sg_table *st, struct address_space *mapping,
+bool dirty, bool backup)
 {
struct sgt_iter sgt_iter;
struct pagevec pvec;
@@ -49,7 +49,6 @@ void shmem_free_st(struct sg_table *st, struct address_space 
*mapping,
check_release_pagevec(&pvec);
 
sg_free_table(st);
-   kfree(st);
 }
 
 struct sg_table *shmem_alloc_st(struct drm_i915_private *i915,
@@ -171,7 +170,8 @@ struct sg_table *shmem_alloc_st(struct drm_i915_private 
*i915,
 err_sg:
sg_mark_end(sg);
if (sg != st->sgl) {
-   shmem_free_st(st, mapping, false, false);
+   shmem_free_st_table(st, mapping, false, false);
+   kfree(st);
} else {
mapping_clear_unevictable(mapping);
sg_free_table(st);
@@ -254,7 +254,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
return 0;
 
 err_pages:
-   shmem_free_st(st, mapping, false, false);
+   shmem_free_st_table(

[PATCH 3/3] drm/i915: Initial introduction of vma resources

2021-10-26 Thread Thomas Hellström
From: Thomas Hellström 

The vma resource are needed for asynchronous bind management and are
similar to TTM resources. They contain the data needed for
asynchronous unbinding (typically the vm range, any backend
private information and a means to do refcounting and to hold
the unbinding for error capture).

When a vma is bound, a vma resource is created and attached to the
vma, and on async unbinding it is detached from the vma, and instead
the vm records the fence marking unbind complete. This fence needs to
be waited on before we can bind the same region again, so either
the fence can be recorded for this particular range only, using an
interval tree, or as a simpler approach, for the whole vm. The latter
means no binding can take place on a vm until all detached vma
resources scheduled for unbind are signaled. With an interval tree
fence recording, the interval tree needs to be searched for fences
to be signaled before binding can take place.

But most of that is for later, this patch only introduces stub vma
resources without unbind capability and the fences of which are waited
for sync during unbinding. At this point we're interested in the hold
capability as a POC for error capture. Note that the current sync waiting
at unbind time is done uninterruptible, but that's OK since we're
only ever waiting during error capture, and in that case there's very
little gpu activity (if any) that can stall.

Signed-off-by: Thomas Hellström 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|   8 +-
 drivers/gpu/drm/i915/i915_vma.c   | 192 +-
 drivers/gpu/drm/i915/i915_vma.h   |  15 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.c  |  14 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.h  |   2 +-
 drivers/gpu/drm/i915/i915_vma_types.h |   5 +
 6 files changed, 217 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 9338cdb0ed56..3b7d5de14b23 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1374,9 +1374,15 @@ eb_relocate_entry(struct i915_execbuffer *eb,
 */
if (reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
GRAPHICS_VER(eb->i915) == 6) {
+   struct i915_vma_resource *vma_res =
+   i915_vma_resource_alloc();
+
+   if (IS_ERR(vma_res))
+   return PTR_ERR(vma_res);
+
err = i915_vma_bind(target->vma,
target->vma->obj->cache_level,
-   PIN_GLOBAL, NULL);
+   PIN_GLOBAL, NULL, vma_res);
if (err)
return err;
}
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 90546fa58fc1..2b331c5f0a5f 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -38,8 +38,35 @@
 #include "i915_trace.h"
 #include "i915_vma.h"
 
+/**
+ * struct i915_vma_resource - Snapshotted unbind information.
+ * @unbind_fence: Fence to mark unbinding complete. Note that this fence
+ * is not considered published until unbind is scheduled, and as such it
+ * is illegal to access this fence before scheduled unbind other than
+ * for refcounting.
+ * @lock: The @unbind_fence lock. We're also using it to protect the weak
+ * pointer to the struct i915_vma, @vma during lookup and takedown.
+ * @vma: Weak back-pointer to the parent vma struct. This pointer is
+ * protected by @lock, and a reference on @vma needs to be taken
+ * using kref_get_unless_zero.
+ * @hold_count: Number of holders blocking the fence from finishing.
+ * The vma itself is keeping a hold, which is released when unbind
+ * is scheduled.
+ */
+struct i915_vma_resource {
+   struct dma_fence unbind_fence;
+   /* See above for description of the lock. */
+   spinlock_t lock;
+   struct i915_vma *vma;
+   refcount_t hold_count;
+};
+
 static struct kmem_cache *slab_vmas;
 
+static void i915_vma_resource_init(struct i915_vma_resource *vma_res,
+  struct i915_vma *vma);
+static struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource 
*vma_res);
+
 struct i915_vma *i915_vma_alloc(void)
 {
return kmem_cache_zalloc(slab_vmas, GFP_KERNEL);
@@ -363,6 +390,8 @@ int i915_vma_wait_for_bind(struct i915_vma *vma)
  * @cache_level: mapping cache level
  * @flags: flags like global or local mapping
  * @work: preallocated worker for allocating and binding the PTE
+ * @vma_res: pointer to a preallocated vma resource. The resource is either
+ * consumed or freed.
  *
  * DMA addresses are taken from the scatter-gather table of this object (or of
  * this VMA in case of non-default GGTT views) and PTE

Re: [PATCH for-next 0/3] EFA dmabuf memory regions

2021-10-26 Thread Gal Pressman
On 12/10/2021 15:09, Gal Pressman wrote:
> Hey all,
>
> This is a followup to my previous RFCs [1][2], which now adds a new api
> to the RDMA subsystem that allows drivers to get a pinned dmabuf memory
> region without requiring an implementation of the move_notify callback.
> The new api makes use of the dynamic attachment api implemented in the
> RDMA subsystem, but calls dma_buf_pin() in order to make sure that the
> callback will not be called, as suggested by Christian.
>
> As explained in the previous RFC, move_notify requires the RDMA device
> to support on-demand-paging (ODP) which is not common on most devices
> (only supported by mlx5).
>
> While the dynamic requirement makes sense for certain GPUs, some devices
> (such as habanalabs) have device memory that is always "pinned" and do
> not need/use the move_notify operation.
>
> Patch #1 changes the dmabuf documentation to make it clear that pinning
> does not necessarily mean the memory must be moved to system memory, it
> is up to the exporter to decide.
> Patch #2 adds the RDMA api that allows drivers to get pinned dmabuf
> memory regions.
> Patch #3 adds the EFA implementation of the dmabuf importer.
>
> The motivation of this submission is to use habanalabs as the dmabuf
> exporter, and EFA as the importer to allow for peer2peer access through
> libibverbs.
>
> [1] 
> https://lore.kernel.org/linux-rdma/20210818074352.29950-1-galpr...@amazon.com/
> [2] 
> https://lore.kernel.org/linux-rdma/20211007104301.76693-1-galpr...@amazon.com/
>
> Thanks


Hey Jason, did you get a chance to take a look?



Re: [PATCH v6 14/16] drm/mediatek: add ovl_adaptor support for MT8195

2021-10-26 Thread Nancy . Lin
Hi Chun-Kuang,

Thanks for the review.

On Tue, 2021-10-26 at 07:11 +0800, Chun-Kuang Hu wrote:
>   Hi, Nancy:
> 
> Nancy.Lin  於 2021年10月4日 週一 下午2:21寫道:
> > 
> > Add ovl_adaptor driver for MT8195.
> > Ovl_adaptor is an encapsulated module and designed for simplified
> > DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
> > an ETHDR. Two RDMAs merge into one layer, so this module support 4
> > layers.
> > 
> > Signed-off-by: Nancy.Lin 
> > ---
> >  drivers/gpu/drm/mediatek/Makefile |   1 +
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  16 +
> >  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 498
> > ++
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h|   1 +
> >  4 files changed, 516 insertions(+)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > 
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> > index fb158a1e7f06..3abd27d7c91d 100644
> > --- a/drivers/gpu/drm/mediatek/Makefile
> > +++ b/drivers/gpu/drm/mediatek/Makefile
> > @@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \
> >   mtk_disp_gamma.o \
> >   mtk_disp_merge.o \
> >   mtk_disp_ovl.o \
> > + mtk_disp_ovl_adaptor.o \
> >   mtk_disp_rdma.o \
> >   mtk_drm_crtc.o \
> >   mtk_drm_ddp_comp.o \
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index 2446ad0a4977..6a4f4c42aedb 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -113,6 +113,22 @@ void mtk_rdma_enable_vblank(struct device
> > *dev,
> > void *vblank_cb_data);
> >  void mtk_rdma_disable_vblank(struct device *dev);
> > 
> > +int mtk_ovl_adaptor_clk_enable(struct device *dev);
> > +void mtk_ovl_adaptor_clk_disable(struct device *dev);
> > +void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
> > +   unsigned int h, unsigned int vrefresh,
> > +   unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt);
> > +void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> > idx,
> > + struct mtk_plane_state *state,
> > + struct cmdq_pkt *cmdq_pkt);
> > +void mtk_ovl_adaptor_enable_vblank(struct device *dev,
> > +  void (*vblank_cb)(void *),
> > +  void *vblank_cb_data);
> > +void mtk_ovl_adaptor_disable_vblank(struct device *dev);
> > +void mtk_ovl_adaptor_start(struct device *dev);
> > +void mtk_ovl_adaptor_stop(struct device *dev);
> > +unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
> > +
> >  int mtk_mdp_rdma_clk_enable(struct device *dev);
> >  void mtk_mdp_rdma_clk_disable(struct device *dev);
> >  void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt
> > *cmdq_pkt);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > new file mode 100644
> > index ..bfb5a9d29c26
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > @@ -0,0 +1,498 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "mtk_drm_drv.h"
> > +#include "mtk_drm_crtc.h"
> > +#include "mtk_drm_ddp_comp.h"
> > +#include "mtk_disp_drv.h"
> 
> Alphabetic order.
> 
OK.

> > +#include "mtk_ethdr.h"
> > +
> > +#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
> > +#define MTK_OVL_ADAPTOR_LAYER_NUM 4
> > +
> > +enum mtk_ovl_adaptor_comp_type {
> > +   OVL_ADAPTOR_TYPE_RDMA = 0,
> > +   OVL_ADAPTOR_TYPE_MERGE,
> > +   OVL_ADAPTOR_TYPE_ETHDR,
> > +   OVL_ADAPTOR_TYPE_NUM,
> > +};
> > +
> > +enum mtk_ovl_adaptor_comp_id {
> > +   OVL_ADAPTOR_MDP_RDMA0,
> > +   OVL_ADAPTOR_MDP_RDMA1,
> > +   OVL_ADAPTOR_MDP_RDMA2,
> > +   OVL_ADAPTOR_MDP_RDMA3,
> > +   OVL_ADAPTOR_MDP_RDMA4,
> > +   OVL_ADAPTOR_MDP_RDMA5,
> > +   OVL_ADAPTOR_MDP_RDMA6,
> > +   OVL_ADAPTOR_MDP_RDMA7,
> > +   OVL_ADAPTOR_MERGE0,
> > +   OVL_ADAPTOR_MERGE1,
> > +   OVL_ADAPTOR_MERGE2,
> > +   OVL_ADAPTOR_MERGE3,
> > +   OVL_ADAPTOR_ETHDR0,
> > +   OVL_ADAPTOR_ID_MAX
> > +};
> > +
> > +struct ovl_adaptor_comp_match {
> > +   enum mtk_ovl_adaptor_comp_type type;
> > +   int alias_id;
> > +};
> > +
> > +struct mtk_disp_ovl_adaptor {
> > +   struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
> > +   struct device *mmsys_dev;
> > +};
> > +
> > +static const char * const ovl_adaptor_comp_str[] = {
> > +   "OVL_ADAPTOR_MDP_RDMA0",
> > +   "OVL_ADAPTOR_MDP_RDMA1",
> > +   

[PATCH v3] dma-buf: remove restriction of IOCTL:DMA_BUF_SET_NAME

2021-10-26 Thread guangming.cao
From: Guangming Cao 

On Thu, 2021-10-14 at 18:25 +0800, guangming@mediatek.com wrote:
> From: Guangming Cao 
> 
> In this patch(https://patchwork.freedesktop.org/patch/310349),
> it add a new IOCTL to support dma-buf user to set debug name.
> 
> But it also added a limitation of this IOCTL, it needs the
> attachments of dmabuf should be empty, otherwise it will fail.
> 
> For the original series, the idea was that allowing name change
> mid-use could confuse the users about the dma-buf.
> However, the rest of the series also makes sure each dma-buf have a
> unique
> inode(https://patchwork.freedesktop.org/patch/310387/), and any
> accounting
> should probably use that, without relying on the name as much.
> 
> So, removing this restriction will let dma-buf userspace users to use
> it
> more comfortably and without any side effect.
> 
Hi christian, sumit,

Just a gentle ping for this patch, please kindly let me know your comments 
about this patch.
Thanks!

Guangming

> Signed-off-by: Guangming Cao 
> ---
>  drivers/dma-buf/dma-buf.c | 17 +++--
>  1 file changed, 3 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 511fe0d217a0..5fbb3a2068a3 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -325,10 +325,8 @@ static __poll_t dma_buf_poll(struct file *file,
> poll_table *poll)
>  
>  /**
>   * dma_buf_set_name - Set a name to a specific dma_buf to track the
> usage.
> - * The name of the dma-buf buffer can only be set when the dma-buf
> is not
> - * attached to any devices. It could theoritically support changing
> the
> - * name of the dma-buf if the same piece of memory is used for
> multiple
> - * purpose between different devices.
> + * It could support changing the name of the dma-buf if the same
> + * piece of memory is used for multiple purpose between different
> devices.
>   *
>   * @dmabuf: [in] dmabuf buffer that will be renamed.
>   * @buf:[in] A piece of userspace memory that contains the
> name of
> @@ -341,25 +339,16 @@ static __poll_t dma_buf_poll(struct file *file,
> poll_table *poll)
>  static long dma_buf_set_name(struct dma_buf *dmabuf, const char
> __user *buf)
>  {
>   char *name = strndup_user(buf, DMA_BUF_NAME_LEN);
> - long ret = 0;
>  
>   if (IS_ERR(name))
>   return PTR_ERR(name);
>  
> - dma_resv_lock(dmabuf->resv, NULL);
> - if (!list_empty(&dmabuf->attachments)) {
> - ret = -EBUSY;
> - kfree(name);
> - goto out_unlock;
> - }
>   spin_lock(&dmabuf->name_lock);
>   kfree(dmabuf->name);
>   dmabuf->name = name;
>   spin_unlock(&dmabuf->name_lock);
>  
> -out_unlock:
> - dma_resv_unlock(dmabuf->resv);
> - return ret;
> + return 0;
>  }
>  
>  static long dma_buf_ioctl(struct file *file,


Re: [PATCH] drm/i915/selftests: Allow engine reset failure to do a GT reset in hangcheck selftest

2021-10-26 Thread Thomas Hellström

Hi,

On 10/21/21 22:37, Matthew Brost wrote:

On Thu, Oct 21, 2021 at 08:15:49AM +0200, Thomas Hellström wrote:

Hi, Matthew,

On Mon, 2021-10-11 at 16:47 -0700, Matthew Brost wrote:

The hangcheck selftest blocks per engine resets by setting magic bits
in
the reset flags. This is incorrect for GuC submission because if the
GuC
fails to reset an engine we would like to do a full GT reset. Do no
set
these magic bits when using GuC submission.

Side note this lockless algorithm with magic bits to block resets
really
should be ripped out.


Lockless algorithm aside, from a quick look at the code in
intel_reset.c it appears to me like the interface that falls back to a
full GT reset is intel_gt_handle_error() whereas intel_engine_reset()
is explicitly intended to not do that, so is there a discrepancy
between GuC and non-GuC here?


With GuC submission when an engine reset fails, we get an engine reset
failure notification which triggers a full GT reset
(intel_guc_engine_failure_process_msg in intel_guc_submission.c). That
reset is blocking by setting these magic bits. Clearing the bits in this
function doesn't seem to unblock that reset either, the driver tries to
unload with a worker blocked, and results in the blow up. Something with
this lockless algorithm could be wrong as clear of the bit should
unlblock the reset but it is doesn't. We can look into that but in the
meantime we need to fix this test to be able to fail gracefully and not
crash CI.

Matt


Hmm, OK I think the situation is a bit unfortunate with the selftest 
hangcheck as the code is sprinkled with "using_guc" to disable anything 
that manually does per-engine resets or verifies the per-engine reset 
count, leaving it very difficult to understand what the test actually 
does except perhaps checking that GuC actually did a reset.


A better approach would probably be to disable all tests that doesn't do 
anything exept iterating through the engines with GuC, and for the other 
tests, extract what's left to test into GuC specific tests.


The bit-locks are obviously there to verify that we don't do concurrent 
per-engine resets or global resets while a per-engine reset is 
happening. Even in the GuC case it appears at least the latter is true 
for this particular self-test, but at the same time the selftest doesn't 
assume anything is trying to reset concurrently and therefore doesn't 
use clear_and_wake_up_bit() when releasing the bit-locks.


But as much as I want the selftests to start running again, TBH I don't 
think I can contribute to even more code being conditioned on GuC with 
an R-B here. Could we disable the per-engine reset tests when GuC is 
enabled for now or try a clear_and_wake_up_bit() instead.


/Thomas



/Thomas



Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 12 
  1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 7e2d99dd012d..90a03c60c80c 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -734,7 +734,8 @@ static int __igt_reset_engine(struct intel_gt
*gt, bool active)
 reset_engine_count = i915_reset_engine_count(global,
engine);
  
 st_engine_heartbeat_disable(engine);

-   set_bit(I915_RESET_ENGINE + id, >->reset.flags);
+   if (!using_guc)
+   set_bit(I915_RESET_ENGINE + id, >-

reset.flags);

 count = 0;
 do {
 struct i915_request *rq = NULL;
@@ -824,7 +825,8 @@ static int __igt_reset_engine(struct intel_gt
*gt, bool active)
 if (err)
 break;
 } while (time_before(jiffies, end_time));
-   clear_bit(I915_RESET_ENGINE + id, >->reset.flags);
+   if (!using_guc)
+   clear_bit(I915_RESET_ENGINE + id, >-

reset.flags);

 st_engine_heartbeat_enable(engine);
 pr_info("%s: Completed %lu %s resets\n",
 engine->name, count, active ? "active" :
"idle");
@@ -1042,7 +1044,8 @@ static int __igt_reset_engines(struct intel_gt
*gt,
 yield(); /* start all threads before we begin */
  
 st_engine_heartbeat_disable_no_pm(engine);

-   set_bit(I915_RESET_ENGINE + id, >->reset.flags);
+   if (!using_guc)
+   set_bit(I915_RESET_ENGINE + id, >-

reset.flags);

 do {
 struct i915_request *rq = NULL;
 struct intel_selftest_saved_policy saved;
@@ -1165,7 +1168,8 @@ static int __igt_reset_engines(struct intel_gt
*gt,
 if (err)
 break;
 } while (time_before(jiffies, end_time));
-   clear_bit(I915_RESET_ENGINE +

Re: [PATCH] video: fbdev: cirrusfb: check pixclock to avoid divide by zero

2021-10-26 Thread Geert Uytterhoeven
Hi George,

On Mon, Oct 25, 2021 at 9:37 PM George Kennedy
 wrote:
> On 10/25/2021 3:07 PM, Greg KH wrote:
> > On Mon, Oct 25, 2021 at 02:01:30PM -0500, George Kennedy wrote:
> >> Do a sanity check on pixclock value before using it as a divisor.
> >>
> >> Syzkaller reported a divide error in cirrusfb_check_pixclock.
> >>
> >> divide error:  [#1] SMP KASAN PTI
> >> CPU: 0 PID: 14938 Comm: cirrusfb_test Not tainted 5.15.0-rc6 #1
> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2
> >> RIP: 0010:cirrusfb_check_var+0x6f1/0x1260
> >>
> >> Call Trace:
> >>   fb_set_var+0x398/0xf90
> >>   do_fb_ioctl+0x4b8/0x6f0
> >>   fb_ioctl+0xeb/0x130
> >>   __x64_sys_ioctl+0x19d/0x220
> >>   do_syscall_64+0x3a/0x80
> >>   entry_SYSCALL_64_after_hwframe+0x44/0xae
> >>
> >> Signed-off-by: George Kennedy 
> >> ---
> >>   drivers/video/fbdev/cirrusfb.c | 3 +++
> >>   1 file changed, 3 insertions(+)
> >>
> >> diff --git a/drivers/video/fbdev/cirrusfb.c 
> >> b/drivers/video/fbdev/cirrusfb.c
> >> index 93802ab..099ddcb 100644
> >> --- a/drivers/video/fbdev/cirrusfb.c
> >> +++ b/drivers/video/fbdev/cirrusfb.c
> >> @@ -477,6 +477,9 @@ static int cirrusfb_check_pixclock(const struct 
> >> fb_var_screeninfo *var,
> >>  struct cirrusfb_info *cinfo = info->par;
> >>  unsigned maxclockidx = var->bits_per_pixel >> 3;
> >>
> >> +if (!var->pixclock)
> >> +return -EINVAL;

This is not correct: fbdev drivers should round up invalid values,
and only return an error if rounding up cannot yield a valid value.

> > Shouldn't you be checking further up the call chain where this got set
> > to 0?
>
> The same pixclock check is done in these fb drivers:
>
> arch/arm/mach-rpc/include/mach/acornfb.h:if (!var->pixclock)
> drivers/video/fbdev/asiliantfb.c:if (!var->pixclock)
> drivers/video/fbdev/clps711x-fb.c:if (!var->pixclock)
> drivers/video/fbdev/core/fbmon.c:if (!var->pixclock)
> drivers/video/fbdev/core/modedb.c:if (!var->pixclock)
> drivers/video/fbdev/cirrusfb.c:if (!var->pixclock)
> drivers/video/fbdev/kyro/fbdev.c:if (!var->pixclock)
> drivers/video/fbdev/riva/fbdev.c:if (!var->pixclock)
> drivers/video/fbdev/uvesafb.c:if (!var->pixclock)
>
> >
> > What logic allows this to be a valid value?  What about all other fb
> > drivers?
>
> The "check_var" function, which is set into the ".fb_check_var" element
> of the fb_ops struct, should do the check, but in the case of cirrusfb,
> that is not being done.
>
> All this patch does is add the same pixclock check that the other above
> fb drivers do.

Indeed, several drivers are not following the rounding rules.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


[PATCH] drm/msm/dp: fix missing #include

2021-10-26 Thread Arnd Bergmann
From: Arnd Bergmann 

Some randconfig builds fail when drm/drm_bridge.h is not included
implicitly in this file:

drivers/gpu/drm/msm/dp/dp_parser.c:279:25: error: implicit declaration of 
function 'devm_drm_panel_bridge_add' [-Werror,-Wimplicit-function-declaration]
parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);

Fixes: 4b296d15b355 ("drm/msm/dp: Allow attaching a drm_panel")
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/msm/dp/dp_parser.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 81dbcc86d08a..a7acc23f742b 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -8,6 +8,7 @@
 
 #include 
 #include 
+#include 
 
 #include "dp_parser.h"
 #include "dp_reg.h"
-- 
2.29.2



[PATCH] drm/i915/dmabuf: include asm/smp.h for cache operations

2021-10-26 Thread Arnd Bergmann
From: Arnd Bergmann 

The x86 low-level cache management operations are declared in
asm/smp.h, so drivers that call into this code need to include
the header:

drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c:248:3: error: implicit declaration 
of function 'wbinvd_on_all_cpus' [-Werror,-Wimplicit-function-declaration]
wbinvd_on_all_cpus();
^

Fixes: a035154da45d ("drm/i915/dmabuf: add paranoid flush-on-acquire")
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 1adcd8e02d29..853a989fcb9b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "i915_gem_object.h"
-- 
2.29.2



[PATCH] dma-buf: st: fix error handling in test_get_fences()

2021-10-26 Thread Arnd Bergmann
From: Arnd Bergmann 

The new driver incorrectly unwinds after errors, as clang points out:

drivers/dma-buf/st-dma-resv.c:295:7: error: variable 'i' is used uninitialized 
whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
if (r) {
^
drivers/dma-buf/st-dma-resv.c:336:9: note: uninitialized use occurs here
while (i--)
   ^
drivers/dma-buf/st-dma-resv.c:295:3: note: remove the 'if' if its condition is 
always false
if (r) {
^~~~
drivers/dma-buf/st-dma-resv.c:288:6: error: variable 'i' is used uninitialized 
whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
if (r) {
^
drivers/dma-buf/st-dma-resv.c:336:9: note: uninitialized use occurs here
while (i--)
   ^
drivers/dma-buf/st-dma-resv.c:288:2: note: remove the 'if' if its condition is 
always false
if (r) {
^~~~
drivers/dma-buf/st-dma-resv.c:280:10: note: initialize the variable 'i' to 
silence this warning
int r, i;
^
 = 0

Skip cleaning up the bits that have not been allocated at this point.

Fixes: 1d51775cd3f5 ("dma-buf: add dma_resv selftest v4")
Signed-off-by: Arnd Bergmann 
---
I'm not familiar with these interfaces, so I'm just guessing where
we should jump after an error, please double-check and fix if necessary.
---
 drivers/dma-buf/st-dma-resv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c
index 6f3ba756da3e..bc32b3eedcb6 100644
--- a/drivers/dma-buf/st-dma-resv.c
+++ b/drivers/dma-buf/st-dma-resv.c
@@ -287,7 +287,7 @@ static int test_get_fences(void *arg, bool shared)
r = dma_resv_lock(&resv, NULL);
if (r) {
pr_err("Resv locking failed\n");
-   goto err_free;
+   goto err_resv;
}
 
if (shared) {
@@ -295,7 +295,7 @@ static int test_get_fences(void *arg, bool shared)
if (r) {
pr_err("Resv shared slot allocation failed\n");
dma_resv_unlock(&resv);
-   goto err_free;
+   goto err_resv;
}
 
dma_resv_add_shared_fence(&resv, f);
@@ -336,6 +336,7 @@ static int test_get_fences(void *arg, bool shared)
while (i--)
dma_fence_put(fences[i]);
kfree(fences);
+err_resv:
dma_resv_fini(&resv);
dma_fence_put(f);
return r;
-- 
2.29.2



Re: [Linaro-mm-sig] [PATCH] dma-buf: add attachments empty check for dma_buf_release

2021-10-26 Thread guangming.cao
From: Guangming Cao 

On Tue, 2021-10-19 at 23:11 +0200, Daniel Vetter wrote:
> On Tue, Oct 19, 2021 at 05:37:27PM +0200, Christian K鰊ig wrote:
> > 
> > 
> > Am 19.10.21 um 14:41 schrieb Daniel Vetter:
> > > On Tue, Oct 19, 2021 at 08:23:45PM +0800, 
> > > guangming@mediatek.com wrote:
> > > > From: Guangming Cao 
> > > > 
> > > > Since there is no mandatory inspection for attachments in
> > > > dma_buf_release.
> > > > There will be a case that dma_buf already released but
> > > > attachment is still
> > > > in use, which can points to the dmabuf, and it maybe cause
> > > > some unexpected issues.
> > > > 
> > > > With IOMMU, when this cases occurs, there will have IOMMU
> > > > address
> > > > translation fault(s) followed by this warning,
> > > > I think it's useful for dma devices to debug issue.
> > > > 
> > > > Signed-off-by: Guangming Cao 
> > > 
> > > This feels a lot like hand-rolling kobject debugging. If you want
> > > to do
> > > this then I think adding kobject debug support to
> > > dma_buf/dma_buf_attachment would be better than hand-rolling
> > > something
> > > bespoke here.
> > 
> > Well I would call that overkill.
> 
> I think if done right the object debug stuff should be able to give
> you a
> backtrace. Which might be useful if you have a dma-buf heaps design
> where
> you really have no clue why a buffer was allocated/attached without
> some
> hints.
Well, I think it's the finally solution, for current thinking, it maybe bring a 
high
overloading. Just as this revert patch: 
https://lore.kernel.org/lkml/CA+wgaPMHA+8+LxfGNL+q4=xrdxqfu4txowlx7e28z9z7kps...@mail.gmail.com/
So, we need to find a lightweight way to do this.

Guangming
> 
> > > Also on the patch itself: You don't need the trylock. For
> > > correctly
> > > working code non one else can get at the dma-buf, so no locking
> > > needed to
> > > iterate through the attachment list. For incorrect code the
> > > kernel will be
> > > on fire pretty soon anyway, trying to do locking won't help :-)
> > > And
> > > without the trylock we can catch more bugs (e.g. if you also
> > > forgot to
> > > unlock and not just forgot to detach).

Yes, It's also a error case, I will remove to lock at next version patch. 
Thanks!

Guangming

> > 
> > You also don't need the WARN(!list_empty...) because a few line
> > below we
> > already have a "WARN_ON(!list_empty(&dmabuf->attachments));".

Sorry, could you tell me wich function will check it?
I didn't found it so I submit this patch.

Guangming
> 
> Yeah this patch here alone isn't really that useful I think. Maybe we
> could add the dmabuf->exp_name or so to that warning, but otherwise
> the
> info printed here isn't all that useful for debugging. Grabbing a

I also printed dmabuf->exp_name in warn message.

The reason adding it here is that some users on ANDROID of dma-buf is not 
familiar
with linux dma-buf or maybe write some problematic code, add this check can find
who lost call get_dma_buf or any other api can let let the dma-buf lifecycle is
under users' expectation.
Add it just like check in dma-fence:
https://github.com/torvalds/linux/blob/master/drivers/dma-buf/dma-fence.c#L519

Do you have any suggestion to debug this part?

Guangming

> backtrace of the allocator or attacher otoh should fairly immedialy
> point
> at the buggy code.
> -Daniel
> 
> > 
> > Christian.
> > 
> > > -Daniel
> > > 
> > > > ---
> > > >   drivers/dma-buf/dma-buf.c | 23 +++
> > > >   1 file changed, 23 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-
> > > > buf.c
> > > > index 511fe0d217a0..672404857d6a 100644
> > > > --- a/drivers/dma-buf/dma-buf.c
> > > > +++ b/drivers/dma-buf/dma-buf.c
> > > > @@ -74,6 +74,29 @@ static void dma_buf_release(struct dentry
> > > > *dentry)
> > > >  */
> > > > BUG_ON(dmabuf->cb_shared.active || dmabuf-
> > > > >cb_excl.active);
> > > > +   /* attachment check */
> > > > +   if (dma_resv_trylock(dmabuf->resv) &&
> > > > WARN(!list_empty(&dmabuf->attachments),
> > > > +   "%s err, inode:%08lu size:%08zu name:%s exp_name:%s
> > > > flags:0x%08x mode:0x%08x, %s\n",
> > > > +   __func__, file_inode(dmabuf->file)->i_ino, dmabuf-
> > > > >size,
> > > > +   dmabuf->name, dmabuf->exp_name,
> > > > +   dmabuf->file->f_flags, dmabuf->file->f_mode,
> > > > +   "Release dmabuf before detach all attachments, dump
> > > > attach:\n")) {
> > > > +   int attach_cnt = 0;
> > > > +   dma_addr_t dma_addr;
> > > > +   struct dma_buf_attachment *attach_obj;
> > > > +   /* dump all attachment info */
> > > > +   list_for_each_entry(attach_obj, &dmabuf-
> > > > >attachments, node) {
> > > > +   dma_addr = (dma_addr_t)0;
> > > > +   if (attach_obj->sgt)
> > > > +   dma_addr =
> > > > sg_dma_address(attach_obj->sgt->sgl);
> > > > +

Re: [PATCH 00/47] GuC submission support

2021-10-26 Thread Joonas Lahtinen
Quoting Matthew Brost (2021-10-25 18:15:09)
> On Mon, Oct 25, 2021 at 12:37:02PM +0300, Joonas Lahtinen wrote:
> > Quoting Matthew Brost (2021-10-22 19:42:19)
> > > On Fri, Oct 22, 2021 at 12:35:04PM +0300, Joonas Lahtinen wrote:
> > > > Hi Matt & John,
> > > > 
> > > > Can you please queue patches with the right Fixes: references to convert
> > > > all the GuC tracepoints to be protected by the LOW_LEVEL_TRACEPOINTS
> > > > protection for now. Please do so before next Wednesday so we get it
> > > > queued in drm-intel-next-fixes.
> > > > 
> > > 
> > > Don't we already do that? I checked i915_trace.h and every tracepoint I
> > > added (intel_context class, i915_request_guc_submit) is protected by
> > > LOW_LEVEL_TRACEPOINTS.
> > > 
> > > The only thing I changed outside of that protection is adding the guc_id
> > > field to existing i915_request class tracepoints.
> > 
> > It's the first search hit for "guc" inside the i915_trace.h file :)
> > 
> > > Without the guc_id in
> > > those tracepoints these are basically useless with GuC submission. We
> > > could revert that if it is a huge deal but as I said then they are
> > > useless...
> > 
> > Let's eliminate it for now and restore the tracepoint exactly as it was.
> > 
> 
> Don't really agree - let's render tracepoints to be useless? Are
> tracepoints ABI? I googled this and couldn't really find a definie
> answer. If tracepoints are ABI, then OK I can revert this change but
> still this is a poor technical decision (tracepoints should not be ABI).

Thats a very heated discussion in general. But the fact is that if
tracepoint changes have caused regressions to applications, they have
been forced to be remain untouched. You are free to raise the discussion
with Linus/LKML if you feel that should not be the case. So the end
result is that tracepoints are effectively in limbo, not ABI unless some
application uses them like ABI.

Feel free to search the intel-gfx/lkml for "tracepoints" keyword and look
for threads with many replies. It's not that I would not agree, it's more
that I'm not in the mood for repeating that discussion over and over again
and always land in the same spot.

So for now, we don't add anything new to tracepoints we can't guarantee
to always be there untouched. Similarly, we don't guarantee any of them
to remain stable. So we try to be compatible with the limbo.

I'm long overdue waiting for some stable consumer to step up for the
tracepoints, so we can then start discussion what would actually be the
best way of getting that information out for them. In ~5 years that has
not happened.

> > If there is an immediate need, we should instead have an auxilary tracepoint
> > which is enabled only through LOW_LEVEL_TRACEPOINTS and that amends the
> > information of the basic tracepoint.
> > 
> 
> Regardless of what I said above, I'll post 2 patches. The 1st just
> remove the GuC, the 2nd modify the tracepoint to include guc_id if
> LOW_LEVEL_TRACEPOINTS is defined.

Thanks. Let's get a patch merged which simply drops the guc_id for now
to unblock things.

For the second, an auxilary tracepoint will be preferred instead of
mutating the existing one (regardless of the LOW_LEVEL_TRACEPOINTS).

I only noticed a patch that mutates the tracepoints, can you
double-check sending the first patch?

Regards, Joonas

> 
> > For the longer term solution we should align towards the dma fence
> > tracepoints. When those are combined with the OA information, one should
> > be able to get a good understanding of both the software and hardware
> > scheduling decisions.
> > 
> 
> Not sure about this either. I use these tracepoins to correlate things
> to the GuC log. Between the 2, if you know what you are doing you
> basically can figure out everything that is happening. Fields in the
> trace translate directly to fields in the GuC log. Some of these fields
> are backend specific, not sure how these could be pushed the dma fence
> tracepoints. For what it is worth, without these tracepoints we'd likely
> still have a bunch of bugs in the GuC firmware. I understand these
> points, several other i915 developers do, and several of the GuC
> firmware developers do too.
> 
> Matt
> 
> > Regards, Joonas
> > 
> > > 
> > > Matt
> > > 
> > > > There's the orthogonal track to discuss what would be the stable set of
> > > > tracepoints we could expose. However, before that discussion is closed,
> > > > let's keep a rather strict line to avoid potential maintenance burned.
> > > > 
> > > > We can then relax in the future as needed.
> > > > 
> > > > Regards, Joonas
> > > > 
> > > > Quoting Matthew Brost (2021-06-24 10:04:29)
> > > > > As discussed in [1], [2] we are enabling GuC submission support in the
> > > > > i915. This is a subset of the patches in step 5 described in [1],
> > > > > basically it is absolute to enable CI with GuC submission on gen11+
> > > > > platforms.
> > > > > 
> > > > > This series itself will likely be broken down into smaller patch sets 
> > > >

Re: [PATCH] drm/i915/trace: Hide backend specific fields behind Kconfig

2021-10-26 Thread Joonas Lahtinen
Quoting John Harrison (2021-10-26 00:06:54)
> On 10/25/2021 09:34, Matthew Brost wrote:
> > Hide the guc_id and tail fields, for request trace points, behind
> > CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS Kconfig option. Trace points
> > are ABI (maybe?) so don't change them without kernel developers Kconfig
> > options.
> The i915 sw arch team have previously hard blocked requests for changes 
> to trace points from user land tool developers on the grounds that trace 
> points are not ABI and are free to change at whim as and when the i915 
> internal implementation changes. They are purely for use of developers 
> to debug the i915 driver as the i915 driver currently stands at any 
> given instant.

Correct. That is indicated by the LOW_LEVEL_TRACEPOINTS.

All the discussions about stable usage really revolve around the low level
backend specific scheduling tracepoints to analyze hardware utilization.
And those even become infeasible to expose when GuC scheduling is enabled
as the information really goes to GuC log.

Luckily we have added the mechanism to get the actual utilization
through OA via gpuvis tool, so we don't have to guesstimate it from the
KMD scheduling tracepoints (which are for KMD debugging).

> So I don't see how it can be argued that we must not update any trace 
> points to allow for debugging of i915 scheduling issues on current 
> platforms. And having to enable extra config options just to keep 
> existing higher level trace points usable seems broken.

We can update them (even outside LOW_LEVEL_TRACEPOINTS) but there should
not be any backend specific data added outside the LOW_LEVEL_TRACEPOINTS,
just to prevent anyone from starting to use them in some
visualization/analysis tooling.

If you have the energy to drive the general LKML/Linux Plumbers level
discussion about tracepoint stability limbo into a conclusion, I'll be
more than happy to see it resolved :)

Regards, Joonas

> 
> John.
> 
> 
> >
> > Signed-off-by: Matthew Brost 
> > ---
> >   drivers/gpu/drm/i915/i915_trace.h | 27 +++
> >   1 file changed, 27 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_trace.h 
> > b/drivers/gpu/drm/i915/i915_trace.h
> > index 9795f456cccf..4f5238d02b51 100644
> > --- a/drivers/gpu/drm/i915/i915_trace.h
> > +++ b/drivers/gpu/drm/i915/i915_trace.h
> > @@ -787,6 +787,7 @@ TRACE_EVENT(i915_request_queue,
> > __entry->ctx, __entry->seqno, __entry->flags)
> >   );
> >   
> > +#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS)
> >   DECLARE_EVENT_CLASS(i915_request,
> >   TP_PROTO(struct i915_request *rq),
> >   TP_ARGS(rq),
> > @@ -816,6 +817,32 @@ DECLARE_EVENT_CLASS(i915_request,
> > __entry->guc_id, __entry->ctx, __entry->seqno,
> > __entry->tail)
> >   );
> > +#else
> > +DECLARE_EVENT_CLASS(i915_request,
> > + TP_PROTO(struct i915_request *rq),
> > + TP_ARGS(rq),
> > +
> > + TP_STRUCT__entry(
> > +  __field(u32, dev)
> > +  __field(u64, ctx)
> > +  __field(u16, class)
> > +  __field(u16, instance)
> > +  __field(u32, seqno)
> > +  ),
> > +
> > + TP_fast_assign(
> > +__entry->dev = 
> > rq->engine->i915->drm.primary->index;
> > +__entry->class = rq->engine->uabi_class;
> > +__entry->instance = rq->engine->uabi_instance;
> > +__entry->ctx = rq->fence.context;
> > +__entry->seqno = rq->fence.seqno;
> > +),
> > +
> > + TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u",
> > +   __entry->dev, __entry->class, __entry->instance,
> > +   __entry->ctx, __entry->seqno)
> > +);
> > +#endif
> >   
> >   DEFINE_EVENT(i915_request, i915_request_add,
> >TP_PROTO(struct i915_request *rq),
> 


Re: [PATCH] drm/i915/guc: Fix recursive lock in GuC submission

2021-10-26 Thread Joonas Lahtinen
Quoting Matthew Brost (2021-10-25 20:13:22)
> On Mon, Oct 25, 2021 at 03:23:00PM +0300, Joonas Lahtinen wrote:
> > Quoting Thomas Hellström (2021-10-21 08:39:48)
> > > On Wed, 2021-10-20 at 12:21 -0700, Matthew Brost wrote:
> > 
> > 
> > 
> > > > Fixes: 1a52faed31311 ("drm/i915/guc: Take engine PM when a context is
> > > > pinned with GuC submission")
> > > > Signed-off-by: Matthew Brost 
> > > > Cc: sta...@vger.kernel.org
> > 
> > This Cc: stable annotation is unnecessary.
> > 
> > Please always use "dim fixes 1a52faed31311" for helping to decide which
> > Cc's are needed. In this case stable is not needed. If it was, there
> > would be an indication of kernel version. In this case this is fine to
> > be picked up by in drm-intel-next-fixes PR.
> > 
> > Let's pay attention to the right Fixes: annotation while submitting and
> > reviewing patches.
> > 
> 
> Will do. Working on getting push rights. Is there any documentation with
> all the rules when pushing as it seems like there are a lot of rules.

Yes, we have the documentation here:

https://drm.pages.freedesktop.org/maintainer-tools/committer-guidelines.html

And more specifically this topic:

https://drm.pages.freedesktop.org/maintainer-tools/committer-drm-intel.html#labeling-fixes-before-pushing

I could even recommend to at least do a cursory read through the wider
documentation about how the different trees interact:

https://drm.pages.freedesktop.org/maintainer-tools/index.html

Makes it easier to understand how the tags are used.

Regards, Joonas

> 
> Matt 
> 
> > Regards, Joonas


Re: [PATCH 1/2] drm/i915/gtt: flush the scratch page

2021-10-26 Thread Thomas Hellström



On 10/22/21 18:48, Matthew Auld wrote:

The scratch page is directly visible in the users address space, and
while this is forced as CACHE_LLC, by the kernel, we still have to
contend with things like "Bypass-LLC" MOCS. So just flush no matter
what.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Cc: Chris Wilson 
Cc: Ramalingam C 


Reviewed-by: Thomas Hellström 


---
  drivers/gpu/drm/i915/gt/intel_gtt.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 67d14afa6623..b6c088423319 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -273,6 +273,7 @@ static void poison_scratch_page(struct drm_i915_gem_object 
*scratch)
val = POISON_FREE;
  
  	memset(vaddr, val, scratch->base.size);

+   clflush_cache_range(vaddr, scratch->base.size);
  }
  
  int setup_scratch_page(struct i915_address_space *vm)


[Bug 211807] [drm:drm_dp_mst_dpcd_read] *ERROR* mstb 000000004e6288dd port 3: DPCD read on addr 0x60 for 1 bytes NAKed

2021-10-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211807

--- Comment #12 from zwer...@mail.de ---
As mentioned before, I get the same error with a monitor connected with DP to a
Lenovo ThinkPad USB-C Dock Gen2. My Laptop has an Intel i7 10510U no additional
graphics card. I am using Debian testing with the provided kernel.

Furthermore sudo dmesg output says:
[  148.088024] wrong crc01 50 63 ff ff 00 00 00 00 50 63 ff ff 00 00 00
[  148.088028] wrong crc00 04 90 c0 01 00 00 00 00 00 00 00 00 00 00 00
[  148.088029] wrong crc00 00 00 00 95 00 00 00 00 00 00 00 00
[  148.152590] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
deb5c7d4 port 1: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  148.182726] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
deb5c7d4 port 0: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  148.202439] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
deb5c7d4 port 3: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  148.557719] [drm:drm_dp_mst_hpd_irq [drm_kms_helper]] *ERROR* Got unknown
reply 0x00 (GET_MSG_TRANSACTION_VERSION)
[  148.812803] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
e591bea5 port 1: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  149.036253] wrong crc80 81 40 95 00 a9 40 b3 00 d1 00 e1 c0 37 38 51
[  149.036257] wrong crc56 0a 20 20 20 20 20 00 00 00 ff 00 4c 35 4c 4d
[  149.036259] wrong crc51 53 31 37 34 34 38 33 0a 01 05 02 00
[  149.119816] wrong crc80 81 40 95 00 a9 40 b3 00 d1 00 e1 c0 37 38 51
[  149.119819] wrong crc56 0a 20 20 20 20 20 00 00 00 ff 00 4c 35 4c 4d
[  149.119821] wrong crc51 53 31 37 34 34 38 33 0a 01 05 02 00
[  149.161970] wrong crc20 20 20 20 20 00 00 00 fc 00 50 41 32 37 38 51
[  149.161973] wrong crc56 0a 20 20 20 20 20 00 00 00 ff 00 4c 00 00 00
[  149.161975] wrong crc00 00 00 00 00 00 00 00 00 00 00 00
[  149.219517] wrong crc80 81 40 95 00 a9 40 b3 00 d1 00 e1 c0 37 38 51
[  149.219520] wrong crc56 0a 20 20 20 20 20 00 00 00 ff 00 4c 35 4c 4d
[  149.219522] wrong crc51 53 31 37 34 34 38 33 0a 01 05 02 00
[  149.248529] wrong crc22 02 80 00 ff ff ff ff ff ff 00 06 b3 56 5e 00
[  149.248532] wrong crca0 a0 a0 29 50 30 20 35 00 55 50 21 00 00 1a 00
[  149.248534] wrong crc00 00 fd 00 2e 4b 70 70 1e 01 0a 20 d3
[  149.357568] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
e591bea5 port 3: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  149.386520] wrong crc22 02 80 00 ff ff ff ff ff ff 00 06 b3 00 27 01
[  149.386523] wrong crc01 01 01 16 1e 01 04 a5 3c 22 78 3b ff 00 1a 00
[  149.386524] wrong crc00 00 fd 00 2e 4b 70 70 1e 01 0a 20 d3
[  149.433016] wrong crc80 81 40 95 00 a9 40 b3 00 d1 00 e1 c0 37 38 51
[  149.433019] wrong crc56 0a 20 20 20 20 20 00 00 00 ff 00 4c 35 4c 4d
[  149.433020] wrong crc51 53 31 37 34 34 38 33 0a 01 05 02 00
[  149.452176] wrong crc22 02 80 00 ff ff ff ff ff ff 00 06 b3 00 27 01
[  149.452179] wrong crc01 01 01 16 1e 01 04 a5 3c 22 78 3b ff 00 1a 00
[  149.452180] wrong crc00 00 fd 00 2e 4b 70 70 1e 01 0a 20 d3
[  149.465498] wrong crc80 81 40 95 00 a9 40 b3 00 d1 00 e1 c0 56 5e 00
[  149.465501] wrong crca0 a0 a0 29 50 30 20 35 00 55 50 21 00 35 4c 4d
[  149.465503] wrong crc51 53 31 37 34 34 38 33 0a 01 05 02 00
[  149.476472] i915 :00:02.0: [drm] DP-3: EDID is invalid:
[  149.476477]  [00] BAD  00 ff ff ff ff ff ff 00 06 b3 00 27 01 01 01 01
[  149.476479]  [00] BAD  16 1e 01 04 a5 3c 22 78 3b ff 00 1a 00 00 00 fd
[  149.476481]  [00] BAD  00 2e 4b 70 70 1e 01 0a 20 80 81 40 95 00 a9 40
[  149.476483]  [00] BAD  b3 00 d1 00 e1 c0 56 5e 00 a0 a0 a0 29 50 30 20
[  149.476484]  [00] BAD  35 00 55 50 21 00 35 4c 4d 51 53 31 37 34 34 38
[  149.476486]  [00] BAD  33 0a 01 05 02 20 20 20 20 20 00 00 00 fc 00 50
[  149.476487]  [00] BAD  41 32 37 38 51 56 0a 20 20 20 20 20 00 00 00 ff
[  149.476489]  [00] BAD  00 4c 35 4c 4d 51 53 31 37 34 34 38 33 0a 01 05
[  149.533039] wrong crc22 02 80 00 ff ff ff ff ff ff 00 06 b3 56 5e 00
[  149.533042] wrong crca0 a0 a0 29 50 30 20 35 00 55 50 21 00 00 1a 00
[  149.533044] wrong crc00 00 fd 00 2e 4b 70 70 1e 01 0a 20 d3
[  149.698698] wrong crc01 05 6c ff ff 00 00 00 00 05 6c ff ff 00 00 00
[  149.698702] wrong crc00 04 90 c0 01 00 00 00 00 00 00 00 00 00 00 00
[  149.698704] wrong crc00 00 00 00 95 00 00 00 00 00 00 00 00
[  149.732698] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
76514e96 port 1: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  149.750841] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
76514e96 port 0: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  149.772810] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
76514e96 port 3: DPCD read on addr 0x4b0 for 1 bytes NAKed
[  150.080471] failed hdr00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  154.083081] [drm:drm_dp_send_link_address [drm_kms_helper]] *ERROR* Sending
link address failed with -5
[  156.605509] [drm:drm_dp_mst_dpcd_read [drm_kms_helper]] *ERROR* mstb
f470192a port 1:

Re: [PATCH 1/2] drm/i915/gtt: flush the scratch page

2021-10-26 Thread Thomas Hellström



On 10/22/21 18:48, Matthew Auld wrote:

The scratch page is directly visible in the users address space, and
while this is forced as CACHE_LLC, by the kernel, we still have to
contend with things like "Bypass-LLC" MOCS. So just flush no matter
what.

Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Cc: Chris Wilson 
Cc: Ramalingam C 
---
  drivers/gpu/drm/i915/gt/intel_gtt.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 67d14afa6623..b6c088423319 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -273,6 +273,7 @@ static void poison_scratch_page(struct drm_i915_gem_object 
*scratch)
val = POISON_FREE;
  
  	memset(vaddr, val, scratch->base.size);

+   clflush_cache_range(vaddr, scratch->base.size);


Actually, we should probably use drm_clflush_virt_range() here?

/Thomas




  }
  
  int setup_scratch_page(struct i915_address_space *vm)


Re: [PATCH 2/2] drm/i915/gtt: stop caching the scratch page

2021-10-26 Thread Thomas Hellström



On 10/22/21 18:48, Matthew Auld wrote:

Normal users shouldn't be hitting this, likely this would indicate a
userspace bug. So don't bother caching, which should be safe now that we
manually flush the page.

Suggested-by: Chris Wilson 
Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Cc: Chris Wilson 
Cc: Ramalingam C 


Reviewed-by: Thomas Hellström 




Re: Lockdep spalt on killing a processes

2021-10-26 Thread Christian König

Am 26.10.21 um 04:33 schrieb Andrey Grodzovsky:

On 2021-10-25 3:56 p.m., Christian König wrote:

In general I'm all there to get this fixed, but there is one major 
problem: Drivers don't expect the lock to be dropped.



I am probably missing something but in my approach we only modify the 
code for those clients that call dma_fence_signal,
not dma_fence_signal_locked. In those cases the drivers are agnostic 
to lock behavior (or should be at least) since the lock
is acquired within the dma fence code. Note that if you are worried 
about calling the callback without lock then same exact
concern is relevant to using the irq_work directly in the fence code 
since the irq_work will execute at a later time without locked

fence->lock (which is the point of using irq_work).


Yeah, I've seen that it just doesn't make much sense to me.



What we could do is to change all drivers so they call always call 
the dma_fence_signal functions and drop the _locked variants. This 
way we could move calling the callback out of the spinlock.


But that requires audit of all drivers, so quite a lot of work to do.



As i said earlier - if we only modify dma_fence_signal and don't touch 
dma_fence_signal_locked then our only concern should the users of 
dma_fence_signal.


Yes, but what do you do with the drivers who call the _locked variant?


Let me please know if I am still missing some point of yours.


Well, I mean we need to be able to handle this for all drivers.

Regards,
Christian.



Andrey




Regards,
Christian.

Am 25.10.21 um 21:10 schrieb Andrey Grodzovsky:
Adding back Daniel (somehow he got off the addresses list) and Chris 
who worked a lot in this area.


On 2021-10-21 2:34 a.m., Christian König wrote:



Am 20.10.21 um 21:32 schrieb Andrey Grodzovsky:

On 2021-10-04 4:14 a.m., Christian König wrote:


The problem is a bit different.

The callback is on the dependent fence, while we need to signal 
the scheduler fence.


Daniel is right that this needs an irq_work struct to handle this 
properly.


Christian.



So we had some discussions with Christian regarding irq_work and 
agreed I should look into doing it but stepping back for a sec -


Why we insist on calling the dma_fence_cb  with fence->lock locked 
? Is it because of dma_fence_add_callback ?
Because we first test for DMA_FENCE_FLAG_SIGNALED_BIT and only 
after that lock the fence->lock ? If so, can't we
move DMA_FENCE_FLAG_SIGNALED_BIT  check inside the locked section 
? Because if in theory
we could call the cb with unlocked fence->lock (i.e. this kind of 
iteration 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Felixir.bootlin.com%2Flinux%2Fv5.15-rc6%2Fsource%2Fdrivers%2Fgpu%2Fdrm%2Fttm%2Fttm_resource.c%23L117&data=04%7C01%7Candrey.grodzovsky%40amd.com%7Cc8a4525f94c244bebbd208d997f19242%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637707886075917091%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=YBq%2BNkDuYKERc8XJDWTfeM%2FSknpuCBHQYgN8Uo5PFv0%3D&reserved=0)

we wouldn't have the lockdep splat. And in general, is it really
the correct approach to call a third party code from a call back 
with locked spinlock ? We don't know what the cb does inside
and I don't see any explicit restrictions in documentation of 
dma_fence_func_t what can and cannot be done there.


Yeah, that's exactly what I meant with using the irq_work directly 
in the fence code.



My idea is not to use irq work at all but instead to implement 
unlocked dma_fence cb execution using iteration
which drops the spinlock each time next cb is executed and acquiring 
it again after (until cb_list is empy).






The problem is dma_fence_signal_locked() which is used by quite a 
number of drivers to signal the fence while holding the lock.



For this I think we should not reuse dma_fence_signal_locked inside 
dma_fence_signal and instead implement it using the
unlocked iteration I mentioned above. I looked a bit in the code and 
the history and I see that until some time ago
(this commit by Chris 0fc89b6802ba1fcc561b0c906e0cefd384e3b2e5), 
indeed dma_fence_signal was doing it's own, locked iteration
and wasn't reusing dma_fence_signal_locked. This way whoever relies 
on the dma_fence_signal_locked won't be impacted
an who is not (like us in 
drm_sched_fence_scheduled/drm_sched_fence_finished) should also not 
be impacted by more narrow
scope of the lock. I also looked at dma_fence_default_wait and how 
it locks the fence->lock and check if fence is signaled

before wait start and I don't see a problem there either.

I attached quick draft of this proposal to clarify.

Andrey




Otherwise we could indeed simplify the fence handling a lot.

Christian.



Andrey




Am 01.10.21 um 17:10 schrieb Andrey Grodzovsky:
From what I see here you supposed to have actual deadlock and 
not only warning, sched_fence->finished is  first signaled from 
within
hw fence done callback (drm_sched_job_done_cb) but then again 

Re: [PATCH] dma-buf: st: fix error handling in test_get_fences()

2021-10-26 Thread Christian König

Am 26.10.21 um 10:34 schrieb Arnd Bergmann:

From: Arnd Bergmann 

The new driver incorrectly unwinds after errors, as clang points out:

drivers/dma-buf/st-dma-resv.c:295:7: error: variable 'i' is used uninitialized 
whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
 if (r) {
 ^
drivers/dma-buf/st-dma-resv.c:336:9: note: uninitialized use occurs here
 while (i--)
^
drivers/dma-buf/st-dma-resv.c:295:3: note: remove the 'if' if its condition is 
always false
 if (r) {
 ^~~~
drivers/dma-buf/st-dma-resv.c:288:6: error: variable 'i' is used uninitialized 
whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
 if (r) {
 ^
drivers/dma-buf/st-dma-resv.c:336:9: note: uninitialized use occurs here
 while (i--)
^
drivers/dma-buf/st-dma-resv.c:288:2: note: remove the 'if' if its condition is 
always false
 if (r) {
 ^~~~
drivers/dma-buf/st-dma-resv.c:280:10: note: initialize the variable 'i' to 
silence this warning
 int r, i;
 ^
  = 0

Skip cleaning up the bits that have not been allocated at this point.

Fixes: 1d51775cd3f5 ("dma-buf: add dma_resv selftest v4")
Signed-off-by: Arnd Bergmann 


I already send out a patch to fix this up, but forgot to fix both gotos.

Going to add my rb and using that one here instead.

Thanks,
Christian.


---
I'm not familiar with these interfaces, so I'm just guessing where
we should jump after an error, please double-check and fix if necessary.
---
  drivers/dma-buf/st-dma-resv.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c
index 6f3ba756da3e..bc32b3eedcb6 100644
--- a/drivers/dma-buf/st-dma-resv.c
+++ b/drivers/dma-buf/st-dma-resv.c
@@ -287,7 +287,7 @@ static int test_get_fences(void *arg, bool shared)
r = dma_resv_lock(&resv, NULL);
if (r) {
pr_err("Resv locking failed\n");
-   goto err_free;
+   goto err_resv;
}
  
  	if (shared) {

@@ -295,7 +295,7 @@ static int test_get_fences(void *arg, bool shared)
if (r) {
pr_err("Resv shared slot allocation failed\n");
dma_resv_unlock(&resv);
-   goto err_free;
+   goto err_resv;
}
  
  		dma_resv_add_shared_fence(&resv, f);

@@ -336,6 +336,7 @@ static int test_get_fences(void *arg, bool shared)
while (i--)
dma_fence_put(fences[i]);
kfree(fences);
+err_resv:
dma_resv_fini(&resv);
dma_fence_put(f);
return r;




Re: Two minor etnaviv DMA-buf cleanups

2021-10-26 Thread Christian König

Just a gentle ping on those two.

The changes are straight forward and I just need an ack.

Adding Daniel, maybe he has a minute :)

Cheers,
Christian.

Am 25.10.21 um 10:05 schrieb Christian König:

Hi guys,

just two minor cleanups related to the new DMA-buf iterators. Can I get an rb 
or ack-by for that?

Thanks,
Christian.






Re: [PATCH v3] dma-buf: remove restriction of IOCTL:DMA_BUF_SET_NAME

2021-10-26 Thread Christian König

Am 14.10.21 um 12:25 schrieb guangming@mediatek.com:

From: Guangming Cao 

In this patch(https://patchwork.freedesktop.org/patch/310349),
it add a new IOCTL to support dma-buf user to set debug name.

But it also added a limitation of this IOCTL, it needs the
attachments of dmabuf should be empty, otherwise it will fail.

For the original series, the idea was that allowing name change
mid-use could confuse the users about the dma-buf.
However, the rest of the series also makes sure each dma-buf have a unique
inode(https://patchwork.freedesktop.org/patch/310387/), and any accounting
should probably use that, without relying on the name as much.

So, removing this restriction will let dma-buf userspace users to use it
more comfortably and without any side effect.

Signed-off-by: Guangming Cao 


We could now cleanup the return value from dma_buf_set_name() into a 
void since that function can't fail any more as far as I can see.


But that isn't mandatory I think, patch is Reviewed-by: Christian König 



Regards,
Christian.


---
  drivers/dma-buf/dma-buf.c | 17 +++--
  1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 511fe0d217a0..5fbb3a2068a3 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -325,10 +325,8 @@ static __poll_t dma_buf_poll(struct file *file, poll_table 
*poll)
  
  /**

   * dma_buf_set_name - Set a name to a specific dma_buf to track the usage.
- * The name of the dma-buf buffer can only be set when the dma-buf is not
- * attached to any devices. It could theoritically support changing the
- * name of the dma-buf if the same piece of memory is used for multiple
- * purpose between different devices.
+ * It could support changing the name of the dma-buf if the same
+ * piece of memory is used for multiple purpose between different devices.
   *
   * @dmabuf: [in] dmabuf buffer that will be renamed.
   * @buf:[in] A piece of userspace memory that contains the name of
@@ -341,25 +339,16 @@ static __poll_t dma_buf_poll(struct file *file, 
poll_table *poll)
  static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
  {
char *name = strndup_user(buf, DMA_BUF_NAME_LEN);
-   long ret = 0;
  
  	if (IS_ERR(name))

return PTR_ERR(name);
  
-	dma_resv_lock(dmabuf->resv, NULL);

-   if (!list_empty(&dmabuf->attachments)) {
-   ret = -EBUSY;
-   kfree(name);
-   goto out_unlock;
-   }
spin_lock(&dmabuf->name_lock);
kfree(dmabuf->name);
dmabuf->name = name;
spin_unlock(&dmabuf->name_lock);
  
-out_unlock:

-   dma_resv_unlock(dmabuf->resv);
-   return ret;
+   return 0;
  }
  
  static long dma_buf_ioctl(struct file *file,




[PATCH v2] drm: panel-orientation-quirks: Add quirk for GPD Win3

2021-10-26 Thread Mario
Fixes screen orientation for GPD Win 3 handheld gaming console.

Signed-off-by: Mario Risoldi 
---
 drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c 
b/drivers/gpu/drm/drm_panel_orientation_quirks.c
index f6bdec7fa925..f6177c1d9872 100644
--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -185,6 +185,12 @@ static const struct dmi_system_id orientation_data[] = {
  DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
},
.driver_data = (void *)&gpd_win2,
+   }, {/* GPD Win 3 */
+   .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03")
+   },
+   .driver_data = (void *)&lcd720x1280_rightside_up,
}, {/* I.T.Works TW891 */
.matches = {
  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
-- 
2.33.1



[PATCH v2 0/8] Add new formats support to vkms

2021-10-26 Thread Igor Torrente
Summary
===
This series of patches refactor some vkms components in order to introduce
new formats to the planes and writeback connector.

Now in the blend function, the plane's pixels are converted to ARGB16161616
and then blended together.

The CRC is calculated based on the ARGB1616161616 buffer. And if required,
this buffer is copied/converted to the writeback buffer format.

And to handle the pixel conversion, new functions were added to convert
from a specific format to ARGB16161616 (the reciprocal is also true).

Tests
=
This patch series was tested using the following igt tests:
-t ".*kms_plane.*"
-t ".*kms_writeback.*"
-t ".*kms_cursor_crc*"
-t ".*kms_flip.*"

New tests passing
---
- pipe-A-cursor-size-change
- pipe-A-cursor-alpha-transparent

Performance
---
Following some optimization proposed by Pekka Paalanen, now the code
runs way faster than V1 and slightly faster than the current implementation.

|  Frametime  |
|:---:|:-:|:--:|::|
|  implmentation  |  Current  |  Per-pixel(V1) | Per-line(V2) |
| frametime range |  8~22 ms  |32~56 ms|6~19 ms   |
| Average |  10.0 ms  | 35.8 ms|8.6 ms|

Writeback test
--
During the development of this patch series, I discovered that the
writeback-check-output test wasn't filling the plane correctly.

So, currently, this patch series is failing in this test. But I sent a
patch to igt to fix it[1].

XRGB to ARGB behavior
=
During the development, I decided to always fill the alpha channel of
the output pixel whenever the conversion from a format without an alpha
channel to ARGB16161616 is necessary. Therefore, I ignore the value
received from the XRGB and overwrite the value with 0x.

---
Igor Torrente (8):
  drm: vkms: Replace the deprecated drm_mode_config_init
  drm: vkms: Alloc the compose frame using vzalloc
  drm: vkms: Replace hardcoded value of `vkms_composer.map` to
DRM_FORMAT_MAX_PLANES
  drm: vkms: Add fb information to `vkms_writeback_job`
  drm: drm_atomic_helper: Add a new helper to deal with the writeback
connector validation
  drm: vkms: Refactor the plane composer to accept new formats
  drm: vkms: Exposes ARGB_1616161616 and adds XRGB_16161616 formats
  drm: vkms: Add support to the RGB565 format

 drivers/gpu/drm/drm_atomic_helper.c   |  47 
 drivers/gpu/drm/vkms/vkms_composer.c  | 329 +++---
 drivers/gpu/drm/vkms/vkms_drv.c   |   6 +-
 drivers/gpu/drm/vkms/vkms_drv.h   |  14 +-
 drivers/gpu/drm/vkms/vkms_formats.h   | 252 
 drivers/gpu/drm/vkms/vkms_plane.c |  17 +-
 drivers/gpu/drm/vkms/vkms_writeback.c |  33 ++-
 include/drm/drm_atomic_helper.h   |   3 +
 8 files changed, 545 insertions(+), 156 deletions(-)
 create mode 100644 drivers/gpu/drm/vkms/vkms_formats.h

-- 
2.30.2



[PATCH v2 2/8] drm: vkms: Alloc the compose frame using vzalloc

2021-10-26 Thread Igor Torrente
Currently, the memory to the composition frame is being allocated using
the kzmalloc. This comes with the limitation of maximum size of one
page size(which in the x86_64 is 4Kb and 4MB for default and hugepage
respectively).

Somes test of igt (e.g. kms_plane@pixel-format) uses more than 4MB when
testing some pixel formats like ARGB16161616.

This problem is addessed by allocating the memory using kvzalloc that
circunvents this limitation.

Signed-off-by: Igor Torrente 
---
 drivers/gpu/drm/vkms/vkms_composer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index 9e8204be9a14..82f79e508f81 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -180,7 +180,7 @@ static int compose_active_planes(void **vaddr_out,
int i;
 
if (!*vaddr_out) {
-   *vaddr_out = kzalloc(gem_obj->size, GFP_KERNEL);
+   *vaddr_out = kvzalloc(gem_obj->size, GFP_KERNEL);
if (!*vaddr_out) {
DRM_ERROR("Cannot allocate memory for output frame.");
return -ENOMEM;
@@ -263,7 +263,7 @@ void vkms_composer_worker(struct work_struct *work)
crtc_state);
if (ret) {
if (ret == -EINVAL && !wb_pending)
-   kfree(vaddr_out);
+   kvfree(vaddr_out);
return;
}
 
@@ -275,7 +275,7 @@ void vkms_composer_worker(struct work_struct *work)
crtc_state->wb_pending = false;
spin_unlock_irq(&out->composer_lock);
} else {
-   kfree(vaddr_out);
+   kvfree(vaddr_out);
}
 
/*
-- 
2.30.2



[PATCH v2 1/8] drm: vkms: Replace the deprecated drm_mode_config_init

2021-10-26 Thread Igor Torrente
The `drm_mode_config_init` was deprecated since c3b790e commit, and it's
being replaced by the `drmm_mode_config_init`.

Signed-off-by: Igor Torrente 
---
V2: Change the code style(Thomas Zimmermann).
---
 drivers/gpu/drm/vkms/vkms_drv.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 0ffe5f0e33f7..ee4d96dabe19 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -140,8 +140,12 @@ static const struct drm_mode_config_helper_funcs 
vkms_mode_config_helpers = {
 static int vkms_modeset_init(struct vkms_device *vkmsdev)
 {
struct drm_device *dev = &vkmsdev->drm;
+   int ret;
+
+   ret = drmm_mode_config_init(dev);
+   if (ret < 0)
+   return ret;
 
-   drm_mode_config_init(dev);
dev->mode_config.funcs = &vkms_mode_funcs;
dev->mode_config.min_width = XRES_MIN;
dev->mode_config.min_height = YRES_MIN;
-- 
2.30.2



[PATCH v2 4/8] drm: vkms: Add fb information to `vkms_writeback_job`

2021-10-26 Thread Igor Torrente
This commit is the groundwork to introduce new formats to the planes and
writeback buffer. As part of it, a new buffer metadata field is added to
`vkms_writeback_job`, this metadata is represented by the `vkms_composer`
struct.

This will allow us, in the future, to have different compositing and wb
format types.

Signed-off-by: Igor Torrente 
---
V2: Change the code to get the drm_framebuffer reference and not copy its
contents(Thomas Zimmermann).
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  4 ++--
 drivers/gpu/drm/vkms/vkms_drv.h   | 12 ++--
 drivers/gpu/drm/vkms/vkms_plane.c | 10 +-
 drivers/gpu/drm/vkms/vkms_writeback.c | 21 ++---
 4 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index 82f79e508f81..383ca657ddf7 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -153,7 +153,7 @@ static void compose_plane(struct vkms_composer 
*primary_composer,
  struct vkms_composer *plane_composer,
  void *vaddr_out)
 {
-   struct drm_framebuffer *fb = &plane_composer->fb;
+   struct drm_framebuffer *fb = plane_composer->fb;
void *vaddr;
void (*pixel_blend)(const u8 *p_src, u8 *p_dst);
 
@@ -174,7 +174,7 @@ static int compose_active_planes(void **vaddr_out,
 struct vkms_composer *primary_composer,
 struct vkms_crtc_state *crtc_state)
 {
-   struct drm_framebuffer *fb = &primary_composer->fb;
+   struct drm_framebuffer *fb = primary_composer->fb;
struct drm_gem_object *gem_obj = drm_gem_fb_get_obj(fb, 0);
const void *vaddr;
int i;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 64e62993b06f..9e4c1e95bbb1 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -20,13 +20,8 @@
 #define XRES_MAX  8192
 #define YRES_MAX  8192
 
-struct vkms_writeback_job {
-   struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
-   struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
-};
-
 struct vkms_composer {
-   struct drm_framebuffer fb;
+   struct drm_framebuffer *fb;
struct drm_rect src, dst;
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
unsigned int offset;
@@ -34,6 +29,11 @@ struct vkms_composer {
unsigned int cpp;
 };
 
+struct vkms_writeback_job {
+   struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
+   struct vkms_composer composer;
+};
+
 /**
  * vkms_plane_state - Driver specific plane state
  * @base: base plane state
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c 
b/drivers/gpu/drm/vkms/vkms_plane.c
index 32409e15244b..0a28cb7a85e2 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -50,12 +50,12 @@ static void vkms_plane_destroy_state(struct drm_plane 
*plane,
struct vkms_plane_state *vkms_state = to_vkms_plane_state(old_state);
struct drm_crtc *crtc = vkms_state->base.base.crtc;
 
-   if (crtc) {
+   if (crtc && vkms_state->composer->fb) {
/* dropping the reference we acquired in
 * vkms_primary_plane_update()
 */
-   if (drm_framebuffer_read_refcount(&vkms_state->composer->fb))
-   drm_framebuffer_put(&vkms_state->composer->fb);
+   if (drm_framebuffer_read_refcount(vkms_state->composer->fb))
+   drm_framebuffer_put(vkms_state->composer->fb);
}
 
kfree(vkms_state->composer);
@@ -110,9 +110,9 @@ static void vkms_plane_atomic_update(struct drm_plane 
*plane,
composer = vkms_plane_state->composer;
memcpy(&composer->src, &new_state->src, sizeof(struct drm_rect));
memcpy(&composer->dst, &new_state->dst, sizeof(struct drm_rect));
-   memcpy(&composer->fb, fb, sizeof(struct drm_framebuffer));
+   composer->fb = fb;
memcpy(&composer->map, &shadow_plane_state->data, 
sizeof(composer->map));
-   drm_framebuffer_get(&composer->fb);
+   drm_framebuffer_get(composer->fb);
composer->offset = fb->offsets[0];
composer->pitch = fb->pitches[0];
composer->cpp = fb->format->cpp[0];
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
b/drivers/gpu/drm/vkms/vkms_writeback.c
index 8694227f555f..32734cdbf6c2 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -75,12 +75,15 @@ static int vkms_wb_prepare_job(struct 
drm_writeback_connector *wb_connector,
if (!vkmsjob)
return -ENOMEM;
 
-   ret = drm_gem_fb_vmap(job->fb, vkmsjob->map, vkmsjob->data);
+   ret = drm_gem_fb_vmap(job->fb, vkmsjob->composer.map, vkmsjob->data);
if (ret) {
DRM_ERROR("vmap failed: %d\n", ret);
goto err_kfree;
}
 
+   vkmsjob->com

[PATCH v2 5/8] drm: drm_atomic_helper: Add a new helper to deal with the writeback connector validation

2021-10-26 Thread Igor Torrente
Add a helper function to validate the connector configuration receive in
the encoder atomic_check by the drivers.

So the drivers don't need do these common validations themselves.

Signed-off-by: Igor Torrente 
---
V2: Move the format verification to a new helper at the drm_atomic_helper.c
(Thomas Zimmermann).
---
 drivers/gpu/drm/drm_atomic_helper.c   | 47 +++
 drivers/gpu/drm/vkms/vkms_writeback.c |  9 +++--
 include/drm/drm_atomic_helper.h   |  3 ++
 3 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 2c0c6ec92820..c2653b9824b5 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -766,6 +766,53 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
 
+/**
+ * drm_atomic_helper_check_wb_connector_state() - Check writeback encoder state
+ * @encoder: encoder state to check
+ * @conn_state: connector state to check
+ *
+ * Checks if the wriback connector state is valid, and returns a erros if it
+ * isn't.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int
+drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder,
+struct drm_connector_state *conn_state)
+{
+   struct drm_writeback_job *wb_job = conn_state->writeback_job;
+   struct drm_property_blob *pixel_format_blob;
+   bool format_supported = false;
+   struct drm_framebuffer *fb;
+   int i, n_formats;
+   u32 *formats;
+
+   if (!wb_job || !wb_job->fb)
+   return 0;
+
+   pixel_format_blob = wb_job->connector->pixel_formats_blob_ptr;
+   n_formats = pixel_format_blob->length / sizeof(u32);
+   formats = pixel_format_blob->data;
+   fb = wb_job->fb;
+
+   for (i = 0; i < n_formats; i++) {
+   if (fb->format->format == formats[i]) {
+   format_supported = true;
+   break;
+   }
+   }
+
+   if (!format_supported) {
+   DRM_DEBUG_KMS("Invalid pixel format %p4cc\n",
+ &fb->format->format);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state);
+
 /**
  * drm_atomic_helper_check_plane_state() - Check plane state for validity
  * @plane_state: plane state to check
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
b/drivers/gpu/drm/vkms/vkms_writeback.c
index 32734cdbf6c2..42f3396c523a 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -30,6 +30,7 @@ static int vkms_wb_encoder_atomic_check(struct drm_encoder 
*encoder,
 {
struct drm_framebuffer *fb;
const struct drm_display_mode *mode = &crtc_state->mode;
+   int ret;
 
if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
return 0;
@@ -41,11 +42,9 @@ static int vkms_wb_encoder_atomic_check(struct drm_encoder 
*encoder,
return -EINVAL;
}
 
-   if (fb->format->format != vkms_wb_formats[0]) {
-   DRM_DEBUG_KMS("Invalid pixel format %p4cc\n",
- &fb->format->format);
-   return -EINVAL;
-   }
+   ret = drm_atomic_helper_check_wb_encoder_state(encoder, conn_state);
+   if (ret < 0)
+   return ret;
 
return 0;
 }
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 4045e2507e11..3fbf695da60f 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -40,6 +40,9 @@ struct drm_private_state;
 
 int drm_atomic_helper_check_modeset(struct drm_device *dev,
struct drm_atomic_state *state);
+int
+drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder,
+struct drm_connector_state 
*conn_state);
 int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
const struct drm_crtc_state *crtc_state,
int min_scale,
-- 
2.30.2



[PATCH v2 7/8] drm: vkms: Exposes ARGB_1616161616 and adds XRGB_16161616 formats

2021-10-26 Thread Igor Torrente
This will be useful to write tests that depends on these formats.

ARGB format is already used as the universal format for internal uses.
Here we are just exposing it to the user space.

XRGB follows the a similar implementation of the former format.
Just overwriting the alpha channel.

Signed-off-by: Igor Torrente 
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  4 
 drivers/gpu/drm/vkms/vkms_formats.h   | 25 +
 drivers/gpu/drm/vkms/vkms_plane.c |  5 -
 drivers/gpu/drm/vkms/vkms_writeback.c |  2 ++
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index 69fe3a89bdc9..f16fcfc88cea 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -164,6 +164,8 @@ static void ((*get_line_fmt_transform_function(u32 format))
return &ARGB_to_ARGB16161616;
else if (format == DRM_FORMAT_ARGB16161616)
return &get_ARGB16161616;
+   else if (format == DRM_FORMAT_XRGB16161616)
+   return &XRGB16161616_to_ARGB16161616;
else
return &XRGB_to_ARGB16161616;
 }
@@ -175,6 +177,8 @@ static void ((*get_output_line_function(u32 format))
return &convert_to_ARGB;
else if (format == DRM_FORMAT_ARGB16161616)
return &convert_to_ARGB16161616;
+   else if (format == DRM_FORMAT_XRGB16161616)
+   return &convert_to_XRGB16161616;
else
return &convert_to_XRGB;
 }
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h 
b/drivers/gpu/drm/vkms/vkms_formats.h
index 5b850fce69f3..aa433edd00bd 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -89,6 +89,19 @@ static void get_ARGB16161616(void *pixels_addr, int length, 
u64 *line_buffer)
}
 }
 
+static void XRGB16161616_to_ARGB16161616(void *pixels_addr, int length,
+u64 *line_buffer)
+{
+   __le64 *src_pixels = pixels_addr;
+   int i;
+
+   for (i = 0; i < length; i++) {
+   line_buffer[i] = le64_to_cpu(*src_pixels) | (0xllu << 48);
+
+   src_pixels++;
+   }
+}
+
 /*
  * The following functions are used as blend operations. But unlike the
  * `alpha_blend`, these functions take an ARGB16161616 pixel from the
@@ -152,4 +165,16 @@ static void convert_to_ARGB16161616(void *pixels_addr, int 
length,
}
 }
 
+static void convert_to_XRGB16161616(void *pixels_addr, int length,
+   u64 *line_buffer)
+{
+   __le64 *dst_pixels = pixels_addr;
+   int i;
+
+   for (i = 0; i < length; i++) {
+   *dst_pixels = cpu_to_le64(line_buffer[i] | (0xllu << 48));
+   dst_pixels++;
+   }
+}
+
 #endif /* _VKMS_FORMATS_H_ */
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c 
b/drivers/gpu/drm/vkms/vkms_plane.c
index 0a28cb7a85e2..516e48b38806 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -13,11 +13,14 @@
 
 static const u32 vkms_formats[] = {
DRM_FORMAT_XRGB,
+   DRM_FORMAT_XRGB16161616
 };
 
 static const u32 vkms_plane_formats[] = {
DRM_FORMAT_ARGB,
-   DRM_FORMAT_XRGB
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XRGB16161616,
+   DRM_FORMAT_ARGB16161616
 };
 
 static struct drm_plane_state *
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
b/drivers/gpu/drm/vkms/vkms_writeback.c
index 42f3396c523a..0f7bb77f981e 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -14,6 +14,8 @@
 
 static const u32 vkms_wb_formats[] = {
DRM_FORMAT_XRGB,
+   DRM_FORMAT_XRGB16161616,
+   DRM_FORMAT_ARGB16161616
 };
 
 static const struct drm_connector_funcs vkms_wb_connector_funcs = {
-- 
2.30.2



[PATCH v2 3/8] drm: vkms: Replace hardcoded value of `vkms_composer.map` to DRM_FORMAT_MAX_PLANES

2021-10-26 Thread Igor Torrente
The `map` vector at `vkms_composer` uses a hardcoded value to define its
size.

If someday the maximum number of planes increases, this hardcoded value
can be a problem.

This value is being replaced with the DRM_FORMAT_MAX_PLANES macro.

Signed-off-by: Igor Torrente 
---
 drivers/gpu/drm/vkms/vkms_drv.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index d48c23d40ce5..64e62993b06f 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -28,7 +28,7 @@ struct vkms_writeback_job {
 struct vkms_composer {
struct drm_framebuffer fb;
struct drm_rect src, dst;
-   struct dma_buf_map map[4];
+   struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
unsigned int offset;
unsigned int pitch;
unsigned int cpp;
-- 
2.30.2



[PATCH v2 6/8] drm: vkms: Refactor the plane composer to accept new formats

2021-10-26 Thread Igor Torrente
Currently the blend function only accepts XRGB_ and ARGB_
as a color input.

This patch refactors all the functions related to the plane composition
to overcome this limitation.

Now the blend function receives a struct `vkms_pixel_composition_functions`
containing two handlers.

One will generate a buffer of each line of the frame with the pixels
converted to ARGB16161616. And the other will take this line buffer,
do some computation on it, and store the pixels in the destination.

Both the handlers have the same signature. They receive a pointer to
the pixels that will be processed(`pixels_addr`), the number of pixels
that will be treated(`length`), and the intermediate buffer of the size
of a frame line (`line_buffer`).

The first function has been totally described previously.

The second is more interesting, as it has to perform two roles depending
on where it is called in the code.

The first is to convert(if necessary) the data received in the
`line_buffer` and write in the memory pointed by `pixels_addr`.

The second role is to perform the `alpha_blend`. So, it takes the pixels
in the `line_buffer` and `pixels_addr`, executes the blend, and stores
the result back to the `pixels_addr`.

The per-line implementation was chosen for performance reasons.
The per-pixel functions were having performance issues due to indirect
function call overhead.

The per-line code trades off memory for execution time. The `line_buffer`
allows us to diminish the number of function calls.

Results in the IGT test `kms_cursor_crc`:

| Frametime   |
|:---:|:-:|:--:|::|
|  implmentation  |  Current  |  Per-pixel | Per-line |
| frametime range |  8~22 ms  |  32~56 ms  |  6~19 ms |
| Average |  10.0 ms  |   35.8 ms  |  8.6 ms  |

Reported-by: kernel test robot 
Signed-off-by: Igor Torrente 
---
V2: Improves the performance drastically, by perfoming the operations
per-line and not per-pixel(Pekka Paalanen).
Minor improvements(Pekka Paalanen).
---
 drivers/gpu/drm/vkms/vkms_composer.c | 321 ---
 drivers/gpu/drm/vkms/vkms_formats.h  | 155 +
 2 files changed, 342 insertions(+), 134 deletions(-)
 create mode 100644 drivers/gpu/drm/vkms/vkms_formats.h

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index 383ca657ddf7..69fe3a89bdc9 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -9,18 +9,26 @@
 #include 
 
 #include "vkms_drv.h"
-
-static u32 get_pixel_from_buffer(int x, int y, const u8 *buffer,
-const struct vkms_composer *composer)
-{
-   u32 pixel;
-   int src_offset = composer->offset + (y * composer->pitch)
- + (x * composer->cpp);
-
-   pixel = *(u32 *)&buffer[src_offset];
-
-   return pixel;
-}
+#include "vkms_formats.h"
+
+#define get_output_vkms_composer(buffer_pointer, composer) \
+   ((struct vkms_composer) {   \
+   .fb = &(struct drm_framebuffer) {   \
+   .format = &(struct drm_format_info) {   \
+   .format = DRM_FORMAT_ARGB16161616,  \
+   },  \
+   },  \
+   .map[0].vaddr = (buffer_pointer),   \
+   .src = (composer)->src, \
+   .dst = (composer)->dst, \
+   .cpp = sizeof(u64), \
+   .pitch = drm_rect_width(&(composer)->dst) * sizeof(u64) \
+   })
+
+struct vkms_pixel_composition_functions {
+   void (*get_src_line)(void *pixels_addr, int length, u64 *line_buffer);
+   void (*set_output_line)(void *pixels_addr, int length, u64 
*line_buffer);
+};
 
 /**
  * compute_crc - Compute CRC value on output frame
@@ -31,179 +39,222 @@ static u32 get_pixel_from_buffer(int x, int y, const u8 
*buffer,
  * returns CRC value computed using crc32 on the visible portion of
  * the final framebuffer at vaddr_out
  */
-static uint32_t compute_crc(const u8 *vaddr,
+static uint32_t compute_crc(const __le64 *vaddr,
const struct vkms_composer *composer)
 {
-   int x, y;
-   u32 crc = 0, pixel = 0;
-   int x_src = composer->src.x1 >> 16;
-   int y_src = composer->src.y1 >> 16;
-   int h_src = drm_rect_height(&composer->src) >> 16;
-   int w_src = drm_rect_width(&composer->src) >> 16;
-
-   for (y = y_src; y < y_src + h_src; ++y) {
-   for (x = x_src; x < x_src + w_src; ++x) {
-   pixel = get_pixel_from_buffer(x, y, vaddr, composer);
-   crc = crc32_le(crc, (void *)&pixel,

[PATCH v2 8/8] drm: vkms: Add support the RGB565 format

2021-10-26 Thread Igor Torrente
Adds this common format to vkms.

This commit also adds new helper macros to deal with fixed-point
arithmetic.

It was done to improve the precision of the conversion to ARGB16161616
since the "conversion ratio" is not an integer.

Signed-off-by: Igor Torrente 
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  4 ++
 drivers/gpu/drm/vkms/vkms_formats.h   | 72 +++
 drivers/gpu/drm/vkms/vkms_plane.c |  6 ++-
 drivers/gpu/drm/vkms/vkms_writeback.c |  3 +-
 4 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index f16fcfc88cea..57ec82839a89 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -166,6 +166,8 @@ static void ((*get_line_fmt_transform_function(u32 format))
return &get_ARGB16161616;
else if (format == DRM_FORMAT_XRGB16161616)
return &XRGB16161616_to_ARGB16161616;
+   else if (format == DRM_FORMAT_RGB565)
+   return &RGB565_to_ARGB16161616;
else
return &XRGB_to_ARGB16161616;
 }
@@ -179,6 +181,8 @@ static void ((*get_output_line_function(u32 format))
return &convert_to_ARGB16161616;
else if (format == DRM_FORMAT_XRGB16161616)
return &convert_to_XRGB16161616;
+   else if (format == DRM_FORMAT_RGB565)
+   return &convert_to_RGB565;
else
return &convert_to_XRGB;
 }
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h 
b/drivers/gpu/drm/vkms/vkms_formats.h
index aa433edd00bd..1e2db1a844aa 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -8,6 +8,26 @@
 #define pixel_offset(composer, x, y) \
((composer)->offset + ((y) * (composer)->pitch) + ((x) * 
(composer)->cpp))
 
+/*
+ * FP stands for _Fixed Point_ and **not** _Float Point_
+ * LF stands for Long Float (i.e. double)
+ * The following macros help doing fixed point arithmetic.
+ */
+/*
+ * With FP scale 15 we have 17 and 15 bits of integer and fractional parts
+ * respectively.
+ *  |     0.000    |
+ * 31  0
+ */
+#define FP_SCALE 15
+
+#define LF_TO_FP(a) ((a) * (u64)(1 << FP_SCALE))
+#define INT_TO_FP(a) ((a) << FP_SCALE)
+#define FP_MUL(a, b) ((s32)(((s64)(a) * (b)) >> FP_SCALE))
+#define FP_DIV(a, b) ((s32)(((s64)(a) << FP_SCALE) / (b)))
+/* This macro converts a fixed point number to int, and round half up it */
+#define FP_TO_INT_ROUND_UP(a) (((a) + (1 << (FP_SCALE - 1))) >> FP_SCALE)
+
 /*
  * packed_pixels_addr - Get the pointer to pixel of a given pair of coordinates
  *
@@ -102,6 +122,35 @@ static void XRGB16161616_to_ARGB16161616(void 
*pixels_addr, int length,
}
 }
 
+static void RGB565_to_ARGB16161616(void *pixels_addr, int length,
+  u64 *line_buffer)
+{
+   __le16 *src_pixels = pixels_addr;
+   int i;
+
+   for (i = 0; i < length; i++) {
+   u16 rgb_565 = le16_to_cpu(*src_pixels);
+   int fp_r = INT_TO_FP((rgb_565 >> 11) & 0x1f);
+   int fp_g = INT_TO_FP((rgb_565 >> 5) & 0x3f);
+   int fp_b = INT_TO_FP(rgb_565 & 0x1f);
+
+   /*
+* The magic constants is the "conversion ratio" and is 
calculated
+* dividing 65535(2^16 - 1) by 31(2^5 -1) and 63(2^6 - 1) 
respectively.
+*/
+   int fp_rb_ratio = LF_TO_FP(2114.032258065);
+   int fp_g_ratio = LF_TO_FP(1040.238095238);
+
+   u64 r = FP_TO_INT_ROUND_UP(FP_MUL(fp_r, fp_rb_ratio));
+   u64 g = FP_TO_INT_ROUND_UP(FP_MUL(fp_g, fp_g_ratio));
+   u64 b = FP_TO_INT_ROUND_UP(FP_MUL(fp_b, fp_rb_ratio));
+
+   line_buffer[i] = 0xllu << 48 | r << 32 | g << 16 | b;
+
+   src_pixels++;
+   }
+}
+
 /*
  * The following functions are used as blend operations. But unlike the
  * `alpha_blend`, these functions take an ARGB16161616 pixel from the
@@ -177,4 +226,27 @@ static void convert_to_XRGB16161616(void *pixels_addr, int 
length,
}
 }
 
+static void convert_to_RGB565(void *pixels_addr, int length,
+ u64 *line_buffer)
+{
+   __le16 *dst_pixels = pixels_addr;
+   int i;
+
+   for (i = 0; i < length; i++)  {
+   int fp_r = INT_TO_FP((line_buffer[i] >> 32) & 0x);
+   int fp_g = INT_TO_FP((line_buffer[i] >> 16) & 0x);
+   int fp_b = INT_TO_FP(line_buffer[i] & 0xllu);
+
+   int fp_rb_ratio = LF_TO_FP(2114.032258065);
+   int fp_g_ratio = LF_TO_FP(1040.238095238);
+
+   u16 r = FP_TO_INT_ROUND_UP(FP_DIV(fp_r, fp_rb_ratio));
+   u16 g = FP_TO_INT_ROUND_UP(FP_DIV(fp_g, fp_g_ratio));
+   u16 b = FP_TO_INT_ROUND_UP(FP_DIV(fp_b, fp_rb_ratio));
+
+   *dst_pixels = cpu_to_le16(r 

[PATCH v2 8/8] drm: vkms: Add support to the RGB565 format

2021-10-26 Thread Igor Torrente
Adds this common format to vkms.

This commit also adds new helper macros to deal with fixed-point
arithmetic.

It was done to improve the precision of the conversion to ARGB16161616
since the "conversion ratio" is not an integer.

Signed-off-by: Igor Torrente 
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  4 ++
 drivers/gpu/drm/vkms/vkms_formats.h   | 72 +++
 drivers/gpu/drm/vkms/vkms_plane.c |  6 ++-
 drivers/gpu/drm/vkms/vkms_writeback.c |  3 +-
 4 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index f16fcfc88cea..57ec82839a89 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -166,6 +166,8 @@ static void ((*get_line_fmt_transform_function(u32 format))
return &get_ARGB16161616;
else if (format == DRM_FORMAT_XRGB16161616)
return &XRGB16161616_to_ARGB16161616;
+   else if (format == DRM_FORMAT_RGB565)
+   return &RGB565_to_ARGB16161616;
else
return &XRGB_to_ARGB16161616;
 }
@@ -179,6 +181,8 @@ static void ((*get_output_line_function(u32 format))
return &convert_to_ARGB16161616;
else if (format == DRM_FORMAT_XRGB16161616)
return &convert_to_XRGB16161616;
+   else if (format == DRM_FORMAT_RGB565)
+   return &convert_to_RGB565;
else
return &convert_to_XRGB;
 }
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h 
b/drivers/gpu/drm/vkms/vkms_formats.h
index aa433edd00bd..1e2db1a844aa 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -8,6 +8,26 @@
 #define pixel_offset(composer, x, y) \
((composer)->offset + ((y) * (composer)->pitch) + ((x) * 
(composer)->cpp))
 
+/*
+ * FP stands for _Fixed Point_ and **not** _Float Point_
+ * LF stands for Long Float (i.e. double)
+ * The following macros help doing fixed point arithmetic.
+ */
+/*
+ * With FP scale 15 we have 17 and 15 bits of integer and fractional parts
+ * respectively.
+ *  |     0.000    |
+ * 31  0
+ */
+#define FP_SCALE 15
+
+#define LF_TO_FP(a) ((a) * (u64)(1 << FP_SCALE))
+#define INT_TO_FP(a) ((a) << FP_SCALE)
+#define FP_MUL(a, b) ((s32)(((s64)(a) * (b)) >> FP_SCALE))
+#define FP_DIV(a, b) ((s32)(((s64)(a) << FP_SCALE) / (b)))
+/* This macro converts a fixed point number to int, and round half up it */
+#define FP_TO_INT_ROUND_UP(a) (((a) + (1 << (FP_SCALE - 1))) >> FP_SCALE)
+
 /*
  * packed_pixels_addr - Get the pointer to pixel of a given pair of coordinates
  *
@@ -102,6 +122,35 @@ static void XRGB16161616_to_ARGB16161616(void 
*pixels_addr, int length,
}
 }
 
+static void RGB565_to_ARGB16161616(void *pixels_addr, int length,
+  u64 *line_buffer)
+{
+   __le16 *src_pixels = pixels_addr;
+   int i;
+
+   for (i = 0; i < length; i++) {
+   u16 rgb_565 = le16_to_cpu(*src_pixels);
+   int fp_r = INT_TO_FP((rgb_565 >> 11) & 0x1f);
+   int fp_g = INT_TO_FP((rgb_565 >> 5) & 0x3f);
+   int fp_b = INT_TO_FP(rgb_565 & 0x1f);
+
+   /*
+* The magic constants is the "conversion ratio" and is 
calculated
+* dividing 65535(2^16 - 1) by 31(2^5 -1) and 63(2^6 - 1) 
respectively.
+*/
+   int fp_rb_ratio = LF_TO_FP(2114.032258065);
+   int fp_g_ratio = LF_TO_FP(1040.238095238);
+
+   u64 r = FP_TO_INT_ROUND_UP(FP_MUL(fp_r, fp_rb_ratio));
+   u64 g = FP_TO_INT_ROUND_UP(FP_MUL(fp_g, fp_g_ratio));
+   u64 b = FP_TO_INT_ROUND_UP(FP_MUL(fp_b, fp_rb_ratio));
+
+   line_buffer[i] = 0xllu << 48 | r << 32 | g << 16 | b;
+
+   src_pixels++;
+   }
+}
+
 /*
  * The following functions are used as blend operations. But unlike the
  * `alpha_blend`, these functions take an ARGB16161616 pixel from the
@@ -177,4 +226,27 @@ static void convert_to_XRGB16161616(void *pixels_addr, int 
length,
}
 }
 
+static void convert_to_RGB565(void *pixels_addr, int length,
+ u64 *line_buffer)
+{
+   __le16 *dst_pixels = pixels_addr;
+   int i;
+
+   for (i = 0; i < length; i++)  {
+   int fp_r = INT_TO_FP((line_buffer[i] >> 32) & 0x);
+   int fp_g = INT_TO_FP((line_buffer[i] >> 16) & 0x);
+   int fp_b = INT_TO_FP(line_buffer[i] & 0xllu);
+
+   int fp_rb_ratio = LF_TO_FP(2114.032258065);
+   int fp_g_ratio = LF_TO_FP(1040.238095238);
+
+   u16 r = FP_TO_INT_ROUND_UP(FP_DIV(fp_r, fp_rb_ratio));
+   u16 g = FP_TO_INT_ROUND_UP(FP_DIV(fp_g, fp_g_ratio));
+   u16 b = FP_TO_INT_ROUND_UP(FP_DIV(fp_b, fp_rb_ratio));
+
+   *dst_pixels = cpu_to_le16(r 

[PATCH v2 0/9] drm/i915: PREEMPT_RT related fixups.

2021-10-26 Thread Sebastian Andrzej Siewior
the following patches are from the PREEMPT_RT queue. It is mostly about
disabling interrupts/preemption which leads to problems. Patches 1-4 are
independent of PREEMPT_RT.

Unfortunately DRM_I915_LOW_LEVEL_TRACEPOINTS had to be disabled because
it acquires locks from within trace points. It has been pointed out in
the previous post that this makes any kind of debugging impossible.
Making the uncore.lock a raw_spinlock_t doubles the latencies in my
limited testing [0]. I don't know the difference on other hardware. Also
it worries me a little that wait_for_atomic() has 50ms as the upper
spin/wait limit if the condition does not become true.

I tested it on a SandyBridge with built-in i915 by using X, OpenGL and
playing videos without noticing any warnings. However, some code paths
were not entered.

[0] https://lore.kernel.org/all/20211006164628.s2mtsdd2jdbfy...@linutronix.de/

Sebastian




[PATCH 3/9] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock()

2021-10-26 Thread Sebastian Andrzej Siewior
execlists_dequeue() is invoked from a function which uses
local_irq_disable() to disable interrupts so the spin_lock() behaves
like spin_lock_irq().
This breaks PREEMPT_RT because local_irq_disable() + spin_lock() is not
the same as spin_lock_irq().

execlists_dequeue_irq() and execlists_dequeue() has each one caller
only. If intel_engine_cs::active::lock is acquired and released with the
_irq suffix then it behaves almost as if execlists_dequeue() would be
invoked with disabled interrupts. The difference is the last part of the
function which is then invoked with enabled interrupts.
I can't tell if this makes a difference. From looking at it, it might
work to move the last unlock at the end of the function as I didn't find
anything that would acquire the lock again.

Reported-by: Clark Williams 
Signed-off-by: Sebastian Andrzej Siewior 
Reviewed-by: Maarten Lankhorst 
---
 .../drm/i915/gt/intel_execlists_submission.c| 17 +
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index bedb80057046a..1dbcac05f44eb 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -1284,7 +1284,7 @@ static void execlists_dequeue(struct intel_engine_cs 
*engine)
 * and context switches) submission.
 */
 
-   spin_lock(&sched_engine->lock);
+   spin_lock_irq(&sched_engine->lock);
 
/*
 * If the queue is higher priority than the last
@@ -1384,7 +1384,7 @@ static void execlists_dequeue(struct intel_engine_cs 
*engine)
 * Even if ELSP[1] is occupied and not worthy
 * of timeslices, our queue might be.
 */
-   spin_unlock(&sched_engine->lock);
+   spin_unlock_irq(&sched_engine->lock);
return;
}
}
@@ -1410,7 +1410,7 @@ static void execlists_dequeue(struct intel_engine_cs 
*engine)
 
if (last && !can_merge_rq(last, rq)) {
spin_unlock(&ve->base.sched_engine->lock);
-   spin_unlock(&engine->sched_engine->lock);
+   spin_unlock_irq(&engine->sched_engine->lock);
return; /* leave this for another sibling */
}
 
@@ -1572,7 +1572,7 @@ static void execlists_dequeue(struct intel_engine_cs 
*engine)
 */
sched_engine->queue_priority_hint = queue_prio(sched_engine);
i915_sched_engine_reset_on_empty(sched_engine);
-   spin_unlock(&sched_engine->lock);
+   spin_unlock_irq(&sched_engine->lock);
 
/*
 * We can skip poking the HW if we ended up with exactly the same set
@@ -1598,13 +1598,6 @@ static void execlists_dequeue(struct intel_engine_cs 
*engine)
}
 }
 
-static void execlists_dequeue_irq(struct intel_engine_cs *engine)
-{
-   local_irq_disable(); /* Suspend interrupts across request submission */
-   execlists_dequeue(engine);
-   local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */
-}
-
 static void clear_ports(struct i915_request **ports, int count)
 {
memset_p((void **)ports, NULL, count);
@@ -2424,7 +2417,7 @@ static void execlists_submission_tasklet(struct 
tasklet_struct *t)
}
 
if (!engine->execlists.pending[0]) {
-   execlists_dequeue_irq(engine);
+   execlists_dequeue(engine);
start_timeslice(engine);
}
 
-- 
2.33.1



[PATCH 8/9] drm/i915: Disable tracing points on PREEMPT_RT

2021-10-26 Thread Sebastian Andrzej Siewior
Luca Abeni reported this:
| BUG: scheduling while atomic: kworker/u8:2/15203/0x0003
| CPU: 1 PID: 15203 Comm: kworker/u8:2 Not tainted 4.19.1-rt3 #10
| Call Trace:
|  rt_spin_lock+0x3f/0x50
|  gen6_read32+0x45/0x1d0 [i915]
|  g4x_get_vblank_counter+0x36/0x40 [i915]
|  trace_event_raw_event_i915_pipe_update_start+0x7d/0xf0 [i915]

The tracing events use trace_i915_pipe_update_start() among other events
use functions acquire spinlock_t locks which are transformed into
sleeping locks on PREEMPT_RT. A few trace points use
intel_get_crtc_scanline(), others use ->get_vblank_counter() wich also
might acquire a sleeping locks on PREEMPT_RT.
At the time the arguments are evaluated within trace point, preemption
is disabled and so the locks must not be acquired on PREEMPT_RT.

Based on this I don't see any other way than disable trace points on
PREMPT_RT.

Reported-by: Luca Abeni 
Cc: Steven Rostedt 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/i915_trace.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 9795f456cccfc..0f8341ca67385 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -2,6 +2,10 @@
 #if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
 #define _I915_TRACE_H_
 
+#ifdef CONFIG_PREEMPT_RT
+#define NOTRACE
+#endif
+
 #include 
 #include 
 #include 
-- 
2.33.1



[PATCH 4/9] drm/i915: Drop the irqs_disabled() check

2021-10-26 Thread Sebastian Andrzej Siewior
The !irqs_disabled() check triggers on PREEMPT_RT even with
i915_sched_engine::lock acquired. The reason is the lock is transformed
into a sleeping lock on PREEMPT_RT and does not disable interrupts.

There is no need to check for disabled interrupts. The lockdep
annotation below already check if the lock has been acquired by the
caller and will yell if the interrupts are not disabled.

Remove the !irqs_disabled() check.

Reported-by: Maarten Lankhorst 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/i915_request.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index 820a1f38b271e..3bbe34ff3b15a 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -559,7 +559,6 @@ bool __i915_request_submit(struct i915_request *request)
 
RQ_TRACE(request, "\n");
 
-   GEM_BUG_ON(!irqs_disabled());
lockdep_assert_held(&engine->sched_engine->lock);
 
/*
@@ -668,7 +667,6 @@ void __i915_request_unsubmit(struct i915_request *request)
 */
RQ_TRACE(request, "\n");
 
-   GEM_BUG_ON(!irqs_disabled());
lockdep_assert_held(&engine->sched_engine->lock);
 
/*
-- 
2.33.1



[PATCH 2/9] drm/i915/gt: Queue and wait for the irq_work item.

2021-10-26 Thread Sebastian Andrzej Siewior
Disabling interrupts and invoking the irq_work function directly breaks
on PREEMPT_RT.
PREEMPT_RT does not invoke all irq_work from hardirq context because
some of the user have spinlock_t locking in the callback function.
These locks are then turned into a sleeping locks which can not be
acquired with disabled interrupts.

Using irq_work_queue() has the benefit that the irqwork will be invoked
in the regular context. In general there is "no" delay between enqueuing
the callback and its invocation because the interrupt is raised right
away on architectures which support it (which includes x86).

Use irq_work_queue() + irq_work_sync() instead invoking the callback
directly.

Reported-by: Clark Williams 
Signed-off-by: Sebastian Andrzej Siewior 
Reviewed-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index 209cf265bf746..6e1b9068d944c 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -311,10 +311,9 @@ void __intel_breadcrumbs_park(struct intel_breadcrumbs *b)
/* Kick the work once more to drain the signalers, and disarm the irq */
irq_work_sync(&b->irq_work);
while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) {
-   local_irq_disable();
-   signal_irq_work(&b->irq_work);
-   local_irq_enable();
+   irq_work_queue(&b->irq_work);
cond_resched();
+   irq_work_sync(&b->irq_work);
}
 }
 
-- 
2.33.1



[PATCH 1/9] drm/i915: Don't disable interrupts and pretend a lock as been acquired in __timeline_mark_lock().

2021-10-26 Thread Sebastian Andrzej Siewior
This is a revert of commits
   d67739268cf0e ("drm/i915/gt: Mark up the nested engine-pm timeline lock as 
irqsafe")
   6c69a45445af9 ("drm/i915/gt: Mark context->active_count as protected by 
timeline->mutex")

The existing code leads to a different behaviour depending on whether
lockdep is enabled or not. Any following lock that is acquired without
disabling interrupts (but needs to) will not be noticed by lockdep.

This it not just a lockdep annotation but is used but an actual mutex_t
that is properly used as a lock but in case of __timeline_mark_lock()
lockdep is only told that it is acquired but no lock has been acquired.

It appears that its purpose is just satisfy the lockdep_assert_held()
check in intel_context_mark_active(). The other problem with disabling
interrupts is that on PREEMPT_RT interrupts are also disabled which
leads to problems for instance later during memory allocation.

Add a CONTEXT_IS_PARKED bit to intel_engine_cs and set_bit/clear_bit it
instead of mutex_acquire/mutex_release. Use test_bit in the two
identified spots which relied on the lockdep annotation.

Acked-by: Peter Zijlstra (Intel) 
Suggested--by: Peter Zijlstra (Intel) 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/gt/intel_context.h   |  3 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |  1 +
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 38 +--
 drivers/gpu/drm/i915/i915_request.h   |  3 +-
 4 files changed, 7 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 246c37d72cd73..8a575629ef1b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -211,7 +211,8 @@ static inline void intel_context_enter(struct intel_context 
*ce)
 
 static inline void intel_context_mark_active(struct intel_context *ce)
 {
-   lockdep_assert_held(&ce->timeline->mutex);
+   lockdep_assert(lockdep_is_held(&ce->timeline->mutex) ||
+  test_bit(CONTEXT_IS_PARKED, &ce->flags));
++ce->active_count;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 9e0177dc5484e..329f470d125f2 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -118,6 +118,7 @@ struct intel_context {
 #define CONTEXT_LRCA_DIRTY 9
 #define CONTEXT_GUC_INIT   10
 #define CONTEXT_PERMA_PIN  11
+#define CONTEXT_IS_PARKED  12
 
struct {
u64 timeout_us;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index a1334b48dde7b..456f1f5d0c04e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -80,39 +80,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
return 0;
 }
 
-#if IS_ENABLED(CONFIG_LOCKDEP)
-
-static unsigned long __timeline_mark_lock(struct intel_context *ce)
-{
-   unsigned long flags;
-
-   local_irq_save(flags);
-   mutex_acquire(&ce->timeline->mutex.dep_map, 2, 0, _THIS_IP_);
-
-   return flags;
-}
-
-static void __timeline_mark_unlock(struct intel_context *ce,
-  unsigned long flags)
-{
-   mutex_release(&ce->timeline->mutex.dep_map, _THIS_IP_);
-   local_irq_restore(flags);
-}
-
-#else
-
-static unsigned long __timeline_mark_lock(struct intel_context *ce)
-{
-   return 0;
-}
-
-static void __timeline_mark_unlock(struct intel_context *ce,
-  unsigned long flags)
-{
-}
-
-#endif /* !IS_ENABLED(CONFIG_LOCKDEP) */
-
 static void duration(struct dma_fence *fence, struct dma_fence_cb *cb)
 {
struct i915_request *rq = to_request(fence);
@@ -159,7 +126,6 @@ static bool switch_to_kernel_context(struct intel_engine_cs 
*engine)
 {
struct intel_context *ce = engine->kernel_context;
struct i915_request *rq;
-   unsigned long flags;
bool result = true;
 
/*
@@ -214,7 +180,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs 
*engine)
 * engine->wakeref.count, we may see the request completion and retire
 * it causing an underflow of the engine->wakeref.
 */
-   flags = __timeline_mark_lock(ce);
+   set_bit(CONTEXT_IS_PARKED, &ce->flags);
GEM_BUG_ON(atomic_read(&ce->timeline->active_count) < 0);
 
rq = __i915_request_create(ce, GFP_NOWAIT);
@@ -246,7 +212,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs 
*engine)
 
result = false;
 out_unlock:
-   __timeline_mark_unlock(ce, flags);
+   clear_bit(CONTEXT_IS_PARKED, &ce->flags);
return result;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_request.h 
b/drivers/gpu/drm/i915/i915_request.h
index dc359242d1aec..c5898882bb27a 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/driv

[PATCH 9/9] drm/i915: skip DRM_I915_LOW_LEVEL_TRACEPOINTS with NOTRACE

2021-10-26 Thread Sebastian Andrzej Siewior
The order of the header files is important. If this header file is
included after tracepoint.h was included then the NOTRACE here becomes a
nop. Currently this happens for two .c files which use the tracepoitns
behind DRM_I915_LOW_LEVEL_TRACEPOINTS.

Cc: Steven Rostedt 
Signed-off-by: Sebastian Andrzej Siewior 
Signed-off-by: Thomas Gleixner 
---
 drivers/gpu/drm/i915/i915_trace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 0f8341ca67385..0aefb14c638ae 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -826,7 +826,7 @@ DEFINE_EVENT(i915_request, i915_request_add,
 TP_ARGS(rq)
 );
 
-#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS)
+#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) && !defined(NOTRACE)
 DEFINE_EVENT(i915_request, i915_request_guc_submit,
 TP_PROTO(struct i915_request *rq),
 TP_ARGS(rq)
-- 
2.33.1



[PATCH 6/9] drm/i915: Don't disable interrupts on PREEMPT_RT during atomic updates

2021-10-26 Thread Sebastian Andrzej Siewior
From: Mike Galbraith 

Commit
   8d7849db3eab7 ("drm/i915: Make sprite updates atomic")

started disabling interrupts across atomic updates. This breaks on PREEMPT_RT
because within this section the code attempt to acquire spinlock_t locks which
are sleeping locks on PREEMPT_RT.

According to the comment the interrupts are disabled to avoid random delays and
not required for protection or synchronisation.
If this needs to happen with disabled interrupts on PREEMPT_RT, and the
whole section is restricted to register access then all sleeping locks
need to be acquired before interrupts are disabled and some function
maybe moved after enabling interrupts again.
This includes:
- prepare_to_wait() + finish_wait() due its wake queue.
- drm_crtc_vblank_put() -> vblank_disable_fn() drm_device::vbl_lock.
- skl_pfit_enable(), intel_update_plane(), vlv_atomic_update_fifo() and
  maybe others due to intel_uncore::lock
- drm_crtc_arm_vblank_event() due to drm_device::event_lock and
  drm_device::vblank_time_lock.

Don't disable interrupts on PREEMPT_RT during atomic updates.

[bigeasy: drop local locks, commit message]

Signed-off-by: Mike Galbraith 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/display/intel_crtc.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c 
b/drivers/gpu/drm/i915/display/intel_crtc.c
index 254e67141a776..7a39029b083f4 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -425,7 +425,8 @@ void intel_pipe_update_start(const struct intel_crtc_state 
*new_crtc_state)
 */
intel_psr_wait_for_idle(new_crtc_state);
 
-   local_irq_disable();
+   if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+   local_irq_disable();
 
crtc->debug.min_vbl = min;
crtc->debug.max_vbl = max;
@@ -450,11 +451,13 @@ void intel_pipe_update_start(const struct 
intel_crtc_state *new_crtc_state)
break;
}
 
-   local_irq_enable();
+   if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+   local_irq_enable();
 
timeout = schedule_timeout(timeout);
 
-   local_irq_disable();
+   if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+   local_irq_disable();
}
 
finish_wait(wq, &wait);
@@ -487,7 +490,8 @@ void intel_pipe_update_start(const struct intel_crtc_state 
*new_crtc_state)
return;
 
 irq_disable:
-   local_irq_disable();
+   if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+   local_irq_disable();
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE)
@@ -566,7 +570,8 @@ void intel_pipe_update_end(struct intel_crtc_state 
*new_crtc_state)
new_crtc_state->uapi.event = NULL;
}
 
-   local_irq_enable();
+   if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+   local_irq_enable();
 
/* Send VRR Push to terminate Vblank */
intel_vrr_send_push(new_crtc_state);
-- 
2.33.1



[PATCH 7/9] drm/i915: Don't check for atomic context on PREEMPT_RT

2021-10-26 Thread Sebastian Andrzej Siewior
The !in_atomic() check in _wait_for_atomic() triggers on PREEMPT_RT
because the uncore::lock is a spinlock_t and does not disable
preemption or interrupts.

Changing the uncore:lock to a raw_spinlock_t doubles the worst case
latency on an otherwise idle testbox during testing. Therefore I'm
currently unsure about changing this.

Link: https://lore.kernel.org/all/20211006164628.s2mtsdd2jdbfy...@linutronix.de/
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/i915_utils.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index 7a5925072466a..b7b56fb1e2fc7 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -344,7 +344,7 @@ wait_remaining_ms_from_jiffies(unsigned long 
timestamp_jiffies, int to_wait_ms)
 #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000)
 
 /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */
-#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT)
+#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) && 
!defined(CONFIG_PREEMPT_RT)
 # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic())
 #else
 # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0)
-- 
2.33.1



[PATCH 5/9] drm/i915: Use preempt_disable/enable_rt() where recommended

2021-10-26 Thread Sebastian Andrzej Siewior
From: Mike Galbraith 

Mario Kleiner suggest in commit
  ad3543ede630f ("drm/intel: Push get_scanout_position() timestamping into kms 
driver.")

a spots where preemption should be disabled on PREEMPT_RT. The
difference is that on PREEMPT_RT the intel_uncore::lock disables neither
preemption nor interrupts and so region remains preemptible.

The area covers only register reads and writes. The part that worries me
is:
- __intel_get_crtc_scanline() the worst case is 100us if no match is
  found.

- intel_crtc_scanlines_since_frame_timestamp() not sure how long this
  may take in the worst case.

It was in the RT queue for a while and nobody complained.
Disable preemption on PREEPMPT_RT during timestamping.

[bigeasy: patch description.]

Cc: Mario Kleiner 
Signed-off-by: Mike Galbraith 
Signed-off-by: Thomas Gleixner 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/i915_irq.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 77680bca46eec..be8f60226 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -916,7 +916,8 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
 */
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
-   /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
+   if (IS_ENABLED(CONFIG_PREEMPT_RT))
+   preempt_disable();
 
/* Get optional system timestamp before query. */
if (stime)
@@ -980,7 +981,8 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
if (etime)
*etime = ktime_get();
 
-   /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
+   if (IS_ENABLED(CONFIG_PREEMPT_RT))
+   preempt_enable();
 
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 
-- 
2.33.1



Re: [PATCH v3] dma-buf: remove restriction of IOCTL:DMA_BUF_SET_NAME

2021-10-26 Thread guangming.cao
From: Guangming Cao 

On Tue, 2021-10-26 at 13:18 +0200, Christian König wrote:
> Am 14.10.21 um 12:25 schrieb guangming@mediatek.com:
> > From: Guangming Cao 
> > 
> > In this patch(https://patchwork.freedesktop.org/patch/310349),
> > it add a new IOCTL to support dma-buf user to set debug name.
> > 
> > But it also added a limitation of this IOCTL, it needs the
> > attachments of dmabuf should be empty, otherwise it will fail.
> > 
> > For the original series, the idea was that allowing name change
> > mid-use could confuse the users about the dma-buf.
> > However, the rest of the series also makes sure each dma-buf have a
> > unique
> > inode(https://patchwork.freedesktop.org/patch/310387/), and any
> > accounting
> > should probably use that, without relying on the name as much.
> > 
> > So, removing this restriction will let dma-buf userspace users to
> > use it
> > more comfortably and without any side effect.
> > 
> > Signed-off-by: Guangming Cao 
> 
> We could now cleanup the return value from dma_buf_set_name() into a 
> void since that function can't fail any more as far as I can see.
> 
> But that isn't mandatory I think, patch is Reviewed-by: Christian
> König 
> 
>

So, here is no need to check return value of 'strndup_user',
just return without error code if the almost impossible error occurs?

Guangming.

> Regards,
> Christian.
> 
> > ---
> >   drivers/dma-buf/dma-buf.c | 17 +++--
> >   1 file changed, 3 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> > index 511fe0d217a0..5fbb3a2068a3 100644
> > --- a/drivers/dma-buf/dma-buf.c
> > +++ b/drivers/dma-buf/dma-buf.c
> > @@ -325,10 +325,8 @@ static __poll_t dma_buf_poll(struct file
> > *file, poll_table *poll)
> >   
> >   /**
> >* dma_buf_set_name - Set a name to a specific dma_buf to track
> > the usage.
> > - * The name of the dma-buf buffer can only be set when the dma-buf 
> > is not
> > - * attached to any devices. It could theoritically support
> > changing the
> > - * name of the dma-buf if the same piece of memory is used for
> > multiple
> > - * purpose between different devices.
> > + * It could support changing the name of the dma-buf if the same
> > + * piece of memory is used for multiple purpose between different
> > devices.
> >*
> >* @dmabuf: [in] dmabuf buffer that will be renamed.
> >* @buf:[in] A piece of userspace memory that contains
> > the name of
> > @@ -341,25 +339,16 @@ static __poll_t dma_buf_poll(struct file
> > *file, poll_table *poll)
> >   static long dma_buf_set_name(struct dma_buf *dmabuf, const char
> > __user *buf)
> >   {
> > char *name = strndup_user(buf, DMA_BUF_NAME_LEN);
> > -   long ret = 0;
> >   
> > if (IS_ERR(name))
> > return PTR_ERR(name);
> >   
> > -   dma_resv_lock(dmabuf->resv, NULL);
> > -   if (!list_empty(&dmabuf->attachments)) {
> > -   ret = -EBUSY;
> > -   kfree(name);
> > -   goto out_unlock;
> > -   }
> > spin_lock(&dmabuf->name_lock);
> > kfree(dmabuf->name);
> > dmabuf->name = name;
> > spin_unlock(&dmabuf->name_lock);
> >   
> > -out_unlock:
> > -   dma_resv_unlock(dmabuf->resv);
> > -   return ret;
> > +   return 0;
> >   }
> >   
> >   static long dma_buf_ioctl(struct file *file,
> 
> 


Re: [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-26 Thread Paul Menzel

Dear Mark,


Thank you for your patch.

On 13.10.21 20:12, Mark Yacoub wrote:

From: Mark Yacoub 

[Why]
1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
or Degamma props in the new CRTC state, allowing any invalid size to
be passed on.
2. Each driver has its own LUT size, which could also be different for
legacy users.


How can the problem be reproduced?


[How]
1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
assigned by the driver when it's initializing its color and CTM
management.
2. Create drm_atomic_helper_check_crtc which is called by
drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
they match the sizes in the new CRTC state.
3. Rename older lut checks that test for the color channels to indicate
it's a channel check. It's not included in drm_atomic_helper_check_crtc
as it's hardware specific and is to be called by the driver.
4. As the LUT size check now happens in drm_atomic_helper_check, remove
the lut check in intel_color.c

Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK


If I am not mistaken, the Fixes tag is used for commits I believe. Maybe 
use Resolves or something similar?



Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)


Please add a space before the (.

How did you test this?


v1:
1. Fix typos
2. Remove the LUT size check from intel driver
3. Rename old LUT check to indicate it's a channel change

Signed-off-by: Mark Yacoub 
---
  drivers/gpu/drm/drm_atomic_helper.c| 60 ++
  drivers/gpu/drm/drm_color_mgmt.c   | 14 ++---
  drivers/gpu/drm/i915/display/intel_color.c | 14 ++---
  include/drm/drm_atomic_helper.h|  1 +
  include/drm/drm_color_mgmt.h   |  7 +--
  include/drm/drm_crtc.h | 11 
  6 files changed, 89 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5e..5feb2ad0209c3 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -929,6 +929,62 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
  }
  EXPORT_SYMBOL(drm_atomic_helper_check_planes);
  
+/**

+ * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
+ * @state: the driver state object
+ *
+ * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new
+ * state holds them.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->gamma_lut) {
+   uint64_t supported_lut_size = crtc->gamma_lut_size;
+   uint32_t supported_legacy_lut_size = crtc->gamma_size;
+   uint32_t new_state_lut_size =
+   drm_color_lut_size(new_crtc_state->gamma_lut);
+
+   if (new_state_lut_size != supported_lut_size &&
+   new_state_lut_size != supported_legacy_lut_size) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Gamma LUT size. Should be %u (or %u 
for legacy) but got %u.\n",
+   supported_lut_size,
+   supported_legacy_lut_size,
+   new_state_lut_size);
+   return -EINVAL;
+   }
+   }
+
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->degamma_lut) {
+   uint32_t new_state_lut_size =
+   drm_color_lut_size(new_crtc_state->degamma_lut);
+   uint64_t supported_lut_size = crtc->degamma_lut_size;
+
+   if (new_state_lut_size != supported_lut_size) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Degamma LUT size. Should be %u but 
got %u.\n",
+   supported_lut_size, new_state_lut_size);
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_crtcs);
+
  /**
   * drm_atomic_helper_check - validate state object
   * @dev: DRM device
@@ -974,6 +1030,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
  
+	ret = drm_atomic_helper_check_crtcs(state);

+   if (ret)
+   return ret;
+
if (state->legacy_cursor_update)
state->async_update = !drm_a

[PULL] drm-misc-fixes

2021-10-26 Thread Maarten Lankhorst
Hi Dave and Dan,

Last pull request for me for v5.15 I hope.
Out for vacation until the third week of november,
Maxime offered to do the remainder of v5.15.

~Maarten

drm-misc-fixes-2021-10-26:
drm-misc-fixes for v5.15-rc8:
- Fix fence leak in ttm_transfered_destroy.
- Add quirk for Aya Neo 2021
- Reset property count for each drm damage selftest so full run will work 
correctly.
The following changes since commit 74056092ff415e7e20ce2544689b32ee811c4f0b:

  drm/kmb: Enable ADV bridge after modeset (2021-10-21 11:08:09 +0200)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2021-10-26

for you to fetch changes up to ee71fb6c4d99c51f2d82a32c503c872b7e40e7f7:

  drm/i915/selftests: Properly reset mock object propers for each test 
(2021-10-22 11:09:45 +0200)


drm-misc-fixes for v5.15-rc8:
- Fix fence leak in ttm_transfered_destroy.
- Add quirk for Aya Neo 2021
- Reset property count for each drm damage selftest so full run will work 
correctly.


Bryant Mairs (1):
  drm: panel-orientation-quirks: Add quirk for Aya Neo 2021

Christian König (1):
  drm/ttm: fix memleak in ttm_transfered_destroy

Daniel Vetter (1):
  drm/i915/selftests: Properly reset mock object propers for each test

 drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++
 drivers/gpu/drm/selftests/test-drm_damage_helper.c | 1 +
 drivers/gpu/drm/ttm/ttm_bo_util.c  | 1 +
 3 files changed, 8 insertions(+)


[Bug 211807] [drm:drm_dp_mst_dpcd_read] *ERROR* mstb 000000004e6288dd port 3: DPCD read on addr 0x60 for 1 bytes NAKed

2021-10-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211807

--- Comment #13 from Alex Deucher (alexdeuc...@gmail.com) ---
(In reply to zwerg12 from comment #12)
> As mentioned before, I get the same error with a monitor connected with DP
> to a Lenovo ThinkPad USB-C Dock Gen2. My Laptop has an Intel i7 10510U no
> additional graphics card. I am using Debian testing with the provided kernel.
> 
> 
> During this my notebook monitor is blinking.
> This setup worked for around four weeks when suddenly these errors occurred.


Can you bisect?

-- 
You may reply to this email to add a comment.

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

Re: [PATCH] video: fbdev: cirrusfb: check pixclock to avoid divide by zero

2021-10-26 Thread George Kennedy

Hi Geert,

On 10/26/2021 4:30 AM, Geert Uytterhoeven wrote:

Hi George,

On Mon, Oct 25, 2021 at 9:37 PM George Kennedy
 wrote:

On 10/25/2021 3:07 PM, Greg KH wrote:

On Mon, Oct 25, 2021 at 02:01:30PM -0500, George Kennedy wrote:

Do a sanity check on pixclock value before using it as a divisor.

Syzkaller reported a divide error in cirrusfb_check_pixclock.

divide error:  [#1] SMP KASAN PTI
CPU: 0 PID: 14938 Comm: cirrusfb_test Not tainted 5.15.0-rc6 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2
RIP: 0010:cirrusfb_check_var+0x6f1/0x1260

Call Trace:
   fb_set_var+0x398/0xf90
   do_fb_ioctl+0x4b8/0x6f0
   fb_ioctl+0xeb/0x130
   __x64_sys_ioctl+0x19d/0x220
   do_syscall_64+0x3a/0x80
   entry_SYSCALL_64_after_hwframe+0x44/0xae

Signed-off-by: George Kennedy 
---
   drivers/video/fbdev/cirrusfb.c | 3 +++
   1 file changed, 3 insertions(+)

diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index 93802ab..099ddcb 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -477,6 +477,9 @@ static int cirrusfb_check_pixclock(const struct 
fb_var_screeninfo *var,
  struct cirrusfb_info *cinfo = info->par;
  unsigned maxclockidx = var->bits_per_pixel >> 3;

+if (!var->pixclock)
+return -EINVAL;

This is not correct: fbdev drivers should round up invalid values,
and only return an error if rounding up cannot yield a valid value.


What default value would you recommend? Here are examples of some of the 
possible cirrusfb pixclock values:

4: 25MHz
2: 50Mhz
12500: 80Mhz

We can plug in a default value, but I believe it is just covering up the 
fact that an incorrect value has been copied in.


I would think we would want to keep this driver consistent with the 
other fb drivers that return failure with the incorrect value.


Thank you,
George



Shouldn't you be checking further up the call chain where this got set
to 0?

The same pixclock check is done in these fb drivers:

arch/arm/mach-rpc/include/mach/acornfb.h:if (!var->pixclock)
drivers/video/fbdev/asiliantfb.c:if (!var->pixclock)
drivers/video/fbdev/clps711x-fb.c:if (!var->pixclock)
drivers/video/fbdev/core/fbmon.c:if (!var->pixclock)
drivers/video/fbdev/core/modedb.c:if (!var->pixclock)
drivers/video/fbdev/cirrusfb.c:if (!var->pixclock)
drivers/video/fbdev/kyro/fbdev.c:if (!var->pixclock)
drivers/video/fbdev/riva/fbdev.c:if (!var->pixclock)
drivers/video/fbdev/uvesafb.c:if (!var->pixclock)


What logic allows this to be a valid value?  What about all other fb
drivers?

The "check_var" function, which is set into the ".fb_check_var" element
of the fb_ops struct, should do the check, but in the case of cirrusfb,
that is not being done.

All this patch does is add the same pixclock check that the other above
fb drivers do.

Indeed, several drivers are not following the rounding rules.

Gr{oetje,eeting}s,

 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
 -- Linus Torvalds




Re: [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire

2021-10-26 Thread Guenter Roeck
On Mon, Oct 18, 2021 at 06:45:03PM +0100, Matthew Auld wrote:
> As pointed out by Thomas, we likely need to flush the pages here if the
> GPU can read the page contents directly from main memory. Underneath we
> don't know what the sg_table is pointing to, so just add a
> wbinvd_on_all_cpus() here, for now.
> 
> Reported-by: Thomas Hellström 
> Signed-off-by: Matthew Auld 
> Cc: Thomas Hellström 

With nosmp builds:

Error log:
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c: In function 
'i915_gem_object_get_pages_dmabuf':
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c:248:17: error: implicit declaration 
of function 'wbinvd_on_all_cpus' [-Werror=implicit-function-declaration]
  248 | wbinvd_on_all_cpus();
  | ^~

Guenter

> ---
>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> index 5be505ebbb7b..1adcd8e02d29 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> @@ -232,6 +232,7 @@ struct dma_buf *i915_gem_prime_export(struct 
> drm_gem_object *gem_obj, int flags)
>  
>  static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
>  {
> + struct drm_i915_private *i915 = to_i915(obj->base.dev);
>   struct sg_table *pages;
>   unsigned int sg_page_sizes;
>  
> @@ -242,8 +243,11 @@ static int i915_gem_object_get_pages_dmabuf(struct 
> drm_i915_gem_object *obj)
>   if (IS_ERR(pages))
>   return PTR_ERR(pages);
>  
> - sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
> + /* XXX: consider doing a vmap flush or something */
> + if (!HAS_LLC(i915) || i915_gem_object_can_bypass_llc(obj))
> + wbinvd_on_all_cpus();
>  
> + sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
>   __i915_gem_object_set_pages(obj, pages, sg_page_sizes);
>  
>   return 0;
> -- 
> 2.26.3
> 


Re: [PATCH] dma-buf: st: fix error handling in test_get_fences()

2021-10-26 Thread Nathan Chancellor
On Tue, Oct 26, 2021 at 10:34:37AM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> The new driver incorrectly unwinds after errors, as clang points out:
> 
> drivers/dma-buf/st-dma-resv.c:295:7: error: variable 'i' is used 
> uninitialized whenever 'if' condition is true 
> [-Werror,-Wsometimes-uninitialized]
> if (r) {
> ^
> drivers/dma-buf/st-dma-resv.c:336:9: note: uninitialized use occurs here
> while (i--)
>^
> drivers/dma-buf/st-dma-resv.c:295:3: note: remove the 'if' if its condition 
> is always false
> if (r) {
> ^~~~
> drivers/dma-buf/st-dma-resv.c:288:6: error: variable 'i' is used 
> uninitialized whenever 'if' condition is true 
> [-Werror,-Wsometimes-uninitialized]
> if (r) {
> ^
> drivers/dma-buf/st-dma-resv.c:336:9: note: uninitialized use occurs here
> while (i--)
>^
> drivers/dma-buf/st-dma-resv.c:288:2: note: remove the 'if' if its condition 
> is always false
> if (r) {
> ^~~~
> drivers/dma-buf/st-dma-resv.c:280:10: note: initialize the variable 'i' to 
> silence this warning
> int r, i;
> ^
>  = 0
> 
> Skip cleaning up the bits that have not been allocated at this point.
> 
> Fixes: 1d51775cd3f5 ("dma-buf: add dma_resv selftest v4")
> Signed-off-by: Arnd Bergmann 

Reviewed-by: Nathan Chancellor 

> ---
> I'm not familiar with these interfaces, so I'm just guessing where
> we should jump after an error, please double-check and fix if necessary.
> ---
>  drivers/dma-buf/st-dma-resv.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c
> index 6f3ba756da3e..bc32b3eedcb6 100644
> --- a/drivers/dma-buf/st-dma-resv.c
> +++ b/drivers/dma-buf/st-dma-resv.c
> @@ -287,7 +287,7 @@ static int test_get_fences(void *arg, bool shared)
>   r = dma_resv_lock(&resv, NULL);
>   if (r) {
>   pr_err("Resv locking failed\n");
> - goto err_free;
> + goto err_resv;
>   }
>  
>   if (shared) {
> @@ -295,7 +295,7 @@ static int test_get_fences(void *arg, bool shared)
>   if (r) {
>   pr_err("Resv shared slot allocation failed\n");
>   dma_resv_unlock(&resv);
> - goto err_free;
> + goto err_resv;
>   }
>  
>   dma_resv_add_shared_fence(&resv, f);
> @@ -336,6 +336,7 @@ static int test_get_fences(void *arg, bool shared)
>   while (i--)
>   dma_fence_put(fences[i]);
>   kfree(fences);
> +err_resv:
>   dma_resv_fini(&resv);
>   dma_fence_put(f);
>   return r;
> -- 
> 2.29.2
> 


Re: [PATCH] video: fbdev: cirrusfb: check pixclock to avoid divide by zero

2021-10-26 Thread Geert Uytterhoeven
Hi George,

On Tue, Oct 26, 2021 at 3:38 PM George Kennedy
 wrote:
> On 10/26/2021 4:30 AM, Geert Uytterhoeven wrote:
> > On Mon, Oct 25, 2021 at 9:37 PM George Kennedy
> >  wrote:
> >> On 10/25/2021 3:07 PM, Greg KH wrote:
> >>> On Mon, Oct 25, 2021 at 02:01:30PM -0500, George Kennedy wrote:
>  Do a sanity check on pixclock value before using it as a divisor.
> 
>  Syzkaller reported a divide error in cirrusfb_check_pixclock.
> 
>  divide error:  [#1] SMP KASAN PTI
>  CPU: 0 PID: 14938 Comm: cirrusfb_test Not tainted 5.15.0-rc6 #1
>  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2
>  RIP: 0010:cirrusfb_check_var+0x6f1/0x1260
> 
>  Call Trace:
> fb_set_var+0x398/0xf90
> do_fb_ioctl+0x4b8/0x6f0
> fb_ioctl+0xeb/0x130
> __x64_sys_ioctl+0x19d/0x220
> do_syscall_64+0x3a/0x80
> entry_SYSCALL_64_after_hwframe+0x44/0xae
> 
>  Signed-off-by: George Kennedy 

>  --- a/drivers/video/fbdev/cirrusfb.c
>  +++ b/drivers/video/fbdev/cirrusfb.c
>  @@ -477,6 +477,9 @@ static int cirrusfb_check_pixclock(const struct 
>  fb_var_screeninfo *var,
>    struct cirrusfb_info *cinfo = info->par;
>    unsigned maxclockidx = var->bits_per_pixel >> 3;
> 
>  +if (!var->pixclock)
>  +return -EINVAL;
> > This is not correct: fbdev drivers should round up invalid values,
> > and only return an error if rounding up cannot yield a valid value.
>
> What default value would you recommend? Here are examples of some of the
> possible cirrusfb pixclock values:
> 4: 25MHz
> 2: 50Mhz
> 12500: 80Mhz

You should pick the lowest supported value.

> We can plug in a default value, but I believe it is just covering up the
> fact that an incorrect value has been copied in.

Passing zero is not incorrect.  The driver is supposed to round it
up to a valid value.

> I would think we would want to keep this driver consistent with the
> other fb drivers that return failure with the incorrect value.

I disagree: non-conformant behavior should be fixed, not copied.

> >>> Shouldn't you be checking further up the call chain where this got set
> >>> to 0?
> >> The same pixclock check is done in these fb drivers:
> >>
> >> arch/arm/mach-rpc/include/mach/acornfb.h:if (!var->pixclock)
> >> drivers/video/fbdev/asiliantfb.c:if (!var->pixclock)
> >> drivers/video/fbdev/clps711x-fb.c:if (!var->pixclock)
> >> drivers/video/fbdev/core/fbmon.c:if (!var->pixclock)
> >> drivers/video/fbdev/core/modedb.c:if (!var->pixclock)
> >> drivers/video/fbdev/cirrusfb.c:if (!var->pixclock)
> >> drivers/video/fbdev/kyro/fbdev.c:if (!var->pixclock)
> >> drivers/video/fbdev/riva/fbdev.c:if (!var->pixclock)
> >> drivers/video/fbdev/uvesafb.c:if (!var->pixclock)
> >>
> >>> What logic allows this to be a valid value?  What about all other fb
> >>> drivers?
> >> The "check_var" function, which is set into the ".fb_check_var" element
> >> of the fb_ops struct, should do the check, but in the case of cirrusfb,
> >> that is not being done.
> >>
> >> All this patch does is add the same pixclock check that the other above
> >> fb drivers do.
> > Indeed, several drivers are not following the rounding rules.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


[PATCH] drm/msm/dpu: Remove commit and its uses in dpu_crtc_set_crc_source()

2021-10-26 Thread Nathan Chancellor
Clang warns:

drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c:162:6: error: variable 'commit' is 
uninitialized when used here [-Werror,-Wuninitialized]
if (commit)
^~
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c:106:32: note: initialize the variable 
'commit' to silence this warning
struct drm_crtc_commit *commit;
  ^
   = NULL
1 error generated.

The assignment and use of commit in the main body of
dpu_crtc_set_crc_source() were removed from v1 to v2 but the call to
drm_crtc_commit_put() at the end was not. Do that now so there is no
more warning.

Fixes: 78d9b458cc21 ("drm/msm/dpu: Add CRC support for DPU")
Link: https://github.com/ClangBuiltLinux/linux/issues/1493
Reported-by: "kernelci.org bot" 
Signed-off-by: Nathan Chancellor 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 2523e829f485..967245b8cc02 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -103,7 +103,6 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, 
const char *src_name)
 {
enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name);
enum dpu_crtc_crc_source current_source;
-   struct drm_crtc_commit *commit;
struct dpu_crtc_state *crtc_state;
struct drm_device *drm_dev = crtc->dev;
struct dpu_crtc_mixer *m;
@@ -159,8 +158,6 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, 
const char *src_name)
 
 
 cleanup:
-   if (commit)
-   drm_crtc_commit_put(commit);
drm_modeset_unlock(&crtc->mutex);
 
return ret;

base-commit: 00326bfa4e6363e4b0b8b019ecd2556fdda5ad1c
-- 
2.33.1.637.gf443b226ca



Re: [PATCH v3 03/34] component: Introduce the aggregate bus_type

2021-10-26 Thread kernel test robot
Hi Stephen,

I love your patch! Yet something to improve:

[auto build test ERROR on e4e737bb5c170df6135a127739a9e6148ee3da82]

url:
https://github.com/0day-ci/linux/commits/Stephen-Boyd/component-Make-into-an-aggregate-bus/20211026-080422
base:   e4e737bb5c170df6135a127739a9e6148ee3da82
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/748369f5c5e62a44653d9b76cdbdadc835dd54d2
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Stephen-Boyd/component-Make-into-an-aggregate-bus/20211026-080422
git checkout 748369f5c5e62a44653d9b76cdbdadc835dd54d2
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross 
ARCH=nios2 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   drivers/base/component.c: In function '__component_add':
>> drivers/base/component.c:858:13: error: variable 'ret' set but not used 
>> [-Werror=unused-but-set-variable]
 858 | int ret;
 | ^~~
   cc1: all warnings being treated as errors


vim +/ret +858 drivers/base/component.c

2a41e6070dd7ef Russell King  2014-01-10  853  
3521ee994bca90 Daniel Vetter 2019-02-08  854  static int __component_add(struct 
device *dev, const struct component_ops *ops,
3521ee994bca90 Daniel Vetter 2019-02-08  855int subcomponent)
2a41e6070dd7ef Russell King  2014-01-10  856  {
2a41e6070dd7ef Russell King  2014-01-10  857struct component *component;
2a41e6070dd7ef Russell King  2014-01-10 @858int ret;
2a41e6070dd7ef Russell King  2014-01-10  859  
2a41e6070dd7ef Russell King  2014-01-10  860component = 
kzalloc(sizeof(*component), GFP_KERNEL);
2a41e6070dd7ef Russell King  2014-01-10  861if (!component)
2a41e6070dd7ef Russell King  2014-01-10  862return -ENOMEM;
2a41e6070dd7ef Russell King  2014-01-10  863  
2a41e6070dd7ef Russell King  2014-01-10  864component->ops = ops;
2a41e6070dd7ef Russell King  2014-01-10  865component->dev = dev;
3521ee994bca90 Daniel Vetter 2019-02-08  866component->subcomponent = 
subcomponent;
2a41e6070dd7ef Russell King  2014-01-10  867  
2a41e6070dd7ef Russell King  2014-01-10  868dev_dbg(dev, "adding component 
(ops %ps)\n", ops);
2a41e6070dd7ef Russell King  2014-01-10  869  
2a41e6070dd7ef Russell King  2014-01-10  870mutex_lock(&component_mutex);
2a41e6070dd7ef Russell King  2014-01-10  871list_add_tail(&component->node, 
&component_list);
2a41e6070dd7ef Russell King  2014-01-10  872mutex_unlock(&component_mutex);
2a41e6070dd7ef Russell King  2014-01-10  873  
748369f5c5e62a Stephen Boyd  2021-10-25  874/*
748369f5c5e62a Stephen Boyd  2021-10-25  875 * Try to bind.
748369f5c5e62a Stephen Boyd  2021-10-25  876 *
748369f5c5e62a Stephen Boyd  2021-10-25  877 * Note: we don't check the 
return value here because component devices
748369f5c5e62a Stephen Boyd  2021-10-25  878 * don't care that the 
aggregate device can actually probe or not. They
748369f5c5e62a Stephen Boyd  2021-10-25  879 * only care about adding 
themselves to the component_list and then
748369f5c5e62a Stephen Boyd  2021-10-25  880 * waiting for their 
component_ops::bind_component callback to be
748369f5c5e62a Stephen Boyd  2021-10-25  881 * called.
748369f5c5e62a Stephen Boyd  2021-10-25  882 */
748369f5c5e62a Stephen Boyd  2021-10-25  883ret = 
bus_rescan_devices(&aggregate_bus_type);
748369f5c5e62a Stephen Boyd  2021-10-25  884  
748369f5c5e62a Stephen Boyd  2021-10-25  885return 0;
2a41e6070dd7ef Russell King  2014-01-10  886  }
3521ee994bca90 Daniel Vetter 2019-02-08  887  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [RFC v2 00/22] Add Support for Plane Color Lut and CSC features

2021-10-26 Thread Harry Wentland



On 2021-10-12 17:01, Shankar, Uma wrote:
> 
> 
>> -Original Message-
>> From: Pekka Paalanen 
>> Sent: Tuesday, October 12, 2021 5:25 PM
>> To: Shankar, Uma 
>> Cc: intel-...@lists.freedesktop.org; dri-devel@lists.freedesktop.org;
>> harry.wentl...@amd.com; ville.syrj...@linux.intel.com; brian.star...@arm.com;
>> sebast...@sebastianwick.net; shashank.sha...@amd.com
>> Subject: Re: [RFC v2 00/22] Add Support for Plane Color Lut and CSC features
>>
>> On Tue,  7 Sep 2021 03:08:42 +0530
>> Uma Shankar  wrote:
>>
>>> This is how a typical display color hardware pipeline looks like:
>>>  +---+
>>>  |RAM|
>>>  |  +--++-++-+   |
>>>  |  | FB 1 ||  FB 2   || FB N|   |
>>>  |  +--++-++-+   |
>>>  +---+
>>>|  Plane Color Hardware Block |
>>> ++
>>>  | +---v-+   +---v---+   +---v--+ |
>>>  | | Plane A |   | Plane B   |   | Plane N  | |
>>>  | | DeGamma |   | Degamma   |   | Degamma  | |
>>>  | +---+-+   +---+---+   +---+--+ |
>>>  | | |   ||
>>>  | +---v-+   +---v---+   +---v--+ |
>>>  | |Plane A  |   | Plane B   |   | Plane N  | |
>>>  | |CSC/CTM  |   | CSC/CTM   |   | CSC/CTM  | |
>>>  | +---+-+   ++--+   ++-+ |
>>>  | |  |   |   |
>>>  | +---v-+   +v--+   +v-+ |
>>>  | | Plane A |   | Plane B   |   | Plane N  | |
>>>  | | Gamma   |   | Gamma |   | Gamma| |
>>>  | +---+-+   ++--+   ++-+ |
>>>  | |  |   |   |
>>>  ++
>>> +--v--v---v---|
>>> ||   ||
>>> ||   Pipe Blender||
>>> +++
>>> |||
>>> |+---v--+ |
>>> ||  Pipe DeGamma| |
>>> ||  | |
>>> |+---+--+ |
>>> ||Pipe Color  |
>>> |+---v--+ Hardware|
>>> ||  Pipe CSC/CTM| |
>>> ||  | |
>>> |+---+--+ |
>>> |||
>>> |+---v--+ |
>>> ||  Pipe Gamma  | |
>>> ||  | |
>>> |+---+--+ |
>>> |||
>>> +-+
>>>  |
>>>  v
>>>Pipe Output
>>>
>>> This patch series adds properties for plane color features. It adds
>>> properties for degamma used to linearize data and CSC used for gamut
>>> conversion. It also includes Gamma support used to again non-linearize
>>> data as per panel supported color space. These can be utilize by user
>>> space to convert planes from one format to another, one color space to
>>> another etc.
>>>
>>> Userspace can take smart blending decisions and utilize these hardware
>>> supported plane color features to get accurate color profile. The same
>>> can help in consistent color quality from source to panel taking
>>> advantage of advanced color features in hardware.
>>>
>>> These patches add the property interfaces and enable helper functions.
>>> This series adds Intel's XE_LPD hw specific plane gamma feature. We
>>> can build up and add other platform/hardware specific implementation
>>> on top of this series.
>>>
>>> Credits: Special mention and credits to Ville Syrjala for coming up
>>> with a design for this feature and inputs. This series is based on his
>>> original design and idea.
>>>
>>> Note: Userspace support for this new UAPI will be done on Chrome in
>>> alignment with weston and general opensource community.
>>> Discussion ongoing with Harry Wentland, Pekka and community on color
>>> pipeline and UAPI design. Harry's RFC below:
>>> https://patchwork.freedesktop.org/series/89506/ We need to converge on 
>>> a common UAPI interface which caters to all the
>>> modern color hardware pipelines.
>>>
>>> ToDo: State readout for this feature will be added next.
>>>
>>> v2: Added UAPI description and added change in the rfc section of
>>> kernel Documentation folder
>>
>> Hi,
>>
>> thank you for this. I do believe the KMS UAPI should expose what hardware 
>> can do
>> (prescribed operations) rather than how they would be often used (to realize 
>> a
>> conversion from one space description to another). This proposal fits quite 
>> nicely
>> with what I have 

Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware Pipeline

2021-10-26 Thread Harry Wentland
Thanks, Uma, for the updated patches. I'm finally finding
time to go through them.

On 2021-10-15 03:42, Pekka Paalanen wrote:
> On Thu, 14 Oct 2021 19:44:25 +
> "Shankar, Uma"  wrote:
> 
>>> -Original Message-
>>> From: Pekka Paalanen 
>>> Sent: Wednesday, October 13, 2021 2:01 PM
>>> To: Shankar, Uma 
>>> Cc: harry.wentl...@amd.com; ville.syrj...@linux.intel.com; intel- 
>>> g...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
>>> brian.star...@arm.com; sebast...@sebastianwick.net; 
>>> shashank.sha...@amd.com
>>> Subject: Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware Pipeline
>>>
>>> On Tue, 12 Oct 2021 20:58:27 +
>>> "Shankar, Uma"  wrote:
>>>   
> -Original Message-
> From: Pekka Paalanen 
> Sent: Tuesday, October 12, 2021 4:01 PM
> To: Shankar, Uma 
> Cc: intel-...@lists.freedesktop.org; 
> dri-devel@lists.freedesktop.org; harry.wentl...@amd.com; 
> ville.syrj...@linux.intel.com; brian.star...@arm.com; 
> sebast...@sebastianwick.net; shashank.sha...@amd.com
> Subject: Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware 
> Pipeline
>
> On Tue,  7 Sep 2021 03:08:43 +0530 Uma Shankar 
>  wrote:
>  
>> This is a RFC proposal for plane color hardware blocks.
>> It exposes the property interface to userspace and calls out the 
>> details or interfaces created and the intended purpose.
>>
>> Credits: Ville Syrjälä 
>> Signed-off-by: Uma Shankar 
>> ---
>>  Documentation/gpu/rfc/drm_color_pipeline.rst | 167
>> +++
>>  1 file changed, 167 insertions(+)  create mode 100644 
>> Documentation/gpu/rfc/drm_color_pipeline.rst
>>
>> diff --git a/Documentation/gpu/rfc/drm_color_pipeline.rst
>> b/Documentation/gpu/rfc/drm_color_pipeline.rst
>> new file mode 100644
>> index ..0d1ca858783b
>> --- /dev/null
>> +++ b/Documentation/gpu/rfc/drm_color_pipeline.rst
>> @@ -0,0 +1,167 @@
>> +==
>> +Display Color Pipeline: Proposed DRM Properties  
> 
> ...
> 
>>> cf. BT.2100 Annex 1, "The relationship between the OETF, the EOTF and 
>>> the OOTF", although I find those diagrams somewhat confusing still. It 
>>> does not seem to clearly account for transmission non-linear encoding being 
>>> different from the display EOTF.
>>>
>>> Different documents use OOTF to refer to different things. Then there 
>>> is also the fundamental difference between PQ and HLG systems, where 
>>> OOTF is by definition in different places of the 
>>> camera-transmission-display pipeline.  
>>
>> Agree this is a bit confusing, I admit I was much more confused than what 
>> you were for sure.
>> Will do some research to get my understanding in place. Thanks for all the 
>> inputs.
> 
> I'm sure I was at least equally confused or even more at the start. I
> have just had a year of casual reading, discussions, and a W3C workshop
> attendance to improve my understanding. :-)
> 
> Now I know enough to be dangerous.
> 
> ...
> 
>> +
>> +UAPI Name: PLANE_DEGAMMA_MODE
>> +Description: Enum property with values as blob_id's which 
>> +advertizes
>> the  
>
> Is enum with blob id values even a thing?  

 Yeah we could have. This is a dynamic enum created with blobs. Each 
 entry contains the data structure to extract the full color 
 capabilities of the hardware. It’s a very interesting play with 
 blobs (@ville.syrj...@linux.intel.com brainchild)  
>>>
>>> Yes, I think I can imagine how that works. The blobs are created 
>>> immutable, unable to change once the plane has been advertised to 
>>> userspace, because their IDs are used as enum values. But that is ok, 
>>> because the blob describes capabilities that cannot change during the 
>>> device's lifetime... or can they? What if you would want to extend the 
>>> blob format, do you need a KMS client cap to change the format which 
>>> would be impossible because you can't change an enum definition after it 
>>> has been installed so you cannot swap the blob to a new one?
>>>
>>> This also relies on enums being identified by their string names, 
>>> because the numerical value is not a constant but a blob ID and gets 
>>> determined when the immutable blob is created.
>>>
>>> Did I understand correctly?  
>>
>> Yes that’s right. We are not expecting these structures to change as
>> they represent the platforms capabilities.
> 
> Until there comes a new platform whose capabilities you cannot quite
> describe with the existing structure. What's the plan to deal with that?
> A new enum value, like LUT2 instead of LUT? I suppose that works.
> 

See my comment on the coverletter. It would be great if we could come
up with a PWL definition that's generic enough to work on all HW
that uses PWL and not require compositors to learn a new LUT2
type in the future.

>>
>>> As a userspace developer, I can totally work 

Re: [RFC 06/13] soc: mediatek: apu: Add apu core driver

2021-10-26 Thread AngeloGioacchino Del Regno

Il 23/10/21 13:14, Flora Fu ha scritto:

Add apu core driver.
The core driver will init the reset part of apu functions.

Signed-off-by: Flora Fu 
---
  drivers/soc/mediatek/Kconfig   | 18 +
  drivers/soc/mediatek/apusys/Makefile   |  3 +
  drivers/soc/mediatek/apusys/apu-core.c | 91 ++
  drivers/soc/mediatek/apusys/apu-core.h | 11 
  4 files changed, 123 insertions(+)
  create mode 100644 drivers/soc/mediatek/apusys/apu-core.c
  create mode 100644 drivers/soc/mediatek/apusys/apu-core.h



Hello Flora,

I don't think that this custom probe/init mechanism through apu-core.c
can ever be a thing: you should simply register a number of platform
drivers (likely modules) and let the kernel decide what to probe
first, what to probe last, as it's done for every kernel driver.

I understand that this may reduce probe deferrals, as it's a controlled
probe sequence, made specifically for apusys, but it's anyway something
that won't give you big gains (and if it was, then you should still let
the kernel decide and eventually optimize that mechanism somehow).


I want to note that, since this series is rather huge, I will probably
do more than one incremental review of it... and for how things look,
this will most probably be split to more than one series, to allow getting
reviews from specific subsystem maintainers, leading to better code quality
and robustness in the end.

Some more details are coming in reply of other patches in this series.

Thanks,
- Angelo


Re: [RFC 04/13] iommu/mediatek: Add APU iommu support

2021-10-26 Thread AngeloGioacchino Del Regno

Il 23/10/21 13:14, Flora Fu ha scritto:

APU IOMMU is a new iommu HW. it use a new pagetable.
Add support for mt8192 apu iommu.

Signed-off-by: Yong Wu 
Signed-off-by: Flora Fu 
---
  drivers/iommu/mtk_iommu.c | 57 +++
  include/dt-bindings/memory/mt8192-larb-port.h |  4 ++
  2 files changed, 61 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 90be8ebbc98a..a5f8f19e053a 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -133,6 +133,7 @@
  /* 2 bits: iommu type */
  #define MTK_IOMMU_TYPE_MM (0x0 << 13)
  #define MTK_IOMMU_TYPE_INFRA  (0x1 << 13)
+#define MTK_IOMMU_TYPE_APU (0x2 << 13)
  #define MTK_IOMMU_TYPE_MASK   (0x3 << 13)
  #define IFA_IOMMU_PCIe_SUPPORTBIT(15)
  
@@ -185,6 +186,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int ban

  #define MTK_IOMMU_4GB_MODE_REMAP_BASE  0x14000UL
  
  static LIST_HEAD(m4ulist);	/* List all the M4U HWs */

+static LIST_HEAD(apulist); /* List the apu iommu HWs */
  
  #define for_each_m4u(data, head)  list_for_each_entry(data, head, list)
  
@@ -209,6 +211,13 @@ static const struct mtk_iommu_iova_region mt8192_multi_dom[] = {

#endif
  };
  
+static const struct mtk_iommu_iova_region mt8192_multi_dom_apu[] = {

+   { .iova_base = 0x0, .size = SZ_4G}, /* APU DATA */
+   { .iova_base = 0x400ULL,.size = 0x400},  /* APU VLM */
+   { .iova_base = 0x1000ULL,   .size = 0x1000}, /* APU VPU */
+   { .iova_base = 0x7000ULL,   .size = 0x1260}, /* APU REG */
+};
+
  /* If 2 M4U share a domain(use the same hwlist), Put the corresponding info 
in first data.*/
  static struct mtk_iommu_data *mtk_iommu_get_frst_data(struct list_head 
*hwlist)
  {
@@ -923,6 +932,37 @@ static int mtk_iommu_mm_dts_parse(struct device *dev,
return 0;
  }
  
+static int mtk_iommu_apu_prepare(struct device *dev)

+{
+   struct device_node *apupower_node;
+   struct platform_device *apudev;
+   struct device_link *link;
+
+   apupower_node = of_find_compatible_node(NULL, NULL, 
"mediatek,apusys-power");


Is it expected to have PM ops in the apusys-power driver? Currently, I can't see
any, but maybe it's because of how complex is this entire implementation.

In any case, the name suggests that this controls power for the entire APU... so
it would be more appropriate if apusys-power would expose a power domain (since 
it
also has some sort of OPP, from what I can see), in which case you wouldn't be
retrieving it here like you're doing right now... but simply as a power domain,
simplifying the entire handling of that in here.



+   if (!apupower_node) {
+   dev_warn(dev, "Can't find apu power node!\n");
+   return -EINVAL;
+   }
+
+   if (!of_device_is_available(apupower_node)) {
+   of_node_put(apupower_node);
+   return -EPERM;
+   }
+
+   apudev = of_find_device_by_node(apupower_node);
+   if (!apudev) {
+   of_node_put(apupower_node);
+   return -EPROBE_DEFER;
+   }
+
+   link = device_link_add(&apudev->dev, dev, DL_FLAG_PM_RUNTIME);
+   if (!link)
+   dev_err(dev, "Unable link %s.\n", apudev->name);
+
+   of_node_put(apupower_node);
+   return 0;
+}
+
  static int mtk_iommu_probe(struct platform_device *pdev)
  {
struct mtk_iommu_data   *data;
@@ -1021,6 +1061,10 @@ static int mtk_iommu_probe(struct platform_device *pdev)
}
  
  		data->pericfg = infracfg;

+   } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_APU)) {
+   ret = mtk_iommu_apu_prepare(dev);
+   if (ret)
+   goto out_runtime_disable;
}
  
  	platform_set_drvdata(pdev, data);

@@ -1268,6 +1312,18 @@ static const struct mtk_iommu_plat_data mt8192_data = {
   {0, 14, 16}, {0, 13, 18, 17}},
  };
  
+static const struct mtk_iommu_plat_data mt8192_data_apu = {

+   .m4u_plat   = M4U_MT8192,
+   .flags  = WR_THROT_EN | DCM_DISABLE | MTK_IOMMU_TYPE_APU |
+ SHARE_PGTABLE,
+   .inv_sel_reg= REG_MMU_INV_SEL_GEN2,
+   .hw_list= &apulist,
+   .bank_nr= 1,
+   .bank_enable= {true},
+   .iova_region= mt8192_multi_dom_apu,
+   .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom_apu),
+};
+
  static const struct mtk_iommu_plat_data mt8195_data_infra = {
.m4u_plat = M4U_MT8195,
.flags= WR_THROT_EN | DCM_DISABLE |
@@ -1323,6 +1379,7 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
+   { .compatib

Re: [RFC 12/13] arm64: dts: mt8192: Add apu tinysys

2021-10-26 Thread AngeloGioacchino Del Regno

Il 23/10/21 13:14, Flora Fu ha scritto:

Add node for APU tinysys.

Signed-off-by: Flora Fu 
---
  arch/arm64/boot/dts/mediatek/mt8192.dtsi | 36 
  1 file changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c505c6926839..8108084a3f6f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -925,6 +925,42 @@
#iommu-cells = <1>;
};
  
+		apusys_rv@19001000 {

+   compatible = "mediatek,mt8192-apusys-rv";
+   reg = <0 0x1900 0 0x1000>,
+ <0 0x19001000 0 0x1000>,
+ <0 0x19002000 0 0x10>;
+   reg-names = "apu_mbox",
+   "md32_sysctrl",
+   "apu_wdt";
+   mediatek,apusys-power = <&apusys_power>;


As said on the IOMMU commit, I think that apusys-power can be passed as a
power domain here as well... also keeping in mind that the apuspm power
domain is being used in both the IOMMU and in apusys-power already, so you
could even pass only the apusys-power pd here, because apuspm would be
already being turned on by the former...

...unless there's any possibility to have some functionality with apuspm up
but apusys-power down? From how it looks right now, that's not a thing.


+   power-domains = <&apuspm 0>;
+   iommus = <&iommu_apu IOMMU_PORT_APU_DATA>;
+   interrupts = ,
+;
+   interrupt-names = "apu_wdt",
+ "mbox0_irq";
+   apu_ctrl {
+   compatible = "mediatek,apu-ctrl-rpmsg";
+   mtk,rpmsg-name = "apu-ctrl-rpmsg";


This is supposed to be "mediatek,rpmsg-name" instead... or it won't work.


+   };
+
+   apu_pwr_tx {
+   compatible = "mediatek,apupwr-tx-rpmsg";
+   mtk,rpmsg-name = "apupwr-tx-rpmsg";
+   };
+
+   apu_pwr_rx {
+   compatible = "mediatek,apupwr-rx-rpmsg";
+   mtk,rpmsg-name = "apupwr-rx-rpmsg";
+   };
+
+   apu_mdw_rpmsg {
+   compatible = "mediatek,apu-mdw-rpmsg";
+   mtk,rpmsg-name = "apu-mdw-rpmsg";
+   };
+   };
+
apu_conn: apu_conn@1902 {
compatible = "mediatek,mt8192-apu-conn", "syscon";
reg = <0 0x1902 0 0x1000>;



Re: [RFC 08/13] soc: mediatek: apu: Add apusys rv driver

2021-10-26 Thread AngeloGioacchino Del Regno

Il 23/10/21 13:14, Flora Fu ha scritto:

Add driver for control APU tinysys

APU integrated subsystem having MD32RV33 (MD32) that runs tinysys
The tinsys is running on a micro processor in APU.
Its firmware is load and boot from Kernel side. Kernel and tinysys use
IPI to tx/rx messages.

Signed-off-by: Flora Fu 
---
  drivers/soc/mediatek/apusys/Makefile|   6 +
  drivers/soc/mediatek/apusys/apu-config.h| 100 +++
  drivers/soc/mediatek/apusys/apu-core.c  |   2 +
  drivers/soc/mediatek/apusys/apu-core.h  |   2 +
  drivers/soc/mediatek/apusys/apu-ipi.c   | 486 


I'm not sure of that, but your apu-ipi.c may be more suited to be in
drivers/remoteproc instead.


  drivers/soc/mediatek/apusys/apu-mbox.c  |  83 ++


apu-mbox.c should go to drivers/mailbox/ and you should register it with
the mailbox API as a mailbox controller instead of what you're currently
doing...

From what I see, you have functions in there that can be indeed mapped
to struct mbox_chan_ops .send_data and .peek_data... also your function
apu_mbox_wait_inbox seems to be waiting on an interrupt, and such irq is
apparently your "mbox0_irq" (as you named it in the dt).
In that case, you can also manage that in your drivers/mailbox/ driver.
+

  drivers/soc/mediatek/apusys/apu-mbox.h  |  27 +
  drivers/soc/mediatek/apusys/apu-rproc.c | 806 


The apu-rproc.c driver seems to be a good candidate to be moved away from

drivers/soc/mediatek/apusys/ - as this is indeed a remoteproc driver.

Having it as drivers/remoteproc/mtk_apu.c seems to be a good option.




  drivers/soc/mediatek/apusys/apu-sw-logger.c | 429 +++


This one definitely belongs here in drivers/soc/mediatek, and it's a consumer
of the mailbox driver.


  drivers/soc/mediatek/apusys/apu.h   | 256 +++
  drivers/soc/mediatek/apusys/mt81xx-plat.c   | 320 


If we end up keeping to be in need to have a separate mt81xx-plat.c file,
then I believe this should have another name, so that it becomes one that
aggregates all of the very-platform-specific functions in one, instead of
having one file for each platform.

Though, it may also be possible that this file will disappear entirely:
since most of the things here will be moved around, it may become mostly
empty... but it's probably too soon to judge.


  11 files changed, 2517 insertions(+)
  create mode 100644 drivers/soc/mediatek/apusys/apu-config.h
  create mode 100644 drivers/soc/mediatek/apusys/apu-ipi.c
  create mode 100644 drivers/soc/mediatek/apusys/apu-mbox.c
  create mode 100644 drivers/soc/mediatek/apusys/apu-mbox.h
  create mode 100644 drivers/soc/mediatek/apusys/apu-rproc.c
  create mode 100644 drivers/soc/mediatek/apusys/apu-sw-logger.c
  create mode 100644 drivers/soc/mediatek/apusys/apu.h
  create mode 100644 drivers/soc/mediatek/apusys/mt81xx-plat.c



snip...


diff --git a/drivers/soc/mediatek/apusys/apu-ipi.c 
b/drivers/soc/mediatek/apusys/apu-ipi.c
new file mode 100644
index ..547e034b3620
--- /dev/null
+++ b/drivers/soc/mediatek/apusys/apu-ipi.c


snip...


+int apu_ipi_init(struct platform_device *pdev, struct mtk_apu *apu)
+{
+   struct device *dev = apu->dev;
+   int i, ret;
+
+   tx_serial_no = 0;
+   rx_serial_no = 0;
+
+   mutex_init(&apu->send_lock);
+   spin_lock_init(&apu->usage_cnt_lock);
+   for (i = 0; i < APU_IPI_MAX; i++) {
+   mutex_init(&apu->ipi_desc[i].lock);
+   lockdep_set_class_and_name(&apu->ipi_desc[i].lock,
+  &ipi_lock_key[i],
+  apu->platdata->ipi_attrs[i].name);
+   }
+
+   init_waitqueue_head(&apu->run.wq);
+   init_waitqueue_head(&apu->ack_wq);
+
+   /* APU initialization IPI register */
+   ret = apu_ipi_register(apu, APU_IPI_INIT, apu_init_ipi_handler, apu);
+   if (ret) {
+   dev_err(dev, "failed to register ipi for init, ret=%d\n",
+   ret);
+   return ret;
+   }
+
+   /* add rpmsg subdev */
+   apu_add_rpmsg_subdev(apu);
+
+   /* register mailbox IRQ */
+   apu->mbox0_irq_number = platform_get_irq_byname(pdev, "mbox0_irq");
+   dev_info(&pdev->dev, "%s: mbox0_irq = %d\n", __func__,
+apu->mbox0_irq_number);
+
+   ret = devm_request_threaded_irq(&pdev->dev, apu->mbox0_irq_number,
+   NULL, apu_ipi_handler, IRQF_ONESHOT,
+   "apu_ipi", apu);


This is the mailbox interrupt... but it's handled in this driver instead of
being handler in the mailbox driver... it's a bit confusing.

Is this interrupt supposed to fire as a mailbox doorbell or..?
In that case, you should request it in the mailbox driver and register an
interrupt controller (still, in the mailbox driver) so that you can export
a sw interrupt to this one.

Or, maybe you can use notifiers to catch the mailbox mess

Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware Pipeline

2021-10-26 Thread Harry Wentland



On 2021-10-14 15:44, Shankar, Uma wrote:
> 
> 
>> -Original Message-
>> From: Pekka Paalanen 
>> Sent: Wednesday, October 13, 2021 2:01 PM
>> To: Shankar, Uma 
>> Cc: harry.wentl...@amd.com; ville.syrj...@linux.intel.com; intel- 
>> g...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
>> brian.star...@arm.com; sebast...@sebastianwick.net; 
>> shashank.sha...@amd.com
>> Subject: Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware Pipeline
>>
>> On Tue, 12 Oct 2021 20:58:27 +
>> "Shankar, Uma"  wrote:
>>
 -Original Message-
 From: Pekka Paalanen 
 Sent: Tuesday, October 12, 2021 4:01 PM
 To: Shankar, Uma 
 Cc: intel-...@lists.freedesktop.org; 
 dri-devel@lists.freedesktop.org; harry.wentl...@amd.com; 
 ville.syrj...@linux.intel.com; brian.star...@arm.com; 
 sebast...@sebastianwick.net; shashank.sha...@amd.com
 Subject: Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware 
 Pipeline

 On Tue,  7 Sep 2021 03:08:43 +0530 Uma Shankar 
  wrote:

> This is a RFC proposal for plane color hardware blocks.
> It exposes the property interface to userspace and calls out the 
> details or interfaces created and the intended purpose.
>
> Credits: Ville Syrjälä 
> Signed-off-by: Uma Shankar 
> ---
>  Documentation/gpu/rfc/drm_color_pipeline.rst | 167
> +++
>  1 file changed, 167 insertions(+)  create mode 100644 
> Documentation/gpu/rfc/drm_color_pipeline.rst
>
> diff --git a/Documentation/gpu/rfc/drm_color_pipeline.rst
> b/Documentation/gpu/rfc/drm_color_pipeline.rst
> new file mode 100644
> index ..0d1ca858783b
> --- /dev/null
> +++ b/Documentation/gpu/rfc/drm_color_pipeline.rst
> @@ -0,0 +1,167 @@
> +==
> +Display Color Pipeline: Proposed DRM Properties
>>
>> ...
>>
> +Proposal is to have below properties for a plane:
> +
> +* Plane Degamma or Pre-Curve:
> + * This will be used to linearize the input framebuffer data.
> + * It will apply the reverse of the color transfer function.
> + * It can be a degamma curve or OETF for HDR.

 As you want to produce light-linear values, you use EOTF or inverse OETF.

 The term OETF has a built-in assumption that that happens in a camera:
 it takes in light and produces and electrical signal. Lately I 
 have personally started talking about non-linear encoding of color 
 values, since EOTF is often associated with displays if nothing 
 else is said (taking
>> in an electrical signal and producing light).

 So this would be decoding the color values into light-linear color 
 values. That is what an EOTF does, yes, but I feel there is a 
 nuanced difference. A piece of equipment implements an EOTF by 
 turning an electrical signal into light, hence EOTF often refers 
 to specific equipment. You could talk about content EOTF to denote 
 content value encoding, as opposed to output or display EOTF, but 
 that might be confusing if you look at e.g. the diagrams in
 BT.2100: is it the EOTF
>> or is it the inverse OETF? Is the (inverse?) OOTF included?

 So I try to side-step those questions by talking about encoding.
>>>
>>> The idea here is that frame buffer presented to display plane engine 
>>> will be non-
>> linear.
>>> So output of a media decode should result in content with EOTF applied.
>>
>> Hi,
>>
>> sure, but the question is: which EOTF. There can be many different 
>> things called "EOTF" in a single pipeline, and then it's up to the 
>> document writer to make the difference between them. Comparing two 
>> documents with different conventions causes a lot of confusion in my 
>> personal experience, so it is good to define the concepts more carefully.
> 
> Hi Pekka,
> I think you have given some nice inputs to really deep dive and document here.
> Will update this with the right expectations wrt what transfer functions to 
> be used at various stages in the operation pipeline.
> 
>>> So output of a media decode should result in content with EOTF applied.
>>
>> I suspect you have it backwards. Media decode produces electrical
>> (non-linear) pixel color values. If EOTF was applied, they would be 
>> linear instead (and require more memory to achieve the same visual 
>> precision).
>>
>> If you want to put it this way, you could say "with inverse EOTF 
>> applied", but that might be slightly confusing because it is already 
>> baked in to the video, it's not something a media decoder has to 
>> specifically apply, I think. However, the (inverse) EOTF in this case is the 
>> content EOTF, not the display EOTF.
>>
>> If content and display EOTF differ, then one must apply first content 
>> EOTF and then inverse display EOTF to get values that are correctly 
>> encoded for the display. (This is necessary but not sufficient in
>> general.)

Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware Pipeline

2021-10-26 Thread Harry Wentland



On 2021-10-12 16:58, Shankar, Uma wrote:
> 
> 
>> -Original Message-
>> From: Pekka Paalanen 
>> Sent: Tuesday, October 12, 2021 4:01 PM
>> To: Shankar, Uma 
>> Cc: intel-...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
>> harry.wentl...@amd.com; ville.syrj...@linux.intel.com; 
>> brian.star...@arm.com; sebast...@sebastianwick.net; 
>> shashank.sha...@amd.com
>> Subject: Re: [RFC v2 01/22] drm: RFC for Plane Color Hardware Pipeline
>>
>> On Tue,  7 Sep 2021 03:08:43 +0530
>> Uma Shankar  wrote:
>>

snip

>>> +
>>> +
>>> +This patch series adds properties for plane color features. It adds 
>>> +properties for degamma used to linearize data and CSC used for 
>>> +gamut conversion. It also includes Gamma support used to again 
>>> +non-linearize data as per panel supported color space. These can be 
>>> +utilize by user space to convert planes from one format to another, 
>>> +one color space to another etc.
>>
>> FWIW, this is exactly the structure I have assumed in the Weston CM&HDR work.
> 
> This is great to hear that we are aligned wrt how the pipeline should work.
> 
> Thanks Pekka for taking time out and providing the feedback.
> 
> @harry.wentl...@amd.com We can work together and build our design to 
> accommodate
> both Intel and AMD's hardware needs. This will also make things generic 
> enough for any
> other hardware vendor as well.
> 

Definitely. I think we're on the right path. Personally I would like to
arrive at a solid KMS definition for this by the time Weston guys
get to the HDR enablement with SW composition so we can start looking
at KMS offloading for HDR planes as next step.

Harry

> Thanks & Regards,
> Uma Shankar
> 
>>> +
>>> +Userspace can take smart blending decisions and utilize these 
>>> +hardware supported plane color features to get accurate color 
>>> +profile. The same can help in consistent color quality from source 
>>> +to panel taking advantage of advanced color features in hardware.
>>> +
>>> +These patches add the property interfaces and enable helper functions.
>>> +This series adds Intel's XE_LPD hw specific plane gamma feature. We 
>>> +can build up and add other platform/hardware specific 
>>> +implementation on top of this series.
>>> +
>>> +Credits: Special mention and credits to Ville Syrjala for coming up 
>>> +with a design for this feature and inputs. This series is based on 
>>> +his original design and idea.
>>
>>
>> Thanks,
>> pq



Re: [Intel-gfx] [PATCH v2 14/17] uapi/drm/dg2: Format modifier for DG2 unified compression and clear color

2021-10-26 Thread Ramalingam C
On 2021-10-25 at 14:20:02 +0300, Juha-Pekka Heikkila wrote:
> On 21.10.2021 17.35, Ville Syrjälä wrote:
> > On Thu, Oct 21, 2021 at 07:56:24PM +0530, Ramalingam C wrote:
> > > From: Matt Roper 
> > > 
> > > DG2 unifies render compression and media compression into a single
> > > format for the first time.  The programming and buffer layout is
> > > supposed to match compression on older gen12 platforms, but the
> > > actual compression algorithm is different from any previous platform; as
> > > such, we need a new framebuffer modifier to represent buffers in this
> > > format, but otherwise we can re-use the existing gen12 compression driver
> > > logic.
> > > 
> > > DG2 clear color render compression uses Tile4 layout. Therefore, we need
> > > to define a new format modifier for uAPI to support clear color rendering.
> > > 
> > > Signed-off-by: Matt Roper 
> > > Signed-off-by: Mika Kahola  (v2)
> > > Signed-off-by: Juha-Pekka Heikkilä 
> > > Signed-off-by: Ramalingam C 
> > > cc: Simon Ser 
> > > Cc: Pekka Paalanen 
> > > ---
> > >   drivers/gpu/drm/i915/display/intel_display.c  |  3 ++
> > >   .../drm/i915/display/intel_display_types.h| 10 +++-
> > >   drivers/gpu/drm/i915/display/intel_fb.c   |  7 +++
> > >   .../drm/i915/display/skl_universal_plane.c| 49 +--
> > >   include/uapi/drm/drm_fourcc.h | 30 
> > >   5 files changed, 94 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 9b678839bf2b..2949fe9f5b9f 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -1013,6 +1013,9 @@ intel_get_format_info(const struct drm_mode_fb_cmd2 
> > > *cmd)
> > > cmd->pixel_format);
> > >   case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
> > >   case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
> > > + case I915_FORMAT_MOD_F_TILED_DG2_RC_CCS:
> > > + case I915_FORMAT_MOD_F_TILED_DG2_MC_CCS:
> > > + case I915_FORMAT_MOD_F_TILED_DG2_RC_CCS_CC:
> > >   return lookup_format_info(gen12_ccs_formats,
> > > ARRAY_SIZE(gen12_ccs_formats),
> > > cmd->pixel_format);
> > 
> > That seems not right. Flat CCS is invisible to the user so the format
> > info should not include a CCS plane.
> > 
> 
> I had cleaned out those rc and mc ccs from here long time ago, I wonder
> where did they come back from? On my development tree they're not there.
> Also I915_FORMAT_MOD_F_TILED_DG2_RC_CCS_CC is here in totally wrong place,
> it should have its own gen12_flat_ccs_cc_formats table.

Oops, there was another piece missed from this upstreaming effort. I
will push that too...

Ram
> 
> /Juha-Pekka


Re: [PATCH] video: fbdev: cirrusfb: check pixclock to avoid divide by zero

2021-10-26 Thread George Kennedy

Hi Geert,

On 10/26/2021 10:11 AM, Geert Uytterhoeven wrote:

Hi George,

On Tue, Oct 26, 2021 at 3:38 PM George Kennedy
 wrote:

On 10/26/2021 4:30 AM, Geert Uytterhoeven wrote:

On Mon, Oct 25, 2021 at 9:37 PM George Kennedy
 wrote:

On 10/25/2021 3:07 PM, Greg KH wrote:

On Mon, Oct 25, 2021 at 02:01:30PM -0500, George Kennedy wrote:

Do a sanity check on pixclock value before using it as a divisor.

Syzkaller reported a divide error in cirrusfb_check_pixclock.

divide error:  [#1] SMP KASAN PTI
CPU: 0 PID: 14938 Comm: cirrusfb_test Not tainted 5.15.0-rc6 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2
RIP: 0010:cirrusfb_check_var+0x6f1/0x1260

Call Trace:
fb_set_var+0x398/0xf90
do_fb_ioctl+0x4b8/0x6f0
fb_ioctl+0xeb/0x130
__x64_sys_ioctl+0x19d/0x220
do_syscall_64+0x3a/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae

Signed-off-by: George Kennedy 
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -477,6 +477,9 @@ static int cirrusfb_check_pixclock(const struct 
fb_var_screeninfo *var,
   struct cirrusfb_info *cinfo = info->par;
   unsigned maxclockidx = var->bits_per_pixel >> 3;

+if (!var->pixclock)
+return -EINVAL;

This is not correct: fbdev drivers should round up invalid values,
and only return an error if rounding up cannot yield a valid value.

What default value would you recommend? Here are examples of some of the
possible cirrusfb pixclock values:
4: 25MHz
2: 50Mhz
12500: 80Mhz

You should pick the lowest supported value.


In bestclock() the frequency value ("freq") is not allowed to go below 8000.

    if (freq < 8000)
    freq = 8000;

If pixclock is passed in as zero to cirrusfb_check_pixclock(), is it ok 
to then set the value of pixclock to 125000, which will result in "freq" 
being set to 8000 (or adjust the passed in pixclock value to make sure 
"freq" does not get below 8000)?


Thank you,
George



We can plug in a default value, but I believe it is just covering up the
fact that an incorrect value has been copied in.

Passing zero is not incorrect.  The driver is supposed to round it
up to a valid value.


I would think we would want to keep this driver consistent with the
other fb drivers that return failure with the incorrect value.

I disagree: non-conformant behavior should be fixed, not copied.


Shouldn't you be checking further up the call chain where this got set
to 0?

The same pixclock check is done in these fb drivers:

arch/arm/mach-rpc/include/mach/acornfb.h:if (!var->pixclock)
drivers/video/fbdev/asiliantfb.c:if (!var->pixclock)
drivers/video/fbdev/clps711x-fb.c:if (!var->pixclock)
drivers/video/fbdev/core/fbmon.c:if (!var->pixclock)
drivers/video/fbdev/core/modedb.c:if (!var->pixclock)
drivers/video/fbdev/cirrusfb.c:if (!var->pixclock)
drivers/video/fbdev/kyro/fbdev.c:if (!var->pixclock)
drivers/video/fbdev/riva/fbdev.c:if (!var->pixclock)
drivers/video/fbdev/uvesafb.c:if (!var->pixclock)


What logic allows this to be a valid value?  What about all other fb
drivers?

The "check_var" function, which is set into the ".fb_check_var" element
of the fb_ops struct, should do the check, but in the case of cirrusfb,
that is not being done.

All this patch does is add the same pixclock check that the other above
fb drivers do.

Indeed, several drivers are not following the rounding rules.

Gr{oetje,eeting}s,

 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
 -- Linus Torvalds




Re: [PATCH 00/47] GuC submission support

2021-10-26 Thread Matthew Brost
On Tue, Oct 26, 2021 at 11:59:35AM +0300, Joonas Lahtinen wrote:
> Quoting Matthew Brost (2021-10-25 18:15:09)
> > On Mon, Oct 25, 2021 at 12:37:02PM +0300, Joonas Lahtinen wrote:
> > > Quoting Matthew Brost (2021-10-22 19:42:19)
> > > > On Fri, Oct 22, 2021 at 12:35:04PM +0300, Joonas Lahtinen wrote:
> > > > > Hi Matt & John,
> > > > > 
> > > > > Can you please queue patches with the right Fixes: references to 
> > > > > convert
> > > > > all the GuC tracepoints to be protected by the LOW_LEVEL_TRACEPOINTS
> > > > > protection for now. Please do so before next Wednesday so we get it
> > > > > queued in drm-intel-next-fixes.
> > > > > 
> > > > 
> > > > Don't we already do that? I checked i915_trace.h and every tracepoint I
> > > > added (intel_context class, i915_request_guc_submit) is protected by
> > > > LOW_LEVEL_TRACEPOINTS.
> > > > 
> > > > The only thing I changed outside of that protection is adding the guc_id
> > > > field to existing i915_request class tracepoints.
> > > 
> > > It's the first search hit for "guc" inside the i915_trace.h file :)
> > > 
> > > > Without the guc_id in
> > > > those tracepoints these are basically useless with GuC submission. We
> > > > could revert that if it is a huge deal but as I said then they are
> > > > useless...
> > > 
> > > Let's eliminate it for now and restore the tracepoint exactly as it was.
> > > 
> > 
> > Don't really agree - let's render tracepoints to be useless? Are
> > tracepoints ABI? I googled this and couldn't really find a definie
> > answer. If tracepoints are ABI, then OK I can revert this change but
> > still this is a poor technical decision (tracepoints should not be ABI).
> 
> Thats a very heated discussion in general. But the fact is that if
> tracepoint changes have caused regressions to applications, they have
> been forced to be remain untouched. You are free to raise the discussion
> with Linus/LKML if you feel that should not be the case. So the end
> result is that tracepoints are effectively in limbo, not ABI unless some
> application uses them like ABI.
> 

Not trying to start or fight a holy war. If the current rules are don't
change tracepoints, we won't. Patch posted, let's stay focused, get an
RB, and move on.

Matt

> Feel free to search the intel-gfx/lkml for "tracepoints" keyword and look
> for threads with many replies. It's not that I would not agree, it's more
> that I'm not in the mood for repeating that discussion over and over again
> and always land in the same spot.
> 
> So for now, we don't add anything new to tracepoints we can't guarantee
> to always be there untouched. Similarly, we don't guarantee any of them
> to remain stable. So we try to be compatible with the limbo.
> 
> I'm long overdue waiting for some stable consumer to step up for the
> tracepoints, so we can then start discussion what would actually be the
> best way of getting that information out for them. In ~5 years that has
> not happened.
> 
> > > If there is an immediate need, we should instead have an auxilary 
> > > tracepoint
> > > which is enabled only through LOW_LEVEL_TRACEPOINTS and that amends the
> > > information of the basic tracepoint.
> > > 
> > 
> > Regardless of what I said above, I'll post 2 patches. The 1st just
> > remove the GuC, the 2nd modify the tracepoint to include guc_id if
> > LOW_LEVEL_TRACEPOINTS is defined.
> 
> Thanks. Let's get a patch merged which simply drops the guc_id for now
> to unblock things.
> 
> For the second, an auxilary tracepoint will be preferred instead of
> mutating the existing one (regardless of the LOW_LEVEL_TRACEPOINTS).
> 
> I only noticed a patch that mutates the tracepoints, can you
> double-check sending the first patch?
> 
> Regards, Joonas
> 
> > 
> > > For the longer term solution we should align towards the dma fence
> > > tracepoints. When those are combined with the OA information, one should
> > > be able to get a good understanding of both the software and hardware
> > > scheduling decisions.
> > > 
> > 
> > Not sure about this either. I use these tracepoins to correlate things
> > to the GuC log. Between the 2, if you know what you are doing you
> > basically can figure out everything that is happening. Fields in the
> > trace translate directly to fields in the GuC log. Some of these fields
> > are backend specific, not sure how these could be pushed the dma fence
> > tracepoints. For what it is worth, without these tracepoints we'd likely
> > still have a bunch of bugs in the GuC firmware. I understand these
> > points, several other i915 developers do, and several of the GuC
> > firmware developers do too.
> > 
> > Matt
> > 
> > > Regards, Joonas
> > > 
> > > > 
> > > > Matt
> > > > 
> > > > > There's the orthogonal track to discuss what would be the stable set 
> > > > > of
> > > > > tracepoints we could expose. However, before that discussion is 
> > > > > closed,
> > > > > let's keep a rather strict line to avoid potential maintenance burned.
> > > > > 
> > > > > We can then

Re: [PATCH v4 1/5] drm/mediatek: Use mailbox rx_callback instead of cmdq_task_cb

2021-10-26 Thread Chun-Kuang Hu
Hi, Jason:

jason-jh.lin  於 2021年10月26日 週二 下午1:29寫道:
>
> From: Chun-Kuang Hu 
>
> rx_callback is a standard mailbox callback mechanism and could cover the
> function of proprietary cmdq_task_cb, so use the standard one instead of
> the proprietary one.

Reviewed-by: Chun-Kuang Hu 

>
> Signed-off-by: Chun-Kuang Hu 
> Signed-off-by: jason-jh.lin 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 16 +---
>  1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index a4e80e499674..369d3e68c0b6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -4,6 +4,8 @@
>   */
>
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -222,9 +224,11 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct 
> drm_crtc *crtc,
>  }
>
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> -static void ddp_cmdq_cb(struct cmdq_cb_data data)
> +static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  {
> -   cmdq_pkt_destroy(data.data);
> +   struct cmdq_cb_data *data = mssg;
> +
> +   cmdq_pkt_destroy(data->pkt);
>  }
>  #endif
>
> @@ -475,7 +479,12 @@ static void mtk_drm_crtc_update_config(struct 
> mtk_drm_crtc *mtk_crtc,
> cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> mtk_crtc_ddp_config(crtc, cmdq_handle);
> cmdq_pkt_finalize(cmdq_handle);
> -   cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> +   
> dma_sync_single_for_device(mtk_crtc->cmdq_client->chan->mbox->dev,
> +  cmdq_handle->pa_base,
> +  cmdq_handle->cmd_buf_size,
> +  DMA_TO_DEVICE);
> +   mbox_send_message(mtk_crtc->cmdq_client->chan, cmdq_handle);
> +   mbox_client_txdone(mtk_crtc->cmdq_client->chan, 0);
> }
>  #endif
> mtk_crtc->config_updating = false;
> @@ -839,6 +848,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
> }
>
> if (mtk_crtc->cmdq_client) {
> +   mtk_crtc->cmdq_client->client.rx_callback = ddp_cmdq_cb;
> ret = of_property_read_u32_index(priv->mutex_node,
>  "mediatek,gce-events",
>  
> drm_crtc_index(&mtk_crtc->base),
> --
> 2.18.0
>


Re: [PATCH 00/47] GuC submission support

2021-10-26 Thread Matthew Brost
On Tue, Oct 26, 2021 at 11:59:35AM +0300, Joonas Lahtinen wrote:
> Quoting Matthew Brost (2021-10-25 18:15:09)
> > On Mon, Oct 25, 2021 at 12:37:02PM +0300, Joonas Lahtinen wrote:
> > > Quoting Matthew Brost (2021-10-22 19:42:19)
> > > > On Fri, Oct 22, 2021 at 12:35:04PM +0300, Joonas Lahtinen wrote:
> > > > > Hi Matt & John,
> > > > > 
> > > > > Can you please queue patches with the right Fixes: references to 
> > > > > convert
> > > > > all the GuC tracepoints to be protected by the LOW_LEVEL_TRACEPOINTS
> > > > > protection for now. Please do so before next Wednesday so we get it
> > > > > queued in drm-intel-next-fixes.
> > > > > 
> > > > 
> > > > Don't we already do that? I checked i915_trace.h and every tracepoint I
> > > > added (intel_context class, i915_request_guc_submit) is protected by
> > > > LOW_LEVEL_TRACEPOINTS.
> > > > 
> > > > The only thing I changed outside of that protection is adding the guc_id
> > > > field to existing i915_request class tracepoints.
> > > 
> > > It's the first search hit for "guc" inside the i915_trace.h file :)
> > > 
> > > > Without the guc_id in
> > > > those tracepoints these are basically useless with GuC submission. We
> > > > could revert that if it is a huge deal but as I said then they are
> > > > useless...
> > > 
> > > Let's eliminate it for now and restore the tracepoint exactly as it was.
> > > 
> > 
> > Don't really agree - let's render tracepoints to be useless? Are
> > tracepoints ABI? I googled this and couldn't really find a definie
> > answer. If tracepoints are ABI, then OK I can revert this change but
> > still this is a poor technical decision (tracepoints should not be ABI).
> 
> Thats a very heated discussion in general. But the fact is that if
> tracepoint changes have caused regressions to applications, they have
> been forced to be remain untouched. You are free to raise the discussion
> with Linus/LKML if you feel that should not be the case. So the end
> result is that tracepoints are effectively in limbo, not ABI unless some
> application uses them like ABI.
> 
> Feel free to search the intel-gfx/lkml for "tracepoints" keyword and look
> for threads with many replies. It's not that I would not agree, it's more
> that I'm not in the mood for repeating that discussion over and over again
> and always land in the same spot.
> 
> So for now, we don't add anything new to tracepoints we can't guarantee
> to always be there untouched. Similarly, we don't guarantee any of them
> to remain stable. So we try to be compatible with the limbo.
> 
> I'm long overdue waiting for some stable consumer to step up for the
> tracepoints, so we can then start discussion what would actually be the
> best way of getting that information out for them. In ~5 years that has
> not happened.
> 
> > > If there is an immediate need, we should instead have an auxilary 
> > > tracepoint
> > > which is enabled only through LOW_LEVEL_TRACEPOINTS and that amends the
> > > information of the basic tracepoint.
> > > 
> > 
> > Regardless of what I said above, I'll post 2 patches. The 1st just
> > remove the GuC, the 2nd modify the tracepoint to include guc_id if
> > LOW_LEVEL_TRACEPOINTS is defined.
> 
> Thanks. Let's get a patch merged which simply drops the guc_id for now
> to unblock things.
> 
> For the second, an auxilary tracepoint will be preferred instead of
> mutating the existing one (regardless of the LOW_LEVEL_TRACEPOINTS).
> 
> I only noticed a patch that mutates the tracepoints, can you
> double-check sending the first patch?

Sorry for the double reply - missed this one in the first.

I changed my plans / mind after I send the original email. I only sent a
patch which includes guc_id when LOW_LEVEL_TRACEPOINTS is enabled. That
is the bear minimum I live with. Without it any time there is a problem
results in hacking the kernel. I can't do that. This is a good
compromise.

Matt

> 
> Regards, Joonas
> 
> > 
> > > For the longer term solution we should align towards the dma fence
> > > tracepoints. When those are combined with the OA information, one should
> > > be able to get a good understanding of both the software and hardware
> > > scheduling decisions.
> > > 
> > 
> > Not sure about this either. I use these tracepoins to correlate things
> > to the GuC log. Between the 2, if you know what you are doing you
> > basically can figure out everything that is happening. Fields in the
> > trace translate directly to fields in the GuC log. Some of these fields
> > are backend specific, not sure how these could be pushed the dma fence
> > tracepoints. For what it is worth, without these tracepoints we'd likely
> > still have a bunch of bugs in the GuC firmware. I understand these
> > points, several other i915 developers do, and several of the GuC
> > firmware developers do too.
> > 
> > Matt
> > 
> > > Regards, Joonas
> > > 
> > > > 
> > > > Matt
> > > > 
> > > > > There's the orthogonal track to discuss what would be the stable set 
> > > > > of
> > > > > trac

Re: [PATCH v4 2/5] drm/mediatek: Remove the pointer of struct cmdq_client

2021-10-26 Thread Chun-Kuang Hu
Hi, Jason:

jason-jh.lin  於 2021年10月26日 週二 下午1:29寫道:
>
> From: Chun-Kuang Hu 
>
> In mailbox rx_callback, it pass struct mbox_client to callback
> function, but it could not map back to mtk_drm_crtc instance
> because struct cmdq_client use a pointer to struct mbox_client:
>
> struct cmdq_client {
> struct mbox_client client;
> struct mbox_chan *chan;
> };
>
> struct mtk_drm_crtc {
> /* client instance data */
> struct cmdq_client *cmdq_client;
> };
>
> so remove the pointer of struct cmdq_client and let mtk_drm_crtc
> instance define cmdq_client as:
>
> struct mtk_drm_crtc {
> /* client instance data */
> struct cmdq_client cmdq_client;
> };
>
> and in rx_callback function, use struct mbox_client to get
> struct mtk_drm_crtc.

Reviewed-by: Chun-Kuang Hu 

>
> Signed-off-by: Chun-Kuang Hu 
> Signed-off-by: jason-jh.lin 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 37 +
>  1 file changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 369d3e68c0b6..e23e3224ac67 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -52,7 +52,7 @@ struct mtk_drm_crtc {
> boolpending_async_planes;
>
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> -   struct cmdq_client  *cmdq_client;
> +   struct cmdq_client  cmdq_client;
> u32 cmdq_event;
>  #endif
>
> @@ -472,19 +472,19 @@ static void mtk_drm_crtc_update_config(struct 
> mtk_drm_crtc *mtk_crtc,
> mtk_mutex_release(mtk_crtc->mutex);
> }
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> -   if (mtk_crtc->cmdq_client) {
> -   mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
> -   cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, 
> PAGE_SIZE);
> +   if (mtk_crtc->cmdq_client.chan) {
> +   mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
> +   cmdq_handle = cmdq_pkt_create(&mtk_crtc->cmdq_client, 
> PAGE_SIZE);
> cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> mtk_crtc_ddp_config(crtc, cmdq_handle);
> cmdq_pkt_finalize(cmdq_handle);
> -   
> dma_sync_single_for_device(mtk_crtc->cmdq_client->chan->mbox->dev,
> +   
> dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
>cmdq_handle->pa_base,
>cmdq_handle->cmd_buf_size,
>DMA_TO_DEVICE);
> -   mbox_send_message(mtk_crtc->cmdq_client->chan, cmdq_handle);
> -   mbox_client_txdone(mtk_crtc->cmdq_client->chan, 0);
> +   mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
> +   mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
> }
>  #endif
> mtk_crtc->config_updating = false;
> @@ -498,7 +498,7 @@ static void mtk_crtc_ddp_irq(void *data)
> struct mtk_drm_private *priv = crtc->dev->dev_private;
>
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> -   if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
> +   if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
>  #else
> if (!priv->data->shadow_register)
>  #endif
> @@ -838,17 +838,20 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
> mutex_init(&mtk_crtc->hw_lock);
>
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> -   mtk_crtc->cmdq_client =
> -   cmdq_mbox_create(mtk_crtc->mmsys_dev,
> -drm_crtc_index(&mtk_crtc->base));
> -   if (IS_ERR(mtk_crtc->cmdq_client)) {
> +   mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
> +   mtk_crtc->cmdq_client.client.tx_block = false;
> +   mtk_crtc->cmdq_client.client.knows_txdone = true;
> +   mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
> +   mtk_crtc->cmdq_client.chan =
> +   mbox_request_channel(&mtk_crtc->cmdq_client.client,
> +drm_crtc_index(&mtk_crtc->base));
> +   if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
> dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, 
> writing register by CPU now\n",
> drm_crtc_index(&mtk_crtc->base));
> -   mtk_crtc->cmdq_client = NULL;
> +   mtk_crtc->cmdq_client.chan = NULL;
> }
>
> -   if (mtk_crtc->cmdq_client) {
> -   mtk_crtc->cmdq_client->client.rx_callback = ddp_cmdq_cb;
> +   if (mtk_crtc->cmdq_client.chan) {
> ret = of_property_read_u32_index(priv->mutex_node,
>  "mediatek,gce-events",
>  

Re: [PATCH v4 3/5] drm/mediatek: Detect CMDQ execution timeout

2021-10-26 Thread Chun-Kuang Hu
Hi, Jason:

jason-jh.lin  於 2021年10月26日 週二 下午1:29寫道:
>
> From: Chun-Kuang Hu 
>
> CMDQ is used to update display register in vblank period, so
> it should be execute in next 2 vblank. One vblank interrupt
> before send message (occasionally) and one vblank interrupt
> after cmdq done. If it fail to execute in next 3 vblank,
> tiemout happen.

Reviewed-by: Chun-Kuang Hu 

>
> Signed-off-by: Chun-Kuang Hu 
> Signed-off-by: jason-jh.lin 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 20 ++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index e23e3224ac67..dad1f85ee315 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -54,6 +54,7 @@ struct mtk_drm_crtc {
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> struct cmdq_client  cmdq_client;
> u32 cmdq_event;
> +   u32 cmdq_vblank_cnt;
>  #endif
>
> struct device   *mmsys_dev;
> @@ -227,7 +228,10 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct 
> drm_crtc *crtc,
>  static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  {
> struct cmdq_cb_data *data = mssg;
> +   struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, 
> client);
> +   struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct 
> mtk_drm_crtc, cmdq_client);
>
> +   mtk_crtc->cmdq_vblank_cnt = 0;
> cmdq_pkt_destroy(data->pkt);
>  }
>  #endif
> @@ -483,6 +487,15 @@ static void mtk_drm_crtc_update_config(struct 
> mtk_drm_crtc *mtk_crtc,
>cmdq_handle->pa_base,
>cmdq_handle->cmd_buf_size,
>DMA_TO_DEVICE);
> +   /*
> +* CMDQ command should execute in next 3 vblank.
> +* One vblank interrupt before send message (occasionally)
> +* and one vblank interrupt after cmdq done,
> +* so it's timeout after 3 vblank interrupt.
> +* If it fail to execute in next 3 vblank, timeout happen.
> +*/
> +   mtk_crtc->cmdq_vblank_cnt = 3;
> +
> mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
> mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
> }
> @@ -499,11 +512,14 @@ static void mtk_crtc_ddp_irq(void *data)
>
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
> +   mtk_crtc_ddp_config(crtc, NULL);
> +   else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt 
> == 0)
> +   DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
> + drm_crtc_index(&mtk_crtc->base));
>  #else
> if (!priv->data->shadow_register)
> -#endif
> mtk_crtc_ddp_config(crtc, NULL);
> -
> +#endif
> mtk_drm_finish_page_flip(mtk_crtc);
>  }
>
> --
> 2.18.0
>


Re: [PATCH v2 13/17] drm/i915/dg2: Tile 4 plane format support

2021-10-26 Thread Ramalingam C
On 2021-10-21 at 17:27:08 +0300, Lisovskiy, Stanislav wrote:
> On Thu, Oct 21, 2021 at 07:56:23PM +0530, Ramalingam C wrote:
> > From: Stanislav Lisovskiy 
> > 
> > TileF(Tile4 in bspec) format is 4K tile organized into
> > 64B subtiles with same basic shape as for legacy TileY
> > which will be supported by Display13.
> > 
> > v2: - Fixed wrong case condition(Jani Nikula)
> > - Increased I915_FORMAT_MOD_F_TILED up to 12(Imre Deak)
> > 
> > v3: - s/I915_TILING_F/TILING_4/g
> > - s/I915_FORMAT_MOD_F_TILED/I915_FORMAT_MOD_4_TILED/g
> > - Removed unneeded fencing code
> > 
> > Cc: Imre Deak 
> > Cc: Matt Roper 
> > Cc: Maarten Lankhorst 
> > Signed-off-by: Stanislav Lisovskiy 
> > Signed-off-by: Matt Roper 
> > Signed-off-by: Juha-Pekka Heikkilä 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c  |  1 +
> >  drivers/gpu/drm/i915/display/intel_fb.c   |  7 
> >  drivers/gpu/drm/i915/display/intel_fbc.c  |  1 +
> >  .../drm/i915/display/intel_plane_initial.c|  1 +
> >  .../drm/i915/display/skl_universal_plane.c| 36 ++-
> >  drivers/gpu/drm/i915/i915_drv.h   |  1 +
> >  drivers/gpu/drm/i915/i915_pci.c   |  1 +
> >  drivers/gpu/drm/i915/i915_reg.h   |  1 +
> >  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
> >  drivers/gpu/drm/i915/intel_pm.c   |  1 +
> >  include/uapi/drm/drm_fourcc.h |  8 +
> >  11 files changed, 50 insertions(+), 9 deletions(-)
> 
> Was I supposed to change TILE_F/TILE_4 everywhere first,
> as per your comment?
Stan, if you think that is the right think to do, please go ahead!

Ram
> 
> Stan
> 
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index ce5d6633029a..9b678839bf2b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -8877,6 +8877,7 @@ static int intel_atomic_check_async(struct 
> > intel_atomic_state *state)
> > case I915_FORMAT_MOD_X_TILED:
> > case I915_FORMAT_MOD_Y_TILED:
> > case I915_FORMAT_MOD_Yf_TILED:
> > +   case I915_FORMAT_MOD_4_TILED:
> > break;
> > default:
> > drm_dbg_kms(&i915->drm,
> > diff --git a/drivers/gpu/drm/i915/display/intel_fb.c 
> > b/drivers/gpu/drm/i915/display/intel_fb.c
> > index fa1f375e696b..e19739fef825 100644
> > --- a/drivers/gpu/drm/i915/display/intel_fb.c
> > +++ b/drivers/gpu/drm/i915/display/intel_fb.c
> > @@ -127,6 +127,12 @@ intel_tile_width_bytes(const struct drm_framebuffer 
> > *fb, int color_plane)
> > return 128;
> > else
> > return 512;
> > +   case I915_FORMAT_MOD_4_TILED:
> > +   /*
> > +* Each 4K tile consists of 64B(8*8) subtiles, with
> > +* same shape as Y Tile(i.e 4*16B OWords)
> > +*/
> > +   return 128;
> > case I915_FORMAT_MOD_Y_TILED_CCS:
> > if (is_ccs_plane(fb, color_plane))
> > return 128;
> > @@ -305,6 +311,7 @@ unsigned int intel_surf_alignment(const struct 
> > drm_framebuffer *fb,
> > case I915_FORMAT_MOD_Y_TILED_CCS:
> > case I915_FORMAT_MOD_Yf_TILED_CCS:
> > case I915_FORMAT_MOD_Y_TILED:
> > +   case I915_FORMAT_MOD_4_TILED:
> > case I915_FORMAT_MOD_Yf_TILED:
> > return 1 * 1024 * 1024;
> > default:
> > diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c 
> > b/drivers/gpu/drm/i915/display/intel_fbc.c
> > index 1f66de77a6b1..f079a771f802 100644
> > --- a/drivers/gpu/drm/i915/display/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
> > @@ -747,6 +747,7 @@ static bool tiling_is_valid(struct drm_i915_private 
> > *dev_priv,
> > case DRM_FORMAT_MOD_LINEAR:
> > case I915_FORMAT_MOD_Y_TILED:
> > case I915_FORMAT_MOD_Yf_TILED:
> > +   case I915_FORMAT_MOD_4_TILED:
> > return DISPLAY_VER(dev_priv) >= 9;
> > case I915_FORMAT_MOD_X_TILED:
> > return true;
> > diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c 
> > b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> > index dcd698a02da2..d80855ee9b96 100644
> > --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
> > +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> > @@ -125,6 +125,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
> > case DRM_FORMAT_MOD_LINEAR:
> > case I915_FORMAT_MOD_X_TILED:
> > case I915_FORMAT_MOD_Y_TILED:
> > +   case I915_FORMAT_MOD_4_TILED:
> > break;
> > default:
> > drm_dbg(&dev_priv->drm,
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
> > b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > index 7444b88829ea..0eb4509f7f7a 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > @@ -

Re: [PATCH v4 4/5] drm/mediatek: Add cmdq_handle in mtk_crtc

2021-10-26 Thread Chun-Kuang Hu
Hi, Jason:

jason-jh.lin  於 2021年10月26日 週二 下午1:29寫道:
>
> From: Chun-Kuang Hu 
>
> One mtk_crtc need just one cmdq_handle, so add one cmdq_handle
> in mtk_crtc to prevent frequently allocation and free of
> cmdq_handle.
>
> Signed-off-by: Chun-Kuang Hu 
> Signed-off-by: jason-jh.lin 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 64 +++--
>  1 file changed, 60 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index dad1f85ee315..31f05efc1bc0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -53,6 +53,7 @@ struct mtk_drm_crtc {
>
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> struct cmdq_client  cmdq_client;
> +   struct cmdq_pkt cmdq_handle;
> u32 cmdq_event;
> u32 cmdq_vblank_cnt;
>  #endif
> @@ -107,12 +108,59 @@ static void mtk_drm_finish_page_flip(struct 
> mtk_drm_crtc *mtk_crtc)
> }
>  }
>
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct 
> cmdq_pkt *pkt,
> +  size_t size)
> +{
> +   struct device *dev;
> +   dma_addr_t dma_addr;
> +
> +   pkt->va_base = kzalloc(size, GFP_KERNEL);
> +   if (!pkt->va_base) {
> +   kfree(pkt);
> +   return -ENOMEM;
> +   }
> +   pkt->buf_size = size;
> +   pkt->cl = (void *)client;
> +
> +   dev = client->chan->mbox->dev;
> +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
> + DMA_TO_DEVICE);
> +   if (dma_mapping_error(dev, dma_addr)) {
> +   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
> +   kfree(pkt->va_base);
> +   kfree(pkt);
> +   return -ENOMEM;
> +   }
> +
> +   pkt->pa_base = dma_addr;
> +
> +   return 0;
> +}
> +
> +static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> +{
> +   struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> +
> +   dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
> +DMA_TO_DEVICE);
> +   kfree(pkt->va_base);
> +   kfree(pkt);
> +}
> +#endif
> +
>  static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
>  {
> struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
>
> mtk_mutex_put(mtk_crtc->mutex);
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +   mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
>
> +   if (mtk_crtc->cmdq_client.chan)

This is not related to this patch, so move to an independent patch.

Regards,
Chun-Kuang.

> +   mbox_free_channel(mtk_crtc->cmdq_client.chan);
> + mtk_crtc->cmdq_client.chan = NULL;
> +#endif
> drm_crtc_cleanup(crtc);
>  }
>
> @@ -227,12 +275,10 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct 
> drm_crtc *crtc,
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  {
> -   struct cmdq_cb_data *data = mssg;
> struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, 
> client);
> struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct 
> mtk_drm_crtc, cmdq_client);
>
> mtk_crtc->cmdq_vblank_cnt = 0;
> -   cmdq_pkt_destroy(data->pkt);
>  }
>  #endif
>
> @@ -438,7 +484,7 @@ static void mtk_drm_crtc_update_config(struct 
> mtk_drm_crtc *mtk_crtc,
>bool needs_vblank)
>  {
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> -   struct cmdq_pkt *cmdq_handle;
> +   struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
>  #endif
> struct drm_crtc *crtc = &mtk_crtc->base;
> struct mtk_drm_private *priv = crtc->dev->dev_private;
> @@ -478,7 +524,7 @@ static void mtk_drm_crtc_update_config(struct 
> mtk_drm_crtc *mtk_crtc,
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> if (mtk_crtc->cmdq_client.chan) {
> mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
> -   cmdq_handle = cmdq_pkt_create(&mtk_crtc->cmdq_client, 
> PAGE_SIZE);
> +   cmdq_handle->cmd_buf_size = 0;
> cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> mtk_crtc_ddp_config(crtc, cmdq_handle);
> @@ -877,6 +923,16 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
> drm_crtc_index(&mtk_crtc->base));
> mbox_free_channel(mtk_crtc->cmdq_client.chan);
> mtk_crtc->cmdq_client.chan = NULL;
> +   } else {
> +   ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
> + &mtk_crtc->cmdq_handle,
> +  

Re: [PATCH] mm/migrate.c: Remove MIGRATE_PFN_LOCKED

2021-10-26 Thread Felix Kuehling
Am 2021-10-25 um 12:16 a.m. schrieb Alistair Popple:
> MIGRATE_PFN_LOCKED is used to indicate to migrate_vma_prepare() that a
> source page was already locked during migrate_vma_collect(). If it
> wasn't then the a second attempt is made to lock the page. However if
> the first attempt failed it's unlikely a second attempt will succeed,
> and the retry adds complexity. So clean this up by removing the retry
> and MIGRATE_PFN_LOCKED flag.
>
> Destination pages are also meant to have the MIGRATE_PFN_LOCKED flag
> set, but nothing actually checks that.
>
> Signed-off-by: Alistair Popple 

It makes sense to me. Do you have any empirical data on how much more
likely migrations are going to fail with this change due to contested
page locks?

Either way, the patch is

Acked-by: Felix Kuehling 


> ---
>  Documentation/vm/hmm.rst |   2 +-
>  arch/powerpc/kvm/book3s_hv_uvmem.c   |   4 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_migrate.c |   2 -
>  drivers/gpu/drm/nouveau/nouveau_dmem.c   |   4 +-
>  include/linux/migrate.h  |   1 -
>  lib/test_hmm.c   |   5 +-
>  mm/migrate.c | 145 +--
>  7 files changed, 35 insertions(+), 128 deletions(-)
>
> diff --git a/Documentation/vm/hmm.rst b/Documentation/vm/hmm.rst
> index a14c2938e7af..f2a59ed82ed3 100644
> --- a/Documentation/vm/hmm.rst
> +++ b/Documentation/vm/hmm.rst
> @@ -360,7 +360,7 @@ between device driver specific code and shared common 
> code:
> system memory page, locks the page with ``lock_page()``, and fills in the
> ``dst`` array entry with::
>  
> - dst[i] = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
> + dst[i] = migrate_pfn(page_to_pfn(dpage));
>  
> Now that the driver knows that this page is being migrated, it can
> invalidate device private MMU mappings and copy device private memory
> diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
> b/arch/powerpc/kvm/book3s_hv_uvmem.c
> index a7061ee3b157..28c436df9935 100644
> --- a/arch/powerpc/kvm/book3s_hv_uvmem.c
> +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
> @@ -560,7 +560,7 @@ static int __kvmppc_svm_page_out(struct vm_area_struct 
> *vma,
> gpa, 0, page_shift);
>  
>   if (ret == U_SUCCESS)
> - *mig.dst = migrate_pfn(pfn) | MIGRATE_PFN_LOCKED;
> + *mig.dst = migrate_pfn(pfn);
>   else {
>   unlock_page(dpage);
>   __free_page(dpage);
> @@ -774,7 +774,7 @@ static int kvmppc_svm_page_in(struct vm_area_struct *vma,
>   }
>   }
>  
> - *mig.dst = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
> + *mig.dst = migrate_pfn(page_to_pfn(dpage));
>   migrate_vma_pages(&mig);
>  out_finalize:
>   migrate_vma_finalize(&mig);
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
> b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
> index 4a16e3c257b9..41d9417f182b 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
> @@ -300,7 +300,6 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, 
> struct svm_range *prange,
>   migrate->dst[i] = svm_migrate_addr_to_pfn(adev, dst[i]);
>   svm_migrate_get_vram_page(prange, migrate->dst[i]);
>   migrate->dst[i] = migrate_pfn(migrate->dst[i]);
> - migrate->dst[i] |= MIGRATE_PFN_LOCKED;
>   src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE,
> DMA_TO_DEVICE);
>   r = dma_mapping_error(dev, src[i]);
> @@ -580,7 +579,6 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, 
> struct svm_range *prange,
> dst[i] >> PAGE_SHIFT, page_to_pfn(dpage));
>  
>   migrate->dst[i] = migrate_pfn(page_to_pfn(dpage));
> - migrate->dst[i] |= MIGRATE_PFN_LOCKED;
>   j++;
>   }
>  
> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c 
> b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> index 92987daa5e17..3828aafd3ac4 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> @@ -166,7 +166,7 @@ static vm_fault_t nouveau_dmem_fault_copy_one(struct 
> nouveau_drm *drm,
>   goto error_dma_unmap;
>   mutex_unlock(&svmm->mutex);
>  
> - args->dst[0] = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
> + args->dst[0] = migrate_pfn(page_to_pfn(dpage));
>   return 0;
>  
>  error_dma_unmap:
> @@ -602,7 +602,7 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct 
> nouveau_drm *drm,
>   ((paddr >> PAGE_SHIFT) << NVIF_VMM_PFNMAP_V0_ADDR_SHIFT);
>   if (src & MIGRATE_PFN_WRITE)
>   *pfn |= NVIF_VMM_PFNMAP_V0_W;
> - return migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
> + return migrate_pfn(page_to_pfn(dpage));
>  
>  out_dma_unmap:
>   dma_unmap_page(dev, *dma

Re: [PATCH v4 5/5] drm/mediatek: Clear pending flag when cmdq packet is done

2021-10-26 Thread Chun-Kuang Hu
Hi, Jason:

jason-jh.lin  於 2021年10月26日 週二 下午1:29寫道:
>
> From: Yongqiang Niu 
>
> In cmdq mode, packet may be flushed before it is executed, so
> the pending flag should be cleared after cmdq packet is done.

Reviewed-by: Chun-Kuang Hu 

>
> Signed-off-by: Yongqiang Niu 
> Signed-off-by: jason-jh.lin 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 51 ++---
>  1 file changed, 46 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 31f05efc1bc0..ea285795776f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -275,8 +275,42 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct 
> drm_crtc *crtc,
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  {
> +   struct cmdq_cb_data *data = mssg;
> struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, 
> client);
> struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct 
> mtk_drm_crtc, cmdq_client);
> +   struct mtk_crtc_state *state;
> +   unsigned int i;
> +
> +   if (data->sta < 0)
> +   return;
> +
> +   state = to_mtk_crtc_state(mtk_crtc->base.state);
> +
> +   state->pending_config = false;
> +
> +   if (mtk_crtc->pending_planes) {
> +   for (i = 0; i < mtk_crtc->layer_nr; i++) {
> +   struct drm_plane *plane = &mtk_crtc->planes[i];
> +   struct mtk_plane_state *plane_state;
> +
> +   plane_state = to_mtk_plane_state(plane->state);
> +
> +   plane_state->pending.config = false;
> +   }
> +   mtk_crtc->pending_planes = false;
> +   }
> +
> +   if (mtk_crtc->pending_async_planes) {
> +   for (i = 0; i < mtk_crtc->layer_nr; i++) {
> +   struct drm_plane *plane = &mtk_crtc->planes[i];
> +   struct mtk_plane_state *plane_state;
> +
> +   plane_state = to_mtk_plane_state(plane->state);
> +
> +   plane_state->pending.async_config = false;
> +   }
> +   mtk_crtc->pending_async_planes = false;
> +   }
>
> mtk_crtc->cmdq_vblank_cnt = 0;
>  }
> @@ -432,7 +466,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
> state->pending_vrefresh, 0,
> cmdq_handle);
>
> -   state->pending_config = false;
> +   if (!cmdq_handle)
> +   state->pending_config = false;
> }
>
> if (mtk_crtc->pending_planes) {
> @@ -452,9 +487,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
> mtk_ddp_comp_layer_config(comp, local_layer,
>   plane_state,
>   cmdq_handle);
> -   plane_state->pending.config = false;
> +   if (!cmdq_handle)
> +   plane_state->pending.config = false;
> }
> -   mtk_crtc->pending_planes = false;
> +
> +   if (!cmdq_handle)
> +   mtk_crtc->pending_planes = false;
> }
>
> if (mtk_crtc->pending_async_planes) {
> @@ -474,9 +512,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
> mtk_ddp_comp_layer_config(comp, local_layer,
>   plane_state,
>   cmdq_handle);
> -   plane_state->pending.async_config = false;
> +   if (!cmdq_handle)
> +   plane_state->pending.async_config = false;
> }
> -   mtk_crtc->pending_async_planes = false;
> +
> +   if (!cmdq_handle)
> +   mtk_crtc->pending_async_planes = false;
> }
>  }
>
> --
> 2.18.0
>


[PATCH drm-fixes v3] drm/ttm: remove ttm_bo_vm_insert_huge()

2021-10-26 Thread Jason Gunthorpe
The huge page functionality in TTM does not work safely because PUD and
PMD entries do not have a special bit.

get_user_pages_fast() considers any page that passed pmd_huge() as
usable:

if (unlikely(pmd_trans_huge(pmd) || pmd_huge(pmd) ||
 pmd_devmap(pmd))) {

And vmf_insert_pfn_pmd_prot() unconditionally sets

entry = pmd_mkhuge(pfn_t_pmd(pfn, prot));

eg on x86 the page will be _PAGE_PRESENT | PAGE_PSE.

As such gup_huge_pmd() will try to deref a struct page:

head = try_grab_compound_head(pmd_page(orig), refs, flags);

and thus crash.

So, iomem cannot be installed using vmf_insert_pfn_pud/pmd_prot().

Thomas further notices that the drivers are not expecting the struct page
to be used by anything - in particular the refcount incr above will cause
them to malfunction. This means even the struct page memory cannot be
used.

Therefore everything about this is not able to fully work correctly
considering GUP_fast. Delete it entirely. It can return someday along with
a proper PMD/PUD_SPECIAL bit in the page table itself to gate GUP_fast.

Cc: sta...@vger.kernel.org
Fixes: 314b6580adc5 ("drm/ttm, drm/vmwgfx: Support huge TTM pagefaults")
Reviewed-by: Christian König 
Reviewed-by: Thomas Hellström 
Acked-by: Daniel Vetter 
Signed-off-by: Jason Gunthorpe 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c|  2 +-
 drivers/gpu/drm/nouveau/nouveau_gem.c  |  2 +-
 drivers/gpu/drm/radeon/radeon_gem.c|  2 +-
 drivers/gpu/drm/ttm/ttm_bo_vm.c| 94 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h|  4 -
 drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 72 +
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c   |  3 -
 include/drm/ttm/ttm_bo_api.h   |  3 +-
 8 files changed, 7 insertions(+), 175 deletions(-)

Daniel/David, please grab it thanks

v3:
 - Updated commit message
v2: https://lore.kernel.org/r/0-v2-a44694790652+4ac-ttm_pmd_...@nvidia.com
 - Remove the entire thing as per Thomas's advice
v1: https://lore.kernel.org/r/0-v1-69e7da97f81f+21c-ttm_pmd_...@nvidia.com

Jason

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index d6aa032890ee8b..a1e63ba4c54a59 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -61,7 +61,7 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
}
 
 ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
-   TTM_BO_VM_NUM_PREFAULT, 1);
+   TTM_BO_VM_NUM_PREFAULT);
 
 drm_dev_exit(idx);
} else {
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c 
b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 8c2ecc28272322..c89d5964148fd5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -56,7 +56,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)
 
nouveau_bo_del_io_reserve_lru(bo);
prot = vm_get_page_prot(vma->vm_flags);
-   ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1);
+   ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);
nouveau_bo_add_io_reserve_lru(bo);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c 
b/drivers/gpu/drm/radeon/radeon_gem.c
index 458f92a7088797..a36a4f2c76b097 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -61,7 +61,7 @@ static vm_fault_t radeon_gem_fault(struct vm_fault *vmf)
goto unlock_resv;
 
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
-  TTM_BO_VM_NUM_PREFAULT, 1);
+  TTM_BO_VM_NUM_PREFAULT);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
goto unlock_mclk;
 
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index f56be5bc0861ec..e5af7f9e94b273 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -171,89 +171,6 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
 }
 EXPORT_SYMBOL(ttm_bo_vm_reserve);
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-/**
- * ttm_bo_vm_insert_huge - Insert a pfn for PUD or PMD faults
- * @vmf: Fault data
- * @bo: The buffer object
- * @page_offset: Page offset from bo start
- * @fault_page_size: The size of the fault in pages.
- * @pgprot: The page protections.
- * Does additional checking whether it's possible to insert a PUD or PMD
- * pfn and performs the insertion.
- *
- * Return: VM_FAULT_NOPAGE on successful insertion, VM_FAULT_FALLBACK if
- * a huge fault was not possible, or on insertion error.
- */
-static vm_fault_t ttm_bo_vm_insert_huge(struct vm_fault *vmf,
-  

Re: amdgpu "Fatal error during GPU init"; Ryzen 5600G integrated GPU + kernel 5.14.13

2021-10-26 Thread PGNet Dev

sbios settings


given suggestion this may be a BIOS issue, I've posted this issue as a question 
@,

  
https://forum.asrock.com/forum_posts.asp?TID=19749&title=x470d4u-p4-20-ryzen5600g-fatal-error-gpu-boot

and pinged ASRockRack tech support via their online tech supp form.

If anyone _here_ knows an appropriate contact @ ASRockRack to link into this 
discussion, that'd be useful/appreciated!


Re: [PATCH] video: fbdev: cirrusfb: check pixclock to avoid divide by zero

2021-10-26 Thread Geert Uytterhoeven
Hi George,

On Tue, Oct 26, 2021 at 5:48 PM George Kennedy
 wrote:
> On 10/26/2021 10:11 AM, Geert Uytterhoeven wrote:
> > On Tue, Oct 26, 2021 at 3:38 PM George Kennedy
> >  wrote:
> >> On 10/26/2021 4:30 AM, Geert Uytterhoeven wrote:
> >>> On Mon, Oct 25, 2021 at 9:37 PM George Kennedy
> >>>  wrote:
>  On 10/25/2021 3:07 PM, Greg KH wrote:
> > On Mon, Oct 25, 2021 at 02:01:30PM -0500, George Kennedy wrote:
> >> Do a sanity check on pixclock value before using it as a divisor.
> >>
> >> Syzkaller reported a divide error in cirrusfb_check_pixclock.
> >>
> >> divide error:  [#1] SMP KASAN PTI
> >> CPU: 0 PID: 14938 Comm: cirrusfb_test Not tainted 5.15.0-rc6 #1
> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2
> >> RIP: 0010:cirrusfb_check_var+0x6f1/0x1260
> >>
> >> Call Trace:
> >> fb_set_var+0x398/0xf90
> >> do_fb_ioctl+0x4b8/0x6f0
> >> fb_ioctl+0xeb/0x130
> >> __x64_sys_ioctl+0x19d/0x220
> >> do_syscall_64+0x3a/0x80
> >> entry_SYSCALL_64_after_hwframe+0x44/0xae
> >>
> >> Signed-off-by: George Kennedy 
> >> --- a/drivers/video/fbdev/cirrusfb.c
> >> +++ b/drivers/video/fbdev/cirrusfb.c
> >> @@ -477,6 +477,9 @@ static int cirrusfb_check_pixclock(const struct 
> >> fb_var_screeninfo *var,
> >>struct cirrusfb_info *cinfo = info->par;
> >>unsigned maxclockidx = var->bits_per_pixel >> 3;
> >>
> >> +if (!var->pixclock)
> >> +return -EINVAL;
> >>> This is not correct: fbdev drivers should round up invalid values,
> >>> and only return an error if rounding up cannot yield a valid value.
> >> What default value would you recommend? Here are examples of some of the
> >> possible cirrusfb pixclock values:
> >> 4: 25MHz
> >> 2: 50Mhz
> >> 12500: 80Mhz
> > You should pick the lowest supported value.
>
> In bestclock() the frequency value ("freq") is not allowed to go below 8000.
>
>  if (freq < 8000)
>  freq = 8000;
>
> If pixclock is passed in as zero to cirrusfb_check_pixclock(), is it ok
> to then set the value of pixclock to 125000, which will result in "freq"
> being set to 8000 (or adjust the passed in pixclock value to make sure
> "freq" does not get below 8000)?

No, clock rate is the inverse of clock period.
So the smallest clock period (fb_var_screeninfo.pixclock) corresponds
to the largest clock rate (freq in bestclock()).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH 3/3] drm/i915: Initial introduction of vma resources

2021-10-26 Thread kernel test robot
Hi "Thomas,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next 
tegra-drm/drm/tegra/for-next airlied/drm-next v5.15-rc7 next-20211026]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Thomas-Hellstr-m/Prepare-error-capture-for-asynchronous-migration/20211026-150944
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-defconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# 
https://github.com/0day-ci/linux/commit/6c17f33fae142e4401d64d5399eb28e3c68f13a1
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Thomas-Hellstr-m/Prepare-error-capture-for-asynchronous-migration/20211026-150944
git checkout 6c17f33fae142e4401d64d5399eb28e3c68f13a1
# save the attached .config to linux build tree
mkdir build_dir
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/drm/i915/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/i915/i915_vma.c:1519: warning: expecting prototype for 
>> i915_vma_resource_hold(). Prototype was for i915_vma_resource_unhold() 
>> instead


vim +1519 drivers/gpu/drm/i915/i915_vma.c

  1508  
  1509  /**
  1510   * i915_vma_resource_hold - Unhold the signaling of the vma resource 
unbind
  1511   * fence.
  1512   * @vma_res: The vma resource.
  1513   * @lockdep_cookie: The lockdep cookie returned from 
i915_vma_resource_hold.
  1514   *
  1515   * The function may leave a dma_fence critical section.
  1516   */
  1517  void i915_vma_resource_unhold(struct i915_vma_resource *vma_res,
  1518bool lockdep_cookie)
> 1519  {
  1520  dma_fence_end_signalling(lockdep_cookie);
  1521  
  1522  if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
  1523  unsigned long irq_flags;
  1524  
  1525  /* Inefficient open-coded might_lock_irqsave() */
  1526  spin_lock_irqsave(&vma_res->lock, irq_flags);
  1527  spin_unlock_irqrestore(&vma_res->lock, irq_flags);
  1528  }
  1529  
  1530  __i915_vma_resource_unhold(vma_res);
  1531  }
  1532  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


[PATCH] drm: Link CMA framebuffer helpers into KMS helper library

2021-10-26 Thread Thomas Zimmermann
Linking the CMA frambuffer helpers into a CMA helper library in
commit 4b2b5e142ff4 ("drm: Move GEM memory managers into modules")
results in linker errors:

  arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: \
  in function `drm_fb_cma_get_gem_obj': \
  drivers/gpu/drm/drm_fb_cma_helper.c:46: undefined reference \
  to `drm_gem_fb_get_obj'
  arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46: \
  undefined reference to `drm_gem_fb_get_obj'
  arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46: \
  undefined reference to `drm_gem_fb_get_obj'
  arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: in \
  function `drm_fb_cma_sync_non_coherent': \
  drivers/gpu/drm/drm_fb_cma_helper.c:133: undefined reference \
  to `drm_atomic_helper_damage_iter_init'
  arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:135: \
  undefined reference to `drm_atomic_helper_damage_iter_next'

Link the CMA framebuffer helpers into the KMS helper library to
fix the problem.

Signed-off-by: Thomas Zimmermann 
Fixes: 4b2b5e142ff4 ("drm: Move GEM memory managers into modules")
Reported-by: Naresh Kamboju 
Reported-by: Linux Kernel Functional Testing 
Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7f6eb11b6aac..1c41156deb5f 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -34,7 +34,6 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += drm_privacy_screen.o 
drm_privacy_screen_x86.
 obj-$(CONFIG_DRM_DP_AUX_BUS) += drm_dp_aux_bus.o
 
 drm_cma_helper-y := drm_gem_cma_helper.o
-drm_cma_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
 obj-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_cma_helper.o
 
 drm_shmem_helper-y := drm_gem_shmem_helper.o
@@ -59,6 +58,7 @@ drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o 
drm_dp_helper.o \
 
 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
+drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
 drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
 drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
 
-- 
2.33.1



Re: gpu: drm_fb_cma_helper.c:46: undefined reference to `drm_gem_fb_get_obj'

2021-10-26 Thread Thomas Zimmermann

Hi

Am 25.10.21 um 16:01 schrieb Naresh Kamboju:

On Mon, 25 Oct 2021 at 17:43, Naresh Kamboju  wrote:


Regression found on arm gcc-11 built with multi_v5_defconfig
Following build warnings / errors reported on linux next 20211025.

metadata:
 git_describe: next-20211025
 git_repo: https://gitlab.com/Linaro/lkft/mirrors/next/linux-next
 git_short_log: 9ae1fbdeabd3 (\"Add linux-next specific files for 
20211025\")
 target_arch: arm
 toolchain: gcc-11
 config: multi_v5_defconfig

build error :
--
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: in
function `drm_fb_cma_get_gem_obj':
drivers/gpu/drm/drm_fb_cma_helper.c:46: undefined reference to
`drm_gem_fb_get_obj'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46:
undefined reference to `drm_gem_fb_get_obj'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46:
undefined reference to `drm_gem_fb_get_obj'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: in
function `drm_fb_cma_sync_non_coherent':
drivers/gpu/drm/drm_fb_cma_helper.c:133: undefined reference to
`drm_atomic_helper_damage_iter_init'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:135:
undefined reference to `drm_atomic_helper_damage_iter_next'
make[1]: *** [Makefile:1252: vmlinux] Error 1
make[1]: Target '__all' not remade because of errors.
make: *** [Makefile:226: __sub-make] Error 2

Reported-by: Linux Kernel Functional Testing 


The bisection script pointed to the first bad commit,

commit 4b2b5e142ff499a2bef2b8db0272bbda1088a3fe
drm: Move GEM memory managers into modules


Could you please try the patch at [1]? It fixes the problem for me.

Best regards
Thomas

[1] https://patchwork.freedesktop.org/patch/461426/




build link:
---
https://builds.tuxbuild.com/1zzgFZBGjpQ5R0lawQFW9iJ39Hp/build.log

build config:
-
https://builds.tuxbuild.com/1zzgFZBGjpQ5R0lawQFW9iJ39Hp/config

# To install tuxmake on your system globally
# sudo pip3 install -U tuxmake
tuxmake --runtime podman --target-arch arm --toolchain gcc-11
--kconfig multi_v5_defconfig

--
Linaro LKFT
https://lkft.linaro.org


- Naresh



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


OpenPGP_signature
Description: OpenPGP digital signature


[RESEND PATCH v3 1/6] drm/ingenic: Simplify code by using hwdescs array

2021-10-26 Thread Paul Cercueil
Instead of having one 'hwdesc' variable for the plane #0, one for the
plane #1 and one for the palette, use a 'hwdesc[3]' array, where the
DMA hardware descriptors are indexed by the plane's number.

v2: dma_hwdesc_addr() extended to support palette hwdesc. The palette
hwdesc is now hwdesc[3] to simplify things. Add
ingenic_drm_configure_hwdesc*() functions to factorize code.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 78 ++-
 1 file changed, 48 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index a5df1c8d34cd..95c12c2aba14 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -41,6 +41,8 @@
 #include 
 #include 
 
+#define HWDESC_PALETTE 2
+
 struct ingenic_dma_hwdesc {
u32 next;
u32 addr;
@@ -49,9 +51,7 @@ struct ingenic_dma_hwdesc {
 } __aligned(16);
 
 struct ingenic_dma_hwdescs {
-   struct ingenic_dma_hwdesc hwdesc_f0;
-   struct ingenic_dma_hwdesc hwdesc_f1;
-   struct ingenic_dma_hwdesc hwdesc_pal;
+   struct ingenic_dma_hwdesc hwdesc[3];
u16 palette[256] __aligned(16);
 };
 
@@ -141,6 +141,14 @@ static inline struct ingenic_drm *drm_nb_get_priv(struct 
notifier_block *nb)
return container_of(nb, struct ingenic_drm, clock_nb);
 }
 
+static inline dma_addr_t dma_hwdesc_addr(const struct ingenic_drm *priv,
+unsigned int idx)
+{
+   u32 offset = offsetof(struct ingenic_dma_hwdescs, hwdesc[idx]);
+
+   return priv->dma_hwdescs_phys + offset;
+}
+
 static int ingenic_drm_update_pixclk(struct notifier_block *nb,
 unsigned long action,
 void *data)
@@ -558,9 +566,9 @@ static void ingenic_drm_plane_atomic_update(struct 
drm_plane *plane,
struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
struct drm_plane_state *newstate = 
drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *oldstate = 
drm_atomic_get_old_plane_state(state, plane);
+   unsigned int width, height, cpp, next_id, plane_id;
struct drm_crtc_state *crtc_state;
struct ingenic_dma_hwdesc *hwdesc;
-   unsigned int width, height, cpp, offset;
dma_addr_t addr;
u32 fourcc;
 
@@ -569,16 +577,14 @@ static void ingenic_drm_plane_atomic_update(struct 
drm_plane *plane,
drm_fb_cma_sync_non_coherent(&priv->drm, oldstate, 
newstate);
 
crtc_state = newstate->crtc->state;
+   plane_id = !!(priv->soc_info->has_osd && plane != &priv->f0);
 
addr = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0);
width = newstate->src_w >> 16;
height = newstate->src_h >> 16;
cpp = newstate->fb->format->cpp[0];
 
-   if (!priv->soc_info->has_osd || plane == &priv->f0)
-   hwdesc = &priv->dma_hwdescs->hwdesc_f0;
-   else
-   hwdesc = &priv->dma_hwdescs->hwdesc_f1;
+   hwdesc = &priv->dma_hwdescs->hwdesc[plane_id];
 
hwdesc->addr = addr;
hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4);
@@ -588,12 +594,8 @@ static void ingenic_drm_plane_atomic_update(struct 
drm_plane *plane,
 
ingenic_drm_plane_config(priv->dev, plane, fourcc);
 
-   if (fourcc == DRM_FORMAT_C8)
-   offset = offsetof(struct ingenic_dma_hwdescs, 
hwdesc_pal);
-   else
-   offset = offsetof(struct ingenic_dma_hwdescs, 
hwdesc_f0);
-
-   priv->dma_hwdescs->hwdesc_f0.next = 
priv->dma_hwdescs_phys + offset;
+   next_id = fourcc == DRM_FORMAT_C8 ? HWDESC_PALETTE : 0;
+   priv->dma_hwdescs->hwdesc[0].next = 
dma_hwdesc_addr(priv, next_id);
 
crtc_state->color_mgmt_changed = fourcc == 
DRM_FORMAT_C8;
}
@@ -846,6 +848,35 @@ static void __maybe_unused ingenic_drm_release_rmem(void 
*d)
of_reserved_mem_device_release(d);
 }
 
+static void ingenic_drm_configure_hwdesc(struct ingenic_drm *priv,
+unsigned int hwdesc,
+unsigned int next_hwdesc, u32 id)
+{
+   struct ingenic_dma_hwdesc *desc = &priv->dma_hwdescs->hwdesc[hwdesc];
+
+   desc->next = dma_hwdesc_addr(priv, next_hwdesc);
+   desc->id = id;
+}
+
+static void ingenic_drm_configure_hwdesc_palette(struct ingenic_drm *priv)
+{
+   struct ingenic_dma_hwdesc *desc;
+
+   ingenic_drm_configure_hwdesc(priv, HWDESC_PALETTE, 0, 0xc0);
+
+   desc = &priv->dma_hwdescs->hwdesc[HWDESC_PALETTE];
+   desc->addr = priv->dma_hwdescs_phys
+   + offsetof(struct

[RESEND PATCH v3 2/6] drm/ingenic: Add support for private objects

2021-10-26 Thread Paul Cercueil
Until now, the ingenic-drm as well as the ingenic-ipu drivers used to
put state-specific information in their respective private structure.

Add boilerplate code to support private objects in the two drivers, so
that state-specific information can be put in the state-specific private
structure.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 61 +++
 drivers/gpu/drm/ingenic/ingenic-ipu.c | 54 
 2 files changed, 115 insertions(+)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index 95c12c2aba14..5dbeca0f8f37 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -64,6 +64,10 @@ struct jz_soc_info {
unsigned int num_formats_f0, num_formats_f1;
 };
 
+struct ingenic_drm_private_state {
+   struct drm_private_state base;
+};
+
 struct ingenic_drm {
struct drm_device drm;
/*
@@ -99,8 +103,16 @@ struct ingenic_drm {
struct mutex clk_mutex;
bool update_clk_rate;
struct notifier_block clock_nb;
+
+   struct drm_private_obj private_obj;
 };
 
+static inline struct ingenic_drm_private_state *
+to_ingenic_drm_priv_state(struct drm_private_state *state)
+{
+   return container_of(state, struct ingenic_drm_private_state, base);
+}
+
 static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
@@ -766,6 +778,28 @@ ingenic_drm_gem_create_object(struct drm_device *drm, 
size_t size)
return &obj->base;
 }
 
+static struct drm_private_state *
+ingenic_drm_duplicate_state(struct drm_private_obj *obj)
+{
+   struct ingenic_drm_private_state *state = 
to_ingenic_drm_priv_state(obj->state);
+
+   state = kmemdup(state, sizeof(*state), GFP_KERNEL);
+   if (!state)
+   return NULL;
+
+   __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
+
+   return &state->base;
+}
+
+static void ingenic_drm_destroy_state(struct drm_private_obj *obj,
+ struct drm_private_state *state)
+{
+   struct ingenic_drm_private_state *priv_state = 
to_ingenic_drm_priv_state(state);
+
+   kfree(priv_state);
+}
+
 DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops);
 
 static const struct drm_driver ingenic_drm_driver_data = {
@@ -836,6 +870,11 @@ static struct drm_mode_config_helper_funcs 
ingenic_drm_mode_config_helpers = {
.atomic_commit_tail = drm_atomic_helper_commit_tail,
 };
 
+static const struct drm_private_state_funcs ingenic_drm_private_state_funcs = {
+   .atomic_duplicate_state = ingenic_drm_duplicate_state,
+   .atomic_destroy_state = ingenic_drm_destroy_state,
+};
+
 static void ingenic_drm_unbind_all(void *d)
 {
struct ingenic_drm *priv = d;
@@ -877,9 +916,15 @@ static void ingenic_drm_configure_hwdesc_plane(struct 
ingenic_drm *priv,
ingenic_drm_configure_hwdesc(priv, plane, plane, 0xf0 | plane);
 }
 
+static void ingenic_drm_atomic_private_obj_fini(struct drm_device *drm, void 
*private_obj)
+{
+   drm_atomic_private_obj_fini(private_obj);
+}
+
 static int ingenic_drm_bind(struct device *dev, bool has_components)
 {
struct platform_device *pdev = to_platform_device(dev);
+   struct ingenic_drm_private_state *private_state;
const struct jz_soc_info *soc_info;
struct ingenic_drm *priv;
struct clk *parent_clk;
@@ -1148,6 +1193,20 @@ static int ingenic_drm_bind(struct device *dev, bool 
has_components)
goto err_devclk_disable;
}
 
+   private_state = kzalloc(sizeof(*private_state), GFP_KERNEL);
+   if (!private_state) {
+   ret = -ENOMEM;
+   goto err_clk_notifier_unregister;
+   }
+
+   drm_atomic_private_obj_init(drm, &priv->private_obj, 
&private_state->base,
+   &ingenic_drm_private_state_funcs);
+
+   ret = drmm_add_action_or_reset(drm, ingenic_drm_atomic_private_obj_fini,
+  &priv->private_obj);
+   if (ret)
+   goto err_private_state_free;
+
ret = drm_dev_register(drm, 0);
if (ret) {
dev_err(dev, "Failed to register DRM driver\n");
@@ -1158,6 +1217,8 @@ static int ingenic_drm_bind(struct device *dev, bool 
has_components)
 
return 0;
 
+err_private_state_free:
+   kfree(private_state);
 err_clk_notifier_unregister:
clk_notifier_unregister(parent_clk, &priv->clock_nb);
 err_devclk_disable:
diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c 
b/drivers/gpu/drm/ingenic/ingenic-ipu.c
index aeb8a757d213..c819293b8317 100644
--- a/drivers/gpu/drm/ingenic/ingenic-ipu.c
+++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c
@@ -45,6 +45,10 @@ struct soc_info {
  unsigned int weight, unsigned int offset);
 };
 
+struct ingenic_ipu_private_state {
+   struct drm_private_state base;
+};
+
 stru

[RESEND PATCH v3 3/6] drm/ingenic: Move IPU scale settings to private state

2021-10-26 Thread Paul Cercueil
The IPU scaling information is computed in the plane's ".atomic_check"
callback, and used in the ".atomic_update" callback. As such, it is
state-specific, and should be moved to a private state structure.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-ipu.c | 73 ---
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c 
b/drivers/gpu/drm/ingenic/ingenic-ipu.c
index c819293b8317..2737fc521e15 100644
--- a/drivers/gpu/drm/ingenic/ingenic-ipu.c
+++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c
@@ -47,6 +47,8 @@ struct soc_info {
 
 struct ingenic_ipu_private_state {
struct drm_private_state base;
+
+   unsigned int num_w, num_h, denom_w, denom_h;
 };
 
 struct ingenic_ipu {
@@ -58,8 +60,6 @@ struct ingenic_ipu {
const struct soc_info *soc_info;
bool clk_enabled;
 
-   unsigned int num_w, num_h, denom_w, denom_h;
-
dma_addr_t addr_y, addr_u, addr_v;
 
struct drm_property *sharpness_prop;
@@ -85,6 +85,30 @@ to_ingenic_ipu_priv_state(struct drm_private_state *state)
return container_of(state, struct ingenic_ipu_private_state, base);
 }
 
+static struct ingenic_ipu_private_state *
+ingenic_ipu_get_priv_state(struct ingenic_ipu *priv, struct drm_atomic_state 
*state)
+{
+   struct drm_private_state *priv_state;
+
+   priv_state = drm_atomic_get_private_obj_state(state, 
&priv->private_obj);
+   if (IS_ERR(priv_state))
+   return ERR_CAST(priv_state);
+
+   return to_ingenic_ipu_priv_state(priv_state);
+}
+
+static struct ingenic_ipu_private_state *
+ingenic_ipu_get_new_priv_state(struct ingenic_ipu *priv, struct 
drm_atomic_state *state)
+{
+   struct drm_private_state *priv_state;
+
+   priv_state = drm_atomic_get_new_private_obj_state(state, 
&priv->private_obj);
+   if (!priv_state)
+   return NULL;
+
+   return to_ingenic_ipu_priv_state(priv_state);
+}
+
 /*
  * Apply conventional cubic convolution kernel. Both parameters
  *  and return value are 15.16 signed fixed-point.
@@ -305,11 +329,16 @@ static void ingenic_ipu_plane_atomic_update(struct 
drm_plane *plane,
const struct drm_format_info *finfo;
u32 ctrl, stride = 0, coef_index = 0, format = 0;
bool needs_modeset, upscaling_w, upscaling_h;
+   struct ingenic_ipu_private_state *ipu_state;
int err;
 
if (!newstate || !newstate->fb)
return;
 
+   ipu_state = ingenic_ipu_get_new_priv_state(ipu, state);
+   if (WARN_ON(!ipu_state))
+   return;
+
finfo = drm_format_info(newstate->fb->format->format);
 
if (!ipu->clk_enabled) {
@@ -482,27 +511,27 @@ static void ingenic_ipu_plane_atomic_update(struct 
drm_plane *plane,
if (ipu->soc_info->has_bicubic)
ctrl |= JZ_IPU_CTRL_ZOOM_SEL;
 
-   upscaling_w = ipu->num_w > ipu->denom_w;
+   upscaling_w = ipu_state->num_w > ipu_state->denom_w;
if (upscaling_w)
ctrl |= JZ_IPU_CTRL_HSCALE;
 
-   if (ipu->num_w != 1 || ipu->denom_w != 1) {
+   if (ipu_state->num_w != 1 || ipu_state->denom_w != 1) {
if (!ipu->soc_info->has_bicubic && !upscaling_w)
-   coef_index |= (ipu->denom_w - 1) << 16;
+   coef_index |= (ipu_state->denom_w - 1) << 16;
else
-   coef_index |= (ipu->num_w - 1) << 16;
+   coef_index |= (ipu_state->num_w - 1) << 16;
ctrl |= JZ_IPU_CTRL_HRSZ_EN;
}
 
-   upscaling_h = ipu->num_h > ipu->denom_h;
+   upscaling_h = ipu_state->num_h > ipu_state->denom_h;
if (upscaling_h)
ctrl |= JZ_IPU_CTRL_VSCALE;
 
-   if (ipu->num_h != 1 || ipu->denom_h != 1) {
+   if (ipu_state->num_h != 1 || ipu_state->denom_h != 1) {
if (!ipu->soc_info->has_bicubic && !upscaling_h)
-   coef_index |= ipu->denom_h - 1;
+   coef_index |= ipu_state->denom_h - 1;
else
-   coef_index |= ipu->num_h - 1;
+   coef_index |= ipu_state->num_h - 1;
ctrl |= JZ_IPU_CTRL_VRSZ_EN;
}
 
@@ -513,13 +542,13 @@ static void ingenic_ipu_plane_atomic_update(struct 
drm_plane *plane,
/* Set the LUT index register */
regmap_write(ipu->map, JZ_REG_IPU_RSZ_COEF_INDEX, coef_index);
 
-   if (ipu->num_w != 1 || ipu->denom_w != 1)
+   if (ipu_state->num_w != 1 || ipu_state->denom_w != 1)
ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_HRSZ_COEF_LUT,
- ipu->num_w, ipu->denom_w);
+ ipu_state->num_w, ipu_state->denom_w);
 
-   if (ipu->num_h != 1 || ipu->denom_h != 1)
+   if (ipu_state->num_h != 1 || ipu_state->denom_h != 1)
ingenic_ipu_set_coefs(ipu, JZ_REG_IPU_VRSZ_COEF_LUT,
-

[RESEND PATCH v3 0/6] drm/ingenic: Various improvements v3

2021-10-26 Thread Paul Cercueil
Hi,

I resend the V3 of my patchset for drm/ingenic, verbatim.

The previous submission of my V3 received a lot of replies, but none of
these replies were actually talking about the patches themselves.

Cheers,
-Paul


Paul Cercueil (6):
  drm/ingenic: Simplify code by using hwdescs array
  drm/ingenic: Add support for private objects
  drm/ingenic: Move IPU scale settings to private state
  drm/ingenic: Set DMA descriptor chain register when starting CRTC
  drm/ingenic: Upload palette before frame
  drm/ingenic: Attach bridge chain to encoders

 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 278 +-
 drivers/gpu/drm/ingenic/ingenic-ipu.c | 127 --
 2 files changed, 333 insertions(+), 72 deletions(-)

-- 
2.33.0



[RESEND PATCH v3 4/6] drm/ingenic: Set DMA descriptor chain register when starting CRTC

2021-10-26 Thread Paul Cercueil
Setting the DMA descriptor chain register in the probe function has been
fine until now, because we only ever had one descriptor per foreground.

As the driver will soon have real descriptor chains, and the DMA
descriptor chain register updates itself to point to the current
descriptor being processed, this register needs to be reset after a full
modeset to point to the first descriptor of the chain.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index 5dbeca0f8f37..cbc76cede99e 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -186,6 +186,10 @@ static void ingenic_drm_crtc_atomic_enable(struct drm_crtc 
*crtc,
 
regmap_write(priv->map, JZ_REG_LCD_STATE, 0);
 
+   /* Set address of our DMA descriptor chain */
+   regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, 0));
+   regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1));
+
regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
   JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE,
   JZ_LCD_CTRL_ENABLE);
-- 
2.33.0



[RESEND PATCH v3 5/6] drm/ingenic: Upload palette before frame

2021-10-26 Thread Paul Cercueil
When using C8 color mode, make sure that the palette is always uploaded
before a frame; otherwise the very first frame will have wrong colors.

Do that by changing the link order of the DMA descriptors.

v3: Fix ingenic_drm_get_new_priv_state() called instead of
ingenic_drm_get_priv_state()

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 53 ---
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index cbc76cede99e..a5e2880e07a1 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -66,6 +66,7 @@ struct jz_soc_info {
 
 struct ingenic_drm_private_state {
struct drm_private_state base;
+   bool use_palette;
 };
 
 struct ingenic_drm {
@@ -113,6 +114,30 @@ to_ingenic_drm_priv_state(struct drm_private_state *state)
return container_of(state, struct ingenic_drm_private_state, base);
 }
 
+static struct ingenic_drm_private_state *
+ingenic_drm_get_priv_state(struct ingenic_drm *priv, struct drm_atomic_state 
*state)
+{
+   struct drm_private_state *priv_state;
+
+   priv_state = drm_atomic_get_private_obj_state(state, 
&priv->private_obj);
+   if (IS_ERR(priv_state))
+   return ERR_CAST(priv_state);
+
+   return to_ingenic_drm_priv_state(priv_state);
+}
+
+static struct ingenic_drm_private_state *
+ingenic_drm_get_new_priv_state(struct ingenic_drm *priv, struct 
drm_atomic_state *state)
+{
+   struct drm_private_state *priv_state;
+
+   priv_state = drm_atomic_get_new_private_obj_state(state, 
&priv->private_obj);
+   if (!priv_state)
+   return NULL;
+
+   return to_ingenic_drm_priv_state(priv_state);
+}
+
 static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
@@ -183,11 +208,18 @@ static void ingenic_drm_crtc_atomic_enable(struct 
drm_crtc *crtc,
   struct drm_atomic_state *state)
 {
struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
+   struct ingenic_drm_private_state *priv_state;
+   unsigned int next_id;
+
+   priv_state = ingenic_drm_get_priv_state(priv, state);
+   if (WARN_ON(IS_ERR(priv_state)))
+   return;
 
regmap_write(priv->map, JZ_REG_LCD_STATE, 0);
 
-   /* Set address of our DMA descriptor chain */
-   regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, 0));
+   /* Set addresses of our DMA descriptor chains */
+   next_id = priv_state->use_palette ? HWDESC_PALETTE : 0;
+   regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_addr(priv, next_id));
regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_addr(priv, 1));
 
regmap_update_bits(priv->map, JZ_REG_LCD_CTRL,
@@ -393,6 +425,7 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane 
*plane,
struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(state,

 plane);
struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
+   struct ingenic_drm_private_state *priv_state;
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
int ret;
@@ -405,6 +438,10 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane 
*plane,
if (WARN_ON(!crtc_state))
return -EINVAL;
 
+   priv_state = ingenic_drm_get_priv_state(priv, state);
+   if (IS_ERR(priv_state))
+   return PTR_ERR(priv_state);
+
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
  DRM_PLANE_HELPER_NO_SCALING,
  DRM_PLANE_HELPER_NO_SCALING,
@@ -423,6 +460,9 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane 
*plane,
 (new_plane_state->src_h >> 16) != new_plane_state->crtc_h))
return -EINVAL;
 
+   priv_state->use_palette = new_plane_state->fb &&
+   new_plane_state->fb->format->format == DRM_FORMAT_C8;
+
/*
 * Require full modeset if enabling or disabling a plane, or changing
 * its position, size or depth.
@@ -583,6 +623,7 @@ static void ingenic_drm_plane_atomic_update(struct 
drm_plane *plane,
struct drm_plane_state *newstate = 
drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *oldstate = 
drm_atomic_get_old_plane_state(state, plane);
unsigned int width, height, cpp, next_id, plane_id;
+   struct ingenic_drm_private_state *priv_state;
struct drm_crtc_state *crtc_state;
struct ingenic_dma_hwdesc *hwdesc;
dma_addr_t addr;
@@ -600,19 +641,19 @@ static void ingenic_drm_plane_atomic_update(struct 
drm_plane *plane,
height

[RESEND PATCH v3 6/6] drm/ingenic: Attach bridge chain to encoders

2021-10-26 Thread Paul Cercueil
Attach a top-level bridge to each encoder, which will be used for
negociating the bus format and flags.

All the bridges are now attached with DRM_BRIDGE_ATTACH_NO_CONNECTOR.

Signed-off-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 92 +--
 1 file changed, 70 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index a5e2880e07a1..a05a9fa6e115 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -108,6 +109,19 @@ struct ingenic_drm {
struct drm_private_obj private_obj;
 };
 
+struct ingenic_drm_bridge {
+   struct drm_encoder encoder;
+   struct drm_bridge bridge, *next_bridge;
+
+   struct drm_bus_cfg bus_cfg;
+};
+
+static inline struct ingenic_drm_bridge *
+to_ingenic_drm_bridge(struct drm_encoder *encoder)
+{
+   return container_of(encoder, struct ingenic_drm_bridge, encoder);
+}
+
 static inline struct ingenic_drm_private_state *
 to_ingenic_drm_priv_state(struct drm_private_state *state)
 {
@@ -668,11 +682,10 @@ static void ingenic_drm_encoder_atomic_mode_set(struct 
drm_encoder *encoder,
 {
struct ingenic_drm *priv = drm_device_get_priv(encoder->dev);
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
-   struct drm_connector *conn = conn_state->connector;
-   struct drm_display_info *info = &conn->display_info;
+   struct ingenic_drm_bridge *bridge = to_ingenic_drm_bridge(encoder);
unsigned int cfg, rgbcfg = 0;
 
-   priv->panel_is_sharp = info->bus_flags & DRM_BUS_FLAG_SHARP_SIGNALS;
+   priv->panel_is_sharp = bridge->bus_cfg.flags & 
DRM_BUS_FLAG_SHARP_SIGNALS;
 
if (priv->panel_is_sharp) {
cfg = JZ_LCD_CFG_MODE_SPECIAL_TFT_1 | JZ_LCD_CFG_REV_POLARITY;
@@ -685,19 +698,19 @@ static void ingenic_drm_encoder_atomic_mode_set(struct 
drm_encoder *encoder,
cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
-   if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
+   if (bridge->bus_cfg.flags & DRM_BUS_FLAG_DE_LOW)
cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
-   if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
+   if (bridge->bus_cfg.flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
 
if (!priv->panel_is_sharp) {
-   if (conn->connector_type == DRM_MODE_CONNECTOR_TV) {
+   if (conn_state->connector->connector_type == 
DRM_MODE_CONNECTOR_TV) {
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
cfg |= JZ_LCD_CFG_MODE_TV_OUT_I;
else
cfg |= JZ_LCD_CFG_MODE_TV_OUT_P;
} else {
-   switch (*info->bus_formats) {
+   switch (bridge->bus_cfg.format) {
case MEDIA_BUS_FMT_RGB565_1X16:
cfg |= JZ_LCD_CFG_MODE_GENERIC_16BIT;
break;
@@ -723,20 +736,29 @@ static void ingenic_drm_encoder_atomic_mode_set(struct 
drm_encoder *encoder,
regmap_write(priv->map, JZ_REG_LCD_RGBC, rgbcfg);
 }
 
-static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder,
-   struct drm_crtc_state *crtc_state,
-   struct drm_connector_state 
*conn_state)
+static int ingenic_drm_bridge_attach(struct drm_bridge *bridge,
+enum drm_bridge_attach_flags flags)
+{
+   struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge->encoder);
+
+   return drm_bridge_attach(bridge->encoder, ib->next_bridge,
+&ib->bridge, flags);
+}
+
+static int ingenic_drm_bridge_atomic_check(struct drm_bridge *bridge,
+  struct drm_bridge_state 
*bridge_state,
+  struct drm_crtc_state *crtc_state,
+  struct drm_connector_state 
*conn_state)
 {
-   struct drm_display_info *info = &conn_state->connector->display_info;
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+   struct ingenic_drm_bridge *ib = to_ingenic_drm_bridge(bridge->encoder);
 
-   if (info->num_bus_formats != 1)
-   return -EINVAL;
+   ib->bus_cfg = bridge_state->output_bus_cfg;
 
if (conn_state->connector->connector_type == DRM_MODE_CONNECTOR_TV)
return 0;
 
-   switch (*info->bus_formats) {
+   switch (bridge_state->output_bus_cfg.format) {
case MEDIA_BUS_FMT_RGB888_3X8:
case MEDIA_BUS_FMT_RGB888_3X8_DELTA:

Re: gpu: drm_fb_cma_helper.c:46: undefined reference to `drm_gem_fb_get_obj'

2021-10-26 Thread Thomas Zimmermann

Hi

Am 25.10.21 um 14:13 schrieb Naresh Kamboju:

Regression found on arm gcc-11 built with multi_v5_defconfig
Following build warnings / errors reported on linux next 20211025.

metadata:
 git_describe: next-20211025
 git_repo: https://gitlab.com/Linaro/lkft/mirrors/next/linux-next
 git_short_log: 9ae1fbdeabd3 (\"Add linux-next specific files for 
20211025\")
 target_arch: arm
 toolchain: gcc-11
 config: multi_v5_defconfig

build error :
--
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: in
function `drm_fb_cma_get_gem_obj':
drivers/gpu/drm/drm_fb_cma_helper.c:46: undefined reference to
`drm_gem_fb_get_obj'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46:
undefined reference to `drm_gem_fb_get_obj'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46:
undefined reference to `drm_gem_fb_get_obj'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: in
function `drm_fb_cma_sync_non_coherent':
drivers/gpu/drm/drm_fb_cma_helper.c:133: undefined reference to
`drm_atomic_helper_damage_iter_init'
arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:135:
undefined reference to `drm_atomic_helper_damage_iter_next'
make[1]: *** [Makefile:1252: vmlinux] Error 1
make[1]: Target '__all' not remade because of errors.
make: *** [Makefile:226: __sub-make] Error 2

Reported-by: Linux Kernel Functional Testing 


build link:
---
https://builds.tuxbuild.com/1zzgFZBGjpQ5R0lawQFW9iJ39Hp/build.log

build config:
-
https://builds.tuxbuild.com/1zzgFZBGjpQ5R0lawQFW9iJ39Hp/config


Looking at this config, there is:

CONFIG_DRM=y
# CONFIG_DRM_DP_AUX_CHARDEV is not set
# CONFIG_DRM_DEBUG_MM is not set
# CONFIG_DRM_DEBUG_SELFTEST is not set
CONFIG_DRM_KMS_HELPER=m
# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
# CONFIG_DRM_DP_CEC is not set
CONFIG_DRM_GEM_CMA_HELPER=y
CONFIG_DRM_KMS_CMA_HELPER=y

GEM_CMA_HELPER depends on KMS_HELPER, but the latter is a module. That's 
probably the cause of the problem. Is it intentionally set this way?


Best regards
Thomas



# To install tuxmake on your system globally
# sudo pip3 install -U tuxmake
tuxmake --runtime podman --target-arch arm --toolchain gcc-11
--kconfig multi_v5_defconfig

--
Linaro LKFT
https://lkft.linaro.org



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] drm: Link CMA framebuffer helpers into KMS helper library

2021-10-26 Thread Sam Ravnborg
Hi Thomas,

On Tue, Oct 26, 2021 at 07:57:00PM +0200, Thomas Zimmermann wrote:
> Linking the CMA frambuffer helpers into a CMA helper library in
> commit 4b2b5e142ff4 ("drm: Move GEM memory managers into modules")
> results in linker errors:
> 
>   arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: \
> in function `drm_fb_cma_get_gem_obj': \
> drivers/gpu/drm/drm_fb_cma_helper.c:46: undefined reference \
> to `drm_gem_fb_get_obj'
>   arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46: \
> undefined reference to `drm_gem_fb_get_obj'
>   arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:46: \
> undefined reference to `drm_gem_fb_get_obj'
>   arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.o: in \
> function `drm_fb_cma_sync_non_coherent': \
> drivers/gpu/drm/drm_fb_cma_helper.c:133: undefined reference \
> to `drm_atomic_helper_damage_iter_init'
>   arm-linux-gnueabihf-ld: drivers/gpu/drm/drm_fb_cma_helper.c:135: \
> undefined reference to `drm_atomic_helper_damage_iter_next'
> 
> Link the CMA framebuffer helpers into the KMS helper library to
> fix the problem.
> 
> Signed-off-by: Thomas Zimmermann 
> Fixes: 4b2b5e142ff4 ("drm: Move GEM memory managers into modules")
> Reported-by: Naresh Kamboju 
> Reported-by: Linux Kernel Functional Testing 
> Cc: Daniel Vetter 
> Cc: Maarten Lankhorst 
> Cc: Maxime Ripard 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: dri-devel@lists.freedesktop.org

Patch looks fine,
Reviewed-by: Sam Ravnborg 

Sam


Re: [RESEND PATCH v3 0/6] drm/ingenic: Various improvements v3

2021-10-26 Thread H. Nikolaus Schaller
Hi Paul,

> Am 26.10.2021 um 20:12 schrieb Paul Cercueil :
> 
> Hi,
> 
> I resend the V3 of my patchset for drm/ingenic, verbatim.
> 
> The previous submission of my V3 received a lot of replies, but none of
> these replies were actually talking about the patches themselves.

Indeed. And since we have finally managed to add jz4780 HDMI support
(I didn't find to work in the latest comments) on top of the series as is,
please go ahead and add my

tested-by: Nikolaus Schaller 

BR and thanks,
Nikolaus

> 
> Cheers,
> -Paul
> 
> 
> Paul Cercueil (6):
>  drm/ingenic: Simplify code by using hwdescs array
>  drm/ingenic: Add support for private objects
>  drm/ingenic: Move IPU scale settings to private state
>  drm/ingenic: Set DMA descriptor chain register when starting CRTC
>  drm/ingenic: Upload palette before frame
>  drm/ingenic: Attach bridge chain to encoders
> 
> drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 278 +-
> drivers/gpu/drm/ingenic/ingenic-ipu.c | 127 --
> 2 files changed, 333 insertions(+), 72 deletions(-)
> 
> -- 
> 2.33.0
> 



Re: [PATCH v2 1/2] drm/msm/dp: Add support for SC7280 eDP

2021-10-26 Thread sbillaka

Hi Stephen,

On 2021-10-21 23:32, Stephen Boyd wrote:

Quoting Sankeerth Billakanti (2021-10-20 05:14:10)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c 
b/drivers/gpu/drm/msm/dp/dp_ctrl.c

index 62e75dc..9fea49c 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1238,9 +1240,21 @@ static int dp_ctrl_link_train(struct 
dp_ctrl_private *ctrl,

link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING;

dp_aux_link_configure(ctrl->aux, &link_info);
+
+   if (dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5) {


Please add a static inline macro in include/drm/drm_dp_helper.h that
makes this more readable. Something similar to drm_dp_is_branch() but
with a human readable replacement for "is_branch". Maybe drm_dp_ssc()?

Okay, I will add a macro, drm_dp_max_downspread (to be consistent with 
the spec and other macros in the file) in drm_dp_helper.h file.



+   ssc = DP_SPREAD_AMP_0_5;
+   drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 
1);

+   }
+
drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
&encoding, 1);

+   if (dpcd[DP_EDP_CONFIGURATION_CAP] & 
DP_ALTERNATE_SCRAMBLER_RESET_CAP) {


And this one already has a helper,
drm_dp_alternate_scrambler_reset_cap().


Okay, I will use that.


+   assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
+   drm_dp_dpcd_write(ctrl->aux, DP_EDP_CONFIGURATION_SET,
+   &assr, 1);
+   }
+
ret = dp_ctrl_link_train_1(ctrl, training_step);
if (ret) {
DRM_ERROR("link training #1 failed. ret=%d\n", ret);
@@ -1312,9 +1326,11 @@ static int 
dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl)

struct dp_io *dp_io = &ctrl->parser->io;
struct phy *phy = dp_io->phy;
struct phy_configure_opts_dp *opts_dp = &dp_io->phy_opts.dp;
+   const u8 *dpcd = ctrl->panel->dpcd;

opts_dp->lanes = ctrl->link->link_params.num_lanes;
opts_dp->link_rate = ctrl->link->link_params.rate / 100;
+   opts_dp->ssc = dpcd[DP_MAX_DOWNSPREAD] & 
DP_MAX_DOWNSPREAD_0_5;

dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
ctrl->link->link_params.rate * 
1000);


@@ -1406,7 +1422,7 @@ void dp_ctrl_host_deinit(struct dp_ctrl 
*dp_ctrl)


 static bool dp_ctrl_use_fixed_nvid(struct dp_ctrl_private *ctrl)
 {
-   u8 *dpcd = ctrl->panel->dpcd;
+   const u8 *dpcd = ctrl->panel->dpcd;

/*
 * For better interop experience, used a fixed NVID=0x8000
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c

index c867745..c16311b 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -144,8 +144,16 @@ static const struct msm_dp_config sc8180x_dp_cfg 
= {

.num_descs = 3,
 };

+static const struct msm_dp_config sc7280_dp_cfg = {
+   .descs = (struct msm_dp_desc[]) {


const


Will add it.

+   { .io_start = 0x0aea, .connector_type = 
DRM_MODE_CONNECTOR_eDP },

+   },
+   .num_descs = 1,
+};
+
 static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg },
+   { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_cfg },
{ .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg },
{ .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg },
{}
@@ -1440,7 +1448,7 @@ void msm_dp_irq_postinstall(struct msm_dp 
*dp_display)


dp_hpd_event_setup(dp);

-   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
+   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 1);


This has no explanation. What is it?

Will add explanation for it as a comment.


Re: [PATCH v2 2/2] drm/bridge: parade-ps8640: Populate devices on aux-bus

2021-10-26 Thread Philip Chen
Hi,

On Mon, Oct 25, 2021 at 1:10 PM Stephen Boyd  wrote:
>
> Quoting Philip Chen (2021-10-21 14:06:00)
> > diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
> > b/drivers/gpu/drm/bridge/parade-ps8640.c
> > index 220ca3b03d24..f99a2e0808b7 100644
> > --- a/drivers/gpu/drm/bridge/parade-ps8640.c
> > +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
> > @@ -149,6 +150,23 @@ static inline struct ps8640 *aux_to_ps8640(struct 
> > drm_dp_aux *aux)
> > return container_of(aux, struct ps8640, aux);
> >  }
> >
> > +static bool ps8640_of_panel_on_aux_bus(struct device *dev)
> > +{
> > +   struct device_node *bus, *panel;
> > +
> > +   bus = of_get_child_by_name(dev->of_node, "aux-bus");
> > +   if (!bus)
> > +   return false;
> > +   of_node_put(bus);
>
> This should come after the next line...
>
> > +
> > +   panel = of_get_child_by_name(bus, "panel");
>
> here, so that 'bus' can't go away before getting children nodes. It
> doesn't actually matter in this case because 'device' holds the aux-bus,
> but we shouldn't add anti-patterns to the code lest someone copies it
> where it actually matters.
Thanks for pointing it out.
I will fix it in v3.

>
> > +   if (!panel)
> > +   return false;
> > +   of_node_put(panel);
> > +
> > +   return true;
> > +}
> > +
> >  static void ps8640_ensure_hpd(struct ps8640 *ps_bridge)
> >  {
> > struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
>
> Otherwise
>
> Reviewed-by: Stephen Boyd 


Re: [PATCH v2] drm: panel-orientation-quirks: Add quirk for GPD Win3

2021-10-26 Thread Sam Ravnborg
Hi Mario,

On Tue, Oct 26, 2021 at 01:27:37PM +0200, Mario wrote:
> Fixes screen orientation for GPD Win 3 handheld gaming console.
> 
> Signed-off-by: Mario Risoldi 

Thanks for the resend.
A couple of points for your, hopefully soonish, next contribution:

1) Use the same name/email in the Signed-off-by and a sender mail.
As an alternative add an From: Mario Risoldi  in the
top of the changelog. Otherwise there is a warning about the mismatch.

2) When you make a v2 it is always a good service to the readers to tell
what was changed.
In this case you could have added the following:
"
v2:
  - Added changelog and s-o-b (Sam)
"

It is perfectly fine in the DRM subsystem to have this part of the
changelog. Other subsystmes do not want to see it in the changelog so
there it must go below the end-of-changelog marker - the "---"

Patch is applied to drm-misc-next and will hopefully find its way to
upstream within 1-2 weeks.
So for this patch you do not need to do more.

Sam

> ---
>  drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c 
> b/drivers/gpu/drm/drm_panel_orientation_quirks.c
> index f6bdec7fa925..f6177c1d9872 100644
> --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
> +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
> @@ -185,6 +185,12 @@ static const struct dmi_system_id orientation_data[] = {
> DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
>   },
>   .driver_data = (void *)&gpd_win2,
> + }, {/* GPD Win 3 */
> + .matches = {
> +   DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
> +   DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03")
> + },
> + .driver_data = (void *)&lcd720x1280_rightside_up,
>   }, {/* I.T.Works TW891 */
>   .matches = {
> DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
> -- 
> 2.33.1


[PATCH v3 1/2] drm/bridge: parade-ps8640: Enable runtime power management

2021-10-26 Thread Philip Chen
Fit ps8640 driver into runtime power management framework:

First, break _poweron() to 3 parts: (1) turn on power and wait for
ps8640's internal MCU to finish init (2) check panel HPD (which is
proxied by GPIO9) (3) the other configs. As runtime_resume() can be
called before panel is powered, we only add (1) to _resume() and leave
(2)(3) to _pre_enable(). We also add (2) to _aux_transfer() as we want
to ensure panel HPD is asserted before we start AUX CH transactions.

Second, the original driver has a mysterious delay of 50 ms between (2)
and (3). Since Parade's support can't explain what the delay is for,
and we don't see removing the delay break any boards at hand, remove
the delay to fit into this driver change.

In addition, rename "powered" to "pre_enabled" and don't check for it
in the pm_runtime calls. The pm_runtime calls are already refcounted
so there's no reason to check there. The other user of "powered",
_get_edid(), only cares if pre_enable() has already been called.

Lastly, change some existing DRM_...() logging to dev_...() along the
way, since DRM_...() seem to be deprecated in [1].

[1] https://patchwork.freedesktop.org/patch/454760/

Signed-off-by: Philip Chen 
Reviewed-by: Douglas Anderson 
---

Changes in v3:
- Fix typo/wording in the commit message.
- Add ps8640_aux_transfer_msg() for AUX operation. In
  ps8640_aux_transfer(), wrap around ps8640_aux_transfer_msg()
  with PM operations and HPD check.
- Document why autosuspend_delay is set to 500ms.

 drivers/gpu/drm/bridge/parade-ps8640.c | 186 +++--
 1 file changed, 115 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 3aaa90913bf8..ac42a3473770 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -100,7 +101,7 @@ struct ps8640 {
struct regulator_bulk_data supplies[2];
struct gpio_desc *gpio_reset;
struct gpio_desc *gpio_powerdown;
-   bool powered;
+   bool pre_enabled;
 };
 
 static const struct regmap_config ps8640_regmap_config[] = {
@@ -148,8 +149,29 @@ static inline struct ps8640 *aux_to_ps8640(struct 
drm_dp_aux *aux)
return container_of(aux, struct ps8640, aux);
 }
 
-static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
-  struct drm_dp_aux_msg *msg)
+static void ps8640_ensure_hpd(struct ps8640 *ps_bridge)
+{
+   struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
+   struct device *dev = &ps_bridge->page[PAGE2_TOP_CNTL]->dev;
+   int status;
+   int ret;
+
+   /*
+* Apparently something about the firmware in the chip signals that
+* HPD goes high by reporting GPIO9 as high (even though HPD isn't
+* actually connected to GPIO9).
+*/
+   ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+   status & PS_GPIO9, 20 * 1000, 200 * 1000);
+
+   if (ret < 0)
+   dev_warn(dev, "HPD didn't go high: %d\n", ret);
+
+   return ret;
+}
+
+static ssize_t ps8640_aux_transfer_msg(struct drm_dp_aux *aux,
+  struct drm_dp_aux_msg *msg)
 {
struct ps8640 *ps_bridge = aux_to_ps8640(aux);
struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL];
@@ -274,38 +296,49 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
return len;
 }
 
-static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge,
-const enum ps8640_vdo_control ctrl)
+static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
+  struct drm_dp_aux_msg *msg)
+{
+   struct ps8640 *ps_bridge = aux_to_ps8640(aux);
+   struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev;
+   int ret;
+
+   pm_runtime_get_sync(dev);
+   ret = ps8640_ensure_hpd(ps_bridge);
+   if (!ret)
+   ret = ps8640_aux_transfer_msg(aux, msg);
+   pm_runtime_mark_last_busy(dev);
+   pm_runtime_put_autosuspend(dev);
+
+   return ret;
+}
+
+static void ps8640_bridge_vdo_control(struct ps8640 *ps_bridge,
+ const enum ps8640_vdo_control ctrl)
 {
struct regmap *map = ps_bridge->regmap[PAGE3_DSI_CNTL1];
+   struct device *dev = &ps_bridge->page[PAGE3_DSI_CNTL1]->dev;
u8 vdo_ctrl_buf[] = { VDO_CTL_ADD, ctrl };
int ret;
 
ret = regmap_bulk_write(map, PAGE3_SET_ADD,
vdo_ctrl_buf, sizeof(vdo_ctrl_buf));
 
-   if (ret < 0) {
-   DRM_ERROR("failed to %sable VDO: %d\n",
- ctrl == ENABLE ? "en" : "dis", ret);
-   return ret;
-   }
-
-   return 0;
+   if (ret < 0)
+   dev_err(dev, "failed to %sable VDO: %d\n",
+   ctrl == ENABLE ? "en

[PATCH v3 2/2] drm/bridge: parade-ps8640: Populate devices on aux-bus

2021-10-26 Thread Philip Chen
Conventionally, panel is listed under the root of the device tree.
When userland asks for display mode, ps8640 bridge is responsible
for returning EDID when ps8640_bridge_get_edid() is called.

Now enable a new option of listing panel under "aux-bus" of ps8640
bridge node in the device tree. In this case, panel driver can retrieve
EDID by triggering AUX transactions, without ps8640_bridge_get_edid()
calls at all.

To prevent the "old" and "new" options from interfering with each
other's logic flow, disable DRM_BRIDGE_OP_EDID when the new option
is taken.

Signed-off-by: Philip Chen 
Reviewed-by: Stephen Boyd 
---

Changes in v3:
- Fix when to call of_node_put() in ps8640_of_panel_on_aux_bus()

Changes in v2:
- Add of_node_put() calls in ps8640_of_panel_on_aux_bus()
- Select DRM_DP_AUX_BUS for PS8640 driver in Kconfig
- Replace _put_sync() with _put_sync_suspend() in ps8640_post_disable()

 drivers/gpu/drm/bridge/Kconfig |  1 +
 drivers/gpu/drm/bridge/parade-ps8640.c | 53 +++---
 2 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 431b6e12a81f..61db5a66b493 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -182,6 +182,7 @@ config DRM_PARADE_PS8622
 config DRM_PARADE_PS8640
tristate "Parade PS8640 MIPI DSI to eDP Converter"
depends on OF
+   select DRM_DP_AUX_BUS
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index ac42a3473770..e737f1a27f30 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -14,6 +14,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -149,7 +150,24 @@ static inline struct ps8640 *aux_to_ps8640(struct 
drm_dp_aux *aux)
return container_of(aux, struct ps8640, aux);
 }
 
-static void ps8640_ensure_hpd(struct ps8640 *ps_bridge)
+static bool ps8640_of_panel_on_aux_bus(struct device *dev)
+{
+   struct device_node *bus, *panel;
+
+   bus = of_get_child_by_name(dev->of_node, "aux-bus");
+   if (!bus)
+   return false;
+
+   panel = of_get_child_by_name(bus, "panel");
+   of_node_put(bus);
+   if (!panel)
+   return false;
+   of_node_put(panel);
+
+   return true;
+}
+
+static int ps8640_ensure_hpd(struct ps8640 *ps_bridge)
 {
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
struct device *dev = &ps_bridge->page[PAGE2_TOP_CNTL]->dev;
@@ -556,17 +574,6 @@ static int ps8640_probe(struct i2c_client *client)
if (!ps_bridge)
return -ENOMEM;
 
-   /* port@1 is ps8640 output port */
-   ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL);
-   if (ret < 0)
-   return ret;
-   if (!panel)
-   return -ENODEV;
-
-   ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
-   if (IS_ERR(ps_bridge->panel_bridge))
-   return PTR_ERR(ps_bridge->panel_bridge);
-
ps_bridge->supplies[0].supply = "vdd33";
ps_bridge->supplies[1].supply = "vdd12";
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
@@ -589,9 +596,16 @@ static int ps8640_probe(struct i2c_client *client)
 
ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
ps_bridge->bridge.of_node = dev->of_node;
-   ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
 
+   /*
+* In the device tree, if panel is listed under aux-bus of the bridge
+* node, panel driver should be able to retrieve EDID by itself using
+* aux-bus. So let's not set DRM_BRIDGE_OP_EDID here.
+*/
+   if (!ps8640_of_panel_on_aux_bus(&client->dev))
+   ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
+
ps_bridge->page[PAGE0_DP_CNTL] = client;
 
ps_bridge->regmap[PAGE0_DP_CNTL] = devm_regmap_init_i2c(client, 
ps8640_regmap_config);
@@ -630,6 +644,19 @@ static int ps8640_probe(struct i2c_client *client)
if (ret)
return ret;
 
+   devm_of_dp_aux_populate_ep_devices(&ps_bridge->aux);
+
+   /* port@1 is ps8640 output port */
+   ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL);
+   if (ret < 0)
+   return ret;
+   if (!panel)
+   return -ENODEV;
+
+   ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
+   if (IS_ERR(ps_bridge->panel_bridge))
+   return PTR_ERR(ps_bridge->panel_bridge);
+
drm_bridge_add(&ps_bridge->bridge);
 
return 0;
-- 
2.33.0.1079.g6e70778dc9-goog



Re: [RESEND PATCH v3 0/6] drm/ingenic: Various improvements v3

2021-10-26 Thread Sam Ravnborg
Hi Nikolaus,
On Tue, Oct 26, 2021 at 08:50:19PM +0200, H. Nikolaus Schaller wrote:
> Hi Paul,
> 
> > Am 26.10.2021 um 20:12 schrieb Paul Cercueil :
> > 
> > Hi,
> > 
> > I resend the V3 of my patchset for drm/ingenic, verbatim.
> > 
> > The previous submission of my V3 received a lot of replies, but none of
> > these replies were actually talking about the patches themselves.
> 
> Indeed. And since we have finally managed to add jz4780 HDMI support
> (I didn't find to work in the latest comments) on top of the series as is,
> please go ahead and add my
> 
> tested-by: Nikolaus Schaller 
Capital T, but I expect Paul to fix it.

If you have read the patches it would be good if you could add an
Acked-by: or Reviewed-by: tag on the individual patches.
Paul are not supposed to apply the patches until someone claims they have
looked at the patches, documented by one of these tags.

And I have no head to do so myself today.

Sam


Re: [PATCH v2 1/2] drm/bridge: parade-ps8640: Enable runtime power management

2021-10-26 Thread Philip Chen
Hi

On Mon, Oct 25, 2021 at 1:05 PM Stephen Boyd  wrote:
>
> Quoting Philip Chen (2021-10-21 14:05:59)
> > Fit ps8640 driver into runtime power management framework:
> >
> > First, break _poweron() to 3 parts: (1) turn on power and wait for
> > ps8640's internal MCU to finish init (2) check panel HPD (which is
> > proxied by GPIO9) (3) the other configs. As runtime_resume() can be
> > called before panel is powered, we only add (1) to _resume() and leave
> > (2)(3) to _pre_enable(). We also add (2) to _aux_transfer() as we want
> > to ensure panel HPD is asserted before we start AUX CH transactions.
> >
> > The original driver has a mysterious delay of 50 ms between (2) and
> > (3). Since Parade's support can't explain what the delay is for, and we
> > don't see removing the delay break any boards at hand, remove the dalay
>
> s/dalay/delay/
Thanks.
I've fixed it in v3.
>
> > to fit into this driver change.
> >
> > Besides, rename "powered" to "pre_enabled" and don't check for it in
>
> "Besides" doesn't make sense here. Probably "In addition" or "Also"?
Thanks.
I've fixed it in v3.
>
> > the pm_runtime calls. The pm_runtime calls are already refcounted so
> > there's no reason to check there. The other user of "powered",
> > _get_edid(), only cares if pre_enable() has already been called.
> >
> > Lastly, change some existing DRM_...() logging to dev_...() along the
> > way, since DRM_...() seem to be deprecated in [1].
> >
> > [1] https://patchwork.freedesktop.org/patch/454760/
> >
> > Signed-off-by: Philip Chen 
> > Reviewed-by: Douglas Anderson 
> > ---
> > diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
> > b/drivers/gpu/drm/bridge/parade-ps8640.c
> > index 3aaa90913bf8..220ca3b03d24 100644
> > --- a/drivers/gpu/drm/bridge/parade-ps8640.c
> > +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
> > @@ -148,6 +149,25 @@ static inline struct ps8640 *aux_to_ps8640(struct 
> > drm_dp_aux *aux)
> > return container_of(aux, struct ps8640, aux);
> >  }
> >
> > +static void ps8640_ensure_hpd(struct ps8640 *ps_bridge)
> > +{
> > +   struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
> > +   struct device *dev = &ps_bridge->page[PAGE2_TOP_CNTL]->dev;
> > +   int status;
> > +   int ret;
> > +
> > +   /*
> > +* Apparently something about the firmware in the chip signals that
> > +* HPD goes high by reporting GPIO9 as high (even though HPD isn't
> > +* actually connected to GPIO9).
> > +*/
> > +   ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
> > +   status & PS_GPIO9, 20 * 1000, 200 * 1000);
> > +
> > +   if (ret < 0)
> > +   dev_warn(dev, "HPD didn't go high: %d", ret);
>
> Missing newline on the print message.
Thanks.
I've fixed it in v3.
>
> > +}
> > +
> >  static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
> >struct drm_dp_aux_msg *msg)
> >  {
> > @@ -171,6 +191,9 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux 
> > *aux,
> > if (msg->address & ~SWAUX_ADDR_MASK)
> > return -EINVAL;
> >
> > +   pm_runtime_get_sync(dev);
> > +   ps8640_ensure_hpd(ps_bridge);
>
> Shouldn't we bail out of here with an error if we can't ensure hpd?
Sounds about right.
I fixed this in v3.
PTAL.
>
> > +
> > switch (request) {
> > case DP_AUX_NATIVE_WRITE:
> > case DP_AUX_NATIVE_READ:
> > @@ -180,14 +203,15 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux 
> > *aux,
> > case DP_AUX_I2C_READ:
> > break;
> > default:
> > -   return -EINVAL;
> > +   ret = -EINVAL;
> > +   goto exit;
> > }
> >
> > ret = regmap_write(map, PAGE0_AUXCH_CFG3, AUXCH_CFG3_RESET);
> > if (ret) {
> > DRM_DEV_ERROR(dev, "failed to write PAGE0_AUXCH_CFG3: %d\n",
> >   ret);
> > -   return ret;
> > +   goto exit;
> > }
> >
> > /* Assume it's good */
> > @@ -213,7 +237,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux 
> > *aux,
> > DRM_DEV_ERROR(dev,
> >   "failed to write WDATA: %d\n",
> >   ret);
> > -   return ret;
> > +   goto exit;
> > }
> > }
> > }
> > @@ -228,7 +252,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux 
> > *aux,
> > if (ret) {
> > DRM_DEV_ERROR(dev, "failed to read PAGE0_SWAUX_STATUS: 
> > %d\n",
> >   ret);
> > -   return ret;
> > +   goto exit;
> > }
> >
> > switch (data & SWAUX_STATUS_MASK) {
> > @@ -250,9 +274,11 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux 
> > *aux,
> > len = data 

[PATCH v3 1/3] drm: Rename lut check functions to lut channel checks

2021-10-26 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
This function and enum do not do generic checking on the luts but they
test color channels in the LUTs.
Keeping the name explicit as more generic LUT checks will follow.

Tested on Eldrid ChromeOS (TGL).

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_color_mgmt.c   | 12 ++--
 drivers/gpu/drm/i915/display/intel_color.c | 10 +-
 include/drm/drm_color_mgmt.h   |  7 ---
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index bb14f488c8f6c..6f4e04746d90f 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -585,17 +585,17 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
 EXPORT_SYMBOL(drm_plane_create_color_properties);
 
 /**
- * drm_color_lut_check - check validity of lookup table
+ * drm_color_lut_channels_check - check validity of the channels in the lookup 
table
  * @lut: property blob containing LUT to check
  * @tests: bitmask of tests to run
  *
- * Helper to check whether a userspace-provided lookup table is valid and
- * satisfies hardware requirements.  Drivers pass a bitmask indicating which of
- * the tests in &drm_color_lut_tests should be performed.
+ * Helper to check whether each color channel of userspace-provided lookup 
table is valid and
+ * satisfies hardware requirements. Drivers pass a bitmask indicating which of 
in
+ * &drm_color_lut_channels_tests should be performed.
  *
  * Returns 0 on success, -EINVAL on failure.
  */
-int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
+int drm_color_lut_channels_check(const struct drm_property_blob *lut, u32 
tests)
 {
const struct drm_color_lut *entry;
int i;
@@ -625,4 +625,4 @@ int drm_color_lut_check(const struct drm_property_blob 
*lut, u32 tests)
 
return 0;
 }
-EXPORT_SYMBOL(drm_color_lut_check);
+EXPORT_SYMBOL(drm_color_lut_channels_check);
diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
b/drivers/gpu/drm/i915/display/intel_color.c
index dab892d2251ba..4bb1bc76c4de9 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -1285,7 +1285,7 @@ static int check_luts(const struct intel_crtc_state 
*crtc_state)
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
const struct drm_property_blob *degamma_lut = 
crtc_state->hw.degamma_lut;
int gamma_length, degamma_length;
-   u32 gamma_tests, degamma_tests;
+   u32 gamma_channels_tests, degamma_channels_tests;
 
/* Always allow legacy gamma LUT with no further checking. */
if (crtc_state_is_legacy_gamma(crtc_state))
@@ -1300,15 +1300,15 @@ static int check_luts(const struct intel_crtc_state 
*crtc_state)
 
degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
-   degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
-   gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
+   degamma_channels_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
+   gamma_channels_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
 
if (check_lut_size(degamma_lut, degamma_length) ||
check_lut_size(gamma_lut, gamma_length))
return -EINVAL;
 
-   if (drm_color_lut_check(degamma_lut, degamma_tests) ||
-   drm_color_lut_check(gamma_lut, gamma_tests))
+   if (drm_color_lut_channels_check(degamma_lut, degamma_channels_tests) ||
+   drm_color_lut_channels_check(gamma_lut, gamma_channels_tests))
return -EINVAL;
 
return 0;
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 81c298488b0c8..cb1bf361ad3e3 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -94,12 +94,12 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
  enum drm_color_range default_range);
 
 /**
- * enum drm_color_lut_tests - hw-specific LUT tests to perform
+ * enum drm_color_lut_channels_tests - hw-specific LUT tests to perform
  *
  * The drm_color_lut_check() function takes a bitmask of the values here to
  * determine which tests to apply to a userspace-provided LUT.
  */
-enum drm_color_lut_tests {
+enum drm_color_lut_channels_tests {
/**
 * @DRM_COLOR_LUT_EQUAL_CHANNELS:
 *
@@ -119,5 +119,6 @@ enum drm_color_lut_tests {
DRM_COLOR_LUT_NON_DECREASING = BIT(1),
 };
 
-int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests);
+int drm_color_lut_channels_check(const struct drm_property_blob *lut,
+u32 tests);
 #endif
-- 
2.33.0.1079.g6e70778dc9-goog



[PATCH v3 2/3] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-26 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
or Degamma props in the new CRTC state, allowing any invalid size to
be passed on.
2. Each driver has its own LUT size, which could also be different for
legacy users.

[How]
1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
assigned by the driver when it's initializing its color and CTM
management.
2. Create drm_atomic_helper_check_crtc which is called by
drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
they match the sizes in the new CRTC state.
3. As the LUT size check now happens in drm_atomic_helper_check, remove
the lut check in intel_color.c

Resolves: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)

v2:
1. Remove the rename to a parent commit.
2. Create a drm drm_check_lut_size instead of intel only function.

v1:
1. Fix typos
2. Remove the LUT size check from intel driver
3. Rename old LUT check to indicate it's a channel change

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_atomic_helper.c| 56 ++
 drivers/gpu/drm/drm_color_mgmt.c   |  2 +
 drivers/gpu/drm/i915/display/intel_color.c | 39 ---
 include/drm/drm_atomic_helper.h|  1 +
 include/drm/drm_color_mgmt.h   | 13 +
 include/drm/drm_crtc.h | 11 +
 6 files changed, 102 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5e..c565b3516cce9 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -929,6 +929,58 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_check_planes);
 
+/**
+ * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
+ * @state: the driver state object
+ *
+ * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new
+ * state holds them.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->gamma_lut) {
+   if (drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_lut_size) ||
+   drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Gamma LUT size. Should be %u 
(or %u for legacy) but got %u.\n",
+   crtc->gamma_lut_size, crtc->gamma_size,
+   drm_color_lut_size(
+   new_crtc_state->gamma_lut));
+   return -EINVAL;
+   }
+   }
+
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->degamma_lut) {
+   if (drm_check_lut_size(new_crtc_state->degamma_lut,
+  crtc->degamma_lut_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid DeGamma LUT size. Should be %u 
but got %u.\n",
+   crtc->degamma_lut_size,
+   drm_color_lut_size(
+   new_crtc_state->degamma_lut));
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_crtcs);
+
 /**
  * drm_atomic_helper_check - validate state object
  * @dev: DRM device
@@ -974,6 +1026,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
 
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
if (state->legacy_cursor_update)
state->async_update = !drm_atomic_helper_async_check(dev, 
state);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 6f4e04746d90f..6bb59645a75bc 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -166,6 +166,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
struct drm_mode_config *config = &dev->mode_config;
 
if (degamma_lut_size) {
+   crtc->degamma_lut_size = degamma_lut_size;
drm_object_attach_property(&crtc->

[PATCH v3 3/3] amd/amdgpu_dm: Verify Gamma and Degamma LUT sizes using DRM Core check

2021-10-26 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
drm_atomic_helper_check_crtc now verifies both legacy and non-legacy LUT
sizes. There is no need to check it within amdgpu_dm_atomic_check.

[How]
Remove the local call to verify LUT sizes and use DRM Core function
instead.

Tested on ChromeOS Zork.

v1:
Remove amdgpu_dm_verify_lut_sizes everywhere.

Signed-off-by: Mark Yacoub 
Reviewed-by: Sean Paul 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  8 ++---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 -
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 35 ---
 3 files changed, 4 insertions(+), 40 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 f74663b6b046e..47f8de1cfc3a5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10244,6 +10244,10 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
}
}
 #endif
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 
@@ -10253,10 +10257,6 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
dm_old_crtc_state->dsc_force_changed == false)
continue;
 
-   ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
-   if (ret)
-   goto fail;
-
if (!new_crtc_state->enable)
continue;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index fcb9c4a629c32..22730e5542092 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -617,7 +617,6 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
 
 void amdgpu_dm_init_color_mod(void);
-int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
  struct dc_plane_state *dc_plane_state);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a022e5bb30a5c..319f8a8a89835 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -284,37 +284,6 @@ static int __set_input_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
-/**
- * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of
- * the expected size.
- * Returns 0 on success.
- */
-int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
-{
-   const struct drm_color_lut *lut = NULL;
-   uint32_t size = 0;
-
-   lut = __extract_blob_lut(crtc_state->degamma_lut, &size);
-   if (lut && size != MAX_COLOR_LUT_ENTRIES) {
-   DRM_DEBUG_DRIVER(
-   "Invalid Degamma LUT size. Should be %u but got %u.\n",
-   MAX_COLOR_LUT_ENTRIES, size);
-   return -EINVAL;
-   }
-
-   lut = __extract_blob_lut(crtc_state->gamma_lut, &size);
-   if (lut && size != MAX_COLOR_LUT_ENTRIES &&
-   size != MAX_COLOR_LEGACY_LUT_ENTRIES) {
-   DRM_DEBUG_DRIVER(
-   "Invalid Gamma LUT size. Should be %u (or %u for 
legacy) but got %u.\n",
-   MAX_COLOR_LUT_ENTRIES, MAX_COLOR_LEGACY_LUT_ENTRIES,
-   size);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 /**
  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
  * @crtc: amdgpu_dm crtc state
@@ -348,10 +317,6 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
bool is_legacy;
int r;
 
-   r = amdgpu_dm_verify_lut_sizes(&crtc->base);
-   if (r)
-   return r;
-
degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_size);
regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, ®amma_size);
 
-- 
2.33.0.1079.g6e70778dc9-goog



  1   2   >