Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2014 Advanced Micro Devices, Inc.
0003  * Copyright 2008 Red Hat Inc.
0004  * Copyright 2009 Jerome Glisse.
0005  *
0006  * Permission is hereby granted, free of charge, to any person obtaining a
0007  * copy of this software and associated documentation files (the "Software"),
0008  * to deal in the Software without restriction, including without limitation
0009  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010  * and/or sell copies of the Software, and to permit persons to whom the
0011  * Software is furnished to do so, subject to the following conditions:
0012  *
0013  * The above copyright notice and this permission notice shall be included in
0014  * all copies or substantial portions of the Software.
0015  *
0016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0019  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0020  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0021  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0022  * OTHER DEALINGS IN THE SOFTWARE.
0023  *
0024  */
0025 #include <linux/firmware.h>
0026 #include "amdgpu.h"
0027 #include "amdgpu_gfx.h"
0028 #include "amdgpu_rlc.h"
0029 
0030 /**
0031  * amdgpu_gfx_rlc_enter_safe_mode - Set RLC into safe mode
0032  *
0033  * @adev: amdgpu_device pointer
0034  *
0035  * Set RLC enter into safe mode if RLC is enabled and haven't in safe mode.
0036  */
0037 void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev)
0038 {
0039     if (adev->gfx.rlc.in_safe_mode)
0040         return;
0041 
0042     /* if RLC is not enabled, do nothing */
0043     if (!adev->gfx.rlc.funcs->is_rlc_enabled(adev))
0044         return;
0045 
0046     if (adev->cg_flags &
0047         (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG |
0048          AMD_CG_SUPPORT_GFX_3D_CGCG)) {
0049         adev->gfx.rlc.funcs->set_safe_mode(adev);
0050         adev->gfx.rlc.in_safe_mode = true;
0051     }
0052 }
0053 
0054 /**
0055  * amdgpu_gfx_rlc_exit_safe_mode - Set RLC out of safe mode
0056  *
0057  * @adev: amdgpu_device pointer
0058  *
0059  * Set RLC exit safe mode if RLC is enabled and have entered into safe mode.
0060  */
0061 void amdgpu_gfx_rlc_exit_safe_mode(struct amdgpu_device *adev)
0062 {
0063     if (!(adev->gfx.rlc.in_safe_mode))
0064         return;
0065 
0066     /* if RLC is not enabled, do nothing */
0067     if (!adev->gfx.rlc.funcs->is_rlc_enabled(adev))
0068         return;
0069 
0070     if (adev->cg_flags &
0071         (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG |
0072          AMD_CG_SUPPORT_GFX_3D_CGCG)) {
0073         adev->gfx.rlc.funcs->unset_safe_mode(adev);
0074         adev->gfx.rlc.in_safe_mode = false;
0075     }
0076 }
0077 
0078 /**
0079  * amdgpu_gfx_rlc_init_sr - Init save restore block
0080  *
0081  * @adev: amdgpu_device pointer
0082  * @dws: the size of save restore block
0083  *
0084  * Allocate and setup value to save restore block of rlc.
0085  * Returns 0 on succeess or negative error code if allocate failed.
0086  */
0087 int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws)
0088 {
0089     const u32 *src_ptr;
0090     volatile u32 *dst_ptr;
0091     u32 i;
0092     int r;
0093 
0094     /* allocate save restore block */
0095     r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
0096                       AMDGPU_GEM_DOMAIN_VRAM,
0097                       &adev->gfx.rlc.save_restore_obj,
0098                       &adev->gfx.rlc.save_restore_gpu_addr,
0099                       (void **)&adev->gfx.rlc.sr_ptr);
0100     if (r) {
0101         dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r);
0102         amdgpu_gfx_rlc_fini(adev);
0103         return r;
0104     }
0105 
0106     /* write the sr buffer */
0107     src_ptr = adev->gfx.rlc.reg_list;
0108     dst_ptr = adev->gfx.rlc.sr_ptr;
0109     for (i = 0; i < adev->gfx.rlc.reg_list_size; i++)
0110         dst_ptr[i] = cpu_to_le32(src_ptr[i]);
0111     amdgpu_bo_kunmap(adev->gfx.rlc.save_restore_obj);
0112     amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
0113 
0114     return 0;
0115 }
0116 
0117 /**
0118  * amdgpu_gfx_rlc_init_csb - Init clear state block
0119  *
0120  * @adev: amdgpu_device pointer
0121  *
0122  * Allocate and setup value to clear state block of rlc.
0123  * Returns 0 on succeess or negative error code if allocate failed.
0124  */
0125 int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
0126 {
0127     u32 dws;
0128     int r;
0129 
0130     /* allocate clear state block */
0131     adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev);
0132     r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
0133                       AMDGPU_GEM_DOMAIN_VRAM,
0134                       &adev->gfx.rlc.clear_state_obj,
0135                       &adev->gfx.rlc.clear_state_gpu_addr,
0136                       (void **)&adev->gfx.rlc.cs_ptr);
0137     if (r) {
0138         dev_err(adev->dev, "(%d) failed to create rlc csb bo\n", r);
0139         amdgpu_gfx_rlc_fini(adev);
0140         return r;
0141     }
0142 
0143     return 0;
0144 }
0145 
0146 /**
0147  * amdgpu_gfx_rlc_init_cpt - Init cp table
0148  *
0149  * @adev: amdgpu_device pointer
0150  *
0151  * Allocate and setup value to cp table of rlc.
0152  * Returns 0 on succeess or negative error code if allocate failed.
0153  */
0154 int amdgpu_gfx_rlc_init_cpt(struct amdgpu_device *adev)
0155 {
0156     int r;
0157 
0158     r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
0159                       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
0160                       &adev->gfx.rlc.cp_table_obj,
0161                       &adev->gfx.rlc.cp_table_gpu_addr,
0162                       (void **)&adev->gfx.rlc.cp_table_ptr);
0163     if (r) {
0164         dev_err(adev->dev, "(%d) failed to create cp table bo\n", r);
0165         amdgpu_gfx_rlc_fini(adev);
0166         return r;
0167     }
0168 
0169     /* set up the cp table */
0170     amdgpu_gfx_rlc_setup_cp_table(adev);
0171     amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj);
0172     amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
0173 
0174     return 0;
0175 }
0176 
0177 /**
0178  * amdgpu_gfx_rlc_setup_cp_table - setup cp the buffer of cp table
0179  *
0180  * @adev: amdgpu_device pointer
0181  *
0182  * Write cp firmware data into cp table.
0183  */
0184 void amdgpu_gfx_rlc_setup_cp_table(struct amdgpu_device *adev)
0185 {
0186     const __le32 *fw_data;
0187     volatile u32 *dst_ptr;
0188     int me, i, max_me;
0189     u32 bo_offset = 0;
0190     u32 table_offset, table_size;
0191 
0192     max_me = adev->gfx.rlc.funcs->get_cp_table_num(adev);
0193 
0194     /* write the cp table buffer */
0195     dst_ptr = adev->gfx.rlc.cp_table_ptr;
0196     for (me = 0; me < max_me; me++) {
0197         if (me == 0) {
0198             const struct gfx_firmware_header_v1_0 *hdr =
0199                 (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data;
0200             fw_data = (const __le32 *)
0201                 (adev->gfx.ce_fw->data +
0202                  le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0203             table_offset = le32_to_cpu(hdr->jt_offset);
0204             table_size = le32_to_cpu(hdr->jt_size);
0205         } else if (me == 1) {
0206             const struct gfx_firmware_header_v1_0 *hdr =
0207                 (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data;
0208             fw_data = (const __le32 *)
0209                 (adev->gfx.pfp_fw->data +
0210                  le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0211             table_offset = le32_to_cpu(hdr->jt_offset);
0212             table_size = le32_to_cpu(hdr->jt_size);
0213         } else if (me == 2) {
0214             const struct gfx_firmware_header_v1_0 *hdr =
0215                 (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data;
0216             fw_data = (const __le32 *)
0217                 (adev->gfx.me_fw->data +
0218                  le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0219             table_offset = le32_to_cpu(hdr->jt_offset);
0220             table_size = le32_to_cpu(hdr->jt_size);
0221         } else if (me == 3) {
0222             const struct gfx_firmware_header_v1_0 *hdr =
0223                 (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
0224             fw_data = (const __le32 *)
0225                 (adev->gfx.mec_fw->data +
0226                  le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0227             table_offset = le32_to_cpu(hdr->jt_offset);
0228             table_size = le32_to_cpu(hdr->jt_size);
0229         } else  if (me == 4) {
0230             const struct gfx_firmware_header_v1_0 *hdr =
0231                 (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data;
0232             fw_data = (const __le32 *)
0233                 (adev->gfx.mec2_fw->data +
0234                  le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0235             table_offset = le32_to_cpu(hdr->jt_offset);
0236             table_size = le32_to_cpu(hdr->jt_size);
0237         }
0238 
0239         for (i = 0; i < table_size; i ++) {
0240             dst_ptr[bo_offset + i] =
0241                 cpu_to_le32(le32_to_cpu(fw_data[table_offset + i]));
0242         }
0243 
0244         bo_offset += table_size;
0245     }
0246 }
0247 
0248 /**
0249  * amdgpu_gfx_rlc_fini - Free BO which used for RLC
0250  *
0251  * @adev: amdgpu_device pointer
0252  *
0253  * Free three BO which is used for rlc_save_restore_block, rlc_clear_state_block
0254  * and rlc_jump_table_block.
0255  */
0256 void amdgpu_gfx_rlc_fini(struct amdgpu_device *adev)
0257 {
0258     /* save restore block */
0259     if (adev->gfx.rlc.save_restore_obj) {
0260         amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj,
0261                       &adev->gfx.rlc.save_restore_gpu_addr,
0262                       (void **)&adev->gfx.rlc.sr_ptr);
0263     }
0264 
0265     /* clear state block */
0266     amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj,
0267                   &adev->gfx.rlc.clear_state_gpu_addr,
0268                   (void **)&adev->gfx.rlc.cs_ptr);
0269 
0270     /* jump table block */
0271     amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj,
0272                   &adev->gfx.rlc.cp_table_gpu_addr,
0273                   (void **)&adev->gfx.rlc.cp_table_ptr);
0274 }
0275 
0276 static int amdgpu_gfx_rlc_init_microcode_v2_0(struct amdgpu_device *adev)
0277 {
0278     const struct common_firmware_header *common_hdr;
0279     const struct rlc_firmware_header_v2_0 *rlc_hdr;
0280     struct amdgpu_firmware_info *info;
0281     unsigned int *tmp;
0282     unsigned int i;
0283 
0284     rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
0285 
0286     adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
0287     adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
0288     adev->gfx.rlc.save_and_restore_offset =
0289         le32_to_cpu(rlc_hdr->save_and_restore_offset);
0290     adev->gfx.rlc.clear_state_descriptor_offset =
0291         le32_to_cpu(rlc_hdr->clear_state_descriptor_offset);
0292     adev->gfx.rlc.avail_scratch_ram_locations =
0293         le32_to_cpu(rlc_hdr->avail_scratch_ram_locations);
0294     adev->gfx.rlc.reg_restore_list_size =
0295         le32_to_cpu(rlc_hdr->reg_restore_list_size);
0296     adev->gfx.rlc.reg_list_format_start =
0297         le32_to_cpu(rlc_hdr->reg_list_format_start);
0298     adev->gfx.rlc.reg_list_format_separate_start =
0299         le32_to_cpu(rlc_hdr->reg_list_format_separate_start);
0300     adev->gfx.rlc.starting_offsets_start =
0301         le32_to_cpu(rlc_hdr->starting_offsets_start);
0302     adev->gfx.rlc.reg_list_format_size_bytes =
0303         le32_to_cpu(rlc_hdr->reg_list_format_size_bytes);
0304     adev->gfx.rlc.reg_list_size_bytes =
0305         le32_to_cpu(rlc_hdr->reg_list_size_bytes);
0306     adev->gfx.rlc.register_list_format =
0307         kmalloc(adev->gfx.rlc.reg_list_format_size_bytes +
0308             adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
0309     if (!adev->gfx.rlc.register_list_format) {
0310         dev_err(adev->dev, "failed to allocate memory for rlc register_list_format\n");
0311         return -ENOMEM;
0312     }
0313 
0314     tmp = (unsigned int *)((uintptr_t)rlc_hdr +
0315             le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
0316     for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
0317         adev->gfx.rlc.register_list_format[i] = le32_to_cpu(tmp[i]);
0318 
0319     adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
0320 
0321     tmp = (unsigned int *)((uintptr_t)rlc_hdr +
0322             le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
0323     for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
0324         adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
0325 
0326     if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0327         info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G];
0328         info->ucode_id = AMDGPU_UCODE_ID_RLC_G;
0329         info->fw = adev->gfx.rlc_fw;
0330         if (info->fw) {
0331             common_hdr = (const struct common_firmware_header *)info->fw->data;
0332             adev->firmware.fw_size +=
0333                 ALIGN(le32_to_cpu(common_hdr->ucode_size_bytes), PAGE_SIZE);
0334         }
0335     }
0336 
0337     return 0;
0338 }
0339 
0340 static void amdgpu_gfx_rlc_init_microcode_v2_1(struct amdgpu_device *adev)
0341 {
0342     const struct rlc_firmware_header_v2_1 *rlc_hdr;
0343     struct amdgpu_firmware_info *info;
0344 
0345     rlc_hdr = (const struct rlc_firmware_header_v2_1 *)adev->gfx.rlc_fw->data;
0346     adev->gfx.rlc_srlc_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_ucode_ver);
0347     adev->gfx.rlc_srlc_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_feature_ver);
0348     adev->gfx.rlc.save_restore_list_cntl_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_cntl_size_bytes);
0349     adev->gfx.rlc.save_restore_list_cntl = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_cntl_offset_bytes);
0350     adev->gfx.rlc_srlg_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_ucode_ver);
0351     adev->gfx.rlc_srlg_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_feature_ver);
0352     adev->gfx.rlc.save_restore_list_gpm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_gpm_size_bytes);
0353     adev->gfx.rlc.save_restore_list_gpm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_gpm_offset_bytes);
0354     adev->gfx.rlc_srls_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_ucode_ver);
0355     adev->gfx.rlc_srls_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_feature_ver);
0356     adev->gfx.rlc.save_restore_list_srm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_srm_size_bytes);
0357     adev->gfx.rlc.save_restore_list_srm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_srm_offset_bytes);
0358     adev->gfx.rlc.reg_list_format_direct_reg_list_length =
0359         le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
0360 
0361     if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0362         if (adev->gfx.rlc.save_restore_list_gpm_size_bytes) {
0363             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
0364             info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;
0365             info->fw = adev->gfx.rlc_fw;
0366             adev->firmware.fw_size +=
0367                 ALIGN(adev->gfx.rlc.save_restore_list_gpm_size_bytes, PAGE_SIZE);
0368         }
0369 
0370         if (adev->gfx.rlc.save_restore_list_srm_size_bytes) {
0371             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM];
0372             info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM;
0373             info->fw = adev->gfx.rlc_fw;
0374             adev->firmware.fw_size +=
0375                 ALIGN(adev->gfx.rlc.save_restore_list_srm_size_bytes, PAGE_SIZE);
0376         }
0377     }
0378 }
0379 
0380 static void amdgpu_gfx_rlc_init_microcode_v2_2(struct amdgpu_device *adev)
0381 {
0382     const struct rlc_firmware_header_v2_2 *rlc_hdr;
0383     struct amdgpu_firmware_info *info;
0384 
0385     rlc_hdr = (const struct rlc_firmware_header_v2_2 *)adev->gfx.rlc_fw->data;
0386     adev->gfx.rlc.rlc_iram_ucode_size_bytes = le32_to_cpu(rlc_hdr->rlc_iram_ucode_size_bytes);
0387     adev->gfx.rlc.rlc_iram_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->rlc_iram_ucode_offset_bytes);
0388     adev->gfx.rlc.rlc_dram_ucode_size_bytes = le32_to_cpu(rlc_hdr->rlc_dram_ucode_size_bytes);
0389     adev->gfx.rlc.rlc_dram_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->rlc_dram_ucode_offset_bytes);
0390 
0391     if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0392         if (adev->gfx.rlc.rlc_iram_ucode_size_bytes) {
0393             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_IRAM];
0394             info->ucode_id = AMDGPU_UCODE_ID_RLC_IRAM;
0395             info->fw = adev->gfx.rlc_fw;
0396             adev->firmware.fw_size +=
0397                 ALIGN(adev->gfx.rlc.rlc_iram_ucode_size_bytes, PAGE_SIZE);
0398         }
0399 
0400         if (adev->gfx.rlc.rlc_dram_ucode_size_bytes) {
0401             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_DRAM];
0402             info->ucode_id = AMDGPU_UCODE_ID_RLC_DRAM;
0403             info->fw = adev->gfx.rlc_fw;
0404             adev->firmware.fw_size +=
0405                 ALIGN(adev->gfx.rlc.rlc_dram_ucode_size_bytes, PAGE_SIZE);
0406         }
0407     }
0408 }
0409 
0410 static void amdgpu_gfx_rlc_init_microcode_v2_3(struct amdgpu_device *adev)
0411 {
0412     const struct rlc_firmware_header_v2_3 *rlc_hdr;
0413     struct amdgpu_firmware_info *info;
0414 
0415     rlc_hdr = (const struct rlc_firmware_header_v2_3 *)adev->gfx.rlc_fw->data;
0416     adev->gfx.rlcp_ucode_version = le32_to_cpu(rlc_hdr->rlcp_ucode_version);
0417     adev->gfx.rlcp_ucode_feature_version = le32_to_cpu(rlc_hdr->rlcp_ucode_feature_version);
0418     adev->gfx.rlc.rlcp_ucode_size_bytes = le32_to_cpu(rlc_hdr->rlcp_ucode_size_bytes);
0419     adev->gfx.rlc.rlcp_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->rlcp_ucode_offset_bytes);
0420 
0421     adev->gfx.rlcv_ucode_version = le32_to_cpu(rlc_hdr->rlcv_ucode_version);
0422     adev->gfx.rlcv_ucode_feature_version = le32_to_cpu(rlc_hdr->rlcv_ucode_feature_version);
0423     adev->gfx.rlc.rlcv_ucode_size_bytes = le32_to_cpu(rlc_hdr->rlcv_ucode_size_bytes);
0424     adev->gfx.rlc.rlcv_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->rlcv_ucode_offset_bytes);
0425 
0426     if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0427         if (adev->gfx.rlc.rlcp_ucode_size_bytes) {
0428             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_P];
0429             info->ucode_id = AMDGPU_UCODE_ID_RLC_P;
0430             info->fw = adev->gfx.rlc_fw;
0431             adev->firmware.fw_size +=
0432                 ALIGN(adev->gfx.rlc.rlcp_ucode_size_bytes, PAGE_SIZE);
0433         }
0434 
0435         if (adev->gfx.rlc.rlcv_ucode_size_bytes) {
0436             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_V];
0437             info->ucode_id = AMDGPU_UCODE_ID_RLC_V;
0438             info->fw = adev->gfx.rlc_fw;
0439             adev->firmware.fw_size +=
0440                 ALIGN(adev->gfx.rlc.rlcv_ucode_size_bytes, PAGE_SIZE);
0441         }
0442     }
0443 }
0444 
0445 static void amdgpu_gfx_rlc_init_microcode_v2_4(struct amdgpu_device *adev)
0446 {
0447     const struct rlc_firmware_header_v2_4 *rlc_hdr;
0448     struct amdgpu_firmware_info *info;
0449 
0450     rlc_hdr = (const struct rlc_firmware_header_v2_4 *)adev->gfx.rlc_fw->data;
0451     adev->gfx.rlc.global_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->global_tap_delays_ucode_size_bytes);
0452     adev->gfx.rlc.global_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->global_tap_delays_ucode_offset_bytes);
0453     adev->gfx.rlc.se0_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se0_tap_delays_ucode_size_bytes);
0454     adev->gfx.rlc.se0_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se0_tap_delays_ucode_offset_bytes);
0455     adev->gfx.rlc.se1_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se1_tap_delays_ucode_size_bytes);
0456     adev->gfx.rlc.se1_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se1_tap_delays_ucode_offset_bytes);
0457     adev->gfx.rlc.se2_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se2_tap_delays_ucode_size_bytes);
0458     adev->gfx.rlc.se2_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se2_tap_delays_ucode_offset_bytes);
0459     adev->gfx.rlc.se3_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se3_tap_delays_ucode_size_bytes);
0460     adev->gfx.rlc.se3_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se3_tap_delays_ucode_offset_bytes);
0461 
0462     if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0463         if (adev->gfx.rlc.global_tap_delays_ucode_size_bytes) {
0464             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS];
0465             info->ucode_id = AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS;
0466             info->fw = adev->gfx.rlc_fw;
0467             adev->firmware.fw_size +=
0468                 ALIGN(adev->gfx.rlc.global_tap_delays_ucode_size_bytes, PAGE_SIZE);
0469         }
0470 
0471         if (adev->gfx.rlc.se0_tap_delays_ucode_size_bytes) {
0472             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE0_TAP_DELAYS];
0473             info->ucode_id = AMDGPU_UCODE_ID_SE0_TAP_DELAYS;
0474             info->fw = adev->gfx.rlc_fw;
0475             adev->firmware.fw_size +=
0476                 ALIGN(adev->gfx.rlc.se0_tap_delays_ucode_size_bytes, PAGE_SIZE);
0477         }
0478 
0479         if (adev->gfx.rlc.se1_tap_delays_ucode_size_bytes) {
0480             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE1_TAP_DELAYS];
0481             info->ucode_id = AMDGPU_UCODE_ID_SE1_TAP_DELAYS;
0482             info->fw = adev->gfx.rlc_fw;
0483             adev->firmware.fw_size +=
0484                 ALIGN(adev->gfx.rlc.se1_tap_delays_ucode_size_bytes, PAGE_SIZE);
0485         }
0486 
0487         if (adev->gfx.rlc.se2_tap_delays_ucode_size_bytes) {
0488             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE2_TAP_DELAYS];
0489             info->ucode_id = AMDGPU_UCODE_ID_SE2_TAP_DELAYS;
0490             info->fw = adev->gfx.rlc_fw;
0491             adev->firmware.fw_size +=
0492                 ALIGN(adev->gfx.rlc.se2_tap_delays_ucode_size_bytes, PAGE_SIZE);
0493         }
0494 
0495         if (adev->gfx.rlc.se3_tap_delays_ucode_size_bytes) {
0496             info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE3_TAP_DELAYS];
0497             info->ucode_id = AMDGPU_UCODE_ID_SE3_TAP_DELAYS;
0498             info->fw = adev->gfx.rlc_fw;
0499             adev->firmware.fw_size +=
0500                 ALIGN(adev->gfx.rlc.se3_tap_delays_ucode_size_bytes, PAGE_SIZE);
0501         }
0502     }
0503 }
0504 
0505 int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,
0506                   uint16_t version_major,
0507                   uint16_t version_minor)
0508 {
0509     int err;
0510 
0511     if (version_major < 2) {
0512         /* only support rlc_hdr v2.x and onwards */
0513         dev_err(adev->dev, "unsupported rlc fw hdr\n");
0514         return -EINVAL;
0515     }
0516 
0517     /* is_rlc_v2_1 is still used in APU code path */
0518     if (version_major == 2 && version_minor == 1)
0519         adev->gfx.rlc.is_rlc_v2_1 = true;
0520 
0521     if (version_minor >= 0) {
0522         err = amdgpu_gfx_rlc_init_microcode_v2_0(adev);
0523         if (err) {
0524             dev_err(adev->dev, "fail to init rlc v2_0 microcode\n");
0525             return err;
0526         }
0527     }
0528     if (version_minor >= 1)
0529         amdgpu_gfx_rlc_init_microcode_v2_1(adev);
0530     if (version_minor >= 2)
0531         amdgpu_gfx_rlc_init_microcode_v2_2(adev);
0532     if (version_minor == 3)
0533         amdgpu_gfx_rlc_init_microcode_v2_3(adev);
0534     if (version_minor == 4)
0535         amdgpu_gfx_rlc_init_microcode_v2_4(adev);
0536 
0537     return 0;
0538 }