On Mon, Nov 3, 2025 at 2:54 AM Yo-Jung Leo Lin (AMD) <[email protected]> wrote:
>
> Currently, the available UMA allocation configs in the integrated system
> information table have not been parsed. Add a helper function to retrieve
> and store these configs.
>
> Co-developed-by: Mario Limonciello (AMD) <[email protected]>
> Signed-off-by: Mario Limonciello (AMD) <[email protected]>
> Signed-off-by: Yo-Jung Leo Lin (AMD) <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c     | 32 ++++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 75 
> ++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h |  1 +
>  drivers/gpu/drm/amd/amdgpu/atom.h                |  4 ++
>  4 files changed, 107 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> index 763f2b8dcf13..58cc3bc9d42d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
> @@ -28,6 +28,7 @@
>  #include "amdgpu.h"
>  #include "amdgpu_atombios.h"
>  #include "amdgpu_atomfirmware.h"
> +#include "atomfirmware.h"
>  #include "amdgpu_i2c.h"
>  #include "amdgpu_display.h"
>
> @@ -1877,6 +1878,10 @@ void amdgpu_atombios_fini(struct amdgpu_device *adev)
>         if (adev->mode_info.atom_context) {
>                 kfree(adev->mode_info.atom_context->scratch);
>                 kfree(adev->mode_info.atom_context->iio);
> +               kfree(adev->mode_info.atom_context->uma_carveout_options);
> +               adev->mode_info.atom_context->uma_carveout_options = NULL;
> +               adev->mode_info.atom_context->uma_carveout_nr = 0;
> +               adev->mode_info.atom_context->uma_carveout_index = 0;
>         }
>         kfree(adev->mode_info.atom_context);
>         adev->mode_info.atom_context = NULL;
> @@ -1891,16 +1896,19 @@ void amdgpu_atombios_fini(struct amdgpu_device *adev)
>   *
>   * Initializes the driver info and register access callbacks for the
>   * ATOM interpreter (r4xx+).
> - * Returns 0 on sucess, -ENOMEM on failure.
> + * Returns 0 on success, -ENOMEM on memory allocation error, or -EINVAL on 
> ATOM ROM parsing error
>   * Called at driver startup.
>   */
>  int amdgpu_atombios_init(struct amdgpu_device *adev)
>  {
>         struct card_info *atom_card_info =
>             kzalloc(sizeof(struct card_info), GFP_KERNEL);
> +       int rc;
>
> -       if (!atom_card_info)
> -               return -ENOMEM;
> +       if (!atom_card_info) {
> +               rc = -ENOMEM;
> +               goto out_card_info;
> +       }
>
>         adev->mode_info.atom_card_info = atom_card_info;
>         atom_card_info->dev = adev_to_drm(adev);
> @@ -1913,8 +1921,16 @@ int amdgpu_atombios_init(struct amdgpu_device *adev)
>
>         adev->mode_info.atom_context = amdgpu_atom_parse(atom_card_info, 
> adev->bios);
>         if (!adev->mode_info.atom_context) {
> -               amdgpu_atombios_fini(adev);
> -               return -ENOMEM;
> +               rc = -ENOMEM;
> +               goto out_atom_ctx;
> +       }
> +
> +       rc = amdgpu_atomfirmware_get_uma_carveout_info(adev);
> +
> +       if (rc) {
> +               drm_dbg(adev_to_drm(adev), "Failed to get UMA carveout info: 
> %d\n", rc);
> +               if (rc != -ENODEV)
> +                       goto out_uma_info;
>         }
>
>         mutex_init(&adev->mode_info.atom_context->mutex);
> @@ -1930,6 +1946,12 @@ int amdgpu_atombios_init(struct amdgpu_device *adev)
>         }
>
>         return 0;
> +
> +out_uma_info:
> +out_atom_ctx:
> +       amdgpu_atombios_fini(adev);
> +out_card_info:
> +       return rc;
>  }
>
>  int amdgpu_atombios_get_data_table(struct amdgpu_device *adev,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
> index 636385c80f64..698416e84f1f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
> @@ -21,12 +21,14 @@
>   *
>   */
>
> +#include "linux/slab.h"
>  #include <drm/amdgpu_drm.h>
>  #include "amdgpu.h"
>  #include "atomfirmware.h"
>  #include "amdgpu_atomfirmware.h"
>  #include "atom.h"
>  #include "atombios.h"
> +#include "atomfirmware.h"
>  #include "soc15_hw_ip.h"
>
>  union firmware_info {
> @@ -296,6 +298,79 @@ static int convert_atom_mem_type_to_vram_type(struct 
> amdgpu_device *adev,
>         return vram_type;
>  }
>
> +static int __amdgpu_atomfirmware_get_uma_carveout_info_v2_3(struct 
> amdgpu_device *adev,
> +                                                           union igp_info 
> *igp_info)
> +{
> +       struct atom_context *ctx = adev->mode_info.atom_context;
> +       struct uma_carveout_option *opts;
> +
> +       opts = kzalloc(sizeof(igp_info->v23.UMASizeControlOption), 
> GFP_KERNEL);
> +
> +       if (!opts)
> +               goto out_mem;
> +
> +       memcpy(opts, igp_info->v23.UMASizeControlOption,
> +               sizeof(igp_info->v23.UMASizeControlOption));
> +
> +       ctx->uma_carveout_index = igp_info->v23.UMACarveoutIndex;
> +       ctx->uma_carveout_nr = igp_info->v23.UMACarveoutIndexMax;
> +       ctx->uma_carveout_options = opts;
> +
> +       return 0;
> +
> +out_mem:
> +       return -ENOMEM;
> +}
> +
> +static int __amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device 
> *adev,
> +                                                      u8 frev, u8 crev,
> +                                                      union igp_info 
> *igp_info)
> +{
> +       switch (frev) {
> +       case 2:
> +               switch (crev) {
> +               case 3:
> +                       return 
> __amdgpu_atomfirmware_get_uma_carveout_info_v2_3(adev, igp_info);
> +               break;
> +               default:
> +                       break;
> +               }
> +               break;
> +       default:
> +               break;
> +       }
> +       return -ENODEV;
> +}

I think this function can be moved into
amdgpu_atomfirmware_get_uma_carveout_info().

> +
> +int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev)
> +{
> +       struct amdgpu_mode_info *mode_info = &adev->mode_info;
> +       union igp_info *igp_info;
> +       u16 data_offset, size;
> +       u8 frev, crev;
> +       int index;
> +
> +       if (!(adev->flags & AMD_IS_APU))
> +               return -ENODEV;
> +
> +       if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
> +               return -ENODEV;
> +
> +       index = 
> get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
> +                                           integratedsysteminfo);
> +
> +       if (!amdgpu_atom_parse_data_header(mode_info->atom_context,
> +                                         index, &size,
> +                                         &frev, &crev, &data_offset)) {
> +               return -EINVAL;
> +       }
> +
> +       igp_info = (union igp_info *)
> +                       (mode_info->atom_context->bios + data_offset);
> +
> +       return __amdgpu_atomfirmware_get_uma_carveout_info(adev, frev, crev, 
> igp_info);
> +}
> +
>  int
>  amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
>                                   int *vram_width, int *vram_type,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
> index 649b5530d8ae..fb3f34a36569 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
> @@ -32,6 +32,7 @@ void amdgpu_atomfirmware_scratch_regs_init(struct 
> amdgpu_device *adev);
>  int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
>  int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
>         int *vram_width, int *vram_type, int *vram_vendor);
> +int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev);
>  int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
>  int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev);
>  bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h 
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index 825ff28731f5..f07c612f0386 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -153,6 +153,10 @@ struct atom_context {
>         uint8_t vbios_ver_str[STRLEN_NORMAL];
>         uint8_t date[STRLEN_NORMAL];
>         uint8_t build_num[STRLEN_NORMAL];
> +
> +       uint8_t uma_carveout_index;
> +       uint8_t uma_carveout_nr;
> +       struct uma_carveout_option *uma_carveout_options;

I don't think these really belong in the atom context.  They don't
really have anything to do with atombios.  I think it makes more sense
to do this in amdgpu_acpi_init() if atcs supports uma resizing.  If
the atcs support is present, then call the atomfirmware function to
parse the atom table and if all of that is ok, then register the sysfs
interface.

Alex


>  };
>
>  extern int amdgpu_atom_debug;
>
> --
> 2.43.0
>

Reply via email to