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; +} + +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; }; extern int amdgpu_atom_debug; -- 2.43.0
