[PATCH 4/4] drm/i915: Improve long running OCL w/a for GuC submission

2021-12-10 Thread John . C . Harrison
From: John Harrison 

A workaround was added to the driver to allow OpenCL workloads to run
'forever' by disabling pre-emption on the RCS engine for Gen12.
It is not totally unbound as the heartbeat will kick in eventually
and cause a reset of the hung engine.

However, this does not work well in GuC submission mode. In GuC mode,
the pre-emption timeout is how GuC detects hung contexts and triggers
a per engine reset. Thus, disabling the timeout means also losing all
per engine reset ability. A full GT reset will still occur when the
heartbeat finally expires, but that is a much more destructive and
undesirable mechanism.

The purpose of the workaround is actually to give OpenCL tasks longer
to reach a pre-emption point after a pre-emption request has been
issued. This is necessary because Gen12 does not support mid-thread
pre-emption and OpenCL can have long running threads.

So, rather than disabling the timeout completely, just set it to a
'long' value. Likewise, bump the heartbeat interval. That gives the
OpenCL thread sufficient time to reach a pre-emption point without
being killed off either by the GuC or by the heartbeat.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 42 +--
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 352254e001b4..26af8d60fe2b 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -382,9 +382,45 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
intel_engine_id id,
engine->props.timeslice_duration_ms =
CONFIG_DRM_I915_TIMESLICE_DURATION;
 
-   /* Override to uninterruptible for OpenCL workloads. */
-   if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS)
-   engine->props.preempt_timeout_ms = 0;
+   /*
+* Mid-thread pre-emption is not available in Gen12. Unfortunately,
+* some OpenCL workloads run quite long threads. That means they get
+* reset due to not pre-empting in a timely manner.
+* The execlist solution was to disable pre-emption completely.
+* However, pre-emption timeouts are the way GuC detects hung contexts
+* and triggers engine resets. Thus, without pre-emption, there is no
+* per engine reset. And full GT reset is much more intrusive. So keep
+* the timeout for GuC submission platforms and just bump it to be
+* much larger. Also bump the heartbeat timeout to match, otherwise
+* the heartbeat can expire before the pre-emption can timeout and
+* thus trigger a full GT reset anyway.
+*/
+   if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS) {
+   if (intel_uc_wants_guc_submission(>uc)) {
+   const unsigned long min_preempt = 7500;
+   const unsigned long min_beat = 5000;
+
+   if (engine->props.preempt_timeout_ms &&
+   engine->props.preempt_timeout_ms < min_preempt) {
+   drm_info(>i915->drm, "Bumping pre-emption 
timeout from %ld to %ld on %s to allow slow compute pre-emption\n",
+engine->props.preempt_timeout_ms,
+min_preempt, engine->name);
+
+   engine->props.preempt_timeout_ms = min_preempt;
+   }
+
+   if (engine->props.heartbeat_interval_ms &&
+   engine->props.heartbeat_interval_ms < min_beat) {
+   drm_info(>i915->drm, "Bumping heartbeat 
interval from %ld to %ld on %s to allow slow compute pre-emption\n",
+engine->props.heartbeat_interval_ms,
+min_beat, engine->name);
+
+   engine->props.heartbeat_interval_ms = min_beat;
+   }
+   } else {
+   engine->props.preempt_timeout_ms = 0;
+   }
+   }
 
engine->defaults = engine->props; /* never to change again */
 
-- 
2.25.1



[PATCH 3/4] drm/i915/guc: Flag an error if an engine reset fails

2021-12-10 Thread John . C . Harrison
From: John Harrison 

If GuC encounters an error during engine reset, the i915 driver
promotes to full GT reset. This includes an info message about why the
reset is happening. However, that is not treated as a failure by any
of the CI systems because resets are an expected occurrance during
testing. This kind of failure is a major problem and should never
happen. So, complain more loudly and make sure CI notices.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 +++---
 1 file changed, 11 insertions(+), 3 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 9739da6f..6015815f1da0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4018,11 +4018,12 @@ int intel_guc_engine_failure_process_msg(struct 
intel_guc *guc,
 const u32 *msg, u32 len)
 {
struct intel_engine_cs *engine;
+   struct intel_gt *gt = guc_to_gt(guc);
u8 guc_class, instance;
u32 reason;
 
if (unlikely(len != 3)) {
-   drm_err(_to_gt(guc)->i915->drm, "Invalid length %u", len);
+   drm_err(>i915->drm, "Invalid length %u", len);
return -EPROTO;
}
 
@@ -4032,12 +4033,19 @@ int intel_guc_engine_failure_process_msg(struct 
intel_guc *guc,
 
engine = guc_lookup_engine(guc, guc_class, instance);
if (unlikely(!engine)) {
-   drm_err(_to_gt(guc)->i915->drm,
+   drm_err(>i915->drm,
"Invalid engine %d:%d", guc_class, instance);
return -EPROTO;
}
 
-   intel_gt_handle_error(guc_to_gt(guc), engine->mask,
+   /*
+* This is an unexpected failure of a hardware feature. So, log a real
+* error message not just the informational that comes with the reset.
+*/
+   drm_err(>i915->drm, "GuC engine reset request failed on %d:%d (%s) 
because %d",
+   guc_class, instance, engine->name, reason);
+
+   intel_gt_handle_error(gt, engine->mask,
  I915_ERROR_CAPTURE,
  "GuC failed to reset %s (reason=0x%08x)\n",
  engine->name, reason);
-- 
2.25.1



[PATCH 0/4] More fixes/tweaks to GuC support

2021-12-10 Thread John . C . Harrison
From: John Harrison 

Allow engine resets on RCS, report problems with engine resets,
improve GuC log usability.

Signed-off-by: John Harrison 


John Harrison (4):
  drm/i915/guc: Speed up GuC log dumps
  drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
  drm/i915/guc: Flag an error if an engine reset fails
  drm/i915: Improve long running OCL w/a for GuC submission

 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 42 +-
 drivers/gpu/drm/i915/gt/intel_gt_debugfs.h| 21 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h|  5 +-
 .../drm/i915/gt/uc/intel_guc_log_debugfs.c| 58 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 -
 5 files changed, 125 insertions(+), 15 deletions(-)

-- 
2.25.1



[PATCH 2/4] drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM

2021-12-10 Thread John . C . Harrison
From: John Harrison 

Lots of testing is done with the DEBUG_GEM config option enabled but
not the DEBUG_GUC option. That means we only get teeny-tiny GuC logs
which are not hugely useful. Enabling full DEBUG_GUC also spews lots
of other detailed output that is not generally desired. However,
bigger GuC logs are extremely useful for almost any regression debug.
So enable bigger logs for DEBUG_GEM builds as well.

Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
index ac1ee1d5ce10..fe6ab7550a14 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
@@ -15,9 +15,12 @@
 
 struct intel_guc;
 
-#ifdef CONFIG_DRM_I915_DEBUG_GUC
+#if defined(CONFIG_DRM_I915_DEBUG_GUC)
 #define CRASH_BUFFER_SIZE  SZ_2M
 #define DEBUG_BUFFER_SIZE  SZ_16M
+#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define CRASH_BUFFER_SIZE  SZ_1M
+#define DEBUG_BUFFER_SIZE  SZ_2M
 #else
 #define CRASH_BUFFER_SIZE  SZ_8K
 #define DEBUG_BUFFER_SIZE  SZ_64K
-- 
2.25.1



[PATCH 1/4] drm/i915/guc: Speed up GuC log dumps

2021-12-10 Thread John . C . Harrison
From: John Harrison 

Add support for telling the debugfs interface the size of the GuC log
dump in advance. Without that, the underlying framework keeps calling
the 'show' function with larger and larger buffer allocations until it
fits. That means reading the log from graphics memory many times - 16
times with the full 18MB log size.

v2: Don't return error codes from size query. Report overflow in the
error dump as well (review feedback from Daniele).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_gt_debugfs.h| 21 +--
 .../drm/i915/gt/uc/intel_guc_log_debugfs.c| 58 ++-
 2 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h
index e307ceb99031..17e79b735cfe 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h
@@ -10,11 +10,7 @@
 
 struct intel_gt;
 
-#define DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(__name)  
\
-   static int __name ## _open(struct inode *inode, struct file *file) \
-{  \
-   return single_open(file, __name ## _show, inode->i_private);\
-}  \
+#define __GT_DEBUGFS_ATTRIBUTE_FOPS(__name)\
 static const struct file_operations __name ## _fops = {
\
.owner = THIS_MODULE,   \
.open = __name ## _open,\
@@ -23,6 +19,21 @@ static const struct file_operations __name ## _fops = {  
\
.release = single_release,  \
 }
 
+#define DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(__name)  \
+static int __name ## _open(struct inode *inode, struct file *file) \
+{  \
+   return single_open(file, __name ## _show, inode->i_private);\
+}  \
+__GT_DEBUGFS_ATTRIBUTE_FOPS(__name)
+
+#define DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(__name, __size_vf) 
\
+static int __name ## _open(struct inode *inode, struct file *file) 
\
+{  
\
+   return single_open_size(file, __name ## _show, inode->i_private,
\
+   __size_vf(inode->i_private));   
\
+}  
\
+__GT_DEBUGFS_ATTRIBUTE_FOPS(__name)
+
 void intel_gt_debugfs_register(struct intel_gt *gt);
 
 struct intel_gt_debugfs_file {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
index 8fd068049376..ddfbe334689f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
@@ -10,22 +10,74 @@
 #include "intel_guc.h"
 #include "intel_guc_log.h"
 #include "intel_guc_log_debugfs.h"
+#include "intel_uc.h"
+
+static u32 obj_to_guc_log_dump_size(struct drm_i915_gem_object *obj)
+{
+   u32 size;
+
+   if (!obj)
+   return PAGE_SIZE;
+
+   /* "0x%08x 0x%08x 0x%08x 0x%08x\n" => 16 bytes -> 44 chars => x2.75 */
+   size = ((obj->base.size * 11) + 3) / 4;
+
+   /* Add padding for final blank line, any extra header info, etc. */
+   size = PAGE_ALIGN(size + PAGE_SIZE);
+
+   return size;
+}
+
+static u32 guc_log_dump_size(struct intel_guc_log *log)
+{
+   struct intel_guc *guc = log_to_guc(log);
+
+   if (!intel_guc_is_supported(guc))
+   return PAGE_SIZE;
+
+   if (!log->vma)
+   return PAGE_SIZE;
+
+   return obj_to_guc_log_dump_size(log->vma->obj);
+}
 
 static int guc_log_dump_show(struct seq_file *m, void *data)
 {
struct drm_printer p = drm_seq_file_printer(m);
+   int ret;
 
-   return intel_guc_log_dump(m->private, , false);
+   ret = intel_guc_log_dump(m->private, , false);
+
+   if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
+   pr_warn_once("preallocated size:%zx for %s exceeded\n",
+m->size, __func__);
+
+   return ret;
+}
+DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_log_dump, guc_log_dump_size);
+
+static u32 guc_load_err_dump_size(struct intel_guc_log *log)
+{
+   struct intel_guc *guc = log_to_guc(log);
+   struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
+
+   if (!intel_guc_is_supported(guc))
+   return PAGE_SIZE;
+
+   return obj_to_guc_log_dump_size(uc->load_err_log);
 }
-DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(guc_log_dump);
 
 static int guc_load_err_log_dump_show(struct seq_file *m, void 

Re: [PATCH 3/3] drm: bridge: Switch to devm_drm_of_get_bridge

2021-12-10 Thread Jagan Teki
Hi Linus,

On Sat, Dec 11, 2021 at 5:37 AM Linus Walleij  wrote:
>
> On Fri, Dec 10, 2021 at 6:49 PM Jagan Teki  wrote:
> >
> > devm_drm_of_get_bridge is capable of looking up the downstream
> > bridge and panel and trying to add a panel bridge if the panel
> > is found.
> >
> > Replace explicit finding calls with devm_drm_of_get_bridge.
> >
> > Cc: Philipp Zabel 
> > Cc: Chun-Kuang Hu 
> > Cc: Linus Walleij 
> > Signed-off-by: Jagan Teki 
>
> Nice overall!
>
> > -   /* Look for a panel as a child to this node */
> > -   for_each_available_child_of_node(dev->of_node, child) {
> > -   panel = of_drm_find_panel(child);
> > -   if (IS_ERR(panel)) {
> > -   dev_err(dev, "failed to find panel try bridge 
> > (%ld)\n",
> > -   PTR_ERR(panel));
> > -   panel = NULL;
> > -
> > -   bridge = of_drm_find_bridge(child);
> > -   if (!bridge) {
> > -   dev_err(dev, "failed to find bridge\n");
> > -   return -EINVAL;
> > -   }
> > -   }
> > -   }
> > -   if (panel) {
> > -   bridge = drm_panel_bridge_add_typed(panel,
> > -   DRM_MODE_CONNECTOR_DSI);
>
> And we are guaranteed that the right type of connector will be
> used here? (Just checking.)

Yes. Each panel driver initialised the connector_type via
drm_panel_init and it will check during devm_drm_of_get_bridge.

>
> > -   if (IS_ERR(bridge)) {
> > -   dev_err(dev, "error adding panel bridge\n");
> > -   return PTR_ERR(bridge);
> > -   }
> > -   dev_info(dev, "connected to panel\n");
> > -   d->panel = panel;
>
> How does this assignment happen after your patch?
> I'm using that...
>
> devm_drm_of_get_bridge() needs some more argument right?

Yes, but I think we don't need to preserve the panel here. Yes I
didn't add that change, will take care in v2.

>
> > -   } else if (bridge) {
> > -   /* TODO: AV8100 HDMI encoder goes here for example */
> > -   dev_info(dev, "connected to non-panel bridge 
> > (unsupported)\n");
> > -   return -ENODEV;
> > -   } else {
> > -   dev_err(dev, "no panel or bridge\n");
> > -   return -ENODEV;
> > +   bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> > +   if (IS_ERR(bridge)) {
> > +   dev_err(dev, "error to get bridge\n");
> > +   return PTR_ERR(bridge);
>
> I'm gonna want to test this somehow on the hardware. But the TODO comment
> there wasn't supposed to be deleted if I will still need to take some special
> action whether this is a panel bridge or some other bridge.

Agreed. Even I do like to add this prints, since
devm_drm_of_get_bridge is not able to return differentiated bridge so
it it not possible now. May be we can discuss this point.

Thanks,
Jagan.


Re: [PATCH 7/7] drm/i915/guc: Selftest for stealing of guc ids

2021-12-10 Thread Matthew Brost
On Fri, Dec 10, 2021 at 05:33:02PM -0800, John Harrison wrote:
> On 12/10/2021 16:56, Matthew Brost wrote:
> > Testing the stealing of guc ids is hard from user spaec as we have 64k
> spaec -> space
> 
> > guc_ids. Add a selftest, which artificially reduces the number of guc
> > ids, and forces a steal. Details of test has comment in code so will not
> has -> are
> 
> But would a copy really be so hard? It is useful to be able to read
> what a patch does from the commit log and not have to delve inside every
> time.
> 
> 
> > repeat here.
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >   drivers/gpu/drm/i915/gt/uc/intel_guc.h|  12 ++
> >   .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  15 +-
> >   drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 171 ++
> >   3 files changed, 193 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > index 1cb46098030d..307380a2e2ff 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > @@ -94,6 +94,11 @@ struct intel_guc {
> >  * @guc_ids: used to allocate new guc_ids, single-lrc
> >  */
> > struct ida guc_ids;
> > +   /**
> > +* @num_guc_ids: Number of guc_ids, selftest feature to be able
> > +* to reduce this number of test.
> of test -> while testing
> 
> Should have a CONFIG_SELFTEST around it? And define a wrapper that is
> GUC_MAX_LRC_DESCRIPTORS or num_guc_ids as appropriate.
> 

Missed this. Basically decided again a SELFTEST wrapper because SRIOV
needs this anyways. Can hide this if you insist.

Matt

> 
> > +*/
> > +   int num_guc_ids;
> > /**
> >  * @guc_ids_bitmap: used to allocate new guc_ids, multi-lrc
> >  */
> > @@ -202,6 +207,13 @@ struct intel_guc {
> >  */
> > struct delayed_work work;
> > } timestamp;
> > +
> > +#ifdef CONFIG_DRM_I915_SELFTEST
> > +   /**
> > +* @number_guc_id_stole: The number of guc_ids that have been stole
> > +*/
> > +   int number_guc_id_stole;
> stole -> stolen (in all three cases)
> 
> > +#endif
> >   };
> >   static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
> > 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 96fcf869e3ff..57019b190bfb 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -145,7 +145,7 @@ guc_create_parallel(struct intel_engine_cs **engines,
> >* use should be low and 1/16 should be sufficient. Minimum of 32 guc_ids 
> > for
> >* multi-lrc.
> >*/
> > -#define NUMBER_MULTI_LRC_GUC_ID(GUC_MAX_LRC_DESCRIPTORS / 16)
> > +#define NUMBER_MULTI_LRC_GUC_ID(guc)   
> > (guc->submission_state.num_guc_ids / 16)
> And keep the original definition for the non CONFIG_SELFTEST case?
> 
> >   /*
> >* Below is a set of functions which control the GuC scheduling state 
> > which
> > @@ -1775,7 +1775,7 @@ int intel_guc_submission_init(struct intel_guc *guc)
> >   destroyed_worker_func);
> > guc->submission_state.guc_ids_bitmap =
> > -   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID, GFP_KERNEL);
> > +   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL);
> > if (!guc->submission_state.guc_ids_bitmap)
> > return -ENOMEM;
> > @@ -1869,13 +1869,13 @@ static int new_guc_id(struct intel_guc *guc, struct 
> > intel_context *ce)
> > if (intel_context_is_parent(ce))
> > ret = 
> > bitmap_find_free_region(guc->submission_state.guc_ids_bitmap,
> > - NUMBER_MULTI_LRC_GUC_ID,
> > + NUMBER_MULTI_LRC_GUC_ID(guc),
> >   
> > order_base_2(ce->parallel.number_children
> >+ 1));
> > else
> > ret = ida_simple_get(>submission_state.guc_ids,
> > -NUMBER_MULTI_LRC_GUC_ID,
> > -GUC_MAX_LRC_DESCRIPTORS,
> > +NUMBER_MULTI_LRC_GUC_ID(guc),
> > +guc->submission_state.num_guc_ids,
> >  GFP_KERNEL | __GFP_RETRY_MAYFAIL |
> >  __GFP_NOWARN);
> > if (unlikely(ret < 0))
> > @@ -1941,6 +1941,10 @@ static int steal_guc_id(struct intel_guc *guc, 
> > struct intel_context *ce)
> > set_context_guc_id_invalid(cn);
> > +#ifdef CONFIG_DRM_I915_SELFTEST
> > +   guc->number_guc_id_stole++;
> > +#endif
> > +
> > return 0;
> > } else {
> > return -EAGAIN;
> > @@ -3779,6 +3783,7 @@ static bool __guc_submission_selected(struct 
> > intel_guc *guc)
> >   

Re: [PATCH 7/7] drm/i915/guc: Selftest for stealing of guc ids

2021-12-10 Thread Matthew Brost
On Fri, Dec 10, 2021 at 05:33:02PM -0800, John Harrison wrote:
> On 12/10/2021 16:56, Matthew Brost wrote:
> > Testing the stealing of guc ids is hard from user spaec as we have 64k
> spaec -> space
> 
> > guc_ids. Add a selftest, which artificially reduces the number of guc
> > ids, and forces a steal. Details of test has comment in code so will not
> has -> are
> 

Yep.

> But would a copy really be so hard? It is useful to be able to read
> what a patch does from the commit log and not have to delve inside every
> time.
> 

Will c & p.

> 
> > repeat here.
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >   drivers/gpu/drm/i915/gt/uc/intel_guc.h|  12 ++
> >   .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  15 +-
> >   drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 171 ++
> >   3 files changed, 193 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > index 1cb46098030d..307380a2e2ff 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > @@ -94,6 +94,11 @@ struct intel_guc {
> >  * @guc_ids: used to allocate new guc_ids, single-lrc
> >  */
> > struct ida guc_ids;
> > +   /**
> > +* @num_guc_ids: Number of guc_ids, selftest feature to be able
> > +* to reduce this number of test.
> of test -> while testing
> 
> Should have a CONFIG_SELFTEST around it? And define a wrapper that is
> GUC_MAX_LRC_DESCRIPTORS or num_guc_ids as appropriate.
> 
> 
> > +*/
> > +   int num_guc_ids;
> > /**
> >  * @guc_ids_bitmap: used to allocate new guc_ids, multi-lrc
> >  */
> > @@ -202,6 +207,13 @@ struct intel_guc {
> >  */
> > struct delayed_work work;
> > } timestamp;
> > +
> > +#ifdef CONFIG_DRM_I915_SELFTEST
> > +   /**
> > +* @number_guc_id_stole: The number of guc_ids that have been stole
> > +*/
> > +   int number_guc_id_stole;
> stole -> stolen (in all three cases)
> 

Sure.

> > +#endif
> >   };
> >   static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
> > 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 96fcf869e3ff..57019b190bfb 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -145,7 +145,7 @@ guc_create_parallel(struct intel_engine_cs **engines,
> >* use should be low and 1/16 should be sufficient. Minimum of 32 guc_ids 
> > for
> >* multi-lrc.
> >*/
> > -#define NUMBER_MULTI_LRC_GUC_ID(GUC_MAX_LRC_DESCRIPTORS / 16)
> > +#define NUMBER_MULTI_LRC_GUC_ID(guc)   
> > (guc->submission_state.num_guc_ids / 16)
> And keep the original definition for the non CONFIG_SELFTEST case?
>

Probably could hide submission_state.num_guc_ids behind a
CONFIG_SELFTEST define but SRIOV needs this anyways so didn't bother. If
you insist can I hide this.
 
> >   /*
> >* Below is a set of functions which control the GuC scheduling state 
> > which
> > @@ -1775,7 +1775,7 @@ int intel_guc_submission_init(struct intel_guc *guc)
> >   destroyed_worker_func);
> > guc->submission_state.guc_ids_bitmap =
> > -   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID, GFP_KERNEL);
> > +   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL);
> > if (!guc->submission_state.guc_ids_bitmap)
> > return -ENOMEM;
> > @@ -1869,13 +1869,13 @@ static int new_guc_id(struct intel_guc *guc, struct 
> > intel_context *ce)
> > if (intel_context_is_parent(ce))
> > ret = 
> > bitmap_find_free_region(guc->submission_state.guc_ids_bitmap,
> > - NUMBER_MULTI_LRC_GUC_ID,
> > + NUMBER_MULTI_LRC_GUC_ID(guc),
> >   
> > order_base_2(ce->parallel.number_children
> >+ 1));
> > else
> > ret = ida_simple_get(>submission_state.guc_ids,
> > -NUMBER_MULTI_LRC_GUC_ID,
> > -GUC_MAX_LRC_DESCRIPTORS,
> > +NUMBER_MULTI_LRC_GUC_ID(guc),
> > +guc->submission_state.num_guc_ids,
> >  GFP_KERNEL | __GFP_RETRY_MAYFAIL |
> >  __GFP_NOWARN);
> > if (unlikely(ret < 0))
> > @@ -1941,6 +1941,10 @@ static int steal_guc_id(struct intel_guc *guc, 
> > struct intel_context *ce)
> > set_context_guc_id_invalid(cn);
> > +#ifdef CONFIG_DRM_I915_SELFTEST
> > +   guc->number_guc_id_stole++;
> > +#endif
> > +
> > return 0;
> > } else {
> > return -EAGAIN;
> > @@ -3779,6 +3783,7 @@ static bool 

Re: [Intel-gfx] [PATCH 5/7] drm/i915/guc: Add extra debug on CT deadlock

2021-12-10 Thread Matthew Brost
On Fri, Dec 10, 2021 at 05:45:05PM -0800, John Harrison wrote:
> On 12/10/2021 17:43, John Harrison wrote:
> > On 12/10/2021 16:56, Matthew Brost wrote:
> > > Print CT state (H2G + G2H head / tail pointers, credits) on CT
> > > deadlock.
> > > 
> > > Signed-off-by: Matthew Brost 
> > Reviewed-by: John Harrison 
> > 
> > > ---
> > >   drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 9 +
> > >   1 file changed, 9 insertions(+)
> > > 
> > > 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 a0cc34be7b56..ee5525c6f79b 100644
> > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > > @@ -523,6 +523,15 @@ static inline bool ct_deadlocked(struct
> > > intel_guc_ct *ct)
> > >   CT_ERROR(ct, "Communication stalled for %lld ms, desc
> > > status=%#x,%#x\n",
> > >    ktime_ms_delta(ktime_get(), ct->stall_time),
> > >    send->status, recv->status);
> > > +    CT_ERROR(ct, "H2G Space: %u\n",
> > > + atomic_read(>ctbs.send.space) * 4);
> > > +    CT_ERROR(ct, "Head: %u\n", ct->ctbs.send.desc->head);
> > > +    CT_ERROR(ct, "Tail: %u\n", ct->ctbs.send.desc->tail);
> Actually, aren't these offsets in dwords? So, scaling the dword space to
> bytes but leaving this as dwords would produce a confusing numbers.
> 

Copy + pasted from CT debugfs but yes it is slightly confusing. I'd
rather leave the head / tail in native format but I'll add info to both
the space / pointers print indicating the units.

Matt

> John.
> 
> > > +    CT_ERROR(ct, "G2H Space: %u\n",
> > > + atomic_read(>ctbs.recv.space) * 4);
> > > +    CT_ERROR(ct, "Head: %u\n", ct->ctbs.recv.desc->head);
> > > +    CT_ERROR(ct, "Tail: %u\n", ct->ctbs.recv.desc->tail);
> > > +
> > >   ct->ctbs.send.broken = true;
> > >   }
> > 
> 


Re: [Intel-gfx] [PATCH 5/7] drm/i915/guc: Add extra debug on CT deadlock

2021-12-10 Thread John Harrison

On 12/10/2021 17:43, John Harrison wrote:

On 12/10/2021 16:56, Matthew Brost wrote:

Print CT state (H2G + G2H head / tail pointers, credits) on CT
deadlock.

Signed-off-by: Matthew Brost 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 9 +
  1 file changed, 9 insertions(+)

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 a0cc34be7b56..ee5525c6f79b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -523,6 +523,15 @@ static inline bool ct_deadlocked(struct 
intel_guc_ct *ct)
  CT_ERROR(ct, "Communication stalled for %lld ms, desc 
status=%#x,%#x\n",

   ktime_ms_delta(ktime_get(), ct->stall_time),
   send->status, recv->status);
+    CT_ERROR(ct, "H2G Space: %u\n",
+ atomic_read(>ctbs.send.space) * 4);
+    CT_ERROR(ct, "Head: %u\n", ct->ctbs.send.desc->head);
+    CT_ERROR(ct, "Tail: %u\n", ct->ctbs.send.desc->tail);
Actually, aren't these offsets in dwords? So, scaling the dword space to 
bytes but leaving this as dwords would produce a confusing numbers.


John.


+    CT_ERROR(ct, "G2H Space: %u\n",
+ atomic_read(>ctbs.recv.space) * 4);
+    CT_ERROR(ct, "Head: %u\n", ct->ctbs.recv.desc->head);
+    CT_ERROR(ct, "Tail: %u\n", ct->ctbs.recv.desc->tail);
+
  ct->ctbs.send.broken = true;
  }






Re: [PATCH 5/7] drm/i915/guc: Add extra debug on CT deadlock

2021-12-10 Thread John Harrison

On 12/10/2021 16:56, Matthew Brost wrote:

Print CT state (H2G + G2H head / tail pointers, credits) on CT
deadlock.

Signed-off-by: Matthew Brost 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 9 +
  1 file changed, 9 insertions(+)

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 a0cc34be7b56..ee5525c6f79b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -523,6 +523,15 @@ static inline bool ct_deadlocked(struct intel_guc_ct *ct)
CT_ERROR(ct, "Communication stalled for %lld ms, desc 
status=%#x,%#x\n",
 ktime_ms_delta(ktime_get(), ct->stall_time),
 send->status, recv->status);
+   CT_ERROR(ct, "H2G Space: %u\n",
+atomic_read(>ctbs.send.space) * 4);
+   CT_ERROR(ct, "Head: %u\n", ct->ctbs.send.desc->head);
+   CT_ERROR(ct, "Tail: %u\n", ct->ctbs.send.desc->tail);
+   CT_ERROR(ct, "G2H Space: %u\n",
+atomic_read(>ctbs.recv.space) * 4);
+   CT_ERROR(ct, "Head: %u\n", ct->ctbs.recv.desc->head);
+   CT_ERROR(ct, "Tail: %u\n", ct->ctbs.recv.desc->tail);
+
ct->ctbs.send.broken = true;
}
  




Re: [PATCH 7/7] drm/i915/guc: Selftest for stealing of guc ids

2021-12-10 Thread John Harrison

On 12/10/2021 16:56, Matthew Brost wrote:

Testing the stealing of guc ids is hard from user spaec as we have 64k

spaec -> space


guc_ids. Add a selftest, which artificially reduces the number of guc
ids, and forces a steal. Details of test has comment in code so will not

has -> are

But would a copy really be so hard? It is useful to be able to 
read what a patch does from the commit log and not have to delve inside 
every time.




repeat here.

Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|  12 ++
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  15 +-
  drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 171 ++
  3 files changed, 193 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 1cb46098030d..307380a2e2ff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -94,6 +94,11 @@ struct intel_guc {
 * @guc_ids: used to allocate new guc_ids, single-lrc
 */
struct ida guc_ids;
+   /**
+* @num_guc_ids: Number of guc_ids, selftest feature to be able
+* to reduce this number of test.

of test -> while testing

Should have a CONFIG_SELFTEST around it? And define a wrapper that is 
GUC_MAX_LRC_DESCRIPTORS or num_guc_ids as appropriate.




+*/
+   int num_guc_ids;
/**
 * @guc_ids_bitmap: used to allocate new guc_ids, multi-lrc
 */
@@ -202,6 +207,13 @@ struct intel_guc {
 */
struct delayed_work work;
} timestamp;
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   /**
+* @number_guc_id_stole: The number of guc_ids that have been stole
+*/
+   int number_guc_id_stole;

stole -> stolen (in all three cases)


+#endif
  };
  
  static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)

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 96fcf869e3ff..57019b190bfb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -145,7 +145,7 @@ guc_create_parallel(struct intel_engine_cs **engines,
   * use should be low and 1/16 should be sufficient. Minimum of 32 guc_ids for
   * multi-lrc.
   */
-#define NUMBER_MULTI_LRC_GUC_ID(GUC_MAX_LRC_DESCRIPTORS / 16)
+#define NUMBER_MULTI_LRC_GUC_ID(guc)   (guc->submission_state.num_guc_ids / 16)

And keep the original definition for the non CONFIG_SELFTEST case?

  
  /*

   * Below is a set of functions which control the GuC scheduling state which
@@ -1775,7 +1775,7 @@ int intel_guc_submission_init(struct intel_guc *guc)
  destroyed_worker_func);
  
  	guc->submission_state.guc_ids_bitmap =

-   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID, GFP_KERNEL);
+   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL);
if (!guc->submission_state.guc_ids_bitmap)
return -ENOMEM;
  
@@ -1869,13 +1869,13 @@ static int new_guc_id(struct intel_guc *guc, struct intel_context *ce)
  
  	if (intel_context_is_parent(ce))

ret = 
bitmap_find_free_region(guc->submission_state.guc_ids_bitmap,
- NUMBER_MULTI_LRC_GUC_ID,
+ NUMBER_MULTI_LRC_GUC_ID(guc),
  
order_base_2(ce->parallel.number_children
   + 1));
else
ret = ida_simple_get(>submission_state.guc_ids,
-NUMBER_MULTI_LRC_GUC_ID,
-GUC_MAX_LRC_DESCRIPTORS,
+NUMBER_MULTI_LRC_GUC_ID(guc),
+guc->submission_state.num_guc_ids,
 GFP_KERNEL | __GFP_RETRY_MAYFAIL |
 __GFP_NOWARN);
if (unlikely(ret < 0))
@@ -1941,6 +1941,10 @@ static int steal_guc_id(struct intel_guc *guc, struct 
intel_context *ce)
  
  		set_context_guc_id_invalid(cn);
  
+#ifdef CONFIG_DRM_I915_SELFTEST

+   guc->number_guc_id_stole++;
+#endif
+
return 0;
} else {
return -EAGAIN;
@@ -3779,6 +3783,7 @@ static bool __guc_submission_selected(struct intel_guc 
*guc)
  
  void intel_guc_submission_init_early(struct intel_guc *guc)

  {
+   guc->submission_state.num_guc_ids = GUC_MAX_LRC_DESCRIPTORS;
guc->submission_supported = __guc_submission_supported(guc);
guc->submission_selected = __guc_submission_selected(guc);
  }
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index fb0e4a7bd8ca..9ab355e64b3f 100644
--- 

Re: [PATCH 4/7] drm/i915/guc: Don't hog IRQs when destroying contexts

2021-12-10 Thread Matthew Brost
On Fri, Dec 10, 2021 at 05:07:12PM -0800, John Harrison wrote:
> On 12/10/2021 16:56, Matthew Brost wrote:
> > From: John Harrison 
> > 
> > While attempting to debug a CT deadlock issue in various CI failures
> > (most easily reproduced with gem_ctx_create/basic-files), I was seeing
> > CPU deadlock errors being reported. This were because the context
> > destroy loop was blocking waiting on H2G space from inside an IRQ
> > spinlock. There was deadlock as such, it's just that the H2G queue was
> There was *no* deadlock as such
> 

Let's fix this up when applying the series.

With that:
Reviewed-by: Matthew Brost 

> John.
> 
> > full of context destroy commands and GuC was taking a long time to
> > process them. However, the kernel was seeing the large amount of time
> > spent inside the IRQ lock as a dead CPU. Various Bad Things(tm) would
> > then happen (heartbeat failures, CT deadlock errors, outstanding H2G
> > WARNs, etc.).
> > 
> > Re-working the loop to only acquire the spinlock around the list
> > management (which is all it is meant to protect) rather than the
> > entire destroy operation seems to fix all the above issues.
> > 
> > Signed-off-by: John Harrison 
> > ---
> >   .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 45 ---
> >   1 file changed, 28 insertions(+), 17 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 36c2965db49b..96fcf869e3ff 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -2644,7 +2644,6 @@ static inline void guc_lrc_desc_unpin(struct 
> > intel_context *ce)
> > unsigned long flags;
> > bool disabled;
> > -   lockdep_assert_held(>submission_state.lock);
> > GEM_BUG_ON(!intel_gt_pm_is_awake(gt));
> > GEM_BUG_ON(!lrc_desc_registered(guc, ce->guc_id.id));
> > GEM_BUG_ON(ce != __get_context(guc, ce->guc_id.id));
> > @@ -2660,7 +2659,7 @@ static inline void guc_lrc_desc_unpin(struct 
> > intel_context *ce)
> > }
> > spin_unlock_irqrestore(>guc_state.lock, flags);
> > if (unlikely(disabled)) {
> > -   __release_guc_id(guc, ce);
> > +   release_guc_id(guc, ce);
> > __guc_context_destroy(ce);
> > return;
> > }
> > @@ -2694,36 +2693,48 @@ static void __guc_context_destroy(struct 
> > intel_context *ce)
> >   static void guc_flush_destroyed_contexts(struct intel_guc *guc)
> >   {
> > -   struct intel_context *ce, *cn;
> > +   struct intel_context *ce;
> > unsigned long flags;
> > GEM_BUG_ON(!submission_disabled(guc) &&
> >guc_submission_initialized(guc));
> > -   spin_lock_irqsave(>submission_state.lock, flags);
> > -   list_for_each_entry_safe(ce, cn,
> > ->submission_state.destroyed_contexts,
> > -destroyed_link) {
> > -   list_del_init(>destroyed_link);
> > -   __release_guc_id(guc, ce);
> > +   while (!list_empty(>submission_state.destroyed_contexts)) {
> > +   spin_lock_irqsave(>submission_state.lock, flags);
> > +   ce = 
> > list_first_entry_or_null(>submission_state.destroyed_contexts,
> > + struct intel_context,
> > + destroyed_link);
> > +   if (ce)
> > +   list_del_init(>destroyed_link);
> > +   spin_unlock_irqrestore(>submission_state.lock, flags);
> > +
> > +   if (!ce)
> > +   break;
> > +
> > +   release_guc_id(guc, ce);
> > __guc_context_destroy(ce);
> > }
> > -   spin_unlock_irqrestore(>submission_state.lock, flags);
> >   }
> >   static void deregister_destroyed_contexts(struct intel_guc *guc)
> >   {
> > -   struct intel_context *ce, *cn;
> > +   struct intel_context *ce;
> > unsigned long flags;
> > -   spin_lock_irqsave(>submission_state.lock, flags);
> > -   list_for_each_entry_safe(ce, cn,
> > ->submission_state.destroyed_contexts,
> > -destroyed_link) {
> > -   list_del_init(>destroyed_link);
> > +   while (!list_empty(>submission_state.destroyed_contexts)) {
> > +   spin_lock_irqsave(>submission_state.lock, flags);
> > +   ce = 
> > list_first_entry_or_null(>submission_state.destroyed_contexts,
> > + struct intel_context,
> > + destroyed_link);
> > +   if (ce)
> > +   list_del_init(>destroyed_link);
> > +   spin_unlock_irqrestore(>submission_state.lock, flags);
> > +
> > +   if (!ce)
> > +   break;
> > +
> > guc_lrc_desc_unpin(ce);
> > }
> > -   spin_unlock_irqrestore(>submission_state.lock, flags);
> >   }
> >   static void destroyed_worker_func(struct work_struct *w)
> 


Re: [PATCH 2/7] drm/i915/guc: Only assign guc_id.id when stealing guc_id

2021-12-10 Thread John Harrison

On 12/10/2021 16:56, Matthew Brost wrote:

Previously assigned whole guc_id structure (list, spin lock) which is
incorrect, only assign the guc_id.id.

Fixes: 0f7976506de61 ("drm/i915/guc: Rework and simplify locking")
Signed-off-by: Matthew Brost 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

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 9b7b4f4e0d91..0fb2eeff0262 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1935,7 +1935,7 @@ static int steal_guc_id(struct intel_guc *guc, struct 
intel_context *ce)
GEM_BUG_ON(intel_context_is_parent(cn));
  
  		list_del_init(>guc_id.link);

-   ce->guc_id = cn->guc_id;
+   ce->guc_id.id = cn->guc_id.id;
  
  		spin_lock(>guc_state.lock);

clr_context_registered(cn);




Re: [PATCH 4/7] drm/i915/guc: Don't hog IRQs when destroying contexts

2021-12-10 Thread John Harrison

On 12/10/2021 16:56, Matthew Brost wrote:

From: John Harrison 

While attempting to debug a CT deadlock issue in various CI failures
(most easily reproduced with gem_ctx_create/basic-files), I was seeing
CPU deadlock errors being reported. This were because the context
destroy loop was blocking waiting on H2G space from inside an IRQ
spinlock. There was deadlock as such, it's just that the H2G queue was

There was *no* deadlock as such

John.


full of context destroy commands and GuC was taking a long time to
process them. However, the kernel was seeing the large amount of time
spent inside the IRQ lock as a dead CPU. Various Bad Things(tm) would
then happen (heartbeat failures, CT deadlock errors, outstanding H2G
WARNs, etc.).

Re-working the loop to only acquire the spinlock around the list
management (which is all it is meant to protect) rather than the
entire destroy operation seems to fix all the above issues.

Signed-off-by: John Harrison 
---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 45 ---
  1 file changed, 28 insertions(+), 17 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 36c2965db49b..96fcf869e3ff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2644,7 +2644,6 @@ static inline void guc_lrc_desc_unpin(struct 
intel_context *ce)
unsigned long flags;
bool disabled;
  
-	lockdep_assert_held(>submission_state.lock);

GEM_BUG_ON(!intel_gt_pm_is_awake(gt));
GEM_BUG_ON(!lrc_desc_registered(guc, ce->guc_id.id));
GEM_BUG_ON(ce != __get_context(guc, ce->guc_id.id));
@@ -2660,7 +2659,7 @@ static inline void guc_lrc_desc_unpin(struct 
intel_context *ce)
}
spin_unlock_irqrestore(>guc_state.lock, flags);
if (unlikely(disabled)) {
-   __release_guc_id(guc, ce);
+   release_guc_id(guc, ce);
__guc_context_destroy(ce);
return;
}
@@ -2694,36 +2693,48 @@ static void __guc_context_destroy(struct intel_context 
*ce)
  
  static void guc_flush_destroyed_contexts(struct intel_guc *guc)

  {
-   struct intel_context *ce, *cn;
+   struct intel_context *ce;
unsigned long flags;
  
  	GEM_BUG_ON(!submission_disabled(guc) &&

   guc_submission_initialized(guc));
  
-	spin_lock_irqsave(>submission_state.lock, flags);

-   list_for_each_entry_safe(ce, cn,
->submission_state.destroyed_contexts,
-destroyed_link) {
-   list_del_init(>destroyed_link);
-   __release_guc_id(guc, ce);
+   while (!list_empty(>submission_state.destroyed_contexts)) {
+   spin_lock_irqsave(>submission_state.lock, flags);
+   ce = 
list_first_entry_or_null(>submission_state.destroyed_contexts,
+ struct intel_context,
+ destroyed_link);
+   if (ce)
+   list_del_init(>destroyed_link);
+   spin_unlock_irqrestore(>submission_state.lock, flags);
+
+   if (!ce)
+   break;
+
+   release_guc_id(guc, ce);
__guc_context_destroy(ce);
}
-   spin_unlock_irqrestore(>submission_state.lock, flags);
  }
  
  static void deregister_destroyed_contexts(struct intel_guc *guc)

  {
-   struct intel_context *ce, *cn;
+   struct intel_context *ce;
unsigned long flags;
  
-	spin_lock_irqsave(>submission_state.lock, flags);

-   list_for_each_entry_safe(ce, cn,
->submission_state.destroyed_contexts,
-destroyed_link) {
-   list_del_init(>destroyed_link);
+   while (!list_empty(>submission_state.destroyed_contexts)) {
+   spin_lock_irqsave(>submission_state.lock, flags);
+   ce = 
list_first_entry_or_null(>submission_state.destroyed_contexts,
+ struct intel_context,
+ destroyed_link);
+   if (ce)
+   list_del_init(>destroyed_link);
+   spin_unlock_irqrestore(>submission_state.lock, flags);
+
+   if (!ce)
+   break;
+
guc_lrc_desc_unpin(ce);
}
-   spin_unlock_irqrestore(>submission_state.lock, flags);
  }
  
  static void destroyed_worker_func(struct work_struct *w)




[PATCH 6/7] drm/i915/guc: Kick G2H tasklet if no credits

2021-12-10 Thread Matthew Brost
Let's be paranoid and kick the G2H tasklet, which dequeues messages, if
G2H credit are exhausted.

Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

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 ee5525c6f79b..334c5ab1c7b1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -591,12 +591,19 @@ static inline bool h2g_has_room(struct intel_guc_ct *ct, 
u32 len_dw)
 
 static int has_room_nb(struct intel_guc_ct *ct, u32 h2g_dw, u32 g2h_dw)
 {
+   bool h2g = h2g_has_room(ct, h2g_dw);
+   bool g2h = g2h_has_room(ct, g2h_dw);
+
lockdep_assert_held(>ctbs.send.lock);
 
-   if (unlikely(!h2g_has_room(ct, h2g_dw) || !g2h_has_room(ct, g2h_dw))) {
+   if (unlikely(!h2g || !g2h)) {
if (ct->stall_time == KTIME_MAX)
ct->stall_time = ktime_get();
 
+   /* Be paranoid and kick G2H tasklet to free credits */
+   if (!g2h)
+   tasklet_hi_schedule(>receive_tasklet);
+
if (unlikely(ct_deadlocked(ct)))
return -EPIPE;
else
-- 
2.33.1



[PATCH 5/7] drm/i915/guc: Add extra debug on CT deadlock

2021-12-10 Thread Matthew Brost
Print CT state (H2G + G2H head / tail pointers, credits) on CT
deadlock.

Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 9 +
 1 file changed, 9 insertions(+)

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 a0cc34be7b56..ee5525c6f79b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -523,6 +523,15 @@ static inline bool ct_deadlocked(struct intel_guc_ct *ct)
CT_ERROR(ct, "Communication stalled for %lld ms, desc 
status=%#x,%#x\n",
 ktime_ms_delta(ktime_get(), ct->stall_time),
 send->status, recv->status);
+   CT_ERROR(ct, "H2G Space: %u\n",
+atomic_read(>ctbs.send.space) * 4);
+   CT_ERROR(ct, "Head: %u\n", ct->ctbs.send.desc->head);
+   CT_ERROR(ct, "Tail: %u\n", ct->ctbs.send.desc->tail);
+   CT_ERROR(ct, "G2H Space: %u\n",
+atomic_read(>ctbs.recv.space) * 4);
+   CT_ERROR(ct, "Head: %u\n", ct->ctbs.recv.desc->head);
+   CT_ERROR(ct, "Tail: %u\n", ct->ctbs.recv.desc->tail);
+
ct->ctbs.send.broken = true;
}
 
-- 
2.33.1



[PATCH 4/7] drm/i915/guc: Don't hog IRQs when destroying contexts

2021-12-10 Thread Matthew Brost
From: John Harrison 

While attempting to debug a CT deadlock issue in various CI failures
(most easily reproduced with gem_ctx_create/basic-files), I was seeing
CPU deadlock errors being reported. This were because the context
destroy loop was blocking waiting on H2G space from inside an IRQ
spinlock. There was deadlock as such, it's just that the H2G queue was
full of context destroy commands and GuC was taking a long time to
process them. However, the kernel was seeing the large amount of time
spent inside the IRQ lock as a dead CPU. Various Bad Things(tm) would
then happen (heartbeat failures, CT deadlock errors, outstanding H2G
WARNs, etc.).

Re-working the loop to only acquire the spinlock around the list
management (which is all it is meant to protect) rather than the
entire destroy operation seems to fix all the above issues.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 45 ---
 1 file changed, 28 insertions(+), 17 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 36c2965db49b..96fcf869e3ff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2644,7 +2644,6 @@ static inline void guc_lrc_desc_unpin(struct 
intel_context *ce)
unsigned long flags;
bool disabled;
 
-   lockdep_assert_held(>submission_state.lock);
GEM_BUG_ON(!intel_gt_pm_is_awake(gt));
GEM_BUG_ON(!lrc_desc_registered(guc, ce->guc_id.id));
GEM_BUG_ON(ce != __get_context(guc, ce->guc_id.id));
@@ -2660,7 +2659,7 @@ static inline void guc_lrc_desc_unpin(struct 
intel_context *ce)
}
spin_unlock_irqrestore(>guc_state.lock, flags);
if (unlikely(disabled)) {
-   __release_guc_id(guc, ce);
+   release_guc_id(guc, ce);
__guc_context_destroy(ce);
return;
}
@@ -2694,36 +2693,48 @@ static void __guc_context_destroy(struct intel_context 
*ce)
 
 static void guc_flush_destroyed_contexts(struct intel_guc *guc)
 {
-   struct intel_context *ce, *cn;
+   struct intel_context *ce;
unsigned long flags;
 
GEM_BUG_ON(!submission_disabled(guc) &&
   guc_submission_initialized(guc));
 
-   spin_lock_irqsave(>submission_state.lock, flags);
-   list_for_each_entry_safe(ce, cn,
->submission_state.destroyed_contexts,
-destroyed_link) {
-   list_del_init(>destroyed_link);
-   __release_guc_id(guc, ce);
+   while (!list_empty(>submission_state.destroyed_contexts)) {
+   spin_lock_irqsave(>submission_state.lock, flags);
+   ce = 
list_first_entry_or_null(>submission_state.destroyed_contexts,
+ struct intel_context,
+ destroyed_link);
+   if (ce)
+   list_del_init(>destroyed_link);
+   spin_unlock_irqrestore(>submission_state.lock, flags);
+
+   if (!ce)
+   break;
+
+   release_guc_id(guc, ce);
__guc_context_destroy(ce);
}
-   spin_unlock_irqrestore(>submission_state.lock, flags);
 }
 
 static void deregister_destroyed_contexts(struct intel_guc *guc)
 {
-   struct intel_context *ce, *cn;
+   struct intel_context *ce;
unsigned long flags;
 
-   spin_lock_irqsave(>submission_state.lock, flags);
-   list_for_each_entry_safe(ce, cn,
->submission_state.destroyed_contexts,
-destroyed_link) {
-   list_del_init(>destroyed_link);
+   while (!list_empty(>submission_state.destroyed_contexts)) {
+   spin_lock_irqsave(>submission_state.lock, flags);
+   ce = 
list_first_entry_or_null(>submission_state.destroyed_contexts,
+ struct intel_context,
+ destroyed_link);
+   if (ce)
+   list_del_init(>destroyed_link);
+   spin_unlock_irqrestore(>submission_state.lock, flags);
+
+   if (!ce)
+   break;
+
guc_lrc_desc_unpin(ce);
}
-   spin_unlock_irqrestore(>submission_state.lock, flags);
 }
 
 static void destroyed_worker_func(struct work_struct *w)
-- 
2.33.1



[PATCH 2/7] drm/i915/guc: Only assign guc_id.id when stealing guc_id

2021-12-10 Thread Matthew Brost
Previously assigned whole guc_id structure (list, spin lock) which is
incorrect, only assign the guc_id.id.

Fixes: 0f7976506de61 ("drm/i915/guc: Rework and simplify locking")
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 9b7b4f4e0d91..0fb2eeff0262 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1935,7 +1935,7 @@ static int steal_guc_id(struct intel_guc *guc, struct 
intel_context *ce)
GEM_BUG_ON(intel_context_is_parent(cn));
 
list_del_init(>guc_id.link);
-   ce->guc_id = cn->guc_id;
+   ce->guc_id.id = cn->guc_id.id;
 
spin_lock(>guc_state.lock);
clr_context_registered(cn);
-- 
2.33.1



[PATCH 3/7] drm/i915/guc: Remove racey GEM_BUG_ON

2021-12-10 Thread Matthew Brost
A full GT reset can race with the last context put resulting in the
context ref count being zero but the destroyed bit not yet being set.
Remove GEM_BUG_ON in scrub_guc_desc_for_outstanding_g2h that asserts the
destroyed bit must be set in ref count is zero.

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 --
 1 file changed, 2 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 0fb2eeff0262..36c2965db49b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1040,8 +1040,6 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
 
spin_unlock(>guc_state.lock);
 
-   GEM_BUG_ON(!do_put && !destroyed);
-
if (pending_enable || destroyed || deregister) {
decr_outstanding_submission_g2h(guc);
if (deregister)
-- 
2.33.1



[PATCH 0/7] Fix stealing guc_ids + test

2021-12-10 Thread Matthew Brost
Patches 1 & 2 address bugs in stealing of guc_ids and patch 7 tests this
path.

Patches 4-6 address some issues with the CTs exposed by the selftest in
patch 7. Basically if a lot of contexts were all deregistered all at
once, the CT channel could deadlock.

Patch 3 is a small fix that is already review but just included for CI.

Signed-off-by: Matthew Brost 

John Harrison (1):
  drm/i915/guc: Don't hog IRQs when destroying contexts

Matthew Brost (6):
  drm/i915/guc: Use correct context lock when callig
clr_context_registered
  drm/i915/guc: Only assign guc_id.id when stealing guc_id
  drm/i915/guc: Remove racey GEM_BUG_ON
  drm/i915/guc: Add extra debug on CT deadlock
  drm/i915/guc: Kick G2H tasklet if no credits
  drm/i915/guc: Selftest for stealing of guc ids

 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  12 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  18 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  68 ---
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 171 ++
 4 files changed, 241 insertions(+), 28 deletions(-)

-- 
2.33.1



[PATCH 1/7] drm/i915/guc: Use correct context lock when callig clr_context_registered

2021-12-10 Thread Matthew Brost
s/ce/cn/ when grabbing guc_state.lock before calling
clr_context_registered.

Fixes: 0f7976506de61 ("drm/i915/guc: Rework and simplify locking")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 ++--
 1 file changed, 2 insertions(+), 2 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 1f9d4fde421f..9b7b4f4e0d91 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1937,9 +1937,9 @@ static int steal_guc_id(struct intel_guc *guc, struct 
intel_context *ce)
list_del_init(>guc_id.link);
ce->guc_id = cn->guc_id;
 
-   spin_lock(>guc_state.lock);
+   spin_lock(>guc_state.lock);
clr_context_registered(cn);
-   spin_unlock(>guc_state.lock);
+   spin_unlock(>guc_state.lock);
 
set_context_guc_id_invalid(cn);
 
-- 
2.33.1



[PATCH 7/7] drm/i915/guc: Selftest for stealing of guc ids

2021-12-10 Thread Matthew Brost
Testing the stealing of guc ids is hard from user spaec as we have 64k
guc_ids. Add a selftest, which artificially reduces the number of guc
ids, and forces a steal. Details of test has comment in code so will not
repeat here.

Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  12 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  15 +-
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 171 ++
 3 files changed, 193 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 1cb46098030d..307380a2e2ff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -94,6 +94,11 @@ struct intel_guc {
 * @guc_ids: used to allocate new guc_ids, single-lrc
 */
struct ida guc_ids;
+   /**
+* @num_guc_ids: Number of guc_ids, selftest feature to be able
+* to reduce this number of test.
+*/
+   int num_guc_ids;
/**
 * @guc_ids_bitmap: used to allocate new guc_ids, multi-lrc
 */
@@ -202,6 +207,13 @@ struct intel_guc {
 */
struct delayed_work work;
} timestamp;
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   /**
+* @number_guc_id_stole: The number of guc_ids that have been stole
+*/
+   int number_guc_id_stole;
+#endif
 };
 
 static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
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 96fcf869e3ff..57019b190bfb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -145,7 +145,7 @@ guc_create_parallel(struct intel_engine_cs **engines,
  * use should be low and 1/16 should be sufficient. Minimum of 32 guc_ids for
  * multi-lrc.
  */
-#define NUMBER_MULTI_LRC_GUC_ID(GUC_MAX_LRC_DESCRIPTORS / 16)
+#define NUMBER_MULTI_LRC_GUC_ID(guc)   (guc->submission_state.num_guc_ids / 16)
 
 /*
  * Below is a set of functions which control the GuC scheduling state which
@@ -1775,7 +1775,7 @@ int intel_guc_submission_init(struct intel_guc *guc)
  destroyed_worker_func);
 
guc->submission_state.guc_ids_bitmap =
-   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID, GFP_KERNEL);
+   bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL);
if (!guc->submission_state.guc_ids_bitmap)
return -ENOMEM;
 
@@ -1869,13 +1869,13 @@ static int new_guc_id(struct intel_guc *guc, struct 
intel_context *ce)
 
if (intel_context_is_parent(ce))
ret = 
bitmap_find_free_region(guc->submission_state.guc_ids_bitmap,
- NUMBER_MULTI_LRC_GUC_ID,
+ NUMBER_MULTI_LRC_GUC_ID(guc),
  
order_base_2(ce->parallel.number_children
   + 1));
else
ret = ida_simple_get(>submission_state.guc_ids,
-NUMBER_MULTI_LRC_GUC_ID,
-GUC_MAX_LRC_DESCRIPTORS,
+NUMBER_MULTI_LRC_GUC_ID(guc),
+guc->submission_state.num_guc_ids,
 GFP_KERNEL | __GFP_RETRY_MAYFAIL |
 __GFP_NOWARN);
if (unlikely(ret < 0))
@@ -1941,6 +1941,10 @@ static int steal_guc_id(struct intel_guc *guc, struct 
intel_context *ce)
 
set_context_guc_id_invalid(cn);
 
+#ifdef CONFIG_DRM_I915_SELFTEST
+   guc->number_guc_id_stole++;
+#endif
+
return 0;
} else {
return -EAGAIN;
@@ -3779,6 +3783,7 @@ static bool __guc_submission_selected(struct intel_guc 
*guc)
 
 void intel_guc_submission_init_early(struct intel_guc *guc)
 {
+   guc->submission_state.num_guc_ids = GUC_MAX_LRC_DESCRIPTORS;
guc->submission_supported = __guc_submission_supported(guc);
guc->submission_selected = __guc_submission_selected(guc);
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index fb0e4a7bd8ca..9ab355e64b3f 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -3,8 +3,21 @@
  * Copyright �� 2021 Intel Corporation
  */
 
+#include "selftests/igt_spinner.h"
 #include "selftests/intel_scheduler_helpers.h"
 
+static int request_add_spin(struct i915_request *rq, struct igt_spinner *spin)
+{
+   int err = 0;
+
+   i915_request_get(rq);
+   i915_request_add(rq);
+   if (spin && !igt_wait_for_spinner(spin, rq))
+   err = -ETIMEDOUT;
+
+   

Re: [Patch v2] drm/amdgpu: Don't inherit GEM object VMAs in child process

2021-12-10 Thread Felix Kuehling

On 2021-12-10 4:48 p.m., Rajneesh Bhardwaj wrote:

When an application having open file access to a node forks, its shared
mappings also get reflected in the address space of child process even
though it cannot access them with the object permissions applied. With the
existing permission checks on the gem objects, it might be reasonable to
also create the VMAs with VM_DONTCOPY flag so a user space application
doesn't need to explicitly call the madvise(addr, len, MADV_DONTFORK)
system call to prevent the pages in the mapped range to appear in the
address space of the child process. It also prevents the memory leaks
due to additional reference counts on the mapped BOs in the child
process that prevented freeing the memory in the parent for which we had
worked around earlier in the user space inside the thunk library.

Additionally, we faced this issue when using CRIU to checkpoint restore
an application that had such inherited mappings in the child which
confuse CRIU when it mmaps on restore. Having this flag set for the
render node VMAs helps. VMAs mapped via KFD already take care of this so
this is needed only for the render nodes.

To limit the impact of the change to user space consumers such as OpenGL
etc, limit it to KFD BOs only.

Cc: Felix Kuehling 

Signed-off-by: David Yat Sin 
Signed-off-by: Rajneesh Bhardwaj 


Acked-by: Felix Kuehling 



---

Changes in v2:
  * Addressed Christian's concerns for user space impact
  * Further reduced the scope to KFD BOs only

  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a224b5295edd..64a7931eda8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -263,6 +263,9 @@ static int amdgpu_gem_object_mmap(struct drm_gem_object 
*obj, struct vm_area_str
!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
vma->vm_flags &= ~VM_MAYWRITE;
  
+	if (bo->kfd_bo)

+   vma->vm_flags |= VM_DONTCOPY;
+
return drm_gem_ttm_mmap(obj, vma);
  }
  


Re: Reuse framebuffer after a kexec (amdgpu / efifb)

2021-12-10 Thread Felix Kuehling

On 2021-12-10 10:13 a.m., Christian König wrote:



Am 10.12.21 um 15:25 schrieb Guilherme G. Piccoli:

On 10/12/2021 11:16, Alex Deucher wrote:> [...]

Why not just reload the driver after kexec?

Alex

Because the original issue is the kdump case, and we want a very very
tiny kernel - also, the crash originally could have been caused by
amdgpu itself, so if it's a GPU issue, we don't want to mess with that
in kdump. And I confess I tried modprobe amdgpu after a kdump, no
success - kdump won't call shutdown handlers, so GPU will be in a
"rogue" state...

My question was about regular kexec because it's much simpler usually,
we can do whatever we want there. My line of thought was: if I make it
work in regular kexec with a simple framebuffer, I might be able to get
it working on kdump heheh


How about issuing a PCIe reset and re-initializing the ASIC with just 
the VBIOS?


That should be pretty straightforward I think.


Do you actually need to restore the exact boot-up mode? If you have the 
same framebuffer memory layout (width, height, bpp, stride) the precise 
display timing doesn't really matter. So we "just" need to switch to a 
mode that's compatible with the efifb framebuffer parameters and point 
the display engine at the efifb as the scan-out buffer.


Regards,
  Felix




Christian.


Re: [PATCH 3/3] drm: bridge: Switch to devm_drm_of_get_bridge

2021-12-10 Thread Linus Walleij
On Sat, Dec 11, 2021 at 1:07 AM Linus Walleij  wrote:
> On Fri, Dec 10, 2021 at 6:49 PM Jagan Teki  wrote:

> > -   dev_info(dev, "connected to panel\n");
> > -   d->panel = panel;
>
> How does this assignment happen after your patch?
> I'm using that...
>
> devm_drm_of_get_bridge() needs some more argument right?

Actually it is only used in unbind right below:

   if (d->panel)
drm_panel_bridge_remove(d->bridge_out);

If it is not needed at all after your patch (because devm removes
the bridge) then also delete this code, and delete the
struct drm_panel *panel from struct mcde_dsi at the top
and possibly also drop the header #include 
entirely.

Yours,
Linus Walleij


Re: [Intel-gfx] [PATCH 2/4] drm/i915/guc: Speed up GuC log dumps

2021-12-10 Thread Daniele Ceraolo Spurio




On 12/9/2021 8:40 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

Add support for telling the debugfs interface the size of the GuC log
dump in advance. Without that, the underlying framework keeps calling
the 'show' function with larger and larger buffer allocations until it
fits. That means reading the log from graphics memory many times - 16
times with the full 18MB log size.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/intel_gt_debugfs.h| 21 ++--
  .../drm/i915/gt/uc/intel_guc_log_debugfs.c| 54 +--
  2 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h
index e307ceb99031..1adea367d99b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.h
@@ -10,11 +10,7 @@
  
  struct intel_gt;
  
-#define DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(__name)\

-   static int __name ## _open(struct inode *inode, struct file *file) \
-{  \
-   return single_open(file, __name ## _show, inode->i_private); \
-}  \
+#define __GT_DEBUGFS_ATTRIBUTE_FOPS(__name)\
  static const struct file_operations __name ## _fops = {   
\
.owner = THIS_MODULE,   \
.open = __name ## _open,\
@@ -23,6 +19,21 @@ static const struct file_operations __name ## _fops = {  
\
.release = single_release,  \
  }
  
+#define DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(__name)			\

+static int __name ## _open(struct inode *inode, struct file *file) \
+{  \
+   return single_open(file, __name ## _show, inode->i_private); \
+}  \
+__GT_DEBUGFS_ATTRIBUTE_FOPS(__name)
+
+#define DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(__name, __size_vf) \
+static int __name ## _open(struct inode *inode, struct file *file) \
+{  \
+return single_open_size(file, __name ## _show, inode->i_private,\
+   __size_vf(inode->i_private));\
+}  \
+__GT_DEBUGFS_ATTRIBUTE_FOPS(__name)
+
  void intel_gt_debugfs_register(struct intel_gt *gt);
  
  struct intel_gt_debugfs_file {

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
index 46026c2c1722..da7dd099fd93 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
@@ -10,14 +10,62 @@
  #include "intel_guc.h"
  #include "intel_guc_log.h"
  #include "intel_guc_log_debugfs.h"
+#include "intel_uc.h"
+
+static u32 obj_to_guc_log_dump_size(struct drm_i915_gem_object *obj)
+{
+   u32 size;
+
+   if (!obj)
+   return -ENODEV;
+
+   /* "0x%08x 0x%08x 0x%08x 0x%08x\n" => 16 bytes -> 44 chars => x2.75 */
+   size = ((obj->base.size * 11) + 3) / 4;
+
+   /* Add padding for final blank line, any extra header info, etc. */
+   size = PAGE_ALIGN(size + PAGE_SIZE);
+
+   return size;
+}
+
+static u32 guc_log_dump_size(struct intel_guc_log *log)
+{
+   struct intel_guc *guc = log_to_guc(log);
+
+   if (!intel_guc_is_supported(guc))
+   return -ENODEV;
+
+   if (!log->vma)
+   return -ENODEV;


You're returning these error codes as a u32 and passing them as a size 
to single_open_size, so they're going to be read as a massive positive 
number. Same for the error code from obj_to_guc_log_dump_size. Either 
return a safe size on error (PAGE_SIZE?) or make the 
DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE smarter and don't even 
attempt to open the file if the function that calculates the size 
returns zero or an error.



+
+   return obj_to_guc_log_dump_size(log->vma->obj);
+}
  
  static int guc_log_dump_show(struct seq_file *m, void *data)

  {
struct drm_printer p = drm_seq_file_printer(m);
+   int ret;
+
+   ret = intel_guc_log_dump(m->private, , false);
+
+   if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
+   pr_warn_once("preallocated size:%zx for %s exceeded\n",
+m->size, __func__);


Do we need this debug log in guc_load_err_log_dump_show as well? or 
maybe just move it at the end of intel_guc_log_dump?


Daniele


+
+   return ret;
+}
+DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_log_dump, guc_log_dump_size);
+
+static u32 guc_load_err_dump_size(struct intel_guc_log *log)
+{
+   struct 

[PATCH -next] drm/vmwgfx: use %zu to print size_t

2021-12-10 Thread Randy Dunlap
Prevent a build format warning by using the correct format specifier
to print size_t data.

Fixes this build warning:

../drivers/gpu/drm/vmwgfx/vmwgfx_gem.c:230:33: warning: format ‘%ld’ expects 
argument of type ‘long int’, but argument 4 has type ‘size_t {aka unsigned 
int}’ [-Wformat=]

Fixes: 8afa13a0583f ("drm/vmwgfx: Implement DRIVER_GEM")
Signed-off-by: Randy Dunlap 
Cc: Zack Rusin 
Cc: VMware Graphics 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Martin Krastev 
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- next-2021-1210.orig/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+++ next-2021-1210/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
@@ -227,7 +227,7 @@ static void vmw_bo_print_info(int id, st
break;
}
 
-   seq_printf(m, "\t\t0x%08x: %12ld bytes %s, type = %s",
+   seq_printf(m, "\t\t0x%08x: %12zu bytes %s, type = %s",
   id, bo->base.base.size, placement, type);
seq_printf(m, ", priority = %u, pin_count = %u, GEM refs = %d, TTM refs 
= %d",
   bo->base.priority,


[PATCH v2 2/3] drm/i915/uc: Prepare for different firmware key sizes

2021-12-10 Thread Daniele Ceraolo Spurio
From: Michal Wajdeczko 

Future GuC/HuC firmwares might be signed with different key sizes.
Don't assume that it must be always 2048 bits long.

Signed-off-by: Michal Wajdeczko 
Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index b7fa51aefdff..01683f5f95bd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -322,13 +322,6 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
 
/* now RSA */
-   if (unlikely(css->key_size_dw != UOS_RSA_SCRATCH_COUNT)) {
-   drm_warn(>drm, "%s firmware %s: unexpected key size: %u 
!= %u\n",
-intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
-css->key_size_dw, UOS_RSA_SCRATCH_COUNT);
-   err = -EPROTO;
-   goto fail;
-   }
uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
 
/* At least, it should have header, uCode and RSA. Size of all three. */
-- 
2.25.1



[PATCH v2 3/3] drm/i915/guc: support bigger RSA keys

2021-12-10 Thread Daniele Ceraolo Spurio
Some of the newer HW will use bigger RSA keys to authenticate the GuC
binary. On those platforms the HW will read the key from memory instead
of the RSA registers, so we need to copy it in a dedicated vma, like we
do for the HuC. The address of the key is provided to the HW via the
first RSA register.

v2: clarify that the RSA behavior is hardcoded in the bootrom (Matt)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Michal Wajdeczko 
Cc: John Harrison 
Cc: Matthew Brost 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 73 +--
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  2 -
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 86 ++-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  1 +
 5 files changed, 114 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 796483a41353..31420ce1ce6b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -40,9 +40,8 @@ static void guc_prepare_xfer(struct intel_uncore *uncore)
}
 }
 
-/* Copy RSA signature from the fw image to HW for verification */
-static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
-   struct intel_uncore *uncore)
+static int guc_xfer_rsa_mmio(struct intel_uc_fw *guc_fw,
+struct intel_uncore *uncore)
 {
u32 rsa[UOS_RSA_SCRATCH_COUNT];
size_t copied;
@@ -58,6 +57,27 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
return 0;
 }
 
+static int guc_xfer_rsa_vma(struct intel_uc_fw *guc_fw,
+   struct intel_uncore *uncore)
+{
+   struct intel_guc *guc = container_of(guc_fw, struct intel_guc, fw);
+
+   intel_uncore_write(uncore, UOS_RSA_SCRATCH(0),
+  intel_guc_ggtt_offset(guc, guc_fw->rsa_data));
+
+   return 0;
+}
+
+/* Copy RSA signature from the fw image to HW for verification */
+static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
+   struct intel_uncore *uncore)
+{
+   if (guc_fw->rsa_data)
+   return guc_xfer_rsa_vma(guc_fw, uncore);
+   else
+   return guc_xfer_rsa_mmio(guc_fw, uncore);
+}
+
 /*
  * Read the GuC status register (GUC_STATUS) and store it in the
  * specified location; then return a boolean indicating whether
@@ -142,7 +162,10 @@ int intel_guc_fw_upload(struct intel_guc *guc)
/*
 * Note that GuC needs the CSS header plus uKernel code to be copied
 * by the DMA engine in one operation, whereas the RSA signature is
-* loaded via MMIO.
+* loaded separately, either by copying it to the UOS_RSA_SCRATCH
+* register (if key size <= 256) or through a ggtt-pinned vma (if key
+* size > 256). The RSA size and therefore the way we provide it to the
+* HW is fixed for each platform and hard-coded in the bootrom.
 */
ret = guc_xfer_rsa(>fw, uncore);
if (ret)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index c10736dddfb4..d10b227ac4aa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -54,65 +54,6 @@ void intel_huc_init_early(struct intel_huc *huc)
}
 }
 
-static int intel_huc_rsa_data_create(struct intel_huc *huc)
-{
-   struct intel_gt *gt = huc_to_gt(huc);
-   struct intel_guc *guc = >uc.guc;
-   struct i915_vma *vma;
-   size_t copied;
-   void *vaddr;
-   int err;
-
-   err = i915_inject_probe_error(gt->i915, -ENXIO);
-   if (err)
-   return err;
-
-   /*
-* HuC firmware will sit above GUC_GGTT_TOP and will not map
-* through GTT. Unfortunately, this means GuC cannot perform
-* the HuC auth. as the rsa offset now falls within the GuC
-* inaccessible range. We resort to perma-pinning an additional
-* vma within the accessible range that only contains the rsa
-* signature. The GuC can use this extra pinning to perform
-* the authentication since its GGTT offset will be GuC
-* accessible.
-*/
-   GEM_BUG_ON(huc->fw.rsa_size > PAGE_SIZE);
-   vma = intel_guc_allocate_vma(guc, PAGE_SIZE);
-   if (IS_ERR(vma))
-   return PTR_ERR(vma);
-
-   vaddr = i915_gem_object_pin_map_unlocked(vma->obj,
-
i915_coherent_map_type(gt->i915,
-   
vma->obj, true));
-   if (IS_ERR(vaddr)) {
-   i915_vma_unpin_and_release(, 0);
-   err = PTR_ERR(vaddr);
-   goto unpin_out;
-   }
-
-   copied = intel_uc_fw_copy_rsa(>fw, vaddr, vma->size);
-   i915_gem_object_unpin_map(vma->obj);
-
-   if (copied < huc->fw.rsa_size) {
-   

[PATCH v2 1/3] drm/i915/uc: correctly track uc_fw init failure

2021-12-10 Thread Daniele Ceraolo Spurio
The FAILURE state of uc_fw currently implies that the fw is loadable
(i.e init completed), so we can't use it for init failures and instead
need a dedicated error code.

Note that this currently does not cause any issues because if we fail to
init any of the firmwares we abort the load, but better be accurate
anyway in case things change in the future.

Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  4 ++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  | 17 +++--
 4 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 196424be0998..796483a41353 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -164,6 +164,6 @@ int intel_guc_fw_upload(struct intel_guc *guc)
return 0;
 
 out:
-   intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_FAIL);
+   intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
return ret;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ff4b6869b80b..c10736dddfb4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -199,7 +199,7 @@ int intel_huc_auth(struct intel_huc *huc)
 
 fail:
i915_probe_error(gt->i915, "HuC: Authentication failed %d\n", ret);
-   intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_FAIL);
+   intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 3aa87be4f2e4..b7fa51aefdff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -540,7 +540,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 
dst_offset, u32 dma_flags)
i915_probe_error(gt->i915, "Failed to load %s firmware %s (%d)\n",
 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
 err);
-   intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_FAIL);
+   intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
return err;
 }
 
@@ -558,7 +558,7 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
if (err) {
DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",
 intel_uc_fw_type_repr(uc_fw->type), err);
-   intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_FAIL);
+   intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_INIT_FAIL);
}
 
return err;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index 1e00bf65639e..fd17abf2ab02 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -32,11 +32,12 @@ struct intel_gt;
  * ||MISSING <--/|\--> ERROR|
  * |   fetch|V  |
  * || AVAILABLE |
- * ++-   | -+
+ * ++-   |   \ -+
+ * |||\--> INIT FAIL|
  * |   init |V  |
  * ||/--> LOADABLE <<---\   |
  * ++-   \ /\\   \ -+
- * || FAIL <--<  \--> TRANSFERRED \ |
+ * ||LOAD FAIL <--<  \--> TRANSFERRED \ |
  * |   upload   |  \   /   \  / |
  * ||   \-/ \--> RUNNING|
  * ++---+
@@ -50,8 +51,9 @@ enum intel_uc_fw_status {
INTEL_UC_FIRMWARE_MISSING, /* blob not found on the system */
INTEL_UC_FIRMWARE_ERROR, /* invalid format or version */
INTEL_UC_FIRMWARE_AVAILABLE, /* blob found and copied in mem */
+   INTEL_UC_FIRMWARE_INIT_FAIL, /* failed to prepare fw objects for load */
INTEL_UC_FIRMWARE_LOADABLE, /* all fw-required objects are ready */
-   INTEL_UC_FIRMWARE_FAIL, /* failed to xfer or init/auth the fw */
+   INTEL_UC_FIRMWARE_LOAD_FAIL, /* failed to xfer or init/auth the fw */
INTEL_UC_FIRMWARE_TRANSFERRED, /* dma xfer done */
INTEL_UC_FIRMWARE_RUNNING /* init/auth done */
 };
@@ -130,10 +132,12 @@ const char *intel_uc_fw_status_repr(enum 
intel_uc_fw_status status)
return "ERROR";
case INTEL_UC_FIRMWARE_AVAILABLE:
return "AVAILABLE";
+   case INTEL_UC_FIRMWARE_INIT_FAIL:
+   

[PATCH v2 0/3] drm/i915: Support bigger GuC RSA keys

2021-12-10 Thread Daniele Ceraolo Spurio
Some of the newer platforms use a bigger RSA key to authenticate the GuC,
which is provided to the HW via a ggtt-pinned object instead of mmio.

While doing the changes for this I've also spotted an inconsistency in
the error status of the fw on init failure, so I've added a path to fix
that as well.

v2: clarify in comments that the expected RSA size is hardcoded in the
bootrom (Matt)

Cc: Michal Wajdeczko 
Cc: John Harrison 
Cc: Matthew Brost 

Daniele Ceraolo Spurio (2):
  drm/i915/uc: correctly track uc_fw init failure
  drm/i915/guc: support bigger RSA keys

Michal Wajdeczko (1):
  drm/i915/uc: Prepare for different firmware key sizes

 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 33 ++--
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 75 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  2 -
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 95 ---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  | 18 +++--
 5 files changed, 128 insertions(+), 95 deletions(-)

-- 
2.25.1



Re: [PATCH 3/3] drm: bridge: Switch to devm_drm_of_get_bridge

2021-12-10 Thread Linus Walleij
On Fri, Dec 10, 2021 at 6:49 PM Jagan Teki  wrote:
>
> devm_drm_of_get_bridge is capable of looking up the downstream
> bridge and panel and trying to add a panel bridge if the panel
> is found.
>
> Replace explicit finding calls with devm_drm_of_get_bridge.
>
> Cc: Philipp Zabel 
> Cc: Chun-Kuang Hu 
> Cc: Linus Walleij 
> Signed-off-by: Jagan Teki 

Nice overall!

> -   /* Look for a panel as a child to this node */
> -   for_each_available_child_of_node(dev->of_node, child) {
> -   panel = of_drm_find_panel(child);
> -   if (IS_ERR(panel)) {
> -   dev_err(dev, "failed to find panel try bridge 
> (%ld)\n",
> -   PTR_ERR(panel));
> -   panel = NULL;
> -
> -   bridge = of_drm_find_bridge(child);
> -   if (!bridge) {
> -   dev_err(dev, "failed to find bridge\n");
> -   return -EINVAL;
> -   }
> -   }
> -   }
> -   if (panel) {
> -   bridge = drm_panel_bridge_add_typed(panel,
> -   DRM_MODE_CONNECTOR_DSI);

And we are guaranteed that the right type of connector will be
used here? (Just checking.)

> -   if (IS_ERR(bridge)) {
> -   dev_err(dev, "error adding panel bridge\n");
> -   return PTR_ERR(bridge);
> -   }
> -   dev_info(dev, "connected to panel\n");
> -   d->panel = panel;

How does this assignment happen after your patch?
I'm using that...

devm_drm_of_get_bridge() needs some more argument right?

> -   } else if (bridge) {
> -   /* TODO: AV8100 HDMI encoder goes here for example */
> -   dev_info(dev, "connected to non-panel bridge 
> (unsupported)\n");
> -   return -ENODEV;
> -   } else {
> -   dev_err(dev, "no panel or bridge\n");
> -   return -ENODEV;
> +   bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> +   if (IS_ERR(bridge)) {
> +   dev_err(dev, "error to get bridge\n");
> +   return PTR_ERR(bridge);

I'm gonna want to test this somehow on the hardware. But the TODO comment
there wasn't supposed to be deleted if I will still need to take some special
action whether this is a panel bridge or some other bridge.

Yours,
Linus Walleij


Re: [PATCH v3 12/13] drm/msm/dsi: Add support for DSC configuration

2021-12-10 Thread Marijn Suijten
Hi Vinod,

On 2021-11-16 11:52:55, Vinod Koul wrote:
> When DSC is enabled, we need to configure DSI registers accordingly and
> configure the respective stream compression registers.
> 
> Add support to calculate the register setting based on DSC params and
> timing information and configure these registers.
> 
> Signed-off-by: Vinod Koul 
> ---
>  drivers/gpu/drm/msm/dsi/dsi.xml.h  |  10 +++
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 113 -
>  2 files changed, 122 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h 
> b/drivers/gpu/drm/msm/dsi/dsi.xml.h
> index 49b551ad1bff..c1c85df58c4b 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
> @@ -706,4 +706,14 @@ static inline uint32_t DSI_VERSION_MAJOR(uint32_t val)
>  #define REG_DSI_CPHY_MODE_CTRL   
> 0x02d4
>  
>  
> +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL  0x029c
> +
> +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL2 0x02a0
> +
> +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL
> 0x02a4
> +
> +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2   
> 0x02a8
> +
> +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL3   
> 0x02ac

I presume you are aware that these files are autogenerated, but there
does not seem to be any link to patches adding these registers to the
XML files in either envytools to mesa, nor could I find any merge/pull
requests on the matter.  Would you mind posting those?  Before doing so
though, consider the comment below about register mapping.

> +
>  #endif /* DSI_XML */
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 31d385d8d834..2c14c36f0b3d 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -908,6 +908,20 @@ static void dsi_ctrl_config(struct msm_dsi_host 
> *msm_host, bool enable,
>   dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0));
>  }
>  
> +static int dsi_dsc_update_pic_dim(struct msm_display_dsc_config *dsc,
> +   int pic_width, int pic_height)

This function - adopted from downstream - does not seem to perform a
whole lot, especially without the modulo checks against the slice size.
Perhaps it can be inlined?

> +{
> + if (!dsc || !pic_width || !pic_height) {
> + pr_err("DSI: invalid input: pic_width: %d pic_height: %d\n", 
> pic_width, pic_height);
> + return -EINVAL;
> + }
> +
> + dsc->drm->pic_width = pic_width;
> + dsc->drm->pic_height = pic_height;
> +
> + return 0;
> +}
> +
>  static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool 
> is_bonded_dsi)
>  {
>   struct drm_display_mode *mode = msm_host->mode;
> @@ -940,7 +954,68 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
>   hdisplay /= 2;
>   }
>  
> + if (msm_host->dsc) {
> + struct msm_display_dsc_config *dsc = msm_host->dsc;
> +
> + /* update dsc params with timing params */
> + dsi_dsc_update_pic_dim(dsc, mode->hdisplay, mode->vdisplay);
> + DBG("Mode Width- %d x Height %d\n", dsc->drm->pic_width, 
> dsc->drm->pic_height);

This seems to be pretty non-standard and perhaps unnecessary debug code,
with a stray dash in there.  Is is needed here, and if so how about
using %dx%d\n to format width and height?

> +
> + /* we do the calculations for dsc parameters here so that
> +  * panel can use these parameters
> +  */
> + dsi_populate_dsc_params(dsc);
> +
> + /* Divide the display by 3 but keep back/font porch and
> +  * pulse width same
> +  */

A more general nit on the comments in this patch series: it is
appreciated if comments explain the rationale rather than - or in
addition to - merely paraphrasing the code that follows.

> + h_total -= hdisplay;
> + hdisplay /= 3;
> + h_total += hdisplay;
> + ha_end = ha_start + hdisplay;
> + }
> +
>   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
> + if (msm_host->dsc) {
> + struct msm_display_dsc_config *dsc = msm_host->dsc;
> + u32 reg, intf_width, slice_per_intf;
> + u32 total_bytes_per_intf;
> +
> + /* first calculate dsc parameters and then program
> +  * compress mode registers
> +  */
> + intf_width = hdisplay;
> + slice_per_intf = DIV_ROUND_UP(intf_width, 
> dsc->drm->slice_width);
> +
> + dsc->drm->slice_count = 1;
> + dsc->bytes_in_slice = 
> DIV_ROUND_UP(dsc->drm->slice_width * 8, 8);

If I am not mistaken this is the same 

[PATCH 6/7] drm/amdgpu: Ensure kunmap is called on error

2021-12-10 Thread ira . weiny
From: Ira Weiny 

The default case leaves the buffer object mapped in error.

Add amdgpu_bo_kunmap() to that case to ensure the mapping is cleaned up.

Signed-off-by: Ira Weiny 

---
NOTE: It seems like this function could use a fair bit of refactoring
but this is the easiest way to fix the actual bug.
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 6f8de11a17f1..b3ffd0f6b35f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -889,6 +889,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
return 0;
 
default:
+   amdgpu_bo_kunmap(bo);
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
}
 
-- 
2.31.1



[PATCH 5/7] drm/msm: Alter comment to use kmap_local_page()

2021-12-10 Thread ira . weiny
From: Ira Weiny 

kmap() is being deprecated.  So this comment could be misleading in the
future.

Change this comment to point to using kmap_local_page().  While here
remove 'we' from the comment.

Signed-off-by: Ira Weiny 
---
 drivers/gpu/drm/msm/msm_gem_submit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 282628d6b72c..654ae0d13eaf 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -438,8 +438,8 @@ static int submit_reloc(struct msm_gem_submit *submit, 
struct msm_gem_object *ob
return -EINVAL;
}
 
-   /* For now, just map the entire thing.  Eventually we probably
-* to do it page-by-page, w/ kmap() if not vmap()d..
+   /* For now, just map the entire thing.  Eventually it should probably
+* be done page-by-page, w/ kmap_local_page() if not vmap()d..
 */
ptr = msm_gem_get_vaddr_locked(>base);
 
-- 
2.31.1



[PATCH 3/7] drm/gma: Remove calls to kmap()

2021-12-10 Thread ira . weiny
From: Ira Weiny 

kmap() is being deprecated and these instances are easy to convert to
kmap_local_page().

Furthermore, in gma_crtc_cursor_set() use the memcpy_from_page() helper
instead of an open coded use of kmap_local_page().

Signed-off-by: Ira Weiny 
---
 drivers/gpu/drm/gma500/gma_display.c | 6 ++
 drivers/gpu/drm/gma500/mmu.c | 8 
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gma_display.c 
b/drivers/gpu/drm/gma500/gma_display.c
index cbcecbaa041b..caf7c7b321a9 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -334,7 +334,7 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc,
struct gtt_range *gt;
struct gtt_range *cursor_gt = gma_crtc->cursor_gt;
struct drm_gem_object *obj;
-   void *tmp_dst, *tmp_src;
+   void *tmp_dst;
int ret = 0, i, cursor_pages;
 
/* If we didn't get a handle then turn the cursor off */
@@ -400,9 +400,7 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc,
/* Copy the cursor to cursor mem */
tmp_dst = dev_priv->vram_addr + cursor_gt->offset;
for (i = 0; i < cursor_pages; i++) {
-   tmp_src = kmap(gt->pages[i]);
-   memcpy(tmp_dst, tmp_src, PAGE_SIZE);
-   kunmap(gt->pages[i]);
+   memcpy_from_page(tmp_dst, gt->pages[i], 0, PAGE_SIZE);
tmp_dst += PAGE_SIZE;
}
 
diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c
index fe9ace2a7967..a70b01ccdf70 100644
--- a/drivers/gpu/drm/gma500/mmu.c
+++ b/drivers/gpu/drm/gma500/mmu.c
@@ -184,17 +184,17 @@ struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver 
*driver,
pd->invalid_pte = 0;
}
 
-   v = kmap(pd->dummy_pt);
+   v = kmap_local_page(pd->dummy_pt);
for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
v[i] = pd->invalid_pte;
 
-   kunmap(pd->dummy_pt);
+   kunmap_local(v);
 
-   v = kmap(pd->p);
+   v = kmap_local_page(pd->p);
for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
v[i] = pd->invalid_pde;
 
-   kunmap(pd->p);
+   kunmap_local(v);
 
clear_page(kmap(pd->dummy_page));
kunmap(pd->dummy_page);
-- 
2.31.1



[PATCH 4/7] drm/radeon: Replace kmap() with kmap_local_page()

2021-12-10 Thread ira . weiny
From: Ira Weiny 

kmap() is being deprecated and this usage is local to the thread.  Use
kmap_local_page() instead.

Signed-off-by: Ira Weiny 
---
 drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index 11b21d605584..76d7906e1785 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -907,11 +907,11 @@ static ssize_t radeon_ttm_gtt_read(struct file *f, char 
__user *buf,
 
page = rdev->gart.pages[p];
if (page) {
-   ptr = kmap(page);
+   ptr = kmap_local_page(page);
ptr += off;
 
r = copy_to_user(buf, ptr, cur_size);
-   kunmap(rdev->gart.pages[p]);
+   kunmap_local(ptr);
} else
r = clear_user(buf, cur_size);
 
-- 
2.31.1



[PATCH 7/7] drm/radeon: Ensure kunmap is called on error

2021-12-10 Thread ira . weiny
From: Ira Weiny 

The default case leaves the buffer object mapped in error.

Add radeon_bo_kunmap() to that case to ensure the mapping is cleaned up.

Signed-off-by: Ira Weiny 

---
NOTE: It seems like this function could use a fair bit of refactoring
but this is the easiest way to fix the actual bug.
---
 drivers/gpu/drm/radeon/radeon_uvd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c 
b/drivers/gpu/drm/radeon/radeon_uvd.c
index 2ea86919d953..7462010e0e6d 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -563,6 +563,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, 
struct radeon_bo *bo,
 
default:
 
+   radeon_bo_kunmap(bo);
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
return -EINVAL;
}
-- 
2.31.1



[PATCH 0/7] DRM kmap() fixes and kmap_local_page() conversions

2021-12-10 Thread ira . weiny
From: Ira Weiny 

This series starts by converting the last easy kmap() uses to
kmap_local_page().

There is one more call to kmap() wrapped in ttm_bo_kmap_ttm().  Unfortunately,
ttm_bo_kmap_ttm() is called in a number of different ways including some which
are not thread local.  I have a patch to convert that call.  However, it is not
straight forward so it is not included in this series.

The final 2 patches fix bugs found while working on the ttm_bo_kmap_ttm()
conversion.


Ira Weiny (7):
drm/i915: Replace kmap() with kmap_local_page()
drm/amd: Replace kmap() with kmap_local_page()
drm/gma: Remove calls to kmap()
drm/radeon: Replace kmap() with kmap_local_page()
drm/msm: Alter comment to use kmap_local_page()
drm/amdgpu: Ensure kunmap is called on error
drm/radeon: Ensure kunmap is called on error

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 1 +
drivers/gpu/drm/gma500/gma_display.c | 6 ++
drivers/gpu/drm/gma500/mmu.c | 8 
drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 4 ++--
drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 8 
drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 4 ++--
drivers/gpu/drm/i915/gt/shmem_utils.c | 4 ++--
drivers/gpu/drm/i915/i915_gem.c | 8 
drivers/gpu/drm/i915/i915_gpu_error.c | 4 ++--
drivers/gpu/drm/msm/msm_gem_submit.c | 4 ++--
drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++--
drivers/gpu/drm/radeon/radeon_uvd.c | 1 +
13 files changed, 32 insertions(+), 32 deletions(-)

--
2.31.1



[PATCH 2/7] drm/amd: Replace kmap() with kmap_local_page()

2021-12-10 Thread ira . weiny
From: Ira Weiny 

kmap() is being deprecated.  These maps are thread local and can be
replaced with kmap_local_page().

Replace kmap() with kmap_local_page()

Signed-off-by: Ira Weiny 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index c875f1cdd2af..a3a2c73a44bb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -2281,9 +2281,9 @@ static ssize_t amdgpu_iomem_read(struct file *f, char 
__user *buf,
if (p->mapping != adev->mman.bdev.dev_mapping)
return -EPERM;
 
-   ptr = kmap(p);
+   ptr = kmap_local_page(p);
r = copy_to_user(buf, ptr + off, bytes);
-   kunmap(p);
+   kunmap_local(ptr);
if (r)
return -EFAULT;
 
@@ -2332,9 +2332,9 @@ static ssize_t amdgpu_iomem_write(struct file *f, const 
char __user *buf,
if (p->mapping != adev->mman.bdev.dev_mapping)
return -EPERM;
 
-   ptr = kmap(p);
+   ptr = kmap_local_page(p);
r = copy_from_user(ptr + off, buf, bytes);
-   kunmap(p);
+   kunmap_local(ptr);
if (r)
return -EFAULT;
 
-- 
2.31.1



[PATCH 1/7] drm/i915: Replace kmap() with kmap_local_page()

2021-12-10 Thread ira . weiny
From: Ira Weiny 

kmap() is being deprecated and these usages are all local to the thread
so there is no reason kmap_local_page() can't be used.

Replace kmap() calls with kmap_local_page().

Signed-off-by: Ira Weiny 
---
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c  | 4 ++--
 drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 8 
 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c   | 4 ++--
 drivers/gpu/drm/i915/gt/shmem_utils.c  | 4 ++--
 drivers/gpu/drm/i915/i915_gem.c| 8 
 drivers/gpu/drm/i915/i915_gpu_error.c  | 4 ++--
 6 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index d77da59fae04..fa8b820e14aa 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -597,9 +597,9 @@ i915_gem_object_create_shmem_from_data(struct 
drm_i915_private *dev_priv,
if (err < 0)
goto fail;
 
-   vaddr = kmap(page);
+   vaddr = kmap_local_page(page);
memcpy(vaddr, data, len);
-   kunmap(page);
+   kunmap_local(vaddr);
 
err = pagecache_write_end(file, file->f_mapping,
  offset, len, len,
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 6d30cdfa80f3..e59e1725e29d 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -144,7 +144,7 @@ static int check_partial_mapping(struct drm_i915_gem_object 
*obj,
intel_gt_flush_ggtt_writes(_i915(obj->base.dev)->gt);
 
p = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
-   cpu = kmap(p) + offset_in_page(offset);
+   cpu = kmap_local_page(p) + offset_in_page(offset);
drm_clflush_virt_range(cpu, sizeof(*cpu));
if (*cpu != (u32)page) {
pr_err("Partial view for %lu [%u] (offset=%llu, size=%u [%llu, 
row size %u], fence=%d, tiling=%d, stride=%d) misalignment, expected write to 
page (%llu + %u [0x%llx]) of 0x%x, found 0x%x\n",
@@ -162,7 +162,7 @@ static int check_partial_mapping(struct drm_i915_gem_object 
*obj,
}
*cpu = 0;
drm_clflush_virt_range(cpu, sizeof(*cpu));
-   kunmap(p);
+   kunmap_local(cpu);
 
 out:
__i915_vma_put(vma);
@@ -237,7 +237,7 @@ static int check_partial_mappings(struct 
drm_i915_gem_object *obj,
intel_gt_flush_ggtt_writes(_i915(obj->base.dev)->gt);
 
p = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
-   cpu = kmap(p) + offset_in_page(offset);
+   cpu = kmap_local_page(p) + offset_in_page(offset);
drm_clflush_virt_range(cpu, sizeof(*cpu));
if (*cpu != (u32)page) {
pr_err("Partial view for %lu [%u] (offset=%llu, size=%u 
[%llu, row size %u], fence=%d, tiling=%d, stride=%d) misalignment, expected 
write to page (%llu + %u [0x%llx]) of 0x%x, found 0x%x\n",
@@ -255,7 +255,7 @@ static int check_partial_mappings(struct 
drm_i915_gem_object *obj,
}
*cpu = 0;
drm_clflush_virt_range(cpu, sizeof(*cpu));
-   kunmap(p);
+   kunmap_local(cpu);
if (err)
return err;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
index f8948de72036..743a414f86f3 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
@@ -743,7 +743,7 @@ static void swizzle_page(struct page *page)
char *vaddr;
int i;
 
-   vaddr = kmap(page);
+   vaddr = kmap_local_page(page);
 
for (i = 0; i < PAGE_SIZE; i += 128) {
memcpy(temp, [i], 64);
@@ -751,7 +751,7 @@ static void swizzle_page(struct page *page)
memcpy([i + 64], temp, 64);
}
 
-   kunmap(page);
+   kunmap_local(vaddr);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c 
b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 0683b27a3890..cba4f210d093 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -104,7 +104,7 @@ static int __shmem_rw(struct file *file, loff_t off,
if (IS_ERR(page))
return PTR_ERR(page);
 
-   vaddr = kmap(page);
+   vaddr = kmap_local_page(page);
if (write) {
memcpy(vaddr + offset_in_page(off), ptr, this);
set_page_dirty(page);
@@ -112,7 +112,7 @@ static int __shmem_rw(struct file *file, loff_t off,
memcpy(ptr, vaddr + offset_in_page(off), this);
}
mark_page_accessed(page);
-   

[pull] amdgpu, amdkfd drm-next-5.17

2021-12-10 Thread Alex Deucher
Hi Dave, Daniel,

More stuff for 5.17.

The following changes since commit 70897848730470cc477d5d89e6222c0f6a9ac173:

  drm/amdgpu/display: Only set vblank_disable_immediate when PSR is not enabled 
(2021-12-01 16:00:58 -0500)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-5.17-2021-12-10

for you to fetch changes up to 3c021931023a30316db415044531b116b85e6ebd:

  drm/amdgpu: replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi 
(2021-12-07 13:13:07 -0500)


amd-drm-next-5.17-2021-12-10:

amdgpu:
- warning fixes
- vkms fixes
- Misc code cleanups
- RAS fixes
- IH fixes
- DP to HDMI PCON support
- DSC MST fixes
- LTTPR fixes
- Misc display fixes

amdkfd:
- Misc code cleanups
- Double free fix
- More IP version enumeration changes and cleanups


Alex Deucher (1):
  drm/amdgpu: handle SRIOV VCN revision parsing

Anthony Koo (2):
  drm/amd/display: [FW Promotion] Release 0.0.95
  drm/amd/display: [FW Promotion] Release 0.0.96

Aric Cyr (2):
  drm/amd/display: 3.2.164
  drm/amd/display: Reduce stack usage

Brandon Syu (1):
  drm/amd/display: Fix dual eDP abnormal display issue

Christophe JAILLET (2):
  drm/amdkfd: Use bitmap_zalloc() when applicable
  drm/amdkfd: Slighly optimize 'init_doorbell_bitmap()'

Claudio Suarez (3):
  drm/amdgpu: update drm_display_info correctly when the edid is read
  drm/amdgpu: use drm_edid_get_monitor_name() instead of duplicating the 
code
  drm/amdgpu: replace drm_detect_hdmi_monitor() with 
drm_display_info.is_hdmi

Dale Zhao (1):
  drm/amd/display: add hdmi disable debug check

Darren Powell (2):
  amdgpu/pm: Create shared array of power profile name strings
  amdgpu/pm: Modify implmentations of get_power_profile_mode to use 
amdgpu_pp_profile_name

Evgenii Krasnikov (1):
  drm/amd/display: add function for eDP and backlight power on

Fangzhi Zuo (2):
  drm/amd/display: Add DP-HDMI FRL PCON SST Support in DM
  drm/amd/display: Add DP-HDMI FRL PCON Support in DC

Flora Cui (5):
  drm/amdgpu: cancel the correct hrtimer on exit
  drm/amdgpu: fix vkms crtc settings
  drm/amdgpu: check atomic flag to differeniate with legacy path
  drm/amdgpu: drop the critial WARN_ON in amdgpu_vkms
  drm/amdgpu: free vkms_output after use

George Shen (5):
  drm/amd/display: Add vendor specific LTTPR workarounds for DCN31
  drm/amd/display: Skip vendor specific LTTPR w/a outside link training
  drm/amd/display: Add 16ms AUX RD interval W/A for specific LTTPR
  drm/amd/display: Apply LTTPR workarounds to non-transparent mode
  drm/amd/display: Add W/A for PHY tests with certain LTTPR

Graham Sider (3):
  drm/amdkfd: replace asic_name with amdgpu_asic_name
  drm/amdkfd: add kfd_device_info_init function
  drm/amdkfd: remove hardcoded device_info structs

Guchun Chen (2):
  drm/amdgpu: declare static function to fix compiler warning
  drm/amdgpu: fix the missed handling for SDMA2 and SDMA3

Jane Jian (1):
  drm/amdgpu/sriov/vcn: add new vcn ip revision check case for 
SIENNA_CICHLID

Jarif Aftab (1):
  drm/amd/display: Added Check For dc->res_pool

Jiapeng Chong (1):
  drm/amd/display: Fix warning comparing pointer to 0

Jimmy Kizito (1):
  drm/amd/display: Add work around for tunneled MST.

Jude Shih (1):
  drm/amd/display: Move link_enc init logic to DC

Lijo Lazar (3):
  drm/amd/pm: Add warning for unexpected PG requests
  drm/amdgpu: Use MAX_HWIP instead of HW_ID_MAX
  drm/amdgpu: Don't halt RLC on GFX suspend

Lv Ruyi (1):
  drm/amd/display: fix application of sizeof to pointer

Meenakshikumar Somasundaram (2):
  drm/amd/display: Fix for otg synchronization logic
  drm/amd/display: Adding dpia debug bits for hpd delay

Michael Strauss (1):
  drm/amd/display: Add force detile buffer size debug flag

Mikita Lipski (2):
  drm/amd/display: PSR panel capability debugfs
  drm/amd/display: prevent reading unitialized links

Mustapha Ghaddar (1):
  drm/amd/display: Fix for the no Audio bug with Tiled Displays

Nicholas Kazlauskas (4):
  drm/amd/display: Allow DSC on supported MST branch devices
  drm/amd/display: Fix DPIA outbox timeout after S3/S4/reset
  drm/amd/display: Query DMCUB for dp alt status
  drm/amd/display: Fix out of bounds access on DNC31 stream encoder regs

Oliver Logush (1):
  drm/amd/display: Rename a struct field to describe a cea component better

Perry Yuan (1):
  drm/amd/display: add connector type check for CRC source set

Philip Yang (5):
  drm/amdgpu: handle IH ring1 overflow
  drm/amdkfd: set "r = 0" explicitly before goto
  drm/amdkfd: fix double free mem structure
  drm/amdkfd: process_info lock not needed for svm
  drm/amdkfd: err_pin_bo path 

Re: RPI 7" display touch controller

2021-12-10 Thread Tim Harvey
On Fri, Dec 10, 2021 at 11:29 AM Tim Harvey  wrote:
>
> On Fri, Dec 10, 2021 at 10:41 AM Dave Stevenson
>  wrote:
> >
> > On Fri, 10 Dec 2021 at 18:20, Tim Harvey  wrote:
> > >
> > > On Thu, Nov 18, 2021 at 12:52 PM Tim Harvey  wrote:
> > > >
> > > > On Thu, Nov 18, 2021 at 10:30 AM Dave Stevenson
> > > >  wrote:
> > > > >
> > > > > On Thu, 18 Nov 2021 at 17:36, Tim Harvey  
> > > > > wrote:
> > > > > >
> > > > > > On Thu, Nov 18, 2021 at 6:28 AM Dave Stevenson
> > > > > >  wrote:
> > > > > > >
> > > > > > > Hi Tim
> > > > > > >
> > > > > > > On Thu, 18 Nov 2021 at 01:26, Tim Harvey  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > Greetings,
> > > > > > > >
> > > > > > > > I'm trying to get a RPI 7" touchscreen display working on an 
> > > > > > > > IMX8MM
> > > > > > > > board and while I've been able to get the MIPI DSI display and
> > > > > > > > backlight working I still can't seem to figure out the touch
> > > > > > > > controller.
> > > > > > > >
> > > > > > > > It's supposed to have an FT5406 controller on it without an 
> > > > > > > > interrupt
> > > > > > > > so I added polling support 
> > > > > > > > drivers/input/touchscreen/edt-ft5x06.c
> > > > > > > > which I was able to verify using another touchscreen with that
> > > > > > > > controller but when reading data from the FT5406 on the RPI 
> > > > > > > > controller
> > > > > > > > the data does not make sense.
> > > > > > > >
> > > > > > > > These panels appear to route the I2C from the FT5406 to a 
> > > > > > > > STM32F103
> > > > > > > > MPU that then provides a different I2C slave interface to the 
> > > > > > > > 15pin
> > > > > > > > connector that I'm connected to. On that I2C interface I see an 
> > > > > > > > i2c
> > > > > > > > slave at 0x45 which is managed by the regulator driver Marek 
> > > > > > > > wrote
> > > > > > > > (drivers/regulator/rpi-panel-attiny-regulator.c) and there is 
> > > > > > > > also an
> > > > > > > > i2c slave at 0x38 which I assumed was the FT5406 but I believe 
> > > > > > > > the MPU
> > > > > > > > is perhaps obfuscating that touch data.
> > > > > > > >
> > > > > > > > Anyone have any ideas on how to make that touch controller 
> > > > > > > > useful?
> > > > > > >
> > > > > > > There should be nothing unusual. 0x38 is the EDT touch controller.
> > > > > > > Starting with the Raspberry Pi OS Bullseye release, we're now 
> > > > > > > using
> > > > > > > the panel directly from DRM rather than through the firmware. 
> > > > > > > That's
> > > > > > > based on the branch at
> > > > > > > https://github.com/raspberrypi/linux/tree/rpi-5.10.y/
> > > > > > >
> > > > > >
> > > > > > Dave,
> > > > > >
> > > > > > That sounds like the driver that made it into mainline with Eric's
> > > > > > commit 2f733d6194bd ("drm/panel: Add support for the Raspberry Pi 7"
> > > > > > Touchscreen."). I looked there but that driver just deals with the 
> > > > > > DSI
> > > > > > and not with touch.
> > > > >
> > > > > No, we've reverted away from that driver as it exposes no regulator
> > > > > framework either, so again the touch element loses power.
> > > > >
> > > > > > > I also added polling support to edt-ft5x04.c.
> > > > > > > For DT, it uses a combination of the overlays vc4-kms-v3d,
> > > > > > > vc4-kms-dsi-7inch, and that includes edt-ft5406.dtsi, all of 
> > > > > > > which are
> > > > > > > in /arch/arm/boot/dts/overlays
> > > > > >
> > > > > > It doesn't look like you ever submitted your edt-ft5x04 polling mode
> > > > > > support upstream. I saw another series to add polling support
> > > > > > submitted by Nicolas back in 2019 but was never followed up on
> > > > > > (https://patchwork.kernel.org/project/linux-input/list/?series=112187=both).
> > > > >
> > > > > No I haven't as it's been crazy trying to get this lot to work under
> > > > > KMS at all over the last couple of months.
> > > > >
> > > > > > I have updated Nicolas' patch with the changes requested and am 
> > > > > > happy
> > > > > > to submit it upstream. The benefit of his patch is that it uses a dt
> > > > > > binding for the polling interval. I'm happy to submit this upstream.
> > > > >
> > > > > I hadn't seen Nicolas' patches, hence implementing it myself.
> > > > >
> > > > > If you've implemented the requested changes, could you check that the
> > > > > polling rate is as expected? We were seeing that the input framework
> > > > > wasn't delivering the requested poll rate when CONFIG_HZ=100 is
> > > > > defined in the config. I must confess that I haven't checked it on my
> > > > > current patch, but it was on my list of things to do.
> > > > > There was a report that "bd88ce25335d Input: raspberrypi-ts - switch
> > > > > to using polled mode of input devices" dropped the polling rate from
> > > > > the desired 60Hz in switching to that framework.
> > > >
> > > > Ok, I'll make a note to test that and submit it.
> > > >
> > > > >
> > > > > > >
> > > > > > > The main issue I had was configuring the regulator framework
> > > > > > > 

Re: [PATCH v4 0/6] Expand display core documentation

2021-12-10 Thread Rodrigo Siqueira Jordao




On 2021-12-09 4:04 p.m., Yann Dirson wrote:



Thanks for this. It's really good to see this.

Reviewed-by: Harry Wentland 


Hearfully seconded, let's get this rolling :)

Reviewed-by: Yann Dirson 


Series applied to amd-staging-drm-next

Thanks a lot!



Harry

On 2021-12-09 09:20, Rodrigo Siqueira wrote:

Display Core (DC) is one of the components under amdgpu, and it has
multiple features directly related to the KMS API. Unfortunately,
we
don't have enough documentation about DC in the upstream, which
makes
the life of some external contributors a little bit more
challenging.
For these reasons, this patchset reworks part of the DC
documentation
and introduces a new set of details on how the display core works
on DCN
IP. Another improvement that this documentation effort tries to
bring is
making explicit some of our hardware-specific details to guide
user-space developers better.

In my view, it is easier to review this series if you apply it in
your
local kernel and build the HTML version (make htmldocs). I'm
suggesting
this approach because I added a few SVG diagrams that will be
easier to
see in the HTML version. If you cannot build the documentation, try
to
open the SVG images while reviewing the content. In summary, in
this
series, you will find:

1. Patch 1: Re-arrange of display core documentation. This is
preparation work for the other patches, but it is also a way to
expand
this documentation.
2. Patch 2 to 4: Document some common debug options related to
display.
3. Patch 5: This patch provides an overview of how our display core
next
works and a brief explanation of each component.
4. Patch 6: We use a lot of acronyms in our driver; for this
reason, we
exposed a glossary with common terms used by display core.

Please let us know what you think we can improve this series and
what
kind of content you want to see for the next series.

Changes since V3:
  - Add new acronyms to amdgpu glossary
  - Add link between dc and amdgpu glossary
Changes since V2:
  - Add a comment about MMHUBBUB
Changes since V1:
  - Group amdgpu documentation together.
  - Create index pages.
  - Mirror display folder in the documentation.
  - Divide glossary based on driver context.
  - Make terms more consistent and update CPLIB
  - Add new acronyms to the glossary

Thanks
Siqueira

Rodrigo Siqueira (6):
   Documentation/gpu: Reorganize DC documentation
   Documentation/gpu: Document amdgpu_dm_visual_confirm debugfs
   entry
   Documentation/gpu: Document pipe split visual confirmation
   Documentation/gpu: How to collect DTN log
   Documentation/gpu: Add basic overview of DC pipeline
   Documentation/gpu: Add amdgpu and dc glossary

  Documentation/gpu/amdgpu-dc.rst   |   74 --
  Documentation/gpu/amdgpu/amdgpu-glossary.rst  |   87 ++
  .../gpu/amdgpu/display/config_example.svg |  414 ++
  Documentation/gpu/amdgpu/display/dc-debug.rst |   77 ++
  .../gpu/amdgpu/display/dc-glossary.rst|  237 
  .../amdgpu/display/dc_pipeline_overview.svg   | 1125
  +
  .../gpu/amdgpu/display/dcn-overview.rst   |  171 +++
  .../gpu/amdgpu/display/display-manager.rst|   42 +
  .../gpu/amdgpu/display/global_sync_vblank.svg |  485 +++
  Documentation/gpu/amdgpu/display/index.rst|   29 +
  .../gpu/{amdgpu.rst => amdgpu/index.rst}  |   25 +-
  Documentation/gpu/drivers.rst |3 +-
  12 files changed, 2690 insertions(+), 79 deletions(-)
  delete mode 100644 Documentation/gpu/amdgpu-dc.rst
  create mode 100644 Documentation/gpu/amdgpu/amdgpu-glossary.rst
  create mode 100644
  Documentation/gpu/amdgpu/display/config_example.svg
  create mode 100644 Documentation/gpu/amdgpu/display/dc-debug.rst
  create mode 100644
  Documentation/gpu/amdgpu/display/dc-glossary.rst
  create mode 100644
  Documentation/gpu/amdgpu/display/dc_pipeline_overview.svg
  create mode 100644
  Documentation/gpu/amdgpu/display/dcn-overview.rst
  create mode 100644
  Documentation/gpu/amdgpu/display/display-manager.rst
  create mode 100644
  Documentation/gpu/amdgpu/display/global_sync_vblank.svg
  create mode 100644 Documentation/gpu/amdgpu/display/index.rst
  rename Documentation/gpu/{amdgpu.rst => amdgpu/index.rst} (95%)








[Patch v2] drm/amdgpu: Don't inherit GEM object VMAs in child process

2021-12-10 Thread Rajneesh Bhardwaj
When an application having open file access to a node forks, its shared
mappings also get reflected in the address space of child process even
though it cannot access them with the object permissions applied. With the
existing permission checks on the gem objects, it might be reasonable to
also create the VMAs with VM_DONTCOPY flag so a user space application
doesn't need to explicitly call the madvise(addr, len, MADV_DONTFORK)
system call to prevent the pages in the mapped range to appear in the
address space of the child process. It also prevents the memory leaks
due to additional reference counts on the mapped BOs in the child
process that prevented freeing the memory in the parent for which we had
worked around earlier in the user space inside the thunk library.

Additionally, we faced this issue when using CRIU to checkpoint restore
an application that had such inherited mappings in the child which
confuse CRIU when it mmaps on restore. Having this flag set for the
render node VMAs helps. VMAs mapped via KFD already take care of this so
this is needed only for the render nodes.

To limit the impact of the change to user space consumers such as OpenGL
etc, limit it to KFD BOs only.

Cc: Felix Kuehling 

Signed-off-by: David Yat Sin 
Signed-off-by: Rajneesh Bhardwaj 
---

Changes in v2:
 * Addressed Christian's concerns for user space impact
 * Further reduced the scope to KFD BOs only

 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a224b5295edd..64a7931eda8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -263,6 +263,9 @@ static int amdgpu_gem_object_mmap(struct drm_gem_object 
*obj, struct vm_area_str
!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
vma->vm_flags &= ~VM_MAYWRITE;
 
+   if (bo->kfd_bo)
+   vma->vm_flags |= VM_DONTCOPY;
+
return drm_gem_ttm_mmap(obj, vma);
 }
 
-- 
2.17.1



Re: [PATCH v5 7/7] dt-bindings:ast2600-clock Add CRT reset define

2021-12-10 Thread Rob Herring
On Wed, 08 Dec 2021 09:33:37 +0800, Tommy Haung wrote:
> Add new CRT reset define for ast2600.
> 
> Reported-by: kernel test robot 
> Signed-off-by: Tommy Haung 
> ---
>  include/dt-bindings/clock/ast2600-clock.h | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring 


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

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

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

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

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

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

Cc: Peter Zijlstra 
Signed-off-by: Sebastian Andrzej Siewior 
Acked-by: Daniel Vetter 
---
v1…v2:
 - Add commit 6dcb85a0ad990 as reference.
 - Name the bit CONTEXT_IS_PARKING.

 drivers/gpu/drm/i915/gt/intel_context.h   |  3 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |  1 +
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 38 +--
 drivers/gpu/drm/i915/i915_request.h   |  3 +-
 4 files changed, 7 insertions(+), 38 deletions(-)

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

Re: [PATCH v11 3/8] dt-bindings: display: Add ingenic, jz4780-dw-hdmi DT Schema

2021-12-10 Thread Paul Cercueil

Hi Nikolaus,

Le ven., déc. 10 2021 at 10:53:18 -0600, Rob Herring  
a écrit :

On Thu, Dec 02, 2021 at 07:39:48PM +0100, H. Nikolaus Schaller wrote:

 From: Sam Ravnborg 

 Add DT bindings for the hdmi driver for the Ingenic JZ4780 SoC.
 Based on .txt binding from Zubair Lutfullah Kakakhel

 We also add generic ddc-i2c-bus to synopsys,dw-hdmi.yaml

 Signed-off-by: Sam Ravnborg 
 Signed-off-by: H. Nikolaus Schaller 
 Cc: Rob Herring 
 Cc: devicet...@vger.kernel.org
 ---
  .../display/bridge/ingenic,jz4780-hdmi.yaml   | 78 
+++

  .../display/bridge/synopsys,dw-hdmi.yaml  |  3 +
  2 files changed, 81 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml


 diff --git 
a/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml 
b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml

 new file mode 100644
 index 0..49ae1130efded
 --- /dev/null
 +++ 
b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml

 @@ -0,0 +1,78 @@
 +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
 +%YAML 1.2
 +---
 +$id: 
http://devicetree.org/schemas/display/bridge/ingenic,jz4780-hdmi.yaml#

 +$schema: http://devicetree.org/meta-schemas/core.yaml#
 +
 +title: Bindings for Ingenic JZ4780 HDMI Transmitter
 +
 +maintainers:
 +  - H. Nikolaus Schaller 
 +
 +description: |
 +  The HDMI Transmitter in the Ingenic JZ4780 is a Synopsys 
DesignWare HDMI 1.4

 +  TX controller IP with accompanying PHY IP.
 +
 +allOf:
 +  - $ref: synopsys,dw-hdmi.yaml#
 +
 +properties:
 +  compatible:
 +const: ingenic,jz4780-dw-hdmi
 +
 +  reg-io-width:
 +const: 4
 +
 +  clocks:
 +maxItems: 2
 +
 +  hdmi-5v-supply:
 +description: regulator to provide +5V at the connector


Being part of the connector, that belongs in a connector node.


I believe that means adding .atomic_{enable,disable} callbacks to the 
display-connector bridge (drivers/gpu/drm/bridge/display-connector.c) 
which would enable/disable the regulator.


Unless it messes up with e.g. cable detection (which I believe requires 
the regulator to be enabled), in that case unconditionally enable it in 
the connector's probe function.



 +
 +  ports:
 +$ref: /schemas/graph.yaml#/properties/ports


You need to define what each 'port' node is.


Have a look at 
Documentation/devicetree/bindings/display/ingenic,lcd.yaml for an 
example on how to do this.



 +
 +required:
 +  - compatible
 +  - clocks
 +  - clock-names
 +  - hdmi-5v-supply
 +  - ports
 +  - reg-io-width
 +
 +unevaluatedProperties: false
 +
 +examples:
 +  - |
 +#include 
 +
 +hdmi: hdmi@1018 {
 +compatible = "ingenic,jz4780-dw-hdmi";
 +reg = <0x1018 0x8000>;
 +reg-io-width = <4>;
 +ddc-i2c-bus = <>;
 +interrupt-parent = <>;
 +interrupts = <3>;
 +clocks = < JZ4780_CLK_AHB0>, < JZ4780_CLK_HDMI>;
 +clock-names = "iahb", "isfr";
 +hdmi-5v-supply = <_power>;
 +
 +ports {
 +#address-cells = <1>;
 +#size-cells = <0>;
 +hdmi_in: port@0 {
 +reg = <0>;
 +dw_hdmi_in: endpoint {
 +remote-endpoint = <_lcd_out>;
 +};
 +};
 +hdmi_out: port@1 {
 +reg = <1>;
 +dw_hdmi_out: endpoint {
 +remote-endpoint = <_con>;
 +};
 +};
 +};
 +};
 +
 +...
 diff --git 
a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml

 index 9be44a682e67a..9cbeabaee0968 100644
 --- 
a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
 +++ 
b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml

 @@ -50,6 +50,9 @@ properties:
interrupts:
  maxItems: 1

 +  ddc-i2c-bus:
 +description: An I2C interface if the internal DDC I2C driver 
is not to be used


That too is already defined to be part of the connector node.


Just remove the property then, since you don't use it in the ci20 
bindings.


Cheers,
-Paul


 +
  additionalProperties: true

  ...
 --
 2.33.0







[PATCH 2/2] platform/chrome: Add driver for ChromeOS privacy-screen

2021-12-10 Thread Rajat Jain
This adds the ACPI driver for the ChromeOS privacy screen that is
present on some chromeos devices.

Note that I found that ACPI drivers are bound to their devices AFTER
the drm probe. So on chromebooks with privacy-screen, this causes a
probe deferral for i915 driver, which results in a delay of about 250ms
in my experiments. However, per my personal experience, it did not
result in any user perceived delay of splash screen
(https://hansdegoede.livejournal.com/25948.html)

In future if this probe deferral turns out to be an issue, we can
consider turning this ACPI driver into something that is probed earlier
than the drm drivers.

Signed-off-by: Rajat Jain 
---
This patch is rebased on top of linux-next/master

 drivers/platform/chrome/Kconfig  |  10 ++
 drivers/platform/chrome/Makefile |   1 +
 drivers/platform/chrome/chromeos_priv_scrn.c | 133 +++
 3 files changed, 144 insertions(+)
 create mode 100644 drivers/platform/chrome/chromeos_priv_scrn.c

diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index ccc23d8686e8..3f874bbd3d03 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -243,6 +243,16 @@ config CROS_USBPD_NOTIFY
  To compile this driver as a module, choose M here: the
  module will be called cros_usbpd_notify.
 
+config CHROMEOS_PRIVACY_SCREEN
+   bool "ChromeOS Privacy Screen support"
+   depends on ACPI
+   depends on DRM
+   default n
+   select DRM_PRIVACY_SCREEN
+   help
+ This driver provides the support needed for the in-built electronic
+ privacy screen that is present on some ChromeOS devices.
+
 source "drivers/platform/chrome/wilco_ec/Kconfig"
 
 endif # CHROMEOS_PLATFORMS
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index f901d2e43166..cfa0bb4e9e34 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -4,6 +4,7 @@
 CFLAGS_cros_ec_trace.o:=   -I$(src)
 
 obj-$(CONFIG_CHROMEOS_LAPTOP)  += chromeos_laptop.o
+obj-$(CONFIG_CHROMEOS_PRIVACY_SCREEN)  += chromeos_priv_scrn.o
 obj-$(CONFIG_CHROMEOS_PSTORE)  += chromeos_pstore.o
 obj-$(CONFIG_CHROMEOS_TBMC)+= chromeos_tbmc.o
 obj-$(CONFIG_CROS_EC)  += cros_ec.o
diff --git a/drivers/platform/chrome/chromeos_priv_scrn.c 
b/drivers/platform/chrome/chromeos_priv_scrn.c
new file mode 100644
index ..00536154acd6
--- /dev/null
+++ b/drivers/platform/chrome/chromeos_priv_scrn.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ *  chromeos_priv_scrn.c - ChromeOS Privacy Screen support
+ *
+ * Copyright (C) 2022 The Chromium OS Authors
+ *
+ */
+
+#include 
+#include 
+
+/*
+ * The DSM (Define Specific Method) constants below are the agreed API with
+ * the firmware team, on how to control privacy screen using ACPI methods.
+ */
+#define PRIV_SCRN_DSM_REVID1   /* DSM version */
+#define PRIV_SCRN_DSM_FN_GET_STATUS1   /* Get privacy screen status */
+#define PRIV_SCRN_DSM_FN_ENABLE2   /* Enable privacy 
screen */
+#define PRIV_SCRN_DSM_FN_DISABLE   3   /* Disable privacy screen */
+
+static const guid_t chromeos_priv_scrn_dsm_guid =
+   GUID_INIT(0xc7033113, 0x8720, 0x4ceb,
+ 0x90, 0x90, 0x9d, 0x52, 0xb3, 0xe5, 0x2d, 0x73);
+
+static void
+chromeos_priv_scrn_get_hw_state(struct drm_privacy_screen *drm_priv_scrn)
+{
+   union acpi_object *obj;
+   acpi_handle handle;
+   struct device *priv_scrn = drm_priv_scrn->dev.parent;
+
+   if (!priv_scrn)
+   return;
+
+   handle = acpi_device_handle(to_acpi_device(priv_scrn));
+   obj = acpi_evaluate_dsm(handle, _priv_scrn_dsm_guid,
+   PRIV_SCRN_DSM_REVID,
+   PRIV_SCRN_DSM_FN_GET_STATUS, NULL);
+   if (!obj) {
+   dev_err(priv_scrn, "_DSM failed to get privacy-screen state\n");
+   return;
+   }
+
+   if (obj->type != ACPI_TYPE_INTEGER)
+   dev_err(priv_scrn, "Bad _DSM to get privacy-screen state\n");
+   else if (obj->integer.value == 1)
+   drm_priv_scrn->hw_state = drm_priv_scrn->sw_state =
+   PRIVACY_SCREEN_ENABLED;
+   else
+   drm_priv_scrn->hw_state = drm_priv_scrn->sw_state =
+   PRIVACY_SCREEN_DISABLED;
+
+   ACPI_FREE(obj);
+}
+
+static int
+chromeos_priv_scrn_set_sw_state(struct drm_privacy_screen *drm_priv_scrn,
+   enum drm_privacy_screen_status state)
+{
+   union acpi_object *obj = NULL;
+   acpi_handle handle;
+   struct device *priv_scrn = drm_priv_scrn->dev.parent;
+
+   if (!priv_scrn)
+   return -ENODEV;
+
+   handle = acpi_device_handle(to_acpi_device(priv_scrn));
+
+   if (state == PRIVACY_SCREEN_DISABLED) {
+ 

[PATCH 1/2] drm/privacy_screen_x86: Add entry for ChromeOS privacy-screen

2021-12-10 Thread Rajat Jain
Add a static entry in the x86 table, to detect and wait for
privacy-screen on some ChromeOS platforms.

Please note that this means that if CONFIG_CHROMEOS_PRIVACY_SCREEN is
enabled, and if "GOOG0010" device is found in ACPI, then the i915 probe
shall return EPROBE_DEFER until a platform driver actually registers the
privacy-screen: https://hansdegoede.livejournal.com/25948.html

Signed-off-by: Rajat Jain 
---
This patch is rebased on top of linux-next/master

 drivers/gpu/drm/drm_privacy_screen_x86.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/drm_privacy_screen_x86.c 
b/drivers/gpu/drm/drm_privacy_screen_x86.c
index a2cafb294ca6..3728870a98e7 100644
--- a/drivers/gpu/drm/drm_privacy_screen_x86.c
+++ b/drivers/gpu/drm/drm_privacy_screen_x86.c
@@ -45,6 +45,17 @@ static bool __init detect_thinkpad_privacy_screen(void)
 
return (output & 0x1) ? true : false;
 }
+#elif IS_ENABLED(CONFIG_CHROMEOS_PRIVACY_SCREEN)
+
+static bool __init detect_chromeos_privacy_screen(void)
+{
+   if (!acpi_dev_present("GOOG0010", NULL, -1))
+   return false;
+
+   pr_info("%s: Need to wait for ChromeOS privacy-screen", __func__);
+   return true;
+
+}
 #endif
 
 static const struct arch_init_data arch_init_data[] __initconst = {
@@ -57,6 +68,15 @@ static const struct arch_init_data arch_init_data[] 
__initconst = {
},
.detect = detect_thinkpad_privacy_screen,
},
+#elif IS_ENABLED(CONFIG_CHROMEOS_PRIVACY_SCREEN)
+   {
+   .lookup = {
+   .dev_id = NULL,
+   .con_id = NULL,
+   .provider = "privacy_screen-GOOG0010:00",
+   },
+   .detect = detect_chromeos_privacy_screen,
+   },
 #endif
 };
 
-- 
2.34.1.173.g76aa8bc2d0-goog



Re: [git pull] drm fixes for 5.16-rc5

2021-12-10 Thread pr-tracker-bot
The pull request you sent on Fri, 10 Dec 2021 14:28:53 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2021-12-10

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/9b302ffe4e8d7e62f3170aa0097ff979880ba61d

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


[PATCH] drm/i915/ttm: fix large buffer population trucation

2021-12-10 Thread Robert Beckett
ttm->num_pages is uint32_t which was causing very large buffers to
only populate a truncated size.

This fixes gem_create@create-clear igt test on large memory systems.

Fixes: 7ae034590cea ("drm/i915/ttm: add tt shmem backend")
Signed-off-by: Robert Beckett 
---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 218a9b3037c7..923cc7ad8d70 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -166,7 +166,7 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device 
*bdev,
struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
const unsigned int max_segment = i915_sg_segment_size();
-   const size_t size = ttm->num_pages << PAGE_SHIFT;
+   const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
struct file *filp = i915_tt->filp;
struct sgt_iter sgt_iter;
struct sg_table *st;
-- 
2.25.1



Re: RPI 7" display touch controller

2021-12-10 Thread Tim Harvey
On Fri, Dec 10, 2021 at 10:41 AM Dave Stevenson
 wrote:
>
> On Fri, 10 Dec 2021 at 18:20, Tim Harvey  wrote:
> >
> > On Thu, Nov 18, 2021 at 12:52 PM Tim Harvey  wrote:
> > >
> > > On Thu, Nov 18, 2021 at 10:30 AM Dave Stevenson
> > >  wrote:
> > > >
> > > > On Thu, 18 Nov 2021 at 17:36, Tim Harvey  wrote:
> > > > >
> > > > > On Thu, Nov 18, 2021 at 6:28 AM Dave Stevenson
> > > > >  wrote:
> > > > > >
> > > > > > Hi Tim
> > > > > >
> > > > > > On Thu, 18 Nov 2021 at 01:26, Tim Harvey  
> > > > > > wrote:
> > > > > > >
> > > > > > > Greetings,
> > > > > > >
> > > > > > > I'm trying to get a RPI 7" touchscreen display working on an 
> > > > > > > IMX8MM
> > > > > > > board and while I've been able to get the MIPI DSI display and
> > > > > > > backlight working I still can't seem to figure out the touch
> > > > > > > controller.
> > > > > > >
> > > > > > > It's supposed to have an FT5406 controller on it without an 
> > > > > > > interrupt
> > > > > > > so I added polling support drivers/input/touchscreen/edt-ft5x06.c
> > > > > > > which I was able to verify using another touchscreen with that
> > > > > > > controller but when reading data from the FT5406 on the RPI 
> > > > > > > controller
> > > > > > > the data does not make sense.
> > > > > > >
> > > > > > > These panels appear to route the I2C from the FT5406 to a 
> > > > > > > STM32F103
> > > > > > > MPU that then provides a different I2C slave interface to the 
> > > > > > > 15pin
> > > > > > > connector that I'm connected to. On that I2C interface I see an 
> > > > > > > i2c
> > > > > > > slave at 0x45 which is managed by the regulator driver Marek wrote
> > > > > > > (drivers/regulator/rpi-panel-attiny-regulator.c) and there is 
> > > > > > > also an
> > > > > > > i2c slave at 0x38 which I assumed was the FT5406 but I believe 
> > > > > > > the MPU
> > > > > > > is perhaps obfuscating that touch data.
> > > > > > >
> > > > > > > Anyone have any ideas on how to make that touch controller useful?
> > > > > >
> > > > > > There should be nothing unusual. 0x38 is the EDT touch controller.
> > > > > > Starting with the Raspberry Pi OS Bullseye release, we're now using
> > > > > > the panel directly from DRM rather than through the firmware. That's
> > > > > > based on the branch at
> > > > > > https://github.com/raspberrypi/linux/tree/rpi-5.10.y/
> > > > > >
> > > > >
> > > > > Dave,
> > > > >
> > > > > That sounds like the driver that made it into mainline with Eric's
> > > > > commit 2f733d6194bd ("drm/panel: Add support for the Raspberry Pi 7"
> > > > > Touchscreen."). I looked there but that driver just deals with the DSI
> > > > > and not with touch.
> > > >
> > > > No, we've reverted away from that driver as it exposes no regulator
> > > > framework either, so again the touch element loses power.
> > > >
> > > > > > I also added polling support to edt-ft5x04.c.
> > > > > > For DT, it uses a combination of the overlays vc4-kms-v3d,
> > > > > > vc4-kms-dsi-7inch, and that includes edt-ft5406.dtsi, all of which 
> > > > > > are
> > > > > > in /arch/arm/boot/dts/overlays
> > > > >
> > > > > It doesn't look like you ever submitted your edt-ft5x04 polling mode
> > > > > support upstream. I saw another series to add polling support
> > > > > submitted by Nicolas back in 2019 but was never followed up on
> > > > > (https://patchwork.kernel.org/project/linux-input/list/?series=112187=both).
> > > >
> > > > No I haven't as it's been crazy trying to get this lot to work under
> > > > KMS at all over the last couple of months.
> > > >
> > > > > I have updated Nicolas' patch with the changes requested and am happy
> > > > > to submit it upstream. The benefit of his patch is that it uses a dt
> > > > > binding for the polling interval. I'm happy to submit this upstream.
> > > >
> > > > I hadn't seen Nicolas' patches, hence implementing it myself.
> > > >
> > > > If you've implemented the requested changes, could you check that the
> > > > polling rate is as expected? We were seeing that the input framework
> > > > wasn't delivering the requested poll rate when CONFIG_HZ=100 is
> > > > defined in the config. I must confess that I haven't checked it on my
> > > > current patch, but it was on my list of things to do.
> > > > There was a report that "bd88ce25335d Input: raspberrypi-ts - switch
> > > > to using polled mode of input devices" dropped the polling rate from
> > > > the desired 60Hz in switching to that framework.
> > >
> > > Ok, I'll make a note to test that and submit it.
> > >
> > > >
> > > > > >
> > > > > > The main issue I had was configuring the regulator framework
> > > > > > appropriately to allow the touch controller power to be separate 
> > > > > > from
> > > > > > the bridge power. Without that if DRM powered down the panel it 
> > > > > > killed
> > > > > > the touch controller too, and the touch driver never reinitialised
> > > > > > itself.
> > > > >
> > > > > I'm using the same drivers/regulator/rpi-panel-attiny-regulator.c
> > > > > 

[PATCH v2 4/4] drm: exynos: dsi: Switch to atomic funcs

2021-12-10 Thread Jagan Teki
The new support drm bridges are moving towards atomic functions.

Replace atomic version of functions to continue the transition
to the atomic API.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- new patch 

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 37ad94b563c4..f2c12a356952 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1372,7 +1372,8 @@ static void exynos_dsi_unregister_te_irq(struct 
exynos_dsi *dsi)
}
 }
 
-static void exynos_dsi_enable(struct drm_bridge *bridge)
+static void exynos_dsi_atomic_enable(struct drm_bridge *bridge,
+struct drm_bridge_state *old_bridge_state)
 {
struct exynos_dsi *dsi = bridge_to_dsi(bridge);
const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
@@ -1390,19 +1391,20 @@ static void exynos_dsi_enable(struct drm_bridge *bridge)
dsi->state |= DSIM_STATE_ENABLED;
 
if (dsi->out_bridge)
-   funcs->pre_enable(dsi->out_bridge);
+   funcs->atomic_pre_enable(dsi->out_bridge, old_bridge_state);
 
exynos_dsi_set_display_mode(bridge);
exynos_dsi_set_display_enable(dsi, true);
 
if (dsi->out_bridge)
-   funcs->enable(dsi->out_bridge);
+   funcs->atomic_enable(dsi->out_bridge, old_bridge_state);
 
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
return;
 }
 
-static void exynos_dsi_disable(struct drm_bridge *bridge)
+static void exynos_dsi_atomic_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
 {
struct exynos_dsi *dsi = bridge_to_dsi(bridge);
const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
@@ -1413,12 +1415,12 @@ static void exynos_dsi_disable(struct drm_bridge 
*bridge)
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
if (dsi->out_bridge)
-   funcs->disable(dsi->out_bridge);
+   funcs->atomic_disable(dsi->out_bridge, old_bridge_state);
 
exynos_dsi_set_display_enable(dsi, false);
 
if (dsi->out_bridge)
-   funcs->post_disable(dsi->out_bridge);
+   funcs->atomic_post_disable(dsi->out_bridge, old_bridge_state);
 
dsi->state &= ~DSIM_STATE_ENABLED;
pm_runtime_put_sync(dsi->dev);
@@ -1433,8 +1435,11 @@ static int exynos_dsi_attach(struct drm_bridge *bridge,
 }
 
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
-   .enable = exynos_dsi_enable,
-   .disable= exynos_dsi_disable,
+   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+   .atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
+   .atomic_reset   = drm_atomic_helper_bridge_reset,
+   .atomic_enable  = exynos_dsi_atomic_enable,
+   .atomic_disable = exynos_dsi_atomic_disable,
.attach = exynos_dsi_attach,
 };
 
@@ -1605,7 +1610,7 @@ static void exynos_dsi_unbind(struct device *dev, struct 
device *master,
 {
struct exynos_dsi *dsi = dev_get_drvdata(dev);
 
-   exynos_dsi_disable(>bridge);
+   exynos_dsi_atomic_disable(>bridge, NULL);
 
mipi_dsi_host_unregister(>dsi_host);
 }
-- 
2.25.1



[PATCH v2 3/4] drm: exynos: dsi: Convert to bridge driver

2021-12-10 Thread Jagan Teki
Convert the encoders to bridge drivers in order to standardize on
a single API with built-in dumb encoder support for compatibility
with existing component drivers.

Driver bridge conversion will help to reuse the same bridge on
different platforms as exynos dsi driver can be used as a Samsung
DSIM and use it for i.MX8MM platform.

Bridge conversion,

- Drops drm_encoder_helper_funcs, bridge_chain.

- Adds drm_bridge_funcs and register a drm bridge.

Convert it.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- drop bridge_chain

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 84 +
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 8c6f7ac82822..37ad94b563c4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,7 +254,7 @@ struct exynos_dsi_driver_data {
 struct exynos_dsi {
struct drm_encoder encoder;
struct mipi_dsi_host dsi_host;
-   struct list_head bridge_chain;
+   struct drm_bridge bridge;
struct drm_bridge *out_bridge;
struct device *dev;
 
@@ -284,9 +284,9 @@ struct exynos_dsi {
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
+static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
-   return container_of(e, struct exynos_dsi, encoder);
+   return container_of(b, struct exynos_dsi, bridge);
 }
 
 enum reg_idx {
@@ -877,9 +877,10 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
return 0;
 }
 
-static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
+static void exynos_dsi_set_display_mode(struct drm_bridge *bridge)
 {
-   struct drm_display_mode *m = >encoder.crtc->state->adjusted_mode;
+   struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+   struct drm_display_mode *m = 
>encoder->crtc->state->adjusted_mode;
unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
u32 reg;
 
@@ -1371,10 +1372,10 @@ static void exynos_dsi_unregister_te_irq(struct 
exynos_dsi *dsi)
}
 }
 
-static void exynos_dsi_enable(struct drm_encoder *encoder)
+static void exynos_dsi_enable(struct drm_bridge *bridge)
 {
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
-   struct drm_bridge *iter;
+   struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+   const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
int ret;
 
if (dsi->state & DSIM_STATE_ENABLED)
@@ -1388,52 +1389,53 @@ static void exynos_dsi_enable(struct drm_encoder 
*encoder)
 
dsi->state |= DSIM_STATE_ENABLED;
 
-   list_for_each_entry_reverse(iter, >bridge_chain, chain_node) {
-   if (iter->funcs->pre_enable)
-   iter->funcs->pre_enable(iter);
-   }
+   if (dsi->out_bridge)
+   funcs->pre_enable(dsi->out_bridge);
 
-   exynos_dsi_set_display_mode(dsi);
+   exynos_dsi_set_display_mode(bridge);
exynos_dsi_set_display_enable(dsi, true);
 
-   list_for_each_entry(iter, >bridge_chain, chain_node) {
-   if (iter->funcs->enable)
-   iter->funcs->enable(iter);
-   }
+   if (dsi->out_bridge)
+   funcs->enable(dsi->out_bridge);
 
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
return;
 }
 
-static void exynos_dsi_disable(struct drm_encoder *encoder)
+static void exynos_dsi_disable(struct drm_bridge *bridge)
 {
-   struct exynos_dsi *dsi = encoder_to_dsi(encoder);
-   struct drm_bridge *iter;
+   struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+   const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
 
if (!(dsi->state & DSIM_STATE_ENABLED))
return;
 
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-   list_for_each_entry_reverse(iter, >bridge_chain, chain_node) {
-   if (iter->funcs->disable)
-   iter->funcs->disable(iter);
-   }
+   if (dsi->out_bridge)
+   funcs->disable(dsi->out_bridge);
 
exynos_dsi_set_display_enable(dsi, false);
 
-   list_for_each_entry(iter, >bridge_chain, chain_node) {
-   if (iter->funcs->post_disable)
-   iter->funcs->post_disable(iter);
-   }
+   if (dsi->out_bridge)
+   funcs->post_disable(dsi->out_bridge);
 
dsi->state &= ~DSIM_STATE_ENABLED;
pm_runtime_put_sync(dsi->dev);
 }
 
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = 
{
-   .enable = exynos_dsi_enable,
-   .disable = exynos_dsi_disable,
+static int exynos_dsi_attach(struct drm_bridge *bridge,
+enum drm_bridge_attach_flags flags)
+{
+   struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+   return drm_bridge_attach(bridge->encoder, 

[PATCH v2 2/4] drm: exynos: dsi: Use drm panel_bridge API

2021-12-10 Thread Jagan Teki
Replace the manual panel handling code by a drm panel_bridge via
devm_drm_of_get_bridge().

Adding panel_bridge handling,

- Drops drm_connector and related operations as drm_bridge_attach
  creates connector during attachment.

- Drops panel pointer and iterate the bridge, so-that it can operate
  the normal bridge and panel_bridge in constitutive callbacks.

This simplifies the driver and allows all components in the display
pipeline to be treated as bridges.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- new patch

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 147 +++-
 1 file changed, 14 insertions(+), 133 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0bb44e476633..8c6f7ac82822 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,8 +254,6 @@ struct exynos_dsi_driver_data {
 struct exynos_dsi {
struct drm_encoder encoder;
struct mipi_dsi_host dsi_host;
-   struct drm_connector connector;
-   struct drm_panel *panel;
struct list_head bridge_chain;
struct drm_bridge *out_bridge;
struct device *dev;
@@ -285,7 +283,6 @@ struct exynos_dsi {
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
-#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
 static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
 {
@@ -1391,42 +1388,21 @@ static void exynos_dsi_enable(struct drm_encoder 
*encoder)
 
dsi->state |= DSIM_STATE_ENABLED;
 
-   if (dsi->panel) {
-   ret = drm_panel_prepare(dsi->panel);
-   if (ret < 0)
-   goto err_put_sync;
-   } else {
-   list_for_each_entry_reverse(iter, >bridge_chain,
-   chain_node) {
-   if (iter->funcs->pre_enable)
-   iter->funcs->pre_enable(iter);
-   }
+   list_for_each_entry_reverse(iter, >bridge_chain, chain_node) {
+   if (iter->funcs->pre_enable)
+   iter->funcs->pre_enable(iter);
}
 
exynos_dsi_set_display_mode(dsi);
exynos_dsi_set_display_enable(dsi, true);
 
-   if (dsi->panel) {
-   ret = drm_panel_enable(dsi->panel);
-   if (ret < 0)
-   goto err_display_disable;
-   } else {
-   list_for_each_entry(iter, >bridge_chain, chain_node) {
-   if (iter->funcs->enable)
-   iter->funcs->enable(iter);
-   }
+   list_for_each_entry(iter, >bridge_chain, chain_node) {
+   if (iter->funcs->enable)
+   iter->funcs->enable(iter);
}
 
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
return;
-
-err_display_disable:
-   exynos_dsi_set_display_enable(dsi, false);
-   drm_panel_unprepare(dsi->panel);
-
-err_put_sync:
-   dsi->state &= ~DSIM_STATE_ENABLED;
-   pm_runtime_put(dsi->dev);
 }
 
 static void exynos_dsi_disable(struct drm_encoder *encoder)
@@ -1439,17 +1415,12 @@ static void exynos_dsi_disable(struct drm_encoder 
*encoder)
 
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-   if (dsi->panel)
-   drm_panel_disable(dsi->panel);
-
list_for_each_entry_reverse(iter, >bridge_chain, chain_node) {
if (iter->funcs->disable)
iter->funcs->disable(iter);
}
 
exynos_dsi_set_display_enable(dsi, false);
-   if (dsi->panel)
-   drm_panel_unprepare(dsi->panel);
 
list_for_each_entry(iter, >bridge_chain, chain_node) {
if (iter->funcs->post_disable)
@@ -1460,70 +1431,6 @@ static void exynos_dsi_disable(struct drm_encoder 
*encoder)
pm_runtime_put_sync(dsi->dev);
 }
 
-static enum drm_connector_status
-exynos_dsi_detect(struct drm_connector *connector, bool force)
-{
-   return connector->status;
-}
-
-static void exynos_dsi_connector_destroy(struct drm_connector *connector)
-{
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-   connector->dev = NULL;
-}
-
-static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
-   .detect = exynos_dsi_detect,
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .destroy = exynos_dsi_connector_destroy,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int exynos_dsi_get_modes(struct drm_connector *connector)
-{
-   struct exynos_dsi *dsi = connector_to_dsi(connector);
-
-   if (dsi->panel)
-   return drm_panel_get_modes(dsi->panel, connector);
-
-   return 0;
-}
-
-static const struct 

[PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers

2021-12-10 Thread Jagan Teki
Trigger the panel operation helpers only if host found the panel.

Add check.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- new patch 

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 8d137857818c..0bb44e476633 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1439,7 +1439,8 @@ static void exynos_dsi_disable(struct drm_encoder 
*encoder)
 
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-   drm_panel_disable(dsi->panel);
+   if (dsi->panel)
+   drm_panel_disable(dsi->panel);
 
list_for_each_entry_reverse(iter, >bridge_chain, chain_node) {
if (iter->funcs->disable)
@@ -1447,7 +1448,8 @@ static void exynos_dsi_disable(struct drm_encoder 
*encoder)
}
 
exynos_dsi_set_display_enable(dsi, false);
-   drm_panel_unprepare(dsi->panel);
+   if (dsi->panel)
+   drm_panel_unprepare(dsi->panel);
 
list_for_each_entry(iter, >bridge_chain, chain_node) {
if (iter->funcs->post_disable)
-- 
2.25.1



[PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge

2021-12-10 Thread Jagan Teki
Updated series about drm bridge conversion of exynos dsi.

Patch 1: panel checker

Patch 2: panel_bridge API

Patch 3: Bridge conversion

Patch 4: Atomic functions

[1] 
https://patchwork.kernel.org/project/dri-devel/cover/20211122070633.89219-1-ja...@amarulasolutions.com/

Any inputs?
Jagan.

Jagan Teki (4):
  drm: exynos: dsi: Check panel for panel helpers
  drm: exynos: dsi: Use drm panel_bridge API
  drm: exynos: dsi: Convert to bridge driver
  drm: exynos: dsi: Switch to atomic funcs

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 208 ++--
 1 file changed, 51 insertions(+), 157 deletions(-)

-- 
2.25.1



Re: Reuse framebuffer after a kexec (amdgpu / efifb)

2021-12-10 Thread Alex Deucher
On Fri, Dec 10, 2021 at 10:24 AM Guilherme G. Piccoli
 wrote:
>
> On 10/12/2021 12:13, Christian König wrote:
> > [...]
> > How about issuing a PCIe reset and re-initializing the ASIC with just
> > the VBIOS?
> >
> > That should be pretty straightforward I think.
> >
> > Christian.
>
>
> Thanks Christian, that'd be perfect! Is it feasible? Per Alex comment,
> we'd need to run atombios commands to reprogram the timings, display
> info, etc...like a small driver would do, a full init.
>

You need the equivalent of a GOP driver or a full GPU driver.  I think
it would be less effort to just fix up any problems amdgpu has when
trying to load after the crash than to write a new mini driver.  By
the time you add everything you'd need, you'd be pretty close to a
full GPU driver.

> Also, what kind of PCIe reset is recommended for this adapter? Like a
> hot reset, powering-off/re-power, FLR or that MODE2 reset present in
> amdgpu code? Remembering this is an APU device.

You'd need to issue the relevant device specific reset sequence.  It
would be a mode2 reset on vangogh, but varies on other asics.  It
would probably be easiest to just fix up the logic in amdgpu to detect
bad GPU state on driver load and do a GPU reset before driver init.
We already have the logic in place for some dGPUs, but APUs only
recently got full GPU reset support due to architectural limitations
and hardware bugs.

Alex


Re: Reuse framebuffer after a kexec (amdgpu / efifb)

2021-12-10 Thread Alex Deucher
On Fri, Dec 10, 2021 at 9:25 AM Guilherme G. Piccoli
 wrote:
>
> On 10/12/2021 11:16, Alex Deucher wrote:> [...]
> > Why not just reload the driver after kexec?
> >
> > Alex
>
> Because the original issue is the kdump case, and we want a very very
> tiny kernel - also, the crash originally could have been caused by
> amdgpu itself, so if it's a GPU issue, we don't want to mess with that
> in kdump. And I confess I tried modprobe amdgpu after a kdump, no
> success - kdump won't call shutdown handlers, so GPU will be in a
> "rogue" state...
>
> My question was about regular kexec because it's much simpler usually,
> we can do whatever we want there. My line of thought was: if I make it
> work in regular kexec with a simple framebuffer, I might be able to get
> it working on kdump heheh
>

Well if the GPU is hung, I'm not sure if you'll be able to get back
the display environment without a GPU reset and once you do that,
you've lost any state you might have been trying to preserve.

Alex


Re: RPI 7" display touch controller

2021-12-10 Thread Dave Stevenson
On Fri, 10 Dec 2021 at 18:20, Tim Harvey  wrote:
>
> On Thu, Nov 18, 2021 at 12:52 PM Tim Harvey  wrote:
> >
> > On Thu, Nov 18, 2021 at 10:30 AM Dave Stevenson
> >  wrote:
> > >
> > > On Thu, 18 Nov 2021 at 17:36, Tim Harvey  wrote:
> > > >
> > > > On Thu, Nov 18, 2021 at 6:28 AM Dave Stevenson
> > > >  wrote:
> > > > >
> > > > > Hi Tim
> > > > >
> > > > > On Thu, 18 Nov 2021 at 01:26, Tim Harvey  
> > > > > wrote:
> > > > > >
> > > > > > Greetings,
> > > > > >
> > > > > > I'm trying to get a RPI 7" touchscreen display working on an IMX8MM
> > > > > > board and while I've been able to get the MIPI DSI display and
> > > > > > backlight working I still can't seem to figure out the touch
> > > > > > controller.
> > > > > >
> > > > > > It's supposed to have an FT5406 controller on it without an 
> > > > > > interrupt
> > > > > > so I added polling support drivers/input/touchscreen/edt-ft5x06.c
> > > > > > which I was able to verify using another touchscreen with that
> > > > > > controller but when reading data from the FT5406 on the RPI 
> > > > > > controller
> > > > > > the data does not make sense.
> > > > > >
> > > > > > These panels appear to route the I2C from the FT5406 to a STM32F103
> > > > > > MPU that then provides a different I2C slave interface to the 15pin
> > > > > > connector that I'm connected to. On that I2C interface I see an i2c
> > > > > > slave at 0x45 which is managed by the regulator driver Marek wrote
> > > > > > (drivers/regulator/rpi-panel-attiny-regulator.c) and there is also 
> > > > > > an
> > > > > > i2c slave at 0x38 which I assumed was the FT5406 but I believe the 
> > > > > > MPU
> > > > > > is perhaps obfuscating that touch data.
> > > > > >
> > > > > > Anyone have any ideas on how to make that touch controller useful?
> > > > >
> > > > > There should be nothing unusual. 0x38 is the EDT touch controller.
> > > > > Starting with the Raspberry Pi OS Bullseye release, we're now using
> > > > > the panel directly from DRM rather than through the firmware. That's
> > > > > based on the branch at
> > > > > https://github.com/raspberrypi/linux/tree/rpi-5.10.y/
> > > > >
> > > >
> > > > Dave,
> > > >
> > > > That sounds like the driver that made it into mainline with Eric's
> > > > commit 2f733d6194bd ("drm/panel: Add support for the Raspberry Pi 7"
> > > > Touchscreen."). I looked there but that driver just deals with the DSI
> > > > and not with touch.
> > >
> > > No, we've reverted away from that driver as it exposes no regulator
> > > framework either, so again the touch element loses power.
> > >
> > > > > I also added polling support to edt-ft5x04.c.
> > > > > For DT, it uses a combination of the overlays vc4-kms-v3d,
> > > > > vc4-kms-dsi-7inch, and that includes edt-ft5406.dtsi, all of which are
> > > > > in /arch/arm/boot/dts/overlays
> > > >
> > > > It doesn't look like you ever submitted your edt-ft5x04 polling mode
> > > > support upstream. I saw another series to add polling support
> > > > submitted by Nicolas back in 2019 but was never followed up on
> > > > (https://patchwork.kernel.org/project/linux-input/list/?series=112187=both).
> > >
> > > No I haven't as it's been crazy trying to get this lot to work under
> > > KMS at all over the last couple of months.
> > >
> > > > I have updated Nicolas' patch with the changes requested and am happy
> > > > to submit it upstream. The benefit of his patch is that it uses a dt
> > > > binding for the polling interval. I'm happy to submit this upstream.
> > >
> > > I hadn't seen Nicolas' patches, hence implementing it myself.
> > >
> > > If you've implemented the requested changes, could you check that the
> > > polling rate is as expected? We were seeing that the input framework
> > > wasn't delivering the requested poll rate when CONFIG_HZ=100 is
> > > defined in the config. I must confess that I haven't checked it on my
> > > current patch, but it was on my list of things to do.
> > > There was a report that "bd88ce25335d Input: raspberrypi-ts - switch
> > > to using polled mode of input devices" dropped the polling rate from
> > > the desired 60Hz in switching to that framework.
> >
> > Ok, I'll make a note to test that and submit it.
> >
> > >
> > > > >
> > > > > The main issue I had was configuring the regulator framework
> > > > > appropriately to allow the touch controller power to be separate from
> > > > > the bridge power. Without that if DRM powered down the panel it killed
> > > > > the touch controller too, and the touch driver never reinitialised
> > > > > itself.
> > > >
> > > > I'm using the same drivers/regulator/rpi-panel-attiny-regulator.c
> > > > regulator driver from mainline that Marek added as the power-supply
> > > > for the panel as well as the backlight controller. It looks like the
> > > > version in the rpi-5.10.y has several patches on top of it so I'll
> > > > take a look at those differences to see if it may be affecting the
> > > > touchscreen controller. It's really strange to me that the 

Re: [PATCH 1/3] drm: bridge: nwl-dsi: Drop panel_bridge from nwl_dsi

2021-12-10 Thread Guido Günther
Hi,
On Fri, Dec 10, 2021 at 11:18:17PM +0530, Jagan Teki wrote:
> panel_bridge pointer never used anywhere except the one it
> looked up at nwl_dsi_bridge_attach.
> 
> Drop it from the nwl_dsi structure.
> 
> Cc: Guido Günther 
> Signed-off-by: Jagan Teki 

Reviewed-by: Guido Günther 

> ---
>  drivers/gpu/drm/bridge/nwl-dsi.c | 7 ++-
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c 
> b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..6becdcdc99fe 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -65,7 +65,6 @@ struct nwl_dsi_transfer {
>  struct nwl_dsi {
>   struct drm_bridge bridge;
>   struct mipi_dsi_host dsi_host;
> - struct drm_bridge *panel_bridge;
>   struct device *dev;
>   struct phy *phy;
>   union phy_configure_opts phy_cfg;
> @@ -924,13 +923,11 @@ static int nwl_dsi_bridge_attach(struct drm_bridge 
> *bridge,
>   if (IS_ERR(panel_bridge))
>   return PTR_ERR(panel_bridge);
>   }
> - dsi->panel_bridge = panel_bridge;
>  
> - if (!dsi->panel_bridge)
> + if (!panel_bridge)
>   return -EPROBE_DEFER;
>  
> - return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
> -  flags);
> + return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
>  }
>  
>  static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
> -- 
> 2.25.1
> 


Re: RPI 7" display touch controller

2021-12-10 Thread Tim Harvey
On Thu, Nov 18, 2021 at 12:52 PM Tim Harvey  wrote:
>
> On Thu, Nov 18, 2021 at 10:30 AM Dave Stevenson
>  wrote:
> >
> > On Thu, 18 Nov 2021 at 17:36, Tim Harvey  wrote:
> > >
> > > On Thu, Nov 18, 2021 at 6:28 AM Dave Stevenson
> > >  wrote:
> > > >
> > > > Hi Tim
> > > >
> > > > On Thu, 18 Nov 2021 at 01:26, Tim Harvey  wrote:
> > > > >
> > > > > Greetings,
> > > > >
> > > > > I'm trying to get a RPI 7" touchscreen display working on an IMX8MM
> > > > > board and while I've been able to get the MIPI DSI display and
> > > > > backlight working I still can't seem to figure out the touch
> > > > > controller.
> > > > >
> > > > > It's supposed to have an FT5406 controller on it without an interrupt
> > > > > so I added polling support drivers/input/touchscreen/edt-ft5x06.c
> > > > > which I was able to verify using another touchscreen with that
> > > > > controller but when reading data from the FT5406 on the RPI controller
> > > > > the data does not make sense.
> > > > >
> > > > > These panels appear to route the I2C from the FT5406 to a STM32F103
> > > > > MPU that then provides a different I2C slave interface to the 15pin
> > > > > connector that I'm connected to. On that I2C interface I see an i2c
> > > > > slave at 0x45 which is managed by the regulator driver Marek wrote
> > > > > (drivers/regulator/rpi-panel-attiny-regulator.c) and there is also an
> > > > > i2c slave at 0x38 which I assumed was the FT5406 but I believe the MPU
> > > > > is perhaps obfuscating that touch data.
> > > > >
> > > > > Anyone have any ideas on how to make that touch controller useful?
> > > >
> > > > There should be nothing unusual. 0x38 is the EDT touch controller.
> > > > Starting with the Raspberry Pi OS Bullseye release, we're now using
> > > > the panel directly from DRM rather than through the firmware. That's
> > > > based on the branch at
> > > > https://github.com/raspberrypi/linux/tree/rpi-5.10.y/
> > > >
> > >
> > > Dave,
> > >
> > > That sounds like the driver that made it into mainline with Eric's
> > > commit 2f733d6194bd ("drm/panel: Add support for the Raspberry Pi 7"
> > > Touchscreen."). I looked there but that driver just deals with the DSI
> > > and not with touch.
> >
> > No, we've reverted away from that driver as it exposes no regulator
> > framework either, so again the touch element loses power.
> >
> > > > I also added polling support to edt-ft5x04.c.
> > > > For DT, it uses a combination of the overlays vc4-kms-v3d,
> > > > vc4-kms-dsi-7inch, and that includes edt-ft5406.dtsi, all of which are
> > > > in /arch/arm/boot/dts/overlays
> > >
> > > It doesn't look like you ever submitted your edt-ft5x04 polling mode
> > > support upstream. I saw another series to add polling support
> > > submitted by Nicolas back in 2019 but was never followed up on
> > > (https://patchwork.kernel.org/project/linux-input/list/?series=112187=both).
> >
> > No I haven't as it's been crazy trying to get this lot to work under
> > KMS at all over the last couple of months.
> >
> > > I have updated Nicolas' patch with the changes requested and am happy
> > > to submit it upstream. The benefit of his patch is that it uses a dt
> > > binding for the polling interval. I'm happy to submit this upstream.
> >
> > I hadn't seen Nicolas' patches, hence implementing it myself.
> >
> > If you've implemented the requested changes, could you check that the
> > polling rate is as expected? We were seeing that the input framework
> > wasn't delivering the requested poll rate when CONFIG_HZ=100 is
> > defined in the config. I must confess that I haven't checked it on my
> > current patch, but it was on my list of things to do.
> > There was a report that "bd88ce25335d Input: raspberrypi-ts - switch
> > to using polled mode of input devices" dropped the polling rate from
> > the desired 60Hz in switching to that framework.
>
> Ok, I'll make a note to test that and submit it.
>
> >
> > > >
> > > > The main issue I had was configuring the regulator framework
> > > > appropriately to allow the touch controller power to be separate from
> > > > the bridge power. Without that if DRM powered down the panel it killed
> > > > the touch controller too, and the touch driver never reinitialised
> > > > itself.
> > >
> > > I'm using the same drivers/regulator/rpi-panel-attiny-regulator.c
> > > regulator driver from mainline that Marek added as the power-supply
> > > for the panel as well as the backlight controller. It looks like the
> > > version in the rpi-5.10.y has several patches on top of it so I'll
> > > take a look at those differences to see if it may be affecting the
> > > touchscreen controller. It's really strange to me that the touch
> > > controller's I2C goes through the STM32F103 MPU (as in the MPU's I2C
> > > master connects to the touchscreen controller and a different MPU I2C
> > > bus presents the touch controller like they are translating
> > > something?).
> >
> > The touchscreen I2C does NOT go through the STM.
> > The TS 

Re: [Intel-gfx] [PATCH] drm/i915/guc: Use correct context lock when callig clr_context_registered

2021-12-10 Thread Matthew Brost
On Fri, Dec 10, 2021 at 08:41:22AM +, Tvrtko Ursulin wrote:
> 
> On 09/12/2021 19:14, Daniele Ceraolo Spurio wrote:
> > 
> > 
> > On 12/9/2021 10:48 AM, Matthew Brost wrote:
> > > s/ce/cn/ when grabbing guc_state.lock before calling
> > > clr_context_registered.
> > > 
> > > Fixes: 0f7976506de61 ("drm/i915/guc: Rework and simplify locking")
> > > Signed-off-by: Matthew Brost 
> > > Cc: 
> 
> I think Cc: stable is not needed here:
> 
> $ git tag --contains 0f7976506de61
> drm-intel-fixes-2021-11-18
> drm-intel-gt-next-2021-10-08
> drm-intel-gt-next-2021-10-21
> drm-intel-gt-next-2021-11-22
> drm-intel-next-2021-10-15
> drm-intel-next-fixes-2021-11-09
> v5.16-rc1
> v5.16-rc2
> v5.16-rc3
> v5.16-rc4
> 
> So still can hit 5.16 via fixes. Rodrigo, did I get this right and you will
> be able to pick it up next week or so?
> 

Will remove.

> > Reviewed-by: Daniele Ceraolo Spurio 
> > 
> > I'm assuming we didn't see any splat from the lockdep assert in
> > clr_context_registered in our CI runs because we never hit this case as
> > it requires 64k+ contexts. Maybe we can add a selftest to purposely
> > exercise this path? Not a blocker for merging this fix.
> 
> Was the bug found by inspection or reported?
>

Internal testing.
 
> Given the buggy function is called steal_guc_id, so if the implication is
> there is no testing for guc id stealing, then it indeed please add some
> coverage ASAP.
>

Will do. I'll aim to get something out next week.

Matt
 
> Regards,
> 
> Tvrtko
> 
> > 
> > Daniele
> > 
> > > ---
> > >   drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 ++--
> > >   1 file changed, 2 insertions(+), 2 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 1f9d4fde421f..9b7b4f4e0d91 100644
> > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > @@ -1937,9 +1937,9 @@ static int steal_guc_id(struct intel_guc *guc,
> > > struct intel_context *ce)
> > >   list_del_init(>guc_id.link);
> > >   ce->guc_id = cn->guc_id;
> > > -    spin_lock(>guc_state.lock);
> > > +    spin_lock(>guc_state.lock);
> > >   clr_context_registered(cn);
> > > -    spin_unlock(>guc_state.lock);
> > > +    spin_unlock(>guc_state.lock);
> > >   set_context_guc_id_invalid(cn);
> > 


[PATCH v2 03/11] drm/tegra: vic: Fix DMA API misuse

2021-12-10 Thread Robin Murphy
Upon failure, dma_alloc_coherent() returns NULL. If that does happen,
passing some uninitialised stack contents to dma_mapping_error() - which
belongs to a different API in the first place - has precious little
chance of detecting it.

Also include the correct header, because the fragile transitive
inclusion currently providing it is going to break soon.

Fixes: 20e7dce255e9 ("drm/tegra: Remove memory allocation from Falcon library")
CC: Thierry Reding 
CC: Mikko Perttunen 
CC: dri-devel@lists.freedesktop.org
Signed-off-by: Robin Murphy 

---

It also doesn't appear to handle failure of the tegra_drm_alloc() path
either, but that's a loose thread I have no desire to pull on... ;)

v2: Resend as part of the series, originally posted separately here:

https://lore.kernel.org/dri-devel/2703882439344010e33bf21ecd63cf9e5e6dc00d.1637781007.git.robin.mur...@arm.com/

 drivers/gpu/drm/tegra/vic.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index c02010ff2b7f..da4af5371991 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -232,10 +233,8 @@ static int vic_load_firmware(struct vic *vic)
 
if (!client->group) {
virt = dma_alloc_coherent(vic->dev, size, , GFP_KERNEL);
-
-   err = dma_mapping_error(vic->dev, iova);
-   if (err < 0)
-   return err;
+   if (!virt)
+   return -ENOMEM;
} else {
virt = tegra_drm_alloc(tegra, size, );
}
-- 
2.28.0.dirty



[PATCH v2 02/11] gpu: host1x: Add missing DMA API include

2021-12-10 Thread Robin Murphy
Host1x seems to be relying on picking up dma-mapping.h transitively from
iova.h, which has no reason to include it in the first place. Fix the
former issue before we totally break things by fixing the latter one.

CC: Thierry Reding 
CC: Mikko Perttunen 
CC: dri-devel@lists.freedesktop.org
Signed-off-by: Robin Murphy 
---

v2: No change

 drivers/gpu/host1x/bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index 218e3718fd68..881fad5c3307 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.28.0.dirty



[PATCH 2/3] Revert "drm/bridge: dw-mipi-dsi: Find the possible DSI devices"

2021-12-10 Thread Jagan Teki
This reverts commit c206c7faeb3263a7cc7b4de443a3877cd7a5e74b.

In order to avoid any probe ordering issues, the I2C based downstream
bridge drivers now register and attach the DSI devices at the probe
instead of doing it on drm_bridge_function.attach().

Examples of those commits are:

commit <6ef7ee48765f> ("drm/bridge: sn65dsi83: Register and attach our
DSI device at probe")
commit  ("drm/bridge: lt8912b: Register and attach our DSI
device at probe")
commit <864c49a31d6b> ("drm/bridge: adv7511: Register and attach our DSI
device at probe")

dw-mipi-dsi has panel or bridge finding code based on previous downstream
bridges, so revert the same and make the panel or bridge funding in host
attach as before.

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 58 +--
 1 file changed, 15 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index e44e18a0112a..7900da1d4325 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -246,7 +246,6 @@ struct dw_mipi_dsi {
 
struct clk *pclk;
 
-   bool device_found;
unsigned int lane_mbps; /* per lane */
u32 channel;
u32 lanes;
@@ -310,37 +309,13 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 
reg)
return readl(dsi->base + reg);
 }
 
-static int dw_mipi_dsi_panel_or_bridge(struct dw_mipi_dsi *dsi,
-  struct device_node *node)
-{
-   struct drm_bridge *bridge;
-   struct drm_panel *panel;
-   int ret;
-
-   ret = drm_of_find_panel_or_bridge(node, 1, 0, , );
-   if (ret)
-   return ret;
-
-   if (panel) {
-   bridge = drm_panel_bridge_add_typed(panel,
-   DRM_MODE_CONNECTOR_DSI);
-   if (IS_ERR(bridge))
-   return PTR_ERR(bridge);
-   }
-
-   dsi->panel_bridge = bridge;
-
-   if (!dsi->panel_bridge)
-   return -EPROBE_DEFER;
-
-   return 0;
-}
-
 static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
   struct mipi_dsi_device *device)
 {
struct dw_mipi_dsi *dsi = host_to_dsi(host);
const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
int ret;
 
if (device->lanes > dsi->plat_data->max_data_lanes) {
@@ -354,14 +329,22 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
 
-   if (!dsi->device_found) {
-   ret = dw_mipi_dsi_panel_or_bridge(dsi, host->dev->of_node);
-   if (ret)
-   return ret;
+   ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,
+ , );
+   if (ret)
+   return ret;
 
-   dsi->device_found = true;
+   if (panel) {
+   bridge = drm_panel_bridge_add_typed(panel,
+   DRM_MODE_CONNECTOR_DSI);
+   if (IS_ERR(bridge))
+   return PTR_ERR(bridge);
}
 
+   dsi->panel_bridge = bridge;
+
+   drm_bridge_add(>bridge);
+
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
@@ -1016,16 +999,6 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge 
*bridge,
/* Set the encoder type as caller does not know it */
bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
 
-   if (!dsi->device_found) {
-   int ret;
-
-   ret = dw_mipi_dsi_panel_or_bridge(dsi, dsi->dev->of_node);
-   if (ret)
-   return ret;
-
-   dsi->device_found = true;
-   }
-
/* Attach the panel-bridge to the dsi bridge */
return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
 flags);
@@ -1208,7 +1181,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
 #ifdef CONFIG_OF
dsi->bridge.of_node = pdev->dev.of_node;
 #endif
-   drm_bridge_add(>bridge);
 
return dsi;
 }
-- 
2.25.1



[PATCH 3/3] drm: bridge: Switch to devm_drm_of_get_bridge

2021-12-10 Thread Jagan Teki
devm_drm_of_get_bridge is capable of looking up the downstream
bridge and panel and trying to add a panel bridge if the panel
is found.

Replace explicit finding calls with devm_drm_of_get_bridge.

Cc: Philipp Zabel 
Cc: Chun-Kuang Hu 
Cc: Linus Walleij 
Signed-off-by: Jagan Teki 
---
Note: for mcde_dsi child lookups has dependecy with
https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-ja...@amarulasolutions.com/

 drivers/gpu/drm/bridge/analogix/anx7625.c | 13 +--
 drivers/gpu/drm/bridge/chipone-icn6211.c  |  7 +---
 drivers/gpu/drm/bridge/nwl-dsi.c  | 18 ++---
 drivers/gpu/drm/bridge/nxp-ptn3460.c  |  7 +---
 drivers/gpu/drm/bridge/parade-ps8622.c|  7 +---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 15 ++-
 drivers/gpu/drm/mcde/mcde_dsi.c   | 39 +++
 drivers/gpu/drm/mediatek/mtk_dsi.c| 14 ++-
 8 files changed, 18 insertions(+), 102 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 001fb39d9919..065cc3b041dd 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1333,8 +1333,6 @@ static int anx7625_parse_dt(struct device *dev,
struct anx7625_platform_data *pdata)
 {
struct device_node *np = dev->of_node, *ep0;
-   struct drm_panel *panel;
-   int ret;
int bus_type, mipi_lanes;
 
anx7625_get_swing_setting(dev, pdata);
@@ -1371,16 +1369,7 @@ static int anx7625_parse_dt(struct device *dev,
if (of_property_read_bool(np, "analogix,audio-enable"))
pdata->audio_en = 1;
 
-   ret = drm_of_find_panel_or_bridge(np, 1, 0, , NULL);
-   if (ret < 0) {
-   if (ret == -ENODEV)
-   return 0;
-   return ret;
-   }
-   if (!panel)
-   return -ENODEV;
-
-   pdata->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
+   pdata->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
if (IS_ERR(pdata->panel_bridge))
return PTR_ERR(pdata->panel_bridge);
DRM_DEV_DEBUG_DRIVER(dev, "get panel node.\n");
diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c 
b/drivers/gpu/drm/bridge/chipone-icn6211.c
index a6151db95586..23c34039ac48 100644
--- a/drivers/gpu/drm/bridge/chipone-icn6211.c
+++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -178,7 +178,6 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = 
{
 static int chipone_parse_dt(struct chipone *icn)
 {
struct device *dev = icn->dev;
-   struct drm_panel *panel;
int ret;
 
icn->vdd1 = devm_regulator_get_optional(dev, "vdd1");
@@ -214,11 +213,7 @@ static int chipone_parse_dt(struct chipone *icn)
return PTR_ERR(icn->enable_gpio);
}
 
-   ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, , NULL);
-   if (ret)
-   return ret;
-
-   icn->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
+   icn->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
if (IS_ERR(icn->panel_bridge))
return PTR_ERR(icn->panel_bridge);
 
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 6becdcdc99fe..f6859dfa6d36 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -910,22 +910,10 @@ static int nwl_dsi_bridge_attach(struct drm_bridge 
*bridge,
 {
struct nwl_dsi *dsi = bridge_to_dsi(bridge);
struct drm_bridge *panel_bridge;
-   struct drm_panel *panel;
-   int ret;
-
-   ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, ,
- _bridge);
-   if (ret)
-   return ret;
-
-   if (panel) {
-   panel_bridge = drm_panel_bridge_add(panel);
-   if (IS_ERR(panel_bridge))
-   return PTR_ERR(panel_bridge);
-   }
 
-   if (!panel_bridge)
-   return -EPROBE_DEFER;
+   panel_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node, 1, 
0);
+   if (IS_ERR(panel_bridge))
+   return PTR_ERR(panel_bridge);
 
return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
 }
diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c 
b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index e941c1132598..1ab91f4e057b 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -263,7 +263,6 @@ static int ptn3460_probe(struct i2c_client *client,
struct device *dev = >dev;
struct ptn3460_bridge *ptn_bridge;
struct drm_bridge *panel_bridge;
-   struct drm_panel *panel;
int ret;
 
ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL);
@@ -271,11 +270,7 @@ static int ptn3460_probe(struct i2c_client *client,
return 

[PATCH 1/3] drm: bridge: nwl-dsi: Drop panel_bridge from nwl_dsi

2021-12-10 Thread Jagan Teki
panel_bridge pointer never used anywhere except the one it
looked up at nwl_dsi_bridge_attach.

Drop it from the nwl_dsi structure.

Cc: Guido Günther 
Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/nwl-dsi.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..6becdcdc99fe 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -65,7 +65,6 @@ struct nwl_dsi_transfer {
 struct nwl_dsi {
struct drm_bridge bridge;
struct mipi_dsi_host dsi_host;
-   struct drm_bridge *panel_bridge;
struct device *dev;
struct phy *phy;
union phy_configure_opts phy_cfg;
@@ -924,13 +923,11 @@ static int nwl_dsi_bridge_attach(struct drm_bridge 
*bridge,
if (IS_ERR(panel_bridge))
return PTR_ERR(panel_bridge);
}
-   dsi->panel_bridge = panel_bridge;
 
-   if (!dsi->panel_bridge)
+   if (!panel_bridge)
return -EPROBE_DEFER;
 
-   return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
-flags);
+   return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
 }
 
 static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
-- 
2.25.1



[PATCH 14/17] arm64: dts: mt8192: Add apu tinysys node

2021-12-10 Thread Flora Fu
Add node for APU tinysys.

Signed-off-by: Flora Fu 

---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 35 
 1 file changed, 35 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 62acaba7b033..de73fbf0cb90 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -914,6 +914,41 @@
#mbox-cells = <1>;
};
 
+   apusys_rv@19001000 {
+   compatible = "mediatek,mt8192-apusys-rv", "simple-mfd";
+   reg = <0 0x1900 0 0x1000>,
+ <0 0x19001000 0 0x1000>,
+ <0 0x19002000 0 0x10>;
+   reg-names = "apu_mbox",
+   "md32_sysctrl",
+   "apu_wdt";
+   power-domains = < 0>;
+   iommus = <_apu IOMMU_PORT_APU_DATA>;
+   interrupts = ;
+   interrupt-names = "apu_wdt";
+   mboxes = <_mailbox 0>;
+
+   apu_ctrl {
+   compatible = "mediatek,apu-ctrl-rpmsg";
+   mtk,rpmsg-name = "apu-ctrl-rpmsg";
+   };
+
+   apu_pwr_tx {
+   compatible = "mediatek,apupwr-tx-rpmsg";
+   mtk,rpmsg-name = "apupwr-tx-rpmsg";
+   };
+
+   apu_pwr_rx {
+   compatible = "mediatek,apupwr-rx-rpmsg";
+   mtk,rpmsg-name = "apupwr-rx-rpmsg";
+   };
+
+   apu_mdw_rpmsg {
+   compatible = "mediatek,apu-mdw-rpmsg";
+   mtk,rpmsg-name = "apu-mdw-rpmsg";
+   };
+   };
+
iommu_apu: iommu@1901 {
compatible = "mediatek,mt8192-iommu-apu";
reg = <0 0x1901 0 0x1000>;
-- 
2.18.0



[PATCH 08/17] remoteproc: mediatek: Add APU remoteproc driver

2021-12-10 Thread Flora Fu
APU integrated subsystem having MD32RV33 (MD32) that runs tinysys
The tinysys is runs on a microprocessor in APU. Its firmware
is loaded and booted from Kernel side. Kernel and tinysys use IPI
to send and receive messages.

Signed-off-by: Pi-Cheng Chen 
Signed-off-by: Flora Fu 

---
 drivers/remoteproc/Kconfig|   12 +
 drivers/remoteproc/Makefile   |2 +
 drivers/remoteproc/mtk-apu-ipi.c  |  474 +
 drivers/remoteproc/mtk-apu-rproc.c| 1054 +
 include/linux/remoteproc/mtk-apu-config.h |  100 ++
 include/linux/remoteproc/mtk-apu.h|  217 +
 6 files changed, 1859 insertions(+)
 create mode 100644 drivers/remoteproc/mtk-apu-ipi.c
 create mode 100644 drivers/remoteproc/mtk-apu-rproc.c
 create mode 100644 include/linux/remoteproc/mtk-apu-config.h
 create mode 100644 include/linux/remoteproc/mtk-apu.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index f2e961f998ca..72fc5fe7f4b5 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -54,6 +54,18 @@ config INGENIC_VPU_RPROC
  This can be either built-in or a loadable module.
  If unsure say N.
 
+config MTK_APU_RPROC
+   tristate "MediaTek APU remoteproc support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_APU_MBOX
+   select MTK_SCP
+   help
+ Say y here to support MediaTek AI Processing Unit Subsystem
+ via the remote processor framework.
+
+ It's safe to say N here.
+
 config MTK_SCP
tristate "Mediatek SCP support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 0ac256b6c977..1c1f1e443c56 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_IMX_REMOTEPROC)  += imx_rproc.o
 obj-$(CONFIG_IMX_DSP_REMOTEPROC)   += imx_dsp_rproc.o
 obj-$(CONFIG_INGENIC_VPU_RPROC)+= ingenic_rproc.o
 obj-$(CONFIG_MTK_SCP)  += mtk_scp.o mtk_scp_ipi.o
+obj-$(CONFIG_MTK_APU_RPROC)+= apu.o
+apu-objs   += mtk-apu-rproc.o mtk-apu-ipi.o
 obj-$(CONFIG_OMAP_REMOTEPROC)  += omap_remoteproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
diff --git a/drivers/remoteproc/mtk-apu-ipi.c b/drivers/remoteproc/mtk-apu-ipi.c
new file mode 100644
index ..62197441eb0b
--- /dev/null
+++ b/drivers/remoteproc/mtk-apu-ipi.c
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct apu_mbox_hdr {
+   unsigned int id;
+   unsigned int len;
+   unsigned int serial_no;
+   unsigned int csum;
+};
+
+#define IPI_BUF_SIZE (round_up(sizeof(struct mtk_share_obj) * 2, PAGE_SIZE))
+
+static struct lock_class_key ipi_lock_key[APU_IPI_MAX];
+static unsigned int tx_serial_no;
+static unsigned int rx_serial_no;
+
+#if IS_ENABLED(CONFIG_MTK_APU_DEBUG)
+static inline void dump_msg_buf(struct mtk_apu *apu, void *data, u32 len)
+{
+   struct device *dev = apu->dev;
+   u32 i;
+   int size = 64, num;
+   u8 buf[64], *ptr = buf;
+   int ret;
+
+   dev_info(dev, "= dump message =\n");
+   for (i = 0; i < len; i++) {
+   num = snprintf(ptr, size, "%02x ", ((u8 *)data)[i]);
+   if (num <= 0) {
+   dev_info(dev, "%s: snprintf return error(num = %d)\n",
+__func__, num);
+   return;
+   }
+   size -= num;
+   ptr += num;
+
+   if ((i + 1) % 4 == 0) {
+   ret = snprintf(ptr++, size--, " ");
+   if (ret <= 0) {
+   dev_info(dev, "%s: snprintf return error(ret = 
%d)\n",
+__func__, ret);
+   return;
+   }
+   }
+
+   if ((i + 1) % 16 == 0 || (i + 1) >= len) {
+   dev_info(dev, "%s\n", buf);
+   size = 64;
+   ptr = buf;
+   }
+   }
+   dev_info(dev, "\n");
+}
+#endif
+
+static u32 calculate_csum(void *data, u32 len)
+{
+   u32 csum = 0, res = 0, i;
+   u8 *ptr;
+
+   for (i = 0; i < (len / sizeof(csum)); i++)
+   csum += *(((u32 *)data) + i);
+
+   ptr = (u8 *)data + len / sizeof(csum) * sizeof(csum);
+   for (i = 0; i < (len % sizeof(csum)); i++)
+   res |= *(ptr + i) << i * 8;
+
+   csum += res;
+
+   return csum;
+}
+
+static inline bool bypass_check(u32 id)
+{
+   /* whitelist IPI used in power off flow */
+   return id == APU_IPI_DEEP_IDLE;
+}
+
+static void 

[PATCH 10/17] soc: mediatek: apu: Add APU software logger dirver

2021-12-10 Thread Flora Fu
The APU software logger is for debug for remote processor.
The remote microprocessor's logs will be output to the mapped
memory and application processor can read logs from the
dedicated reserved registers

Signed-off-by: Flora Fu 

---
 drivers/soc/mediatek/apusys/Makefile|   2 +
 drivers/soc/mediatek/apusys/apu-sw-logger.c | 540 
 2 files changed, 542 insertions(+)
 create mode 100644 drivers/soc/mediatek/apusys/apu-sw-logger.c

diff --git a/drivers/soc/mediatek/apusys/Makefile 
b/drivers/soc/mediatek/apusys/Makefile
index 8fff18d63dc1..6fb69abcf3b9 100644
--- a/drivers/soc/mediatek/apusys/Makefile
+++ b/drivers/soc/mediatek/apusys/Makefile
@@ -5,3 +5,5 @@ obj-$(CONFIG_MTK_APU) += mtk_apu_pwr.o
 mtk_apu_pwr-objs += apu-pwr.o
 mtk_apu_pwr-objs += apu-pwr-ipi.o
 mtk_apu_pwr-$(CONFIG_MTK_APU_DEBUG) += apu-pwr-dbg.o
+
+obj-$(CONFIG_MTK_APU_DEBUG) += apu-sw-logger.o
diff --git a/drivers/soc/mediatek/apusys/apu-sw-logger.c 
b/drivers/soc/mediatek/apusys/apu-sw-logger.c
new file mode 100644
index ..98a9748e92a7
--- /dev/null
+++ b/drivers/soc/mediatek/apusys/apu-sw-logger.c
@@ -0,0 +1,540 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define APUSYS_LOGGER_DIR "apu_logger"
+
+#define LOG_LINE_MAX_LENS SZ_128
+#define APU_LOG_SIZE SZ_1M
+#define APU_LOG_BUF_SIZE SZ_1M
+
+#define LOG_W_PTR 0x0
+#define LOG_R_PTR 0x4
+#define LOG_OV_FLG 0xC
+
+struct sw_logger_seq_data {
+   u32 w_ptr;
+   u32 r_ptr;
+   u32 overflow_flg;
+   int i;
+   int is_finished;
+   char *data;
+   bool startl_first;
+};
+
+struct apu_sw_logger {
+   struct device *dev;
+   struct dentry *dbg_root;
+   dma_addr_t handle;
+   char *sw_log_buf;
+   void __iomem *apu_slog;
+   spinlock_t logger_spinlock; /* logger status update lock */
+   struct sw_logger_seq_data pseqdata_lock;
+   struct sw_logger_seq_data *pseqdata;
+};
+
+static struct dentry *log_root;
+static struct dentry *log_seqlog;
+static struct dentry *log_seqlogl;
+static struct device *sw_logger_dev;
+
+static void sw_logger_buf_invalidate(struct apu_sw_logger *logger)
+{
+   dma_sync_single_for_cpu(logger->dev, logger->handle, APU_LOG_SIZE,
+   DMA_FROM_DEVICE);
+}
+
+static int sw_logger_buf_alloc(struct device *dev)
+{
+   struct apu_sw_logger *logger = dev_get_drvdata(dev);
+   int ret;
+
+   ret = dma_set_coherent_mask(logger->dev, DMA_BIT_MASK(64));
+   if (ret)
+   return ret;
+
+   logger->sw_log_buf = kzalloc(APU_LOG_SIZE, GFP_KERNEL);
+   if (!logger->sw_log_buf)
+   return -ENOMEM;
+
+   logger->handle = dma_map_single(logger->dev, logger->sw_log_buf,
+   APU_LOG_SIZE, DMA_FROM_DEVICE);
+   if (dma_mapping_error(logger->dev, logger->handle) != 0) {
+   kfree(logger->sw_log_buf);
+   logger->sw_log_buf = NULL;
+   return -EFAULT;
+   }
+
+   return 0;
+}
+
+int sw_logger_config_init(struct config_v1 *conf)
+{
+   int ret;
+   unsigned long flags;
+   struct logger_init_info *st_logger_init_info;
+   struct apu_sw_logger *logger;
+
+   if (!conf)
+   return -EINVAL;
+
+   if (!sw_logger_dev) {
+   pr_debug("%s: logger NA and skip logger\n",
+__func__);
+   return 0;
+   }
+
+   logger = dev_get_drvdata(sw_logger_dev);
+   if (!logger->sw_log_buf) {
+   ret = sw_logger_buf_alloc(logger->dev);
+   if (ret) {
+   dev_err(logger->dev, "%s: sw_logger_buf_alloc fail\n",
+   __func__);
+   return ret;
+   }
+   }
+
+   spin_lock_irqsave(>logger_spinlock, flags);
+   iowrite32(0, logger->apu_slog + LOG_W_PTR);
+   iowrite32(0, logger->apu_slog + LOG_R_PTR);
+   iowrite32(0, logger->apu_slog + LOG_OV_FLG);
+   spin_unlock_irqrestore(>logger_spinlock, flags);
+
+   st_logger_init_info = (struct logger_init_info *)
+   get_apu_config_user_ptr(conf, LOGGER_INIT_INFO);
+
+   st_logger_init_info->iova = logger->handle;
+
+   return 0;
+}
+EXPORT_SYMBOL(sw_logger_config_init);
+
+void sw_logger_config_remove(void)
+{
+   struct apu_sw_logger *logger = dev_get_drvdata(sw_logger_dev);
+
+   if (logger->handle)
+   dma_unmap_single(logger->dev, logger->handle,
+APU_LOG_SIZE, DMA_FROM_DEVICE);
+   kfree(logger->sw_log_buf);
+   logger->sw_log_buf = NULL;
+}
+EXPORT_SYMBOL(sw_logger_config_remove);
+
+/*
+ * seq_start() takes a position as an argument and returns an iterator which
+ * will start reading at that position.
+ * 

[PATCH 17/17] arm64: dts: mt8192: Set up regulators for APU subsys

2021-12-10 Thread Flora Fu
Set up APU regulators for mdla and vvpu.

Signed-off-by: Flora Fu 

---
 arch/arm64/boot/dts/mediatek/mt8192-evb.dts | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192-evb.dts 
b/arch/arm64/boot/dts/mediatek/mt8192-evb.dts
index 5d9e108e41f5..431008466d77 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8192-evb.dts
@@ -35,3 +35,8 @@
domain-supply = <_vproc1_buck_reg>;
};
 };
+
+_power {
+   vvpu-supply = <_vproc1_buck_reg>;
+   vmdla-supply = <_vproc2_buck_reg>;
+};
-- 
2.18.0



[PATCH 12/17] arm64: dts: mt8192: Add APU mtk-apu-mailbox node

2021-12-10 Thread Flora Fu
Add mtk-apu-mailbox for mt8192 SOC.

Signed-off-by: Flora Fu 

---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index cb2b171e0080..5c97dc7985b4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -906,6 +906,13 @@
#clock-cells = <1>;
};
 
+   apu_mailbox: apu_mailbox@1900 {
+   compatible = "mediatek,mtk-apu-mailbox";
+   reg = <0 0x1900 0 0x100>;
+   interrupts = ;
+   #mbox-cells = <1>;
+   };
+
apu_conn: apu_conn@1902 {
compatible = "mediatek,mt8192-apu-conn", "syscon";
reg = <0 0x1902 0 0x1000>;
-- 
2.18.0



[PATCH 16/17] arm64: dts: mt8192: Add apu-sw-logger node

2021-12-10 Thread Flora Fu
Add apu-sw-logger node to enable debug into tinysys.

Signed-off-by: Flora Fu 

---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index f95d381ff1cc..c8cc58e74f3c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -914,6 +914,12 @@
#mbox-cells = <1>;
};
 
+   apusys_sw_logger@1940 {
+   compatible = "mediatek,apu-sw-logger";
+   reg = <0 0x1940 0 0x10>;
+   iommus = <_apu IOMMU_PORT_APU_DATA>;
+   };
+
apusys_rv@19001000 {
compatible = "mediatek,mt8192-apusys-rv", "simple-mfd";
reg = <0 0x1900 0 0x1000>,
-- 
2.18.0



[PATCH 15/17] arm64: dts: mt8192: Add APU power nodes

2021-12-10 Thread Flora Fu
Add APU power node for MT8192.

Signed-off-by: Flora Fu 

---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 61 
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index de73fbf0cb90..f95d381ff1cc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -996,6 +996,67 @@
};
};
 
+   apusys_power: apusys_power@190f1000 {
+   compatible = "mediatek,mt8192-apu-power";
+   reg = <0 0x190f1000 0 0x1000>,
+ <0 0x19000600 0 0x100>;
+   reg-names = "apu_pcu",
+   "apu_spare";
+   power-domains = < 0>;
+   clocks = < CLK_TOP_DSP_SEL>,
+   < CLK_TOP_DSP1_SEL>,
+   < CLK_TOP_DSP1_NPUPLL_SEL>,
+   < CLK_TOP_DSP2_SEL>,
+   < CLK_TOP_DSP2_NPUPLL_SEL>,
+   < CLK_TOP_DSP5_SEL>,
+   < CLK_TOP_DSP5_APUPLL_SEL>,
+   < CLK_TOP_IPU_IF_SEL>,
+   <>,
+   < CLK_TOP_MAINPLL_D4_D2>,
+   < CLK_TOP_UNIVPLL_D4_D2>,
+   < CLK_TOP_UNIVPLL_D6_D2>,
+   < CLK_TOP_MMPLL_D6>,
+   < CLK_TOP_MMPLL_D5>,
+   < CLK_TOP_MMPLL_D4>,
+   < CLK_TOP_UNIVPLL_D5>,
+   < CLK_TOP_UNIVPLL_D4>,
+   < CLK_TOP_UNIVPLL_D3>,
+   < CLK_TOP_MAINPLL_D6>,
+   < CLK_TOP_MAINPLL_D4>,
+   < CLK_TOP_MAINPLL_D3>,
+   < CLK_TOP_TVDPLL>,
+   < CLK_TOP_APUPLL>,
+   < CLK_TOP_NPUPLL>,
+   < CLK_APMIXED_APUPLL>,
+   < CLK_APMIXED_NPUPLL>;
+   clock-names = "clk_top_dsp_sel",
+   "clk_top_dsp1_sel",
+   "clk_top_dsp1_npupll_sel",
+   "clk_top_dsp2_sel",
+   "clk_top_dsp2_npupll_sel",
+   "clk_top_dsp5_sel",
+   "clk_top_dsp5_apupll_sel",
+   "clk_top_ipu_if_sel",
+   "clk_top_clk26m",
+   "clk_top_mainpll_d4_d2",
+   "clk_top_univpll_d4_d2",
+   "clk_top_univpll_d6_d2",
+   "clk_top_mmpll_d6",
+   "clk_top_mmpll_d5",
+   "clk_top_mmpll_d4",
+   "clk_top_univpll_d5",
+   "clk_top_univpll_d4",
+   "clk_top_univpll_d3",
+   "clk_top_mainpll_d6",
+   "clk_top_mainpll_d4",
+   "clk_top_mainpll_d3",
+   "clk_top_tvdpll_ck",
+   "clk_top_apupll_ck",
+   "clk_top_npupll_ck",
+   "clk_apmixed_apupll_rate",
+   "clk_apmixed_npupll_rate";
+   };
+
camsys: clock-controller@1a00 {
compatible = "mediatek,mt8192-camsys";
reg = <0 0x1a00 0 0x1000>;
-- 
2.18.0



[PATCH 13/17] arm64: dts: mt8192: Add APU-IOMMU nodes

2021-12-10 Thread Flora Fu
Add APU-IOMMI nodes

Signed-off-by: Yong Wu 
Signed-off-by: Flora Fu 

---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 5c97dc7985b4..62acaba7b033 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -913,6 +914,14 @@
#mbox-cells = <1>;
};
 
+   iommu_apu: iommu@1901 {
+   compatible = "mediatek,mt8192-iommu-apu";
+   reg = <0 0x1901 0 0x1000>;
+   interrupts = ;
+   power-domains = < 0>;
+   #iommu-cells = <1>;
+   };
+
apu_conn: apu_conn@1902 {
compatible = "mediatek,mt8192-apu-conn", "syscon";
reg = <0 0x1902 0 0x1000>;
-- 
2.18.0



[PATCH 09/17] soc: mediatek: apu: Add Apu power driver

2021-12-10 Thread Flora Fu
Add APU power driver to support for subsys clock
and regulator controller.
Add MT8192 platform APU power driver's platform data.

Signed-off-by: Flora Fu 

---
 drivers/soc/mediatek/apusys/Kconfig   |  23 +
 drivers/soc/mediatek/apusys/Makefile  |   5 +
 drivers/soc/mediatek/apusys/apu-pwr-dbg.c | 167 ++
 drivers/soc/mediatek/apusys/apu-pwr-ipi.c | 377 +
 drivers/soc/mediatek/apusys/apu-pwr.c | 613 ++
 drivers/soc/mediatek/apusys/apu-pwr.h | 260 +
 6 files changed, 1445 insertions(+)
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr-dbg.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr-ipi.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr.h

diff --git a/drivers/soc/mediatek/apusys/Kconfig 
b/drivers/soc/mediatek/apusys/Kconfig
index 332e323e02ae..1daf73c74c17 100644
--- a/drivers/soc/mediatek/apusys/Kconfig
+++ b/drivers/soc/mediatek/apusys/Kconfig
@@ -11,4 +11,27 @@ config MTK_APU_PM
  APU power domain shall be enabled before accessing the
  internal sub modules.
 
+config MTK_APU
+   tristate "MediaTek APUSYS Support"
+   select REGMAP
+   select MAILBOX
+   select MTK_APU_MBOX
+   select MTK_APU_RPROC
+   select MTK_SCP
+   help
+ Say yes here to add support for the APU tinysys and enable
+ sub modules include apu power and middleware.
+ The tinysys firmware is loaded and booted from Kernel side through
+ rproc framework. The related sub modules in application processor
+ use IPI to communicate with APU tinysys.
+
+config MTK_APU_DEBUG
+   tristate "MediaTek APUSYS debug functions"
+   depends on MTK_APU
+   help
+ Say yes here to enable debug features in APU.
+ The debug configuration will enable kernel driver debug and register a
+ logger for retrieving debug logs from remote processor.
+ Disable it if you don't need them.
+
 endif # MTK_APUSYS
diff --git a/drivers/soc/mediatek/apusys/Makefile 
b/drivers/soc/mediatek/apusys/Makefile
index 8821c0f0b7b7..8fff18d63dc1 100644
--- a/drivers/soc/mediatek/apusys/Makefile
+++ b/drivers/soc/mediatek/apusys/Makefile
@@ -1,2 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_MTK_APU_PM) += mtk-apu-pm.o
+
+obj-$(CONFIG_MTK_APU) += mtk_apu_pwr.o
+mtk_apu_pwr-objs += apu-pwr.o
+mtk_apu_pwr-objs += apu-pwr-ipi.o
+mtk_apu_pwr-$(CONFIG_MTK_APU_DEBUG) += apu-pwr-dbg.o
diff --git a/drivers/soc/mediatek/apusys/apu-pwr-dbg.c 
b/drivers/soc/mediatek/apusys/apu-pwr-dbg.c
new file mode 100644
index ..ee81271cbb2c
--- /dev/null
+++ b/drivers/soc/mediatek/apusys/apu-pwr-dbg.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "apu-pwr.h"
+
+#define DEBUG_MAX_ARGS_NUM (5)
+
+struct dentry *apu_power_debugfs;
+
+static int apu_power_set_parameter(struct apu_power *apupwr,
+  enum APU_POWER_PARAM param,
+  u32 argc, u32 *args)
+{
+   struct device *dev = apupwr->dev;
+   int ret = 0;
+
+   switch (param) {
+   case POWER_PARAM_FIX_OPP:
+   if (args[0] == 0) {
+   apu_update_fixed_opp_by_reg(dev, 0x);
+   apu_power_notify_uP_opp_limit(apupwr,
+ OPP_LIMIT_FIX_OPP);
+   }
+   break;
+   case POWER_PARAM_DVFS_DEBUG:
+   if (args[0] >= 0 && args[0] <= 0x) {
+   apu_update_fixed_opp_by_reg(dev, args[0]);
+   apu_power_notify_uP_opp_limit(apupwr,
+ OPP_LIMIT_DVFS_DEBUG);
+   }
+   break;
+   case POWER_PARAM_ULOG_LEVEL:
+   ret = (argc == 1) ? 0 : -EINVAL;
+   if (ret) {
+   dev_err(dev,
+   "invalid argument, expected:1, received:%d\n",
+   argc);
+   goto out;
+   }
+   apupwr->dbg_option = POWER_PARAM_ULOG_LEVEL;
+   apupwr->ulog_level = args[0];
+   apu_power_set_ulog_level(apupwr, args[0]);
+   break;
+
+   default:
+   dev_err(dev, "unsupport the power parameter:%d\n", param);
+   break;
+   }
+
+out:
+   return ret;
+}
+
+static int apu_power_dbg_show(struct seq_file *s, void *unused)
+{
+   struct apu_power *apupwr = (struct apu_power *)s->private;
+   u32 ulog_level = apupwr->ulog_level;
+   u32 dbg_option = apupwr->dbg_option;
+
+   switch (dbg_option) {
+   case POWER_PARAM_ULOG_LEVEL:
+   seq_printf(s, "ulog_level = %d\n", ulog_level);
+   

[PATCH 11/17] soc: mediatek: apu: Add middleware driver

2021-12-10 Thread Flora Fu
The APU middleware is responsible to receive all user's requests
and control command and device related flow.
In Kernel side, the middleware use the IPI to send command
to remote tinysys to dispatch commands to AI engines in APU.

Signed-off-by: JB Tsai 
Signed-off-by: Flora Fu 

---
 drivers/soc/mediatek/apusys/Makefile |  10 +
 drivers/soc/mediatek/apusys/apu-device.h |  39 +
 drivers/soc/mediatek/apusys/mdw-cmd.c| 618 +++
 drivers/soc/mediatek/apusys/mdw-drv.c| 226 ++
 drivers/soc/mediatek/apusys/mdw-ioctl.c  | 331 
 drivers/soc/mediatek/apusys/mdw-ioctl.h  | 256 +++
 drivers/soc/mediatek/apusys/mdw-mem.c| 938 +++
 drivers/soc/mediatek/apusys/mdw-mem.h|  23 +
 drivers/soc/mediatek/apusys/mdw-rv-cmd.c | 158 
 drivers/soc/mediatek/apusys/mdw-rv-dev.c | 386 ++
 drivers/soc/mediatek/apusys/mdw-rv-msg.h |  90 +++
 drivers/soc/mediatek/apusys/mdw-rv.c | 131 
 drivers/soc/mediatek/apusys/mdw-rv.h |  98 +++
 drivers/soc/mediatek/apusys/mdw-sysfs.c  | 200 +
 drivers/soc/mediatek/apusys/mdw.h| 207 +
 15 files changed, 3711 insertions(+)
 create mode 100644 drivers/soc/mediatek/apusys/apu-device.h
 create mode 100644 drivers/soc/mediatek/apusys/mdw-cmd.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-drv.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-ioctl.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-ioctl.h
 create mode 100644 drivers/soc/mediatek/apusys/mdw-mem.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-mem.h
 create mode 100644 drivers/soc/mediatek/apusys/mdw-rv-cmd.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-rv-dev.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-rv-msg.h
 create mode 100644 drivers/soc/mediatek/apusys/mdw-rv.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw-rv.h
 create mode 100644 drivers/soc/mediatek/apusys/mdw-sysfs.c
 create mode 100644 drivers/soc/mediatek/apusys/mdw.h

diff --git a/drivers/soc/mediatek/apusys/Makefile 
b/drivers/soc/mediatek/apusys/Makefile
index 6fb69abcf3b9..9104c2979b85 100644
--- a/drivers/soc/mediatek/apusys/Makefile
+++ b/drivers/soc/mediatek/apusys/Makefile
@@ -7,3 +7,13 @@ mtk_apu_pwr-objs += apu-pwr-ipi.o
 mtk_apu_pwr-$(CONFIG_MTK_APU_DEBUG) += apu-pwr-dbg.o
 
 obj-$(CONFIG_MTK_APU_DEBUG) += apu-sw-logger.o
+
+obj-$(CONFIG_MTK_APU) += mtk_apu_mdw.o
+mtk_apu_mdw-objs += mdw-drv.o
+mtk_apu_mdw-objs += mdw-ioctl.o
+mtk_apu_mdw-objs += mdw-mem.o
+mtk_apu_mdw-objs += mdw-cmd.o
+mtk_apu_mdw-objs += mdw-rv.o
+mtk_apu_mdw-objs += mdw-rv-cmd.o
+mtk_apu_mdw-objs += mdw-rv-dev.o
+mtk_apu_mdw-$(CONFIG_DEBUG_FS) += mdw-sysfs.o
diff --git a/drivers/soc/mediatek/apusys/apu-device.h 
b/drivers/soc/mediatek/apusys/apu-device.h
new file mode 100644
index ..8a3ddf8d
--- /dev/null
+++ b/drivers/soc/mediatek/apusys/apu-device.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef APUSYS_DEVICE_H
+#define APUSYS_DEVICE_H
+
+#include 
+
+/* device type */
+enum {
+   APUSYS_DEVICE_NONE,
+
+   APUSYS_DEVICE_SAMPLE,
+   APUSYS_DEVICE_MDLA,
+   APUSYS_DEVICE_VPU,
+   APUSYS_DEVICE_EDMA,
+   APUSYS_DEVICE_RT = 32,
+   APUSYS_DEVICE_SAMPLE_RT,
+   APUSYS_DEVICE_MDLA_RT,
+   APUSYS_DEVICE_VPU_RT,
+
+   APUSYS_DEVICE_MAX = 64,
+};
+
+/* device definition */
+#define APUSYS_DEVICE_META_SIZE (32)
+
+struct apusys_device {
+   int dev_type;
+   int idx;
+   int preempt_type;
+   u8 preempt_level;
+   char meta_data[APUSYS_DEVICE_META_SIZE];
+   void *private;
+   int (*send_cmd)(int type, void *hnd, struct apusys_device *dev);
+};
+#endif
diff --git a/drivers/soc/mediatek/apusys/mdw-cmd.c 
b/drivers/soc/mediatek/apusys/mdw-cmd.c
new file mode 100644
index ..231a82b4ba0e
--- /dev/null
+++ b/drivers/soc/mediatek/apusys/mdw-cmd.c
@@ -0,0 +1,618 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+
+#include "mdw.h"
+#include "mdw-mem.h"
+
+static struct mdw_mem *mdw_cmd_get_mem(u64 handle)
+{
+   struct mdw_mem *m = NULL;
+
+   m = mdw_mem_get(handle);
+   if (!m)
+   return NULL;
+
+   mdw_mem_dma_map(m);
+
+   return m;
+}
+
+static int mdw_cmd_put_mem(struct mdw_mem *m)
+{
+   return mdw_mem_dma_unmap(m);
+}
+
+static void mdw_cmd_put_cmdbufs(struct mdw_fpriv *mpriv, struct mdw_cmd *c)
+{
+   struct mdw_subcmd_kinfo *ksubcmd = NULL;
+   unsigned int i = 0, j = 0;
+
+   if (!c->cmdbufs)
+   return;
+
+   /* flush cmdbufs and execinfos */
+   apusys_mem_invalidate_kva(c->cmdbufs->vaddr, c->cmdbufs->size);
+
+   for (i = 0; i < c->num_subcmds; i++) {
+   ksubcmd = >ksubcmds[i];
+   for (j = 0; j < ksubcmd->info->num_cmdbufs; j++) {
+   if (!ksubcmd->ori_cbs[j])
+   continue;
+

[PATCH 07/17] iommu/mediatek: Support APU iommu and config data for mt8192

2021-12-10 Thread Flora Fu
APU IOMMU is a new iommu HW. it uses a new pagetable.
Add support for mt8192 apu iommu.

Signed-off-by: Yong Wu 
Signed-off-by: Flora Fu 

---
 drivers/iommu/mtk_iommu.c | 45 ++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 8377f3c37283..4bc7c76062e6 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -133,6 +133,7 @@
 /* 2 bits: iommu type */
 #define MTK_IOMMU_TYPE_MM  (0x0 << 13)
 #define MTK_IOMMU_TYPE_INFRA   (0x1 << 13)
+#define MTK_IOMMU_TYPE_APU (0x2 << 13)
 #define MTK_IOMMU_TYPE_MASK(0x3 << 13)
 #define IFA_IOMMU_PCIe_SUPPORT BIT(15)
 
@@ -185,6 +186,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data 
*data, unsigned int ban
 #define MTK_IOMMU_4GB_MODE_REMAP_BASE   0x14000UL
 
 static LIST_HEAD(m4ulist); /* List all the M4U HWs */
+static LIST_HEAD(apulist); /* List the apu iommu HWs */
 
 #define for_each_m4u(data, head)  list_for_each_entry(data, head, list)
 
@@ -209,6 +211,13 @@ static const struct mtk_iommu_iova_region 
mt8192_multi_dom[] = {
#endif
 };
 
+static const struct mtk_iommu_iova_region mt8192_multi_dom_apu[] = {
+   { .iova_base = 0x0, .size = SZ_4G}, /* APU DATA */
+   { .iova_base = 0x400ULL,.size = 0x400},  /* APU VLM */
+   { .iova_base = 0x1000ULL,   .size = 0x1000}, /* APU VPU */
+   { .iova_base = 0x7000ULL,   .size = 0x1260}, /* APU REG */
+};
+
 /* If 2 M4U share a domain(use the same hwlist), Put the corresponding info in 
first data.*/
 static struct mtk_iommu_data *mtk_iommu_get_frst_data(struct list_head *hwlist)
 {
@@ -638,24 +647,45 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct 
iommu_domain *domain,
 
 static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 {
+   unsigned int flag = DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-   struct mtk_iommu_data *data;
+   struct mtk_iommu_data *data, *curdata;
+   struct device_link *link;
 
if (!fwspec || fwspec->ops != _iommu_ops)
return ERR_PTR(-ENODEV); /* Not a iommu client device */
 
data = dev_iommu_priv_get(dev);
 
+   if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_APU)) {
+   /*
+* The APU IOMMU HWs must work together. The consumer device
+* must connect with all the apu iommu HWs at the same time.
+*/
+   for_each_m4u(curdata, data->hw_list) {
+   link = device_link_add(dev, curdata->dev, flag);
+   if (!link)
+   dev_err(dev, "Unable to link %s\n", 
dev_name(curdata->dev));
+   }
+   }
return >iommu;
 }
 
 static void mtk_iommu_release_device(struct device *dev)
 {
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   struct mtk_iommu_data *data;
 
if (!fwspec || fwspec->ops != _iommu_ops)
return;
 
+   data = dev_iommu_priv_get(dev);
+   if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_APU)) {
+   struct list_head *head = data->hw_list;
+
+   for_each_m4u(data, head)
+   device_link_remove(dev, data->dev);
+   }
iommu_fwspec_free(dev);
 }
 
@@ -1270,6 +1300,18 @@ static const struct mtk_iommu_plat_data mt8192_data = {
   {0, 14, 16}, {0, 13, 18, 17}},
 };
 
+static const struct mtk_iommu_plat_data mt8192_data_apu = {
+   .m4u_plat   = M4U_MT8192,
+   .flags  = DCM_DISABLE | MTK_IOMMU_TYPE_APU |
+ SHARE_PGTABLE,
+   .inv_sel_reg= REG_MMU_INV_SEL_GEN2,
+   .hw_list= ,
+   .bank_nr= 1,
+   .bank_enable= {true},
+   .iova_region= mt8192_multi_dom_apu,
+   .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom_apu),
+};
+
 static const struct mtk_iommu_plat_data mt8195_data_infra = {
.m4u_plat = M4U_MT8195,
.flags= WR_THROT_EN | DCM_DISABLE |
@@ -1325,6 +1367,7 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
{ .compatible = "mediatek,mt8173-m4u", .data = _data},
{ .compatible = "mediatek,mt8183-m4u", .data = _data},
{ .compatible = "mediatek,mt8192-m4u", .data = _data},
+   { .compatible = "mediatek,mt8192-iommu-apu",   .data = 
_data_apu},
{ .compatible = "mediatek,mt8195-iommu-infra", .data = 
_data_infra},
{ .compatible = "mediatek,mt8195-iommu-vdo",   .data = 
_data_vdo},
{ .compatible = "mediatek,mt8195-iommu-vpp",   .data = 
_data_vpp},
-- 
2.18.0



[PATCH 06/17] mailbox: mediatek: add mtk-apu-mailbox driver

2021-12-10 Thread Flora Fu
Add mtk-apu-mailbox driver to support communication with
APU remote microprocessor.

Signed-off-by: Pi-Cheng Chen 
Signed-off-by: Flora Fu 

---
 drivers/mailbox/Kconfig   |   9 ++
 drivers/mailbox/Makefile  |   2 +
 drivers/mailbox/mtk-apu-mailbox.c | 162 ++
 3 files changed, 173 insertions(+)
 create mode 100644 drivers/mailbox/mtk-apu-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..aeaaadd4cb8d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,15 @@ config STM32_IPCC
  with hardware for Inter-Processor Communication Controller (IPCC)
  between processors. Say Y here if you want to have this support.
 
+config MTK_APU_MBOX
+   tristate "MediaTek APU Mailbox Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   help
+ Say yes here to add support for the MediaTek APU Mailbox
+ driver. The mailbox implementation provides access from the
+ application processor to the MediaTek AI Processing Unit.
+ If unsure say N.
+
 config MTK_CMDQ_MBOX
tristate "MediaTek CMDQ Mailbox Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..e24ad25c3378 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)  += tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC)   += stm32-ipcc.o
 
+obj-$(CONFIG_MTK_APU_MBOX) += mtk-apu-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)  += zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-apu-mailbox.c 
b/drivers/mailbox/mtk-apu-mailbox.c
new file mode 100644
index ..860db0504907
--- /dev/null
+++ b/drivers/mailbox/mtk-apu-mailbox.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define INBOX  (0x0)
+#define OUTBOX (0x20)
+#define INBOX_IRQ  (0xc0)
+#define OUTBOX_IRQ (0xc4)
+#define INBOX_IRQ_MASK (0xd0)
+
+#define MSG_MBOX_SLOTS (4)
+
+struct mtk_apu_mailbox {
+   struct device *dev;
+   void __iomem *regs;
+   spinlock_t lock; /* register access lock */
+   struct mbox_controller controller;
+   u32 msgs[MSG_MBOX_SLOTS];
+};
+
+static irqreturn_t mtk_apu_mailbox_threaded_irq(int irq, void *dev_id)
+{
+   struct mtk_apu_mailbox *mbox = dev_id;
+   struct mbox_chan *link = >controller.chans[0];
+   int i;
+
+   for (i = 0; i < MSG_MBOX_SLOTS; i++)
+   mbox->msgs[i] = readl(mbox->regs + OUTBOX + i * sizeof(u32));
+
+   mbox_chan_received_data(link, >msgs);
+   writel(readl(mbox->regs + OUTBOX_IRQ), mbox->regs + OUTBOX_IRQ);
+
+   return IRQ_HANDLED;
+}
+
+static int mtk_apu_mailbox_send_data(struct mbox_chan *chan, void *data)
+{
+   struct mtk_apu_mailbox *mbox = container_of(chan->mbox,
+   struct mtk_apu_mailbox,
+   controller);
+   int i;
+
+   spin_lock(>lock);
+   writel(~BIT(MSG_MBOX_SLOTS - 1), mbox->regs + INBOX_IRQ_MASK);
+   for (i = 0; i < MSG_MBOX_SLOTS; i++)
+   writel(((u32 *)data)[i], mbox->regs + INBOX + i * sizeof(u32));
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static bool mtk_apu_mailbox_last_tx_done(struct mbox_chan *chan)
+{
+   struct mtk_apu_mailbox *mbox = container_of(chan->mbox,
+   struct mtk_apu_mailbox,
+   controller);
+
+   return readl(mbox->regs + INBOX_IRQ) == 0;
+}
+
+static const struct mbox_chan_ops mtk_apu_mailbox_ops = {
+   .send_data = mtk_apu_mailbox_send_data,
+   .last_tx_done = mtk_apu_mailbox_last_tx_done,
+};
+
+static int mtk_apu_mailbox_probe(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct resource *res;
+   struct mtk_apu_mailbox *mbox;
+   int ret = 0;
+
+   mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+   if (!mbox)
+   return -ENOMEM;
+
+   mbox->dev = dev;
+   platform_set_drvdata(pdev, mbox);
+   spin_lock_init(>lock);
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!res)
+   return -ENODEV;
+
+   mbox->regs = devm_ioremap_resource(dev, res);
+   if (IS_ERR(mbox->regs))
+   return PTR_ERR(mbox->regs);
+
+   ret = devm_request_threaded_irq(dev,
+   irq_of_parse_and_map(dev->of_node, 0),
+   NULL, mtk_apu_mailbox_threaded_irq,
+   IRQF_ONESHOT, dev_name(dev), mbox);
+   if (ret) {
+   dev_err(dev, 

[PATCH 05/17] dt-bindings: soc: mediatek: apu: Add apu logger compatible

2021-12-10 Thread Flora Fu
Add new document for apu logger compatible.

Signed-off-by: Flora Fu 

---
 .../soc/mediatek/mediatek,apu-logger.yaml | 42 +++
 1 file changed, 42 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-logger.yaml

diff --git 
a/Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-logger.yaml 
b/Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-logger.yaml
new file mode 100644
index ..9e56fb3b8080
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-logger.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2021 (C) MediaTek Inc.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/mediatek/mediatek,apu-logger.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: MediaTek APU Logger for debug into microprocessor
+
+description: |
+  The APU logger is for debug usage. The APU remote microprocessor's logs
+  will be output to the mapped memory and application processor can read
+  logs from the dedicated reserved registers.
+
+maintainers:
+  - Flora Fu 
+
+properties:
+  compatible:
+items:
+  - enum:
+  - mediatek,apu-sw-logger
+  reg:
+maxItems: 1
+
+  iommus:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+apusys_sw_logger@1940 {
+  compatible = "mediatek,apu-sw-logger";
+  reg = <0x1940 0x10>;
+  iommus = <_apu IOMMU_PORT_APU_DATA>;
+};
-- 
2.18.0



[PATCH 03/17] dt-bindings: remoteproc: mediatek: Add APU rproc compatible

2021-12-10 Thread Flora Fu
Add new binding document for the APU remote processor.
The initial version is used for MT8192 SOC.

Signed-off-by: Pi-Cheng Chen 
Signed-off-by: Flora Fu 

---
 .../bindings/remoteproc/mediatek,apu-rv.yaml  | 106 ++
 1 file changed, 106 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/mediatek,apu-rv.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/mediatek,apu-rv.yaml 
b/Documentation/devicetree/bindings/remoteproc/mediatek,apu-rv.yaml
new file mode 100644
index ..c390b85040eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/mediatek,apu-rv.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2021 (C) MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/mediatek,apu-rv.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek APU remote processor controller bindings
+
+description: |
+  APU integrated subsystem having MD32RV33 (MD32) that runs tinysys.
+  The tinysys runs on a microprocessor in APU.
+  Its firmware is loaded and booted from Kernel side.
+  Kernel and tinysys uses IPI to send and receive messages.
+
+maintainers:
+  - Flora Fu 
+  - Pi-Cheng Chen 
+
+properties:
+  compatible:
+items:
+  - enum:
+  - mediatek,mt8192-apusys-rv
+  - const: simple-mfd
+
+  reg:
+minItems: 1
+
+  reg-names:
+minItems: 1
+
+  power-domains:
+maxItems: 1
+
+  iommus:
+maxItems: 1
+
+  interrupts:
+description: List of interrupts.
+
+  interrupt-names:
+description: Name list of interrupts.
+
+  mboxes:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - interrupts
+  - mboxes
+
+additionalProperties:
+  type: object
+  description:
+Represent subnodes that will register as rpmsg devices.
+  properties:
+compatible:
+  enum:
+- mediatek,apu-ctrl-rpmsg
+- mediatek,apupwr-tx-rpmsg
+- mediatek,apupwr-rx-rpmsg
+- mediatek,apu-mdw-rpmsg
+mediatek,rpmsg-name:
+  $ref: /schemas/types.yaml#/definitions/string-array
+  description:
+Contains the name for the rpmsg device. Used to match
+the subnode to rpmsg device announced by APU.
+  required:
+- compatible
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+
+apusys_rv@19001000 {
+  compatible = "mediatek,mt8192-apusys-rv", "simple-mfd";
+  reg = <0x19001000 0x1000>;
+  reg-names = "md32_sysctrl";
+  power-domains = < 0>;
+  iommus = <_apu IOMMU_PORT_APU_DATA>;
+  interrupts = ;
+  interrupt-names = "apu_wdt";
+  mboxes = <_mailbox 0>;
+  apu_ctrl {
+compatible = "mediatek,apu-ctrl-rpmsg";
+mediatek,rpmsg-name = "apu-ctrl-rpmsg";
+  };
+  apu_pwr_tx {
+compatible = "mediatek,apupwr-tx-rpmsg";
+mediatek,rpmsg-name = "apupwr-tx-rpmsg";
+  };
+  apu_pwr_rx {
+compatible = "mediatek,apupwr-rx-rpmsg";
+mediatek,rpmsg-name = "apupwr-rx-rpmsg";
+  };
+  apu_mdw_rpmsg {
+compatible = "mediatek,apu-mdw-rpmsg";
+mediatek,rpmsg-name = "apu-mdw-rpmsg";
+  };
+};
-- 
2.18.0



[PATCH 04/17] dt-bindings: soc: mediatek: apu: Add APU power compatible

2021-12-10 Thread Flora Fu
Add new document for APU power compatible.

Signed-off-by: Flora Fu 

---
 .../soc/mediatek/mediatek,apu-pwr.yaml| 80 +++
 1 file changed, 80 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-pwr.yaml

diff --git 
a/Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-pwr.yaml 
b/Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-pwr.yaml
new file mode 100644
index ..00f67dddb162
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-pwr.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2021 (C) MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mediatek,apu-pwr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek APU Power driver bindings
+
+description: |
+  MediaTek AI Process Unit (APU) power driver supports for subsys clock and
+  regulator controller.
+
+maintainers:
+  - Flora Fu 
+
+properties:
+  compatible:
+items:
+  - enum:
+  - mediatek,mt8192-apu-power
+  reg:
+minItems: 1
+
+  reg-names:
+minItems: 1
+
+  power-domains:
+maxItems: 1
+
+  vvpu-supply:
+description: apu vpu regulator supply.
+
+  vmdla-supply:
+description: apu mdla regulator supply.
+
+  clocks:
+description: Contains module clock source and clock names
+
+  clock-names:
+description: Names of the clocks list in clocks property
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - vvpu-supply
+  - vmdla-supply
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+apusys_power: apusys_power@190f1000 {
+  compatible = "mediatek,mt8192-apu-power";
+  reg = <0x190f1000 0x1000>;
+  reg-names = "apu_pcu";
+  power-domains = < 0>;
+  vvpu-supply = <_vproc1_buck_reg>;
+  vmdla-supply = <_vproc2_buck_reg>;
+  clocks = < CLK_TOP_DSP_SEL>,
+   < CLK_TOP_DSP1_SEL>,
+   < CLK_TOP_DSP1_NPUPLL_SEL>,
+   < CLK_TOP_DSP2_SEL>,
+   < CLK_TOP_DSP2_NPUPLL_SEL>,
+   < CLK_TOP_DSP5_SEL>,
+   < CLK_TOP_DSP5_APUPLL_SEL>,
+   < CLK_TOP_IPU_IF_SEL>,
+   <>;
+  clock-names = "clk_top_dsp_sel",
+"clk_top_dsp1_sel",
+"clk_top_dsp1_npupll_sel",
+"clk_top_dsp2_sel",
+"clk_top_dsp2_npupll_sel",
+"clk_top_dsp5_sel",
+"clk_top_dsp5_apupll_sel",
+"clk_top_ipu_if_sel",
+"clk_top_clk26m";
+};
-- 
2.18.0



[PATCH 02/17] dt-bindings: memory: mediatek: Add MT8192 apu iommu bindings

2021-12-10 Thread Flora Fu
MT8192 has one APU iommu hardware and add apu iommu bindings.

Signed-off-by: Flora Fu 

---
 .../devicetree/bindings/iommu/mediatek,iommu.yaml  | 7 +--
 include/dt-bindings/memory/mt8192-larb-port.h  | 4 
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml 
b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index c528a299afa9..14fae9642ec9 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -77,6 +77,7 @@ properties:
   - mediatek,mt8173-m4u  # generation two
   - mediatek,mt8183-m4u  # generation two
   - mediatek,mt8192-m4u  # generation two
+  - mediatek,mt8192-iommu-apu# generation two
   - mediatek,mt8195-iommu-vdo# generation two
   - mediatek,mt8195-iommu-vpp# generation two
   - mediatek,mt8195-iommu-infra  # generation two
@@ -154,6 +155,7 @@ allOf:
 compatible:
   enum:
 - mediatek,mt8192-m4u
+- mediatek,mt8192-iommu-apu
 - mediatek,mt8195-iommu-vdo
 - mediatek,mt8195-iommu-vpp
 
@@ -165,8 +167,9 @@ allOf:
   not:
 properties:
   compatible:
-contains:
-  const: mediatek,mt8195-iommu-infra
+enum:
+  - mediatek,mt8192-iommu-apu
+  - mediatek,mt8195-iommu-infra
 
 then:
   required:
diff --git a/include/dt-bindings/memory/mt8192-larb-port.h 
b/include/dt-bindings/memory/mt8192-larb-port.h
index 23035a52c675..908d6831bf99 100644
--- a/include/dt-bindings/memory/mt8192-larb-port.h
+++ b/include/dt-bindings/memory/mt8192-larb-port.h
@@ -240,4 +240,8 @@
 #define M4U_PORT_L20_IPE_RSC_RDMA0 MTK_M4U_ID(20, 4)
 #define M4U_PORT_L20_IPE_RSC_WDMA  MTK_M4U_ID(20, 5)
 
+#define IOMMU_PORT_APU_DATAMTK_M4U_ID(0, 0)
+#define IOMMU_PORT_APU_VLM MTK_M4U_ID(0, 1)
+#define IOMMU_PORT_APU_VPU MTK_M4U_ID(0, 2)
+
 #endif
-- 
2.18.0



[PATCH 01/17] dt-bindings: mailbox: mediatek: Add APU mailbox compatible

2021-12-10 Thread Flora Fu
Add the mailbox compatible for the MediaTek APU.
The MT8192 and MT8195 SOC will use it.

Signed-off-by: Pi-Cheng Chen 
Signed-off-by: Flora Fu 

---
 .../mailbox/mediatek,apu-mailbox.yaml | 47 +++
 1 file changed, 47 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml

diff --git 
a/Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml 
b/Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml
new file mode 100644
index ..ffd0e1623955
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) 2021 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mediatek,apu-mailbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek AI Processing Unit mailbox controller bindings
+
+description:
+  The APU mailbox controller provides access from the
+  application processor to the MediaTek AI Processing Unit.
+
+maintainers:
+  - Pi-Cheng Chen 
+
+properties:
+  compatible:
+enum:
+  - mediatek,mtk-apu-mailbox
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  "#mbox-cells":
+const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#mbox-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+apu_mailbox: apu_mailbox@1900 {
+  compatible = "mediatek,mtk-apu-mailbox";
+  reg = <0x1900 0x100>;
+  interrupts = ;
+  #mbox-cells = <1>;
+};
-- 
2.18.0



[PATCH 00/17] MediaTek MT8192 APU

2021-12-10 Thread Flora Fu
The MediaTek AI Processing Unit (APU) is a proprietary hardware
in the SoC to support AI functions.
The patches support the MT8192 APU runs on internal microprocessor.
Software packages contins mailbox, iommu, APU remote processor,
power control, middleware and debug looger.

This series is based on drivers implemented in
MT8192 apu power domain[1], apu SMC[2] and IOMMU[2] patches.
[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=593809
[2] https://patchwork.kernel.org/patch/12670253
[3] https://patchwork.kernel.org/project/linux-mediatek/list/?series=551641
The device tree depends on [4][5][6] which haven't yet been accepted.
[4] https://patchwork.kernel.org/patch/12456165
[5] https://patchwork.kernel.org/patch/12134935
[6] https://patchwork.kernel.org/patch/12140237

Change notes:
Initial RFC: 
https://patchwork.kernel.org/project/linux-mediatek/list/?series=568939

Flora Fu (17):
  dt-bindings: mailbox: mediatek: Add APU mailbox compatible
  dt-bindings: memory: mediatek: Add MT8192 apu iommu bindings
  dt-bindings: remoteproc: mediatek: Add APU rproc compatible
  dt-bindings: soc: mediatek: apu: Add APU power compatible
  dt-bindings: soc: mediatek: apu: Add apu logger compatible
  mailbox: mediatek: add mtk-apu-mailbox driver
  iommu/mediatek: Support APU iommu and config data for mt8192
  remoteproc: mediatek: Add APU remoteproc driver
  soc: mediatek: apu: Add Apu power driver
  soc: mediatek: apu: Add APU software logger dirver
  soc: mediatek: apu: Add middleware driver
  arm64: dts: mt8192: Add APU mtk-apu-mailbox node
  arm64: dts: mt8192: Add APU-IOMMU nodes
  arm64: dts: mt8192: Add apu tinysys node
  arm64: dts: mt8192: Add APU power nodes
  arm64: dts: mt8192: Add apu-sw-logger node
  arm64: dts: mt8192: Set up regulators for APU subsys

 .../bindings/iommu/mediatek,iommu.yaml|7 +-
 .../mailbox/mediatek,apu-mailbox.yaml |   47 +
 .../bindings/remoteproc/mediatek,apu-rv.yaml  |  106 ++
 .../soc/mediatek/mediatek,apu-logger.yaml |   42 +
 .../soc/mediatek/mediatek,apu-pwr.yaml|   80 ++
 arch/arm64/boot/dts/mediatek/mt8192-evb.dts   |5 +
 arch/arm64/boot/dts/mediatek/mt8192.dtsi  |  118 ++
 drivers/iommu/mtk_iommu.c |   45 +-
 drivers/mailbox/Kconfig   |9 +
 drivers/mailbox/Makefile  |2 +
 drivers/mailbox/mtk-apu-mailbox.c |  162 +++
 drivers/remoteproc/Kconfig|   12 +
 drivers/remoteproc/Makefile   |2 +
 drivers/remoteproc/mtk-apu-ipi.c  |  474 
 drivers/remoteproc/mtk-apu-rproc.c| 1054 +
 drivers/soc/mediatek/apusys/Kconfig   |   23 +
 drivers/soc/mediatek/apusys/Makefile  |   17 +
 drivers/soc/mediatek/apusys/apu-device.h  |   39 +
 drivers/soc/mediatek/apusys/apu-pwr-dbg.c |  167 +++
 drivers/soc/mediatek/apusys/apu-pwr-ipi.c |  377 ++
 drivers/soc/mediatek/apusys/apu-pwr.c |  613 ++
 drivers/soc/mediatek/apusys/apu-pwr.h |  260 
 drivers/soc/mediatek/apusys/apu-sw-logger.c   |  540 +
 drivers/soc/mediatek/apusys/mdw-cmd.c |  618 ++
 drivers/soc/mediatek/apusys/mdw-drv.c |  226 
 drivers/soc/mediatek/apusys/mdw-ioctl.c   |  331 ++
 drivers/soc/mediatek/apusys/mdw-ioctl.h   |  256 
 drivers/soc/mediatek/apusys/mdw-mem.c |  938 +++
 drivers/soc/mediatek/apusys/mdw-mem.h |   23 +
 drivers/soc/mediatek/apusys/mdw-rv-cmd.c  |  158 +++
 drivers/soc/mediatek/apusys/mdw-rv-dev.c  |  386 ++
 drivers/soc/mediatek/apusys/mdw-rv-msg.h  |   90 ++
 drivers/soc/mediatek/apusys/mdw-rv.c  |  131 ++
 drivers/soc/mediatek/apusys/mdw-rv.h  |   98 ++
 drivers/soc/mediatek/apusys/mdw-sysfs.c   |  200 
 drivers/soc/mediatek/apusys/mdw.h |  207 
 include/dt-bindings/memory/mt8192-larb-port.h |4 +
 include/linux/remoteproc/mtk-apu-config.h |  100 ++
 include/linux/remoteproc/mtk-apu.h|  217 
 39 files changed, 8181 insertions(+), 3 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/mailbox/mediatek,apu-mailbox.yaml
 create mode 100644 
Documentation/devicetree/bindings/remoteproc/mediatek,apu-rv.yaml
 create mode 100644 
Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-logger.yaml
 create mode 100644 
Documentation/devicetree/bindings/soc/mediatek/mediatek,apu-pwr.yaml
 create mode 100644 drivers/mailbox/mtk-apu-mailbox.c
 create mode 100644 drivers/remoteproc/mtk-apu-ipi.c
 create mode 100644 drivers/remoteproc/mtk-apu-rproc.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-device.h
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr-dbg.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr-ipi.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr.c
 create mode 100644 drivers/soc/mediatek/apusys/apu-pwr.h
 create mode 100644 

Re: [PATCH] drm: i915: display: intel_dmc: Fixes an unsigned subtraction which can never be negative.

2021-12-10 Thread Lucas De Marchi

On Thu, Dec 09, 2021 at 08:41:24PM -0800, Harshit Mogalapalli wrote:

smatch warning:
drivers/gpu/drm/i915/display/intel_dmc.c:601 parse_dmc_fw() warn:
unsigned 'fw->size - offset' is never less than zero

Firmware size is size_t and offset is u32. So the subtraction is
unsigned which can never be less than zero.

Fixes: 3d5928a168a9 ("drm/i915/xelpd: Pipe A DMC plugging")
Signed-off-by: Harshit Mogalapalli 



Reviewed-by: Lucas De Marchi 

"s|drm: i915: display: Fixes|drm/i915/display: Fix|" in the subject,
that I will do when applying after we have the CI results.

thanks
Lucas De Marchi


---
drivers/gpu/drm/i915/display/intel_dmc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c 
b/drivers/gpu/drm/i915/display/intel_dmc.c
index 0cab18f972d1..2f477c298b00 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -598,7 +598,7 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv,
continue;

offset = readcount + dmc->dmc_info[id].dmc_offset * 4;
-   if (fw->size - offset < 0) {
+   if (offset > fw->size) {
drm_err(_priv->drm, "Reading beyond the fw_size\n");
continue;
}
--
2.27.0



Re: [PATCH] drm/dp: Actually read Adjust Request Post Cursor2 register

2021-12-10 Thread Kees Cook
On Fri, Dec 10, 2021 at 12:06:20PM +0200, Jani Nikula wrote:
> On Thu, 09 Dec 2021, Kees Cook  wrote:
> > On Thu, Dec 09, 2021 at 05:20:45PM -0500, Harry Wentland wrote:
> >> 
> >> 
> >> On 2021-12-09 01:23, Kees Cook wrote:
> >> > On Wed, Dec 08, 2021 at 01:19:28PM +0200, Jani Nikula wrote:
> >> >> On Fri, 03 Dec 2021, Kees Cook  wrote:
> >> >>> The link_status array was not large enough to read the Adjust Request
> >> >>> Post Cursor2 register. Adjust the size to include it. Found with a
> >> >>> -Warray-bounds build:
> >> >>>
> >> >>> drivers/gpu/drm/drm_dp_helper.c: In function 
> >> >>> 'drm_dp_get_adjust_request_post_cursor':
> >> >>> drivers/gpu/drm/drm_dp_helper.c:59:27: error: array subscript 10 is 
> >> >>> outside array bounds of 'const u8[6]' {aka 'const unsigned char[6]'} 
> >> >>> [-Werror=array-bounds]
> >> >>>59 | return link_status[r - DP_LANE0_1_STATUS];
> >> >>>   |~~~^~~
> >> >>> drivers/gpu/drm/drm_dp_helper.c:147:51: note: while referencing 
> >> >>> 'link_status'
> >> >>>   147 | u8 drm_dp_get_adjust_request_post_cursor(const u8 
> >> >>> link_status[DP_LINK_STATUS_SIZE],
> >> >>>   |  
> >> >>> ~^~~~
> >> >>>
> >> >>> Fixes: 79465e0ffeb9 ("drm/dp: Add helper to get post-cursor 
> >> >>> adjustments")
> >> >>> Signed-off-by: Kees Cook 
> >> >>
> >> >> Using DP_ADJUST_REQUEST_POST_CURSOR2 has been deprecated since DP 1.3
> >> >> published in 2014, and Tegra is the only user of
> >> >> drm_dp_get_adjust_request_post_cursor().
> >> > 
> >> > I see POST_CURSOR2 is used here too:
> >> > 
> >> > drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> >> > 
> >> 
> >> Looks like we read and parse that in the admgpu driver without
> >> using drm_dp_get_adjust_request_post_cursor.
> >
> > Right, and probably that could be switched to use it, but I'm not sure
> > what the impact of the larger link_status read is.
> >
> >> 
> >> I don't have a strong feeling but I liked your original
> >> patch a bit better. I'm not sure what it means when part
> >> of a spec is deprecated. Once a spec is written display
> >> vendors might implement it. We should make sure that
> >> displays like that are always handled in a sane manner.
> >
> > Jani, Dave, any guidance here? I'm fine with whatever, but the current
> > code is for sure broken. ;)
> 
> Post Cursor2 was completely optional for the transmitter even before it
> was deprecated.
> 
> And now we'd be adding 5 bytes extra to all link status reads. To fix
> the only user of drm_dp_get_adjust_request_post_cursor() that apparently
> has never worked as intended. I'm just not convinced.
> 
> I was trying to look through the implications of DP_LINK_STATUS_SIZE
> increase, and at least drm_dp_dpcd_read_phy_link_status() comes across
> as something probably needing attention.

Okay, it sounds like you'd prefer the "make it tegra-specific" patch I
proposed. I will work that up as a proper patch and send it.

Thanks!

-- 
Kees Cook


Re: [PATCH v11 3/8] dt-bindings: display: Add ingenic, jz4780-dw-hdmi DT Schema

2021-12-10 Thread Rob Herring
On Thu, Dec 02, 2021 at 07:39:48PM +0100, H. Nikolaus Schaller wrote:
> From: Sam Ravnborg 
> 
> Add DT bindings for the hdmi driver for the Ingenic JZ4780 SoC.
> Based on .txt binding from Zubair Lutfullah Kakakhel
> 
> We also add generic ddc-i2c-bus to synopsys,dw-hdmi.yaml
> 
> Signed-off-by: Sam Ravnborg 
> Signed-off-by: H. Nikolaus Schaller 
> Cc: Rob Herring 
> Cc: devicet...@vger.kernel.org
> ---
>  .../display/bridge/ingenic,jz4780-hdmi.yaml   | 78 +++
>  .../display/bridge/synopsys,dw-hdmi.yaml  |  3 +
>  2 files changed, 81 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml 
> b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml
> new file mode 100644
> index 0..49ae1130efded
> --- /dev/null
> +++ 
> b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml
> @@ -0,0 +1,78 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/ingenic,jz4780-hdmi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Bindings for Ingenic JZ4780 HDMI Transmitter
> +
> +maintainers:
> +  - H. Nikolaus Schaller 
> +
> +description: |
> +  The HDMI Transmitter in the Ingenic JZ4780 is a Synopsys DesignWare HDMI 
> 1.4
> +  TX controller IP with accompanying PHY IP.
> +
> +allOf:
> +  - $ref: synopsys,dw-hdmi.yaml#
> +
> +properties:
> +  compatible:
> +const: ingenic,jz4780-dw-hdmi
> +
> +  reg-io-width:
> +const: 4
> +
> +  clocks:
> +maxItems: 2
> +
> +  hdmi-5v-supply:
> +description: regulator to provide +5V at the connector

Being part of the connector, that belongs in a connector node.

> +
> +  ports:
> +$ref: /schemas/graph.yaml#/properties/ports

You need to define what each 'port' node is.

> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - hdmi-5v-supply
> +  - ports
> +  - reg-io-width
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +#include 
> +
> +hdmi: hdmi@1018 {
> +compatible = "ingenic,jz4780-dw-hdmi";
> +reg = <0x1018 0x8000>;
> +reg-io-width = <4>;
> +ddc-i2c-bus = <>;
> +interrupt-parent = <>;
> +interrupts = <3>;
> +clocks = < JZ4780_CLK_AHB0>, < JZ4780_CLK_HDMI>;
> +clock-names = "iahb", "isfr";
> +hdmi-5v-supply = <_power>;
> +
> +ports {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +hdmi_in: port@0 {
> +reg = <0>;
> +dw_hdmi_in: endpoint {
> +remote-endpoint = <_lcd_out>;
> +};
> +};
> +hdmi_out: port@1 {
> +reg = <1>;
> +dw_hdmi_out: endpoint {
> +remote-endpoint = <_con>;
> +};
> +};
> +};
> +};
> +
> +...
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml 
> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
> index 9be44a682e67a..9cbeabaee0968 100644
> --- a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
> @@ -50,6 +50,9 @@ properties:
>interrupts:
>  maxItems: 1
>  
> +  ddc-i2c-bus:
> +description: An I2C interface if the internal DDC I2C driver is not to 
> be used

That too is already defined to be part of the connector node.

> +
>  additionalProperties: true
>  
>  ...
> -- 
> 2.33.0
> 
> 


Re: [PATCH v12, 15/19] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192

2021-12-10 Thread Rob Herring
On Thu, Dec 02, 2021 at 11:45:40AM +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for mt8192.
> 
> Signed-off-by: Yunfei Dong 
> ---
>  .../media/mediatek,vcodec-subdev-decoder.yaml | 266 ++
>  1 file changed, 266 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml 
> b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
> new file mode 100644
> index ..67cbcf8b3373
> --- /dev/null
> +++ 
> b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
> @@ -0,0 +1,266 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +
> +%YAML 1.2
> +---
> +$id: 
> "http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#;
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#;
> +
> +title: Mediatek Video Decode Accelerator With Multi Hardware
> +
> +maintainers:
> +  - Yunfei Dong 
> +
> +description: |
> +  Mediatek Video Decode is the video decode hardware present in Mediatek
> +  SoCs which supports high resolution decoding functionalities. Required
> +  parent and child device node.
> +
> +  About the Decoder Hardware Block Diagram, please check below:
> +
> ++-++
> +| ||
> +| input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output |
> +|||   | || |
> ++||---+-||-+
> +  lat workqueue   |  core workqueue 
> 
> +
> -||-||--
> + || ||  
> 
> + \/ \/
> +   +--+
> +   |enable/disable|
> +   |   clk powerirqiommu  |
> +   | (lat/lat soc/core0/core1)|
> +   +--+
> +
> +  As above, there are parent and child devices, child mean each hardware. 
> The child device
> +  controls the information of each hardware independent which include 
> clk/power/irq.
> +
> +  There are two workqueues in parent device: lat workqueue and core 
> workqueue. They are used
> +  to lat and core hardware deocder. Lat workqueue need to get input 
> bitstream and lat buffer,
> +  then enable lat to decode, writing the result to lat buffer, dislabe 
> hardware when lat decode
> +  done. Core workqueue need to get lat buffer and output buffer, then enable 
> core to decode,
> +  writing the result to output buffer, disable hardware when core decode 
> done. These two
> +  hardwares will decode each frame cyclically.
> +
> +  For the smi common may not the same for each hardware, can't combine all 
> hardware in one node,
> +  or leading to iommu fault when access dram data.
> +
> +properties:
> +  compatible:
> +const: mediatek,mt8192-vcodec-dec
> +
> +  reg:
> +maxItems: 1
> +
> +  iommus:
> +minItems: 1
> +maxItems: 32
> +description: |
> +  List of the hardware port in respective IOMMU block for current Socs.
> +  Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  mediatek,scp:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +maxItems: 1
> +description: |
> +  The node of system control processor (SCP), using
> +  the remoteproc & rpmsg framework.
> +  $ref: /schemas/remoteproc/mtk,scp.yaml

'$ref' is not valid here. Just 'See remoteproc/mtk,scp.yaml'

> +
> +  dma-ranges:
> +maxItems: 1
> +description: |
> +  Describes the physical address space of IOMMU maps to memory.
> +
> +  "#address-cells":
> +const: 1
> +
> +  "#size-cells":
> +const: 1
> +
> +  ranges: true
> +
> +# Required child node:
> +patternProperties:
> +  vcodec-lat:

'^vcodec-lat@[0-9a-f]+$':

> +type: object
> +
> +properties:
> +  compatible:
> +const: mediatek,mtk-vcodec-lat
> +
> +  reg:
> +maxItems: 1
> +
> +  interrupts:
> +maxItems: 1
> +
> +  iommus:
> +minItems: 1
> +maxItems: 32
> +description: |
> +  List of the hardware port in respective IOMMU block for current 
> Socs.
> +  Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  clocks:
> +maxItems: 5
> +
> +  clock-names:
> +items:
> +  - const: sel
> +  - const: soc-vdec
> +  - const: soc-lat
> +  - const: vdec
> +  - const: top
> +
> +  assigned-clocks:
> +

[PATCH 2/2] drm/panel: panel-simple: add bus_format and connector_type to cdtech_s070wv95_ct16 panel

2021-12-10 Thread Giulio Benetti
Add bus_format and connector_type to cdtech_s070wv95_ct16 panel.

Signed-off-by: Giulio Benetti 
---
 drivers/gpu/drm/panel/panel-simple.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index c8ad713865cb..dc300ace4d68 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1295,6 +1295,8 @@ static const struct panel_desc cdtech_s070wv95_ct16 = {
.width = 154,
.height = 85,
},
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+   .connector_type = DRM_MODE_CONNECTOR_DPI,
 };
 
 static const struct display_timing chefree_ch101olhlwh_002_timing = {
-- 
2.25.1



[PATCH 1/2] drm/panel: panel-simple: add bus_format and connector_type to cdtech_s043wq26h_ct7 panel

2021-12-10 Thread Giulio Benetti
Add bus_format and connector_type to cdtech_s043wq26h_ct7 panel.

Signed-off-by: Giulio Benetti 
---
 drivers/gpu/drm/panel/panel-simple.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index eb475a3a774b..c8ad713865cb 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1215,7 +1215,9 @@ static const struct panel_desc cdtech_s043wq26h_ct7 = {
.width = 95,
.height = 54,
},
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
+   .connector_type = DRM_MODE_CONNECTOR_DPI,
 };
 
 /* S070PWS19HP-FC21 2017/04/22 */
-- 
2.25.1



Re: [PATCH v2 03/11] mm/gup: migrate PIN_LONGTERM dev coherent pages to system

2021-12-10 Thread Felix Kuehling

On 2021-12-09 8:31 p.m., Alistair Popple wrote:

On Friday, 10 December 2021 3:54:31 AM AEDT Sierra Guiza, Alejandro (Alex) 
wrote:

On 12/9/2021 10:29 AM, Felix Kuehling wrote:

Am 2021-12-09 um 5:53 a.m. schrieb Alistair Popple:

On Thursday, 9 December 2021 5:55:26 AM AEDT Sierra Guiza, Alejandro (Alex) 
wrote:

On 12/8/2021 11:30 AM, Felix Kuehling wrote:

Am 2021-12-08 um 11:58 a.m. schrieb Felix Kuehling:

Am 2021-12-08 um 6:31 a.m. schrieb Alistair Popple:

On Tuesday, 7 December 2021 5:52:43 AM AEDT Alex Sierra wrote:

Avoid long term pinning for Coherent device type pages. This could
interfere with their own device memory manager.
If caller tries to get user device coherent pages with PIN_LONGTERM flag
set, those pages will be migrated back to system memory.

Signed-off-by: Alex Sierra
---
mm/gup.c | 32 ++--
1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 886d6148d3d0..1572eacf07f4 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1689,17 +1689,37 @@ struct page *get_dump_page(unsigned long addr)
#endif /* CONFIG_ELF_CORE */

#ifdef CONFIG_MIGRATION

+static int migrate_device_page(unsigned long address,
+   struct page *page)
+{
+   struct vm_area_struct *vma = find_vma(current->mm, address);
+   struct vm_fault vmf = {
+   .vma = vma,
+   .address = address & PAGE_MASK,
+   .flags = FAULT_FLAG_USER,
+   .pgoff = linear_page_index(vma, address),
+   .gfp_mask = GFP_KERNEL,
+   .page = page,
+   };
+   if (page->pgmap && page->pgmap->ops->migrate_to_ram)
+   return page->pgmap->ops->migrate_to_ram();

How does this synchronise against pgmap being released? As I understand things
at this point we're not holding a reference on either the page or pgmap, so
the page and therefore the pgmap may have been freed.

I think a similar problem exists for device private fault handling as well and
it has been on my list of things to fix for a while. I think the solution is to
call try_get_page(), except it doesn't work with device pages due to the whole
refcount thing. That issue is blocking a fair bit of work now so I've started
looking into it.

At least the page should have been pinned by the __get_user_pages_locked
call in __gup_longterm_locked. That refcount is dropped in
check_and_migrate_movable_pages when it returns 0 or an error.

Never mind. We unpin the pages first. Alex, would the migration work if
we unpinned them afterwards? Also, the normal CPU page fault code path
seems to make sure the page is locked (check in pfn_swap_entry_to_page)
before calling migrate_to_ram.

I don't think that's true. The check in pfn_swap_entry_to_page() is only for
migration entries:

BUG_ON(is_migration_entry(entry) && !PageLocked(p));

As this is coherent memory though why do we have to call into a device driver
to do the migration? Couldn't this all be done in the kernel?

I think you're right. I hadn't thought of that mainly because I'm even
less familiar with the non-device migration code. Alex, can you give
that a try? As long as the driver still gets a page-free callback when
the device page is freed, it should work.

Yes, you should still get the page-free callback when the migration code drops
the last page reference.


ACK.Will do

There is currently not really any support for migrating device pages based on
pfn. What I think is needed is something like migrate_pages(), but that API
won't work for a couple of reasons - main one being that it relies on pages
being LRU pages.

I've been working on a series to implement an equivalent of migrate_pages() for
device-private (and by extension device-coherent) pages. It might also be useful
here so I will try and get it posted as an RFC next week.
If we want to make progress on this patch series in the shorter term, we 
could just fail get_user_pages with FOLL_LONGTERM for DEVICE_COHERENT 
pages. Then add the migration support when your patch series is ready.


Regards,
  Felix




  - Alistair


Alex Sierra


Regards,
Felix



No, you can not unpinned after migration. Due to the expected_count VS
page_count condition at migrate_page_move_mapping, during migrate_page call.

Regards,
Alex Sierra


Regards,
 Felix







Re: [PATCH v7 1/3] drm/dsi: transer dsi hs packet aligned

2021-12-10 Thread Chun-Kuang Hu
Hi, Dave & Daniel:

This patch looks good to me, how do you think about it?

Regards,
Chun-Kuang.

Jitao Shi  於 2021年11月4日 週四 上午11:36寫道:
>
> Hi sirs
>
> Pls help to review this change.
>
> Best Regards
> Jitao.
>
> On Tue, 2021-10-05 at 07:53 +0800, Chun-Kuang Hu wrote:
> > Hi, Jitao:
> >
> > Jitao Shi  於 2021年9月16日 週四 上午6:31寫道:
> > >
> > > Some DSI devices reqire the hs packet starting and ending
> > > at same time on all dsi lanes. So use a flag to those devices.
> > >
> >
> > Reviewed-by: Chun-Kuang Hu 
> >
> > > Signed-off-by: Jitao Shi 
> > > ---
> > >  include/drm/drm_mipi_dsi.h | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/include/drm/drm_mipi_dsi.h
> > > b/include/drm/drm_mipi_dsi.h
> > > index af7ba8071eb0..8e8563792682 100644
> > > --- a/include/drm/drm_mipi_dsi.h
> > > +++ b/include/drm/drm_mipi_dsi.h
> > > @@ -177,6 +177,7 @@ struct mipi_dsi_device_info {
> > >   * @lp_rate: maximum lane frequency for low power mode in hertz,
> > > this should
> > >   * be set to the real limits of the hardware, zero is only
> > > accepted for
> > >   * legacy drivers
> > > + * @hs_packet_end_aligned: transfer dsi hs packet ending aligned
> > >   */
> > >  struct mipi_dsi_device {
> > > struct mipi_dsi_host *host;
> > > @@ -189,6 +190,7 @@ struct mipi_dsi_device {
> > > unsigned long mode_flags;
> > > unsigned long hs_rate;
> > > unsigned long lp_rate;
> > > +   bool hs_packet_end_aligned;
> > >  };
> > >
> > >  #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
> > > --
> > > 2.25.1


Re: [PATCH] drm/panel: ilitek-ili9881c: Avoid unbalance prepare/unprepare

2021-12-10 Thread Dave Stevenson
Hi Michael

On Fri, 10 Dec 2021 at 09:05, Michael Nazzareno Trimarchi
 wrote:
>
> Hi Dave
>
> some questions below
>
> On Thu, Dec 9, 2021 at 7:10 PM Michael Nazzareno Trimarchi
>  wrote:
> >
> > Hi Dave
> >
> > On Thu, Dec 9, 2021 at 6:58 PM Dave Stevenson
> >  wrote:
> > >
> > > Hi Michael
> > >
> > > On Thu, 9 Dec 2021 at 16:58, Michael Nazzareno Trimarchi
> > >  wrote:
> > > >
> > > > Hi all
> > > >
> > > > On Sat, Oct 16, 2021 at 4:58 PM Michael Trimarchi
> > > >  wrote:
> > > > >
> > > > > All the panel driver check the fact that their prepare/unprepare
> > > > > call was already called. It's not an ideal solution but fix
> > > > > for now the problem on ili9881c
> > > > >
> > > > > [ 9862.283296] [ cut here ]
> > > > > [ 9862.288490] unbalanced disables for vcc3v3_lcd
> > > > > [ 9862.293555] WARNING: CPU: 0 PID: 1 at drivers/regulator/core.c:2851
> > > > > _regulator_disable+0xd4/0x190
> > > > >
> > > > > from:
> > > > >
> > > > > [ 9862.038619]  drm_panel_unprepare+0x2c/0x4c
> > > > > [ 9862.043212]  panel_bridge_post_disable+0x18/0x24
> > > > > [ 9862.048390]  dw_mipi_dsi_bridge_post_disable+0x3c/0xf0
> > > > > [ 9862.054153]  drm_atomic_bridge_chain_post_disable+0x8c/0xd0
> > > > >
> > > > > and:
> > > > >
> > > > > [ 9862.183103]  drm_panel_unprepare+0x2c/0x4c
> > > > > [ 9862.187695]  panel_bridge_post_disable+0x18/0x24
> > > > > [ 9862.192872]  drm_atomic_bridge_chain_post_disable+0x8c/0xd0
> > > > > [ 9862.199117]  disable_outputs+0x120/0x31c
> > >
> > > This is down to the dw-mipi-dsi driver calling the post_disable hook
> > > explicitly at [1], but then also allowing the framework to call it.
> > > The explicit call is down to limitations in the DSI support, so we
> > > can't control the DSI host state to a fine enough degree (an ongoing
> > > discussion [2] [3]). There shouldn't be a need to handle mismatched
> > > calling in individual panel drivers.
> > >
> > >   Dave
> > >
> > > [1] 
> > > https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c#L894
> > > [2] 
> > > https://lists.freedesktop.org/archives/dri-devel/2021-November/332060.html
> > > [3] 
> > > https://lists.freedesktop.org/archives/dri-devel/2021-December/334007.html
> >
> > I'm in the second case. I need to enable HS mode after the panel is
> > initialized. Time to time I have timeout
> > on dsi command or I have wrong panel initialization. So I explicit call from
> > the bridge but I understand that is not correct in the design point of view.
> >
> > So this patch can not be queued because it's a known problem that
> > people are discussing
> >
> Author: Michael Trimarchi 
> Date:   Thu Dec 9 15:45:48 2021 +0100
>
> drm: bridge: samsung-dsim: Enable panel/bridge before exist from standby
>
> We need to exist from standby as last operation to have a proper video
> working. This code implement the same code was before the bridge
> migration
>
> Signed-off-by: Michael Trimarchi 
>
> diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c
> b/drivers/gpu/drm/bridge/samsung-dsim.c
> index 654851edbd9b..21265ae80022 100644
> --- a/drivers/gpu/drm/bridge/samsung-dsim.c
> +++ b/drivers/gpu/drm/bridge/samsung-dsim.c
> @@ -1838,6 +1838,7 @@ static void samsung_dsim_atomic_enable(struct
> drm_bridge *bridge,
>struct drm_bridge_state
> *old_bridge_state)
>  {
> struct samsung_dsim *dsi = bridge_to_dsi(bridge);
> +   struct drm_atomic_state old_state;
> int ret;
>
> if (dsi->state & DSIM_STATE_ENABLED)
> @@ -1859,6 +1860,9 @@ static void samsung_dsim_atomic_enable(struct
> drm_bridge *bridge,
> }
>
> samsung_dsim_set_display_mode(dsi);
> +
> +   drm_atomic_bridge_chain_enable(dsi->out_bridge, _state);

Calling this is contrary to the documentation [1]

"Note: the bridge passed should be the one closest to the encoder"

You're passing in a bridge that is half way down the chain, from a
bridge atomic_enable that is already being called by
drm_atomic_bridge_chain_enable

[1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_bridge.c#L695

> +
> samsung_dsim_set_display_enable(dsi, true);
>
> dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
>
> Right now I'm doing this to enable the change. I must change the panel
> to avoid double enabled
>
> I have some questions:
>
> - the chain is an element (bridge/panel) linked together via some
> connector (I hope I understand) when I enable
> a bridge chain, all the elements should move from some status to
> another. If we mark them already this should
> not avoid that one element can be enabled two times? An element that
> sources two other elements should for instance
> receive the enable from two times before switching on.

I don't claim to be an expert, just that I've been trying to get DSI
working on a number of devices.

The bridge chain is meant to be managed by the framework via

Re: [PATCH] drm/i915: Stop doing writeback from the shrinker

2021-12-10 Thread Tvrtko Ursulin



On 10/12/2021 14:46, Thomas Hellström wrote:

On Fri, 2021-12-10 at 11:05 +, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

This effectively removes writeback which was added in 2d6692e642e7
("drm/i915: Start writeback from the shrinker").

Digging through the history it seems we went back and forth on the
topic
of whether it would be safe a couple of times. See for instance
5537252b6b6d ("drm/i915: Invalidate our pages under memory pressure")
where Hugh Dickins has advised against it. I do not have enough
expertise
in the memory management area so am hoping for expert input here.

Reason for proposing removal is that there are reports from the field
which indicate a sysetm wide deadlock (of a sort) implicating i915
doing
writeback at shrinking time.

Signature is a hung task notifier kicking in and task traces such as:


It would be interesting to see what exactly the find_get_entry is
blocked on. The other two tasks are blocked on the shrinker_rwsem which
is held by i915. If it's indeed a deadlock with either of those two,


It may indeed be a livelock instead of a deadlock. I have received a 
newer trace and it indeed shows kswapd in running state. But no progress 
in 120s and dead machine sounded like too suspicious it could happen 
with just a gaming workload so I assumed a more serious issue than just 
severe memory pressure.



then the fix Chris is working on for an unrelated issue we discovered
with shrinking would move out the writeback call from the
shrinker_rwsem and resolve this, but if i915 is in turn deadlocking
with another process and these two are just hanging waiting for the
shrinker_rwsem, we would still have other issues.


Presumably this would involve an extra worker and tracking on a list or 
something?


Otherwise my main hope really was to get a verdict from memory 
management experts on pros & cons of doing writeback from the driver in 
any flavour.



Do you by any chance have the list of the locks held by the system at
this point?


No, but maybe Renato you could also collect "echo d" and "echo m" to 
sysrq-trigger when things go bad?


Regards,

Tvrtko


Re: Reuse framebuffer after a kexec (amdgpu / efifb)

2021-12-10 Thread Christian König

Am 10.12.21 um 16:24 schrieb Guilherme G. Piccoli:

On 10/12/2021 12:13, Christian König wrote:

[...]
How about issuing a PCIe reset and re-initializing the ASIC with just
the VBIOS?

That should be pretty straightforward I think.

Christian.


Thanks Christian, that'd be perfect! Is it feasible? Per Alex comment,
we'd need to run atombios commands to reprogram the timings, display
info, etc...like a small driver would do, a full init.

Also, what kind of PCIe reset is recommended for this adapter? Like a
hot reset, powering-off/re-power, FLR or that MODE2 reset present in
amdgpu code? Remembering this is an APU device.


Well, Alex is the expert on that.

APU makes the whole thing pretty tricky since the VBIOS is part of the 
system BIOS there and I'm not sure you can only re-initialize the GPU 
without a complete reset.


On dGPUs just making sure the ROM is mapped and calling the VESA modeset 
BIOS functions might already do the trick.


Christian.



Thanks a lot!





Re: [PATCH v7 08/11] drm/i915/pxp: Use to_gt() helper

2021-12-10 Thread Matt Roper
On Fri, Dec 10, 2021 at 03:07:56AM +0200, Andi Shyti wrote:
> Use to_gt() helper consistently throughout the codebase.
> Pure mechanical s/i915->gt/to_gt(i915). No functional changes.
> 
> Signed-off-by: Andi Shyti 

Reviewed-by: Matt Roper 

> ---
> Hi,
> 
> the inline of i915_dev_to_pxp() was accidentally removed in v6.
> Thanks Matt.
> 
> Andi
> 
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
> b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> index 5d169624ad60..195b2323ec00 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> @@ -16,7 +16,9 @@
>  
>  static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
>  {
> - return _to_i915(i915_kdev)->gt.pxp;
> + struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
> +
> + return _gt(i915)->pxp;
>  }
>  
>  static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
> -- 
> 2.34.1
> 

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795


  1   2   >