diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 636385c80f64..7f4751e5caaf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -296,6 +296,83 @@ 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 amdgpu_uma_carveout_info *uma_info) +{ + struct uma_carveout_option *opts; + uint8_t nr_uma_options; + int i; + + nr_uma_options = igp_info->v23.UMACarveoutIndexMax; + + if (!nr_uma_options) + return -ENODEV; + + if (nr_uma_options > MAX_UMA_OPTION_ENTRIES) { + drm_dbg(adev_to_drm(adev), + "Number of UMA options exceeds max table size. Options will not be parsed"); + return -EINVAL; + } + + uma_info->num_entries = nr_uma_options; + uma_info->uma_option_index = igp_info->v23.UMACarveoutIndex; + + opts = igp_info->v23.UMASizeControlOption; + + for (i = 0; i < nr_uma_options; i++) { + if (!opts[i].memoryCarvedGb) + uma_info->entries[i].memory_carved_mb = 512; + else + uma_info->entries[i].memory_carved_mb = (uint32_t)opts[i].memoryCarvedGb << 10; + + uma_info->entries[i].flags = opts[i].uma_carveout_option_flags.all8; + strscpy(uma_info->entries[i].name, opts[i].optionName, MAX_UMA_OPTION_NAME); + } + + return 0; +} + +int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev, + struct amdgpu_uma_carveout_info *uma_info) +{ + 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; + + 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); + + switch (frev) { + case 2: + switch (crev) { + case 3: + return amdgpu_atomfirmware_get_uma_carveout_info_v2_3(adev, igp_info, uma_info); + break; + default: + break; + } + break; + default: + break; + } + return -ENODEV; +} + int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, int *vram_width, int *vram_type, |
