Re: [PATCH 3/6] drm/amdgpu: Flush VM updates for split bindings eagerly.

2023-11-01 Thread Christian König

Am 02.11.23 um 03:36 schrieb Lang Yu:

On 10/31/ , Christian König wrote:

Am 31.10.23 um 14:59 schrieb Bas Nieuwenhuizen:


On Tue, Oct 31, 2023 at 2:57 PM Christian König
 wrote:

 Am 31.10.23 um 14:40 schrieb Tatsuyuki Ishi:
 > The current amdgpu_gem_va_update_vm only tries to perform
 updates for the
 > BO specified in the GEM ioctl; however, when a binding is split, the
 > adjacent bindings also need to be updated. Such updates
 currently ends up
 > getting deferred until next submission which causes stalls.

 Yeah, that is a necessity. The hardware simply doesn't support
 what you
 try to do here in all cases.


What can the hardware not do here? Is this just needing to wait for TLB
flushes before we can free pagetables, can we just delay that?

On some hardware generations (especially Navi1x, but also everything older
than Polaris) you can't invalidate the TLB while it is in use.

Hi Christian,

non-legacy invalidation can invalidate the TLB while it is in use.
Right? Thanks.


Right, the problem is that they are only available starting with Vega 
(for GFX8 they only work for the APUs IIRC).


Regards,
Christian.



Regards,
Lang


For Polaris and older it just means that you don't have a guarantee that the
shader can't access the memory any more. So delaying the free operation
helps here.

But for Navi1x it's a workaround for a hardware bug. If you try to
invalidate the TLB while it is in use you can potentially triggering memory
accesses to random addresses.

That's why we still delay TLB invalidation's to the next CS and use a new
VMID for each submission instead of invalidating the old one.

I'm currently working on changing that for Navi2x and newer (maybe Vega as
well), but this is something you can really only do on some hw generations
after validating that it works.

Regards,
Christian.



 So this approach won't work in general.

 Regards,
 Christian.

 >
 > Introduce a new state "dirty", shared between per-VM BOs and
 traditional
 > BOs, containing all BOs that have pending updates in `invalids`.
 > amdgpu_gem_va_update_vm will now simply flush any pending
 updates for BOs
 > in the dirty state.
 >
 > Signed-off-by: Tatsuyuki Ishi 
 > ---
 >   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 18 ---
 >   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 66
 ++---
 >   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  3 ++
 >   3 files changed, 63 insertions(+), 24 deletions(-)
 >
 > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 > index a1b15d0d6c48..01d3a97248b0 100644
 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 > @@ -604,10 +604,9 @@ int amdgpu_gem_metadata_ioctl(struct
 drm_device *dev, void *data,
 >    * vital here, so they are not reported back to userspace.
 >    */
 >   static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
 > -                                 struct amdgpu_vm *vm,
 > -                                 struct amdgpu_bo_va *bo_va,
 > -                                 uint32_t operation)
 > +                                 struct amdgpu_vm *vm)
 >   {
 > +     struct amdgpu_bo_va *bo_va;
 >       int r;
 >
 >       if (!amdgpu_vm_ready(vm))
 > @@ -617,12 +616,18 @@ static void amdgpu_gem_va_update_vm(struct
 amdgpu_device *adev,
 >       if (r)
 >               goto error;
 >
 > -     if (operation == AMDGPU_VA_OP_MAP ||
 > -         operation == AMDGPU_VA_OP_REPLACE) {
 > +     spin_lock(&vm->status_lock);
 > +     while (!list_empty(&vm->dirty)) {
 > +             bo_va = list_first_entry(&vm->dirty, struct
 amdgpu_bo_va,
 > +                                      base.vm_status);
 > +             spin_unlock(&vm->status_lock);
 > +
 >               r = amdgpu_vm_bo_update(adev, bo_va, false);
 >               if (r)
 >                       goto error;
 > +             spin_lock(&vm->status_lock);
 >       }
 > +     spin_unlock(&vm->status_lock);
 >
 >       r = amdgpu_vm_update_pdes(adev, vm, false);
 >
 > @@ -792,8 +797,7 @@ int amdgpu_gem_va_ioctl(struct drm_device
 *dev, void *data,
 >               break;
 >       }
 >       if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) &&
 !amdgpu_vm_debug)
 > -             amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
 > -  args->operation);
 > +             amdgpu_gem_va_update_vm(adev, &fpriv->vm);
 >
 >   error:
 >       drm_exec_fini(&exec);
 > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
 b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
 > index dd6f72e2a1d6..01d31891cd05 100644
 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
 > +++ b/drivers/gpu/drm/amd

[PATCH] drm/amd/display: Set color_mgmt_changed to true on unsuspend

2023-11-01 Thread Joshua Ashton
Otherwise we can end up with a frame on unsuspend where color management
is not applied when userspace has not committed themselves.

Fixes re-applying color management on Steam Deck/Gamescope on S3 resume.

Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 +
 1 file changed, 1 insertion(+)

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 adbeb2c897b5..ae650707f234 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2967,6 +2967,7 @@ static int dm_resume(void *handle)
dc_stream_release(dm_new_crtc_state->stream);
dm_new_crtc_state->stream = NULL;
}
+   dm_new_crtc_state->base.color_mgmt_changed = true;
}
 
for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, 
i) {
-- 
2.42.0



Re: [PATCH v4 09/32] drm/amd/display: add plane 3D LUT driver-specific properties

2023-11-01 Thread Joshua Ashton




On 10/5/23 18:15, Melissa Wen wrote:

Add 3D LUT property for plane color transformations using a 3D lookup
table. 3D LUT allows for highly accurate and complex color
transformations and is suitable to adjust the balance between color
channels. It's also more complex to manage and require more
computational resources.

Since a 3D LUT has a limited number of entries in each dimension we want
to use them in an optimal fashion. This means using the 3D LUT in a
colorspace that is optimized for human vision, such as sRGB, PQ, or
another non-linear space. Therefore, userpace may need one 1D LUT
(shaper) before it to delinearize content and another 1D LUT after 3D
LUT (blend) to linearize content again for blending. The next patches
add these 1D LUTs to the plane color mgmt pipeline.

v3:
- improve commit message about 3D LUT
- describe the 3D LUT entries and size (Harry)

v4:
- advertise 3D LUT max size as the size of a single-dimension

Signed-off-by: Melissa Wen 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 18 +++
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  9 
  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 14 +++
  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 23 +++
  4 files changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 62044d41da75..f7adaa52c23f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -363,6 +363,24 @@ struct amdgpu_mode_info {
 * @plane_hdr_mult_property:
 */
struct drm_property *plane_hdr_mult_property;
+   /**
+* @plane_lut3d_property: Plane property for color transformation using
+* a 3D LUT (pre-blending), a three-dimensional array where each
+* element is an RGB triplet. Each dimension has a size of the cubed
+* root of lut3d_size. The array contains samples from the approximated
+* function. On AMD, values between samples are estimated by
+* tetrahedral interpolation. The array is accessed with three indices,
+* one for each input dimension (color channel), blue being the
+* outermost dimension, red the innermost.
+*/
+   struct drm_property *plane_lut3d_property;
+   /**
+* @plane_degamma_lut_size_property: Plane property to define the max
+* size of 3D LUT as supported by the driver (read-only). The max size
+* is the max size of one dimension and, therefore, the max number of
+* entries for 3D LUT array is the 3D LUT size cubed;
+*/
+   struct drm_property *plane_lut3d_size_property;
  };
  
  #define AMDGPU_MAX_BL_LEVEL 0xFF

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index bb2ce843369d..7a2350c62cf1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -784,6 +784,11 @@ struct dm_plane_state {
 * TF is needed for any subsequent linear-to-non-linear transforms.
 */
__u64 hdr_mult;
+   /**
+* @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
+* &struct drm_color_lut.
+*/
+   struct drm_property_blob *lut3d;
  };
  
  struct dm_crtc_state {

@@ -869,6 +874,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector 
*connector,
  
  void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
  
+/* 3D LUT max size is 17x17x17 (4913 entries) */

+#define MAX_COLOR_3DLUT_SIZE 17
+#define MAX_COLOR_3DLUT_BITDEPTH 12
+/* 1D LUT size */
  #define MAX_COLOR_LUT_ENTRIES 4096
  /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
  #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index caf49a044ab4..011f2f9ec890 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -230,6 +230,20 @@ amdgpu_dm_create_color_properties(struct amdgpu_device 
*adev)
return -ENOMEM;
adev->mode_info.plane_hdr_mult_property = prop;
  
+	prop = drm_property_create(adev_to_drm(adev),

+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_LUT3D", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_lut3d_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_lut3d_size_property = prop;
+
return 0;
  }
  #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/

Re: [PATCH 3/6] drm/amdgpu: Flush VM updates for split bindings eagerly.

2023-11-01 Thread Lang Yu
On 10/31/ , Christian König wrote:
> Am 31.10.23 um 14:59 schrieb Bas Nieuwenhuizen:
> > 
> > 
> > On Tue, Oct 31, 2023 at 2:57 PM Christian König
> >  wrote:
> > 
> > Am 31.10.23 um 14:40 schrieb Tatsuyuki Ishi:
> > > The current amdgpu_gem_va_update_vm only tries to perform
> > updates for the
> > > BO specified in the GEM ioctl; however, when a binding is split, the
> > > adjacent bindings also need to be updated. Such updates
> > currently ends up
> > > getting deferred until next submission which causes stalls.
> > 
> > Yeah, that is a necessity. The hardware simply doesn't support
> > what you
> > try to do here in all cases.
> > 
> > 
> > What can the hardware not do here? Is this just needing to wait for TLB
> > flushes before we can free pagetables, can we just delay that?
> 
> On some hardware generations (especially Navi1x, but also everything older
> than Polaris) you can't invalidate the TLB while it is in use.

Hi Christian,

non-legacy invalidation can invalidate the TLB while it is in use.
Right? Thanks.

Regards,
Lang

> For Polaris and older it just means that you don't have a guarantee that the
> shader can't access the memory any more. So delaying the free operation
> helps here.
> 
> But for Navi1x it's a workaround for a hardware bug. If you try to
> invalidate the TLB while it is in use you can potentially triggering memory
> accesses to random addresses.
> 
> That's why we still delay TLB invalidation's to the next CS and use a new
> VMID for each submission instead of invalidating the old one.
> 
> I'm currently working on changing that for Navi2x and newer (maybe Vega as
> well), but this is something you can really only do on some hw generations
> after validating that it works.
> 
> Regards,
> Christian.
> 
> > 
> > 
> > So this approach won't work in general.
> > 
> > Regards,
> > Christian.
> > 
> > >
> > > Introduce a new state "dirty", shared between per-VM BOs and
> > traditional
> > > BOs, containing all BOs that have pending updates in `invalids`.
> > > amdgpu_gem_va_update_vm will now simply flush any pending
> > updates for BOs
> > > in the dirty state.
> > >
> > > Signed-off-by: Tatsuyuki Ishi 
> > > ---
> > >   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 18 ---
> > >   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 66
> > ++---
> > >   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  3 ++
> > >   3 files changed, 63 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > index a1b15d0d6c48..01d3a97248b0 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> > > @@ -604,10 +604,9 @@ int amdgpu_gem_metadata_ioctl(struct
> > drm_device *dev, void *data,
> > >    * vital here, so they are not reported back to userspace.
> > >    */
> > >   static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
> > > -                                 struct amdgpu_vm *vm,
> > > -                                 struct amdgpu_bo_va *bo_va,
> > > -                                 uint32_t operation)
> > > +                                 struct amdgpu_vm *vm)
> > >   {
> > > +     struct amdgpu_bo_va *bo_va;
> > >       int r;
> > >
> > >       if (!amdgpu_vm_ready(vm))
> > > @@ -617,12 +616,18 @@ static void amdgpu_gem_va_update_vm(struct
> > amdgpu_device *adev,
> > >       if (r)
> > >               goto error;
> > >
> > > -     if (operation == AMDGPU_VA_OP_MAP ||
> > > -         operation == AMDGPU_VA_OP_REPLACE) {
> > > +     spin_lock(&vm->status_lock);
> > > +     while (!list_empty(&vm->dirty)) {
> > > +             bo_va = list_first_entry(&vm->dirty, struct
> > amdgpu_bo_va,
> > > +                                      base.vm_status);
> > > +             spin_unlock(&vm->status_lock);
> > > +
> > >               r = amdgpu_vm_bo_update(adev, bo_va, false);
> > >               if (r)
> > >                       goto error;
> > > +             spin_lock(&vm->status_lock);
> > >       }
> > > +     spin_unlock(&vm->status_lock);
> > >
> > >       r = amdgpu_vm_update_pdes(adev, vm, false);
> > >
> > > @@ -792,8 +797,7 @@ int amdgpu_gem_va_ioctl(struct drm_device
> > *dev, void *data,
> > >               break;
> > >       }
> > >       if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) &&
> > !amdgpu_vm_debug)
> > > -             amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
> > > -  args->operation);
> > > +             amdgpu_gem_va_update_vm(adev, &fpriv->vm);
> > >
> > >   error:
> > >       drm_exec_fini(&exec);
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> > b

RE: [PATCH v2 1/2] drm/amdgpu: Optimize the asic type fix code

2023-11-01 Thread Feng, Kenneth
[AMD Official Use Only - General]

Reviewed-by: Kenneth Feng 


-Original Message-
From: Ma, Jun 
Sent: Thursday, November 2, 2023 8:58 AM
To: Ma, Jun ; amd-gfx@lists.freedesktop.org; Feng, Kenneth 
; Deucher, Alexander 
Cc: Ma, Jun 
Subject: Re: [PATCH v2 1/2] drm/amdgpu: Optimize the asic type fix code

ping...

Regards,
Ma Jun

On 11/1/2023 11:04 AM, Ma Jun wrote:
> Use a new struct array to define the asic information which asic type
> needs to be fixed.
>
> Signed-off-by: Ma Jun 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 35 ++---
>  include/drm/amd_asic_type.h |  5 
>  2 files changed, 31 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 84703e0a73bd..756cf49557a2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2067,6 +2067,14 @@ static const struct pci_device_id pciidlist[] =
> {
>
>  MODULE_DEVICE_TABLE(pci, pciidlist);
>
> +static const struct amdgpu_asic_type_quirk asic_type_quirks[] = {
> + /* differentiate between P10 and P11 asics with the same DID */
> + {0x67FF, 0xE3, CHIP_POLARIS10},
> + {0x67FF, 0xE7, CHIP_POLARIS10},
> + {0x67FF, 0xF3, CHIP_POLARIS10},
> + {0x67FF, 0xF7, CHIP_POLARIS10},
> +};
> +
>  static struct drm_driver amdgpu_kms_driver;
>
>  static void amdgpu_get_secondary_funcs(struct amdgpu_device *adev) @@
> -2109,6 +2117,22 @@ static void amdgpu_init_debug_options(struct 
> amdgpu_device *adev)
>   }
>  }
>
> +static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev,
> +unsigned long flags) {
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(asic_type_quirks); i++) {
> + if (pdev->device == asic_type_quirks[i].device &&
> + pdev->revision == asic_type_quirks[i].revision) {
> + flags &= ~AMD_ASIC_MASK;
> + flags |= asic_type_quirks[i].type;
> + break;
> + }
> + }
> +
> + return flags;
> +}
> +
>  static int amdgpu_pci_probe(struct pci_dev *pdev,
>   const struct pci_device_id *ent)  { @@ -2138,15 
> +2162,8 @@
> static int amdgpu_pci_probe(struct pci_dev *pdev,
>"See modparam exp_hw_support\n");
>   return -ENODEV;
>   }
> - /* differentiate between P10 and P11 asics with the same DID */
> - if (pdev->device == 0x67FF &&
> - (pdev->revision == 0xE3 ||
> -  pdev->revision == 0xE7 ||
> -  pdev->revision == 0xF3 ||
> -  pdev->revision == 0xF7)) {
> - flags &= ~AMD_ASIC_MASK;
> - flags |= CHIP_POLARIS10;
> - }
> +
> + flags = amdgpu_fix_asic_type(pdev, flags);
>
>   /* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU 
> mapping,
>* however, SME requires an indirect IOMMU mapping because the
> encryption diff --git a/include/drm/amd_asic_type.h
> b/include/drm/amd_asic_type.h index 90b69270f2fa..724c45e3e9a7 100644
> --- a/include/drm/amd_asic_type.h
> +++ b/include/drm/amd_asic_type.h
> @@ -68,4 +68,9 @@ enum amd_asic_type {
>
>  extern const char *amdgpu_asic_name[];
>
> +struct amdgpu_asic_type_quirk {
> + unsigned short device;  /* PCI device ID */
> + u8 revision;/* revision ID */
> + unsigned short type;/* real ASIC type */
> +};
>  #endif /*__AMD_ASIC_TYPE_H__ */


Re: [PATCH v2 1/2] drm/amdgpu: Optimize the asic type fix code

2023-11-01 Thread Ma, Jun
ping...

Regards,
Ma Jun

On 11/1/2023 11:04 AM, Ma Jun wrote:
> Use a new struct array to define the asic information which
> asic type needs to be fixed.
> 
> Signed-off-by: Ma Jun 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 35 ++---
>  include/drm/amd_asic_type.h |  5 
>  2 files changed, 31 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 84703e0a73bd..756cf49557a2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2067,6 +2067,14 @@ static const struct pci_device_id pciidlist[] = {
>  
>  MODULE_DEVICE_TABLE(pci, pciidlist);
>  
> +static const struct amdgpu_asic_type_quirk asic_type_quirks[] = {
> + /* differentiate between P10 and P11 asics with the same DID */
> + {0x67FF, 0xE3, CHIP_POLARIS10},
> + {0x67FF, 0xE7, CHIP_POLARIS10},
> + {0x67FF, 0xF3, CHIP_POLARIS10},
> + {0x67FF, 0xF7, CHIP_POLARIS10},
> +};
> +
>  static struct drm_driver amdgpu_kms_driver;
>  
>  static void amdgpu_get_secondary_funcs(struct amdgpu_device *adev)
> @@ -2109,6 +2117,22 @@ static void amdgpu_init_debug_options(struct 
> amdgpu_device *adev)
>   }
>  }
>  
> +static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned 
> long flags)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(asic_type_quirks); i++) {
> + if (pdev->device == asic_type_quirks[i].device &&
> + pdev->revision == asic_type_quirks[i].revision) {
> + flags &= ~AMD_ASIC_MASK;
> + flags |= asic_type_quirks[i].type;
> + break;
> + }
> + }
> +
> + return flags;
> +}
> +
>  static int amdgpu_pci_probe(struct pci_dev *pdev,
>   const struct pci_device_id *ent)
>  {
> @@ -2138,15 +2162,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
>"See modparam exp_hw_support\n");
>   return -ENODEV;
>   }
> - /* differentiate between P10 and P11 asics with the same DID */
> - if (pdev->device == 0x67FF &&
> - (pdev->revision == 0xE3 ||
> -  pdev->revision == 0xE7 ||
> -  pdev->revision == 0xF3 ||
> -  pdev->revision == 0xF7)) {
> - flags &= ~AMD_ASIC_MASK;
> - flags |= CHIP_POLARIS10;
> - }
> +
> + flags = amdgpu_fix_asic_type(pdev, flags);
>  
>   /* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU 
> mapping,
>* however, SME requires an indirect IOMMU mapping because the 
> encryption
> diff --git a/include/drm/amd_asic_type.h b/include/drm/amd_asic_type.h
> index 90b69270f2fa..724c45e3e9a7 100644
> --- a/include/drm/amd_asic_type.h
> +++ b/include/drm/amd_asic_type.h
> @@ -68,4 +68,9 @@ enum amd_asic_type {
>  
>  extern const char *amdgpu_asic_name[];
>  
> +struct amdgpu_asic_type_quirk {
> + unsigned short device;  /* PCI device ID */
> + u8 revision;/* revision ID */
> + unsigned short type;/* real ASIC type */
> +};
>  #endif /*__AMD_ASIC_TYPE_H__ */


Re: [PATCH] drm/amdgpu/smu13: drop compute workload workaround

2023-11-01 Thread Wang, Yang(Kevin)
[AMD Official Use Only - General]

Reviewed-by: Yang Wang 

Best Regards,
Kevin

From: amd-gfx  on behalf of Alex Deucher 

Sent: Thursday, November 2, 2023 03:50
To: amd-gfx@lists.freedesktop.org 
Cc: Deucher, Alexander 
Subject: [PATCH] drm/amdgpu/smu13: drop compute workload workaround

This was fixed in PMFW before launch and is no longer
required.

Signed-off-by: Alex Deucher 
---
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 32 ++-
 1 file changed, 2 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index ef0c30075658..82c4e1f1c6f0 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2530,38 +2530,10 @@ static int smu_v13_0_0_set_power_profile_mode(struct 
smu_context *smu,
 }
 }

-   if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE &&
-   (((smu->adev->pdev->device == 0x744C) && 
(smu->adev->pdev->revision == 0xC8)) ||
-   ((smu->adev->pdev->device == 0x744C) && 
(smu->adev->pdev->revision == 0xCC {
-   ret = smu_cmn_update_table(smu,
-  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-  WORKLOAD_PPLIB_COMPUTE_BIT,
-  (void *)(&activity_monitor_external),
-  false);
-   if (ret) {
-   dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-   return ret;
-   }
-
-   ret = smu_cmn_update_table(smu,
-  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-  WORKLOAD_PPLIB_CUSTOM_BIT,
-  (void *)(&activity_monitor_external),
-  true);
-   if (ret) {
-   dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-   return ret;
-   }
-
-   workload_type = smu_cmn_to_asic_specific_index(smu,
-  
CMN2ASIC_MAPPING_WORKLOAD,
-  
PP_SMC_POWER_PROFILE_CUSTOM);
-   } else {
-   /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
-   workload_type = smu_cmn_to_asic_specific_index(smu,
+   /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
+   workload_type = smu_cmn_to_asic_specific_index(smu,

CMN2ASIC_MAPPING_WORKLOAD,

smu->power_profile_mode);
-   }

 if (workload_type < 0)
 return -EINVAL;
--
2.41.0



Re: [PATCH] drm/amdgpu: fix error handling in amdgpu_vm_init

2023-11-01 Thread Felix Kuehling

On 2023-10-31 11:18, Alex Deucher wrote:

On Tue, Oct 31, 2023 at 11:12 AM Christian König
 wrote:

When clearing the root PD fails we need to properly release it again.

Signed-off-by: Christian König 

Acked-by: Alex Deucher 
Has this been submitted? I see some intermittent failures in the PSDB 
that may be related to this.


Regards,
  Felix






---
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 31 +-
  1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index d72daf15662f..5877f6e9b893 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2042,7 +2042,8 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long 
timeout)
   * Returns:
   * 0 for success, error for failure.
   */
-int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t 
xcp_id)
+int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+  int32_t xcp_id)
  {
 struct amdgpu_bo *root_bo;
 struct amdgpu_bo_vm *root;
@@ -2061,6 +2062,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm, int32_t xcp
 INIT_LIST_HEAD(&vm->done);
 INIT_LIST_HEAD(&vm->pt_freed);
 INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
+   INIT_KFIFO(vm->faults);

 /* create scheduler entities for page table updates */
 r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
@@ -2103,34 +2105,33 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm, int32_t xcp
 false, &root, xcp_id);
 if (r)
 goto error_free_delayed;
-   root_bo = &root->bo;
+
+   root_bo = amdgpu_bo_ref(&root->bo);
 r = amdgpu_bo_reserve(root_bo, true);
-   if (r)
-   goto error_free_root;
+   if (r) {
+   amdgpu_bo_unref(&root->shadow);
+   amdgpu_bo_unref(&root_bo);
+   goto error_free_delayed;
+   }

+   amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
 r = dma_resv_reserve_fences(root_bo->tbo.base.resv, 1);
 if (r)
-   goto error_unreserve;
-
-   amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
+   goto error_free_root;

 r = amdgpu_vm_pt_clear(adev, vm, root, false);
 if (r)
-   goto error_unreserve;
+   goto error_free_root;

 amdgpu_bo_unreserve(vm->root.bo);
-
-   INIT_KFIFO(vm->faults);
+   amdgpu_bo_unref(&root_bo);

 return 0;

-error_unreserve:
-   amdgpu_bo_unreserve(vm->root.bo);
-
  error_free_root:
-   amdgpu_bo_unref(&root->shadow);
+   amdgpu_vm_pt_free_root(adev, vm);
+   amdgpu_bo_unreserve(vm->root.bo);
 amdgpu_bo_unref(&root_bo);
-   vm->root.bo = NULL;

  error_free_delayed:
 dma_fence_put(vm->last_tlb_flush);
--
2.34.1



Re: [PATCH] drm/edid: add a quirk for two 240Hz Samsung monitors

2023-11-01 Thread Alex Deucher
On Wed, Nov 1, 2023 at 5:01 PM Hamza Mahfooz  wrote:
>
> Without this fix the 5120x1440@240 timing of these monitors
> leads to screen flickering.
>
> Cc: sta...@vger.kernel.org # 6.1+
> Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1442
> Co-developed-by: Harry Wentland 
> Signed-off-by: Harry Wentland 
> Signed-off-by: Hamza Mahfooz 
> ---
>  drivers/gpu/drm/drm_edid.c | 47 +++---
>  1 file changed, 44 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index bca2af4fe1fc..3fdb8907f66b 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -89,6 +89,8 @@ static int oui(u8 first, u8 second, u8 third)
>  #define EDID_QUIRK_NON_DESKTOP (1 << 12)
>  /* Cap the DSC target bitrate to 15bpp */
>  #define EDID_QUIRK_CAP_DSC_15BPP   (1 << 13)
> +/* Fix up a particular 5120x1440@240Hz timing */
> +#define EDID_QUIRK_FIXUP_5120_1440_240 (1 << 14)

What is wrong with the original timing that needs to be fixed?

Alex


>
>  #define MICROSOFT_IEEE_OUI 0xca125c
>
> @@ -170,6 +172,12 @@ static const struct edid_quirk {
> EDID_QUIRK('S', 'A', 'M', 596, EDID_QUIRK_PREFER_LARGE_60),
> EDID_QUIRK('S', 'A', 'M', 638, EDID_QUIRK_PREFER_LARGE_60),
>
> +   /* Samsung C49G95T */
> +   EDID_QUIRK('S', 'A', 'M', 0x7053, EDID_QUIRK_FIXUP_5120_1440_240),
> +
> +   /* Samsung S49AG95 */
> +   EDID_QUIRK('S', 'A', 'M', 0x71ac, EDID_QUIRK_FIXUP_5120_1440_240),
> +
> /* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
> EDID_QUIRK('S', 'N', 'Y', 0x2541, EDID_QUIRK_FORCE_12BPC),
>
> @@ -6586,7 +6594,37 @@ static void update_display_info(struct drm_connector 
> *connector,
> drm_edid_to_eld(connector, drm_edid);
>  }
>
> -static struct drm_display_mode *drm_mode_displayid_detailed(struct 
> drm_device *dev,
> +static void drm_mode_displayid_detailed_edid_quirks(struct drm_connector 
> *connector,
> +   struct drm_display_mode 
> *mode)
> +{
> +   unsigned int hsync_width;
> +   unsigned int vsync_width;
> +
> +   if (connector->display_info.quirks & EDID_QUIRK_FIXUP_5120_1440_240) {
> +   if (mode->hdisplay == 5120 && mode->vdisplay == 1440 &&
> +   mode->clock == 1939490) {
> +   hsync_width = mode->hsync_end - mode->hsync_start;
> +   vsync_width = mode->vsync_end - mode->vsync_start;
> +
> +   mode->clock = 2018490;
> +   mode->hdisplay = 5120;
> +   mode->hsync_start = 5120 + 8;
> +   mode->hsync_end = 5120 + 8 + hsync_width;
> +   mode->htotal = 5200;
> +
> +   mode->vdisplay = 1440;
> +   mode->vsync_start = 1440 + 165;
> +   mode->vsync_end = 1440 + 165 + vsync_width;
> +   mode->vtotal = 1619;
> +
> +   drm_dbg_kms(connector->dev,
> +   "[CONNECTOR:%d:%s] Samsung 240Hz mode 
> quirk applied\n",
> +   connector->base.id, connector->name);
> +   }
> +   }
> +}
> +
> +static struct drm_display_mode *drm_mode_displayid_detailed(struct 
> drm_connector *connector,
> struct 
> displayid_detailed_timings_1 *timings,
> bool type_7)
>  {
> @@ -6605,7 +6643,7 @@ static struct drm_display_mode 
> *drm_mode_displayid_detailed(struct drm_device *d
> bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
> bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
>
> -   mode = drm_mode_create(dev);
> +   mode = drm_mode_create(connector->dev);
> if (!mode)
> return NULL;
>
> @@ -6628,6 +,9 @@ static struct drm_display_mode 
> *drm_mode_displayid_detailed(struct drm_device *d
>
> if (timings->flags & 0x80)
> mode->type |= DRM_MODE_TYPE_PREFERRED;
> +
> +   drm_mode_displayid_detailed_edid_quirks(connector, mode);
> +
> drm_mode_set_name(mode);
>
> return mode;
> @@ -6650,7 +6691,7 @@ static int add_displayid_detailed_1_modes(struct 
> drm_connector *connector,
> for (i = 0; i < num_timings; i++) {
> struct displayid_detailed_timings_1 *timings = 
> &det->timings[i];
>
> -   newmode = drm_mode_displayid_detailed(connector->dev, 
> timings, type_7);
> +   newmode = drm_mode_displayid_detailed(connector, timings, 
> type_7);
> if (!newmode)
> continue;
>
> --
> 2.42.0
>


[PATCH] drm/edid: add a quirk for two 240Hz Samsung monitors

2023-11-01 Thread Hamza Mahfooz
Without this fix the 5120x1440@240 timing of these monitors
leads to screen flickering.

Cc: sta...@vger.kernel.org # 6.1+
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1442
Co-developed-by: Harry Wentland 
Signed-off-by: Harry Wentland 
Signed-off-by: Hamza Mahfooz 
---
 drivers/gpu/drm/drm_edid.c | 47 +++---
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index bca2af4fe1fc..3fdb8907f66b 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -89,6 +89,8 @@ static int oui(u8 first, u8 second, u8 third)
 #define EDID_QUIRK_NON_DESKTOP (1 << 12)
 /* Cap the DSC target bitrate to 15bpp */
 #define EDID_QUIRK_CAP_DSC_15BPP   (1 << 13)
+/* Fix up a particular 5120x1440@240Hz timing */
+#define EDID_QUIRK_FIXUP_5120_1440_240 (1 << 14)
 
 #define MICROSOFT_IEEE_OUI 0xca125c
 
@@ -170,6 +172,12 @@ static const struct edid_quirk {
EDID_QUIRK('S', 'A', 'M', 596, EDID_QUIRK_PREFER_LARGE_60),
EDID_QUIRK('S', 'A', 'M', 638, EDID_QUIRK_PREFER_LARGE_60),
 
+   /* Samsung C49G95T */
+   EDID_QUIRK('S', 'A', 'M', 0x7053, EDID_QUIRK_FIXUP_5120_1440_240),
+
+   /* Samsung S49AG95 */
+   EDID_QUIRK('S', 'A', 'M', 0x71ac, EDID_QUIRK_FIXUP_5120_1440_240),
+
/* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
EDID_QUIRK('S', 'N', 'Y', 0x2541, EDID_QUIRK_FORCE_12BPC),
 
@@ -6586,7 +6594,37 @@ static void update_display_info(struct drm_connector 
*connector,
drm_edid_to_eld(connector, drm_edid);
 }
 
-static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device 
*dev,
+static void drm_mode_displayid_detailed_edid_quirks(struct drm_connector 
*connector,
+   struct drm_display_mode 
*mode)
+{
+   unsigned int hsync_width;
+   unsigned int vsync_width;
+
+   if (connector->display_info.quirks & EDID_QUIRK_FIXUP_5120_1440_240) {
+   if (mode->hdisplay == 5120 && mode->vdisplay == 1440 &&
+   mode->clock == 1939490) {
+   hsync_width = mode->hsync_end - mode->hsync_start;
+   vsync_width = mode->vsync_end - mode->vsync_start;
+
+   mode->clock = 2018490;
+   mode->hdisplay = 5120;
+   mode->hsync_start = 5120 + 8;
+   mode->hsync_end = 5120 + 8 + hsync_width;
+   mode->htotal = 5200;
+
+   mode->vdisplay = 1440;
+   mode->vsync_start = 1440 + 165;
+   mode->vsync_end = 1440 + 165 + vsync_width;
+   mode->vtotal = 1619;
+
+   drm_dbg_kms(connector->dev,
+   "[CONNECTOR:%d:%s] Samsung 240Hz mode quirk 
applied\n",
+   connector->base.id, connector->name);
+   }
+   }
+}
+
+static struct drm_display_mode *drm_mode_displayid_detailed(struct 
drm_connector *connector,
struct 
displayid_detailed_timings_1 *timings,
bool type_7)
 {
@@ -6605,7 +6643,7 @@ static struct drm_display_mode 
*drm_mode_displayid_detailed(struct drm_device *d
bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
 
-   mode = drm_mode_create(dev);
+   mode = drm_mode_create(connector->dev);
if (!mode)
return NULL;
 
@@ -6628,6 +,9 @@ static struct drm_display_mode 
*drm_mode_displayid_detailed(struct drm_device *d
 
if (timings->flags & 0x80)
mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+   drm_mode_displayid_detailed_edid_quirks(connector, mode);
+
drm_mode_set_name(mode);
 
return mode;
@@ -6650,7 +6691,7 @@ static int add_displayid_detailed_1_modes(struct 
drm_connector *connector,
for (i = 0; i < num_timings; i++) {
struct displayid_detailed_timings_1 *timings = &det->timings[i];
 
-   newmode = drm_mode_displayid_detailed(connector->dev, timings, 
type_7);
+   newmode = drm_mode_displayid_detailed(connector, timings, 
type_7);
if (!newmode)
continue;
 
-- 
2.42.0



[PATCH 11/12] drm/amd/display: Fix handling duplicate planes on one stream

2023-11-01 Thread Hersen Wu
From: Sung Joon Kim 

[why]
DML2 does not handle the case when we have
a single stream sourcing 2 or more planes
that are duplicates of one another. To properly
handle this scenario, pipe index to plane index
mapping is used to decide which plane is being
processed and programmed.

[how]
Create static array of pipe index to plane index map.
Populate the array properly and use in appropriate places.

Reviewed-by: Xi (Alex) Liu 
Acked-by: Hersen Wu 
Signed-off-by: Sung Joon Kim 
Signed-off-by: Hersen Wu 
---
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   | 45 ++--
 .../amd/display/dc/dml2/dml2_internal_types.h |  3 ++
 .../display/dc/dml2/dml2_translation_helper.c | 54 ---
 .../display/dc/dml2/dml2_translation_helper.h |  2 +-
 .../gpu/drm/amd/display/dc/dml2/dml2_utils.c  | 18 ---
 .../drm/amd/display/dc/dml2/dml2_wrapper.c|  2 +-
 6 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index 82a1152e18b5..1a2b24cc6b61 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -55,10 +55,11 @@ struct dc_pipe_mapping_scratch {
struct dc_plane_pipe_pool pipe_pool;
 };
 
-static bool get_plane_id(const struct dc_state *state, const struct 
dc_plane_state *plane,
-   unsigned int stream_id, unsigned int *plane_id)
+static bool get_plane_id(struct dml2_context *dml2, const struct dc_state 
*state, const struct dc_plane_state *plane,
+   unsigned int stream_id, unsigned int plane_index, unsigned int 
*plane_id)
 {
int i, j;
+   bool is_plane_duplicate = dml2->v20.scratch.plane_duplicate_exists;
 
if (!plane_id)
return false;
@@ -66,7 +67,8 @@ static bool get_plane_id(const struct dc_state *state, const 
struct dc_plane_sta
for (i = 0; i < state->stream_count; i++) {
if (state->streams[i]->stream_id == stream_id) {
for (j = 0; j < state->stream_status[i].plane_count; 
j++) {
-   if (state->stream_status[i].plane_states[j] == 
plane) {
+   if (state->stream_status[i].plane_states[j] == 
plane &&
+   (!is_plane_duplicate || 
(is_plane_duplicate && (j == plane_index {
*plane_id = (i << 16) | j;
return true;
}
@@ -123,8 +125,9 @@ static struct pipe_ctx *find_master_pipe_of_plane(struct 
dml2_context *ctx,
unsigned int plane_id_assigned_to_pipe;
 
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-   if (state->res_ctx.pipe_ctx[i].plane_state && 
get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
-   state->res_ctx.pipe_ctx[i].stream->stream_id, 
&plane_id_assigned_to_pipe)) {
+   if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, 
state, state->res_ctx.pipe_ctx[i].plane_state,
+   state->res_ctx.pipe_ctx[i].stream->stream_id,
+   
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx],
 &plane_id_assigned_to_pipe)) {
if (plane_id_assigned_to_pipe == plane_id)
return &state->res_ctx.pipe_ctx[i];
}
@@ -141,8 +144,9 @@ static unsigned int find_pipes_assigned_to_plane(struct 
dml2_context *ctx,
unsigned int plane_id_assigned_to_pipe;
 
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-   if (state->res_ctx.pipe_ctx[i].plane_state && 
get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
-   state->res_ctx.pipe_ctx[i].stream->stream_id, 
&plane_id_assigned_to_pipe)) {
+   if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, 
state, state->res_ctx.pipe_ctx[i].plane_state,
+   state->res_ctx.pipe_ctx[i].stream->stream_id,
+   
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx],
 &plane_id_assigned_to_pipe)) {
if (plane_id_assigned_to_pipe == plane_id)
pipes[num_found++] = i;
}
@@ -609,6 +613,7 @@ static struct pipe_ctx *assign_pipes_to_plane(struct 
dml2_context *ctx, struct d
const struct dc_plane_state *plane,
int odm_factor,
int mpc_factor,
+   int plane_index,
struct dc_plane_pipe_pool *pipe_pool,
const struct dc_state *existing_state)
 {
@@ -620,7 +625,7 @@ static struct pipe_ctx *assign_pipes_to_plane(struct 
dml2_context *ctx, struct d
unsigned int next_pipe_to_assign;
int odm_slice,

[PATCH 09/12] drm/amd/display: Set stream's DP test pattern upon test request

2023-11-01 Thread Hersen Wu
From: George Shen 

[Why]
A recent refactor of DC's DP test pattern automation code requires the
DC stream's test pattern and test pattern color space fields to be
correctly populated before calling dc_link_dp_set_test_pattern.

[How]
Populate stream's test pattern type and color space fields before
calling into DC to program DP test pattern.

Reviewed-by: Aurabindo Pillai 
Acked-by: Hersen Wu 
Signed-off-by: George Shen 
Signed-off-by: Hersen Wu 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 9cd83b780102..ed784cf27d39 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -1216,6 +1216,9 @@ bool dm_helpers_dp_handle_test_pattern_request(
 
}
 
+   pipe_ctx->stream->test_pattern.type = test_pattern;
+   pipe_ctx->stream->test_pattern.color_space = test_pattern_color_space;
+
dc_link_dp_set_test_pattern(
(struct dc_link *) link,
test_pattern,
-- 
2.25.1



[PATCH 12/12] drm/amd/display: Promote DAL to 3.2.259

2023-11-01 Thread Hersen Wu
From: Aric Cyr 

Acked-by: Hersen Wu 
Signed-off-by: Aric Cyr 

Summary:

- Enable DCN35 physymclk root clock gating
- Fix DP automation test pattern bug
- Disable OTG for mode switch from TMDS to FRL
- Refactor DML2
- Revert Fix handling duplicate planes on one stream
- Revert Enable DCN clock gating
- Implement cursor P-State allow for SubVP
- Optimize pipe otg allocation
- Save and restore mall state while switching from ODM to Subvp
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 09328f1670aa..c5e7da302acb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -49,7 +49,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.258"
+#define DC_VER "3.2.259"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.25.1



[PATCH 10/12] drm/amd/display: Enable physymclk RCO

2023-11-01 Thread Hersen Wu
From: Daniel Miess 

[Why]
Enable the last of the RCO options for dcn35

[How]
Breakout RCO from dccg35_set_physymclk so that
physymclk RCO can be set in dccg_init without
disabling physymclk

Reviewed-by: Nicholas Kazlauskas 
Reviewed-by: Jun Lei 
Acked-by: Hersen Wu 
Signed-off-by: Daniel Miess 
Signed-off-by: Hersen Wu 
---
 .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c | 72 ++-
 .../drm/amd/display/dc/dcn35/dcn35_resource.c | 20 +-
 .../drm/amd/display/dc/hwss/dce/dce_hwseq.h   | 18 -
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   | 24 ++-
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |  5 ++
 5 files changed, 102 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
index 277aae811eea..479f3683c0b7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
@@ -325,6 +325,43 @@ static void dccg35_set_dpstreamclk(
}
 }
 
+static void dccg35_set_physymclk_root_clock_gating(
+   struct dccg *dccg,
+   int phy_inst,
+   bool enable)
+{
+   struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+   if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+   return;
+
+   switch (phy_inst) {
+   case 0:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+   PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 1:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+   PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 2:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+   PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 3:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+   PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 4:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+   PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   default:
+   BREAK_TO_DEBUGGER();
+   return;
+   }
+}
+
 static void dccg35_set_physymclk(
struct dccg *dccg,
int phy_inst,
@@ -340,16 +377,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
PHYASYMCLK_EN, 1,
PHYASYMCLK_SRC_SEL, clk_src);
-   if 
(dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
-   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
-   PHYASYMCLK_ROOT_GATE_DISABLE, 1);
} else {
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
PHYASYMCLK_EN, 0,
PHYASYMCLK_SRC_SEL, 0);
-   if 
(dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
-   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
-   PHYASYMCLK_ROOT_GATE_DISABLE, 0);
}
break;
case 1:
@@ -357,16 +388,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
PHYBSYMCLK_EN, 1,
PHYBSYMCLK_SRC_SEL, clk_src);
-   if 
(dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
-   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
-   PHYBSYMCLK_ROOT_GATE_DISABLE, 1);
} else {
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
PHYBSYMCLK_EN, 0,
PHYBSYMCLK_SRC_SEL, 0);
-   if 
(dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
-   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
-   PHYBSYMCLK_ROOT_GATE_DISABLE, 0);
}
break;
case 2:
@@ -374,16 +399,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
PHYCSYMCLK_EN, 1,
PHYCSYMCLK_SRC_SEL, clk_src);
-   if 
(dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
-   REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
-   PHYCSYMCLK_ROOT_GATE_DISABLE, 1);
} else {
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
PHYCSYMCLK_EN, 0,
   

[PATCH 08/12] drm/amd/display: Remove unused duplicate register definition

2023-11-01 Thread Hersen Wu
From: Joshua Aberback 

[Why]
DCN32 uses ABM register definitions in dcn32_resource.h, remove
duplicate from dce_abm.h to avoid confusion.

Reviewed-by: Dillon Varone 
Acked-by: Hersen Wu 
Signed-off-by: Joshua Aberback 
Signed-off-by: Hersen Wu 
---
 drivers/gpu/drm/amd/display/dc/dce/dce_abm.h | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h 
b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
index c50aa30614be..051e4c2b4cf2 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
@@ -128,21 +128,6 @@
SRI(DC_ABM1_ACE_THRES_12, ABM, id), \
NBIO_SR(BIOS_SCRATCH_2)
 
-#define ABM_DCN32_REG_LIST(id)\
-   SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \
-   SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \
-   SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \
-   SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \
-   SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \
-   SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \
-   SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \
-   SRI(BL1_PWM_USER_LEVEL, ABM, id), \
-   SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \
-   SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \
-   SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \
-   SRI(DC_ABM1_ACE_THRES_12, ABM, id), \
-   NBIO_SR(BIOS_SCRATCH_2)
-
 #define ABM_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
 
-- 
2.25.1



[PATCH 07/12] drm/amd/display: Disable OTG for mode timing switch on DCN35

2023-11-01 Thread Hersen Wu
From: Ovidiu Bunea 

[why]
Doing a mode timing change causes a hang when OTG is not disabled.

[how]
Add link_enc null check in disable_otg_wa to cover this case.

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Hersen Wu 
Signed-off-by: Ovidiu Bunea 
Signed-off-by: Hersen Wu 
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 085ac191c94f..0fa4fcd00de2 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -124,7 +124,8 @@ static void dcn35_disable_otg_wa(struct clk_mgr 
*clk_mgr_base, struct dc_state *
 
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
-   if (pipe->stream && (pipe->stream->dpms_off || 
dc_is_virtual_signal(pipe->stream->signal))) {
+   if (pipe->stream && (pipe->stream->dpms_off || 
dc_is_virtual_signal(pipe->stream->signal) ||
+!pipe->stream->link_enc)) {
struct stream_encoder *stream_enc = 
pipe->stream_res.stream_enc;
 
if (disable) {
-- 
2.25.1



[PATCH 06/12] drm/amd/display: Remove references to unused dml arch version

2023-11-01 Thread Hersen Wu
From: Chaitanya Dhere 

Clean-up the code to remove references of all unused
dml architecture versions since only dml2 is actively
used.

Reviewed-by: Jun Lei 
Acked-by: Hersen Wu 
Signed-off-by: Chaitanya Dhere 
Signed-off-by: Hersen Wu 
---
 .../amd/display/dc/dml2/dml2_dc_resource_mgmt.c  | 16 ++--
 .../amd/display/dc/dml2/dml2_internal_types.h|  1 -
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index d2046e770c50..82a1152e18b5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -911,26 +911,14 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct 
dc_state *state, const s
unsigned int stream_id;
 
const unsigned int *ODMMode, *DPPPerSurface;
-   unsigned int odm_mode_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}, 
dpp_per_surface_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0};
struct dc_pipe_mapping_scratch scratch;
 
if (ctx->config.map_dc_pipes_with_callbacks)
return map_dc_pipes_with_callbacks(
ctx, state, disp_cfg, mapping, existing_state);
 
-   if (ctx->architecture == dml2_architecture_21) {
-   /*
-* Extract ODM and DPP outputs from DML2.1 and map them in an 
array as required for pipe mapping in dml2_map_dc_pipes.
-* As data cannot be directly extracted in const pointers, 
assign these arrays to const pointers before proceeding to
-* maximize the reuse of existing code. Const pointers are 
required because dml2.0 dml_display_cfg_st is const.
-*
-*/
-   ODMMode = (const unsigned int *)odm_mode_array;
-   DPPPerSurface = (const unsigned int *)dpp_per_surface_array;
-   } else {
-   ODMMode = (unsigned int *)disp_cfg->hw.ODMMode;
-   DPPPerSurface = disp_cfg->hw.DPPPerSurface;
-   }
+   ODMMode = (unsigned int *)disp_cfg->hw.ODMMode;
+   DPPPerSurface = disp_cfg->hw.DPPPerSurface;
 
for (stream_index = 0; stream_index < state->stream_count; 
stream_index++) {
memset(&scratch, 0, sizeof(struct dc_pipe_mapping_scratch));
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
index ed5b767d46e0..df46a866f801 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
@@ -104,7 +104,6 @@ struct dml2_helper_det_policy_scratch {
 
 enum dml2_architecture {
dml2_architecture_20,
-   dml2_architecture_21
 };
 
 struct dml2_context {
-- 
2.25.1



[PATCH 05/12] drm/amd/display: Revert Fix handling duplicate planes on one stream

2023-11-01 Thread Hersen Wu
From: Sung Joon Kim 

This reverts commit 2b30049e735fce887108ed4d01726c4daf69ed3d

Reviewed-by: Aric Cyr 
Acked-by: Hersen Wu 
Signed-off-by: Sung Joon Kim 
Signed-off-by: Hersen Wu 
---
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   | 45 ---
 .../amd/display/dc/dml2/dml2_internal_types.h |  3 -
 .../display/dc/dml2/dml2_translation_helper.c | 78 ++-
 .../display/dc/dml2/dml2_translation_helper.h |  2 +-
 .../gpu/drm/amd/display/dc/dml2/dml2_utils.c  | 18 ++---
 .../drm/amd/display/dc/dml2/dml2_wrapper.c|  2 +-
 6 files changed, 34 insertions(+), 114 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index 38cfea3ea755..d2046e770c50 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -55,11 +55,10 @@ struct dc_pipe_mapping_scratch {
struct dc_plane_pipe_pool pipe_pool;
 };
 
-static bool get_plane_id(struct dml2_context *dml2, const struct dc_state 
*state, const struct dc_plane_state *plane,
-   unsigned int stream_id, unsigned int plane_index, unsigned int 
*plane_id)
+static bool get_plane_id(const struct dc_state *state, const struct 
dc_plane_state *plane,
+   unsigned int stream_id, unsigned int *plane_id)
 {
int i, j;
-   bool is_plane_duplicate = dml2->v20.scratch.plane_duplicate_exists;
 
if (!plane_id)
return false;
@@ -67,8 +66,7 @@ static bool get_plane_id(struct dml2_context *dml2, const 
struct dc_state *state
for (i = 0; i < state->stream_count; i++) {
if (state->streams[i]->stream_id == stream_id) {
for (j = 0; j < state->stream_status[i].plane_count; 
j++) {
-   if (state->stream_status[i].plane_states[j] == 
plane &&
-   (!is_plane_duplicate || 
(is_plane_duplicate && (j == plane_index {
+   if (state->stream_status[i].plane_states[j] == 
plane) {
*plane_id = (i << 16) | j;
return true;
}
@@ -125,9 +123,8 @@ static struct pipe_ctx *find_master_pipe_of_plane(struct 
dml2_context *ctx,
unsigned int plane_id_assigned_to_pipe;
 
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-   if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, 
state, state->res_ctx.pipe_ctx[i].plane_state,
-   state->res_ctx.pipe_ctx[i].stream->stream_id,
-   
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx],
 &plane_id_assigned_to_pipe)) {
+   if (state->res_ctx.pipe_ctx[i].plane_state && 
get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
+   state->res_ctx.pipe_ctx[i].stream->stream_id, 
&plane_id_assigned_to_pipe)) {
if (plane_id_assigned_to_pipe == plane_id)
return &state->res_ctx.pipe_ctx[i];
}
@@ -144,9 +141,8 @@ static unsigned int find_pipes_assigned_to_plane(struct 
dml2_context *ctx,
unsigned int plane_id_assigned_to_pipe;
 
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-   if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, 
state, state->res_ctx.pipe_ctx[i].plane_state,
-   state->res_ctx.pipe_ctx[i].stream->stream_id,
-   
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx],
 &plane_id_assigned_to_pipe)) {
+   if (state->res_ctx.pipe_ctx[i].plane_state && 
get_plane_id(state, state->res_ctx.pipe_ctx[i].plane_state,
+   state->res_ctx.pipe_ctx[i].stream->stream_id, 
&plane_id_assigned_to_pipe)) {
if (plane_id_assigned_to_pipe == plane_id)
pipes[num_found++] = i;
}
@@ -613,7 +609,6 @@ static struct pipe_ctx *assign_pipes_to_plane(struct 
dml2_context *ctx, struct d
const struct dc_plane_state *plane,
int odm_factor,
int mpc_factor,
-   int plane_index,
struct dc_plane_pipe_pool *pipe_pool,
const struct dc_state *existing_state)
 {
@@ -625,7 +620,7 @@ static struct pipe_ctx *assign_pipes_to_plane(struct 
dml2_context *ctx, struct d
unsigned int next_pipe_to_assign;
int odm_slice, mpc_slice;
 
-   if (!get_plane_id(ctx, state, plane, stream->stream_id, plane_index, 
&plane_id)) {
+   if (!get_plane_id(state, plane, stream->stream_id, &plane_id)) {
ASSERT(false);
return master_pipe;
}
@@ -672,16 +667,12 @@ static void free_pipe(struct pipe_ctx *pipe)
 }
 
 st

[PATCH 04/12] drm/amd/display: Create optc.h file

2023-11-01 Thread Hersen Wu
From: Rodrigo Siqueira 

For all the components that participate in DCN architecture, there is a
header in the dc/inch/hw. For some reason, OPTC broke this pattern and
added all the primary functions/structs associated with that in the
dcn10_optc.h file. For consistency's sake, this commit introduces a new
optc.h file and extracts the code from dcn10_optc to this new file.

Reviewed-by: Hamza Mahfooz 
Acked-by: Hersen Wu 
Signed-off-by: Rodrigo Siqueira 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   |   2 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 186 +--
 drivers/gpu/drm/amd/display/dc/inc/hw/optc.h  | 219 ++
 3 files changed, 221 insertions(+), 186 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/inc/hw/optc.h

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index 0f580ea37576..133af994a08c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -37,7 +37,7 @@
 #include 
 #include 
 #include 
-#include "dcn10/dcn10_optc.h"
+#include "dc/inc/hw/optc.h"
 
 #include "dc/inc/core_types.h"
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
index aaf6c981fd9e..ab81594a7fad 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -26,7 +26,7 @@
 #ifndef __DC_TIMING_GENERATOR_DCN10_H__
 #define __DC_TIMING_GENERATOR_DCN10_H__
 
-#include "timing_generator.h"
+#include "optc.h"
 
 #define DCN10TG_FROM_TG(tg)\
container_of(tg, struct optc, base)
@@ -594,190 +594,6 @@ struct dcn_optc_mask {
TG_REG_FIELD_LIST_DCN3_5(uint32_t)
 };
 
-struct optc {
-   struct timing_generator base;
-
-   const struct dcn_optc_registers *tg_regs;
-   const struct dcn_optc_shift *tg_shift;
-   const struct dcn_optc_mask *tg_mask;
-
-   int opp_count;
-
-   uint32_t max_h_total;
-   uint32_t max_v_total;
-
-   uint32_t min_h_blank;
-
-   uint32_t min_h_sync_width;
-   uint32_t min_v_sync_width;
-   uint32_t min_v_blank;
-   uint32_t min_v_blank_interlace;
-
-   int vstartup_start;
-   int vupdate_offset;
-   int vupdate_width;
-   int vready_offset;
-   struct dc_crtc_timing orginal_patched_timing;
-   enum signal_type signal;
-};
-
 void dcn10_timing_generator_init(struct optc *optc);
 
-struct dcn_otg_state {
-   uint32_t v_blank_start;
-   uint32_t v_blank_end;
-   uint32_t v_sync_a_pol;
-   uint32_t v_total;
-   uint32_t v_total_max;
-   uint32_t v_total_min;
-   uint32_t v_total_min_sel;
-   uint32_t v_total_max_sel;
-   uint32_t v_sync_a_start;
-   uint32_t v_sync_a_end;
-   uint32_t h_blank_start;
-   uint32_t h_blank_end;
-   uint32_t h_sync_a_start;
-   uint32_t h_sync_a_end;
-   uint32_t h_sync_a_pol;
-   uint32_t h_total;
-   uint32_t underflow_occurred_status;
-   uint32_t otg_enabled;
-   uint32_t blank_enabled;
-   uint32_t vertical_interrupt1_en;
-   uint32_t vertical_interrupt1_line;
-   uint32_t vertical_interrupt2_en;
-   uint32_t vertical_interrupt2_line;
-};
-
-void optc1_read_otg_state(struct optc *optc1,
-   struct dcn_otg_state *s);
-
-bool optc1_get_hw_timing(struct timing_generator *tg,
-   struct dc_crtc_timing *hw_crtc_timing);
-
-bool optc1_validate_timing(
-   struct timing_generator *optc,
-   const struct dc_crtc_timing *timing);
-
-void optc1_program_timing(
-   struct timing_generator *optc,
-   const struct dc_crtc_timing *dc_crtc_timing,
-   int vready_offset,
-   int vstartup_start,
-   int vupdate_offset,
-   int vupdate_width,
-   const enum signal_type signal,
-   bool use_vbios);
-
-void optc1_setup_vertical_interrupt0(
-   struct timing_generator *optc,
-   uint32_t start_line,
-   uint32_t end_line);
-void optc1_setup_vertical_interrupt1(
-   struct timing_generator *optc,
-   uint32_t start_line);
-void optc1_setup_vertical_interrupt2(
-   struct timing_generator *optc,
-   uint32_t start_line);
-
-void optc1_program_global_sync(
-   struct timing_generator *optc,
-   int vready_offset,
-   int vstartup_start,
-   int vupdate_offset,
-   int vupdate_width);
-
-bool optc1_disable_crtc(struct timing_generator *optc);
-
-bool optc1_is_counter_moving(struct timing_generator *optc);
-
-void optc1_get_position(struct timing_generator *optc,
-   struct crtc_position *position);
-
-uint32_t optc1_get_vblank_counter(struct timing_generator *optc);
-
-void optc1_get_crtc_scanoutpos(
-   struct timing_generator *optc,
-   uint32_t *v_blank_start,
-   uint32_t *v

[PATCH 01/12] drm/amd/display: save and restore mall state when applying minimal transition

2023-11-01 Thread Hersen Wu
From: Wenjing Liu 

[why]
There is a case when we are switching from ODM combine to Subvp where
minimal transition based off subvp state is required. In thise case, we
need to save and restore mall state when applying minimal transition.

Reviewed-by: Dillon Varone 
Acked-by: Hersen Wu 
Signed-off-by: Wenjing Liu 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index de8e5b18a12c..7b9bf5cb4529 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4116,8 +4116,17 @@ static bool 
commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
bool success = false;
struct dc_state *minimal_transition_context;
struct pipe_split_policy_backup policy;
+   struct mall_temp_config mall_temp_config;
 
/* commit based on new context */
+   /* Since all phantom pipes are removed in full validation,
+* we have to save and restore the subvp/mall config when
+* we do a minimal transition since the flags marking the
+* pipe as subvp/phantom will be cleared (dc copy constructor
+* creates a shallow copy).
+*/
+   if (dc->res_pool->funcs->save_mall_state)
+   dc->res_pool->funcs->save_mall_state(dc, context, 
&mall_temp_config);
minimal_transition_context = create_minimal_transition_state(dc,
context, &policy);
if (minimal_transition_context) {
@@ -4126,9 +4135,20 @@ static bool 
commit_minimal_transition_state_for_windowed_mpo_odm(struct dc *dc,
dc->hwss.is_pipe_topology_transition_seamless(
dc, minimal_transition_context, 
context)) {
DC_LOG_DC("%s base = new state\n", __func__);
+
success = dc_commit_state_no_check(dc, 
minimal_transition_context) == DC_OK;
}
release_minimal_transition_state(dc, 
minimal_transition_context, &policy);
+   if (dc->res_pool->funcs->restore_mall_state)
+   dc->res_pool->funcs->restore_mall_state(dc, context, 
&mall_temp_config);
+   /* If we do a minimal transition with plane removal and the 
context
+* has subvp we also have to retain back the phantom stream / 
planes
+* since the refcount is decremented as part of the min 
transition
+* (we commit a state with no subvp, so the phantom streams / 
planes
+* had to be removed).
+*/
+   if (dc->res_pool->funcs->retain_phantom_pipes)
+   dc->res_pool->funcs->retain_phantom_pipes(dc, context);
}
 
if (!success) {
-- 
2.25.1



[PATCH 03/12] drm/amd/display: Revert Enable DCN clock gating

2023-11-01 Thread Hersen Wu
From: Daniel Miess 

[Why]
DCN clock gating enablement is preventing light up on
high resolution DSC display

[How]
This reverts commit 933b6692d58671e47dff15b77abe69ccb4891298.

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Hersen Wu 
Signed-off-by: Daniel Miess 
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h|  6 +-
 drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c| 12 
 drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c | 10 +-
 drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h |  1 +
 .../gpu/drm/amd/display/dc/dcn35/dcn35_resource.c|  2 +-
 .../gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c  | 11 ++-
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h |  4 
 drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h  |  2 ++
 8 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
index 76da59d8caaf..ab6d09c6fe34 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
@@ -291,11 +291,7 @@
type SYMCLKB_FE_SRC_SEL;\
type SYMCLKC_FE_SRC_SEL;\
type SYMCLKD_FE_SRC_SEL;\
-   type SYMCLKE_FE_SRC_SEL;\
-   type DTBCLK_P0_GATE_DISABLE;\
-   type DTBCLK_P1_GATE_DISABLE;\
-   type DTBCLK_P2_GATE_DISABLE;\
-   type DTBCLK_P3_GATE_DISABLE;\
+   type SYMCLKE_FE_SRC_SEL;
 
 struct dccg_shift {
DCCG_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
index c5d7f67d9856..277aae811eea 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
@@ -744,17 +744,6 @@ static void dccg35_disable_symclk_se(struct dccg *dccg, 
uint32_t stream_enc_inst
}
 }
 
-static void dccg35_set_dtbclk_dto_gating(struct dccg *dccg, bool enable)
-{
-   struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
-
-   REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
-   DTBCLK_P0_GATE_DISABLE, enable ? 0x0 : 0x1,
-   DTBCLK_P1_GATE_DISABLE, enable ? 0x0 : 0x1,
-   DTBCLK_P2_GATE_DISABLE, enable ? 0x0 : 0x1,
-   DTBCLK_P3_GATE_DISABLE, enable ? 0x0 : 0x1);
-}
-
 static const struct dccg_funcs dccg35_funcs = {
.update_dpp_dto = dccg35_update_dpp_dto,
.dpp_root_clock_control = dccg35_dpp_root_clock_control,
@@ -780,7 +769,6 @@ static const struct dccg_funcs dccg35_funcs = {
.enable_symclk_se = dccg35_enable_symclk_se,
.disable_symclk_se = dccg35_disable_symclk_se,
.set_dtbclk_p_src = dccg35_set_dtbclk_p_src,
-   .set_dtbclk_dto_gating = dccg35_set_dtbclk_dto_gating,
 };
 
 struct dccg *dccg35_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
index 0f60c40e1fc5..46f71ff08fd1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
@@ -332,6 +332,13 @@ void pg_cntl35_io_clk_pg_control(struct pg_cntl *pg_cntl, 
bool power_on)
pg_cntl->pg_res_enable[PG_DCIO] = power_on;
 }
 
+void pg_cntl35_set_force_poweron_domain22(struct pg_cntl *pg_cntl, bool 
power_on)
+{
+   struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl);
+
+   REG_UPDATE(DOMAIN22_PG_CONFIG, DOMAIN_POWER_FORCEON, power_on ? 1 : 0);
+}
+
 static bool pg_cntl35_plane_otg_status(struct pg_cntl *pg_cntl)
 {
struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl);
@@ -501,7 +508,8 @@ static const struct pg_cntl_funcs pg_cntl35_funcs = {
.mpcc_pg_control = pg_cntl35_mpcc_pg_control,
.opp_pg_control = pg_cntl35_opp_pg_control,
.optc_pg_control = pg_cntl35_optc_pg_control,
-   .dwb_pg_control = pg_cntl35_dwb_pg_control
+   .dwb_pg_control = pg_cntl35_dwb_pg_control,
+   .set_force_poweron_domain22 = pg_cntl35_set_force_poweron_domain22
 };
 
 struct pg_cntl *pg_cntl35_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h
index 3de240884d22..069dae08e222 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h
@@ -183,6 +183,7 @@ void pg_cntl35_optc_pg_control(struct pg_cntl *pg_cntl,
unsigned int optc_inst, bool power_on);
 void pg_cntl35_dwb_pg_control(struct pg_cntl *pg_cntl, bool power_on);
 void pg_cntl35_init_pg_status(struct pg_cntl *pg_cntl);
+void pg_cntl35_set_force_poweron_domain22(struct pg_cntl *pg_cntl, bool 
power_on);
 
 struct pg_cntl *pg_cntl35_create(
struct dc_context *ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
index 4eb76896fd63..e35d4c028d01 100644
--- a/drivers/gpu/drm/amd/display/d

[PATCH 02/12] drm/amd/display: For cursor P-State allow for SubVP

2023-11-01 Thread Hersen Wu
From: Alvin Lee 

[Description]
- Similar to FPO, SubVP should also force cursor P-State
  allow instead of relying on natural assertion
- Implement code path to force and unforce cursor P-State
  allow for SubVP

Reviewed-by: Samson Tam 
Acked-by: Hersen Wu 
Signed-off-by: Alvin Lee 
---
 .../drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 17 ++---
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index 1b9f21fd4f17..6a65af8c36b9 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -615,12 +615,6 @@ void dcn32_update_force_pstate(struct dc *dc, struct 
dc_state *context)
pipe->stream->fpo_in_use)) {
if (hubp && 
hubp->funcs->hubp_update_force_pstate_disallow)

hubp->funcs->hubp_update_force_pstate_disallow(hubp, false);
-   }
-
-   /* Today only FPO uses cursor P-State force. Only clear cursor 
P-State force
-* if it's not FPO.
-*/
-   if (!pipe->stream || !pipe->stream->fpo_in_use) {
if (hubp && 
hubp->funcs->hubp_update_force_cursor_pstate_disallow)

hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, false);
}
@@ -632,17 +626,10 @@ void dcn32_update_force_pstate(struct dc *dc, struct 
dc_state *context)
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
struct hubp *hubp = pipe->plane_res.hubp;
 
-   if (pipe->stream && pipe->plane_state && 
pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+   if (pipe->stream && (pipe->stream->mall_stream_config.type == 
SUBVP_MAIN ||
+   pipe->stream->fpo_in_use)) {
if (hubp && 
hubp->funcs->hubp_update_force_pstate_disallow)

hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
-   }
-
-   if (pipe->stream && pipe->stream->fpo_in_use) {
-   if (hubp && 
hubp->funcs->hubp_update_force_pstate_disallow)
-   
hubp->funcs->hubp_update_force_pstate_disallow(hubp, true);
-   /* For now only force cursor p-state disallow for FPO
-* Needs to be added for subvp once FW side gets updated
-*/
if (hubp && 
hubp->funcs->hubp_update_force_cursor_pstate_disallow)

hubp->funcs->hubp_update_force_cursor_pstate_disallow(hubp, true);
}
-- 
2.25.1



[PATCH 00/12] DC Patches October 30, 2023

2023-11-01 Thread Hersen Wu
Title: DC Patches October 30, 2023

Start from:
  9379d9fc18582c69862dc25fb770ae2e102f29d6
  drm/amd/display: 3.2.258

Stopped at:
  0a6aa88e926196036c7cf9edb70924b659461617
  drm/amd/display: 3.2.259

This DC patchset brings improvements in multiple areas. In summary, we
highlight:

- Enable DCN35 physymclk root clock gating
- Fix DP automation test pattern bug
- Disable OTG for mode switch from TMDS to FRL
- Refactor DML2
- Revert Fix handling duplicate planes on one stream
- Revert Enable DCN clock gating
- Implement cursor P-State allow for SubVP
- Save and restore mall state while switching from ODM to Subvp


Alvin Lee (1):
  drm/amd/display: For cursor P-State allow for SubVP

Aric Cyr (1):
  drm/amd/display: Promote DAL to 3.2.259

Chaitanya Dhere (1):
  drm/amd/display: Remove references to unused dml arch version

Daniel Miess (2):
  drm/amd/display: Revert Enable DCN clock gating
  drm/amd/display: Enable physymclk RCO

George Shen (1):
  drm/amd/display: Set stream's DP test pattern upon test request

Joshua Aberback (1):
  drm/amd/display: Remove unused duplicate register definition

Ovidiu Bunea (1):
  drm/amd/display: Disable OTG for mode timing switch on DCN35

Rodrigo Siqueira (1):
  drm/amd/display: Create optc.h file

Sung Joon Kim (2):
  drm/amd/display: Revert Fix handling duplicate planes on one stream
  drm/amd/display: Fix handling duplicate planes on one stream

Wenjing Liu (1):
  drm/amd/display: save and restore mall state when applying minimal
transition

 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   3 +
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   |   2 +-
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |   3 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  20 ++
 drivers/gpu/drm/amd/display/dc/dc.h   |   2 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_abm.h  |  15 --
 .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 186 +--
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h |   6 +-
 .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c |  84 ---
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.c  |  10 +-
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.h  |   1 +
 .../drm/amd/display/dc/dcn35/dcn35_resource.c |  22 +-
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   |  16 +-
 .../amd/display/dc/dml2/dml2_internal_types.h |   1 -
 .../display/dc/dml2/dml2_translation_helper.c |  40 +---
 .../drm/amd/display/dc/hwss/dce/dce_hwseq.h   |  18 +-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   |  17 +-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  33 ++-
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |   9 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/optc.h  | 219 ++
 .../gpu/drm/amd/display/dc/inc/hw/pg_cntl.h   |   2 +
 21 files changed, 380 insertions(+), 329 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/inc/hw/optc.h

-- 
2.25.1



[PATCH] drm/amdgpu/smu13: drop compute workload workaround

2023-11-01 Thread Alex Deucher
This was fixed in PMFW before launch and is no longer
required.

Signed-off-by: Alex Deucher 
---
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 32 ++-
 1 file changed, 2 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index ef0c30075658..82c4e1f1c6f0 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2530,38 +2530,10 @@ static int smu_v13_0_0_set_power_profile_mode(struct 
smu_context *smu,
}
}
 
-   if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE &&
-   (((smu->adev->pdev->device == 0x744C) && 
(smu->adev->pdev->revision == 0xC8)) ||
-   ((smu->adev->pdev->device == 0x744C) && 
(smu->adev->pdev->revision == 0xCC {
-   ret = smu_cmn_update_table(smu,
-  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-  WORKLOAD_PPLIB_COMPUTE_BIT,
-  (void *)(&activity_monitor_external),
-  false);
-   if (ret) {
-   dev_err(smu->adev->dev, "[%s] Failed to get activity 
monitor!", __func__);
-   return ret;
-   }
-
-   ret = smu_cmn_update_table(smu,
-  SMU_TABLE_ACTIVITY_MONITOR_COEFF,
-  WORKLOAD_PPLIB_CUSTOM_BIT,
-  (void *)(&activity_monitor_external),
-  true);
-   if (ret) {
-   dev_err(smu->adev->dev, "[%s] Failed to set activity 
monitor!", __func__);
-   return ret;
-   }
-
-   workload_type = smu_cmn_to_asic_specific_index(smu,
-  
CMN2ASIC_MAPPING_WORKLOAD,
-  
PP_SMC_POWER_PROFILE_CUSTOM);
-   } else {
-   /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
-   workload_type = smu_cmn_to_asic_specific_index(smu,
+   /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
+   workload_type = smu_cmn_to_asic_specific_index(smu,
   
CMN2ASIC_MAPPING_WORKLOAD,
   smu->power_profile_mode);
-   }
 
if (workload_type < 0)
return -EINVAL;
-- 
2.41.0



Re: [PATCH] drm/amdgpu: Fix the vram base start address

2023-11-01 Thread Arunpravin Paneer Selvam

Hi Christian,

On 10/30/2023 9:34 PM, Christian König wrote:



Am 30.10.23 um 13:22 schrieb Arunpravin Paneer Selvam:

If the size returned by drm buddy allocator is higher than
the required size, we take the higher size to calculate
the buffer start address. This is required if we couldn't
trim the buffer to the requested size. This will fix the
display corruption issue on APU's which has limited VRAM
size.

gitlab issue link: https://gitlab.freedesktop.org/drm/amd/-/issues/2859
JIRA ticket link: https://ontrack-internal.amd.com/browse/SWDEV-425461

Fixes: 0a1844bf0b53 ("drm/buddy: Improve contiguous memory allocation")
Signed-off-by: Arunpravin Paneer Selvam 



Acked-by: Christian König 

IIRC that hack with the start address is actually not needed any more, 
but we need to double check this.
okay, can we just remove this hack and keep the vres->base.start value 
as the start address of the first block from the

allocated list.

Thanks,
Arun


Christian.


---
  drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 15 +--
  1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c

index 18f58efc9dc7..08916538a615 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -77,7 +77,16 @@ static inline bool 
amdgpu_is_vram_mgr_blocks_contiguous(struct list_head *head)

  return true;
  }
  +static inline u64 amdgpu_vram_mgr_blocks_size(struct list_head *head)
+{
+    struct drm_buddy_block *block;
+    u64 size = 0;
  +    list_for_each_entry(block, head, link)
+    size += amdgpu_vram_mgr_block_size(block);
+
+    return size;
+}
    /**
   * DOC: mem_info_vram_total
@@ -516,6 +525,8 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,

  mutex_unlock(&mgr->lock);
    vres->base.start = 0;
+    size = max_t(u64, amdgpu_vram_mgr_blocks_size(&vres->blocks),
+ vres->base.size);
  list_for_each_entry(block, &vres->blocks, link) {
  unsigned long start;
  @@ -523,8 +534,8 @@ static int amdgpu_vram_mgr_new(struct 
ttm_resource_manager *man,

  amdgpu_vram_mgr_block_size(block);
  start >>= PAGE_SHIFT;
  -    if (start > PFN_UP(vres->base.size))
-    start -= PFN_UP(vres->base.size);
+    if (start > PFN_UP(size))
+    start -= PFN_UP(size);
  else
  start = 0;
  vres->base.start = max(vres->base.start, start);






Re: [PATCH 03/11] drm/amdkfd: Improve amdgpu_vm_handle_moved

2023-11-01 Thread Felix Kuehling

On 2023-10-17 17:13, Felix Kuehling wrote:

Let amdgpu_vm_handle_moved update all BO VA mappings of BOs reserved by
the caller. This will be useful for handling extra BO VA mappings in
KFD VMs that are managed through the render node API.

Signed-off-by: Felix Kuehling 
Reviewed-by: Christian König 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  | 22 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 19 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  3 ++-
  4 files changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 74769afaa33d..c8f2907ebd6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1113,7 +1113,6 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_bo_list_entry *e;
struct amdgpu_bo_va *bo_va;
-   struct amdgpu_bo *bo;
unsigned int i;
int r;
  
@@ -1141,26 +1140,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)

return r;
}
  
-	amdgpu_bo_list_for_each_entry(e, p->bo_list) {

-   /* ignore duplicates */
-   bo = ttm_to_amdgpu_bo(e->tv.bo);
-   if (!bo)
-   continue;
-
-   bo_va = e->bo_va;
-   if (bo_va == NULL)
-   continue;
-
-   r = amdgpu_vm_bo_update(adev, bo_va, false);
-   if (r)
-   return r;
-
-   r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
-   if (r)
-   return r;
-   }


FYI, removing this loop seemed to cause PSDB failures, mostly in RADV 
tests. It may have been a glitch in the infrastructure, but the failures 
were consistent on the three subsequent patches, too. Restoring this 
loop seems to make the tests pass, so I'll do that for now. I don't have 
time to debug CS with RADV, and this change is not needed for my ROCm work.


Regards,
  Felix



-
-   r = amdgpu_vm_handle_moved(adev, vm);
+   r = amdgpu_vm_handle_moved(adev, vm, &p->ticket);
if (r)
return r;
  
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c

index b5e28fa3f414..e7e87a3b2601 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -409,7 +409,7 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment 
*attach)
if (!r)
r = amdgpu_vm_clear_freed(adev, vm, NULL);
if (!r)
-   r = amdgpu_vm_handle_moved(adev, vm);
+   r = amdgpu_vm_handle_moved(adev, vm, ticket);
  
  		if (r && r != -EBUSY)

DRM_ERROR("Failed to invalidate VM page tables (%d))\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index d72daf15662f..c586d0e93d75 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1285,6 +1285,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
   *
   * @adev: amdgpu_device pointer
   * @vm: requested vm
+ * @ticket: optional reservation ticket used to reserve the VM
   *
   * Make sure all BOs which are moved are updated in the PTs.
   *
@@ -1294,11 +1295,12 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
   * PTs have to be reserved!
   */
  int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
-  struct amdgpu_vm *vm)
+  struct amdgpu_vm *vm,
+  struct ww_acquire_ctx *ticket)
  {
struct amdgpu_bo_va *bo_va;
struct dma_resv *resv;
-   bool clear;
+   bool clear, unlock;
int r;
  
  	spin_lock(&vm->status_lock);

@@ -1321,17 +1323,24 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
spin_unlock(&vm->status_lock);
  
  		/* Try to reserve the BO to avoid clearing its ptes */

-   if (!adev->debug_vm && dma_resv_trylock(resv))
+   if (!adev->debug_vm && dma_resv_trylock(resv)) {
clear = false;
+   unlock = true;
+   /* The caller is already holding the reservation lock */
+   } else if (ticket && dma_resv_locking_ctx(resv) == ticket) {
+   clear = false;
+   unlock = false;
/* Somebody else is using the BO right now */
-   else
+   } else {
clear = true;
+   unlock = false;
+   }
  
  		r = amdgpu_vm_bo_update(adev, bo_va, clear);

if (r)
return r;
  
-		if (!clear)

+  

[PATCH 2/2] drm/amdgpu: Use drm_exec for seq64 bo lock

2023-11-01 Thread Arunpravin Paneer Selvam
Replace seq64 bo lock sequences with drm_exec.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 73 ++-
 1 file changed, 33 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
index 63d8b68023be..810f7637096e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
@@ -25,6 +25,8 @@
 #include "amdgpu.h"
 #include "amdgpu_seq64.h"
 
+#include 
+
 /**
  * DOC: amdgpu_seq64
  *
@@ -68,11 +70,8 @@ static inline u64 amdgpu_seq64_get_va_base(struct 
amdgpu_device *adev)
 int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 struct amdgpu_bo_va **bo_va)
 {
-   struct ttm_validate_buffer seq64_tv;
-   struct amdgpu_bo_list_entry pd;
-   struct ww_acquire_ctx ticket;
-   struct list_head list;
struct amdgpu_bo *bo;
+   struct drm_exec exec;
u64 seq64_addr;
int r;
 
@@ -80,23 +79,20 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
if (!bo)
return -EINVAL;
 
-   INIT_LIST_HEAD(&list);
-   INIT_LIST_HEAD(&seq64_tv.head);
-
-   seq64_tv.bo = &bo->tbo;
-   seq64_tv.num_shared = 1;
-
-   list_add(&seq64_tv.head, &list);
-   amdgpu_vm_get_pd_bo(vm, &list, &pd);
-
-   r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
-   if (r)
-   return r;
+   drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
+   drm_exec_until_all_locked(&exec) {
+   r = amdgpu_vm_lock_pd(vm, &exec, 0);
+   if (likely(!r))
+   r = drm_exec_lock_obj(&exec, &bo->tbo.base);
+   drm_exec_retry_on_contention(&exec);
+   if (unlikely(r))
+   goto error;
+   }
 
*bo_va = amdgpu_vm_bo_add(adev, vm, bo);
if (!*bo_va) {
r = -ENOMEM;
-   goto error_vm;
+   goto error;
}
 
seq64_addr = amdgpu_seq64_get_va_base(adev);
@@ -104,23 +100,19 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
 AMDGPU_PTE_READABLE);
if (r) {
DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r);
-   goto error_map;
+   amdgpu_vm_bo_del(adev, *bo_va);
+   goto error;
}
 
r = amdgpu_vm_bo_update(adev, *bo_va, false);
if (r) {
DRM_ERROR("failed to do vm_bo_update on userq sem\n");
-   goto error_map;
+   amdgpu_vm_bo_del(adev, *bo_va);
+   goto error;
}
 
-   ttm_eu_backoff_reservation(&ticket, &list);
-
-   return 0;
-
-error_map:
-   amdgpu_vm_bo_del(adev, *bo_va);
-error_vm:
-   ttm_eu_backoff_reservation(&ticket, &list);
+error:
+   drm_exec_fini(&exec);
return r;
 }
 
@@ -134,12 +126,10 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
  */
 void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
 {
-   struct ttm_validate_buffer seq64_tv;
-   struct amdgpu_bo_list_entry pd;
-   struct ww_acquire_ctx ticket;
-   struct list_head list;
struct amdgpu_vm *vm;
struct amdgpu_bo *bo;
+   struct drm_exec exec;
+   int r;
 
if (!fpriv->seq64_va)
return;
@@ -149,20 +139,23 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, 
struct amdgpu_fpriv *fpriv)
return;
 
vm = &fpriv->vm;
-   INIT_LIST_HEAD(&list);
-   INIT_LIST_HEAD(&seq64_tv.head);
 
-   seq64_tv.bo = &bo->tbo;
-   seq64_tv.num_shared = 1;
-
-   list_add(&seq64_tv.head, &list);
-   amdgpu_vm_get_pd_bo(vm, &list, &pd);
+   drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
+   drm_exec_until_all_locked(&exec) {
+   r = amdgpu_vm_lock_pd(vm, &exec, 0);
+   if (likely(!r))
+   r = drm_exec_lock_obj(&exec, &bo->tbo.base);
+   drm_exec_retry_on_contention(&exec);
+   if (unlikely(r))
+   goto error;
+   }
 
-   ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
amdgpu_vm_bo_del(adev, fpriv->seq64_va);
-   ttm_eu_backoff_reservation(&ticket, &list);
 
fpriv->seq64_va = NULL;
+
+error:
+   drm_exec_fini(&exec);
 }
 
 /**
-- 
2.25.1



[PATCH 1/2] drm/amdgpu: Enable seq64 manager and fix bugs

2023-11-01 Thread Arunpravin Paneer Selvam
- Enable the seq64 mapping sequence.
- Fix wflinfo va conflict and other bugs.

v1:
  - The seq64 area needs to be included in the AMDGPU_VA_RESERVED_SIZE
otherwise the areas will conflict with user space allocations (Alex)

  - It needs to be mapped read only in the user VM (Alex)

v2:
  - Instead of just one define for TOP/BOTTOM
reserved space separate them into two (Christian)

  - Fix the CPU and VA calculations and while at it
also cleanup error handling and kerneldoc (Christian)

Signed-off-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Arunpravin Paneer Selvam 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c  |  6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c  |  8 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c| 69 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.h|  9 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h   |  5 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c|  5 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c|  5 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c|  5 +-
 11 files changed, 68 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
index 23d054526e7c..c7622efdafee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
@@ -28,7 +28,7 @@ uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev)
 {
uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT;
 
-   addr -= AMDGPU_VA_RESERVED_SIZE;
+   addr -= AMDGPU_VA_RESERVED_CSA_SIZE;
addr = amdgpu_gmc_sign_extend(addr);
 
return addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 849fffbb367d..f4455ed78e72 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -687,10 +687,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void 
*data,
uint64_t vm_size;
int r = 0;
 
-   if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
+   if (args->va_address < AMDGPU_VA_RESERVED_BOTTOM) {
dev_dbg(dev->dev,
"va_address 0x%llx is in reserved area 0x%llx\n",
-   args->va_address, AMDGPU_VA_RESERVED_SIZE);
+   args->va_address, AMDGPU_VA_RESERVED_BOTTOM);
return -EINVAL;
}
 
@@ -706,7 +706,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
args->va_address &= AMDGPU_GMC_HOLE_MASK;
 
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
-   vm_size -= AMDGPU_VA_RESERVED_SIZE;
+   vm_size -= AMDGPU_VA_RESERVED_TOP;
if (args->va_address + args->map_size > vm_size) {
dev_dbg(dev->dev,
"va_address 0x%llx is in top reserved area 0x%llx\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index b5ebafd4a3ad..bb4aa14b868c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -894,14 +894,14 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
dev_info->ids_flags |= 
AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD;
 
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
-   vm_size -= AMDGPU_VA_RESERVED_SIZE;
+   vm_size -= AMDGPU_VA_RESERVED_TOP;
 
/* Older VCE FW versions are buggy and can handle only 40bits */
if (adev->vce.fw_version &&
adev->vce.fw_version < AMDGPU_VCE_FW_53_45)
vm_size = min(vm_size, 1ULL << 40);
 
-   dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
+   dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_BOTTOM;
dev_info->virtual_address_max =
min(vm_size, AMDGPU_GMC_HOLE_START);
 
@@ -1365,6 +1365,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, 
struct drm_file *file_priv)
goto error_vm;
}
 
+   r = amdgpu_seq64_map(adev, &fpriv->vm, &fpriv->seq64_va);
+   if (r)
+   goto error_vm;
+
mutex_init(&fpriv->bo_list_lock);
idr_init_base(&fpriv->bo_list_handles, 1);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 70fe3b39c004..108908a10b92 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1325,7 +1325,7 @@ int amdgpu_mes_self_test(struct amdgpu_device *adev)
goto error_fini;
}
 
-   ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_SIZE;
+   ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM;
  

Re: [PATCH] drm/amdgpu: fix GRBM read timeout when do mes_self_test

2023-11-01 Thread Alex Deucher
On Wed, Nov 1, 2023 at 5:02 AM Tim Huang  wrote:
>
> Use a proper MEID to make sure the CP_HQD_* and CP_GFX_HQD_* registers
> can be touched when initialize the compute and gfx mqd in mes_self_test.
> Otherwise, we expect no response from CP and an GRBM eventual timeout.
>
> Signed-off-by: Tim Huang 

Acked-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> index 70fe3b39c004..5ff76163ea27 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> @@ -556,8 +556,20 @@ static void amdgpu_mes_queue_init_mqd(struct 
> amdgpu_device *adev,
> mqd_prop.hqd_queue_priority = p->hqd_queue_priority;
> mqd_prop.hqd_active = false;
>
> +   if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
> +   p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
> +   mutex_lock(&adev->srbm_mutex);
> +   amdgpu_gfx_select_me_pipe_q(adev, p->ring->me, p->ring->pipe, 
> 0, 0, 0);
> +   }
> +
> mqd_mgr->init_mqd(adev, q->mqd_cpu_ptr, &mqd_prop);
>
> +   if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
> +   p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
> +   mutex_unlock(&adev->srbm_mutex);
> +   amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, 0);
> +   }
> +
> amdgpu_bo_unreserve(q->mqd_obj);
>  }
>
> @@ -993,9 +1005,13 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int 
> gang_id,
> switch (queue_type) {
> case AMDGPU_RING_TYPE_GFX:
> ring->funcs = adev->gfx.gfx_ring[0].funcs;
> +   ring->me = adev->gfx.gfx_ring[0].me;
> +   ring->pipe = adev->gfx.gfx_ring[0].pipe;
> break;
> case AMDGPU_RING_TYPE_COMPUTE:
> ring->funcs = adev->gfx.compute_ring[0].funcs;
> +   ring->me = adev->gfx.compute_ring[0].me;
> +   ring->pipe = adev->gfx.compute_ring[0].pipe;
> break;
> case AMDGPU_RING_TYPE_SDMA:
> ring->funcs = adev->sdma.instance[0].ring.funcs;
> --
> 2.39.2
>


[PATCH 3/3] drm/amdgpu: Query and report boot status

2023-11-01 Thread Hawking Zhang
Query boot status and report boot errors. A follow
up change is needed to stop GPU initialization if boot
fails.

v2: only invoke the call for dGPU (Le/Lijo)

Signed-off-by: Hawking Zhang 
Reviewed-by: Tao Zhou 
Reviewed-by: Yang Wang 
Reviewed-by: Le Ma 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index c317a4869492..02d6246df938 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1070,6 +1070,8 @@ static int amdgpu_device_asic_init(struct amdgpu_device 
*adev)
amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(11, 0, 0)) {
amdgpu_psp_wait_for_bootloader(adev);
ret = amdgpu_atomfirmware_asic_init(adev, true);
+   /* TODO: check the return val and stop device initialization if 
boot fails */
+   amdgpu_psp_query_boot_status(adev);
return ret;
} else {
return amdgpu_atom_asic_init(adev->mode_info.atom_context);
-- 
2.17.1



[PATCH 2/3] drm/amdgpu: Add psp v13 function to query boot status

2023-11-01 Thread Hawking Zhang
Add psp v13 function to query boot status.

v2: limit the use case to dGPU only (Lijo)

Signed-off-by: Hawking Zhang 
Reviewed-by: Tao Zhou 
Reviewed-by: Yang Wang 
Reviewed-by: Le Ma 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 15 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h |  3 +
 drivers/gpu/drm/amd/amdgpu/psp_v13_0.c  | 78 +
 3 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index e6dc3cfbac0e..66d9c189af29 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -2120,6 +2120,21 @@ int amdgpu_psp_wait_for_bootloader(struct amdgpu_device 
*adev)
return ret;
 }
 
+int amdgpu_psp_query_boot_status(struct amdgpu_device *adev)
+{
+   struct psp_context *psp = &adev->psp;
+   int ret;
+
+   if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
+   return 0;
+
+   if (psp->funcs &&
+   psp->funcs->query_boot_status)
+   ret = psp->funcs->query_boot_status(psp);
+
+   return ret;
+}
+
 static int psp_hw_start(struct psp_context *psp)
 {
struct amdgpu_device *adev = psp->adev;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 7111dd32e66f..5d36ad3f48c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -134,6 +134,7 @@ struct psp_funcs {
int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
int (*vbflash_stat)(struct psp_context *psp);
int (*fatal_error_recovery_quirk)(struct psp_context *psp);
+   int (*query_boot_status)(struct psp_context *psp);
 };
 
 struct ta_funcs {
@@ -537,4 +538,6 @@ int is_psp_fw_valid(struct psp_bin_desc bin);
 
 int amdgpu_psp_wait_for_bootloader(struct amdgpu_device *adev);
 
+int amdgpu_psp_query_boot_status(struct amdgpu_device *adev);
+
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c 
b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
index 4142e2fcd866..3cf4684d0d3f 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
@@ -759,6 +759,83 @@ static int psp_v13_0_fatal_error_recovery_quirk(struct 
psp_context *psp)
return 0;
 }
 
+
+static void psp_v13_0_boot_error_reporting(struct amdgpu_device *adev,
+  uint32_t inst,
+  uint32_t boot_error)
+{
+   uint32_t socket_id;
+   uint32_t aid_id;
+   uint32_t hbm_id;
+   uint32_t reg_data;
+
+   socket_id = REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, SOCKET_ID);
+   aid_id = REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, AID_ID);
+   hbm_id = REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, HBM_ID);
+
+   reg_data = RREG32_SOC15(MP0, inst, regMP0_SMN_C2PMSG_109);
+   dev_info(adev->dev, "socket: %d, aid: %d, firmware boot failed, fw 
status is 0x%x\n",
+socket_id, aid_id, reg_data);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_MEM_TRAINING))
+   dev_info(adev->dev, "socket: %d, aid: %d, hbm: %d, memory 
training failed\n",
+socket_id, aid_id, hbm_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_FW_LOAD))
+   dev_info(adev->dev, "socket: %d, aid: %d, firmware load failed 
at boot time\n",
+socket_id, aid_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, 
GPU_ERR_WAFL_LINK_TRAINING))
+   dev_info(adev->dev, "socket: %d, aid: %d, wafl link training 
failed\n",
+socket_id, aid_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, 
GPU_ERR_XGMI_LINK_TRAINING))
+   dev_info(adev->dev, "socket: %d, aid: %d, xgmi link training 
failed\n",
+socket_id, aid_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, 
GPU_ERR_USR_CP_LINK_TRAINING))
+   dev_info(adev->dev, "socket: %d, aid: %d, usr cp link training 
failed\n",
+socket_id, aid_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, 
GPU_ERR_USR_DP_LINK_TRAINING))
+   dev_info(adev->dev, "socket: %d, aid: %d, usr dp link training 
failed\n",
+socket_id, aid_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_HBM_MEM_TEST))
+   dev_info(adev->dev, "socket: %d, aid: %d, hbm: %d, hbm memory 
test failed\n",
+socket_id, aid_id, hbm_id);
+
+   if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, 
GPU_ERR_HBM_BIST_TEST))
+   dev_info(adev->dev, "socket: %d, aid: %d, hbm: %d, hbm bist 
test failed\n",
+socket_id, aid_id, hbm_id);
+}
+
+static int psp_v13_0_query_boot_status(struct psp_context *psp)
+{
+   struct amdgpu_device *adev = psp->adev;
+   

[PATCH 1/3] drm/amdgpu: Add C2PMSG_109/126 reg field shift/masks

2023-11-01 Thread Hawking Zhang
Add MP0_C2PMSG_109/126 register field shift/masks
that are used to identify boot status by driver.

Signed-off-by: Hawking Zhang 
Reviewed-by: Tao Zhou 
Reviewed-by: Yang Wang 
Reviewed-by: Le Ma 
---
 .../include/asic_reg/mp/mp_13_0_2_sh_mask.h   | 28 +++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h 
b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h
index 6e29a185de51..765d9ca2316f 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h
@@ -242,6 +242,34 @@
 //MP0_SMN_C2PMSG_103
 #define MP0_SMN_C2PMSG_103__CONTENT__SHIFT 
   0x0
 #define MP0_SMN_C2PMSG_103__CONTENT_MASK   
   0xL
+//MP0_SMN_C2PMSG_109
+#define MP0_SMN_C2PMSG_109__CONTENT__SHIFT 
   0x0
+#define MP0_SMN_C2PMSG_109__CONTENT_MASK   
   0xL
+//MP0_SMN_C2PMSG_126
+#define MP0_SMN_C2PMSG_126__GPU_ERR_MEM_TRAINING__SHIFT
   0x0
+#define MP0_SMN_C2PMSG_126__GPU_ERR_FW_LOAD__SHIFT 
   0x1
+#define MP0_SMN_C2PMSG_126__GPU_ERR_WAFL_LINK_TRAINING__SHIFT  
   0x2
+#define MP0_SMN_C2PMSG_126__GPU_ERR_XGMI_LINK_TRAINING__SHIFT  
   0x3
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_CP_LINK_TRAINING__SHIFT
   0x4
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_DP_LINK_TRAINING__SHIFT
   0x5
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_MEM_TEST__SHIFT
   0x6
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_BIST_TEST__SHIFT   
   0x7
+#define MP0_SMN_C2PMSG_126__SOCKET_ID__SHIFT   
   0x8
+#define MP0_SMN_C2PMSG_126__AID_ID__SHIFT  
   0xb
+#define MP0_SMN_C2PMSG_126__HBM_ID__SHIFT  
   0xd
+#define MP0_SMN_C2PMSG_126__BOOT_STATUS__SHIFT 
   0x1f
+#define MP0_SMN_C2PMSG_126__GPU_ERR_MEM_TRAINING_MASK  
   0x0001L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_FW_LOAD_MASK   
   0x0002L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_WAFL_LINK_TRAINING_MASK
   0x0004L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_XGMI_LINK_TRAINING_MASK
   0x0008L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_CP_LINK_TRAINING_MASK  
   0x0010L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_DP_LINK_TRAINING_MASK  
   0x0020L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_MEM_TEST_MASK  
   0x0040L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_BIST_TEST_MASK 
   0x0080L
+#define MP0_SMN_C2PMSG_126__SOCKET_ID_MASK 
   0x0700L
+#define MP0_SMN_C2PMSG_126__AID_ID_MASK
   0x1800L
+#define MP0_SMN_C2PMSG_126__HBM_ID_MASK
   0x2000L
+#define MP0_SMN_C2PMSG_126__BOOT_STATUS_MASK   
   0x8000L
 //MP0_SMN_IH_CREDIT
 #define MP0_SMN_IH_CREDIT__CREDIT_VALUE__SHIFT 
   0x0
 #define MP0_SMN_IH_CREDIT__CLIENT_ID__SHIFT
   0x10
-- 
2.17.1



[PATCH Review 1/1] drm/amdgpu: Reset vram error data info

2023-11-01 Thread Stanley . Yang
Reset error data info stored in vram  when user clear eeprom table.

Signed-off-by: Stanley.Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c   | 97 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h   |  2 +
 .../gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c|  4 +
 3 files changed, 77 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 753260745554..9c1072ea5760 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -2336,6 +2336,77 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
return ret;
 }
 
+int amdgpu_ras_error_data_init(struct ras_err_data *err_data)
+{
+   memset(err_data, 0, sizeof(*err_data));
+
+   INIT_LIST_HEAD(&err_data->err_node_list);
+
+   return 0;
+}
+
+static void amdgpu_ras_error_node_release(struct ras_err_node *err_node)
+{
+   if (!err_node)
+   return;
+
+   list_del(&err_node->node);
+   kvfree(err_node);
+}
+
+void amdgpu_ras_error_data_fini(struct ras_err_data *err_data)
+{
+   struct ras_err_node *err_node, *tmp;
+
+   list_for_each_entry_safe(err_node, tmp, &err_data->err_node_list, node)
+   amdgpu_ras_error_node_release(err_node);
+}
+
+static void amdgpu_ras_reset_error_info(struct ras_manager *obj)
+{
+   struct ras_err_data *err_data;
+
+   if (!obj)
+   return;
+
+   err_data = &obj->err_data;
+
+   /* release all error nodes */
+   amdgpu_ras_error_data_fini(err_data);
+
+   /* reset error data and init */
+   amdgpu_ras_error_data_init(err_data);
+}
+
+/* reset vram bad pages data and umc ras manager error count */
+int amdgpu_ras_reset_vram_bad_pages(struct amdgpu_device *adev)
+{
+   struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
+   struct ras_err_handler_data *data;
+   struct ras_manager *obj;
+
+   if (!con || !con->eh_data)
+   return 0;
+
+   mutex_lock(&con->recovery_lock);
+
+   data = con->eh_data;
+   data->space_left += data->count;
+   data->count = 0;
+   memset(data->bps, 0, data->space_left * sizeof(data->bps));
+
+   mutex_unlock(&con->recovery_lock);
+
+   list_for_each_entry(obj, &con->head, node) {
+   if (obj->head.block == AMDGPU_RAS_BLOCK__UMC) {
+   amdgpu_ras_reset_error_info(obj);
+   break;
+   }
+   }
+
+   return 0;
+}
+
 /*
  * write error record array to eeprom, the function should be
  * protected by recovery_lock
@@ -3556,32 +3627,6 @@ void amdgpu_ras_inst_reset_ras_error_count(struct 
amdgpu_device *adev,
}
 }
 
-int amdgpu_ras_error_data_init(struct ras_err_data *err_data)
-{
-   memset(err_data, 0, sizeof(*err_data));
-
-   INIT_LIST_HEAD(&err_data->err_node_list);
-
-   return 0;
-}
-
-static void amdgpu_ras_error_node_release(struct ras_err_node *err_node)
-{
-   if (!err_node)
-   return;
-
-   list_del(&err_node->node);
-   kvfree(err_node);
-}
-
-void amdgpu_ras_error_data_fini(struct ras_err_data *err_data)
-{
-   struct ras_err_node *err_node, *tmp;
-
-   list_for_each_entry_safe(err_node, tmp, &err_data->err_node_list, node)
-   amdgpu_ras_error_node_release(err_node);
-}
-
 static struct ras_err_node *amdgpu_ras_error_find_node_by_id(struct 
ras_err_data *err_data,
 struct 
amdgpu_smuio_mcm_config_info *mcm_info)
 {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 665414c22ca9..64710517b9fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -622,6 +622,8 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
 int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev,
unsigned long *new_cnt);
 
+int amdgpu_ras_reset_vram_bad_pages(struct amdgpu_device *adev);
+
 static inline enum ta_ras_block
 amdgpu_ras_block_to_ta(enum amdgpu_ras_block block) {
switch (block) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
index 65aa218380be..40060f1b8ad6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
@@ -462,6 +462,10 @@ int amdgpu_ras_eeprom_reset_table(struct 
amdgpu_ras_eeprom_control *control)
 
mutex_unlock(&control->ras_tbl_mutex);
 
+   /* reset dad pages in vram structure */
+   if (amdgpu_ras_reset_vram_bad_pages(adev))
+   dev_warn(adev->dev, "reset vram bad pages structure failed, 
need reboot system\n");
+
return res;
 }
 
-- 
2.25.1



[PATCH v2] drm/amdgpu: fix GRBM read timeout when do mes_self_test

2023-11-01 Thread Tim Huang
Use a proper MEID to make sure the CP_HQD_* and CP_GFX_HQD_* registers
can be touched when initialize the compute and gfx mqd in mes_self_test.
Otherwise, we expect no response from CP and an GRBM eventual timeout.

Signed-off-by: Tim Huang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 70fe3b39c004..45280fb0e00c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -556,8 +556,20 @@ static void amdgpu_mes_queue_init_mqd(struct amdgpu_device 
*adev,
mqd_prop.hqd_queue_priority = p->hqd_queue_priority;
mqd_prop.hqd_active = false;
 
+   if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
+   p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
+   mutex_lock(&adev->srbm_mutex);
+   amdgpu_gfx_select_me_pipe_q(adev, p->ring->me, p->ring->pipe, 
0, 0, 0);
+   }
+
mqd_mgr->init_mqd(adev, q->mqd_cpu_ptr, &mqd_prop);
 
+   if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
+   p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
+   amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, 0);
+   mutex_unlock(&adev->srbm_mutex);
+   }
+
amdgpu_bo_unreserve(q->mqd_obj);
 }
 
@@ -993,9 +1005,13 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int 
gang_id,
switch (queue_type) {
case AMDGPU_RING_TYPE_GFX:
ring->funcs = adev->gfx.gfx_ring[0].funcs;
+   ring->me = adev->gfx.gfx_ring[0].me;
+   ring->pipe = adev->gfx.gfx_ring[0].pipe;
break;
case AMDGPU_RING_TYPE_COMPUTE:
ring->funcs = adev->gfx.compute_ring[0].funcs;
+   ring->me = adev->gfx.compute_ring[0].me;
+   ring->pipe = adev->gfx.compute_ring[0].pipe;
break;
case AMDGPU_RING_TYPE_SDMA:
ring->funcs = adev->sdma.instance[0].ring.funcs;
-- 
2.39.2



[PATCH] drm/amdgpu: fix GRBM read timeout when do mes_self_test

2023-11-01 Thread Tim Huang
Use a proper MEID to make sure the CP_HQD_* and CP_GFX_HQD_* registers
can be touched when initialize the compute and gfx mqd in mes_self_test.
Otherwise, we expect no response from CP and an GRBM eventual timeout.

Signed-off-by: Tim Huang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 70fe3b39c004..5ff76163ea27 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -556,8 +556,20 @@ static void amdgpu_mes_queue_init_mqd(struct amdgpu_device 
*adev,
mqd_prop.hqd_queue_priority = p->hqd_queue_priority;
mqd_prop.hqd_active = false;
 
+   if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
+   p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
+   mutex_lock(&adev->srbm_mutex);
+   amdgpu_gfx_select_me_pipe_q(adev, p->ring->me, p->ring->pipe, 
0, 0, 0);
+   }
+
mqd_mgr->init_mqd(adev, q->mqd_cpu_ptr, &mqd_prop);
 
+   if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
+   p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
+   mutex_unlock(&adev->srbm_mutex);
+   amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, 0);
+   }
+
amdgpu_bo_unreserve(q->mqd_obj);
 }
 
@@ -993,9 +1005,13 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int 
gang_id,
switch (queue_type) {
case AMDGPU_RING_TYPE_GFX:
ring->funcs = adev->gfx.gfx_ring[0].funcs;
+   ring->me = adev->gfx.gfx_ring[0].me;
+   ring->pipe = adev->gfx.gfx_ring[0].pipe;
break;
case AMDGPU_RING_TYPE_COMPUTE:
ring->funcs = adev->gfx.compute_ring[0].funcs;
+   ring->me = adev->gfx.compute_ring[0].me;
+   ring->pipe = adev->gfx.compute_ring[0].pipe;
break;
case AMDGPU_RING_TYPE_SDMA:
ring->funcs = adev->sdma.instance[0].ring.funcs;
-- 
2.39.2



[PATCH] drm/radeon/ni_dpm: add an error code check in ni_dpm_init

2023-11-01 Thread Su Hui
ni_patch_single_dependency_table_based_on_leakage() return zero or
negative error code. But ni_patch_dependency_tables_based_on_leakage()
doesn't check the return value of the first function call. It's same for
ni_dpm_init(). It's better to add this error code check.

Signed-off-by: Su Hui 
---
 drivers/gpu/drm/radeon/ni_dpm.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 3e1c1a392fb7..f521dc929a06 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -1010,6 +1010,8 @@ static int 
ni_patch_dependency_tables_based_on_leakage(struct radeon_device *rde
 
ret = ni_patch_single_dependency_table_based_on_leakage(rdev,

&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
+   if (ret)
+   return ret;
 
ret = ni_patch_single_dependency_table_based_on_leakage(rdev,

&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
@@ -4098,7 +4100,12 @@ int ni_dpm_init(struct radeon_device *rdev)
rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 
72000;
rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
 
-   ni_patch_dependency_tables_based_on_leakage(rdev);
+   ret = ni_patch_dependency_tables_based_on_leakage(rdev);
+   if (ret) {
+   
kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
+   r600_free_extended_power_table(rdev);
+   return ret;
+   }
 
if (rdev->pm.dpm.voltage_response_time == 0)
rdev->pm.dpm.voltage_response_time = 
R600_VOLTAGERESPONSETIME_DFLT;
-- 
2.30.2