LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/amdgpu - amdgpu_atomfirmware.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 341 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 14 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  */
      23             : 
      24             : #include <drm/amdgpu_drm.h>
      25             : #include "amdgpu.h"
      26             : #include "atomfirmware.h"
      27             : #include "amdgpu_atomfirmware.h"
      28             : #include "atom.h"
      29             : #include "atombios.h"
      30             : #include "soc15_hw_ip.h"
      31             : 
      32             : union firmware_info {
      33             :         struct atom_firmware_info_v3_1 v31;
      34             :         struct atom_firmware_info_v3_2 v32;
      35             :         struct atom_firmware_info_v3_3 v33;
      36             :         struct atom_firmware_info_v3_4 v34;
      37             : };
      38             : 
      39             : /*
      40             :  * Helper function to query firmware capability
      41             :  *
      42             :  * @adev: amdgpu_device pointer
      43             :  *
      44             :  * Return firmware_capability in firmwareinfo table on success or 0 if not
      45             :  */
      46           0 : uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *adev)
      47             : {
      48           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
      49             :         int index;
      50             :         u16 data_offset, size;
      51             :         union firmware_info *firmware_info;
      52             :         u8 frev, crev;
      53           0 :         u32 fw_cap = 0;
      54             : 
      55           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
      56             :                         firmwareinfo);
      57             : 
      58           0 :         if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
      59             :                                 index, &size, &frev, &crev, &data_offset)) {
      60             :                 /* support firmware_info 3.1 + */
      61           0 :                 if ((frev == 3 && crev >=1) || (frev > 3)) {
      62           0 :                         firmware_info = (union firmware_info *)
      63           0 :                                 (mode_info->atom_context->bios + data_offset);
      64           0 :                         fw_cap = le32_to_cpu(firmware_info->v31.firmware_capability);
      65             :                 }
      66             :         }
      67             : 
      68           0 :         return fw_cap;
      69             : }
      70             : 
      71             : /*
      72             :  * Helper function to query gpu virtualizaiton capability
      73             :  *
      74             :  * @adev: amdgpu_device pointer
      75             :  *
      76             :  * Return true if gpu virtualization is supported or false if not
      77             :  */
      78           0 : bool amdgpu_atomfirmware_gpu_virtualization_supported(struct amdgpu_device *adev)
      79             : {
      80             :         u32 fw_cap;
      81             : 
      82           0 :         fw_cap = adev->mode_info.firmware_flags;
      83             : 
      84           0 :         return (fw_cap & ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION) ? true : false;
      85             : }
      86             : 
      87           0 : void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
      88             : {
      89           0 :         int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
      90             :                                                 firmwareinfo);
      91             :         uint16_t data_offset;
      92             : 
      93           0 :         if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL,
      94             :                                           NULL, NULL, &data_offset)) {
      95           0 :                 struct atom_firmware_info_v3_1 *firmware_info =
      96           0 :                         (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios +
      97             :                                                            data_offset);
      98             : 
      99           0 :                 adev->bios_scratch_reg_offset =
     100           0 :                         le32_to_cpu(firmware_info->bios_scratch_reg_startaddr);
     101             :         }
     102           0 : }
     103             : 
     104           0 : int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
     105             : {
     106           0 :         struct atom_context *ctx = adev->mode_info.atom_context;
     107           0 :         int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     108             :                                                 vram_usagebyfirmware);
     109             :         struct vram_usagebyfirmware_v2_1 *firmware_usage;
     110             :         uint32_t start_addr, size;
     111             :         uint16_t data_offset;
     112           0 :         int usage_bytes = 0;
     113             : 
     114           0 :         if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
     115           0 :                 firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
     116           0 :                 DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n",
     117             :                           le32_to_cpu(firmware_usage->start_address_in_kb),
     118             :                           le16_to_cpu(firmware_usage->used_by_firmware_in_kb),
     119             :                           le16_to_cpu(firmware_usage->used_by_driver_in_kb));
     120             : 
     121           0 :                 start_addr = le32_to_cpu(firmware_usage->start_address_in_kb);
     122           0 :                 size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb);
     123             : 
     124           0 :                 if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
     125             :                         (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
     126             :                         ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
     127             :                         /* Firmware request VRAM reservation for SR-IOV */
     128           0 :                         adev->mman.fw_vram_usage_start_offset = (start_addr &
     129           0 :                                 (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
     130           0 :                         adev->mman.fw_vram_usage_size = size << 10;
     131             :                         /* Use the default scratch size */
     132           0 :                         usage_bytes = 0;
     133             :                 } else {
     134           0 :                         usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10;
     135             :                 }
     136             :         }
     137           0 :         ctx->scratch_size_bytes = 0;
     138           0 :         if (usage_bytes == 0)
     139           0 :                 usage_bytes = 20 * 1024;
     140             :         /* allocate some scratch memory */
     141           0 :         ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
     142           0 :         if (!ctx->scratch)
     143             :                 return -ENOMEM;
     144           0 :         ctx->scratch_size_bytes = usage_bytes;
     145           0 :         return 0;
     146             : }
     147             : 
     148             : union igp_info {
     149             :         struct atom_integrated_system_info_v1_11 v11;
     150             :         struct atom_integrated_system_info_v1_12 v12;
     151             :         struct atom_integrated_system_info_v2_1 v21;
     152             : };
     153             : 
     154             : union umc_info {
     155             :         struct atom_umc_info_v3_1 v31;
     156             :         struct atom_umc_info_v3_2 v32;
     157             :         struct atom_umc_info_v3_3 v33;
     158             : };
     159             : 
     160             : union vram_info {
     161             :         struct atom_vram_info_header_v2_3 v23;
     162             :         struct atom_vram_info_header_v2_4 v24;
     163             :         struct atom_vram_info_header_v2_5 v25;
     164             :         struct atom_vram_info_header_v2_6 v26;
     165             :         struct atom_vram_info_header_v3_0 v30;
     166             : };
     167             : 
     168             : union vram_module {
     169             :         struct atom_vram_module_v9 v9;
     170             :         struct atom_vram_module_v10 v10;
     171             :         struct atom_vram_module_v11 v11;
     172             :         struct atom_vram_module_v3_0 v30;
     173             : };
     174             : 
     175             : static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
     176             :                                               int atom_mem_type)
     177             : {
     178             :         int vram_type;
     179             : 
     180           0 :         if (adev->flags & AMD_IS_APU) {
     181           0 :                 switch (atom_mem_type) {
     182             :                 case Ddr2MemType:
     183             :                 case LpDdr2MemType:
     184             :                         vram_type = AMDGPU_VRAM_TYPE_DDR2;
     185             :                         break;
     186             :                 case Ddr3MemType:
     187             :                 case LpDdr3MemType:
     188             :                         vram_type = AMDGPU_VRAM_TYPE_DDR3;
     189             :                         break;
     190             :                 case Ddr4MemType:
     191             :                         vram_type = AMDGPU_VRAM_TYPE_DDR4;
     192             :                         break;
     193             :                 case LpDdr4MemType:
     194             :                         vram_type = AMDGPU_VRAM_TYPE_LPDDR4;
     195             :                         break;
     196             :                 case Ddr5MemType:
     197             :                         vram_type = AMDGPU_VRAM_TYPE_DDR5;
     198             :                         break;
     199             :                 case LpDdr5MemType:
     200             :                         vram_type = AMDGPU_VRAM_TYPE_LPDDR5;
     201             :                         break;
     202             :                 default:
     203             :                         vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
     204             :                         break;
     205             :                 }
     206             :         } else {
     207           0 :                 switch (atom_mem_type) {
     208             :                 case ATOM_DGPU_VRAM_TYPE_GDDR5:
     209             :                         vram_type = AMDGPU_VRAM_TYPE_GDDR5;
     210             :                         break;
     211             :                 case ATOM_DGPU_VRAM_TYPE_HBM2:
     212             :                 case ATOM_DGPU_VRAM_TYPE_HBM2E:
     213             :                         vram_type = AMDGPU_VRAM_TYPE_HBM;
     214             :                         break;
     215             :                 case ATOM_DGPU_VRAM_TYPE_GDDR6:
     216             :                         vram_type = AMDGPU_VRAM_TYPE_GDDR6;
     217             :                         break;
     218             :                 default:
     219             :                         vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
     220             :                         break;
     221             :                 }
     222             :         }
     223             : 
     224             :         return vram_type;
     225             : }
     226             : 
     227             : 
     228             : int
     229           0 : amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
     230             :                                   int *vram_width, int *vram_type,
     231             :                                   int *vram_vendor)
     232             : {
     233           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
     234           0 :         int index, i = 0;
     235             :         u16 data_offset, size;
     236             :         union igp_info *igp_info;
     237             :         union vram_info *vram_info;
     238             :         union vram_module *vram_module;
     239             :         u8 frev, crev;
     240             :         u8 mem_type;
     241             :         u8 mem_vendor;
     242             :         u32 mem_channel_number;
     243             :         u32 mem_channel_width;
     244             :         u32 module_id;
     245             : 
     246           0 :         if (adev->flags & AMD_IS_APU)
     247             :                 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     248             :                                                     integratedsysteminfo);
     249             :         else
     250           0 :                 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     251             :                                                     vram_info);
     252             : 
     253           0 :         if (amdgpu_atom_parse_data_header(mode_info->atom_context,
     254             :                                           index, &size,
     255             :                                           &frev, &crev, &data_offset)) {
     256           0 :                 if (adev->flags & AMD_IS_APU) {
     257           0 :                         igp_info = (union igp_info *)
     258           0 :                                 (mode_info->atom_context->bios + data_offset);
     259           0 :                         switch (frev) {
     260             :                         case 1:
     261           0 :                                 switch (crev) {
     262             :                                 case 11:
     263             :                                 case 12:
     264           0 :                                         mem_channel_number = igp_info->v11.umachannelnumber;
     265           0 :                                         if (!mem_channel_number)
     266           0 :                                                 mem_channel_number = 1;
     267             :                                         /* channel width is 64 */
     268           0 :                                         if (vram_width)
     269           0 :                                                 *vram_width = mem_channel_number * 64;
     270           0 :                                         mem_type = igp_info->v11.memorytype;
     271           0 :                                         if (vram_type)
     272           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     273             :                                         break;
     274             :                                 default:
     275             :                                         return -EINVAL;
     276             :                                 }
     277             :                                 break;
     278             :                         case 2:
     279           0 :                                 switch (crev) {
     280             :                                 case 1:
     281             :                                 case 2:
     282           0 :                                         mem_channel_number = igp_info->v21.umachannelnumber;
     283           0 :                                         if (!mem_channel_number)
     284           0 :                                                 mem_channel_number = 1;
     285             :                                         /* channel width is 64 */
     286           0 :                                         if (vram_width)
     287           0 :                                                 *vram_width = mem_channel_number * 64;
     288           0 :                                         mem_type = igp_info->v21.memorytype;
     289           0 :                                         if (vram_type)
     290           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     291             :                                         break;
     292             :                                 default:
     293             :                                         return -EINVAL;
     294             :                                 }
     295             :                                 break;
     296             :                         default:
     297             :                                 return -EINVAL;
     298             :                         }
     299             :                 } else {
     300           0 :                         vram_info = (union vram_info *)
     301           0 :                                 (mode_info->atom_context->bios + data_offset);
     302           0 :                         module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16;
     303           0 :                         if (frev == 3) {
     304           0 :                                 switch (crev) {
     305             :                                 /* v30 */
     306             :                                 case 0:
     307           0 :                                         vram_module = (union vram_module *)vram_info->v30.vram_module;
     308           0 :                                         mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF;
     309           0 :                                         if (vram_vendor)
     310           0 :                                                 *vram_vendor = mem_vendor;
     311           0 :                                         mem_type = vram_info->v30.memory_type;
     312           0 :                                         if (vram_type)
     313           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     314           0 :                                         mem_channel_number = vram_info->v30.channel_num;
     315           0 :                                         mem_channel_width = vram_info->v30.channel_width;
     316           0 :                                         if (vram_width)
     317           0 :                                                 *vram_width = mem_channel_number * (1 << mem_channel_width);
     318             :                                         break;
     319             :                                 default:
     320             :                                         return -EINVAL;
     321             :                                 }
     322           0 :                         } else if (frev == 2) {
     323           0 :                                 switch (crev) {
     324             :                                 /* v23 */
     325             :                                 case 3:
     326           0 :                                         if (module_id > vram_info->v23.vram_module_num)
     327           0 :                                                 module_id = 0;
     328           0 :                                         vram_module = (union vram_module *)vram_info->v23.vram_module;
     329           0 :                                         while (i < module_id) {
     330           0 :                                                 vram_module = (union vram_module *)
     331           0 :                                                         ((u8 *)vram_module + vram_module->v9.vram_module_size);
     332           0 :                                                 i++;
     333             :                                         }
     334           0 :                                         mem_type = vram_module->v9.memory_type;
     335           0 :                                         if (vram_type)
     336           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     337           0 :                                         mem_channel_number = vram_module->v9.channel_num;
     338           0 :                                         mem_channel_width = vram_module->v9.channel_width;
     339           0 :                                         if (vram_width)
     340           0 :                                                 *vram_width = mem_channel_number * (1 << mem_channel_width);
     341           0 :                                         mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
     342           0 :                                         if (vram_vendor)
     343           0 :                                                 *vram_vendor = mem_vendor;
     344             :                                         break;
     345             :                                 /* v24 */
     346             :                                 case 4:
     347           0 :                                         if (module_id > vram_info->v24.vram_module_num)
     348           0 :                                                 module_id = 0;
     349           0 :                                         vram_module = (union vram_module *)vram_info->v24.vram_module;
     350           0 :                                         while (i < module_id) {
     351           0 :                                                 vram_module = (union vram_module *)
     352           0 :                                                         ((u8 *)vram_module + vram_module->v10.vram_module_size);
     353           0 :                                                 i++;
     354             :                                         }
     355           0 :                                         mem_type = vram_module->v10.memory_type;
     356           0 :                                         if (vram_type)
     357           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     358           0 :                                         mem_channel_number = vram_module->v10.channel_num;
     359           0 :                                         mem_channel_width = vram_module->v10.channel_width;
     360           0 :                                         if (vram_width)
     361           0 :                                                 *vram_width = mem_channel_number * (1 << mem_channel_width);
     362           0 :                                         mem_vendor = (vram_module->v10.vender_rev_id) & 0xF;
     363           0 :                                         if (vram_vendor)
     364           0 :                                                 *vram_vendor = mem_vendor;
     365             :                                         break;
     366             :                                 /* v25 */
     367             :                                 case 5:
     368           0 :                                         if (module_id > vram_info->v25.vram_module_num)
     369           0 :                                                 module_id = 0;
     370           0 :                                         vram_module = (union vram_module *)vram_info->v25.vram_module;
     371           0 :                                         while (i < module_id) {
     372           0 :                                                 vram_module = (union vram_module *)
     373           0 :                                                         ((u8 *)vram_module + vram_module->v11.vram_module_size);
     374           0 :                                                 i++;
     375             :                                         }
     376           0 :                                         mem_type = vram_module->v11.memory_type;
     377           0 :                                         if (vram_type)
     378           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     379           0 :                                         mem_channel_number = vram_module->v11.channel_num;
     380           0 :                                         mem_channel_width = vram_module->v11.channel_width;
     381           0 :                                         if (vram_width)
     382           0 :                                                 *vram_width = mem_channel_number * (1 << mem_channel_width);
     383           0 :                                         mem_vendor = (vram_module->v11.vender_rev_id) & 0xF;
     384           0 :                                         if (vram_vendor)
     385           0 :                                                 *vram_vendor = mem_vendor;
     386             :                                         break;
     387             :                                 /* v26 */
     388             :                                 case 6:
     389           0 :                                         if (module_id > vram_info->v26.vram_module_num)
     390           0 :                                                 module_id = 0;
     391           0 :                                         vram_module = (union vram_module *)vram_info->v26.vram_module;
     392           0 :                                         while (i < module_id) {
     393           0 :                                                 vram_module = (union vram_module *)
     394           0 :                                                         ((u8 *)vram_module + vram_module->v9.vram_module_size);
     395           0 :                                                 i++;
     396             :                                         }
     397           0 :                                         mem_type = vram_module->v9.memory_type;
     398           0 :                                         if (vram_type)
     399           0 :                                                 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
     400           0 :                                         mem_channel_number = vram_module->v9.channel_num;
     401           0 :                                         mem_channel_width = vram_module->v9.channel_width;
     402           0 :                                         if (vram_width)
     403           0 :                                                 *vram_width = mem_channel_number * (1 << mem_channel_width);
     404           0 :                                         mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
     405           0 :                                         if (vram_vendor)
     406           0 :                                                 *vram_vendor = mem_vendor;
     407             :                                         break;
     408             :                                 default:
     409             :                                         return -EINVAL;
     410             :                                 }
     411             :                         } else {
     412             :                                 /* invalid frev */
     413             :                                 return -EINVAL;
     414             :                         }
     415             :                 }
     416             : 
     417             :         }
     418             : 
     419             :         return 0;
     420             : }
     421             : 
     422             : /*
     423             :  * Return true if vbios enabled ecc by default, if umc info table is available
     424             :  * or false if ecc is not enabled or umc info table is not available
     425             :  */
     426           0 : bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
     427             : {
     428           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
     429             :         int index;
     430             :         u16 data_offset, size;
     431             :         union umc_info *umc_info;
     432             :         u8 frev, crev;
     433           0 :         bool ecc_default_enabled = false;
     434             :         u8 umc_config;
     435             :         u32 umc_config1;
     436             : 
     437           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     438             :                         umc_info);
     439             : 
     440           0 :         if (amdgpu_atom_parse_data_header(mode_info->atom_context,
     441             :                                 index, &size, &frev, &crev, &data_offset)) {
     442           0 :                 if (frev == 3) {
     443           0 :                         umc_info = (union umc_info *)
     444           0 :                                 (mode_info->atom_context->bios + data_offset);
     445           0 :                         switch (crev) {
     446             :                         case 1:
     447           0 :                                 umc_config = le32_to_cpu(umc_info->v31.umc_config);
     448           0 :                                 ecc_default_enabled =
     449             :                                         (umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
     450           0 :                                 break;
     451             :                         case 2:
     452           0 :                                 umc_config = le32_to_cpu(umc_info->v32.umc_config);
     453           0 :                                 ecc_default_enabled =
     454             :                                         (umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
     455           0 :                                 break;
     456             :                         case 3:
     457           0 :                                 umc_config = le32_to_cpu(umc_info->v33.umc_config);
     458           0 :                                 umc_config1 = le32_to_cpu(umc_info->v33.umc_config1);
     459           0 :                                 ecc_default_enabled =
     460             :                                         ((umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ||
     461           0 :                                          (umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE)) ? true : false;
     462           0 :                                 break;
     463             :                         default:
     464             :                                 /* unsupported crev */
     465             :                                 return false;
     466             :                         }
     467             :                 }
     468             :         }
     469             : 
     470             :         return ecc_default_enabled;
     471             : }
     472             : 
     473             : /*
     474             :  * Helper function to query sram ecc capablity
     475             :  *
     476             :  * @adev: amdgpu_device pointer
     477             :  *
     478             :  * Return true if vbios supports sram ecc or false if not
     479             :  */
     480           0 : bool amdgpu_atomfirmware_sram_ecc_supported(struct amdgpu_device *adev)
     481             : {
     482             :         u32 fw_cap;
     483             : 
     484           0 :         fw_cap = adev->mode_info.firmware_flags;
     485             : 
     486           0 :         return (fw_cap & ATOM_FIRMWARE_CAP_SRAM_ECC) ? true : false;
     487             : }
     488             : 
     489             : /*
     490             :  * Helper function to query dynamic boot config capability
     491             :  *
     492             :  * @adev: amdgpu_device pointer
     493             :  *
     494             :  * Return true if vbios supports dynamic boot config or false if not
     495             :  */
     496           0 : bool amdgpu_atomfirmware_dynamic_boot_config_supported(struct amdgpu_device *adev)
     497             : {
     498             :         u32 fw_cap;
     499             : 
     500           0 :         fw_cap = adev->mode_info.firmware_flags;
     501             : 
     502           0 :         return (fw_cap & ATOM_FIRMWARE_CAP_DYNAMIC_BOOT_CFG_ENABLE) ? true : false;
     503             : }
     504             : 
     505             : /**
     506             :  * amdgpu_atomfirmware_ras_rom_addr -- Get the RAS EEPROM addr from VBIOS
     507             :  * @adev: amdgpu_device pointer
     508             :  * @i2c_address: pointer to u8; if not NULL, will contain
     509             :  *    the RAS EEPROM address if the function returns true
     510             :  *
     511             :  * Return true if VBIOS supports RAS EEPROM address reporting,
     512             :  * else return false. If true and @i2c_address is not NULL,
     513             :  * will contain the RAS ROM address.
     514             :  */
     515           0 : bool amdgpu_atomfirmware_ras_rom_addr(struct amdgpu_device *adev,
     516             :                                       u8 *i2c_address)
     517             : {
     518           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
     519             :         int index;
     520             :         u16 data_offset, size;
     521             :         union firmware_info *firmware_info;
     522             :         u8 frev, crev;
     523             : 
     524           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     525             :                                             firmwareinfo);
     526             : 
     527           0 :         if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
     528             :                                           index, &size, &frev, &crev,
     529             :                                           &data_offset)) {
     530             :                 /* support firmware_info 3.4 + */
     531           0 :                 if ((frev == 3 && crev >=4) || (frev > 3)) {
     532           0 :                         firmware_info = (union firmware_info *)
     533           0 :                                 (mode_info->atom_context->bios + data_offset);
     534             :                         /* The ras_rom_i2c_slave_addr should ideally
     535             :                          * be a 19-bit EEPROM address, which would be
     536             :                          * used as is by the driver; see top of
     537             :                          * amdgpu_eeprom.c.
     538             :                          *
     539             :                          * When this is the case, 0 is of course a
     540             :                          * valid RAS EEPROM address, in which case,
     541             :                          * we'll drop the first "if (firm...)" and only
     542             :                          * leave the check for the pointer.
     543             :                          *
     544             :                          * The reason this works right now is because
     545             :                          * ras_rom_i2c_slave_addr contains the EEPROM
     546             :                          * device type qualifier 1010b in the top 4
     547             :                          * bits.
     548             :                          */
     549           0 :                         if (firmware_info->v34.ras_rom_i2c_slave_addr) {
     550           0 :                                 if (i2c_address)
     551           0 :                                         *i2c_address = firmware_info->v34.ras_rom_i2c_slave_addr;
     552             :                                 return true;
     553             :                         }
     554             :                 }
     555             :         }
     556             : 
     557             :         return false;
     558             : }
     559             : 
     560             : 
     561             : union smu_info {
     562             :         struct atom_smu_info_v3_1 v31;
     563             :         struct atom_smu_info_v4_0 v40;
     564             : };
     565             : 
     566             : union gfx_info {
     567             :         struct atom_gfx_info_v2_2 v22;
     568             :         struct atom_gfx_info_v2_4 v24;
     569             :         struct atom_gfx_info_v2_7 v27;
     570             :         struct atom_gfx_info_v3_0 v30;
     571             : };
     572             : 
     573           0 : int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
     574             : {
     575           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
     576           0 :         struct amdgpu_pll *spll = &adev->clock.spll;
     577           0 :         struct amdgpu_pll *mpll = &adev->clock.mpll;
     578             :         uint8_t frev, crev;
     579             :         uint16_t data_offset;
     580           0 :         int ret = -EINVAL, index;
     581             : 
     582           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     583             :                                             firmwareinfo);
     584           0 :         if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
     585             :                                    &frev, &crev, &data_offset)) {
     586           0 :                 union firmware_info *firmware_info =
     587           0 :                         (union firmware_info *)(mode_info->atom_context->bios +
     588             :                                                 data_offset);
     589             : 
     590           0 :                 adev->clock.default_sclk =
     591           0 :                         le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
     592           0 :                 adev->clock.default_mclk =
     593           0 :                         le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
     594             : 
     595           0 :                 adev->pm.current_sclk = adev->clock.default_sclk;
     596           0 :                 adev->pm.current_mclk = adev->clock.default_mclk;
     597             : 
     598           0 :                 ret = 0;
     599             :         }
     600             : 
     601           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     602             :                                             smu_info);
     603           0 :         if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
     604             :                                    &frev, &crev, &data_offset)) {
     605           0 :                 union smu_info *smu_info =
     606           0 :                         (union smu_info *)(mode_info->atom_context->bios +
     607             :                                            data_offset);
     608             : 
     609             :                 /* system clock */
     610           0 :                 if (frev == 3)
     611           0 :                         spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz);
     612           0 :                 else if (frev == 4)
     613           0 :                         spll->reference_freq = le32_to_cpu(smu_info->v40.core_refclk_10khz);
     614             : 
     615           0 :                 spll->reference_div = 0;
     616           0 :                 spll->min_post_div = 1;
     617           0 :                 spll->max_post_div = 1;
     618           0 :                 spll->min_ref_div = 2;
     619           0 :                 spll->max_ref_div = 0xff;
     620           0 :                 spll->min_feedback_div = 4;
     621           0 :                 spll->max_feedback_div = 0xff;
     622           0 :                 spll->best_vco = 0;
     623             : 
     624           0 :                 ret = 0;
     625             :         }
     626             : 
     627           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     628             :                                             umc_info);
     629           0 :         if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
     630             :                                    &frev, &crev, &data_offset)) {
     631           0 :                 union umc_info *umc_info =
     632           0 :                         (union umc_info *)(mode_info->atom_context->bios +
     633             :                                            data_offset);
     634             : 
     635             :                 /* memory clock */
     636           0 :                 mpll->reference_freq = le32_to_cpu(umc_info->v31.mem_refclk_10khz);
     637             : 
     638           0 :                 mpll->reference_div = 0;
     639           0 :                 mpll->min_post_div = 1;
     640           0 :                 mpll->max_post_div = 1;
     641           0 :                 mpll->min_ref_div = 2;
     642           0 :                 mpll->max_ref_div = 0xff;
     643           0 :                 mpll->min_feedback_div = 4;
     644           0 :                 mpll->max_feedback_div = 0xff;
     645           0 :                 mpll->best_vco = 0;
     646             : 
     647           0 :                 ret = 0;
     648             :         }
     649             : 
     650             :         /* if asic is Navi+, the rlc reference clock is used for system clock
     651             :          * from vbios gfx_info table */
     652           0 :         if (adev->asic_type >= CHIP_NAVI10) {
     653           0 :                 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     654             :                                                    gfx_info);
     655           0 :                 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
     656             :                                           &frev, &crev, &data_offset)) {
     657           0 :                         union gfx_info *gfx_info = (union gfx_info *)
     658           0 :                                 (mode_info->atom_context->bios + data_offset);
     659           0 :                         if ((frev == 3) ||
     660           0 :                             (frev == 2 && crev == 6)) {
     661           0 :                                 spll->reference_freq = le32_to_cpu(gfx_info->v30.golden_tsc_count_lower_refclk);
     662           0 :                                 ret = 0;
     663           0 :                         } else if ((frev == 2) &&
     664           0 :                                    (crev >= 2) &&
     665             :                                    (crev != 6)) {
     666           0 :                                 spll->reference_freq = le32_to_cpu(gfx_info->v22.rlc_gpu_timer_refclk);
     667           0 :                                 ret = 0;
     668             :                         } else {
     669           0 :                                 BUG();
     670             :                         }
     671             :                 }
     672             :         }
     673             : 
     674           0 :         return ret;
     675             : }
     676             : 
     677           0 : int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev)
     678             : {
     679           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
     680             :         int index;
     681             :         uint8_t frev, crev;
     682             :         uint16_t data_offset;
     683             : 
     684           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     685             :                                             gfx_info);
     686           0 :         if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
     687             :                                    &frev, &crev, &data_offset)) {
     688           0 :                 union gfx_info *gfx_info = (union gfx_info *)
     689           0 :                         (mode_info->atom_context->bios + data_offset);
     690           0 :                 if (frev == 2) {
     691           0 :                         switch (crev) {
     692             :                         case 4:
     693           0 :                                 adev->gfx.config.max_shader_engines = gfx_info->v24.max_shader_engines;
     694           0 :                                 adev->gfx.config.max_cu_per_sh = gfx_info->v24.max_cu_per_sh;
     695           0 :                                 adev->gfx.config.max_sh_per_se = gfx_info->v24.max_sh_per_se;
     696           0 :                                 adev->gfx.config.max_backends_per_se = gfx_info->v24.max_backends_per_se;
     697           0 :                                 adev->gfx.config.max_texture_channel_caches = gfx_info->v24.max_texture_channel_caches;
     698           0 :                                 adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs);
     699           0 :                                 adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds;
     700           0 :                                 adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth;
     701           0 :                                 adev->gfx.config.gs_prim_buffer_depth =
     702           0 :                                         le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth);
     703           0 :                                 adev->gfx.config.double_offchip_lds_buf =
     704           0 :                                         gfx_info->v24.gc_double_offchip_lds_buffer;
     705           0 :                                 adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size);
     706           0 :                                 adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd);
     707           0 :                                 adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu;
     708           0 :                                 adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size);
     709           0 :                                 return 0;
     710             :                         case 7:
     711           0 :                                 adev->gfx.config.max_shader_engines = gfx_info->v27.max_shader_engines;
     712           0 :                                 adev->gfx.config.max_cu_per_sh = gfx_info->v27.max_cu_per_sh;
     713           0 :                                 adev->gfx.config.max_sh_per_se = gfx_info->v27.max_sh_per_se;
     714           0 :                                 adev->gfx.config.max_backends_per_se = gfx_info->v27.max_backends_per_se;
     715           0 :                                 adev->gfx.config.max_texture_channel_caches = gfx_info->v27.max_texture_channel_caches;
     716           0 :                                 adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v27.gc_num_gprs);
     717           0 :                                 adev->gfx.config.max_gs_threads = gfx_info->v27.gc_num_max_gs_thds;
     718           0 :                                 adev->gfx.config.gs_vgt_table_depth = gfx_info->v27.gc_gs_table_depth;
     719           0 :                                 adev->gfx.config.gs_prim_buffer_depth = le16_to_cpu(gfx_info->v27.gc_gsprim_buff_depth);
     720           0 :                                 adev->gfx.config.double_offchip_lds_buf = gfx_info->v27.gc_double_offchip_lds_buffer;
     721           0 :                                 adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v27.gc_wave_size);
     722           0 :                                 adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v27.gc_max_waves_per_simd);
     723           0 :                                 adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v27.gc_max_scratch_slots_per_cu;
     724           0 :                                 adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v27.gc_lds_size);
     725           0 :                                 return 0;
     726             :                         default:
     727             :                                 return -EINVAL;
     728             :                         }
     729           0 :                 } else if (frev == 3) {
     730           0 :                         switch (crev) {
     731             :                         case 0:
     732           0 :                                 adev->gfx.config.max_shader_engines = gfx_info->v30.max_shader_engines;
     733           0 :                                 adev->gfx.config.max_cu_per_sh = gfx_info->v30.max_cu_per_sh;
     734           0 :                                 adev->gfx.config.max_sh_per_se = gfx_info->v30.max_sh_per_se;
     735           0 :                                 adev->gfx.config.max_backends_per_se = gfx_info->v30.max_backends_per_se;
     736           0 :                                 adev->gfx.config.max_texture_channel_caches = gfx_info->v30.max_texture_channel_caches;
     737           0 :                                 return 0;
     738             :                         default:
     739             :                                 return -EINVAL;
     740             :                         }
     741             :                 } else {
     742             :                         return -EINVAL;
     743             :                 }
     744             : 
     745             :         }
     746             :         return -EINVAL;
     747             : }
     748             : 
     749             : /*
     750             :  * Helper function to query two stage mem training capability
     751             :  *
     752             :  * @adev: amdgpu_device pointer
     753             :  *
     754             :  * Return true if two stage mem training is supported or false if not
     755             :  */
     756           0 : bool amdgpu_atomfirmware_mem_training_supported(struct amdgpu_device *adev)
     757             : {
     758             :         u32 fw_cap;
     759             : 
     760           0 :         fw_cap = adev->mode_info.firmware_flags;
     761             : 
     762           0 :         return (fw_cap & ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING) ? true : false;
     763             : }
     764             : 
     765           0 : int amdgpu_atomfirmware_get_fw_reserved_fb_size(struct amdgpu_device *adev)
     766             : {
     767           0 :         struct atom_context *ctx = adev->mode_info.atom_context;
     768             :         union firmware_info *firmware_info;
     769             :         int index;
     770             :         u16 data_offset, size;
     771             :         u8 frev, crev;
     772             :         int fw_reserved_fb_size;
     773             : 
     774           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     775             :                         firmwareinfo);
     776             : 
     777           0 :         if (!amdgpu_atom_parse_data_header(ctx, index, &size,
     778             :                                 &frev, &crev, &data_offset))
     779             :                 /* fail to parse data_header */
     780             :                 return 0;
     781             : 
     782           0 :         firmware_info = (union firmware_info *)(ctx->bios + data_offset);
     783             : 
     784           0 :         if (frev !=3)
     785             :                 return -EINVAL;
     786             : 
     787           0 :         switch (crev) {
     788             :         case 4:
     789           0 :                 fw_reserved_fb_size =
     790           0 :                         (firmware_info->v34.fw_reserved_size_in_kb << 10);
     791           0 :                 break;
     792             :         default:
     793             :                 fw_reserved_fb_size = 0;
     794             :                 break;
     795             :         }
     796             : 
     797             :         return fw_reserved_fb_size;
     798             : }
     799             : 
     800             : /*
     801             :  * Helper function to execute asic_init table
     802             :  *
     803             :  * @adev: amdgpu_device pointer
     804             :  * @fb_reset: flag to indicate whether fb is reset or not
     805             :  *
     806             :  * Return 0 if succeed, otherwise failed
     807             :  */
     808           0 : int amdgpu_atomfirmware_asic_init(struct amdgpu_device *adev, bool fb_reset)
     809             : {
     810           0 :         struct amdgpu_mode_info *mode_info = &adev->mode_info;
     811             :         struct atom_context *ctx;
     812             :         uint8_t frev, crev;
     813             :         uint16_t data_offset;
     814             :         uint32_t bootup_sclk_in10khz, bootup_mclk_in10khz;
     815             :         struct asic_init_ps_allocation_v2_1 asic_init_ps_v2_1;
     816             :         int index;
     817             : 
     818           0 :         if (!mode_info)
     819             :                 return -EINVAL;
     820             : 
     821           0 :         ctx = mode_info->atom_context;
     822           0 :         if (!ctx)
     823             :                 return -EINVAL;
     824             : 
     825             :         /* query bootup sclk/mclk from firmware_info table */
     826           0 :         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
     827             :                                             firmwareinfo);
     828           0 :         if (amdgpu_atom_parse_data_header(ctx, index, NULL,
     829             :                                 &frev, &crev, &data_offset)) {
     830           0 :                 union firmware_info *firmware_info =
     831           0 :                         (union firmware_info *)(ctx->bios +
     832             :                                                 data_offset);
     833             : 
     834           0 :                 bootup_sclk_in10khz =
     835             :                         le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
     836           0 :                 bootup_mclk_in10khz =
     837             :                         le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
     838             :         } else {
     839             :                 return -EINVAL;
     840             :         }
     841             : 
     842           0 :         index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1,
     843             :                                             asic_init);
     844           0 :         if (amdgpu_atom_parse_cmd_header(mode_info->atom_context, index, &frev, &crev)) {
     845           0 :                 if (frev == 2 && crev >= 1) {
     846           0 :                         memset(&asic_init_ps_v2_1, 0, sizeof(asic_init_ps_v2_1));
     847           0 :                         asic_init_ps_v2_1.param.engineparam.sclkfreqin10khz = bootup_sclk_in10khz;
     848           0 :                         asic_init_ps_v2_1.param.memparam.mclkfreqin10khz = bootup_mclk_in10khz;
     849           0 :                         asic_init_ps_v2_1.param.engineparam.engineflag = b3NORMAL_ENGINE_INIT;
     850           0 :                         if (!fb_reset)
     851           0 :                                 asic_init_ps_v2_1.param.memparam.memflag = b3DRAM_SELF_REFRESH_EXIT;
     852             :                         else
     853           0 :                                 asic_init_ps_v2_1.param.memparam.memflag = 0;
     854             :                 } else {
     855             :                         return -EINVAL;
     856             :                 }
     857             :         } else {
     858             :                 return -EINVAL;
     859             :         }
     860             : 
     861           0 :         return amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, (uint32_t *)&asic_init_ps_v2_1);
     862             : }

Generated by: LCOV version 1.14