Re: [syzbot] [hardening?] [mm?] BUG: bad usercopy in con_font_op

2023-03-03 Thread syzbot
syzbot has bisected this issue to:

commit 24d69384bcd34b9dcaf5dab744bf7096e84d1abd
Author: Samuel Thibault 
Date:   Thu Jan 19 15:19:16 2023 +

VT: Add KD_FONT_OP_SET/GET_TALL operations

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=120b3232c8
start commit:   2eb29d59ddf0 Merge tag 'drm-next-2023-03-03-1' of git://an..
git tree:   upstream
final oops: https://syzkaller.appspot.com/x/report.txt?x=110b3232c8
console output: https://syzkaller.appspot.com/x/log.txt?x=160b3232c8
kernel config:  https://syzkaller.appspot.com/x/.config?x=cab35c936731a347
dashboard link: https://syzkaller.appspot.com/bug?extid=3af17071816b61e807ed
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=10b71504c8
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=16f02d9cc8

Reported-by: syzbot+3af17071816b61e80...@syzkaller.appspotmail.com
Fixes: 24d69384bcd3 ("VT: Add KD_FONT_OP_SET/GET_TALL operations")

For information about bisection process see: https://goo.gl/tpsmEJ#bisection


Re: [PATCH v2 1/2] drm/i915/gt: Create per-tile debugfs files

2023-03-03 Thread Andi Shyti
On Wed, Mar 01, 2023 at 09:35:33PM +, Sripada, Radhakrishna wrote:
> I am not sure if Tiles is appropriate usage here. Since MTL does not have the 
> concept of tiles.
> Shouldn't we be using gt instead of tile in our usage?
> 
> With s/tile/gt/g,
> Reviewed-by: Radhakrishna Sripada  

Just one question... you reviewed twice Patch number 1. Did you
mean to review patch 1 and patch 2?

Thanks,
Andi

> 
> > -Original Message-
> > From: dri-devel  On Behalf Of Andi
> > Shyti
> > Sent: Wednesday, March 1, 2023 3:03 AM
> > To: intel-...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> > Cc: Tvrtko Ursulin ; Andi Shyti
> > ; Patelczyk, Maciej ; Andi
> > Shyti ; Wajdeczko, Michal
> > 
> > Subject: [PATCH v2 1/2] drm/i915/gt: Create per-tile debugfs files
> > 
> > To support multi-GT configurations, we need to generate
> > independent debug files for each GT.
> > 
> > To achieve this create a separate directory for each GT under the
> > debugfs directory. For instance, in a system with two tiles, the
> > debugfs structure would look like this:
> > 
> > /sys/kernel/debug/dri
> >   └── 0
> >   ├── gt0
> >   │   ├── drpc
> >   │   ├── engines
> >   │   ├── forcewake
> >   │   ├── frequency
> >   │   └── rps_boost
> >   └── gt1
> >   :   ├── drpc
> >   :   ├── engines
> >   :   ├── forcewake
> >       ├── frequency
> >       └── rps_boost
> > 
> > Signed-off-by: Andi Shyti 
> > Cc: Tvrtko Ursulin 
> > ---
> >  drivers/gpu/drm/i915/gt/intel_gt_debugfs.c| 4 +++-
> >  drivers/gpu/drm/i915/gt/uc/intel_guc.h| 2 ++
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c| 5 -
> >  drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c | 2 ++
> >  4 files changed, 11 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c
> > b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c
> > index 5fc2df01aa0df..4dc23b8d3aa2d 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c
> > @@ -83,11 +83,13 @@ static void gt_debugfs_register(struct intel_gt *gt,
> > struct dentry *root)
> >  void intel_gt_debugfs_register(struct intel_gt *gt)
> >  {
> > struct dentry *root;
> > +   char gtname[4];
> > 
> > if (!gt->i915->drm.primary->debugfs_root)
> > return;
> > 
> > -   root = debugfs_create_dir("gt", gt->i915->drm.primary->debugfs_root);
> > +   snprintf(gtname, sizeof(gtname), "gt%u", gt->info.id);
> > +   root = debugfs_create_dir(gtname, gt->i915->drm.primary-
> > >debugfs_root);
> > if (IS_ERR(root))
> > return;
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > index bb4dfe707a7d0..e46aac1a41e6d 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > @@ -42,6 +42,8 @@ struct intel_guc {
> > /** @capture: the error-state-capture module's data and objects */
> > struct intel_guc_state_capture *capture;
> > 
> > +   struct dentry *dbgfs_node;
> > +
> > /** @sched_engine: Global engine used to submit requests to GuC */
> > struct i915_sched_engine *sched_engine;
> > /**
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > index 195db8c9d4200..55bc8b55fbc05 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > @@ -542,8 +542,11 @@ static int guc_log_relay_create(struct intel_guc_log
> > *log)
> >  */
> > n_subbufs = 8;
> > 
> > +   if (!guc->dbgfs_node)
> > +   return -ENOENT;
> > +
> > guc_log_relay_chan = relay_open("guc_log",
> > -   i915->drm.primary->debugfs_root,
> > +   guc->dbgfs_node,
> > subbuf_size, n_subbufs,
> > _callbacks, i915);
> > if (!guc_log_relay_chan) {
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
> > b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
> > index 284d6fbc2d08c..2f93cc4e408a8 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c
> > @@ -54,6 +54,8 @@ void intel_uc_debugfs_register(struct intel_uc *uc, struct
> > dentry *gt_root)
> > if (IS_ERR(root))
> > return;
> > 
> > +   uc->guc.dbgfs_node = root;
> > +
> > intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), uc);
> > 
> > intel_guc_debugfs_register(>guc, root);
> > --
> > 2.39.1
> 


Re: [PATCH v6 8/8] drm/i915/pxp: Enable PXP with MTL-GSC-CS

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Enable PXP with MTL-GSC-CS: add the has_pxp into device info
and increase the debugfs teardown timeouts to align with
new GSC-CS + firmware specs.

Signed-off-by: Alan Previn 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/i915_pci.c  | 1 +
  drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c | 9 -
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 2 +-
  3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index a8d942b16223..4ecf0f2ab6ec 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -1150,6 +1150,7 @@ static const struct intel_device_info mtl_info = {
.has_guc_deprivilege = 1,
.has_mslice_steering = 0,
.has_snoop = 1,
+   .has_pxp = 1,
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
.require_force_probe = 1,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
index 9f6e300486b4..ddf9f8bb7791 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
@@ -14,6 +14,7 @@
  
  #include "intel_pxp.h"

  #include "intel_pxp_debugfs.h"
+#include "intel_pxp_gsccs.h"
  #include "intel_pxp_irq.h"
  #include "intel_pxp_types.h"
  
@@ -45,6 +46,7 @@ static int pxp_terminate_set(void *data, u64 val)

  {
struct intel_pxp *pxp = data;
struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
+   int timeout_ms;
  
  	if (!intel_pxp_is_active(pxp))

return -ENODEV;
@@ -54,8 +56,13 @@ static int pxp_terminate_set(void *data, u64 val)
intel_pxp_irq_handler(pxp, 
GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT);
spin_unlock_irq(gt->irq_lock);
  
+	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))

+   timeout_ms = GSC_PENDING_RETRY_LATENCY_MS;
+   else
+   timeout_ms = 250;
+
if (!wait_for_completion_timeout(>termination,
-msecs_to_jiffies(100)))
+msecs_to_jiffies(timeout_ms)))
return -ETIMEDOUT;
  
  	return 0;

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 4ddf2ee60222..03f006f9dc2e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -44,7 +44,7 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, 
u32 id, bool in_pla
  KCR_SIP(pxp->kcr_base),
  mask,
  in_play ? mask : 0,
- 100);
+ 250);
  
  	intel_runtime_pm_put(uncore->rpm, wakeref);
  




Re: [PATCH v6 7/8] drm/i915/pxp: On MTL, KCR enabling doesn't wait on tee component

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

On legacy platforms, KCR HW enabling is done at the time the mei
component interface is bound. It's also disabled during unbind.
However, for MTL onwards, we don't depend on a tee component
to start sending GSC-CS firmware messages.

Thus, immediately enable (or disable) KCR HW on PXP's init,
fini and resume.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp.c| 19 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_pm.c |  3 ++-
  2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 61041277be24..e2f2cc5f6a6e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -119,6 +119,7 @@ static void destroy_vcs_context(struct intel_pxp *pxp)
  static void pxp_init_full(struct intel_pxp *pxp)
  {
struct intel_gt *gt = pxp->ctrl_gt;
+   intel_wakeref_t wakeref;
int ret;
  
  	/*

@@ -140,10 +141,15 @@ static void pxp_init_full(struct intel_pxp *pxp)
if (ret)
return;
  
-	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
ret = intel_pxp_gsccs_init(pxp);
-   else
+   if (!ret) {
+   with_intel_runtime_pm(>ctrl_gt->i915->runtime_pm, 
wakeref)
+   intel_pxp_init_hw(pxp);


personal preference: I'd move this (and the matching call in fini) 
inside intel_pxp_gsccs_init/fini. That way we can see this as more 
back-end specific: the gsccs initialize everything immediately, while 
the tee back-end follows a 2-step approach with the component.
Not a blocker since it is a personal preference, so with or without the 
change:


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   }
+   } else {
ret = intel_pxp_tee_component_init(pxp);
+   }
if (ret)
goto out_context;
  
@@ -239,15 +245,20 @@ int intel_pxp_init(struct drm_i915_private *i915)
  
  void intel_pxp_fini(struct drm_i915_private *i915)

  {
+   intel_wakeref_t wakeref;
+
if (!i915->pxp)
return;
  
  	i915->pxp->arb_is_valid = false;
  
-	if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0))

+   if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0)) {
+   with_intel_runtime_pm(>pxp->ctrl_gt->i915->runtime_pm, 
wakeref)
+   intel_pxp_fini_hw(i915->pxp);
intel_pxp_gsccs_fini(i915->pxp);
-   else
+   } else {
intel_pxp_tee_component_fini(i915->pxp);
+   }
  
  	destroy_vcs_context(i915->pxp);
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c

index 4f836b317424..1a04067f61fc 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -43,8 +43,9 @@ void intel_pxp_resume_complete(struct intel_pxp *pxp)
 * The PXP component gets automatically unbound when we go into S3 and
 * re-bound after we come out, so in that scenario we can defer the
 * hw init to the bind call.
+* NOTE: GSC-CS backend doesn't rely on components.
 */
-   if (!pxp->pxp_component)
+   if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
return;
  
  	intel_pxp_init_hw(pxp);




Re: [PATCH v6 6/8] drm/i915/pxp: MTL-KCR interrupt ctrl's are in GT-0

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Despite KCR subsystem being in the media-tile (close to the
GSC-CS), the IRQ controls for it are on GT-0 with other global
IRQ controls. Thus, add a helper for KCR hw interrupt
enable/disable functions to get the correct gt structure (for
uncore) for MTL.


This is not correct. On MTL, the interrupts logic isn't on any 
particular GT, it is in a shared area. The fact that we handle all 
interrupts as if they were triggered on the root GT is an i915 
implementation decision. Both uncores have access to the irq regs and 
the 2 GTs share the irq lock. A comparable example is the media GuC, 
where the interrupts enable/disable functions are called with the media 
GT structure.



In the helper, we get GT-0's handle for uncore when touching
IRQ registers despite the pxp->ctrl_gt being the media-tile.
No difference for legacy of course.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 24 +---
  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h |  8 +++
  3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
index 4b8e70caa3ad..9f6e300486b4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
@@ -44,7 +44,7 @@ static int pxp_terminate_get(void *data, u64 *val)
  static int pxp_terminate_set(void *data, u64 val)
  {
struct intel_pxp *pxp = data;
-   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);


In this function the only use you have of the GT is to take 
gt->irq_lock, but that's shared between the GTs so it is ok to use the 
media GT for it.


  
  	if (!intel_pxp_is_active(pxp))

return -ENODEV;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 91e9622c07d0..3a725397349f 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -4,10 +4,12 @@
   */
  #include 
  
+#include "gt/intel_gt.h"

  #include "gt/intel_gt_irq.h"
  #include "gt/intel_gt_regs.h"
  #include "gt/intel_gt_types.h"
  
+#include "i915_drv.h"

  #include "i915_irq.h"
  #include "i915_reg.h"
  
@@ -17,6 +19,22 @@

  #include "intel_pxp_types.h"
  #include "intel_runtime_pm.h"
  
+/**

+ * intel_pxp_get_irq_gt - Find the correct GT that owns KCR interrupts
+ * @pxp: pointer to pxp struct
+ *
+ * For platforms with a single GT, we return the pxp->ctrl_gt (as expected)
+ * but for MTL+ that has a media-tile, although the KCR engine is in the
+ * media-tile (i.e. pxp->ctrl_gt), the IRQ controls are on the root tile.
+ * In the end, we don't use pxp->ctrl_gt for IRQ, we always return root gt.
+ */
+struct intel_gt *intel_pxp_get_irq_gt(struct intel_pxp *pxp)
+{
+   WARN_ON_ONCE(!pxp->ctrl_gt->i915->media_gt && 
!gt_is_root(pxp->ctrl_gt));
+
+   return to_gt(pxp->ctrl_gt->i915);
+}
+
  /**
   * intel_pxp_irq_handler - Handles PXP interrupts.
   * @pxp: pointer to pxp struct
@@ -29,7 +47,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
return;
  
-	gt = pxp->ctrl_gt;

+   gt = intel_pxp_get_irq_gt(pxp);


same as above, only use here is the lock.

  
  	lockdep_assert_held(gt->irq_lock);
  
@@ -68,7 +86,7 @@ static inline void pxp_irq_reset(struct intel_gt *gt)
  
  void intel_pxp_irq_enable(struct intel_pxp *pxp)

  {
-   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);


in this function we use the gt for:

1 - the lock: see above about this

2 - gen11_gt_reset_one_iir(): this should work with the media GT (we use 
it for media GuC)


3 - writes to the GEN11_CRYPTO_* regs: those should also work with the 
media GT uncore as these regs are in the same range as the GuC scratch 
regs and we use the media uncore for those accesses.


  
  	spin_lock_irq(gt->irq_lock);
  
@@ -83,7 +101,7 @@ void intel_pxp_irq_enable(struct intel_pxp *pxp)
  
  void intel_pxp_irq_disable(struct intel_pxp *pxp)

  {
-   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
  


AFAICS this functions uses the same 3 cases as above.

Overall, I am not sure this patch is required. Am I missing something?

Daniele


/*
 * We always need to submit a global termination when we re-enable the
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
index 8c292dc86f68..eea87c9eb62b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
@@ -9,6 +9,7 @@
  #include 
  
  struct intel_pxp;

+struct intel_gt;
  
  #define GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT BIT(1)

  #define 

Re: [PATCH v6 5/8] drm/i915/pxp: Add ARB session creation and cleanup

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Add MTL's function for ARB session creation using PXP firmware
version 4.3 ABI structure format.

Also add MTL's function for ARB session invalidation but this
reuses PXP firmware version 4.2 ABI structure format.

Before checking the return status, look at the GSC-CS-Mem-Header's
pending-bit which means the GSC firmware is busy and we should
resubmit.

Signed-off-by: Alan Previn 
---
  drivers/gpu/drm/i915/pxp/intel_pxp.c  | 34 --
  .../drm/i915/pxp/intel_pxp_cmd_interface_43.h | 21 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c| 62 +++
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h|  4 ++
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 11 +++-
  5 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index aecc65b5da70..61041277be24 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -290,6 +290,8 @@ static bool pxp_component_bound(struct intel_pxp *pxp)
  
  static int __pxp_global_teardown_final(struct intel_pxp *pxp)

  {
+   int timeout;
+
if (!pxp->arb_is_valid)
return 0;
/*
@@ -299,7 +301,12 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
intel_pxp_mark_termination_in_progress(pxp);
intel_pxp_terminate(pxp, false);
  
-	if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250)))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   timeout = GSC_PENDING_RETRY_LATENCY_MS;
+   else
+   timeout = 250;
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
  
  	return 0;

@@ -307,6 +314,8 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
  
  static int __pxp_global_teardown_restart(struct intel_pxp *pxp)

  {
+   int timeout;
+
if (pxp->arb_is_valid)
return 0;
/*
@@ -315,7 +324,12 @@ static int __pxp_global_teardown_restart(struct intel_pxp 
*pxp)
 */
pxp_queue_termination(pxp);
  
-	if (!wait_for_completion_timeout(>termination, msecs_to_jiffies(250)))

+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+   timeout = GSC_PENDING_RETRY_LATENCY_MS;
+   else
+   timeout = 250;
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
  
  	return 0;

@@ -353,8 +367,20 @@ int intel_pxp_start(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return -ENODEV;
  
-	if (wait_for(pxp_component_bound(pxp), 250))

-   return -ENXIO;
+   if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
+   /*
+* GSC-fw loading, GSC-proxy init (requiring an mei component 
driver) and
+* HuC-fw loading must all occur first before we start 
requesting for PXP
+* sessions. Checking HuC authentication (the last dependency)  
will suffice.
+* Let's use a much larger 8 second timeout considering all the 
types of
+* dependencies prior to that.
+*/
+   if (wait_for(intel_huc_is_authenticated(>ctrl_gt->uc.huc), 
8000))


This big timeout needs an ack from userspace drivers, as intel_pxp_start 
is called during context creation and the current way to query if the 
feature is supported is to create a protected context. Unfortunately, we 
do need to wait to confirm that PXP is available (although in most cases 
it shouldn't take even close to 8 secs), because until everything is 
setup we're not sure if things will work as expected. I see 2 potential 
mitigations in case the timeout doesn't work as-is:


1) we return -EAGAIN (or another dedicated error code) to userspace if 
the prerequisite steps aren't done yet. This would indicate that the 
feature is there, but that we haven't completed the setup yet. The 
caller can then decide if they want to retry immediately or later. Pro: 
more flexibility for userspace; Cons: new interface return code.


2) we add a getparam to say if PXP is supported in HW and the support is 
compiled in i915. Userspace can query this as a way to check the feature 
support and only create the context if they actually need it for PXP 
operations. Pro: simpler kernel implementation; Cons: new getparam, plus 
even if the getparam returns true the pxp_start could later fail, so 
userspace needs to handle that case.



+   return -ENXIO;
+   } else {
+   if (wait_for(pxp_component_bound(pxp), 250))
+   return -ENXIO;
+   }
  
  	mutex_lock(>arb_mutex);
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h

index b2523d6918c7..9089e02a8c2d 100644
--- 

[PATCH 2/2] drm/i915/pmu: Use correct requested freq for SLPC

2023-03-03 Thread Ashutosh Dixit
SLPC does not use 'struct intel_rps'. Use UNSLICE_RATIO bits from
GEN6_RPNSWREQ for SLPC. See intel_rps_get_requested_frequency.

Bspec: 52745

Signed-off-by: Ashutosh Dixit 
---
 drivers/gpu/drm/i915/i915_pmu.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index f0a1e36915b8..5ee836610801 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -394,8 +394,13 @@ frequency_sample(struct intel_gt *gt, unsigned int 
period_ns)
 * frequency. Fortunately, the read should rarely fail!
 */
val = intel_rps_get_cagf(rps, intel_rps_read_rpstat_fw(rps));
-   if (!val)
-   val = rps->cur_freq;
+   if (!val) {
+   if (intel_uc_uses_guc_slpc(>uc))
+   val = intel_rps_read_punit_req(rps) >>
+   GEN9_SW_REQ_UNSLICE_RATIO_SHIFT;
+   else
+   val = rps->cur_freq;
+   }
 
add_sample_mult(>sample[__I915_SAMPLE_FREQ_ACT],
intel_gpu_freq(rps, val), period_ns / 1000);
-- 
2.38.0



[PATCH 0/2] drm/i915/pmu: Freq sampling: Fix requested freq fallback

2023-03-03 Thread Ashutosh Dixit
A couple of minor fixes to the PMU requested freq fallback for PMU freq
sampling.

Ashutosh Dixit (2):
  drm/i915/pmu: Use only freq bits for falling back to requested freq
  drm/i915/pmu: Use correct requested freq for SLPC

 drivers/gpu/drm/i915/i915_pmu.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

-- 
2.38.0



[PATCH 1/2] drm/i915/pmu: Use only freq bits for falling back to requested freq

2023-03-03 Thread Ashutosh Dixit
On newer generations, the GEN12_RPSTAT1 register contains more than freq
information, e.g. see GEN12_VOLTAGE_MASK. Therefore use only the freq bits
to decide whether to fall back to requested freq.

Signed-off-by: Ashutosh Dixit 
---
 drivers/gpu/drm/i915/i915_pmu.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 52531ab28c5f..f0a1e36915b8 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -393,10 +393,8 @@ frequency_sample(struct intel_gt *gt, unsigned int 
period_ns)
 * case we assume the system is running at the intended
 * frequency. Fortunately, the read should rarely fail!
 */
-   val = intel_rps_read_rpstat_fw(rps);
-   if (val)
-   val = intel_rps_get_cagf(rps, val);
-   else
+   val = intel_rps_get_cagf(rps, intel_rps_read_rpstat_fw(rps));
+   if (!val)
val = rps->cur_freq;
 
add_sample_mult(>sample[__I915_SAMPLE_FREQ_ACT],
-- 
2.38.0



Re: [PATCH v6 4/8] drm/i915/pxp: Add GSC-CS backend to send GSC fw messages

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/27/2023 6:21 PM, Alan Previn wrote:

Add GSC engine based method for sending PXP firmware packets
to the GSC firmware for MTL (and future) products.

Use the newly added helpers to populate the GSC-CS memory
header and send the message packet to the FW by dispatching
the GSC_HECI_CMD_PKT instruction on the GSC engine.

We use non-priveleged batches for submission to GSC engine
which require two buffers for the request:
  - a buffer for the HECI packet that contains PXP FW commands
  - a batch-buffer that contains the engine instruction for
sending the HECI packet to the GSC firmware.

Thus, add the allocation and freeing of these buffers in gsccs
init and fini.

The GSC-fw may reply to commands with a SUCCESS but with an
additional pending-bit set in the reply packet. This bit
means the GSC-FW is currently busy and the caller needs to
try again with the gsc_message_handle the fw gave. The
GSC-fw requires a non-zero host_session_handle provided
by the caller to enable gsc_message_handle tracking.

Thus, allocate the host_session_handle at init and destroy it
at fini (the latter requiring an FYI to the gsc-firmware).
Also ensure the send-message function allows replay of the
gsc_message_handle.

Signed-off-by: Alan Previn 
---
  .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |   4 +
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c| 239 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h|   4 +
  drivers/gpu/drm/i915/pxp/intel_pxp_types.h|   6 +
  4 files changed, 251 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
index ad67e3f49c20..b2523d6918c7 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
@@ -12,6 +12,10 @@
  /* PXP-Cmd-Op definitions */
  #define PXP43_CMDID_START_HUC_AUTH 0x003A
  
+/* PXP-Packet sizes for MTL's GSCCS-HECI instruction */

+#define PXP43_MAX_HECI_IN_SIZE (SZ_32K)
+#define PXP43_MAX_HECI_OUT_SIZE (SZ_32K)
+
  /* PXP-Input-Packet: HUC-Authentication */
  struct pxp43_start_huc_auth_in {
struct pxp_cmd_header header;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
index 13693e78b57e..30aa660a975f 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
@@ -6,19 +6,226 @@
  #include "gem/i915_gem_internal.h"
  
  #include "gt/intel_context.h"

+#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
  
  #include "i915_drv.h"

  #include "intel_pxp_cmd_interface_43.h"
  #include "intel_pxp_gsccs.h"
  #include "intel_pxp_types.h"
  
+static int

+gsccs_send_message(struct intel_pxp *pxp,
+  void *msg_in, size_t msg_in_size,
+  void *msg_out, size_t msg_out_size_max,
+  size_t *msg_out_len,
+  u64 *gsc_msg_handle_retry)
+{
+   struct intel_gt *gt = pxp->ctrl_gt;
+   struct drm_i915_private *i915 = gt->i915;
+   struct gsccs_session_resources *exec =  >gsccs_res;


in the alloc/free functions you called this object *strm_res; IMO better 
to use a consistent naming so it is clear they're the same object



+   struct intel_gsc_mtl_header *header = exec->pkt_vaddr;
+   struct intel_gsc_heci_non_priv_pkt pkt;
+   bool null_pkt = !msg_in && !msg_out;
+   size_t max_msg_size;
+   u32 reply_size;
+   int ret;
+
+   if (!exec->ce)
+   return -ENODEV;
+
+   max_msg_size = PXP43_MAX_HECI_IN_SIZE - sizeof(*header);


Using the same max_msg_size for both in and out only works if 
PXP43_MAX_HECI_IN_SIZE == PXP43_MAX_HECI_OUT_SIZE. This is true now, but 
I'd add a:


BUILD_BUG_ON(PXP43_MAX_HECI_IN_SIZE  != PXP43_MAX_HECI_OUT_SIZE);

just to be safe. Potentially also a:

GEM_BUG_ON(exec->pkt_vma->size < (PXP43_MAX_HECI_IN_SIZE + 
PXP43_MAX_HECI_OUT_SIZE));


After checking that exec->pkt_vma exists.


+
+   if (msg_in_size > max_msg_size || msg_out_size_max > max_msg_size)
+   return -ENOSPC;
+
+   if (!exec->pkt_vma || !exec->bb_vma)
+   return -ENOENT;
+
+   mutex_lock(>tee_mutex);
+
+   memset(header, 0, sizeof(*header));
+   intel_gsc_uc_heci_cmd_emit_mtl_header(header, GSC_HECI_MEADDRESS_PXP,
+ msg_in_size + sizeof(*header),
+ exec->host_session_handle);
+
+   /* check if this is a host-session-handle cleanup call */
+   if (null_pkt)


nit: can't you just use if (!msg_in && !msg_out) instead of a local var? 
not a blocker.



+   header->flags |= GSC_HECI_FLAG_MSG_CLEANUP;
+
+   /* copy caller provided gsc message handle if this is polling for a 
prior msg completion */
+   header->gsc_message_handle = *gsc_msg_handle_retry;
+
+   /* NOTE: zero size packets are used for session-cleanups */
+ 

Re: [PATCH] drm/i915: Set wedged if enable guc communication failed

2023-03-03 Thread Ceraolo Spurio, Daniele




On 3/2/2023 1:50 PM, Zhanjun Dong wrote:

Add err code check for enable_communication on resume path. When resume failed, 
we can no longer use the GPU, marking the GPU as wedged.


This is slightly incorrect. If we fail to enable communication, the 
consequence is that we can't use the GuC. That translates to a failure 
to use the GT only if GuC submission is enabled; in execlists submission 
mode we can keep going, although we might end up losing HuC 
functionality (which is not considered a fatal error). Therefore, the 
code below should be updated to reflect this.




Signed-off-by: Zhanjun Dong 
---
  drivers/gpu/drm/i915/gt/intel_gt_pm.c | 7 ++-
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 9 +++--
  2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index cef3d6f5c34e..42a7d75ce39e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -401,8 +401,13 @@ int intel_gt_runtime_resume(struct intel_gt *gt)
intel_ggtt_restore_fences(gt->ggtt);
  
  	ret = intel_uc_runtime_resume(>uc);

-   if (ret)
+   if (ret) {
+   /* Resume failed, we can no longer use the GPU, marking the GPU
+* as wedged.
+*/
+   intel_gt_set_wedged(gt);


intel_gt_set_wedged calls intel_runtime_pm_get, so it will deadlock if 
you call if from within the runtime_resume flow.



return ret;
+   }
  
  	return 0;

  }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 6648691bd645..d4f428acf20a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -698,8 +698,13 @@ static int __uc_resume(struct intel_uc *uc, bool 
enable_communication)
/* Make sure we enable communication if and only if it's disabled */
GEM_BUG_ON(enable_communication == intel_guc_ct_enabled(>ct));
  
-	if (enable_communication)

-   guc_enable_communication(guc);
+   if (enable_communication) {
+   err = guc_enable_communication(guc);
+   if (err) {
+   guc_dbg(guc, "Failed to resume, %pe", ERR_PTR(err));


nit: this isn't exactly a failure to resume because the GuC is running. 
It's more a failure to re-establish communication with the GuC.


Daniele


+   return err;
+   }
+   }
  
  	/* If we are only resuming GuC communication but not reloading

 * GuC, we need to ensure the ARAT timer interrupt is enabled




Re: [PATCH v9 12/15] drm/msm: Add deadline based boost support

2023-03-03 Thread Dmitry Baryshkov

On 03/03/2023 19:03, Rob Clark wrote:

On Fri, Mar 3, 2023 at 2:10 AM Dmitry Baryshkov
 wrote:


On 03/03/2023 01:53, Rob Clark wrote:

From: Rob Clark 

Track the nearest deadline on a fence timeline and set a timer to expire
shortly before to trigger boost if the fence has not yet been signaled.

v2: rebase

Signed-off-by: Rob Clark 
---
   drivers/gpu/drm/msm/msm_fence.c | 74 +
   drivers/gpu/drm/msm/msm_fence.h | 20 +
   2 files changed, 94 insertions(+)


Reviewed-by: Dmitry Baryshkov 

A small question: do we boost to fit into the deadline or to miss the
deadline for as little as possible? If the former is the case, we might
need to adjust 3ms depending on the workload.


The goal is as much to run with higher clock on the next frame as it
is to not miss a deadline.  Ie. we don't want devfreq to come to the
conclusion that running at <50% clks is best due to the amount of
utilization caused by missing ever other vblank.


Ack, thanks for the explanation.



But 3ms is mostly just "seems like a good compromise" value.  It might change.

BR,
-R



diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c
index 56641408ea74..51b461f32103 100644
--- a/drivers/gpu/drm/msm/msm_fence.c
+++ b/drivers/gpu/drm/msm/msm_fence.c
@@ -8,6 +8,35 @@

   #include "msm_drv.h"
   #include "msm_fence.h"
+#include "msm_gpu.h"
+
+static struct msm_gpu *fctx2gpu(struct msm_fence_context *fctx)
+{
+ struct msm_drm_private *priv = fctx->dev->dev_private;
+ return priv->gpu;
+}
+
+static enum hrtimer_restart deadline_timer(struct hrtimer *t)
+{
+ struct msm_fence_context *fctx = container_of(t,
+ struct msm_fence_context, deadline_timer);
+
+ kthread_queue_work(fctx2gpu(fctx)->worker, >deadline_work);
+
+ return HRTIMER_NORESTART;
+}
+
+static void deadline_work(struct kthread_work *work)
+{
+ struct msm_fence_context *fctx = container_of(work,
+ struct msm_fence_context, deadline_work);
+
+ /* If deadline fence has already passed, nothing to do: */
+ if (msm_fence_completed(fctx, fctx->next_deadline_fence))
+ return;
+
+ msm_devfreq_boost(fctx2gpu(fctx), 2);
+}


   struct msm_fence_context *
@@ -36,6 +65,13 @@ msm_fence_context_alloc(struct drm_device *dev, volatile 
uint32_t *fenceptr,
   fctx->completed_fence = fctx->last_fence;
   *fctx->fenceptr = fctx->last_fence;

+ hrtimer_init(>deadline_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ fctx->deadline_timer.function = deadline_timer;
+
+ kthread_init_work(>deadline_work, deadline_work);
+
+ fctx->next_deadline = ktime_get();
+
   return fctx;
   }

@@ -62,6 +98,8 @@ void msm_update_fence(struct msm_fence_context *fctx, 
uint32_t fence)
   spin_lock_irqsave(>spinlock, flags);
   if (fence_after(fence, fctx->completed_fence))
   fctx->completed_fence = fence;
+ if (msm_fence_completed(fctx, fctx->next_deadline_fence))
+ hrtimer_cancel(>deadline_timer);
   spin_unlock_irqrestore(>spinlock, flags);
   }

@@ -92,10 +130,46 @@ static bool msm_fence_signaled(struct dma_fence *fence)
   return msm_fence_completed(f->fctx, f->base.seqno);
   }

+static void msm_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
+{
+ struct msm_fence *f = to_msm_fence(fence);
+ struct msm_fence_context *fctx = f->fctx;
+ unsigned long flags;
+ ktime_t now;
+
+ spin_lock_irqsave(>spinlock, flags);
+ now = ktime_get();
+
+ if (ktime_after(now, fctx->next_deadline) ||
+ ktime_before(deadline, fctx->next_deadline)) {
+ fctx->next_deadline = deadline;
+ fctx->next_deadline_fence =
+ max(fctx->next_deadline_fence, (uint32_t)fence->seqno);
+
+ /*
+  * Set timer to trigger boost 3ms before deadline, or
+  * if we are already less than 3ms before the deadline
+  * schedule boost work immediately.
+  */
+ deadline = ktime_sub(deadline, ms_to_ktime(3));
+
+ if (ktime_after(now, deadline)) {
+ kthread_queue_work(fctx2gpu(fctx)->worker,
+ >deadline_work);
+ } else {
+ hrtimer_start(>deadline_timer, deadline,
+ HRTIMER_MODE_ABS);
+ }
+ }
+
+ spin_unlock_irqrestore(>spinlock, flags);
+}
+
   static const struct dma_fence_ops msm_fence_ops = {
   .get_driver_name = msm_fence_get_driver_name,
   .get_timeline_name = msm_fence_get_timeline_name,
   .signaled = msm_fence_signaled,
+ .set_deadline = msm_fence_set_deadline,
   };

   struct dma_fence *
diff --git a/drivers/gpu/drm/msm/msm_fence.h b/drivers/gpu/drm/msm/msm_fence.h
index 7f1798c54cd1..cdaebfb94f5c 100644
--- a/drivers/gpu/drm/msm/msm_fence.h
+++ b/drivers/gpu/drm/msm/msm_fence.h
@@ -52,6 +52,26 

Re: [PATCH] dt-bindings: yamllint: Require a space after a comment '#'

2023-03-03 Thread Jakub Kicinski
On Fri,  3 Mar 2023 15:42:23 -0600 Rob Herring wrote:
> Enable yamllint to check the prefered commenting style of requiring a
> space after a comment character '#'. Fix the cases in the tree which
> have a warning with this enabled. Most cases just need a space after the
> '#'. A couple of cases with comments which were not intended to be
> comments are revealed. Those were in ti,sa2ul.yaml, ti,cal.yaml, and
> brcm,bcmgenet.yaml.
> 
> Signed-off-by: Rob Herring 

Acked-by: Jakub Kicinski 


Re: [PATCH] dt-bindings: yamllint: Require a space after a comment '#'

2023-03-03 Thread Dmitry Baryshkov

On 03/03/2023 23:42, Rob Herring wrote:

Enable yamllint to check the prefered commenting style of requiring a
space after a comment character '#'. Fix the cases in the tree which
have a warning with this enabled. Most cases just need a space after the
'#'. A couple of cases with comments which were not intended to be
comments are revealed. Those were in ti,sa2ul.yaml, ti,cal.yaml, and
brcm,bcmgenet.yaml.

Signed-off-by: Rob Herring 
---
Cc: Krzysztof Kozlowski 
Cc: Stephen Boyd 
Cc: Herbert Xu 
Cc: "David S. Miller" 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
Cc: Thomas Gleixner 
Cc: Marc Zyngier 
Cc: Mauro Carvalho Chehab 
Cc: Eric Dumazet 
Cc: Jakub Kicinski 
Cc: Paolo Abeni 
Cc: Andrew Lunn 
Cc: Heiner Kallweit 
Cc: Vinod Koul 
Cc: Kishon Vijay Abraham I 
Cc: Mark Brown 
Cc: Conor Dooley 
Cc: linux-...@vger.kernel.org
Cc: linux-cry...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedr...@lists.freedesktop.org
Cc: linux-me...@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-...@lists.infradead.org
Cc: linux-g...@vger.kernel.org
Cc: alsa-de...@alsa-project.org
Cc: linux-ri...@lists.infradead.org
Cc: linux-...@vger.kernel.org
---
  Documentation/devicetree/bindings/.yamllint   |  2 +-
  .../bindings/clock/qcom,a53pll.yaml   |  4 ++--
  .../devicetree/bindings/crypto/ti,sa2ul.yaml  |  4 ++--
  .../bindings/display/msm/qcom,mdp5.yaml   |  2 +-
  .../interrupt-controller/arm,gic.yaml |  4 ++--
  .../loongson,pch-msi.yaml |  2 +-
  .../bindings/media/renesas,vin.yaml   |  4 ++--
  .../devicetree/bindings/media/ti,cal.yaml |  4 ++--
  .../bindings/net/brcm,bcmgenet.yaml   |  2 --
  .../bindings/net/cortina,gemini-ethernet.yaml |  6 ++---
  .../devicetree/bindings/net/mdio-gpio.yaml|  4 ++--
  .../phy/marvell,armada-cp110-utmi-phy.yaml|  2 +-
  .../bindings/phy/phy-stm32-usbphyc.yaml   |  2 +-
  .../phy/qcom,sc7180-qmp-usb3-dp-phy.yaml  |  2 +-
  .../bindings/pinctrl/pinctrl-mt8192.yaml  |  2 +-
  .../regulator/nxp,pca9450-regulator.yaml  |  8 +++
  .../regulator/rohm,bd71828-regulator.yaml | 20 
  .../regulator/rohm,bd71837-regulator.yaml |  6 ++---
  .../regulator/rohm,bd71847-regulator.yaml |  6 ++---
  .../bindings/soc/renesas/renesas.yaml |  2 +-
  .../devicetree/bindings/soc/ti/ti,pruss.yaml  |  2 +-
  .../bindings/sound/amlogic,axg-tdm-iface.yaml |  2 +-
  .../bindings/sound/qcom,lpass-rx-macro.yaml   |  4 ++--
  .../bindings/sound/qcom,lpass-tx-macro.yaml   |  4 ++--
  .../bindings/sound/qcom,lpass-va-macro.yaml   |  4 ++--
  .../sound/qcom,q6dsp-lpass-ports.yaml |  2 +-
  .../bindings/sound/simple-card.yaml   | 24 +--
  .../bindings/spi/microchip,mpfs-spi.yaml  |  2 +-
  28 files changed, 65 insertions(+), 67 deletions(-)


Reviewed-by: Dmitry Baryshkov  # drm/msm
(and other Qualcom-specific schemas)

--
With best wishes
Dmitry



Re: [PATCH v3] drm/msm/dp: check core_initialized flag at both host_init() and host_deinit()

2023-03-03 Thread Dmitry Baryshkov

On 04/03/2023 00:45, Kuogee Hsieh wrote:


On 3/2/2023 11:04 AM, Dmitry Baryshkov wrote:
On Thu, 2 Mar 2023 at 20:41, Kuogee Hsieh  
wrote:


On 3/1/2023 1:15 PM, Dmitry Baryshkov wrote:

On 01/03/2023 18:57, Kuogee Hsieh wrote:

On 2/28/2023 6:16 PM, Dmitry Baryshkov wrote:

On Wed, 1 Mar 2023 at 02:17, Kuogee Hsieh 
wrote:

There is a reboot/suspend test case where system suspend is forced
during system booting up. Since dp_display_host_init() of external
DP is executed at hpd thread context, this test case may created a
scenario that dp_display_host_deinit() from pm_suspend() run before
dp_display_host_init() if hpd thread has no chance to run during
booting up while suspend request command was issued. At this 
scenario

system will crash at aux register access at dp_display_host_deinit()
since aux clock had not yet been enabled by dp_display_host_init().
Therefore we have to ensure aux clock enabled by checking
core_initialized flag before access aux registers at pm_suspend.

Can a call to dp_display_host_init() be moved from
dp_display_config_hpd() to dp_display_bind()?

yes,  Sankeerth's  "drm/msm/dp: enable pm_runtime support for dp
driver" patch is doing that which is under review.

https://patchwork.freedesktop.org/patch/523879/?series=114297=1

No, he is doing another thing. He is moving these calls to pm_runtime
callbacks, not to the dp_display_bind().


Related question: what is the primary reason for having
EV_HPD_INIT_SETUP and calling dp_display_config_hpd() via the event
thread? Does DP driver really depend on DPU irqs being installed? As
far as I understand, DP device uses MDSS interrupts and those IRQs 
are

available and working at the time of dp_display_probe() /
dp_display_bind().

HDP gpio pin has to run through DP aux module 100ms denouncing logic
and have its mask bits.

Therefore DP irq has to be enabled to receive DP isr with mask bits 
set.

So... DP irq is enabled by the MDSS, not by the DPU. Again, why does
DP driver depend on DPU irqs being installed?

sorry, previously i mis understand your question -- why does DP driver
depend on DPU irqs being installed?

now, I think you are asking why  dpu_irq_postinstall() ==>
msm_dp_irq_postinstall() ==> event_thread ==> dp_display_config_hdp()
==> enable_irq(dp->irq)

With the below test i had run, i think the reason is to make sure
dp->irq be requested before enable it.

I just run the execution timing order test and collect execution order
as descending order at below,

1) dp_display_probe() -- start

2) dp_display_bind()

3) msm_dp_modeset_init()  ==> dp_display_request_irq() ==>
dp_display_get_next_bridge()

4) dpu_irq_postinstall() ==> msm_dp_irq_postinstall() ==>
enable_irq(dp->irq)

5) dp_display_probe() -- end

dp->irq is request at msm_dp_modeset_init() and enabled after.

Should be moved to probe.


That bring up the issue to move DP's dp_display_host_init() executed at
dp_display_bind().

Since eDP have dp_dispaly_host_init() executed at
dp_display_get_next_bridge() which executed after dp_display_bind().

If moved DP's dp_display_host_init() to dp_dispaly_bind() which means DP
will be ready to receive HPD irq before eDP ready.

And the AUX bus population should also be moved to probe(), which
means we should call dp_display_host_init() from probe() too.
Having aux_bus_populate in probe would allow moving component_add() to
the done_probing() callback, making probe/defer case more robust


This may create some uncertainties at execution flow and complicate
things up.

Hopefully the changes suggested above will make it simpler.


ok, I will create another patch to


patchset



1) move dp_display_host_init() to probe()

2) move component_add() to done_probing() for eDP

3) keep DP as simple platform device (component_add() still executed in 
probe())


4) move devm_request_irq() to probe, add IRQF_NO_AUTOEN instead of 
calling disable_irq() right after request_irq()


5) drop DP_HPD_INIT_SETUP and related code



Meanwhile, can you approve this patch so that it will not block our 
internal daily testing?


Quoting your commit message: "Since dp_display_host_init() of external
DP is executed at hpd thread context...". After these changes the 
mentioned function will no longer be executed from the hpd thread. So, 
let's rework the probe/init sequence first, then we can see if this 
patch is still necessary and how should it look.


--
With best wishes
Dmitry



Re: [PATCH v3] drm/msm/dp: check core_initialized flag at both host_init() and host_deinit()

2023-03-03 Thread Kuogee Hsieh



On 3/2/2023 11:04 AM, Dmitry Baryshkov wrote:

On Thu, 2 Mar 2023 at 20:41, Kuogee Hsieh  wrote:


On 3/1/2023 1:15 PM, Dmitry Baryshkov wrote:

On 01/03/2023 18:57, Kuogee Hsieh wrote:

On 2/28/2023 6:16 PM, Dmitry Baryshkov wrote:

On Wed, 1 Mar 2023 at 02:17, Kuogee Hsieh 
wrote:

There is a reboot/suspend test case where system suspend is forced
during system booting up. Since dp_display_host_init() of external
DP is executed at hpd thread context, this test case may created a
scenario that dp_display_host_deinit() from pm_suspend() run before
dp_display_host_init() if hpd thread has no chance to run during
booting up while suspend request command was issued. At this scenario
system will crash at aux register access at dp_display_host_deinit()
since aux clock had not yet been enabled by dp_display_host_init().
Therefore we have to ensure aux clock enabled by checking
core_initialized flag before access aux registers at pm_suspend.

Can a call to dp_display_host_init() be moved from
dp_display_config_hpd() to dp_display_bind()?

yes,  Sankeerth's  "drm/msm/dp: enable pm_runtime support for dp
driver" patch is doing that which is under review.

https://patchwork.freedesktop.org/patch/523879/?series=114297=1

No, he is doing another thing. He is moving these calls to pm_runtime
callbacks, not to the dp_display_bind().


Related question: what is the primary reason for having
EV_HPD_INIT_SETUP and calling dp_display_config_hpd() via the event
thread? Does DP driver really depend on DPU irqs being installed? As
far as I understand, DP device uses MDSS interrupts and those IRQs are
available and working at the time of dp_display_probe() /
dp_display_bind().

HDP gpio pin has to run through DP aux module 100ms denouncing logic
and have its mask bits.

Therefore DP irq has to be enabled to receive DP isr with mask bits set.

So... DP irq is enabled by the MDSS, not by the DPU. Again, why does
DP driver depend on DPU irqs being installed?

sorry, previously i mis understand your question -- why does DP driver
depend on DPU irqs being installed?

now, I think you are asking why  dpu_irq_postinstall() ==>
msm_dp_irq_postinstall() ==> event_thread ==> dp_display_config_hdp()
==> enable_irq(dp->irq)

With the below test i had run, i think the reason is to make sure
dp->irq be requested before enable it.

I just run the execution timing order test and collect execution order
as descending order at below,

1) dp_display_probe() -- start

2) dp_display_bind()

3) msm_dp_modeset_init()  ==> dp_display_request_irq() ==>
dp_display_get_next_bridge()

4) dpu_irq_postinstall() ==> msm_dp_irq_postinstall() ==>
enable_irq(dp->irq)

5) dp_display_probe() -- end

dp->irq is request at msm_dp_modeset_init() and enabled after.

Should be moved to probe.


That bring up the issue to move DP's dp_display_host_init() executed at
dp_display_bind().

Since eDP have dp_dispaly_host_init() executed at
dp_display_get_next_bridge() which executed after dp_display_bind().

If moved DP's dp_display_host_init() to dp_dispaly_bind() which means DP
will be ready to receive HPD irq before eDP ready.

And the AUX bus population should also be moved to probe(), which
means we should call dp_display_host_init() from probe() too.
Having aux_bus_populate in probe would allow moving component_add() to
the done_probing() callback, making probe/defer case more robust


This may create some uncertainties at execution flow and complicate
things up.

Hopefully the changes suggested above will make it simpler.


ok, I will create another patch to

1) move dp_display_host_init() to probe()

2) move component_add() to done_probing() for eDP

3) keep DP as simple platform device (component_add() still executed in 
probe())


Meanwhile, can you approve this patch so that it will not block our 
internal daily testing?








Re: [PATCH v15 00/16] drm: Add Samsung MIPI DSIM bridge

2023-03-03 Thread Marek Szyprowski
Hi Jagan,

On 03.03.2023 15:51, Jagan Teki wrote:
> This series supports common bridge support for Samsung MIPI DSIM
> which is used in Exynos and i.MX8MM SoC's.
>
> The final bridge supports both the Exynos and i.MX8M Mini/Nano/Plus.
>
> Inki Dae: please note that this series added on top of exynos-drm-next
> since few exynos dsi changes are not been part of drm-misc-next.
> Request you to pick these via exynos-drm-next, or let me know if you
> have any comments?

I gave it a try on Exynos TM2e and unfortunately it nukes again:

exynos-drm exynos-drm: bound 1397.hdmi (ops hdmi_component_ops)
Unable to handle kernel paging request at virtual address 003d454d414e5675
...
[003d454d414e5675] address between user and kernel address ranges
Internal error: Oops: 9604 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 9 Comm: kworker/u16:0 Not tainted 6.2.0-next-20230303+ #13341
Hardware name: Samsung TM2E board (DT)
Workqueue: events_unbound deferred_probe_work_func
pstate: 00c5 (nzcv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : drm_connector_list_iter_next+0x58/0x100
lr : drm_connector_list_iter_next+0x2c/0x100
sp : 8bbab910
...
Call trace:
  drm_connector_list_iter_next+0x58/0x100
  drm_mode_config_reset+0xfc/0x144
  exynos_drm_bind+0x160/0x1b8
  try_to_bring_up_aggregate_device+0x168/0x1d4
  __component_add+0xa8/0x170
  component_add+0x14/0x20
  hdmi_probe+0x3fc/0x6d4
  platform_probe+0x68/0xd8
  really_probe+0x148/0x2b4
  __driver_probe_device+0x78/0xe0
  driver_probe_device+0xd8/0x160
  __device_attach_driver+0xb8/0x138
  bus_for_each_drv+0x84/0xe0
  __device_attach+0xa8/0x1b0
  device_initial_probe+0x14/0x20
  bus_probe_device+0xb0/0xb4
  deferred_probe_work_func+0x8c/0xc8
  process_one_work+0x288/0x6c8
  worker_thread+0x24c/0x450
  kthread+0x118/0x11c
  ret_from_fork+0x10/0x20
Code: 54000580 d1008061 f90006c1 9100c064 (b9403061)
---[ end trace  ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: disabled
CPU features: 0x460002,0e3c0400,421b
Memory Limit: none
---[ end Kernel panic - not syncing: Oops: Fatal exception ]---


The debugging saga strikes again. I will try to analyze this on Monday...


> Patch 0001 - 0002: find child DSI bridge and panel
>
> Patch 0003 - 0004: optional PHY, PMS_P offset
>
> Patch 0005   : introduce hw_type
>
> Patch 0006 : fixing host init
>
> Patch 0007 : atomic_check
>
> Patch 0008 : input_bus_flags
>
> Patch 0009 : atomic_get_input_bus_fmts
>
> Patch 0010 - 0011: component vs bridge
>
> Patch 0012 : DSIM bridge
>
> Patch 0013 - 0014: i.MX8M Mini/Nano
>
> Patch 0015 - 0016: i.MX8M Plus
>
> Changes for v15:
> - drop drm_of helpers
> - re-added find DSI bridge/Panel helper in dsim
> - collect RB from Marek V
> - fixed leading underscore in function names
> - commit messages updated
> - rebased on exynos-drm-next
>
> Changes for v13:
> - remove devm call for DSI panel or bridge finding
> - rebased on drm-misc-next
>
> Changes for v12:
> - collect RB from Marek V
> - add te_irq_handler hook
> - fix comments from Marek V
> - update atomic_get_input_bus_fmts logic
>
> Changes for v11:
> - collect RB from Frieder Schrempf
> - collect ACK from Rob
> - collect ACK from Robert
> - fix BIT macro replacements
> - fix checkpatch --strict warnings
> - fix unneeded commit text
> - drop extra lines
>
> Changes for v10:
> - rebase on drm-misc-next
> - add drm_of_dsi_find_panel_or_bridge
> - add devm_drm_of_dsi_get_bridge
> - fix host initialization (Thanks to Marek Szyprowski)
> - rearrange the tiny patches for easy to review
> - update simple names for enum hw_type
> - add is_hw_exynos macro
> - rework on commit messages
>
> Changes for v9:
> - rebase on drm-misc-next
> - drop drm bridge attach fix for Exynos
> - added prepare_prev_first flag
> - added pre_enable_prev_first flag
> - fix bridge chain order for exynos
> - added fix for Exynos host init for first DSI transfer
> - added MEDIA_BUS_FMT_FIXED
> - return MEDIA_BUS_FMT_RGB888_1X24 output_fmt if supported output_fmt
>list is unsupported.
> - added MEDIA_BUS_FMT_YUYV10_1X20
> - added MEDIA_BUS_FMT_YUYV12_1X24
>
> Changes for v8:
> * fixed comment lines
> * fixed commit messages
> * fixed video mode bits
> * collect Marek Ack
> * fixed video mode bit names
> * update input formats logic
> * added imx8mplus support
>
> Changes for v7:
> * fix the drm bridge attach chain for exynos drm dsi driver
> * fix the hw_type checking logic
>
> Changes for v6:
> * handle previous bridge for exynos dsi while attaching bridge
>
> Changes for v5:
> * bridge changes to support multi-arch
> * updated and clear commit messages
>

Re: [PATCH 00/17] MODULE_LICENSE removals, sixth tranche

2023-03-03 Thread Luis Chamberlain
Stupid question, if you're removing MODULE_LICENSE() than why keep the
other stupid MODULE_*() crap too? If its of no use, be gone!

  Luis


Re: [PATCH] drm/amdgpu: remove dead code

2023-03-03 Thread Alex Deucher
Applied.  Thanks!

Alex

On Fri, Mar 3, 2023 at 7:03 AM Muhammad Usama Anjum
 wrote:
>
> The less than zero comparison of unsigned variable "value" is never
> true. Remove dead code.
>
> Fixes: c3ed0e72c872 ("drm/amdgpu: added a sysfs interface for thermal 
> throttling")
> Signed-off-by: Muhammad Usama Anjum 
> ---
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index f212cae0353f..0ffe351c1a1d 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -1738,7 +1738,7 @@ static ssize_t amdgpu_set_apu_thermal_cap(struct device 
> *dev,
> if (ret)
> return ret;
>
> -   if (value < 0 || value > 100) {
> +   if (value > 100) {
> dev_err(dev, "Invalid argument !\n");
> return -EINVAL;
> }
> --
> 2.39.2
>


Re: [PATCH] dt-bindings: yamllint: Require a space after a comment '#'

2023-03-03 Thread Conor Dooley
On Fri, Mar 03, 2023 at 03:42:23PM -0600, Rob Herring wrote:
> Enable yamllint to check the prefered commenting style of requiring a
> space after a comment character '#'. Fix the cases in the tree which
> have a warning with this enabled. Most cases just need a space after the
> '#'. A couple of cases with comments which were not intended to be
> comments are revealed. Those were in ti,sa2ul.yaml, ti,cal.yaml, and
> brcm,bcmgenet.yaml.
> 
> Signed-off-by: Rob Herring 
> ---

> Cc: Conor Dooley 

> diff --git a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml 
> b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
> index 1051690e3753..74a817cc7d94 100644
> --- a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
> +++ b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
> @@ -22,7 +22,7 @@ properties:
>- items:
>- const: microchip,mpfs-qspi
>- const: microchip,coreqspi-rtl-v2
> -  - const: microchip,coreqspi-rtl-v2 #FPGA QSPI
> +  - const: microchip,coreqspi-rtl-v2 # FPGA QSPI
>- const: microchip,mpfs-spi

I had to think for a minute as to what that comment even meant...
Reviewed-by: Conor Dooley 

Thanks,
Conor.


signature.asc
Description: PGP signature


[PATCH AUTOSEL 5.15 41/50] drivers: base: component: fix memory leak with using debugfs_lookup()

2023-03-03 Thread Sasha Levin
From: Greg Kroah-Hartman 

[ Upstream commit 8deb87b1e810dd558371e88ffd44339fbef27870 ]

When calling debugfs_lookup() the result must have dput() called on it,
otherwise the memory will leak over time.  To make things simpler, just
call debugfs_lookup_and_remove() instead which handles all of the logic
at once.

Cc: "Rafael J. Wysocki" 
Link: 
https://lore.kernel.org/r/20230202141621.2296458-1-gre...@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/base/component.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 870485cbbb87c..058f1a2cb2a9a 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -130,7 +130,7 @@ static void component_master_debugfs_add(struct master *m)
 
 static void component_master_debugfs_del(struct master *m)
 {
-   debugfs_remove(debugfs_lookup(dev_name(m->parent), 
component_debugfs_dir));
+   debugfs_lookup_and_remove(dev_name(m->parent), component_debugfs_dir);
 }
 
 #else
-- 
2.39.2



[PATCH AUTOSEL 6.1 48/60] drivers: base: component: fix memory leak with using debugfs_lookup()

2023-03-03 Thread Sasha Levin
From: Greg Kroah-Hartman 

[ Upstream commit 8deb87b1e810dd558371e88ffd44339fbef27870 ]

When calling debugfs_lookup() the result must have dput() called on it,
otherwise the memory will leak over time.  To make things simpler, just
call debugfs_lookup_and_remove() instead which handles all of the logic
at once.

Cc: "Rafael J. Wysocki" 
Link: 
https://lore.kernel.org/r/20230202141621.2296458-1-gre...@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/base/component.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 5eadeac6c5322..7dbf14a1d9157 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -125,7 +125,7 @@ static void component_debugfs_add(struct aggregate_device 
*m)
 
 static void component_debugfs_del(struct aggregate_device *m)
 {
-   debugfs_remove(debugfs_lookup(dev_name(m->parent), 
component_debugfs_dir));
+   debugfs_lookup_and_remove(dev_name(m->parent), component_debugfs_dir);
 }
 
 #else
-- 
2.39.2



[PATCH AUTOSEL 6.2 52/64] drivers: base: component: fix memory leak with using debugfs_lookup()

2023-03-03 Thread Sasha Levin
From: Greg Kroah-Hartman 

[ Upstream commit 8deb87b1e810dd558371e88ffd44339fbef27870 ]

When calling debugfs_lookup() the result must have dput() called on it,
otherwise the memory will leak over time.  To make things simpler, just
call debugfs_lookup_and_remove() instead which handles all of the logic
at once.

Cc: "Rafael J. Wysocki" 
Link: 
https://lore.kernel.org/r/20230202141621.2296458-1-gre...@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/base/component.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 5eadeac6c5322..7dbf14a1d9157 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -125,7 +125,7 @@ static void component_debugfs_add(struct aggregate_device 
*m)
 
 static void component_debugfs_del(struct aggregate_device *m)
 {
-   debugfs_remove(debugfs_lookup(dev_name(m->parent), 
component_debugfs_dir));
+   debugfs_lookup_and_remove(dev_name(m->parent), component_debugfs_dir);
 }
 
 #else
-- 
2.39.2



[PATCH] dt-bindings: yamllint: Require a space after a comment '#'

2023-03-03 Thread Rob Herring
Enable yamllint to check the prefered commenting style of requiring a
space after a comment character '#'. Fix the cases in the tree which
have a warning with this enabled. Most cases just need a space after the
'#'. A couple of cases with comments which were not intended to be
comments are revealed. Those were in ti,sa2ul.yaml, ti,cal.yaml, and
brcm,bcmgenet.yaml.

Signed-off-by: Rob Herring 
---
Cc: Krzysztof Kozlowski 
Cc: Stephen Boyd 
Cc: Herbert Xu 
Cc: "David S. Miller" 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
Cc: Thomas Gleixner 
Cc: Marc Zyngier 
Cc: Mauro Carvalho Chehab 
Cc: Eric Dumazet 
Cc: Jakub Kicinski 
Cc: Paolo Abeni 
Cc: Andrew Lunn 
Cc: Heiner Kallweit 
Cc: Vinod Koul 
Cc: Kishon Vijay Abraham I 
Cc: Mark Brown 
Cc: Conor Dooley 
Cc: linux-...@vger.kernel.org
Cc: linux-cry...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedr...@lists.freedesktop.org
Cc: linux-me...@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-...@lists.infradead.org
Cc: linux-g...@vger.kernel.org
Cc: alsa-de...@alsa-project.org
Cc: linux-ri...@lists.infradead.org
Cc: linux-...@vger.kernel.org
---
 Documentation/devicetree/bindings/.yamllint   |  2 +-
 .../bindings/clock/qcom,a53pll.yaml   |  4 ++--
 .../devicetree/bindings/crypto/ti,sa2ul.yaml  |  4 ++--
 .../bindings/display/msm/qcom,mdp5.yaml   |  2 +-
 .../interrupt-controller/arm,gic.yaml |  4 ++--
 .../loongson,pch-msi.yaml |  2 +-
 .../bindings/media/renesas,vin.yaml   |  4 ++--
 .../devicetree/bindings/media/ti,cal.yaml |  4 ++--
 .../bindings/net/brcm,bcmgenet.yaml   |  2 --
 .../bindings/net/cortina,gemini-ethernet.yaml |  6 ++---
 .../devicetree/bindings/net/mdio-gpio.yaml|  4 ++--
 .../phy/marvell,armada-cp110-utmi-phy.yaml|  2 +-
 .../bindings/phy/phy-stm32-usbphyc.yaml   |  2 +-
 .../phy/qcom,sc7180-qmp-usb3-dp-phy.yaml  |  2 +-
 .../bindings/pinctrl/pinctrl-mt8192.yaml  |  2 +-
 .../regulator/nxp,pca9450-regulator.yaml  |  8 +++
 .../regulator/rohm,bd71828-regulator.yaml | 20 
 .../regulator/rohm,bd71837-regulator.yaml |  6 ++---
 .../regulator/rohm,bd71847-regulator.yaml |  6 ++---
 .../bindings/soc/renesas/renesas.yaml |  2 +-
 .../devicetree/bindings/soc/ti/ti,pruss.yaml  |  2 +-
 .../bindings/sound/amlogic,axg-tdm-iface.yaml |  2 +-
 .../bindings/sound/qcom,lpass-rx-macro.yaml   |  4 ++--
 .../bindings/sound/qcom,lpass-tx-macro.yaml   |  4 ++--
 .../bindings/sound/qcom,lpass-va-macro.yaml   |  4 ++--
 .../sound/qcom,q6dsp-lpass-ports.yaml |  2 +-
 .../bindings/sound/simple-card.yaml   | 24 +--
 .../bindings/spi/microchip,mpfs-spi.yaml  |  2 +-
 28 files changed, 65 insertions(+), 67 deletions(-)

diff --git a/Documentation/devicetree/bindings/.yamllint 
b/Documentation/devicetree/bindings/.yamllint
index 214abd3ec440..4abe9f0a1d46 100644
--- a/Documentation/devicetree/bindings/.yamllint
+++ b/Documentation/devicetree/bindings/.yamllint
@@ -19,7 +19,7 @@ rules:
   colons: {max-spaces-before: 0, max-spaces-after: 1}
   commas: {min-spaces-after: 1, max-spaces-after: 1}
   comments:
-require-starting-space: false
+require-starting-space: true
 min-spaces-from-content: 1
   comments-indentation: disable
   document-start:
diff --git a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml 
b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
index 525ebaa93c85..64bfd0f5d4d0 100644
--- a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
@@ -45,14 +45,14 @@ required:
 additionalProperties: false
 
 examples:
-  #Example 1 - A53 PLL found on MSM8916 devices
+  # Example 1 - A53 PLL found on MSM8916 devices
   - |
 a53pll: clock@b016000 {
 compatible = "qcom,msm8916-a53pll";
 reg = <0xb016000 0x40>;
 #clock-cells = <0>;
 };
-  #Example 2 - A53 PLL found on IPQ6018 devices
+  # Example 2 - A53 PLL found on IPQ6018 devices
   - |
 a53pll_ipq: clock-controller@b116000 {
 compatible = "qcom,ipq6018-a53pll";
diff --git a/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml 
b/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml
index 0c15fefb6671..77ec8bc70bf7 100644
--- a/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml
+++ b/Documentation/devicetree/bindings/crypto/ti,sa2ul.yaml
@@ -26,8 +26,8 @@ properties:
   dmas:
 items:
   - description: TX DMA Channel
-  - description: RX DMA Channel #1
-  - description: RX DMA Channel #2
+  - description: 'RX DMA Channel #1'
+  - description: 'RX DMA Channel #2'
 
   dma-names:
 items:
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
index ef461ad6ce4a..a763cf8da122 100644
--- 

Re: [PATCH] drm/amd/display: Simplify same effect if/else blocks

2023-03-03 Thread Hamza Mahfooz

On 1/15/23 05:00, Deepak R Varma wrote:

The if / else block code has same effect irrespective of the logical
evaluation.  Hence, simply the implementation by removing the unnecessary
conditional evaluation. While at it, also fix the long line checkpatch
complaint. Issue identified using cond_no_effect.cocci Coccinelle
semantic patch script.

Signed-off-by: Deepak R Varma 


Applied, thanks!


---
Please note: The proposed change is compile tested only. If there are any
inbuilt test cases that I should run for further verification, I will appreciate
guidance about it. Thank you.

  drivers/gpu/drm/amd/display/dc/core/dc.c | 11 +++
  1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 0cb8d1f934d1..776209e5d21f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3470,14 +3470,9 @@ static void commit_planes_for_stream(struct dc *dc,
/* Since phantom pipe programming is moved to 
post_unlock_program_front_end,
 * move the SubVP lock to after the phantom pipes have been 
setup
 */
-   if (should_lock_all_pipes && 
dc->hwss.interdependent_update_lock) {
-   if (dc->hwss.subvp_pipe_control_lock)
-   dc->hwss.subvp_pipe_control_lock(dc, context, 
false, should_lock_all_pipes, NULL, subvp_prev_use);
-   } else {
-   if (dc->hwss.subvp_pipe_control_lock)
-   dc->hwss.subvp_pipe_control_lock(dc, context, 
false, should_lock_all_pipes, NULL, subvp_prev_use);
-   }
-
+   if (dc->hwss.subvp_pipe_control_lock)
+   dc->hwss.subvp_pipe_control_lock(dc, context, false, 
should_lock_all_pipes,
+NULL, subvp_prev_use);
return;
}
  


--
Hamza



Re: [PATCH] drm/etnaviv: fix reference leak when mmaping imported buffer

2023-03-03 Thread Christian Gmeiner
>
> drm_gem_prime_mmap() takes a reference on the GEM object, but before that
> drm_gem_mmap_obj() already takes a reference, which will be leaked as only
> one reference is dropped when the mapping is closed. Drop the extra
> reference when dma_buf_mmap() succeeds.
>
> Signed-off-by: Lucas Stach 

Reviewed-by: Christian Gmeiner 

> ---
>  drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 10 +-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c 
> b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
> index 7031db145a77..3524b5811682 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
> @@ -91,7 +91,15 @@ static void *etnaviv_gem_prime_vmap_impl(struct 
> etnaviv_gem_object *etnaviv_obj)
>  static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
> struct vm_area_struct *vma)
>  {
> -   return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
> +   int ret;
> +
> +   ret = dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
> +   if (!ret) {
> +   /* Drop the reference acquired by drm_gem_mmap_obj(). */
> +   drm_gem_object_put(_obj->base);
> +   }
> +
> +   return ret;
>  }
>
>  static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = {
> --
> 2.30.2
>


-- 
greets
--
Christian Gmeiner, MSc

https://christian-gmeiner.info/privacypolicy


Re: [PATCH v6] drm/virtio: Add option to disable KMS support

2023-03-03 Thread Dmitry Osipenko
On 3/3/23 02:35, Rob Clark wrote:
> From: Rob Clark 
> 
> Add a build option to disable modesetting support.  This is useful in
> cases where the guest only needs to use the GPU in a headless mode, or
> (such as in the CrOS usage) window surfaces are proxied to a host
> compositor.
> 
> As the modesetting ioctls are a big surface area for potential security
> bugs to be found (it's happened in the past, we should assume it will
> again in the future), it makes sense to have a build option to disable
> those ioctls in cases where they serve no legitimate purpose.
> 
> v2: Use more if (IS_ENABLED(...))
> v3: Also permit the host to advertise no scanouts
> v4: Spiff out commit msg
> v5: Make num_scanouts==0 and DRM_VIRTIO_GPU_KMS=n behave the same
> v6: Drop conditionally building virtgpu_display.c and early-out of
> it's init/fini fxns instead
> 
> Signed-off-by: Rob Clark 
> Reviewed-by: Dmitry Osipenko 
> Reviewed-by: Javier Martinez Canillas 
> ---

Applied to misc-next

-- 
Best regards,
Dmitry



Re: [PATCH] drm/amd/display: Simplify same effect if/else blocks

2023-03-03 Thread Harry Wentland



On 3/2/23 11:37, Harry Wentland wrote:
> 
> 
> On 3/1/23 15:21, Deepak R Varma wrote:
>> On Mon, Jan 23, 2023 at 12:23:19AM +0530, Deepak R Varma wrote:
>>> On Sun, Jan 15, 2023 at 12:52:10PM -0800, Joe Perches wrote:
 On Sun, 2023-01-15 at 15:30 +0530, Deepak R Varma wrote:
> The if / else block code has same effect irrespective of the logical
> evaluation.  Hence, simply the implementation by removing the unnecessary
> conditional evaluation. While at it, also fix the long line checkpatch
> complaint. Issue identified using cond_no_effect.cocci Coccinelle
> semantic patch script.
>
> Signed-off-by: Deepak R Varma 
> ---
> Please note: The proposed change is compile tested only. If there are any
> inbuilt test cases that I should run for further verification, I will 
> appreciate
> guidance about it. Thank you.

 Preface: I do not know the code.

 Perhaps Rodrigo Siqueira made a copy/paste error submitting the code for
 commit 9114b55fabae ("drm/amd/display: Fix SubVP control flow in the MPO 
 context")
 as the code prior to this change is identical.

 Perhaps one of the false uses should be true or dependent on the
 interdependent_update_lock state.
>>>
>>> Thank you Joe for the recommendation.
>>>
>>> Hi Rodrigo,
>>> Can you review and comment on if and what is wrong with your commit?
>>
>> Hello Rodrigo, Alex,
>> Could you please suggest what would be the necessary fix for this typo error?
>>
> 
> It's not quite a "typo" error. When I look at this code in our internal repo 
> I see
> a couple missing lock calls here that differ between the two cases. I don't 
> know why
> this was never ported over and am surprised it doesn't lead to issues.
> 
> I would prefer we keep the code as-is for now until this gets sorted.
> 

Actually I was wrong. Too many similar-looking snippets in this
function made me look at the wrong thing. This change is fine and
Reviewed-by: Harry Wentland  Harry
> 
>> Thank you,
>> Deepak.
>>
>>>
>>> Thank you,
>>> ./drv
>>>

> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc.c
 []
> @@ -3470,14 +3470,9 @@ static void commit_planes_for_stream(struct dc *dc,
>   /* Since phantom pipe programming is moved to 
> post_unlock_program_front_end,
>* move the SubVP lock to after the phantom pipes have been 
> setup
>*/
> - if (should_lock_all_pipes && 
> dc->hwss.interdependent_update_lock) {
> - if (dc->hwss.subvp_pipe_control_lock)
> - dc->hwss.subvp_pipe_control_lock(dc, context, 
> false, should_lock_all_pipes, NULL, subvp_prev_use);
> - } else {
> - if (dc->hwss.subvp_pipe_control_lock)
> - dc->hwss.subvp_pipe_control_lock(dc, context, 
> false, should_lock_all_pipes, NULL, subvp_prev_use);
> - }
> -

 Perhaps something like:

if (dc->hwss.subvp_pipe_control_lock)
dc->hwss.subvp_pipe_control_lock(dc, context,
 should_lock_all_pipes 
 &&
 
 dc->hwss.interdependent_update_lock,
 should_lock_all_pipes, 
 NULL, subvp_prev_use);

> + if (dc->hwss.subvp_pipe_control_lock)
> + dc->hwss.subvp_pipe_control_lock(dc, context, false, 
> should_lock_all_pipes,
> +  NULL, subvp_prev_use);
>   return;
>   }
>  

>>>
>>>
>>
>>
> 



Re: [PATCH] drm/i915/pxp: limit drm-errors or warning on firmware API failures

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/3/2023 9:48 PM, Alan Previn wrote:

MESA driver is creating protected context on every driver handle
creation to query caps bits for app. So when running CI tests,
they are observing hundreds of drm_errors when enabling PXP
in .config but using SOC fusing or BIOS configuration that cannot
support PXP sessions.

The fixes tag referenced below was to resolve a related issue
where we wanted to silence error messages, but that case was due
to outdated IFWI (firmware) that definitely needed an upgrade and
was, at that point, considered a one-off case as opposed to today's
realization that default CI was enabling PXP in kernel config for
all testing.

So with this patch, let's strike a balance between issues that is
critical but are root-caused from HW/platform gaps (louder drm-warn
but just ONCE) vs other cases where it could also come from session
state machine (which cannot be a WARN_ONCE since it can be triggered
due to runtime operation events).

Let's use helpers for these so as more functions are added in future
features / HW (or as FW designers continue to bless upstreaming of
the error codes and meanings), we only need to update the helpers.

NOTE: Don't completely remove FW errors (via drm_debug) or else cusomer
apps that really needs to know that content protection failed won't
be aware of it.

Fixes: b762787bf767 ("drm/i915/pxp: Use drm_dbg if arb session failed due to fw 
version")
Signed-off-by: Alan Previn 
---
  .../i915/pxp/intel_pxp_cmd_interface_cmn.h|  3 +
  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  2 +-
  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 73 +++
  3 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
index ae9b151b7cb7..6f6541d5e49a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
@@ -18,6 +18,9 @@
  enum pxp_status {
PXP_STATUS_SUCCESS = 0x0,
PXP_STATUS_ERROR_API_VERSION = 0x1002,
+   PXP_STATUS_NOT_READY = 0x100e,
+   PXP_STATUS_PLATFCONFIG_KF1_NOVERIF = 0x101a,
+   PXP_STATUS_PLATFCONFIG_KF1_BAD = 0x101f,
PXP_STATUS_OP_NOT_PERMITTED = 0x4013
  };
  
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c

index 448cacb0465d..7de849cb6c47 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -74,7 +74,7 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
  
  	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true);

if (ret) {
-   drm_err(>i915->drm, "arb session failed to go in play\n");
+   drm_dbg(>i915->drm, "arb session failed to go in play\n");
return ret;
}
drm_dbg(>i915->drm, "PXP ARB session is alive\n");
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index d9d248b48093..2d3bcff93da3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -19,6 +19,37 @@
  #include "intel_pxp_tee.h"
  #include "intel_pxp_types.h"
  
+static bool

+is_fw_err_platform_config(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return true;
+   default:
+   break;
+   }
+   return false;
+}
+
+static const char *
+fw_err_to_string(u32 type)
+{
+   switch (type) {
+   case PXP_STATUS_ERROR_API_VERSION:
+   return "ERR_API_VERSION";
+   case PXP_STATUS_NOT_READY:
+   return "ERR_NOT_READY";
+   case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+   case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+   return "ERR_PLATFORM_CONFIG";
+   default:
+   break;
+   }
+   return NULL;
+}
+
  static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
void *msg_in, u32 msg_in_size,
void *msg_out, u32 msg_out_max_size,
@@ -307,15 +338,21 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp 
*pxp,
   _out, sizeof(msg_out),
   NULL);
  
-	if (ret)

-   drm_err(>drm, "Failed to send tee msg ret=[%d]\n", ret);
-   else if (msg_out.header.status == PXP_STATUS_ERROR_API_VERSION)
-   drm_dbg(>drm, "PXP firmware version unsupported, requested: 
"
-   "CMD-ID-[0x%08x] on API-Ver-[0x%08x]\n",
-   msg_in.header.command_id, msg_in.header.api_version);
-   else if (msg_out.header.status != 0x0)
-   drm_warn(>drm, "PXP firmware failed arb session init request 
ret=[0x%08x]\n",
-

Re: [Intel-gfx] [PATCH 2/2] drm/i915/guc: Allow for very slow GuC loading

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/17/2023 3:47 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

A failure to load the GuC is occasionally observed where the GuC log
actually showed that the GuC had loaded just fine. The implication
being that the load just took ever so slightly longer than the 200ms
timeout. Given that the actual time should be tens of milliseconds at
the slowest, this should never happen. So far the issue has generally
been caused by a bad IFWI resulting in low frequencies during boot
(depsite the KMD requesting max frequency). However, the issue seems
to happen more often than one would like.

So a) increase the timeout so that the user still gets a working
system even in the case of slow load. And b) report the frequency
during the load to see if that is the case of the slow down.


Some refs would be good here. From a quick search, these seems to match:

https://gitlab.freedesktop.org/drm/intel/-/issues/7931
https://gitlab.freedesktop.org/drm/intel/-/issues/8060
https://gitlab.freedesktop.org/drm/intel/-/issues/8083
https://gitlab.freedesktop.org/drm/intel/-/issues/8136
https://gitlab.freedesktop.org/drm/intel/-/issues/8137



Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 37 +--
  1 file changed, 34 insertions(+), 3 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 2f5942606913d..72e003f50617d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -12,6 +12,7 @@
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_mcr.h"
  #include "gt/intel_gt_regs.h"
+#include "gt/intel_rps.h"
  #include "intel_guc_fw.h"
  #include "intel_guc_print.h"
  #include "i915_drv.h"
@@ -139,9 +140,12 @@ static int guc_wait_ucode(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
struct intel_uncore *uncore = gt->uncore;
+   ktime_t before, after, delta;
bool success;
u32 status;
-   int ret;
+   int ret, count;
+   u64 delta_ms;
+   u32 before_freq;
  
  	/*

 * Wait for the GuC to start up.
@@ -159,13 +163,32 @@ static int guc_wait_ucode(struct intel_guc *guc)
 * issues to be resolved. In the meantime bump the timeout to
 * 200ms. Even at slowest clock, this should be sufficient. And
 * in the working case, a larger timeout makes no difference.
+*
+* IFWI updates have also been seen to cause sporadic failures due to
+* the requested frequency not being granted and thus the firmware
+* load is attempted at minimum frequency. That can lead to load times
+* in the seconds range. However, there is a limit on how long an
+* individual wait_for() can wait. So wrap it in a loop.
 */
-   ret = wait_for(guc_load_done(uncore, , ), 200);
+   before_freq = intel_rps_read_actual_frequency(>gt->rps);
+   before = ktime_get();
+   for (count = 0; count < 20; count++) {
+   ret = wait_for(guc_load_done(uncore, , ), 1000);


Isn't 20 secs a bit too long for an in-place wait? I get that if the GuC 
doesn't load (or fail to) within a few secs the HW is likely toast, but 
still that seems a bit too long to me. What's the worst case load time 
ever observed? I suggest reducing the wait to 3 secs as a compromise, if 
that's bigger than the worst case.


The patch LGTM apart from this point.

Daniele


+   if (!ret || !success)
+   break;
+
+   guc_dbg(guc, "load still in progress, count = %d, freq = 
%dMHz\n",
+   count, 
intel_rps_read_actual_frequency(>gt->rps));
+   }
+   after = ktime_get();
+   delta = ktime_sub(after, before);
+   delta_ms = ktime_to_ms(delta);
if (ret || !success) {
u32 ukernel = REG_FIELD_GET(GS_UKERNEL_MASK, status);
u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);
  
-		guc_info(guc, "load failed: status = 0x%08X, ret = %d\n", status, ret);

+   guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = 
%dMHz, ret = %d\n",
+status, delta_ms, 
intel_rps_read_actual_frequency(>gt->rps), ret);
guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, 
UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n",
 REG_FIELD_GET(GS_MIA_IN_RESET, status),
 bootrom, ukernel,
@@ -206,6 +229,14 @@ static int guc_wait_ucode(struct intel_guc *guc)
/* Uncommon/unexpected error, see earlier status code print for 
details */
if (ret == 0)
ret = -ENXIO;
+   } else if (delta_ms > 200) {
+   guc_warn(guc, "excessive init time: %lldms! [freq = %dMHz, before = 
%dMHz, status = 0x%08X, count = %d, ret = %d]\n",
+delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
+ 

Re: [Intel-gfx] [PATCH 1/2] drm/i915/guc: Improve GuC load error reporting

2023-03-03 Thread Ceraolo Spurio, Daniele




On 2/17/2023 3:47 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

There are multiple ways in which the GuC load can fail. The driver was
reporting the status register as is, but not everyone can read the
matrix unfiltered. So add decoding of the common error cases.

Also, remove the comment about interrupt based load completion
checking being not recommended. The interrupt was removed from the GuC
firmware some time ago so it is no longer an option anyway. While at
it, also abort the timeout if a known error code is reported. No need
to keep waiting if the GuC has already given up the load.

Signed-off-by: John Harrison 
---
  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   | 17 
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 95 +++
  drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h|  4 +-
  3 files changed, 95 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index 8085fb1812748..750fe0c6d8529 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -21,6 +21,9 @@ enum intel_guc_load_status {
INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH   = 0x02,
INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH   = 0x03,
INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE  = 0x04,
+   INTEL_GUC_LOAD_STATUS_HWCONFIG_START   = 0x05,
+   INTEL_GUC_LOAD_STATUS_HWCONFIG_DONE= 0x06,
+   INTEL_GUC_LOAD_STATUS_HWCONFIG_ERROR   = 0x07,
INTEL_GUC_LOAD_STATUS_GDT_DONE = 0x10,
INTEL_GUC_LOAD_STATUS_IDT_DONE = 0x20,
INTEL_GUC_LOAD_STATUS_LAPIC_DONE   = 0x30,
@@ -38,4 +41,18 @@ enum intel_guc_load_status {
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
  };
  
+enum intel_bootrom_load_status {

+   INTEL_BOOTROM_STATUS_NO_KEY_FOUND = 0x13,
+   INTEL_BOOTROM_STATUS_AES_PROD_KEY_FOUND   = 0x1A,
+   INTEL_BOOTROM_STATUS_RSA_FAILED   = 0x50,
+   INTEL_BOOTROM_STATUS_PAVPC_FAILED = 0x73,
+   INTEL_BOOTROM_STATUS_WOPCM_FAILED = 0x74,
+   INTEL_BOOTROM_STATUS_LOADLOC_FAILED   = 0x75,
+   INTEL_BOOTROM_STATUS_JUMP_PASSED  = 0x76,
+   INTEL_BOOTROM_STATUS_JUMP_FAILED  = 0x77,
+   INTEL_BOOTROM_STATUS_RC6CTXCONFIG_FAILED  = 0x79,
+   INTEL_BOOTROM_STATUS_MPUMAP_INCORRECT = 0x7a,


nit: you've used uppercase for the other hex characters, while only this 
one has a lowercase "a"



+   INTEL_BOOTROM_STATUS_EXCEPTION= 0x7E,
+};


I've double checked the defines against the specs and they all match.


+
  #endif /* _ABI_GUC_ERRORS_ABI_H */
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 69133420c78b2..2f5942606913d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -88,31 +88,64 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
  /*
   * Read the GuC status register (GUC_STATUS) and store it in the
   * specified location; then return a boolean indicating whether
- * the value matches either of two values representing completion
- * of the GuC boot process.
+ * the value matches either completion or a known failure code.
   *
   * This is used for polling the GuC status in a wait_for()
   * loop below.
   */
-static inline bool guc_ready(struct intel_uncore *uncore, u32 *status)
+static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, 
bool *success)
  {
u32 val = intel_uncore_read(uncore, GUC_STATUS);
u32 uk_val = REG_FIELD_GET(GS_UKERNEL_MASK, val);
+   u32 br_val = REG_FIELD_GET(GS_BOOTROM_MASK, val);
  
  	*status = val;

-   return uk_val == INTEL_GUC_LOAD_STATUS_READY;
+   *success = true;


It feels a bit weird to default this to true. If we don't return true 
from one of the switches below, we can end up returning false from the 
wait but leaving success to true. I understand that this is used more as 
a "not failed" flag rather than a success one, so it is functionally 
correct, but maybe rename it? not a blocker.


Apart from the nits, the patch LGTM:

Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   switch (uk_val) {
+   case INTEL_GUC_LOAD_STATUS_READY:
+   return true;
+
+   case INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH:
+   case INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH:
+   case INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE:
+   case INTEL_GUC_LOAD_STATUS_HWCONFIG_ERROR:
+   case INTEL_GUC_LOAD_STATUS_DPC_ERROR:
+   case INTEL_GUC_LOAD_STATUS_EXCEPTION:
+   case INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID:
+

Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Matt Turner
On Fri, Mar 3, 2023 at 10:08 AM Tvrtko Ursulin
 wrote:
>
>
> On 03/03/2023 14:48, Rob Clark wrote:
> > On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
> >  wrote:
> >>
> >>
> >> On 03/03/2023 03:21, Rodrigo Vivi wrote:
> >>> On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
>  From: Rob Clark 
> 
> >>>
> >>> missing some wording here...
> >>>
>  v2: rebase
> 
>  Signed-off-by: Rob Clark 
>  ---
> drivers/gpu/drm/i915/i915_request.c | 20 
> 1 file changed, 20 insertions(+)
> 
>  diff --git a/drivers/gpu/drm/i915/i915_request.c 
>  b/drivers/gpu/drm/i915/i915_request.c
>  index 7503dcb9043b..44491e7e214c 100644
>  --- a/drivers/gpu/drm/i915/i915_request.c
>  +++ b/drivers/gpu/drm/i915/i915_request.c
>  @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct 
>  dma_fence *fence)
>    return i915_request_enable_breadcrumb(to_request(fence));
> }
> 
>  +static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t 
>  deadline)
>  +{
>  +struct i915_request *rq = to_request(fence);
>  +
>  +if (i915_request_completed(rq))
>  +return;
>  +
>  +if (i915_request_started(rq))
>  +return;
> >>>
> >>> why do we skip the boost if already started?
> >>> don't we want to boost the freq anyway?
> >>
> >> I'd wager Rob is just copying the current i915 wait boost logic.
> >
> > Yup, and probably incorrectly.. Matt reported fewer boosts/sec
> > compared to your RFC, this could be the bug
>
> Hm, there I have preserved this same !i915_request_started logic.
>
> Presumably it's not just fewer boosts but lower performance. How is he
> setting the deadline? Somehow from clFlush or so?
>
> Regards,
>
> Tvrtko
>
> P.S. Take note that I did not post the latest version of my RFC. The one
> where I fix the fence chain and array misses you pointed out. I did not
> think it would be worthwhile given no universal love for it, but if
> people are testing with it more widely that I was aware perhaps I should.

Yep, that would be great. We're interested in it for ChromeOS. Please
Cc me on the series when you send it.


Re: [PATCH] drm/amd/display: Simplify same effect if/else blocks

2023-03-03 Thread Deepak R Varma
On Thu, Mar 02, 2023 at 11:37:30AM -0500, Harry Wentland wrote:
> 
> 
> On 3/1/23 15:21, Deepak R Varma wrote:
> > On Mon, Jan 23, 2023 at 12:23:19AM +0530, Deepak R Varma wrote:
> >> On Sun, Jan 15, 2023 at 12:52:10PM -0800, Joe Perches wrote:
> >>> On Sun, 2023-01-15 at 15:30 +0530, Deepak R Varma wrote:
>  The if / else block code has same effect irrespective of the logical
>  evaluation.  Hence, simply the implementation by removing the unnecessary
>  conditional evaluation. While at it, also fix the long line checkpatch
>  complaint. Issue identified using cond_no_effect.cocci Coccinelle
>  semantic patch script.
> 
>  Signed-off-by: Deepak R Varma 
>  ---
>  Please note: The proposed change is compile tested only. If there are any
>  inbuilt test cases that I should run for further verification, I will 
>  appreciate
>  guidance about it. Thank you.
> >>>
> >>> Preface: I do not know the code.
> >>>
> >>> Perhaps Rodrigo Siqueira made a copy/paste error submitting the code for
> >>> commit 9114b55fabae ("drm/amd/display: Fix SubVP control flow in the MPO 
> >>> context")
> >>> as the code prior to this change is identical.
> >>>
> >>> Perhaps one of the false uses should be true or dependent on the
> >>> interdependent_update_lock state.
> >>
> >> Thank you Joe for the recommendation.
> >>
> >> Hi Rodrigo,
> >> Can you review and comment on if and what is wrong with your commit?
> > 
> > Hello Rodrigo, Alex,
> > Could you please suggest what would be the necessary fix for this typo 
> > error?
> > 
> 
> It's not quite a "typo" error. When I look at this code in our internal repo 
> I see
> a couple missing lock calls here that differ between the two cases. I don't 
> know why
> this was never ported over and am surprised it doesn't lead to issues.
> 
> I would prefer we keep the code as-is for now until this gets sorted.

Sounds good. Do let me know if I can be of any help.

Deepak.

> 
> Harry
> 
> > Thank you,
> > Deepak.
> > 
> >>
> >> Thank you,
> >> ./drv
> >>
> >>>
>  diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
>  b/drivers/gpu/drm/amd/display/dc/core/dc.c
> >>> []
>  @@ -3470,14 +3470,9 @@ static void commit_planes_for_stream(struct dc 
>  *dc,
>   /* Since phantom pipe programming is moved to 
>  post_unlock_program_front_end,
>    * move the SubVP lock to after the phantom pipes have 
>  been setup
>    */
>  -if (should_lock_all_pipes && 
>  dc->hwss.interdependent_update_lock) {
>  -if (dc->hwss.subvp_pipe_control_lock)
>  -dc->hwss.subvp_pipe_control_lock(dc, 
>  context, false, should_lock_all_pipes, NULL, subvp_prev_use);
>  -} else {
>  -if (dc->hwss.subvp_pipe_control_lock)
>  -dc->hwss.subvp_pipe_control_lock(dc, 
>  context, false, should_lock_all_pipes, NULL, subvp_prev_use);
>  -}
>  -
> >>>
> >>> Perhaps something like:
> >>>
> >>>   if (dc->hwss.subvp_pipe_control_lock)
> >>>   dc->hwss.subvp_pipe_control_lock(dc, context,
> >>>should_lock_all_pipes 
> >>> &&
> >>>
> >>> dc->hwss.interdependent_update_lock,
> >>>should_lock_all_pipes, 
> >>> NULL, subvp_prev_use);
> >>>
>  +if (dc->hwss.subvp_pipe_control_lock)
>  +dc->hwss.subvp_pipe_control_lock(dc, context, 
>  false, should_lock_all_pipes,
>  + NULL, 
>  subvp_prev_use);
>   return;
>   }
>   
> >>>
> >>
> >>
> > 
> > 
> 




Re: [PATCH 4/4] drm/imx: add driver for HDMI TX Parallel Video Interface

2023-03-03 Thread Luca Ceresoli
Hello Lucas,

On Fri, 26 Aug 2022 21:24:24 +0200
Lucas Stach  wrote:

> This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
> full timing generator and can switch between different video sources. On
> the i.MX8MP however the only supported source is the LCDIF.

Reading this sentence I had assumed that the i.MX8MP does only support
the LCDIF as an input to the PVI, but after having read the reference
manual it does not seem to have such a limitation. Do you mean that
"this driver only supports the LCDIF as an input"?

> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> @@ -0,0 +1,201 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright (C) 2022 Pengutronix, Lucas Stach 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define HTX_PVI_CTL  0x0
> +#define  PVI_CTL_OP_VSYNC_POLBIT(18)
> +#define  PVI_CTL_OP_HSYNC_POLBIT(17)
> +#define  PVI_CTL_OP_DE_POL   BIT(16)
> +#define  PVI_CTL_INP_VSYNC_POL   BIT(14)
> +#define  PVI_CTL_INP_HSYNC_POL   BIT(13)
> +#define  PVI_CTL_INP_DE_POL  BIT(12)
> +#define  PVI_CTL_INPUT_LCDIF BIT(2)

According to the reference manual there is actually a 2-bit field here:
HTX_PVI_MOD, using bits 2:1, and whose "LCDIF" value is 0b10. Thus while
it obviously won't change the resulting code, it seems more correct to
define this as (2 << 1).

> +static void imx_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
> +struct drm_bridge_state *bridge_state)
> +{
> + struct drm_atomic_state *state = bridge_state->base.state;
> + struct imx_hdmi_pvi *pvi = to_imx_hdmi_pvi(bridge);
> + struct drm_connector_state *conn_state;
> + const struct drm_display_mode *mode;
> + struct drm_crtc_state *crtc_state;
> + struct drm_connector *connector;
> + u32 bus_flags, val;
> +
> + connector = drm_atomic_get_new_connector_for_encoder(state, 
> bridge->encoder);
> + conn_state = drm_atomic_get_new_connector_state(state, connector);
> + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> +
> + if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
> + return;
> +
> + mode = _state->adjusted_mode;
> +
> + val = PVI_CTL_INPUT_LCDIF;
> +
> + if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> + val |= PVI_CTL_OP_VSYNC_POL | PVI_CTL_INP_VSYNC_POL;
> +
> + if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> + val |= PVI_CTL_OP_HSYNC_POL | PVI_CTL_INP_HSYNC_POL;
> +
> + if (pvi->next_bridge->timings)
> + bus_flags = pvi->next_bridge->timings->input_bus_flags;
> + else if (bridge_state)
> + bus_flags = bridge_state->input_bus_cfg.flags;
> +
> + if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
> + val |= PVI_CTL_OP_DE_POL | PVI_CTL_INP_DE_POL;
> +
> + writel(val, pvi->regs + HTX_PVI_CTL);
> + val |= PVI_CTL_EN;
> + writel(val, pvi->regs + HTX_PVI_CTL);

I guess I'm missing something here: why can't one just write the
register once, with the enable bit set? I tried removing the first
writel() and everything seems to work just the same.

> +static void imx_hdmi_pvi_bridge_disable(struct drm_bridge *bridge,
> + struct drm_bridge_state *bridge_state)
> +{
> + struct imx_hdmi_pvi *pvi = to_imx_hdmi_pvi(bridge);
> +
> + writel(0x0, pvi->regs + HTX_PVI_CTL);

A very minor nit: why not simply writel(0, ...)?

With these fixed:
Reviewed-by: Luca Ceresoli 

And definitely:
Tested-by: Luca Ceresoli 

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH 3/4] dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI

2023-03-03 Thread Luca Ceresoli
On Fri, 26 Aug 2022 21:24:23 +0200
Lucas Stach  wrote:

> Add binding for the i.MX8MP HDMI parallel video interface block.
> 
> Signed-off-by: Lucas Stach 
> Tested-by: Marek Vasut 
> ---
>  .../display/imx/fsl,imx8mp-hdmi-pvi.yaml  | 83 +++
>  1 file changed, 83 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml 
> b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
> new file mode 100644
> index ..bf25d29c03ab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
> @@ -0,0 +1,83 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/imx/fsl,imx8mp-hdmi-pvi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8MP HDMI Parallel Video Interface
> +
> +maintainers:
> +  - Lucas Stach 
> +
> +description: |
> +  The HDMI parallel video interface is timing and sync generator block in the

s/is timing/is a timing/

With that fixed:
Luca Ceresoli 

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH 2/4] drm/imx: add bridge wrapper driver for i.MX8MP DWC HDMI

2023-03-03 Thread Luca Ceresoli
On Fri, 26 Aug 2022 21:24:22 +0200
Lucas Stach  wrote:

> Add a simple wrapper driver for the DWC HDMI bridge driver that
> implements the few bits that are necessary to abstract the i.MX8MP
> SoC integration.
> 
> Signed-off-by: Lucas Stach 
> Tested-by: Marek Vasut 

Tested-by: Luca Ceresoli 

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH v9 12/15] drm/msm: Add deadline based boost support

2023-03-03 Thread Rob Clark
On Fri, Mar 3, 2023 at 2:10 AM Dmitry Baryshkov
 wrote:
>
> On 03/03/2023 01:53, Rob Clark wrote:
> > From: Rob Clark 
> >
> > Track the nearest deadline on a fence timeline and set a timer to expire
> > shortly before to trigger boost if the fence has not yet been signaled.
> >
> > v2: rebase
> >
> > Signed-off-by: Rob Clark 
> > ---
> >   drivers/gpu/drm/msm/msm_fence.c | 74 +
> >   drivers/gpu/drm/msm/msm_fence.h | 20 +
> >   2 files changed, 94 insertions(+)
>
> Reviewed-by: Dmitry Baryshkov 
>
> A small question: do we boost to fit into the deadline or to miss the
> deadline for as little as possible? If the former is the case, we might
> need to adjust 3ms depending on the workload.

The goal is as much to run with higher clock on the next frame as it
is to not miss a deadline.  Ie. we don't want devfreq to come to the
conclusion that running at <50% clks is best due to the amount of
utilization caused by missing ever other vblank.

But 3ms is mostly just "seems like a good compromise" value.  It might change.

BR,
-R

> >
> > diff --git a/drivers/gpu/drm/msm/msm_fence.c 
> > b/drivers/gpu/drm/msm/msm_fence.c
> > index 56641408ea74..51b461f32103 100644
> > --- a/drivers/gpu/drm/msm/msm_fence.c
> > +++ b/drivers/gpu/drm/msm/msm_fence.c
> > @@ -8,6 +8,35 @@
> >
> >   #include "msm_drv.h"
> >   #include "msm_fence.h"
> > +#include "msm_gpu.h"
> > +
> > +static struct msm_gpu *fctx2gpu(struct msm_fence_context *fctx)
> > +{
> > + struct msm_drm_private *priv = fctx->dev->dev_private;
> > + return priv->gpu;
> > +}
> > +
> > +static enum hrtimer_restart deadline_timer(struct hrtimer *t)
> > +{
> > + struct msm_fence_context *fctx = container_of(t,
> > + struct msm_fence_context, deadline_timer);
> > +
> > + kthread_queue_work(fctx2gpu(fctx)->worker, >deadline_work);
> > +
> > + return HRTIMER_NORESTART;
> > +}
> > +
> > +static void deadline_work(struct kthread_work *work)
> > +{
> > + struct msm_fence_context *fctx = container_of(work,
> > + struct msm_fence_context, deadline_work);
> > +
> > + /* If deadline fence has already passed, nothing to do: */
> > + if (msm_fence_completed(fctx, fctx->next_deadline_fence))
> > + return;
> > +
> > + msm_devfreq_boost(fctx2gpu(fctx), 2);
> > +}
> >
> >
> >   struct msm_fence_context *
> > @@ -36,6 +65,13 @@ msm_fence_context_alloc(struct drm_device *dev, volatile 
> > uint32_t *fenceptr,
> >   fctx->completed_fence = fctx->last_fence;
> >   *fctx->fenceptr = fctx->last_fence;
> >
> > + hrtimer_init(>deadline_timer, CLOCK_MONOTONIC, 
> > HRTIMER_MODE_ABS);
> > + fctx->deadline_timer.function = deadline_timer;
> > +
> > + kthread_init_work(>deadline_work, deadline_work);
> > +
> > + fctx->next_deadline = ktime_get();
> > +
> >   return fctx;
> >   }
> >
> > @@ -62,6 +98,8 @@ void msm_update_fence(struct msm_fence_context *fctx, 
> > uint32_t fence)
> >   spin_lock_irqsave(>spinlock, flags);
> >   if (fence_after(fence, fctx->completed_fence))
> >   fctx->completed_fence = fence;
> > + if (msm_fence_completed(fctx, fctx->next_deadline_fence))
> > + hrtimer_cancel(>deadline_timer);
> >   spin_unlock_irqrestore(>spinlock, flags);
> >   }
> >
> > @@ -92,10 +130,46 @@ static bool msm_fence_signaled(struct dma_fence *fence)
> >   return msm_fence_completed(f->fctx, f->base.seqno);
> >   }
> >
> > +static void msm_fence_set_deadline(struct dma_fence *fence, ktime_t 
> > deadline)
> > +{
> > + struct msm_fence *f = to_msm_fence(fence);
> > + struct msm_fence_context *fctx = f->fctx;
> > + unsigned long flags;
> > + ktime_t now;
> > +
> > + spin_lock_irqsave(>spinlock, flags);
> > + now = ktime_get();
> > +
> > + if (ktime_after(now, fctx->next_deadline) ||
> > + ktime_before(deadline, fctx->next_deadline)) {
> > + fctx->next_deadline = deadline;
> > + fctx->next_deadline_fence =
> > + max(fctx->next_deadline_fence, 
> > (uint32_t)fence->seqno);
> > +
> > + /*
> > +  * Set timer to trigger boost 3ms before deadline, or
> > +  * if we are already less than 3ms before the deadline
> > +  * schedule boost work immediately.
> > +  */
> > + deadline = ktime_sub(deadline, ms_to_ktime(3));
> > +
> > + if (ktime_after(now, deadline)) {
> > + kthread_queue_work(fctx2gpu(fctx)->worker,
> > + >deadline_work);
> > + } else {
> > + hrtimer_start(>deadline_timer, deadline,
> > + HRTIMER_MODE_ABS);
> > + }
> > + }
> > +
> > + spin_unlock_irqrestore(>spinlock, flags);
> > +}
> > +
> >   static const struct dma_fence_ops msm_fence_ops = {
> >   .get_driver_name = 

[PATCH v2 3/4] drm/msm/adreno: drop bogus pm_runtime_set_active()

2023-03-03 Thread Johan Hovold
The runtime PM status can only be updated while runtime PM is disabled.

Drop the bogus pm_runtime_set_active() call that was made after enabling
runtime PM and which (incidentally but correctly) left the runtime PM
status set to 'suspended'.

Fixes: 2c087a336676 ("drm/msm/adreno: Load the firmware before bringing up the 
hardware")
Signed-off-by: Johan Hovold 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index f9a0b11c2e43..d9100e3870bc 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -438,9 +438,6 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
 */
pm_runtime_enable(>dev);
 
-   /* Make sure pm runtime is active and reset any previous errors */
-   pm_runtime_set_active(>dev);
-
ret = pm_runtime_get_sync(>dev);
if (ret < 0) {
pm_runtime_put_noidle(>dev);
-- 
2.39.2



[PATCH v2 4/4] drm/msm/adreno: clean up component ops indentation

2023-03-03 Thread Johan Hovold
Clean up the component ops initialisers which were indented one level
too far.

Signed-off-by: Johan Hovold 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index d9100e3870bc..f2cdc5ad7ce7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -571,8 +571,8 @@ static void adreno_unbind(struct device *dev, struct device 
*master,
 }
 
 static const struct component_ops a3xx_ops = {
-   .bind   = adreno_bind,
-   .unbind = adreno_unbind,
+   .bind   = adreno_bind,
+   .unbind = adreno_unbind,
 };
 
 static void adreno_device_register_headless(void)
-- 
2.39.2



[PATCH v2 0/4] drm/msm/adreno: fix runtime PM imbalance at unbind

2023-03-03 Thread Johan Hovold
As reported by Bjorn, we can end up with an unbalanced runtime PM
disable count if unbind() is called before the DRM device is opened
(e.g. if component bind fails due to the panel driver not having been
loaded yet).

As runtime PM must currently stay disabled until the firmware has been
loaded, fix this by making the runtime PM disable call at unbind()
conditional.

The rest of the series fixes further imbalances in the load_gpu() error
paths and removes a bogus pm_runtime_set_active() call. Included is also
a related indentation cleanup.

Johan


Changes in v2
 - fix the runtime PM imbalance in the gpu load error paths (new)

 - drop the patch removing the pm_runtime_disable() from
   adreno_gpu_cleanup() as this function can currently still be called
   with runtime PM enabled if suspending the scheduler in
   adreno_system_suspend() at unbind fails


Johan Hovold (4):
  drm/msm/adreno: fix runtime PM imbalance at unbind
  drm/msm/adreno: fix runtime PM imbalance at gpu load
  drm/msm/adreno: drop bogus pm_runtime_set_active()
  drm/msm/adreno: clean up component ops indentation

 drivers/gpu/drm/msm/adreno/adreno_device.c | 26 +-
 1 file changed, 16 insertions(+), 10 deletions(-)

-- 
2.39.2



[PATCH v2 1/4] drm/msm/adreno: fix runtime PM imbalance at unbind

2023-03-03 Thread Johan Hovold
A recent commit moved enabling of runtime PM from adreno_gpu_init() to
adreno_load_gpu() (called on first open()), which means that unbind()
may now be called with runtime PM disabled in case the device was never
opened in between.

Make sure to only forcibly suspend and disable runtime PM at unbind() in
case runtime PM has been enabled to prevent a disable count imbalance.

This specifically avoids leaving runtime PM disabled when the device
is later opened after a successful bind:

msm_dpu ae01000.display-controller: [drm:adreno_load_gpu [msm]] *ERROR* 
Couldn't power up the GPU: -13

Fixes: 4b18299b3365 ("drm/msm/adreno: Defer enabling runpm until hw_init()")
Reported-by: Bjorn Andersson 
Link: 
https://lore.kernel.org/lkml/20230203181245.3523937-1-quic_bjora...@quicinc.com
Cc: sta...@vger.kernel.org  # 6.0
Signed-off-by: Johan Hovold 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 36f062c7582f..c5c4c93b3689 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -558,7 +558,8 @@ static void adreno_unbind(struct device *dev, struct device 
*master,
struct msm_drm_private *priv = dev_get_drvdata(master);
struct msm_gpu *gpu = dev_to_gpu(dev);
 
-   WARN_ON_ONCE(adreno_system_suspend(dev));
+   if (pm_runtime_enabled(dev))
+   WARN_ON_ONCE(adreno_system_suspend(dev));
gpu->funcs->destroy(gpu);
 
priv->gpu_pdev = NULL;
-- 
2.39.2



[PATCH v2 2/4] drm/msm/adreno: fix runtime PM imbalance at gpu load

2023-03-03 Thread Johan Hovold
A recent commit moved enabling of runtime PM to GPU load time (first
open()) but failed to update the error paths so that runtime PM is
disabled if initialisation of the GPU fails. This would trigger a
warning about the unbalanced disable count on the next open() attempt.

Note that pm_runtime_put_noidle() is sufficient to balance the usage
count when pm_runtime_put_sync() fails (and is chosen over
pm_runtime_resume_and_get() for consistency reasons).

Fixes: 4b18299b3365 ("drm/msm/adreno: Defer enabling runpm until hw_init()")
Cc: sta...@vger.kernel.org  # 6.0
Signed-off-by: Johan Hovold 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index c5c4c93b3689..f9a0b11c2e43 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -443,20 +443,21 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
 
ret = pm_runtime_get_sync(>dev);
if (ret < 0) {
-   pm_runtime_put_sync(>dev);
+   pm_runtime_put_noidle(>dev);
DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret);
-   return NULL;
+   goto err_disable_rpm;
}
 
mutex_lock(>lock);
ret = msm_gpu_hw_init(gpu);
mutex_unlock(>lock);
-   pm_runtime_put_autosuspend(>dev);
if (ret) {
DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
-   return NULL;
+   goto err_put_rpm;
}
 
+   pm_runtime_put_autosuspend(>dev);
+
 #ifdef CONFIG_DEBUG_FS
if (gpu->funcs->debugfs_init) {
gpu->funcs->debugfs_init(gpu, dev->primary);
@@ -465,6 +466,13 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
 #endif
 
return gpu;
+
+err_put_rpm:
+   pm_runtime_put_sync(>dev);
+err_disable_rpm:
+   pm_runtime_disable(>dev);
+
+   return NULL;
 }
 
 static int find_chipid(struct device *dev, struct adreno_rev *rev)
-- 
2.39.2



Re: [PATCH v15 02/16] drm: exynos: dsi: Lookup OF-graph or Child node devices

2023-03-03 Thread Marek Vasut

On 3/3/23 15:51, Jagan Teki wrote:

[...]


--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1470,18 +1470,52 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
struct device *dev = dsi->dev;
struct drm_encoder *encoder = >encoder;
struct drm_device *drm = encoder->dev;
+   struct device_node *np = dev->of_node;
+   struct device_node *remote;
struct drm_panel *panel;
int ret;
  
-	panel = of_drm_find_panel(device->dev.of_node);

+   /**


This shouldn't be kerneldoc style comment, drop that extra asterisk (*).


+* Devices can also be child nodes when we also control that device
+* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).


[...]

With that fixed:

Reviewed-by: Marek Vasut 


Re: [PATCH v15 01/16] drm: exynos: dsi: Drop explicit call to bridge detach

2023-03-03 Thread Marek Vasut

On 3/3/23 15:51, Jagan Teki wrote:

Exynos DSI already converted into a bridge driver, so bridge
detach will suppose happened during bridge chain removal done
by the bridge core.

Drop the explicit call chain to detach the bridge.

Signed-off-by: Jagan Teki 
---
Changes for v15, v13, v12, v11:
- none
Changes for v10:
- new patch

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 06d6513ddaae..df15501b1075 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1531,8 +1531,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host 
*host,
struct exynos_dsi *dsi = host_to_dsi(host);
struct drm_device *drm = dsi->encoder.dev;
  
-	if (dsi->out_bridge->funcs->detach)

-   dsi->out_bridge->funcs->detach(dsi->out_bridge);
dsi->out_bridge = NULL;
  
  	if (drm->mode_config.poll_enabled)


Considering also the discussion in v15 12/16

Reviewed-by: Marek Vasut 


Re: [PATCH v9 11/15] drm/atomic-helper: Set fence deadline for vblank

2023-03-03 Thread Ville Syrjälä
On Fri, Mar 03, 2023 at 07:45:05AM -0800, Rob Clark wrote:
> On Fri, Mar 3, 2023 at 7:12 AM Ville Syrjälä
>  wrote:
> >
> > On Thu, Mar 02, 2023 at 03:53:33PM -0800, Rob Clark wrote:
> > > From: Rob Clark 
> > >
> > > For an atomic commit updating a single CRTC (ie. a pageflip) calculate
> > > the next vblank time, and inform the fence(s) of that deadline.
> > >
> > > v2: Comment typo fix (danvet)
> > >
> > > Signed-off-by: Rob Clark 
> > > Reviewed-by: Daniel Vetter 
> > > Signed-off-by: Rob Clark 
> > > ---
> > >  drivers/gpu/drm/drm_atomic_helper.c | 36 +
> > >  1 file changed, 36 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > index d579fd8f7cb8..d8ee98ce2fc5 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -1511,6 +1511,40 @@ void 
> > > drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
> > >  }
> > >  EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
> > >
> > > +/*
> > > + * For atomic updates which touch just a single CRTC, calculate the time 
> > > of the
> > > + * next vblank, and inform all the fences of the deadline.
> > > + */
> > > +static void set_fence_deadline(struct drm_device *dev,
> > > +struct drm_atomic_state *state)
> > > +{
> > > + struct drm_crtc *crtc, *wait_crtc = NULL;
> > > + struct drm_crtc_state *new_crtc_state;
> > > + struct drm_plane *plane;
> > > + struct drm_plane_state *new_plane_state;
> > > + ktime_t vbltime;
> > > + int i;
> > > +
> > > + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
> > > + if (wait_crtc)
> > > + return;
> > > + wait_crtc = crtc;
> > > + }
> > > +
> > > + /* If no CRTCs updated, then nothing to do: */
> > > + if (!wait_crtc)
> > > + return;
> >
> > Is there an actual point in limiting this to single crtc updates?
> > That immediately excludes tiled displays/etc.
> >
> > Handling an arbitrary number of crtcs shouldn't really be a lot
> > more complicated should it?
> 
> I guess I could find the soonest upcoming vblank of all the CRTCs and
> use that as the deadline?

Yeah, that seems reasonable. The flips are supposed to happen
atomically (if possible) anyway so collapsing the thing to
a single deadline for all makes sense to me.

-- 
Ville Syrjälä
Intel


Re: [PATCH v9 11/15] drm/atomic-helper: Set fence deadline for vblank

2023-03-03 Thread Rob Clark
On Fri, Mar 3, 2023 at 7:12 AM Ville Syrjälä
 wrote:
>
> On Thu, Mar 02, 2023 at 03:53:33PM -0800, Rob Clark wrote:
> > From: Rob Clark 
> >
> > For an atomic commit updating a single CRTC (ie. a pageflip) calculate
> > the next vblank time, and inform the fence(s) of that deadline.
> >
> > v2: Comment typo fix (danvet)
> >
> > Signed-off-by: Rob Clark 
> > Reviewed-by: Daniel Vetter 
> > Signed-off-by: Rob Clark 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c | 36 +
> >  1 file changed, 36 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index d579fd8f7cb8..d8ee98ce2fc5 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -1511,6 +1511,40 @@ void drm_atomic_helper_commit_modeset_enables(struct 
> > drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
> >
> > +/*
> > + * For atomic updates which touch just a single CRTC, calculate the time 
> > of the
> > + * next vblank, and inform all the fences of the deadline.
> > + */
> > +static void set_fence_deadline(struct drm_device *dev,
> > +struct drm_atomic_state *state)
> > +{
> > + struct drm_crtc *crtc, *wait_crtc = NULL;
> > + struct drm_crtc_state *new_crtc_state;
> > + struct drm_plane *plane;
> > + struct drm_plane_state *new_plane_state;
> > + ktime_t vbltime;
> > + int i;
> > +
> > + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
> > + if (wait_crtc)
> > + return;
> > + wait_crtc = crtc;
> > + }
> > +
> > + /* If no CRTCs updated, then nothing to do: */
> > + if (!wait_crtc)
> > + return;
>
> Is there an actual point in limiting this to single crtc updates?
> That immediately excludes tiled displays/etc.
>
> Handling an arbitrary number of crtcs shouldn't really be a lot
> more complicated should it?

I guess I could find the soonest upcoming vblank of all the CRTCs and
use that as the deadline?

BR,
-R

> > +
> > + if (drm_crtc_next_vblank_start(wait_crtc, ))
> > + return;
> > +
> > + for_each_new_plane_in_state (state, plane, new_plane_state, i) {
> > + if (!new_plane_state->fence)
> > + continue;
> > + dma_fence_set_deadline(new_plane_state->fence, vbltime);
> > + }
> > +}
> > +
> >  /**
> >   * drm_atomic_helper_wait_for_fences - wait for fences stashed in plane 
> > state
> >   * @dev: DRM device
> > @@ -1540,6 +1574,8 @@ int drm_atomic_helper_wait_for_fences(struct 
> > drm_device *dev,
> >   struct drm_plane_state *new_plane_state;
> >   int i, ret;
> >
> > + set_fence_deadline(dev, state);
> > +
> >   for_each_new_plane_in_state(state, plane, new_plane_state, i) {
> >   if (!new_plane_state->fence)
> >   continue;
> > --
> > 2.39.1
>
> --
> Ville Syrjälä
> Intel


Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Rob Clark
On Fri, Mar 3, 2023 at 7:20 AM Ville Syrjälä
 wrote:
>
> On Fri, Mar 03, 2023 at 05:00:03PM +0200, Ville Syrjälä wrote:
> > On Fri, Mar 03, 2023 at 06:48:43AM -0800, Rob Clark wrote:
> > > On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
> > >  wrote:
> > > >
> > > >
> > > > On 03/03/2023 03:21, Rodrigo Vivi wrote:
> > > > > On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
> > > > >> From: Rob Clark 
> > > > >>
> > > > >
> > > > > missing some wording here...
> > > > >
> > > > >> v2: rebase
> > > > >>
> > > > >> Signed-off-by: Rob Clark 
> > > > >> ---
> > > > >>   drivers/gpu/drm/i915/i915_request.c | 20 
> > > > >>   1 file changed, 20 insertions(+)
> > > > >>
> > > > >> diff --git a/drivers/gpu/drm/i915/i915_request.c 
> > > > >> b/drivers/gpu/drm/i915/i915_request.c
> > > > >> index 7503dcb9043b..44491e7e214c 100644
> > > > >> --- a/drivers/gpu/drm/i915/i915_request.c
> > > > >> +++ b/drivers/gpu/drm/i915/i915_request.c
> > > > >> @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct 
> > > > >> dma_fence *fence)
> > > > >>  return i915_request_enable_breadcrumb(to_request(fence));
> > > > >>   }
> > > > >>
> > > > >> +static void i915_fence_set_deadline(struct dma_fence *fence, 
> > > > >> ktime_t deadline)
> > > > >> +{
> > > > >> +struct i915_request *rq = to_request(fence);
> > > > >> +
> > > > >> +if (i915_request_completed(rq))
> > > > >> +return;
> > > > >> +
> > > > >> +if (i915_request_started(rq))
> > > > >> +return;
> > > > >
> > > > > why do we skip the boost if already started?
> > > > > don't we want to boost the freq anyway?
> > > >
> > > > I'd wager Rob is just copying the current i915 wait boost logic.
> > >
> > > Yup, and probably incorrectly.. Matt reported fewer boosts/sec
> > > compared to your RFC, this could be the bug
> >
> > I don't think i915 calls drm_atomic_helper_wait_for_fences()
> > so that could explain something.
>
> Oh, I guess this wasn't even supposed to take over the current
> display boost stuff since you didn't remove the old one.

Right, I didn't try to replace the current thing.. but hopefully at
least make it possible for i915 to use more of the atomic helpers in
the future

BR,
-R

> The current one just boosts after a missed vblank. The deadline
> could use your timer approach I suppose and boost already a bit
> earlier in the hopes of not missing the vblank.
>
> --
> Ville Syrjälä
> Intel


Re: [Freedreno] [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Rob Clark
On Fri, Mar 3, 2023 at 7:08 AM Tvrtko Ursulin
 wrote:
>
>
> On 03/03/2023 14:48, Rob Clark wrote:
> > On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
> >  wrote:
> >>
> >>
> >> On 03/03/2023 03:21, Rodrigo Vivi wrote:
> >>> On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
>  From: Rob Clark 
> 
> >>>
> >>> missing some wording here...
> >>>
>  v2: rebase
> 
>  Signed-off-by: Rob Clark 
>  ---
> drivers/gpu/drm/i915/i915_request.c | 20 
> 1 file changed, 20 insertions(+)
> 
>  diff --git a/drivers/gpu/drm/i915/i915_request.c 
>  b/drivers/gpu/drm/i915/i915_request.c
>  index 7503dcb9043b..44491e7e214c 100644
>  --- a/drivers/gpu/drm/i915/i915_request.c
>  +++ b/drivers/gpu/drm/i915/i915_request.c
>  @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct 
>  dma_fence *fence)
>    return i915_request_enable_breadcrumb(to_request(fence));
> }
> 
>  +static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t 
>  deadline)
>  +{
>  +struct i915_request *rq = to_request(fence);
>  +
>  +if (i915_request_completed(rq))
>  +return;
>  +
>  +if (i915_request_started(rq))
>  +return;
> >>>
> >>> why do we skip the boost if already started?
> >>> don't we want to boost the freq anyway?
> >>
> >> I'd wager Rob is just copying the current i915 wait boost logic.
> >
> > Yup, and probably incorrectly.. Matt reported fewer boosts/sec
> > compared to your RFC, this could be the bug
>
> Hm, there I have preserved this same !i915_request_started logic.
>
> Presumably it's not just fewer boosts but lower performance. How is he
> setting the deadline? Somehow from clFlush or so?

Yeah, fewer boosts, lower freq/perf.. I cobbled together a quick mesa
hack to set the DEADLINE flag on syncobj waits, but it seems likely
that I missed something somewhere

BR,
-R

> Regards,
>
> Tvrtko
>
> P.S. Take note that I did not post the latest version of my RFC. The one
> where I fix the fence chain and array misses you pointed out. I did not
> think it would be worthwhile given no universal love for it, but if
> people are testing with it more widely that I was aware perhaps I should.
>
>  +
>  +/*
>  + * TODO something more clever for deadlines that are in the
>  + * future.  I think probably track the nearest deadline in
>  + * rq->timeline and set timer to trigger boost accordingly?
>  + */
> >>>
> >>> I'm afraid it will be very hard to find some heuristics of what's
> >>> late enough for the boost no?
> >>> I mean, how early to boost the freq on an upcoming deadline for the
> >>> timer?
> >>
> >> We can off load this patch from Rob and deal with it separately, or
> >> after the fact?
> >
> > That is completely my intention, I expect you to replace my i915 patch ;-)
> >
> > Rough idea when everyone is happy with the core bits is to setup an
> > immutable branch without the driver specific patches, which could be
> > merged into drm-next and $driver-next and then each driver team can
> > add there own driver patches on top
> >
> > BR,
> > -R
> >
> >> It's a half solution without a smarter scheduler too. Like
> >> https://lore.kernel.org/all/20210208105236.28498-10-ch...@chris-wilson.co.uk/,
> >> or if GuC plans to do something like that at any point.
> >>
> >> Or bump the priority too if deadline is looming?
> >>
> >> IMO it is not very effective to fiddle with the heuristic on an ad-hoc
> >> basis. For instance I have a new heuristics which improves the
> >> problematic OpenCL cases for further 5% (relative to the current
> >> waitboost improvement from adding missing syncobj waitboost). But I
> >> can't really test properly for regressions over platforms, stacks,
> >> workloads.. :(
> >>
> >> Regards,
> >>
> >> Tvrtko
> >>
> >>>
>  +
>  +intel_rps_boost(rq);
>  +}
>  +
> static signed long i915_fence_wait(struct dma_fence *fence,
>   bool interruptible,
>   signed long timeout)
>  @@ -182,6 +201,7 @@ const struct dma_fence_ops i915_fence_ops = {
>    .signaled = i915_fence_signaled,
>    .wait = i915_fence_wait,
>    .release = i915_fence_release,
>  +.set_deadline = i915_fence_set_deadline,
> };
> 
> static void irq_execute_cb(struct irq_work *wrk)
>  --
>  2.39.1
> 


Re: [PATCH] Change the meaning of the fields in the ttm_place structure from pfn to bytes

2023-03-03 Thread Stanislaw Gruszka
On Fri, Mar 03, 2023 at 03:55:56PM +0100, Michel Dänzer wrote:
> On 3/3/23 08:16, Somalapuram Amaranath wrote:
> > Change the ttm_place structure member fpfn, lpfn, mem_type to
> > res_start, res_end, res_type.
> > Change the unsigned to u64.
> > Fix the dependence in all the DRM drivers and
> > clean up PAGE_SHIFT operation.
> > 
> > Signed-off-by: Somalapuram Amaranath 
> > 
> > [...]
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> > index 44367f03316f..5b5104e724e3 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> > @@ -131,11 +131,12 @@ static int amdgpu_gtt_mgr_new(struct 
> > ttm_resource_manager *man,
> > goto err_free;
> > }
> >  
> > -   if (place->lpfn) {
> > +   if (place->res_end) {
> > spin_lock(>lock);
> > r = drm_mm_insert_node_in_range(>mm, >mm_nodes[0],
> > -   num_pages, tbo->page_alignment,
> > -   0, place->fpfn, place->lpfn,
> > +   num_pages, tbo->page_alignment, 
> > 0,
> > +   place->res_start << PAGE_SHIFT,
> > +   place->res_end << PAGE_SHIFT,
> > DRM_MM_INSERT_BEST);
> 
> This should be >> or no shift instead of <<, shouldn't it? Multiplying a 
> value in bytes by the page size doesn't make sense.
> 
> 
> I didn't check the rest of the patch in detail, but it's easy introduce 
> subtle regressions with this kind of change. It'll require a lot of review & 
> testing scrutiny.

Also good justification. The changelog says only what is done, nothing about 
why the change is needed.

Regards
Stanislaw


Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Ville Syrjälä
On Fri, Mar 03, 2023 at 05:00:03PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 03, 2023 at 06:48:43AM -0800, Rob Clark wrote:
> > On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
> >  wrote:
> > >
> > >
> > > On 03/03/2023 03:21, Rodrigo Vivi wrote:
> > > > On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
> > > >> From: Rob Clark 
> > > >>
> > > >
> > > > missing some wording here...
> > > >
> > > >> v2: rebase
> > > >>
> > > >> Signed-off-by: Rob Clark 
> > > >> ---
> > > >>   drivers/gpu/drm/i915/i915_request.c | 20 
> > > >>   1 file changed, 20 insertions(+)
> > > >>
> > > >> diff --git a/drivers/gpu/drm/i915/i915_request.c 
> > > >> b/drivers/gpu/drm/i915/i915_request.c
> > > >> index 7503dcb9043b..44491e7e214c 100644
> > > >> --- a/drivers/gpu/drm/i915/i915_request.c
> > > >> +++ b/drivers/gpu/drm/i915/i915_request.c
> > > >> @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct 
> > > >> dma_fence *fence)
> > > >>  return i915_request_enable_breadcrumb(to_request(fence));
> > > >>   }
> > > >>
> > > >> +static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t 
> > > >> deadline)
> > > >> +{
> > > >> +struct i915_request *rq = to_request(fence);
> > > >> +
> > > >> +if (i915_request_completed(rq))
> > > >> +return;
> > > >> +
> > > >> +if (i915_request_started(rq))
> > > >> +return;
> > > >
> > > > why do we skip the boost if already started?
> > > > don't we want to boost the freq anyway?
> > >
> > > I'd wager Rob is just copying the current i915 wait boost logic.
> > 
> > Yup, and probably incorrectly.. Matt reported fewer boosts/sec
> > compared to your RFC, this could be the bug
> 
> I don't think i915 calls drm_atomic_helper_wait_for_fences()
> so that could explain something.

Oh, I guess this wasn't even supposed to take over the current 
display boost stuff since you didn't remove the old one.

The current one just boosts after a missed vblank. The deadline
could use your timer approach I suppose and boost already a bit
earlier in the hopes of not missing the vblank.

-- 
Ville Syrjälä
Intel


Re: [PATCH v9 11/15] drm/atomic-helper: Set fence deadline for vblank

2023-03-03 Thread Ville Syrjälä
On Thu, Mar 02, 2023 at 03:53:33PM -0800, Rob Clark wrote:
> From: Rob Clark 
> 
> For an atomic commit updating a single CRTC (ie. a pageflip) calculate
> the next vblank time, and inform the fence(s) of that deadline.
> 
> v2: Comment typo fix (danvet)
> 
> Signed-off-by: Rob Clark 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 36 +
>  1 file changed, 36 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index d579fd8f7cb8..d8ee98ce2fc5 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -1511,6 +1511,40 @@ void drm_atomic_helper_commit_modeset_enables(struct 
> drm_device *dev,
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
>  
> +/*
> + * For atomic updates which touch just a single CRTC, calculate the time of 
> the
> + * next vblank, and inform all the fences of the deadline.
> + */
> +static void set_fence_deadline(struct drm_device *dev,
> +struct drm_atomic_state *state)
> +{
> + struct drm_crtc *crtc, *wait_crtc = NULL;
> + struct drm_crtc_state *new_crtc_state;
> + struct drm_plane *plane;
> + struct drm_plane_state *new_plane_state;
> + ktime_t vbltime;
> + int i;
> +
> + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
> + if (wait_crtc)
> + return;
> + wait_crtc = crtc;
> + }
> +
> + /* If no CRTCs updated, then nothing to do: */
> + if (!wait_crtc)
> + return;

Is there an actual point in limiting this to single crtc updates?
That immediately excludes tiled displays/etc.

Handling an arbitrary number of crtcs shouldn't really be a lot
more complicated should it?

> +
> + if (drm_crtc_next_vblank_start(wait_crtc, ))
> + return;
> +
> + for_each_new_plane_in_state (state, plane, new_plane_state, i) {
> + if (!new_plane_state->fence)
> + continue;
> + dma_fence_set_deadline(new_plane_state->fence, vbltime);
> + }
> +}
> +
>  /**
>   * drm_atomic_helper_wait_for_fences - wait for fences stashed in plane state
>   * @dev: DRM device
> @@ -1540,6 +1574,8 @@ int drm_atomic_helper_wait_for_fences(struct drm_device 
> *dev,
>   struct drm_plane_state *new_plane_state;
>   int i, ret;
>  
> + set_fence_deadline(dev, state);
> +
>   for_each_new_plane_in_state(state, plane, new_plane_state, i) {
>   if (!new_plane_state->fence)
>   continue;
> -- 
> 2.39.1

-- 
Ville Syrjälä
Intel


Re: [PATCH v15 12/16] drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge

2023-03-03 Thread Jagan Teki
On Fri, Mar 3, 2023 at 8:38 PM Maxime Ripard  wrote:
>
> On Fri, Mar 03, 2023 at 08:21:34PM +0530, Jagan Teki wrote:
> > +static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
> > + struct mipi_dsi_device *device)
> > +{
> > + struct samsung_dsim *dsi = host_to_dsi(host);
> > + const struct samsung_dsim_plat_data *pdata = dsi->plat_data;
> > +
> > + if (dsi->out_bridge->funcs->detach)
> > + dsi->out_bridge->funcs->detach(dsi->out_bridge);
>
> You should never call into the bridge ops directly. If there's an issue
> in the helpers somewhere else, fix that instead.

Agreed, it was added by mistake and it was removed in Exynos. I will fix it.

Jagan.


Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Tvrtko Ursulin



On 03/03/2023 14:48, Rob Clark wrote:

On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
 wrote:



On 03/03/2023 03:21, Rodrigo Vivi wrote:

On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:

From: Rob Clark 



missing some wording here...


v2: rebase

Signed-off-by: Rob Clark 
---
   drivers/gpu/drm/i915/i915_request.c | 20 
   1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index 7503dcb9043b..44491e7e214c 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct dma_fence 
*fence)
  return i915_request_enable_breadcrumb(to_request(fence));
   }

+static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
+{
+struct i915_request *rq = to_request(fence);
+
+if (i915_request_completed(rq))
+return;
+
+if (i915_request_started(rq))
+return;


why do we skip the boost if already started?
don't we want to boost the freq anyway?


I'd wager Rob is just copying the current i915 wait boost logic.


Yup, and probably incorrectly.. Matt reported fewer boosts/sec
compared to your RFC, this could be the bug


Hm, there I have preserved this same !i915_request_started logic.

Presumably it's not just fewer boosts but lower performance. How is he 
setting the deadline? Somehow from clFlush or so?


Regards,

Tvrtko

P.S. Take note that I did not post the latest version of my RFC. The one 
where I fix the fence chain and array misses you pointed out. I did not 
think it would be worthwhile given no universal love for it, but if 
people are testing with it more widely that I was aware perhaps I should.



+
+/*
+ * TODO something more clever for deadlines that are in the
+ * future.  I think probably track the nearest deadline in
+ * rq->timeline and set timer to trigger boost accordingly?
+ */


I'm afraid it will be very hard to find some heuristics of what's
late enough for the boost no?
I mean, how early to boost the freq on an upcoming deadline for the
timer?


We can off load this patch from Rob and deal with it separately, or
after the fact?


That is completely my intention, I expect you to replace my i915 patch ;-)

Rough idea when everyone is happy with the core bits is to setup an
immutable branch without the driver specific patches, which could be
merged into drm-next and $driver-next and then each driver team can
add there own driver patches on top

BR,
-R


It's a half solution without a smarter scheduler too. Like
https://lore.kernel.org/all/20210208105236.28498-10-ch...@chris-wilson.co.uk/,
or if GuC plans to do something like that at any point.

Or bump the priority too if deadline is looming?

IMO it is not very effective to fiddle with the heuristic on an ad-hoc
basis. For instance I have a new heuristics which improves the
problematic OpenCL cases for further 5% (relative to the current
waitboost improvement from adding missing syncobj waitboost). But I
can't really test properly for regressions over platforms, stacks,
workloads.. :(

Regards,

Tvrtko




+
+intel_rps_boost(rq);
+}
+
   static signed long i915_fence_wait(struct dma_fence *fence,
 bool interruptible,
 signed long timeout)
@@ -182,6 +201,7 @@ const struct dma_fence_ops i915_fence_ops = {
  .signaled = i915_fence_signaled,
  .wait = i915_fence_wait,
  .release = i915_fence_release,
+.set_deadline = i915_fence_set_deadline,
   };

   static void irq_execute_cb(struct irq_work *wrk)
--
2.39.1



Re: [PATCH v15 12/16] drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge

2023-03-03 Thread Maxime Ripard
On Fri, Mar 03, 2023 at 08:21:34PM +0530, Jagan Teki wrote:
> +static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
> + struct mipi_dsi_device *device)
> +{
> + struct samsung_dsim *dsi = host_to_dsi(host);
> + const struct samsung_dsim_plat_data *pdata = dsi->plat_data;
> +
> + if (dsi->out_bridge->funcs->detach)
> + dsi->out_bridge->funcs->detach(dsi->out_bridge);

You should never call into the bridge ops directly. If there's an issue
in the helpers somewhere else, fix that instead.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v15 08/16] drm: exynos: dsi: Add input_bus_flags

2023-03-03 Thread Maxime Ripard
On Fri, Mar 03, 2023 at 04:00:19PM +0100, Maxime Ripard wrote:
> On Fri, Mar 03, 2023 at 08:21:30PM +0530, Jagan Teki wrote:
> > LCDIF-DSIM glue logic inverts the HS/VS/DE signals and expecting
> > the i.MX8M Mini/Nano DSI host to add additional Data Enable signal
> > active low (DE_LOW). This makes the valid data transfer on each
> > horizontal line.
> > 
> > So, add additional bus flags DE_LOW setting via input_bus_flags
> > for i.MX8M Mini/Nano platforms.
> > 
> > Reviewed-by: Marek Vasut 
> > Reviewed-by: Frieder Schrempf 
> > Suggested-by: Marek Vasut 
> > Signed-off-by: Jagan Teki 
> > ---
> > Changes for v15, v13:
> > - none
> > Changes for v12:
> > - collect RB from Marek
> > Changes for v11:
> > - collect RB from Frieder
> > Changes for v10, v9:
> > - none
> > Changes for v8:
> > - add DE_LOW for i.MX8M Mini/Nano platforms.
> > Changes for v7, v6:
> > - none
> > Changes for v5:
> > - rebased based on updated bridge changes
> > Changes for v4 - v1:
> > - none
> > 
> >  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 8 
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
> > b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> > index 796480e4a18b..5d971b607e1a 100644
> > --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> > +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> > @@ -1736,6 +1736,10 @@ static const struct component_ops 
> > exynos_dsi_component_ops = {
> > .unbind = exynos_dsi_unbind,
> >  };
> >  
> > +static const struct drm_bridge_timings dsim_bridge_timings_de_low = {
> > +   .input_bus_flags = DRM_BUS_FLAG_DE_LOW,
> > +};
> > +
> >  static int exynos_dsi_probe(struct platform_device *pdev)
> >  {
> > struct device *dev = >dev;
> > @@ -1822,6 +1826,10 @@ static int exynos_dsi_probe(struct platform_device 
> > *pdev)
> > dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
> > dsi->bridge.pre_enable_prev_first = true;
> >  
> > +   /* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */
> > +   if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)
> 
> That commit isn't bisectable, you add that enum variant in the last
> patch so this won't compile.

Scratch that, it's defined in the previous patch, sorry

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v15 08/16] drm: exynos: dsi: Add input_bus_flags

2023-03-03 Thread Maxime Ripard
On Fri, Mar 03, 2023 at 08:21:30PM +0530, Jagan Teki wrote:
> LCDIF-DSIM glue logic inverts the HS/VS/DE signals and expecting
> the i.MX8M Mini/Nano DSI host to add additional Data Enable signal
> active low (DE_LOW). This makes the valid data transfer on each
> horizontal line.
> 
> So, add additional bus flags DE_LOW setting via input_bus_flags
> for i.MX8M Mini/Nano platforms.
> 
> Reviewed-by: Marek Vasut 
> Reviewed-by: Frieder Schrempf 
> Suggested-by: Marek Vasut 
> Signed-off-by: Jagan Teki 
> ---
> Changes for v15, v13:
> - none
> Changes for v12:
> - collect RB from Marek
> Changes for v11:
> - collect RB from Frieder
> Changes for v10, v9:
> - none
> Changes for v8:
> - add DE_LOW for i.MX8M Mini/Nano platforms.
> Changes for v7, v6:
> - none
> Changes for v5:
> - rebased based on updated bridge changes
> Changes for v4 - v1:
> - none
> 
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
> b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index 796480e4a18b..5d971b607e1a 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -1736,6 +1736,10 @@ static const struct component_ops 
> exynos_dsi_component_ops = {
>   .unbind = exynos_dsi_unbind,
>  };
>  
> +static const struct drm_bridge_timings dsim_bridge_timings_de_low = {
> + .input_bus_flags = DRM_BUS_FLAG_DE_LOW,
> +};
> +
>  static int exynos_dsi_probe(struct platform_device *pdev)
>  {
>   struct device *dev = >dev;
> @@ -1822,6 +1826,10 @@ static int exynos_dsi_probe(struct platform_device 
> *pdev)
>   dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>   dsi->bridge.pre_enable_prev_first = true;
>  
> + /* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */
> + if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)

That commit isn't bisectable, you add that enum variant in the last
patch so this won't compile.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Ville Syrjälä
On Fri, Mar 03, 2023 at 06:48:43AM -0800, Rob Clark wrote:
> On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
>  wrote:
> >
> >
> > On 03/03/2023 03:21, Rodrigo Vivi wrote:
> > > On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
> > >> From: Rob Clark 
> > >>
> > >
> > > missing some wording here...
> > >
> > >> v2: rebase
> > >>
> > >> Signed-off-by: Rob Clark 
> > >> ---
> > >>   drivers/gpu/drm/i915/i915_request.c | 20 
> > >>   1 file changed, 20 insertions(+)
> > >>
> > >> diff --git a/drivers/gpu/drm/i915/i915_request.c 
> > >> b/drivers/gpu/drm/i915/i915_request.c
> > >> index 7503dcb9043b..44491e7e214c 100644
> > >> --- a/drivers/gpu/drm/i915/i915_request.c
> > >> +++ b/drivers/gpu/drm/i915/i915_request.c
> > >> @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct 
> > >> dma_fence *fence)
> > >>  return i915_request_enable_breadcrumb(to_request(fence));
> > >>   }
> > >>
> > >> +static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t 
> > >> deadline)
> > >> +{
> > >> +struct i915_request *rq = to_request(fence);
> > >> +
> > >> +if (i915_request_completed(rq))
> > >> +return;
> > >> +
> > >> +if (i915_request_started(rq))
> > >> +return;
> > >
> > > why do we skip the boost if already started?
> > > don't we want to boost the freq anyway?
> >
> > I'd wager Rob is just copying the current i915 wait boost logic.
> 
> Yup, and probably incorrectly.. Matt reported fewer boosts/sec
> compared to your RFC, this could be the bug

I don't think i915 calls drm_atomic_helper_wait_for_fences()
so that could explain something.

-- 
Ville Syrjälä
Intel


Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Rob Clark
On Thu, Mar 2, 2023 at 7:21 PM Rodrigo Vivi  wrote:
>
> On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
> > From: Rob Clark 
> >
>
> missing some wording here...

the wording should be "Pls replace this patch, kthx" ;-)

>
> > v2: rebase
> >
> > Signed-off-by: Rob Clark 
> > ---
> >  drivers/gpu/drm/i915/i915_request.c | 20 
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_request.c 
> > b/drivers/gpu/drm/i915/i915_request.c
> > index 7503dcb9043b..44491e7e214c 100644
> > --- a/drivers/gpu/drm/i915/i915_request.c
> > +++ b/drivers/gpu/drm/i915/i915_request.c
> > @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct dma_fence 
> > *fence)
> >   return i915_request_enable_breadcrumb(to_request(fence));
> >  }
> >
> > +static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t 
> > deadline)
> > +{
> > + struct i915_request *rq = to_request(fence);
> > +
> > + if (i915_request_completed(rq))
> > + return;
> > +
> > + if (i915_request_started(rq))
> > + return;
>
> why do we skip the boost if already started?
> don't we want to boost the freq anyway?
>
> > +
> > + /*
> > +  * TODO something more clever for deadlines that are in the
> > +  * future.  I think probably track the nearest deadline in
> > +  * rq->timeline and set timer to trigger boost accordingly?
> > +  */
>
> I'm afraid it will be very hard to find some heuristics of what's
> late enough for the boost no?
> I mean, how early to boost the freq on an upcoming deadline for the
> timer?

So, from my understanding of i915 boosting, it applies more
specifically to a given request (vs msm which just bumps up the freq
until the next devfreq sampling period which then recalculates target
freq based on busy cycles and avg freq over the last sampling period).
For msm I just set a timer for 3ms before the deadline and boost if
the fence isn't signaled when the timer fires.  It is kinda impossible
to predict, even for userspace, how long a job will take to complete,
so the goal isn't really to finish the specified job by the deadline,
but instead to avoid devfreq landing at a local minimum (maximum?)

AFAIU what I _think_ would make sense for i915 is to do the same thing
you do if you miss a vblank pageflip deadline if the deadline passes
without the fence signaling.

BR,
-R

> > +
> > + intel_rps_boost(rq);
> > +}
> > +
> >  static signed long i915_fence_wait(struct dma_fence *fence,
> >  bool interruptible,
> >  signed long timeout)
> > @@ -182,6 +201,7 @@ const struct dma_fence_ops i915_fence_ops = {
> >   .signaled = i915_fence_signaled,
> >   .wait = i915_fence_wait,
> >   .release = i915_fence_release,
> > + .set_deadline = i915_fence_set_deadline,
> >  };
> >
> >  static void irq_execute_cb(struct irq_work *wrk)
> > --
> > 2.39.1
> >


Re: [PATCH] Change the meaning of the fields in the ttm_place structure from pfn to bytes

2023-03-03 Thread Michel Dänzer
On 3/3/23 08:16, Somalapuram Amaranath wrote:
> Change the ttm_place structure member fpfn, lpfn, mem_type to
> res_start, res_end, res_type.
> Change the unsigned to u64.
> Fix the dependence in all the DRM drivers and
> clean up PAGE_SHIFT operation.
> 
> Signed-off-by: Somalapuram Amaranath 
> 
> [...]
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> index 44367f03316f..5b5104e724e3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
> @@ -131,11 +131,12 @@ static int amdgpu_gtt_mgr_new(struct 
> ttm_resource_manager *man,
>   goto err_free;
>   }
>  
> - if (place->lpfn) {
> + if (place->res_end) {
>   spin_lock(>lock);
>   r = drm_mm_insert_node_in_range(>mm, >mm_nodes[0],
> - num_pages, tbo->page_alignment,
> - 0, place->fpfn, place->lpfn,
> + num_pages, tbo->page_alignment, 
> 0,
> + place->res_start << PAGE_SHIFT,
> + place->res_end << PAGE_SHIFT,
>   DRM_MM_INSERT_BEST);

This should be >> or no shift instead of <<, shouldn't it? Multiplying a value 
in bytes by the page size doesn't make sense.


I didn't check the rest of the patch in detail, but it's easy introduce subtle 
regressions with this kind of change. It'll require a lot of review & testing 
scrutiny.


-- 
Earthling Michel Dänzer|  https://redhat.com
Libre software enthusiast  | Mesa and Xwayland developer



[PATCH v15 16/16] drm: bridge: samsung-dsim: Add i.MX8M Plus support

2023-03-03 Thread Jagan Teki
From: Marek Vasut 

Add extras to support i.MX8M Plus. The main change is the removal of
HS/VS/DE signal inversion in the LCDIFv3-DSIM glue logic, otherwise
the implementation of this IP in i.MX8M Plus is very much compatible
with the i.MX8M Mini/Nano one.

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Acked-by: Robert Foss 
Signed-off-by: Marek Vasut 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect RB from Frieder
- collect ACK from Robert
Changes for v10:
- none
Changes for v9:
- added im8mp in DSIM_STATE_REINITIALIZED check
- drop previous = NULL check

 drivers/gpu/drm/bridge/samsung-dsim.c | 23 +++
 include/drm/bridge/samsung-dsim.h |  1 +
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 3ffdaedaa261..b4a5348b763c 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -479,6 +479,7 @@ samsung_dsim_types[DSIM_TYPE_COUNT] = {
[DSIM_TYPE_EXYNOS5422] = _dsi_driver_data,
[DSIM_TYPE_EXYNOS5433] = _dsi_driver_data,
[DSIM_TYPE_IMX8MM] = _dsi_driver_data,
+   [DSIM_TYPE_IMX8MP] = _dsi_driver_data,
 };
 
 static inline struct samsung_dsim *host_to_dsi(struct mipi_dsi_host *h)
@@ -1452,10 +1453,17 @@ static int samsung_dsim_atomic_check(struct drm_bridge 
*bridge,
 * 13.6.2.7.2 RGB interface
 * both claim "Vsync, Hsync, and VDEN are active high signals.", the
 * LCDIF must generate inverted HS/VS/DE signals, i.e. active LOW.
+*
+* The i.MX8M Plus glue logic between LCDIFv3 and DSIM does not
+* implement the same behavior, therefore LCDIFv3 must generate
+* HS/VS/DE signals active HIGH.
 */
if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM) {
adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | 
DRM_MODE_FLAG_NVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | 
DRM_MODE_FLAG_PVSYNC);
+   } else if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MP) {
+   adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | 
DRM_MODE_FLAG_NVSYNC);
+   adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | 
DRM_MODE_FLAG_PVSYNC);
}
 
return 0;
@@ -1721,6 +1729,10 @@ static const struct samsung_dsim_host_ops 
generic_dsim_host_ops = {
.unregister_host = generic_dsim_unregister_host,
 };
 
+static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_high = {
+   .input_bus_flags = DRM_BUS_FLAG_DE_HIGH,
+};
+
 static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_low = {
.input_bus_flags = DRM_BUS_FLAG_DE_LOW,
 };
@@ -1810,6 +1822,8 @@ int samsung_dsim_probe(struct platform_device *pdev)
/* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */
if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)
dsi->bridge.timings = _dsim_bridge_timings_de_low;
+   else
+   dsi->bridge.timings = _dsim_bridge_timings_de_high;
 
if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->register_host)
ret = dsi->plat_data->host_ops->register_host(dsi);
@@ -1915,11 +1929,20 @@ static const struct samsung_dsim_plat_data 
samsung_dsim_imx8mm_pdata = {
.host_ops = _dsim_host_ops,
 };
 
+static const struct samsung_dsim_plat_data samsung_dsim_imx8mp_pdata = {
+   .hw_type = DSIM_TYPE_IMX8MP,
+   .host_ops = _dsim_host_ops,
+};
+
 static const struct of_device_id samsung_dsim_of_match[] = {
{
.compatible = "fsl,imx8mm-mipi-dsim",
.data = _dsim_imx8mm_pdata,
},
+   {
+   .compatible = "fsl,imx8mp-mipi-dsim",
+   .data = _dsim_imx8mp_pdata,
+   },
{ /* sentinel. */ }
 };
 MODULE_DEVICE_TABLE(of, samsung_dsim_of_match);
diff --git a/include/drm/bridge/samsung-dsim.h 
b/include/drm/bridge/samsung-dsim.h
index 4ba387c958ae..fb923caf09e1 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -28,6 +28,7 @@ enum samsung_dsim_type {
DSIM_TYPE_EXYNOS5422,
DSIM_TYPE_EXYNOS5433,
DSIM_TYPE_IMX8MM,
+   DSIM_TYPE_IMX8MP,
DSIM_TYPE_COUNT,
 };
 
-- 
2.25.1



[PATCH v15 15/16] dt-bindings: display: exynos: dsim: Add NXP i.MX8M Plus support

2023-03-03 Thread Jagan Teki
Samsung MIPI DSIM bridge can also be found in i.MX8M Plus SoC.

Add dt-bingings for it.

Reviewed-by: Marek Vasut 
Acked-by: Rob Herring 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect ACK from Rob
Changes for v10, v9:
- none

 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt 
b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
index 5133d4d39190..2a5f0889ec32 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
@@ -8,6 +8,7 @@ Required properties:
"samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
"fsl,imx8mm-mipi-dsim" /* for i.MX8M Mini/Nano SoCs */
+   "fsl,imx8mp-mipi-dsim" /* for i.MX8M Plus SoCs */
   - reg: physical base address and length of the registers set for the device
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
-- 
2.25.1



[PATCH v15 14/16] drm: bridge: samsung-dsim: Add i.MX8M Mini/Nano support

2023-03-03 Thread Jagan Teki
Samsung MIPI DSIM master can also be found in i.MX8M Mini/Nano SoC.

Add compatible and associated driver_data for it.

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Acked-by: Robert Foss 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect RB from Frieder
- collect ACK from Robert
Changes for v10, v9:
- none
Changed for v8:
- fix and update the comment
Changes for v7, v6:
- none
Changes for v3:
- enable DSIM_QUIRK_FIXUP_SYNC_POL quirk
Changes for v5:
- [mszyprow] rebased and adjusted to the new driver initialization
- drop quirk
Changes for v4:
- none
Changes for v3:
- enable DSIM_QUIRK_FIXUP_SYNC_POL quirk
Changes for v2:
- collect Laurent r-b
Changes for v1:
- none

 drivers/gpu/drm/bridge/samsung-dsim.c | 44 +++
 1 file changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 42e3536cb2fc..3ffdaedaa261 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -376,6 +376,24 @@ static const unsigned int exynos5433_reg_values[] = {
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
 };
 
+static const unsigned int imx8mm_dsim_reg_values[] = {
+   [RESET_TYPE] = DSIM_SWRST,
+   [PLL_TIMER] = 500,
+   [STOP_STATE_CNT] = 0xf,
+   [PHYCTRL_ULPS_EXIT] = 0,
+   [PHYCTRL_VREG_LP] = 0,
+   [PHYCTRL_SLEW_UP] = 0,
+   [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
+   [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),
+   [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),
+   [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x26),
+   [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),
+   [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),
+   [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x08),
+   [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),
+   [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
+};
+
 static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x50,
@@ -437,6 +455,22 @@ static const struct samsung_dsim_driver_data 
exynos5422_dsi_driver_data = {
.reg_values = exynos5422_reg_values,
 };
 
+static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
+   .reg_ofs = exynos5433_reg_ofs,
+   .plltmr_reg = 0xa0,
+   .has_clklane_stop = 1,
+   .num_clks = 2,
+   .max_freq = 2100,
+   .wait_for_reset = 0,
+   .num_bits_resol = 12,
+   /*
+* Unlike Exynos, PLL_P(PMS_P) offset 14 is used in i.MX8M 
Mini/Nano/Plus
+* downstream driver - drivers/gpu/drm/bridge/sec-dsim.c
+*/
+   .pll_p_offset = 14,
+   .reg_values = imx8mm_dsim_reg_values,
+};
+
 static const struct samsung_dsim_driver_data *
 samsung_dsim_types[DSIM_TYPE_COUNT] = {
[DSIM_TYPE_EXYNOS3250] = _dsi_driver_data,
@@ -444,6 +478,7 @@ samsung_dsim_types[DSIM_TYPE_COUNT] = {
[DSIM_TYPE_EXYNOS5410] = _dsi_driver_data,
[DSIM_TYPE_EXYNOS5422] = _dsi_driver_data,
[DSIM_TYPE_EXYNOS5433] = _dsi_driver_data,
+   [DSIM_TYPE_IMX8MM] = _dsi_driver_data,
 };
 
 static inline struct samsung_dsim *host_to_dsi(struct mipi_dsi_host *h)
@@ -1875,7 +1910,16 @@ const struct dev_pm_ops samsung_dsim_pm_ops = {
 };
 EXPORT_SYMBOL_GPL(samsung_dsim_pm_ops);
 
+static const struct samsung_dsim_plat_data samsung_dsim_imx8mm_pdata = {
+   .hw_type = DSIM_TYPE_IMX8MM,
+   .host_ops = _dsim_host_ops,
+};
+
 static const struct of_device_id samsung_dsim_of_match[] = {
+   {
+   .compatible = "fsl,imx8mm-mipi-dsim",
+   .data = _dsim_imx8mm_pdata,
+   },
{ /* sentinel. */ }
 };
 MODULE_DEVICE_TABLE(of, samsung_dsim_of_match);
-- 
2.25.1



[PATCH v15 13/16] dt-bindings: display: exynos: dsim: Add NXP i.MX8M Mini/Nano support

2023-03-03 Thread Jagan Teki
Samsung MIPI DSIM bridge can also be found in i.MX8M Mini/Nano SoC.

Add dt-bingings for it.

Reviewed-by: Marek Vasut 
Acked-by: Rob Herring 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11, v10, v9:
- none
Changes for v8:
- add comment to include i.MX8M Nano.
Changes for v7, v6, v5, v4:
- none
Changes for v3:
- collect Rob Acked-by
Changes for v2:
- updated comments
Changes for v1:
- new patch

 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt 
b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
index be377786e8cd..5133d4d39190 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
@@ -7,6 +7,7 @@ Required properties:
"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs 
*/
"samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
+   "fsl,imx8mm-mipi-dsim" /* for i.MX8M Mini/Nano SoCs */
   - reg: physical base address and length of the registers set for the device
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
-- 
2.25.1



[PATCH v15 12/16] drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge

2023-03-03 Thread Jagan Teki
Samsung MIPI DSIM controller is common DSI IP that can be used in various
SoCs like Exynos, i.MX8M Mini/Nano.

In order to access this DSI controller between various platform SoCs,
the ideal way to incorporate this in the drm stack is via the drm bridge
driver.

We already have a consolidated code for supporting component and bridge
based DRM drivers, so keep the exynos component based code in existing
exynos_drm_dsi.c and move generic bridge code as part of samsung-dsim.c

Reviewed-by: Marek Vasut 
Signed-off-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
Changes for v15:
- drop redundent 
  dsim->bridge.funcs->atomic_disable(>bridge, NULL);
Changes for v13:
- none
Changes for v11:
- sort MAINTAINERS list
- collect RB from Marek
Changes for v11:
- fix BIT macro replacements
- fix checkpatch --strict warnings
Changes for v10:
- don't add new code
- move the files and update samsung_dsim names
- update commit message
Changes for v9:
- drop the bridge attach fix for Exynos
Changes for v8:
- update the commit message head
Changes for v7:
- fix the drm bridge attach chain for exynos drm dsi driver
- fix the hw_type checking logic
Changes for v6:
- handle previous bridge pointer for exynos dsi
Changes for v5:
- [mszyprow] reworked driver initialization using the same approach as in
  drivers/gpu/drm/{exynos/exynos_dp.c, bridge/analogix/analogix_dp_core.c},
  removed weak functions, moved exynos_dsi_driver back to exynos_drm_dsi.c
  and restored integration with exynos_drm custom initialization.
- updated the commit message [Jagan]
Changes for v4:
- include Inki Dae in MAINTAINERS
- remove dsi_driver probe in exynos_drm_drv to support multi-arch build
Changes for v3:
- restore gpio related fixes
- restore proper bridge chain
- rework initialization issue
- fix header includes in proper way
Changes for v2:
- fixed exynos dsi driver conversion (Marek Szyprowski)
- updated commit message
- updated MAINTAINERS file
Changes for v1:
- don't maintain component_ops in bridge driver
- don't maintain platform glue code in bridge driver
- add platform-specific glue code and make a common bridge

 MAINTAINERS |9 +
 drivers/gpu/drm/bridge/Kconfig  |   12 +
 drivers/gpu/drm/bridge/Makefile |1 +
 drivers/gpu/drm/bridge/samsung-dsim.c   | 1898 +
 drivers/gpu/drm/exynos/Kconfig  |1 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 2051 +--
 include/drm/bridge/samsung-dsim.h   |  114 ++
 7 files changed, 2079 insertions(+), 2007 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/samsung-dsim.c
 create mode 100644 include/drm/bridge/samsung-dsim.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 97d814a19475..f604c36b31bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6737,6 +6737,15 @@ T:   git git://anongit.freedesktop.org/drm/drm-misc
 F: Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
 F: drivers/gpu/drm/panel/panel-samsung-db7430.c
 
+DRM DRIVER FOR SAMSUNG MIPI DSIM BRIDGE
+M: Inki Dae 
+M: Jagan Teki 
+M: Marek Szyprowski 
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/bridge/samsung-dsim.c
+F: include/drm/bridge/samsung-dsim.h
+
 DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
 M: Markuss Broks 
 S: Maintained
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 8b2226f72b24..e9d00bcf2d5c 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -220,6 +220,18 @@ config DRM_PARADE_PS8640
  The PS8640 is a high-performance and low-power
  MIPI DSI to eDP converter
 
+config DRM_SAMSUNG_DSIM
+   tristate "Samsung MIPI DSIM bridge driver"
+   depends on COMMON_CLK
+   depends on OF && HAS_IOMEM
+   select DRM_KMS_HELPER
+   select DRM_MIPI_DSI
+   select DRM_PANEL_BRIDGE
+   help
+ The Samsung MIPI DSIM bridge controller driver.
+ This MIPI DSIM bridge can be found it on Exynos SoCs and
+ NXP's i.MX8M Mini/Nano.
+
 config DRM_SIL_SII8620
tristate "Silicon Image SII8620 HDMI/MHL bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 52f6e8b4a821..2b892b7ed59e 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
megachips-stdp-ge-b850v
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
+obj-$(CONFIG_DRM_SAMSUNG_DSIM) += samsung-dsim.o
 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
 obj-$(CONFIG_DRM_SII902X) += sii902x.o
 obj-$(CONFIG_DRM_SII9234) += sii9234.o
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
new file mode 100644
index ..42e3536cb2fc
--- /dev/null
+++ 

[PATCH v15 11/16] drm: exynos: dsi: Add host helper for te_irq_handler

2023-03-03 Thread Jagan Teki
IRQ handler for te-gpio seems to be common across DSIM host.

However, Exynos is handling this via CRTC drivers but there is no clear
evidence on how the same has been handled in i.MX8MM. Keeping the handler
as-it-is can be a viable option but adding DSIM bridge core in upcoming
patches is not possible to call Exynos CRTC handler as DSIM bridge has
to be common across DRM bridge core instead of platform specific DRM
drivers like Exynos here.

So, this patch handles the handler via platform host helper, so-that
handling platform specific hook across Exynos and generic can be
reasonable till it makes it generic across all platforms.

Reviewed-by: Marek Vasut 
Signed-off-by: Jagan Teki 
---
Changes for v15:
- remove leading  underscores in function names
- collect RB from Marek
Changes for v13:
- none
Changes for v12:
- updated patch
- suggested by Marek V
Changes for v11:
- none
Changes for v10:
- split from previous series patch
"drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge"

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index afe2d293c785..2fc166ebe3c7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -325,6 +325,7 @@ struct exynos_dsim_host_ops {
void (*unregister_host)(struct exynos_dsi *dsim);
int (*attach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device);
int (*detach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device);
+   irqreturn_t (*te_irq_handler)(struct exynos_dsi *dsim);
 };
 
 struct exynos_dsi_enc {
@@ -1333,11 +1334,10 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
 {
struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
-   struct exynos_dsi_enc *dsi_enc = dsi->priv;
-   struct drm_encoder *encoder = _enc->encoder;
+   const struct exynos_dsi_plat_data *pdata = dsi->plat_data;
 
-   if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
-   exynos_drm_crtc_te_handler(encoder->crtc);
+   if (pdata->host_ops && pdata->host_ops->te_irq_handler)
+   return pdata->host_ops->te_irq_handler(dsi);
 
return IRQ_HANDLED;
 }
@@ -1761,6 +1761,17 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
return 0;
 }
 
+static irqreturn_t exynos_dsim_te_irq_handler(struct exynos_dsi *dsim)
+{
+   struct exynos_dsi_enc *dsi_enc = dsim->priv;
+   struct drm_encoder *encoder = _enc->encoder;
+
+   if (dsim->state & DSIM_STATE_VIDOUT_AVAILABLE)
+   exynos_drm_crtc_te_handler(encoder->crtc);
+
+   return IRQ_HANDLED;
+}
+
 static int exynos_dsim_host_attach(struct exynos_dsi *dsim,
   struct mipi_dsi_device *device)
 {
@@ -2075,6 +2086,7 @@ static const struct exynos_dsim_host_ops 
exynos_dsi_host_ops = {
.unregister_host = exynos_dsi_unregister_host,
.attach = exynos_dsim_host_attach,
.detach = exynos_dsim_host_detach,
+   .te_irq_handler = exynos_dsim_te_irq_handler,
 };
 
 static const struct exynos_dsi_plat_data exynos3250_dsi_pdata = {
-- 
2.25.1



[PATCH v15 10/16] drm: exynos: dsi: Consolidate component and bridge

2023-03-03 Thread Jagan Teki
DSI host registration, attach and detach operations are quite
different for the component and bridge-based DRM drivers. 

Supporting generic bridge driver to use both component and bridge
based DRM drivers can be tricky and would require additional host
related operation hooks.

Add host operation hooks for registering and unregistering Exynos
and generic drivers, where Exynos hooks are used in existing Exynos
component based DRM drivers and generic hooks are used in i.MX8M
bridge based DRM drivers. 

Add host attach and detach operation hooks for Exynos component
DRM drivers and those get invoked while DSI core host attach and
detach gets called.

Reviewed-by: Marek Vasut 
Signed-off-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
Changes for v15:
- remove leading  underscores in function names
Changes for v13:
- none
Changes for v12:
- fix unneeded decleration
- collect RB from Marek
Changes for v11:
- none
Changes for v10:
- split from previous series patch
"drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge"

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 169 +++-
 1 file changed, 134 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index c8829f33f36e..afe2d293c785 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -283,10 +283,10 @@ struct exynos_dsi_driver_data {
 
 struct exynos_dsi_plat_data {
enum exynos_dsi_type hw_type;
+   const struct exynos_dsim_host_ops *host_ops;
 };
 
 struct exynos_dsi {
-   struct drm_encoder encoder;
struct mipi_dsi_host dsi_host;
struct drm_bridge bridge;
struct drm_bridge *out_bridge;
@@ -316,6 +316,19 @@ struct exynos_dsi {
 
const struct exynos_dsi_driver_data *driver_data;
const struct exynos_dsi_plat_data *plat_data;
+
+   void *priv;
+};
+
+struct exynos_dsim_host_ops {
+   int (*register_host)(struct exynos_dsi *dsim);
+   void (*unregister_host)(struct exynos_dsi *dsim);
+   int (*attach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device);
+   int (*detach)(struct exynos_dsi *dsim, struct mipi_dsi_device *device);
+};
+
+struct exynos_dsi_enc {
+   struct drm_encoder encoder;
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
@@ -1320,7 +1333,8 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
 {
struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
-   struct drm_encoder *encoder = >encoder;
+   struct exynos_dsi_enc *dsi_enc = dsi->priv;
+   struct drm_encoder *encoder = _enc->encoder;
 
if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
exynos_drm_crtc_te_handler(encoder->crtc);
@@ -1589,9 +1603,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
  struct mipi_dsi_device *device)
 {
struct exynos_dsi *dsi = host_to_dsi(host);
+   const struct exynos_dsi_plat_data *pdata = dsi->plat_data;
struct device *dev = dsi->dev;
-   struct drm_encoder *encoder = >encoder;
-   struct drm_device *drm = encoder->dev;
struct device_node *np = dev->of_node;
struct device_node *remote;
struct drm_panel *panel;
@@ -1648,35 +1661,15 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
 
drm_bridge_add(>bridge);
 
-   drm_bridge_attach(encoder, >bridge,
- list_first_entry_or_null(>bridge_chain,
-  struct drm_bridge,
-  chain_node), 0);
-
-   /*
-* This is a temporary solution and should be made by more generic way.
-*
-* If attached panel device is for command mode one, dsi should register
-* TE interrupt handler.
-*/
-   if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
-   ret = exynos_dsi_register_te_irq(dsi, >dev);
-   if (ret)
+   if (pdata->host_ops && pdata->host_ops->attach) {
+   ret = pdata->host_ops->attach(dsi, device);
+   if (ret < 0)
return ret;
}
 
-   mutex_lock(>mode_config.mutex);
-
dsi->lanes = device->lanes;
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
-   exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
-   !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
-
-   mutex_unlock(>mode_config.mutex);
-
-   if (drm->mode_config.poll_enabled)
-   drm_kms_helper_hotplug_event(drm);
 
return 0;
 }
@@ -1685,14 +1678,16 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host 
*host,
  struct mipi_dsi_device *device)
 {
struct exynos_dsi *dsi = 

[PATCH v15 09/16] drm: exynos: dsi: Add atomic_get_input_bus_fmts

2023-03-03 Thread Jagan Teki
Finding the right input bus format throughout the pipeline is hard
so add atomic_get_input_bus_fmts callback and initialize with the
proper input format from list of supported output formats.

This format can be used in pipeline for negotiating bus format between
the DSI-end of this bridge and the other component closer to pipeline
components.

List of Pixel formats are taken from,
AN13573 i.MX 8/RT MIPI DSI/CSI-2, Rev. 0, 21 March 2022
3.7.4 Pixel formats
Table 14. DSI pixel packing formats

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Tested-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
Changes for v15:
- collect RB from Marek
Changes for v12:
- update the logic suggested by Marek
Changes for v11:
- collect RB from Frieder
- drop extra line
Changes for v10:
- none
Changes for v9:
- added MEDIA_BUS_FMT_FIXED
- return MEDIA_BUS_FMT_RGB888_1X24 output_fmt if supported output_fmt
  list is unsupported.
- added MEDIA_BUS_FMT_YUYV10_1X20, MEDIA_BUS_FMT_YUYV12_1X24
Changes for v8:
- added pixel formats supported by NXP AN13573 i.MX 8/RT MIPI DSI/CSI-2
Changes for v7 - v4:
- none
Changes for v3:
- include media-bus-format.h
Changes for v2:
- none
Changes for v1:
- new patch

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 62 +
 1 file changed, 62 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 5d971b607e1a..c8829f33f36e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1466,6 +1467,66 @@ static void exynos_dsi_atomic_post_disable(struct 
drm_bridge *bridge,
pm_runtime_put_sync(dsi->dev);
 }
 
+/*
+ * This pixel output formats list referenced from,
+ * AN13573 i.MX 8/RT MIPI DSI/CSI-2, Rev. 0, 21 March 2022
+ * 3.7.4 Pixel formats
+ * Table 14. DSI pixel packing formats
+ */
+static const u32 exynos_dsi_pixel_output_fmts[] = {
+   MEDIA_BUS_FMT_YUYV10_1X20,
+   MEDIA_BUS_FMT_YUYV12_1X24,
+   MEDIA_BUS_FMT_UYVY8_1X16,
+   MEDIA_BUS_FMT_RGB101010_1X30,
+   MEDIA_BUS_FMT_RGB121212_1X36,
+   MEDIA_BUS_FMT_RGB565_1X16,
+   MEDIA_BUS_FMT_RGB666_1X18,
+   MEDIA_BUS_FMT_RGB888_1X24,
+};
+
+static bool exynos_dsi_pixel_output_fmt_supported(u32 fmt)
+{
+   int i;
+
+   if (fmt == MEDIA_BUS_FMT_FIXED)
+   return false;
+
+   for (i = 0; i < ARRAY_SIZE(exynos_dsi_pixel_output_fmts); i++) {
+   if (exynos_dsi_pixel_output_fmts[i] == fmt)
+   return true;
+   }
+
+   return false;
+}
+
+static u32 *
+exynos_dsi_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+struct drm_bridge_state *bridge_state,
+struct drm_crtc_state *crtc_state,
+struct drm_connector_state *conn_state,
+u32 output_fmt,
+unsigned int *num_input_fmts)
+{
+   u32 *input_fmts;
+
+   input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+   if (!input_fmts)
+   return NULL;
+
+   if (!exynos_dsi_pixel_output_fmt_supported(output_fmt))
+   /*
+* Some bridge/display drivers are still not able to pass the
+* correct format, so handle those pipelines by falling back
+* to the default format till the supported formats finalized.
+*/
+   output_fmt = MEDIA_BUS_FMT_RGB888_1X24;
+
+   input_fmts[0] = output_fmt;
+   *num_input_fmts = 1;
+
+   return input_fmts;
+}
+
 static int exynos_dsi_atomic_check(struct drm_bridge *bridge,
   struct drm_bridge_state *bridge_state,
   struct drm_crtc_state *crtc_state,
@@ -1514,6 +1575,7 @@ static const struct drm_bridge_funcs 
exynos_dsi_bridge_funcs = {
.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_get_input_bus_fmts  = exynos_dsi_atomic_get_input_bus_fmts,
.atomic_check   = exynos_dsi_atomic_check,
.atomic_pre_enable  = exynos_dsi_atomic_pre_enable,
.atomic_enable  = exynos_dsi_atomic_enable,
-- 
2.25.1



[PATCH v15 08/16] drm: exynos: dsi: Add input_bus_flags

2023-03-03 Thread Jagan Teki
LCDIF-DSIM glue logic inverts the HS/VS/DE signals and expecting
the i.MX8M Mini/Nano DSI host to add additional Data Enable signal
active low (DE_LOW). This makes the valid data transfer on each
horizontal line.

So, add additional bus flags DE_LOW setting via input_bus_flags
for i.MX8M Mini/Nano platforms.

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Suggested-by: Marek Vasut 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect RB from Frieder
Changes for v10, v9:
- none
Changes for v8:
- add DE_LOW for i.MX8M Mini/Nano platforms.
Changes for v7, v6:
- none
Changes for v5:
- rebased based on updated bridge changes
Changes for v4 - v1:
- none

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 796480e4a18b..5d971b607e1a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1736,6 +1736,10 @@ static const struct component_ops 
exynos_dsi_component_ops = {
.unbind = exynos_dsi_unbind,
 };
 
+static const struct drm_bridge_timings dsim_bridge_timings_de_low = {
+   .input_bus_flags = DRM_BUS_FLAG_DE_LOW,
+};
+
 static int exynos_dsi_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -1822,6 +1826,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
dsi->bridge.pre_enable_prev_first = true;
 
+   /* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */
+   if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)
+   dsi->bridge.timings = _bridge_timings_de_low;
+
ret = component_add(dev, _dsi_component_ops);
if (ret)
goto err_disable_runtime;
-- 
2.25.1



[PATCH v15 07/16] drm: exynos: dsi: Add atomic check

2023-03-03 Thread Jagan Teki
Look like an explicit fixing up of mode_flags is required for DSIM IP
present in i.MX8M Mini/Nano SoCs.

At least the LCDIF + DSIM needs active low sync polarities in order
to correlate the correct sync flags of the surrounding components in
the chain to make sure the whole pipeline can work properly.

On the other hand the i.MX 8M Mini Applications Processor Reference Manual,
Rev. 3, 11/2020 says.
"13.6.3.5.2 RGB interface
 Vsync, Hsync, and VDEN are active high signals."

i.MX 8M Mini Applications Processor Reference Manual Rev. 3, 11/2020
3.6.3.5.2 RGB interface
i.MX 8M Nano Applications Processor Reference Manual Rev. 2, 07/2022
13.6.2.7.2 RGB interface
both claim "Vsync, Hsync, and VDEN are active high signals.", the
LCDIF must generate inverted HS/VS/DE signals, i.e. active LOW.

No clear evidence about whether it can be documentation issues or
something, so added proper comments on the code.

Comments are suggested by Marek Vasut.

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect RB from Frieder
- fix commit message
Changes for v10, v9:
- none
Changes for v8:
- update the comments about sync signals polarities
- added clear commit message by including i.MX8M Nano details
Changes for v7:
- fix the hw_type checking logic
Changes for v6:
- none
Changes for v5:
- rebase based new bridge changes [mszyprow]
- remove DSIM_QUIRK_FIXUP_SYNC_POL
- add hw_type check for sync polarities change.
Changes for v4:
- none
Changes for v3:
- add DSIM_QUIRK_FIXUP_SYNC_POL to handle mode_flasg fixup
Changes for v2:
- none
Changes for v1:
- fix mode flags in atomic_check instead of mode_fixup

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 28 +
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index fe195d76ce76..796480e4a18b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -263,6 +263,7 @@ enum exynos_dsi_type {
DSIM_TYPE_EXYNOS5410,
DSIM_TYPE_EXYNOS5422,
DSIM_TYPE_EXYNOS5433,
+   DSIM_TYPE_IMX8MM,
DSIM_TYPE_COUNT,
 };
 
@@ -1465,6 +1466,32 @@ static void exynos_dsi_atomic_post_disable(struct 
drm_bridge *bridge,
pm_runtime_put_sync(dsi->dev);
 }
 
+static int exynos_dsi_atomic_check(struct drm_bridge *bridge,
+  struct drm_bridge_state *bridge_state,
+  struct drm_crtc_state *crtc_state,
+  struct drm_connector_state *conn_state)
+{
+   struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+   struct drm_display_mode *adjusted_mode = _state->adjusted_mode;
+
+   /*
+* The i.MX8M Mini/Nano glue logic between LCDIF and DSIM
+* inverts HS/VS/DE sync signals polarity, therefore, while
+* i.MX 8M Mini Applications Processor Reference Manual Rev. 3, 11/2020
+* 13.6.3.5.2 RGB interface
+* i.MX 8M Nano Applications Processor Reference Manual Rev. 2, 07/2022
+* 13.6.2.7.2 RGB interface
+* both claim "Vsync, Hsync, and VDEN are active high signals.", the
+* LCDIF must generate inverted HS/VS/DE signals, i.e. active LOW.
+*/
+   if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM) {
+   adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | 
DRM_MODE_FLAG_NVSYNC);
+   adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | 
DRM_MODE_FLAG_PVSYNC);
+   }
+
+   return 0;
+}
+
 static void exynos_dsi_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
@@ -1487,6 +1514,7 @@ static const struct drm_bridge_funcs 
exynos_dsi_bridge_funcs = {
.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_check   = exynos_dsi_atomic_check,
.atomic_pre_enable  = exynos_dsi_atomic_pre_enable,
.atomic_enable  = exynos_dsi_atomic_enable,
.atomic_disable = exynos_dsi_atomic_disable,
-- 
2.25.1



[PATCH v15 06/16] drm: exynos: dsi: Handle proper host initialization

2023-03-03 Thread Jagan Teki
From: Marek Szyprowski 

Host transfer() in the DSI master will invoke only when the DSI commands
are sent from DSI devices like DSI Panel or DSI bridges and this host
the transfer wouldn't invoke for I2C-based-DSI bridge drivers.

Handling DSI host initialization in transfer calls misses the controller
setup for I2C configured DSI bridges.

This patch updates the DSI host initialization by calling host to init
from bridge pre_enable as the bridge pre_enable API is invoked by core
as it is common across all classes of DSI device drivers.

The host init during pre_enable is conditional and not invoked for Exynos
as existing downstream drm panels and bridges in Exynos are expecting
the host initialization during DSI transfer.

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Signed-off-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none 
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect RB from Frieder
Changes for v10:
- update the to simple logic to handle all platforms
Changs for v9 - v8:
- none
Changes for v2:
- check initialized state in samsung_dsim_init
Changes for v1:
- keep DSI init in host transfer

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 64cf69995750..fe195d76ce76 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,6 +254,9 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_CMD_LPM BIT(2)
 #define DSIM_STATE_VIDOUT_AVAILABLEBIT(3)
 
+#define exynos_dsi_hw_is_exynos(hw) \
+   ((hw) >= DSIM_TYPE_EXYNOS3250 && (hw) <= DSIM_TYPE_EXYNOS5433)
+
 enum exynos_dsi_type {
DSIM_TYPE_EXYNOS3250,
DSIM_TYPE_EXYNOS4210,
@@ -1343,6 +1346,9 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)
 {
const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
 
+   if (dsi->state & DSIM_STATE_INITIALIZED)
+   return 0;
+
exynos_dsi_reset(dsi);
exynos_dsi_enable_irq(dsi);
 
@@ -1355,6 +1361,8 @@ static int exynos_dsi_init(struct exynos_dsi *dsi)
exynos_dsi_set_phy_ctrl(dsi);
exynos_dsi_init_link(dsi);
 
+   dsi->state |= DSIM_STATE_INITIALIZED;
+
return 0;
 }
 
@@ -1410,6 +1418,16 @@ static void exynos_dsi_atomic_pre_enable(struct 
drm_bridge *bridge,
}
 
dsi->state |= DSIM_STATE_ENABLED;
+
+   /*
+* For Exynos-DSIM the downstream bridge, or panel are expecting
+* the host initialization during DSI transfer.
+*/
+   if (!exynos_dsi_hw_is_exynos(dsi->plat_data->hw_type)) {
+   ret = exynos_dsi_init(dsi);
+   if (ret)
+   return;
+   }
 }
 
 static void exynos_dsi_atomic_enable(struct drm_bridge *bridge,
@@ -1601,12 +1619,9 @@ static ssize_t exynos_dsi_host_transfer(struct 
mipi_dsi_host *host,
if (!(dsi->state & DSIM_STATE_ENABLED))
return -EINVAL;
 
-   if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
-   ret = exynos_dsi_init(dsi);
-   if (ret)
-   return ret;
-   dsi->state |= DSIM_STATE_INITIALIZED;
-   }
+   ret = exynos_dsi_init(dsi);
+   if (ret)
+   return ret;
 
ret = mipi_dsi_create_packet(, msg);
if (ret < 0)
-- 
2.25.1



[PATCH v15 05/16] drm: exynos: dsi: Introduce hw_type platform data

2023-03-03 Thread Jagan Teki
Samsung MIPI DSIM controller is common DSI IP that can be used
in various SoCs like Exynos, i.MX8M Mini/Nano/Plus.

Add hw_type enum via platform_data so that accessing the different
controller data between various platforms becomes easy and meaningful.

Reviewed-by: Marek Vasut 
Reviewed-by: Frieder Schrempf 
Suggested-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13:
- none
Changes for v12:
- collect RB from Marek
Changes for v11:
- collect RB from Frieder
- drop extra line
Changes for v10:
- split from previous series patch
"drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge"
- update enum type names

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 83 -
 1 file changed, 68 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 603fed107fd1..64cf69995750 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,6 +254,15 @@ struct exynos_dsi_transfer {
 #define DSIM_STATE_CMD_LPM BIT(2)
 #define DSIM_STATE_VIDOUT_AVAILABLEBIT(3)
 
+enum exynos_dsi_type {
+   DSIM_TYPE_EXYNOS3250,
+   DSIM_TYPE_EXYNOS4210,
+   DSIM_TYPE_EXYNOS5410,
+   DSIM_TYPE_EXYNOS5422,
+   DSIM_TYPE_EXYNOS5433,
+   DSIM_TYPE_COUNT,
+};
+
 struct exynos_dsi_driver_data {
const unsigned int *reg_ofs;
unsigned int plltmr_reg;
@@ -267,6 +276,10 @@ struct exynos_dsi_driver_data {
const unsigned int *reg_values;
 };
 
+struct exynos_dsi_plat_data {
+   enum exynos_dsi_type hw_type;
+};
+
 struct exynos_dsi {
struct drm_encoder encoder;
struct mipi_dsi_host dsi_host;
@@ -297,6 +310,7 @@ struct exynos_dsi {
struct list_head transfer_list;
 
const struct exynos_dsi_driver_data *driver_data;
+   const struct exynos_dsi_plat_data *plat_data;
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
@@ -524,18 +538,13 @@ static const struct exynos_dsi_driver_data 
exynos5422_dsi_driver_data = {
.reg_values = exynos5422_reg_values,
 };
 
-static const struct of_device_id exynos_dsi_of_match[] = {
-   { .compatible = "samsung,exynos3250-mipi-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "samsung,exynos4210-mipi-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "samsung,exynos5410-mipi-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "samsung,exynos5422-mipi-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "samsung,exynos5433-mipi-dsi",
- .data = _dsi_driver_data },
-   { }
+static const struct exynos_dsi_driver_data *
+exynos_dsi_types[DSIM_TYPE_COUNT] = {
+   [DSIM_TYPE_EXYNOS3250] = _dsi_driver_data,
+   [DSIM_TYPE_EXYNOS4210] = _dsi_driver_data,
+   [DSIM_TYPE_EXYNOS5410] = _dsi_driver_data,
+   [DSIM_TYPE_EXYNOS5422] = _dsi_driver_data,
+   [DSIM_TYPE_EXYNOS5433] = _dsi_driver_data,
 };
 
 static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
@@ -1468,8 +1477,6 @@ static const struct drm_bridge_funcs 
exynos_dsi_bridge_funcs = {
.attach = exynos_dsi_attach,
 };
 
-MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
-
 static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
  struct mipi_dsi_device *device)
 {
@@ -1704,7 +1711,8 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dsi->dsi_host.dev = dev;
 
dsi->dev = dev;
-   dsi->driver_data = of_device_get_match_data(dev);
+   dsi->plat_data = of_device_get_match_data(dev);
+   dsi->driver_data = exynos_dsi_types[dsi->plat_data->hw_type];
 
dsi->supplies[0].supply = "vddcore";
dsi->supplies[1].supply = "vddio";
@@ -1862,6 +1870,51 @@ static const struct dev_pm_ops exynos_dsi_pm_ops = {
pm_runtime_force_resume)
 };
 
+static const struct exynos_dsi_plat_data exynos3250_dsi_pdata = {
+   .hw_type = DSIM_TYPE_EXYNOS3250,
+};
+
+static const struct exynos_dsi_plat_data exynos4210_dsi_pdata = {
+   .hw_type = DSIM_TYPE_EXYNOS4210,
+};
+
+static const struct exynos_dsi_plat_data exynos5410_dsi_pdata = {
+   .hw_type = DSIM_TYPE_EXYNOS5410,
+};
+
+static const struct exynos_dsi_plat_data exynos5422_dsi_pdata = {
+   .hw_type = DSIM_TYPE_EXYNOS5422,
+};
+
+static const struct exynos_dsi_plat_data exynos5433_dsi_pdata = {
+   .hw_type = DSIM_TYPE_EXYNOS5433,
+};
+
+static const struct of_device_id exynos_dsi_of_match[] = {
+   {
+   .compatible = "samsung,exynos3250-mipi-dsi",
+   .data = _dsi_pdata,
+   },
+   {
+   .compatible = "samsung,exynos4210-mipi-dsi",
+   .data = _dsi_pdata,
+   },
+   {
+   .compatible = "samsung,exynos5410-mipi-dsi",
+   .data = _dsi_pdata,
+   },
+   {
+   

[PATCH v15 04/16] drm: exynos: dsi: Add platform PLL_P (PMS_P) offset

2023-03-03 Thread Jagan Teki
Look like PLL PMS_P offset value varies between platforms that have
Samsung DSIM IP.

However, there is no clear evidence for it as both Exynos and i.MX
8M Mini Application Processor Reference Manual is still referring
the PMS_P offset as 13.

The offset 13 is not working for i.MX8M Mini SoCs but the downstream
NXP sec-dsim.c driver is using offset 14 for i.MX8M Mini SoC platforms
[1] [2].

PMS_P value set in sec_mipi_dsim_check_pll_out using PLLCTRL_SET_P()
with offset 13 and then an additional offset of one bit added in
sec_mipi_dsim_config_pll via PLLCTRL_SET_PMS().

Not sure whether it is reference manual documentation or something
else but this patch trusts the downstream code and handle PLL_P offset
via platform driver data so-that imx8mm driver data shall use
pll_p_offset to 14.

Similar to Mini the i.MX8M Nano/Plus also has P=14, unlike Exynos.

[1] 
https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/gpu/drm/bridge/sec-dsim.c?h=imx_5.4.47_2.2.0#n210
[2] 
https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/gpu/drm/bridge/sec-dsim.c?h=imx_5.4.47_2.2.0#n211

Reviewed-by: Marek Vasut 
Signed-off-by: Frieder Schrempf 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13, v12, v11, v10, v9:
- none
Changes for v8:
- updated commit message for 8M Nano/Plus
Changes for v7, v6:
- none
Changes for v5:
- updated clear commit message
Changes for v4, v3, v2:
- none
Changes for v1:
- updated commit message
- add downstream driver link

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index af16af404e87..603fed107fd1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -194,7 +194,7 @@
 /* DSIM_PLLCTRL */
 #define DSIM_FREQ_BAND(x)  ((x) << 24)
 #define DSIM_PLL_EN(1 << 23)
-#define DSIM_PLL_P(x)  ((x) << 13)
+#define DSIM_PLL_P(x, offset)  ((x) << (offset))
 #define DSIM_PLL_M(x)  ((x) << 4)
 #define DSIM_PLL_S(x)  ((x) << 1)
 
@@ -263,6 +263,7 @@ struct exynos_dsi_driver_data {
unsigned int max_freq;
unsigned int wait_for_reset;
unsigned int num_bits_resol;
+   unsigned int pll_p_offset;
const unsigned int *reg_values;
 };
 
@@ -471,6 +472,7 @@ static const struct exynos_dsi_driver_data 
exynos3_dsi_driver_data = {
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
+   .pll_p_offset = 13,
.reg_values = reg_values,
 };
 
@@ -483,6 +485,7 @@ static const struct exynos_dsi_driver_data 
exynos4_dsi_driver_data = {
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
+   .pll_p_offset = 13,
.reg_values = reg_values,
 };
 
@@ -493,6 +496,7 @@ static const struct exynos_dsi_driver_data 
exynos5_dsi_driver_data = {
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
+   .pll_p_offset = 13,
.reg_values = reg_values,
 };
 
@@ -504,6 +508,7 @@ static const struct exynos_dsi_driver_data 
exynos5433_dsi_driver_data = {
.max_freq = 1500,
.wait_for_reset = 0,
.num_bits_resol = 12,
+   .pll_p_offset = 13,
.reg_values = exynos5433_reg_values,
 };
 
@@ -515,6 +520,7 @@ static const struct exynos_dsi_driver_data 
exynos5422_dsi_driver_data = {
.max_freq = 1500,
.wait_for_reset = 1,
.num_bits_resol = 12,
+   .pll_p_offset = 13,
.reg_values = exynos5422_reg_values,
 };
 
@@ -628,7 +634,8 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi 
*dsi,
writel(driver_data->reg_values[PLL_TIMER],
dsi->reg_base + driver_data->plltmr_reg);
 
-   reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
+   reg = DSIM_PLL_EN | DSIM_PLL_P(p, driver_data->pll_p_offset) |
+ DSIM_PLL_M(m) | DSIM_PLL_S(s);
 
if (driver_data->has_freqband) {
static const unsigned long freq_bands[] = {
-- 
2.25.1



[PATCH v15 03/16] drm: exynos: dsi: Mark PHY as optional

2023-03-03 Thread Jagan Teki
The same Samsung MIPI DSIM master can also be used in NXP's
i.MX8M Mini/Nano/Plus SoC.

In i.MX8M Mini/Nano/Plus SoC the DSI Phy requires a MIPI DPHY
bit to reset in order to activate the PHY and that can be done
via upstream i.MX8M blk-ctrl driver.

So, mark the phy get as optional.

Reviewed-by: Frieder Schrempf 
Reviewed-by: Marek Vasut 
Signed-off-by: Jagan Teki 
---
Changes for v15, v13, v12:
- none
Changes for v11:
- collect Frieder RB
Changes for v10:
- add Plus in commit message
- collect Marek RB
Changes for v9, v8, v7, v6, v5, v4, v3, v2:
- none
Changes for v1:
- new patch

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index f44a5a702ad5..af16af404e87 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1732,7 +1732,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
if (IS_ERR(dsi->reg_base))
return PTR_ERR(dsi->reg_base);
 
-   dsi->phy = devm_phy_get(dev, "dsim");
+   dsi->phy = devm_phy_optional_get(dev, "dsim");
if (IS_ERR(dsi->phy)) {
dev_info(dev, "failed to get dsim phy\n");
return PTR_ERR(dsi->phy);
-- 
2.25.1



[PATCH v15 02/16] drm: exynos: dsi: Lookup OF-graph or Child node devices

2023-03-03 Thread Jagan Teki
In general, for MIPI DSI there are three ways to represent the
pipeline for an upstream bridge to find the connected downstream
panel or bridge.

1. Child panel or bridge as a conventional device tree child node.
2. Child panel or bridge as an OF-graph port node.
3. Child panel or bridge as an OF-graph ports node.

There are three different downstream panels or bridges that are
possible to connect an upstream DSI host bridge - DSI Panel,
DSI Bridge, and I2C-Configured DSI bridge.

An example of the downstream panel represented as a child node,

 {
   compatible = "samsung,exynos5433-mipi-dsi";

   ports {
port@0 {
 reg = <0>;

 dsi_to_mic: endpoint {
  remote-endpoint = <_to_dsi>;
 };
};
   };

   panel@0 {
reg = <0>;
   };
};

An example of the downstream bridge represented as a port node,

 {
   bridge@2c {
compatible = "ti,sn65dsi84";

ports {
 port@0 {
  reg = <0>;

  bridge_in_dsi: endpoint {
   remote-endpoint = <_out_bridge>;
   data-lanes = <1 2>;
  };
 };

 port@2 {
  reg = <2>;

  bridge_out_panel: endpoint {
   remote-endpoint = <_out_bridge>;
  };
 };
};
   };
};

 {
   compatible = "fsl,imx8mm-mipi-dsim";

   port {
dsi_in_lcdif: endpoint@0 {
 reg = <0>;
 remote-endpoint = <_out_dsi>;
};

dsi_out_bridge: endpoint@1 {
 reg = <1>;
 remote-endpoint = <_in_dsi>;
};
   };
};

An example of the downstream bridge represented as a ports node,

 {
   compatible = "fsl,imx8mm-mipi-dsim";

   ports {
port@0 {
 reg = <0>;

 dsi_in_lcdif: endpoint@0 {
  reg = <0>;
  remote-endpoint = <_out_dsi>;
 };
};

port@1 {
 reg = <1>;

 dsi_out_bridge: endpoint {
  remote-endpoint = <_in_dsi>;
 };
};
};

In, summary it is possible to represent all three downstream slaves
devices using OF-graph port or ports node however only DSI Panel and
DSI Bridge are possible but not possible to represent I2C-Configured
DSI bridge child nodes since I2C-Configure bridges are child of I2C
node, not upstream DSI host bridge and it is must represent them
endpoint port linking.

This indeed means, the OF-graph port or ports representation is
mandatory for I2C-Configured DSI bridges.

This patch tries to add an OF-graph port or ports representation
detection code on top of existing child node detection.

It is possible to replace the entire detection code using existing
drm_of helper drm_of_find_panel_or_bridge but it will break the
Exynos DSI since the pipeline doesn't support OF-graph port or ports
node.

Overall, this patch has a combination of child and OF-graph pipeline
detections in order to support the backward compatibility of Exynos
DSI child node and i.MX8M Mini/Nano/Plus OF-graph port or ports
node pipelines.

This is the first common DSI host bridge driver that needs to support
all possible downstream connection pipeline combinations.

Signed-off-by: Jagan Teki 
---
Changes for v15:
- droped from drm_of
- added in exynos dsi
- updated commit messages
Changes for v13, v12:
- none
Changes for v11:
- drop extra line
Changes for v10:
- new patch

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index df15501b1075..f44a5a702ad5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1470,18 +1470,52 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
struct device *dev = dsi->dev;
struct drm_encoder *encoder = >encoder;
struct drm_device *drm = encoder->dev;
+   struct device_node *np = dev->of_node;
+   struct device_node *remote;
struct drm_panel *panel;
int ret;
 
-   panel = of_drm_find_panel(device->dev.of_node);
+   /**
+* Devices can also be child nodes when we also control that device
+* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).
+*
+* Lookup for a child node of the given parent that isn't either port
+* or ports.
+*/
+   for_each_available_child_of_node(np, remote) {
+   if (of_node_name_eq(remote, "port") ||
+   of_node_name_eq(remote, "ports"))
+   continue;
+
+   goto of_find_panel_or_bridge;
+   }
+
+   /*
+* of_graph_get_remote_node() produces a noisy error message if port
+* node isn't found and the absence of the port is a legit case here,
+* 

[PATCH v15 01/16] drm: exynos: dsi: Drop explicit call to bridge detach

2023-03-03 Thread Jagan Teki
Exynos DSI already converted into a bridge driver, so bridge
detach will suppose happened during bridge chain removal done
by the bridge core.

Drop the explicit call chain to detach the bridge.

Signed-off-by: Jagan Teki 
---
Changes for v15, v13, v12, v11:
- none
Changes for v10:
- new patch

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

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 06d6513ddaae..df15501b1075 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1531,8 +1531,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host 
*host,
struct exynos_dsi *dsi = host_to_dsi(host);
struct drm_device *drm = dsi->encoder.dev;
 
-   if (dsi->out_bridge->funcs->detach)
-   dsi->out_bridge->funcs->detach(dsi->out_bridge);
dsi->out_bridge = NULL;
 
if (drm->mode_config.poll_enabled)
-- 
2.25.1



[PATCH v15 00/16] drm: Add Samsung MIPI DSIM bridge

2023-03-03 Thread Jagan Teki
This series supports common bridge support for Samsung MIPI DSIM
which is used in Exynos and i.MX8MM SoC's.

The final bridge supports both the Exynos and i.MX8M Mini/Nano/Plus.

Inki Dae: please note that this series added on top of exynos-drm-next
since few exynos dsi changes are not been part of drm-misc-next.
Request you to pick these via exynos-drm-next, or let me know if you
have any comments?

Patch 0001 - 0002: find child DSI bridge and panel

Patch 0003 - 0004: optional PHY, PMS_P offset

Patch 0005   : introduce hw_type

Patch 0006   : fixing host init

Patch 0007   : atomic_check

Patch 0008   : input_bus_flags

Patch 0009   : atomic_get_input_bus_fmts

Patch 0010 - 0011: component vs bridge

Patch 0012   : DSIM bridge

Patch 0013 - 0014: i.MX8M Mini/Nano

Patch 0015 - 0016: i.MX8M Plus

Changes for v15:
- drop drm_of helpers
- re-added find DSI bridge/Panel helper in dsim
- collect RB from Marek V
- fixed leading underscore in function names
- commit messages updated
- rebased on exynos-drm-next

Changes for v13:
- remove devm call for DSI panel or bridge finding
- rebased on drm-misc-next

Changes for v12:
- collect RB from Marek V
- add te_irq_handler hook
- fix comments from Marek V
- update atomic_get_input_bus_fmts logic

Changes for v11:
- collect RB from Frieder Schrempf
- collect ACK from Rob
- collect ACK from Robert
- fix BIT macro replacements
- fix checkpatch --strict warnings
- fix unneeded commit text
- drop extra lines

Changes for v10:
- rebase on drm-misc-next
- add drm_of_dsi_find_panel_or_bridge
- add devm_drm_of_dsi_get_bridge
- fix host initialization (Thanks to Marek Szyprowski)
- rearrange the tiny patches for easy to review
- update simple names for enum hw_type
- add is_hw_exynos macro
- rework on commit messages

Changes for v9:
- rebase on drm-misc-next
- drop drm bridge attach fix for Exynos
- added prepare_prev_first flag
- added pre_enable_prev_first flag
- fix bridge chain order for exynos
- added fix for Exynos host init for first DSI transfer
- added MEDIA_BUS_FMT_FIXED
- return MEDIA_BUS_FMT_RGB888_1X24 output_fmt if supported output_fmt
  list is unsupported.
- added MEDIA_BUS_FMT_YUYV10_1X20
- added MEDIA_BUS_FMT_YUYV12_1X24

Changes for v8:
* fixed comment lines
* fixed commit messages
* fixed video mode bits
* collect Marek Ack
* fixed video mode bit names
* update input formats logic
* added imx8mplus support

Changes for v7:
* fix the drm bridge attach chain for exynos drm dsi driver
* fix the hw_type checking logic

Changes for v6:
* handle previous bridge for exynos dsi while attaching bridge 

Changes for v5:
* bridge changes to support multi-arch
* updated and clear commit messages
* add hw_type via plat data
* removed unneeded quirk
* rebased on linux-next

Changes for v4:
* include Inki Dae in MAINTAINERS
* remove dsi_driver probe in exynos_drm_drv to support multi-arch build
* update init handling to ensure host init done on first cmd transfer

Changes for v3:
* fix the mult-arch build
* fix dsi host init
* updated commit messages

Changes for v2:
* fix bridge handling
* fix dsi host init
* correct the commit messages

Tested in Engicam i.Core MX8M Mini SoM.

Repo:
https://github.com/openedev/kernel/tree/imx8mm-dsi-v15

v13:
https://lore.kernel.org/all/20230227113925.875425-1-ja...@amarulasolutions.com/

Any inputs?
Jagan.

Jagan Teki (14):
  drm: exynos: dsi: Drop explicit call to bridge detach
  drm: exynos: dsi: Lookup OF-graph or Child node devices
  drm: exynos: dsi: Mark PHY as optional
  drm: exynos: dsi: Add platform PLL_P (PMS_P) offset
  drm: exynos: dsi: Introduce hw_type platform data
  drm: exynos: dsi: Add atomic check
  drm: exynos: dsi: Add input_bus_flags
  drm: exynos: dsi: Add atomic_get_input_bus_fmts
  drm: exynos: dsi: Consolidate component and bridge
  drm: exynos: dsi: Add host helper for te_irq_handler
  drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge
  dt-bindings: display: exynos: dsim: Add NXP i.MX8M Mini/Nano support
  drm: bridge: samsung-dsim: Add i.MX8M Mini/Nano support
  dt-bindings: display: exynos: dsim: Add NXP i.MX8M Plus support

Marek Szyprowski (1):
  drm: exynos: dsi: Handle proper host initialization

Marek Vasut (1):
  drm: bridge: samsung-dsim: Add i.MX8M Plus support

 .../bindings/display/exynos/exynos_dsim.txt   |2 +
 MAINTAINERS   |9 +
 drivers/gpu/drm/bridge/Kconfig|   12 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/samsung-dsim.c | 1965 +
 drivers/gpu/drm/exynos/Kconfig|1 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c   | 1817 +--
 include/drm/bridge/samsung-dsim.h |  115 +
 8 files changed, 2190 insertions(+), 1732 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/samsung-dsim.c
 create mode 100644 include/drm/bridge/samsung-dsim.h

-- 
2.25.1



Re: [PATCH v9 15/15] drm/i915: Add deadline based boost support

2023-03-03 Thread Rob Clark
On Fri, Mar 3, 2023 at 1:58 AM Tvrtko Ursulin
 wrote:
>
>
> On 03/03/2023 03:21, Rodrigo Vivi wrote:
> > On Thu, Mar 02, 2023 at 03:53:37PM -0800, Rob Clark wrote:
> >> From: Rob Clark 
> >>
> >
> > missing some wording here...
> >
> >> v2: rebase
> >>
> >> Signed-off-by: Rob Clark 
> >> ---
> >>   drivers/gpu/drm/i915/i915_request.c | 20 
> >>   1 file changed, 20 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_request.c 
> >> b/drivers/gpu/drm/i915/i915_request.c
> >> index 7503dcb9043b..44491e7e214c 100644
> >> --- a/drivers/gpu/drm/i915/i915_request.c
> >> +++ b/drivers/gpu/drm/i915/i915_request.c
> >> @@ -97,6 +97,25 @@ static bool i915_fence_enable_signaling(struct 
> >> dma_fence *fence)
> >>  return i915_request_enable_breadcrumb(to_request(fence));
> >>   }
> >>
> >> +static void i915_fence_set_deadline(struct dma_fence *fence, ktime_t 
> >> deadline)
> >> +{
> >> +struct i915_request *rq = to_request(fence);
> >> +
> >> +if (i915_request_completed(rq))
> >> +return;
> >> +
> >> +if (i915_request_started(rq))
> >> +return;
> >
> > why do we skip the boost if already started?
> > don't we want to boost the freq anyway?
>
> I'd wager Rob is just copying the current i915 wait boost logic.

Yup, and probably incorrectly.. Matt reported fewer boosts/sec
compared to your RFC, this could be the bug

> >> +
> >> +/*
> >> + * TODO something more clever for deadlines that are in the
> >> + * future.  I think probably track the nearest deadline in
> >> + * rq->timeline and set timer to trigger boost accordingly?
> >> + */
> >
> > I'm afraid it will be very hard to find some heuristics of what's
> > late enough for the boost no?
> > I mean, how early to boost the freq on an upcoming deadline for the
> > timer?
>
> We can off load this patch from Rob and deal with it separately, or
> after the fact?

That is completely my intention, I expect you to replace my i915 patch ;-)

Rough idea when everyone is happy with the core bits is to setup an
immutable branch without the driver specific patches, which could be
merged into drm-next and $driver-next and then each driver team can
add there own driver patches on top

BR,
-R

> It's a half solution without a smarter scheduler too. Like
> https://lore.kernel.org/all/20210208105236.28498-10-ch...@chris-wilson.co.uk/,
> or if GuC plans to do something like that at any point.
>
> Or bump the priority too if deadline is looming?
>
> IMO it is not very effective to fiddle with the heuristic on an ad-hoc
> basis. For instance I have a new heuristics which improves the
> problematic OpenCL cases for further 5% (relative to the current
> waitboost improvement from adding missing syncobj waitboost). But I
> can't really test properly for regressions over platforms, stacks,
> workloads.. :(
>
> Regards,
>
> Tvrtko
>
> >
> >> +
> >> +intel_rps_boost(rq);
> >> +}
> >> +
> >>   static signed long i915_fence_wait(struct dma_fence *fence,
> >> bool interruptible,
> >> signed long timeout)
> >> @@ -182,6 +201,7 @@ const struct dma_fence_ops i915_fence_ops = {
> >>  .signaled = i915_fence_signaled,
> >>  .wait = i915_fence_wait,
> >>  .release = i915_fence_release,
> >> +.set_deadline = i915_fence_set_deadline,
> >>   };
> >>
> >>   static void irq_execute_cb(struct irq_work *wrk)
> >> --
> >> 2.39.1
> >>


[PATCH v13 10/10] drm/bridge: it6505: Register Type C mode switches

2023-03-03 Thread Pin-yen Lin
Register USB Type-C mode switches when the "mode-switch" property and
relevant port are available in Device Tree. Configure the "lane_swap"
state based on the entered alternate mode for a specific Type-C
connector, which ends up updating the lane swap registers of the it6505
chip.

Signed-off-by: Pin-yen Lin 

---

Changes in v13:
- Fix style issues

Changes in v12:
- Fixes style issues in it6505 driver
- Replaced >client->dev with it6505->dev
- Updated the error logs when parsing data-lanes property

Changes in v11:
- Added back "data-lanes" parsing logics
- Removed Kconfig dependency
- Updated the usage of the private data

Changes in v7:
- Fixed style issues in it6505 driver
- Removed the redundant sleep in it6505 driver
- Removed DT property validation in it6505 driver
- Rebased to drm-misc-next
- Extracted common codes to another commit

Changes in v6:
- Changed it6505_typec_mux_set callback function to accommodate with
  the latest drm-misc patches
- Changed the driver implementation to accommodate with the new binding
- Squashed to a single patch

 drivers/gpu/drm/bridge/ite-it6505.c | 185 +++-
 1 file changed, 181 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index d4bc388b68ac..988fe28619ab 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -17,6 +17,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 #include 
@@ -27,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -401,6 +404,11 @@ struct debugfs_entries {
const struct file_operations *fops;
 };
 
+struct it6505_typec_port_data {
+   bool dp_connected;
+   bool lane_swap;
+};
+
 struct it6505 {
struct drm_dp_aux aux;
struct drm_bridge bridge;
@@ -454,6 +462,9 @@ struct it6505 {
struct delayed_work delayed_audio;
struct it6505_audio_data audio;
struct dentry *debugfs;
+   struct completion mux_register;
+   struct drm_dp_typec_switch_desc switch_desc;
+   struct it6505_typec_port_data *port_data;
 
/* it6505 driver hold option */
bool enable_drv_hold;
@@ -3345,12 +3356,163 @@ static void it6505_shutdown(struct i2c_client *client)
it6505_lane_off(it6505);
 }
 
+static void it6505_typec_ports_update(struct it6505 *it6505)
+{
+   unsigned int i;
+
+   /* Check if both ports available and do nothing to retain the current 
one */
+   if (it6505->port_data[0].dp_connected && 
it6505->port_data[1].dp_connected)
+   return;
+
+   for (i = 0; i < 2; i++) {
+   if (it6505->port_data[i].dp_connected)
+   it6505->lane_swap = it6505->port_data[i].lane_swap;
+   }
+}
+
+static int it6505_typec_mux_set(struct typec_mux_dev *mux,
+   struct typec_mux_state *state)
+{
+   struct drm_dp_typec_port_data *port = typec_mux_get_drvdata(mux);
+   struct it6505 *it6505 = port->data;
+   struct device *dev = it6505->dev;
+   struct drm_dp_typec_switch_desc switch_desc = it6505->switch_desc;
+   bool old_dp_connected, new_dp_connected;
+
+   if (switch_desc.num_typec_switches == 1)
+   return 0;
+
+   mutex_lock(>extcon_lock);
+   wait_for_completion(>mux_register);
+
+   old_dp_connected = it6505->port_data[0].dp_connected ||
+  it6505->port_data[1].dp_connected;
+
+   it6505->port_data[port->port_num].dp_connected =
+   state->alt &&
+   state->alt->svid == USB_TYPEC_DP_SID &&
+   state->alt->mode == USB_TYPEC_DP_MODE;
+
+   dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n",
+   it6505->port_data[0].dp_connected, 
it6505->port_data[1].dp_connected);
+
+   new_dp_connected = it6505->port_data[0].dp_connected ||
+  it6505->port_data[1].dp_connected;
+
+   if (it6505->enable_drv_hold) {
+   dev_dbg(dev, "enable driver hold\n");
+   goto unlock;
+   }
+
+   it6505_typec_ports_update(it6505);
+
+   if (!old_dp_connected && new_dp_connected) {
+   int ret = pm_runtime_get_sync(dev);
+
+   /*
+* pm_runtime_force_suspend() disables runtime PM when the
+* system enters suspend state. But on system resume, mux_set
+* can be triggered before pm_runtime_force_resume() re-enables
+* runtime PM. This makes the bridge stay powered off if the
+* downstream display is connected when the system is suspended.
+* Handling the error here to make sure the bridge is powered
+* on, and leave the PM runtime usage count incremented so
+* the future runtime PM calls is balanced.
+*/
+   if (ret < 0)
+   

[PATCH v13 09/10] drm/bridge: it6505: Fix Kconfig indentation

2023-03-03 Thread Pin-yen Lin
Replace the spaces with tab characters in the Kconfig file.

Signed-off-by: Pin-yen Lin 
Reviewed-by: AngeloGioacchino Del Regno 


---

(no changes since v10)

Changes in v10:
- Collected Reviewed-by tag

Changes in v7:
- New in v7

 drivers/gpu/drm/bridge/Kconfig | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 12e8f30c65f7..28dc7711bf5f 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -74,19 +74,19 @@ config DRM_FSL_LDB
  Support for i.MX8MP DPI-to-LVDS on-SoC encoder.
 
 config DRM_ITE_IT6505
-tristate "ITE IT6505 DisplayPort bridge"
-depends on OF
+   tristate "ITE IT6505 DisplayPort bridge"
+   depends on OF
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
-select DRM_DP_AUX_BUS
-select DRM_KMS_HELPER
-select DRM_DP_HELPER
-select EXTCON
-select CRYPTO
-select CRYPTO_HASH
-help
-  ITE IT6505 DisplayPort bridge chip driver.
+   select DRM_DP_AUX_BUS
+   select DRM_KMS_HELPER
+   select DRM_DP_HELPER
+   select EXTCON
+   select CRYPTO
+   select CRYPTO_HASH
+   help
+ ITE IT6505 DisplayPort bridge chip driver.
 
 config DRM_LONTIUM_LT8912B
tristate "Lontium LT8912B DSI/HDMI bridge"
-- 
2.40.0.rc0.216.gc4246ad0f0-goog



[PATCH v13 08/10] dt-bindings: display: bridge: it6505: Add mode-switch support

2023-03-03 Thread Pin-yen Lin
ITE IT6505 can be used in systems to switch the DP traffic between
two downstreams, which can be USB Type-C DisplayPort alternate mode
lane or regular DisplayPort output ports.

Update the binding to accommodate this usage by introducing a
data-lanes and a mode-switch property on endpoints.

Signed-off-by: Pin-yen Lin 

---

(no changes since v12)

Changes in v12:
- Fixed the schema of "data-lanes" property for it6505
- Reworded the description of the mode-switch property

Changes in v11:
- Updated the description of the endpoints in the bindings
- Referenced video-interfaces.yaml instead for the endpoints binding
- Removed duplicated definitions from inherited schema

Changes in v9:
- Fixed subject prefix again
- Changed the naming of the example node for it6505

Changes in v8:
- Updated bindings for data-lanes property
- Fixed subject prefix

Changes in v7:
- Fixed issues reported by dt_binding_check.
- Updated the schema and the example dts for data-lanes.
- Changed to generic naming for the example dts node.

Changes in v6:
- Remove switches node and use endpoints and data-lanes property to
  describe the connections.

 .../bindings/display/bridge/ite,it6505.yaml   | 101 +++---
 1 file changed, 88 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml 
b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml
index c9a882ee6d98..348b02f26041 100644
--- a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml
@@ -75,22 +75,49 @@ properties:
   port@1:
 $ref: /schemas/graph.yaml#/$defs/port-base
 unevaluatedProperties: false
-description: Video port for DP output
+description:
+  Video port for DP output. Each endpoint connects to a video output
+  downstream, and the "data-lanes" property is used to describe the pin
+  connections. 0, 1, 2, 3 in "data-lanes" maps to TX0, TX1, TX2, TX3,
+  respectively.
 
-properties:
-  endpoint:
-$ref: /schemas/graph.yaml#/$defs/endpoint-base
+
+patternProperties:
+  "^endpoint@[01]$":
+$ref: /schemas/media/video-interfaces.yaml#
 unevaluatedProperties: false
 
 properties:
+  reg: true
+
+  remote-endpoint: true
+
   data-lanes:
-minItems: 1
-uniqueItems: true
-items:
-  - enum: [ 0, 1 ]
-  - const: 1
-  - const: 2
-  - const: 3
+oneOf:
+  - items:
+  - enum: [0, 3]
+
+  - items:
+  - const: 0
+  - const: 1
+
+  - items:
+  - const: 3
+  - const: 2
+
+  - items:
+  - const: 0
+  - const: 1
+  - const: 2
+  - const: 3
+
+  mode-switch:
+type: boolean
+description: Serves as Type-C mode switch if present.
+
+required:
+  - reg
+  - remote-endpoint
 
 required:
   - port@0
@@ -102,7 +129,6 @@ required:
   - pwr18-supply
   - interrupts
   - reset-gpios
-  - extcon
   - ports
 
 additionalProperties: false
@@ -139,8 +165,11 @@ examples:
 };
 
 port@1 {
+#address-cells = <1>;
+#size-cells = <0>;
 reg = <1>;
-it6505_out: endpoint {
+it6505_out: endpoint@0 {
+reg = <0>;
 remote-endpoint = <_in>;
 data-lanes = <0 1>;
 };
@@ -148,3 +177,49 @@ examples:
 };
 };
 };
+  - |
+#include 
+
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+dp-bridge@5c {
+compatible = "ite,it6505";
+interrupts = <8 IRQ_TYPE_LEVEL_LOW 8 0>;
+reg = <0x5c>;
+pinctrl-names = "default";
+pinctrl-0 = <_pins>;
+ovdd-supply = <_vsim2_reg>;
+pwr18-supply = <_dpbrdg_dx>;
+reset-gpios = < 177 0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+port@0 {
+reg = <0>;
+it6505_dpi_in: endpoint {
+remote-endpoint = <_out>;
+};
+};
+port@1 {
+#address-cells = <1>;
+#size-cells = <0>;
+reg = <1>;
+ite_typec0: endpoint@0 {
+reg = <0>;
+mode-switch;
+

[PATCH v13 07/10] drm/bridge: anx7625: Register Type C mode switches

2023-03-03 Thread Pin-yen Lin
Register USB Type-C mode switches when the "mode-switch" property and
relevant ports are available in Device Tree. Configure the crosspoint
switch based on the entered alternate mode for a specific Type-C
connector.

Crosspoint switch can also be used for switching the output signal for
different orientations of a single USB Type-C connector, but the
orientation switch is not implemented yet. A TODO is added for this.

Signed-off-by: Pin-yen Lin 

---

(no changes since v12)

Changes in v12:
- Fixed style issues in anx7625 driver
- Fixed the inverted orientation setting in anx7625 driver
- Changed ">client->dev" to "ctx->dev"
- Fix style issues
- Updated the error logs when parsing data-lanes property

Changes in v11:
- Added back "data-lanes" parsing logics
- Removed Kconfig dependency
- Updated the usage of the private data
- Dropped Tested-by tag because of the new changes

Changes in v10:
- Added a TODO for implementing orientation switch for anx7625
- Updated the commit message for the absence of orientation switch
- Fixed typo in the commit message
- Collected Tested-by tag

Changes in v7:
- Fixed style issues in anx7625 driver
- Removed DT property validation in anx7625 driver.
- Extracted common codes to another commit.

Changes in v6:
- Squashed to a single patch

 drivers/gpu/drm/bridge/analogix/anx7625.c | 149 ++
 drivers/gpu/drm/bridge/analogix/anx7625.h |  20 +++
 2 files changed, 169 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 76d46db3f8dc..4361a1b52a67 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -15,6 +15,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 #include 
@@ -2570,6 +2572,146 @@ static void anx7625_runtime_disable(void *data)
pm_runtime_disable(data);
 }
 
+static void anx7625_set_crosspoint_switch(struct anx7625_data *ctx,
+ enum typec_orientation orientation)
+{
+   if (orientation == TYPEC_ORIENTATION_NORMAL) {
+   anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0,
+ SW_SEL1_SSRX_RX1 | SW_SEL1_DPTX0_RX2);
+   anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1,
+ SW_SEL2_SSTX_TX1 | SW_SEL2_DPTX1_TX2);
+   } else if (orientation == TYPEC_ORIENTATION_REVERSE) {
+   anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0,
+ SW_SEL1_SSRX_RX2 | SW_SEL1_DPTX0_RX1);
+   anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1,
+ SW_SEL2_SSTX_TX2 | SW_SEL2_DPTX1_TX1);
+   }
+}
+
+static void anx7625_typec_two_ports_update(struct anx7625_data *ctx)
+{
+   unsigned int i;
+
+   /* Check if both ports available and do nothing to retain the current 
one */
+   if (ctx->port_data[0].dp_connected && ctx->port_data[1].dp_connected)
+   return;
+
+   for (i = 0; i < 2; i++) {
+   if (ctx->port_data[i].dp_connected)
+   anx7625_set_crosspoint_switch(ctx,
+ 
ctx->port_data[i].orientation);
+   }
+}
+
+static int anx7625_typec_mux_set(struct typec_mux_dev *mux,
+struct typec_mux_state *state)
+{
+   struct drm_dp_typec_port_data *port = typec_mux_get_drvdata(mux);
+   struct anx7625_data *ctx = port->data;
+   struct device *dev = ctx->dev;
+   struct drm_dp_typec_switch_desc switch_desc = ctx->switch_desc;
+   bool new_dp_connected, old_dp_connected;
+
+   if (switch_desc.num_typec_switches == 1)
+   return 0;
+
+   wait_for_completion(>mux_register);
+
+   old_dp_connected = ctx->port_data[0].dp_connected ||
+  ctx->port_data[1].dp_connected;
+
+   ctx->port_data[port->port_num].dp_connected =
+   state->alt &&
+   state->alt->svid == USB_TYPEC_DP_SID &&
+   state->alt->mode == USB_TYPEC_DP_MODE;
+
+   dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n",
+   ctx->port_data[0].dp_connected, ctx->port_data[1].dp_connected);
+
+   new_dp_connected = ctx->port_data[0].dp_connected ||
+  ctx->port_data[1].dp_connected;
+
+   /* DP on, power on first */
+   if (!old_dp_connected && new_dp_connected)
+   pm_runtime_get_sync(dev);
+
+   anx7625_typec_two_ports_update(ctx);
+
+   /* DP off, power off last */
+   if (old_dp_connected && !new_dp_connected)
+   pm_runtime_put_sync(dev);
+
+   return 0;
+}
+
+static void anx7625_unregister_typec_switches(struct anx7625_data *ctx)
+{
+   drm_dp_unregister_typec_switches(>switch_desc);
+}
+
+static int anx7625_register_typec_switches(struct device *dev, struct 
anx7625_data *ctx)
+{

[PATCH v13 06/10] drm/bridge: Remove redundant i2c_client in anx7625/it6505

2023-03-03 Thread Pin-yen Lin
These two drivers embed a i2c_client in their private driver data, but
only strict device is actually needed. Replace the i2c_client reference
with a struct device one.

Signed-off-by: Pin-yen Lin 
Reviewed-by: Andy Shevchenko 
---

Changes in v13:
- Update a typo in the commit message
- Collect Reviewed-by tag

Changes in v12:
- New in v12

 drivers/gpu/drm/bridge/analogix/anx7625.c |  96 
 drivers/gpu/drm/bridge/analogix/anx7625.h |   2 +-
 drivers/gpu/drm/bridge/ite-it6505.c   | 128 +++---
 3 files changed, 113 insertions(+), 113 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 3f6bf7674d32..76d46db3f8dc 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -207,7 +207,7 @@ static int anx7625_read_ctrl_status_p0(struct anx7625_data 
*ctx)
 
 static int wait_aux_op_finish(struct anx7625_data *ctx)
 {
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
int val;
int ret;
 
@@ -234,7 +234,7 @@ static int wait_aux_op_finish(struct anx7625_data *ctx)
 static int anx7625_aux_trans(struct anx7625_data *ctx, u8 op, u32 address,
 u8 len, u8 *buf)
 {
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
int ret;
u8 addrh, addrm, addrl;
u8 cmd;
@@ -427,7 +427,7 @@ static int anx7625_odfc_config(struct anx7625_data *ctx,
   u8 post_divider)
 {
int ret;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
 
/* Config input reference clock frequency 27MHz/19.2MHz */
ret = anx7625_write_and(ctx, ctx->i2c.rx_p1_client, MIPI_DIGITAL_PLL_16,
@@ -477,7 +477,7 @@ static int anx7625_set_k_value(struct anx7625_data *ctx)
 
 static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx)
 {
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
unsigned long m, n;
u16 htotal;
int ret;
@@ -575,7 +575,7 @@ static int anx7625_dsi_video_timing_config(struct 
anx7625_data *ctx)
 static int anx7625_swap_dsi_lane3(struct anx7625_data *ctx)
 {
int val;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
 
/* Swap MIPI-DSI data lane 3 P and N */
val = anx7625_reg_read(ctx, ctx->i2c.rx_p1_client, MIPI_SWAP);
@@ -592,7 +592,7 @@ static int anx7625_api_dsi_config(struct anx7625_data *ctx)
 
 {
int val, ret;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
 
/* Swap MIPI-DSI data lane 3 P and N */
ret = anx7625_swap_dsi_lane3(ctx);
@@ -657,7 +657,7 @@ static int anx7625_api_dsi_config(struct anx7625_data *ctx)
 
 static int anx7625_dsi_config(struct anx7625_data *ctx)
 {
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
int ret;
 
DRM_DEV_DEBUG_DRIVER(dev, "config dsi.\n");
@@ -689,7 +689,7 @@ static int anx7625_dsi_config(struct anx7625_data *ctx)
 
 static int anx7625_api_dpi_config(struct anx7625_data *ctx)
 {
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
u16 freq = ctx->dt.pixelclock.min / 1000;
int ret;
 
@@ -720,7 +720,7 @@ static int anx7625_api_dpi_config(struct anx7625_data *ctx)
 
 static int anx7625_dpi_config(struct anx7625_data *ctx)
 {
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
int ret;
 
DRM_DEV_DEBUG_DRIVER(dev, "config dpi\n");
@@ -765,7 +765,7 @@ static int anx7625_read_flash_status(struct anx7625_data 
*ctx)
 static int anx7625_hdcp_key_probe(struct anx7625_data *ctx)
 {
int ret, val;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
u8 ident[FLASH_BUF_LEN];
 
ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
@@ -815,7 +815,7 @@ static int anx7625_hdcp_key_probe(struct anx7625_data *ctx)
 static int anx7625_hdcp_key_load(struct anx7625_data *ctx)
 {
int ret;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
 
/* Select HDCP 1.4 KEY */
ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
@@ -843,7 +843,7 @@ static int anx7625_hdcp_key_load(struct anx7625_data *ctx)
 static int anx7625_hdcp_disable(struct anx7625_data *ctx)
 {
int ret;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
 
dev_dbg(dev, "disable HDCP 1.4\n");
 
@@ -864,7 +864,7 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx)
 {
u8 bcap;
int ret;
-   struct device *dev = >client->dev;
+   struct device *dev = ctx->dev;
 
ret = anx7625_hdcp_key_probe(ctx);
if (ret) {
@@ -922,7 +922,7 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx)
 static void 

[PATCH v13 05/10] drm/bridge: anx7625: Check for Type-C during panel registration

2023-03-03 Thread Pin-yen Lin
The output port endpoints can be connected to USB-C connectors.
Running drm_of_find_panel_or_bridge() with such endpoints leads to
a continuous return value of -EPROBE_DEFER, even though there is
no panel present.

To avoid this, check for the existence of a "mode-switch" property in
the port endpoint, and skip panel registration completely if so.

Signed-off-by: Pin-yen Lin 

---

Changes in v13:
- Use the new typec_mode_switch_node_count helper

Changes in v12:
- Updated to use fwnode_for_each_typec_mode_switch macro
- Dropped collected tags

Changes in v10:
- Collected Reviewed-by and Tested-by tags

Changes in v6:
- New in v6

 drivers/gpu/drm/bridge/analogix/anx7625.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6846199a2ee1..3f6bf7674d32 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1648,7 +1648,8 @@ static int anx7625_get_swing_setting(struct device *dev,
 static int anx7625_parse_dt(struct device *dev,
struct anx7625_platform_data *pdata)
 {
-   struct device_node *np = dev->of_node, *ep0;
+   struct device_node *np = dev->of_node, *ep0, *port_node;
+   unsigned int count;
int bus_type, mipi_lanes;
 
anx7625_get_swing_setting(dev, pdata);
@@ -1687,6 +1688,15 @@ static int anx7625_parse_dt(struct device *dev,
if (of_property_read_bool(np, "analogix,audio-enable"))
pdata->audio_en = 1;
 
+   /*
+* Don't bother finding a panel if a Type-C `mode-switch` property is
+* present in one of the endpoints in the output port.
+*/
+   port_node = of_graph_get_port_by_id(np, 1);
+   count = typec_mode_switch_node_count(_node->fwnode);
+   if (count)
+   return 0;
+
pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0);
if (IS_ERR(pdata->panel_bridge)) {
if (PTR_ERR(pdata->panel_bridge) == -ENODEV) {
-- 
2.40.0.rc0.216.gc4246ad0f0-goog



[PATCH v13 04/10] dt-bindings: display: bridge: anx7625: Add mode-switch support

2023-03-03 Thread Pin-yen Lin
Analogix 7625 can be used in systems to switch the DP traffic between
two downstreams, which can be USB Type-C DisplayPort alternate mode
lane or regular DisplayPort output ports.

Update the binding to accommodate this usage by introducing a
data-lanes and a mode-switch property on endpoints.

Also include the link to the product brief in the bindings.

Signed-off-by: Pin-yen Lin 
Reviewed-by: Krzysztof Kozlowski 
Reviewed-by: Chen-Yu Tsai 
Tested-by: Chen-Yu Tsai 
Reviewed-by: AngeloGioacchino Del Regno 


---

(no changes since v12)

Changes in v12:
- Removed the 4-lane binding in analogix,anx7625.yaml
- Reworded the description for the mode-switch property

Changes in v11:
- Updated the description of the endpoints
- Referenced video-interfaces.yaml instead for the endpoints

Changes in v10:
- Collected Reviewed-by and Tested-by tags

Changes in v9:
- Collected Reviewed-by tag

Changes in v8:
- Updated anx7625 bindings for data-lane property
- Fixed the subject prefix

Changes in v7:
- Fixed issues reported by dt_binding_check
- Updated the schema and the example dts for data-lanes.
- Changed to generic naming for the example dts node.

Changes in v6:
- Remove switches node and use endpoints and data-lanes property to
  describe the connections.

 .../display/bridge/analogix,anx7625.yaml  | 88 ++-
 1 file changed, 85 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml 
b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
index 4590186c4a0b..a50de536cffd 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
@@ -12,7 +12,8 @@ maintainers:
 
 description: |
   The ANX7625 is an ultra-low power 4K Mobile HD Transmitter
-  designed for portable devices.
+  designed for portable devices. Product brief is available at
+  
https://www.analogix.com/en/system/files/AA-002291-PB-6-ANX7625_ProductBrief.pdf
 
 properties:
   compatible:
@@ -112,9 +113,40 @@ properties:
   data-lanes: true
 
   port@1:
-$ref: /schemas/graph.yaml#/properties/port
+$ref: /schemas/graph.yaml#/$defs/port-base
 description:
-  Video port for panel or connector.
+  Video port for panel or connector. Each endpoint connects to a video
+  output downstream, and the "data-lanes" property is used to describe
+  the pin connections. 0, 1, 2, 3 in "data-lanes" maps to SSRX1, SSTX1,
+  SSRX2, SSTX2, respectively.
+
+patternProperties:
+  "^endpoint@[01]$":
+$ref: /schemas/media/video-interfaces.yaml#
+properties:
+  reg: true
+
+  remote-endpoint: true
+
+  data-lanes:
+oneOf:
+  - items:
+  - enum: [0, 1, 2, 3]
+
+  - items:
+  - const: 0
+  - const: 1
+
+  - items:
+  - const: 2
+  - const: 3
+
+  mode-switch:
+type: boolean
+description: Serves as Type-C mode switch if present.
+
+required:
+  - remote-endpoint
 
 required:
   - port@0
@@ -186,3 +218,53 @@ examples:
 };
 };
 };
+  - |
+i2c3 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+encoder@58 {
+compatible = "analogix,anx7625";
+reg = <0x58>;
+pinctrl-names = "default";
+pinctrl-0 = <_dp_pins>;
+enable-gpios = < 176 GPIO_ACTIVE_HIGH>;
+reset-gpios = < 177 GPIO_ACTIVE_HIGH>;
+vdd10-supply = <_dpbrdg>;
+vdd18-supply = <_dpbrdg_dx>;
+vdd33-supply = <_dpbrdg_dx>;
+analogix,audio-enable;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+anx7625_dp_in: endpoint {
+bus-type = <7>;
+remote-endpoint = <_out>;
+};
+};
+
+port@1 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+reg = <1>;
+anx_typec0: endpoint@0 {
+reg = <0>;
+mode-switch;
+data-lanes = <0 1>;
+remote-endpoint = <_port0>;
+};
+anx_typec1: endpoint@1 {
+reg = <1>;
+mode-switch;
+data-lanes = <2 3>;
+remote-endpoint = <_port1>;
+};
+};
+};
+};
+};
-- 

[PATCH v13 03/10] drm/display: Add Type-C switch helpers

2023-03-03 Thread Pin-yen Lin
Add helpers to register and unregister Type-C "switches" for bridges
capable of switching their output between two downstream devices.

The helper registers USB Type-C mode switches when the "mode-switch"
and the "reg" properties are available in Device Tree.

Signed-off-by: Pin-yen Lin 

---

Changes in v13:
- Add typec_mode_switch_node_count helper
- Fix style issues

Changes in v12:
- Add fwnode_for_each_typec_mode_switch macro
- Remove a duplicated dmesg in the helper
- Used IS_REACHABLE instead to guard the function signatures

Changes in v11:
- Use fwnode helpers instead of DT
- Moved the helpers to a new file
- Use "reg" instead of "data-lanes" to determine the port number
- Dropped collected tags due to new changes

Changes in v10:
- Collected Reviewed-by and Tested-by tags
- Replaced "void *" with "typec_mux_set_fn_t" for mux_set callbacks
- Print out the node name when errors on parsing DT
- Use dev_dbg instead of dev_warn when no Type-C switch nodes available
- Made the return path of drm_dp_register_mode_switch clearer

Changes in v8:
- Fixed the build issue when CONFIG_TYPEC=m
- Fixed some style issues

Changes in v7:
- Extracted the common codes to a helper function
- New in v7

 drivers/gpu/drm/display/Makefile  |   1 +
 drivers/gpu/drm/display/drm_dp_typec_helper.c | 105 ++
 include/drm/display/drm_dp_helper.h   |  46 
 3 files changed, 152 insertions(+)
 create mode 100644 drivers/gpu/drm/display/drm_dp_typec_helper.c

diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 17ac4a1006a8..ef80b9fde615 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -14,5 +14,6 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
drm_scdc_helper.o
 drm_display_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
 drm_display_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
+drm_display_helper-$(CONFIG_TYPEC) += drm_dp_typec_helper.o
 
 obj-$(CONFIG_DRM_DISPLAY_HELPER) += drm_display_helper.o
diff --git a/drivers/gpu/drm/display/drm_dp_typec_helper.c 
b/drivers/gpu/drm/display/drm_dp_typec_helper.c
new file mode 100644
index ..0c705a4bca24
--- /dev/null
+++ b/drivers/gpu/drm/display/drm_dp_typec_helper.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+
+static int drm_dp_register_mode_switch(struct device *dev,
+  struct fwnode_handle *fwnode,
+  struct drm_dp_typec_switch_desc 
*switch_desc,
+  void *data, typec_mux_set_fn_t mux_set)
+{
+   struct drm_dp_typec_port_data *port_data;
+   struct typec_mux_desc mux_desc = {};
+   char name[32];
+   u32 port_num;
+   int ret;
+
+   ret = fwnode_property_read_u32(fwnode, "reg", _num);
+   if (ret) {
+   dev_err(dev, "Failed to read reg property: %d\n", ret);
+   return ret;
+   }
+
+   port_data = _desc->typec_ports[port_num];
+   port_data->data = data;
+   port_data->port_num = port_num;
+   port_data->fwnode = fwnode;
+   mux_desc.fwnode = fwnode;
+   mux_desc.drvdata = port_data;
+   snprintf(name, sizeof(name), "%pfwP-%u", fwnode, port_num);
+   mux_desc.name = name;
+   mux_desc.set = mux_set;
+
+   port_data->typec_mux = typec_mux_register(dev, _desc);
+   if (IS_ERR(port_data->typec_mux)) {
+   ret = PTR_ERR(port_data->typec_mux);
+   dev_err(dev, "Mode switch register for port %d failed: %d\n",
+   port_num, ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+/**
+ * drm_dp_register_typec_switches() - register Type-C switches
+ * @dev: Device that registers Type-C switches
+ * @port: Device node for the switch
+ * @switch_desc: A Type-C switch descriptor
+ * @data: Private data for the switches
+ * @mux_set: Callback function for typec_mux_set
+ *
+ * This function registers USB Type-C switches for DP bridges that can switch
+ * the output signal between their output pins.
+ *
+ * Currently only mode switches are implemented, and the function assumes the
+ * given @port device node has endpoints with "mode-switch" property.
+ * The port number is determined by the "reg" property of the endpoint.
+ */
+int drm_dp_register_typec_switches(struct device *dev, struct fwnode_handle 
*port,
+  struct drm_dp_typec_switch_desc *switch_desc,
+  void *data, typec_mux_set_fn_t mux_set)
+{
+   struct fwnode_handle *sw;
+   int ret;
+
+   switch_desc->num_typec_switches = typec_mode_switch_node_count(port);
+   if (!switch_desc->num_typec_switches) {
+   dev_dbg(dev, "No Type-C switches node found\n");
+   return 0;
+   }
+
+   switch_desc->typec_ports = devm_kcalloc(dev, 
switch_desc->num_typec_switches,
+  

[PATCH v13 02/10] platform/chrome: cros_ec_typec: Purge blocking switch devlinks

2023-03-03 Thread Pin-yen Lin
From: Prashant Malani 

When using OF graph, the fw_devlink code will create links between the
individual port driver (cros-ec-typec here) and the parent device for
a Type-C switch (like mode-switch). Since the mode-switch will in turn
have the usb-c-connector (i.e the child of the port driver) as a
supplier, fw_devlink will not be able to resolve the cyclic dependency
correctly.

As a result, the mode-switch driver probe() never runs, so mode-switches
are never registered. Because of that, the port driver probe constantly
fails with -EPROBE_DEFER, because the Type-C connector class requires all
switch devices to be registered prior to port registration.

To break this deadlock and allow the mode-switch registration to occur,
purge all the usb-c-connector nodes' absent suppliers. This eliminates
the connector as a supplier for a switch and allows it to be probed.

Signed-off-by: Prashant Malani 
Signed-off-by: Pin-yen Lin 
Reviewed-by: Chen-Yu Tsai 
Tested-by: Chen-Yu Tsai 
Acked-by: Heikki Krogerus 

---

(no changes since v11)

Changes in v11:
- Collected Acked-by tag

Changes in v10:
- Collected Reviewed-by and Tested-by tags

Changes in v7:
- Fix the long comment lines

Changes in v6:
- New in v6

 drivers/platform/chrome/cros_ec_typec.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/platform/chrome/cros_ec_typec.c 
b/drivers/platform/chrome/cros_ec_typec.c
index 001b0de95a46..bbc95a3ba5a7 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -385,6 +385,16 @@ static int cros_typec_init_ports(struct cros_typec_data 
*typec)
return -EINVAL;
}
 
+   /*
+* OF graph may have set up some device links with switches,
+* since connectors have their own compatible. Purge these
+* to avoid a deadlock in switch probe (the switch mistakenly
+* assumes the connector is a supplier).
+*/
+   if (dev_of_node(dev))
+   device_for_each_child_node(dev, fwnode)
+   fw_devlink_purge_absent_suppliers(fwnode);
+
/* DT uses "reg" to specify port number. */
port_prop = dev->of_node ? "reg" : "port-number";
device_for_each_child_node(dev, fwnode) {
-- 
2.40.0.rc0.216.gc4246ad0f0-goog



[PATCH v13 01/10] device property: Add remote endpoint to devcon matcher

2023-03-03 Thread Pin-yen Lin
From: Prashant Malani 

When searching the device graph for device matches, check the
remote-endpoint itself for a match.

Some drivers register devices for individual endpoints. This allows
the matcher code to evaluate those for a match too, instead
of only looking at the remote parent devices. This is required when a
device supports two mode switches in its endpoints, so we can't simply
register the mode switch with the parent node.

Signed-off-by: Prashant Malani 
Signed-off-by: Pin-yen Lin 

---

Changes in v13:
- Update the kernel doc of fwnode_connection_find_match

Changes in v12:
- Check the availability of the device node in fwnode_graph_devcon_matches
- Ensured valid access to "matches" in fwnode_graph_devcon_matches
- Updated the documentation in fwnode_connection_find_match(es)
- Dropped collected tags due to the new changes

Changes in v11:
- Added missing fwnode_handle_put in drivers/base/property.c

Changes in v10:
- Collected Reviewed-by and Tested-by tags

Changes in v6:
- New in v6

 drivers/base/property.c | 31 ++-
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 083a95791d3b..4426ac2b16ca 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1243,6 +1243,23 @@ static unsigned int fwnode_graph_devcon_matches(const 
struct fwnode_handle *fwno
continue;
}
 
+   ret = match(node, con_id, data);
+   fwnode_handle_put(node);
+   if (ret) {
+   if (matches)
+   matches[count] = ret;
+   count++;
+
+   if (matches && count >= matches_len)
+   break;
+   }
+
+   /*
+* Some drivers may register devices for endpoints. Check
+* the remote-endpoints for matches in addition to the remote
+* port parent.
+*/
+   node = fwnode_graph_get_remote_endpoint(ep);
ret = match(node, con_id, data);
fwnode_handle_put(node);
if (ret) {
@@ -1293,8 +1310,11 @@ static unsigned int fwnode_devcon_matches(const struct 
fwnode_handle *fwnode,
  * @match: Function to check and convert the connection description
  *
  * Find a connection with unique identifier @con_id between @fwnode and another
- * device node. @match will be used to convert the connection description to
- * data the caller is expecting to be returned.
+ * device node. For fwnode graph connections, the graph endpoints are also
+ * checked. @match will be used to convert the connection description to data
+ * the caller is expecting to be returned.
+ *
+ * Return: The pointer to the matched node, or NULL on error.
  */
 void *fwnode_connection_find_match(const struct fwnode_handle *fwnode,
   const char *con_id, void *data,
@@ -1325,9 +1345,10 @@ EXPORT_SYMBOL_GPL(fwnode_connection_find_match);
  * @matches_len: Length of @matches
  *
  * Find up to @matches_len connections with unique identifier @con_id between
- * @fwnode and other device nodes. @match will be used to convert the
- * connection description to data the caller is expecting to be returned
- * through the @matches array.
+ * @fwnode and other device nodes. For fwnode graph connections, the graph
+ * endpoints are also checked. @match will be used to convert the connection
+ * description to data the caller is expecting to be returned through the
+ * @matches array.
  * If @matches is NULL @matches_len is ignored and the total number of resolved
  * matches is returned.
  *
-- 
2.40.0.rc0.216.gc4246ad0f0-goog



[PATCH v13 00/10] Register Type-C mode-switch in DP bridge endpoints

2023-03-03 Thread Pin-yen Lin


This series introduces bindings for anx7625/it6505 to register Type-C
mode-switch in their output endpoints, and use data-lanes property to
describe the pin connections.

This series is not directly related to the built-in mux in anx7625,
which automatically switches between the two orientations of a single
Type-C connector. This series adds support of registering mode switches
for two downstream devices, while we use orientation switches for two
orientations of the Type-C connector.

The first two patch modifies fwnode_graph_devcon_matches and
cros_typec_init_ports to enable the registration of the switches.

Patch 4~6 introduce the bindings for anx7625 and the corresponding driver
modifications.

Patch 7~9 add similar bindings and driver changes for it6505.

v12: 
https://lore.kernel.org/all/20230221095054.1868277-1-treapk...@chromium.org/
v11: 
https://lore.kernel.org/all/20230204133040.1236799-1-treapk...@chromium.org/
v10: 
https://lore.kernel.org/all/20230112042104.4107253-1-treapk...@chromium.org/
v9: https://lore.kernel.org/all/20230109084101.265664-1-treapk...@chromium.org/
v8: https://lore.kernel.org/all/20230107102231.23682-1-treapk...@chromium.org/
v7: https://lore.kernel.org/all/20230105132457.4125372-1-treapk...@chromium.org/
v6: https://lore.kernel.org/all/20221124102056.393220-1-treapk...@chromium.org/
v5: 
https://lore.kernel.org/linux-usb/20220622173605.1168416-1-pmal...@chromium.org/

Changes in v13:
- Update the kernel doc of fwnode_connection_find_match
- Add typec_mode_switch_node_count helper
- Fix style issues
- Update a typo in the commit message
- Collect Reviewed-by tag

Changes in v12:
- Check the availability of the device node in fwnode_graph_devcon_matches
- Ensured valid access to "matches" in fwnode_graph_devcon_matches
- Updated the documentation in fwnode_connection_find_match(es)
- Add fwnode_for_each_typec_mode_switch macro
- Remove a duplicated dmesg in the helper
- Used IS_REACHABLE instead to guard the function signatures
- Removed the 4-lane binding in analogix,anx7625.yaml
- Reworded the description for the mode-switch property
- Fixed style issues in anx7625 driver
- Fixed the inverted orientation setting in anx7625 driver
- Changed ">client->dev" to "ctx->dev"
- Fixed the schema of "data-lanes" property for it6505
- Fixes style issues in it6505 driver
- Replaced >client->dev with it6505->dev
- Updated the error logs when parsing data-lanes property

Changes in v11:
- Added missing fwnode_handle_put in drivers/base/property.c
- Collected Acked-by tag
- Use fwnode helpers instead of DT
- Moved the helpers to a new file
- Use "reg" instead of "data-lanes" to determine the port number
- Updated the description of the endpoints in the bindings
- Referenced video-interfaces.yaml instead for the endpoints binding
- Removed duplicated definitions from inherited schema
- Moved the "data-lanes" parsing logics to bridge drivers
- Removed Kconfig dependencies for the bridge drivers
- Updated the usage of the private bridge driver data
- Added a clarification on the anx7625 built-in mux in the cover letter

Changes in v10:
- Collected Reviewed-by and Tested-by tags
- Replaced "void *" with "typec_mux_set_fn_t" for mux_set callbacks
- Print out the node name when errors on parsing DT
- Use dev_dbg instead of dev_warn when no Type-C switch nodes available
- Made the return path of drm_dp_register_mode_switch clearer
- Added a TODO for implementing orientation switch for anx7625
- Updated the commit message for the absence of orientation switch
- Fixed typo in the commit message

Changes in v9:
- Collected Reviewed-by tag
- Fixed subject prefix again
- Changed the naming of the example node for it6505

Changes in v8:
- Fixed the build issue when CONFIG_TYPEC=m
- Fixed some style issues
- Fixed the subject prefixes for the bindings patch
- Fixed the bindings for data-lanes properties

Changes in v7:
- Fix the long comment lines
- Extracted the common codes to a helper function
- Fixed style issues in anx7625 driver
- Removed DT property validation in anx7625 driver.
- Fixed style issues in it6505 driver
- Removed the redundant sleep in it6505 driver
- Removed DT property validation in it6505 driver
- Rebased to drm-misc-next
- Fixed indentations in bindings patches
- Added a new patch to fix indentations in Kconfig

Changes in v6:
- Changed it6505_typec_mux_set callback function to accommodate with
  the latest drm-misc patches
- Changed the driver implementation to accommodate with the new binding
- Dropped typec-switch binding and use endpoints and data-lanes properties
  to describe the pin connections
- Added new patches (patch 1,2,4) to fix probing issues
- Changed the bindings of it6505/anx7625 and modified the drivers
  accordingly
- Merged it6505/anx7625 driver changes into a single patch

Pin-yen Lin (8):
  drm/display: Add Type-C switch helpers
  dt-bindings: display: bridge: anx7625: Add mode-switch support
  drm/bridge: anx7625: Check for Type-C during panel 

Re: [PATCH] drm/nouveau/fifo: set nvkm_engn_cgrp_get storage-class-specifier to static

2023-03-03 Thread Karol Herbst
Reviewed-by: Karol Herbst 

will push in a moment

On Tue, Feb 28, 2023 at 11:15 PM Tom Rix  wrote:
>
> smatch reports
> drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c:33:18:
>   warning: symbol 'nvkm_engn_cgrp_get' was not declared. Should it be static?
>
> nvkm_engn_cgrp_get is only used in runl.c, so it should be static
>
> Signed-off-by: Tom Rix 
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c 
> b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c
> index b5836cbc29aa..93d628d7d508 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c
> @@ -30,7 +30,7 @@
>  #include 
>  #include 
>
> -struct nvkm_cgrp *
> +static struct nvkm_cgrp *
>  nvkm_engn_cgrp_get(struct nvkm_engn *engn, unsigned long *pirqflags)
>  {
> struct nvkm_cgrp *cgrp = NULL;
> --
> 2.27.0
>



Re: [PATCH] drm/nouveau/nvfw/acr: set wpr_generic_header_dump storage-class-specifier to static

2023-03-03 Thread Karol Herbst
Reviewed-by: Karol Herbst 

will push in a moment

On Thu, Mar 2, 2023 at 1:48 PM Tom Rix  wrote:
>
> gcc with W=1 reports
> drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: error: no previous
>   prototype for ‘wpr_generic_header_dump’ [-Werror=missing-prototypes]
>49 | wpr_generic_header_dump(struct nvkm_subdev *subdev,
>   | ^~~
>
> wpr_generic_header_dump is only used in acr.c, so it should be static
>
> Signed-off-by: Tom Rix 
> ---
>  drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c 
> b/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> index 83a9c48bc58c..7ac90c495737 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
> @@ -45,7 +45,7 @@ wpr_header_v1_dump(struct nvkm_subdev *subdev, const struct 
> wpr_header_v1 *hdr)
> nvkm_debug(subdev, "\tstatus: %d\n", hdr->status);
>  }
>
> -void
> +static void
>  wpr_generic_header_dump(struct nvkm_subdev *subdev, const struct 
> wpr_generic_header *hdr)
>  {
> nvkm_debug(subdev, "wprGenericHeader\n");
> --
> 2.27.0
>



Re: [PATCH] drm/nouveau/fifo: set gf100_fifo_nonstall_block_dump storage-class-specifier to static

2023-03-03 Thread Karol Herbst
Reviewed-by: Karol Herbst 

will push in a moment

On Fri, Mar 3, 2023 at 2:27 PM Tom Rix  wrote:
>
> gcc with W=1 reports
> drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c:451:1: error:
>   no previous prototype for ‘gf100_fifo_nonstall_block’ 
> [-Werror=missing-prototypes]
>   451 | gf100_fifo_nonstall_block(struct nvkm_event *event, int type, int 
> index)
>   | ^
>
> gf100_fifo_nonstall_block is only used in gf100.c, so it should be static
>
> Signed-off-by: Tom Rix 
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c 
> b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
> index 5bb65258c36d..6c94451d0faa 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
> @@ -447,7 +447,7 @@ gf100_fifo_nonstall_allow(struct nvkm_event *event, int 
> type, int index)
> spin_unlock_irqrestore(>lock, flags);
>  }
>
> -void
> +static void
>  gf100_fifo_nonstall_block(struct nvkm_event *event, int type, int index)
>  {
> struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), 
> nonstall.event);
> --
> 2.27.0
>



Re: [PATCH] drm/amdgpu: Implement mmap of imported dma-bufs

2023-03-03 Thread kernel test robot
Hi Marek,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm/drm-next drm-intel/for-linux-next 
drm-tip/drm-tip linus/master next-20230303]
[cannot apply to drm-intel/for-linux-next-fixes v6.2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Marek-Maslanka/drm-amdgpu-Implement-mmap-of-imported-dma-bufs/20230303-191145
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20230303110951.3777850-1-mmaslanka%40chromium.org
patch subject: [PATCH] drm/amdgpu: Implement mmap of imported dma-bufs
config: sparc-allyesconfig 
(https://download.01.org/0day-ci/archive/20230303/202303032218.9kveepuv-...@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/2916257baab842afa387781faf1b595b73249767
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Marek-Maslanka/drm-amdgpu-Implement-mmap-of-imported-dma-bufs/20230303-191145
git checkout 2916257baab842afa387781faf1b595b73249767
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=sparc olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 
| Link: 
https://lore.kernel.org/oe-kbuild-all/202303032218.9kveepuv-...@intel.com/

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c: In function 
'amdgpu_try_dma_buf_mmap':
>> drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c:286:27: warning: variable 'bo' 
>> set but not used [-Wunused-but-set-variable]
 286 | struct amdgpu_bo *bo = NULL;
 |   ^~
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/dc_types.h:36,
from 
drivers/gpu/drm/amd/amdgpu/../display/dc/dm_services_types.h:30,
from 
drivers/gpu/drm/amd/amdgpu/../include/dm_pp_interface.h:26,
from drivers/gpu/drm/amd/amdgpu/amdgpu.h:64,
from drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c:34:
   drivers/gpu/drm/amd/amdgpu/../display/dc/dc_hdmi_types.h: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/dc/dc_hdmi_types.h:53:22: warning: 
'dp_hdmi_dongle_signature_str' defined but not used [-Wunused-const-variable=]
  53 | static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI 
ADAPTOR";
 |  ^~~~


vim +/bo +286 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c

   278  
   279  int amdgpu_try_dma_buf_mmap(struct file *filp, struct vm_area_struct 
*vma)
   280  {
   281  struct drm_file *priv = filp->private_data;
   282  struct drm_device *dev = priv->minor->dev;
   283  struct amdgpu_device *adev = drm_to_adev(dev);
   284  struct ttm_device *bdev = >mman.bdev;
   285  struct ttm_buffer_object *tbo = NULL;
 > 286  struct amdgpu_bo *bo = NULL;
   287  struct drm_gem_object *obj = NULL;
   288  struct drm_vma_offset_node *node;
   289  int ret;
   290  
   291  if (drm_dev_is_unplugged(dev))
   292  return -ENODEV;
   293  
   294  drm_vma_offset_lock_lookup(bdev->vma_manager);
   295  node = drm_vma_offset_exact_lookup_locked(bdev->vma_manager,
   296vma->vm_pgoff,
   297vma_pages(vma));
   298  
   299  if (likely(node)) {
   300  tbo = container_of(node, struct ttm_buffer_object,
   301 base.vma_node);
   302  tbo = ttm_bo_get_unless_zero(tbo);
   303  }
   304  drm_vma_offset_unlock_lookup(bdev->vma_manager);
   305  
   306  if (!tbo)
   307  return -EINVAL;
   308  
   309  bo = ttm_to_amdgpu_bo(tbo);
   310  obj = >base;
   311  
   312  if (!obj->import_attach) {
   313  ret = -EINVAL;
   314  goto done;
   315  }
   316  
   317  ret = dma_buf_mmap(obj->import_attach->dmabuf, vma, 0);
   318  
   319

Re: [PATCH 1/9] drm: execution context for GEM buffers v3

2023-03-03 Thread Luben Tuikov
On 2023-02-28 03:33, Christian König wrote:
> This adds the infrastructure for an execution context for GEM buffers
> which is similar to the existinc TTMs execbuf util and intended to replace
> it in the long term.
> 
> The basic functionality is that we abstracts the necessary loop to lock
> many different GEM buffers with automated deadlock and duplicate handling.
> 
> v2: drop xarray and use dynamic resized array instead, the locking
> overhead is unecessary and measureable.
> v3: drop duplicate tracking, radeon is really the only one needing that.
> 
> Signed-off-by: Christian König 
> ---
>  Documentation/gpu/drm-mm.rst |  12 ++
>  drivers/gpu/drm/Kconfig  |   6 +
>  drivers/gpu/drm/Makefile |   2 +
>  drivers/gpu/drm/drm_exec.c   | 249 +++
>  include/drm/drm_exec.h   | 115 
>  5 files changed, 384 insertions(+)
>  create mode 100644 drivers/gpu/drm/drm_exec.c
>  create mode 100644 include/drm/drm_exec.h
> 
> diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
> index a79fd3549ff8..a52e6f4117d6 100644
> --- a/Documentation/gpu/drm-mm.rst
> +++ b/Documentation/gpu/drm-mm.rst
> @@ -493,6 +493,18 @@ DRM Sync Objects
>  .. kernel-doc:: drivers/gpu/drm/drm_syncobj.c
> :export:
>  
> +DRM Execution context
> +=
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_exec.c
> +   :doc: Overview
> +
> +.. kernel-doc:: include/drm/drm_exec.h
> +   :internal:
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_exec.c
> +   :export:
> +
>  GPU Scheduler
>  =
>  
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 17d252dc25e2..84a5fc28c48d 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -200,6 +200,12 @@ config DRM_TTM
> GPU memory types. Will be enabled automatically if a device driver
> uses it.
>  
> +config DRM_EXEC
> + tristate
> + depends on DRM
> + help
> +   Execution context for command submissions
> +
>  config DRM_BUDDY
>   tristate
>   depends on DRM
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index ab4460fcd63f..d40defbb0347 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -78,6 +78,8 @@ obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += 
> drm_panel_orientation_quirks.o
>  #
>  # Memory-management helpers
>  #
> +#
> +obj-$(CONFIG_DRM_EXEC) += drm_exec.o
>  
>  obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
>  
> diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
> new file mode 100644
> index ..df546cc5a227
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_exec.c
> @@ -0,0 +1,249 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +
> +#include 
> +#include 
> +#include 
> +
> +/**
> + * DOC: Overview
> + *
> + * This component mainly abstracts the retry loop necessary for locking
> + * multiple GEM objects while preparing hardware operations (e.g. command
> + * submissions, page table updates etc..).
> + *
> + * If a contention is detected while locking a GEM object the cleanup 
> procedure
> + * unlocks all previously locked GEM objects and locks the contended one 
> first
> + * before locking any further objects.
> + *
> + * After an object is locked fences slots can optionally be reserved on the
> + * dma_resv object inside the GEM object.
> + *
> + * A typical usage pattern should look like this::
> + *
> + *   struct drm_gem_object *obj;
> + *   struct drm_exec exec;
> + *   unsigned long index;
> + *   int ret;
> + *
> + *   drm_exec_init(, true);
> + *   drm_exec_while_not_all_locked() {
> + *   ret = drm_exec_prepare_obj(, boA, 1);
> + *   drm_exec_continue_on_contention();
> + *   if (ret)
> + *   goto error;
> + *
> + *   ret = drm_exec_lock(, boB, 1);
> + *   drm_exec_continue_on_contention();
> + *   if (ret)
> + *   goto error;
> + *   }
> + *
> + *   drm_exec_for_each_locked_object(, index, obj) {
> + *   dma_resv_add_fence(obj->resv, fence, DMA_RESV_USAGE_READ);
> + *   ...
> + *   }
> + *   drm_exec_fini();

Maybe add the error: label here to show how recovery is to be had.

> + *
> + * See struct dma_exec for more details.
> + */
> +
> +/* Dummy value used to initially enter the retry loop */
> +#define DRM_EXEC_DUMMY (void*)~0
> +
> +/* Unlock all objects and drop references */
> +static void drm_exec_unlock_all(struct drm_exec *exec)
> +{
> + struct drm_gem_object *obj;
> + unsigned long index;
> +
> + drm_exec_for_each_locked_object(exec, index, obj) {
> + dma_resv_unlock(obj->resv);
> + drm_gem_object_put(obj);
> + }
> +
> + if (exec->prelocked) {
> + dma_resv_unlock(exec->prelocked->resv);
> + drm_gem_object_put(exec->prelocked);
> + exec->prelocked = NULL;
> + }
> +}
> +
> +/**
> + * drm_exec_init - initialize a drm_exec object
> + * @exec: the 

[PATCH v2] drm/i915/gvt: Make use of idr_find and idr_for_each_entry in dmabuf

2023-03-03 Thread Cai Huoqing
This patch uses the already existing IDR mechanism to simplify
and improve the dmabuf code.

Using 'vgpu.object_idr' directly instead of 'dmabuf_obj_list_head'
or 'dmabuf.list', because the dmabuf_obj can be found by 'idr_find'
or 'idr_for_each_entry'.

Signed-off-by: Cai Huoqing 
---
v1->v2:
1.Use idr_find to get the target one and free it instead of free all 
dma objs.
2.Revert the original code 'ret' related
3.Add '&& !idr_is_empty()' like the original code '&& !list_empty()'

v1 link:

https://lore.kernel.org/lkml/20230302115318.79487-1-cai.huoq...@linux.dev/

 drivers/gpu/drm/i915/gvt/dmabuf.c | 58 +++
 drivers/gpu/drm/i915/gvt/dmabuf.h |  1 -
 drivers/gpu/drm/i915/gvt/gvt.h|  1 -
 drivers/gpu/drm/i915/gvt/vgpu.c   |  1 -
 4 files changed, 12 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 6834f9fe40cf..cf619b1ed3ad 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -133,21 +133,15 @@ static void dmabuf_gem_object_free(struct kref *kref)
struct intel_vgpu_dmabuf_obj *obj =
container_of(kref, struct intel_vgpu_dmabuf_obj, kref);
struct intel_vgpu *vgpu = obj->vgpu;
-   struct list_head *pos;
struct intel_vgpu_dmabuf_obj *dmabuf_obj;
 
if (vgpu && test_bit(INTEL_VGPU_STATUS_ACTIVE, vgpu->status) &&
-   !list_empty(>dmabuf_obj_list_head)) {
-   list_for_each(pos, >dmabuf_obj_list_head) {
-   dmabuf_obj = list_entry(pos, struct 
intel_vgpu_dmabuf_obj, list);
-   if (dmabuf_obj == obj) {
-   list_del(pos);
-   idr_remove(>object_idr,
-  dmabuf_obj->dmabuf_id);
-   kfree(dmabuf_obj->info);
-   kfree(dmabuf_obj);
-   break;
-   }
+   !idr_is_empty(>object_idr)) {
+   dmabuf_obj = idr_find(>object_idr, obj->dmabuf_id);
+   if (dmabuf_obj) {
+   idr_remove(>object_idr, obj->dmabuf_id);
+   kfree(dmabuf_obj->info);
+   kfree(dmabuf_obj);
}
} else {
/* Free the orphan dmabuf_objs here */
@@ -340,13 +334,12 @@ static struct intel_vgpu_dmabuf_obj *
 pick_dmabuf_by_info(struct intel_vgpu *vgpu,
struct intel_vgpu_fb_info *latest_info)
 {
-   struct list_head *pos;
struct intel_vgpu_fb_info *fb_info;
struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
struct intel_vgpu_dmabuf_obj *ret = NULL;
+   int id;
 
-   list_for_each(pos, >dmabuf_obj_list_head) {
-   dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, 
list);
+   idr_for_each_entry(>object_idr, dmabuf_obj, id) {
if (!dmabuf_obj->info)
continue;
 
@@ -366,24 +359,6 @@ pick_dmabuf_by_info(struct intel_vgpu *vgpu,
return ret;
 }
 
-static struct intel_vgpu_dmabuf_obj *
-pick_dmabuf_by_num(struct intel_vgpu *vgpu, u32 id)
-{
-   struct list_head *pos;
-   struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
-   struct intel_vgpu_dmabuf_obj *ret = NULL;
-
-   list_for_each(pos, >dmabuf_obj_list_head) {
-   dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, 
list);
-   if (dmabuf_obj->dmabuf_id == id) {
-   ret = dmabuf_obj;
-   break;
-   }
-   }
-
-   return ret;
-}
-
 static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
  struct intel_vgpu_fb_info *fb_info)
 {
@@ -477,11 +452,6 @@ int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void 
*args)
 
update_fb_info(gfx_plane_info, _info);
 
-   INIT_LIST_HEAD(_obj->list);
-   mutex_lock(>dmabuf_lock);
-   list_add_tail(_obj->list, >dmabuf_obj_list_head);
-   mutex_unlock(>dmabuf_lock);
-
gvt_dbg_dpy("vgpu%d: %s new dmabuf_obj ref %d, id %d\n", vgpu->id,
__func__, kref_read(_obj->kref), ret);
 
@@ -508,7 +478,7 @@ int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, unsigned 
int dmabuf_id)
 
mutex_lock(>dmabuf_lock);
 
-   dmabuf_obj = pick_dmabuf_by_num(vgpu, dmabuf_id);
+   dmabuf_obj = idr_find(>object_idr, dmabuf_id);
if (dmabuf_obj == NULL) {
gvt_vgpu_err("invalid dmabuf id:%d\n", dmabuf_id);
ret = -EINVAL;
@@ -570,23 +540,19 @@ int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, 
unsigned int dmabuf_id)
 
 void intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu)
 {
-   struct list_head *pos, *n;
struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+   int id;
 
mutex_lock(>dmabuf_lock);
-   list_for_each_safe(pos, n, 

Re: [PATCH v2 3/8] accel/qaic: Add MHI controller

2023-03-03 Thread Stanislaw Gruszka
On Wed, Mar 01, 2023 at 09:09:57AM -0700, Jeffrey Hugo wrote:
> On 2/28/2023 4:52 AM, Stanislaw Gruszka wrote:
> > On Mon, Feb 06, 2023 at 08:41:40AM -0700, Jeffrey Hugo wrote:
> > > + mhi_cntl = kzalloc(sizeof(*mhi_cntl), GFP_KERNEL);
> > [snip]
> > > + mhi_cntl->irq = kmalloc(sizeof(*mhi_cntl->irq), GFP_KERNEL);
> > 
> > I recommend usage of devm_kzalloc(), devm_kmalloc() for those
> > to simplify error and exit paths.
> 
> When this was written, I didn't want to pass the struct device to the
> mhi_controller just for the purpose of using devm_*.  Today, I'm thinking
> that is not the end of the world, and devm has advantages. Will change.

If already available _dev->dev can not be used in devm_ due to
different life times of pci_dev->dev and mhi_cntl, I don't think change
would be justifiable and kmalloc/kzalloc should stay.

Regards
Stanislaw



Re: [PATCH v2 5/8] accel/qaic: Add datapath

2023-03-03 Thread Stanislaw Gruszka
On Wed, Mar 01, 2023 at 11:14:35AM -0700, Jeffrey Hugo wrote:
> On 3/1/2023 10:05 AM, Stanislaw Gruszka wrote:
> > On Wed, Mar 01, 2023 at 09:08:03AM -0700, Jeffrey Hugo wrote:
> > > > This looks a bit suspicious. Are you sure you can modify
> > > > sg->dma_address and still use it as valid value ?
> > > 
> > > A single entry in the sg table is a contiguous mapping of memory.  If it
> > > wasn't contiguous, it would have to be broken up into multiple entries.  
> > > In
> > > the simple case, a driver is going to take the dma_address/len pair and 
> > > hand
> > > that directly to the device.  Then the device is going to access every
> > > address in that range.
> > > 
> > > If the device can access every address from dma_address to dma_address +
> > > len, why can't it access a subset of that?
> > 
> > Required address alignment can be broken. Not sure if only that.
> 
> AIC100 doesn't have required alignment.  AIC100 can access any 64-bit
> address, at a byte level granularity.  The only restriction AIC100 has is
> that the size of a transfer is restricted to a 32-bit value, so max
> individual transfer size of 4GB.  Transferring more than 4GB requires
> multiple transactions.
> 
> > > > > Are you suggesting renaming
> > > > > this function?  I guess I'm not quite understanding your comment 
> > > > > here. Can
> > > > > you elaborate?
> > > > 
> > > > Renaming would be nice. I was thinking by simplifying it, not sure
> > > > now if that's easy achievable, though.
> > > 
> > > Ok.  I'll think on this.
> > 
> > Maybe this function could be removed ? And create sg lists
> > that hardware can handle without any modification.
> > Just idea to consider, not any requirement.
> 
> Ok, so this is part of our "slicing" operation, and thus required.
> 
> Maybe how slicing works is not clear.
> 
> Lets say that we have a workload on AIC100 that can identify a license plate
> in a picture (aka lprnet).  Lets assume this workload only needs the RGB
> values of a RGBA file (a "jpeg" we are processing).
> 
> Userspace allocates a BO to hold the entire file.  A quarter of the file is
> R values, a quarter is G values, etc.  For simplicity, lets assume the R
> values are all sequentially listed, then the G values, then the B values,
> finally the A values.  When we allocate the BO, we map it once.  If we have
> an IOMMU, this optimizes the IOMMU mappings.  BOs can be quite large.  We
> have some test workloads based on real world workloads where each BO is
> 16-32M in size, and there are multiple BOs.  I don't want to map a 32M BO N
> duplicate times in the IOMMU.
> 
> So, now userspace slices the BO.  It tells us we need to transfer the RGB
> values (the first 75% of the BO), but not the A values.  So, we create a
> copy of the mapped SG and edit it to represent this transfer, which is a
> subset of the entire BO.  Using the slice information and the mapping
> information, we construct the DMA engine commands that can be used to
> transfer the relevant portions of the BO to the device.
> 
> It sounds like you are suggesting, lets flip this around.  Don't map the
> entire BO once.  Instead, wait for the slice info from userspace, construct
> a sg list based on the parts of the BO for the slice, and map that.  Then
> the driver gets a mapped SG it can just use.  The issue I see with that is
> slices can overlap.  You can transfer the same part of a BO multiple times.
> Maybe lprnet has multiple threads on AIC100 where thread A consumes R data,
> thread B consumes R and G data, and thread C consumes B data.  We need to
> transfer the R data twice to different device locations so that threads A
> and B can consume the R data independently.
> 
> If we map per slice, we are going to map the R part of the BO twice in the
> IOMMU.  Is that valid?  It feels possible that there exists some IOMMU
> implementation that won't allow multiple IOVAs to map to the same DDR PA
> because that is weird and the implementer thinks its a software bug.  I
> don't want to run into that.  Assuming it is valid, that is multiple
> mappings in the IOMMU TLB which could have been a single mapping.  We are
> wasting IOMMU resources.
> 
> There are some ARM systems we support with limited IOVA space in the IOMMU,
> and we've had some issues with exhausting that space.  The current
> implementation is influenced by those experiences.

Ok, then the current implementation seems reasonable.
Thanks for explanation!

Regards
Stanislaw


Re: [PATCH 1/9] drm: execution context for GEM buffers v3

2023-03-03 Thread Luben Tuikov
On 2023-02-28 14:13, Danilo Krummrich wrote:
> On 2/28/23 09:33, Christian König wrote:
>> This adds the infrastructure for an execution context for GEM buffers
>> which is similar to the existinc TTMs execbuf util and intended to replace
> 
> "existing"
> 
>> it in the long term.
>>
>> The basic functionality is that we abstracts the necessary loop to lock
>> many different GEM buffers with automated deadlock and duplicate handling.
>>
>> v2: drop xarray and use dynamic resized array instead, the locking
>>  overhead is unecessary and measureable.
> 
> "unecessary", "measurable"

"unnecessary".
-- 
Regards,
Luben



[PATCH] drm/nouveau/fifo: set gf100_fifo_nonstall_block_dump storage-class-specifier to static

2023-03-03 Thread Tom Rix
gcc with W=1 reports
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c:451:1: error:
  no previous prototype for ‘gf100_fifo_nonstall_block’ 
[-Werror=missing-prototypes]
  451 | gf100_fifo_nonstall_block(struct nvkm_event *event, int type, int index)
  | ^

gf100_fifo_nonstall_block is only used in gf100.c, so it should be static

Signed-off-by: Tom Rix 
---
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
index 5bb65258c36d..6c94451d0faa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
@@ -447,7 +447,7 @@ gf100_fifo_nonstall_allow(struct nvkm_event *event, int 
type, int index)
spin_unlock_irqrestore(>lock, flags);
 }
 
-void
+static void
 gf100_fifo_nonstall_block(struct nvkm_event *event, int type, int index)
 {
struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), 
nonstall.event);
-- 
2.27.0



Re: [PATCH] drm/i915/gvt: Make use of idr_find and idr_for_each_entry in dmabuf

2023-03-03 Thread Cai Huoqing
On 03 3月 23 15:12:16, Zhenyu Wang wrote:
> On 2023.03.02 19:53:18 +0800, Cai Huoqing wrote:
> > This patch uses the already existing IDR mechanism to simplify
> > and improve the dmabuf code.
> > 
> > Using 'vgpu.object_idr' directly instead of 'dmabuf_obj_list_head'
> > or 'dmabuf.list', because the dmabuf_obj can be found by 'idr_find'
> > or 'idr_for_each_entry'.
> > 
> > Signed-off-by: Cai Huoqing 
> > ---
> >  drivers/gpu/drm/i915/gvt/dmabuf.c | 69 +++
> >  drivers/gpu/drm/i915/gvt/dmabuf.h |  1 -
> >  drivers/gpu/drm/i915/gvt/gvt.h|  1 -
> >  drivers/gpu/drm/i915/gvt/vgpu.c   |  1 -
> >  4 files changed, 16 insertions(+), 56 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c 
> > b/drivers/gpu/drm/i915/gvt/dmabuf.c
> > index 6834f9fe40cf..7933bd843ae8 100644
> > --- a/drivers/gpu/drm/i915/gvt/dmabuf.c
> > +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
> > @@ -133,21 +133,15 @@ static void dmabuf_gem_object_free(struct kref *kref)
> > struct intel_vgpu_dmabuf_obj *obj =
> > container_of(kref, struct intel_vgpu_dmabuf_obj, kref);
> > struct intel_vgpu *vgpu = obj->vgpu;
> > -   struct list_head *pos;
> > struct intel_vgpu_dmabuf_obj *dmabuf_obj;
> > +   int id;
> >  
> > -   if (vgpu && test_bit(INTEL_VGPU_STATUS_ACTIVE, vgpu->status) &&
> > -   !list_empty(>dmabuf_obj_list_head)) {
> > -   list_for_each(pos, >dmabuf_obj_list_head) {
> > -   dmabuf_obj = list_entry(pos, struct 
> > intel_vgpu_dmabuf_obj, list);
> > -   if (dmabuf_obj == obj) {
> > -   list_del(pos);
> > -   idr_remove(>object_idr,
> > -  dmabuf_obj->dmabuf_id);
> > -   kfree(dmabuf_obj->info);
> > -   kfree(dmabuf_obj);
> > -   break;
> > -   }
> > +   if (vgpu && test_bit(INTEL_VGPU_STATUS_ACTIVE, vgpu->status)) {
> > +   idr_for_each_entry(>object_idr, dmabuf_obj, id) {
> > +   idr_remove(>object_idr, id);
> > +   kfree(dmabuf_obj->info);
> > +   kfree(dmabuf_obj);
> 
> This is wrong, it is not to free all dmabuf objects, but just for target one.
Indeed, I will use idr_find for the target.

> 
> > +   break;
> > }
> > } else {
> > /* Free the orphan dmabuf_objs here */
> > @@ -340,13 +334,11 @@ static struct intel_vgpu_dmabuf_obj *
> >  pick_dmabuf_by_info(struct intel_vgpu *vgpu,
> > struct intel_vgpu_fb_info *latest_info)
> >  {
> > -   struct list_head *pos;
> > struct intel_vgpu_fb_info *fb_info;
> > struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
> > -   struct intel_vgpu_dmabuf_obj *ret = NULL;
> > +   int id;
> >  
> > -   list_for_each(pos, >dmabuf_obj_list_head) {
> > -   dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, 
> > list);
> > +   idr_for_each_entry(>object_idr, dmabuf_obj, id) {
> > if (!dmabuf_obj->info)
> > continue;
> >  
> > @@ -357,31 +349,11 @@ pick_dmabuf_by_info(struct intel_vgpu *vgpu,
> > (fb_info->drm_format_mod == latest_info->drm_format_mod) &&
> > (fb_info->drm_format == latest_info->drm_format) &&
> > (fb_info->width == latest_info->width) &&
> > -   (fb_info->height == latest_info->height)) {
> > -   ret = dmabuf_obj;
> > -   break;
> > -   }
> 
> Maybe just keep original code's use of extra ret to not include this 
> cumbersome diff?
Ok, will revert 'ret' related.

Thanks,
Cai-
> 
> > -   }
> > -
> > -   return ret;
> > -}
> > -
> > -static struct intel_vgpu_dmabuf_obj *
> > -pick_dmabuf_by_num(struct intel_vgpu *vgpu, u32 id)
> > -{
> > -   struct list_head *pos;
> > -   struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
> > -   struct intel_vgpu_dmabuf_obj *ret = NULL;
> > -
> > -   list_for_each(pos, >dmabuf_obj_list_head) {
> > -   dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, 
> > list);
> > -   if (dmabuf_obj->dmabuf_id == id) {
> > -   ret = dmabuf_obj;
> > -   break;
> > -   }
> > +   (fb_info->height == latest_info->height))
> > +   return dmabuf_obj;
> > }
> >  
> > -   return ret;
> > +   return dmabuf_obj;
> >  }
> >  
> >  static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
> > @@ -477,11 +449,6 @@ int intel_vgpu_query_plane(struct intel_vgpu *vgpu, 
> > void *args)
> >  
> > update_fb_info(gfx_plane_info, _info);
> >  
> > -   INIT_LIST_HEAD(_obj->list);
> > -   mutex_lock(>dmabuf_lock);
> > -   list_add_tail(_obj->list, >dmabuf_obj_list_head);
> > -   mutex_unlock(>dmabuf_lock);
> > -
> > gvt_dbg_dpy("vgpu%d: %s new dmabuf_obj ref %d, id %d\n", vgpu->id,
> > __func__, kref_read(_obj->kref), 

[PATCH v4 24/30] drm/msm/dpu: rework plane CSC setting

2023-03-03 Thread Dmitry Baryshkov
Rework the code flushing CSC settings for the plane. Separate out the
pipe and pipe_cfg as a preparation for r_pipe support.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 47 +--
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5f8c71a6093f..c637713e23c7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -576,29 +576,19 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
 };
 
-static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, 
const struct dpu_format *fmt)
+static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe,
+   const struct dpu_format 
*fmt)
 {
-   struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
const struct dpu_csc_cfg *csc_ptr;
 
-   if (!pdpu) {
-   DPU_ERROR("invalid plane\n");
-   return NULL;
-   }
-
if (!DPU_FORMAT_IS_YUV(fmt))
return NULL;
 
-   if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
+   if (BIT(DPU_SSPP_CSC_10BIT) & pipe->sspp->cap->features)
csc_ptr = _csc10_YUV2RGB_601L;
else
csc_ptr = _csc_YUV2RGB_601L;
 
-   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-   csc_ptr->csc_mv[0],
-   csc_ptr->csc_mv[1],
-   csc_ptr->csc_mv[2]);
-
return csc_ptr;
 }
 
@@ -1050,6 +1040,28 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return 0;
 }
 
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe 
*pipe)
+{
+   const struct dpu_format *format =
+   to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+   const struct dpu_csc_cfg *csc_ptr;
+
+   if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+   return;
+
+   csc_ptr = _dpu_plane_get_csc(pipe, format);
+   if (!csc_ptr)
+   return;
+
+   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+   csc_ptr->csc_mv[0],
+   csc_ptr->csc_mv[1],
+   csc_ptr->csc_mv[2]);
+
+   pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
struct dpu_plane *pdpu;
@@ -1073,13 +1085,8 @@ void dpu_plane_flush(struct drm_plane *plane)
else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-   else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
-   const struct dpu_format *fmt = 
to_dpu_format(msm_framebuffer_format(plane->state->fb));
-   const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, 
fmt);
-
-   if (csc_ptr)
-   pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
csc_ptr);
-   }
+   else
+   dpu_plane_flush_csc(pdpu, >pipe);
 
/* flag h/w flush complete */
if (plane->state)
-- 
2.39.2



  1   2   >