[PATCH v2] drm/amdkfd: use time_is_before_jiffies(a + b) to replace "jiffies - a > b"

2022-07-27 Thread Yu Zhe
time_is_before_jiffies deals with timer wrapping correctly.

Signed-off-by: Yu Zhe 
---
 drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index a9466d154395..34772fe74296 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -146,7 +146,7 @@ static void interrupt_wq(struct work_struct *work)
struct kfd_dev *dev = container_of(work, struct kfd_dev,
interrupt_work);
uint32_t ih_ring_entry[KFD_MAX_RING_ENTRY_SIZE];
-   long start_jiffies = jiffies;
+   unsigned long start_jiffies = jiffies;
 
if (dev->device_info.ih_ring_entry_size > sizeof(ih_ring_entry)) {
dev_err_once(dev->adev->dev, "Ring entry too small\n");
@@ -156,7 +156,7 @@ static void interrupt_wq(struct work_struct *work)
while (dequeue_ih_ring_entry(dev, ih_ring_entry)) {
dev->device_info.event_interrupt_class->interrupt_wq(dev,
ih_ring_entry);
-   if (jiffies - start_jiffies > HZ) {
+   if (time_is_before_jiffies(start_jiffies + HZ)) {
/* If we spent more than a second processing signals,
 * reschedule the worker to avoid soft-lockup warnings
 */
-- 
2.11.0



Re: [PATCH] dma-buf: Fix one use-after-free of fence

2022-07-27 Thread Alex Deucher
Did this ever land?  I don't see it in drm-misc.

Alex

On Thu, Jul 7, 2022 at 4:05 AM Christian König  wrote:
>
> Am 07.07.22 um 10:02 schrieb xinhui pan:
> > Need get the new fence when we replace the old one.
> >
> > Fixes: 047a1b877ed48 ("dma-buf & drm/amdgpu: remove dma_resv workaround")
> > Signed-off-by: xinhui pan 
>
> Good catch, Reviewed-by: Christian König 
>
> Going to push that in a minute.
>
> Christian.
>
> > ---
> >   drivers/dma-buf/dma-resv.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
> > index 0cce6e4ec946..205acb2c744d 100644
> > --- a/drivers/dma-buf/dma-resv.c
> > +++ b/drivers/dma-buf/dma-resv.c
> > @@ -343,7 +343,7 @@ void dma_resv_replace_fences(struct dma_resv *obj, 
> > uint64_t context,
> >   if (old->context != context)
> >   continue;
> >
> > - dma_resv_list_set(list, i, replacement, usage);
> > + dma_resv_list_set(list, i, dma_fence_get(replacement), usage);
> >   dma_fence_put(old);
> >   }
> >   }
>


Re: [PATCH 5/6] drm/i915/guc: Support larger contexts on newer hardware

2022-07-27 Thread John Harrison

On 7/27/2022 19:42, john.c.harri...@intel.com wrote:

From: Matthew Brost 

The GuC needs a copy of a golden context for implementing watchdog
resets (aka media resets). This context is larger on newer platforms.
So adjust the size being allocated/copied accordingly.

Signed-off-by: Matthew Brost 
Signed-off-by: John Harrison 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 10 +++---
  1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index ba7541f3ca610..74cbe8eaf5318 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -464,7 +464,11 @@ static void fill_engine_enable_masks(struct intel_gt *gt,
  }
  
  #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))

-#define LRC_SKIP_SIZE (LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE)
+#define XEHP_LR_HW_CONTEXT_SIZE (96 * sizeof(u32))
+#define LR_HW_CONTEXT_SZ(i915) (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50) ? \
+   XEHP_LR_HW_CONTEXT_SIZE : \
+   LR_HW_CONTEXT_SIZE)
+#define LRC_SKIP_SIZE(i915) (LRC_PPHWSP_SZ * PAGE_SIZE + 
LR_HW_CONTEXT_SZ(i915))
  static int guc_prep_golden_context(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
@@ -525,7 +529,7 @@ static int guc_prep_golden_context(struct intel_guc *guc)
 * on all engines).
 */
ads_blob_write(guc, ads.eng_state_size[guc_class],
-  real_size - LRC_SKIP_SIZE);
+  real_size - LRC_SKIP_SIZE(gt->i915));
ads_blob_write(guc, ads.golden_context_lrca[guc_class],
   addr_ggtt);
  
@@ -599,7 +603,7 @@ static void guc_init_golden_context(struct intel_guc *guc)

}
  
  		GEM_BUG_ON(ads_blob_read(guc, ads.eng_state_size[guc_class]) !=

-  real_size - LRC_SKIP_SIZE);
+  real_size - LRC_SKIP_SIZE(gt->i915));
GEM_BUG_ON(ads_blob_read(guc, 
ads.golden_context_lrca[guc_class]) != addr_ggtt);
  
  		addr_ggtt += alloc_size;




Re: [PATCH 2/6] drm/i915/guc: Fix issues with live_preempt_cancel

2022-07-27 Thread John Harrison

On 7/27/2022 19:42, john.c.harri...@intel.com wrote:

From: Matthew Brost 

Having semaphores results in different behavior when a dependent request
is cancelled. In the case of semaphores the request could be on the HW
and complete successfully while without the request is held in the
driver and the error from the dependent request is propagated. Fix
live_preempt_cancel to take this behavior into account.

Also update live_preempt_cancel to use new function intel_context_ban
rather than intel_context_set_banned.

Signed-off-by: Matthew Brost 
Signed-off-by: John Harrison 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/selftest_execlists.c | 16 +++-
  1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c 
b/drivers/gpu/drm/i915/gt/selftest_execlists.c
index 02fc97a0ab502..015f8cd3463e2 100644
--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
+++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
@@ -2087,7 +2087,7 @@ static int __cancel_active0(struct live_preempt_cancel 
*arg)
goto out;
}
  
-	intel_context_set_banned(rq->context);

+   intel_context_ban(rq->context, rq);
err = intel_engine_pulse(arg->engine);
if (err)
goto out;
@@ -2146,7 +2146,7 @@ static int __cancel_active1(struct live_preempt_cancel 
*arg)
if (err)
goto out;
  
-	intel_context_set_banned(rq[1]->context);

+   intel_context_ban(rq[1]->context, rq[1]);
err = intel_engine_pulse(arg->engine);
if (err)
goto out;
@@ -2229,7 +2229,7 @@ static int __cancel_queued(struct live_preempt_cancel 
*arg)
if (err)
goto out;
  
-	intel_context_set_banned(rq[2]->context);

+   intel_context_ban(rq[2]->context, rq[2]);
err = intel_engine_pulse(arg->engine);
if (err)
goto out;
@@ -2244,7 +2244,13 @@ static int __cancel_queued(struct live_preempt_cancel 
*arg)
goto out;
}
  
-	if (rq[1]->fence.error != 0) {

+   /*
+* The behavior between having semaphores and not is different. With
+* semaphores the subsequent request is on the hardware and not 
cancelled
+* while without the request is held in the driver and cancelled.
+*/
+   if (intel_engine_has_semaphores(rq[1]->engine) &&
+   rq[1]->fence.error != 0) {
pr_err("Normal inflight1 request did not complete\n");
err = -EINVAL;
goto out;
@@ -2292,7 +2298,7 @@ static int __cancel_hostile(struct live_preempt_cancel 
*arg)
goto out;
}
  
-	intel_context_set_banned(rq->context);

+   intel_context_ban(rq->context, rq);
err = intel_engine_pulse(arg->engine); /* force reset */
if (err)
goto out;




[PATCH 3/6] drm/i915/guc: Add selftest for a hung GuC

2022-07-27 Thread John . C . Harrison
From: Rahul Kumar Singh 

Add a test to check that the hangcheck will recover from a submission
hang in the GuC.

Signed-off-by: Rahul Kumar Singh 
Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |   1 +
 .../drm/i915/gt/uc/selftest_guc_hangcheck.c   | 159 ++
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 0b8c6450fa344..ff205c4125857 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -5177,4 +5177,5 @@ bool intel_guc_virtual_engine_has_heartbeat(const struct 
intel_engine_cs *ve)
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftest_guc.c"
 #include "selftest_guc_multi_lrc.c"
+#include "selftest_guc_hangcheck.c"
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
new file mode 100644
index 0..af913c4b09d37
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright �� 2019 Intel Corporation
+ */
+
+#include "selftests/igt_spinner.h"
+#include "selftests/igt_reset.h"
+#include "selftests/intel_scheduler_helpers.h"
+#include "gt/intel_engine_heartbeat.h"
+#include "gem/selftests/mock_context.h"
+
+#define BEAT_INTERVAL  100
+
+static struct i915_request *nop_request(struct intel_engine_cs *engine)
+{
+   struct i915_request *rq;
+
+   rq = intel_engine_create_kernel_request(engine);
+   if (IS_ERR(rq))
+   return rq;
+
+   i915_request_get(rq);
+   i915_request_add(rq);
+
+   return rq;
+}
+
+static int intel_hang_guc(void *arg)
+{
+   struct intel_gt *gt = arg;
+   int ret = 0;
+   struct i915_gem_context *ctx;
+   struct intel_context *ce;
+   struct igt_spinner spin;
+   struct i915_request *rq;
+   intel_wakeref_t wakeref;
+   struct i915_gpu_error *global = >i915->gpu_error;
+   struct intel_engine_cs *engine;
+   unsigned int reset_count;
+   u32 guc_status;
+   u32 old_beat;
+
+   ctx = kernel_context(gt->i915, NULL);
+   if (IS_ERR(ctx)) {
+   pr_err("Failed get kernel context: %ld\n", PTR_ERR(ctx));
+   return PTR_ERR(ctx);
+   }
+
+   wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+   ce = intel_context_create(gt->engine[BCS0]);
+   if (IS_ERR(ce)) {
+   ret = PTR_ERR(ce);
+   pr_err("Failed to create spinner request: %d\n", ret);
+   goto err;
+   }
+
+   engine = ce->engine;
+   reset_count = i915_reset_count(global);
+
+   old_beat = engine->props.heartbeat_interval_ms;
+   ret = intel_engine_set_heartbeat(engine, BEAT_INTERVAL);
+   if (ret) {
+   pr_err("Failed to boost heatbeat interval: %d\n", ret);
+   goto err;
+   }
+
+   ret = igt_spinner_init(, engine->gt);
+   if (ret) {
+   pr_err("Failed to create spinner: %d\n", ret);
+   goto err;
+   }
+
+   rq = igt_spinner_create_request(, ce, MI_NOOP);
+   intel_context_put(ce);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+   pr_err("Failed to create spinner request: %d\n", ret);
+   goto err_spin;
+   }
+
+   ret = request_add_spin(rq, );
+   if (ret) {
+   i915_request_put(rq);
+   pr_err("Failed to add Spinner request: %d\n", ret);
+   goto err_spin;
+   }
+
+   ret = intel_reset_guc(gt);
+   if (ret) {
+   i915_request_put(rq);
+   pr_err("Failed to reset GuC, ret = %d\n", ret);
+   goto err_spin;
+   }
+
+   guc_status = intel_uncore_read(gt->uncore, GUC_STATUS);
+   if (!(guc_status & GS_MIA_IN_RESET)) {
+   i915_request_put(rq);
+   pr_err("GuC failed to reset: status = 0x%08X\n", guc_status);
+   ret = -EIO;
+   goto err_spin;
+   }
+
+   /* Wait for the heartbeat to cause a reset */
+   ret = intel_selftest_wait_for_rq(rq);
+   i915_request_put(rq);
+   if (ret) {
+   pr_err("Request failed to complete: %d\n", ret);
+   goto err_spin;
+   }
+
+   if (i915_reset_count(global) == reset_count) {
+   pr_err("Failed to record a GPU reset\n");
+   ret = -EINVAL;
+   goto err_spin;
+   }
+
+err_spin:
+   igt_spinner_end();
+   igt_spinner_fini();
+   intel_engine_set_heartbeat(engine, old_beat);
+
+   if (ret == 0) {
+   rq = nop_request(engine);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+

[PATCH 4/6] drm/i915/selftest: Cope with not having an RCS engine

2022-07-27 Thread John . C . Harrison
From: John Harrison 

It is no longer guaranteed that there will always be an RCS engine.
So, use the helper function for finding the first available engine that
can be used for general purpose selftets.

Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c 
b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 6493265d5f642..7f3bb1d34dfbf 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -1302,13 +1302,15 @@ static int igt_reset_wait(void *arg)
 {
struct intel_gt *gt = arg;
struct i915_gpu_error *global = >i915->gpu_error;
-   struct intel_engine_cs *engine = gt->engine[RCS0];
+   struct intel_engine_cs *engine;
struct i915_request *rq;
unsigned int reset_count;
struct hang h;
long timeout;
int err;
 
+   engine = intel_selftest_find_any_engine(gt);
+
if (!engine || !intel_engine_can_store_dword(engine))
return 0;
 
@@ -1432,7 +1434,7 @@ static int __igt_reset_evict_vma(struct intel_gt *gt,
 int (*fn)(void *),
 unsigned int flags)
 {
-   struct intel_engine_cs *engine = gt->engine[RCS0];
+   struct intel_engine_cs *engine;
struct drm_i915_gem_object *obj;
struct task_struct *tsk = NULL;
struct i915_request *rq;
@@ -1444,6 +1446,8 @@ static int __igt_reset_evict_vma(struct intel_gt *gt,
if (!gt->ggtt->num_fences && flags & EXEC_OBJECT_NEEDS_FENCE)
return 0;
 
+   engine = intel_selftest_find_any_engine(gt);
+
if (!engine || !intel_engine_can_store_dword(engine))
return 0;
 
@@ -1819,12 +1823,14 @@ static int igt_handle_error(void *arg)
 {
struct intel_gt *gt = arg;
struct i915_gpu_error *global = >i915->gpu_error;
-   struct intel_engine_cs *engine = gt->engine[RCS0];
+   struct intel_engine_cs *engine;
struct hang h;
struct i915_request *rq;
struct i915_gpu_coredump *error;
int err;
 
+   engine = intel_selftest_find_any_engine(gt);
+
/* Check that we can issue a global GPU and engine reset */
 
if (!intel_has_reset_engine(gt))
-- 
2.37.1



[PATCH 2/6] drm/i915/guc: Fix issues with live_preempt_cancel

2022-07-27 Thread John . C . Harrison
From: Matthew Brost 

Having semaphores results in different behavior when a dependent request
is cancelled. In the case of semaphores the request could be on the HW
and complete successfully while without the request is held in the
driver and the error from the dependent request is propagated. Fix
live_preempt_cancel to take this behavior into account.

Also update live_preempt_cancel to use new function intel_context_ban
rather than intel_context_set_banned.

Signed-off-by: Matthew Brost 
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/selftest_execlists.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c 
b/drivers/gpu/drm/i915/gt/selftest_execlists.c
index 02fc97a0ab502..015f8cd3463e2 100644
--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
+++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
@@ -2087,7 +2087,7 @@ static int __cancel_active0(struct live_preempt_cancel 
*arg)
goto out;
}
 
-   intel_context_set_banned(rq->context);
+   intel_context_ban(rq->context, rq);
err = intel_engine_pulse(arg->engine);
if (err)
goto out;
@@ -2146,7 +2146,7 @@ static int __cancel_active1(struct live_preempt_cancel 
*arg)
if (err)
goto out;
 
-   intel_context_set_banned(rq[1]->context);
+   intel_context_ban(rq[1]->context, rq[1]);
err = intel_engine_pulse(arg->engine);
if (err)
goto out;
@@ -2229,7 +2229,7 @@ static int __cancel_queued(struct live_preempt_cancel 
*arg)
if (err)
goto out;
 
-   intel_context_set_banned(rq[2]->context);
+   intel_context_ban(rq[2]->context, rq[2]);
err = intel_engine_pulse(arg->engine);
if (err)
goto out;
@@ -2244,7 +2244,13 @@ static int __cancel_queued(struct live_preempt_cancel 
*arg)
goto out;
}
 
-   if (rq[1]->fence.error != 0) {
+   /*
+* The behavior between having semaphores and not is different. With
+* semaphores the subsequent request is on the hardware and not 
cancelled
+* while without the request is held in the driver and cancelled.
+*/
+   if (intel_engine_has_semaphores(rq[1]->engine) &&
+   rq[1]->fence.error != 0) {
pr_err("Normal inflight1 request did not complete\n");
err = -EINVAL;
goto out;
@@ -2292,7 +2298,7 @@ static int __cancel_hostile(struct live_preempt_cancel 
*arg)
goto out;
}
 
-   intel_context_set_banned(rq->context);
+   intel_context_ban(rq->context, rq);
err = intel_engine_pulse(arg->engine); /* force reset */
if (err)
goto out;
-- 
2.37.1



[PATCH 0/6] Random assortment of (mostly) GuC related patches

2022-07-27 Thread John . C . Harrison
From: John Harrison 

Pushing a bunch of patches which had gotten forgotten about.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/selftest: Cope with not having an RCS engine
  drm/i915/guc: Don't abort on CTB_UNUSED status

Matthew Brost (2):
  drm/i915/guc: Fix issues with live_preempt_cancel
  drm/i915/guc: Support larger contexts on newer hardware

Michał Winiarski (1):
  drm/i915/guc: Route semaphores to GuC for Gen12+

Rahul Kumar Singh (1):
  drm/i915/guc: Add selftest for a hung GuC

 drivers/gpu/drm/i915/gt/selftest_execlists.c  |  16 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |  12 +-
 .../gt/uc/abi/guc_communication_ctb_abi.h |   8 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  10 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  18 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h|   4 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  15 ++
 .../drm/i915/gt/uc/selftest_guc_hangcheck.c   | 159 ++
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 9 files changed, 227 insertions(+), 16 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c

-- 
2.37.1



[PATCH 6/6] drm/i915/guc: Don't abort on CTB_UNUSED status

2022-07-27 Thread John . C . Harrison
From: John Harrison 

When the KMD sends a CLIENT_RESET request to GuC (as part of the
suspend sequence), GuC will mark the CTB buffer as 'UNUSED'. If the
KMD then checked the CTB queue, it would see a non-zero status value
and report the buffer as corrupted.

Technically, no G2H messages should be received once the CLIENT_RESET
has been sent. However, if a context was outstanding on an engine then
it would get reset and a reset notification would be sent. So, don't
actually treat UNUSED as a catastrophic error. Just flag it up as
unexpected and keep going.

Signed-off-by: John Harrison 
---
 .../i915/gt/uc/abi/guc_communication_ctb_abi.h |  8 +---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c  | 18 --
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
index df83c1cc7c7a6..28b8387f97b77 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
@@ -37,6 +37,7 @@
  *  |   |   |   - _`GUC_CTB_STATUS_OVERFLOW` = 1 (head/tail too large) 
|
  *  |   |   |   - _`GUC_CTB_STATUS_UNDERFLOW` = 2 (truncated message)  
|
  *  |   |   |   - _`GUC_CTB_STATUS_MISMATCH` = 4 (head/tail modified)  
|
+ *  |   |   |   - _`GUC_CTB_STATUS_UNUSED` = 8 (CTB is not in use) 
|
  *  
+---+---+--+
  *  |...|   | RESERVED = MBZ   
|
  *  
+---+---+--+
@@ -49,9 +50,10 @@ struct guc_ct_buffer_desc {
u32 tail;
u32 status;
 #define GUC_CTB_STATUS_NO_ERROR0
-#define GUC_CTB_STATUS_OVERFLOW(1 << 0)
-#define GUC_CTB_STATUS_UNDERFLOW   (1 << 1)
-#define GUC_CTB_STATUS_MISMATCH(1 << 2)
+#define GUC_CTB_STATUS_OVERFLOWBIT(0)
+#define GUC_CTB_STATUS_UNDERFLOW   BIT(1)
+#define GUC_CTB_STATUS_MISMATCHBIT(2)
+#define GUC_CTB_STATUS_UNUSED  BIT(3)
u32 reserved[13];
 } __packed;
 static_assert(sizeof(struct guc_ct_buffer_desc) == 64);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index f01325cd1b625..11b5d4ddb19ce 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -816,8 +816,22 @@ static int ct_read(struct intel_guc_ct *ct, struct 
ct_incoming_msg **msg)
if (unlikely(ctb->broken))
return -EPIPE;
 
-   if (unlikely(desc->status))
-   goto corrupted;
+   if (unlikely(desc->status)) {
+   u32 status = desc->status;
+
+   if (status & GUC_CTB_STATUS_UNUSED) {
+   /*
+* Potentially valid if a CLIENT_RESET request resulted 
in
+* contexts/engines being reset. But should never 
happen as
+* no contexts should be active when CLIENT_RESET is 
sent.
+*/
+   CT_ERROR(ct, "Unexpected G2H after GuC has stopped!\n");
+   status &= ~GUC_CTB_STATUS_UNUSED;
+   }
+
+   if (status)
+   goto corrupted;
+   }
 
GEM_BUG_ON(head > size);
 
-- 
2.37.1



[PATCH 5/6] drm/i915/guc: Support larger contexts on newer hardware

2022-07-27 Thread John . C . Harrison
From: Matthew Brost 

The GuC needs a copy of a golden context for implementing watchdog
resets (aka media resets). This context is larger on newer platforms.
So adjust the size being allocated/copied accordingly.

Signed-off-by: Matthew Brost 
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index ba7541f3ca610..74cbe8eaf5318 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -464,7 +464,11 @@ static void fill_engine_enable_masks(struct intel_gt *gt,
 }
 
 #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
-#define LRC_SKIP_SIZE (LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE)
+#define XEHP_LR_HW_CONTEXT_SIZE (96 * sizeof(u32))
+#define LR_HW_CONTEXT_SZ(i915) (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50) ? \
+   XEHP_LR_HW_CONTEXT_SIZE : \
+   LR_HW_CONTEXT_SIZE)
+#define LRC_SKIP_SIZE(i915) (LRC_PPHWSP_SZ * PAGE_SIZE + 
LR_HW_CONTEXT_SZ(i915))
 static int guc_prep_golden_context(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -525,7 +529,7 @@ static int guc_prep_golden_context(struct intel_guc *guc)
 * on all engines).
 */
ads_blob_write(guc, ads.eng_state_size[guc_class],
-  real_size - LRC_SKIP_SIZE);
+  real_size - LRC_SKIP_SIZE(gt->i915));
ads_blob_write(guc, ads.golden_context_lrca[guc_class],
   addr_ggtt);
 
@@ -599,7 +603,7 @@ static void guc_init_golden_context(struct intel_guc *guc)
}
 
GEM_BUG_ON(ads_blob_read(guc, ads.eng_state_size[guc_class]) !=
-  real_size - LRC_SKIP_SIZE);
+  real_size - LRC_SKIP_SIZE(gt->i915));
GEM_BUG_ON(ads_blob_read(guc, 
ads.golden_context_lrca[guc_class]) != addr_ggtt);
 
addr_ggtt += alloc_size;
-- 
2.37.1



[PATCH 1/6] drm/i915/guc: Route semaphores to GuC for Gen12+

2022-07-27 Thread John . C . Harrison
From: Michał Winiarski 

In GuC submission mode, there is an option to use auto-switch out
semaphores and have GuC auto-switch in a waiting context. This
requires routing the semaphore interrupt to GuC.

Signed-off-by: Michał Winiarski 
Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h|  4 
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
index 8dc063f087eb1..a7092f711e9cd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
@@ -102,6 +102,10 @@
 #define   GUC_SEND_TRIGGER   (1<<0)
 #define GEN11_GUC_HOST_INTERRUPT   _MMIO(0x1901f0)
 
+#define GEN12_GUC_SEM_INTR_ENABLES _MMIO(0xc71c)
+#define   GUC_SEM_INTR_ROUTE_TO_GUCBIT(31)
+#define   GUC_SEM_INTR_ENABLE_ALL  (0xff)
+
 #define GUC_NUM_DOORBELLS  256
 
 /* format of the HW-monitored doorbell cacheline */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 76916aed897ad..0b8c6450fa344 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4191,13 +4191,27 @@ int intel_guc_submission_setup(struct intel_engine_cs 
*engine)
 
 void intel_guc_submission_enable(struct intel_guc *guc)
 {
+   struct intel_gt *gt = guc_to_gt(guc);
+
+   /* Enable and route to GuC */
+   if (GRAPHICS_VER(gt->i915) >= 12)
+   intel_uncore_write(gt->uncore, GEN12_GUC_SEM_INTR_ENABLES,
+  GUC_SEM_INTR_ROUTE_TO_GUC |
+  GUC_SEM_INTR_ENABLE_ALL);
+
guc_init_lrc_mapping(guc);
guc_init_engine_stats(guc);
 }
 
 void intel_guc_submission_disable(struct intel_guc *guc)
 {
+   struct intel_gt *gt = guc_to_gt(guc);
+
/* Note: By the time we're here, GuC may have already been reset */
+
+   /* Disable and route to host */
+   if (GRAPHICS_VER(gt->i915) >= 12)
+   intel_uncore_write(gt->uncore, GEN12_GUC_SEM_INTR_ENABLES, 0x0);
 }
 
 static bool __guc_submission_supported(struct intel_guc *guc)
-- 
2.37.1



[PATCH v4 2/2] drm: panel: Add novatek nt35596s panel driver

2022-07-27 Thread Molly Sophia
Novatek NT35596s is a generic DSI IC that drives command and video mode
panels. Add the driver for it. Currently add support for the LCD panel
from JDI connected with this IC, as found on Xiaomi Mi Mix2s phones.

Changes in v4:
- No change.

Changes in v3:
- Embed the support into existing driver (panel-novatek-nt36672a), as
  these two IC are similar with different initialization commands.

Signed-off-by: Molly Sophia 
---
 drivers/gpu/drm/panel/Kconfig |   7 +-
 .../gpu/drm/panel/panel-novatek-nt36672a.c| 246 --
 2 files changed, 234 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 38799effd00a..ecc1b9aa6a1c 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -328,14 +328,15 @@ config DRM_PANEL_NOVATEK_NT35950
  mobile phones.
 
 config DRM_PANEL_NOVATEK_NT36672A
-   tristate "Novatek NT36672A DSI panel"
+   tristate "Novatek NT36672A/NT35596S DSI panel"
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
help
  Say Y here if you want to enable support for the panels built
- around the Novatek NT36672A display controller, such as some
- Tianma panels used in a few Xiaomi Poco F1 mobile phones.
+ around the Novatek NT36672A or NT35596S display controller, such
+ as some Tianma panels used in a few Xiaomi Poco F1 mobile phones
+ or the JDI panels used in Xiaomi Mi Mix2S mobile phones.
 
 config DRM_PANEL_NOVATEK_NT39016
tristate "Novatek NT39016 RGB/SPI panel"
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
index 231f371901e8..fcdde538d847 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
@@ -3,13 +3,15 @@
  * Copyright (C) 2020 Linaro Ltd
  * Author: Sumit Semwal 
  *
- * This driver is for the DSI interface to panels using the NT36672A display 
driver IC
+ * Copyright (C) 2022 Molly Sophia 
+ *
+ * This driver is for the DSI interface to panels using the NT36672A/NT35596S 
display driver IC
  * from Novatek.
  * Currently supported are the Tianma FHD+ panels found in some Xiaomi phones, 
including
- * some variants of the Poco F1 phone.
+ * some variants of the Poco F1 phone, and the JDI FHD+ panels found in Xiaomi 
Mi Mix2S phones.
  *
- * Panels using the Novatek NT37762A IC should add appropriate configuration 
per-panel and
- * use this driver.
+ * Panels using the Novatek NT37762A or NT35596S IC should add appropriate 
configuration
+ * per-panel and use this driver.
  */
 
 #include 
@@ -123,12 +125,14 @@ static int nt36672a_panel_unprepare(struct drm_panel 
*panel)
if (!pinfo->prepared)
return 0;
 
-   /* send off cmds */
-   ret = nt36672a_send_cmds(panel, pinfo->desc->off_cmds,
-pinfo->desc->num_off_cmds);
+   if (pinfo->desc->num_off_cmds != 0) {
+   /* send off cmds if present */
+   ret = nt36672a_send_cmds(panel, pinfo->desc->off_cmds,
+   pinfo->desc->num_off_cmds);
 
-   if (ret < 0)
-   dev_err(panel->dev, "failed to send DCS off cmds: %d\n", ret);
+   if (ret < 0)
+   dev_err(panel->dev, "failed to send DCS off cmds: 
%d\n", ret);
+   }
 
ret = mipi_dsi_dcs_set_display_off(pinfo->link);
if (ret < 0)
@@ -211,13 +215,15 @@ static int nt36672a_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   /* Send rest of the init cmds */
-   err = nt36672a_send_cmds(panel, pinfo->desc->on_cmds_2,
-pinfo->desc->num_on_cmds_2);
+   if (pinfo->desc->num_on_cmds_2 != 0) {
+   /* Send rest of the init cmds if present */
+   err = nt36672a_send_cmds(panel, pinfo->desc->on_cmds_2,
+   pinfo->desc->num_on_cmds_2);
 
-   if (err < 0) {
-   dev_err(panel->dev, "failed to send DCS Init 2nd Code: %d\n", 
err);
-   goto poweroff;
+   if (err < 0) {
+   dev_err(panel->dev, "failed to send DCS Init 2nd Code: 
%d\n", err);
+   goto poweroff;
+   }
}
 
msleep(120);
@@ -601,6 +607,212 @@ static const struct nt36672a_panel_desc 
tianma_fhd_video_panel_desc = {
.num_off_cmds = ARRAY_SIZE(tianma_fhd_video_off_cmds),
 };
 
+static const struct nt36672a_panel_cmd jdi_nt35596s_video_on_cmds[] = {
+   { .data = { 0xff, 0x24 } },
+   { .data = { 0x9d, 0x34 } },
+   { .data = { 0xfb, 0x01 } },
+   { .data = { 0xc4, 0x25 } },
+   { .data = { 0xd1, 0x08 } },
+   { .data = { 0xd2, 0x84 } },
+   { .data = { 0xff, 0x26 } },
+   { .data = { 0xfb, 0x01 } },
+   { .data = { 0x03, 0x1c } 

[PATCH v4 0/2] Add driver for Novatek NT35596S panel

2022-07-27 Thread Molly Sophia
These patches add support for Novatek NT35596S based JDI FHD panels,
found in Xiaomi Mi Mix2S mobile phones.

Changes in v4:
- Correct numeric order of the items in binding.

Changes in v3:
- Embed the support into existing driver (panel-novatek-nt36672a), as
  these two IC are similar with different initialization commands.

Changes in v2:
- Correct items order in Makefile and improve failure handling.

Molly Sophia (2):
  dt-bindings: display: panel: Add Novatek NT35596S panel bindings
  drm: panel: Add novatek nt35596s panel driver

 .../display/panel/novatek,nt36672a.yaml   |  20 +-
 drivers/gpu/drm/panel/Kconfig |   7 +-
 .../gpu/drm/panel/panel-novatek-nt36672a.c| 246 --
 3 files changed, 247 insertions(+), 26 deletions(-)

-- 
2.37.1



[PATCH v4 1/2] dt-bindings: display: panel: Add Novatek NT35596S panel bindings

2022-07-27 Thread Molly Sophia
Add documentation for "novatek,nt35596s" panel.

Changes in v4:
- Correct numeric order of the items.

Changes in v3:
- Embed the documentation into existing one (novatek,nt36672a).

Signed-off-by: Molly Sophia 
---
 .../display/panel/novatek,nt36672a.yaml   | 20 ---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml 
b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
index 563766d283f6..d21a4a87a9d8 100644
--- a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
+++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
@@ -20,14 +20,20 @@ allOf:
 
 properties:
   compatible:
-items:
-  - enum:
-  - tianma,fhd-video
-  - const: novatek,nt36672a
+oneOf:
+  - items:
+  - enum:
+  - jdi,fhd-nt35596s
+  - const: novatek,nt35596s
+
+  - items:
+  - enum:
+  - tianma,fhd-video
+  - const: novatek,nt36672a
+
 description: This indicates the panel manufacturer of the panel that is
-  in turn using the NT36672A panel driver. This compatible string
-  determines how the NT36672A panel driver is configured for the indicated
-  panel. The novatek,nt36672a compatible shall always be provided as a 
fallback.
+  in turn using the NT36672A or the NT35596S panel driver. This compatible 
string
+  determines how the panel driver is configured for the indicated panel.
 
   reset-gpios:
 maxItems: 1
-- 
2.37.1



[PATCH 3/7] drm/i915/guc: Add GuC <-> kernel time stamp translation information

2022-07-27 Thread John . C . Harrison
From: John Harrison 

It is useful to be able to match GuC events to kernel events when
looking at the GuC log. That requires being able to convert GuC
timestamps to kernel time. So, when dumping error captures and/or GuC
logs, include a stamp in both time zones plus the clock frequency.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_gt_regs.h|  2 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c | 19 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h |  2 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c |  2 ++
 drivers/gpu/drm/i915/i915_gpu_error.c  | 12 
 drivers/gpu/drm/i915/i915_gpu_error.h  |  3 +++
 6 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 60d6eb5f245b7..fc7979bd91db5 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1007,6 +1007,8 @@
 #define   GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC (1 << 9)
 #define   GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC  (1 << 7)
 
+#define GUCPMTIMESTAMP _MMIO(0xc3e8)
+
 #define __GEN9_RCS0_MOCS0  0xc800
 #define GEN9_GFX_MOCS(i)   _MMIO(__GEN9_RCS0_MOCS0 + (i) * 
4)
 #define __GEN9_VCS0_MOCS0  0xc900
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2706a8c650900..ab4aacc516aa4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -389,6 +389,25 @@ void intel_guc_write_params(struct intel_guc *guc)
intel_uncore_forcewake_put(uncore, FORCEWAKE_GT);
 }
 
+void intel_guc_dump_time_info(struct intel_guc *guc, struct drm_printer *p)
+{
+   struct intel_gt *gt = guc_to_gt(guc);
+   intel_wakeref_t wakeref;
+   u32 stamp = 0;
+   u64 ktime;
+
+   intel_device_info_print_runtime(RUNTIME_INFO(gt->i915), p);
+
+   with_intel_runtime_pm(>i915->runtime_pm, wakeref)
+   stamp = intel_uncore_read(gt->uncore, GUCPMTIMESTAMP);
+   ktime = ktime_get_boottime_ns();
+
+   drm_printf(p, "Kernel timestamp: 0x%08llX [%llu]\n", ktime, ktime);
+   drm_printf(p, "GuC timestamp: 0x%08X [%u]\n", stamp, stamp);
+   drm_printf(p, "CS timestamp frequency: %u Hz, %u ns\n",
+  gt->clock_frequency, gt->clock_period_ns);
+}
+
 int intel_guc_init(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index a7acffbf15d1f..804133df1ac9b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -464,4 +464,6 @@ void intel_guc_load_status(struct intel_guc *guc, struct 
drm_printer *p);
 
 void intel_guc_write_barrier(struct intel_guc *guc);
 
+void intel_guc_dump_time_info(struct intel_guc *guc, struct drm_printer *p);
+
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index 991d4a02248dc..07d31ae32f765 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -764,6 +764,8 @@ int intel_guc_log_dump(struct intel_guc_log *log, struct 
drm_printer *p,
if (!obj)
return 0;
 
+   intel_guc_dump_time_info(guc, p);
+
map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
if (IS_ERR(map)) {
DRM_DEBUG("Failed to pin object\n");
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 32e92651ef7c2..addba75252343 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -678,6 +678,7 @@ static void err_print_uc(struct drm_i915_error_state_buf *m,
 
intel_uc_fw_dump(_uc->guc_fw, );
intel_uc_fw_dump(_uc->huc_fw, );
+   err_printf(m, "GuC timestamp: 0x%08x\n", error_uc->timestamp);
intel_gpu_error_print_vma(m, NULL, error_uc->guc_log);
 }
 
@@ -720,6 +721,8 @@ static void err_print_gt_global_nonguc(struct 
drm_i915_error_state_buf *m,
int i;
 
err_printf(m, "GT awake: %s\n", str_yes_no(gt->awake));
+   err_printf(m, "CS timestamp frequency: %u Hz, %d ns\n",
+  gt->clock_frequency, gt->clock_period_ns);
err_printf(m, "EIR: 0x%08x\n", gt->eir);
err_printf(m, "PGTBL_ER: 0x%08x\n", gt->pgtbl_er);
 
@@ -1675,6 +1678,13 @@ gt_record_uc(struct intel_gt_coredump *gt,
 */
error_uc->guc_fw.path = kstrdup(uc->guc.fw.path, ALLOW_FAIL);
error_uc->huc_fw.path = kstrdup(uc->huc.fw.path, ALLOW_FAIL);
+
+   /*
+* Save the GuC log and include a timestamp reference for converting the
+* log times to system times (in conjunction with the error->boottime 
and
+* gt->clock_frequency fields saved elsewhere).
+*/
+   error_uc->timestamp = 

[PATCH 4/7] drm/i915/guc: Record CTB info in error logs

2022-07-27 Thread John . C . Harrison
From: John Harrison 

When debugging GuC communication issues, it is useful to have the CTB
info available. So add the state and buffer contents to the error
capture log.

Also, add a sub-structure for the GuC specific error capture info as
it is now becoming numerous.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 59 +++
 drivers/gpu/drm/i915/i915_gpu_error.h | 20 +++--
 2 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index addba75252343..543ba63f958ea 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -671,6 +671,18 @@ static void err_print_pciid(struct 
drm_i915_error_state_buf *m,
   pdev->subsystem_device);
 }
 
+static void err_print_guc_ctb(struct drm_i915_error_state_buf *m,
+ const char *name,
+ const struct intel_ctb_coredump *ctb)
+{
+   if (!ctb->size)
+   return;
+
+   err_printf(m, "GuC %s CTB: raw: 0x%08X, 0x%08X/%08X, cached: 
0x%08X/%08X, desc = 0x%08X, buf = 0x%08X x 0x%08X\n",
+  name, ctb->raw_status, ctb->raw_head, ctb->raw_tail,
+  ctb->head, ctb->tail, ctb->desc_offset, ctb->cmds_offset, 
ctb->size);
+}
+
 static void err_print_uc(struct drm_i915_error_state_buf *m,
 const struct intel_uc_coredump *error_uc)
 {
@@ -678,8 +690,12 @@ static void err_print_uc(struct drm_i915_error_state_buf 
*m,
 
intel_uc_fw_dump(_uc->guc_fw, );
intel_uc_fw_dump(_uc->huc_fw, );
-   err_printf(m, "GuC timestamp: 0x%08x\n", error_uc->timestamp);
-   intel_gpu_error_print_vma(m, NULL, error_uc->guc_log);
+   err_printf(m, "GuC timestamp: 0x%08x\n", error_uc->guc.timestamp);
+   intel_gpu_error_print_vma(m, NULL, error_uc->guc.vma_log);
+   err_printf(m, "GuC CTB fence: %d\n", error_uc->guc.last_fence);
+   err_print_guc_ctb(m, "Send", error_uc->guc.ctb + 0);
+   err_print_guc_ctb(m, "Recv", error_uc->guc.ctb + 1);
+   intel_gpu_error_print_vma(m, NULL, error_uc->guc.vma_ctb);
 }
 
 static void err_free_sgl(struct scatterlist *sgl)
@@ -854,7 +870,7 @@ static void __err_print_to_sgl(struct 
drm_i915_error_state_buf *m,
if (error->gt) {
bool print_guc_capture = false;
 
-   if (error->gt->uc && error->gt->uc->is_guc_capture)
+   if (error->gt->uc && error->gt->uc->guc.is_guc_capture)
print_guc_capture = true;
 
err_print_gt_display(m, error->gt);
@@ -1009,7 +1025,8 @@ static void cleanup_uc(struct intel_uc_coredump *uc)
 {
kfree(uc->guc_fw.path);
kfree(uc->huc_fw.path);
-   i915_vma_coredump_free(uc->guc_log);
+   i915_vma_coredump_free(uc->guc.vma_log);
+   i915_vma_coredump_free(uc->guc.vma_ctb);
 
kfree(uc);
 }
@@ -1658,6 +1675,23 @@ gt_record_engines(struct intel_gt_coredump *gt,
}
 }
 
+static void gt_record_guc_ctb(struct intel_ctb_coredump *saved,
+ const struct intel_guc_ct_buffer *ctb,
+ const void *blob_ptr, struct intel_guc *guc)
+{
+   if (!ctb || !ctb->desc)
+   return;
+
+   saved->raw_status = ctb->desc->status;
+   saved->raw_head = ctb->desc->head;
+   saved->raw_tail = ctb->desc->tail;
+   saved->head = ctb->head;
+   saved->tail = ctb->tail;
+   saved->size = ctb->size;
+   saved->desc_offset = ((void *)ctb->desc) - blob_ptr;
+   saved->cmds_offset = ((void *)ctb->cmds) - blob_ptr;
+}
+
 static struct intel_uc_coredump *
 gt_record_uc(struct intel_gt_coredump *gt,
 struct i915_vma_compress *compress)
@@ -1684,9 +1718,16 @@ gt_record_uc(struct intel_gt_coredump *gt,
 * log times to system times (in conjunction with the error->boottime 
and
 * gt->clock_frequency fields saved elsewhere).
 */
-   error_uc->timestamp = intel_uncore_read(gt->_gt->uncore, 
GUCPMTIMESTAMP);
-   error_uc->guc_log = create_vma_coredump(gt->_gt, uc->guc.log.vma,
-   "GuC log buffer", compress);
+   error_uc->guc.timestamp = intel_uncore_read(gt->_gt->uncore, 
GUCPMTIMESTAMP);
+   error_uc->guc.vma_log = create_vma_coredump(gt->_gt, uc->guc.log.vma,
+   "GuC log buffer", compress);
+   error_uc->guc.vma_ctb = create_vma_coredump(gt->_gt, uc->guc.ct.vma,
+   "GuC CT buffer", compress);
+   error_uc->guc.last_fence = uc->guc.ct.requests.last_fence;
+   gt_record_guc_ctb(error_uc->guc.ctb + 0, >guc.ct.ctbs.send,
+ uc->guc.ct.ctbs.send.desc, (struct intel_guc 
*)>guc);
+   gt_record_guc_ctb(error_uc->guc.ctb + 1, >guc.ct.ctbs.recv,
+ 

[PATCH 6/7] drm/i915/guc: Make GuC log sizes runtime configurable

2022-07-27 Thread John . C . Harrison
From: John Harrison 

The GuC log buffer sizes had to be configured statically at compile
time. This can be quite troublesome when needing to get larger logs
out of a released driver. So re-organise the code to allow a boot time
module parameter override.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  53 ++
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c|  14 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c| 176 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h|  42 +++--
 drivers/gpu/drm/i915/i915_params.c|  12 ++
 drivers/gpu/drm/i915/i915_params.h|   3 +
 6 files changed, 226 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index ab4aacc516aa4..01f2705cb94a3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -224,53 +224,22 @@ static u32 guc_ctl_feature_flags(struct intel_guc *guc)
 
 static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
 {
-   u32 offset = intel_guc_ggtt_offset(guc, guc->log.vma) >> PAGE_SHIFT;
-   u32 flags;
-
-   #if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
-   #define LOG_UNIT SZ_1M
-   #define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
-   #else
-   #define LOG_UNIT SZ_4K
-   #define LOG_FLAG 0
-   #endif
-
-   #if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
-   #define CAPTURE_UNIT SZ_1M
-   #define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
-   #else
-   #define CAPTURE_UNIT SZ_4K
-   #define CAPTURE_FLAG 0
-   #endif
-
-   BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
-   BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
-   BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
-   BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
-   BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
-   BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
-
-   BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
-   (GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
-   BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
-   (GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
-   BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
-   (GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
+   struct intel_guc_log *log = >log;
+   u32 offset, flags;
+
+   GEM_BUG_ON(!log->sizes_initialised);
+
+   offset = intel_guc_ggtt_offset(guc, log->vma) >> PAGE_SHIFT;
 
flags = GUC_LOG_VALID |
GUC_LOG_NOTIFY_ON_HALF_FULL |
-   CAPTURE_FLAG |
-   LOG_FLAG |
-   ((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
-   ((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
-   ((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << 
GUC_LOG_CAPTURE_SHIFT) |
+   log->sizes[GUC_LOG_SECTIONS_DEBUG].flag |
+   log->sizes[GUC_LOG_SECTIONS_CAPTURE].flag |
+   (log->sizes[GUC_LOG_SECTIONS_CRASH].count << 
GUC_LOG_CRASH_SHIFT) |
+   (log->sizes[GUC_LOG_SECTIONS_DEBUG].count << 
GUC_LOG_DEBUG_SHIFT) |
+   (log->sizes[GUC_LOG_SECTIONS_CAPTURE].count << 
GUC_LOG_CAPTURE_SHIFT) |
(offset << GUC_LOG_BUF_ADDR_SHIFT);
 
-   #undef LOG_UNIT
-   #undef LOG_FLAG
-   #undef CAPTURE_UNIT
-   #undef CAPTURE_FLAG
-
return flags;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index b54b7883320b1..d2ac53d4f3b6e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -656,16 +656,17 @@ static void check_guc_capture_size(struct intel_guc *guc)
struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
int min_size = guc_capture_output_min_size_est(guc);
int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER;
+   u32 buffer_size = intel_guc_log_section_size_capture(>log);
 
if (min_size < 0)
drm_warn(>drm, "Failed to calculate GuC error state 
capture buffer minimum size: %d!\n",
 min_size);
-   else if (min_size > CAPTURE_BUFFER_SIZE)
+   else if (min_size > buffer_size)
drm_warn(>drm, "GuC error state capture buffer is too 
small: %d < %d\n",
-CAPTURE_BUFFER_SIZE, min_size);
-   else if (spare_size > CAPTURE_BUFFER_SIZE)
+buffer_size, min_size);
+   else if (spare_size > buffer_size)
drm_notice(>drm, "GuC error state capture buffer maybe 
too small: %d < %d (min = %d)\n",
-  CAPTURE_BUFFER_SIZE, spare_size, min_size);
+  buffer_size, spare_size, min_size);
 }
 
 /*
@@ -1294,7 +1295,8 @@ static void __guc_capture_process_output(struct intel_guc 
*guc)
 
log_buf_state = 

[PATCH 2/7] drm/i915/guc: Fix capture size warning and bump the size

2022-07-27 Thread John . C . Harrison
From: John Harrison 

There was a size check to warn if the GuC error state capture buffer
allocation would be too small to fit a reasonable amount of capture
data for the current platform. Unfortunately, the test was done too
early in the boot sequence and was actually testing 'if(-ENODEV >
size)'.

Move the check to be later. The check is only used to print a warning
message, so it doesn't really matter how early or late it is done.
Note that it is not possible to dynamically size the buffer because
the allocation needs to be done before the engine information is
available (at least, it would be in the intended two-phase GuC init
process).

Now that the check works, it is reporting size too small for newer
platforms. The check includes a 3x oversample multiplier to allow for
multiple error captures to be bufferd by GuC before i915 has a chance
to read them out. This is less important than simply being big enough
to fit the first capture.

So a) bump the default size to be large enough for one capture minimum
and b) make the warning only if one capture won't fit, instead use a
notice for the 3x size.

Note that the size estimate is a worst case scenario. Actual captures
will likely be smaller.

Lastly, use drm_warn istead of DRM_WARN as the former provides more
infmration and the latter is deprecated.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 40 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_capture.h|  1 -
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c|  4 --
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h|  4 +-
 4 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 75257bd20ff01..b54b7883320b1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -600,10 +600,8 @@ intel_guc_capture_getnullheader(struct intel_guc *guc,
return 0;
 }
 
-#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3
-
-int
-intel_guc_capture_output_min_size_est(struct intel_guc *guc)
+static int
+guc_capture_output_min_size_est(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
struct intel_engine_cs *engine;
@@ -623,13 +621,8 @@ intel_guc_capture_output_min_size_est(struct intel_guc 
*guc)
 * For each engine instance, there would be 1 x 
guc_state_capture_group_t output
 * followed by 3 x guc_state_capture_t lists. The latter is how the 
register
 * dumps are split across different register types (where the '3' are 
global vs class
-* vs instance). Finally, let's multiply the whole thing by 3x (just so 
we are
-* not limited to just 1 round of data in a worst case full register 
dump log)
-*
-* NOTE: intel_guc_log that allocates the log buffer would round this 
size up to
-* a power of two.
+* vs instance).
 */
-
for_each_engine(engine, gt, id) {
worst_min_size += sizeof(struct 
guc_state_capture_group_header_t) +
 (3 * sizeof(struct 
guc_state_capture_header_t));
@@ -649,7 +642,30 @@ intel_guc_capture_output_min_size_est(struct intel_guc 
*guc)
 
worst_min_size += (num_regs * sizeof(struct guc_mmio_reg));
 
-   return (worst_min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER);
+   return worst_min_size;
+}
+
+/*
+ * Add on a 3x multiplier to allow for multiple back-to-back captures occurring
+ * before the i915 can read the data out and process it
+ */
+#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3
+
+static void check_guc_capture_size(struct intel_guc *guc)
+{
+   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+   int min_size = guc_capture_output_min_size_est(guc);
+   int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER;
+
+   if (min_size < 0)
+   drm_warn(>drm, "Failed to calculate GuC error state 
capture buffer minimum size: %d!\n",
+min_size);
+   else if (min_size > CAPTURE_BUFFER_SIZE)
+   drm_warn(>drm, "GuC error state capture buffer is too 
small: %d < %d\n",
+CAPTURE_BUFFER_SIZE, min_size);
+   else if (spare_size > CAPTURE_BUFFER_SIZE)
+   drm_notice(>drm, "GuC error state capture buffer maybe 
too small: %d < %d (min = %d)\n",
+  CAPTURE_BUFFER_SIZE, spare_size, min_size);
 }
 
 /*
@@ -1580,5 +1596,7 @@ int intel_guc_capture_init(struct intel_guc *guc)
INIT_LIST_HEAD(>capture->outlist);
INIT_LIST_HEAD(>capture->cachelist);
 
+   check_guc_capture_size(guc);
+
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
index d3d7bd0b6db64..fbd3713c7832d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
@@ -21,7 +21,6 

[PATCH 1/7] drm/i915/guc: Add a helper for log buffer size

2022-07-27 Thread John . C . Harrison
From: Alan Previn 

Add a helper to get GuC log buffer size.

Signed-off-by: Alan Previn 
Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 49 --
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index 25b2d7ce6640d..492bbf419d4df 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -15,6 +15,32 @@
 
 static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log);
 
+static u32 intel_guc_log_size(struct intel_guc_log *log)
+{
+   /*
+*  GuC Log buffer Layout:
+*
+*  NB: Ordering must follow "enum guc_log_buffer_type".
+*
+*  +===+ 00B
+*  |  Debug state header   |
+*  +---+ 32B
+*  |Crash dump state header|
+*  +---+ 64B
+*  | Capture state header  |
+*  +---+ 96B
+*  |   |
+*  +===+ PAGE_SIZE (4KB)
+*  |  Debug logs   |
+*  +===+ + DEBUG_SIZE
+*  |Crash Dump logs|
+*  +===+ + CRASH_SIZE
+*  | Capture logs  |
+*  +===+ + CAPTURE_SIZE
+*/
+   return PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE + 
CAPTURE_BUFFER_SIZE;
+}
+
 /**
  * DOC: GuC firmware log
  *
@@ -461,32 +487,11 @@ int intel_guc_log_create(struct intel_guc_log *log)
 
GEM_BUG_ON(log->vma);
 
-   /*
-*  GuC Log buffer Layout
-* (this ordering must follow "enum guc_log_buffer_type" definition)
-*
-*  +===+ 00B
-*  |  Debug state header   |
-*  +---+ 32B
-*  |Crash dump state header|
-*  +---+ 64B
-*  | Capture state header  |
-*  +---+ 96B
-*  |   |
-*  +===+ PAGE_SIZE (4KB)
-*  |  Debug logs   |
-*  +===+ + DEBUG_SIZE
-*  |Crash Dump logs|
-*  +===+ + CRASH_SIZE
-*  | Capture logs  |
-*  +===+ + CAPTURE_SIZE
-*/
if (intel_guc_capture_output_min_size_est(guc) > CAPTURE_BUFFER_SIZE)
DRM_WARN("GuC log buffer for state_capture maybe too small. %d 
< %d\n",
 CAPTURE_BUFFER_SIZE, 
intel_guc_capture_output_min_size_est(guc));
 
-   guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
-  CAPTURE_BUFFER_SIZE;
+   guc_log_size = intel_guc_log_size(log);
 
vma = intel_guc_allocate_vma(guc, guc_log_size);
if (IS_ERR(vma)) {
-- 
2.37.1



[PATCH 5/7] drm/i915/guc: Use streaming loads to speed up dumping the guc log

2022-07-27 Thread John . C . Harrison
From: Chris Wilson 

Use a temporary page and mempy_from_wc to reduce the time it takes to
dump the guc log to debugfs.

Signed-off-by: Chris Wilson 
Signed-off-by: John Harrison 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 24 --
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index 07d31ae32f765..4722d4b18ed19 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -750,8 +750,9 @@ int intel_guc_log_dump(struct intel_guc_log *log, struct 
drm_printer *p,
struct intel_guc *guc = log_to_guc(log);
struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
struct drm_i915_gem_object *obj = NULL;
-   u32 *map;
-   int i = 0;
+   void *map;
+   u32 *page;
+   int i, j;
 
if (!intel_guc_is_supported(guc))
return -ENODEV;
@@ -764,23 +765,34 @@ int intel_guc_log_dump(struct intel_guc_log *log, struct 
drm_printer *p,
if (!obj)
return 0;
 
+   page = (u32 *)__get_free_page(GFP_KERNEL);
+   if (!page)
+   return -ENOMEM;
+
intel_guc_dump_time_info(guc, p);
 
map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
if (IS_ERR(map)) {
DRM_DEBUG("Failed to pin object\n");
drm_puts(p, "(log data unaccessible)\n");
+   free_page((unsigned long)page);
return PTR_ERR(map);
}
 
-   for (i = 0; i < obj->base.size / sizeof(u32); i += 4)
-   drm_printf(p, "0x%08x 0x%08x 0x%08x 0x%08x\n",
-  *(map + i), *(map + i + 1),
-  *(map + i + 2), *(map + i + 3));
+   for (i = 0; i < obj->base.size; i += PAGE_SIZE) {
+   if (!i915_memcpy_from_wc(page, map + i, PAGE_SIZE))
+   memcpy(page, map + i, PAGE_SIZE);
+
+   for (j = 0; j < PAGE_SIZE / sizeof(u32); j += 4)
+   drm_printf(p, "0x%08x 0x%08x 0x%08x 0x%08x\n",
+  *(page + j + 0), *(page + j + 1),
+  *(page + j + 2), *(page + j + 3));
+   }
 
drm_puts(p, "\n");
 
i915_gem_object_unpin_map(obj);
+   free_page((unsigned long)page);
 
return 0;
 }
-- 
2.37.1



Re: [PATCH] drm/amdkfd: use time_is_before_jiffies(a + b) to replace "jiffies - a > b"

2022-07-27 Thread Yu Zhe

在 2022年07月28日 00:04, Felix Kuehling 写道:


This patch introduces a build warning for me:
   CC [M]  drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.o
In file included from /home/fkuehlin/compute/kernel/include/linux/spinlock.h:54,
  from /home/fkuehlin/compute/kernel/include/linux/mmzone.h:8,
  from /home/fkuehlin/compute/kernel/include/linux/gfp.h:6,
  from /home/fkuehlin/compute/kernel/include/linux/slab.h:15,
  from 
/home/fkuehlin/compute/kernel/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.c:44:
/home/fkuehlin/compute/kernel/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.c:
 In function ?interrupt_wq?:
/home/fkuehlin/compute/kernel/include/linux/typecheck.h:12:18: warning: 
comparison of distinct pointer types lacks a cast
12 |  (void)(&__dummy == &__dummy2); \
   |  ^~
/home/fkuehlin/compute/kernel/include/linux/jiffies.h:106:3: note: in expansion 
of macro ?typecheck?
   106 |   typecheck(unsigned long, b) && \
   |   ^
/home/fkuehlin/compute/kernel/include/linux/jiffies.h:154:35: note: in 
expansion of macro ?time_after?
   154 | #define time_is_before_jiffies(a) time_after(jiffies, a)
   |   ^~
/home/fkuehlin/compute/kernel/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.c:159:7:
 note: in expansion of macro ?time_is_before_jiffies?
   159 |   if (time_is_before_jiffies(start_jiffies + HZ)) {
   |   ^~
I think you need to change the the definition of start_jiffies to be
unsigned long. Do you want to submit a v2 of your patch?


Yes, I will submit v2 patch later.


That said, I think the existing code was fine, though the type-mismatch
highlighted by your patch is a bit iffy.


And if the timer wrap changes in the future you won't have to alter your driver 
code. So I think it's better.


Regards,
   Felix
Am 2022-07-26 um 22:59 schrieb Yu Zhe:

time_is_before_jiffies deals with timer wrapping correctly.
Signed-off-by: Yu Zhe 
---
   drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index a9466d154395..6397926e059c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -156,7 +156,7 @@ static void interrupt_wq(struct work_struct *work)
   while (dequeue_ih_ring_entry(dev, ih_ring_entry)) {
   dev->device_info.event_interrupt_class->interrupt_wq(dev,
   ih_ring_entry);
-if (jiffies - start_jiffies > HZ) {
+if (time_is_before_jiffies(start_jiffies + HZ)) {
   /* If we spent more than a second processing signals,
* reschedule the worker to avoid soft-lockup warnings
*/




[PATCH 7/7] drm/i915/guc: Reduce spam from error capture

2022-07-27 Thread John . C . Harrison
From: John Harrison 

Some debug code got left in when the GuC based register save for error
capture was added. Remove that.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 67 ---
 1 file changed, 28 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index d2ac53d4f3b6e..8f11651460131 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -1383,33 +1383,22 @@ guc_capture_reg_to_str(const struct intel_guc *guc, u32 
owner, u32 type,
return NULL;
 }
 
-#ifdef CONFIG_DRM_I915_DEBUG_GUC
-#define __out(a, ...) \
-   do { \
-   drm_warn((&(a)->i915->drm), __VA_ARGS__); \
-   i915_error_printf((a), __VA_ARGS__); \
-   } while (0)
-#else
-#define __out(a, ...) \
-   i915_error_printf(a, __VA_ARGS__)
-#endif
-
 #define GCAP_PRINT_INTEL_ENG_INFO(ebuf, eng) \
do { \
-   __out(ebuf, "i915-Eng-Name: %s command stream\n", \
- (eng)->name); \
-   __out(ebuf, "i915-Eng-Inst-Class: 0x%02x\n", (eng)->class); 
\
-   __out(ebuf, "i915-Eng-Inst-Id: 0x%02x\n", (eng)->instance); 
\
-   __out(ebuf, "i915-Eng-LogicalMask: 0x%08x\n", \
- (eng)->logical_mask); \
+   i915_error_printf(ebuf, "i915-Eng-Name: %s command 
stream\n", \
+ (eng)->name); \
+   i915_error_printf(ebuf, "i915-Eng-Inst-Class: 0x%02x\n", 
(eng)->class); \
+   i915_error_printf(ebuf, "i915-Eng-Inst-Id: 0x%02x\n", 
(eng)->instance); \
+   i915_error_printf(ebuf, "i915-Eng-LogicalMask: 0x%08x\n", \
+ (eng)->logical_mask); \
} while (0)
 
 #define GCAP_PRINT_GUC_INST_INFO(ebuf, node) \
do { \
-   __out(ebuf, "GuC-Engine-Inst-Id: 0x%08x\n", \
- (node)->eng_inst); \
-   __out(ebuf, "GuC-Context-Id: 0x%08x\n", (node)->guc_id); \
-   __out(ebuf, "LRCA: 0x%08x\n", (node)->lrca); \
+   i915_error_printf(ebuf, "GuC-Engine-Inst-Id: 0x%08x\n", \
+ (node)->eng_inst); \
+   i915_error_printf(ebuf, "GuC-Context-Id: 0x%08x\n", 
(node)->guc_id); \
+   i915_error_printf(ebuf, "LRCA: 0x%08x\n", (node)->lrca); \
} while (0)
 
 int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *ebuf,
@@ -1441,57 +1430,57 @@ int intel_guc_capture_print_engine_node(struct 
drm_i915_error_state_buf *ebuf,
 
guc = >engine->gt->uc.guc;
 
-   __out(ebuf, "global --- GuC Error Capture on %s command stream:\n",
- ee->engine->name);
+   i915_error_printf(ebuf, "global --- GuC Error Capture on %s command 
stream:\n",
+ ee->engine->name);
 
node = ee->guc_capture_node;
if (!node) {
-   __out(ebuf, "  No matching ee-node\n");
+   i915_error_printf(ebuf, "  No matching ee-node\n");
return 0;
}
 
-   __out(ebuf, "Coverage:  %s\n", grptype[node->is_partial]);
+   i915_error_printf(ebuf, "Coverage:  %s\n", grptype[node->is_partial]);
 
for (i = GUC_CAPTURE_LIST_TYPE_GLOBAL; i < GUC_CAPTURE_LIST_TYPE_MAX; 
++i) {
-   __out(ebuf, "  RegListType: %s\n",
- datatype[i % GUC_CAPTURE_LIST_TYPE_MAX]);
-   __out(ebuf, "Owner-Id: %d\n", node->reginfo[i].vfid);
+   i915_error_printf(ebuf, "  RegListType: %s\n",
+ datatype[i % GUC_CAPTURE_LIST_TYPE_MAX]);
+   i915_error_printf(ebuf, "Owner-Id: %d\n", 
node->reginfo[i].vfid);
 
switch (i) {
case GUC_CAPTURE_LIST_TYPE_GLOBAL:
default:
break;
case GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS:
-   __out(ebuf, "GuC-Eng-Class: %d\n", node->eng_class);
-   __out(ebuf, "i915-Eng-Class: %d\n",
- guc_class_to_engine_class(node->eng_class));
+   i915_error_printf(ebuf, "GuC-Eng-Class: %d\n", 
node->eng_class);
+   i915_error_printf(ebuf, "i915-Eng-Class: %d\n",
+ 
guc_class_to_engine_class(node->eng_class));
break;
case GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE:
eng = intel_guc_lookup_engine(guc, node->eng_class, 
node->eng_inst);
if (eng)
GCAP_PRINT_INTEL_ENG_INFO(ebuf, eng);
else
-   __out(ebuf, "i915-Eng-Lookup Fail!\n");
+   

[PATCH 0/7] Fixes and improvements to GuC logging and error capture

2022-07-27 Thread John . C . Harrison
From: John Harrison 

Fix bugs and improve the usability/effectiveness of GuC logging and
GuC related error captures.

Signed-off-by: John Harrison 


Alan Previn (1):
  drm/i915/guc: Add a helper for log buffer size

Chris Wilson (1):
  drm/i915/guc: Use streaming loads to speed up dumping the guc log

John Harrison (5):
  drm/i915/guc: Fix capture size warning and bump the size
  drm/i915/guc: Add GuC <-> kernel time stamp translation information
  drm/i915/guc: Record CTB info in error logs
  drm/i915/guc: Make GuC log sizes runtime configurable
  drm/i915/guc: Reduce spam from error capture

 drivers/gpu/drm/i915/gt/intel_gt_regs.h   |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  72 +++--
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   2 +
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 113 
 .../gpu/drm/i915/gt/uc/intel_guc_capture.h|   1 -
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c| 253 +++---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h|  42 +--
 drivers/gpu/drm/i915/i915_gpu_error.c |  67 -
 drivers/gpu/drm/i915/i915_gpu_error.h |  21 +-
 drivers/gpu/drm/i915/i915_params.c|  12 +
 drivers/gpu/drm/i915/i915_params.h|   3 +
 11 files changed, 427 insertions(+), 161 deletions(-)

-- 
2.37.1



Re: [PATCH v3 1/2] dt-bindings: display: panel: Add Novatek NT35596S panel bindings

2022-07-27 Thread Molly Sophia
Thanks! I'll handle that and send the new patches later.

Best regards,
Molly

On Wed, Jul 27, 2022 at 6:24 PM Krzysztof Kozlowski
 wrote:
>
> On 26/07/2022 12:15, Molly Sophia wrote:
> > Add documentation for "novatek,nt35596s" panel.
> >
> > Changes in v3:
> > - Embed the documentation into existing one (novatek,nt36672a).
> >
> > Signed-off-by: Molly Sophia 
> > ---
> >  .../display/panel/novatek,nt36672a.yaml   | 20 ---
> >  1 file changed, 13 insertions(+), 7 deletions(-)
> >
> > diff --git 
> > a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml 
> > b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> > index 563766d283f6..560fb66d0e5a 100644
> > --- a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> > +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> > @@ -20,14 +20,20 @@ allOf:
> >
> >  properties:
> >compatible:
> > -items:
> > -  - enum:
> > -  - tianma,fhd-video
> > -  - const: novatek,nt36672a
> > +oneOf:
> > +  - items:
> > +  - enum:
> > +  - tianma,fhd-video
> > +  - const: novatek,nt36672a
> > +
> > +  - items:
> > +  - enum:
> > +  - jdi,fhd-nt35596s
> > +  - const: novatek,nt35596s
>
> This entire entry should be rather before nt36672a judging by numbers:
>
> +oneOf:
> +  - items:
> +  - enum:
> +  - jdi,fhd-nt35596s
> +  - const: novatek,nt35596s
> +
> +  - items:
> +  - enum:
> +  - tianma,fhd-video
> +  - const: novatek,nt36672a
>
>
> Best regards,
> Krzysztof


Re: [PATCH] drm/i915/guc: Don't send policy update for child contexts.

2022-07-27 Thread John Harrison

On 7/27/2022 18:50, Ceraolo Spurio, Daniele wrote:

On 7/27/2022 6:44 PM, John Harrison wrote:

On 7/27/2022 17:33, Daniele Ceraolo Spurio wrote:

The GuC FW applies the parent context policy to all the children,
so individual updates to the children are not supported and we
should not send them.

Note that sending the message did not have any functional consequences,
because the GuC just drops it and logs an error; since we were trying
to set the child policy to match the parent anyway the message being
dropped was not a problem.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 

Needs a Fixes tag for the original v70 update patch?


I don't think so. I added the explanation about it not being a 
functional issue to make it clear that everything still works as 
expected without this patch, just with a bit of extra noise in the GuC 
logs. If you think it is still worth applying to older kernels I'll 
add the tag in.


Daniele
Hmm. It is strictly speaking a bug fix. But yes, the only impact is 
extra H2G traffic on context registration and in the GuC log. So maybe 
not worth worrying about.


Reviewed-by: John Harrison 





John.


---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 26 
+--

  1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

index 76916aed897a..5e31e2540297 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2420,7 +2420,6 @@ static int guc_context_policy_init_v70(struct 
intel_context *ce, bool loop)

  struct context_policy policy;
  u32 execution_quantum;
  u32 preemption_timeout;
-    bool missing = false;
  unsigned long flags;
  int ret;
  @@ -2438,32 +2437,9 @@ static int 
guc_context_policy_init_v70(struct intel_context *ce, bool loop)

__guc_context_policy_add_preempt_to_idle(, 1);
    ret = __guc_context_set_context_policies(guc, , loop);
-    missing = ret != 0;
-
-    if (!missing && intel_context_is_parent(ce)) {
-    struct intel_context *child;
-
-    for_each_child(ce, child) {
-    __guc_context_policy_start_klv(, child->guc_id.id);
-
-    if (engine->flags & I915_ENGINE_WANT_FORCED_PREEMPTION)
- __guc_context_policy_add_preempt_to_idle(, 1);
-
-    child->guc_state.prio = ce->guc_state.prio;
-    __guc_context_policy_add_priority(, 
ce->guc_state.prio);
- __guc_context_policy_add_execution_quantum(, 
execution_quantum);
- __guc_context_policy_add_preemption_timeout(, 
preemption_timeout);

-
-    ret = __guc_context_set_context_policies(guc, , 
loop);

-    if (ret) {
-    missing = true;
-    break;
-    }
-    }
-    }
    spin_lock_irqsave(>guc_state.lock, flags);
-    if (missing)
+    if (ret != 0)
  set_context_policy_required(ce);
  else
  clr_context_policy_required(ce);








Re: [PATCH] drm/i915/guc: Don't send policy update for child contexts.

2022-07-27 Thread Ceraolo Spurio, Daniele




On 7/27/2022 6:44 PM, John Harrison wrote:

On 7/27/2022 17:33, Daniele Ceraolo Spurio wrote:

The GuC FW applies the parent context policy to all the children,
so individual updates to the children are not supported and we
should not send them.

Note that sending the message did not have any functional consequences,
because the GuC just drops it and logs an error; since we were trying
to set the child policy to match the parent anyway the message being
dropped was not a problem.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 

Needs a Fixes tag for the original v70 update patch?


I don't think so. I added the explanation about it not being a 
functional issue to make it clear that everything still works as 
expected without this patch, just with a bit of extra noise in the GuC 
logs. If you think it is still worth applying to older kernels I'll add 
the tag in.


Daniele



John.


---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 26 +--
  1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

index 76916aed897a..5e31e2540297 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2420,7 +2420,6 @@ static int guc_context_policy_init_v70(struct 
intel_context *ce, bool loop)

  struct context_policy policy;
  u32 execution_quantum;
  u32 preemption_timeout;
-    bool missing = false;
  unsigned long flags;
  int ret;
  @@ -2438,32 +2437,9 @@ static int 
guc_context_policy_init_v70(struct intel_context *ce, bool loop)

  __guc_context_policy_add_preempt_to_idle(, 1);
    ret = __guc_context_set_context_policies(guc, , loop);
-    missing = ret != 0;
-
-    if (!missing && intel_context_is_parent(ce)) {
-    struct intel_context *child;
-
-    for_each_child(ce, child) {
-    __guc_context_policy_start_klv(, child->guc_id.id);
-
-    if (engine->flags & I915_ENGINE_WANT_FORCED_PREEMPTION)
- __guc_context_policy_add_preempt_to_idle(, 1);
-
-    child->guc_state.prio = ce->guc_state.prio;
-    __guc_context_policy_add_priority(, 
ce->guc_state.prio);
- __guc_context_policy_add_execution_quantum(, 
execution_quantum);
- __guc_context_policy_add_preemption_timeout(, 
preemption_timeout);

-
-    ret = __guc_context_set_context_policies(guc, , 
loop);

-    if (ret) {
-    missing = true;
-    break;
-    }
-    }
-    }
    spin_lock_irqsave(>guc_state.lock, flags);
-    if (missing)
+    if (ret != 0)
  set_context_policy_required(ce);
  else
  clr_context_policy_required(ce);






Re: [PATCH] drm/i915/guc: Don't send policy update for child contexts.

2022-07-27 Thread John Harrison

On 7/27/2022 17:33, Daniele Ceraolo Spurio wrote:

The GuC FW applies the parent context policy to all the children,
so individual updates to the children are not supported and we
should not send them.

Note that sending the message did not have any functional consequences,
because the GuC just drops it and logs an error; since we were trying
to set the child policy to match the parent anyway the message being
dropped was not a problem.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 

Needs a Fixes tag for the original v70 update patch?

John.


---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 26 +--
  1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 76916aed897a..5e31e2540297 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2420,7 +2420,6 @@ static int guc_context_policy_init_v70(struct 
intel_context *ce, bool loop)
struct context_policy policy;
u32 execution_quantum;
u32 preemption_timeout;
-   bool missing = false;
unsigned long flags;
int ret;
  
@@ -2438,32 +2437,9 @@ static int guc_context_policy_init_v70(struct intel_context *ce, bool loop)

__guc_context_policy_add_preempt_to_idle(, 1);
  
  	ret = __guc_context_set_context_policies(guc, , loop);

-   missing = ret != 0;
-
-   if (!missing && intel_context_is_parent(ce)) {
-   struct intel_context *child;
-
-   for_each_child(ce, child) {
-   __guc_context_policy_start_klv(, 
child->guc_id.id);
-
-   if (engine->flags & I915_ENGINE_WANT_FORCED_PREEMPTION)
-   
__guc_context_policy_add_preempt_to_idle(, 1);
-
-   child->guc_state.prio = ce->guc_state.prio;
-   __guc_context_policy_add_priority(, 
ce->guc_state.prio);
-   __guc_context_policy_add_execution_quantum(, 
execution_quantum);
-   __guc_context_policy_add_preemption_timeout(, 
preemption_timeout);
-
-   ret = __guc_context_set_context_policies(guc, , 
loop);
-   if (ret) {
-   missing = true;
-   break;
-   }
-   }
-   }
  
  	spin_lock_irqsave(>guc_state.lock, flags);

-   if (missing)
+   if (ret != 0)
set_context_policy_required(ce);
else
clr_context_policy_required(ce);




[PATCH v3] gpu/drm/bridge/cadence: avoid flush_scheduled_work() usage

2022-07-27 Thread Tetsuo Handa
Like commit c4f135d643823a86 ("workqueue: Wrap flush_workqueue() using a
macro") says, flush_scheduled_work() is dangerous and will be forbidden.
We are on the way for removing all flush_scheduled_work() callers from
the kernel, and this patch is for removing flush_scheduled_work() call
 from cadence driver.

Since cdns-mhdp8546 driver uses 4 works

  mhdp->modeset_retry_work
  mhdp->hpd_work
  mhdp->hdcp.check_work
  mhdp->hdcp.prop_work

I assume that flush_scheduled_work() in cdns_mhdp_remove() needs to wait
for only these 4 works.

Since mhdp->modeset_retry_work already uses cancel_work_sync(), I assume
that flush_scheduled_work() needs to wait for only 3 works. But I came to
wonder whether mhdp->hdcp.check_work should be flushed or cancelled.

While flush_scheduled_work() waits for completion of works which were
already queued to system_wq, mhdp->hdcp.check_work is a delayed work.
That is, this work won't be queued to system_wq unless timeout expires.

Current code will wait for mhdp->hdcp.check_work only if timeout already
expired. If timeout is not expired yet, flush_scheduled_work() will fail
to cancel mhdp->hdcp.check_work, and cdns_mhdp_hdcp_check_work() which is
triggered by mhdp->hdcp.check_work will schedule hdcp->check_work, which
is too late for flush_scheduled_work() to wait for completion of
cdns_mhdp_hdcp_prop_work().

But since I couldn't get comments on how do we want to handle this race
window [1], this patch chose "do nothing" for mhdp->hdcp.check_work and
mhdp->hdcp.prop_work. That is, I assume that flush_scheduled_work() in
cdns_mhdp_remove() needs to wait for only mhdp->hpd_work work.

Link: 
https://lkml.kernel.org/r/943273cb-c2ec-24e3-5edb-64eacc6e2...@i-love.sakura.ne.jp
 [1]
Signed-off-by: Tetsuo Handa 
---
 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index ab63e7b11944..31442a922502 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -2605,7 +2605,8 @@ static int cdns_mhdp_remove(struct platform_device *pdev)
pm_runtime_disable(>dev);
 
cancel_work_sync(>modeset_retry_work);
-   flush_scheduled_work();
+   flush_work(>hpd_work);
+   /* Ignoring mhdp->hdcp.check_work and mhdp->hdcp.prop_work here. */
 
clk_disable_unprepare(mhdp->clk);
 
-- 
2.18.4


[PATCH] drm/i915/guc: Don't send policy update for child contexts.

2022-07-27 Thread Daniele Ceraolo Spurio
The GuC FW applies the parent context policy to all the children,
so individual updates to the children are not supported and we
should not send them.

Note that sending the message did not have any functional consequences,
because the GuC just drops it and logs an error; since we were trying
to set the child policy to match the parent anyway the message being
dropped was not a problem.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 26 +--
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 76916aed897a..5e31e2540297 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2420,7 +2420,6 @@ static int guc_context_policy_init_v70(struct 
intel_context *ce, bool loop)
struct context_policy policy;
u32 execution_quantum;
u32 preemption_timeout;
-   bool missing = false;
unsigned long flags;
int ret;
 
@@ -2438,32 +2437,9 @@ static int guc_context_policy_init_v70(struct 
intel_context *ce, bool loop)
__guc_context_policy_add_preempt_to_idle(, 1);
 
ret = __guc_context_set_context_policies(guc, , loop);
-   missing = ret != 0;
-
-   if (!missing && intel_context_is_parent(ce)) {
-   struct intel_context *child;
-
-   for_each_child(ce, child) {
-   __guc_context_policy_start_klv(, 
child->guc_id.id);
-
-   if (engine->flags & I915_ENGINE_WANT_FORCED_PREEMPTION)
-   
__guc_context_policy_add_preempt_to_idle(, 1);
-
-   child->guc_state.prio = ce->guc_state.prio;
-   __guc_context_policy_add_priority(, 
ce->guc_state.prio);
-   __guc_context_policy_add_execution_quantum(, 
execution_quantum);
-   __guc_context_policy_add_preemption_timeout(, 
preemption_timeout);
-
-   ret = __guc_context_set_context_policies(guc, , 
loop);
-   if (ret) {
-   missing = true;
-   break;
-   }
-   }
-   }
 
spin_lock_irqsave(>guc_state.lock, flags);
-   if (missing)
+   if (ret != 0)
set_context_policy_required(ce);
else
clr_context_policy_required(ce);
-- 
2.25.1



Re: [PATCH v2 0/7] drm/msm/dsi regulator improvements

2022-07-27 Thread Mark Brown
On Tue, Jul 26, 2022 at 10:38:17AM -0700, Douglas Anderson wrote:

> * After that I have patches that add to the regulator API and then
>   show a usage of those in the DSI driver. I'd expect that the two
>   regulator patches could land in the regulator tree. The DSI patches
>   would need to wait until the new regulator changes are available.

The following changes since commit f2906aa863381afb0015a9eb7fefad885d4e5a56:

  Linux 5.19-rc1 (2022-06-05 17:18:54 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 
tags/regulator-load-bulk-api

for you to fetch changes up to 1de452a0edda26f1483d1d934f692eab13ba669a:

  regulator: core: Allow drivers to define their init data as const (2022-07-27 
13:47:30 +0100)


regulator: Consumer load management improvements

The main goal of this series is to make a small dent in cleaning up
the way we deal with regulator loads. The idea is to add some extra
functionality to the regulator "bulk" API so that consumers can
specify the load using that.


Douglas Anderson (2):
  regulator: core: Allow specifying an initial load w/ the bulk API
  regulator: core: Allow drivers to define their init data as const

 drivers/regulator/core.c   | 20 
 drivers/regulator/devres.c | 28 
 include/linux/regulator/consumer.h | 16 
 3 files changed, 52 insertions(+), 12 deletions(-)


signature.asc
Description: PGP signature


RE: [PATCH] drm/i915/ttm: don't leak the ccs state

2022-07-27 Thread C, Ramalingam
> -Original Message-
> From: Auld, Matthew 
> Sent: Wednesday, July 27, 2022 10:14 PM
> To: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Thomas Hellström 
> ; C,
> Ramalingam 
> Subject: [PATCH] drm/i915/ttm: don't leak the ccs state
> 
> The kernel only manages the ccs state with lmem-only objects, however the 
> kernel should still take
> care not to leak the CCS state from the previous user.
> 
> Fixes: 48760ffe923a ("drm/i915/gt: Clear compress metadata for Flat-ccs 
> objects")
> Signed-off-by: Matthew Auld 
> Cc: Thomas Hellström 
> Cc: Ramalingam C 
> ---
>  drivers/gpu/drm/i915/gt/intel_migrate.c | 23 ++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c 
> b/drivers/gpu/drm/i915/gt/intel_migrate.c
> index a69b244f14d0..9a0814422ba4 100644
> --- a/drivers/gpu/drm/i915/gt/intel_migrate.c
> +++ b/drivers/gpu/drm/i915/gt/intel_migrate.c
> @@ -708,7 +708,7 @@ intel_context_migrate_copy(struct intel_context *ce,
>   u8 src_access, dst_access;
>   struct i915_request *rq;
>   int src_sz, dst_sz;
> - bool ccs_is_src;
> + bool ccs_is_src, overwrite_ccs;
>   int err;
> 
>   GEM_BUG_ON(ce->vm != ce->engine->gt->migrate.context->vm);
> @@ -749,6 +749,8 @@ intel_context_migrate_copy(struct intel_context *ce,
>   get_ccs_sg_sgt(_ccs, bytes_to_cpy);
>   }
> 
> + overwrite_ccs = HAS_FLAT_CCS(i915) && !ccs_bytes_to_cpy &&
> +dst_is_lmem;
> +
>   src_offset = 0;
>   dst_offset = CHUNK_SZ;
>   if (HAS_64K_PAGES(ce->engine->i915)) { @@ -852,6 +854,25 @@
> intel_context_migrate_copy(struct intel_context *ce,
>   if (err)
>   goto out_rq;
>   ccs_bytes_to_cpy -= ccs_sz;
> + } else if (overwrite_ccs) {
> + err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
> + if (err)
> + goto out_rq;
> +
> + /*
> +  * While we can't always restore/manage the CCS state,
> +  * we still need to ensure we don't leak the CCS state
> +  * from the previous user, so make sure we overwrite it
> +  * with something.
> +  */
> + err = emit_copy_ccs(rq, dst_offset, INDIRECT_ACCESS,
> + dst_offset, DIRECT_ACCESS, len);
> + if (err)
> + goto out_rq;
> +
> + err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
> + if (err)
> + goto out_rq;
The change is looking good to the purpose. But shouldn't this be the part of 
lmem allocation itself?

Ram.
>   }
> 
>   /* Arbitration is re-enabled between requests. */
> --
> 2.37.1



[PATCH] drm/amdgpu: Fix stub fence refcount underflow

2022-07-27 Thread Felix Kuehling
Don't drop the stub fence reference after installing it as a replacement
for the eviction fence. dma_resv_replace_fences doesn't take another
reference to the fence, so it takes ownership of the reference passed
in by us.

Fixes: 548e7432dc2d ("dma-buf: add dma_resv_replace_fences v2")
CC: Christian König 
Signed-off-by: Felix Kuehling 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 87a3a3ae9448..a6c7dcd8c345 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -294,7 +294,6 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct 
amdgpu_bo *bo,
replacement = dma_fence_get_stub();
dma_resv_replace_fences(bo->tbo.base.resv, ef->base.context,
replacement, DMA_RESV_USAGE_READ);
-   dma_fence_put(replacement);
return 0;
 }
 
-- 
2.32.0



Re: (subset) [PATCH v2 0/7] drm/msm/dsi regulator improvements

2022-07-27 Thread Mark Brown
On Tue, 26 Jul 2022 10:38:17 -0700, Douglas Anderson wrote:
> The main goal of this series is to make a small dent in cleaning up
> the way we deal with regulator loads. The idea is to add some extra
> functionality to the regulator "bulk" API so that consumers can
> specify the load using that. Though I didn't convert everyone over, I
> include patches in this series that show how the Qualcomm DSI driver
> is improved by this.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 
for-next

Thanks!

[4/7] regulator: core: Allow specifying an initial load w/ the bulk API
  commit: 6eabfc018e8d1033e7fc1efce30a872e2dccb537
[6/7] regulator: core: Allow drivers to define their init data as const
  commit: 1de452a0edda26f1483d1d934f692eab13ba669a

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


Re: [PATCH] mm: Fix a null ptr deref with CONFIG_DEBUG_VM enabled in wp_page_reuse

2022-07-27 Thread Zack Rusin
On Wed, 2022-07-27 at 20:24 +0100, Matthew Wilcox wrote:
> On Wed, Jul 27, 2022 at 03:14:07PM -0400, Zack Rusin wrote:
> > From: Zack Rusin 
> > 
> > Write page faults on last references might not have a valid page anymore.
> > wp_page_reuse has always dealt with that scenario by making
> > sure the page isn't null (or the reference was shared) before doing
> > anything with it. Recently added checks in VM_BUG_ON (enabled by the
> > CONFIG_DEBUG_VM option) use PageAnon helpers which assume the passed
> > page is never null, before making sure there is a valid page to work
> > with.
> > 
> > Move the VM_BUG_ON, which unconditionally uses the page, after the
> > code that checks that we have a valid one.
> 
> Message-ID: 
> 

Ah, great, thanks.

z


Re: [PATCH] mm: Fix a null ptr deref with CONFIG_DEBUG_VM enabled in wp_page_reuse

2022-07-27 Thread Matthew Wilcox
On Wed, Jul 27, 2022 at 03:14:07PM -0400, Zack Rusin wrote:
> From: Zack Rusin 
> 
> Write page faults on last references might not have a valid page anymore.
> wp_page_reuse has always dealt with that scenario by making
> sure the page isn't null (or the reference was shared) before doing
> anything with it. Recently added checks in VM_BUG_ON (enabled by the
> CONFIG_DEBUG_VM option) use PageAnon helpers which assume the passed
> page is never null, before making sure there is a valid page to work
> with.
> 
> Move the VM_BUG_ON, which unconditionally uses the page, after the
> code that checks that we have a valid one.

Message-ID: 



[PATCH] mm: Fix a null ptr deref with CONFIG_DEBUG_VM enabled in wp_page_reuse

2022-07-27 Thread Zack Rusin
From: Zack Rusin 

Write page faults on last references might not have a valid page anymore.
wp_page_reuse has always dealt with that scenario by making
sure the page isn't null (or the reference was shared) before doing
anything with it. Recently added checks in VM_BUG_ON (enabled by the
CONFIG_DEBUG_VM option) use PageAnon helpers which assume the passed
page is never null, before making sure there is a valid page to work
with.

Move the VM_BUG_ON, which unconditionally uses the page, after the
code that checks that we have a valid one.

Fixes a kernel oops, which is easy to reproduce with 3D apps on arm64 and
x86 on kernels with CONFIG_DEBUG_VM set:

Unable to handle kernel paging request at virtual address dfff8001
KASAN: null-ptr-deref in range [0x0008-0x000f]
Mem abort info:
  ESR = 0x9604
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x04: level 0 translation fault
Data abort info:
  ISV = 0, ISS = 0x0004
  CM = 0, WnR = 0
[dfff8001] address between user and kernel address ranges
Internal error: Oops: 9604 [#1] SMP
CPU: 0 PID: 2396 Comm: Xwayland Tainted: G U5.19.0-rc2-vmwgfx 
#28
Hardware name: VMware, Inc. VMware20,1/VBSA, BIOS 
VMW201.00V.20138482.BA64.2207201941 07/20/2022
pstate: 1045 (nzcV daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : _compound_head+0x24/0xd0
lr : wp_page_reuse+0x8c/0x544
sp : 800013637aa0
x29: 800013637aa0 x28: 2a28b730 x27: 800013637cc8
x26:  x25: 800013637d00 x24: 0c742168
x23: 126c6fa0 x22: 13ce59a0 x21: 2a28b730
x20:  x19:  x18: 
x17:  x16:  x15: 
x14: 126c6f22 x13: 65676170206c6c75 x12: 600019dc772f
x11: 1fffe00019dc772e x10: 600019dc772e x9 : 885b1a78
x8 : cee3b977 x7 : 0001 x6 : 600019dc772e
x5 : cee3b970 x4 : 600019dc772f x3 : 126c6f99
x2 : 0001 x1 : dfff8000 x0 : 0008
Call trace:
 _compound_head+0x24/0xd0
 wp_page_reuse+0x8c/0x544
 finish_mkwrite_fault+0x1a0/0x274
 do_wp_page+0x6cc/0x1000
 __handle_mm_fault+0xdc8/0x2620
 handle_mm_fault+0x21c/0x530
 do_page_fault+0x250/0xa40
 do_mem_abort+0x78/0x1b4
 el0_da+0x80/0x1c0
 el0t_64_sync_handler+0xf8/0x140
 el0t_64_sync+0x1a0/0x1a4
Code: aa0003f3 91002000 f2fbffe1 d343fc02 (38e16841)
---[ end trace  ]---

Fixes: 6c287605fd56 ("mm: remember exclusively mapped anonymous pages with 
PG_anon_exclusive")
Signed-off-by: Zack Rusin 
Cc: David Hildenbrand 
Cc: Vlastimil Babka 
Cc: Andrea Arcangeli 
Cc: Christoph Hellwig 
Cc: David Rientjes 
Cc: Don Dutile 
Cc: Hugh Dickins 
Cc: Jan Kara 
Cc: Jann Horn 
Cc: Jason Gunthorpe 
Cc: John Hubbard 
Cc: Khalid Aziz 
Cc: "Kirill A. Shutemov" 
Cc: Liang Zhang 
Cc: "Matthew Wilcox (Oracle)" 
Cc: Michal Hocko 
Cc: Mike Kravetz 
Cc: Mike Rapoport 
Cc: Nadav Amit 
Cc: Oded Gabbay 
Cc: Oleg Nesterov 
Cc: Pedro Demarchi Gomes 
Cc: Peter Xu 
Cc: Rik van Riel 
Cc: Roman Gushchin 
Cc: Shakeel Butt 
Cc: Yang Shi 
Cc: Andrew Morton 
Cc: Muchun Song 
Cc: Minchan Kim 
Cc: David Howells 
Cc: Miaohe Lin 
Cc: NeilBrown 
Cc: Suren Baghdasaryan 
Cc: Hongchen Zhang 
Cc: linux...@kvack.org
---
 mm/memory.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 7a089145cad4..3e28c652cf60 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3043,15 +3043,16 @@ static inline void wp_page_reuse(struct vm_fault *vmf)
pte_t entry;
 
VM_BUG_ON(!(vmf->flags & FAULT_FLAG_WRITE));
-   VM_BUG_ON(PageAnon(page) && !PageAnonExclusive(page));
 
/*
 * Clear the pages cpupid information as the existing
 * information potentially belongs to a now completely
 * unrelated process.
 */
-   if (page)
+   if (page) {
+   VM_BUG_ON(PageAnon(page) && !PageAnonExclusive(page));
page_cpupid_xchg_last(page, (1 << LAST_CPUPID_SHIFT) - 1);
+   }
 
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
entry = pte_mkyoung(vmf->orig_pte);
-- 
2.34.1



Re: [PATCH] dt-bindings: display: use spi-peripheral-props.yaml

2022-07-27 Thread Sam Ravnborg
Hi Krzysztof,

On Wed, Jul 27, 2022 at 06:43:12PM +0200, Krzysztof Kozlowski wrote:
> Instead of listing directly properties typical for SPI peripherals,
> reference the spi-peripheral-props.yaml schema.  This allows using all
> properties typical for SPI-connected devices, even these which device
> bindings author did not tried yet.
> 
> Remove the spi-* properties which now come via spi-peripheral-props.yaml
> schema, except for the cases when device schema adds some constraints
> like maximum frequency.
> 
> While changing additionalProperties->unevaluatedProperties, put it in
> typical place, just before example DTS.
> 
> The sitronix,st7735r references also panel-common.yaml and lists
> explicitly allowed properties, thus here reference only
> spi-peripheral-props.yaml for purpose of documenting the SPI slave
> device and bringing spi-max-frequency type validation.
> 
> Signed-off-by: Krzysztof Kozlowski 
Acked-by: Sam Ravnborg 

I assume this will be added to the same tree as the SPI CPHA and CPOL
patch.

Sam


[PATCH] drm/i915/ttm: don't leak the ccs state

2022-07-27 Thread Matthew Auld
The kernel only manages the ccs state with lmem-only objects, however
the kernel should still take care not to leak the CCS state from the
previous user.

Fixes: 48760ffe923a ("drm/i915/gt: Clear compress metadata for Flat-ccs 
objects")
Signed-off-by: Matthew Auld 
Cc: Thomas Hellström 
Cc: Ramalingam C 
---
 drivers/gpu/drm/i915/gt/intel_migrate.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c 
b/drivers/gpu/drm/i915/gt/intel_migrate.c
index a69b244f14d0..9a0814422ba4 100644
--- a/drivers/gpu/drm/i915/gt/intel_migrate.c
+++ b/drivers/gpu/drm/i915/gt/intel_migrate.c
@@ -708,7 +708,7 @@ intel_context_migrate_copy(struct intel_context *ce,
u8 src_access, dst_access;
struct i915_request *rq;
int src_sz, dst_sz;
-   bool ccs_is_src;
+   bool ccs_is_src, overwrite_ccs;
int err;
 
GEM_BUG_ON(ce->vm != ce->engine->gt->migrate.context->vm);
@@ -749,6 +749,8 @@ intel_context_migrate_copy(struct intel_context *ce,
get_ccs_sg_sgt(_ccs, bytes_to_cpy);
}
 
+   overwrite_ccs = HAS_FLAT_CCS(i915) && !ccs_bytes_to_cpy && dst_is_lmem;
+
src_offset = 0;
dst_offset = CHUNK_SZ;
if (HAS_64K_PAGES(ce->engine->i915)) {
@@ -852,6 +854,25 @@ intel_context_migrate_copy(struct intel_context *ce,
if (err)
goto out_rq;
ccs_bytes_to_cpy -= ccs_sz;
+   } else if (overwrite_ccs) {
+   err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
+   if (err)
+   goto out_rq;
+
+   /*
+* While we can't always restore/manage the CCS state,
+* we still need to ensure we don't leak the CCS state
+* from the previous user, so make sure we overwrite it
+* with something.
+*/
+   err = emit_copy_ccs(rq, dst_offset, INDIRECT_ACCESS,
+   dst_offset, DIRECT_ACCESS, len);
+   if (err)
+   goto out_rq;
+
+   err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
+   if (err)
+   goto out_rq;
}
 
/* Arbitration is re-enabled between requests. */
-- 
2.37.1



[PATCH] dt-bindings: display: use spi-peripheral-props.yaml

2022-07-27 Thread Krzysztof Kozlowski
Instead of listing directly properties typical for SPI peripherals,
reference the spi-peripheral-props.yaml schema.  This allows using all
properties typical for SPI-connected devices, even these which device
bindings author did not tried yet.

Remove the spi-* properties which now come via spi-peripheral-props.yaml
schema, except for the cases when device schema adds some constraints
like maximum frequency.

While changing additionalProperties->unevaluatedProperties, put it in
typical place, just before example DTS.

The sitronix,st7735r references also panel-common.yaml and lists
explicitly allowed properties, thus here reference only
spi-peripheral-props.yaml for purpose of documenting the SPI slave
device and bringing spi-max-frequency type validation.

Signed-off-by: Krzysztof Kozlowski 

---

Technically, this depends on [1] merged to SPI tree, if we want to
preserve existing behavior of not allowing SPI CPHA and CPOL in each of
schemas in this patch.

If this patch comes independently via different tree, the SPI CPHA and
CPOL will be allowed for brief period of time, before [1] is merged.
This will not have negative impact, just DT schema checks will be
loosened for that period.

[1] 
https://lore.kernel.org/all/20220722191539.90641-2-krzysztof.kozlow...@linaro.org/
---
 .../devicetree/bindings/display/panel/lg,lg4573.yaml   | 2 +-
 .../devicetree/bindings/display/sitronix,st7735r.yaml  | 1 +
 .../devicetree/bindings/display/solomon,ssd1307fb.yaml | 7 +++
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml 
b/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml
index b4314ce7b411..ee357e139ac0 100644
--- a/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml
+++ b/Documentation/devicetree/bindings/display/panel/lg,lg4573.yaml
@@ -15,13 +15,13 @@ maintainers:
 
 allOf:
   - $ref: panel-common.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
 
 properties:
   compatible:
 const: lg,lg4573
 
   reg: true
-  spi-max-frequency: true
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml 
b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
index 157b1a7b18f9..53f181ef3670 100644
--- a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
+++ b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
@@ -15,6 +15,7 @@ description:
 
 allOf:
   - $ref: panel/panel-common.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml 
b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
index 3fbd87c2c120..669f70b1b4c4 100644
--- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
+++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
@@ -49,9 +49,6 @@ properties:
   vbat-supply:
 description: The supply for VBAT
 
-  # Only required for SPI
-  spi-max-frequency: true
-
   solomon,height:
 $ref: /schemas/types.yaml#/definitions/uint32
 default: 16
@@ -153,6 +150,8 @@ required:
   - reg
 
 allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
   - if:
   properties:
 compatible:
@@ -223,7 +222,7 @@ allOf:
 solomon,dclk-frq:
   default: 10
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
-- 
2.34.1



[PATCH v5 10/10] drm: rcar-du: Add RZ/G2L DU Support

2022-07-27 Thread Biju Das
The LCD controller is composed of Frame Compression Processor (FCPVD),
Video Signal Processor (VSPD), and Display Unit (DU).

It has DPI/DSI interfaces and supports a maximum resolution of 1080p
along with 2 RPFs to support blending of two picture layers and
raster operations (ROPs).

The DU part is similar to RCar like DU is connected to VSPD, so most of
the framework related functionality is based on RCar DU.

Signed-off-by: Biju Das 
---
v4->v5:
 * Started using RCar DU libs(kms, vsp and encoder)
 * Started using rcar_du_device, rcar_du_write, rcar_du_crtc,
   rcar_du_format_info and rcar_du_encoder.
v3->v4:
 * Removed rzg2l_du_group.h and struct rzg2l_du_group
 * Renamed __rzg2l_du_group_start_stop->rzg2l_du_start_stop
 * Removed rzg2l_du_group_restart
 * Updated rzg2l_du_crtc_set_display_timing
 * Removed mode_valid callback.
 * Updated rzg2l_du_crtc_create() parameters
 * Updated compatible
 * Removed RZG2L_DU_MAX_GROUPS
v3:
 * New patch after removing all the indirections and by adding
   new DRM driver.
---
 drivers/gpu/drm/rcar-du/Kconfig|  17 +-
 drivers/gpu/drm/rcar-du/Makefile   |  13 +
 drivers/gpu/drm/rcar-du/rzg2l_du_crtc.c| 718 +
 drivers/gpu/drm/rcar-du/rzg2l_du_crtc.h|  26 +
 drivers/gpu/drm/rcar-du/rzg2l_du_drv.c | 206 ++
 drivers/gpu/drm/rcar-du/rzg2l_du_drv.h |  20 +
 drivers/gpu/drm/rcar-du/rzg2l_du_encoder.c |  26 +
 drivers/gpu/drm/rcar-du/rzg2l_du_encoder.h |  19 +
 drivers/gpu/drm/rcar-du/rzg2l_du_kms.c | 158 +
 drivers/gpu/drm/rcar-du/rzg2l_du_kms.h |  17 +
 drivers/gpu/drm/rcar-du/rzg2l_du_regs.h|  67 ++
 drivers/gpu/drm/rcar-du/rzg2l_du_vsp.c |  82 +++
 drivers/gpu/drm/rcar-du/rzg2l_du_vsp.h |  29 +
 13 files changed, 1396 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_crtc.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_crtc.h
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_drv.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_drv.h
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_encoder.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_encoder.h
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_kms.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_kms.h
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_regs.h
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_vsp.c
 create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_du_vsp.h

diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index f8e1341be5f8..c45416197a2b 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -11,6 +11,18 @@ config DRM_RCAR_DU
  Choose this option if you have an R-Car chipset.
  If M is selected the module will be called rcar-du-drm.
 
+config DRM_RZG2L_DU
+   tristate "DRM Support for RZ/G2L DU"
+   depends on DRM && OF
+   depends on ARM || ARM64
+   depends on ARCH_RENESAS || COMPILE_TEST
+   select DRM_KMS_HELPER
+   select DRM_GEM_CMA_HELPER
+   select VIDEOMODE_HELPERS
+   help
+ Choose this option if you have an RZ/G2L chipset.
+ If M is selected the module will be called rzg2l-du-drm.
+
 config DRM_RCAR_USE_CMM
bool "R-Car DU Color Management Module (CMM) Support"
depends on DRM_RCAR_DU
@@ -62,8 +74,9 @@ config DRM_RZG2L_MIPI_DSI
 config DRM_RCAR_VSP
bool "R-Car DU VSP Compositor Support" if ARM
default y if ARM64
-   depends on DRM_RCAR_DU
+   depends on DRM_RCAR_DU || DRM_RZG2L_DU
depends on VIDEO_RENESAS_VSP1=y || (VIDEO_RENESAS_VSP1 && DRM_RCAR_DU=m)
+   depends on VIDEO_RENESAS_VSP1=y || (VIDEO_RENESAS_VSP1 && 
DRM_RZG2L_DU=m)
help
  Enable support to expose the R-Car VSP Compositor as KMS planes.
 
@@ -75,7 +88,7 @@ config DRM_RCAR_WRITEBACK
 config DRM_RCAR_LIB
bool
default y
-   depends on DRM_RCAR_DU
+   depends on DRM_RCAR_DU || DRM_RZG2L_DU
 
 config DRM_RCAR_VSP_LIB
bool
diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile
index cee1f69926db..445ff4e7186f 100644
--- a/drivers/gpu/drm/rcar-du/Makefile
+++ b/drivers/gpu/drm/rcar-du/Makefile
@@ -19,6 +19,19 @@ obj-$(CONFIG_DRM_RCAR_DW_HDMI)   += 
rcar_dw_hdmi.o
 obj-$(CONFIG_DRM_RCAR_LVDS)+= rcar_lvds.o
 obj-$(CONFIG_DRM_RCAR_MIPI_DSI)+= rcar_mipi_dsi.o
 
+rzg2l-du-drm-y := rzg2l_du_crtc.o \
+ rzg2l_du_drv.o \
+ rzg2l_du_encoder.o \
+ rzg2l_du_kms.o \
+
+rzg2l-du-drm-$(CONFIG_DRM_RCAR_LIB) += rcar_du_encoder_lib.o \
+  rcar_du_kms_lib.o
+
+rzg2l-du-drm-$(CONFIG_DRM_RCAR_VSP)+= rzg2l_du_vsp.o
+rzg2l-du-drm-$(CONFIG_DRM_RCAR_VSP_LIB)+= rcar_du_vsp_lib.o
+rzg2l-du-drm-$(CONFIG_DRM_RCAR_WRITEBACK) += rcar_du_writeback.o
+
+obj-$(CONFIG_DRM_RZG2L_DU) += rzg2l-du-drm.o
 

[PATCH v5 05/10] drm: rcar-du: Add rcar_du_lib_mode_cfg_helper_fns()

2022-07-27 Thread Biju Das
Add rcar_du_lib_mode_cfg_helper_fns() in RCar DU kms lib to get the
pointer to rcar_du_mode_config_helper, so that both rcar_du_atomic_
commit_tail() and rcar_du_mode_config_helper can be reused by
rcar_du_modeset_init() and rzg2l_du_modeset_init().

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 44 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c | 56 +++
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h |  3 ++
 3 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 9d65a7d6d96e..ed8d14701178 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -64,52 +64,10 @@ static int rcar_du_atomic_check(struct drm_device *dev,
return rcar_du_atomic_check_planes(dev, state);
 }
 
-static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
-{
-   struct drm_device *dev = old_state->dev;
-   struct rcar_du_device *rcdu = to_rcar_du_device(dev);
-   struct drm_crtc_state *crtc_state;
-   struct drm_crtc *crtc;
-   unsigned int i;
-
-   /*
-* Store RGB routing to DPAD0 and DPAD1, the hardware will be configured
-* when starting the CRTCs.
-*/
-   rcdu->dpad1_source = -1;
-
-   for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
-   struct rcar_du_crtc_state *rcrtc_state =
-   to_rcar_crtc_state(crtc_state);
-   struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
-   if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0))
-   rcdu->dpad0_source = rcrtc->index;
-
-   if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
-   rcdu->dpad1_source = rcrtc->index;
-   }
-
-   /* Apply the atomic update. */
-   drm_atomic_helper_commit_modeset_disables(dev, old_state);
-   drm_atomic_helper_commit_planes(dev, old_state,
-   DRM_PLANE_COMMIT_ACTIVE_ONLY);
-   drm_atomic_helper_commit_modeset_enables(dev, old_state);
-
-   drm_atomic_helper_commit_hw_done(old_state);
-   drm_atomic_helper_wait_for_flip_done(dev, old_state);
-
-   drm_atomic_helper_cleanup_planes(dev, old_state);
-}
-
 /* 
-
  * Initialization
  */
 
-static const struct drm_mode_config_helper_funcs rcar_du_mode_config_helper = {
-   .atomic_commit_tail = rcar_du_atomic_commit_tail,
-};
-
 static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
.fb_create = rcar_du_fb_create,
.atomic_check = rcar_du_atomic_check,
@@ -415,7 +373,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
dev->mode_config.min_height = 0;
dev->mode_config.normalize_zpos = true;
dev->mode_config.funcs = _du_mode_config_funcs;
-   dev->mode_config.helper_private = _du_mode_config_helper;
+   dev->mode_config.helper_private = rcar_du_lib_mode_cfg_helper_fns();
 
if (rcdu->info->gen < 3) {
dev->mode_config.max_width = 4095;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
index d8f778a7b6db..a1027436cfe3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
@@ -461,3 +461,59 @@ rcar_du_lib_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
 
return drm_gem_fb_create(dev, file_priv, mode_cmd);
 }
+
+/* 
-
+ * Atomic Check and Update
+ */
+
+static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
+{
+   struct drm_device *dev = old_state->dev;
+   struct rcar_du_device *rcdu = to_rcar_du_device(dev);
+   struct drm_crtc_state *crtc_state;
+   struct drm_crtc *crtc;
+   unsigned int i;
+
+   /*
+* Store RGB routing to DPAD0 and DPAD1, the hardware will be configured
+* when starting the CRTCs.
+*/
+   rcdu->dpad1_source = -1;
+
+   for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
+   struct rcar_du_crtc_state *rcrtc_state =
+   to_rcar_crtc_state(crtc_state);
+   struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+   if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0))
+   rcdu->dpad0_source = rcrtc->index;
+
+   if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
+   rcdu->dpad1_source = rcrtc->index;
+   }
+
+   /* Apply the atomic update. */
+   drm_atomic_helper_commit_modeset_disables(dev, old_state);
+   drm_atomic_helper_commit_planes(dev, old_state,
+   DRM_PLANE_COMMIT_ACTIVE_ONLY);
+   

[PATCH v5 06/10] drm: rcar-du: Move rcar_du_encoders_init()

2022-07-27 Thread Biju Das
RZ/G2L supports only DSI and DPI. Add rcar_du_encoders_init() to handle
the pointer to du_output_name(), so that we can share du_encoders_init()
between RCar and RZ/G2L kms drivers.

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c |  92 +---
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c | 100 ++
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h |   6 ++
 3 files changed, 108 insertions(+), 90 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index ed8d14701178..7586520e1871 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -74,95 +74,6 @@ static const struct drm_mode_config_funcs 
rcar_du_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
 };
 
-static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
-enum rcar_du_output output,
-struct of_endpoint *ep)
-{
-   struct device_node *entity;
-   int ret;
-
-   /* Locate the connected entity and initialize the encoder. */
-   entity = of_graph_get_remote_port_parent(ep->local_node);
-   if (!entity) {
-   dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
-   ep->local_node);
-   return -ENODEV;
-   }
-
-   if (!of_device_is_available(entity)) {
-   dev_dbg(rcdu->dev,
-   "connected entity %pOF is disabled, skipping\n",
-   entity);
-   of_node_put(entity);
-   return -ENODEV;
-   }
-
-   ret = rcar_du_encoder_init(rcdu, output, entity);
-   if (ret && ret != -EPROBE_DEFER && ret != -ENOLINK)
-   dev_warn(rcdu->dev,
-"failed to initialize encoder %pOF on output %s (%d), 
skipping\n",
-entity, rcar_du_output_name(output), ret);
-
-   of_node_put(entity);
-
-   return ret;
-}
-
-static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
-{
-   struct device_node *np = rcdu->dev->of_node;
-   struct device_node *ep_node;
-   unsigned int num_encoders = 0;
-
-   /*
-* Iterate over the endpoints and create one encoder for each output
-* pipeline.
-*/
-   for_each_endpoint_of_node(np, ep_node) {
-   enum rcar_du_output output;
-   struct of_endpoint ep;
-   unsigned int i;
-   int ret;
-
-   ret = of_graph_parse_endpoint(ep_node, );
-   if (ret < 0) {
-   of_node_put(ep_node);
-   return ret;
-   }
-
-   /* Find the output route corresponding to the port number. */
-   for (i = 0; i < RCAR_DU_OUTPUT_MAX; ++i) {
-   if (rcdu->info->routes[i].possible_crtcs &&
-   rcdu->info->routes[i].port == ep.port) {
-   output = i;
-   break;
-   }
-   }
-
-   if (i == RCAR_DU_OUTPUT_MAX) {
-   dev_warn(rcdu->dev,
-"port %u references unexisting output, 
skipping\n",
-ep.port);
-   continue;
-   }
-
-   /* Process the output pipeline. */
-   ret = rcar_du_encoders_init_one(rcdu, output, );
-   if (ret < 0) {
-   if (ret == -EPROBE_DEFER) {
-   of_node_put(ep_node);
-   return ret;
-   }
-
-   continue;
-   }
-
-   num_encoders++;
-   }
-
-   return num_encoders;
-}
-
 static int rcar_du_properties_init(struct rcar_du_device *rcdu)
 {
/*
@@ -462,7 +373,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
}
 
/* Initialize the encoders. */
-   ret = rcar_du_encoders_init(rcdu);
+   ret = rcar_du_encoders_init(rcdu, rcar_du_output_name,
+   rcar_du_encoder_init);
if (ret < 0)
return ret;
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
index a1027436cfe3..d41fee590ee4 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
@@ -517,3 +517,103 @@ rcar_du_lib_mode_cfg_helper_fns(void)
 {
return _du_mode_config_helper;
 }
+
+static int
+rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
+ enum rcar_du_output output,
+ struct of_endpoint *ep,
+ const char *output_name,
+ int (*rcar_du_encoder_init_fn)(struct rcar_du_device 
*r,
+   

[PATCH v5 07/10] drm: rcar-du: Move rcar_du_properties_init()

2022-07-27 Thread Biju Das
Move rcar_du_properties_init() to RCar DU kms lib, so that it can be
shared by both RCar and RZ/G2L kms drivers.

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 16 
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c | 16 
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h |  2 ++
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 7586520e1871..b3ebe694be6e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -74,22 +74,6 @@ static const struct drm_mode_config_funcs 
rcar_du_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
 };
 
-static int rcar_du_properties_init(struct rcar_du_device *rcdu)
-{
-   /*
-* The color key is expressed as an RGB888 triplet stored in a 32-bit
-* integer in XRGB format. Bit 24 is used as a flag to disable (0)
-* or enable source color keying (1).
-*/
-   rcdu->props.colorkey =
-   drm_property_create_range(>ddev, 0, "colorkey",
- 0, 0x01ff);
-   if (rcdu->props.colorkey == NULL)
-   return -ENOMEM;
-
-   return 0;
-}
-
 static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
 {
const struct device_node *np = rcdu->dev->of_node;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
index d41fee590ee4..a56f3d6db321 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
@@ -617,3 +617,19 @@ int rcar_du_encoders_init(struct rcar_du_device *rcdu,
 
return num_encoders;
 }
+
+int rcar_du_properties_init(struct rcar_du_device *rcdu)
+{
+   /*
+* The color key is expressed as an RGB888 triplet stored in a 32-bit
+* integer in XRGB format. Bit 24 is used as a flag to disable (0)
+* or enable source color keying (1).
+*/
+   rcdu->props.colorkey =
+   drm_property_create_range(>ddev, 0, "colorkey",
+ 0, 0x01ff);
+   if (rcdu->props.colorkey == NULL)
+   return -ENOMEM;
+
+   return 0;
+}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h 
b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h
index 02d6ed5aa154..b04c42bbae5c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h
@@ -52,4 +52,6 @@ int rcar_du_encoders_init(struct rcar_du_device *rcdu,
 enum rcar_du_output output,
 struct device_node *enc_node));
 
+int rcar_du_properties_init(struct rcar_du_device *rcdu);
+
 #endif /* __RCAR_DU_KMS_LIB_H__ */
-- 
2.25.1



[PATCH v5 09/10] dt-bindings: display: Document Renesas RZ/G2L DU bindings

2022-07-27 Thread Biju Das
The RZ/G2L LCD controller is composed of Frame Compression Processor
(FCPVD), Video Signal Processor (VSPD), and Display Unit (DU).

The DU module supports the following hardware features
− Display Parallel Interface (DPI) and MIPI LINK Video Interface
− Display timing master
− Generates video timings
− Selecting the polarity of output DCLK, HSYNC, VSYNC, and DE
− Supports Progressive
− Input data format (from VSPD): RGB888, RGB666
− Output data format: same as Input data format
− Supporting Full HD (1920 pixels x 1080 lines) for MIPI-DSI Output
− Supporting WXGA (1280 pixels x 800 lines) for Parallel Output

This patch document DU module found on RZ/G2L LCDC.

Signed-off-by: Biju Das 
Reviewed-by: Rob Herring 
---
v4->v5:
 * Added Rb tag from Rob.
v3->v4:
 * Changed compatible name from renesas,du-r9a07g044->renesas,r9a07g044-du
 * started using same compatible for RZ/G2{L,LC}
v3: New patch
---
 .../bindings/display/renesas,rzg2l-du.yaml| 124 ++
 1 file changed, 124 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml

diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml 
b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
new file mode 100644
index ..7626043debd8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/renesas,rzg2l-du.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/G2L Display Unit (DU)
+
+maintainers:
+  - Laurent Pinchart 
+  - Biju Das 
+
+description: |
+  These DT bindings describe the Display Unit embedded in the Renesas RZ/G2L
+  and RZ/V2L SoCs.
+
+properties:
+  compatible:
+enum:
+  - renesas,r9a07g044-du # RZ/G2{L,LC}
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Main clock
+  - description: Register access clock
+  - description: Video clock
+
+  clock-names:
+items:
+  - const: aclk
+  - const: pclk
+  - const: vclk
+
+  resets:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+description: |
+  The connections to the DU output video ports are modeled using the OF
+  graph bindings specified in Documentation/devicetree/bindings/graph.txt.
+  The number of ports and their assignment are model-dependent. Each port
+  shall have a single endpoint.
+
+patternProperties:
+  "^port@[0-1]$":
+$ref: /schemas/graph.yaml#/properties/port
+unevaluatedProperties: false
+
+required:
+  - port@0
+
+unevaluatedProperties: false
+
+  renesas,vsps:
+$ref: "/schemas/types.yaml#/definitions/phandle-array"
+items:
+  items:
+- description: phandle to VSP instance that serves the DU channel
+- description: Channel index identifying the LIF instance in that VSP
+description:
+  A list of phandle and channel index tuples to the VSPs that handle the
+  memory interfaces for the DU channels.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - power-domains
+  - ports
+  - renesas,vsps
+
+additionalProperties: false
+
+examples:
+  # RZ/G2L DU
+  - |
+#include 
+#include 
+
+display@1089 {
+compatible = "renesas,r9a07g044-du";
+reg = <0x1089 0x1>;
+interrupts = ;
+clocks = < CPG_MOD R9A07G044_LCDC_CLK_A>,
+ < CPG_MOD R9A07G044_LCDC_CLK_P>,
+ < CPG_MOD R9A07G044_LCDC_CLK_D>;
+clock-names = "aclk", "pclk", "vclk";
+resets = < R9A07G044_LCDC_RESET_N>;
+power-domains = <>;
+
+renesas,vsps = < 0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+endpoint {
+remote-endpoint = <_in>;
+};
+};
+port@1 {
+reg = <1>;
+endpoint {
+};
+};
+};
+};
+
+...
-- 
2.25.1



[PATCH v5 01/10] drm: rcar-du: Move rcar_du_vsp_plane_prepare_fb()

2022-07-27 Thread Biju Das
Move rcar_du_vsp_plane_prepare_fb() to RCar DU vsp lib so that
both RCar and RZ/G2L DU vsp drivers can share this function.

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 21 -
 drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c | 21 +
 drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h |  7 +++
 3 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index d192c31a5fe1..72128915a2ff 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -124,27 +124,6 @@ static void rcar_du_vsp_plane_setup(struct 
rcar_du_vsp_plane *plane)
  plane->index, );
 }
 
-static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
-   struct drm_plane_state *state)
-{
-   struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
-   struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
-   int ret;
-
-   /*
-* There's no need to prepare (and unprepare) the framebuffer when the
-* plane is not visible, as it will not be displayed.
-*/
-   if (!state->visible)
-   return 0;
-
-   ret = rcar_du_vsp_map_fb(vsp, state->fb, rstate->sg_tables);
-   if (ret < 0)
-   return ret;
-
-   return drm_gem_plane_helper_prepare_fb(plane, state);
-}
-
 static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
 struct drm_plane_state *state)
 {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
index 80da12f1fe71..40d44bf521c0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
@@ -147,6 +147,27 @@ int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct 
drm_framebuffer *fb,
return ret;
 }
 
+int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+struct drm_plane_state *state)
+{
+   struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
+   struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
+   int ret;
+
+   /*
+* There's no need to prepare (and unprepare) the framebuffer when the
+* plane is not visible, as it will not be displayed.
+*/
+   if (!state->visible)
+   return 0;
+
+   ret = rcar_du_vsp_map_fb(vsp, state->fb, rstate->sg_tables);
+   if (ret < 0)
+   return ret;
+
+   return drm_gem_plane_helper_prepare_fb(plane, state);
+}
+
 void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
  struct sg_table sg_tables[3])
 {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h
index abfde19fd1a3..d79cdf7d7316 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h
@@ -66,6 +66,8 @@ void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct 
drm_framebuffer *fb,
 int rcar_du_lib_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
 unsigned int crtcs,
 const struct drm_plane_helper_funcs 
*rcar_du_vsp_plane_helper_funcs);
+int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+struct drm_plane_state *state);
 #else
 static inline void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { };
 static inline void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { };
@@ -88,6 +90,11 @@ rcar_du_lib_vsp_init(struct rcar_du_vsp *vsp, struct 
device_node *np,
 {
return -ENXIO;
 }
+static inline int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+  struct drm_plane_state *state)
+{
+   return -ENXIO;
+}
 #endif
 
 #endif /* __RCAR_DU_VSP_LIB_H__ */
-- 
2.25.1



[PATCH v5 08/10] drm: rcar-du: Add rcar_du_lib_vsps_init()

2022-07-27 Thread Biju Das
Add rcar_du_lib_vsps_init() to RCar DU kms lib to handle both
rcar_du_vsp_init() and rzg2l_du_vsp_init().

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 88 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c | 89 +++
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h |  5 ++
 3 files changed, 95 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index b3ebe694be6e..73269b7e067e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -74,92 +74,6 @@ static const struct drm_mode_config_funcs 
rcar_du_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
 };
 
-static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
-{
-   const struct device_node *np = rcdu->dev->of_node;
-   const char *vsps_prop_name = "renesas,vsps";
-   struct of_phandle_args args;
-   struct {
-   struct device_node *np;
-   unsigned int crtcs_mask;
-   } vsps[RCAR_DU_MAX_VSPS] = { { NULL, }, };
-   unsigned int vsps_count = 0;
-   unsigned int cells;
-   unsigned int i;
-   int ret;
-
-   /*
-* First parse the DT vsps property to populate the list of VSPs. Each
-* entry contains a pointer to the VSP DT node and a bitmask of the
-* connected DU CRTCs.
-*/
-   ret = of_property_count_u32_elems(np, vsps_prop_name);
-   if (ret < 0) {
-   /* Backward compatibility with old DTBs. */
-   vsps_prop_name = "vsps";
-   ret = of_property_count_u32_elems(np, vsps_prop_name);
-   }
-   cells = ret / rcdu->num_crtcs - 1;
-   if (cells > 1)
-   return -EINVAL;
-
-   for (i = 0; i < rcdu->num_crtcs; ++i) {
-   unsigned int j;
-
-   ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
-  cells, i, );
-   if (ret < 0)
-   goto error;
-
-   /*
-* Add the VSP to the list or update the corresponding existing
-* entry if the VSP has already been added.
-*/
-   for (j = 0; j < vsps_count; ++j) {
-   if (vsps[j].np == args.np)
-   break;
-   }
-
-   if (j < vsps_count)
-   of_node_put(args.np);
-   else
-   vsps[vsps_count++].np = args.np;
-
-   vsps[j].crtcs_mask |= BIT(i);
-
-   /*
-* Store the VSP pointer and pipe index in the CRTC. If the
-* second cell of the 'renesas,vsps' specifier isn't present,
-* default to 0 to remain compatible with older DT bindings.
-*/
-   rcdu->crtcs[i].vsp = >vsps[j];
-   rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
-   }
-
-   /*
-* Then initialize all the VSPs from the node pointers and CRTCs bitmask
-* computed previously.
-*/
-   for (i = 0; i < vsps_count; ++i) {
-   struct rcar_du_vsp *vsp = >vsps[i];
-
-   vsp->index = i;
-   vsp->dev = rcdu;
-
-   ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
-   if (ret < 0)
-   goto error;
-   }
-
-   return 0;
-
-error:
-   for (i = 0; i < ARRAY_SIZE(vsps); ++i)
-   of_node_put(vsps[i].np);
-
-   return ret;
-}
-
 static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
 {
const struct device_node *np = rcdu->dev->of_node;
@@ -331,7 +245,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 
/* Initialize the compositors. */
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
-   ret = rcar_du_vsps_init(rcdu);
+   ret = rcar_du_lib_vsps_init(rcdu, rcar_du_vsp_init);
if (ret < 0)
return ret;
}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
index a56f3d6db321..c9fa4d1c78fd 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
@@ -633,3 +633,92 @@ int rcar_du_properties_init(struct rcar_du_device *rcdu)
 
return 0;
 }
+
+int rcar_du_lib_vsps_init(struct rcar_du_device *rcdu,
+ int (*rcar_du_vsp_init_fn)(struct rcar_du_vsp *vsp,
+struct device_node *np,
+unsigned int crtcs))
+{
+   const struct device_node *np = rcdu->dev->of_node;
+   const char *vsps_prop_name = "renesas,vsps";
+   struct of_phandle_args args;
+   struct {
+   struct device_node *np;
+   

[PATCH v5 04/10] drm: rcar-du: Add rcar_du_lib_fb_create()

2022-07-27 Thread Biju Das
Move the common code from rcar_du_fb_create->rcar_du_lib_fb_create,
so that rzg2l_du_fb_create() can reuse the common code.

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 64 +
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c | 69 +++
 drivers/gpu/drm/rcar-du/rcar_du_kms_lib.h |  4 ++
 3 files changed, 74 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index ea2b7d5f1c23..9d65a7d6d96e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -41,69 +41,7 @@ static struct drm_framebuffer *
 rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
  const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   struct rcar_du_device *rcdu = to_rcar_du_device(dev);
-   const struct rcar_du_format_info *format;
-   unsigned int chroma_pitch;
-   unsigned int max_pitch;
-   unsigned int align;
-   unsigned int i;
-
-   format = rcar_du_format_info(mode_cmd->pixel_format);
-   if (format == NULL) {
-   dev_dbg(dev->dev, "unsupported pixel format %08x\n",
-   mode_cmd->pixel_format);
-   return ERR_PTR(-EINVAL);
-   }
-
-   if (rcdu->info->gen < 3) {
-   /*
-* On Gen2 the DU limits the pitch to 4095 pixels and requires
-* buffers to be aligned to a 16 pixels boundary (or 128 bytes
-* on some platforms).
-*/
-   unsigned int bpp = format->planes == 1 ? format->bpp / 8 : 1;
-
-   max_pitch = 4095 * bpp;
-
-   if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
-   align = 128;
-   else
-   align = 16 * bpp;
-   } else {
-   /*
-* On Gen3 the memory interface is handled by the VSP that
-* limits the pitch to 65535 bytes and has no alignment
-* constraint.
-*/
-   max_pitch = 65535;
-   align = 1;
-   }
-
-   if (mode_cmd->pitches[0] & (align - 1) ||
-   mode_cmd->pitches[0] > max_pitch) {
-   dev_dbg(dev->dev, "invalid pitch value %u\n",
-   mode_cmd->pitches[0]);
-   return ERR_PTR(-EINVAL);
-   }
-
-   /*
-* Calculate the chroma plane(s) pitch using the horizontal subsampling
-* factor. For semi-planar formats, the U and V planes are combined, the
-* pitch must thus be doubled.
-*/
-   chroma_pitch = mode_cmd->pitches[0] / format->hsub;
-   if (format->planes == 2)
-   chroma_pitch *= 2;
-
-   for (i = 1; i < format->planes; ++i) {
-   if (mode_cmd->pitches[i] != chroma_pitch) {
-   dev_dbg(dev->dev,
-   "luma and chroma pitches are not compatible\n");
-   return ERR_PTR(-EINVAL);
-   }
-   }
-
-   return drm_gem_fb_create(dev, file_priv, mode_cmd);
+   return rcar_du_lib_fb_create(dev, file_priv, mode_cmd);
 }
 
 /* 
-
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
index 6461b99e08dc..d8f778a7b6db 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms_lib.c
@@ -392,3 +392,72 @@ int rcar_du_dumb_create(struct drm_file *file, struct 
drm_device *dev,
 
return drm_gem_cma_dumb_create_internal(file, dev, args);
 }
+
+struct drm_framebuffer *
+rcar_du_lib_fb_create(struct drm_device *dev, struct drm_file *file_priv,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   struct rcar_du_device *rcdu = to_rcar_du_device(dev);
+   const struct rcar_du_format_info *format;
+   unsigned int chroma_pitch;
+   unsigned int max_pitch;
+   unsigned int align;
+   unsigned int i;
+
+   format = rcar_du_format_info(mode_cmd->pixel_format);
+   if (format == NULL) {
+   dev_dbg(dev->dev, "unsupported pixel format %08x\n",
+   mode_cmd->pixel_format);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (rcdu->info->gen < 3) {
+   /*
+* On Gen2 the DU limits the pitch to 4095 pixels and requires
+* buffers to be aligned to a 16 pixels boundary (or 128 bytes
+* on some platforms).
+*/
+   unsigned int bpp = format->planes == 1 ? format->bpp / 8 : 1;
+
+   max_pitch = 4095 * bpp;
+
+   if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
+   align = 128;
+   else
+   align = 16 * bpp;
+   } else {
+   /*
+  

[PATCH v5 03/10] drm: rcar-du: Move rcar_du_vsp_plane_atomic_update()

2022-07-27 Thread Biju Das
Move rcar_du_vsp_plane_atomic_update() to RCar DU vsp lib so that
both RCar and RZ/G2L DU vsp drivers can share this function.

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 51 ---
 drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c | 51 +++
 drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h |  6 +++
 3 files changed, 57 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index c9090e581b12..aa63e2d19649 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -88,42 +88,6 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, );
 }
 
-static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
-{
-   struct rcar_du_vsp_plane_state *state =
-   to_rcar_vsp_plane_state(plane->plane.state);
-   struct rcar_du_crtc *crtc = to_rcar_crtc(state->state.crtc);
-   struct drm_framebuffer *fb = plane->plane.state->fb;
-   const struct rcar_du_format_info *format;
-   struct vsp1_du_atomic_config cfg = {
-   .pixelformat = 0,
-   .pitch = fb->pitches[0],
-   .alpha = state->state.alpha >> 8,
-   .zpos = state->state.zpos,
-   };
-   unsigned int i;
-
-   cfg.src.left = state->state.src.x1 >> 16;
-   cfg.src.top = state->state.src.y1 >> 16;
-   cfg.src.width = drm_rect_width(>state.src) >> 16;
-   cfg.src.height = drm_rect_height(>state.src) >> 16;
-
-   cfg.dst.left = state->state.dst.x1;
-   cfg.dst.top = state->state.dst.y1;
-   cfg.dst.width = drm_rect_width(>state.dst);
-   cfg.dst.height = drm_rect_height(>state.dst);
-
-   for (i = 0; i < state->format->planes; ++i)
-   cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
-  + fb->offsets[i];
-
-   format = rcar_du_format_info(state->format->fourcc);
-   cfg.pixelformat = format->v4l2;
-
-   vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
- plane->index, );
-}
-
 static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
@@ -135,21 +99,6 @@ static int rcar_du_vsp_plane_atomic_check(struct drm_plane 
*plane,
>format);
 }
 
-static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
-   struct drm_atomic_state *state)
-{
-   struct drm_plane_state *old_state = 
drm_atomic_get_old_plane_state(state, plane);
-   struct drm_plane_state *new_state = 
drm_atomic_get_new_plane_state(state, plane);
-   struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
-   struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
-
-   if (new_state->visible)
-   rcar_du_vsp_plane_setup(rplane);
-   else if (old_state->crtc)
-   vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,
- rplane->index, NULL);
-}
-
 static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
.prepare_fb = rcar_du_vsp_plane_prepare_fb,
.cleanup_fb = rcar_du_vsp_plane_cleanup_fb,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
index 9062837e68da..97f8ac22b582 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
@@ -85,6 +85,42 @@ static const u32 rcar_du_vsp_formats[] = {
DRM_FORMAT_YVU444,
 };
 
+static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+{
+   struct rcar_du_vsp_plane_state *state =
+   to_rcar_vsp_plane_state(plane->plane.state);
+   struct rcar_du_crtc *crtc = to_rcar_crtc(state->state.crtc);
+   struct drm_framebuffer *fb = plane->plane.state->fb;
+   const struct rcar_du_format_info *format;
+   struct vsp1_du_atomic_config cfg = {
+   .pixelformat = 0,
+   .pitch = fb->pitches[0],
+   .alpha = state->state.alpha >> 8,
+   .zpos = state->state.zpos,
+   };
+   unsigned int i;
+
+   cfg.src.left = state->state.src.x1 >> 16;
+   cfg.src.top = state->state.src.y1 >> 16;
+   cfg.src.width = drm_rect_width(>state.src) >> 16;
+   cfg.src.height = drm_rect_height(>state.src) >> 16;
+
+   cfg.dst.left = state->state.dst.x1;
+   cfg.dst.top = state->state.dst.y1;
+   cfg.dst.width = drm_rect_width(>state.dst);
+   cfg.dst.height = drm_rect_height(>state.dst);
+
+   for (i = 0; i < state->format->planes; ++i)
+   cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
+  + fb->offsets[i];
+
+   format = rcar_du_format_info(state->format->fourcc);
+   cfg.pixelformat = 

[PATCH v5 02/10] drm: rcar-du: Move rcar_du_vsp_plane_cleanup_fb()

2022-07-27 Thread Biju Das
Move rcar_du_vsp_plane_cleanup_fb() to RCar DU vsp lib so that
it can be shared by both RCar and RZ/G2L DU vsp drivers.

Signed-off-by: Biju Das 
---
v5:
 * New patch
---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 12 
 drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c | 12 
 drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h |  6 ++
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 72128915a2ff..c9090e581b12 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -124,18 +124,6 @@ static void rcar_du_vsp_plane_setup(struct 
rcar_du_vsp_plane *plane)
  plane->index, );
 }
 
-static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
-struct drm_plane_state *state)
-{
-   struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
-   struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
-
-   if (!state->visible)
-   return;
-
-   rcar_du_vsp_unmap_fb(vsp, state->fb, rstate->sg_tables);
-}
-
 static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
index 40d44bf521c0..9062837e68da 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.c
@@ -181,6 +181,18 @@ void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct 
drm_framebuffer *fb,
}
 }
 
+void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+   struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
+   struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
+
+   if (!state->visible)
+   return;
+
+   rcar_du_vsp_unmap_fb(vsp, state->fb, rstate->sg_tables);
+}
+
 static struct drm_plane_state *
 rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
 {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h
index d79cdf7d7316..094ada022fe5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp_lib.h
@@ -68,6 +68,8 @@ int rcar_du_lib_vsp_init(struct rcar_du_vsp *vsp, struct 
device_node *np,
 const struct drm_plane_helper_funcs 
*rcar_du_vsp_plane_helper_funcs);
 int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
 struct drm_plane_state *state);
+void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *state);
 #else
 static inline void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { };
 static inline void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { };
@@ -95,6 +97,10 @@ static inline int rcar_du_vsp_plane_prepare_fb(struct 
drm_plane *plane,
 {
return -ENXIO;
 }
+static inline void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+   struct drm_plane_state *state)
+{
+}
 #endif
 
 #endif /* __RCAR_DU_VSP_LIB_H__ */
-- 
2.25.1



[PATCH v5 00/10] Add RZ/G2L Display support

2022-07-27 Thread Biju Das
RZ/G2L LCD controller composed of Frame compression Processor(FCPVD),
Video signal processor (VSPD) and Display unit(DU). The output of LCDC is
connected to Display parallel interface and MIPI link video interface.

This patch series aims to add basic display support on RZ/G2L SMARC EVK
platform. The output from DSI is connected to ADV7535.

The DU controller is similar to R-Car as it is connected to VSPD,
so most of code is based on R-Car with new CRTC/DRM driver specific to
RZ/G2L.

Basic RCar DU lib created for kms, vsp and encoder drivers[1].

This patch series enhances the RCar DU libs and RZ/G2L started using
this libs and there by code size is reduced to almost 50%.

Further enhancement possible by sharing common code for DRM and CRTC.

Note:-
This patch series depend upon [1]
[1] 
https://lore.kernel.org/dri-devel/20220726164208.1048444-1-biju.das...@bp.renesas.com/T/#t

v4->v5:
 * Added Rb tag from Rob for binding patch.
 * Started using RCar DU libs(kms, vsp and encoder)
 * Started using rcar_du_device, rcar_du_write, rcar_du_crtc,
   rcar_du_format_info and rcar_du_encoder.
v3->v4:
 * Changed compatible name from renesas,du-r9a07g044->renesas,r9a07g044-du
 * started using same compatible for RZ/G2{L,LC}
 * Removed rzg2l_du_group.h and struct rzg2l_du_group
 * Renamed __rzg2l_du_group_start_stop->rzg2l_du_start_stop
 * Removed rzg2l_du_group_restart
 * Updated rzg2l_du_crtc_set_display_timing
 * Removed mode_valid callback.
 * Updated rzg2l_du_crtc_create() parameters
 * Updated compatible
 * Removed RZG2L_DU_MAX_GROUPS
V2->v3:
 * Added new bindings for RZ/G2L DU
 * Removed indirection and created new DRM driver based on R-Car DU
v1->v2:
 * Based on [1], all references to 'rzg2l_lcdc' replaced with 'rzg2l_du'
 * Updated commit description for bindings
 * Removed LCDC references from bindings
 * Changed clock name from du.0->aclk from bindings
 * Changed reset name from du.0->du from bindings
 * Replaced crtc_helper_funcs->rcar_crtc_helper_funcs
 * Updated macro DRM_RZG2L_LCDC->DRM_RZG2L_DU
 * Replaced rzg2l-lcdc-drm->rzg2l-du-drm
 * Added forward declaration for struct reset_control

[1] 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220312084205.31462-2-biju.das...@bp.renesas.com/

RFC->v1:
 * Changed  minItems->maxItems for renesas,vsps.
 * Added RZ/G2L LCDC driver with special handling for CRTC reusing
   most of RCar DU code
 * Fixed the comments for num_rpf from rpf's->RPFs/ and vsp->VSP.
RFC:
 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-18-biju.das...@bp.renesas.com/
 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-12-biju.das...@bp.renesas.com/
 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-13-biju.das...@bp.renesas.com/
 
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-19-biju.das...@bp.renesas.com/

Modetest output:-
root@smarc-rzg2l:~# modetest -M rzg2l-du
Encoders:
id  crtctypepossible crtcs  possible clones
41  40  none0x0001  0x0001
43  0   Virtual 0x0001  0x0002

Connectors:
id  encoder status  namesize (mm)   modes   encoders
42  41  connected   HDMI-A-1520x320 29  41
  modes:
index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
  #0 1920x1080 59.72 1920 1968 2000 2080 1080 1082 1087  138000 flags: 
phsync, nvsync; type: preferred, driver
  #1 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: 
phsync, pvsync; type: driver
  #2 1920x1080 59.94 1920 2008 2052 2200 1080 1084 1089 1125 148352 flags: 
phsync, pvsync; type: driver
  #3 1920x1080 59.94 1920 2008 2052 2200 1080 1084 1089 1125 148352 flags: 
phsync, pvsync; type: driver
  #4 1280x1024 75.02 1280 1296 1440 1688 1024 1025 1028 1066 135000 flags: 
phsync, pvsync; type: driver
  #5 1280x1024 60.02 1280 1328 1440 1688 1024 1025 1028 1066 108000 flags: 
phsync, pvsync; type: driver
  #6 1152x864 75.00 1152 1216 1344 1600 864 865 868 900 108000 flags: phsync, 
pvsync; type: driver
  #7 1280x720 60.00 1280 1390 1430 1650 720 725 730 750 74250 flags: phsync, 
pvsync; type: driver
  #8 1280x720 59.94 1280 1390 1430 1650 720 725 730 750 74176 flags: phsync, 
pvsync; type: driver
  #9 1280x720 50.00 1280 1720 1760 1980 720 725 730 750 74250 flags: phsync, 
pvsync; type: driver
  #10 1280x720 50.00 1280 1720 1760 1980 720 725 730 750 74250 flags: phsync, 
pvsync; type: driver
  #11 1024x768 75.03 1024 1040 1136 1312 768 769 772 800 78750 flags: phsync, 
pvsync; type: driver
  #12 1024x768 70.07 1024 1048 1184 1328 768 771 777 806 75000 flags: nhsync, 
nvsync; type: driver
  #13 1024x768 60.00 1024 1048 1184 1344 768 771 777 806 65000 flags: nhsync, 
nvsync; type: driver
  #14 832x624 74.55 832 864 928 1152 624 625 628 667 57284 flags: nhsync, 
nvsync; type: driver
  #15 800x600 75.00 800 816 896 1056 600 601 604 625 49500 

Re: [PATCH] drm/amdkfd: use time_is_before_jiffies(a + b) to replace "jiffies - a > b"

2022-07-27 Thread Felix Kuehling

This patch introduces a build warning for me:

  CC [M]  drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.o
In file included from /home/fkuehlin/compute/kernel/include/linux/spinlock.h:54,
 from /home/fkuehlin/compute/kernel/include/linux/mmzone.h:8,
 from /home/fkuehlin/compute/kernel/include/linux/gfp.h:6,
 from /home/fkuehlin/compute/kernel/include/linux/slab.h:15,
 from 
/home/fkuehlin/compute/kernel/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.c:44:
/home/fkuehlin/compute/kernel/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.c:
 In function ?interrupt_wq?:
/home/fkuehlin/compute/kernel/include/linux/typecheck.h:12:18: warning: 
comparison of distinct pointer types lacks a cast
   12 |  (void)(&__dummy == &__dummy2); \
  |  ^~
/home/fkuehlin/compute/kernel/include/linux/jiffies.h:106:3: note: in expansion 
of macro ?typecheck?
  106 |   typecheck(unsigned long, b) && \
  |   ^
/home/fkuehlin/compute/kernel/include/linux/jiffies.h:154:35: note: in 
expansion of macro ?time_after?
  154 | #define time_is_before_jiffies(a) time_after(jiffies, a)
  |   ^~
/home/fkuehlin/compute/kernel/drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_interrupt.c:159:7:
 note: in expansion of macro ?time_is_before_jiffies?
  159 |   if (time_is_before_jiffies(start_jiffies + HZ)) {
  |   ^~

I think you need to change the the definition of start_jiffies to be 
unsigned long. Do you want to submit a v2 of your patch?


That said, I think the existing code was fine, though the type-mismatch 
highlighted by your patch is a bit iffy.


Regards,
  Felix


Am 2022-07-26 um 22:59 schrieb Yu Zhe:

time_is_before_jiffies deals with timer wrapping correctly.

Signed-off-by: Yu Zhe 
---
  drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index a9466d154395..6397926e059c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -156,7 +156,7 @@ static void interrupt_wq(struct work_struct *work)
while (dequeue_ih_ring_entry(dev, ih_ring_entry)) {
dev->device_info.event_interrupt_class->interrupt_wq(dev,
ih_ring_entry);
-   if (jiffies - start_jiffies > HZ) {
+   if (time_is_before_jiffies(start_jiffies + HZ)) {
/* If we spent more than a second processing signals,
 * reschedule the worker to avoid soft-lockup warnings
 */


Re: [PATCH -next] drm/amd/display: remove unneeded semicolon

2022-07-27 Thread Rodrigo Siqueira Jordao




On 2022-07-26 18:28, Yang Li wrote:

Eliminate the following coccicheck warning:
./drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c:2344:67-68: Unneeded 
semicolon

Reported-by: Abaci Robot 
Signed-off-by: Yang Li 
---
  drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
index 39428488a052..ca44df4fca74 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
@@ -2341,7 +2341,7 @@ void 
dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc,
dout_wb.wb_dst_width = 
wb_info->dwb_params.dest_width;
dout_wb.wb_dst_height = 
wb_info->dwb_params.dest_height;
dout_wb.wb_htaps_luma = 
wb_info->dwb_params.scaler_taps.h_taps;
-   dout_wb.wb_vtaps_luma = 
wb_info->dwb_params.scaler_taps.v_taps;;
+   dout_wb.wb_vtaps_luma = 
wb_info->dwb_params.scaler_taps.v_taps;
dout_wb.wb_htaps_chroma = 
wb_info->dwb_params.scaler_taps.h_taps_c;
dout_wb.wb_vtaps_chroma = 
wb_info->dwb_params.scaler_taps.v_taps_c;
dout_wb.wb_hratio = 
wb_info->dwb_params.cnv_params.crop_en ?


Reviewed-by: Rodrigo Siqueira 

And applied to amd-staging-drm-next.

Thanks
Siqueira


Re: [PATCH v2] drm/ttm: Fix dummy res NULL ptr deref bug

2022-07-27 Thread André Almeida
Hi Arunpravin,

Às 02:30 de 27/07/22, Arunpravin Paneer Selvam escreveu:
> Check the bo->resource value before accessing the resource
> mem_type.
> 
> v2: Fix commit description unwrapped warning
> 
> 
> [   40.191227][  T184] general protection fault, probably for non-canonical 
> address 0xdc02:  [#1] SMP KASAN PTI
> [   40.192995][  T184] KASAN: null-ptr-deref in range 
> [0x0010-0x0017]
> [   40.194411][  T184] CPU: 1 PID: 184 Comm: systemd-udevd Not tainted 
> 5.19.0-rc4-00721-gb297c22b7070 #1
> [   40.196063][  T184] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), 
> BIOS 1.16.0-debian-1.16.0-4 04/01/2014
> [   40.199605][  T184] RIP: 0010:ttm_bo_validate+0x1b3/0x240 [ttm]
> [   40.200754][  T184] Code: e8 72 c5 ff ff 83 f8 b8 74 d4 85 c0 75 54 49 8b 
> 9e 58 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 8d 7b 10 48 89 fa 48 c1 ea 03 
> <0f> b6 04 02 84 c0 74 04 3c 03 7e 44 8b 53 10 31 c0 85 d2 0f 85 58
> [   40.203685][  T184] RSP: 0018:c96df0c8 EFLAGS: 00010202
> [   40.204630][  T184] RAX: dc00 RBX:  RCX: 
> 11102f4bb71b
> [   40.205864][  T184] RDX: 0002 RSI: c96df208 RDI: 
> 0010
> [   40.207102][  T184] RBP: 192dbe1a R08: c96df208 R09: 
> 
> [   40.208394][  T184] R10: 88817a5f R11: 0001 R12: 
> c96df110
> [   40.209692][  T184] R13: c96df0f0 R14: 88817a5db800 R15: 
> c96df208
> [   40.210862][  T184] FS:  7f6b1d16e8c0() GS:88839d70() 
> knlGS:
> [   40.212250][  T184] CS:  0010 DS:  ES:  CR0: 80050033
> [   40.213275][  T184] CR2: 55a1001d4ff0 CR3: 0001700f4000 CR4: 
> 06e0
> [   40.214469][  T184] Call Trace:
> [   40.214974][  T184]  
> [   40.215438][  T184]  ? ttm_bo_bounce_temp_buffer+0x140/0x140 [ttm]
> [   40.216572][  T184]  ? mutex_spin_on_owner+0x240/0x240
> [   40.217456][  T184]  ? drm_vma_offset_add+0xaa/0x100 [drm]
> [   40.218457][  T184]  ttm_bo_init_reserved+0x3d6/0x540 [ttm]
> [   40.219410][  T184]  ? shmem_get_inode+0x744/0x980
> [   40.220231][  T184]  ttm_bo_init_validate+0xb1/0x200 [ttm]
> [   40.221172][  T184]  ? bo_driver_evict_flags+0x340/0x340 [drm_vram_helper]
> [   40.222530][  T184]  ? ttm_bo_init_reserved+0x540/0x540 [ttm]
> [   40.223643][  T184]  ? __do_sys_finit_module+0x11a/0x1c0
> [   40.224654][  T184]  ? __shmem_file_setup+0x102/0x280
> [   40.234764][  T184]  drm_gem_vram_create+0x305/0x480 [drm_vram_helper]
> [   40.235766][  T184]  ? bo_driver_evict_flags+0x340/0x340 [drm_vram_helper]
> [   40.236846][  T184]  ? __kasan_slab_free+0x108/0x180
> [   40.237650][  T184]  drm_gem_vram_fill_create_dumb+0x134/0x340 
> [drm_vram_helper]
> [   40.238864][  T184]  ? local_pci_probe+0xdf/0x180
> [   40.239674][  T184]  ? drmm_vram_helper_init+0x400/0x400 [drm_vram_helper]
> [   40.240826][  T184]  drm_client_framebuffer_create+0x19c/0x400 [drm]
> [   40.241955][  T184]  ? drm_client_buffer_delete+0x200/0x200 [drm]
> [   40.243001][  T184]  ? drm_client_pick_crtcs+0x554/0xb80 [drm]
> [   40.244030][  T184]  drm_fb_helper_generic_probe+0x23f/0x940 
> [drm_kms_helper]
> [   40.245226][  T184]  ? __cond_resched+0x1c/0xc0
> [   40.245987][  T184]  ? drm_fb_helper_memory_range_to_clip+0x180/0x180 
> [drm_kms_helper]
> [   40.247316][  T184]  ? mutex_unlock+0x80/0x100
> [   40.248005][  T184]  ? __mutex_unlock_slowpath+0x2c0/0x2c0
> [   40.249083][  T184]  drm_fb_helper_single_fb_probe+0x907/0xf00 
> [drm_kms_helper]
> [   40.250314][  T184]  ? drm_fb_helper_check_var+0x1180/0x1180 
> [drm_kms_helper]
> [   40.251540][  T184]  ? __cond_resched+0x1c/0xc0
> [   40.252321][  T184]  ? mutex_lock+0x9f/0x100
> [   40.253062][  T184]  __drm_fb_helper_initial_config_and_unlock+0xb9/0x2c0 
> [drm_kms_helper]
> [   40.254394][  T184]  drm_fbdev_client_hotplug+0x56f/0x840 [drm_kms_helper]
> [   40.255477][  T184]  drm_fbdev_generic_setup+0x165/0x3c0 [drm_kms_helper]
> [   40.256607][  T184]  bochs_pci_probe+0x6b7/0x900 [bochs]
> [   40.257515][  T184]  ? _raw_spin_lock_irqsave+0x87/0x100
> [   40.258312][  T184]  ? bochs_hw_init+0x480/0x480 [bochs]
> [   40.259244][  T184]  ? bochs_hw_init+0x480/0x480 [bochs]
> [   40.260186][  T184]  local_pci_probe+0xdf/0x180
> [   40.260928][  T184]  pci_call_probe+0x15f/0x500
> [   40.265798][  T184]  ? _raw_spin_lock+0x81/0x100
> [   40.266508][  T184]  ? pci_pm_suspend_noirq+0x980/0x980
> [   40.267322][  T184]  ? pci_assign_irq+0x81/0x280
> [   40.268096][  T184]  ? pci_match_device+0x351/0x6c0
> [   40.268883][  T184]  ? kernfs_put+0x18/0x40
> [   40.269611][  T184]  pci_device_probe+0xee/0x240
> [   40.270352][  T184]  really_probe+0x435/0xa80
> [   40.271021][  T184]  __driver_probe_device+0x2ab/0x480
> [   40.271828][  T184]  driver_probe_device+0x49/0x140
> [   40.272627][  T184]  __driver_attach+0x1bd/0x4c0
> [   40.273372][  T184]  ? __device_attach_driver+0x240/0x240
> 

Re: [PATCH] drm/amdgpu: fix i2s_pdata out of bound array access

2022-07-27 Thread Alex Deucher
On Wed, Jul 27, 2022 at 11:16 AM Mukunda,Vijendar
 wrote:
>
> On 7/27/22 8:25 PM, Alex Deucher wrote:
> > On Wed, Jul 27, 2022 at 10:42 AM Vijendar Mukunda
> >  wrote:
> >>
> >> Fixed following Smatch static checker warning:
> >>
> >> drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:393 acp_hw_init()
> >> error: buffer overflow 'i2s_pdata' 3 <= 3
> >> drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:396 acp_hw_init()
> >> error: buffer overflow 'i2s_pdata' 3 <= 3
> >>
> >> Reported-by: Dan Carpenter 
> >> Signed-off-by: Vijendar Mukunda 
> >> ---
> >>  drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 8 
> >>  1 file changed, 8 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c 
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> >> index bcc7ee02e0fc..6d72355ac492 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> >> @@ -390,14 +390,6 @@ static int acp_hw_init(void *handle)
> >> i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
> >> i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
> >>
> >> -   i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
> >> -   switch (adev->asic_type) {
> >> -   case CHIP_STONEY:
> >> -   i2s_pdata[3].quirks |= 
> >> DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
> >> -   break;
> >> -   default:
> >> -   break;
> >> -   }
> >
> > Is this actually not used or should we just increase the allocation size?
> >
> > Alex
> it's my bad. i2s_pdata array size is 3. when we recently included code
> changes for JD platform , this piece of code was added mistakenly for
> Stoney platform switch case.

Thanks.  Patch is:
Acked-by: Alex Deucher 

>
> --
> Vijendar
>
> >
> >> adev->acp.acp_res[0].name = "acp2x_dma";
> >> adev->acp.acp_res[0].flags = IORESOURCE_MEM;
> >> adev->acp.acp_res[0].start = acp_base;
> >> --
> >> 2.25.1
> >>
>


Re: [PATCH] drm/amdgpu: fix i2s_pdata out of bound array access

2022-07-27 Thread Mukunda,Vijendar
On 7/27/22 8:25 PM, Alex Deucher wrote:
> On Wed, Jul 27, 2022 at 10:42 AM Vijendar Mukunda
>  wrote:
>>
>> Fixed following Smatch static checker warning:
>>
>> drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:393 acp_hw_init()
>> error: buffer overflow 'i2s_pdata' 3 <= 3
>> drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:396 acp_hw_init()
>> error: buffer overflow 'i2s_pdata' 3 <= 3
>>
>> Reported-by: Dan Carpenter 
>> Signed-off-by: Vijendar Mukunda 
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 8 
>>  1 file changed, 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
>> index bcc7ee02e0fc..6d72355ac492 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
>> @@ -390,14 +390,6 @@ static int acp_hw_init(void *handle)
>> i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
>> i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
>>
>> -   i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
>> -   switch (adev->asic_type) {
>> -   case CHIP_STONEY:
>> -   i2s_pdata[3].quirks |= 
>> DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
>> -   break;
>> -   default:
>> -   break;
>> -   }
> 
> Is this actually not used or should we just increase the allocation size?
> 
> Alex
it's my bad. i2s_pdata array size is 3. when we recently included code
changes for JD platform , this piece of code was added mistakenly for
Stoney platform switch case.

--
Vijendar

> 
>> adev->acp.acp_res[0].name = "acp2x_dma";
>> adev->acp.acp_res[0].flags = IORESOURCE_MEM;
>> adev->acp.acp_res[0].start = acp_base;
>> --
>> 2.25.1
>>



Re: [PATCH] drm/amdgpu: fix i2s_pdata out of bound array access

2022-07-27 Thread Alex Deucher
On Wed, Jul 27, 2022 at 10:42 AM Vijendar Mukunda
 wrote:
>
> Fixed following Smatch static checker warning:
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:393 acp_hw_init()
> error: buffer overflow 'i2s_pdata' 3 <= 3
> drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:396 acp_hw_init()
> error: buffer overflow 'i2s_pdata' 3 <= 3
>
> Reported-by: Dan Carpenter 
> Signed-off-by: Vijendar Mukunda 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 8 
>  1 file changed, 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> index bcc7ee02e0fc..6d72355ac492 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
> @@ -390,14 +390,6 @@ static int acp_hw_init(void *handle)
> i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
> i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
>
> -   i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
> -   switch (adev->asic_type) {
> -   case CHIP_STONEY:
> -   i2s_pdata[3].quirks |= 
> DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
> -   break;
> -   default:
> -   break;
> -   }

Is this actually not used or should we just increase the allocation size?

Alex

> adev->acp.acp_res[0].name = "acp2x_dma";
> adev->acp.acp_res[0].flags = IORESOURCE_MEM;
> adev->acp.acp_res[0].start = acp_base;
> --
> 2.25.1
>


[PATCH] drm/amdgpu: fix i2s_pdata out of bound array access

2022-07-27 Thread Vijendar Mukunda
Fixed following Smatch static checker warning:

drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:393 acp_hw_init()
error: buffer overflow 'i2s_pdata' 3 <= 3
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c:396 acp_hw_init()
error: buffer overflow 'i2s_pdata' 3 <= 3

Reported-by: Dan Carpenter 
Signed-off-by: Vijendar Mukunda 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index bcc7ee02e0fc..6d72355ac492 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -390,14 +390,6 @@ static int acp_hw_init(void *handle)
i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
 
-   i2s_pdata[3].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
-   switch (adev->asic_type) {
-   case CHIP_STONEY:
-   i2s_pdata[3].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
-   break;
-   default:
-   break;
-   }
adev->acp.acp_res[0].name = "acp2x_dma";
adev->acp.acp_res[0].flags = IORESOURCE_MEM;
adev->acp.acp_res[0].start = acp_base;
-- 
2.25.1



Re: [PATCH v3 5/6] drm/i915/gt: Batch TLB invalidations

2022-07-27 Thread Andi Shyti
Hi Mauro,

I think there are still some unanswered questions from Tvrtko on
this patch, am I right?

Andi

On Wed, Jul 27, 2022 at 02:29:55PM +0200, Mauro Carvalho Chehab wrote:
> From: Chris Wilson 
> 
> Invalidate TLB in batches, in order to reduce performance regressions.
> 
> Currently, every caller performs a full barrier around a TLB
> invalidation, ignoring all other invalidations that may have already
> removed their PTEs from the cache. As this is a synchronous operation
> and can be quite slow, we cause multiple threads to contend on the TLB
> invalidate mutex blocking userspace.
> 
> We only need to invalidate the TLB once after replacing our PTE to
> ensure that there is no possible continued access to the physical
> address before releasing our pages. By tracking a seqno for each full
> TLB invalidate we can quickly determine if one has been performed since
> rewriting the PTE, and only if necessary trigger one for ourselves.
> 
> That helps to reduce the performance regression introduced by TLB
> invalidate logic.
> 
> [mchehab: rebased to not require moving the code to a separate file]
> 
> Cc: sta...@vger.kernel.org
> Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store")
> Suggested-by: Tvrtko Ursulin 
> Signed-off-by: Chris Wilson 
> Cc: Fei Yang 
> Signed-off-by: Mauro Carvalho Chehab 
> ---
> 
> To avoid mailbombing on a large number of people, only mailing lists were C/C 
> on the cover.
> See [PATCH v3 0/6] at: 
> https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/
> 
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 +-
>  drivers/gpu/drm/i915/gem/i915_gem_pages.c | 21 +---
>  drivers/gpu/drm/i915/gt/intel_gt.c| 53 ++-
>  drivers/gpu/drm/i915/gt/intel_gt.h| 12 -
>  drivers/gpu/drm/i915/gt/intel_gt_types.h  | 18 ++-
>  drivers/gpu/drm/i915/gt/intel_ppgtt.c |  8 ++-
>  drivers/gpu/drm/i915/i915_vma.c   | 33 +---
>  drivers/gpu/drm/i915/i915_vma.h   |  1 +
>  drivers/gpu/drm/i915/i915_vma_resource.c  |  5 +-
>  drivers/gpu/drm/i915/i915_vma_resource.h  |  6 ++-
>  10 files changed, 125 insertions(+), 35 deletions(-)
> 
> 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 5cf36a130061..9f6b14ec189a 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -335,7 +335,6 @@ struct drm_i915_gem_object {
>  #define I915_BO_READONLY  BIT(7)
>  #define I915_TILING_QUIRK_BIT 8 /* unknown swizzling; do not release! */
>  #define I915_BO_PROTECTED BIT(9)
> -#define I915_BO_WAS_BOUND_BIT 10
>   /**
>* @mem_flags - Mutable placement-related flags
>*
> @@ -616,6 +615,8 @@ struct drm_i915_gem_object {
>* pages were last acquired.
>*/
>   bool dirty:1;
> +
> + u32 tlb;
>   } mm;
>  
>   struct {
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> index 6835279943df..8357dbdcab5c 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -191,6 +191,18 @@ static void unmap_object(struct drm_i915_gem_object 
> *obj, void *ptr)
>   vunmap(ptr);
>  }
>  
> +static void flush_tlb_invalidate(struct drm_i915_gem_object *obj)
> +{
> + struct drm_i915_private *i915 = to_i915(obj->base.dev);
> + struct intel_gt *gt = to_gt(i915);
> +
> + if (!obj->mm.tlb)
> + return;
> +
> + intel_gt_invalidate_tlb(gt, obj->mm.tlb);
> + obj->mm.tlb = 0;
> +}
> +
>  struct sg_table *
>  __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
>  {
> @@ -216,14 +228,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
> *obj)
>   __i915_gem_object_reset_page_iter(obj);
>   obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0;
>  
> - if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, >flags)) {
> - struct drm_i915_private *i915 = to_i915(obj->base.dev);
> - struct intel_gt *gt = to_gt(i915);
> - intel_wakeref_t wakeref;
> -
> - with_intel_gt_pm_if_awake(gt, wakeref)
> - intel_gt_invalidate_tlbs(gt);
> - }
> + flush_tlb_invalidate(obj);
>  
>   return pages;
>  }
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
> b/drivers/gpu/drm/i915/gt/intel_gt.c
> index 5c55a90672f4..f435e06125aa 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -38,8 +38,6 @@ static void __intel_gt_init_early(struct intel_gt *gt)
>  {
>   spin_lock_init(>irq_lock);
>  
> - mutex_init(>tlb_invalidate_lock);
> -
>   INIT_LIST_HEAD(>closed_vma);
>   spin_lock_init(>closed_lock);
>  
> @@ -50,6 +48,8 @@ static void __intel_gt_init_early(struct intel_gt *gt)
> 

Re: [Intel-gfx] [PATCH v3 6/6] drm/i915/gt: describe the new tlb parameter at i915_vma_resource

2022-07-27 Thread Andi Shyti
Hi Mauro,

> TLB cache invalidation can happen on two different situations:
> 
> 1. synchronously, at __vma_put_pages();
> 2. asynchronously.
> 
> On the first case, TLB cache invalidation happens inside
> __vma_put_pages(). So, no need to do it later on.
> 
> However, on the second case, the pages will keep in memory
> until __i915_vma_evict() is called.
> 
> So, we need to store the TLB data at struct i915_vma_resource,
> in order to do a TLB cache invalidation before allowing
> userspace to re-use the same memory.
> 
> So, i915_vma_resource_unbind() has gained a new parameter
> in order to store the TLB data at the second case.
> 
> Document it.
> 
> Signed-off-by: Mauro Carvalho Chehab 
> ---
> 
> To avoid mailbombing on a large number of people, only mailing lists were C/C 
> on the cover.
> See [PATCH v3 0/6] at: 
> https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/
> 
>  drivers/gpu/drm/i915/i915_vma_resource.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_vma_resource.c 
> b/drivers/gpu/drm/i915/i915_vma_resource.c
> index 5a67995ea5fe..4fe09ea0a825 100644
> --- a/drivers/gpu/drm/i915/i915_vma_resource.c
> +++ b/drivers/gpu/drm/i915/i915_vma_resource.c
> @@ -216,6 +216,10 @@ i915_vma_resource_fence_notify(struct i915_sw_fence 
> *fence,
>  /**
>   * i915_vma_resource_unbind - Unbind a vma resource
>   * @vma_res: The vma resource to unbind.
> + * @tlb: pointer to vma->obj->mm.tlb associated with the resource
> + *to be stored at vma_res->tlb. When not-NULL, it will be used
> + *to do TLB cache invalidation before freeing a VMA resource.
> + *used only for async unbind.

/used/Used/

With that:

Reviewed-by: Andi Shyti 

Thanks,
Andi


Re: [Intel-gfx] [PATCH v3 2/6] drm/i915/gt: document with_intel_gt_pm_if_awake()

2022-07-27 Thread Andi Shyti
Hi Mauro,

> Add a kernel-doc markup to document this new macro.
> 
> Reviewed-by: Tvrtko Ursulin 
> Signed-off-by: Mauro Carvalho Chehab 

Reviewed-by: Andi Shyti 

Andi


Re: [Freedreno] [PATCH] drm/msm/dsi: Don't set a load before disabling a regulator

2022-07-27 Thread Doug Anderson
Hi,

On Wed, Jul 27, 2022 at 6:59 AM Dmitry Baryshkov
 wrote:
>
> On Wed, 27 Jul 2022 at 16:57, Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Tue, Jul 26, 2022 at 4:53 PM Abhinav Kumar  
> > wrote:
> > >
> > > On 7/25/2022 5:49 PM, Douglas Anderson wrote:
> > > > As of commit 5451781dadf8 ("regulator: core: Only count load for
> > > > enabled consumers"), a load isn't counted for a disabled
> > > > regulator. That means all the code in the DSI driver to specify and
> > > > set loads before disabling a regulator is not actually doing anything
> > > > useful. Let's remove it.
> > > >
> > > > It should be noted that all of the loads set that were being specified
> > > > were pointless noise anyway. The only use for this number is to pick
> > > > between low power and high power modes of regulators. Regulators
> > > > appear to do this changeover at loads on the order of 1 uA. You
> > > > would a lot of clients of the same rail for that 100 uA number to
> > >
> > > I guess you meant "you would need a lot of clients"
> >
> > Yeah, sorry. :( I'll fix it up if I need a v3.
> >
> >
> > > > @@ -259,15 +259,7 @@ static inline struct msm_dsi_host 
> > > > *to_msm_dsi_host(struct mipi_dsi_host *host)
> > > >   static void dsi_host_regulator_disable(struct msm_dsi_host *msm_host)
> > > >   {
> > > It seems like now we can drop this function dsi_host_regulator_disable()
> > > entirely and just call regulator_bulk_disable() ?
> >
> > Sure, if you want. One could still argue that it provides a tiny bit
> > of abstraction and avoids the caller from having to know where to find
> > the number of regulators and all that, but I can go either way. Is
> > this worth a v3, do you think? If so, I might tack it on at the end of
> > the series.
>
> I'd say, drop it. Having extra single-call wrappers doesn't seem to add a lot.

Sounds good. I'll wait a little bit of time for feedback on the larger
series and then send a v3, probably next week.

-Doug


Re: [Freedreno] [PATCH] drm/msm/dsi: Don't set a load before disabling a regulator

2022-07-27 Thread Doug Anderson
Hi,

On Tue, Jul 26, 2022 at 4:53 PM Abhinav Kumar  wrote:
>
> On 7/25/2022 5:49 PM, Douglas Anderson wrote:
> > As of commit 5451781dadf8 ("regulator: core: Only count load for
> > enabled consumers"), a load isn't counted for a disabled
> > regulator. That means all the code in the DSI driver to specify and
> > set loads before disabling a regulator is not actually doing anything
> > useful. Let's remove it.
> >
> > It should be noted that all of the loads set that were being specified
> > were pointless noise anyway. The only use for this number is to pick
> > between low power and high power modes of regulators. Regulators
> > appear to do this changeover at loads on the order of 1 uA. You
> > would a lot of clients of the same rail for that 100 uA number to
>
> I guess you meant "you would need a lot of clients"

Yeah, sorry. :( I'll fix it up if I need a v3.


> > @@ -259,15 +259,7 @@ static inline struct msm_dsi_host 
> > *to_msm_dsi_host(struct mipi_dsi_host *host)
> >   static void dsi_host_regulator_disable(struct msm_dsi_host *msm_host)
> >   {
> It seems like now we can drop this function dsi_host_regulator_disable()
> entirely and just call regulator_bulk_disable() ?

Sure, if you want. One could still argue that it provides a tiny bit
of abstraction and avoids the caller from having to know where to find
the number of regulators and all that, but I can go either way. Is
this worth a v3, do you think? If so, I might tack it on at the end of
the series.

Note that I say "v3" because I actually included this patch in a
larger series and called that series "v2" [1].


[1] https://lore.kernel.org/r/20220726173824.1166873-1-diand...@chromium.org


Re: [Freedreno] [PATCH] drm/msm/dsi: Don't set a load before disabling a regulator

2022-07-27 Thread Dmitry Baryshkov
On Wed, 27 Jul 2022 at 16:57, Doug Anderson  wrote:
>
> Hi,
>
> On Tue, Jul 26, 2022 at 4:53 PM Abhinav Kumar  
> wrote:
> >
> > On 7/25/2022 5:49 PM, Douglas Anderson wrote:
> > > As of commit 5451781dadf8 ("regulator: core: Only count load for
> > > enabled consumers"), a load isn't counted for a disabled
> > > regulator. That means all the code in the DSI driver to specify and
> > > set loads before disabling a regulator is not actually doing anything
> > > useful. Let's remove it.
> > >
> > > It should be noted that all of the loads set that were being specified
> > > were pointless noise anyway. The only use for this number is to pick
> > > between low power and high power modes of regulators. Regulators
> > > appear to do this changeover at loads on the order of 1 uA. You
> > > would a lot of clients of the same rail for that 100 uA number to
> >
> > I guess you meant "you would need a lot of clients"
>
> Yeah, sorry. :( I'll fix it up if I need a v3.
>
>
> > > @@ -259,15 +259,7 @@ static inline struct msm_dsi_host 
> > > *to_msm_dsi_host(struct mipi_dsi_host *host)
> > >   static void dsi_host_regulator_disable(struct msm_dsi_host *msm_host)
> > >   {
> > It seems like now we can drop this function dsi_host_regulator_disable()
> > entirely and just call regulator_bulk_disable() ?
>
> Sure, if you want. One could still argue that it provides a tiny bit
> of abstraction and avoids the caller from having to know where to find
> the number of regulators and all that, but I can go either way. Is
> this worth a v3, do you think? If so, I might tack it on at the end of
> the series.

I'd say, drop it. Having extra single-call wrappers doesn't seem to add a lot.

>
> Note that I say "v3" because I actually included this patch in a
> larger series and called that series "v2" [1].
>
>
> [1] https://lore.kernel.org/r/20220726173824.1166873-1-diand...@chromium.org



-- 
With best wishes
Dmitry


Re: [PATCH] drm: Fix EDID firmware load on resume

2022-07-27 Thread Matthieu CHARETTE

Hi,

Caching the EDID via the firmware API makes the kernel able to reclaim 
the memory in case it's needed. And eventually, the kernel will load it 
again before suspending.
But for 128 bytes, even if we have many monitors it will not make any 
difference.
I don't know if storing a platform device can take more memory than 128 
bytes of data.
I let you decide which option is better. Just tell me if I should cache 
the bytes instead.


Thanks.

Matthieu

On Wed, Jul 27 2022 at 10:18:48 AM +0200, Takashi Iwai  
wrote:

On Wed, 27 Jul 2022 09:41:52 +0200,
Matthieu CHARETTE wrote:


 Loading an EDID using drm.edid_firmware parameter makes resume to 
fail
 after firmware cache is being cleaned. This is because edid_load() 
use a
 temporary device to request the firmware. This cause the EDID 
firmware
 not to be cached from suspend. And, requesting the EDID firmware 
return

 an error during resume.
 So the request_firmware() call should use a permanent device for 
each

 connector. Also, we should cache the EDID even if no monitor is
 connected, in case it's plugged while suspended.

 Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2061
 Signed-off-by: Matthieu CHARETTE 


Can we simply cache the already loaded EDID bytes instead?
Something like below (totally untested).


thanks,

Takashi

-- 8< --
diff --git a/drivers/gpu/drm/drm_connector.c 
b/drivers/gpu/drm/drm_connector.c

index 1c48d162c77e..b9d2803b518b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -286,6 +286,7 @@ int drm_connector_init(struct drm_device *dev,
connector->status = connector_status_unknown;
connector->display_info.panel_orientation =
DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+   connector->firmware_edid = NULL;

drm_connector_get_cmdline_mode(connector);

@@ -485,6 +486,7 @@ void drm_connector_cleanup(struct drm_connector 
*connector)

ida_simple_remove(>mode_config.connector_ida,
  connector->index);

+   kfree(connector->firmware_edid);
kfree(connector->display_info.bus_formats);
drm_mode_object_unregister(dev, >base);
kfree(connector->name);
diff --git a/drivers/gpu/drm/drm_edid_load.c 
b/drivers/gpu/drm/drm_edid_load.c

index 37d8ba3ddb46..a38fe4e00e4a 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -253,6 +253,13 @@ static void *edid_load(struct drm_connector 
*connector, const char *name,

edid = new_edid;
}

+   connector->firmware_edid = drm_edid_duplicate((struct edid *)edid);
+   if (!connector->firmware_edid) {
+   kfree(edid);
+   edid = ERR_PTR(-ENOMEM);
+   goto out;
+   }
+
DRM_INFO("Got %s EDID base block and %d extension%s from "
"\"%s\" for connector \"%s\"\n", (builtin >= 0) ? "built-in" :
"external", valid_extensions, valid_extensions == 1 ? "" : "s",
@@ -269,6 +276,12 @@ struct edid *drm_load_edid_firmware(struct 
drm_connector *connector)

char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
struct edid *edid;

+   /* already loaded? */
+   if (connector->firmware_edid) {
+   edid = drm_edid_duplicate(connector->firmware_edid);
+   return edid ? edid : ERR_PTR(-ENOMEM);
+   }
+
if (edid_firmware[0] == '\0')
return ERR_PTR(-ENOENT);

diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 3ac4bf87f257..b5d0c87327a3 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1528,6 +1528,8 @@ struct drm_connector {
enum drm_connector_force force;
 	/** @override_edid: has the EDID been overwritten through debugfs 
for testing? */

bool override_edid;
+   /** @firmware_edid: the cached firmware EDID bytes */
+   struct edid *firmware_edid;
 	/** @epoch_counter: used to detect any other changes in connector, 
besides status */

u64 epoch_counter;






[drm:drm-next 6/19] drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c:676:1: sparse: sparse: symbol 'gv100_disp_core_mthd_base' was not declared. Should it be static?

2022-07-27 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm/drm drm-next
head:   2bc7ea71a73747a77e7f83bc085b0d2393235410
commit: acbe9ecfb7fb14db868ddbeda8f43e623026316b [6/19] drm/nouveau/disp: merge 
head/outp/ior code into chipset files
config: alpha-randconfig-s032-20220725
compiler: alpha-linux-gcc (GCC) 12.1.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
git remote add drm git://anongit.freedesktop.org/drm/drm
git fetch --no-tags drm drm-next
git checkout acbe9ecfb7fb14db868ddbeda8f43e623026316b
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 
CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=alpha 
SHELL=/bin/bash drivers/gpu/drm/

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

sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c:676:1: sparse: sparse: 
>> symbol 'gv100_disp_core_mthd_base' was not declared. Should it be static?

vim +/gv100_disp_core_mthd_base +676 
drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c

   674  
   675  const struct nvkm_disp_mthd_list
 > 676  gv100_disp_core_mthd_base = {
   677  .mthd = 0x,
   678  .addr = 0x00,
   679  .data = {
   680  { 0x0200, 0x680200 },
   681  { 0x0208, 0x680208 },
   682  { 0x020c, 0x68020c },
   683  { 0x0210, 0x680210 },
   684  { 0x0214, 0x680214 },
   685  { 0x0218, 0x680218 },
   686  { 0x021c, 0x68021c },
   687  {}
   688  }
   689  };
   690  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
#
# Automatically generated file; DO NOT EDIT.
# Linux/alpha 5.19.0-rc6 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="alpha-linux-gcc (GCC) 12.1.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=120100
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23800
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23800
CONFIG_LLD_VERSION=0
CONFIG_CC_HAS_ASM_GOTO=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=123
CONFIG_CONSTRUCTORS=y
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
# CONFIG_SYSVIPC is not set
CONFIG_WATCH_QUEUE=y
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_USELIB is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_SIM=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
# end of IRQ subsystem

CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_TIME_KUNIT_TEST=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_HZ_PERIODIC=y
# CONFIG_NO_HZ_IDLE is not set
# CONFIG_NO_HZ is not set
CONFIG_HIGH_RES_TIMERS=y
# end of Timers subsystem

CONFIG_BPF=y

#
# BPF subsystem
#
CONFIG_BPF_SYSCALL=y
# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set
# end of BPF subsystem

CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PREEMPT_NONE=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_PSI=y
CONFIG_PSI_DEFAULT_DISABLED=y
# end of CPU/Task time and stats accounting

CONFIG_CPU_ISOLATION=y

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
CONFIG_TINY_SRCU=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_RCU_NEED_SEGCBLIST=y
# end of RCU Subsystem

CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IKHEADERS=y

#
# Scheduler features
#
# end of Scheduler features

CONFIG_CC_HAS_INT128=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y
# CONFIG_CGROUPS is not set
# CONFIG_NAMESPACES is not set
CONFIG_CHECKPOINT_RESTORE=y
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
CONFIG_RD_XZ=y
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_RD_ZSTD is not set
# CONFIG_BOOT_CONFIG is not set
CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
CONFIG_EXPERT=y
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_SYSFS_SYSCALL=y
# CONFIG_FHANDLE is not set
# CONFIG_POSIX_TIMERS is not set
# CONFIG_PRINTK is not set
CONFIG_BUG=y
CONFIG_PCSPKR_PLATFORM=y
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
CONFIG_EPOLL=y
# CONFIG_SIGNALFD is 

Re: [PATCH 8/8] drm/tidss: Enable Dual and Duplicate Modes for OLDI

2022-07-27 Thread Tomi Valkeinen

Hi,

On 19/07/2022 11:08, Aradhya Bhatia wrote:

The AM625 DSS peripheral supports 2 OLDI TXes which can work to enable 2
duplicated displays of smaller resolutions or enable a single Dual-Link
display with a higher resolution (1920x1200).

Configure the necessary register to enable the different modes.

Signed-off-by: Aradhya Bhatia 
---
  drivers/gpu/drm/tidss/tidss_dispc.c | 44 +++--
  1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c
index 0b9689453ee8..28cb61259471 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -1021,8 +1021,8 @@ static void dispc_enable_oldi(struct dispc_device *dispc, 
u32 hw_videoport,
int count = 0;
  
  	/*

-* For the moment DUALMODESYNC, MASTERSLAVE, MODE, and SRC
-* bits of DISPC_VP_DSS_OLDI_CFG are set statically to 0.
+* For the moment MASTERSLAVE, and SRC bits of DISPC_VP_DSS_OLDI_CFG are
+* set statically to 0.
 */
  
  	if (fmt->data_width == 24)

@@ -1039,7 +1039,45 @@ static void dispc_enable_oldi(struct dispc_device 
*dispc, u32 hw_videoport,
  
  	oldi_cfg |= BIT(0); /* ENABLE */
  
-	dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, oldi_cfg);

+   /*
+* As per all the current implementations of DSS, the OLDI TXes are 
present only on
+* hw_videoport = 0 (OLDI TX 0). However, the config register for 2nd 
OLDI TX (OLDI TX 1)
+* is present in the address space of hw_videoport = 1. Hence, using 
"hw_videoport + 1" to
+* configure OLDI TX 1.
+*/
+
+   switch (dispc->oldi_mode) {
+   case OLDI_MODE_OFF:
+   oldi_cfg &= ~BIT(0); /* DISABLE */
+   dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   dispc_vp_write(dispc, hw_videoport + 1, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   break;
+
+   case OLDI_SINGLE_LINK_SINGLE_MODE_0:
+   dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   break;
+
+   case OLDI_SINGLE_LINK_SINGLE_MODE_1:
+   dispc_vp_write(dispc, hw_videoport + 1, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   break;
+
+   case OLDI_SINGLE_LINK_DUPLICATE_MODE:
+   oldi_cfg |= BIT(5); /* DUPLICATE MODE */
+   dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   dispc_vp_write(dispc, hw_videoport + 1, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   break;
+
+   case OLDI_DUAL_LINK:
+   oldi_cfg |= BIT(11); /* DUALMODESYNC */
+   dispc_vp_write(dispc, hw_videoport, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   dispc_vp_write(dispc, hw_videoport + 1, DISPC_VP_DSS_OLDI_CFG, 
oldi_cfg);
+   break;
+
+   default:
+   dev_warn(dispc->dev, "%s: Incorrect oldi mode. Returning.\n",
+__func__);
+   return;
+   }
  
  	while (!(oldi_reset_bit & dispc_read(dispc, DSS_SYSSTATUS)) &&

   count < 1)


This feels a bit hacky:

- The function is dispc_enable_oldi, but the above code also disables 
oldi. We have code in dispc_vp_unprepare() which disables OLDI at the 
moment.


- The function takes hw_videoport as a parameter, and is designed to 
work on that videoport. The above operates on two videoports. Isn't the 
function also called for hw_videoport +1, which would result in reg 
writes to hw_videoport + 2?


- No matching code in dispc_vp_unprepare

Obviously the duplicate mode (I presume that's "cloning") and the dual 
link complicate things here, and I have to say I haven't worked with 
such setups. But I think somehow this should be restructured so that 
common configuration (common to the OLDIs) is done somewhere else.


I would guess that there are other drivers that support cloning and dual 
mode. Did you have a look how they handle things?


 Tomi


Re: [Intel-gfx] [PATCH v2 06/21] drm/i915/gt: Batch TLB invalidations

2022-07-27 Thread Tvrtko Ursulin



On 27/07/2022 12:48, Mauro Carvalho Chehab wrote:

On Wed, 20 Jul 2022 11:49:59 +0100
Tvrtko Ursulin  wrote:


On 20/07/2022 08:13, Mauro Carvalho Chehab wrote:

On Mon, 18 Jul 2022 14:52:05 +0100
Tvrtko Ursulin  wrote:
   


On 14/07/2022 13:06, Mauro Carvalho Chehab wrote:

From: Chris Wilson 

Invalidate TLB in patch, in order to reduce performance regressions.


"in batches"?


Yeah. Will fix it.



+void vma_invalidate_tlb(struct i915_address_space *vm, u32 tlb)
+{
+   /*
+* Before we release the pages that were bound by this vma, we
+* must invalidate all the TLBs that may still have a reference
+* back to our physical address. It only needs to be done once,
+* so after updating the PTE to point away from the pages, record
+* the most recent TLB invalidation seqno, and if we have not yet
+* flushed the TLBs upon release, perform a full invalidation.
+*/
+   WRITE_ONCE(tlb, intel_gt_next_invalidate_tlb_full(vm->gt));


Shouldn't tlb be a pointer for this to make sense?


Oh, my mistake! Will fix at the next version.

   

diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c 
b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
index d8b94d638559..2da6c82a8bd2 100644
--- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
@@ -206,8 +206,12 @@ void ppgtt_bind_vma(struct i915_address_space *vm,
void ppgtt_unbind_vma(struct i915_address_space *vm,
  struct i915_vma_resource *vma_res)
{
-   if (vma_res->allocated)
-   vm->clear_range(vm, vma_res->start, vma_res->vma_size);
+   if (!vma_res->allocated)
+   return;
+
+   vm->clear_range(vm, vma_res->start, vma_res->vma_size);
+   if (vma_res->tlb)
+   vma_invalidate_tlb(vm, *vma_res->tlb);


The patch is about more than batching? If there is a security hole in
this area (unbind) with the current code?


No, I don't think there's a security hole. The rationale for this is
not due to it.


In this case obvious question is why are these changes in the patch
which declares itself to be about batching invalidations? Because...


Because vma_invalidate_tlb() basically stores a TLB seqno, but the
actual invalidation is deferred to when the pages are unset, at
__i915_gem_object_unset_pages().

So, what happens is:

- on VMA sync mode, the need to invalidate TLB is marked at
   __vma_put_pages(), before VMA unbind;
- on async, this is deferred to happen at ppgtt_unbind_vma(), where
   it marks the need to invalidate TLBs.

On both cases, __i915_gem_object_unset_pages() is called later,
when the driver is ready to unmap the page.


Sorry still not clear to me why is the patch moving marking of the need 
to invalidate (regardless if it a bit like today, or a seqno like in 
this patch) from bind to unbind?


What if the seqno was stored in i915_vma_bind, where the bit is set 
today, and all the hunks which touch the unbind and evict would 
disappear from the patch. What wouldn't work in that case, if anything?


Regards,

Tvrtko




I am explaining why it looks to me that the patch is doing two things.
Implementing batching _and_ adding invalidation points at VMA unbind
sites, while so far we had it at backing store release only. Maybe I am
wrong and perhaps I am too slow to pick up on the explanation here.

So if the patch is doing two things please split it up.

I am further confused by the invalidation call site in evict and in
unbind - why there can't be one logical site since the logical sequence
is evict -> unbind.


The invalidation happens only on one place: __i915_gem_object_unset_pages().

Despite its name, vma_invalidate_tlb() just marks the need of doing TLB
invalidation.

Regards,
Mauro


[PATCH v3 0/6] drm/i915: reduce TLB performance regressions

2022-07-27 Thread Mauro Carvalho Chehab
Doing TLB invalidation cause performance regressions, like:
[424.370996] i915 :00:02.0: [drm] *ERROR* rcs0 TLB invalidation did 
not complete in 4ms!

As reported at:
https://gitlab.freedesktop.org/drm/intel/-/issues/6424

as this is an expensive operation. So, reduce the need of it by:
  - checking if the engine is awake;
  - checking if the engine is not wedged;
  - batching operations.

Additionally, add a workaround for a known hardware issue on some GPUs.

In order to double-check that this series won't be introducing any regressions,
I used this new IGT test:

https://patchwork.freedesktop.org/patch/495684/?series=106757=1

Checking the results for 3 different patchsets, on Broadwell:

1) On the top of drm-tip (2022y-07m-14d-08h-35m-36) - e. g. with TLB
invalidation and serialization patches:

$ sudo build/tests/gem_exec_tlb|grep Subtest
Subtest close-clear: SUCCESS (10.490s)
Subtest madv-clear: SUCCESS (10.484s)
Subtest u-unmap-clear: SUCCESS (10.527s)
Subtest u-shrink-clear: SUCCESS (10.506s)
Subtest close-dumb: SUCCESS (10.165s)
Subtest madv-dumb: SUCCESS (10.177s)
Subtest u-unmap-dumb: SUCCESS (10.172s)
Subtest u-shrink-dumb: SUCCESS (10.172s)

2) With the new version of the batch TLB invalidation patches from this series:

$ sudo build/tests/gem_exec_tlb|grep Subtest
Subtest close-clear: SUCCESS (10.483s)
Subtest madv-clear: SUCCESS (10.495s)
Subtest u-unmap-clear: SUCCESS (10.545s)
Subtest u-shrink-clear: SUCCESS (10.508s)
Subtest close-dumb: SUCCESS (10.172s)
Subtest madv-dumb: SUCCESS (10.169s)
Subtest u-unmap-dumb: SUCCESS (10.174s)
Subtest u-shrink-dumb: SUCCESS (10.176s)

3) Changing the TLB invalidation routine to do nothing[1]:

$ sudo ~/freedesktop-igt/build/tests/gem_exec_tlb|grep Subtest
(gem_exec_tlb:1958) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1958) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1958) CRITICAL: Found deadbeef in a new (clear) buffer 
after 3 tries!
(gem_exec_tlb:1956) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1956) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1956) CRITICAL: Found deadbeef in a new (clear) buffer 
after 89 tries!
(gem_exec_tlb:1957) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1957) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1957) CRITICAL: Found deadbeef in a new (clear) buffer 
after 256 tries!
(gem_exec_tlb:1960) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1960) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1960) CRITICAL: Found deadbeef in a new (clear) buffer 
after 845 tries!
(gem_exec_tlb:1961) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1961) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1961) CRITICAL: Found deadbeef in a new (clear) buffer 
after 1138 tries!
(gem_exec_tlb:1954) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1954) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1954) CRITICAL: Found deadbeef in a new (clear) buffer 
after 1359 tries!
(gem_exec_tlb:1955) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1955) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1955) CRITICAL: Found deadbeef in a new (clear) buffer 
after 1794 tries!
(gem_exec_tlb:1959) CRITICAL: Test assertion failure function check_bo, 
file ../tests/i915/gem_exec_tlb.c:384:
(gem_exec_tlb:1959) CRITICAL: Failed assertion: !sq
(gem_exec_tlb:1959) CRITICAL: Found deadbeef in a new (clear) buffer 
after 2139 tries!
Dynamic subtest smem0 failed.
 DEBUG 
(gem_exec_tlb:1944) DEBUG: 2M hole:20 contains poison:6b6b6b6b
(gem_exec_tlb:1944) DEBUG: Running writer for 20 at 30 on bcs0
(gem_exec_tlb:1944) DEBUG: Closing hole:20 on rcs0, sample:deadbeef
(gem_exec_tlb:1944) DEBUG: Rechecking hole:20, sample:6b6b6b6b
  END  
Subtest close-clear: FAIL (10.434s)
Subtest madv-clear: SUCCESS (10.479s)
Subtest u-unmap-clear: SUCCESS (10.512s)

In summary, the test does properly detect fail when TLB cache invalidation 
doesn't happen,
as shown at result (3). It also shows that both current drm-tip and drm-tip 
with this series
applied don't have TLB invalidation cache issues.

[1] I applied this patch on the top of drm-tip:

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 

[PATCH v3 6/6] drm/i915/gt: describe the new tlb parameter at i915_vma_resource

2022-07-27 Thread Mauro Carvalho Chehab
TLB cache invalidation can happen on two different situations:

1. synchronously, at __vma_put_pages();
2. asynchronously.

On the first case, TLB cache invalidation happens inside
__vma_put_pages(). So, no need to do it later on.

However, on the second case, the pages will keep in memory
until __i915_vma_evict() is called.

So, we need to store the TLB data at struct i915_vma_resource,
in order to do a TLB cache invalidation before allowing
userspace to re-use the same memory.

So, i915_vma_resource_unbind() has gained a new parameter
in order to store the TLB data at the second case.

Document it.

Signed-off-by: Mauro Carvalho Chehab 
---

To avoid mailbombing on a large number of people, only mailing lists were C/C 
on the cover.
See [PATCH v3 0/6] at: 
https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/

 drivers/gpu/drm/i915/i915_vma_resource.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_vma_resource.c 
b/drivers/gpu/drm/i915/i915_vma_resource.c
index 5a67995ea5fe..4fe09ea0a825 100644
--- a/drivers/gpu/drm/i915/i915_vma_resource.c
+++ b/drivers/gpu/drm/i915/i915_vma_resource.c
@@ -216,6 +216,10 @@ i915_vma_resource_fence_notify(struct i915_sw_fence *fence,
 /**
  * i915_vma_resource_unbind - Unbind a vma resource
  * @vma_res: The vma resource to unbind.
+ * @tlb: pointer to vma->obj->mm.tlb associated with the resource
+ *  to be stored at vma_res->tlb. When not-NULL, it will be used
+ *  to do TLB cache invalidation before freeing a VMA resource.
+ *  used only for async unbind.
  *
  * At this point this function does little more than publish a fence that
  * signals immediately unless signaling is held back.
-- 
2.36.1



[PATCH v3 5/6] drm/i915/gt: Batch TLB invalidations

2022-07-27 Thread Mauro Carvalho Chehab
From: Chris Wilson 

Invalidate TLB in batches, in order to reduce performance regressions.

Currently, every caller performs a full barrier around a TLB
invalidation, ignoring all other invalidations that may have already
removed their PTEs from the cache. As this is a synchronous operation
and can be quite slow, we cause multiple threads to contend on the TLB
invalidate mutex blocking userspace.

We only need to invalidate the TLB once after replacing our PTE to
ensure that there is no possible continued access to the physical
address before releasing our pages. By tracking a seqno for each full
TLB invalidate we can quickly determine if one has been performed since
rewriting the PTE, and only if necessary trigger one for ourselves.

That helps to reduce the performance regression introduced by TLB
invalidate logic.

[mchehab: rebased to not require moving the code to a separate file]

Cc: sta...@vger.kernel.org
Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store")
Suggested-by: Tvrtko Ursulin 
Signed-off-by: Chris Wilson 
Cc: Fei Yang 
Signed-off-by: Mauro Carvalho Chehab 
---

To avoid mailbombing on a large number of people, only mailing lists were C/C 
on the cover.
See [PATCH v3 0/6] at: 
https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/

 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 +-
 drivers/gpu/drm/i915/gem/i915_gem_pages.c | 21 +---
 drivers/gpu/drm/i915/gt/intel_gt.c| 53 ++-
 drivers/gpu/drm/i915/gt/intel_gt.h| 12 -
 drivers/gpu/drm/i915/gt/intel_gt_types.h  | 18 ++-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c |  8 ++-
 drivers/gpu/drm/i915/i915_vma.c   | 33 +---
 drivers/gpu/drm/i915/i915_vma.h   |  1 +
 drivers/gpu/drm/i915/i915_vma_resource.c  |  5 +-
 drivers/gpu/drm/i915/i915_vma_resource.h  |  6 ++-
 10 files changed, 125 insertions(+), 35 deletions(-)

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 5cf36a130061..9f6b14ec189a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -335,7 +335,6 @@ struct drm_i915_gem_object {
 #define I915_BO_READONLY  BIT(7)
 #define I915_TILING_QUIRK_BIT 8 /* unknown swizzling; do not release! */
 #define I915_BO_PROTECTED BIT(9)
-#define I915_BO_WAS_BOUND_BIT 10
/**
 * @mem_flags - Mutable placement-related flags
 *
@@ -616,6 +615,8 @@ struct drm_i915_gem_object {
 * pages were last acquired.
 */
bool dirty:1;
+
+   u32 tlb;
} mm;
 
struct {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 6835279943df..8357dbdcab5c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -191,6 +191,18 @@ static void unmap_object(struct drm_i915_gem_object *obj, 
void *ptr)
vunmap(ptr);
 }
 
+static void flush_tlb_invalidate(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct intel_gt *gt = to_gt(i915);
+
+   if (!obj->mm.tlb)
+   return;
+
+   intel_gt_invalidate_tlb(gt, obj->mm.tlb);
+   obj->mm.tlb = 0;
+}
+
 struct sg_table *
 __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 {
@@ -216,14 +228,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
*obj)
__i915_gem_object_reset_page_iter(obj);
obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0;
 
-   if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, >flags)) {
-   struct drm_i915_private *i915 = to_i915(obj->base.dev);
-   struct intel_gt *gt = to_gt(i915);
-   intel_wakeref_t wakeref;
-
-   with_intel_gt_pm_if_awake(gt, wakeref)
-   intel_gt_invalidate_tlbs(gt);
-   }
+   flush_tlb_invalidate(obj);
 
return pages;
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 5c55a90672f4..f435e06125aa 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -38,8 +38,6 @@ static void __intel_gt_init_early(struct intel_gt *gt)
 {
spin_lock_init(>irq_lock);
 
-   mutex_init(>tlb_invalidate_lock);
-
INIT_LIST_HEAD(>closed_vma);
spin_lock_init(>closed_lock);
 
@@ -50,6 +48,8 @@ static void __intel_gt_init_early(struct intel_gt *gt)
intel_gt_init_reset(gt);
intel_gt_init_requests(gt);
intel_gt_init_timelines(gt);
+   mutex_init(>tlb.invalidate_lock);
+   seqcount_mutex_init(>tlb.seqno, >tlb.invalidate_lock);
intel_gt_pm_init_early(gt);
 
intel_uc_init_early(>uc);
@@ -770,6 +770,7 @@ void intel_gt_driver_late_release_all(struct 
drm_i915_private 

[PATCH v3 3/6] drm/i915/gt: Invalidate TLB of the OA unit at TLB invalidations

2022-07-27 Thread Mauro Carvalho Chehab
From: Chris Wilson 

Ensure that the TLB of the OA unit is also invalidated
on gen12 HW, as just invalidating the TLB of an engine is not
enough.

Cc: sta...@vger.kernel.org
Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store")
Signed-off-by: Chris Wilson 
Cc: Fei Yang 
Reviewed-by: Andi Shyti 
Acked-by: Tvrtko Ursulin 
Acked-by: Thomas Hellström 
Signed-off-by: Mauro Carvalho Chehab 
---

To avoid mailbombing on a large number of people, only mailing lists were C/C 
on the cover.
See [PATCH v3 0/6] at: 
https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/

 drivers/gpu/drm/i915/gt/intel_gt.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index c4d43da84d8e..1d84418e8676 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -11,6 +11,7 @@
 #include "pxp/intel_pxp.h"
 
 #include "i915_drv.h"
+#include "i915_perf_oa_regs.h"
 #include "intel_context.h"
 #include "intel_engine_pm.h"
 #include "intel_engine_regs.h"
@@ -969,6 +970,15 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
awake |= engine->mask;
}
 
+   /* Wa_2207587034:tgl,dg1,rkl,adl-s,adl-p */
+   if (awake &&
+   (IS_TIGERLAKE(i915) ||
+IS_DG1(i915) ||
+IS_ROCKETLAKE(i915) ||
+IS_ALDERLAKE_S(i915) ||
+IS_ALDERLAKE_P(i915)))
+   intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
+
spin_unlock_irq(>lock);
 
for_each_engine_masked(engine, gt, awake, tmp) {
-- 
2.36.1



[PATCH v3 2/6] drm/i915/gt: document with_intel_gt_pm_if_awake()

2022-07-27 Thread Mauro Carvalho Chehab
Add a kernel-doc markup to document this new macro.

Reviewed-by: Tvrtko Ursulin 
Signed-off-by: Mauro Carvalho Chehab 
---

To avoid mailbombing on a large number of people, only mailing lists were C/C 
on the cover.
See [PATCH v3 0/6] at: 
https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/

 drivers/gpu/drm/i915/gt/intel_gt_pm.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index a334787a4939..6c9a46452364 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -55,6 +55,14 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt)
for (tmp = 1, intel_gt_pm_get(gt); tmp; \
 intel_gt_pm_put(gt), tmp = 0)
 
+/**
+ * with_intel_gt_pm_if_awake - if GT is PM awake, get a reference to prevent
+ * it to sleep, run some code and then asynchrously put the reference
+ * away.
+ *
+ * @gt: pointer to the gt
+ * @wf: pointer to a temporary wakeref.
+ */
 #define with_intel_gt_pm_if_awake(gt, wf) \
for (wf = intel_gt_pm_get_if_awake(gt); wf; intel_gt_pm_put_async(gt), 
wf = 0)
 
-- 
2.36.1



[PATCH v3 1/6] drm/i915/gt: Ignore TLB invalidations on idle engines

2022-07-27 Thread Mauro Carvalho Chehab
From: Chris Wilson 

Check if the device is powered down prior to any engine activity,
as, on such cases, all the TLBs were already invalidated, so an
explicit TLB invalidation is not needed, thus reducing the
performance regression impact due to it.

This becomes more significant with GuC, as it can only do so when
the connection to the GuC is awake.

Cc: sta...@vger.kernel.org
Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store")
Signed-off-by: Chris Wilson 
Cc: Fei Yang 
Reviewed-by: Andi Shyti 
Acked-by: Thomas Hellström 
Acked-by: Tvrtko Ursulin 
Signed-off-by: Mauro Carvalho Chehab 
---

To avoid mailbombing on a large number of people, only mailing lists were C/C 
on the cover.
See [PATCH v3 0/6] at: 
https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/

 drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 ++
 drivers/gpu/drm/i915/gt/intel_gt.c| 17 ++---
 drivers/gpu/drm/i915/gt/intel_gt_pm.h |  3 +++
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 97c820eee115..6835279943df 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -6,14 +6,15 @@
 
 #include 
 
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_pm.h"
+
 #include "i915_drv.h"
 #include "i915_gem_object.h"
 #include "i915_scatterlist.h"
 #include "i915_gem_lmem.h"
 #include "i915_gem_mman.h"
 
-#include "gt/intel_gt.h"
-
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 struct sg_table *pages,
 unsigned int sg_page_sizes)
@@ -217,10 +218,11 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
*obj)
 
if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, >flags)) {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct intel_gt *gt = to_gt(i915);
intel_wakeref_t wakeref;
 
-   with_intel_runtime_pm_if_active(>runtime_pm, wakeref)
-   intel_gt_invalidate_tlbs(to_gt(i915));
+   with_intel_gt_pm_if_awake(gt, wakeref)
+   intel_gt_invalidate_tlbs(gt);
}
 
return pages;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 68c2b0d8f187..c4d43da84d8e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -12,6 +12,7 @@
 
 #include "i915_drv.h"
 #include "intel_context.h"
+#include "intel_engine_pm.h"
 #include "intel_engine_regs.h"
 #include "intel_ggtt_gmch.h"
 #include "intel_gt.h"
@@ -924,6 +925,7 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
struct drm_i915_private *i915 = gt->i915;
struct intel_uncore *uncore = gt->uncore;
struct intel_engine_cs *engine;
+   intel_engine_mask_t awake, tmp;
enum intel_engine_id id;
const i915_reg_t *regs;
unsigned int num = 0;
@@ -947,26 +949,31 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
 
GEM_TRACE("\n");
 
-   assert_rpm_wakelock_held(>runtime_pm);
-
mutex_lock(>tlb_invalidate_lock);
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 
spin_lock_irq(>lock); /* serialise invalidate with GT reset */
 
+   awake = 0;
for_each_engine(engine, gt, id) {
struct reg_and_bit rb;
 
+   if (!intel_engine_pm_is_awake(engine))
+   continue;
+
rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num);
if (!i915_mmio_reg_offset(rb.reg))
continue;
 
intel_uncore_write_fw(uncore, rb.reg, rb.bit);
+   awake |= engine->mask;
}
 
spin_unlock_irq(>lock);
 
-   for_each_engine(engine, gt, id) {
+   for_each_engine_masked(engine, gt, awake, tmp) {
+   struct reg_and_bit rb;
+
/*
 * HW architecture suggest typical invalidation time at 40us,
 * with pessimistic cases up to 100us and a recommendation to
@@ -974,12 +981,8 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
 */
const unsigned int timeout_us = 100;
const unsigned int timeout_ms = 4;
-   struct reg_and_bit rb;
 
rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num);
-   if (!i915_mmio_reg_offset(rb.reg))
-   continue;
-
if (__intel_wait_for_register_fw(uncore,
 rb.reg, rb.bit, 0,
 timeout_us, timeout_ms,
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index bc898df7a48c..a334787a4939 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ 

[PATCH v3 4/6] drm/i915/gt: Skip TLB invalidations once wedged

2022-07-27 Thread Mauro Carvalho Chehab
From: Chris Wilson 

Skip all further TLB invalidations once the device is wedged and
had been reset, as, on such cases, it can no longer process instructions
on the GPU and the user no longer has access to the TLB's in each engine.

So, an attempt to do a TLB cache invalidation will produce a timeout.

That helps to reduce the performance regression introduced by TLB
invalidate logic.

Cc: sta...@vger.kernel.org
Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store")
Signed-off-by: Chris Wilson 
Cc: Fei Yang 
Cc: Tvrtko Ursulin 
Reviewed-by: Andi Shyti 
Acked-by: Thomas Hellström 
Signed-off-by: Mauro Carvalho Chehab 
---

To avoid mailbombing on a large number of people, only mailing lists were C/C 
on the cover.
See [PATCH v3 0/6] at: 
https://lore.kernel.org/all/cover.1658924372.git.mche...@kernel.org/

 drivers/gpu/drm/i915/gt/intel_gt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 1d84418e8676..5c55a90672f4 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -934,6 +934,9 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
if (I915_SELFTEST_ONLY(gt->awake == -ENODEV))
return;
 
+   if (intel_gt_is_wedged(gt))
+   return;
+
if (GRAPHICS_VER(i915) == 12) {
regs = gen12_regs;
num = ARRAY_SIZE(gen12_regs);
-- 
2.36.1



Re: [PATCH] drm/tests: Split up test cases in igt_check_drm_format_min_pitch

2022-07-27 Thread Maíra Canal
Hi all,

Friendly ping: is someone available to take this, please?

Best Regards,
- Maíra Canal

On 7/17/22 15:43, Maíra Canal wrote:
> The igt_check_drm_format_min_pitch() function had a lot of
> KUNIT_EXPECT_* calls, all of which ended up allocating and initializing
> various test assertion structures on the stack.
> 
> This behavior was producing -Wframe-larger-than warnings on PowerPC, i386,
> and MIPS architectures, such as:
> 
> drivers/gpu/drm/tests/drm_format_test.c: In function 
> 'igt_check_drm_format_min_pitch':
> drivers/gpu/drm/tests/drm_format_test.c:271:1: error: the frame size of
> 3712 bytes is larger than 2048 bytes
> 
> So, the igt_check_drm_format_min_pitch() test case was split into three
> smaller functions: one testing single plane formats, one testing multiple
> planes formats, and the other testing tiled formats.
> 
> Reported-by: kernel test robot 
> Reported-by: Guenter Roeck 
> Signed-off-by: Maíra Canal 
> ---
>  drivers/gpu/drm/tests/drm_format_test.c | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_format_test.c 
> b/drivers/gpu/drm/tests/drm_format_test.c
> index 056cb8599d6d..28f2b8f88818 100644
> --- a/drivers/gpu/drm/tests/drm_format_test.c
> +++ b/drivers/gpu/drm/tests/drm_format_test.c
> @@ -91,7 +91,7 @@ static void igt_check_drm_format_block_height(struct kunit 
> *test)
>   KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
>  }
>  
> -static void igt_check_drm_format_min_pitch(struct kunit *test)
> +static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit 
> *test)
>  {
>   const struct drm_format_info *info = NULL;
>  
> @@ -175,6 +175,11 @@ static void igt_check_drm_format_min_pitch(struct kunit 
> *test)
>   (uint64_t)UINT_MAX * 4);
>   KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 
> 1)),
>   (uint64_t)(UINT_MAX - 1) * 4);
> +}
> +
> +static void igt_check_drm_format_min_pitch_for_multiple_planes(struct kunit 
> *test)
> +{
> + const struct drm_format_info *info = NULL;
>  
>   /* Test 2 planes format */
>   info = drm_format_info(DRM_FORMAT_NV12);
> @@ -249,6 +254,11 @@ static void igt_check_drm_format_min_pitch(struct kunit 
> *test)
>   (uint64_t)(UINT_MAX - 1) / 2);
>   KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) 
> / 2),
>   (uint64_t)(UINT_MAX - 1) / 2);
> +}
> +
> +static void igt_check_drm_format_min_pitch_for_tiled_format(struct kunit 
> *test)
> +{
> + const struct drm_format_info *info = NULL;
>  
>   /* Test tiled format */
>   info = drm_format_info(DRM_FORMAT_X0L2);
> @@ -273,7 +283,9 @@ static void igt_check_drm_format_min_pitch(struct kunit 
> *test)
>  static struct kunit_case drm_format_tests[] = {
>   KUNIT_CASE(igt_check_drm_format_block_width),
>   KUNIT_CASE(igt_check_drm_format_block_height),
> - KUNIT_CASE(igt_check_drm_format_min_pitch),
> + KUNIT_CASE(igt_check_drm_format_min_pitch_for_single_plane),
> + KUNIT_CASE(igt_check_drm_format_min_pitch_for_multiple_planes),
> + KUNIT_CASE(igt_check_drm_format_min_pitch_for_tiled_format),
>   { }
>  };
>  


Re: [Intel-gfx] [PATCH v2 06/21] drm/i915/gt: Batch TLB invalidations

2022-07-27 Thread Mauro Carvalho Chehab
On Wed, 20 Jul 2022 11:49:59 +0100
Tvrtko Ursulin  wrote:

> On 20/07/2022 08:13, Mauro Carvalho Chehab wrote:
> > On Mon, 18 Jul 2022 14:52:05 +0100
> > Tvrtko Ursulin  wrote:
> >   
> >>
> >> On 14/07/2022 13:06, Mauro Carvalho Chehab wrote:  
> >>> From: Chris Wilson 
> >>>
> >>> Invalidate TLB in patch, in order to reduce performance regressions.  
> >>
> >> "in batches"?  
> > 
> > Yeah. Will fix it.

> > +void vma_invalidate_tlb(struct i915_address_space *vm, u32 tlb)
> > +{
> > +   /*
> > +* Before we release the pages that were bound by this vma, we
> > +* must invalidate all the TLBs that may still have a reference
> > +* back to our physical address. It only needs to be done once,
> > +* so after updating the PTE to point away from the pages, record
> > +* the most recent TLB invalidation seqno, and if we have not yet
> > +* flushed the TLBs upon release, perform a full invalidation.
> > +*/
> > +   WRITE_ONCE(tlb, intel_gt_next_invalidate_tlb_full(vm->gt));  
> 
> Shouldn't tlb be a pointer for this to make sense?

Oh, my mistake! Will fix at the next version.

> >   
> >>> diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c 
> >>> b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> >>> index d8b94d638559..2da6c82a8bd2 100644
> >>> --- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> >>> +++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> >>> @@ -206,8 +206,12 @@ void ppgtt_bind_vma(struct i915_address_space *vm,
> >>>void ppgtt_unbind_vma(struct i915_address_space *vm,
> >>> struct i915_vma_resource *vma_res)
> >>>{
> >>> - if (vma_res->allocated)
> >>> - vm->clear_range(vm, vma_res->start, vma_res->vma_size);
> >>> + if (!vma_res->allocated)
> >>> + return;
> >>> +
> >>> + vm->clear_range(vm, vma_res->start, vma_res->vma_size);
> >>> + if (vma_res->tlb)
> >>> + vma_invalidate_tlb(vm, *vma_res->tlb);  
> >>
> >> The patch is about more than batching? If there is a security hole in
> >> this area (unbind) with the current code?  
> > 
> > No, I don't think there's a security hole. The rationale for this is
> > not due to it.  
> 
> In this case obvious question is why are these changes in the patch 
> which declares itself to be about batching invalidations? Because...

Because vma_invalidate_tlb() basically stores a TLB seqno, but the
actual invalidation is deferred to when the pages are unset, at
__i915_gem_object_unset_pages().

So, what happens is:

- on VMA sync mode, the need to invalidate TLB is marked at
  __vma_put_pages(), before VMA unbind;
- on async, this is deferred to happen at ppgtt_unbind_vma(), where
  it marks the need to invalidate TLBs.

On both cases, __i915_gem_object_unset_pages() is called later,
when the driver is ready to unmap the page.

> I am explaining why it looks to me that the patch is doing two things. 
> Implementing batching _and_ adding invalidation points at VMA unbind 
> sites, while so far we had it at backing store release only. Maybe I am 
> wrong and perhaps I am too slow to pick up on the explanation here.
> 
> So if the patch is doing two things please split it up.
> 
> I am further confused by the invalidation call site in evict and in 
> unbind - why there can't be one logical site since the logical sequence 
> is evict -> unbind.

The invalidation happens only on one place: __i915_gem_object_unset_pages().

Despite its name, vma_invalidate_tlb() just marks the need of doing TLB
invalidation.

Regards,
Mauro


[PATCH 09/12] drm/format-helper: Rework XRGB8888-to-XRGB2101010 conversion

2022-07-27 Thread Thomas Zimmermann
Update XRGB-to-XRGB2101010 conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 35 +
 include/drm/drm_format_helper.h |  6 ++---
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 155827eebe99..209f63b66c5f 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -504,26 +504,34 @@ static void drm_fb_xrgb_to_xrgb2101010_line(void 
*dbuf, const void *sbuf, un
 }
 
 /**
- * drm_fb_xrgb_to_xrgb2101010_toio - Convert XRGB to XRGB2101010 clip
- * buffer
- * @dst: XRGB2101010 destination buffer (iomem)
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB source buffer
+ * drm_fb_xrgb_to_xrgb2101010 - Convert XRGB to XRGB2101010 clip buffer
+ * @dst: Array of XRGB2101010 destination buffers
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of XRGB source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
  * Drivers can use this function for XRGB2101010 devices that don't natively
  * support XRGB.
  */
-void drm_fb_xrgb_to_xrgb2101010_toio(void __iomem *dst,
-unsigned int dst_pitch, const void 
*vaddr,
-const struct drm_framebuffer *fb,
-const struct drm_rect *clip)
+void drm_fb_xrgb_to_xrgb2101010(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+   const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+   const struct drm_rect *clip)
 {
-   drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false,
-drm_fb_xrgb_to_xrgb2101010_line);
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, 
vmap[0].vaddr, fb,
+clip, false, 
drm_fb_xrgb_to_xrgb2101010_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb,
+   clip, false, drm_fb_xrgb_to_xrgb2101010_line);
 }
-EXPORT_SYMBOL(drm_fb_xrgb_to_xrgb2101010_toio);
 
 static void drm_fb_xrgb_to_gray8_line(void *dbuf, const void *sbuf, 
unsigned int pixels)
 {
@@ -628,8 +636,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int 
*dst_pitch, uint32_t d
}
} else if (dst_format == DRM_FORMAT_XRGB2101010) {
if (fb_format == DRM_FORMAT_XRGB) {
-   drm_fb_xrgb_to_xrgb2101010_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
-   vmap[0].vaddr, fb, 
clip);
+   drm_fb_xrgb_to_xrgb2101010(dst, dst_pitch, vmap, 
fb, clip);
return 0;
}
}
diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h
index 8c633dbab5d6..6807440ce29c 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -29,9 +29,9 @@ void drm_fb_xrgb_to_rgb565(struct iosys_map *dst, const 
unsigned int *dst_pi
 void drm_fb_xrgb_to_rgb888(struct iosys_map *dst, const unsigned int 
*dst_pitch,
   const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
   const struct drm_rect *clip);
-void drm_fb_xrgb_to_xrgb2101010_toio(void __iomem *dst, unsigned int 
dst_pitch,
-const void *vaddr, const struct 
drm_framebuffer *fb,
-const struct drm_rect *clip);
+void drm_fb_xrgb_to_xrgb2101010(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+   const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+   const struct drm_rect *clip);
 void drm_fb_xrgb_to_gray8(void *dst, unsigned int dst_pitch, const void 
*vaddr,
  const struct drm_framebuffer *fb, const struct 
drm_rect *clip);
 
-- 
2.37.1



[PATCH 10/12] drm/format-helper: Rework XRGB8888-to-GRAY8 conversion

2022-07-27 Thread Thomas Zimmermann
Update XRGB-to-GRAY8 conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 25 +++--
 drivers/gpu/drm/gud/gud_pipe.c  |  7 +--
 drivers/gpu/drm/tiny/st7586.c   |  5 -
 include/drm/drm_format_helper.h |  5 +++--
 4 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 209f63b66c5f..521932fac491 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -552,9 +552,9 @@ static void drm_fb_xrgb_to_gray8_line(void *dbuf, const 
void *sbuf, unsigned
 
 /**
  * drm_fb_xrgb_to_gray8 - Convert XRGB to grayscale
- * @dst: 8-bit grayscale destination buffer
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB source buffer
+ * @dst: Array of 8-bit grayscale destination buffers
+ * @dst_pitch: Array of number of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of XRGB source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
@@ -567,10 +567,23 @@ static void drm_fb_xrgb_to_gray8_line(void *dbuf, 
const void *sbuf, unsigned
  *
  * ITU BT.601 is used for the RGB -> luma (brightness) conversion.
  */
-void drm_fb_xrgb_to_gray8(void *dst, unsigned int dst_pitch, const void 
*vaddr,
- const struct drm_framebuffer *fb, const struct 
drm_rect *clip)
+void drm_fb_xrgb_to_gray8(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+ const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+ const struct drm_rect *clip)
 {
-   drm_fb_xfrm(dst, dst_pitch, 1, vaddr, fb, clip, false, 
drm_fb_xrgb_to_gray8_line);
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 1, 
vmap[0].vaddr, fb,
+clip, false, drm_fb_xrgb_to_gray8_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 1, vmap[0].vaddr, fb,
+   clip, false, drm_fb_xrgb_to_gray8_line);
 }
 EXPORT_SYMBOL(drm_fb_xrgb_to_gray8);
 
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 0caa228f736d..7c6dc2bcd14a 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -59,6 +59,7 @@ static size_t gud_xrgb_to_r124(u8 *dst, const struct 
drm_format_info *format
unsigned int bits_per_pixel = 8 / block_width;
unsigned int x, y, width, height;
u8 pix, *pix8, *block = dst; /* Assign to silence compiler warning */
+   struct iosys_map dst_map, vmap;
size_t len;
void *buf;
 
@@ -74,7 +75,9 @@ static size_t gud_xrgb_to_r124(u8 *dst, const struct 
drm_format_info *format
if (!buf)
return 0;
 
-   drm_fb_xrgb_to_gray8(buf, 0, src, fb, rect);
+   iosys_map_set_vaddr(_map, buf);
+   iosys_map_set_vaddr(, src);
+   drm_fb_xrgb_to_gray8(_map, NULL, , fb, rect);
pix8 = buf;
 
for (y = 0; y < height; y++) {
@@ -194,7 +197,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct 
drm_framebuffer *fb,
goto end_cpu_access;
}
} else if (format->format == DRM_FORMAT_R8) {
-   drm_fb_xrgb_to_gray8(buf, 0, vaddr, fb, rect);
+   drm_fb_xrgb_to_gray8(, NULL, map_data, fb, 
rect);
} else if (format->format == DRM_FORMAT_RGB332) {
drm_fb_xrgb_to_rgb332(, NULL, map_data, fb, 
rect);
} else if (format->format == DRM_FORMAT_RGB565) {
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 8eddb020c43e..702350d0f8bc 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -69,12 +69,15 @@ static void st7586_xrgb_to_gray332(u8 *dst, void *vaddr,
size_t len = (clip->x2 - clip->x1) * (clip->y2 - clip->y1);
unsigned int x, y;
u8 *src, *buf, val;
+   struct iosys_map dst_map, vmap;
 
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return;
 
-   drm_fb_xrgb_to_gray8(buf, 0, vaddr, fb, clip);
+   iosys_map_set_vaddr(_map, buf);
+   iosys_map_set_vaddr(, vaddr);
+   drm_fb_xrgb_to_gray8(_map, NULL, , fb, clip);
src = buf;
 
for (y = clip->y1; y < clip->y2; y++) {
diff --git a/include/drm/drm_format_helper.h 

[PATCH 08/12] drm/format-helper: Rework RGB888-to-XRGB8888 conversion

2022-07-27 Thread Thomas Zimmermann
Update RGB888-to-XRGB conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 5ef06f696657..155827eebe99 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -465,12 +465,24 @@ static void drm_fb_rgb888_to_xrgb_line(void *dbuf, 
const void *sbuf, unsigne
}
 }
 
-static void drm_fb_rgb888_to_xrgb_toio(void __iomem *dst, unsigned int 
dst_pitch,
-  const void *vaddr, const struct 
drm_framebuffer *fb,
-  const struct drm_rect *clip)
+static void drm_fb_rgb888_to_xrgb(struct iosys_map *dst, const unsigned 
int *dst_pitch,
+ const struct iosys_map *vmap,
+ const struct drm_framebuffer *fb,
+ const struct drm_rect *clip)
 {
-   drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false,
-drm_fb_rgb888_to_xrgb_line);
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, 
vmap[0].vaddr, fb,
+clip, false, drm_fb_rgb888_to_xrgb_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb,
+   clip, false, drm_fb_rgb888_to_xrgb_line);
 }
 
 static void drm_fb_xrgb_to_xrgb2101010_line(void *dbuf, const void *sbuf, 
unsigned int pixels)
@@ -608,8 +620,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int 
*dst_pitch, uint32_t d
}
} else if (dst_format == DRM_FORMAT_XRGB) {
if (fb_format == DRM_FORMAT_RGB888) {
-   drm_fb_rgb888_to_xrgb_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
-  vmap[0].vaddr, fb, clip);
+   drm_fb_rgb888_to_xrgb(dst, dst_pitch, vmap, fb, 
clip);
return 0;
} else if (fb_format == DRM_FORMAT_RGB565) {
drm_fb_rgb565_to_xrgb(dst, dst_pitch, vmap, fb, 
clip);
-- 
2.37.1



[PATCH 12/12] drm/format-helper: Move destination-buffer handling into internal helper

2022-07-27 Thread Thomas Zimmermann
The format-convertion helpers handle several cases for different
values of destination buffer and pitch. Move that code into the
internal helper drm_fb_xfrm() and avoid quite a bit of duplucation.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 169 +++-
 1 file changed, 64 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index d296d181659d..35aebdb90165 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -41,11 +41,11 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const 
struct drm_format_info
 }
 EXPORT_SYMBOL(drm_fb_clip_offset);
 
-/* TODO: Make this functon work with multi-plane formats. */
-static int drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long 
dst_pixsize,
-  const void *vaddr, const struct drm_framebuffer *fb,
-  const struct drm_rect *clip, bool vaddr_cached_hint,
-  void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned 
int npixels))
+/* TODO: Make this function work with multi-plane formats. */
+static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long 
dst_pixsize,
+const void *vaddr, const struct drm_framebuffer *fb,
+const struct drm_rect *clip, bool vaddr_cached_hint,
+void (*xfrm_line)(void *dbuf, const void *sbuf, 
unsigned int npixels))
 {
unsigned long linepixels = drm_rect_width(clip);
unsigned long lines = drm_rect_height(clip);
@@ -84,11 +84,11 @@ static int drm_fb_xfrm(void *dst, unsigned long dst_pitch, 
unsigned long dst_pix
return 0;
 }
 
-/* TODO: Make this functon work with multi-plane formats. */
-static int drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, 
unsigned long dst_pixsize,
-   const void *vaddr, const struct drm_framebuffer *fb,
-   const struct drm_rect *clip, bool vaddr_cached_hint,
-   void (*xfrm_line)(void *dbuf, const void *sbuf, 
unsigned int npixels))
+/* TODO: Make this function work with multi-plane formats. */
+static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, 
unsigned long dst_pixsize,
+ const void *vaddr, const struct drm_framebuffer 
*fb,
+ const struct drm_rect *clip, bool 
vaddr_cached_hint,
+ void (*xfrm_line)(void *dbuf, const void *sbuf, 
unsigned int npixels))
 {
unsigned long linepixels = drm_rect_width(clip);
unsigned long lines = drm_rect_height(clip);
@@ -129,6 +129,29 @@ static int drm_fb_xfrm_toio(void __iomem *dst, unsigned 
long dst_pitch, unsigned
return 0;
 }
 
+/* TODO: Make this function work with multi-plane formats. */
+static int drm_fb_xfrm(struct iosys_map *dst,
+  const unsigned int *dst_pitch, const u8 *dst_pixsize,
+  const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+  const struct drm_rect *clip, bool vaddr_cached_hint,
+  void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned 
int npixels))
+{
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   return __drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 
dst_pixsize[0],
+ vmap[0].vaddr, fb, clip, false, 
xfrm_line);
+   else
+   return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0],
+vmap[0].vaddr, fb, clip, false, xfrm_line);
+}
+
+
 /**
  * drm_fb_memcpy - Copy clip buffer
  * @dst: Array of destination buffers
@@ -213,14 +236,10 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned 
int *dst_pitch,
 const struct iosys_map *vmap, const struct drm_framebuffer *fb,
 const struct drm_rect *clip, bool cached)
 {
-   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
-   0, 0, 0, 0
-   };
const struct drm_format_info *format = fb->format;
-   u8 cpp = format->cpp[0];
void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels);
 
-   switch (cpp) {
+   switch (format->cpp[0]) {
case 4:
swab_line = drm_fb_swab32_line;
break;
@@ -230,21 +249,10 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned 
int *dst_pitch,
default:
drm_warn_once(fb->dev, "Format %p4cc has unsupported pixel 
size.\n",
  >format);
-   swab_line = NULL;
-   break;
-   }
-   if (!swab_line)
return;
+ 

[PATCH 11/12] drm/format-helper: Rework XRGB8888-to-MONO conversion

2022-07-27 Thread Thomas Zimmermann
Update XRGB-to-MONO conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 28 +++-
 drivers/gpu/drm/solomon/ssd130x.c   |  7 ---
 drivers/gpu/drm/tiny/repaper.c  |  6 +-
 include/drm/drm_format_helper.h |  5 +++--
 4 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 521932fac491..d296d181659d 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -680,9 +680,9 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const 
void *sbuf, unsigned int
 
 /**
  * drm_fb_xrgb_to_mono - Convert XRGB to monochrome
- * @dst: monochrome destination buffer (0=black, 1=white)
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB source buffer
+ * @dst: Array of monochrome destination buffers (0=black, 1=white)
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of XRGB source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
@@ -700,26 +700,36 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const 
void *sbuf, unsigned int
  * x-coordinate that is a multiple of 8, then the caller must take care itself
  * of supplying a suitable clip rectangle.
  */
-void drm_fb_xrgb_to_mono(void *dst, unsigned int dst_pitch, const void 
*vaddr,
-const struct drm_framebuffer *fb, const struct 
drm_rect *clip)
+void drm_fb_xrgb_to_mono(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+const struct drm_rect *clip)
 {
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
unsigned int linepixels = drm_rect_width(clip);
unsigned int lines = drm_rect_height(clip);
unsigned int cpp = fb->format->cpp[0];
unsigned int len_src32 = linepixels * cpp;
struct drm_device *dev = fb->dev;
+   void *vaddr = vmap[0].vaddr;
+   unsigned int dst_pitch_0;
unsigned int y;
-   u8 *mono = dst, *gray8;
+   u8 *mono = dst[0].vaddr, *gray8;
u32 *src32;
 
if (drm_WARN_ON(dev, fb->format->format != DRM_FORMAT_XRGB))
return;
 
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+   dst_pitch_0 = dst_pitch[0];
+
/*
 * The mono destination buffer contains 1 bit per pixel
 */
-   if (!dst_pitch)
-   dst_pitch = DIV_ROUND_UP(linepixels, 8);
+   if (!dst_pitch_0)
+   dst_pitch_0 = DIV_ROUND_UP(linepixels, 8);
 
/*
 * The cma memory is write-combined so reads are uncached.
@@ -744,7 +754,7 @@ void drm_fb_xrgb_to_mono(void *dst, unsigned int 
dst_pitch, const void *vadd
drm_fb_xrgb_to_gray8_line(gray8, src32, linepixels);
drm_fb_gray8_to_mono_line(mono, gray8, linepixels);
vaddr += fb->pitches[0];
-   mono += dst_pitch;
+   mono += dst_pitch_0;
}
 
kfree(src32);
diff --git a/drivers/gpu/drm/solomon/ssd130x.c 
b/drivers/gpu/drm/solomon/ssd130x.c
index 5a3e3b78cd9e..aa7329a65c98 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -537,11 +537,11 @@ static void ssd130x_clear_screen(struct ssd130x_device 
*ssd130x)
kfree(buf);
 }
 
-static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct 
iosys_map *map,
+static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct 
iosys_map *vmap,
struct drm_rect *rect)
 {
struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
-   void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */
+   struct iosys_map dst;
unsigned int dst_pitch;
int ret = 0;
u8 *buf = NULL;
@@ -555,7 +555,8 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, 
const struct iosys_m
if (!buf)
return -ENOMEM;
 
-   drm_fb_xrgb_to_mono(buf, dst_pitch, vmap, fb, rect);
+   iosys_map_set_vaddr(, buf);
+   drm_fb_xrgb_to_mono(, _pitch, vmap, fb, rect);
 
ssd130x_update_rect(ssd130x, buf, rect);
 
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 013790c45d0a..0cdf6ab8fcc5 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -513,6 +513,8 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
 {
struct drm_gem_cma_object *cma_obj = 

[PATCH 06/12] drm/format-helper: Rework XRGB8888-to-RGB888 conversion

2022-07-27 Thread Thomas Zimmermann
Update XRGB-to-RGB888 conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 48 -
 drivers/gpu/drm/gud/gud_pipe.c  |  2 +-
 drivers/gpu/drm/tiny/cirrus.c   |  3 +-
 include/drm/drm_format_helper.h |  8 ++---
 4 files changed, 25 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 8bf5655f5ce0..4edab44336d8 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -383,41 +383,34 @@ static void drm_fb_xrgb_to_rgb888_line(void *dbuf, 
const void *sbuf, unsigne
 
 /**
  * drm_fb_xrgb_to_rgb888 - Convert XRGB to RGB888 clip buffer
- * @dst: RGB888 destination buffer
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @src: XRGB source buffer
+ * @dst: Array of RGB888 destination buffers
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of XRGB source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
  * Drivers can use this function for RGB888 devices that don't natively
  * support XRGB.
  */
-void drm_fb_xrgb_to_rgb888(void *dst, unsigned int dst_pitch, const void 
*src,
-  const struct drm_framebuffer *fb, const struct 
drm_rect *clip)
+void drm_fb_xrgb_to_rgb888(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+  const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+  const struct drm_rect *clip)
 {
-   drm_fb_xfrm(dst, dst_pitch, 3, src, fb, clip, false, 
drm_fb_xrgb_to_rgb888_line);
-}
-EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888);
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
 
-/**
- * drm_fb_xrgb_to_rgb888_toio - Convert XRGB to RGB888 clip buffer
- * @dst: RGB565 destination buffer (iomem)
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB source buffer
- * @fb: DRM framebuffer
- * @clip: Clip rectangle area to copy
- *
- * Drivers can use this function for RGB888 devices that don't natively
- * support XRGB.
- */
-void drm_fb_xrgb_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch,
-   const void *vaddr, const struct 
drm_framebuffer *fb,
-   const struct drm_rect *clip)
-{
-   drm_fb_xfrm_toio(dst, dst_pitch, 3, vaddr, fb, clip, false,
-drm_fb_xrgb_to_rgb888_line);
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 3, 
vmap[0].vaddr, fb,
+clip, false, drm_fb_xrgb_to_rgb888_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 3, vmap[0].vaddr, fb,
+   clip, false, drm_fb_xrgb_to_rgb888_line);
 }
-EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888_toio);
+EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888);
 
 static void drm_fb_rgb565_to_xrgb_line(void *dbuf, const void *sbuf, 
unsigned int pixels)
 {
@@ -598,8 +591,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int 
*dst_pitch, uint32_t d
}
} else if (dst_format == DRM_FORMAT_RGB888) {
if (fb_format == DRM_FORMAT_XRGB) {
-   drm_fb_xrgb_to_rgb888_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
-  vmap[0].vaddr, fb, clip);
+   drm_fb_xrgb_to_rgb888(dst, dst_pitch, vmap, fb, 
clip);
return 0;
}
} else if (dst_format == DRM_FORMAT_XRGB) {
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index a43eb6645352..0caa228f736d 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -201,7 +201,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct 
drm_framebuffer *fb,
drm_fb_xrgb_to_rgb565(, NULL, map_data, fb, 
rect,
  gud_is_big_endian());
} else if (format->format == DRM_FORMAT_RGB888) {
-   drm_fb_xrgb_to_rgb888(buf, 0, vaddr, fb, rect);
+   drm_fb_xrgb_to_rgb888(, NULL, map_data, fb, 
rect);
} else {
len = gud_xrgb_to_color(buf, format, vaddr, fb, 
rect);
}
diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c
index 9cd398e4700b..354d5e854a6f 100644
--- 

[PATCH 03/12] drm/format-helper: Convert drm_fb_swab() to struct iosys_map

2022-07-27 Thread Thomas Zimmermann
Convert drm_fb_swab() to use struct iosys_map() and convert users. The
new interface supports multi-plane color formats.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 38 +
 drivers/gpu/drm/drm_mipi_dbi.c  |  2 +-
 drivers/gpu/drm/gud/gud_pipe.c  |  2 +-
 include/drm/drm_format_helper.h |  6 ++---
 4 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 49589b442f18..fa22d3cb11e8 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -196,9 +196,9 @@ static void drm_fb_swab32_line(void *dbuf, const void 
*sbuf, unsigned int pixels
 
 /**
  * drm_fb_swab - Swap bytes into clip buffer
- * @dst: Destination buffer
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @src: Source buffer
+ * @dst: Array of destination buffers
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  * @cached: Source buffer is mapped cached (eg. not write-combined)
@@ -209,24 +209,42 @@ static void drm_fb_swab32_line(void *dbuf, const void 
*sbuf, unsigned int pixels
  * This function does not apply clipping on dst, i.e. the destination
  * is at the top-left corner.
  */
-void drm_fb_swab(void *dst, unsigned int dst_pitch, const void *src,
-const struct drm_framebuffer *fb, const struct drm_rect *clip,
-bool cached)
+void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch,
+const struct iosys_map *vmap, const struct drm_framebuffer *fb,
+const struct drm_rect *clip, bool cached)
 {
-   u8 cpp = fb->format->cpp[0];
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+   const struct drm_format_info *format = fb->format;
+   u8 cpp = format->cpp[0];
+   void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels);
 
switch (cpp) {
case 4:
-   drm_fb_xfrm(dst, dst_pitch, cpp, src, fb, clip, cached, 
drm_fb_swab32_line);
+   swab_line = drm_fb_swab32_line;
break;
case 2:
-   drm_fb_xfrm(dst, dst_pitch, cpp, src, fb, clip, cached, 
drm_fb_swab16_line);
+   swab_line = drm_fb_swab16_line;
break;
default:
drm_warn_once(fb->dev, "Format %p4cc has unsupported pixel 
size.\n",
- >format->format);
+ >format);
+   swab_line = NULL;
break;
}
+   if (!swab_line)
+   return;
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst->is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], cpp,
+vmap[0].vaddr, fb, clip, cached, swab_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], cpp, vmap[0].vaddr, fb,
+   clip, cached, swab_line);
 }
 EXPORT_SYMBOL(drm_fb_swab);
 
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 22451806fb5c..973a75585cad 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -221,7 +221,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
switch (fb->format->format) {
case DRM_FORMAT_RGB565:
if (swap)
-   drm_fb_swab(dst, 0, src, fb, clip, !gem->import_attach);
+   drm_fb_swab(_map, NULL, data, fb, clip, 
!gem->import_attach);
else
drm_fb_memcpy(_map, NULL, data, fb, clip);
break;
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 449c95a4aee0..a15cda9ba058 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -205,7 +205,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct 
drm_framebuffer *fb,
len = gud_xrgb_to_color(buf, format, vaddr, fb, 
rect);
}
} else if (gud_is_big_endian() && format->cpp[0] > 1) {
-   drm_fb_swab(buf, 0, vaddr, fb, rect, !import_attach);
+   drm_fb_swab(, NULL, map_data, fb, rect, !import_attach);
} else if (compression && !import_attach && pitch == fb->pitches[0]) {
/* can compress directly from the framebuffer */
buf = vaddr + rect->y1 * pitch;
diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h
index 8af6a2717bc9..60944feaa936 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -17,9 +17,9 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const 
struct 

[PATCH 07/12] drm/format-helper: Rework RGB565-to-XRGB8888 conversion

2022-07-27 Thread Thomas Zimmermann
Update RGB565-to-XRGB conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 4edab44336d8..5ef06f696657 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -430,12 +430,24 @@ static void drm_fb_rgb565_to_xrgb_line(void *dbuf, 
const void *sbuf, unsigne
}
 }
 
-static void drm_fb_rgb565_to_xrgb_toio(void __iomem *dst, unsigned int 
dst_pitch,
-  const void *vaddr, const struct 
drm_framebuffer *fb,
-  const struct drm_rect *clip)
+static void drm_fb_rgb565_to_xrgb(struct iosys_map *dst, const unsigned 
int *dst_pitch,
+ const struct iosys_map *vmap,
+ const struct drm_framebuffer *fb,
+ const struct drm_rect *clip)
 {
-   drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false,
-drm_fb_rgb565_to_xrgb_line);
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 4, 
vmap[0].vaddr, fb,
+clip, false, drm_fb_rgb565_to_xrgb_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 4, vmap[0].vaddr, fb,
+   clip, false, drm_fb_rgb565_to_xrgb_line);
 }
 
 static void drm_fb_rgb888_to_xrgb_line(void *dbuf, const void *sbuf, 
unsigned int pixels)
@@ -600,8 +612,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int 
*dst_pitch, uint32_t d
   vmap[0].vaddr, fb, clip);
return 0;
} else if (fb_format == DRM_FORMAT_RGB565) {
-   drm_fb_rgb565_to_xrgb_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
-  vmap[0].vaddr, fb, clip);
+   drm_fb_rgb565_to_xrgb(dst, dst_pitch, vmap, fb, 
clip);
return 0;
}
} else if (dst_format == DRM_FORMAT_XRGB2101010) {
-- 
2.37.1



[PATCH 05/12] drm/format-helper: Rework XRGB8888-to-RGBG565 conversion

2022-07-27 Thread Thomas Zimmermann
Update XRGB-to-RGB565 conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 59 +++--
 drivers/gpu/drm/drm_mipi_dbi.c  |  4 +-
 drivers/gpu/drm/gud/gud_pipe.c  |  3 +-
 drivers/gpu/drm/tiny/cirrus.c   |  3 +-
 include/drm/drm_format_helper.h |  9 ++---
 5 files changed, 30 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 2b5c3746ff4a..8bf5655f5ce0 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -330,9 +330,9 @@ static void drm_fb_xrgb_to_rgb565_swab_line(void *dbuf, 
const void *sbuf,
 
 /**
  * drm_fb_xrgb_to_rgb565 - Convert XRGB to RGB565 clip buffer
- * @dst: RGB565 destination buffer
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB source buffer
+ * @dst: Array of RGB565 destination buffers
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of XRGB source buffer
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  * @swab: Swap bytes
@@ -340,43 +340,31 @@ static void drm_fb_xrgb_to_rgb565_swab_line(void 
*dbuf, const void *sbuf,
  * Drivers can use this function for RGB565 devices that don't natively
  * support XRGB.
  */
-void drm_fb_xrgb_to_rgb565(void *dst, unsigned int dst_pitch, const void 
*vaddr,
-  const struct drm_framebuffer *fb, const struct 
drm_rect *clip,
-  bool swab)
+void drm_fb_xrgb_to_rgb565(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+  const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+  const struct drm_rect *clip, bool swab)
 {
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+   void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels);
+
if (swab)
-   drm_fb_xfrm(dst, dst_pitch, 2, vaddr, fb, clip, false,
-   drm_fb_xrgb_to_rgb565_swab_line);
+   xfrm_line = drm_fb_xrgb_to_rgb565_swab_line;
else
-   drm_fb_xfrm(dst, dst_pitch, 2, vaddr, fb, clip, false,
-   drm_fb_xrgb_to_rgb565_line);
-}
-EXPORT_SYMBOL(drm_fb_xrgb_to_rgb565);
+   xfrm_line = drm_fb_xrgb_to_rgb565_line;
 
-/**
- * drm_fb_xrgb_to_rgb565_toio - Convert XRGB to RGB565 clip buffer
- * @dst: RGB565 destination buffer (iomem)
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: XRGB source buffer
- * @fb: DRM framebuffer
- * @clip: Clip rectangle area to copy
- * @swab: Swap bytes
- *
- * Drivers can use this function for RGB565 devices that don't natively
- * support XRGB.
- */
-void drm_fb_xrgb_to_rgb565_toio(void __iomem *dst, unsigned int dst_pitch,
-   const void *vaddr, const struct 
drm_framebuffer *fb,
-   const struct drm_rect *clip, bool swab)
-{
-   if (swab)
-   drm_fb_xfrm_toio(dst, dst_pitch, 2, vaddr, fb, clip, false,
-drm_fb_xrgb_to_rgb565_swab_line);
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 2, 
vmap[0].vaddr, fb, clip,
+false, xfrm_line);
else
-   drm_fb_xfrm_toio(dst, dst_pitch, 2, vaddr, fb, clip, false,
-drm_fb_xrgb_to_rgb565_line);
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 2, vmap[0].vaddr, fb, 
clip,
+   false, xfrm_line);
 }
-EXPORT_SYMBOL(drm_fb_xrgb_to_rgb565_toio);
+EXPORT_SYMBOL(drm_fb_xrgb_to_rgb565);
 
 static void drm_fb_xrgb_to_rgb888_line(void *dbuf, const void *sbuf, 
unsigned int pixels)
 {
@@ -605,8 +593,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int 
*dst_pitch, uint32_t d
 
} else if (dst_format == DRM_FORMAT_RGB565) {
if (fb_format == DRM_FORMAT_XRGB) {
-   drm_fb_xrgb_to_rgb565_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
-  vmap[0].vaddr, fb, clip, 
false);
+   drm_fb_xrgb_to_rgb565(dst, dst_pitch, vmap, fb, 
clip, false);
return 0;
}
} else if (dst_format == DRM_FORMAT_RGB888) {
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 973a75585cad..d0bdbcb96705 100644

[PATCH 04/12] drm/format-helper: Rework XRGB8888-to-RGBG332 conversion

2022-07-27 Thread Thomas Zimmermann
Update XRGB-to-RGB332 conversion to support struct iosys_map
and convert all users. Although these are single-plane color formats,
the new interface supports multi-plane formats for consistency with
drm_fb_blit().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c   | 25 ++-
 drivers/gpu/drm/gud/gud_pipe.c|  2 +-
 .../gpu/drm/tests/drm_format_helper_test.c| 14 ++-
 include/drm/drm_format_helper.h   |  5 ++--
 4 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index fa22d3cb11e8..2b5c3746ff4a 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -265,18 +265,31 @@ static void drm_fb_xrgb_to_rgb332_line(void *dbuf, 
const void *sbuf, unsigne
 
 /**
  * drm_fb_xrgb_to_rgb332 - Convert XRGB to RGB332 clip buffer
- * @dst: RGB332 destination buffer
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @src: XRGB source buffer
+ * @dst: Array of RGB332 destination buffers
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of XRGB source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
  * Drivers can use this function for RGB332 devices that don't natively 
support XRGB.
  */
-void drm_fb_xrgb_to_rgb332(void *dst, unsigned int dst_pitch, const void 
*src,
-  const struct drm_framebuffer *fb, const struct 
drm_rect *clip)
+void drm_fb_xrgb_to_rgb332(struct iosys_map *dst, const unsigned int 
*dst_pitch,
+  const struct iosys_map *vmap, const struct 
drm_framebuffer *fb,
+  const struct drm_rect *clip)
 {
-   drm_fb_xfrm(dst, dst_pitch, 1, src, fb, clip, false, 
drm_fb_xrgb_to_rgb332_line);
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
+
+   if (!dst_pitch)
+   dst_pitch = default_dst_pitch;
+
+   if (dst[0].is_iomem)
+   drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], 1, 
vmap[0].vaddr, fb, clip,
+false, drm_fb_xrgb_to_rgb332_line);
+   else
+   drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], 1, vmap[0].vaddr, fb, 
clip,
+   false, drm_fb_xrgb_to_rgb332_line);
 }
 EXPORT_SYMBOL(drm_fb_xrgb_to_rgb332);
 
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index a15cda9ba058..426a3ae6cc50 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -196,7 +196,7 @@ static int gud_prep_flush(struct gud_device *gdrm, struct 
drm_framebuffer *fb,
} else if (format->format == DRM_FORMAT_R8) {
drm_fb_xrgb_to_gray8(buf, 0, vaddr, fb, rect);
} else if (format->format == DRM_FORMAT_RGB332) {
-   drm_fb_xrgb_to_rgb332(buf, 0, vaddr, fb, rect);
+   drm_fb_xrgb_to_rgb332(, NULL, map_data, fb, 
rect);
} else if (format->format == DRM_FORMAT_RGB565) {
drm_fb_xrgb_to_rgb565(buf, 0, vaddr, fb, rect, 
gud_is_big_endian());
} else if (format->format == DRM_FORMAT_RGB888) {
diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 98583bf56044..b74dba06f704 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -124,7 +124,8 @@ static void xrgb_to_rgb332_test(struct kunit *test)
 {
const struct xrgb_to_rgb332_case *params = test->param_value;
size_t dst_size;
-   __u8 *dst = NULL;
+   struct iosys_map dst, xrgb;
+   __u8 *buf = NULL;
 
struct drm_framebuffer fb = {
.format = drm_format_info(DRM_FORMAT_XRGB),
@@ -135,12 +136,13 @@ static void xrgb_to_rgb332_test(struct kunit *test)
   >clip);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
-   dst = kunit_kzalloc(test, dst_size, GFP_KERNEL);
-   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst);
+   buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 
-   drm_fb_xrgb_to_rgb332(dst, params->dst_pitch, params->xrgb,
- , >clip);
-   KUNIT_EXPECT_EQ(test, memcmp(dst, params->expected, dst_size), 0);
+   iosys_map_set_vaddr(, buf);
+   iosys_map_set_vaddr(, (void __force *)params->xrgb);
+   drm_fb_xrgb_to_rgb332(, >dst_pitch, , , 
>clip);
+   KUNIT_EXPECT_EQ(test, memcmp(buf, params->expected, dst_size), 0);
 }
 
 static struct kunit_case drm_format_helper_test_cases[] = {
diff --git 

[PATCH 02/12] drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()

2022-07-27 Thread Thomas Zimmermann
Merge drm_fb_memcpy() and drm_fb_memcpy() into drm_fb_memcpy() that
uses struct iosys_map for buffers. The new function also supports
multi-plane color formats. Convert all users of the original helpers.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 77 +
 drivers/gpu/drm/drm_mipi_dbi.c  |  3 +-
 drivers/gpu/drm/gud/gud_pipe.c  |  4 +-
 drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 11 +--
 drivers/gpu/drm/mgag200/mgag200_mode.c  | 11 +--
 drivers/gpu/drm/tiny/cirrus.c   | 21 +++---
 include/drm/drm_format_helper.h |  7 +-
 7 files changed, 63 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 4d74d46ab155..49589b442f18 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -131,63 +131,48 @@ static int drm_fb_xfrm_toio(void __iomem *dst, unsigned 
long dst_pitch, unsigned
 
 /**
  * drm_fb_memcpy - Copy clip buffer
- * @dst: Destination buffer
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: Source buffer
+ * @dst: Array of destination buffers
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
+ * @vmap: Array of source buffers
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
  * This function does not apply clipping on dst, i.e. the destination
  * is at the top-left corner.
  */
-void drm_fb_memcpy(void *dst, unsigned int dst_pitch, const void *vaddr,
-  const struct drm_framebuffer *fb, const struct drm_rect 
*clip)
+void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch,
+  const struct iosys_map *vmap, const struct drm_framebuffer 
*fb,
+  const struct drm_rect *clip)
 {
-   unsigned int cpp = fb->format->cpp[0];
-   size_t len = (clip->x2 - clip->x1) * cpp;
-   unsigned int y, lines = clip->y2 - clip->y1;
-
-   if (!dst_pitch)
-   dst_pitch = len;
+   static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
+   0, 0, 0, 0
+   };
 
-   vaddr += clip_offset(clip, fb->pitches[0], cpp);
-   for (y = 0; y < lines; y++) {
-   memcpy(dst, vaddr, len);
-   vaddr += fb->pitches[0];
-   dst += dst_pitch;
-   }
-}
-EXPORT_SYMBOL(drm_fb_memcpy);
-
-/**
- * drm_fb_memcpy_toio - Copy clip buffer
- * @dst: Destination buffer (iomem)
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @vaddr: Source buffer
- * @fb: DRM framebuffer
- * @clip: Clip rectangle area to copy
- *
- * This function does not apply clipping on dst, i.e. the destination
- * is at the top-left corner.
- */
-void drm_fb_memcpy_toio(void __iomem *dst, unsigned int dst_pitch, const void 
*vaddr,
-   const struct drm_framebuffer *fb, const struct drm_rect 
*clip)
-{
-   unsigned int cpp = fb->format->cpp[0];
-   size_t len = (clip->x2 - clip->x1) * cpp;
-   unsigned int y, lines = clip->y2 - clip->y1;
+   const struct drm_format_info *format = fb->format;
+   unsigned int i, y, lines = drm_rect_height(clip);
 
if (!dst_pitch)
-   dst_pitch = len;
-
-   vaddr += clip_offset(clip, fb->pitches[0], cpp);
-   for (y = 0; y < lines; y++) {
-   memcpy_toio(dst, vaddr, len);
-   vaddr += fb->pitches[0];
-   dst += dst_pitch;
+   dst_pitch = default_dst_pitch;
+
+   for (i = 0; i < format->num_planes; ++i) {
+   unsigned int cpp_i = format->cpp[i];
+   size_t len_i = drm_rect_width(clip) * cpp_i;
+   unsigned int dst_pitch_i = dst_pitch[i];
+   struct iosys_map dst_i = dst[i];
+   struct iosys_map vmap_i = vmap[i];
+
+   if (!dst_pitch_i)
+   dst_pitch_i = len_i;
+
+   iosys_map_incr(_i, clip_offset(clip, fb->pitches[i], 
cpp_i));
+   for (y = 0; y < lines; y++) {
+   iosys_map_memcpy_to(_i, 0, vmap_i.vaddr, len_i);
+   iosys_map_incr(_i, fb->pitches[i]);
+   iosys_map_incr(_i, dst_pitch_i);
+   }
}
 }
-EXPORT_SYMBOL(drm_fb_memcpy_toio);
+EXPORT_SYMBOL(drm_fb_memcpy);
 
 static void drm_fb_swab16_line(void *dbuf, const void *sbuf, unsigned int 
pixels)
 {
@@ -584,7 +569,7 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int 
*dst_pitch, uint32_t d
dst_format = DRM_FORMAT_XRGB2101010;
 
if (dst_format == fb_format) {
-   drm_fb_memcpy_toio(dst[0].vaddr_iomem, dst_pitch[0], 
vmap[0].vaddr, fb, clip);
+   drm_fb_memcpy(dst, dst_pitch, vmap, fb, clip);
return 0;
 
} else if (dst_format == DRM_FORMAT_RGB565) {
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c 

[PATCH 00/12] drm/format-helper: Move to struct iosys_map

2022-07-27 Thread Thomas Zimmermann
Change format-conversion helpers to use struct iosys_map for source
and destination buffers. Update all users. Also prepare interface for
multi-plane color formats.

The format-conversion helpers mostly used to convert to I/O memory
or system memory. To actual memory type depended on the usecase. We
now have drivers upcomming that do the conversion entirely in system
memory. It's a good opportunity to stream-line the interface of the
conversion helpers to use struct iosys_map. Source and destination
buffers can now be either in system or in I/O memory. Note that the
implementation still only supports source buffers in system memory.

This patchset also changes the interface to support multi-plane
color formats, where the values for each component are stored in
distinct memory locations. Converting from RGBRGBRGB to RRRGGGBBB
would require a single source buffer with RGB values and 3 destination
buffers for the R, G and B values. Conversion-helper interfaces now
support this.

Thomas Zimmermann (12):
  drm/format-helper: Provide drm_fb_blit()
  drm/format-helper: Merge drm_fb_memcpy() and drm_fb_memcpy_toio()
  drm/format-helper: Convert drm_fb_swab() to struct iosys_map
  drm/format-helper: Rework XRGB-to-RGBG332 conversion
  drm/format-helper: Rework XRGB-to-RGBG565 conversion
  drm/format-helper: Rework XRGB-to-RGB888 conversion
  drm/format-helper: Rework RGB565-to-XRGB conversion
  drm/format-helper: Rework RGB888-to-XRGB conversion
  drm/format-helper: Rework XRGB-to-XRGB2101010 conversion
  drm/format-helper: Rework XRGB-to-GRAY8 conversion
  drm/format-helper: Rework XRGB-to-MONO conversion
  drm/format-helper: Move destination-buffer handling into internal
helper

 drivers/gpu/drm/drm_format_helper.c   | 379 +-
 drivers/gpu/drm/drm_mipi_dbi.c|   9 +-
 drivers/gpu/drm/gud/gud_pipe.c|  20 +-
 drivers/gpu/drm/hyperv/hyperv_drm_modeset.c   |  11 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c|  11 +-
 drivers/gpu/drm/solomon/ssd130x.c |   7 +-
 .../gpu/drm/tests/drm_format_helper_test.c|  14 +-
 drivers/gpu/drm/tiny/cirrus.c |  19 +-
 drivers/gpu/drm/tiny/repaper.c|   6 +-
 drivers/gpu/drm/tiny/simpledrm.c  |  18 +-
 drivers/gpu/drm/tiny/st7586.c |   5 +-
 include/drm/drm_format_helper.h   |  56 ++-
 12 files changed, 294 insertions(+), 261 deletions(-)


base-commit: 15fbed4f822211fbb7653c2b8591594d92de9551
prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6
-- 
2.37.1



[PATCH 01/12] drm/format-helper: Provide drm_fb_blit()

2022-07-27 Thread Thomas Zimmermann
Provide drm_fb_blit() that works with struct iosys_map. Update all
users of drm_fb_blit_toio(), which required a destination buffer in
I/O memory. The new function's interface works with multi-plane
color formats, although the implementation only supports a single
plane for now.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_format_helper.c | 39 ++---
 drivers/gpu/drm/tiny/simpledrm.c| 18 +++--
 include/drm/drm_format_helper.h |  7 +++---
 3 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index c6182b5de78b..4d74d46ab155 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -8,9 +8,10 @@
  * (at your option) any later version.
  */
 
+#include 
+#include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
@@ -545,9 +546,9 @@ void drm_fb_xrgb_to_gray8(void *dst, unsigned int 
dst_pitch, const void *vad
 EXPORT_SYMBOL(drm_fb_xrgb_to_gray8);
 
 /**
- * drm_fb_blit_toio - Copy parts of a framebuffer to display memory
- * @dst:   The display memory to copy to
- * @dst_pitch: Number of bytes between two consecutive scanlines within dst
+ * drm_fb_blit - Copy parts of a framebuffer to display memory
+ * @dst:   Array of display-memory addresses to copy to
+ * @dst_pitch: Array of numbers of bytes between two consecutive scanlines 
within dst
  * @dst_format:FOURCC code of the display's color format
  * @vmap:  The framebuffer memory to copy from
  * @fb:The framebuffer to copy from
@@ -557,14 +558,18 @@ EXPORT_SYMBOL(drm_fb_xrgb_to_gray8);
  * formats of the display and the framebuffer mismatch, the blit function
  * will attempt to convert between them.
  *
+ * The parameters @dst, @dst_pitch and @vmap refer to arrays. Each array must
+ * have at least as many entries as there are planes in @dst_format's format. 
Each
+ * entry stores the value for the format's respective color plane at the same 
index.
+ *
  * Returns:
  * 0 on success, or
  * -EINVAL if the color-format conversion failed, or
  * a negative error code otherwise.
  */
-int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t 
dst_format,
-const void *vmap, const struct drm_framebuffer *fb,
-const struct drm_rect *clip)
+int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t 
dst_format,
+   const struct iosys_map *vmap, const struct drm_framebuffer *fb,
+   const struct drm_rect *clip)
 {
uint32_t fb_format = fb->format->format;
 
@@ -579,30 +584,35 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int 
dst_pitch, uint32_t dst_for
dst_format = DRM_FORMAT_XRGB2101010;
 
if (dst_format == fb_format) {
-   drm_fb_memcpy_toio(dst, dst_pitch, vmap, fb, clip);
+   drm_fb_memcpy_toio(dst[0].vaddr_iomem, dst_pitch[0], 
vmap[0].vaddr, fb, clip);
return 0;
 
} else if (dst_format == DRM_FORMAT_RGB565) {
if (fb_format == DRM_FORMAT_XRGB) {
-   drm_fb_xrgb_to_rgb565_toio(dst, dst_pitch, vmap, 
fb, clip, false);
+   drm_fb_xrgb_to_rgb565_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
+  vmap[0].vaddr, fb, clip, 
false);
return 0;
}
} else if (dst_format == DRM_FORMAT_RGB888) {
if (fb_format == DRM_FORMAT_XRGB) {
-   drm_fb_xrgb_to_rgb888_toio(dst, dst_pitch, vmap, 
fb, clip);
+   drm_fb_xrgb_to_rgb888_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
+  vmap[0].vaddr, fb, clip);
return 0;
}
} else if (dst_format == DRM_FORMAT_XRGB) {
if (fb_format == DRM_FORMAT_RGB888) {
-   drm_fb_rgb888_to_xrgb_toio(dst, dst_pitch, vmap, 
fb, clip);
+   drm_fb_rgb888_to_xrgb_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
+  vmap[0].vaddr, fb, clip);
return 0;
} else if (fb_format == DRM_FORMAT_RGB565) {
-   drm_fb_rgb565_to_xrgb_toio(dst, dst_pitch, vmap, 
fb, clip);
+   drm_fb_rgb565_to_xrgb_toio(dst[0].vaddr_iomem, 
dst_pitch[0],
+  vmap[0].vaddr, fb, clip);
return 0;
}
} else if (dst_format == DRM_FORMAT_XRGB2101010) {
if (fb_format == DRM_FORMAT_XRGB) {
-   drm_fb_xrgb_to_xrgb2101010_toio(dst, dst_pitch, 
vmap, fb, clip);
+   drm_fb_xrgb_to_xrgb2101010_toio(dst[0].vaddr_iomem, 

Re: [PATCH 2/4] arm64: dts: qcom: add sdm845-google-blueline (Pixel 3)

2022-07-27 Thread Amit Pundir
n Tue, 19 Jul 2022 at 03:43, Dmitry Baryshkov
 wrote:
>
> On 19/07/2022 00:30, Caleb Connolly wrote:
> > From: Amit Pundir 
> >
> > This adds an initial dts for the Blueline (Pixel 3). Supported
> > functionality includes display, Debug UART, UFS, USB-C (peripheral), WiFi,
> > Bluetooth and modem.
> >
> > Bootloader compatible board and msm IDs are needed for the kernel to boot
> > with Pixel3 bootloader, so those are added.
> >
> > GPIOs 0 through 3 and 81 through 84 are configured to not be accessible
> > from the application CPUs, so we mark them as reserved to allow the Pixel 3
> > to boot.
> >
> > The reserved-memory locations where obtained from downstream using
> > kernel logs:
> > https://gist.github.com/calebccff/090d10bfac3cb9e9bd98dda30b054c96
> >
> > The rmtfs region is allocated with UIO, making it technically "dynamic".
> > It's address and size can be read from sysfs:
> >
> > blueline:/ # cat /sys/class/uio/uio0/name
> > rmtfs
> > at /sys/class/uio/uio0/maps/map0/addr
> > 0xf2701000
> > blueline:/ # cat /sys/class/uio/uio0/maps/map0/size
> > 0x0020
> >
> > Like the OnePlus 6, it needs 1kB reserved on either side of the rmtfs
> > memory to workaround some XPU bug which would otherwise cause erroneous
> > XPU violations when accessing the rmtfs_mem region.
> >
> > For wifi, the pixel 3 reports a board-id of 0xFF, and downstream
> > only includes a single bdwlan file. The qcom,ath10k-calibration-variant
> > property is set to ensure that the correct calibration data is used.
> >
> > Signed-off-by: Bjorn Andersson 
> > [AmitP: Cherry-picked and refactored from Bjorn's db845c dts
> >  ("arm64: dts: qcom: Add Dragonboard 845c") 
> > https://lkml.org/lkml/2019/6/6/7]
> > Signed-off-by: Amit Pundir 
> > [sumits: merged commits to add board and msm ids, gpio range reservation,
> >ufs device-reset gpio and adaptation to v5.5+ changes]
> > Signed-off-by: Sumit Semwal 
> > [vinod: Add display nodes]
> > Signed-off-by: Vinod Koul 
> > [caleb: remove db845c bits, cleanup, add reserved-memory for modem/wifi]
> > Signed-off-by: Caleb Connolly 
>
> Thanks for your patch, few minor items to improve.
>
> > ---
> >   arch/arm64/boot/dts/qcom/Makefile |   1 +
> >   .../boot/dts/qcom/sdm845-google-blueline.dts  | 652 ++
> >   2 files changed, 653 insertions(+)
> >   create mode 100644 arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
> >
> > diff --git a/arch/arm64/boot/dts/qcom/Makefile 
> > b/arch/arm64/boot/dts/qcom/Makefile
> > index 2f8aec2cc6db..c151e17e6eb7 100644
> > --- a/arch/arm64/boot/dts/qcom/Makefile
> > +++ b/arch/arm64/boot/dts/qcom/Makefile
> > @@ -100,6 +100,7 @@ dtb-$(CONFIG_ARCH_QCOM)   += sdm845-cheza-r1.dtb
> >   dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r2.dtb
> >   dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r3.dtb
> >   dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c.dtb
> > +dtb-$(CONFIG_ARCH_QCOM)  += sdm845-google-blueline.dtb
> >   dtb-$(CONFIG_ARCH_QCOM) += sdm845-mtp.dtb
> >   dtb-$(CONFIG_ARCH_QCOM) += sdm845-oneplus-enchilada.dtb
> >   dtb-$(CONFIG_ARCH_QCOM) += sdm845-oneplus-fajita.dtb
> > diff --git a/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts 
> > b/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
> > new file mode 100644
> > index ..dec979ad9209
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
> > @@ -0,0 +1,652 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/dts-v1/;
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "sdm845.dtsi"
> > +#include "pm8998.dtsi"
> > +#include "pmi8998.dtsi"
> > +
> > +/delete-node/ _region;
> > +/delete-node/ _mem;
> > +/delete-node/ _mem;
> > +/delete-node/ _region;
> > +/delete-node/ _mem;
> > +/delete-node/ _mem;
> > +/delete-node/ _mem;
> > +
> > +/ {
> > + model = "Google Pixel 3";
> > + compatible = "google,blueline", "qcom,sdm845";
> > + qcom,board-id = <0x00021505 0>;
> > + qcom,msm-id = <321 0x20001>;
> > +
> > + aliases {
> > + serial0 = 
> > + serial1 = 
> > + };
> > +
> > + chosen {
> > + stdout-path = "serial0:115200n8";
> > + };
> > +
> > + volume-keys {
> > + compatible = "gpio-keys";
> > + label = "Volume keys";
> > + autorepeat;
> > +
> > + pinctrl-names = "default";
> > + pinctrl-0 = <_up_gpio>;
> > +
> > + vol-up {
> > + label = "Volume Up";
> > + linux,code = ;
> > + gpios = <_gpio 6 GPIO_ACTIVE_LOW>;
> > + debounce-interval = <15>;
> > + };
> > + };
> > +
> > + reserved-memory {
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > + ranges;
>
> These properties are already part of the sdm845.dtsi, so no need to have
> them here.
>
> > +
> > + mpss_region: 

Re: [PATCH] drm: lcdif: change burst size to 256B

2022-07-27 Thread Marek Vasut

On 7/27/22 05:56, Marco Felsch wrote:

Hi Marek, Liu,


Hi,


On 22-07-26, Liu Ying wrote:

On Tue, 2022-07-26 at 16:19 +0200, Marek Vasut wrote:

On 7/26/22 11:43, Marco Felsch wrote:

FIFO underruns are seen if a AXI bus master with a higher priority
do a
lot of memory access. Increase the burst size to 256B to avoid such
underruns and to improve the memory access efficiency.


Sigh, this again ...


I know.. we also tried the PANIC mode but this somehow didn't worked as
documented. So this was the only way to reduce the underruns without
adapting the interconnect prio for the hdmi-lcdif.


Right, the PANIC watermark didn't work on mxsfb for me either when it 
came to FIFO underruns.


[...]


+* are two known values:
+*  1 - 128Byte
+*  2 - 256Byte
+*
+* Downstream has set the burst size to 256Byte to improve the
memory
+* efficiency so set it here too. This also reduces the FIFO
underrun
+* possibility.
+*/
+   ctrl = CTRLDESCL0_3_P_SIZE(2) | CTRLDESCL0_3_T_SIZE(2) |
+  CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb-

pitches[0]);

+   writel(ctrl, lcdif->base + LCDC_V8_CTRLDESCL0_3);


Nit: I would write the register directly, instead of caching the value
in ctrl.


IMHO it's more readable that way.


I agree, and we can also add to the variable in case there are more 
undocumented bits.


Re: [Intel-gfx] [PATCH v5 1/7] drm: Move and add a few utility macros into drm util header

2022-07-27 Thread Andi Shyti
Hi,

On Mon, Jul 25, 2022 at 12:25:22PM +0300, Gwan-gyeong Mun wrote:
> It moves overflows_type utility macro into drm util header from i915_utils
> header. The overflows_type can be used to catch the truncation between data
> types. And it adds safe_conversion() macro which performs a type conversion
> (cast) of an source value into a new variable, checking that the
> destination is large enough to hold the source value.
> And it adds exact_type and exactly_pgoff_t macro to catch type mis-match
> while compiling.
> 
> v3: Add is_type_unsigned() macro (Mauro)
> Modify overflows_type() macro to consider signed data types (Mauro)
> Fix the problem that safe_conversion() macro always returns true
> v4: Fix kernel-doc markups
> 
> Signed-off-by: Gwan-gyeong Mun 
> Cc: Thomas Hellström 
> Cc: Matthew Auld 
> Cc: Nirmoy Das 
> Cc: Jani Nikula 
> Reviewed-by: Mauro Carvalho Chehab 
> ---
>  drivers/gpu/drm/i915/i915_utils.h |  5 +-
>  include/drm/drm_util.h| 77 +++
>  2 files changed, 78 insertions(+), 4 deletions(-)

Jani and Mauro suggested to have this macro in
include/drm/drm_util.h.

Can I please have an ack from one of the drm maintainers so that
I can go ahead an apply this series?

Thanks,
Andi

> 
> diff --git a/drivers/gpu/drm/i915/i915_utils.h 
> b/drivers/gpu/drm/i915/i915_utils.h
> index c10d68cdc3ca..345e5b2dc1cd 100644
> --- a/drivers/gpu/drm/i915/i915_utils.h
> +++ b/drivers/gpu/drm/i915/i915_utils.h
> @@ -32,6 +32,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #ifdef CONFIG_X86
>  #include 
> @@ -111,10 +112,6 @@ bool i915_error_injected(void);
>  #define range_overflows_end_t(type, start, size, max) \
>   range_overflows_end((type)(start), (type)(size), (type)(max))
>  
> -/* Note we don't consider signbits :| */
> -#define overflows_type(x, T) \
> - (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T))
> -
>  #define ptr_mask_bits(ptr, n) ({ \
>   unsigned long __v = (unsigned long)(ptr);   \
>   (typeof(ptr))(__v & -BIT(n));   \
> diff --git a/include/drm/drm_util.h b/include/drm/drm_util.h
> index 79952d8c4bba..1de9ee5704fa 100644
> --- a/include/drm/drm_util.h
> +++ b/include/drm/drm_util.h
> @@ -62,6 +62,83 @@
>   */
>  #define for_each_if(condition) if (!(condition)) {} else
>  
> +/**
> + * is_type_unsigned - helper for checking data type which is an unsigned data
> + * type or not
> + * @x: The data type to check
> + *
> + * Returns:
> + * True if the data type is an unsigned data type, false otherwise.
> + */
> +#define is_type_unsigned(x) ((typeof(x))-1 >= (typeof(x))0)
> +
> +/**
> + * overflows_type - helper for checking the truncation between data types
> + * @x: Source for overflow type comparison
> + * @T: Destination for overflow type comparison
> + *
> + * It compares the values and size of each data type between the first and
> + * second argument to check whether truncation can occur when assigning the
> + * first argument to the variable of the second argument.
> + * Source and Destination can be used with or without sign bit.
> + * Composite data structures such as union and structure are not considered.
> + * Enum data types are not considered.
> + * Floating point data types are not considered.
> + *
> + * Returns:
> + * True if truncation can occur, false otherwise.
> + */
> +
> +#define overflows_type(x, T) \
> + (is_type_unsigned(x) ? \
> + is_type_unsigned(T) ? \
> + (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T)) ? 1 
> : 0 \
> + : (sizeof(x) >= sizeof(T) && (x) >> (BITS_PER_TYPE(T) - 
> 1)) ? 1 : 0 \
> + : is_type_unsigned(T) ? \
> + ((x) < 0) ? 1 : (sizeof(x) > sizeof(T) && (x) >> 
> BITS_PER_TYPE(T)) ? 1 : 0 \
> + : (sizeof(x) > sizeof(T)) ? \
> + ((x) < 0) ? (((x) * -1) >> BITS_PER_TYPE(T)) ? 1 : 0 \
> + : ((x) >> BITS_PER_TYPE(T)) ? 1 : 0 \
> + : 0)
> +
> +/**
> + * exact_type - break compile if source type and destination value's type are
> + * not the same
> + * @T: Source type
> + * @n: Destination value
> + *
> + * It is a helper macro for a poor man's -Wconversion: only allow variables 
> of
> + * an exact type. It determines whether the source type and destination 
> value's
> + * type are the same while compiling, and it breaks compile if two types are
> + * not the same
> + */
> +#define exact_type(T, n) \
> + BUILD_BUG_ON(!__builtin_constant_p(n) && 
> !__builtin_types_compatible_p(T, typeof(n)))
> +
> +/**
> + * exactly_pgoff_t - helper to check if the type of a value is pgoff_t
> + * @n: value to compare pgoff_t type
> + *
> + * It breaks compile if the argument value's type is not pgoff_t type.
> + */
> +#define exactly_pgoff_t(n) exact_type(pgoff_t, n)
> +
> +/**
> + * safe_conversion - perform a type conversion (cast) of an 

Re: [PATCH v3 1/2] dt-bindings: display: panel: Add Novatek NT35596S panel bindings

2022-07-27 Thread Krzysztof Kozlowski
On 26/07/2022 12:15, Molly Sophia wrote:
> Add documentation for "novatek,nt35596s" panel.
> 
> Changes in v3:
> - Embed the documentation into existing one (novatek,nt36672a).
> 
> Signed-off-by: Molly Sophia 
> ---
>  .../display/panel/novatek,nt36672a.yaml   | 20 ---
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml 
> b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> index 563766d283f6..560fb66d0e5a 100644
> --- a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> @@ -20,14 +20,20 @@ allOf:
>  
>  properties:
>compatible:
> -items:
> -  - enum:
> -  - tianma,fhd-video
> -  - const: novatek,nt36672a
> +oneOf:
> +  - items:
> +  - enum:
> +  - tianma,fhd-video
> +  - const: novatek,nt36672a
> +
> +  - items:
> +  - enum:
> +  - jdi,fhd-nt35596s
> +  - const: novatek,nt35596s

This entire entry should be rather before nt36672a judging by numbers:

+oneOf:
+  - items:
+  - enum:
+  - jdi,fhd-nt35596s
+  - const: novatek,nt35596s
+
+  - items:
+  - enum:
+  - tianma,fhd-video
+  - const: novatek,nt36672a


Best regards,
Krzysztof


Re: [PATCH v6 11/13] leds: rgb: mt6370: Add MediaTek MT6370 current sink type LED Indicator support

2022-07-27 Thread Andy Shevchenko
On Wed, Jul 27, 2022 at 9:37 AM ChiaEn Wu  wrote:
> On Tue, Jul 26, 2022 at 8:18 PM Andy Shevchenko
>  wrote:
>
> ...
>
> > > Just for saving memory space.
> > > Because these led_classdevs do not be used at the same time.
> > > Or do you think it would be better to rewrite it as follows?
> > > -
> > > struct mt6370_led {
> > >struct led_classdev isink;
> > >struct led_classdev_mc mc;
> > >struct mt6370_priv *priv;
> > >u32 default_state;
> > >u32 index;
> > > };
> > > -
> >
> > You obviously didn't get what I'm talking about...
> > Each union to work properly should have an associated variable that
> > holds the information of which field of the union is in use. Do you
> > have such a variable? If not, how does your code know which one to
> > use? If yes, add a proper comment there.
> >
>
> Ummm... from my understanding,
> if the colors of these four LEDs are set to 'LED_COLOR_ID_RGB' or
> 'LED_COLOR_ID_MULTI' in DT,
> their 'led->index' will be set to 'MT6370_VIRTUAL_MULTICOLOR' in
> 'mt6370_leds_probe()'.
> If so, these led devices will be set as 'struct led_classdev_mc' and
> use related ops functions in 'mt6370_init_led_properties()'.
> Instead, they whose 'led->index' is not 'MT6370_VIRTUAL_MULTICOLOR'
> will be set as 'struct led_classdev'.
> So, maybe the member 'index' of the 'struct mt6370_led' is what you
> describe the information of which field of the union is in use?

>From this description it sounds like it is.

> I will add the proper comment here to describe this thing. I'm so
> sorry for misunderstanding your mean last time.

Yes, please add a compressed version of what you said above to the code.

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-07-27 Thread Javier Martinez Canillas
On 7/27/22 10:41, Thomas Zimmermann wrote:

[...]

>>
>>> +static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
>>> +  struct device_node *of_node,
>>> +  u64 fb_base)
>>> +{
>>> +   struct drm_device *dev = >dev;
>>> +   u64 address;
>>> +   void __iomem *cmap_base;
>>> +
>>> +   address = fb_base & 0xff00ul;
>>> +   address += 0x7ff000;
>>> +
>>
>> It would be good to know where these addresses are coming from. Maybe some
>> constant macros or a comment ? Same for the other places where addresses
>> and offsets are used.
> 
> I have no idea where these values come from. I took them from offb. And 
> I suspect that some of these CMAP helpers could be further merged if 
> only it was clear where the numbers come from.  But as i don't have the 
> equipment for testing, I took most of this literally as-is from offb.
>

I see. As Michal mentioned maybe someone more familiar with this platform
could shed some light about these but in any case that could be done later.

[...]

>>> +
>>> +   new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
>>> new_plane_state->crtc);
>>> +
>>> +   new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);
>>> +   new_ofdrm_crtc_state->format = new_fb->format;
>>> +
>>
>> Ah, I understand now why you didn't factor out the .atomic_check callbacks
>> for the two drivers in a fwfb helper. Maybe you can also add a comment to
>> mention that this updates the format so the CRTC palette can be applied in
>> the .atomic_flush callback ?
> 
> Yeah, this code is one reason for not sharing atomic_check in fwfb.  The 
> other reason is that the fwfb code is only a wrapper around the atomic 
> helpers with little extra value.  I did have such fwfb helpers a some 
> point, but removed them.
>

Got it.

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



Re: [PATCH v15 07/11] drm/mediatek: Add retry to prevent misjudgment for sink devices

2022-07-27 Thread AngeloGioacchino Del Regno

Il 27/07/22 06:50, Bo-Chen Chen ha scritto:

For some DP dungles, we need to train more than onece to confirm that we
don't misjudge the status of sink device.


Please fix the typos in your commit title and description.
title: misjudgment -> misjudgement
desc: dungles->dongles; onece->once



Signed-off-by: Bo-Chen Chen 
---
  drivers/gpu/drm/mediatek/mtk_dp.c | 21 ++---
  1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
b/drivers/gpu/drm/mediatek/mtk_dp.c
index ce817cb59445..80d7d6488105 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -42,6 +42,7 @@
  #define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT 3
  #define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
  #define MTK_DP_TRAIN_DOWNSCALE_RETRY 8
+#define MTK_DP_TRAIN_CLEAR_RETRY 50
  
  struct mtk_dp_train_info {

bool tps3;
@@ -1431,11 +1432,25 @@ static int mtk_dp_video_config(struct mtk_dp *mtk_dp)
  
  static int mtk_dp_training(struct mtk_dp *mtk_dp)

  {
+   short max_retry = MTK_DP_TRAIN_CLEAR_RETRY;
int ret;
  
-	ret = mtk_dp_train_start(mtk_dp);

-   if (ret)
-   return ret;
+   /*
+* We do retry to confirm that we don't misjudge the sink status.
+* If it is still failed, we can confirm there are some issues for the
+* sink device.
+*/
+   do {
+   ret = mtk_dp_train_start(mtk_dp);
+   if (!ret)
+   break;
+   } while (--max_retry);
+
+   dev_info(mtk_dp->dev, "dp training clear retry times: %d\n",
+MTK_DP_TRAIN_CLEAR_RETRY - max_retry);


dev_dbg() here.

...after which,

Reviewed-by: AngeloGioacchino Del Regno 



+
+   if (!max_retry)
+   return -ETIMEDOUT;
  
  	ret = mtk_dp_video_config(mtk_dp);

if (ret)




Re: [PATCH v2 06/10] drm/simpledrm: Move some functionality into fwfb helper library

2022-07-27 Thread Javier Martinez Canillas
On 7/27/22 10:24, Thomas Zimmermann wrote:
> Hi
> 
> Am 25.07.22 um 18:23 schrieb Javier Martinez Canillas:
>> On 7/20/22 16:27, Thomas Zimmermann wrote:
>>> Move some of simpledrm's functionality into a helper library. Other
>>> drivers for firmware-provided framebuffers will also need functions
>>> to handle fixed modes and color formats, or update the back buffer.
>>>
>>> Signed-off-by: Thomas Zimmermann 
>>> ---
>>
>> Nice patch!
> 
> TBH it took me 3 tries to get something done for this library and I'm 
> still not happy with the result. I want to share code between simpledrm 
> and ofdrm, but that turns out to be harder then expected. A good part of 
> this code appears to belong into other libraries (you also mentioned 
> this below).
> 
> I don't want to duplicated code between simpledrm and ofdrm without 
> reason, but I expect that this library will somewhen be refactored and 
> dissolved into existing libraries.
>

Yes, I think is a step in the right direction and guess it would be even
more useful once/if a 3rd firmware-provided framebuffer driver is added.

> 
>>
>> [...]
>>
>>> +
>>> +/**
>>> + * DOC: overview
>>> + *
>>> + * The Firmware Framebuffer library FWFB provides helpers for devices with
>>> + * fixed-mode backing storage. It helps drivers to export a display mode of
>>> + * te correct size and copy updates to the backing storage.
>>
>> the
>>
>> it is "backing storage" or "backing store" ? I always thought that storage 
>> was
>> used for non-volatile media while "store" could be volatile and non-volatile.
> 
> Why store? Isn't that a little shop for fashion or groceries? I'm no 
> native speaker; I can't tell if either implies that we're sending 
> pictures to a warehouse or bakery. :)
> 

LOL.

> Would 'back buffer' (in contrast to 'shadow buffer') be clear?
>

Back buffer is more clear indeed.

[...]

>> It seems a little bit arbitrary to me that format is the only field that's
>> a pointer and the other ones are embedded into the struct drm_fwfb. Any
>> reason for that or is just a consequence of how types were used by the
>> simpledrm_device_create() function before that code moved into helpers ?
> 
> Format is constant and comes from statically initialized memory in 
> drm_fourcc.c. I'd expect to be able to compare formats by comparing the 
> pointers. Copying the format here would break the assumption.
>

I see. Makes sense.

>>
>> [...]
>>
>>> +static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, 
>>> uint32_t fourcc)
>>> +{
>>> +   const uint32_t *fourccs_end = fourccs + nfourccs;
>>> +
>>> +   while (fourccs < fourccs_end) {
>>> +   if (*fourccs == fourcc)
>>> +   return true;
>>> +   ++fourccs;
>>> +   }
>>> +   return false;
>>> +}
>>
>> This seems a helper that could be useful besides the drm_fwfb_helper.c file.
>>
>> I believe patches 1-6 shouldn't wait for the others in this series and could
>> just be merged when ready. Patches 7-10 can follow later.
> 
> Yeah, I'd like to move patches 1 to 5 into a new series for merging. 
> Patch 6 is only useful for ofdrm and as I said, maybe there's a better 
> solution then this library. I'd rather keep it here for now.
>

OK.

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



Re: [PATCH v15 06/11] drm/mediatek: Add MT8195 External DisplayPort support

2022-07-27 Thread AngeloGioacchino Del Regno

Il 27/07/22 06:50, Bo-Chen Chen ha scritto:

From: Guillaume Ranquet 

This patch adds External DisplayPort support to the mt8195 eDP driver.

Signed-off-by: Guillaume Ranquet 
Signed-off-by: Bo-Chen Chen 


Reviewed-by: AngeloGioacchino Del Regno 




Re: [PATCH v15 05/11] drm/mediatek: Add MT8195 Embedded DisplayPort driver

2022-07-27 Thread AngeloGioacchino Del Regno

Il 27/07/22 06:50, Bo-Chen Chen ha scritto:

From: Markus Schneider-Pargmann 

This patch adds a embedded displayport driver for the MediaTek mt8195 SoC.

It supports the MT8195, the embedded DisplayPort units. It offers
DisplayPort 1.4 with up to 4 lanes.

The driver creates a child device for the phy. The child device will
never exist without the parent being active. As they are sharing a
register range, the parent passes a regmap pointer to the child so that
both can work with the same register range. The phy driver sets device
data that is read by the parent to get the phy device that can be used
to control the phy properties.

This driver is based on an initial version by
Jitao shi 

Signed-off-by: Markus Schneider-Pargmann 
Signed-off-by: Guillaume Ranquet 
Signed-off-by: Bo-Chen Chen 


Tested-by: AngeloGioacchino Del Regno 
Reviewed-by: AngeloGioacchino Del Regno 



Re: [PATCH v15 04/11] video/hdmi: Add audio_infoframe packing for DP

2022-07-27 Thread AngeloGioacchino Del Regno

Il 27/07/22 06:50, Bo-Chen Chen ha scritto:

From: Markus Schneider-Pargmann 

Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Also constify the frame parameter in hdmi_audio_infoframe_check() as
it is passed to hdmi_audio_infoframe_check_only() which expects a const.

Signed-off-by: Markus Schneider-Pargmann 
Signed-off-by: Guillaume Ranquet 
Signed-off-by: Bo-Chen Chen 


Reviewed-by: AngeloGioacchino Del Regno 




  1   2   >