Re: [PATCH v5 3/3] drm: protect drm_master pointers in drm_lease.c

2021-06-30 Thread Desmond Cheong Zhi Xi

On 30/6/21 12:07 am, Daniel Vetter wrote:

On Tue, Jun 29, 2021 at 11:37:06AM +0800, Desmond Cheong Zhi Xi wrote:

Currently, direct copies of drm_file->master pointers should be
protected by drm_device.master_mutex when being dereferenced. This is
because drm_file->master is not invariant for the lifetime of
drm_file. If drm_file is not the creator of master, then
drm_file->is_master is false, and a call to drm_setmaster_ioctl will
invoke drm_new_set_master, which then allocates a new master for
drm_file and puts the old master.

Thus, without holding drm_device.master_mutex, the old value of
drm_file->master could be freed while it is being used by another
concurrent process.

In drm_lease.c, there are multiple instances where drm_file->master is
accessed and dereferenced while drm_device.master_mutex is not
held. This makes drm_lease.c vulnerable to use-after-free bugs.

We address this issue in 3 ways:

1. Clarify in the kerneldoc that drm_file->master is protected by
drm_device.master_mutex.

2. Add a new drm_file_get_master() function that calls drm_master_get
on drm_file->master while holding on to drm_device.master_mutex. Since
drm_master_get increments the reference count of master, this
prevents master from being freed until we unreference it with
drm_master_put.

3. In each case where drm_file->master is directly accessed and
eventually dereferenced in drm_lease.c, we wrap the access in a call
to the new drm_file_get_master function, then unreference the master
pointer once we are done using it.

Reported-by: Daniel Vetter 
Signed-off-by: Desmond Cheong Zhi Xi 


Series looks very nice, let's see what intel-gfx-ci says. You should get a
mail, but results are also here:

https://patchwork.freedesktop.org/series/91969/#rev2

One tiny comment below.


---
  drivers/gpu/drm/drm_auth.c  | 25 
  drivers/gpu/drm/drm_lease.c | 77 +++--
  include/drm/drm_auth.h  |  1 +
  include/drm/drm_file.h  | 15 ++--
  4 files changed, 95 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index ab1863c5a5a0..c36a0b72be26 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -384,6 +384,31 @@ struct drm_master *drm_master_get(struct drm_master 
*master)
  }
  EXPORT_SYMBOL(drm_master_get);
  
+/**

+ * drm_file_get_master - reference &drm_file.master of @file_priv
+ * @file_priv: DRM file private
+ *
+ * Increments the reference count of @file_priv's &drm_file.master and returns
+ * the &drm_file.master. If @file_priv has no &drm_file.master, returns NULL.
+ *
+ * Master pointers returned from this function should be unreferenced using
+ * drm_master_put().
+ */
+struct drm_master *drm_file_get_master(struct drm_file *file_priv)
+{
+   struct drm_master *master = NULL;
+
+   mutex_lock(&file_priv->minor->dev->master_mutex);
+   if (!file_priv->master)
+   goto unlock;
+   master = drm_master_get(file_priv->master);
+
+unlock:
+   mutex_unlock(&file_priv->minor->dev->master_mutex);
+   return master;
+}
+EXPORT_SYMBOL(drm_file_get_master);
+
  static void drm_master_destroy(struct kref *kref)
  {
struct drm_master *master = container_of(kref, struct drm_master, 
refcount);
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 00fb433bcef1..cdcc87fa9685 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -106,10 +106,19 @@ static bool _drm_has_leased(struct drm_master *master, 
int id)
   */
  bool _drm_lease_held(struct drm_file *file_priv, int id)
  {
-   if (!file_priv || !file_priv->master)
+   bool ret;
+   struct drm_master *master;
+
+   if (!file_priv)
return true;
  
-	return _drm_lease_held_master(file_priv->master, id);

+   master = drm_file_get_master(file_priv);
+   if (master == NULL)
+   return true;
+   ret = _drm_lease_held_master(master, id);
+   drm_master_put(&master);
+
+   return ret;
  }
  
  /**

@@ -128,13 +137,20 @@ bool drm_lease_held(struct drm_file *file_priv, int id)
struct drm_master *master;
bool ret;
  
-	if (!file_priv || !file_priv->master || !file_priv->master->lessor)

+   if (!file_priv)
return true;
  
-	master = file_priv->master;

+   master = drm_file_get_master(file_priv);
+   if (master == NULL)
+   return true;
+   if (!master->lessor) {
+   drm_master_put(&master);
+   return true;
+   }
mutex_lock(&master->dev->mode_config.idr_mutex);
ret = _drm_lease_held_master(master, id);
mutex_unlock(&master->dev->mode_config.idr_mutex);
+   drm_master_put(&master);
return ret;
  }
  
@@ -154,10 +170,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)

int count_in, count_out;
uint32_t crtcs_out = 0;
  
-	if (!file_priv || !file_priv-

Re: [Intel-gfx] [PATCH 0/2] GuC submission / DRM scheduler integration plan + new uAPI

2021-06-30 Thread Daniel Vetter
On Tue, Jun 29, 2021 at 12:35:09PM -0700, Matthew Brost wrote:
> Subject and patches say it all.
> 
> v2: Address comments, patches have details of changes
> v3: Address comments, patches have details of changes
> v4: Address comments, patches have details of changes
> v5: Fix checkpatch and docs warnings
> 
> Signed-off-by: Matthew Brost 

Pushed to drm-intel-gt-next, thanks a lot!
-Daniel

> 
> Matthew Brost (2):
>   drm/doc/rfc: i915 GuC submission / DRM scheduler
>   drm/doc/rfc: i915 new parallel submission uAPI plan
> 
>  Documentation/gpu/rfc/i915_parallel_execbuf.h | 122 +++
>  Documentation/gpu/rfc/i915_scheduler.rst  | 148 ++
>  Documentation/gpu/rfc/index.rst   |   4 +
>  3 files changed, 274 insertions(+)
>  create mode 100644 Documentation/gpu/rfc/i915_parallel_execbuf.h
>  create mode 100644 Documentation/gpu/rfc/i915_scheduler.rst
> 
> -- 
> 2.28.0
> 
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v5 3/3] drm: protect drm_master pointers in drm_lease.c

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 9:18 AM Desmond Cheong Zhi Xi
 wrote:
>
> On 30/6/21 12:07 am, Daniel Vetter wrote:
> > On Tue, Jun 29, 2021 at 11:37:06AM +0800, Desmond Cheong Zhi Xi wrote:
> >> Currently, direct copies of drm_file->master pointers should be
> >> protected by drm_device.master_mutex when being dereferenced. This is
> >> because drm_file->master is not invariant for the lifetime of
> >> drm_file. If drm_file is not the creator of master, then
> >> drm_file->is_master is false, and a call to drm_setmaster_ioctl will
> >> invoke drm_new_set_master, which then allocates a new master for
> >> drm_file and puts the old master.
> >>
> >> Thus, without holding drm_device.master_mutex, the old value of
> >> drm_file->master could be freed while it is being used by another
> >> concurrent process.
> >>
> >> In drm_lease.c, there are multiple instances where drm_file->master is
> >> accessed and dereferenced while drm_device.master_mutex is not
> >> held. This makes drm_lease.c vulnerable to use-after-free bugs.
> >>
> >> We address this issue in 3 ways:
> >>
> >> 1. Clarify in the kerneldoc that drm_file->master is protected by
> >> drm_device.master_mutex.
> >>
> >> 2. Add a new drm_file_get_master() function that calls drm_master_get
> >> on drm_file->master while holding on to drm_device.master_mutex. Since
> >> drm_master_get increments the reference count of master, this
> >> prevents master from being freed until we unreference it with
> >> drm_master_put.
> >>
> >> 3. In each case where drm_file->master is directly accessed and
> >> eventually dereferenced in drm_lease.c, we wrap the access in a call
> >> to the new drm_file_get_master function, then unreference the master
> >> pointer once we are done using it.
> >>
> >> Reported-by: Daniel Vetter 
> >> Signed-off-by: Desmond Cheong Zhi Xi 
> >
> > Series looks very nice, let's see what intel-gfx-ci says. You should get a
> > mail, but results are also here:
> >
> > https://patchwork.freedesktop.org/series/91969/#rev2
> >
> > One tiny comment below.
> >
> >> ---
> >>   drivers/gpu/drm/drm_auth.c  | 25 
> >>   drivers/gpu/drm/drm_lease.c | 77 +++--
> >>   include/drm/drm_auth.h  |  1 +
> >>   include/drm/drm_file.h  | 15 ++--
> >>   4 files changed, 95 insertions(+), 23 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> >> index ab1863c5a5a0..c36a0b72be26 100644
> >> --- a/drivers/gpu/drm/drm_auth.c
> >> +++ b/drivers/gpu/drm/drm_auth.c
> >> @@ -384,6 +384,31 @@ struct drm_master *drm_master_get(struct drm_master 
> >> *master)
> >>   }
> >>   EXPORT_SYMBOL(drm_master_get);
> >>
> >> +/**
> >> + * drm_file_get_master - reference &drm_file.master of @file_priv
> >> + * @file_priv: DRM file private
> >> + *
> >> + * Increments the reference count of @file_priv's &drm_file.master and 
> >> returns
> >> + * the &drm_file.master. If @file_priv has no &drm_file.master, returns 
> >> NULL.
> >> + *
> >> + * Master pointers returned from this function should be unreferenced 
> >> using
> >> + * drm_master_put().
> >> + */
> >> +struct drm_master *drm_file_get_master(struct drm_file *file_priv)
> >> +{
> >> +struct drm_master *master = NULL;
> >> +
> >> +mutex_lock(&file_priv->minor->dev->master_mutex);
> >> +if (!file_priv->master)
> >> +goto unlock;
> >> +master = drm_master_get(file_priv->master);
> >> +
> >> +unlock:
> >> +mutex_unlock(&file_priv->minor->dev->master_mutex);
> >> +return master;
> >> +}
> >> +EXPORT_SYMBOL(drm_file_get_master);
> >> +
> >>   static void drm_master_destroy(struct kref *kref)
> >>   {
> >>  struct drm_master *master = container_of(kref, struct drm_master, 
> >> refcount);
> >> diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
> >> index 00fb433bcef1..cdcc87fa9685 100644
> >> --- a/drivers/gpu/drm/drm_lease.c
> >> +++ b/drivers/gpu/drm/drm_lease.c
> >> @@ -106,10 +106,19 @@ static bool _drm_has_leased(struct drm_master 
> >> *master, int id)
> >>*/
> >>   bool _drm_lease_held(struct drm_file *file_priv, int id)
> >>   {
> >> -if (!file_priv || !file_priv->master)
> >> +bool ret;
> >> +struct drm_master *master;
> >> +
> >> +if (!file_priv)
> >>  return true;
> >>
> >> -return _drm_lease_held_master(file_priv->master, id);
> >> +master = drm_file_get_master(file_priv);
> >> +if (master == NULL)
> >> +return true;
> >> +ret = _drm_lease_held_master(master, id);
> >> +drm_master_put(&master);
> >> +
> >> +return ret;
> >>   }
> >>
> >>   /**
> >> @@ -128,13 +137,20 @@ bool drm_lease_held(struct drm_file *file_priv, int 
> >> id)
> >>  struct drm_master *master;
> >>  bool ret;
> >>
> >> -if (!file_priv || !file_priv->master || !file_priv->master->lessor)
> >> +if (!file_priv)
> >>  return true;
> >>
> >> -master = file_priv->master;
> >> +master = drm_file_get_master(f

Re: [PATCH 1/2] drm/doc/rfc: i915 GuC submission / DRM scheduler

2021-06-30 Thread Martin Peres

On 29/06/2021 22:35, Matthew Brost wrote:

Add entry for i915 GuC submission / DRM scheduler integration plan.
Follow up patch with details of new parallel submission uAPI to come.

v2:
  (Daniel Vetter)
   - Expand explaination of why bonding isn't supported for GuC
 submission
   - CC some of the DRM scheduler maintainers
   - Add priority inheritance / boosting use case
   - Add reasoning for removing in order assumptions
  (Daniel Stone)
   - Add links to priority spec
v4:
  (Tvrtko)
   - Add TODOs section
  (Daniel Vetter)
   - Pull in 1 line from following patch
v5:
  (Checkpatch)
   - Fix typos

Cc: Christian König 
Cc: Luben Tuikov 
Cc: Alex Deucher 
Cc: Steven Price 
Cc: Jon Bloomfield 
Cc: Dave Airlie 
Cc: Daniel Vetter 
Cc: Jason Ekstrand 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Matthew Brost 
Reviewed-by: Daniel Vetter 
Acked-by: Dave Airlie 
---
  Documentation/gpu/rfc/i915_scheduler.rst | 91 
  Documentation/gpu/rfc/index.rst  |  4 ++
  2 files changed, 95 insertions(+)
  create mode 100644 Documentation/gpu/rfc/i915_scheduler.rst

diff --git a/Documentation/gpu/rfc/i915_scheduler.rst 
b/Documentation/gpu/rfc/i915_scheduler.rst
new file mode 100644
index ..7acd386a6b49
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_scheduler.rst
@@ -0,0 +1,91 @@
+=
+I915 GuC Submission/DRM Scheduler Section
+=
+
+Upstream plan
+=
+For upstream the overall plan for landing GuC submission and integrating the
+i915 with the DRM scheduler is:
+
+* Merge basic GuC submission
+   * Basic submission support for all gen11+ platforms
+   * Not enabled by default on any current platforms but can be enabled via
+ modparam enable_guc


Just a quick reminder that a lot of users have this parameter set in 
their grub command line because of the incorrect assumption that quick 
sync requires the HuC which requires the GuC command submission.


Just bear that in mind and make sure there is a minimum of quality in 
the GuC backend before allowing users to use the GuC, even behind this 
kernel parameter.


Maybe a warning in the kernel logs saying that this feature is 
experimental, and use "enable_guc=1" for the fullest quick sync support 
will improve the user satisfaction, and save you some time handling 
unwanted bugs.



+   * Lots of rework will need to be done to integrate with DRM scheduler so
+ no need to nit pick everything in the code, it just should be
+ functional, no major coding style / layering errors, and not regress
+ execlists
+   * Update IGTs / selftests as needed to work with GuC submission
+   * Enable CI on supported platforms for a baseline


What's the plan to keep the comparison between GuC and execlists? The CI 
machines cannot just test the GuC as it would expose users to 
regressions in the default mode, and machines are hard to come by in the 
CI lab.



+   * Rework / get CI heathly for GuC submission in place as needed
+* Merge new parallel submission uAPI
+   * Bonding uAPI completely incompatible with GuC submission, plus it has
+ severe design issues in general, which is why we want to retire it no
+ matter what
+   * New uAPI adds I915_CONTEXT_ENGINES_EXT_PARALLEL context setup step
+ which configures a slot with N contexts
+   * After I915_CONTEXT_ENGINES_EXT_PARALLEL a user can submit N batches to
+ a slot in a single execbuf IOCTL and the batches run on the GPU in
+ paralllel


FYI, this is a typo


+   * Initially only for GuC submission but execlists can be supported if
+ needed
+* Convert the i915 to use the DRM scheduler
+   * GuC submission backend fully integrated with DRM scheduler
+   * All request queues removed from backend (e.g. all backpressure
+ handled in DRM scheduler)
+   * Resets / cancels hook in DRM scheduler
+   * Watchdog hooks into DRM scheduler
+   * Lots of complexity of the GuC backend can be pulled out once
+ integrated with DRM scheduler (e.g. state machine gets
+ simplier, locking gets simplier, etc...)


As much as I would like more consistency in the English language, 
simplier is not a word in the dictionary.



+   * Execlists backend will minimum required to hook in the DRM scheduler


Can't parse this sentence. How about: "Minimum integration of the 
execlists backend in the DRM scheduler"?


Other than these typographical nitpicks, I think the plan is sane 
provided that you can find enough CI machines and add the warning.



+   * Legacy interface
+   * Features like timeslicing / preemption / virtual engines would
+ be difficult to integrate with the DRM scheduler and these
+ features are not required for GuC submission as the 

Re: [PATCH v4 03/17] drm/uAPI: Add "active bpc" as feedback channel for "max bpc" drm property

2021-06-30 Thread Pekka Paalanen
On Tue, 29 Jun 2021 13:02:05 +0200
Werner Sembach  wrote:

> Am 28.06.21 um 19:03 schrieb Werner Sembach:
> > Am 18.06.21 um 11:11 schrieb Werner Sembach:  
> >> Add a new general drm property "active bpc" which can be used by graphic
> >> drivers to report the applied bit depth per pixel back to userspace.
> >>
> >> While "max bpc" can be used to change the color depth, there was no way to
> >> check which one actually got used. While in theory the driver chooses the
> >> best/highest color depth within the max bpc setting a user might not be
> >> fully aware what his hardware is or isn't capable off. This is meant as a
> >> quick way to double check the setup.
> >>
> >> In the future, automatic color calibration for screens might also depend on
> >> this information being available.
> >>
> >> Signed-off-by: Werner Sembach 
> >> ---
> >>  drivers/gpu/drm/drm_connector.c | 51 +
> >>  include/drm/drm_connector.h |  8 ++
> >>  2 files changed, 59 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/drm_connector.c 
> >> b/drivers/gpu/drm/drm_connector.c
> >> index da39e7ff6965..943f6b61053b 100644
> >> --- a/drivers/gpu/drm/drm_connector.c
> >> +++ b/drivers/gpu/drm/drm_connector.c
> >> @@ -1197,6 +1197,14 @@ static const struct drm_prop_enum_list 
> >> dp_colorspaces[] = {
> >>   *drm_connector_attach_max_bpc_property() to create and attach the
> >>   *property to the connector during initialization.
> >>   *
> >> + * active bpc:
> >> + *This read-only range property tells userspace the pixel color 
> >> bit depth
> >> + *actually used by the hardware display engine on "the cable" on a
> >> + *connector. The chosen value depends on hardware capabilities, 
> >> both
> >> + *display engine and connected monitor, and the "max bpc" 
> >> property.
> >> + *Drivers shall use drm_connector_attach_active_bpc_property() to 
> >> install
> >> + *this property.
> >> + *  
> > Regarding "on the cable" and dithering: As far as I can tell, what the 
> > dithering option does, is setting a hardware
> > register here:
> >
> > - 
> > https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4534
> >
> > - 
> > https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4571
> >
> > So dithering seems to be calculated by fixed purpose hardware/firmware 
> > outside of the driver?
> >
> > The Intel driver does not seem to set a target bpc/bpp for this hardware so 
> > I guess it defaults to 6 or 8 bpc?  
> 
> Never mind it does. This switch-case does affect the dithering output:
> https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4537

Hi,

I obviously do not know the intel driver or hardware at all, but
to me that just looks like translating from bits per pixel to bits per
channel in RGB mapping?

> As found in this documentation p.548:
> https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-lkf-vol02c-commandreference-registers-part2.pdf
> 
> So max bpc and active bpc are affecting/affected by the bpc after dithering.

By definition, if the cable carries N bpc, then dithering does not
change that. The cable still carries N bpc, but due to spatial or
temporal dithering, the *observed* color resolution may or may not be
higher than the cable bpc.

Of course, if the cable bpc is 8, and dithering targets 6 bpc, then 2
LSB on the cable are always zero, right?

Maybe one would want to do that if the monitor has a 6 bit panel and it
simply ignored the 2 LSB, and the cable cannot go down to 6 bpc.

So, what does "max bpc" mean right now?

It seems like dither on/off is insufficient information, one would also
need to control the dithering target bpc. I suppose the driver has a
policy on how it chooses the target bpc, but what is that policy? Is
the dither target bpc the cable bpc or the sink bpc?

Needless to say, I'm quite confused.


Thanks,
pq

> >
> > Similar things happen on amd. Here the output dither depth seems to be 
> > written to a fixed value however:
> >
> > - 
> > https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c#L828
> >
> > - 
> > https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c#L769
> >
> > Does anyone know about a resource where I can read up on the used registers 
> > and what this hardware actually does?  
> Searching now for a similar register reference for AMD GPUs.
> >
> > My proposal for now: "max bpc" affects what happens before dither, so I 
> > would keep "active bpc" the same and add another
> > drm property "dither active: true/false". No additional property to control 
> > dither, as amdgpu does have one already
> > (which isn't always active?) and Intel driver does only seem prepared for 
> > dithering at 6bpc (albeit I don't know why to
> > dither at 6bpc and what depth to dither to?).

Re: [PATCH 47/47] drm/i915/guc: Unblock GuC submission on Gen11+

2021-06-30 Thread Martin Peres




On 24/06/2021 10:05, Matthew Brost wrote:

From: Daniele Ceraolo Spurio 

Unblock GuC submission on Gen11+ platforms.

Signed-off-by: Michal Wajdeczko 
Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|  1 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h |  3 +--
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 14 +-
  4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index fae01dc8e1b9..77981788204f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -54,6 +54,7 @@ struct intel_guc {
struct ida guc_ids;
struct list_head guc_id_list;
  
+	bool submission_supported;

bool submission_selected;
  
  	struct i915_vma *ads_vma;

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index a427336ce916..405339202280 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2042,6 +2042,13 @@ void intel_guc_submission_disable(struct intel_guc *guc)
/* Note: By the time we're here, GuC may have already been reset */
  }
  
+static bool __guc_submission_supported(struct intel_guc *guc)

+{
+   /* GuC submission is unavailable for pre-Gen11 */
+   return intel_guc_is_supported(guc) &&
+  INTEL_GEN(guc_to_gt(guc)->i915) >= 11;
+}
+
  static bool __guc_submission_selected(struct intel_guc *guc)
  {
struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
@@ -2054,6 +2061,7 @@ static bool __guc_submission_selected(struct intel_guc 
*guc)
  
  void intel_guc_submission_init_early(struct intel_guc *guc)

  {
+   guc->submission_supported = __guc_submission_supported(guc);
guc->submission_selected = __guc_submission_selected(guc);
  }
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h

index a2a3fad72be1..be767eb6ff71 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
@@ -37,8 +37,7 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
  
  static inline bool intel_guc_submission_is_supported(struct intel_guc *guc)

  {
-   /* XXX: GuC submission is unavailable for now */
-   return false;
+   return guc->submission_supported;
  }
  
  static inline bool intel_guc_submission_is_wanted(struct intel_guc *guc)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 7a69c3c027e9..61be0aa81492 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -34,8 +34,15 @@ static void uc_expand_default_options(struct intel_uc *uc)
return;
}
  
-	/* Default: enable HuC authentication only */

-   i915->params.enable_guc = ENABLE_GUC_LOAD_HUC;
+   /* Intermediate platforms are HuC authentication only */
+   if (IS_DG1(i915) || IS_ALDERLAKE_S(i915)) {
+   drm_dbg(&i915->drm, "Disabling GuC only due to old platform\n");


This comment does not seem accurate, given that DG1 is barely out, and 
ADL is not out yet. How about:


"Disabling GuC on untested platforms"?


+   i915->params.enable_guc = ENABLE_GUC_LOAD_HUC;
+   return;
+   }
+
+   /* Default: enable HuC authentication and GuC submission */
+   i915->params.enable_guc = ENABLE_GUC_LOAD_HUC | ENABLE_GUC_SUBMISSION;


This seems to be in contradiction with the GuC submission plan which 
states:


"Not enabled by default on any current platforms but can be enabled via 
modparam enable_guc".


When you rework the patch, could you please add a warning when the user 
force-enables the GuC Command Submission? Something like:


"WARNING: The user force-enabled the experimental GuC command submission 
backend using i915.enable_guc. Please disable it if experiencing 
stability issues. No bug reports will be accepted on this backend".


This should allow you to work on the backend, while communicating 
clearly to users that it is not ready just yet. Once it has matured, the 
warning can be removed.


Cheers,
Martin


  }
  
  /* Reset GuC providing us with fresh state for both GuC and HuC.

@@ -313,9 +320,6 @@ static int __uc_init(struct intel_uc *uc)
if (i915_inject_probe_failure(uc_to_gt(uc)->i915))
return -ENOMEM;
  
-	/* XXX: GuC submission is unavailable for now */

-   GEM_BUG_ON(intel_uc_uses_guc_submission(uc));
-
ret = intel_guc_init(guc);
if (ret)
return ret;



[PATCH v2 0/2] drm/i915: IRQ fixes

2021-06-30 Thread Thomas Zimmermann
(was: drm/i915: Drop all references to DRM IRQ midlayer)

Fix a bug in the usage of IRQs and cleanup references to the DRM
IRQ midlayer.

Preferably this patchset would be merged through drm-misc-next.

Thomas Zimmermann (2):
  drm/i915: Use the correct IRQ during resume
  drm/i915: Drop all references to DRM IRQ midlayer

 drivers/gpu/drm/i915/gt/intel_ring_submission.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.c |  1 -
 drivers/gpu/drm/i915/i915_irq.c | 10 +-
 drivers/gpu/drm/i915/i915_irq.h |  1 +
 4 files changed, 7 insertions(+), 7 deletions(-)


base-commit: 67f5a18128770817e4218a9e496d2bf5047c51e8
--
2.32.0



[PATCH v2 1/2] drm/i915: Use the correct IRQ during resume

2021-06-30 Thread Thomas Zimmermann
The code in xcs_resume() probably didn't work as intended. It uses
struct drm_device.irq, which is allocated to 0, but never initialized
by i915 to the device's interrupt number.

v2:
* wrap irq code in intel_synchronize_hardirq() (Ville)

Signed-off-by: Thomas Zimmermann 
Fixes: 536f77b1caa0 ("drm/i915/gt: Call stop_ring() from ring resume, again")
Cc: Chris Wilson 
Cc: Mika Kuoppala 
Cc: Daniel Vetter 
Cc: Rodrigo Vivi 
Cc: Joonas Lahtinen 
Cc: Maarten Lankhorst 
Cc: Lucas De Marchi 
---
 drivers/gpu/drm/i915/gt/intel_ring_submission.c | 2 +-
 drivers/gpu/drm/i915/i915_irq.c | 5 +
 drivers/gpu/drm/i915/i915_irq.h | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 5d42a12ef3d6..1b5a22a83db6 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -185,7 +185,7 @@ static int xcs_resume(struct intel_engine_cs *engine)
 ring->head, ring->tail);
 
/* Double check the ring is empty & disabled before we resume */
-   synchronize_hardirq(engine->i915->drm.irq);
+   intel_synchronize_hardirq(engine->i915);
if (!stop_ring(engine))
goto err;
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7d0ce8b9f8ed..2203dca19895 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4575,3 +4575,8 @@ void intel_synchronize_irq(struct drm_i915_private *i915)
 {
synchronize_irq(to_pci_dev(i915->drm.dev)->irq);
 }
+
+void intel_synchronize_hardirq(struct drm_i915_private *i915)
+{
+   synchronize_hardirq(to_pci_dev(i915->drm.dev)->irq);
+}
diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h
index db34d5dbe402..e43b6734f21b 100644
--- a/drivers/gpu/drm/i915/i915_irq.h
+++ b/drivers/gpu/drm/i915/i915_irq.h
@@ -94,6 +94,7 @@ void intel_runtime_pm_disable_interrupts(struct 
drm_i915_private *dev_priv);
 void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
 bool intel_irqs_enabled(struct drm_i915_private *dev_priv);
 void intel_synchronize_irq(struct drm_i915_private *i915);
+void intel_synchronize_hardirq(struct drm_i915_private *i915);
 
 int intel_get_crtc_scanline(struct intel_crtc *crtc);
 void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
-- 
2.32.0



[PATCH v2 2/2] drm/i915: Drop all references to DRM IRQ midlayer

2021-06-30 Thread Thomas Zimmermann
Remove all references to DRM's IRQ midlayer. i915 uses Linux' interrupt
functions directly.

v2:
* also remove an outdated comment
* move IRQ fix into separate patch
* update Fixes tag (Daniel)

Signed-off-by: Thomas Zimmermann 
Fixes: b318b82455bd ("drm/i915: Nuke drm_driver irq vfuncs")
Cc: Ville Syrjälä 
Cc: Chris Wilson 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: intel-...@lists.freedesktop.org
Cc:  # v5.4+
---
 drivers/gpu/drm/i915/i915_drv.c | 1 -
 drivers/gpu/drm/i915/i915_irq.c | 5 -
 2 files changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 850b499c71c8..73de45472f60 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -42,7 +42,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2203dca19895..1d4c683c9de9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -33,7 +33,6 @@
 #include 
 
 #include 
-#include 
 
 #include "display/intel_de.h"
 #include "display/intel_display_types.h"
@@ -4564,10 +4563,6 @@ void intel_runtime_pm_enable_interrupts(struct 
drm_i915_private *dev_priv)
 
 bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
 {
-   /*
-* We only use drm_irq_uninstall() at unload and VT switch, so
-* this is the only thing we need to check.
-*/
return dev_priv->runtime_pm.irqs_enabled;
 }
 
-- 
2.32.0



Re: [PATCH v4 12/17] drm/uAPI: Add "preferred color format" drm property as setting for userspace

2021-06-30 Thread Pekka Paalanen
On Tue, 29 Jun 2021 13:39:18 +0200
Werner Sembach  wrote:

> Am 29.06.21 um 13:17 schrieb Pekka Paalanen:
> > On Tue, 29 Jun 2021 08:12:54 +
> > Simon Ser  wrote:
> >  
> >> On Tuesday, June 22nd, 2021 at 09:15, Pekka Paalanen  
> >> wrote:
> >>  
> >>> yes, I think this makes sense, even if it is a property that one can't
> >>> tell for sure what it does before hand.
> >>>
> >>> Using a pair of properties, preference and active, to ask for something
> >>> and then check what actually worked is good for reducing the
> >>> combinatorial explosion caused by needing to "atomic TEST_ONLY commit"
> >>> test different KMS configurations. Userspace has a better chance of
> >>> finding a configuration that is possible.
> >>>
> >>> OTOH, this has the problem than in UI one cannot tell the user in
> >>> advance which options are truly possible. Given that KMS properties are
> >>> rarely completely independent, and in this case known to depend on
> >>> several other KMS properties, I think it is good enough to know after
> >>> the fact.
> >>>
> >>> If a driver does not use what userspace prefers, there is no way to
> >>> understand why, or what else to change to make it happen. That problem
> >>> exists anyway, because TEST_ONLY commits do not give useful feedback
> >>> but only a yes/no.
> >> By submitting incremental atomic reqs with TEST_ONLY (i.e. only changing 
> >> one
> >> property at a time), user-space can discover which property makes the 
> >> atomic
> >> commit fail.  
> > That works if the properties are independent of each other. Color
> > range, color format, bpc and more may all be interconnected,
> > allowing only certain combinations to work.
> >
> > If all these properties have "auto" setting too, then it would be
> > possible to probe each property individually, but that still does not
> > tell which combinations are valid.
> >
> > If you probe towards a certain configuration by setting the properties
> > one by one, then depending on the order you pick the properties, you
> > may come to a different conclusion on which property breaks the
> > configuration.  
> 
> My mind crossed another point that must be considered: When plugin in
> a Monitor a list of possible Resolutions+Framerate combinations is
> created for xrandr and other userspace (I guess by atomic checks? but
> I don't know).

Hi,

I would not think so, but I hope to be corrected if I'm wrong.

My belief is that the driver collects a list of modes from EDID, some
standard modes, and maybe some other hardcoded modes, and then
validates each entry against all the known limitations like vertical
and horizontal frequency limits, discarding modes that do not fit.

Not all limitations are known during that phase, which is why KMS
property "link-status" exists. When userspace actually programs a mode
(not a TEST_ONLY commit), the link training may fail. The kernel prunes
the mode from the list and sets the link status property to signal
failure, and sends a hotplug uevent. Userspace needs to re-check the
mode list and try again.

That is a generic escape hatch for when TEST_ONLY commit succeeds, but
in reality the hardware cannot do it, you just cannot know until you
actually try for real. It causes end user visible flicker if it happens
on an already running connector, but since it usually happens when
turning a connector on to begin with, there is no flicker to be seen,
just a small delay in finding a mode that works.

> During this drm
> properties are already considered, which is no problem atm because as
> far as i can tell there is currently no drm property that would make
> a certain Resolutions+Framerate combination unreachable that would be
> possible with everything on default.

I would not expect KMS properties to be considered at all. It would
reject modes that are actually possible if the some KMS properties were
changed. So at least going forward, current KMS property values cannot
factor in.

> However for example forcing YCbCr420 encoding would limit the
> available resolutions (my screen for example only supports YCbCr420
> on 4k@60 and @50Hz and on no other resolution or frequency (native is
> 2560x1440@144Hz).
> 
> So would a "force color format" that does not get resetted on
> repluging/reenabling a monitor break the output, for example, of an
> not updated xrandr, unaware of this new property?

Yes, not because the mode list would be missing the mode, but because
actually setting the mode would fail.

RandR in particular is problematic, because it does not actually
understand any KMS properties, it is merely a relay. So anything
that *uses* RandR protocol or xrandr command would also need to be
patched to understand the new properties.

The kernel automatically resetting *some* properties in *some*
occasions seems really fragile and complicated to me, which is why I'm
a lot more keen to see a "reset everything to sensible defaults"
generic mechanism added to KMS.


Thanks,
pq


pgpL4ow74KRZo.pgp
Description: Open

Re: [PATCH] drm/i915: Force DPCD backlight mode for Samsung 16727 panel

2021-06-30 Thread Greg KH
On Wed, Jun 30, 2021 at 12:29:05PM +0800, Aaron Ma wrote:
> Hi Greg:
> 
> Could this patch get a chance to be applied on stable kernel?
> It only for 5.11- kernel, not for Linus' tree.

What is the git commit id for it in Linus's tree?

And if this is not for Linus's tree, please resubmit it and document the
heck out of why it is not valid for Linus's tree and exactly what stable
trees you want this applied to (hint, 5.11 is long end-of-life and 5.12
only has about 1-2 more weeks left...)

thanks,

greg k-h


Re: [PATCH v9 1/5] drm: Add a sharable drm page-pool implementation

2021-06-30 Thread Christian König

Am 30.06.21 um 03:34 schrieb John Stultz:

This adds a shrinker controlled page pool, extracted
out of the ttm_pool logic, and abstracted out a bit
so it can be used by other non-ttm drivers.

Cc: Daniel Vetter 
Cc: Christian Koenig 
Cc: Sumit Semwal 
Cc: Liam Mark 
Cc: Chris Goldsworthy 
Cc: Laura Abbott 
Cc: Brian Starkey 
Cc: Hridya Valsaraju 
Cc: Suren Baghdasaryan 
Cc: Sandeep Patil 
Cc: Daniel Mentz 
Cc: Ørjan Eide 
Cc: Robin Murphy 
Cc: Ezequiel Garcia 
Cc: Simon Ser 
Cc: James Jones 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz 
---
v8:
* Completely rewritten from scratch, using only the
   ttm_pool logic so it can be dual licensed.
v9:
* Add Kerneldoc comments similar to tmm implementation
   as suggested by ChristianK
* Mark some functions static as suggested by ChristianK
* Fix locking issue ChristianK pointed out
* Add methods to block the shrinker so users can
   make atomic calculations across multiple pools, as
   suggested by ChristianK
* Fix up Kconfig dependency issue as Reported-by:
   kernel test robot 
---
  drivers/gpu/drm/Kconfig |   3 +
  drivers/gpu/drm/Makefile|   2 +
  drivers/gpu/drm/page_pool.c | 297 
  include/drm/page_pool.h |  68 +
  4 files changed, 370 insertions(+)
  create mode 100644 drivers/gpu/drm/page_pool.c
  create mode 100644 include/drm/page_pool.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 3c16bd1afd87..52d9ba92b35e 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -177,6 +177,9 @@ config DRM_DP_CEC
  Note: not all adapters support this feature, and even for those
  that do support this they often do not hook up the CEC pin.
  
+config DRM_PAGE_POOL

+   bool
+
  config DRM_TTM
tristate
depends on DRM && MMU
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 5279db4392df..affa4ca3a08e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -39,6 +39,8 @@ obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
  drm_ttm_helper-y := drm_gem_ttm_helper.o
  obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
  
+drm-$(CONFIG_DRM_PAGE_POOL) += page_pool.o

+
  drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
drm_dsc.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
diff --git a/drivers/gpu/drm/page_pool.c b/drivers/gpu/drm/page_pool.c
new file mode 100644
index ..c07bbe3afc32
--- /dev/null
+++ b/drivers/gpu/drm/page_pool.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Sharable page pool implementation
+ *
+ * Extracted from drivers/gpu/drm/ttm/ttm_pool.c
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ * Copyright 2021 Linaro Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Christian König, John Stultz
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+static unsigned long page_pool_size; /* max size of the pool */
+
+MODULE_PARM_DESC(page_pool_size, "Number of pages in the drm page pool");
+module_param(page_pool_size, ulong, 0644);
+
+static atomic_long_t nr_managed_pages;
+
+static struct mutex shrinker_lock;
+static struct list_head shrinker_list;
+static struct shrinker mm_shrinker;
+
+/**
+ * drm_page_pool_set_max - Sets maximum size of all pools
+ *
+ * Sets the maximum number of pages allows in all pools.
+ * This can only be set once, and the first caller wins.
+ */
+void drm_page_pool_set_max(unsigned long max)
+{
+   if (!page_pool_size)
+   page_pool_size = max;
+}
+
+/**
+ * drm_page_pool_get_max - Maximum size of all pools
+ *
+ * Return the maximum number of pages allows in all pools
+ */
+unsigned long drm_page_pool_get_max(void)
+{
+   return page_pool_size;
+}


Well in general I don't think it is a good idea to have getters/sette

Re: [PATCH 2/2] drm/doc/rfc: i915 new parallel submission uAPI plan

2021-06-30 Thread Martin Peres

On 29/06/2021 22:35, Matthew Brost wrote:

Add entry for i915 new parallel submission uAPI plan.

v2:
  (Daniel Vetter):
   - Expand logical order explaination
   - Add dummy header
   - Only allow N BBs in execbuf IOCTL
   - Configure parallel submission per slot not per gem context
v3:
  (Marcin Ślusarz):
   - Lot's of typos / bad english fixed
  (Tvrtko Ursulin):
   - Consistent pseudo code, clean up wording in descriptions
v4:
  (Daniel Vetter)
   - Drop flags
   - Add kernel doc
   - Reword a few things / fix typos
  (Tvrtko)
   - Reword a few things / fix typos
v5:
  (Checkpatch)
   - Fix typos
  (Docs)
   - Fix warning

Cc: Tvrtko Ursulin 
Cc: Tony Ye 
CC: Carl Zhang 
Cc: Daniel Vetter 
Cc: Jason Ekstrand 
Signed-off-by: Matthew Brost 
Acked-by: Daniel Vetter 
Acked-by: Tony Ye 
---
  Documentation/gpu/rfc/i915_parallel_execbuf.h | 122 ++
  Documentation/gpu/rfc/i915_scheduler.rst  |  59 -
  2 files changed, 180 insertions(+), 1 deletion(-)
  create mode 100644 Documentation/gpu/rfc/i915_parallel_execbuf.h

diff --git a/Documentation/gpu/rfc/i915_parallel_execbuf.h 
b/Documentation/gpu/rfc/i915_parallel_execbuf.h
new file mode 100644
index ..8cbe2c4e0172
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_parallel_execbuf.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#define I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT 2 /* see 
i915_context_engines_parallel_submit */
+
+/**
+ * struct drm_i915_context_engines_parallel_submit - Configure engine for
+ * parallel submission.
+ *
+ * Setup a slot in the context engine map to allow multiple BBs to be submitted
+ * in a single execbuf IOCTL. Those BBs will then be scheduled to run on the 
GPU
+ * in parallel. Multiple hardware contexts are created internally in the i915
+ * run these BBs.


The previous sentence makes little sense.


 Once a slot is configured for N BBs only N BBs can be
+ * submitted in each execbuf IOCTL and this is implicit behavior e.g. The user
+ * doesn't tell the execbuf IOCTL there are N BBs, the execbuf IOCTL knows how
+ * many BBs there are based on the slot's configuration. The N BBs are the last
+ * N buffer objects or first N if I915_EXEC_BATCH_FIRST is set.
+ *
+ * The default placement behavior is to create implicit bonds between each
+ * context if each context maps to more than 1 physical engine (e.g. context is
+ * a virtual engine). Also we only allow contexts of same engine class and 
these
+ * contexts must be in logically contiguous order. Examples of the placement
+ * behavior described below. Lastly, the default is to not allow BBs to
+ * preempted mid BB rather insert coordinated preemption on all hardware
+ * contexts between each set of BBs. Flags may be added in the future to change
+ * both of these default behaviors.
+ *
+ * Returns -EINVAL if hardware context placement configuration is invalid or if
+ * the placement configuration isn't supported on the platform / submission
+ * interface.
+ * Returns -ENODEV if extension isn't supported on the platform / submission
+ * interface.
+ *
+ * .. code-block:: none
+ *
+ * Example 1 pseudo code:
+ * CS[X] = generic engine of same class, logical instance X
+ * INVALID = I915_ENGINE_CLASS_INVALID, I915_ENGINE_CLASS_INVALID_NONE
+ * set_engines(INVALID)
+ * set_parallel(engine_index=0, width=2, num_siblings=1,
+ *  engines=CS[0],CS[1])
+ *
+ * Results in the following valid placement:
+ * CS[0], CS[1]
+ *
+ * Example 2 pseudo code:
+ * CS[X] = generic engine of same class, logical instance X
+ * INVALID = I915_ENGINE_CLASS_INVALID, I915_ENGINE_CLASS_INVALID_NONE
+ * set_engines(INVALID)
+ * set_parallel(engine_index=0, width=2, num_siblings=2,
+ *  engines=CS[0],CS[2],CS[1],CS[3])
+ *
+ * Results in the following valid placements:
+ * CS[0], CS[1]
+ * CS[2], CS[3]
+ *
+ * This can also be thought of as 2 virtual engines described by 2-D array
+ * in the engines the field with bonds placed between each index of the
+ * virtual engines. e.g. CS[0] is bonded to CS[1], CS[2] is bonded to
+ * CS[3].
+ * VE[0] = CS[0], CS[2]
+ * VE[1] = CS[1], CS[3]
+ *
+ * Example 3 pseudo code:
+ * CS[X] = generic engine of same class, logical instance X
+ * INVALID = I915_ENGINE_CLASS_INVALID, I915_ENGINE_CLASS_INVALID_NONE
+ * set_engines(INVALID)
+ * set_parallel(engine_index=0, width=2, num_siblings=2,
+ *  engines=CS[0],CS[1],CS[1],CS[3])
+ *
+ * Results in the following valid and invalid placements:
+ * CS[0], CS[1]
+ * CS[1], CS[3] - Not logical contiguous, return -EINVAL
+ */
+struct drm_i915_context_engines_parallel_submit {
+   /**
+* @base: base user extension.
+*/
+   struct i915_user_extension base;
+
+   /**
+* @engine_index: slot for parallel engine
+*/
+   __u16 engine_in

Re: [PATCH v9 0/5] Generic page pool & deferred freeing for system dmabuf hea

2021-06-30 Thread Christian König




Am 30.06.21 um 03:34 schrieb John Stultz:

After an unfortunately long pause (covid work-schedule burnout),
I wanted to revive and resubmit this series.

As before, the point of this series is trying to add both a page
pool as well as deferred-freeingto the DMA-BUF system heap to
improve allocation performance (so that it can match or beat the
old ION system heaps performance).

The combination of the page pool along with deferred freeing
allows us to offload page-zeroing out of the allocation hot
path. This was done originally with ION and this patch series
allows the DMA-BUF system heap to match ION's system heap
allocation performance in a simple microbenchmark [1] (ION
re-added to the kernel for comparision, running on an x86 vm
image):

./dmabuf-heap-bench -i 0 1 system
Testing dmabuf system vs ion heaptype 0 (flags: 0x1)
-
dmabuf heap: alloc 4096 bytes 5000 times in 79314244 ns  15862 ns/call
ion heap:alloc 4096 bytes 5000 times in 107390769 ns 21478 ns/call
dmabuf heap: alloc 1048576 bytes 5000 times in 259083419 ns  51816 ns/call
ion heap:alloc 1048576 bytes 5000 times in 340497344 ns  68099 ns/call
dmabuf heap: alloc 8388608 bytes 5000 times in 2603105563 ns 520621 ns/call
ion heap:alloc 8388608 bytes 5000 times in 3613592860 ns 722718 ns/call
dmabuf heap: alloc 33554432 bytes 5000 times in 12212492979 ns   2442498 ns/call
ion heap:alloc 33554432 bytes 5000 times in 14584157792 ns   2916831 ns/call


Daniel didn't like earlier attempts to re-use the network
page-pool code to achieve this, and suggested the ttm_pool be
used instead, so this series pulls the page pool functionality
out of the ttm_pool logic and creates a generic page pool
that can be shared.

New in v9:
* Tried to address Christian König's feedback on the page pool
   changes (Kerneldoc, static functions, locking issues, duplicative
   order tracking)
* Fix up Kconfig dependency issue as Reported-by:
   kernel test robot 
* Fix compiler warning Reported-by:
   kernel test robot 

I know Christian had some less specific feedback on the deferred free
work that I'd like to revisit, but I wanted to restart the discussion
with this new series, rather then trying to dregdge up and reply to
a ~4mo old thread.


I was already wondering where this was left :)

The kernel test robot pointed out quite a number of bugs. I suggest to 
fix those first and then take a look at my comments on patch #1.


Regards,
Christian.



Input would be greatly appreciated. Testing as well, as I don't
have any development hardware that utilizes the ttm pool.

Thanks
-john

[1] 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsystem%2Fmemory%2Flibdmabufheap%2F%2B%2Frefs%2Fheads%2Fmaster%2Ftests%2Fdmabuf_heap_bench.c&data=04%7C01%7Cchristian.koenig%40amd.com%7C6d982c8c584d4fb914f208d93b673549%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637606136750178732%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=iNOuK8umbpkC4oYSM%2FaM3Ybx45FUWQsoRxPDjznBw70%3D&reserved=0

Cc: Daniel Vetter 
Cc: Christian Koenig 
Cc: Sumit Semwal 
Cc: Liam Mark 
Cc: Chris Goldsworthy 
Cc: Laura Abbott 
Cc: Brian Starkey 
Cc: Hridya Valsaraju 
Cc: Suren Baghdasaryan 
Cc: Sandeep Patil 
Cc: Daniel Mentz 
Cc: Ørjan Eide 
Cc: Robin Murphy 
Cc: Ezequiel Garcia 
Cc: Simon Ser 
Cc: James Jones 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org

John Stultz (5):
   drm: Add a sharable drm page-pool implementation
   drm: ttm_pool: Rework ttm_pool to use drm_page_pool
   dma-buf: system_heap: Add drm pagepool support to system heap
   dma-buf: heaps: Add deferred-free-helper library code
   dma-buf: system_heap: Add deferred freeing to the system heap

  drivers/dma-buf/heaps/Kconfig|   5 +
  drivers/dma-buf/heaps/Makefile   |   1 +
  drivers/dma-buf/heaps/deferred-free-helper.c | 138 +
  drivers/dma-buf/heaps/deferred-free-helper.h |  55 
  drivers/dma-buf/heaps/system_heap.c  |  46 ++-
  drivers/gpu/drm/Kconfig  |   4 +
  drivers/gpu/drm/Makefile |   2 +
  drivers/gpu/drm/page_pool.c  | 297 +++
  drivers/gpu/drm/ttm/ttm_pool.c   | 167 ++-
  include/drm/page_pool.h  |  68 +
  include/drm/ttm/ttm_pool.h   |  14 +-
  11 files changed, 643 insertions(+), 154 deletions(-)
  create mode 100644 drivers/dma-buf/heaps/deferred-free-helper.c
  create mode 100644 drivers/dma-buf/heaps/deferred-free-helper.h
  create mode 100644 drivers/gpu/drm/page_pool.c
  create mode 100644 include/drm/page_pool.h





Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing

2021-06-30 Thread Claire Chang
On Wed, Jun 30, 2021 at 9:43 AM Nathan Chancellor  wrote:
>
> On Thu, Jun 24, 2021 at 11:55:20PM +0800, Claire Chang wrote:
> > Propagate the swiotlb_force into io_tlb_default_mem->force_bounce and
> > use it to determine whether to bounce the data or not. This will be
> > useful later to allow for different pools.
> >
> > Signed-off-by: Claire Chang 
> > Reviewed-by: Christoph Hellwig 
> > Tested-by: Stefano Stabellini 
> > Tested-by: Will Deacon 
> > Acked-by: Stefano Stabellini 
>
> This patch as commit af452ec1b1a3 ("swiotlb: Use is_swiotlb_force_bounce
> for swiotlb data bouncing") causes my Ryzen 3 4300G system to fail to
> get to an X session consistently (although not every single time),
> presumably due to a crash in the AMDGPU driver that I see in dmesg.
>
> I have attached logs at af452ec1b1a3 and f127c9556a8e and I am happy
> to provide any further information, debug, or test patches as necessary.

Are you using swiotlb=force? or the swiotlb_map is called because of
!dma_capable? 
(https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/kernel/dma/direct.h#n93)

`BUG: unable to handle page fault for address: 003a8290` and
the fact it crashed at `_raw_spin_lock_irqsave` look like the memory
(maybe dev->dma_io_tlb_mem) was corrupted?
The dev->dma_io_tlb_mem should be set here
(https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/pci/probe.c#n2528)
through device_initialize.

I can't tell what happened from the logs, but maybe we could try KASAN
to see if it provides more clue.

Thanks,
Claire

>
> Cheers,
> Nathan


Re: [PATCH v4 12/17] drm/uAPI: Add "preferred color format" drm property as setting for userspace

2021-06-30 Thread Werner Sembach

Am 30.06.21 um 10:41 schrieb Pekka Paalanen:


On Tue, 29 Jun 2021 13:39:18 +0200
Werner Sembach  wrote:


Am 29.06.21 um 13:17 schrieb Pekka Paalanen:

On Tue, 29 Jun 2021 08:12:54 +
Simon Ser  wrote:
  

On Tuesday, June 22nd, 2021 at 09:15, Pekka Paalanen  
wrote:
  

yes, I think this makes sense, even if it is a property that one can't
tell for sure what it does before hand.

Using a pair of properties, preference and active, to ask for something
and then check what actually worked is good for reducing the
combinatorial explosion caused by needing to "atomic TEST_ONLY commit"
test different KMS configurations. Userspace has a better chance of
finding a configuration that is possible.

OTOH, this has the problem than in UI one cannot tell the user in
advance which options are truly possible. Given that KMS properties are
rarely completely independent, and in this case known to depend on
several other KMS properties, I think it is good enough to know after
the fact.

If a driver does not use what userspace prefers, there is no way to
understand why, or what else to change to make it happen. That problem
exists anyway, because TEST_ONLY commits do not give useful feedback
but only a yes/no.

By submitting incremental atomic reqs with TEST_ONLY (i.e. only changing one
property at a time), user-space can discover which property makes the atomic
commit fail.

That works if the properties are independent of each other. Color
range, color format, bpc and more may all be interconnected,
allowing only certain combinations to work.

If all these properties have "auto" setting too, then it would be
possible to probe each property individually, but that still does not
tell which combinations are valid.

If you probe towards a certain configuration by setting the properties
one by one, then depending on the order you pick the properties, you
may come to a different conclusion on which property breaks the
configuration.

My mind crossed another point that must be considered: When plugin in
a Monitor a list of possible Resolutions+Framerate combinations is
created for xrandr and other userspace (I guess by atomic checks? but
I don't know).

Hi,

I would not think so, but I hope to be corrected if I'm wrong.

My belief is that the driver collects a list of modes from EDID, some
standard modes, and maybe some other hardcoded modes, and then
validates each entry against all the known limitations like vertical
and horizontal frequency limits, discarding modes that do not fit.

Not all limitations are known during that phase, which is why KMS
property "link-status" exists. When userspace actually programs a mode
(not a TEST_ONLY commit), the link training may fail. The kernel prunes
the mode from the list and sets the link status property to signal
failure, and sends a hotplug uevent. Userspace needs to re-check the
mode list and try again.

That is a generic escape hatch for when TEST_ONLY commit succeeds, but
in reality the hardware cannot do it, you just cannot know until you
actually try for real. It causes end user visible flicker if it happens
on an already running connector, but since it usually happens when
turning a connector on to begin with, there is no flicker to be seen,
just a small delay in finding a mode that works.


During this drm
properties are already considered, which is no problem atm because as
far as i can tell there is currently no drm property that would make
a certain Resolutions+Framerate combination unreachable that would be
possible with everything on default.

I would not expect KMS properties to be considered at all. It would
reject modes that are actually possible if the some KMS properties were
changed. So at least going forward, current KMS property values cannot
factor in.


At least the debugfs variable "force_yuv420_output" did change the 
available modes here: 
https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c#L5165 
before my patch 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=68eb3ae3c63708f823aeeb63bb15197c727bd9bf


Forcing a color format via a DRM property in this function would 
reintroduce the problem.


And I think i915 driver works similar in this regard.




However for example forcing YCbCr420 encoding would limit the
available resolutions (my screen for example only supports YCbCr420
on 4k@60 and @50Hz and on no other resolution or frequency (native is
2560x1440@144Hz).

So would a "force color format" that does not get resetted on
repluging/reenabling a monitor break the output, for example, of an
not updated xrandr, unaware of this new property?

Yes, not because the mode list would be missing the mode, but because
actually setting the mode would fail.
Well, like described above, I think the mode would actually be missing, 
which is also an unexpected behavior from a user perspective.


RandR in particular is problematic, because it does not actually
understand any KMS properties, it is

[RESEND][PATCH] drm/i915: Force DPCD backlight mode for Samsung 16727 panel

2021-06-30 Thread Aaron Ma
Another Samsung OLED panel needs DPCD to get control of backlight.
Kernel 5.12+ support the backlight via:
commit: <4a8d79901d5b> ("drm/i915/dp: Enable Intel's HDR backlight interface 
(only SDR for now)")
Only make backlight work on lower versions of kernel.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3474
Cc: sta...@vger.kernel.org # 5.11-
Signed-off-by: Aaron Ma 
---
 drivers/gpu/drm/drm_dp_helper.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 5bd0934004e3..7b91d8a76cd6 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1960,6 +1960,7 @@ static const struct edid_quirk edid_quirk_list[] = {
{ MFG(0x4d, 0x10), PROD_ID(0xe6, 0x14), 
BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
{ MFG(0x4c, 0x83), PROD_ID(0x47, 0x41), 
BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
{ MFG(0x09, 0xe5), PROD_ID(0xde, 0x08), 
BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
+   { MFG(0x4c, 0x83), PROD_ID(0x57, 0x41), 
BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
 };
 
 #undef MFG
-- 
2.32.0



Re: [PATCH v4 03/17] drm/uAPI: Add "active bpc" as feedback channel for "max bpc" drm property

2021-06-30 Thread Werner Sembach



Am 30.06.21 um 10:21 schrieb Pekka Paalanen:

On Tue, 29 Jun 2021 13:02:05 +0200
Werner Sembach  wrote:


Am 28.06.21 um 19:03 schrieb Werner Sembach:

Am 18.06.21 um 11:11 schrieb Werner Sembach:

Add a new general drm property "active bpc" which can be used by graphic
drivers to report the applied bit depth per pixel back to userspace.

While "max bpc" can be used to change the color depth, there was no way to
check which one actually got used. While in theory the driver chooses the
best/highest color depth within the max bpc setting a user might not be
fully aware what his hardware is or isn't capable off. This is meant as a
quick way to double check the setup.

In the future, automatic color calibration for screens might also depend on
this information being available.

Signed-off-by: Werner Sembach 
---
  drivers/gpu/drm/drm_connector.c | 51 +
  include/drm/drm_connector.h |  8 ++
  2 files changed, 59 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index da39e7ff6965..943f6b61053b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1197,6 +1197,14 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
= {
   *drm_connector_attach_max_bpc_property() to create and attach the
   *property to the connector during initialization.
   *
+ * active bpc:
+ * This read-only range property tells userspace the pixel color bit depth
+ * actually used by the hardware display engine on "the cable" on a
+ * connector. The chosen value depends on hardware capabilities, both
+ * display engine and connected monitor, and the "max bpc" property.
+ * Drivers shall use drm_connector_attach_active_bpc_property() to install
+ * this property.
+ *

Regarding "on the cable" and dithering: As far as I can tell, what the 
dithering option does, is setting a hardware
register here:

- 
https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4534

- 
https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4571

So dithering seems to be calculated by fixed purpose hardware/firmware outside 
of the driver?

The Intel driver does not seem to set a target bpc/bpp for this hardware so I 
guess it defaults to 6 or 8 bpc?

Never mind it does. This switch-case does affect the dithering output:
https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4537

Hi,

I obviously do not know the intel driver or hardware at all, but
to me that just looks like translating from bits per pixel to bits per
channel in RGB mapping?
No, if i understand the documentation correctly: Writing bit depth here 
with dithering enabled sets the dithering target bpc.



As found in this documentation p.548:
https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-lkf-vol02c-commandreference-registers-part2.pdf

So max bpc and active bpc are affecting/affected by the bpc after dithering.

By definition, if the cable carries N bpc, then dithering does not
change that. The cable still carries N bpc, but due to spatial or
temporal dithering, the *observed* color resolution may or may not be
higher than the cable bpc.
Yes, and max bpc and active bpc tell the cable bpc ist not the 
*observed* bpc.


Of course, if the cable bpc is 8, and dithering targets 6 bpc, then 2
LSB on the cable are always zero, right?
I would assume that in this case only 6 bpc are actually send? Isn't the 
whole thing of dithering that you can't send, for example, 8 bpc?


Maybe one would want to do that if the monitor has a 6 bit panel and it
simply ignored the 2 LSB, and the cable cannot go down to 6 bpc.


Is there dithering actually doing this? aka is my assumption above wrong?

AMD code that confused me before, is hinting that you might be right: 
https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c#L826


there is a set_clamp depth and a separate DCP_SPATIAL_DITHER_DEPTH_30BPP



So, what does "max bpc" mean right now?

It seems like dither on/off is insufficient information, one would also
need to control the dithering target bpc. I suppose the driver has a
policy on how it chooses the target bpc, but what is that policy? Is
the dither target bpc the cable bpc or the sink bpc?

Needless to say, I'm quite confused.


... We need someone who knows what dithering on intel and amd gpu 
actually means.


But I don't want this to become a blocker for this patchset, because if 
there is no dithering, which seems to be the norm, the active bpc 
property is already really usefull as it is. So add a note to the docs 
that the value might be invalid when dithering is active for now?





Thanks,
pq


Similar things happen on amd. Here the output dither depth seems to be written 
to a fixed value however:

- 
https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/

[PATCH v3 0/2] drm/i915: IRQ fixes

2021-06-30 Thread Thomas Zimmermann
Fix a bug in the usage of IRQs and cleanup references to the DRM
IRQ midlayer.

Preferably this patchset would be merged through drm-misc-next.

v3:
* also use intel_synchronize_hardirq() from other callsite
v2:
* split patch
* also fix comment
* add intel_synchronize_hardirq() (Ville)
* update Fixes tag (Daniel)

Thomas Zimmermann (2):
  drm/i915: Use the correct IRQ during resume
  drm/i915: Drop all references to DRM IRQ midlayer

 drivers/gpu/drm/i915/gt/intel_engine_cs.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_ring_submission.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.c |  1 -
 drivers/gpu/drm/i915/i915_irq.c | 10 +-
 drivers/gpu/drm/i915/i915_irq.h |  1 +
 5 files changed, 8 insertions(+), 8 deletions(-)


base-commit: 67f5a18128770817e4218a9e496d2bf5047c51e8
--
2.32.0



[PATCH v3 1/2] drm/i915: Use the correct IRQ during resume

2021-06-30 Thread Thomas Zimmermann
The code in xcs_resume() probably didn't work as intended. It uses
struct drm_device.irq, which is allocated to 0, but never initialized
by i915 to the device's interrupt number.

v3:
* also use intel_synchronize_hardirq() at another callsite
v2:
* wrap irq code in intel_synchronize_hardirq() (Ville)

Signed-off-by: Thomas Zimmermann 
Fixes: 536f77b1caa0 ("drm/i915/gt: Call stop_ring() from ring resume, again")
Cc: Chris Wilson 
Cc: Mika Kuoppala 
Cc: Daniel Vetter 
Cc: Rodrigo Vivi 
Cc: Joonas Lahtinen 
Cc: Maarten Lankhorst 
Cc: Lucas De Marchi 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 2 +-
 drivers/gpu/drm/i915/gt/intel_ring_submission.c | 2 +-
 drivers/gpu/drm/i915/i915_irq.c | 5 +
 drivers/gpu/drm/i915/i915_irq.h | 1 +
 4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 88694822716a..5ca3d1664335 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1229,7 +1229,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
return true;
 
/* Waiting to drain ELSP? */
-   synchronize_hardirq(to_pci_dev(engine->i915->drm.dev)->irq);
+   intel_synchronize_hardirq(engine->i915);
intel_engine_flush_submission(engine);
 
/* ELSP is empty, but there are ready requests? E.g. after reset */
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 5d42a12ef3d6..1b5a22a83db6 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -185,7 +185,7 @@ static int xcs_resume(struct intel_engine_cs *engine)
 ring->head, ring->tail);
 
/* Double check the ring is empty & disabled before we resume */
-   synchronize_hardirq(engine->i915->drm.irq);
+   intel_synchronize_hardirq(engine->i915);
if (!stop_ring(engine))
goto err;
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7d0ce8b9f8ed..2203dca19895 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4575,3 +4575,8 @@ void intel_synchronize_irq(struct drm_i915_private *i915)
 {
synchronize_irq(to_pci_dev(i915->drm.dev)->irq);
 }
+
+void intel_synchronize_hardirq(struct drm_i915_private *i915)
+{
+   synchronize_hardirq(to_pci_dev(i915->drm.dev)->irq);
+}
diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h
index db34d5dbe402..e43b6734f21b 100644
--- a/drivers/gpu/drm/i915/i915_irq.h
+++ b/drivers/gpu/drm/i915/i915_irq.h
@@ -94,6 +94,7 @@ void intel_runtime_pm_disable_interrupts(struct 
drm_i915_private *dev_priv);
 void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
 bool intel_irqs_enabled(struct drm_i915_private *dev_priv);
 void intel_synchronize_irq(struct drm_i915_private *i915);
+void intel_synchronize_hardirq(struct drm_i915_private *i915);
 
 int intel_get_crtc_scanline(struct intel_crtc *crtc);
 void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
-- 
2.32.0



[PATCH v3 2/2] drm/i915: Drop all references to DRM IRQ midlayer

2021-06-30 Thread Thomas Zimmermann
Remove all references to DRM's IRQ midlayer. i915 uses Linux' interrupt
functions directly.

v2:
* also remove an outdated comment
* move IRQ fix into separate patch
* update Fixes tag (Daniel)

Signed-off-by: Thomas Zimmermann 
Fixes: b318b82455bd ("drm/i915: Nuke drm_driver irq vfuncs")
Cc: Ville Syrjälä 
Cc: Chris Wilson 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: intel-...@lists.freedesktop.org
Cc:  # v5.4+
---
 drivers/gpu/drm/i915/i915_drv.c | 1 -
 drivers/gpu/drm/i915/i915_irq.c | 5 -
 2 files changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 850b499c71c8..73de45472f60 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -42,7 +42,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2203dca19895..1d4c683c9de9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -33,7 +33,6 @@
 #include 
 
 #include 
-#include 
 
 #include "display/intel_de.h"
 #include "display/intel_display_types.h"
@@ -4564,10 +4563,6 @@ void intel_runtime_pm_enable_interrupts(struct 
drm_i915_private *dev_priv)
 
 bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
 {
-   /*
-* We only use drm_irq_uninstall() at unload and VT switch, so
-* this is the only thing we need to check.
-*/
return dev_priv->runtime_pm.irqs_enabled;
 }
 
-- 
2.32.0



Re: [PATCH v3] drm/radeon: Fix NULL dereference when updating memory stats

2021-06-30 Thread Christian König

Am 24.06.21 um 06:51 schrieb Mikel Rychliski:

radeon_ttm_bo_destroy() is attempting to access the resource object to
update memory counters. However, the resource object is already freed when
ttm calls this function via the destroy callback. This causes an oops when
a bo is freed:

BUG: kernel NULL pointer dereference, address: 0010
RIP: 0010:radeon_ttm_bo_destroy+0x2c/0x100 [radeon]
Call Trace:
 radeon_bo_unref+0x1a/0x30 [radeon]
 radeon_gem_object_free+0x33/0x50 [radeon]
 drm_gem_object_release_handle+0x69/0x70 [drm]
 drm_gem_handle_delete+0x62/0xa0 [drm]
 ? drm_mode_destroy_dumb+0x40/0x40 [drm]
 drm_ioctl_kernel+0xb2/0xf0 [drm]
 drm_ioctl+0x30a/0x3c0 [drm]
 ? drm_mode_destroy_dumb+0x40/0x40 [drm]
 radeon_drm_ioctl+0x49/0x80 [radeon]
 __x64_sys_ioctl+0x8e/0xd0

Avoid the issue by updating the counters in the delete_mem_notify callback
instead. Also, fix memory statistic updating in radeon_bo_move() to
identify the source type correctly. The source type needs to be saved
before the move, because the moved from object may be altered by the move.

Fixes: bfa3357ef9ab ("drm/ttm: allocate resource object instead of embedding it 
v2")
Signed-off-by: Mikel Rychliski 


So, back from vacation. I've reviewed and pushed the patch to drm-misc-next.

Thanks for the help,
Christian.


---
  drivers/gpu/drm/radeon/radeon_object.c | 29 -
  drivers/gpu/drm/radeon/radeon_object.h |  2 +-
  drivers/gpu/drm/radeon/radeon_ttm.c| 13 ++---
  3 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_object.c 
b/drivers/gpu/drm/radeon/radeon_object.c
index bfaaa3c969a3..56ede9d63b12 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -49,23 +49,23 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo 
*bo);
   * function are calling it.
   */
  
-static void radeon_update_memory_usage(struct radeon_bo *bo,

-  unsigned mem_type, int sign)
+static void radeon_update_memory_usage(struct ttm_buffer_object *bo,
+  unsigned int mem_type, int sign)
  {
-   struct radeon_device *rdev = bo->rdev;
+   struct radeon_device *rdev = radeon_get_rdev(bo->bdev);
  
  	switch (mem_type) {

case TTM_PL_TT:
if (sign > 0)
-   atomic64_add(bo->tbo.base.size, &rdev->gtt_usage);
+   atomic64_add(bo->base.size, &rdev->gtt_usage);
else
-   atomic64_sub(bo->tbo.base.size, &rdev->gtt_usage);
+   atomic64_sub(bo->base.size, &rdev->gtt_usage);
break;
case TTM_PL_VRAM:
if (sign > 0)
-   atomic64_add(bo->tbo.base.size, &rdev->vram_usage);
+   atomic64_add(bo->base.size, &rdev->vram_usage);
else
-   atomic64_sub(bo->tbo.base.size, &rdev->vram_usage);
+   atomic64_sub(bo->base.size, &rdev->vram_usage);
break;
}
  }
@@ -76,8 +76,6 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object 
*tbo)
  
  	bo = container_of(tbo, struct radeon_bo, tbo);
  
-	radeon_update_memory_usage(bo, bo->tbo.resource->mem_type, -1);

-
mutex_lock(&bo->rdev->gem.mutex);
list_del_init(&bo->list);
mutex_unlock(&bo->rdev->gem.mutex);
@@ -727,24 +725,21 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool 
has_moved,
  }
  
  void radeon_bo_move_notify(struct ttm_buffer_object *bo,

-  bool evict,
+  unsigned int old_type,
   struct ttm_resource *new_mem)
  {
struct radeon_bo *rbo;
  
+	radeon_update_memory_usage(bo, old_type, -1);

+   if (new_mem)
+   radeon_update_memory_usage(bo, new_mem->mem_type, 1);
+
if (!radeon_ttm_bo_is_radeon_bo(bo))
return;
  
  	rbo = container_of(bo, struct radeon_bo, tbo);

radeon_bo_check_tiling(rbo, 0, 1);
radeon_vm_bo_invalidate(rbo->rdev, rbo);
-
-   /* update statistics */
-   if (!new_mem)
-   return;
-
-   radeon_update_memory_usage(rbo, bo->resource->mem_type, -1);
-   radeon_update_memory_usage(rbo, new_mem->mem_type, 1);
  }
  
  vm_fault_t radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)

diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index 1739c6a142cd..1afc7992ef91 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -161,7 +161,7 @@ extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
  extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
bool force_drop);
  extern void radeon_bo_move_no

Re: [PULL] drm-intel-next-fixes

2021-06-30 Thread Jani Nikula
On Tue, 29 Jun 2021, Rodrigo Vivi  wrote:
> Hi Dave and Daniel,
>
> Here goes drm-intel-next-fixes-2021-06-29:
>
> The biggest fix is the restoration of mmap ioctl for gen12 integrated parts
> which lack was breaking ADL-P with media stack.
> Besides that a small selftest fix and a theoretical overflow on
> i915->pipe_to_crtc_mapping.

My last fixes pull for v5.13 fell between the cracks [1]. There was one
stable worthy fix, but since it was still in drm-intel-fixes when you
ran dim cherry-pick-next-fixes, it was skipped for drm-intel-next-fixes.

I've now dropped the commit and pushed v5.13 to drm-intel-fixes, as
we're past that point. Subsequent dim cherry-pick-next-fixes should pick
it up now.

Please do another next fixes pull request with that. (It's okay to pull
this one already though, doesn't make a difference.)


BR,
Jani.


[1] https://lore.kernel.org/r/87czsbu15r@intel.com



>
> Thanks,
> Rodrigo.
>
> The following changes since commit 1bd8a7dc28c1c410f1ceefae1f2a97c06d1a67c2:
>
>   Merge tag 'exynos-drm-next-for-v5.14' of 
> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into 
> drm-next (2021-06-11 14:19:12 +1000)
>
> are available in the Git repository at:
>
>   git://anongit.freedesktop.org/drm/drm-intel 
> tags/drm-intel-next-fixes-2021-06-29
>
> for you to fetch changes up to c90c4c6574f3feaf2203b5671db1907a1e15c653:
>
>   drm/i915: Reinstate the mmap ioctl for some platforms (2021-06-28 07:43:56 
> -0400)
>
> 
> The biggest fix is the restoration of mmap ioctl for gen12 integrated parts
> which lack was breaking ADL-P with media stack.
> Besides that a small selftest fix and a theoretical overflow on
> i915->pipe_to_crtc_mapping.
>
> 
> Chris Wilson (1):
>   drm/i915/selftests: Reorder tasklet_disable vs local_bh_disable
>
> Jani Nikula (1):
>   drm/i915/dsc: abstract helpers to get bigjoiner primary/secondary crtc
>
> Thomas Hellström (1):
>   drm/i915: Reinstate the mmap ioctl for some platforms
>
>  drivers/gpu/drm/i915/display/intel_display.c   |  7 ++-
>  drivers/gpu/drm/i915/display/intel_display_types.h |  8 
>  drivers/gpu/drm/i915/display/intel_vdsc.c  | 40 +++-
>  drivers/gpu/drm/i915/display/intel_vdsc.h  |  1 +
>  drivers/gpu/drm/i915/gem/i915_gem_mman.c   |  7 +--
>  drivers/gpu/drm/i915/gt/selftest_execlists.c   | 55 
> +-
>  6 files changed, 76 insertions(+), 42 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [PATCH v3 2/2] drm/i915: Drop all references to DRM IRQ midlayer

2021-06-30 Thread Greg KH
On Wed, Jun 30, 2021 at 11:52:28AM +0200, Thomas Zimmermann wrote:
> Remove all references to DRM's IRQ midlayer. i915 uses Linux' interrupt
> functions directly.
> 
> v2:
>   * also remove an outdated comment
>   * move IRQ fix into separate patch
>   * update Fixes tag (Daniel)
> 
> Signed-off-by: Thomas Zimmermann 
> Fixes: b318b82455bd ("drm/i915: Nuke drm_driver irq vfuncs")
> Cc: Ville Syrjälä 
> Cc: Chris Wilson 
> Cc: Jani Nikula 
> Cc: Joonas Lahtinen 
> Cc: Rodrigo Vivi 
> Cc: intel-...@lists.freedesktop.org
> Cc:  # v5.4+
> ---
>  drivers/gpu/drm/i915/i915_drv.c | 1 -
>  drivers/gpu/drm/i915/i915_irq.c | 5 -
>  2 files changed, 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 850b499c71c8..73de45472f60 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -42,7 +42,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 2203dca19895..1d4c683c9de9 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -33,7 +33,6 @@
>  #include 
>  
>  #include 
> -#include 
>  
>  #include "display/intel_de.h"
>  #include "display/intel_display_types.h"
> @@ -4564,10 +4563,6 @@ void intel_runtime_pm_enable_interrupts(struct 
> drm_i915_private *dev_priv)
>  
>  bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
>  {
> - /*
> -  * We only use drm_irq_uninstall() at unload and VT switch, so
> -  * this is the only thing we need to check.
> -  */
>   return dev_priv->runtime_pm.irqs_enabled;
>  }
>  
> -- 
> 2.32.0
> 

How is this a stable-kernel-related fix?

thanks,

greg k-h


Re: [PATCH 2/3] iommu/io-pgtable-arm: Add IOMMU_LLC page protection flag

2021-06-30 Thread Sai Prakash Ranjan

Hi Will,

On 2021-03-25 23:03, Will Deacon wrote:

On Tue, Mar 09, 2021 at 12:10:44PM +0530, Sai Prakash Ranjan wrote:

On 2021-02-05 17:38, Sai Prakash Ranjan wrote:
> On 2021-02-04 03:16, Will Deacon wrote:
> > On Tue, Feb 02, 2021 at 11:56:27AM +0530, Sai Prakash Ranjan wrote:
> > > On 2021-02-01 23:50, Jordan Crouse wrote:
> > > > On Mon, Feb 01, 2021 at 08:20:44AM -0800, Rob Clark wrote:
> > > > > On Mon, Feb 1, 2021 at 3:16 AM Will Deacon  wrote:
> > > > > > On Fri, Jan 29, 2021 at 03:12:59PM +0530, Sai Prakash Ranjan wrote:
> > > > > > > On 2021-01-29 14:35, Will Deacon wrote:
> > > > > > > > On Mon, Jan 11, 2021 at 07:45:04PM +0530, Sai Prakash Ranjan 
wrote:
> > > > > > > > > +#define IOMMU_LLC(1 << 6)
> > > > > > > >
> > > > > > > > On reflection, I'm a bit worried about exposing this because I 
think it
> > > > > > > > will
> > > > > > > > introduce a mismatched virtual alias with the CPU (we don't 
even have a
> > > > > > > > MAIR
> > > > > > > > set up for this memory type). Now, we also have that issue for 
the PTW,
> > > > > > > > but
> > > > > > > > since we always use cache maintenance (i.e. the streaming API) 
for
> > > > > > > > publishing the page-tables to a non-coheren walker, it works 
out.
> > > > > > > > However,
> > > > > > > > if somebody expects IOMMU_LLC to be coherent with a DMA API 
coherent
> > > > > > > > allocation, then they're potentially in for a nasty surprise 
due to the
> > > > > > > > mismatched outer-cacheability attributes.
> > > > > > > >
> > > > > > >
> > > > > > > Can't we add the syscached memory type similar to what is done on 
android?
> > > > > >
> > > > > > Maybe. How does the GPU driver map these things on the CPU side?
> > > > >
> > > > > Currently we use writecombine mappings for everything, although there
> > > > > are some cases that we'd like to use cached (but have not merged
> > > > > patches that would give userspace a way to flush/invalidate)
> > > > >
> > > >
> > > > LLC/system cache doesn't have a relationship with the CPU cache.  Its
> > > > just a
> > > > little accelerator that sits on the connection from the GPU to DDR and
> > > > caches
> > > > accesses. The hint that Sai is suggesting is used to mark the buffers as
> > > > 'no-write-allocate' to prevent GPU write operations from being cached in
> > > > the LLC
> > > > which a) isn't interesting and b) takes up cache space for read
> > > > operations.
> > > >
> > > > Its easiest to think of the LLC as a bonus accelerator that has no cost
> > > > for
> > > > us to use outside of the unfortunate per buffer hint.
> > > >
> > > > We do have to worry about the CPU cache w.r.t I/O coherency (which is a
> > > > different hint) and in that case we have all of concerns that Will
> > > > identified.
> > > >
> > >
> > > For mismatched outer cacheability attributes which Will
> > > mentioned, I was
> > > referring to [1] in android kernel.
> >
> > I've lost track of the conversation here :/
> >
> > When the GPU has a buffer mapped with IOMMU_LLC, is the buffer also
> > mapped
> > into the CPU and with what attributes? Rob said "writecombine for
> > everything" -- does that mean ioremap_wc() / MEMREMAP_WC?
> >
>
> Rob answered this.
>
> > Finally, we need to be careful when we use the word "hint" as
> > "allocation
> > hint" has a specific meaning in the architecture, and if we only
> > mismatch on
> > those then we're actually ok. But I think IOMMU_LLC is more than
> > just a
> > hint, since it actually drives eviction policy (i.e. it enables
> > writeback).
> >
> > Sorry for the pedantry, but I just want to make sure we're all talking
> > about the same things!
> >
>
> Sorry for the confusion which probably was caused by my mentioning of
> android, NWA(no write allocate) is an allocation hint which we can
> ignore
> for now as it is not introduced yet in upstream.
>

Any chance of taking this forward? We do not want to miss out on small 
fps

gain when the product gets released.


Do we have a solution to the mismatched virtual alias?



Sorry for the long delay on this thread.

For mismatched virtual alias question, wasn't this already discussed in 
stretch
when initial support for system cache [1] (which was reverted by you) 
was added?


Excerpt from there,

"As seen in downstream kernels there are few non-coherent devices which
would not want to allocate in system cache, and therefore would want
Inner/Outer non-cached memory. So, we may want to either override the
attributes per-device, or as you suggested we may want to introduce
another memory type 'sys-cached' that can be added with its separate
infra."

As for DMA API usage, we do not have any upstream users (video will be
one if they decide to upstream that).

[1] 
https://patchwork.kernel.org/project/linux-arm-msm/patch/20180615105329.26800-1-vivek.gau...@codeaurora.org/


Thanks,
Sai

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
member

of Code Aurora Forum, hosted by The Linux Foundation


Re: [RFC PATCH 2/9] drm: bridge: Add Samsung SEC MIPI DSIM bridge driver

2021-06-30 Thread Jagan Teki
Hi Frieder,

Thanks for sharing the details.

On Mon, Jun 28, 2021 at 1:49 PM Frieder Schrempf
 wrote:
>
> Hi Jagan,
>
> On 24.06.21 10:30, Krzysztof Kozlowski wrote:
> > On 24/06/2021 04:48, Fabio Estevam wrote:
> >> Hi Jagan/Laurent,
> >>
> >> On Wed, Jun 23, 2021 at 7:23 PM Laurent Pinchart
> >>  wrote:
> >>
> >>> Looking at the register set, it seems to match the Exynos 5433,
> >>> supported by drivers/gpu/drm/exynos/exynos_drm_dsi.c. Can we leverage
> >>> that driver instead of adding a new one for the same IP core ?
> >>
> >> Yes. there was an attempt from Michael in this direction:
> >> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.kernel.org%2Fproject%2Fdri-devel%2Fcover%2F20200911135413.3654800-1-m.tretter%40pengutronix.de%2F&data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C52db05459ef0462d5a9b08d936eab1ba%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637601203901391193%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=LTYk9kpUeB9bgfRITQT6wIij3XTOIk37AHXbzQ2UI4Y%3D&reserved=0
> >
> > That's the proper direction (maybe as Marek suggested - sharing common
> > code like for Analogix DP), not duplicating a driver.
> >
>
> Just to make sure that you are aware of the previous patches and discussions 
> here are some additional pointers:
>
> * i.MX8MM glue code from Marek (+ Cc): [1]
> * DPHY driver from Marek: [2]
> * General discussion about driver implementation: [3]
> * Daniel's (+ Cc) suggested direction to move forward: [4]

It Looks like Daniel's suggestion is to have a common bridge driver
without sharing a code between platforms. It makes sense and clean but
the key issues lie on the exynos side, the exynos drm drives require
potential changes and tests, which indeed are hard but possible -
IMHO. However there is another issue with component_ops the i.MX8M
side MXSFB doesn't use any component_ops but the exynos are fully
component aware.

>
> It looks like you already did a fork of the Exynos driver, so your approach 
> might be generally in line with what Daniel suggested.

I did use PMS computation from exynos and reference driver from imx8
tree. Last 2 days I worked on exynos_drm_dsi.c (with some additions)
and converted a bridge driver and it worked on my i.MX8MM platform.

Right now, I'm checking the possible implementations and will come
back to my approach for further comments.

Jagan.


Re: [PATCH v5 3/3] drm: protect drm_master pointers in drm_lease.c

2021-06-30 Thread Desmond Cheong Zhi Xi

On 30/6/21 4:02 pm, Daniel Vetter wrote:

On Wed, Jun 30, 2021 at 9:18 AM Desmond Cheong Zhi Xi
 wrote:


On 30/6/21 12:07 am, Daniel Vetter wrote:

On Tue, Jun 29, 2021 at 11:37:06AM +0800, Desmond Cheong Zhi Xi wrote:

Currently, direct copies of drm_file->master pointers should be
protected by drm_device.master_mutex when being dereferenced. This is
because drm_file->master is not invariant for the lifetime of
drm_file. If drm_file is not the creator of master, then
drm_file->is_master is false, and a call to drm_setmaster_ioctl will
invoke drm_new_set_master, which then allocates a new master for
drm_file and puts the old master.

Thus, without holding drm_device.master_mutex, the old value of
drm_file->master could be freed while it is being used by another
concurrent process.

In drm_lease.c, there are multiple instances where drm_file->master is
accessed and dereferenced while drm_device.master_mutex is not
held. This makes drm_lease.c vulnerable to use-after-free bugs.

We address this issue in 3 ways:

1. Clarify in the kerneldoc that drm_file->master is protected by
drm_device.master_mutex.

2. Add a new drm_file_get_master() function that calls drm_master_get
on drm_file->master while holding on to drm_device.master_mutex. Since
drm_master_get increments the reference count of master, this
prevents master from being freed until we unreference it with
drm_master_put.

3. In each case where drm_file->master is directly accessed and
eventually dereferenced in drm_lease.c, we wrap the access in a call
to the new drm_file_get_master function, then unreference the master
pointer once we are done using it.

Reported-by: Daniel Vetter 
Signed-off-by: Desmond Cheong Zhi Xi 


Series looks very nice, let's see what intel-gfx-ci says. You should get a
mail, but results are also here:

https://patchwork.freedesktop.org/series/91969/#rev2

One tiny comment below.


---
   drivers/gpu/drm/drm_auth.c  | 25 
   drivers/gpu/drm/drm_lease.c | 77 +++--
   include/drm/drm_auth.h  |  1 +
   include/drm/drm_file.h  | 15 ++--
   4 files changed, 95 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index ab1863c5a5a0..c36a0b72be26 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -384,6 +384,31 @@ struct drm_master *drm_master_get(struct drm_master 
*master)
   }
   EXPORT_SYMBOL(drm_master_get);

+/**
+ * drm_file_get_master - reference &drm_file.master of @file_priv
+ * @file_priv: DRM file private
+ *
+ * Increments the reference count of @file_priv's &drm_file.master and returns
+ * the &drm_file.master. If @file_priv has no &drm_file.master, returns NULL.
+ *
+ * Master pointers returned from this function should be unreferenced using
+ * drm_master_put().
+ */
+struct drm_master *drm_file_get_master(struct drm_file *file_priv)
+{
+struct drm_master *master = NULL;
+
+mutex_lock(&file_priv->minor->dev->master_mutex);
+if (!file_priv->master)
+goto unlock;
+master = drm_master_get(file_priv->master);
+
+unlock:
+mutex_unlock(&file_priv->minor->dev->master_mutex);
+return master;
+}
+EXPORT_SYMBOL(drm_file_get_master);
+
   static void drm_master_destroy(struct kref *kref)
   {
  struct drm_master *master = container_of(kref, struct drm_master, 
refcount);
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 00fb433bcef1..cdcc87fa9685 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -106,10 +106,19 @@ static bool _drm_has_leased(struct drm_master *master, 
int id)
*/
   bool _drm_lease_held(struct drm_file *file_priv, int id)
   {
-if (!file_priv || !file_priv->master)
+bool ret;
+struct drm_master *master;
+
+if (!file_priv)
  return true;

-return _drm_lease_held_master(file_priv->master, id);
+master = drm_file_get_master(file_priv);
+if (master == NULL)
+return true;
+ret = _drm_lease_held_master(master, id);
+drm_master_put(&master);
+
+return ret;
   }

   /**
@@ -128,13 +137,20 @@ bool drm_lease_held(struct drm_file *file_priv, int id)
  struct drm_master *master;
  bool ret;

-if (!file_priv || !file_priv->master || !file_priv->master->lessor)
+if (!file_priv)
  return true;

-master = file_priv->master;
+master = drm_file_get_master(file_priv);
+if (master == NULL)
+return true;
+if (!master->lessor) {
+drm_master_put(&master);
+return true;
+}
  mutex_lock(&master->dev->mode_config.idr_mutex);
  ret = _drm_lease_held_master(master, id);
  mutex_unlock(&master->dev->mode_config.idr_mutex);
+drm_master_put(&master);
  return ret;
   }

@@ -154,10 +170,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file 
*file_priv, uint32_t crtcs_in)
  int count_in, count_out;
  uint32_t crtcs_out = 0;

-if (!file_priv 

Re: [PATCH v3 1/2] drm/i915: Use the correct IRQ during resume

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 11:52:27AM +0200, Thomas Zimmermann wrote:
> The code in xcs_resume() probably didn't work as intended. It uses
> struct drm_device.irq, which is allocated to 0, but never initialized
> by i915 to the device's interrupt number.
> 
> v3:
>   * also use intel_synchronize_hardirq() at another callsite
> v2:
>   * wrap irq code in intel_synchronize_hardirq() (Ville)
> 
> Signed-off-by: Thomas Zimmermann 
> Fixes: 536f77b1caa0 ("drm/i915/gt: Call stop_ring() from ring resume, again")
> Cc: Chris Wilson 
> Cc: Mika Kuoppala 
> Cc: Daniel Vetter 
> Cc: Rodrigo Vivi 
> Cc: Joonas Lahtinen 
> Cc: Maarten Lankhorst 
> Cc: Lucas De Marchi 
> ---
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 2 +-
>  drivers/gpu/drm/i915/gt/intel_ring_submission.c | 2 +-
>  drivers/gpu/drm/i915/i915_irq.c | 5 +
>  drivers/gpu/drm/i915/i915_irq.h | 1 +
>  4 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index 88694822716a..5ca3d1664335 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -1229,7 +1229,7 @@ bool intel_engine_is_idle(struct intel_engine_cs 
> *engine)
>   return true;
>  
>   /* Waiting to drain ELSP? */
> - synchronize_hardirq(to_pci_dev(engine->i915->drm.dev)->irq);
> + intel_synchronize_hardirq(engine->i915);
>   intel_engine_flush_submission(engine);
>  
>   /* ELSP is empty, but there are ready requests? E.g. after reset */
> diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
> b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> index 5d42a12ef3d6..1b5a22a83db6 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> @@ -185,7 +185,7 @@ static int xcs_resume(struct intel_engine_cs *engine)
>ring->head, ring->tail);
>  
>   /* Double check the ring is empty & disabled before we resume */
> - synchronize_hardirq(engine->i915->drm.irq);
> + intel_synchronize_hardirq(engine->i915);
>   if (!stop_ring(engine))
>   goto err;
>  
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 7d0ce8b9f8ed..2203dca19895 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -4575,3 +4575,8 @@ void intel_synchronize_irq(struct drm_i915_private 
> *i915)
>  {
>   synchronize_irq(to_pci_dev(i915->drm.dev)->irq);
>  }
> +
> +void intel_synchronize_hardirq(struct drm_i915_private *i915)
> +{
> + synchronize_hardirq(to_pci_dev(i915->drm.dev)->irq);

I honestly think the hardirq here is about as much cargo-culted as using
the wrong irq number.

I'd just use intel_synchronize_irq in both places and see whether CI
complains, then go with that.
-Daniel

> +}
> diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h
> index db34d5dbe402..e43b6734f21b 100644
> --- a/drivers/gpu/drm/i915/i915_irq.h
> +++ b/drivers/gpu/drm/i915/i915_irq.h
> @@ -94,6 +94,7 @@ void intel_runtime_pm_disable_interrupts(struct 
> drm_i915_private *dev_priv);
>  void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
>  bool intel_irqs_enabled(struct drm_i915_private *dev_priv);
>  void intel_synchronize_irq(struct drm_i915_private *i915);
> +void intel_synchronize_hardirq(struct drm_i915_private *i915);
>  
>  int intel_get_crtc_scanline(struct intel_crtc *crtc);
>  void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
> -- 
> 2.32.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH V2] treewide: Add missing semicolons to __assign_str uses

2021-06-30 Thread Joe Perches
On Sat, 2021-06-12 at 08:42 -0700, Joe Perches wrote:
> The __assign_str macro has an unusual ending semicolon but the vast
> majority of uses of the macro already have semicolon termination.

ping?




RE: [PATCH 04/21] drm/i915/xelpd: Define Degamma Lut range struct for HDR planes

2021-06-30 Thread Shankar, Uma


> -Original Message-
> From: dri-devel  On Behalf Of Harry
> Wentland
> Sent: Monday, June 28, 2021 8:45 PM
> To: Shankar, Uma ; intel-...@lists.freedesktop.org; 
> dri-
> de...@lists.freedesktop.org
> Cc: Modem, Bhanuprakash 
> Subject: Re: [PATCH 04/21] drm/i915/xelpd: Define Degamma Lut range struct for
> HDR planes
> 
> On 2021-06-01 6:52 a.m., Uma Shankar wrote:
> > Define the structure with XE_LPD degamma lut ranges. HDR and SDR
> > planes have different capabilities, implemented respective structure
> > for the HDR planes.
> >
> > Signed-off-by: Uma Shankar 
> > ---
> >  drivers/gpu/drm/i915/display/intel_color.c | 52
> > ++
> >  1 file changed, 52 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_color.c
> > b/drivers/gpu/drm/i915/display/intel_color.c
> > index dab892d2251b..c735d06a6b54 100644
> > --- a/drivers/gpu/drm/i915/display/intel_color.c
> > +++ b/drivers/gpu/drm/i915/display/intel_color.c
> > @@ -2093,6 +2093,58 @@ static void icl_read_luts(struct intel_crtc_state
> *crtc_state)
> > }
> >  }
> >
> > + /* FIXME input bpc? */
> > +__maybe_unused
> > +static const struct drm_color_lut_range d13_degamma_hdr[] = {
> > +   /* segment 1 */
> > +   {
> > +   .flags = (DRM_MODE_LUT_GAMMA |
> 
> Why are these using DRM_MODE_LUT_GAMMA and not
> DRM_MODE_LUT_DEGAMMA when the lut_type for this LUT is
> LUT_TYPE_DEGAMMA?

Thanks Harry for the comments.

Yeah this is an oversight, will fix this.
> 
> 
> > + DRM_MODE_LUT_REFLECT_NEGATIVE |
> > + DRM_MODE_LUT_INTERPOLATE |
> > + DRM_MODE_LUT_NON_DECREASING),
> > +   .count = 128,
> > +   .input_bpc = 24, .output_bpc = 16,
> 
> Why do we need more than 16 bpc for LUT? FP16 is enough to represent HDR in
> linear space. Wouldn't 16 bpc be enough?

Pipe sometimes works internally on higher precision (just to take care of 
rounding etc.), later the
extra data gets dropped at the end of the pipe. So from source side you are 
right, 16bpc is enough
but the lut precision can go higher.

> 
> > +   .start = 0, .end = (1 << 24) - 1,
> > +   .min = 0, .max = (1 << 24) - 1,
> > +   },
> > +   /* segment 2 */
> > +   {
> > +   .flags = (DRM_MODE_LUT_GAMMA |
> > + DRM_MODE_LUT_REFLECT_NEGATIVE |
> > + DRM_MODE_LUT_INTERPOLATE |
> > + DRM_MODE_LUT_REUSE_LAST |
> > + DRM_MODE_LUT_NON_DECREASING),
> > +   .count = 1,
> > +   .input_bpc = 24, .output_bpc = 16,
> > +   .start = (1 << 24) - 1, .end = 1 << 24,
> > +   .min = 0, .max = (1 << 27) - 1,
> 
> How can max be 1 << 27 if input_bpc is 24?

This is to take care of > 1.0 section. 1.0 to 3.0 and 3.0 to 7.0.
So we have 3.24 format for Lut to take care of this. 

Also, I have an action to update the series with UAPI doc and new naming for 
the property.
My apologies for being late on that one. Will update and send that out soon.

Thanks & Regards,
Uma Shankar
> 
> Harry
> 
> > +   },
> > +   /* Segment 3 */
> > +   {
> > +   .flags = (DRM_MODE_LUT_GAMMA |
> > + DRM_MODE_LUT_REFLECT_NEGATIVE |
> > + DRM_MODE_LUT_INTERPOLATE |
> > + DRM_MODE_LUT_REUSE_LAST |
> > + DRM_MODE_LUT_NON_DECREASING),
> > +   .count = 1,
> > +   .input_bpc = 24, .output_bpc = 16,
> > +   .start = 1 << 24, .end = 3 << 24,
> > +   .min = 0, .max = (1 << 27) - 1,
> > +   },
> > +   /* Segment 4 */
> > +   {
> > +   .flags = (DRM_MODE_LUT_GAMMA |
> > + DRM_MODE_LUT_REFLECT_NEGATIVE |
> > + DRM_MODE_LUT_INTERPOLATE |
> > + DRM_MODE_LUT_REUSE_LAST |
> > + DRM_MODE_LUT_NON_DECREASING),
> > +   .count = 1,
> > +   .input_bpc = 24, .output_bpc = 16,
> > +   .start = 3 << 24, .end = 7 << 24,
> > +   .min = 0, .max = (1 << 27) - 1,
> > +   },
> > +};
> > +
> >  void intel_color_init(struct intel_crtc *crtc)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> >



Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing

2021-06-30 Thread Will Deacon
On Wed, Jun 30, 2021 at 05:17:27PM +0800, Claire Chang wrote:
> On Wed, Jun 30, 2021 at 9:43 AM Nathan Chancellor  wrote:
> >
> > On Thu, Jun 24, 2021 at 11:55:20PM +0800, Claire Chang wrote:
> > > Propagate the swiotlb_force into io_tlb_default_mem->force_bounce and
> > > use it to determine whether to bounce the data or not. This will be
> > > useful later to allow for different pools.
> > >
> > > Signed-off-by: Claire Chang 
> > > Reviewed-by: Christoph Hellwig 
> > > Tested-by: Stefano Stabellini 
> > > Tested-by: Will Deacon 
> > > Acked-by: Stefano Stabellini 
> >
> > This patch as commit af452ec1b1a3 ("swiotlb: Use is_swiotlb_force_bounce
> > for swiotlb data bouncing") causes my Ryzen 3 4300G system to fail to
> > get to an X session consistently (although not every single time),
> > presumably due to a crash in the AMDGPU driver that I see in dmesg.
> >
> > I have attached logs at af452ec1b1a3 and f127c9556a8e and I am happy
> > to provide any further information, debug, or test patches as necessary.
> 
> Are you using swiotlb=force? or the swiotlb_map is called because of
> !dma_capable? 
> (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/kernel/dma/direct.h#n93)

The command line is in the dmesg:

  | Kernel command line: initrd=\amd-ucode.img 
initrd=\initramfs-linux-next-llvm.img 
root=PARTUUID=8680aa0c-cf09-4a69-8cf3-970478040ee7 rw intel_pstate=no_hwp 
irqpoll

but I worry that this looks _very_ similar to the issue reported by Qian
Cai which we thought we had fixed. Nathan -- is the failure deterministic?

> `BUG: unable to handle page fault for address: 003a8290` and
> the fact it crashed at `_raw_spin_lock_irqsave` look like the memory
> (maybe dev->dma_io_tlb_mem) was corrupted?
> The dev->dma_io_tlb_mem should be set here
> (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/pci/probe.c#n2528)
> through device_initialize.

I'm less sure about this. 'dma_io_tlb_mem' should be pointing at
'io_tlb_default_mem', which is a page-aligned allocation from memblock.
The spinlock is at offset 0x24 in that structure, and looking at the
register dump from the crash:

Jun 29 18:28:42 hp-4300G kernel: RSP: 0018:adb4013db9e8 EFLAGS: 00010006
Jun 29 18:28:42 hp-4300G kernel: RAX: 003a8290 RBX:  
RCX: 8900572ad580
Jun 29 18:28:42 hp-4300G kernel: RDX: 89005653f024 RSI: 000c 
RDI: 1d17
Jun 29 18:28:42 hp-4300G kernel: RBP: 0a20d000 R08: 000c 
R09: 
Jun 29 18:28:42 hp-4300G kernel: R10: 0a20d000 R11: 89005653f000 
R12: 0212
Jun 29 18:28:42 hp-4300G kernel: R13: 1000 R14: 0002 
R15: 0020
Jun 29 18:28:42 hp-4300G kernel: FS:  7f1f8898ea40() 
GS:89005728() knlGS:
Jun 29 18:28:42 hp-4300G kernel: CS:  0010 DS:  ES:  CR0: 
80050033
Jun 29 18:28:42 hp-4300G kernel: CR2: 003a8290 CR3: 0001020d 
CR4: 00350ee0
Jun 29 18:28:42 hp-4300G kernel: Call Trace:
Jun 29 18:28:42 hp-4300G kernel:  _raw_spin_lock_irqsave+0x39/0x50
Jun 29 18:28:42 hp-4300G kernel:  swiotlb_tbl_map_single+0x12b/0x4c0

Then that correlates with R11 holding the 'dma_io_tlb_mem' pointer and
RDX pointing at the spinlock. Yet RAX is holding junk :/

I agree that enabling KASAN would be a good idea, but I also think we
probably need to get some more information out of swiotlb_tbl_map_single()
to see see what exactly is going wrong in there.

Will


Re: [PATCH v3 2/2] drm/i915: Drop all references to DRM IRQ midlayer

2021-06-30 Thread Thomas Zimmermann

Hi

Am 30.06.21 um 12:06 schrieb Greg KH:

On Wed, Jun 30, 2021 at 11:52:28AM +0200, Thomas Zimmermann wrote:

Remove all references to DRM's IRQ midlayer. i915 uses Linux' interrupt
functions directly.

v2:
* also remove an outdated comment
* move IRQ fix into separate patch
* update Fixes tag (Daniel)

Signed-off-by: Thomas Zimmermann 
Fixes: b318b82455bd ("drm/i915: Nuke drm_driver irq vfuncs")
Cc: Ville Syrjälä 
Cc: Chris Wilson 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: intel-...@lists.freedesktop.org
Cc:  # v5.4+
---
  drivers/gpu/drm/i915/i915_drv.c | 1 -
  drivers/gpu/drm/i915/i915_irq.c | 5 -
  2 files changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 850b499c71c8..73de45472f60 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -42,7 +42,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c

index 2203dca19895..1d4c683c9de9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -33,7 +33,6 @@
  #include 
  
  #include 

-#include 
  
  #include "display/intel_de.h"

  #include "display/intel_display_types.h"
@@ -4564,10 +4563,6 @@ void intel_runtime_pm_enable_interrupts(struct 
drm_i915_private *dev_priv)
  
  bool intel_irqs_enabled(struct drm_i915_private *dev_priv)

  {
-   /*
-* We only use drm_irq_uninstall() at unload and VT switch, so
-* this is the only thing we need to check.
-*/
return dev_priv->runtime_pm.irqs_enabled;
  }
  
--

2.32.0



How is this a stable-kernel-related fix?


Sorry, it isn't. I forgot to remove the rsp Cc tag.

Best regards
Thomas



thanks,

greg k-h



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



OpenPGP_signature
Description: OpenPGP digital signature


[PATCH] drm/vgem: Use 256B aligned pitch

2021-06-30 Thread Tejas Upadhyay
Having different alignment requirement by different drivers,
256B aligned should work for all drm drivers.

Signed-off-by: Tejas Upadhyay 
---
 drivers/gpu/drm/vgem/vgem_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index bf38a7e319d1..1da6df5e256a 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -215,7 +215,7 @@ static int vgem_gem_dumb_create(struct drm_file *file, 
struct drm_device *dev,
struct drm_gem_object *gem_object;
u64 pitch, size;
 
-   pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
+   pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 256);
size = args->height * pitch;
if (size == 0)
return -EINVAL;
-- 
2.31.1



Re: [Intel-gfx] [PATCH] drm/vgem: Use 256B aligned pitch

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 05:32:15PM +0530, Tejas Upadhyay wrote:
> Having different alignment requirement by different drivers,
> 256B aligned should work for all drm drivers.

What.

Like yes vgem abuses dumb_create, but it's not a kms driver. Pitch is
meaningless, and that's why we align it minimally to 1 byte (bpp = bits
per pixel here).

Maybe start with explaining what you're trying to do here.
-Daniel
> 
> Signed-off-by: Tejas Upadhyay 
> ---
>  drivers/gpu/drm/vgem/vgem_drv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
> index bf38a7e319d1..1da6df5e256a 100644
> --- a/drivers/gpu/drm/vgem/vgem_drv.c
> +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> @@ -215,7 +215,7 @@ static int vgem_gem_dumb_create(struct drm_file *file, 
> struct drm_device *dev,
>   struct drm_gem_object *gem_object;
>   u64 pitch, size;
>  
> - pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
> + pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 256);
>   size = args->height * pitch;
>   if (size == 0)
>   return -EINVAL;
> -- 
> 2.31.1
> 
> ___
> Intel-gfx mailing list
> intel-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH V2] treewide: Add missing semicolons to __assign_str uses

2021-06-30 Thread Steven Rostedt
On Wed, 30 Jun 2021 04:28:39 -0700
Joe Perches  wrote:

> On Sat, 2021-06-12 at 08:42 -0700, Joe Perches wrote:
> > The __assign_str macro has an unusual ending semicolon but the vast
> > majority of uses of the macro already have semicolon termination.  
> 
> ping?
> 

I wasn't sure I was the one to take this. I can, as I can run tests on
it as well. I have some last minute fixes sent to me on something else,
and I can apply this along with them.

-- Steve


Re: [RFC PATCH 0/9] arm64: imx8mm: Add MIPI DSI support

2021-06-30 Thread Jagan Teki
Hi Peng,

On Tue, Jun 29, 2021 at 12:40 PM Peng Fan (OSS)  wrote:
>
> Hi Jagan,
>
> > Subject: [RFC PATCH 0/9] arm64: imx8mm: Add MIPI DSI support
> >
> > This series support MIPI DSI on i.MX8MM.
> >
> > It worked directly with existing mxsfb driver but the SEC DSIM timings has 
> > to
> > be validate and tested through all platforms, ie reason I'm sending it as 
> > RFC.
> >
> > Tested on Engicam i.Core MX8M Mini SoM.
>
> Thanks for the work.
>
> >
> > patch 1: dt-bindings for SEC MIPI DSIM
> >
> > patch 2: SEC MIPI DSIM bridge driver
> >
> > patch 3: dt-bindings for SEC DSIM DPHY
> >
> > patch 4: SEC DSIM DPHY driver
> >
> > patch 5: MIPI DPHY reset enable in blk-ctl
> >
> > patch 6: display mix blk ctl node
> >
> > patch 7: eLCDIF node
> >
> > patch 8: MIPI DSI pipeline nodes
> >
> > patch 9: Enable LVDS panel on EDIMM2.2
> >
> > Note:
> > - all these patches on top of Peng Fan's blk-ctl driver.
>
> Would you please update to use V8 patchset?
>
> And the dtb:
> https://patchwork.kernel.org/project/linux-arm-kernel/
> patch/20210604111005.6804-1-peng@oss.nxp.com/

Thanks for the details.

I will rebase to use this series and test. Will update on blk-ctl patches.

Thanks,
Jagan.


[PATCH] dma-buf: fix and rework dma_buf_poll v4

2021-06-30 Thread Christian König
Daniel pointed me towards this function and there are multiple obvious problems
in the implementation.

First of all the retry loop is not working as intended. In general the retry
makes only sense if you grab the reference first and then check the sequence
values.

Then we should always also wait for the exclusive fence.

It's also good practice to keep the reference around when installing callbacks
to fences you don't own.

And last the whole implementation was unnecessary complex and rather hard to
understand which could lead to probably unexpected behavior of the IOCTL.

Fix all this by reworking the implementation from scratch. Dropping the
whole RCU approach and taking the lock instead.

Only mildly tested and needs a thoughtful review of the code.

v2: fix the reference counting as well
v3: keep the excl fence handling as is for stable
v4: back to testing all fences, drop RCU

Signed-off-by: Christian König 
CC: sta...@vger.kernel.org
---
 drivers/dma-buf/dma-buf.c | 132 +-
 include/linux/dma-buf.h   |   2 +-
 2 files changed, 46 insertions(+), 88 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index eadd1eaa2fb5..192c4d34704b 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -72,7 +72,7 @@ static void dma_buf_release(struct dentry *dentry)
 * If you hit this BUG() it means someone dropped their ref to the
 * dma-buf while still having pending operation to the buffer.
 */
-   BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
+   BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);
 
dmabuf->ops->release(dmabuf);
 
@@ -202,16 +202,19 @@ static void dma_buf_poll_cb(struct dma_fence *fence, 
struct dma_fence_cb *cb)
wake_up_locked_poll(dcb->poll, dcb->active);
dcb->active = 0;
spin_unlock_irqrestore(&dcb->poll->lock, flags);
+   dma_fence_put(fence);
 }
 
 static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
 {
+   struct dma_buf_poll_cb_t *dcb;
struct dma_buf *dmabuf;
struct dma_resv *resv;
struct dma_resv_list *fobj;
-   struct dma_fence *fence_excl;
+   struct dma_fence *fence;
+   unsigned shared_count;
__poll_t events;
-   unsigned shared_count, seq;
+   int r, i;
 
dmabuf = file->private_data;
if (!dmabuf || !dmabuf->resv)
@@ -225,101 +228,56 @@ static __poll_t dma_buf_poll(struct file *file, 
poll_table *poll)
if (!events)
return 0;
 
-retry:
-   seq = read_seqcount_begin(&resv->seq);
-   rcu_read_lock();
+   dcb = events & EPOLLOUT ? &dmabuf->cb_out : &dmabuf->cb_in;
+
+   /* Only queue a new one if we are not still waiting for the old one */
+   spin_lock_irq(&dmabuf->poll.lock);
+   if (dcb->active)
+   events = 0;
+   else
+   dcb->active = events;
+   spin_unlock_irq(&dmabuf->poll.lock);
+   if (!events)
+   return 0;
+
+   dma_resv_lock(resv, NULL);
 
-   fobj = rcu_dereference(resv->fence);
-   if (fobj)
+   fobj = dma_resv_get_list(resv);
+   if (fobj && events & EPOLLOUT)
shared_count = fobj->shared_count;
else
shared_count = 0;
-   fence_excl = rcu_dereference(resv->fence_excl);
-   if (read_seqcount_retry(&resv->seq, seq)) {
-   rcu_read_unlock();
-   goto retry;
-   }
 
-   if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) {
-   struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl;
-   __poll_t pevents = EPOLLIN;
-
-   if (shared_count == 0)
-   pevents |= EPOLLOUT;
-
-   spin_lock_irq(&dmabuf->poll.lock);
-   if (dcb->active) {
-   dcb->active |= pevents;
-   events &= ~pevents;
-   } else
-   dcb->active = pevents;
-   spin_unlock_irq(&dmabuf->poll.lock);
-
-   if (events & pevents) {
-   if (!dma_fence_get_rcu(fence_excl)) {
-   /* force a recheck */
-   events &= ~pevents;
-   dma_buf_poll_cb(NULL, &dcb->cb);
-   } else if (!dma_fence_add_callback(fence_excl, &dcb->cb,
-  dma_buf_poll_cb)) {
-   events &= ~pevents;
-   dma_fence_put(fence_excl);
-   } else {
-   /*
-* No callback queued, wake up any additional
-* waiters.
-*/
-   dma_fence_put(fence_excl);
-   dma_buf_poll_cb(NULL, &dcb->cb);
-   }
+  

RE: [Intel-gfx] [PATCH] drm/vgem: Use 256B aligned pitch

2021-06-30 Thread Surendrakumar Upadhyay, TejaskumarX



> -Original Message-
> From: Daniel Vetter 
> Sent: 30 June 2021 17:52
> To: Surendrakumar Upadhyay, TejaskumarX
> 
> Cc: dri-devel@lists.freedesktop.org; intel-...@lists.freedesktop.org;
> ch...@chris-wilson.co.uk
> Subject: Re: [Intel-gfx] [PATCH] drm/vgem: Use 256B aligned pitch
> 
> On Wed, Jun 30, 2021 at 05:32:15PM +0530, Tejas Upadhyay wrote:
> > Having different alignment requirement by different drivers, 256B
> > aligned should work for all drm drivers.
> 
> What.
> 
> Like yes vgem abuses dumb_create, but it's not a kms driver. Pitch is
> meaningless, and that's why we align it minimally to 1 byte (bpp = bits per
> pixel here).
> 
> Maybe start with explaining what you're trying to do here.
> -Daniel
> >

Igt tool tests which are trying to exercise tests through VGEM are getting 
failure (if not 64B aligned) on Intel platforms in creating framebuffer as they 
need them to be 64B aligned. Then 64B alignment is not 
A requirement for all drm drivers.

Thanks,
Tejas

> > Signed-off-by: Tejas Upadhyay
> > 
> > ---
> >  drivers/gpu/drm/vgem/vgem_drv.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c
> > b/drivers/gpu/drm/vgem/vgem_drv.c index bf38a7e319d1..1da6df5e256a
> > 100644
> > --- a/drivers/gpu/drm/vgem/vgem_drv.c
> > +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> > @@ -215,7 +215,7 @@ static int vgem_gem_dumb_create(struct drm_file
> *file, struct drm_device *dev,
> > struct drm_gem_object *gem_object;
> > u64 pitch, size;
> >
> > -   pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
> > +   pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 256);
> > size = args->height * pitch;
> > if (size == 0)
> > return -EINVAL;
> > --
> > 2.31.1
> >
> > ___
> > Intel-gfx mailing list
> > intel-...@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch


[PATCH 0/2] drm/i915/gem: dma-buf fixes for migration

2021-06-30 Thread Thomas Hellström
Our dma-buf code is currently completely broken unless the importer is
dynamic in which case the sg_list caching saves the day. In particular,
the case where another instance of our driver tries to import a dma-buf
exported by our driver ends up in a recursive lock.

Since the recent TTM migration work spec specifies to fix up the dma-buf
code with migration and there's no point in doing so when it's
completely broken, take a first step to make at least the exporter obey
the dma-buf locking rules the dma-buf core enforces for a dynamic exporter:

- Implement and act on pin- and unpin.
- Call move_notify if migrating. (we opt not to migrate while dma-buf_mapped).
- map_dma_buf() is unconditionally called locked.

Add a selftest that ensures that it works with both our own and a fake
dynamic importer.

Also implement migration in the second patch before pinning in pin()
and map_dma_buf().

Note that the importer remains broken for other non-dynamic exporters, but
at least not for the same-driver-separate-instances case.

Regardless whether we want to fix this now with this series, or in an
unspecified future, the selftest may come in handy.

Thomas Hellström (2):
  drm/i915/gem: Make our dma-buf exporter dynamic
  drm/i915/gem: Migrate to system at dma-buf map time

 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  48 ++-
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 118 +-
 2 files changed, 162 insertions(+), 4 deletions(-)

-- 
2.31.1



[PATCH 2/2] drm/i915/gem: Migrate to system at dma-buf map time

2021-06-30 Thread Thomas Hellström
Until we support p2p dma or as a complement to that, migrate data
to system memory at dma-buf map time if possible.

v2:
- Rebase on dynamic exporter. Update the igt_dmabuf_import_same_driver
  selftest to migrate if we are LMEM capable.
v3:
- Migrate also in the pin() callback.

Signed-off-by: Thomas Hellström 
Reviewed-by: Michael J. Ruhl 
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 21 +--
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  |  4 +++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 918c19df7b66..13312d89c2ed 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -34,7 +34,14 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
 * Let's pin it here to avoid having to call the move_notify
 * callback, The call of which is not yet implemented.
 */
-   ret = i915_gem_object_pin_pages(obj);
+   if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM))
+   return ERR_PTR(-EOPNOTSUPP);
+
+   ret = i915_gem_object_migrate(obj, NULL, INTEL_REGION_SMEM);
+   if (!ret)
+   ret = i915_gem_object_wait_migration(obj, 0);
+   if (!ret)
+   ret = i915_gem_object_pin_pages(obj);
if (ret)
goto err;
 
@@ -180,9 +187,19 @@ static int i915_gem_end_cpu_access(struct dma_buf 
*dma_buf, enum dma_data_direct
 static int i915_gem_dmabuf_pin(struct dma_buf_attachment *attach)
 {
struct drm_i915_gem_object *obj = dma_buf_to_obj(attach->dmabuf);
+   int ret;
 
assert_object_held(obj);
-   return i915_gem_object_pin_pages(obj);
+
+   if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM))
+   return -EOPNOTSUPP;
+   ret = i915_gem_object_migrate(obj, NULL, INTEL_REGION_SMEM);
+   if (!ret)
+   ret = i915_gem_object_wait_migration(obj, 0);
+   if (!ret)
+   ret = i915_gem_object_pin_pages(obj);
+
+   return ret;
 }
 
 static void i915_gem_dmabuf_unpin(struct dma_buf_attachment *attach)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
index 868b3469ecbd..b1e87ec08741 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
@@ -106,7 +106,9 @@ static int igt_dmabuf_import_same_driver(void *arg)
int err;
 
force_different_devices = true;
-   obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
+   obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0);
+   if (IS_ERR(obj))
+   obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
if (IS_ERR(obj))
goto out_ret;
 
-- 
2.31.1



[PATCH 1/2] drm/i915/gem: Make our dma-buf exporter dynamic

2021-06-30 Thread Thomas Hellström
If our exported dma-bufs are imported by another instance of our driver,
that instance will typically have the imported dma-bufs locked during
dma_buf_map_attachment(). But the exporter also locks the same reservation
object in the map_dma_buf() callback, which leads to recursive locking.

Add a live selftest to exercise both dynamic and non-dynamic exports,
and as a workaround until we fully support dynamic import and export,
declare the exporter dynamic by providing pin() and unpin() implementations.
For dynamic importers, make sure we keep the pinning also in map_dma_buf(),
to ensure we never need to call dma_buf_move_notify().
Calling dma_buf_move_notify() is at the discretion of the exporter.

v2:
- Extend the selftest with a fake dynamic importer.
- Provide real pin and unpin callbacks to not abuse the interface.

Reported-by: Michael J. Ruhl 
Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  31 -
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 116 +-
 2 files changed, 143 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 616c3a2f1baf..918c19df7b66 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -12,6 +12,8 @@
 #include "i915_gem_object.h"
 #include "i915_scatterlist.h"
 
+I915_SELFTEST_DECLARE(static bool force_different_devices;)
+
 static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
 {
return to_intel_bo(buf->priv);
@@ -25,7 +27,14 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
struct scatterlist *src, *dst;
int ret, i;
 
-   ret = i915_gem_object_pin_pages_unlocked(obj);
+   assert_object_held(obj);
+
+   /*
+* Note. In the dynamic importer case, the object is not yet pinned.
+* Let's pin it here to avoid having to call the move_notify
+* callback, The call of which is not yet implemented.
+*/
+   ret = i915_gem_object_pin_pages(obj);
if (ret)
goto err;
 
@@ -168,6 +177,21 @@ static int i915_gem_end_cpu_access(struct dma_buf 
*dma_buf, enum dma_data_direct
return err;
 }
 
+static int i915_gem_dmabuf_pin(struct dma_buf_attachment *attach)
+{
+   struct drm_i915_gem_object *obj = dma_buf_to_obj(attach->dmabuf);
+
+   assert_object_held(obj);
+   return i915_gem_object_pin_pages(obj);
+}
+
+static void i915_gem_dmabuf_unpin(struct dma_buf_attachment *attach)
+{
+   struct drm_i915_gem_object *obj = dma_buf_to_obj(attach->dmabuf);
+
+   i915_gem_object_unpin_pages(obj);
+}
+
 static const struct dma_buf_ops i915_dmabuf_ops =  {
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
@@ -177,6 +201,8 @@ static const struct dma_buf_ops i915_dmabuf_ops =  {
.vunmap = i915_gem_dmabuf_vunmap,
.begin_cpu_access = i915_gem_begin_cpu_access,
.end_cpu_access = i915_gem_end_cpu_access,
+   .pin = i915_gem_dmabuf_pin,
+   .unpin = i915_gem_dmabuf_unpin,
 };
 
 struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int 
flags)
@@ -241,7 +267,8 @@ struct drm_gem_object *i915_gem_prime_import(struct 
drm_device *dev,
if (dma_buf->ops == &i915_dmabuf_ops) {
obj = dma_buf_to_obj(dma_buf);
/* is it from our device? */
-   if (obj->base.dev == dev) {
+   if (obj->base.dev == dev &&
+   !I915_SELFTEST_ONLY(force_different_devices)) {
/*
 * Importing dmabuf exported from out own gem increases
 * refcount on gem itself instead of f_count of dmabuf.
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
index dd74bc09ec88..868b3469ecbd 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
@@ -35,7 +35,7 @@ static int igt_dmabuf_export(void *arg)
 static int igt_dmabuf_import_self(void *arg)
 {
struct drm_i915_private *i915 = arg;
-   struct drm_i915_gem_object *obj;
+   struct drm_i915_gem_object *obj, *import_obj;
struct drm_gem_object *import;
struct dma_buf *dmabuf;
int err;
@@ -65,14 +65,125 @@ static int igt_dmabuf_import_self(void *arg)
err = -EINVAL;
goto out_import;
}
+   import_obj = to_intel_bo(import);
+
+   i915_gem_object_lock(import_obj, NULL);
+   err = i915_gem_object_get_pages(import_obj);
+   i915_gem_object_unlock(import_obj);
+   if (err) {
+   pr_err("Same object dma-buf get_pages failed!\n");
+   goto out_import;
+   }
 
err = 0;
 out_import:
-   i915_gem_object_put(to_intel_bo(import));
+   i915_gem_objec

Re: [PATCH v6 05/16] drm/panfrost: Drop the pfdev argument passed to panfrost_exception_name()

2021-06-30 Thread Alyssa Rosenzweig
Reviewed-by: Alyssa Rosenzweig 

On Wed, Jun 30, 2021 at 08:27:40AM +0200, Boris Brezillon wrote:
> Currently unused. We'll add it back if we need per-GPU definitions.
> 
> Signed-off-by: Boris Brezillon 
> Reviewed-by: Steven Price 
> ---
>  drivers/gpu/drm/panfrost/panfrost_device.c | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_device.h | 2 +-
>  drivers/gpu/drm/panfrost/panfrost_gpu.c| 2 +-
>  drivers/gpu/drm/panfrost/panfrost_job.c| 2 +-
>  drivers/gpu/drm/panfrost/panfrost_mmu.c| 2 +-
>  5 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
> b/drivers/gpu/drm/panfrost/panfrost_device.c
> index a2a09c51eed7..f7f5ca94f910 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
> @@ -292,7 +292,7 @@ void panfrost_device_fini(struct panfrost_device *pfdev)
>   panfrost_clk_fini(pfdev);
>  }
>  
> -const char *panfrost_exception_name(struct panfrost_device *pfdev, u32 
> exception_code)
> +const char *panfrost_exception_name(u32 exception_code)
>  {
>   switch (exception_code) {
>   /* Non-Fault Status code */
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
> b/drivers/gpu/drm/panfrost/panfrost_device.h
> index 8b2cdb8c701d..2fe1550da7f8 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
> @@ -173,6 +173,6 @@ void panfrost_device_reset(struct panfrost_device *pfdev);
>  int panfrost_device_resume(struct device *dev);
>  int panfrost_device_suspend(struct device *dev);
>  
> -const char *panfrost_exception_name(struct panfrost_device *pfdev, u32 
> exception_code);
> +const char *panfrost_exception_name(u32 exception_code);
>  
>  #endif
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
> b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> index 0e70e27fd8c3..26e4196b6c90 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> @@ -33,7 +33,7 @@ static irqreturn_t panfrost_gpu_irq_handler(int irq, void 
> *data)
>   address |= gpu_read(pfdev, GPU_FAULT_ADDRESS_LO);
>  
>   dev_warn(pfdev->dev, "GPU Fault 0x%08x (%s) at 0x%016llx\n",
> -  fault_status & 0xFF, panfrost_exception_name(pfdev, 
> fault_status),
> +  fault_status & 0xFF, 
> panfrost_exception_name(fault_status),
>address);
>  
>   if (state & GPU_IRQ_MULTIPLE_FAULT)
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index 3c1dbae3ebdd..ea3432ffde40 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -489,7 +489,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void 
> *data)
>  
>   dev_err(pfdev->dev, "js fault, js=%d, status=%s, 
> head=0x%x, tail=0x%x",
>   j,
> - panfrost_exception_name(pfdev, job_read(pfdev, 
> JS_STATUS(j))),
> + panfrost_exception_name(job_read(pfdev, 
> JS_STATUS(j))),
>   job_read(pfdev, JS_HEAD_LO(j)),
>   job_read(pfdev, JS_TAIL_LO(j)));
>  
> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> index 569509c2ba27..2a9bf30edc9d 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> @@ -675,7 +675,7 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int 
> irq, void *data)
>   "TODO",
>   fault_status,
>   (fault_status & (1 << 10) ? "DECODER FAULT" : 
> "SLAVE FAULT"),
> - exception_type, panfrost_exception_name(pfdev, 
> exception_type),
> + exception_type, 
> panfrost_exception_name(exception_type),
>   access_type, access_type_name(pfdev, 
> fault_status),
>   source_id);
>  
> -- 
> 2.31.1
> 


Re: [PATCH 1/2] drm/i915/gem: Make our dma-buf exporter dynamic

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 03:07:00PM +0200, Thomas Hellström wrote:
> If our exported dma-bufs are imported by another instance of our driver,
> that instance will typically have the imported dma-bufs locked during
> dma_buf_map_attachment(). But the exporter also locks the same reservation
> object in the map_dma_buf() callback, which leads to recursive locking.
> 
> Add a live selftest to exercise both dynamic and non-dynamic exports,
> and as a workaround until we fully support dynamic import and export,
> declare the exporter dynamic by providing pin() and unpin() implementations.
> For dynamic importers, make sure we keep the pinning also in map_dma_buf(),
> to ensure we never need to call dma_buf_move_notify().
> Calling dma_buf_move_notify() is at the discretion of the exporter.
> 
> v2:
> - Extend the selftest with a fake dynamic importer.
> - Provide real pin and unpin callbacks to not abuse the interface.
> 
> Reported-by: Michael J. Ruhl 
> Signed-off-by: Thomas Hellström 

I'm not happy with this, because i915 is currently violating the dma-resv
fencing rules for dynamic dma-buf.

Yes since this is just the exporter we can probably get away with yolo'ing
things, but Christian and me just spend a lot of angry typing figuring out
what the rules actually are, so I really don't like bending them even more
just because it's less typing.

All we need for a quick interim fix is to not take the dma_resv_lock from
our map/unamp callbacks. Pinning our backing storage from attach/detach
callbacks (which are also called under dma_resv_lock) would also achieve
that, without mudding any waters. So essentially just moving the
pin/unpin_pages_unlocked and we should be good, which is almost as little
typing.

Michael, since Thomas is on vacations now, care to type that up? The
selftest is imo solid.

This is also consistent with what all other ttm based drivers do (aside
from amdgpu, which is fully dynamic), see drm_gem_map_attach in
drm_prime.c

Adding Christian as fyi.
-Daniel

> ---
>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  31 -
>  .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 116 +-
>  2 files changed, 143 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> index 616c3a2f1baf..918c19df7b66 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> @@ -12,6 +12,8 @@
>  #include "i915_gem_object.h"
>  #include "i915_scatterlist.h"
>  
> +I915_SELFTEST_DECLARE(static bool force_different_devices;)
> +
>  static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
>  {
>   return to_intel_bo(buf->priv);
> @@ -25,7 +27,14 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
> dma_buf_attachment *attachme
>   struct scatterlist *src, *dst;
>   int ret, i;
>  
> - ret = i915_gem_object_pin_pages_unlocked(obj);
> + assert_object_held(obj);
> +
> + /*
> +  * Note. In the dynamic importer case, the object is not yet pinned.
> +  * Let's pin it here to avoid having to call the move_notify
> +  * callback, The call of which is not yet implemented.
> +  */
> + ret = i915_gem_object_pin_pages(obj);
>   if (ret)
>   goto err;
>  
> @@ -168,6 +177,21 @@ static int i915_gem_end_cpu_access(struct dma_buf 
> *dma_buf, enum dma_data_direct
>   return err;
>  }
>  
> +static int i915_gem_dmabuf_pin(struct dma_buf_attachment *attach)
> +{
> + struct drm_i915_gem_object *obj = dma_buf_to_obj(attach->dmabuf);
> +
> + assert_object_held(obj);
> + return i915_gem_object_pin_pages(obj);
> +}
> +
> +static void i915_gem_dmabuf_unpin(struct dma_buf_attachment *attach)
> +{
> + struct drm_i915_gem_object *obj = dma_buf_to_obj(attach->dmabuf);
> +
> + i915_gem_object_unpin_pages(obj);
> +}
> +
>  static const struct dma_buf_ops i915_dmabuf_ops =  {
>   .map_dma_buf = i915_gem_map_dma_buf,
>   .unmap_dma_buf = i915_gem_unmap_dma_buf,
> @@ -177,6 +201,8 @@ static const struct dma_buf_ops i915_dmabuf_ops =  {
>   .vunmap = i915_gem_dmabuf_vunmap,
>   .begin_cpu_access = i915_gem_begin_cpu_access,
>   .end_cpu_access = i915_gem_end_cpu_access,
> + .pin = i915_gem_dmabuf_pin,
> + .unpin = i915_gem_dmabuf_unpin,
>  };
>  
>  struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int 
> flags)
> @@ -241,7 +267,8 @@ struct drm_gem_object *i915_gem_prime_import(struct 
> drm_device *dev,
>   if (dma_buf->ops == &i915_dmabuf_ops) {
>   obj = dma_buf_to_obj(dma_buf);
>   /* is it from our device? */
> - if (obj->base.dev == dev) {
> + if (obj->base.dev == dev &&
> + !I915_SELFTEST_ONLY(force_different_devices)) {
>   /*
>* Importing dmabuf exported from out own gem increases
>* refcount on gem itself instead 

Re: [Intel-gfx] [PATCH] drm/vgem: Use 256B aligned pitch

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 12:46:27PM +, Surendrakumar Upadhyay, TejaskumarX 
wrote:
> 
> 
> > -Original Message-
> > From: Daniel Vetter 
> > Sent: 30 June 2021 17:52
> > To: Surendrakumar Upadhyay, TejaskumarX
> > 
> > Cc: dri-devel@lists.freedesktop.org; intel-...@lists.freedesktop.org;
> > ch...@chris-wilson.co.uk
> > Subject: Re: [Intel-gfx] [PATCH] drm/vgem: Use 256B aligned pitch
> > 
> > On Wed, Jun 30, 2021 at 05:32:15PM +0530, Tejas Upadhyay wrote:
> > > Having different alignment requirement by different drivers, 256B
> > > aligned should work for all drm drivers.
> > 
> > What.
> > 
> > Like yes vgem abuses dumb_create, but it's not a kms driver. Pitch is
> > meaningless, and that's why we align it minimally to 1 byte (bpp = bits per
> > pixel here).
> > 
> > Maybe start with explaining what you're trying to do here.
> > -Daniel
> > >
> 
> Igt tool tests which are trying to exercise tests through VGEM are getting 
> failure (if not 64B aligned) on Intel platforms in creating framebuffer as 
> they need them to be 64B aligned. Then 64B alignment is not 
> A requirement for all drm drivers.

Fix the tests. We're not going to encode alignment constraints for all kms
drivers in vgem, that's not what vgem is for.

Really what we should have done is just give vgem an ioctl to allocate a
buffer, with the size specified in bytes. Not this "abuse dumb_create"
business we're doing. But that's a past mistake, can't really fix that.
-Daniel

> 
> Thanks,
> Tejas
> 
> > > Signed-off-by: Tejas Upadhyay
> > > 
> > > ---
> > >  drivers/gpu/drm/vgem/vgem_drv.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c
> > > b/drivers/gpu/drm/vgem/vgem_drv.c index bf38a7e319d1..1da6df5e256a
> > > 100644
> > > --- a/drivers/gpu/drm/vgem/vgem_drv.c
> > > +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> > > @@ -215,7 +215,7 @@ static int vgem_gem_dumb_create(struct drm_file
> > *file, struct drm_device *dev,
> > >   struct drm_gem_object *gem_object;
> > >   u64 pitch, size;
> > >
> > > - pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
> > > + pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 256);
> > >   size = args->height * pitch;
> > >   if (size == 0)
> > >   return -EINVAL;
> > > --
> > > 2.31.1
> > >
> > > ___
> > > Intel-gfx mailing list
> > > intel-...@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


RE: [PATCH 1/2] drm/i915/gem: Make our dma-buf exporter dynamic

2021-06-30 Thread Ruhl, Michael J
>-Original Message-
>From: Daniel Vetter 
>Sent: Wednesday, June 30, 2021 10:02 AM
>To: Thomas Hellström ; Christian König
>
>Cc: intel-...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Auld,
>Matthew ; maarten.lankho...@linux.intel.com;
>dan...@ffwll.ch; Ruhl, Michael J 
>Subject: Re: [PATCH 1/2] drm/i915/gem: Make our dma-buf exporter dynamic
>
>On Wed, Jun 30, 2021 at 03:07:00PM +0200, Thomas Hellström wrote:
>> If our exported dma-bufs are imported by another instance of our driver,
>> that instance will typically have the imported dma-bufs locked during
>> dma_buf_map_attachment(). But the exporter also locks the same
>reservation
>> object in the map_dma_buf() callback, which leads to recursive locking.
>>
>> Add a live selftest to exercise both dynamic and non-dynamic exports,
>> and as a workaround until we fully support dynamic import and export,
>> declare the exporter dynamic by providing pin() and unpin()
>implementations.
>> For dynamic importers, make sure we keep the pinning also in
>map_dma_buf(),
>> to ensure we never need to call dma_buf_move_notify().
>> Calling dma_buf_move_notify() is at the discretion of the exporter.
>>
>> v2:
>> - Extend the selftest with a fake dynamic importer.
>> - Provide real pin and unpin callbacks to not abuse the interface.
>>
>> Reported-by: Michael J. Ruhl 
>> Signed-off-by: Thomas Hellström 
>
>I'm not happy with this, because i915 is currently violating the dma-resv
>fencing rules for dynamic dma-buf.
>
>Yes since this is just the exporter we can probably get away with yolo'ing
>things, but Christian and me just spend a lot of angry typing figuring out
>what the rules actually are, so I really don't like bending them even more
>just because it's less typing.
>
>All we need for a quick interim fix is to not take the dma_resv_lock from
>our map/unamp callbacks. Pinning our backing storage from attach/detach
>callbacks (which are also called under dma_resv_lock) would also achieve
>that, without mudding any waters. So essentially just moving the
>pin/unpin_pages_unlocked and we should be good, which is almost as little
>typing.
>
>Michael, since Thomas is on vacations now, care to type that up? The
>selftest is imo solid.

Yes, I will get that done.

Mike

>This is also consistent with what all other ttm based drivers do (aside
>from amdgpu, which is fully dynamic), see drm_gem_map_attach in
>drm_prime.c
>
>Adding Christian as fyi.
>-Daniel
>
>> ---
>>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  31 -
>>  .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 116
>+-
>>  2 files changed, 143 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> index 616c3a2f1baf..918c19df7b66 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> @@ -12,6 +12,8 @@
>>  #include "i915_gem_object.h"
>>  #include "i915_scatterlist.h"
>>
>> +I915_SELFTEST_DECLARE(static bool force_different_devices;)
>> +
>>  static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf
>*buf)
>>  {
>>  return to_intel_bo(buf->priv);
>> @@ -25,7 +27,14 @@ static struct sg_table
>*i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
>>  struct scatterlist *src, *dst;
>>  int ret, i;
>>
>> -ret = i915_gem_object_pin_pages_unlocked(obj);
>> +assert_object_held(obj);
>> +
>> +/*
>> + * Note. In the dynamic importer case, the object is not yet pinned.
>> + * Let's pin it here to avoid having to call the move_notify
>> + * callback, The call of which is not yet implemented.
>> + */
>> +ret = i915_gem_object_pin_pages(obj);
>>  if (ret)
>>  goto err;
>>
>> @@ -168,6 +177,21 @@ static int i915_gem_end_cpu_access(struct
>dma_buf *dma_buf, enum dma_data_direct
>>  return err;
>>  }
>>
>> +static int i915_gem_dmabuf_pin(struct dma_buf_attachment *attach)
>> +{
>> +struct drm_i915_gem_object *obj = dma_buf_to_obj(attach-
>>dmabuf);
>> +
>> +assert_object_held(obj);
>> +return i915_gem_object_pin_pages(obj);
>> +}
>> +
>> +static void i915_gem_dmabuf_unpin(struct dma_buf_attachment *attach)
>> +{
>> +struct drm_i915_gem_object *obj = dma_buf_to_obj(attach-
>>dmabuf);
>> +
>> +i915_gem_object_unpin_pages(obj);
>> +}
>> +
>>  static const struct dma_buf_ops i915_dmabuf_ops =  {
>>  .map_dma_buf = i915_gem_map_dma_buf,
>>  .unmap_dma_buf = i915_gem_unmap_dma_buf,
>> @@ -177,6 +201,8 @@ static const struct dma_buf_ops i915_dmabuf_ops =
>{
>>  .vunmap = i915_gem_dmabuf_vunmap,
>>  .begin_cpu_access = i915_gem_begin_cpu_access,
>>  .end_cpu_access = i915_gem_end_cpu_access,
>> +.pin = i915_gem_dmabuf_pin,
>> +.unpin = i915_gem_dmabuf_unpin,
>>  };
>>
>>  struct dma_buf *i915_gem_prime_export(struct drm_gem_object
>*gem_obj, int flags)
>> @@ -241,7 +267,8 @@ struct drm_gem_object
>*i915_gem_prime_import(struct drm_devi

[PATCH 0/3] drm/bochs: Move to tiny/ and simplify

2021-06-30 Thread Thomas Zimmermann
Move the bochs driver to tiny/ and simplify the clean-up code. Also
update GEM VRAM helpers accordingly.

Thomas Zimmermann (3):
  drm/bochs: Move to tiny/
  drm/bochs: Use managed initialization for GEM VRAM helpers
  drm/vram-helper: Unexport drm_vram_helper_{alloc,release}_mm()

 MAINTAINERS   |   2 +-
 drivers/gpu/drm/Kconfig   |   2 -
 drivers/gpu/drm/Makefile  |   1 -
 drivers/gpu/drm/bochs/Kconfig |  11 -
 drivers/gpu/drm/bochs/Makefile|   4 -
 drivers/gpu/drm/bochs/bochs.h |  98 
 drivers/gpu/drm/bochs/bochs_drv.c | 205 ---
 drivers/gpu/drm/bochs/bochs_hw.c  | 323 ---
 drivers/gpu/drm/bochs/bochs_kms.c | 178 ---
 drivers/gpu/drm/bochs/bochs_mm.c  |  24 -
 drivers/gpu/drm/drm_gem_vram_helper.c |   9 +-
 drivers/gpu/drm/tiny/Kconfig  |  13 +
 drivers/gpu/drm/tiny/Makefile |   1 +
 drivers/gpu/drm/tiny/bochs.c  | 735 ++
 include/drm/drm_gem_vram_helper.h |   4 -
 15 files changed, 753 insertions(+), 857 deletions(-)
 delete mode 100644 drivers/gpu/drm/bochs/Kconfig
 delete mode 100644 drivers/gpu/drm/bochs/Makefile
 delete mode 100644 drivers/gpu/drm/bochs/bochs.h
 delete mode 100644 drivers/gpu/drm/bochs/bochs_drv.c
 delete mode 100644 drivers/gpu/drm/bochs/bochs_hw.c
 delete mode 100644 drivers/gpu/drm/bochs/bochs_kms.c
 delete mode 100644 drivers/gpu/drm/bochs/bochs_mm.c
 create mode 100644 drivers/gpu/drm/tiny/bochs.c

--
2.32.0



[PATCH 1/3] drm/bochs: Move to tiny/

2021-06-30 Thread Thomas Zimmermann
The bochs driver is only ~600 lines of code. Putting it into tiny/
cleans up the DRM directory slightly. Some style problems were fixed
and unneeded include statements were removed. No functional changes.

Signed-off-by: Thomas Zimmermann 
---
 MAINTAINERS   |   2 +-
 drivers/gpu/drm/Kconfig   |   2 -
 drivers/gpu/drm/Makefile  |   1 -
 drivers/gpu/drm/bochs/Kconfig |  11 -
 drivers/gpu/drm/bochs/Makefile|   4 -
 drivers/gpu/drm/bochs/bochs.h |  98 
 drivers/gpu/drm/bochs/bochs_drv.c | 205 
 drivers/gpu/drm/bochs/bochs_hw.c  | 323 -
 drivers/gpu/drm/bochs/bochs_kms.c | 178 ---
 drivers/gpu/drm/bochs/bochs_mm.c  |  24 -
 drivers/gpu/drm/tiny/Kconfig  |  13 +
 drivers/gpu/drm/tiny/Makefile |   1 +
 drivers/gpu/drm/tiny/bochs.c  | 768 ++
 13 files changed, 783 insertions(+), 847 deletions(-)
 delete mode 100644 drivers/gpu/drm/bochs/Kconfig
 delete mode 100644 drivers/gpu/drm/bochs/Makefile
 delete mode 100644 drivers/gpu/drm/bochs/bochs.h
 delete mode 100644 drivers/gpu/drm/bochs/bochs_drv.c
 delete mode 100644 drivers/gpu/drm/bochs/bochs_hw.c
 delete mode 100644 drivers/gpu/drm/bochs/bochs_kms.c
 delete mode 100644 drivers/gpu/drm/bochs/bochs_mm.c
 create mode 100644 drivers/gpu/drm/tiny/bochs.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dcb5f0d32303..95bad8d45200 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5680,7 +5680,7 @@ M:Gerd Hoffmann 
 L: virtualizat...@lists.linux-foundation.org
 S: Maintained
 T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/gpu/drm/bochs/
+F: drivers/gpu/drm/tiny/bochs.c
 
 DRM DRIVER FOR BOE HIMAX8279D PANELS
 M: Jerry Han 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1366d8d4610a..0d372354c2d0 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -322,8 +322,6 @@ source "drivers/gpu/drm/tilcdc/Kconfig"
 
 source "drivers/gpu/drm/qxl/Kconfig"
 
-source "drivers/gpu/drm/bochs/Kconfig"
-
 source "drivers/gpu/drm/virtio/Kconfig"
 
 source "drivers/gpu/drm/msm/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 12e6f4e485ed..ad1112154898 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -98,7 +98,6 @@ obj-y += omapdrm/
 obj-$(CONFIG_DRM_SUN4I) += sun4i/
 obj-y  += tilcdc/
 obj-$(CONFIG_DRM_QXL) += qxl/
-obj-$(CONFIG_DRM_BOCHS) += bochs/
 obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
 obj-$(CONFIG_DRM_MSM) += msm/
 obj-$(CONFIG_DRM_TEGRA) += tegra/
diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig
deleted file mode 100644
index 7bcdf294fed8..
--- a/drivers/gpu/drm/bochs/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config DRM_BOCHS
-   tristate "DRM Support for bochs dispi vga interface (qemu stdvga)"
-   depends on DRM && PCI && MMU
-   select DRM_KMS_HELPER
-   select DRM_VRAM_HELPER
-   select DRM_TTM
-   select DRM_TTM_HELPER
-   help
- Choose this option for qemu.
- If M is selected the module will be called bochs-drm.
diff --git a/drivers/gpu/drm/bochs/Makefile b/drivers/gpu/drm/bochs/Makefile
deleted file mode 100644
index 55473371300f..
--- a/drivers/gpu/drm/bochs/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_hw.o
-
-obj-$(CONFIG_DRM_BOCHS)+= bochs-drm.o
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
deleted file mode 100644
index e9645c612aff..
--- a/drivers/gpu/drm/bochs/bochs.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* -- */
-
-#define VBE_DISPI_IOPORT_INDEX   0x01CE
-#define VBE_DISPI_IOPORT_DATA0x01CF
-
-#define VBE_DISPI_INDEX_ID   0x0
-#define VBE_DISPI_INDEX_XRES 0x1
-#define VBE_DISPI_INDEX_YRES 0x2
-#define VBE_DISPI_INDEX_BPP  0x3
-#define VBE_DISPI_INDEX_ENABLE   0x4
-#define VBE_DISPI_INDEX_BANK 0x5
-#define VBE_DISPI_INDEX_VIRT_WIDTH   0x6
-#define VBE_DISPI_INDEX_VIRT_HEIGHT  0x7
-#define VBE_DISPI_INDEX_X_OFFSET 0x8
-#define VBE_DISPI_INDEX_Y_OFFSET 0x9
-#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
-
-#define VBE_DISPI_ID00xB0C0
-#define VBE_DISPI_ID10xB0C1
-#define VBE_DISPI_ID20xB0C2
-#define VBE_DISPI_ID30xB0C3
-#define VBE_DISPI_ID40xB0C4
-#define VBE_DISPI_ID50xB0C5
-
-#define VBE_DISPI_DISABLED   0x00
-#define VBE_DISPI_ENABLED0x01
-#define VBE_DISPI_GETCAPS 

[PATCH 2/3] drm/bochs: Use managed initialization for GEM VRAM helpers

2021-06-30 Thread Thomas Zimmermann
Convert to managed GEM VRAM initialization and switch bochs to
full autocleanup.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/tiny/bochs.c | 43 +---
 1 file changed, 5 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index edcd31db5b9c..254787fbf0ea 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -404,25 +404,6 @@ static void bochs_hw_setbase(struct bochs_device *bochs, 
int x, int y, int strid
 
 /* -- */
 
-static int bochs_mm_init(struct bochs_device *bochs)
-{
-   struct drm_vram_mm *vmm;
-
-   vmm = drm_vram_helper_alloc_mm(bochs->dev, bochs->fb_base,
-  bochs->fb_size);
-   return PTR_ERR_OR_ZERO(vmm);
-}
-
-static void bochs_mm_fini(struct bochs_device *bochs)
-{
-   if (!bochs->dev->vram_mm)
-   return;
-
-   drm_vram_helper_release_mm(bochs->dev);
-}
-
-/* -- */
-
 static const uint32_t bochs_formats[] = {
DRM_FORMAT_XRGB,
DRM_FORMAT_BGRX,
@@ -582,13 +563,6 @@ static int bochs_kms_init(struct bochs_device *bochs)
 /* -- */
 /* drm interface  */
 
-static void bochs_unload(struct drm_device *dev)
-{
-   struct bochs_device *bochs = dev->dev_private;
-
-   bochs_mm_fini(bochs);
-}
-
 static int bochs_load(struct drm_device *dev)
 {
struct bochs_device *bochs;
@@ -602,21 +576,17 @@ static int bochs_load(struct drm_device *dev)
 
ret = bochs_hw_init(dev);
if (ret)
-   goto err;
+   return ret;
 
-   ret = bochs_mm_init(bochs);
+   ret = drmm_vram_helper_init(dev, bochs->fb_base, bochs->fb_size);
if (ret)
-   goto err;
+   return ret;
 
ret = bochs_kms_init(bochs);
if (ret)
-   goto err;
+   return ret;
 
return 0;
-
-err:
-   bochs_unload(dev);
-   return ret;
 }
 
 DEFINE_DRM_GEM_FOPS(bochs_fops);
@@ -630,7 +600,6 @@ static const struct drm_driver bochs_driver = {
.major  = 1,
.minor  = 0,
DRM_GEM_VRAM_DRIVER,
-   .release= bochs_unload,
 };
 
 /* -- */
@@ -693,13 +662,11 @@ static int bochs_pci_probe(struct pci_dev *pdev,
 
ret = drm_dev_register(dev, 0);
if (ret)
-   goto err_unload;
+   goto err_free_dev;
 
drm_fbdev_generic_setup(dev, 32);
return ret;
 
-err_unload:
-   bochs_unload(dev);
 err_free_dev:
drm_dev_put(dev);
return ret;
-- 
2.32.0



[PATCH 3/3] drm/vram-helper: Unexport drm_vram_helper_{alloc, release}_mm()

2021-06-30 Thread Thomas Zimmermann
All GEM-VRAM-based drivers use auto-cleanup via drmm_vram_helper_init().
Unexport the manual APIs and make them internal implementation.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_gem_vram_helper.c | 9 +++--
 include/drm/drm_gem_vram_helper.h | 4 
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 2a1229b8364e..1e9b82e51a07 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -1012,9 +1012,8 @@ static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
  * Helpers for integration with struct drm_device
  */
 
-/* deprecated; use drmm_vram_mm_init() */
-struct drm_vram_mm *drm_vram_helper_alloc_mm(
-   struct drm_device *dev, uint64_t vram_base, size_t vram_size)
+static struct drm_vram_mm *drm_vram_helper_alloc_mm(struct drm_device *dev, 
uint64_t vram_base,
+   size_t vram_size)
 {
int ret;
 
@@ -1036,9 +1035,8 @@ struct drm_vram_mm *drm_vram_helper_alloc_mm(
dev->vram_mm = NULL;
return ERR_PTR(ret);
 }
-EXPORT_SYMBOL(drm_vram_helper_alloc_mm);
 
-void drm_vram_helper_release_mm(struct drm_device *dev)
+static void drm_vram_helper_release_mm(struct drm_device *dev)
 {
if (!dev->vram_mm)
return;
@@ -1047,7 +1045,6 @@ void drm_vram_helper_release_mm(struct drm_device *dev)
kfree(dev->vram_mm);
dev->vram_mm = NULL;
 }
-EXPORT_SYMBOL(drm_vram_helper_release_mm);
 
 static void drm_vram_mm_release(struct drm_device *dev, void *ptr)
 {
diff --git a/include/drm/drm_gem_vram_helper.h 
b/include/drm/drm_gem_vram_helper.h
index f48d181c824b..d3cf06c9af65 100644
--- a/include/drm/drm_gem_vram_helper.h
+++ b/include/drm/drm_gem_vram_helper.h
@@ -204,10 +204,6 @@ void drm_vram_mm_debugfs_init(struct drm_minor *minor);
  * Helpers for integration with struct drm_device
  */
 
-struct drm_vram_mm *drm_vram_helper_alloc_mm(
-   struct drm_device *dev, uint64_t vram_base, size_t vram_size);
-void drm_vram_helper_release_mm(struct drm_device *dev);
-
 int drmm_vram_helper_init(struct drm_device *dev, uint64_t vram_base,
  size_t vram_size);
 
-- 
2.32.0



Re: [PATCH] dma-buf: fix and rework dma_buf_poll v4

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 2:36 PM Christian König
 wrote:
>
> Daniel pointed me towards this function and there are multiple obvious 
> problems
> in the implementation.
>
> First of all the retry loop is not working as intended. In general the retry
> makes only sense if you grab the reference first and then check the sequence
> values.
>
> Then we should always also wait for the exclusive fence.
>
> It's also good practice to keep the reference around when installing callbacks
> to fences you don't own.
>
> And last the whole implementation was unnecessary complex and rather hard to
> understand which could lead to probably unexpected behavior of the IOCTL.
>
> Fix all this by reworking the implementation from scratch. Dropping the
> whole RCU approach and taking the lock instead.
>
> Only mildly tested and needs a thoughtful review of the code.

prime_vgem.c has some basic stuff, but it might actually encoding the
broken behaviour. Would be good to extend/fix that I think so we don't
entirely rely on review. We can't really build easily on top of the
testcase Jason created for import/export, since for implicit sync we
need some driver that attaches the fences for us.

There's also a vc4 one, but I guess that's less useful for us :-)

> v2: fix the reference counting as well
> v3: keep the excl fence handling as is for stable
> v4: back to testing all fences, drop RCU
>
> Signed-off-by: Christian König 
> CC: sta...@vger.kernel.org
> ---
>  drivers/dma-buf/dma-buf.c | 132 +-
>  include/linux/dma-buf.h   |   2 +-
>  2 files changed, 46 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index eadd1eaa2fb5..192c4d34704b 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -72,7 +72,7 @@ static void dma_buf_release(struct dentry *dentry)
>  * If you hit this BUG() it means someone dropped their ref to the
>  * dma-buf while still having pending operation to the buffer.
>  */
> -   BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
> +   BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);
>
> dmabuf->ops->release(dmabuf);
>
> @@ -202,16 +202,19 @@ static void dma_buf_poll_cb(struct dma_fence *fence, 
> struct dma_fence_cb *cb)
> wake_up_locked_poll(dcb->poll, dcb->active);
> dcb->active = 0;
> spin_unlock_irqrestore(&dcb->poll->lock, flags);
> +   dma_fence_put(fence);
>  }
>
>  static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
>  {
> +   struct dma_buf_poll_cb_t *dcb;
> struct dma_buf *dmabuf;
> struct dma_resv *resv;
> struct dma_resv_list *fobj;
> -   struct dma_fence *fence_excl;
> +   struct dma_fence *fence;
> +   unsigned shared_count;
> __poll_t events;
> -   unsigned shared_count, seq;
> +   int r, i;
>
> dmabuf = file->private_data;
> if (!dmabuf || !dmabuf->resv)
> @@ -225,101 +228,56 @@ static __poll_t dma_buf_poll(struct file *file, 
> poll_table *poll)
> if (!events)
> return 0;
>
> -retry:
> -   seq = read_seqcount_begin(&resv->seq);
> -   rcu_read_lock();
> +   dcb = events & EPOLLOUT ? &dmabuf->cb_out : &dmabuf->cb_in;
> +
> +   /* Only queue a new one if we are not still waiting for the old one */
> +   spin_lock_irq(&dmabuf->poll.lock);
> +   if (dcb->active)
> +   events = 0;
> +   else
> +   dcb->active = events;
> +   spin_unlock_irq(&dmabuf->poll.lock);
> +   if (!events)
> +   return 0;
> +
> +   dma_resv_lock(resv, NULL);
>
> -   fobj = rcu_dereference(resv->fence);
> -   if (fobj)
> +   fobj = dma_resv_get_list(resv);
> +   if (fobj && events & EPOLLOUT)
> shared_count = fobj->shared_count;
> else
> shared_count = 0;
> -   fence_excl = rcu_dereference(resv->fence_excl);
> -   if (read_seqcount_retry(&resv->seq, seq)) {
> -   rcu_read_unlock();
> -   goto retry;
> -   }
>
> -   if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) {
> -   struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl;
> -   __poll_t pevents = EPOLLIN;
> -
> -   if (shared_count == 0)
> -   pevents |= EPOLLOUT;
> -
> -   spin_lock_irq(&dmabuf->poll.lock);
> -   if (dcb->active) {
> -   dcb->active |= pevents;
> -   events &= ~pevents;
> -   } else
> -   dcb->active = pevents;
> -   spin_unlock_irq(&dmabuf->poll.lock);
> -
> -   if (events & pevents) {
> -   if (!dma_fence_get_rcu(fence_excl)) {
> -   /* force a recheck */
> -   events &= ~pevents;
> -   dma_buf_po

Re: [PATCH 1/3] drm/bochs: Move to tiny/

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 04:06:57PM +0200, Thomas Zimmermann wrote:
> The bochs driver is only ~600 lines of code. Putting it into tiny/
> cleans up the DRM directory slightly. Some style problems were fixed
> and unneeded include statements were removed. No functional changes.
> 
> Signed-off-by: Thomas Zimmermann 

Really nice! On the series:

Acked-by: Daniel Vetter 

I think I've found one missing static below.

Cheers, Daniel

> ---
>  MAINTAINERS   |   2 +-
>  drivers/gpu/drm/Kconfig   |   2 -
>  drivers/gpu/drm/Makefile  |   1 -
>  drivers/gpu/drm/bochs/Kconfig |  11 -
>  drivers/gpu/drm/bochs/Makefile|   4 -
>  drivers/gpu/drm/bochs/bochs.h |  98 
>  drivers/gpu/drm/bochs/bochs_drv.c | 205 
>  drivers/gpu/drm/bochs/bochs_hw.c  | 323 -
>  drivers/gpu/drm/bochs/bochs_kms.c | 178 ---
>  drivers/gpu/drm/bochs/bochs_mm.c  |  24 -
>  drivers/gpu/drm/tiny/Kconfig  |  13 +
>  drivers/gpu/drm/tiny/Makefile |   1 +
>  drivers/gpu/drm/tiny/bochs.c  | 768 ++
>  13 files changed, 783 insertions(+), 847 deletions(-)
>  delete mode 100644 drivers/gpu/drm/bochs/Kconfig
>  delete mode 100644 drivers/gpu/drm/bochs/Makefile
>  delete mode 100644 drivers/gpu/drm/bochs/bochs.h
>  delete mode 100644 drivers/gpu/drm/bochs/bochs_drv.c
>  delete mode 100644 drivers/gpu/drm/bochs/bochs_hw.c
>  delete mode 100644 drivers/gpu/drm/bochs/bochs_kms.c
>  delete mode 100644 drivers/gpu/drm/bochs/bochs_mm.c
>  create mode 100644 drivers/gpu/drm/tiny/bochs.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index dcb5f0d32303..95bad8d45200 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5680,7 +5680,7 @@ M:  Gerd Hoffmann 
>  L:   virtualizat...@lists.linux-foundation.org
>  S:   Maintained
>  T:   git git://anongit.freedesktop.org/drm/drm-misc
> -F:   drivers/gpu/drm/bochs/
> +F:   drivers/gpu/drm/tiny/bochs.c
>  
>  DRM DRIVER FOR BOE HIMAX8279D PANELS
>  M:   Jerry Han 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 1366d8d4610a..0d372354c2d0 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -322,8 +322,6 @@ source "drivers/gpu/drm/tilcdc/Kconfig"
>  
>  source "drivers/gpu/drm/qxl/Kconfig"
>  
> -source "drivers/gpu/drm/bochs/Kconfig"
> -
>  source "drivers/gpu/drm/virtio/Kconfig"
>  
>  source "drivers/gpu/drm/msm/Kconfig"
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 12e6f4e485ed..ad1112154898 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -98,7 +98,6 @@ obj-y   += omapdrm/
>  obj-$(CONFIG_DRM_SUN4I) += sun4i/
>  obj-y+= tilcdc/
>  obj-$(CONFIG_DRM_QXL) += qxl/
> -obj-$(CONFIG_DRM_BOCHS) += bochs/
>  obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
>  obj-$(CONFIG_DRM_MSM) += msm/
>  obj-$(CONFIG_DRM_TEGRA) += tegra/
> diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig
> deleted file mode 100644
> index 7bcdf294fed8..
> --- a/drivers/gpu/drm/bochs/Kconfig
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -config DRM_BOCHS
> - tristate "DRM Support for bochs dispi vga interface (qemu stdvga)"
> - depends on DRM && PCI && MMU
> - select DRM_KMS_HELPER
> - select DRM_VRAM_HELPER
> - select DRM_TTM
> - select DRM_TTM_HELPER
> - help
> -   Choose this option for qemu.
> -   If M is selected the module will be called bochs-drm.
> diff --git a/drivers/gpu/drm/bochs/Makefile b/drivers/gpu/drm/bochs/Makefile
> deleted file mode 100644
> index 55473371300f..
> --- a/drivers/gpu/drm/bochs/Makefile
> +++ /dev/null
> @@ -1,4 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_hw.o
> -
> -obj-$(CONFIG_DRM_BOCHS)  += bochs-drm.o
> diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
> deleted file mode 100644
> index e9645c612aff..
> --- a/drivers/gpu/drm/bochs/bochs.h
> +++ /dev/null
> @@ -1,98 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -
> -#include 
> -#include 
> -
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -
> -/* -- */
> -
> -#define VBE_DISPI_IOPORT_INDEX   0x01CE
> -#define VBE_DISPI_IOPORT_DATA0x01CF
> -
> -#define VBE_DISPI_INDEX_ID   0x0
> -#define VBE_DISPI_INDEX_XRES 0x1
> -#define VBE_DISPI_INDEX_YRES 0x2
> -#define VBE_DISPI_INDEX_BPP  0x3
> -#define VBE_DISPI_INDEX_ENABLE   0x4
> -#define VBE_DISPI_INDEX_BANK 0x5
> -#define VBE_DISPI_INDEX_VIRT_WIDTH   0x6
> -#define VBE_DISPI_INDEX_VIRT_HEIGHT  0x7
> -#define VBE_DISPI_INDEX_X_OFFSET 0x8
> -#define VBE_DISPI_INDEX_Y_OFFSET 0x9
> -#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0x

Re: [PATCH v6 14/16] drm/panfrost: Kill in-flight jobs on FD close

2021-06-30 Thread Steven Price
On 30/06/2021 07:27, Boris Brezillon wrote:
> If the process who submitted these jobs decided to close the FD before
> the jobs are done it probably means it doesn't care about the result.
> 
> v5:
> * Add a panfrost_exception_is_fault() helper and the
>   DRM_PANFROST_EXCEPTION_MAX_NON_FAULT value
> 
> v4:
> * Don't disable/restore irqs when taking the job_lock (not needed since
>   this lock is never taken from an interrupt context)
> 
> v3:
> * Set fence error to ECANCELED when a TERMINATED exception is received
> 
> Signed-off-by: Boris Brezillon 
> ---
>  drivers/gpu/drm/panfrost/panfrost_device.h |  7 
>  drivers/gpu/drm/panfrost/panfrost_job.c| 42 ++
>  2 files changed, 43 insertions(+), 6 deletions(-)

The panfrost_exception_is_fault() makes the code much more readable -
thanks!

Reviewed-by: Steven Price 

> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
> b/drivers/gpu/drm/panfrost/panfrost_device.h
> index 68e93b7e5b61..193cd87f643c 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
> @@ -184,6 +184,7 @@ enum drm_panfrost_exception_type {
>   DRM_PANFROST_EXCEPTION_KABOOM = 0x05,
>   DRM_PANFROST_EXCEPTION_EUREKA = 0x06,
>   DRM_PANFROST_EXCEPTION_ACTIVE = 0x08,
> + DRM_PANFROST_EXCEPTION_MAX_NON_FAULT = 0x3f,
>   DRM_PANFROST_EXCEPTION_JOB_CONFIG_FAULT = 0x40,
>   DRM_PANFROST_EXCEPTION_JOB_POWER_FAULT = 0x41,
>   DRM_PANFROST_EXCEPTION_JOB_READ_FAULT = 0x42,
> @@ -244,6 +245,12 @@ enum drm_panfrost_exception_type {
>   DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_3 = 0xef,
>  };
>  
> +static inline bool
> +panfrost_exception_is_fault(u32 exception_code)
> +{
> + return exception_code > DRM_PANFROST_EXCEPTION_MAX_NON_FAULT;
> +}
> +
>  const char *panfrost_exception_name(u32 exception_code);
>  bool panfrost_exception_needs_reset(const struct panfrost_device *pfdev,
>   u32 exception_code);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index cf5f9e8b2a27..8a0db9571bfd 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -483,14 +483,21 @@ static void panfrost_job_handle_irq(struct 
> panfrost_device *pfdev, u32 status)
>  
>   if (status & JOB_INT_MASK_ERR(j)) {
>   u32 js_status = job_read(pfdev, JS_STATUS(j));
> + const char *exception_name = 
> panfrost_exception_name(js_status);
>  
>   job_write(pfdev, JS_COMMAND_NEXT(j), JS_COMMAND_NOP);
>  
> - dev_err(pfdev->dev, "js fault, js=%d, status=%s, 
> head=0x%x, tail=0x%x",
> - j,
> - panfrost_exception_name(js_status),
> - job_read(pfdev, JS_HEAD_LO(j)),
> - job_read(pfdev, JS_TAIL_LO(j)));
> + if (!panfrost_exception_is_fault(js_status)) {
> + dev_dbg(pfdev->dev, "js interrupt, js=%d, 
> status=%s, head=0x%x, tail=0x%x",
> + j, exception_name,
> + job_read(pfdev, JS_HEAD_LO(j)),
> + job_read(pfdev, JS_TAIL_LO(j)));
> + } else {
> + dev_err(pfdev->dev, "js fault, js=%d, 
> status=%s, head=0x%x, tail=0x%x",
> + j, exception_name,
> + job_read(pfdev, JS_HEAD_LO(j)),
> + job_read(pfdev, JS_TAIL_LO(j)));
> + }
>  
>   /* If we need a reset, signal it to the timeout
>* handler, otherwise, update the fence error field and
> @@ -499,7 +506,16 @@ static void panfrost_job_handle_irq(struct 
> panfrost_device *pfdev, u32 status)
>   if (panfrost_exception_needs_reset(pfdev, js_status)) {
>   drm_sched_fault(&pfdev->js->queue[j].sched);
>   } else {
> - dma_fence_set_error(pfdev->jobs[j]->done_fence, 
> -EINVAL);
> + int error = 0;
> +
> + if (js_status == 
> DRM_PANFROST_EXCEPTION_TERMINATED)
> + error = -ECANCELED;
> + else if (panfrost_exception_is_fault(js_status))
> + error = -EINVAL;
> +
> + if (error)
> + 
> dma_fence_set_error(pfdev->jobs[j]->done_fence, error);
> +
>   status |= JOB_INT_MASK_DONE(j);
>   }
>   }
> @@ -665,10 +681,24 @@ int panfrost_job_open(struct panfrost_file_priv 
> *panfrost_priv)
>  
>  void panfrost_job_close(struc

Re: [PATCH v3 1/2] drm/i915: Use the correct IRQ during resume

2021-06-30 Thread Thomas Zimmermann

Hi

Am 30.06.21 um 12:49 schrieb Daniel Vetter:

On Wed, Jun 30, 2021 at 11:52:27AM +0200, Thomas Zimmermann wrote:

The code in xcs_resume() probably didn't work as intended. It uses
struct drm_device.irq, which is allocated to 0, but never initialized
by i915 to the device's interrupt number.

v3:
* also use intel_synchronize_hardirq() at another callsite
v2:
* wrap irq code in intel_synchronize_hardirq() (Ville)

Signed-off-by: Thomas Zimmermann 
Fixes: 536f77b1caa0 ("drm/i915/gt: Call stop_ring() from ring resume, again")
Cc: Chris Wilson 
Cc: Mika Kuoppala 
Cc: Daniel Vetter 
Cc: Rodrigo Vivi 
Cc: Joonas Lahtinen 
Cc: Maarten Lankhorst 
Cc: Lucas De Marchi 
---
  drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 2 +-
  drivers/gpu/drm/i915/gt/intel_ring_submission.c | 2 +-
  drivers/gpu/drm/i915/i915_irq.c | 5 +
  drivers/gpu/drm/i915/i915_irq.h | 1 +
  4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 88694822716a..5ca3d1664335 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1229,7 +1229,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
return true;
  
  	/* Waiting to drain ELSP? */

-   synchronize_hardirq(to_pci_dev(engine->i915->drm.dev)->irq);
+   intel_synchronize_hardirq(engine->i915);
intel_engine_flush_submission(engine);
  
  	/* ELSP is empty, but there are ready requests? E.g. after reset */

diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 5d42a12ef3d6..1b5a22a83db6 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -185,7 +185,7 @@ static int xcs_resume(struct intel_engine_cs *engine)
 ring->head, ring->tail);
  
  	/* Double check the ring is empty & disabled before we resume */

-   synchronize_hardirq(engine->i915->drm.irq);
+   intel_synchronize_hardirq(engine->i915);
if (!stop_ring(engine))
goto err;
  
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c

index 7d0ce8b9f8ed..2203dca19895 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4575,3 +4575,8 @@ void intel_synchronize_irq(struct drm_i915_private *i915)
  {
synchronize_irq(to_pci_dev(i915->drm.dev)->irq);
  }
+
+void intel_synchronize_hardirq(struct drm_i915_private *i915)
+{
+   synchronize_hardirq(to_pci_dev(i915->drm.dev)->irq);


I honestly think the hardirq here is about as much cargo-culted as using
the wrong irq number.

I'd just use intel_synchronize_irq in both places and see whether CI
complains, then go with that.


Well, ok. I don't think I have Sandybridge HW available. Would the Intel 
CI infrastructure catch any problems with such a change?


Best regards
Thomas


-Daniel


+}
diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h
index db34d5dbe402..e43b6734f21b 100644
--- a/drivers/gpu/drm/i915/i915_irq.h
+++ b/drivers/gpu/drm/i915/i915_irq.h
@@ -94,6 +94,7 @@ void intel_runtime_pm_disable_interrupts(struct 
drm_i915_private *dev_priv);
  void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
  bool intel_irqs_enabled(struct drm_i915_private *dev_priv);
  void intel_synchronize_irq(struct drm_i915_private *i915);
+void intel_synchronize_hardirq(struct drm_i915_private *i915);
  
  int intel_get_crtc_scanline(struct intel_crtc *crtc);

  void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
--
2.32.0





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



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH 1/2] drm/i915/ttm: Reorganize the ttm move code somewhat

2021-06-30 Thread Matthew Auld
On Thu, 24 Jun 2021 at 20:31, Thomas Hellström
 wrote:
>
> In order to make the code a bit more readable and to facilitate
> async memcpy moves, reorganize the move code a little. Determine
> at an early stage whether to copy or to clear.
>
> Signed-off-by: Thomas Hellström 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 70 ++---
>  1 file changed, 40 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index c39d982c4fa6..4e529adcdfc7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -431,6 +431,7 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj,
>  }
>
>  static int i915_ttm_accel_move(struct ttm_buffer_object *bo,
> +  bool clear,
>struct ttm_resource *dst_mem,
>struct sg_table *dst_st)
>  {
> @@ -449,13 +450,10 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
> *bo,
> return -EINVAL;
>
> dst_level = i915_ttm_cache_level(i915, dst_mem, ttm);
> -   if (!ttm || !ttm_tt_is_populated(ttm)) {
> +   if (clear) {
> if (bo->type == ttm_bo_type_kernel)
> return -EINVAL;

Was that meant to be:
return 0:

?

Also does that mean we are incorrectly falling back to memset, for
non-userspace objects, instead of making it a noop?

>
> -   if (ttm && !(ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC))
> -   return 0;
> -
> intel_engine_pm_get(i915->gt.migrate.context->engine);
> ret = intel_context_migrate_clear(i915->gt.migrate.context, 
> NULL,
>   dst_st->sgl, dst_level,
> @@ -489,27 +487,53 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
> *bo,
> return ret;
>  }
>
> -static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
> -struct ttm_operation_ctx *ctx,
> -struct ttm_resource *dst_mem,
> -struct ttm_place *hop)
> +static void __i915_ttm_move(struct ttm_buffer_object *bo, bool clear,
> +   struct ttm_resource *dst_mem,
> +   struct sg_table *dst_st)
>  {
> struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
> -   struct ttm_resource_manager *dst_man =
> -   ttm_manager_type(bo->bdev, dst_mem->mem_type);
> struct intel_memory_region *dst_reg, *src_reg;
> union {
> struct ttm_kmap_iter_tt tt;
> struct ttm_kmap_iter_iomap io;
> } _dst_iter, _src_iter;
> struct ttm_kmap_iter *dst_iter, *src_iter;
> -   struct sg_table *dst_st;
> int ret;
>
> dst_reg = i915_ttm_region(bo->bdev, dst_mem->mem_type);
> src_reg = i915_ttm_region(bo->bdev, bo->resource->mem_type);
> GEM_BUG_ON(!dst_reg || !src_reg);
>
> +   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_st);
> +   if (ret) {

One future consideration is flat CCS where I don't think we can easily
fall back to memcpy for userspace objects. Maybe we can make this
fallback conditional on DG1 or !ALLOC_USER for now, or just add a
TODO?

> +   dst_iter = !cpu_maps_iomem(dst_mem) ?
> +   ttm_kmap_iter_tt_init(&_dst_iter.tt, bo->ttm) :
> +   ttm_kmap_iter_iomap_init(&_dst_iter.io, 
> &dst_reg->iomap,
> +dst_st, 
> dst_reg->region.start);
> +
> +   src_iter = !cpu_maps_iomem(bo->resource) ?
> +   ttm_kmap_iter_tt_init(&_src_iter.tt, bo->ttm) :
> +   ttm_kmap_iter_iomap_init(&_src_iter.io, 
> &src_reg->iomap,
> +obj->ttm.cached_io_st,
> +src_reg->region.start);
> +
> +   ttm_move_memcpy(bo, dst_mem->num_pages, dst_iter, src_iter);
> +   }
> +}
> +
> +static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
> +struct ttm_operation_ctx *ctx,
> +struct ttm_resource *dst_mem,
> +struct ttm_place *hop)
> +{
> +   struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
> +   struct ttm_resource_manager *dst_man =
> +   ttm_manager_type(bo->bdev, dst_mem->mem_type);
> +   struct ttm_tt *ttm = bo->ttm;
> +   struct sg_table *dst_st;
> +   bool clear;
> +   int ret;
> +
> /* Sync for now. We could do the actual copy async. */
> ret = ttm_bo_wait_ctx(bo, ctx);
> if (ret)
> @@ -526,9 +550,8 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, 
> bool evict,
> }
>
> /* Populate ttm with pages if needed. Typically system memory. */
> -   if (b

Re: [PATCH] dma-buf: fix and rework dma_buf_poll v4

2021-06-30 Thread Christian König

Am 30.06.21 um 16:07 schrieb Daniel Vetter:

On Wed, Jun 30, 2021 at 2:36 PM Christian König
 wrote:

Daniel pointed me towards this function and there are multiple obvious problems
in the implementation.

First of all the retry loop is not working as intended. In general the retry
makes only sense if you grab the reference first and then check the sequence
values.

Then we should always also wait for the exclusive fence.

It's also good practice to keep the reference around when installing callbacks
to fences you don't own.

And last the whole implementation was unnecessary complex and rather hard to
understand which could lead to probably unexpected behavior of the IOCTL.

Fix all this by reworking the implementation from scratch. Dropping the
whole RCU approach and taking the lock instead.

Only mildly tested and needs a thoughtful review of the code.

prime_vgem.c has some basic stuff, but it might actually encoding the
broken behaviour. Would be good to extend/fix that I think so we don't
entirely rely on review. We can't really build easily on top of the
testcase Jason created for import/export, since for implicit sync we
need some driver that attaches the fences for us.


My question is if I can just send that to 
intel-...@lists.freedesktop.org and the CI will pick it up?




There's also a vc4 one, but I guess that's less useful for us :-)


v2: fix the reference counting as well
v3: keep the excl fence handling as is for stable
v4: back to testing all fences, drop RCU

Signed-off-by: Christian König 
CC: sta...@vger.kernel.org
---
  drivers/dma-buf/dma-buf.c | 132 +-
  include/linux/dma-buf.h   |   2 +-
  2 files changed, 46 insertions(+), 88 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index eadd1eaa2fb5..192c4d34704b 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -72,7 +72,7 @@ static void dma_buf_release(struct dentry *dentry)
  * If you hit this BUG() it means someone dropped their ref to the
  * dma-buf while still having pending operation to the buffer.
  */
-   BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
+   BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);

 dmabuf->ops->release(dmabuf);

@@ -202,16 +202,19 @@ static void dma_buf_poll_cb(struct dma_fence *fence, 
struct dma_fence_cb *cb)
 wake_up_locked_poll(dcb->poll, dcb->active);
 dcb->active = 0;
 spin_unlock_irqrestore(&dcb->poll->lock, flags);
+   dma_fence_put(fence);
  }

  static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
  {
+   struct dma_buf_poll_cb_t *dcb;
 struct dma_buf *dmabuf;
 struct dma_resv *resv;
 struct dma_resv_list *fobj;
-   struct dma_fence *fence_excl;
+   struct dma_fence *fence;
+   unsigned shared_count;
 __poll_t events;
-   unsigned shared_count, seq;
+   int r, i;

 dmabuf = file->private_data;
 if (!dmabuf || !dmabuf->resv)
@@ -225,101 +228,56 @@ static __poll_t dma_buf_poll(struct file *file, 
poll_table *poll)
 if (!events)
 return 0;

-retry:
-   seq = read_seqcount_begin(&resv->seq);
-   rcu_read_lock();
+   dcb = events & EPOLLOUT ? &dmabuf->cb_out : &dmabuf->cb_in;
+
+   /* Only queue a new one if we are not still waiting for the old one */
+   spin_lock_irq(&dmabuf->poll.lock);
+   if (dcb->active)
+   events = 0;
+   else
+   dcb->active = events;
+   spin_unlock_irq(&dmabuf->poll.lock);
+   if (!events)
+   return 0;
+
+   dma_resv_lock(resv, NULL);

-   fobj = rcu_dereference(resv->fence);
-   if (fobj)
+   fobj = dma_resv_get_list(resv);
+   if (fobj && events & EPOLLOUT)
 shared_count = fobj->shared_count;
 else
 shared_count = 0;
-   fence_excl = rcu_dereference(resv->fence_excl);
-   if (read_seqcount_retry(&resv->seq, seq)) {
-   rcu_read_unlock();
-   goto retry;
-   }

-   if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) {
-   struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl;
-   __poll_t pevents = EPOLLIN;
-
-   if (shared_count == 0)
-   pevents |= EPOLLOUT;
-
-   spin_lock_irq(&dmabuf->poll.lock);
-   if (dcb->active) {
-   dcb->active |= pevents;
-   events &= ~pevents;
-   } else
-   dcb->active = pevents;
-   spin_unlock_irq(&dmabuf->poll.lock);
-
-   if (events & pevents) {
-   if (!dma_fence_get_rcu(fence_excl)) {
-   /* force a recheck */
-   events &= ~pevents;
-   dma_buf_poll_cb(NULL, &dcb->cb);
-   } els

Re: [PATCH 2/2] drm/ttm, drm/i915: Update ttm_move_memcpy for async use

2021-06-30 Thread Matthew Auld
On Thu, 24 Jun 2021 at 20:31, Thomas Hellström
 wrote:
>
> The buffer object argument to ttm_move_memcpy was only used to
> determine whether the destination memory should be cleared only
> or whether we should copy data. Replace it with a "clear" bool, and
> update the callers.
>
> The intention here is to be able to use ttm_move_memcpy() async under
> a dma-fence as a fallback if an accelerated blit fails in a security-
> critical path where data might leak if the blit is not properly
> performed. For that purpose the bo is an unsuitable argument since
> its relevant members might already have changed at call time.
>
> Finally, update the ttm_move_memcpy kerneldoc that seems to have
> ended up with a stale version.
>
> Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 


[PATCH 0/6] Add support to the mmsys driver to be a reset controller

2021-06-30 Thread Enric Balletbo i Serra
Dear all,

The following patchset is a reimplementation of the patch sent by Jitao
Shi [1] some time ago. As suggested by Chun-Kuang Hu, this time the
reset is done using the reset API, where the mmsys driver is the reset
controller and the mtk_dsi driver is the reset consumer.

Note that the first patch is kind of unrelated change, it's just a
cleanup but is needed if you want to apply all the following patches
cleanly.

This patchset is important in order to have the DSI panel working on some
kukui MT8183 Chromebooks (i.e Lenovo IdeaPad Duet). Without it, you just
get a black screen.

Best regards,
  Enric

[1] 
https://lore.kernel.org/linux-arm-kernel/20210420132614.150242-4-jitao@mediatek.com/

Enric Balletbo i Serra (6):
  arm64: dts: mediatek: Move reset controller constants into common
location
  dt-bindings: mediatek: Add #reset-cells to mmsys system controller
  arm64: dts: mt8173: Add the mmsys reset bit to reset the dsi0
  arm64: dts: mt8183: Add the mmsys reset bit to reset the dsi0
  soc: mediatek: mmsys: Add reset controller support
  drm/mediatek: mtk_dsi: Reset the dsi0 hardware

 .../bindings/arm/mediatek/mediatek,mmsys.txt  |  2 +
 arch/arm64/boot/dts/mediatek/mt8173.dtsi  |  2 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi  |  5 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c|  5 +-
 drivers/soc/mediatek/mtk-mmsys.c  | 69 +++
 drivers/soc/mediatek/mtk-mmsys.h  |  2 +
 .../mt2712-resets.h   |  0
 include/dt-bindings/reset/mt8173-resets.h |  2 +
 .../mt8183-resets.h   |  3 +
 .../mt8192-resets.h   |  0
 10 files changed, 87 insertions(+), 3 deletions(-)
 rename include/dt-bindings/{reset-controller => reset}/mt2712-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/mt8183-resets.h (98%)
 rename include/dt-bindings/{reset-controller => reset}/mt8192-resets.h (100%)

-- 
2.30.2



[PATCH 6/6] drm/mediatek: mtk_dsi: Reset the dsi0 hardware

2021-06-30 Thread Enric Balletbo i Serra
Reset dsi0 HW to default when power on. This prevents to have different
settingbetween the bootloader and the kernel.

As not all Mediatek boards have the reset consumer configured in their
board description, also is not needed on all of them, the reset is optional,
so the change is compatible with all boards.

Cc: Jitao Shi 
Suggested-by: Chun-Kuang Hu 
Signed-off-by: Enric Balletbo i Serra 
---

 drivers/gpu/drm/mediatek/mtk_dsi.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ae403c67cbd9..d8b81e2ab841 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -980,8 +981,10 @@ static int mtk_dsi_bind(struct device *dev, struct device 
*master, void *data)
struct mtk_dsi *dsi = dev_get_drvdata(dev);
 
ret = mtk_dsi_encoder_init(drm, dsi);
+   if (ret)
+   return ret;
 
-   return ret;
+   return device_reset_optional(dev);
 }
 
 static void mtk_dsi_unbind(struct device *dev, struct device *master,
-- 
2.30.2



[PATCH v6 0/4] drm: address potential UAF bugs with drm_master ptrs

2021-06-30 Thread Desmond Cheong Zhi Xi
This patch series addresses potential use-after-free errors when dereferencing 
pointers to struct drm_master. These were identified after one such bug was 
caught by Syzbot in drm_getunique():
https://syzkaller.appspot.com/bug?id=148d2f1dfac64af52ffd27b661981a540724f803

The series is broken up into four patches:

1. Move a call to drm_is_current_master() out from a section locked by 
&dev->mode_config.mutex in drm_mode_getconnector(). This patch does not apply 
to stable.

2. Move a call to _drm_lease_held() out from the section locked by 
&dev->mode_config.idr_mutex in __drm_mode_object_find().

3. Implement a locked version of drm_is_current_master() function that's used 
within drm_auth.c.

4. Identify areas in drm_lease.c where pointers to struct drm_master are 
dereferenced, and ensure that the master pointers are not freed during use.

Changes in v5 -> v6:
- Patch 2:
Add patch 2 to the series. This patch moves the call to _drm_lease_held out 
from the section locked by &dev->mode_config.idr_mutex in 
__drm_mode_object_find.

- Patch 4:
Clarify the kerneldoc for dereferencing drm_file.master, as suggested by Daniel 
Vetter.

Refactor error paths with goto labels so that each function only has a single 
drm_master_put(), as suggested by Emil Velikov.

Modify comparison to NULL into "!master", as suggested by the intel-gfx CI.

Changes in v4 -> v5:
- Patch 1:
Add patch 1 to the series. The changes in patch 1 do not apply to stable 
because they apply to new changes in the drm-misc-next branch. This patch moves 
the call to drm_is_current_master in drm_mode_getconnector out from the section 
locked by &dev->mode_config.mutex.

Additionally, added a missing semicolon to the patch, caught by the intel-gfx 
CI.

- Patch 3:
Move changes to drm_connector.c into patch 1.

Changes in v3 -> v4:
- Patch 3:
Move the call to drm_is_current_master in drm_mode_getconnector out from the 
section locked by &dev->mode_config.mutex. As suggested by Daniel Vetter. This 
avoids a circular lock lock dependency as reported here 
https://patchwork.freedesktop.org/patch/440406/

Additionally, inside drm_is_current_master, instead of grabbing 
&fpriv->master->dev->master_mutex, we grab &fpriv->minor->dev->master_mutex to 
avoid dereferencing a null ptr if fpriv->master is not set.

- Patch 4:
Modify kerneldoc formatting.

Additionally, add a file_priv->master NULL check inside drm_file_get_master, 
and handle the NULL result accordingly in drm_lease.c. As suggested by Daniel 
Vetter.

Changes in v2 -> v3:
- Patch 3:
Move the definition of drm_is_current_master and the _locked version higher up 
in drm_auth.c to avoid needing a forward declaration of 
drm_is_current_master_locked. As suggested by Daniel Vetter.

- Patch 4:
Instead of leaking drm_device.master_mutex into drm_lease.c to protect 
drm_master pointers, add a new drm_file_get_master() function that returns 
drm_file->master while increasing its reference count, to prevent 
drm_file->master from being freed. As suggested by Daniel Vetter.

Changes in v1 -> v2:
- Patch 4:
Move the lock and assignment before the DRM_DEBUG_LEASE in 
drm_mode_get_lease_ioctl, as suggested by Emil Velikov.

Desmond Cheong Zhi Xi (4):
  drm: avoid circular locks in drm_mode_getconnector
  drm: avoid circular locks in __drm_mode_object_find
  drm: add a locked version of drm_is_current_master
  drm: protect drm_master pointers in drm_lease.c

 drivers/gpu/drm/drm_auth.c| 76 +
 drivers/gpu/drm/drm_connector.c   |  5 +-
 drivers/gpu/drm/drm_lease.c   | 81 +++
 drivers/gpu/drm/drm_mode_object.c | 10 ++--
 include/drm/drm_auth.h|  1 +
 include/drm/drm_file.h| 15 --
 6 files changed, 141 insertions(+), 47 deletions(-)

-- 
2.25.1



[PATCH v6 1/4] drm: avoid circular locks in drm_mode_getconnector

2021-06-30 Thread Desmond Cheong Zhi Xi
In preparation for a future patch to take a lock on
drm_device.master_mutex inside drm_is_current_master(), we first move
the call to drm_is_current_master() in drm_mode_getconnector out from the
section locked by &dev->mode_config.mutex. This avoids creating a
circular lock dependency.

Failing to avoid this lock dependency produces the following lockdep
splat:

==
WARNING: possible circular locking dependency detected
5.13.0-rc7-CI-CI_DRM_10254+ #1 Not tainted
--
kms_frontbuffer/1087 is trying to acquire lock:
88810dcd01a8 (&dev->master_mutex){+.+.}-{3:3}, at: 
drm_is_current_master+0x1b/0x40
but task is already holding lock:
88810dcd0488 (&dev->mode_config.mutex){+.+.}-{3:3}, at: 
drm_mode_getconnector+0x1c6/0x4a0
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&dev->mode_config.mutex){+.+.}-{3:3}:
   __mutex_lock+0xab/0x970
   drm_client_modeset_probe+0x22e/0xca0
   __drm_fb_helper_initial_config_and_unlock+0x42/0x540
   intel_fbdev_initial_config+0xf/0x20 [i915]
   async_run_entry_fn+0x28/0x130
   process_one_work+0x26d/0x5c0
   worker_thread+0x37/0x380
   kthread+0x144/0x170
   ret_from_fork+0x1f/0x30
-> #1 (&client->modeset_mutex){+.+.}-{3:3}:
   __mutex_lock+0xab/0x970
   drm_client_modeset_commit_locked+0x1c/0x180
   drm_client_modeset_commit+0x1c/0x40
   __drm_fb_helper_restore_fbdev_mode_unlocked+0x88/0xb0
   drm_fb_helper_set_par+0x34/0x40
   intel_fbdev_set_par+0x11/0x40 [i915]
   fbcon_init+0x270/0x4f0
   visual_init+0xc6/0x130
   do_bind_con_driver+0x1e5/0x2d0
   do_take_over_console+0x10e/0x180
   do_fbcon_takeover+0x53/0xb0
   register_framebuffer+0x22d/0x310
   __drm_fb_helper_initial_config_and_unlock+0x36c/0x540
   intel_fbdev_initial_config+0xf/0x20 [i915]
   async_run_entry_fn+0x28/0x130
   process_one_work+0x26d/0x5c0
   worker_thread+0x37/0x380
   kthread+0x144/0x170
   ret_from_fork+0x1f/0x30
-> #0 (&dev->master_mutex){+.+.}-{3:3}:
   __lock_acquire+0x151e/0x2590
   lock_acquire+0xd1/0x3d0
   __mutex_lock+0xab/0x970
   drm_is_current_master+0x1b/0x40
   drm_mode_getconnector+0x37e/0x4a0
   drm_ioctl_kernel+0xa8/0xf0
   drm_ioctl+0x1e8/0x390
   __x64_sys_ioctl+0x6a/0xa0
   do_syscall_64+0x39/0xb0
   entry_SYSCALL_64_after_hwframe+0x44/0xae
other info that might help us debug this:
Chain exists of: &dev->master_mutex --> &client->modeset_mutex --> 
&dev->mode_config.mutex
 Possible unsafe locking scenario:
   CPU0CPU1
   
  lock(&dev->mode_config.mutex);
   lock(&client->modeset_mutex);
   lock(&dev->mode_config.mutex);
  lock(&dev->master_mutex);
*** DEADLOCK ***
1 lock held by kms_frontbuffer/1087:
 #0: 88810dcd0488 (&dev->mode_config.mutex){+.+.}-{3:3}, at: 
drm_mode_getconnector+0x1c6/0x4a0
stack backtrace:
CPU: 7 PID: 1087 Comm: kms_frontbuffer Not tainted 5.13.0-rc7-CI-CI_DRM_10254+ 
#1
Hardware name: Intel Corporation Ice Lake Client Platform/IceLake U DDR4 SODIMM 
PD RVP TLC, BIOS ICLSFWR1.R00.3234.A01.1906141750 06/14/2019
Call Trace:
 dump_stack+0x7f/0xad
 check_noncircular+0x12e/0x150
 __lock_acquire+0x151e/0x2590
 lock_acquire+0xd1/0x3d0
 __mutex_lock+0xab/0x970
 drm_is_current_master+0x1b/0x40
 drm_mode_getconnector+0x37e/0x4a0
 drm_ioctl_kernel+0xa8/0xf0
 drm_ioctl+0x1e8/0x390
 __x64_sys_ioctl+0x6a/0xa0
 do_syscall_64+0x39/0xb0
 entry_SYSCALL_64_after_hwframe+0x44/0xae

Reported-by: Daniel Vetter 
Signed-off-by: Desmond Cheong Zhi Xi 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/drm_connector.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index da39e7ff6965..2ba257b1ae20 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2414,6 +2414,7 @@ int drm_mode_getconnector(struct drm_device *dev, void 
*data,
struct drm_mode_modeinfo u_mode;
struct drm_mode_modeinfo __user *mode_ptr;
uint32_t __user *encoder_ptr;
+   bool is_current_master;
 
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EOPNOTSUPP;
@@ -2444,9 +2445,11 @@ int drm_mode_getconnector(struct drm_device *dev, void 
*data,
out_resp->connector_type = connector->connector_type;
out_resp->connector_type_id = connector->connector_type_id;
 
+   is_current_master = drm_is_current_master(file_priv);
+
mutex_lock(&dev->mode_config.mutex);
if (out_resp->count_modes == 0) {
-   if (drm_is_current_master(file_priv))
+   if (is_current_master)
connector->funcs->fill_modes(connector,

[PATCH v6 2/4] drm: avoid circular locks in __drm_mode_object_find

2021-06-30 Thread Desmond Cheong Zhi Xi
In a future patch, _drm_lease_held will dereference drm_file->master
only after making a call to drm_file_get_master which increments the
reference count of drm_file->master while holding a lock on
drm_device.master_mutex.

In preparation for this, the call to _drm_lease_held should be moved
out from the section locked by &dev->mode_config.idr_mutex. This
avoids inverting the lock hierarchy for
&dev->master_mutex --> &dev->mode_config.idr_mutex

Signed-off-by: Desmond Cheong Zhi Xi 
---
 drivers/gpu/drm/drm_mode_object.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_object.c 
b/drivers/gpu/drm/drm_mode_object.c
index b26588b52795..63d35f1f98dd 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -146,16 +146,18 @@ struct drm_mode_object *__drm_mode_object_find(struct 
drm_device *dev,
if (obj && obj->id != id)
obj = NULL;
 
-   if (obj && drm_mode_object_lease_required(obj->type) &&
-   !_drm_lease_held(file_priv, obj->id))
-   obj = NULL;
-
if (obj && obj->free_cb) {
if (!kref_get_unless_zero(&obj->refcount))
obj = NULL;
}
mutex_unlock(&dev->mode_config.idr_mutex);
 
+   if (obj && drm_mode_object_lease_required(obj->type) &&
+   !_drm_lease_held(file_priv, obj->id)) {
+   drm_mode_object_put(obj);
+   obj = NULL;
+   }
+
return obj;
 }
 
-- 
2.25.1



[PATCH v6 3/4] drm: add a locked version of drm_is_current_master

2021-06-30 Thread Desmond Cheong Zhi Xi
While checking the master status of the DRM file in
drm_is_current_master(), the device's master mutex should be
held. Without the mutex, the pointer fpriv->master may be freed
concurrently by another process calling drm_setmaster_ioctl(). This
could lead to use-after-free errors when the pointer is subsequently
dereferenced in drm_lease_owner().

The callers of drm_is_current_master() from drm_auth.c hold the
device's master mutex, but external callers do not. Hence, we implement
drm_is_current_master_locked() to be used within drm_auth.c, and
modify drm_is_current_master() to grab the device's master mutex
before checking the master status.

Reported-by: Daniel Vetter 
Signed-off-by: Desmond Cheong Zhi Xi 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/drm_auth.c | 51 --
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index f00e5abdbbf4..ab1863c5a5a0 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -61,6 +61,35 @@
  * trusted clients.
  */
 
+static bool drm_is_current_master_locked(struct drm_file *fpriv)
+{
+   lockdep_assert_held_once(&fpriv->minor->dev->master_mutex);
+
+   return fpriv->is_master && drm_lease_owner(fpriv->master) == 
fpriv->minor->dev->master;
+}
+
+/**
+ * drm_is_current_master - checks whether @priv is the current master
+ * @fpriv: DRM file private
+ *
+ * Checks whether @fpriv is current master on its device. This decides whether 
a
+ * client is allowed to run DRM_MASTER IOCTLs.
+ *
+ * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting
+ * - the current master is assumed to own the non-shareable display hardware.
+ */
+bool drm_is_current_master(struct drm_file *fpriv)
+{
+   bool ret;
+
+   mutex_lock(&fpriv->minor->dev->master_mutex);
+   ret = drm_is_current_master_locked(fpriv);
+   mutex_unlock(&fpriv->minor->dev->master_mutex);
+
+   return ret;
+}
+EXPORT_SYMBOL(drm_is_current_master);
+
 int drm_getmagic(struct drm_device *dev, void *data, struct drm_file 
*file_priv)
 {
struct drm_auth *auth = data;
@@ -223,7 +252,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
if (ret)
goto out_unlock;
 
-   if (drm_is_current_master(file_priv))
+   if (drm_is_current_master_locked(file_priv))
goto out_unlock;
 
if (dev->master) {
@@ -272,7 +301,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
if (ret)
goto out_unlock;
 
-   if (!drm_is_current_master(file_priv)) {
+   if (!drm_is_current_master_locked(file_priv)) {
ret = -EINVAL;
goto out_unlock;
}
@@ -321,7 +350,7 @@ void drm_master_release(struct drm_file *file_priv)
if (file_priv->magic)
idr_remove(&file_priv->master->magic_map, file_priv->magic);
 
-   if (!drm_is_current_master(file_priv))
+   if (!drm_is_current_master_locked(file_priv))
goto out;
 
drm_legacy_lock_master_cleanup(dev, master);
@@ -342,22 +371,6 @@ void drm_master_release(struct drm_file *file_priv)
mutex_unlock(&dev->master_mutex);
 }
 
-/**
- * drm_is_current_master - checks whether @priv is the current master
- * @fpriv: DRM file private
- *
- * Checks whether @fpriv is current master on its device. This decides whether 
a
- * client is allowed to run DRM_MASTER IOCTLs.
- *
- * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting
- * - the current master is assumed to own the non-shareable display hardware.
- */
-bool drm_is_current_master(struct drm_file *fpriv)
-{
-   return fpriv->is_master && drm_lease_owner(fpriv->master) == 
fpriv->minor->dev->master;
-}
-EXPORT_SYMBOL(drm_is_current_master);
-
 /**
  * drm_master_get - reference a master pointer
  * @master: &struct drm_master
-- 
2.25.1



[PATCH v6 4/4] drm: protect drm_master pointers in drm_lease.c

2021-06-30 Thread Desmond Cheong Zhi Xi
Currently, direct copies of drm_file->master pointers should be
protected by drm_device.master_mutex when being dereferenced. This is
because drm_file->master is not invariant for the lifetime of
drm_file. If drm_file is not the creator of master, then
drm_file->is_master is false, and a call to drm_setmaster_ioctl will
invoke drm_new_set_master, which then allocates a new master for
drm_file and puts the old master.

Thus, without holding drm_device.master_mutex, the old value of
drm_file->master could be freed while it is being used by another
concurrent process.

In drm_lease.c, there are multiple instances where drm_file->master is
accessed and dereferenced while drm_device.master_mutex is not
held. This makes drm_lease.c vulnerable to use-after-free bugs.

We address this issue in 3 ways:

1. Clarify in the kerneldoc that drm_file->master is protected by
drm_device.master_mutex.

2. Add a new drm_file_get_master() function that calls drm_master_get
on drm_file->master while holding on to drm_device.master_mutex. Since
drm_master_get increments the reference count of master, this
prevents master from being freed until we unreference it with
drm_master_put.

3. In each case where drm_file->master is directly accessed and
eventually dereferenced in drm_lease.c, we wrap the access in a call
to the new drm_file_get_master function, then unreference the master
pointer once we are done using it.

Reported-by: Daniel Vetter 
Signed-off-by: Desmond Cheong Zhi Xi 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/drm_auth.c  | 25 
 drivers/gpu/drm/drm_lease.c | 81 -
 include/drm/drm_auth.h  |  1 +
 include/drm/drm_file.h  | 15 +--
 4 files changed, 99 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index ab1863c5a5a0..c36a0b72be26 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -384,6 +384,31 @@ struct drm_master *drm_master_get(struct drm_master 
*master)
 }
 EXPORT_SYMBOL(drm_master_get);
 
+/**
+ * drm_file_get_master - reference &drm_file.master of @file_priv
+ * @file_priv: DRM file private
+ *
+ * Increments the reference count of @file_priv's &drm_file.master and returns
+ * the &drm_file.master. If @file_priv has no &drm_file.master, returns NULL.
+ *
+ * Master pointers returned from this function should be unreferenced using
+ * drm_master_put().
+ */
+struct drm_master *drm_file_get_master(struct drm_file *file_priv)
+{
+   struct drm_master *master = NULL;
+
+   mutex_lock(&file_priv->minor->dev->master_mutex);
+   if (!file_priv->master)
+   goto unlock;
+   master = drm_master_get(file_priv->master);
+
+unlock:
+   mutex_unlock(&file_priv->minor->dev->master_mutex);
+   return master;
+}
+EXPORT_SYMBOL(drm_file_get_master);
+
 static void drm_master_destroy(struct kref *kref)
 {
struct drm_master *master = container_of(kref, struct drm_master, 
refcount);
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 00fb433bcef1..92eac73d9001 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -106,10 +106,19 @@ static bool _drm_has_leased(struct drm_master *master, 
int id)
  */
 bool _drm_lease_held(struct drm_file *file_priv, int id)
 {
-   if (!file_priv || !file_priv->master)
+   bool ret;
+   struct drm_master *master;
+
+   if (!file_priv)
return true;
 
-   return _drm_lease_held_master(file_priv->master, id);
+   master = drm_file_get_master(file_priv);
+   if (!master)
+   return true;
+   ret = _drm_lease_held_master(master, id);
+   drm_master_put(&master);
+
+   return ret;
 }
 
 /**
@@ -128,13 +137,22 @@ bool drm_lease_held(struct drm_file *file_priv, int id)
struct drm_master *master;
bool ret;
 
-   if (!file_priv || !file_priv->master || !file_priv->master->lessor)
+   if (!file_priv)
return true;
 
-   master = file_priv->master;
+   master = drm_file_get_master(file_priv);
+   if (!master)
+   return true;
+   if (!master->lessor) {
+   ret = true;
+   goto out;
+   }
mutex_lock(&master->dev->mode_config.idr_mutex);
ret = _drm_lease_held_master(master, id);
mutex_unlock(&master->dev->mode_config.idr_mutex);
+
+out:
+   drm_master_put(&master);
return ret;
 }
 
@@ -154,10 +172,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file 
*file_priv, uint32_t crtcs_in)
int count_in, count_out;
uint32_t crtcs_out = 0;
 
-   if (!file_priv || !file_priv->master || !file_priv->master->lessor)
+   if (!file_priv)
return crtcs_in;
 
-   master = file_priv->master;
+   master = drm_file_get_master(file_priv);
+   if (!master)
+   return crtcs_in;
+   if (!master->lessor) {
+   crtcs_out = crtcs_in;

Re: [PATCH v6 15/16] drm/panfrost: Queue jobs on the hardware

2021-06-30 Thread Steven Price
On 30/06/2021 07:27, Boris Brezillon wrote:
> From: Steven Price 
> 
> The hardware has a set of '_NEXT' registers that can hold a second job
> while the first is executing. Make use of these registers to enqueue a
> second job per slot.
> 
> v5:
> * Fix a comment in panfrost_job_init()
> 
> v3:
> * Fix the done/err job dequeuing logic to get a valid active state
> * Only enable the second slot on GPUs supporting jobchain disambiguation
> * Split interrupt handling in sub-functions
> 
> Signed-off-by: Steven Price 
> Signed-off-by: Boris Brezillon 

FWIW (it has changed a bit since my original version):

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_device.h |   2 +-
>  drivers/gpu/drm/panfrost/panfrost_job.c| 467 +++--
>  2 files changed, 351 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
> b/drivers/gpu/drm/panfrost/panfrost_device.h
> index 193cd87f643c..8b25278f34c8 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
> @@ -102,7 +102,7 @@ struct panfrost_device {
>  
>   struct panfrost_job_slot *js;
>  
> - struct panfrost_job *jobs[NUM_JOB_SLOTS];
> + struct panfrost_job *jobs[NUM_JOB_SLOTS][2];
>   struct list_head scheduled_jobs;
>  
>   struct panfrost_perfcnt *perfcnt;
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index 8a0db9571bfd..71a72fb50e6b 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -4,6 +4,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -140,9 +141,52 @@ static void panfrost_job_write_affinity(struct 
> panfrost_device *pfdev,
>   job_write(pfdev, JS_AFFINITY_NEXT_HI(js), affinity >> 32);
>  }
>  
> +static u32
> +panfrost_get_job_chain_flag(const struct panfrost_job *job)
> +{
> + struct panfrost_fence *f = to_panfrost_fence(job->done_fence);
> +
> + if (!panfrost_has_hw_feature(job->pfdev, 
> HW_FEATURE_JOBCHAIN_DISAMBIGUATION))
> + return 0;
> +
> + return (f->seqno & 1) ? JS_CONFIG_JOB_CHAIN_FLAG : 0;
> +}
> +
> +static struct panfrost_job *
> +panfrost_dequeue_job(struct panfrost_device *pfdev, int slot)
> +{
> + struct panfrost_job *job = pfdev->jobs[slot][0];
> +
> + WARN_ON(!job);
> + pfdev->jobs[slot][0] = pfdev->jobs[slot][1];
> + pfdev->jobs[slot][1] = NULL;
> +
> + return job;
> +}
> +
> +static unsigned int
> +panfrost_enqueue_job(struct panfrost_device *pfdev, int slot,
> +  struct panfrost_job *job)
> +{
> + if (WARN_ON(!job))
> + return 0;
> +
> + if (!pfdev->jobs[slot][0]) {
> + pfdev->jobs[slot][0] = job;
> + return 0;
> + }
> +
> + WARN_ON(pfdev->jobs[slot][1]);
> + pfdev->jobs[slot][1] = job;
> + WARN_ON(panfrost_get_job_chain_flag(job) ==
> + panfrost_get_job_chain_flag(pfdev->jobs[slot][0]));
> + return 1;
> +}
> +
>  static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
>  {
>   struct panfrost_device *pfdev = job->pfdev;
> + unsigned int subslot;
>   u32 cfg;
>   u64 jc_head = job->jc;
>   int ret;
> @@ -168,7 +212,8 @@ static void panfrost_job_hw_submit(struct panfrost_job 
> *job, int js)
>* start */
>   cfg |= JS_CONFIG_THREAD_PRI(8) |
>   JS_CONFIG_START_FLUSH_CLEAN_INVALIDATE |
> - JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE;
> + JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE |
> + panfrost_get_job_chain_flag(job);
>  
>   if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))
>   cfg |= JS_CONFIG_ENABLE_FLUSH_REDUCTION;
> @@ -182,10 +227,17 @@ static void panfrost_job_hw_submit(struct panfrost_job 
> *job, int js)
>   job_write(pfdev, JS_FLUSH_ID_NEXT(js), job->flush_id);
>  
>   /* GO ! */
> - dev_dbg(pfdev->dev, "JS: Submitting atom %p to js[%d] with head=0x%llx",
> - job, js, jc_head);
>  
> - job_write(pfdev, JS_COMMAND_NEXT(js), JS_COMMAND_START);
> + spin_lock(&pfdev->js->job_lock);
> + subslot = panfrost_enqueue_job(pfdev, js, job);
> + /* Don't queue the job if a reset is in progress */
> + if (!atomic_read(&pfdev->reset.pending)) {
> + job_write(pfdev, JS_COMMAND_NEXT(js), JS_COMMAND_START);
> + dev_dbg(pfdev->dev,
> + "JS: Submitting atom %p to js[%d][%d] with head=0x%llx 
> AS %d",
> + job, js, subslot, jc_head, cfg & 0xf);
> + }
> + spin_unlock(&pfdev->js->job_lock);
>  }
>  
>  static int panfrost_acquire_object_fences(struct drm_gem_object **bos,
> @@ -332,7 +384,11 @@ static struct dma_fence *panfrost_job_run(struct 
> drm_sched_job *sched_job)
>   if (unlikely(job->base.s_fence->finished.error))
>   return NULL;
>  

Re: [PATCH v6 16/16] drm/panfrost: Increase the AS_ACTIVE polling timeout

2021-06-30 Thread Steven Price
On 30/06/2021 07:27, Boris Brezillon wrote:
> Experience has shown that 1ms is sometimes not enough, even when the GPU
> is running at its maximum frequency, not to mention that an MMU operation
> might take longer if the GPU is running at a lower frequency, which is
> likely to be the case if devfreq is active.
> 
> Let's pick a significantly bigger timeout value (1ms -> 100ms) to be on
> the safe side.
> 
> v5:
> * New patch
> 
> Signed-off-by: Boris Brezillon 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> index e0356e68e768..0da5b3100ab1 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> @@ -34,7 +34,7 @@ static int wait_ready(struct panfrost_device *pfdev, u32 
> as_nr)
>   /* Wait for the MMU status to indicate there is no active command, in
>* case one is pending. */
>   ret = readl_relaxed_poll_timeout_atomic(pfdev->iomem + AS_STATUS(as_nr),
> - val, !(val & AS_STATUS_AS_ACTIVE), 10, 1000);
> + val, !(val & AS_STATUS_AS_ACTIVE), 10, 10);
>  
>   if (ret) {
>   /* The GPU hung, let's trigger a reset */
> 



[PATCH v5 00/17] New uAPI drm properties for color management

2021-06-30 Thread Werner Sembach
Implementation of https://lkml.org/lkml/2021/5/12/764 now feature complete
albeit not fully tested.

I have now corrected the DSC behavior, but still no wait to test it.

Exact dithering behavior remains a mistery so in case dithering is active it's
not 100% clear what "active bpc" means, or where the "max bpc" limit is applied.

I have no DP MST splitter at hand. I tried my best to not break anything,
but if one who has one could test it would be very helpful.

Things on my TODO list:
- add "min bpc" property
- rewrite "preferred color format" to "force color format"
- make "Broadcast RGB" only affect RGB on AMD too
- remove unreachable enums of "active/preferred/force color format"




[PATCH v5 04/17] drm/amd/display: Add handling for new "active bpc" property

2021-06-30 Thread Werner Sembach
This commit implements the "active bpc" drm property for the AMD GPU
driver.

Signed-off-by: Werner Sembach 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  4 
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f4abb5f215d1..d984de82ae63 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7708,8 +7708,10 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.underscan_vborder_property,
0);
 
-   if (!aconnector->mst_port)
+   if (!aconnector->mst_port) {
drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
+   drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);
+   }
 
/* This defaults to the max in the range, but we want 8bpc for non-edp. 
*/
aconnector->base.state->max_bpc = (connector_type == 
DRM_MODE_CONNECTOR_eDP) ? 16 : 8;
@@ -9078,6 +9080,26 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
mutex_unlock(&dm->dc_lock);
}
 
+   /* Extract information from crtc to communicate it to userspace as 
connector properties */
+   for_each_new_connector_in_state(state, connector, new_con_state, i) {
+   struct drm_crtc *crtc = new_con_state->crtc;
+   struct dc_stream_state *stream;
+
+   if (crtc) {
+   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
crtc);
+   dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+   stream = dm_new_crtc_state->stream;
+
+   if (stream)
+   drm_connector_set_active_bpc_property(connector,
+   stream->timing.flags.DSC ?
+   
stream->timing.dsc_cfg.bits_per_pixel / 16 / 3 :
+   convert_dc_color_depth_into_bpc(
+   
stream->timing.display_color_depth));
+   } else
+   drm_connector_set_active_bpc_property(connector, 0);
+   }
+
/* Count number of newly disabled CRTCs for dropping PM refs later. */
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
  new_crtc_state, i) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5568d4e518e6..0cf38743ec47 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -409,6 +409,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr 
*mgr,
if (connector->max_bpc_property)
drm_connector_attach_max_bpc_property(connector, 8, 16);
 
+   connector->active_bpc_property = master->base.active_bpc_property;
+   if (connector->active_bpc_property)
+   drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);
+
connector->vrr_capable_property = master->base.vrr_capable_property;
if (connector->vrr_capable_property)
drm_connector_attach_vrr_capable_property(connector);
-- 
2.25.1



[PATCH v5 01/17] drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check

2021-06-30 Thread Werner Sembach
Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check that was performed in the
drm_mode_is_420_only() case, but not in the drm_mode_is_420_also() &&
force_yuv420_output case.

Without further knowledge if YCbCr 4:2:0 is supported outside of HDMI,
there is no reason to use RGB when the display
reports drm_mode_is_420_only() even on a non HDMI connection.

This patch also moves both checks in the same if-case. This  eliminates an
extra else-if-case.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 10f878910e55..e081dd3ffb5f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5348,10 +5348,7 @@ static void fill_stream_properties_from_drm_display_mode(
timing_out->v_border_bottom = 0;
/* TODO: un-hardcode */
if (drm_mode_is_420_only(info, mode_in)
-   && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-   timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
-   else if (drm_mode_is_420_also(info, mode_in)
-   && aconnector->force_yuv420_output)
+   || (drm_mode_is_420_also(info, mode_in) && 
aconnector->force_yuv420_output))
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
else if ((connector->display_info.color_formats & 
DRM_COLOR_FORMAT_YCRCB444)
&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-- 
2.25.1



[PATCH v5 02/17] drm/amd/display: Add missing cases convert_dc_color_depth_into_bpc

2021-06-30 Thread Werner Sembach
convert_dc_color_depth_into_bpc() that converts the enum dc_color_depth to
an integer had the casses for COLOR_DEPTH_999 and COLOR_DEPTH_11
missing.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e081dd3ffb5f..f4abb5f215d1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6700,6 +6700,10 @@ static int convert_dc_color_depth_into_bpc (enum 
dc_color_depth display_color_de
return 14;
case COLOR_DEPTH_161616:
return 16;
+   case COLOR_DEPTH_999:
+   return 9;
+   case COLOR_DEPTH_11:
+   return 11;
default:
break;
}
-- 
2.25.1



[PATCH v5 06/17] drm/uAPI: Add "active color format" drm property as feedback for userspace

2021-06-30 Thread Werner Sembach
Add a new general drm property "active color format" which can be used by
graphic drivers to report the used color format back to userspace.

There was no way to check which color format got actually used on a given
monitor. To surely predict this, one must know the exact capabilities of
the monitor, the GPU, and the connection used and what the default
behaviour of the used driver is (e.g. amdgpu prefers YCbCr 4:4:4 while i915
prefers RGB). This property helps eliminating the guessing on this point.

In the future, automatic color calibration for screens might also depend on
this information being available.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/drm_connector.c | 63 +
 include/drm/drm_connector.h |  9 +
 2 files changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 6461d00e8e49..075bdc08d5c3 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -889,6 +889,14 @@ static const struct drm_prop_enum_list 
drm_dp_subconnector_enum_list[] = {
{ DRM_MODE_SUBCONNECTOR_Native,  "Native"}, /* DP */
 };
 
+static const struct drm_prop_enum_list drm_active_color_format_enum_list[] = {
+   { 0, "not applicable" },
+   { DRM_COLOR_FORMAT_RGB444, "rgb" },
+   { DRM_COLOR_FORMAT_YCRCB444, "ycbcr444" },
+   { DRM_COLOR_FORMAT_YCRCB422, "ycbcr422" },
+   { DRM_COLOR_FORMAT_YCRCB420, "ycbcr420" },
+};
+
 DRM_ENUM_NAME_FN(drm_get_dp_subconnector_name,
 drm_dp_subconnector_enum_list)
 
@@ -1206,6 +1214,15 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
= {
  * Drivers shall use drm_connector_attach_active_bpc_property() to install
  * this property. A value of 0 means "not applicable".
  *
+ * active color format:
+ * This read-only property tells userspace the color format actually used
+ * by the hardware display engine "on the cable" on a connector. The chosen
+ * value depends on hardware capabilities, both display engine and
+ * connected monitor. Drivers shall use
+ * drm_connector_attach_active_color_format_property() to install this
+ * property. Possible values are "not applicable", "rgb", "ycbcr444",
+ * "ycbcr422", and "ycbcr420".
+ *
  * Connectors also have one standardized atomic property:
  *
  * CRTC_ID:
@@ -2205,6 +,52 @@ void drm_connector_set_active_bpc_property(struct 
drm_connector *connector, int
 }
 EXPORT_SYMBOL(drm_connector_set_active_bpc_property);
 
+/**
+ * drm_connector_attach_active_color_format_property - attach "active color 
format" property
+ * @connector: connector to attach active color format property on.
+ *
+ * This is used to check the applied color format on a connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_active_color_format_property(struct drm_connector 
*connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->active_color_format_property) {
+   prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 
"active color format",
+   
drm_active_color_format_enum_list,
+   
ARRAY_SIZE(drm_active_color_format_enum_list));
+   if (!prop)
+   return -ENOMEM;
+
+   connector->active_color_format_property = prop;
+   }
+
+   drm_object_attach_property(&connector->base, prop, 0);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_active_color_format_property);
+
+/**
+ * drm_connector_set_active_color_format_property - sets the active color 
format property for a
+ * connector
+ * @connector: drm connector
+ * @active_color_format: color format for the connector currently active "on 
the cable"
+ *
+ * Should be used by atomic drivers to update the active color format over a 
connector.
+ */
+void drm_connector_set_active_color_format_property(struct drm_connector 
*connector,
+   u32 active_color_format)
+{
+   drm_object_property_set_value(&connector->base, 
connector->active_color_format_property,
+ active_color_format);
+}
+EXPORT_SYMBOL(drm_connector_set_active_color_format_property);
+
 /**
  * drm_connector_attach_hdr_output_metadata_property - attach 
"HDR_OUTPUT_METADA" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index eee86de62a5f..8a5197f14e87 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1386,6 +1386,12 @@ struct drm_connector {
 */
struct drm_property *active_bpc_property;
 
+   /**
+* @active_color_format_property: Default connector property for the
+* active color format to be driven out of the connector.

[PATCH v5 05/17] drm/i915/display: Add handling for new "active bpc" property

2021-06-30 Thread Werner Sembach
This commit implements the "active bpc" drm property for the Intel GPU
driver.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/i915/display/intel_display.c | 19 +++
 drivers/gpu/drm/i915/display/intel_dp.c  |  7 +--
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  5 +
 drivers/gpu/drm/i915/display/intel_hdmi.c|  4 +++-
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 6be1b31af07b..1b63d1404d06 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -10839,6 +10839,9 @@ static int intel_atomic_commit(struct drm_device *dev,
 {
struct intel_atomic_state *state = to_intel_atomic_state(_state);
struct drm_i915_private *dev_priv = to_i915(dev);
+   struct drm_connector *connector;
+   struct drm_connector_state *new_conn_state;
+   int i;
int ret = 0;
 
state->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
@@ -10907,6 +10910,22 @@ static int intel_atomic_commit(struct drm_device *dev,
intel_shared_dpll_swap_state(state);
intel_atomic_track_fbs(state);
 
+   /* Extract information from crtc to communicate it to userspace as 
connector properties */
+   for_each_new_connector_in_state(&state->base, connector, 
new_conn_state, i) {
+   struct intel_crtc *crtc = to_intel_crtc(new_conn_state->crtc);
+
+   if (crtc) {
+   struct intel_crtc_state *new_crtc_state =
+   intel_atomic_get_new_crtc_state(state, crtc);
+
+   drm_connector_set_active_bpc_property(connector,
+   new_crtc_state->dsc.compression_enable ?
+   new_crtc_state->dsc.compressed_bpp / 3 :
+   new_crtc_state->pipe_bpp / 3);
+   } else
+   drm_connector_set_active_bpc_property(connector, 0);
+   }
+
drm_atomic_state_get(&state->base);
INIT_WORK(&state->base.commit_work, intel_atomic_commit_work);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6cc03b9e4321..815bc313b954 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4688,10 +4688,13 @@ intel_dp_add_properties(struct intel_dp *intel_dp, 
struct drm_connector *connect
intel_attach_force_audio_property(connector);
 
intel_attach_broadcast_rgb_property(connector);
-   if (HAS_GMCH(dev_priv))
+   if (HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 6, 10);
-   else if (DISPLAY_VER(dev_priv) >= 5)
+   drm_connector_attach_active_bpc_property(connector, 6, 10);
+   } else if (DISPLAY_VER(dev_priv) >= 5) {
drm_connector_attach_max_bpc_property(connector, 6, 12);
+   drm_connector_attach_active_bpc_property(connector, 6, 12);
+   }
 
/* Register HDMI colorspace for case of lspcon */
if (intel_bios_is_lspcon_present(dev_priv, port)) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..16bfc59570a5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -851,6 +851,11 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
if (connector->max_bpc_property)
drm_connector_attach_max_bpc_property(connector, 6, 12);
 
+   connector->active_bpc_property =
+   intel_dp->attached_connector->base.active_bpc_property;
+   if (connector->active_bpc_property)
+   drm_connector_attach_active_bpc_property(connector, 6, 12);
+
return connector;
 
 err:
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 7e51c98c475e..9160e21ac9d6 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2513,8 +2513,10 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, 
struct drm_connector *c
if (DISPLAY_VER(dev_priv) >= 10)
drm_connector_attach_hdr_output_metadata_property(connector);
 
-   if (!HAS_GMCH(dev_priv))
+   if (!HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 8, 12);
+   drm_connector_attach_active_bpc_property(connector, 8, 12);
+   }
 }
 
 /*
-- 
2.25.1



[PATCH v5 03/17] drm/uAPI: Add "active bpc" as feedback channel for "max bpc" drm property

2021-06-30 Thread Werner Sembach
Add a new general drm property "active bpc" which can be used by graphic
drivers to report the applied bit depth per pixel color back to userspace.

While "max bpc" can be used to change the color depth, there was no way to
check which one actually got used. While in theory the driver chooses the
best/highest color depth within the max bpc setting a user might not be
fully aware what his hardware is or isn't capable off. This is meant as a
quick way to double check the setup.

In the future, automatic color calibration for screens might also depend on
this information being available.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/drm_connector.c | 53 +
 include/drm/drm_connector.h |  8 +
 2 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index da39e7ff6965..6461d00e8e49 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1197,6 +1197,15 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
= {
  * drm_connector_attach_max_bpc_property() to create and attach the
  * property to the connector during initialization.
  *
+ * active bpc:
+ * This read-only range property tells userspace the pixel color bit depth
+ * actually used by the hardware display engine "on the cable" on a
+ * connector. This means after display stream compression and dithering
+ * done by the GPU. The chosen value depends on hardware capabilities, both
+ * display engine and connected monitor, and the "max bpc" property.
+ * Drivers shall use drm_connector_attach_active_bpc_property() to install
+ * this property. A value of 0 means "not applicable".
+ *
  * Connectors also have one standardized atomic property:
  *
  * CRTC_ID:
@@ -2152,6 +2161,50 @@ int drm_connector_attach_max_bpc_property(struct 
drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
 
+/**
+ * drm_connector_attach_active_bpc_property - attach "active bpc" property
+ * @connector: connector to attach active bpc property on.
+ * @min: The minimum bit depth supported by the connector.
+ * @max: The maximum bit depth supported by the connector.
+ *
+ * This is used to check the applied bit depth on a connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_active_bpc_property(struct drm_connector *connector, 
int min, int max)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->active_bpc_property) {
+   prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, 
"active bpc",
+min, max);
+   if (!prop)
+   return -ENOMEM;
+
+   connector->active_bpc_property = prop;
+   }
+
+   drm_object_attach_property(&connector->base, prop, 0);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_active_bpc_property);
+
+/**
+ * drm_connector_set_active_bpc_property - sets the active bits per color 
property for a connector
+ * @connector: drm connector
+ * @active_bpc: bits per color for the connector currently active "on the 
cable"
+ *
+ * Should be used by atomic drivers to update the active bits per color over a 
connector.
+ */
+void drm_connector_set_active_bpc_property(struct drm_connector *connector, 
int active_bpc)
+{
+   drm_object_property_set_value(&connector->base, 
connector->active_bpc_property, active_bpc);
+}
+EXPORT_SYMBOL(drm_connector_set_active_bpc_property);
+
 /**
  * drm_connector_attach_hdr_output_metadata_property - attach 
"HDR_OUTPUT_METADA" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 714d1a01c065..eee86de62a5f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1380,6 +1380,12 @@ struct drm_connector {
 */
struct drm_property *max_bpc_property;
 
+   /**
+* @active_bpc_property: Default connector property for the active bpc
+* to be driven out of the connector.
+*/
+   struct drm_property *active_bpc_property;
+
 #define DRM_CONNECTOR_POLL_HPD (1 << 0)
 #define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
 #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
@@ -1702,6 +1708,8 @@ int drm_connector_set_panel_orientation_with_quirk(
int width, int height);
 int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
  int min, int max);
+int drm_connector_attach_active_bpc_property(struct drm_connector *connector, 
int min, int max);
+void drm_connector_set_active_bpc_property(struct drm_connector *connector, 
int active_bpc);
 
 /**
  * struct drm_tile_group - Tile group metadata
-- 
2.25.1



[PATCH v5 13/17] drm/amd/display: Add handling for new "preferred color format" property

2021-06-30 Thread Werner Sembach
This commit implements the "preferred color format" drm property for the
AMD GPU driver.

Signed-off-by: Werner Sembach 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  4 +++
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index b4acedac1ac9..02a5809d4993 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5346,15 +5346,32 @@ static void 
fill_stream_properties_from_drm_display_mode(
timing_out->h_border_right = 0;
timing_out->v_border_top = 0;
timing_out->v_border_bottom = 0;
-   /* TODO: un-hardcode */
-   if (drm_mode_is_420_only(info, mode_in)
-   || (drm_mode_is_420_also(info, mode_in) && 
aconnector->force_yuv420_output))
+
+   if (connector_state
+   && (connector_state->preferred_color_format == 
DRM_COLOR_FORMAT_YCRCB420
+   || aconnector->force_yuv420_output) && 
drm_mode_is_420(info, mode_in))
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
-   else if ((connector->display_info.color_formats & 
DRM_COLOR_FORMAT_YCRCB444)
-   && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
+   else if (connector_state
+   && connector_state->preferred_color_format == 
DRM_COLOR_FORMAT_YCRCB444
+   && connector->display_info.color_formats & 
DRM_COLOR_FORMAT_YCRCB444)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
-   else
+   else if (connector_state
+   && connector_state->preferred_color_format == 
DRM_COLOR_FORMAT_RGB444
+   && !drm_mode_is_420_only(info, mode_in))
timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+   else
+   /*
+* connector_state->preferred_color_format not possible
+* || connector_state->preferred_color_format == 0 (auto)
+* || connector_state->preferred_color_format == 
DRM_COLOR_FORMAT_YCRCB422
+*/
+   if (drm_mode_is_420_only(info, mode_in))
+   timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+   else if ((connector->display_info.color_formats & 
DRM_COLOR_FORMAT_YCRCB444)
+   && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
+   timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
+   else
+   timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
 
timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
timing_out->display_color_depth = convert_color_depth_from_display_info(
@@ -7756,6 +7773,7 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
if (!aconnector->mst_port) {
drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);
+   
drm_connector_attach_preferred_color_format_property(&aconnector->base);

drm_connector_attach_active_color_format_property(&aconnector->base);

drm_connector_attach_active_color_range_property(&aconnector->base);
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index b5d57bbbdd20..2563788ba95a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -413,6 +413,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr 
*mgr,
if (connector->active_bpc_property)
drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);
 
+   connector->preferred_color_format_property = 
master->base.preferred_color_format_property;
+   if (connector->preferred_color_format_property)
+   
drm_connector_attach_preferred_color_format_property(&aconnector->base);
+
connector->active_color_format_property = 
master->base.active_color_format_property;
if (connector->active_color_format_property)

drm_connector_attach_active_color_format_property(&aconnector->base);
-- 
2.25.1



[PATCH v5 07/17] drm/amd/display: Add handling for new "active color format" property

2021-06-30 Thread Werner Sembach
This commit implements the "active color format" drm property for the AMD
GPU driver.

Signed-off-by: Werner Sembach 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 29 +--
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  4 +++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d984de82ae63..098f3d53e681 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6710,6 +6710,24 @@ static int convert_dc_color_depth_into_bpc (enum 
dc_color_depth display_color_de
return 0;
 }
 
+static int convert_dc_pixel_encoding_into_drm_color_format(
+   enum dc_pixel_encoding display_pixel_encoding)
+{
+   switch (display_pixel_encoding) {
+   case PIXEL_ENCODING_RGB:
+   return DRM_COLOR_FORMAT_RGB444;
+   case PIXEL_ENCODING_YCBCR422:
+   return DRM_COLOR_FORMAT_YCRCB422;
+   case PIXEL_ENCODING_YCBCR444:
+   return DRM_COLOR_FORMAT_YCRCB444;
+   case PIXEL_ENCODING_YCBCR420:
+   return DRM_COLOR_FORMAT_YCRCB420;
+   default:
+   break;
+   }
+   return 0;
+}
+
 static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
  struct drm_crtc_state *crtc_state,
  struct drm_connector_state 
*conn_state)
@@ -7711,6 +7729,7 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
if (!aconnector->mst_port) {
drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);
+   
drm_connector_attach_active_color_format_property(&aconnector->base);
}
 
/* This defaults to the max in the range, but we want 8bpc for non-edp. 
*/
@@ -9090,14 +9109,20 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
stream = dm_new_crtc_state->stream;
 
-   if (stream)
+   if (stream) {
drm_connector_set_active_bpc_property(connector,
stream->timing.flags.DSC ?

stream->timing.dsc_cfg.bits_per_pixel / 16 / 3 :
convert_dc_color_depth_into_bpc(

stream->timing.display_color_depth));
-   } else
+   
drm_connector_set_active_color_format_property(connector,
+   
convert_dc_pixel_encoding_into_drm_color_format(
+   
dm_new_crtc_state->stream->timing.pixel_encoding));
+   }
+   } else {
drm_connector_set_active_bpc_property(connector, 0);
+   
drm_connector_set_active_color_format_property(connector, 0);
+   }
}
 
/* Count number of newly disabled CRTCs for dropping PM refs later. */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 0cf38743ec47..13151d13aa73 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -413,6 +413,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr 
*mgr,
if (connector->active_bpc_property)
drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);
 
+   connector->active_color_format_property = 
master->base.active_color_format_property;
+   if (connector->active_color_format_property)
+   
drm_connector_attach_active_color_format_property(&aconnector->base);
+
connector->vrr_capable_property = master->base.vrr_capable_property;
if (connector->vrr_capable_property)
drm_connector_attach_vrr_capable_property(connector);
-- 
2.25.1



[PATCH v5 08/17] drm/i915/display: Add handling for new "active color format" property

2021-06-30 Thread Werner Sembach
This commit implements the "active color format" drm property for the Intel
GPU driver.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/i915/display/intel_display.c | 22 +++-
 drivers/gpu/drm/i915/display/intel_dp.c  |  2 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  5 +
 drivers/gpu/drm/i915/display/intel_hdmi.c|  1 +
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 1b63d1404d06..be38f7148285 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -10609,6 +10609,21 @@ static void 
intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s
}
 }
 
+static int convert_intel_output_format_into_drm_color_format(enum 
intel_output_format output_format)
+{
+   switch (output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   return DRM_COLOR_FORMAT_RGB444;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return DRM_COLOR_FORMAT_YCRCB420;
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return DRM_COLOR_FORMAT_YCRCB444;
+   default:
+   break;
+   }
+   return 0;
+}
+
 static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 {
struct drm_device *dev = state->base.dev;
@@ -10922,8 +10937,13 @@ static int intel_atomic_commit(struct drm_device *dev,
new_crtc_state->dsc.compression_enable ?
new_crtc_state->dsc.compressed_bpp / 3 :
new_crtc_state->pipe_bpp / 3);
-   } else
+   
drm_connector_set_active_color_format_property(connector,
+   
convert_intel_output_format_into_drm_color_format(
+   new_crtc_state->output_format));
+   } else {
drm_connector_set_active_bpc_property(connector, 0);
+   
drm_connector_set_active_color_format_property(connector, 0);
+   }
}
 
drm_atomic_state_get(&state->base);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 815bc313b954..6b85bcdeb238 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4691,9 +4691,11 @@ intel_dp_add_properties(struct intel_dp *intel_dp, 
struct drm_connector *connect
if (HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 6, 10);
drm_connector_attach_active_bpc_property(connector, 6, 10);
+   drm_connector_attach_active_color_format_property(connector);
} else if (DISPLAY_VER(dev_priv) >= 5) {
drm_connector_attach_max_bpc_property(connector, 6, 12);
drm_connector_attach_active_bpc_property(connector, 6, 12);
+   drm_connector_attach_active_color_format_property(connector);
}
 
/* Register HDMI colorspace for case of lspcon */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 16bfc59570a5..3e4237df3360 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -856,6 +856,11 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
if (connector->active_bpc_property)
drm_connector_attach_active_bpc_property(connector, 6, 12);
 
+   connector->active_color_format_property =
+   intel_dp->attached_connector->base.active_color_format_property;
+   if (connector->active_color_format_property)
+   drm_connector_attach_active_color_format_property(connector);
+
return connector;
 
 err:
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 9160e21ac9d6..367aba57b55f 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2516,6 +2516,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, 
struct drm_connector *c
if (!HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 8, 12);
drm_connector_attach_active_bpc_property(connector, 8, 12);
+   drm_connector_attach_active_color_format_property(connector);
}
 }
 
-- 
2.25.1



[PATCH v5 11/17] drm/i915/display: Add handling for new "active color range" property

2021-06-30 Thread Werner Sembach
This commit implements the "active color range" drm property for the Intel
GPU driver.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/i915/display/intel_display.c | 7 +++
 drivers/gpu/drm/i915/display/intel_dp.c  | 1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 5 +
 drivers/gpu/drm/i915/display/intel_hdmi.c| 1 +
 4 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index be38f7148285..b0bcb42a97fc 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -10940,9 +10940,16 @@ static int intel_atomic_commit(struct drm_device *dev,

drm_connector_set_active_color_format_property(connector,

convert_intel_output_format_into_drm_color_format(
new_crtc_state->output_format));
+   drm_connector_set_active_color_range_property(connector,
+   new_crtc_state->limited_color_range ||
+   new_crtc_state->output_format != 
INTEL_OUTPUT_FORMAT_RGB ?
+   DRM_MODE_COLOR_RANGE_LIMITED_16_235 :
+   DRM_MODE_COLOR_RANGE_FULL);
} else {
drm_connector_set_active_bpc_property(connector, 0);

drm_connector_set_active_color_format_property(connector, 0);
+   drm_connector_set_active_color_range_property(connector,
+ 
DRM_MODE_COLOR_RANGE_UNSET);
}
}
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6b85bcdeb238..fd33f753244d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4688,6 +4688,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct 
drm_connector *connect
intel_attach_force_audio_property(connector);
 
intel_attach_broadcast_rgb_property(connector);
+   drm_connector_attach_active_color_range_property(connector);
if (HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 6, 10);
drm_connector_attach_active_bpc_property(connector, 6, 10);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 3e4237df3360..cb876175258f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -861,6 +861,11 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
if (connector->active_color_format_property)
drm_connector_attach_active_color_format_property(connector);
 
+   connector->active_color_range_property =
+   intel_dp->attached_connector->base.active_color_range_property;
+   if (connector->active_color_range_property)
+   drm_connector_attach_active_color_range_property(connector);
+
return connector;
 
 err:
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 367aba57b55f..3ee25e0cc3b9 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2505,6 +2505,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, 
struct drm_connector *c
 
intel_attach_force_audio_property(connector);
intel_attach_broadcast_rgb_property(connector);
+   drm_connector_attach_active_color_range_property(connector);
intel_attach_aspect_ratio_property(connector);
 
intel_attach_hdmi_colorspace_property(connector);
-- 
2.25.1



[PATCH v5 17/17] drm/amd/display: Add handling for new "Broadcast RGB" property

2021-06-30 Thread Werner Sembach
This commit implements the "Broadcast RGB" drm property for the AMD GPU
driver.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 14 +++---
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c|  4 
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 02a5809d4993..80d5a11fb0c5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5247,7 +5247,8 @@ get_aspect_ratio(const struct drm_display_mode *mode_in)
 }
 
 static enum dc_color_space
-get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing)
+get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
+  enum drm_mode_color_range preferred_color_range)
 {
enum dc_color_space color_space = COLOR_SPACE_SRGB;
 
@@ -5278,7 +5279,10 @@ get_output_color_space(const struct dc_crtc_timing 
*dc_crtc_timing)
}
break;
case PIXEL_ENCODING_RGB:
-   color_space = COLOR_SPACE_SRGB;
+   if (preferred_color_range == 
DRM_MODE_COLOR_RANGE_LIMITED_16_235)
+   color_space = COLOR_SPACE_SRGB_LIMITED;
+   else
+   color_space = COLOR_SPACE_SRGB;
break;
 
default:
@@ -5424,7 +5428,10 @@ static void fill_stream_properties_from_drm_display_mode(
 
timing_out->aspect_ratio = get_aspect_ratio(mode_in);
 
-   stream->output_color_space = get_output_color_space(timing_out);
+   stream->output_color_space = get_output_color_space(timing_out,
+   connector_state ?
+   
connector_state->preferred_color_range :
+   
DRM_MODE_COLOR_RANGE_UNSET);
 
stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
@@ -7775,6 +7782,7 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);

drm_connector_attach_preferred_color_format_property(&aconnector->base);

drm_connector_attach_active_color_format_property(&aconnector->base);
+   
drm_connector_attach_preferred_color_range_property(&aconnector->base);

drm_connector_attach_active_color_range_property(&aconnector->base);
}
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 2563788ba95a..80e1389fd0ec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -421,6 +421,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr 
*mgr,
if (connector->active_color_format_property)

drm_connector_attach_active_color_format_property(&aconnector->base);
 
+   connector->preferred_color_range_property = 
master->base.preferred_color_range_property;
+   if (connector->preferred_color_range_property)
+   
drm_connector_attach_preferred_color_range_property(&aconnector->base);
+
connector->active_color_range_property = 
master->base.active_color_range_property;
if (connector->active_color_range_property)

drm_connector_attach_active_color_range_property(&aconnector->base);
-- 
2.25.1



[PATCH v5 10/17] drm/amd/display: Add handling for new "active color range" property

2021-06-30 Thread Werner Sembach
This commit implements the "active color range" drm property for the AMD
GPU driver.

Signed-off-by: Werner Sembach 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 33 +++
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  4 +++
 2 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 098f3d53e681..b4acedac1ac9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6728,6 +6728,33 @@ static int 
convert_dc_pixel_encoding_into_drm_color_format(
return 0;
 }
 
+static int convert_dc_color_space_into_drm_mode_color_range(enum 
dc_color_space color_space)
+{
+   if (color_space == COLOR_SPACE_SRGB ||
+   color_space == COLOR_SPACE_XR_RGB ||
+   color_space == COLOR_SPACE_MSREF_SCRGB ||
+   color_space == COLOR_SPACE_2020_RGB_FULLRANGE ||
+   color_space == COLOR_SPACE_ADOBERGB ||
+   color_space == COLOR_SPACE_DCIP3 ||
+   color_space == COLOR_SPACE_DOLBYVISION ||
+   color_space == COLOR_SPACE_YCBCR601 ||
+   color_space == COLOR_SPACE_XV_YCC_601 ||
+   color_space == COLOR_SPACE_YCBCR709 ||
+   color_space == COLOR_SPACE_XV_YCC_709 ||
+   color_space == COLOR_SPACE_2020_YCBCR ||
+   color_space == COLOR_SPACE_YCBCR709_BLACK ||
+   color_space == COLOR_SPACE_DISPLAYNATIVE ||
+   color_space == COLOR_SPACE_APPCTRL ||
+   color_space == COLOR_SPACE_CUSTOMPOINTS)
+   return DRM_MODE_COLOR_RANGE_FULL;
+   if (color_space == COLOR_SPACE_SRGB_LIMITED ||
+   color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE ||
+   color_space == COLOR_SPACE_YCBCR601_LIMITED ||
+   color_space == COLOR_SPACE_YCBCR709_LIMITED)
+   return DRM_MODE_COLOR_RANGE_LIMITED_16_235;
+   return DRM_MODE_COLOR_RANGE_UNSET;
+}
+
 static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
  struct drm_crtc_state *crtc_state,
  struct drm_connector_state 
*conn_state)
@@ -7730,6 +7757,7 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
drm_connector_attach_active_bpc_property(&aconnector->base, 8, 
16);

drm_connector_attach_active_color_format_property(&aconnector->base);
+   
drm_connector_attach_active_color_range_property(&aconnector->base);
}
 
/* This defaults to the max in the range, but we want 8bpc for non-edp. 
*/
@@ -9118,10 +9146,15 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)

drm_connector_set_active_color_format_property(connector,

convert_dc_pixel_encoding_into_drm_color_format(

dm_new_crtc_state->stream->timing.pixel_encoding));
+   
drm_connector_set_active_color_range_property(connector,
+   
convert_dc_color_space_into_drm_mode_color_range(
+   
dm_new_crtc_state->stream->output_color_space));
}
} else {
drm_connector_set_active_bpc_property(connector, 0);

drm_connector_set_active_color_format_property(connector, 0);
+   drm_connector_set_active_color_range_property(connector,
+ 
DRM_MODE_COLOR_RANGE_UNSET);
}
}
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 13151d13aa73..b5d57bbbdd20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -417,6 +417,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr 
*mgr,
if (connector->active_color_format_property)

drm_connector_attach_active_color_format_property(&aconnector->base);
 
+   connector->active_color_range_property = 
master->base.active_color_range_property;
+   if (connector->active_color_range_property)
+   
drm_connector_attach_active_color_range_property(&aconnector->base);
+
connector->vrr_capable_property = master->base.vrr_capable_property;
if (connector->vrr_capable_property)
drm_connector_attach_vrr_capable_property(connector);
-- 
2.25.1



[PATCH v5 15/17] drm/uAPI: Move "Broadcast RGB" property from driver specific to general context

2021-06-30 Thread Werner Sembach
Add "Broadcast RGB" to general drm context so that more drivers besides
i915 and gma500 can implement it without duplicating code.

Userspace can use this property to tell the graphic driver to use full or
limited color range for a given connector, overwriting the default
behaviour/automatic detection.

Possible options are:
- Automatic (default/current behaviour)
- Full
- Limited 16:235

In theory the driver should be able to automatically detect the monitors
capabilities, but because of flawed standard implementations in Monitors,
this might fail. In this case a manual overwrite is required to not have
washed out colors or lose details in very dark or bright scenes.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/drm_atomic_helper.c |  4 +++
 drivers/gpu/drm/drm_atomic_uapi.c   |  4 +++
 drivers/gpu/drm/drm_connector.c | 46 +
 include/drm/drm_connector.h | 16 ++
 4 files changed, 70 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 90d62f305257..0c89d32efbd0 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -691,6 +691,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (old_connector_state->preferred_color_format !=
new_connector_state->preferred_color_format)
new_crtc_state->connectors_changed = true;
+
+   if (old_connector_state->preferred_color_range !=
+   new_connector_state->preferred_color_range)
+   new_crtc_state->connectors_changed = true;
}
 
if (funcs->atomic_check)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index c536f5e22016..c589bb1a8163 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -798,6 +798,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
state->max_requested_bpc = val;
} else if (property == connector->preferred_color_format_property) {
state->preferred_color_format = val;
+   } else if (property == connector->preferred_color_range_property) {
+   state->preferred_color_range = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -877,6 +879,8 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = state->max_requested_bpc;
} else if (property == connector->preferred_color_format_property) {
*val = state->preferred_color_format;
+   } else if (property == connector->preferred_color_range_property) {
+   *val = state->preferred_color_range;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 67dd59b12258..20ae2e6d907b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -905,6 +905,12 @@ static const struct drm_prop_enum_list 
drm_active_color_format_enum_list[] = {
{ DRM_COLOR_FORMAT_YCRCB420, "ycbcr420" },
 };
 
+static const struct drm_prop_enum_list drm_preferred_color_range_enum_list[] = 
{
+   { DRM_MODE_COLOR_RANGE_UNSET, "Automatic" },
+   { DRM_MODE_COLOR_RANGE_FULL, "Full" },
+   { DRM_MODE_COLOR_RANGE_LIMITED_16_235, "Limited 16:235" },
+};
+
 static const struct drm_prop_enum_list drm_active_color_range_enum_list[] = {
{ DRM_MODE_COLOR_RANGE_UNSET, "Not Applicable" },
{ DRM_MODE_COLOR_RANGE_FULL, "Full" },
@@ -1246,6 +1252,15 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
= {
  * property. Possible values are "not applicable", "rgb", "ycbcr444",
  * "ycbcr422", and "ycbcr420".
  *
+ * Broadcast RGB:
+ * This property is used by userspace to change the used color range. This
+ * property affects the RGB color format as well as the Y'CbCr color
+ * formats, if the driver supports both full and limited Y'CbCr. Drivers to
+ * use the function drm_connector_attach_preferred_color_format_property()
+ * to create and attach the property to the connector during
+ * initialization. Possible values are "Automatic", "Full", and "Limited
+ * 16:235".
+ *
  * active color range:
  * This read-only property tells userspace the color range actually used by
  * the hardware display engine "on the cable" on a connector. The chosen
@@ -2331,6 +2346,37 @@ void 
drm_connector_set_active_color_format_property(struct drm_connector *connec
 }
 EXPORT_SYMBOL(drm_connector_set_active_color_format_property);

[PATCH v5 16/17] drm/i915/display: Use the general "Broadcast RGB" implementation

2021-06-30 Thread Werner Sembach
Change from the i915 specific "Broadcast RGB" drm property implementation
to the general one.

This commit delete all traces of the former "Broadcast RGB" implementation
and add a new one using the new driver agnoistic functions an variables.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |  8 --
 .../gpu/drm/i915/display/intel_connector.c| 28 ---
 .../gpu/drm/i915/display/intel_connector.h|  1 -
 .../drm/i915/display/intel_display_types.h|  8 --
 drivers/gpu/drm/i915/display/intel_dp.c   |  9 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  6 +++-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  8 ++
 drivers/gpu/drm/i915/display/intel_sdvo.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.h   |  1 -
 9 files changed, 12 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index b4e7ac51aa31..f8d5a0e287b0 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -63,8 +63,6 @@ int intel_digital_connector_atomic_get_property(struct 
drm_connector *connector,
 
if (property == dev_priv->force_audio_property)
*val = intel_conn_state->force_audio;
-   else if (property == dev_priv->broadcast_rgb_property)
-   *val = intel_conn_state->broadcast_rgb;
else {
drm_dbg_atomic(&dev_priv->drm,
   "Unknown property [PROP:%d:%s]\n",
@@ -99,11 +97,6 @@ int intel_digital_connector_atomic_set_property(struct 
drm_connector *connector,
return 0;
}
 
-   if (property == dev_priv->broadcast_rgb_property) {
-   intel_conn_state->broadcast_rgb = val;
-   return 0;
-   }
-
drm_dbg_atomic(&dev_priv->drm, "Unknown property [PROP:%d:%s]\n",
   property->base.id, property->name);
return -EINVAL;
@@ -134,7 +127,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
 * up in a modeset.
 */
if (new_conn_state->force_audio != old_conn_state->force_audio ||
-   new_conn_state->broadcast_rgb != old_conn_state->broadcast_rgb ||
new_conn_state->base.colorspace != old_conn_state->base.colorspace 
||
new_conn_state->base.picture_aspect_ratio != 
old_conn_state->base.picture_aspect_ratio ||
new_conn_state->base.content_type != 
old_conn_state->base.content_type ||
diff --git a/drivers/gpu/drm/i915/display/intel_connector.c 
b/drivers/gpu/drm/i915/display/intel_connector.c
index 9bed1ccecea0..89f0edf19182 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -241,34 +241,6 @@ intel_attach_force_audio_property(struct drm_connector 
*connector)
drm_object_attach_property(&connector->base, prop, 0);
 }
 
-static const struct drm_prop_enum_list broadcast_rgb_names[] = {
-   { INTEL_BROADCAST_RGB_AUTO, "Automatic" },
-   { INTEL_BROADCAST_RGB_FULL, "Full" },
-   { INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" },
-};
-
-void
-intel_attach_broadcast_rgb_property(struct drm_connector *connector)
-{
-   struct drm_device *dev = connector->dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   struct drm_property *prop;
-
-   prop = dev_priv->broadcast_rgb_property;
-   if (prop == NULL) {
-   prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
-  "Broadcast RGB",
-  broadcast_rgb_names,
-  ARRAY_SIZE(broadcast_rgb_names));
-   if (prop == NULL)
-   return;
-
-   dev_priv->broadcast_rgb_property = prop;
-   }
-
-   drm_object_attach_property(&connector->base, prop, 0);
-}
-
 void
 intel_attach_aspect_ratio_property(struct drm_connector *connector)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_connector.h 
b/drivers/gpu/drm/i915/display/intel_connector.h
index 661a37a3c6d8..f3058a035476 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.h
+++ b/drivers/gpu/drm/i915/display/intel_connector.h
@@ -28,7 +28,6 @@ int intel_connector_update_modes(struct drm_connector 
*connector,
 struct edid *edid);
 int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
 void intel_attach_force_audio_property(struct drm_connector *connector);
-void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 void intel_attach_aspect_ratio_property(struct drm_connector *connector);
 void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
 void intel_attach_dp_colorspace_property(struct drm_connector *connector);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/dr

[PATCH v5 12/17] drm/uAPI: Add "preferred color format" drm property as setting for userspace

2021-06-30 Thread Werner Sembach
Add a new general drm property "preferred color format" which can be used
by userspace to tell the graphic drivers to which color format to use.

Possible options are:
- auto (default/current behaviour)
- rgb
- ycbcr444
- ycbcr422 (not supported by both amdgpu and i915)
- ycbcr420

In theory the auto option should choose the best available option for the
current setup, but because of bad internal conversion some monitors look
better with rgb and some with ycbcr444.

Also, because of bad shielded connectors and/or cables, it might be
preferable to use the less bandwidth heavy ycbcr422 and ycbcr420 formats
for a signal that is less deceptible to interference.

In the future, automatic color calibration for screens might also depend on
this option being available.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/drm_atomic_helper.c |  4 +++
 drivers/gpu/drm/drm_atomic_uapi.c   |  4 +++
 drivers/gpu/drm/drm_connector.c | 50 -
 include/drm/drm_connector.h | 17 ++
 4 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5..90d62f305257 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -687,6 +687,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (old_connector_state->max_requested_bpc !=
new_connector_state->max_requested_bpc)
new_crtc_state->connectors_changed = true;
+
+   if (old_connector_state->preferred_color_format !=
+   new_connector_state->preferred_color_format)
+   new_crtc_state->connectors_changed = true;
}
 
if (funcs->atomic_check)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 438e9585b225..c536f5e22016 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -796,6 +796,8 @@ static int drm_atomic_connector_set_property(struct 
drm_connector *connector,
   fence_ptr);
} else if (property == connector->max_bpc_property) {
state->max_requested_bpc = val;
+   } else if (property == connector->preferred_color_format_property) {
+   state->preferred_color_format = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -873,6 +875,8 @@ drm_atomic_connector_get_property(struct drm_connector 
*connector,
*val = 0;
} else if (property == connector->max_bpc_property) {
*val = state->max_requested_bpc;
+   } else if (property == connector->preferred_color_format_property) {
+   *val = state->preferred_color_format;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index ebfdd17a7f59..67dd59b12258 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -889,6 +889,14 @@ static const struct drm_prop_enum_list 
drm_dp_subconnector_enum_list[] = {
{ DRM_MODE_SUBCONNECTOR_Native,  "Native"}, /* DP */
 };
 
+static const struct drm_prop_enum_list drm_preferred_color_format_enum_list[] 
= {
+   { 0, "auto" },
+   { DRM_COLOR_FORMAT_RGB444, "rgb" },
+   { DRM_COLOR_FORMAT_YCRCB444, "ycbcr444" },
+   { DRM_COLOR_FORMAT_YCRCB422, "ycbcr422" },
+   { DRM_COLOR_FORMAT_YCRCB420, "ycbcr420" },
+};
+
 static const struct drm_prop_enum_list drm_active_color_format_enum_list[] = {
{ 0, "not applicable" },
{ DRM_COLOR_FORMAT_RGB444, "rgb" },
@@ -1220,11 +1228,20 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
= {
  * Drivers shall use drm_connector_attach_active_bpc_property() to install
  * this property. A value of 0 means "not applicable".
  *
+ * preferred color format:
+ * This property is used by userspace to change the used color format. When
+ * used the driver will use the selected format if valid for the hardware,
+ * sink, and current resolution and refresh rate combination. Drivers to
+ * use the function drm_connector_attach_preferred_color_format_property()
+ * to create and attach the property to the connector during
+ * initialization. Possible values are "auto", "rgb", "ycbcr444",
+ * "ycbcr422", and "ycbcr420".
+ *
  * active color format:
  * This read-only property tells userspace the color format actually used
  * by the hardware display engine "on the cable" on a connector. The chosen
  *

[PATCH v5 09/17] drm/uAPI: Add "active color range" drm property as feedback for userspace

2021-06-30 Thread Werner Sembach
Add a new general drm property "active color range" which can be used by
graphic drivers to report the used color range back to userspace.

There was no way to check which color range got actually used on a given
monitor. To surely predict this, one must know the exact capabilities of
the monitor and what the default behaviour of the used driver is. This
property helps eliminating the guessing at this point.

In the future, automatic color calibration for screens might also depend on
this information being available.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/drm_connector.c | 61 +
 include/drm/drm_connector.h | 27 +++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 075bdc08d5c3..ebfdd17a7f59 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -897,6 +897,12 @@ static const struct drm_prop_enum_list 
drm_active_color_format_enum_list[] = {
{ DRM_COLOR_FORMAT_YCRCB420, "ycbcr420" },
 };
 
+static const struct drm_prop_enum_list drm_active_color_range_enum_list[] = {
+   { DRM_MODE_COLOR_RANGE_UNSET, "Not Applicable" },
+   { DRM_MODE_COLOR_RANGE_FULL, "Full" },
+   { DRM_MODE_COLOR_RANGE_LIMITED_16_235, "Limited 16:235" },
+};
+
 DRM_ENUM_NAME_FN(drm_get_dp_subconnector_name,
 drm_dp_subconnector_enum_list)
 
@@ -1223,6 +1229,15 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
= {
  * property. Possible values are "not applicable", "rgb", "ycbcr444",
  * "ycbcr422", and "ycbcr420".
  *
+ * active color range:
+ * This read-only property tells userspace the color range actually used by
+ * the hardware display engine "on the cable" on a connector. The chosen
+ * value depends on hardware capabilities of the monitor and the used color
+ * format. Drivers shall use
+ * drm_connector_attach_active_color_range_property() to install this
+ * property. Possible values are "Not Applicable", "Full", and "Limited
+ * 16:235".
+ *
  * Connectors also have one standardized atomic property:
  *
  * CRTC_ID:
@@ -2268,6 +2283,52 @@ void 
drm_connector_set_active_color_format_property(struct drm_connector *connec
 }
 EXPORT_SYMBOL(drm_connector_set_active_color_format_property);
 
+/**
+ * drm_connector_attach_active_color_range_property - attach "active color 
range" property
+ * @connector: connector to attach active color range property on.
+ *
+ * This is used to check the applied color range on a connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_active_color_range_property(struct drm_connector 
*connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct drm_property *prop;
+
+   if (!connector->active_color_range_property) {
+   prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 
"active color range",
+   
drm_active_color_range_enum_list,
+   
ARRAY_SIZE(drm_active_color_range_enum_list));
+   if (!prop)
+   return -ENOMEM;
+
+   connector->active_color_range_property = prop;
+   }
+
+   drm_object_attach_property(&connector->base, prop, 
DRM_MODE_COLOR_RANGE_UNSET);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_active_color_range_property);
+
+/**
+ * drm_connector_set_active_color_range_property - sets the active color range 
property for a
+ * connector
+ * @connector: drm connector
+ * @active_color_range: color range for the connector currently active "on the 
cable"
+ *
+ * Should be used by atomic drivers to update the active color range over a 
connector.
+ */
+void drm_connector_set_active_color_range_property(struct drm_connector 
*connector,
+  enum drm_mode_color_range 
active_color_range)
+{
+   drm_object_property_set_value(&connector->base, 
connector->active_color_range_property,
+ active_color_range);
+}
+EXPORT_SYMBOL(drm_connector_set_active_color_range_property);
+
 /**
  * drm_connector_attach_hdr_output_metadata_property - attach 
"HDR_OUTPUT_METADA" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8a5197f14e87..5ef4bb270f71 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -648,6 +648,24 @@ struct drm_tv_connector_state {
unsigned int hue;
 };
 
+/**
+ * enum drm_mode_color_range - color_range info for &drm_connector
+ *
+ * This enum is used to represent full or limited color range on the display
+ * connector signal.
+ *
+ * @DRM_MODE_COLOR_RANGE_UNSET: Color range is 
unspecified/default.
+ * @DRM_MODE_COLOR_RANGE_FULL:  Color range is full range, 0-255 for
+ *   

[PATCH v5 14/17] drm/i915/display: Add handling for new "preferred color format" property

2021-06-30 Thread Werner Sembach
This commit implements the "preferred color format" drm property for the
Intel GPU driver.

Signed-off-by: Werner Sembach 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 7 ++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +
 drivers/gpu/drm/i915/display/intel_hdmi.c   | 6 ++
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fd33f753244d..29bb181ec4be 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -616,9 +616,12 @@ intel_dp_output_format(struct drm_connector *connector,
 {
struct intel_dp *intel_dp = 
intel_attached_dp(to_intel_connector(connector));
const struct drm_display_info *info = &connector->display_info;
+   const struct drm_connector_state *connector_state = connector->state;
 
if (!connector->ycbcr_420_allowed ||
-   !drm_mode_is_420_only(info, mode))
+   !(drm_mode_is_420_only(info, mode) ||
+   (drm_mode_is_420_also(info, mode) && connector_state &&
+   connector_state->preferred_color_format == 
DRM_COLOR_FORMAT_YCRCB420)))
return INTEL_OUTPUT_FORMAT_RGB;
 
if (intel_dp->dfp.rgb_to_ycbcr &&
@@ -4692,10 +4695,12 @@ intel_dp_add_properties(struct intel_dp *intel_dp, 
struct drm_connector *connect
if (HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 6, 10);
drm_connector_attach_active_bpc_property(connector, 6, 10);
+   drm_connector_attach_preferred_color_format_property(connector);
drm_connector_attach_active_color_format_property(connector);
} else if (DISPLAY_VER(dev_priv) >= 5) {
drm_connector_attach_max_bpc_property(connector, 6, 12);
drm_connector_attach_active_bpc_property(connector, 6, 12);
+   drm_connector_attach_preferred_color_format_property(connector);
drm_connector_attach_active_color_format_property(connector);
}
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index cb876175258f..67f0fb649876 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -856,6 +856,11 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
if (connector->active_bpc_property)
drm_connector_attach_active_bpc_property(connector, 6, 12);
 
+   connector->preferred_color_format_property =
+   
intel_dp->attached_connector->base.preferred_color_format_property;
+   if (connector->preferred_color_format_property)
+   drm_connector_attach_preferred_color_format_property(connector);
+
connector->active_color_format_property =
intel_dp->attached_connector->base.active_color_format_property;
if (connector->active_color_format_property)
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 3ee25e0cc3b9..a7b85cd13227 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2153,6 +2153,11 @@ static int intel_hdmi_compute_output_format(struct 
intel_encoder *encoder,
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
}
 
+   if (connector->ycbcr_420_allowed &&
+   conn_state->preferred_color_format == DRM_COLOR_FORMAT_YCRCB420 &&
+   drm_mode_is_420_also(&connector->display_info, adjusted_mode))
+   crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+
ret = intel_hdmi_compute_clock(encoder, crtc_state);
if (ret) {
if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 &&
@@ -2517,6 +2522,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, 
struct drm_connector *c
if (!HAS_GMCH(dev_priv)) {
drm_connector_attach_max_bpc_property(connector, 8, 12);
drm_connector_attach_active_bpc_property(connector, 8, 12);
+   drm_connector_attach_preferred_color_format_property(connector);
drm_connector_attach_active_color_format_property(connector);
}
 }
-- 
2.25.1



Re: [PATCH 1/2] drm/i915/ttm: Reorganize the ttm move code somewhat

2021-06-30 Thread Thomas Hellström
On Wed, 2021-06-30 at 15:19 +0100, Matthew Auld wrote:
> On Thu, 24 Jun 2021 at 20:31, Thomas Hellström
>  wrote:
> > 
> > In order to make the code a bit more readable and to facilitate
> > async memcpy moves, reorganize the move code a little. Determine
> > at an early stage whether to copy or to clear.
> > 
> > Signed-off-by: Thomas Hellström 
> > ---
> >  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 70 ++---
> > 
> >  1 file changed, 40 insertions(+), 30 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > index c39d982c4fa6..4e529adcdfc7 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > @@ -431,6 +431,7 @@ i915_ttm_resource_get_st(struct
> > drm_i915_gem_object *obj,
> >  }
> > 
> >  static int i915_ttm_accel_move(struct ttm_buffer_object *bo,
> > +  bool clear,
> >    struct ttm_resource *dst_mem,
> >    struct sg_table *dst_st)
> >  {
> > @@ -449,13 +450,10 @@ static int i915_ttm_accel_move(struct
> > ttm_buffer_object *bo,
> >     return -EINVAL;
> > 
> >     dst_level = i915_ttm_cache_level(i915, dst_mem, ttm);
> > -   if (!ttm || !ttm_tt_is_populated(ttm)) {
> > +   if (clear) {
> >     if (bo->type == ttm_bo_type_kernel)
> >     return -EINVAL;
> 
> Was that meant to be:
> return 0:
> 
> ?
> 
> Also does that mean we are incorrectly falling back to memset, for
> non-userspace objects, instead of making it a noop?

No, we're deliberately falling back to memset for non-userspace
objects, but the logic only memsets in the BO_ALLOC_CPU_CLEAR case if
everything is implemented correctly.

> 
> > 
> > -   if (ttm && !(ttm->page_flags &
> > TTM_PAGE_FLAG_ZERO_ALLOC))
> > -   return 0;
> > -
> >     intel_engine_pm_get(i915->gt.migrate.context-
> > >engine);
> >     ret = intel_context_migrate_clear(i915-
> > >gt.migrate.context, NULL,
> >   dst_st->sgl,
> > dst_level,
> > @@ -489,27 +487,53 @@ static int i915_ttm_accel_move(struct
> > ttm_buffer_object *bo,
> >     return ret;
> >  }
> > 
> > -static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
> > -    struct ttm_operation_ctx *ctx,
> > -    struct ttm_resource *dst_mem,
> > -    struct ttm_place *hop)
> > +static void __i915_ttm_move(struct ttm_buffer_object *bo, bool
> > clear,
> > +   struct ttm_resource *dst_mem,
> > +   struct sg_table *dst_st)
> >  {
> >     struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
> > -   struct ttm_resource_manager *dst_man =
> > -   ttm_manager_type(bo->bdev, dst_mem->mem_type);
> >     struct intel_memory_region *dst_reg, *src_reg;
> >     union {
> >     struct ttm_kmap_iter_tt tt;
> >     struct ttm_kmap_iter_iomap io;
> >     } _dst_iter, _src_iter;
> >     struct ttm_kmap_iter *dst_iter, *src_iter;
> > -   struct sg_table *dst_st;
> >     int ret;
> > 
> >     dst_reg = i915_ttm_region(bo->bdev, dst_mem->mem_type);
> >     src_reg = i915_ttm_region(bo->bdev, bo->resource-
> > >mem_type);
> >     GEM_BUG_ON(!dst_reg || !src_reg);
> > 
> > +   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_st);
> > +   if (ret) {
> 
> One future consideration is flat CCS where I don't think we can
> easily
> fall back to memcpy for userspace objects. Maybe we can make this
> fallback conditional on DG1 or !ALLOC_USER for now, or just add a
> TODO?

Ugh. Is that true for both clearing and copying, or is it only copying?

Problem is if we hit an engine reset and fence error during initial
clearing / swapin, the plan moving forward is to intercept that and
resort to cpu clearing / copying for security reasons. In the worst
case we at least need to be able to clear.

/Thomas


> 
> > +   dst_iter = !cpu_maps_iomem(dst_mem) ?
> > +   ttm_kmap_iter_tt_init(&_dst_iter.tt, bo-
> > >ttm) :
> > +   ttm_kmap_iter_iomap_init(&_dst_iter.io,
> > &dst_reg->iomap,
> > +    dst_st, dst_reg-
> > >region.start);
> > +
> > +   src_iter = !cpu_maps_iomem(bo->resource) ?
> > +   ttm_kmap_iter_tt_init(&_src_iter.tt, bo-
> > >ttm) :
> > +   ttm_kmap_iter_iomap_init(&_src_iter.io,
> > &src_reg->iomap,
> > +    obj-
> > >ttm.cached_io_st,
> > +    src_reg-
> > >region.start);
> > +
> > +   ttm_move_memcpy(bo, dst_mem->num_pages, dst_iter,
> > src_iter);
> > +   }
> > +}
> > +
> > +static int i915_ttm_move

Re: [PATCH] drm/panel: ws2401: Add driver for WideChips WS2401

2021-06-30 Thread Linus Walleij
Hi Doug,

thanks for your review! I fixed most things except this:

On Fri, Jun 25, 2021 at 6:42 PM Doug Anderson  wrote:

> > +static int ws2401_disable(struct drm_panel *panel)
> > +{
> > +   struct ws2401 *ws = to_ws2401(panel);
> > +
> > +   ws2401_command(ws, MIPI_DCS_SET_DISPLAY_OFF);
> > +   msleep(25);
>
> It feels weird / arbitrary the split between "disable" and "unprepare"
> on this panel driver compared to the "db7430.c" one. In the other
> driver you put the sleep mode here and in this driver you put the
> sleep mode un "unpreapre". Is that for a reason, or just arbitrary?
> Can it be consistent between the two drivers?
>
> I guess maybe this is because in "db7430" the power up order was
> slightly different?

This arbitrary sequence ordering is part of why we can't just have
one display driver to rule them all... sadly they also make semantic
sense.

The vendor driver needs the display to come out of sleep right
after the power-on to send the init sequence. The vendor driver
does exactly this.

The placement of these sleep mode in prepare/unprepare calls
is because of this.

Yours,
Linus Walleij


Re: [PATCH] drm/panel: ws2401: Add driver for WideChips WS2401

2021-06-30 Thread Linus Walleij
On Mon, Jun 28, 2021 at 11:30 AM Noralf Trønnes  wrote:

> > + dev_info(ws->dev, "MTP ID: %02x %02x %02x\n", id1, id2, id3);
> > +}
>
> Why do you read these id's on every power on, it doesn't look like you
> use them?
>
> If they're just informational, they should be available through debugfs,
> see mipi_dbi_debugfs_init().

I moved them to probe. I actually really want to print this into
dmesg so we learn to understand these MTP values better,
if for nothing else so for the fact that they will turn up in google
searches.

The actual display controller vendor comes out in the first
MTP byte, and by collecting this data we can figure out to
some extent what kind of hardware is actually inside some
of these displays. In this case 0xDA is 0x40 so that is
widechips manufacturer ID.

I fixed the rest of the comments!

Yours,
Linus Walleij


Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing

2021-06-30 Thread Nathan Chancellor
Hi Will and Claire,

On Wed, Jun 30, 2021 at 12:43:48PM +0100, Will Deacon wrote:
> On Wed, Jun 30, 2021 at 05:17:27PM +0800, Claire Chang wrote:
> > On Wed, Jun 30, 2021 at 9:43 AM Nathan Chancellor  wrote:
> > >
> > > On Thu, Jun 24, 2021 at 11:55:20PM +0800, Claire Chang wrote:
> > > > Propagate the swiotlb_force into io_tlb_default_mem->force_bounce and
> > > > use it to determine whether to bounce the data or not. This will be
> > > > useful later to allow for different pools.
> > > >
> > > > Signed-off-by: Claire Chang 
> > > > Reviewed-by: Christoph Hellwig 
> > > > Tested-by: Stefano Stabellini 
> > > > Tested-by: Will Deacon 
> > > > Acked-by: Stefano Stabellini 
> > >
> > > This patch as commit af452ec1b1a3 ("swiotlb: Use is_swiotlb_force_bounce
> > > for swiotlb data bouncing") causes my Ryzen 3 4300G system to fail to
> > > get to an X session consistently (although not every single time),
> > > presumably due to a crash in the AMDGPU driver that I see in dmesg.
> > >
> > > I have attached logs at af452ec1b1a3 and f127c9556a8e and I am happy
> > > to provide any further information, debug, or test patches as necessary.
> > 
> > Are you using swiotlb=force? or the swiotlb_map is called because of
> > !dma_capable? 
> > (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/kernel/dma/direct.h#n93)
> 
> The command line is in the dmesg:
> 
>   | Kernel command line: initrd=\amd-ucode.img 
> initrd=\initramfs-linux-next-llvm.img 
> root=PARTUUID=8680aa0c-cf09-4a69-8cf3-970478040ee7 rw intel_pstate=no_hwp 
> irqpoll
> 
> but I worry that this looks _very_ similar to the issue reported by Qian
> Cai which we thought we had fixed. Nathan -- is the failure deterministic?

Yes, for the most part. It does not happen every single boot so when I
was bisecting, I did a series of seven boots and only considered the
revision good when all seven of them made it to LightDM's greeter. My
results that I notated show most bad revisions failed anywhere from four
to six times.

> > `BUG: unable to handle page fault for address: 003a8290` and
> > the fact it crashed at `_raw_spin_lock_irqsave` look like the memory
> > (maybe dev->dma_io_tlb_mem) was corrupted?
> > The dev->dma_io_tlb_mem should be set here
> > (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/pci/probe.c#n2528)
> > through device_initialize.
> 
> I'm less sure about this. 'dma_io_tlb_mem' should be pointing at
> 'io_tlb_default_mem', which is a page-aligned allocation from memblock.
> The spinlock is at offset 0x24 in that structure, and looking at the
> register dump from the crash:
> 
> Jun 29 18:28:42 hp-4300G kernel: RSP: 0018:adb4013db9e8 EFLAGS: 00010006
> Jun 29 18:28:42 hp-4300G kernel: RAX: 003a8290 RBX:  
> RCX: 8900572ad580
> Jun 29 18:28:42 hp-4300G kernel: RDX: 89005653f024 RSI: 000c 
> RDI: 1d17
> Jun 29 18:28:42 hp-4300G kernel: RBP: 0a20d000 R08: 000c 
> R09: 
> Jun 29 18:28:42 hp-4300G kernel: R10: 0a20d000 R11: 89005653f000 
> R12: 0212
> Jun 29 18:28:42 hp-4300G kernel: R13: 1000 R14: 0002 
> R15: 0020
> Jun 29 18:28:42 hp-4300G kernel: FS:  7f1f8898ea40() 
> GS:89005728() knlGS:
> Jun 29 18:28:42 hp-4300G kernel: CS:  0010 DS:  ES:  CR0: 
> 80050033
> Jun 29 18:28:42 hp-4300G kernel: CR2: 003a8290 CR3: 0001020d 
> CR4: 00350ee0
> Jun 29 18:28:42 hp-4300G kernel: Call Trace:
> Jun 29 18:28:42 hp-4300G kernel:  _raw_spin_lock_irqsave+0x39/0x50
> Jun 29 18:28:42 hp-4300G kernel:  swiotlb_tbl_map_single+0x12b/0x4c0
> 
> Then that correlates with R11 holding the 'dma_io_tlb_mem' pointer and
> RDX pointing at the spinlock. Yet RAX is holding junk :/
> 
> I agree that enabling KASAN would be a good idea, but I also think we
> probably need to get some more information out of swiotlb_tbl_map_single()
> to see see what exactly is going wrong in there.

I can certainly enable KASAN and if there is any debug print I can add
or dump anything, let me know!

Cheers,
Nathan


Re: [PATCH] dma-buf: fix and rework dma_buf_poll v4

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 4:22 PM Christian König
 wrote:
>
> Am 30.06.21 um 16:07 schrieb Daniel Vetter:
> > On Wed, Jun 30, 2021 at 2:36 PM Christian König
> >  wrote:
> >> Daniel pointed me towards this function and there are multiple obvious 
> >> problems
> >> in the implementation.
> >>
> >> First of all the retry loop is not working as intended. In general the 
> >> retry
> >> makes only sense if you grab the reference first and then check the 
> >> sequence
> >> values.
> >>
> >> Then we should always also wait for the exclusive fence.
> >>
> >> It's also good practice to keep the reference around when installing 
> >> callbacks
> >> to fences you don't own.
> >>
> >> And last the whole implementation was unnecessary complex and rather hard 
> >> to
> >> understand which could lead to probably unexpected behavior of the IOCTL.
> >>
> >> Fix all this by reworking the implementation from scratch. Dropping the
> >> whole RCU approach and taking the lock instead.
> >>
> >> Only mildly tested and needs a thoughtful review of the code.
> > prime_vgem.c has some basic stuff, but it might actually encoding the
> > broken behaviour. Would be good to extend/fix that I think so we don't
> > entirely rely on review. We can't really build easily on top of the
> > testcase Jason created for import/export, since for implicit sync we
> > need some driver that attaches the fences for us.
>
> My question is if I can just send that to
> intel-...@lists.freedesktop.org and the CI will pick it up?

We do run all the prime_vgem tests.

Btw if you do an igt patch, you can tell CI to run that igt patch
series together with your kernel submission. Pretty useful for hackery
like this, documented how it works here:

https://intel-gfx-ci.01.org/test-with.html

>
> >
> > There's also a vc4 one, but I guess that's less useful for us :-)
> >
> >> v2: fix the reference counting as well
> >> v3: keep the excl fence handling as is for stable
> >> v4: back to testing all fences, drop RCU
> >>
> >> Signed-off-by: Christian König 
> >> CC: sta...@vger.kernel.org
> >> ---
> >>   drivers/dma-buf/dma-buf.c | 132 +-
> >>   include/linux/dma-buf.h   |   2 +-
> >>   2 files changed, 46 insertions(+), 88 deletions(-)
> >>
> >> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> >> index eadd1eaa2fb5..192c4d34704b 100644
> >> --- a/drivers/dma-buf/dma-buf.c
> >> +++ b/drivers/dma-buf/dma-buf.c
> >> @@ -72,7 +72,7 @@ static void dma_buf_release(struct dentry *dentry)
> >>   * If you hit this BUG() it means someone dropped their ref to the
> >>   * dma-buf while still having pending operation to the buffer.
> >>   */
> >> -   BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
> >> +   BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);
> >>
> >>  dmabuf->ops->release(dmabuf);
> >>
> >> @@ -202,16 +202,19 @@ static void dma_buf_poll_cb(struct dma_fence *fence, 
> >> struct dma_fence_cb *cb)
> >>  wake_up_locked_poll(dcb->poll, dcb->active);
> >>  dcb->active = 0;
> >>  spin_unlock_irqrestore(&dcb->poll->lock, flags);
> >> +   dma_fence_put(fence);
> >>   }
> >>
> >>   static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
> >>   {
> >> +   struct dma_buf_poll_cb_t *dcb;
> >>  struct dma_buf *dmabuf;
> >>  struct dma_resv *resv;
> >>  struct dma_resv_list *fobj;
> >> -   struct dma_fence *fence_excl;
> >> +   struct dma_fence *fence;
> >> +   unsigned shared_count;
> >>  __poll_t events;
> >> -   unsigned shared_count, seq;
> >> +   int r, i;
> >>
> >>  dmabuf = file->private_data;
> >>  if (!dmabuf || !dmabuf->resv)
> >> @@ -225,101 +228,56 @@ static __poll_t dma_buf_poll(struct file *file, 
> >> poll_table *poll)
> >>  if (!events)
> >>  return 0;
> >>
> >> -retry:
> >> -   seq = read_seqcount_begin(&resv->seq);
> >> -   rcu_read_lock();
> >> +   dcb = events & EPOLLOUT ? &dmabuf->cb_out : &dmabuf->cb_in;
> >> +
> >> +   /* Only queue a new one if we are not still waiting for the old 
> >> one */
> >> +   spin_lock_irq(&dmabuf->poll.lock);
> >> +   if (dcb->active)
> >> +   events = 0;
> >> +   else
> >> +   dcb->active = events;
> >> +   spin_unlock_irq(&dmabuf->poll.lock);
> >> +   if (!events)
> >> +   return 0;
> >> +
> >> +   dma_resv_lock(resv, NULL);
> >>
> >> -   fobj = rcu_dereference(resv->fence);
> >> -   if (fobj)
> >> +   fobj = dma_resv_get_list(resv);
> >> +   if (fobj && events & EPOLLOUT)
> >>  shared_count = fobj->shared_count;
> >>  else
> >>  shared_count = 0;
> >> -   fence_excl = rcu_dereference(resv->fence_excl);
> >> -   if (read_seqcount_retry(&resv->seq, seq)) {
> >> -   rcu_read_unlock();
> >> -   goto retry;
> >> -   }

Re: [PATCH 09/12] media: hantro: Enable H.264 on Rockchip VDPU2

2021-06-30 Thread Alex Bee

Hi Ezequiel,

Am 29.06.21 um 14:28 schrieb Ezequiel Garcia:

Hi Alex,

On Sat, 2021-06-26 at 10:33 +0200, Alex Bee wrote:

Hi Ezequiel,

Am 26.06.21 um 02:46 schrieb Ezequiel Garcia:

(Adding Nicolas)

Hi Alex,

On Fri, 2021-06-25 at 01:13 +0200, Alex Bee wrote:

Hi Ezequiel,

Am 24.06.21 um 20:26 schrieb Ezequiel Garcia:

Given H.264 support for VDPU2 was just added, let's enable it.
For now, this is only enabled on platform that don't have
an RKVDEC core, such as RK3328.

Is there any reason, you do not want to enabe H.264 on RK3399? I know
H.264 can be done by by rkvdec already, but from what I understand that
shouldn't be an issue: The first decoder found that meets the
requirements will be taken.


Thanks a lot the review.

I really doubt userspace stacks are readily supporting that strategy.

The first decoder device supporting the codec format will be selected,
I doubt features such as profile and levels are checked to decide
which decoder to use.

I'd rather play safe on the kernel side and avoid offering
two competing devices for the same codec.

I wasn't aware of that. Current ffmpeg v4l2_request implementation seems
to not do VIDIOC_ENUM_FRAMESIZES - so we might end up being able to
decode up to 1920x1088 only if hantro decoder is picked/checked first.


Speaking of ffmpeg, now that MPEG-2, VP8 and H.264 control interfaces
are stable, I think one of the next priorities would be to push Jonas'
ffmpeg patches.

It would be really cool if someone could take the lead on that front,
as it would reduce kodi's out of tree stack, enable mpv, and so on.


That's absolutely true.

Note that Jonas himself started upstreaming those patches right after 
H264 uapi got stable [1].


Unfortunately I'm the absolut wrong person for doing/continuing this, 
since the very first time I ever looked at the implementation details 
was just for the response I wrote here. So I asked Jernej whos know all 
the details and contributed to those patches as well - he told me he'll 
continue whenever he finds time next.


Best,

Alex

[1] https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=2898



understanding virtio-gpu

2021-06-30 Thread Enrico Weigelt, metux IT consult

Hello folks,


I'm currently trying to understand how the virtio-gpu driver actually
works and got a few noob questions:

1. virtio_gpu_pci_quirk():

  * what is the explicit framebuffer removal about ?

Do virtio-gpu devices support several framebuffer types (but only
one at a time) ? How does it happen that we can have that vga
framebuffer standing in our way in the first place ?

  * why is it necessary to rename the device with "pci:" prefix ?

since (IMHO) virtio is an actual bus, that may even exist in HW,
but there're also several different virtio transports (got word that
somebody's also working on an socket-based one), it smells very
strange to me, making it look like a pci device.

does it only work w/ pci transport ?
what's the background of this ?

2. features[] array:

  * virgl seems only supported on little endian, and the comment tells
that's because virgl is sending the command stream in native endian.

  * IMHO, this approach isn't entirely correct, since here we're just
looking whether the driver/guest side is LE, but looking at the
host/device side. otoh, it should still work if both sides are BE.

  * shouldn't we add some endianess handshake to the protocol ?
maybe both should announce what's their native endianess and whether
they're capable of doing the conversion, so they can aggree on what
to do exactly ?


I'm currently trying to find ways for using virgl in containers instead
of VMs, so the container workload doesn't need to have any gpu specific
(userland) drivers anymore. Not sure whether I'll need special kernel
support for this at all.


thx,
--mtx

--
---
Hinweis: unverschlüsselte E-Mails können leicht abgehört und manipuliert
werden ! Für eine vertrauliche Kommunikation senden Sie bitte ihren
GPG/PGP-Schlüssel zu.
---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
i...@metux.net -- +49-151-27565287


Re: [PATCH 1/2] drm/i915/ttm: Reorganize the ttm move code somewhat

2021-06-30 Thread Matthew Auld
On Wed, 30 Jun 2021 at 16:27, Thomas Hellström
 wrote:
>
> On Wed, 2021-06-30 at 15:19 +0100, Matthew Auld wrote:
> > On Thu, 24 Jun 2021 at 20:31, Thomas Hellström
> >  wrote:
> > >
> > > In order to make the code a bit more readable and to facilitate
> > > async memcpy moves, reorganize the move code a little. Determine
> > > at an early stage whether to copy or to clear.
> > >
> > > Signed-off-by: Thomas Hellström 
> > > ---
> > >  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 70 ++---
> > > 
> > >  1 file changed, 40 insertions(+), 30 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > index c39d982c4fa6..4e529adcdfc7 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > @@ -431,6 +431,7 @@ i915_ttm_resource_get_st(struct
> > > drm_i915_gem_object *obj,
> > >  }
> > >
> > >  static int i915_ttm_accel_move(struct ttm_buffer_object *bo,
> > > +  bool clear,
> > >struct ttm_resource *dst_mem,
> > >struct sg_table *dst_st)
> > >  {
> > > @@ -449,13 +450,10 @@ static int i915_ttm_accel_move(struct
> > > ttm_buffer_object *bo,
> > > return -EINVAL;
> > >
> > > dst_level = i915_ttm_cache_level(i915, dst_mem, ttm);
> > > -   if (!ttm || !ttm_tt_is_populated(ttm)) {
> > > +   if (clear) {
> > > if (bo->type == ttm_bo_type_kernel)
> > > return -EINVAL;
> >
> > Was that meant to be:
> > return 0:
> >
> > ?
> >
> > Also does that mean we are incorrectly falling back to memset, for
> > non-userspace objects, instead of making it a noop?
>
> No, we're deliberately falling back to memset for non-userspace
> objects, but the logic only memsets in the BO_ALLOC_CPU_CLEAR case if
> everything is implemented correctly.
>
> >
> > >
> > > -   if (ttm && !(ttm->page_flags &
> > > TTM_PAGE_FLAG_ZERO_ALLOC))
> > > -   return 0;
> > > -
> > > intel_engine_pm_get(i915->gt.migrate.context-
> > > >engine);
> > > ret = intel_context_migrate_clear(i915-
> > > >gt.migrate.context, NULL,
> > >   dst_st->sgl,
> > > dst_level,
> > > @@ -489,27 +487,53 @@ static int i915_ttm_accel_move(struct
> > > ttm_buffer_object *bo,
> > > return ret;
> > >  }
> > >
> > > -static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
> > > -struct ttm_operation_ctx *ctx,
> > > -struct ttm_resource *dst_mem,
> > > -struct ttm_place *hop)
> > > +static void __i915_ttm_move(struct ttm_buffer_object *bo, bool
> > > clear,
> > > +   struct ttm_resource *dst_mem,
> > > +   struct sg_table *dst_st)
> > >  {
> > > struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
> > > -   struct ttm_resource_manager *dst_man =
> > > -   ttm_manager_type(bo->bdev, dst_mem->mem_type);
> > > struct intel_memory_region *dst_reg, *src_reg;
> > > union {
> > > struct ttm_kmap_iter_tt tt;
> > > struct ttm_kmap_iter_iomap io;
> > > } _dst_iter, _src_iter;
> > > struct ttm_kmap_iter *dst_iter, *src_iter;
> > > -   struct sg_table *dst_st;
> > > int ret;
> > >
> > > dst_reg = i915_ttm_region(bo->bdev, dst_mem->mem_type);
> > > src_reg = i915_ttm_region(bo->bdev, bo->resource-
> > > >mem_type);
> > > GEM_BUG_ON(!dst_reg || !src_reg);
> > >
> > > +   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_st);
> > > +   if (ret) {
> >
> > One future consideration is flat CCS where I don't think we can
> > easily
> > fall back to memcpy for userspace objects. Maybe we can make this
> > fallback conditional on DG1 or !ALLOC_USER for now, or just add a
> > TODO?
>
> Ugh. Is that true for both clearing and copying, or is it only copying?

With clearing I think we are required to nuke the aux CCS state using
some special blitter command.

For copying/moving I think it's a similar story, where special care
might be needed for the aux state, which likely requires the blitter.
Although tbh I don't really remember all the details.

>
> Problem is if we hit an engine reset and fence error during initial
> clearing / swapin, the plan moving forward is to intercept that and
> resort to cpu clearing / copying for security reasons. In the worst
> case we at least need to be able to clear.
>
> /Thomas
>
>
> >
> > > +   dst_iter = !cpu_maps_iomem(dst_mem) ?
> > > +   ttm_kmap_iter_tt_init(&_dst_iter.tt, bo-
> > > >ttm) :
> > > +   ttm_kmap_iter_iomap_init(&_dst_iter.io,
> > > &dst_reg->iomap,
> > > +dst_st, dst_reg-
>

Re: [Intel-gfx] [PATCH 1/2] drm/i915/ttm: Reorganize the ttm move code somewhat

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 6:54 PM Matthew Auld
 wrote:
>
> On Wed, 30 Jun 2021 at 16:27, Thomas Hellström
>  wrote:
> >
> > On Wed, 2021-06-30 at 15:19 +0100, Matthew Auld wrote:
> > > On Thu, 24 Jun 2021 at 20:31, Thomas Hellström
> > >  wrote:
> > > >
> > > > In order to make the code a bit more readable and to facilitate
> > > > async memcpy moves, reorganize the move code a little. Determine
> > > > at an early stage whether to copy or to clear.
> > > >
> > > > Signed-off-by: Thomas Hellström 
> > > > ---
> > > >  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 70 ++---
> > > > 
> > > >  1 file changed, 40 insertions(+), 30 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > index c39d982c4fa6..4e529adcdfc7 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> > > > @@ -431,6 +431,7 @@ i915_ttm_resource_get_st(struct
> > > > drm_i915_gem_object *obj,
> > > >  }
> > > >
> > > >  static int i915_ttm_accel_move(struct ttm_buffer_object *bo,
> > > > +  bool clear,
> > > >struct ttm_resource *dst_mem,
> > > >struct sg_table *dst_st)
> > > >  {
> > > > @@ -449,13 +450,10 @@ static int i915_ttm_accel_move(struct
> > > > ttm_buffer_object *bo,
> > > > return -EINVAL;
> > > >
> > > > dst_level = i915_ttm_cache_level(i915, dst_mem, ttm);
> > > > -   if (!ttm || !ttm_tt_is_populated(ttm)) {
> > > > +   if (clear) {
> > > > if (bo->type == ttm_bo_type_kernel)
> > > > return -EINVAL;
> > >
> > > Was that meant to be:
> > > return 0:
> > >
> > > ?
> > >
> > > Also does that mean we are incorrectly falling back to memset, for
> > > non-userspace objects, instead of making it a noop?
> >
> > No, we're deliberately falling back to memset for non-userspace
> > objects, but the logic only memsets in the BO_ALLOC_CPU_CLEAR case if
> > everything is implemented correctly.
> >
> > >
> > > >
> > > > -   if (ttm && !(ttm->page_flags &
> > > > TTM_PAGE_FLAG_ZERO_ALLOC))
> > > > -   return 0;
> > > > -
> > > > intel_engine_pm_get(i915->gt.migrate.context-
> > > > >engine);
> > > > ret = intel_context_migrate_clear(i915-
> > > > >gt.migrate.context, NULL,
> > > >   dst_st->sgl,
> > > > dst_level,
> > > > @@ -489,27 +487,53 @@ static int i915_ttm_accel_move(struct
> > > > ttm_buffer_object *bo,
> > > > return ret;
> > > >  }
> > > >
> > > > -static int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
> > > > -struct ttm_operation_ctx *ctx,
> > > > -struct ttm_resource *dst_mem,
> > > > -struct ttm_place *hop)
> > > > +static void __i915_ttm_move(struct ttm_buffer_object *bo, bool
> > > > clear,
> > > > +   struct ttm_resource *dst_mem,
> > > > +   struct sg_table *dst_st)
> > > >  {
> > > > struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
> > > > -   struct ttm_resource_manager *dst_man =
> > > > -   ttm_manager_type(bo->bdev, dst_mem->mem_type);
> > > > struct intel_memory_region *dst_reg, *src_reg;
> > > > union {
> > > > struct ttm_kmap_iter_tt tt;
> > > > struct ttm_kmap_iter_iomap io;
> > > > } _dst_iter, _src_iter;
> > > > struct ttm_kmap_iter *dst_iter, *src_iter;
> > > > -   struct sg_table *dst_st;
> > > > int ret;
> > > >
> > > > dst_reg = i915_ttm_region(bo->bdev, dst_mem->mem_type);
> > > > src_reg = i915_ttm_region(bo->bdev, bo->resource-
> > > > >mem_type);
> > > > GEM_BUG_ON(!dst_reg || !src_reg);
> > > >
> > > > +   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_st);
> > > > +   if (ret) {
> > >
> > > One future consideration is flat CCS where I don't think we can
> > > easily
> > > fall back to memcpy for userspace objects. Maybe we can make this
> > > fallback conditional on DG1 or !ALLOC_USER for now, or just add a
> > > TODO?
> >
> > Ugh. Is that true for both clearing and copying, or is it only copying?
>
> With clearing I think we are required to nuke the aux CCS state using
> some special blitter command.
>
> For copying/moving I think it's a similar story, where special care
> might be needed for the aux state, which likely requires the blitter.
> Although tbh I don't really remember all the details.

There's more than just flat CCS, for dg2 we'll also support resizeable
BAR with the goal to make the non-mappable lmem available too. Afaik
there's no fallback way to access that memory without a copy engine.

I think on those platforms we simply have to go back to wedging the
driver if reset of the copy eng

Re: [PATCH v3 1/2] drm/i915: Use the correct IRQ during resume

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 4:18 PM Thomas Zimmermann  wrote:
>
> Hi
>
> Am 30.06.21 um 12:49 schrieb Daniel Vetter:
> > On Wed, Jun 30, 2021 at 11:52:27AM +0200, Thomas Zimmermann wrote:
> >> The code in xcs_resume() probably didn't work as intended. It uses
> >> struct drm_device.irq, which is allocated to 0, but never initialized
> >> by i915 to the device's interrupt number.
> >>
> >> v3:
> >>  * also use intel_synchronize_hardirq() at another callsite
> >> v2:
> >>  * wrap irq code in intel_synchronize_hardirq() (Ville)
> >>
> >> Signed-off-by: Thomas Zimmermann 
> >> Fixes: 536f77b1caa0 ("drm/i915/gt: Call stop_ring() from ring resume, 
> >> again")
> >> Cc: Chris Wilson 
> >> Cc: Mika Kuoppala 
> >> Cc: Daniel Vetter 
> >> Cc: Rodrigo Vivi 
> >> Cc: Joonas Lahtinen 
> >> Cc: Maarten Lankhorst 
> >> Cc: Lucas De Marchi 
> >> ---
> >>   drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 2 +-
> >>   drivers/gpu/drm/i915/gt/intel_ring_submission.c | 2 +-
> >>   drivers/gpu/drm/i915/i915_irq.c | 5 +
> >>   drivers/gpu/drm/i915/i915_irq.h | 1 +
> >>   4 files changed, 8 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> >> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> >> index 88694822716a..5ca3d1664335 100644
> >> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> >> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> >> @@ -1229,7 +1229,7 @@ bool intel_engine_is_idle(struct intel_engine_cs 
> >> *engine)
> >>  return true;
> >>
> >>  /* Waiting to drain ELSP? */
> >> -synchronize_hardirq(to_pci_dev(engine->i915->drm.dev)->irq);
> >> +intel_synchronize_hardirq(engine->i915);
> >>  intel_engine_flush_submission(engine);
> >>
> >>  /* ELSP is empty, but there are ready requests? E.g. after reset */
> >> diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c 
> >> b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> >> index 5d42a12ef3d6..1b5a22a83db6 100644
> >> --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> >> +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> >> @@ -185,7 +185,7 @@ static int xcs_resume(struct intel_engine_cs *engine)
> >>   ring->head, ring->tail);
> >>
> >>  /* Double check the ring is empty & disabled before we resume */
> >> -synchronize_hardirq(engine->i915->drm.irq);
> >> +intel_synchronize_hardirq(engine->i915);
> >>  if (!stop_ring(engine))
> >>  goto err;
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_irq.c 
> >> b/drivers/gpu/drm/i915/i915_irq.c
> >> index 7d0ce8b9f8ed..2203dca19895 100644
> >> --- a/drivers/gpu/drm/i915/i915_irq.c
> >> +++ b/drivers/gpu/drm/i915/i915_irq.c
> >> @@ -4575,3 +4575,8 @@ void intel_synchronize_irq(struct drm_i915_private 
> >> *i915)
> >>   {
> >>  synchronize_irq(to_pci_dev(i915->drm.dev)->irq);
> >>   }
> >> +
> >> +void intel_synchronize_hardirq(struct drm_i915_private *i915)
> >> +{
> >> +synchronize_hardirq(to_pci_dev(i915->drm.dev)->irq);
> >
> > I honestly think the hardirq here is about as much cargo-culted as using
> > the wrong irq number.
> >
> > I'd just use intel_synchronize_irq in both places and see whether CI
> > complains, then go with that.
>
> Well, ok. I don't think I have Sandybridge HW available. Would the Intel
> CI infrastructure catch any problems with such a change?

If there's anything obvious busted with it it should catch it (like if
we end up calling synchronize_irq from softirq context, where only
synchronize_hardirq is allowed, but I don't think that's the case).

And if I'm wrong we know what kind of comment to put there to explain
why things are different.
-Daniel

> Best regards
> Thomas
>
> > -Daniel
> >
> >> +}
> >> diff --git a/drivers/gpu/drm/i915/i915_irq.h 
> >> b/drivers/gpu/drm/i915/i915_irq.h
> >> index db34d5dbe402..e43b6734f21b 100644
> >> --- a/drivers/gpu/drm/i915/i915_irq.h
> >> +++ b/drivers/gpu/drm/i915/i915_irq.h
> >> @@ -94,6 +94,7 @@ void intel_runtime_pm_disable_interrupts(struct 
> >> drm_i915_private *dev_priv);
> >>   void intel_runtime_pm_enable_interrupts(struct drm_i915_private 
> >> *dev_priv);
> >>   bool intel_irqs_enabled(struct drm_i915_private *dev_priv);
> >>   void intel_synchronize_irq(struct drm_i915_private *i915);
> >> +void intel_synchronize_hardirq(struct drm_i915_private *i915);
> >>
> >>   int intel_get_crtc_scanline(struct intel_crtc *crtc);
> >>   void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
> >> --
> >> 2.32.0
> >>
> >
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH 1/2] drm/i915/gem: Make our dma-buf exporter dynamic

2021-06-30 Thread Daniel Vetter
On Wed, Jun 30, 2021 at 4:01 PM Daniel Vetter  wrote:
> On Wed, Jun 30, 2021 at 03:07:00PM +0200, Thomas Hellström wrote:
> > If our exported dma-bufs are imported by another instance of our driver,
> > that instance will typically have the imported dma-bufs locked during
> > dma_buf_map_attachment(). But the exporter also locks the same reservation
> > object in the map_dma_buf() callback, which leads to recursive locking.
> >
> > Add a live selftest to exercise both dynamic and non-dynamic exports,
> > and as a workaround until we fully support dynamic import and export,
> > declare the exporter dynamic by providing pin() and unpin() implementations.
> > For dynamic importers, make sure we keep the pinning also in map_dma_buf(),
> > to ensure we never need to call dma_buf_move_notify().
> > Calling dma_buf_move_notify() is at the discretion of the exporter.
> >
> > v2:
> > - Extend the selftest with a fake dynamic importer.
> > - Provide real pin and unpin callbacks to not abuse the interface.
> >
> > Reported-by: Michael J. Ruhl 
> > Signed-off-by: Thomas Hellström 
>
> I'm not happy with this, because i915 is currently violating the dma-resv
> fencing rules for dynamic dma-buf.
>
> Yes since this is just the exporter we can probably get away with yolo'ing
> things, but Christian and me just spend a lot of angry typing figuring out
> what the rules actually are, so I really don't like bending them even more
> just because it's less typing.

To clarify what I meant here: I think the code is correct in the sense
that it's not breaking any other existing code upstream in a
functional or security relevant way.

What I meant with yolo merging is that if we land some dynamic dma-buf
exporter support just to fix a bug which with slightly more lines can
be fixed without resorting to quickly enabling dynamic dma-buf
exporting while a) we know i915 is breaking dma-resv rules already and
b) there was just a few weeks of rather angry discussions on this
topic.

That's just a recipe to piss people off, at least if I'd be in
Christian's shoes and see this land I'd get furious. So yolo on the
collaboration and people side of things, not so much technically
incorrect.

Plus with the sketch I described below we can fix the underlying issue
we're seeing in a clean way, by essentially aligning what i915 does to
what all other non-dynamic dma-buf ttm driver implementations do in
drm_prime.c. Defacto that's the only way that works, and it is the
contract for non-dynamic dma-buf for a driver using dma_resv_lock. The
only reason we could get away without lockdep splats with our current
dma-buf code in i915 of attempting to handle dma-buf more dynamic was
because we used our completely independent locking design (and also
never shared with another i915 instance). That illusion falls apart
with i915 using dma-resv and with now multiple i915 instances being
possible.

tldr; Using this way we can cleanly untangle solving the locking issue
at hand from the fairly bigger topic of how we are going to support
dynamic dma-buf and p2p and all that in i915.

I hope this explains a bit better why I have my take here like that.
-Daniel

> All we need for a quick interim fix is to not take the dma_resv_lock from
> our map/unamp callbacks. Pinning our backing storage from attach/detach
> callbacks (which are also called under dma_resv_lock) would also achieve
> that, without mudding any waters. So essentially just moving the
> pin/unpin_pages_unlocked and we should be good, which is almost as little
> typing.
>
> Michael, since Thomas is on vacations now, care to type that up? The
> selftest is imo solid.
>
> This is also consistent with what all other ttm based drivers do (aside
> from amdgpu, which is fully dynamic), see drm_gem_map_attach in
> drm_prime.c
>
> Adding Christian as fyi.
> -Daniel
>
> > ---
> >  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  31 -
> >  .../drm/i915/gem/selftests/i915_gem_dmabuf.c  | 116 +-
> >  2 files changed, 143 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
> > b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> > index 616c3a2f1baf..918c19df7b66 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> > @@ -12,6 +12,8 @@
> >  #include "i915_gem_object.h"
> >  #include "i915_scatterlist.h"
> >
> > +I915_SELFTEST_DECLARE(static bool force_different_devices;)
> > +
> >  static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
> >  {
> >   return to_intel_bo(buf->priv);
> > @@ -25,7 +27,14 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
> > dma_buf_attachment *attachme
> >   struct scatterlist *src, *dst;
> >   int ret, i;
> >
> > - ret = i915_gem_object_pin_pages_unlocked(obj);
> > + assert_object_held(obj);
> > +
> > + /*
> > +  * Note. In the dynamic importer case, the object is not yet pinned.
> > +  * Let's pin it here to avoid h

Re: [PATCH 47/47] drm/i915/guc: Unblock GuC submission on Gen11+

2021-06-30 Thread Matthew Brost
On Wed, Jun 30, 2021 at 11:22:38AM +0300, Martin Peres wrote:
> 
> 
> On 24/06/2021 10:05, Matthew Brost wrote:
> > From: Daniele Ceraolo Spurio 
> > 
> > Unblock GuC submission on Gen11+ platforms.
> > 
> > Signed-off-by: Michal Wajdeczko 
> > Signed-off-by: Daniele Ceraolo Spurio 
> > Signed-off-by: Matthew Brost 
> > ---
> >   drivers/gpu/drm/i915/gt/uc/intel_guc.h|  1 +
> >   drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 
> >   drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h |  3 +--
> >   drivers/gpu/drm/i915/gt/uc/intel_uc.c | 14 +-
> >   4 files changed, 19 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > index fae01dc8e1b9..77981788204f 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > @@ -54,6 +54,7 @@ struct intel_guc {
> > struct ida guc_ids;
> > struct list_head guc_id_list;
> > +   bool submission_supported;
> > bool submission_selected;
> > struct i915_vma *ads_vma;
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > index a427336ce916..405339202280 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -2042,6 +2042,13 @@ void intel_guc_submission_disable(struct intel_guc 
> > *guc)
> > /* Note: By the time we're here, GuC may have already been reset */
> >   }
> > +static bool __guc_submission_supported(struct intel_guc *guc)
> > +{
> > +   /* GuC submission is unavailable for pre-Gen11 */
> > +   return intel_guc_is_supported(guc) &&
> > +  INTEL_GEN(guc_to_gt(guc)->i915) >= 11;
> > +}
> > +
> >   static bool __guc_submission_selected(struct intel_guc *guc)
> >   {
> > struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> > @@ -2054,6 +2061,7 @@ static bool __guc_submission_selected(struct 
> > intel_guc *guc)
> >   void intel_guc_submission_init_early(struct intel_guc *guc)
> >   {
> > +   guc->submission_supported = __guc_submission_supported(guc);
> > guc->submission_selected = __guc_submission_selected(guc);
> >   }
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
> > index a2a3fad72be1..be767eb6ff71 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
> > @@ -37,8 +37,7 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
> >   static inline bool intel_guc_submission_is_supported(struct intel_guc 
> > *guc)
> >   {
> > -   /* XXX: GuC submission is unavailable for now */
> > -   return false;
> > +   return guc->submission_supported;
> >   }
> >   static inline bool intel_guc_submission_is_wanted(struct intel_guc *guc)
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
> > b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> > index 7a69c3c027e9..61be0aa81492 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> > @@ -34,8 +34,15 @@ static void uc_expand_default_options(struct intel_uc 
> > *uc)
> > return;
> > }
> > -   /* Default: enable HuC authentication only */
> > -   i915->params.enable_guc = ENABLE_GUC_LOAD_HUC;
> > +   /* Intermediate platforms are HuC authentication only */
> > +   if (IS_DG1(i915) || IS_ALDERLAKE_S(i915)) {
> > +   drm_dbg(&i915->drm, "Disabling GuC only due to old platform\n");
> 
> This comment does not seem accurate, given that DG1 is barely out, and ADL
> is not out yet. How about:
> 
> "Disabling GuC on untested platforms"?

This isn't my comment but it seems right to me. AFAIK this describes the
current PR but it is subject to change (i.e. we may enable GuC on DG1 by
default at some point).

> 
> > +   i915->params.enable_guc = ENABLE_GUC_LOAD_HUC;
> > +   return;
> > +   }
> > +
> > +   /* Default: enable HuC authentication and GuC submission */
> > +   i915->params.enable_guc = ENABLE_GUC_LOAD_HUC | ENABLE_GUC_SUBMISSION;
> 
> This seems to be in contradiction with the GuC submission plan which states:
> 
> "Not enabled by default on any current platforms but can be enabled via
> modparam enable_guc".
> 

I don't believe any current platform gets this point where GuC
submission would be enabled by default. The first would be ADL-P which
isn't out yet. 

> When you rework the patch, could you please add a warning when the user
> force-enables the GuC Command Submission? Something like:
> 
> "WARNING: The user force-enabled the experimental GuC command submission
> backend using i915.enable_guc. Please disable it if experiencing stability
> issues. No bug reports will be accepted on this backend".
> 
> This should allow you to work on the backend, while communicating clearly to
> users that it is not ready just yet. Once i

[PATCH 1/2 v2] drm/panel: Add DT bindings for Samsung LMS380KF01

2021-06-30 Thread Linus Walleij
This adds device tree bindings for the Samsung Mobile Displays
LMS380KF01 RGB DPI display panel.

Cc: devicet...@vger.kernel.org
Cc: phone-de...@vger.kernel.org
Cc: Douglas Anderson 
Cc: Noralf Trønnes 
Signed-off-by: Linus Walleij 
---
ChangeLog v1->v2:
- Expect SPI bindings to be pulled in for the client and state
  spi-cpha: true etc.
- Make port a required node.
- Update the example to use a proper SPI controller (spi-gpio)
  so we get full validation of the example.
---
 .../display/panel/samsung,lms380kf01.yaml | 97 +++
 1 file changed, 97 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml 
b/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml
new file mode 100644
index ..ebc33c36c124
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,lms380kf01.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung LMS380KF01 display panel
+
+description: The LMS380KF01 is a 480x800 DPI display panel from Samsung Mobile
+  Displays (SMD) utilizing the WideChips WS2401 display controller. It can be
+  used with internal or external backlight control.
+
+maintainers:
+  - Linus Walleij 
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+const: samsung,lms380kf01
+
+  reg: true
+
+  interrupts:
+description: provides an optional ESD (electrostatic discharge)
+  interrupt that signals abnormalities in the display hardware.
+  This can also be raised for other reasons like erroneous
+  configuration.
+maxItems: 1
+
+  reset-gpios: true
+
+  vci-supply:
+description: regulator that supplies the VCI analog voltage
+  usually around 3.0 V
+
+  vccio-supply:
+description: regulator that supplies the VCCIO voltage usually
+  around 1.8 V
+
+  backlight: true
+
+  spi-cpha: true
+
+  spi-cpol: true
+
+  spi-max-frequency:
+maximum: 120
+
+  port: true
+
+required:
+  - compatible
+  - reg
+  - spi-cpha
+  - spi-cpol
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+spi {
+  compatible = "spi-gpio";
+  sck-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+  miso-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+  mosi-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
+  cs-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
+  num-chipselects = <1>;
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  panel@0 {
+compatible = "samsung,lms380kf01";
+spi-max-frequency = <120>;
+spi-cpha;
+spi-cpol;
+reg = <0>;
+vci-supply = <&lcd_3v0_reg>;
+vccio-supply = <&lcd_1v8_reg>;
+reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+interrupt-parent = <&gpio>;
+interrupts = <5 IRQ_TYPE_EDGE_RISING>;
+
+port {
+  panel_in: endpoint {
+remote-endpoint = <&display_out>;
+  };
+};
+  };
+};
+
+...
-- 
2.31.1



[PATCH 2/2 v2] drm/panel: ws2401: Add driver for WideChips WS2401

2021-06-30 Thread Linus Walleij
This adds a driver for panels based on the WideChips WS2401 display
controller. This display controller is used in the Samsung LMS380KF01
display found in the Samsung GT-I8160 (Codina) mobile phone and
possibly others.

As is common with Samsung displays manufacturer commands are necessary
to configure the display to a working state.

The display optionally supports internal backlight control, but can
also use an external backlight.

This driver re-uses the DBI infrastructure to communicate with the
display.

Cc: phone-de...@vger.kernel.org
Cc: Douglas Anderson 
Cc: Noralf Trønnes 
Signed-off-by: Linus Walleij 
---
ChangeLog v1->v2:
- Disable the backlight in ->unprepare() before entering sleep
  mode.
- If we are not using internal backlight, close the L2 access
  after initializing.
- Depromote some talkative dev_info()s to dev_dbg().
- Power up and read the MTP values before we register the display.
  This works fine and is probably how MTP is supposed to work.
- Fix the set-up of gamma values, this was found in the GT-I8160 HD
  kernel tree.
- Bail out properly if drm_panel_of_backlight() returns
  -EDEFER_PROBE.
- Drop OF from dependencies since drm_panel_of_backlight() has
  static inline stubs in the header file.
- Sort MAINTAINERS properly.
- Alphabetize includes
- Use format specifier %#02x so we get 0x... output in debug
- Drop unnecessary braces around if () in debug macro
- Drop unused  include.
---
 MAINTAINERS   |   7 +
 drivers/gpu/drm/panel/Kconfig |   9 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-widechips-ws2401.c| 440 ++
 4 files changed, 457 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-widechips-ws2401.c

diff --git a/MAINTAINERS b/MAINTAINERS
index bd7aff0c120f..10bba4be1678 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5956,6 +5956,13 @@ T:   git git://people.freedesktop.org/~sroland/linux
 F: drivers/gpu/drm/vmwgfx/
 F: include/uapi/drm/vmwgfx_drm.h
 
+DRM DRIVER FOR WIDECHIPS WS2401 PANELS
+M: Linus Walleij 
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml
+F: drivers/gpu/drm/panel/panel-widechips-ws2401.c
+
 DRM DRIVERS
 M: David Airlie 
 M: Daniel Vetter 
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4894913936e9..319fa44c4bc9 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -552,6 +552,15 @@ config DRM_PANEL_VISIONOX_RM69299
  Say Y here if you want to enable support for Visionox
  RM69299  DSI Video Mode panel.
 
+config DRM_PANEL_WIDECHIPS_WS2401
+   tristate "Widechips WS2401 DPI panel driver"
+   depends on SPI && GPIOLIB
+   depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_MIPI_DBI
+   help
+ Say Y here if you want to enable support for the Widechips WS2401 DPI
+ 480x800 display controller used in panels such as Samsung LMS380KF01.
+
 config DRM_PANEL_XINPENG_XPP055C272
tristate "Xinpeng XPP055C272 panel driver"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index cae4d976c069..d94c27df17aa 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -58,4 +58,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += 
panel-tpo-td043mtea1.o
 obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
 obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o
+obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o
 obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
diff --git a/drivers/gpu/drm/panel/panel-widechips-ws2401.c 
b/drivers/gpu/drm/panel/panel-widechips-ws2401.c
new file mode 100644
index ..e5731c08fc94
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-widechips-ws2401.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Panel driver for the WideChips WS2401 480x800 DPI RGB panel, used in
+ * the Samsung Mobile Display (SMD) LMS380KF01.
+ * Found in the Samsung Galaxy Ace 2 GT-I8160 mobile phone.
+ * Linus Walleij 
+ * Inspired by code and know-how in the vendor driver by Gareth Phillips.
+ */
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define WS2401_RESCTL  0xb8 /* Resolution select control */
+#define WS2401_PSMPS   0xbd /* SMPS positive control */
+#define WS2401_NSMPS   0xbe /* SMPS negative control */
+#define WS2401_SMPS0xbf
+#define WS2401_BCMODE  0xc1 /* Backlight control mode */
+#define WS2401_WRBLCTL 0xc3 /* Backlight control */
+#define WS2401_WRDISBV 0xc4 /* W

Re: [PATCH 47/47] drm/i915/guc: Unblock GuC submission on Gen11+

2021-06-30 Thread John Harrison

On 6/30/2021 01:22, Martin Peres wrote:

On 24/06/2021 10:05, Matthew Brost wrote:

From: Daniele Ceraolo Spurio 

Unblock GuC submission on Gen11+ platforms.

Signed-off-by: Michal Wajdeczko 
Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc.h    |  1 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h |  3 +--
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 14 +-
  4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h

index fae01dc8e1b9..77981788204f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -54,6 +54,7 @@ struct intel_guc {
  struct ida guc_ids;
  struct list_head guc_id_list;
  +    bool submission_supported;
  bool submission_selected;
    struct i915_vma *ads_vma;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

index a427336ce916..405339202280 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2042,6 +2042,13 @@ void intel_guc_submission_disable(struct 
intel_guc *guc)
  /* Note: By the time we're here, GuC may have already been 
reset */

  }
  +static bool __guc_submission_supported(struct intel_guc *guc)
+{
+    /* GuC submission is unavailable for pre-Gen11 */
+    return intel_guc_is_supported(guc) &&
+   INTEL_GEN(guc_to_gt(guc)->i915) >= 11;
+}
+
  static bool __guc_submission_selected(struct intel_guc *guc)
  {
  struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
@@ -2054,6 +2061,7 @@ static bool __guc_submission_selected(struct 
intel_guc *guc)

    void intel_guc_submission_init_early(struct intel_guc *guc)
  {
+    guc->submission_supported = __guc_submission_supported(guc);
  guc->submission_selected = __guc_submission_selected(guc);
  }
  diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h

index a2a3fad72be1..be767eb6ff71 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
@@ -37,8 +37,7 @@ int intel_guc_wait_for_pending_msg(struct intel_guc 
*guc,
    static inline bool intel_guc_submission_is_supported(struct 
intel_guc *guc)

  {
-    /* XXX: GuC submission is unavailable for now */
-    return false;
+    return guc->submission_supported;
  }
    static inline bool intel_guc_submission_is_wanted(struct 
intel_guc *guc)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c

index 7a69c3c027e9..61be0aa81492 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -34,8 +34,15 @@ static void uc_expand_default_options(struct 
intel_uc *uc)

  return;
  }
  -    /* Default: enable HuC authentication only */
-    i915->params.enable_guc = ENABLE_GUC_LOAD_HUC;
+    /* Intermediate platforms are HuC authentication only */
+    if (IS_DG1(i915) || IS_ALDERLAKE_S(i915)) {
+    drm_dbg(&i915->drm, "Disabling GuC only due to old 
platform\n");


This comment does not seem accurate, given that DG1 is barely out, and 
ADL is not out yet. How about:


"Disabling GuC on untested platforms"?

Just because something is not in the shops yet does not mean it is new. 
Technology is always obsolete by the time it goes on sale.


And the issue is not a lack of testing, it is a question of whether we 
are allowed to change the default on something that has already started 
being used by customers or not (including pre-release beta customers). 
I.e. it is basically a political decision not an engineering decision.




+    i915->params.enable_guc = ENABLE_GUC_LOAD_HUC;
+    return;
+    }
+
+    /* Default: enable HuC authentication and GuC submission */
+    i915->params.enable_guc = ENABLE_GUC_LOAD_HUC | 
ENABLE_GUC_SUBMISSION;


This seems to be in contradiction with the GuC submission plan which 
states:


"Not enabled by default on any current platforms but can be enabled 
via modparam enable_guc".
All current platforms have already been explicitly tested for above. 
This is setting the default on newer platforms - ADL-P and later. For 
which the official expectation is to have GuC enabled.




When you rework the patch, could you please add a warning when the 
user force-enables the GuC Command Submission? 
There already is one. If you set the module parameter then the kernel is 
tainted. That means 'here be dragons' - you have done something 
officially not supported to your kernel so all bets are off, if it blows 
up it is your own problem.



Something like:

"WARNING: The user force-enabled the experimental GuC command 
submission backend using i915.enable_guc. Please disable it if 
experie

[Bug 213391] AMDGPU retries page fault with some specific processes amdgpu and sometimes followed [gfxhub0] retry page fault until *ERROR* ring gfx timeout, but soft recovered

2021-06-30 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=213391

--- Comment #28 from Leandro Jacques (ls...@yahoo.com) ---
(In reply to Leandro Jacques from comment #25)

Until now, no problems. So the problem is with newer firmware versions, working
without any issues since 2021-06-21 19:26:28 UTC with version 20210315

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

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

[Bug 209457] AMDGPU resume fail with RX 580 GPU

2021-06-30 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=209457

--- Comment #30 from Leandro Jacques (ls...@yahoo.com) ---
(In reply to Leandro Jacques from comment #29)

Until now, no problems. So the problem is with newer firmware versions, working
without any issues since 2021-06-22 17:16:25 UTC with version 20210315

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

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

  1   2   >