1*b843c749SSergey Zigachev /* 2*b843c749SSergey Zigachev * Copyright 2012 Advanced Micro Devices, Inc. 3*b843c749SSergey Zigachev * 4*b843c749SSergey Zigachev * Permission is hereby granted, free of charge, to any person obtaining a 5*b843c749SSergey Zigachev * copy of this software and associated documentation files (the "Software"), 6*b843c749SSergey Zigachev * to deal in the Software without restriction, including without limitation 7*b843c749SSergey Zigachev * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*b843c749SSergey Zigachev * and/or sell copies of the Software, and to permit persons to whom the 9*b843c749SSergey Zigachev * Software is furnished to do so, subject to the following conditions: 10*b843c749SSergey Zigachev * 11*b843c749SSergey Zigachev * The above copyright notice and this permission notice shall be included in 12*b843c749SSergey Zigachev * all copies or substantial portions of the Software. 13*b843c749SSergey Zigachev * 14*b843c749SSergey Zigachev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*b843c749SSergey Zigachev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*b843c749SSergey Zigachev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*b843c749SSergey Zigachev * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*b843c749SSergey Zigachev * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*b843c749SSergey Zigachev * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*b843c749SSergey Zigachev * OTHER DEALINGS IN THE SOFTWARE. 21*b843c749SSergey Zigachev * 22*b843c749SSergey Zigachev */ 23*b843c749SSergey Zigachev #ifndef __AMDGPU_UCODE_H__ 24*b843c749SSergey Zigachev #define __AMDGPU_UCODE_H__ 25*b843c749SSergey Zigachev 26*b843c749SSergey Zigachev struct common_firmware_header { 27*b843c749SSergey Zigachev uint32_t size_bytes; /* size of the entire header+image(s) in bytes */ 28*b843c749SSergey Zigachev uint32_t header_size_bytes; /* size of just the header in bytes */ 29*b843c749SSergey Zigachev uint16_t header_version_major; /* header version */ 30*b843c749SSergey Zigachev uint16_t header_version_minor; /* header version */ 31*b843c749SSergey Zigachev uint16_t ip_version_major; /* IP version */ 32*b843c749SSergey Zigachev uint16_t ip_version_minor; /* IP version */ 33*b843c749SSergey Zigachev uint32_t ucode_version; 34*b843c749SSergey Zigachev uint32_t ucode_size_bytes; /* size of ucode in bytes */ 35*b843c749SSergey Zigachev uint32_t ucode_array_offset_bytes; /* payload offset from the start of the header */ 36*b843c749SSergey Zigachev uint32_t crc32; /* crc32 checksum of the payload */ 37*b843c749SSergey Zigachev }; 38*b843c749SSergey Zigachev 39*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 40*b843c749SSergey Zigachev struct mc_firmware_header_v1_0 { 41*b843c749SSergey Zigachev struct common_firmware_header header; 42*b843c749SSergey Zigachev uint32_t io_debug_size_bytes; /* size of debug array in dwords */ 43*b843c749SSergey Zigachev uint32_t io_debug_array_offset_bytes; /* payload offset from the start of the header */ 44*b843c749SSergey Zigachev }; 45*b843c749SSergey Zigachev 46*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 47*b843c749SSergey Zigachev struct smc_firmware_header_v1_0 { 48*b843c749SSergey Zigachev struct common_firmware_header header; 49*b843c749SSergey Zigachev uint32_t ucode_start_addr; 50*b843c749SSergey Zigachev }; 51*b843c749SSergey Zigachev 52*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 53*b843c749SSergey Zigachev struct psp_firmware_header_v1_0 { 54*b843c749SSergey Zigachev struct common_firmware_header header; 55*b843c749SSergey Zigachev uint32_t ucode_feature_version; 56*b843c749SSergey Zigachev uint32_t sos_offset_bytes; 57*b843c749SSergey Zigachev uint32_t sos_size_bytes; 58*b843c749SSergey Zigachev }; 59*b843c749SSergey Zigachev 60*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 61*b843c749SSergey Zigachev struct gfx_firmware_header_v1_0 { 62*b843c749SSergey Zigachev struct common_firmware_header header; 63*b843c749SSergey Zigachev uint32_t ucode_feature_version; 64*b843c749SSergey Zigachev uint32_t jt_offset; /* jt location */ 65*b843c749SSergey Zigachev uint32_t jt_size; /* size of jt */ 66*b843c749SSergey Zigachev }; 67*b843c749SSergey Zigachev 68*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 69*b843c749SSergey Zigachev struct rlc_firmware_header_v1_0 { 70*b843c749SSergey Zigachev struct common_firmware_header header; 71*b843c749SSergey Zigachev uint32_t ucode_feature_version; 72*b843c749SSergey Zigachev uint32_t save_and_restore_offset; 73*b843c749SSergey Zigachev uint32_t clear_state_descriptor_offset; 74*b843c749SSergey Zigachev uint32_t avail_scratch_ram_locations; 75*b843c749SSergey Zigachev uint32_t master_pkt_description_offset; 76*b843c749SSergey Zigachev }; 77*b843c749SSergey Zigachev 78*b843c749SSergey Zigachev /* version_major=2, version_minor=0 */ 79*b843c749SSergey Zigachev struct rlc_firmware_header_v2_0 { 80*b843c749SSergey Zigachev struct common_firmware_header header; 81*b843c749SSergey Zigachev uint32_t ucode_feature_version; 82*b843c749SSergey Zigachev uint32_t jt_offset; /* jt location */ 83*b843c749SSergey Zigachev uint32_t jt_size; /* size of jt */ 84*b843c749SSergey Zigachev uint32_t save_and_restore_offset; 85*b843c749SSergey Zigachev uint32_t clear_state_descriptor_offset; 86*b843c749SSergey Zigachev uint32_t avail_scratch_ram_locations; 87*b843c749SSergey Zigachev uint32_t reg_restore_list_size; 88*b843c749SSergey Zigachev uint32_t reg_list_format_start; 89*b843c749SSergey Zigachev uint32_t reg_list_format_separate_start; 90*b843c749SSergey Zigachev uint32_t starting_offsets_start; 91*b843c749SSergey Zigachev uint32_t reg_list_format_size_bytes; /* size of reg list format array in bytes */ 92*b843c749SSergey Zigachev uint32_t reg_list_format_array_offset_bytes; /* payload offset from the start of the header */ 93*b843c749SSergey Zigachev uint32_t reg_list_size_bytes; /* size of reg list array in bytes */ 94*b843c749SSergey Zigachev uint32_t reg_list_array_offset_bytes; /* payload offset from the start of the header */ 95*b843c749SSergey Zigachev uint32_t reg_list_format_separate_size_bytes; /* size of reg list format array in bytes */ 96*b843c749SSergey Zigachev uint32_t reg_list_format_separate_array_offset_bytes; /* payload offset from the start of the header */ 97*b843c749SSergey Zigachev uint32_t reg_list_separate_size_bytes; /* size of reg list array in bytes */ 98*b843c749SSergey Zigachev uint32_t reg_list_separate_array_offset_bytes; /* payload offset from the start of the header */ 99*b843c749SSergey Zigachev }; 100*b843c749SSergey Zigachev 101*b843c749SSergey Zigachev /* version_major=2, version_minor=1 */ 102*b843c749SSergey Zigachev struct rlc_firmware_header_v2_1 { 103*b843c749SSergey Zigachev struct rlc_firmware_header_v2_0 v2_0; 104*b843c749SSergey Zigachev uint32_t reg_list_format_direct_reg_list_length; /* length of direct reg list format array */ 105*b843c749SSergey Zigachev uint32_t save_restore_list_cntl_ucode_ver; 106*b843c749SSergey Zigachev uint32_t save_restore_list_cntl_feature_ver; 107*b843c749SSergey Zigachev uint32_t save_restore_list_cntl_size_bytes; 108*b843c749SSergey Zigachev uint32_t save_restore_list_cntl_offset_bytes; 109*b843c749SSergey Zigachev uint32_t save_restore_list_gpm_ucode_ver; 110*b843c749SSergey Zigachev uint32_t save_restore_list_gpm_feature_ver; 111*b843c749SSergey Zigachev uint32_t save_restore_list_gpm_size_bytes; 112*b843c749SSergey Zigachev uint32_t save_restore_list_gpm_offset_bytes; 113*b843c749SSergey Zigachev uint32_t save_restore_list_srm_ucode_ver; 114*b843c749SSergey Zigachev uint32_t save_restore_list_srm_feature_ver; 115*b843c749SSergey Zigachev uint32_t save_restore_list_srm_size_bytes; 116*b843c749SSergey Zigachev uint32_t save_restore_list_srm_offset_bytes; 117*b843c749SSergey Zigachev }; 118*b843c749SSergey Zigachev 119*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 120*b843c749SSergey Zigachev struct sdma_firmware_header_v1_0 { 121*b843c749SSergey Zigachev struct common_firmware_header header; 122*b843c749SSergey Zigachev uint32_t ucode_feature_version; 123*b843c749SSergey Zigachev uint32_t ucode_change_version; 124*b843c749SSergey Zigachev uint32_t jt_offset; /* jt location */ 125*b843c749SSergey Zigachev uint32_t jt_size; /* size of jt */ 126*b843c749SSergey Zigachev }; 127*b843c749SSergey Zigachev 128*b843c749SSergey Zigachev /* version_major=1, version_minor=1 */ 129*b843c749SSergey Zigachev struct sdma_firmware_header_v1_1 { 130*b843c749SSergey Zigachev struct sdma_firmware_header_v1_0 v1_0; 131*b843c749SSergey Zigachev uint32_t digest_size; 132*b843c749SSergey Zigachev }; 133*b843c749SSergey Zigachev 134*b843c749SSergey Zigachev /* gpu info payload */ 135*b843c749SSergey Zigachev struct gpu_info_firmware_v1_0 { 136*b843c749SSergey Zigachev uint32_t gc_num_se; 137*b843c749SSergey Zigachev uint32_t gc_num_cu_per_sh; 138*b843c749SSergey Zigachev uint32_t gc_num_sh_per_se; 139*b843c749SSergey Zigachev uint32_t gc_num_rb_per_se; 140*b843c749SSergey Zigachev uint32_t gc_num_tccs; 141*b843c749SSergey Zigachev uint32_t gc_num_gprs; 142*b843c749SSergey Zigachev uint32_t gc_num_max_gs_thds; 143*b843c749SSergey Zigachev uint32_t gc_gs_table_depth; 144*b843c749SSergey Zigachev uint32_t gc_gsprim_buff_depth; 145*b843c749SSergey Zigachev uint32_t gc_parameter_cache_depth; 146*b843c749SSergey Zigachev uint32_t gc_double_offchip_lds_buffer; 147*b843c749SSergey Zigachev uint32_t gc_wave_size; 148*b843c749SSergey Zigachev uint32_t gc_max_waves_per_simd; 149*b843c749SSergey Zigachev uint32_t gc_max_scratch_slots_per_cu; 150*b843c749SSergey Zigachev uint32_t gc_lds_size; 151*b843c749SSergey Zigachev }; 152*b843c749SSergey Zigachev 153*b843c749SSergey Zigachev /* version_major=1, version_minor=0 */ 154*b843c749SSergey Zigachev struct gpu_info_firmware_header_v1_0 { 155*b843c749SSergey Zigachev struct common_firmware_header header; 156*b843c749SSergey Zigachev uint16_t version_major; /* version */ 157*b843c749SSergey Zigachev uint16_t version_minor; /* version */ 158*b843c749SSergey Zigachev }; 159*b843c749SSergey Zigachev 160*b843c749SSergey Zigachev /* header is fixed size */ 161*b843c749SSergey Zigachev union amdgpu_firmware_header { 162*b843c749SSergey Zigachev struct common_firmware_header common; 163*b843c749SSergey Zigachev struct mc_firmware_header_v1_0 mc; 164*b843c749SSergey Zigachev struct smc_firmware_header_v1_0 smc; 165*b843c749SSergey Zigachev struct psp_firmware_header_v1_0 psp; 166*b843c749SSergey Zigachev struct gfx_firmware_header_v1_0 gfx; 167*b843c749SSergey Zigachev struct rlc_firmware_header_v1_0 rlc; 168*b843c749SSergey Zigachev struct rlc_firmware_header_v2_0 rlc_v2_0; 169*b843c749SSergey Zigachev struct rlc_firmware_header_v2_1 rlc_v2_1; 170*b843c749SSergey Zigachev struct sdma_firmware_header_v1_0 sdma; 171*b843c749SSergey Zigachev struct sdma_firmware_header_v1_1 sdma_v1_1; 172*b843c749SSergey Zigachev struct gpu_info_firmware_header_v1_0 gpu_info; 173*b843c749SSergey Zigachev uint8_t raw[0x100]; 174*b843c749SSergey Zigachev }; 175*b843c749SSergey Zigachev 176*b843c749SSergey Zigachev /* 177*b843c749SSergey Zigachev * fw loading support 178*b843c749SSergey Zigachev */ 179*b843c749SSergey Zigachev enum AMDGPU_UCODE_ID { 180*b843c749SSergey Zigachev AMDGPU_UCODE_ID_SDMA0 = 0, 181*b843c749SSergey Zigachev AMDGPU_UCODE_ID_SDMA1, 182*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_CE, 183*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_PFP, 184*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_ME, 185*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_MEC1, 186*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_MEC1_JT, 187*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_MEC2, 188*b843c749SSergey Zigachev AMDGPU_UCODE_ID_CP_MEC2_JT, 189*b843c749SSergey Zigachev AMDGPU_UCODE_ID_RLC_G, 190*b843c749SSergey Zigachev AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL, 191*b843c749SSergey Zigachev AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM, 192*b843c749SSergey Zigachev AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM, 193*b843c749SSergey Zigachev AMDGPU_UCODE_ID_STORAGE, 194*b843c749SSergey Zigachev AMDGPU_UCODE_ID_SMC, 195*b843c749SSergey Zigachev AMDGPU_UCODE_ID_UVD, 196*b843c749SSergey Zigachev AMDGPU_UCODE_ID_VCE, 197*b843c749SSergey Zigachev AMDGPU_UCODE_ID_VCN, 198*b843c749SSergey Zigachev AMDGPU_UCODE_ID_MAXIMUM, 199*b843c749SSergey Zigachev }; 200*b843c749SSergey Zigachev 201*b843c749SSergey Zigachev /* engine firmware status */ 202*b843c749SSergey Zigachev enum AMDGPU_UCODE_STATUS { 203*b843c749SSergey Zigachev AMDGPU_UCODE_STATUS_INVALID, 204*b843c749SSergey Zigachev AMDGPU_UCODE_STATUS_NOT_LOADED, 205*b843c749SSergey Zigachev AMDGPU_UCODE_STATUS_LOADED, 206*b843c749SSergey Zigachev }; 207*b843c749SSergey Zigachev 208*b843c749SSergey Zigachev /* conform to smu_ucode_xfer_cz.h */ 209*b843c749SSergey Zigachev #define AMDGPU_SDMA0_UCODE_LOADED 0x00000001 210*b843c749SSergey Zigachev #define AMDGPU_SDMA1_UCODE_LOADED 0x00000002 211*b843c749SSergey Zigachev #define AMDGPU_CPCE_UCODE_LOADED 0x00000004 212*b843c749SSergey Zigachev #define AMDGPU_CPPFP_UCODE_LOADED 0x00000008 213*b843c749SSergey Zigachev #define AMDGPU_CPME_UCODE_LOADED 0x00000010 214*b843c749SSergey Zigachev #define AMDGPU_CPMEC1_UCODE_LOADED 0x00000020 215*b843c749SSergey Zigachev #define AMDGPU_CPMEC2_UCODE_LOADED 0x00000040 216*b843c749SSergey Zigachev #define AMDGPU_CPRLC_UCODE_LOADED 0x00000100 217*b843c749SSergey Zigachev 218*b843c749SSergey Zigachev /* amdgpu firmware info */ 219*b843c749SSergey Zigachev struct amdgpu_firmware_info { 220*b843c749SSergey Zigachev /* ucode ID */ 221*b843c749SSergey Zigachev enum AMDGPU_UCODE_ID ucode_id; 222*b843c749SSergey Zigachev /* request_firmware */ 223*b843c749SSergey Zigachev const struct firmware *fw; 224*b843c749SSergey Zigachev /* starting mc address */ 225*b843c749SSergey Zigachev uint64_t mc_addr; 226*b843c749SSergey Zigachev /* kernel linear address */ 227*b843c749SSergey Zigachev void *kaddr; 228*b843c749SSergey Zigachev /* ucode_size_bytes */ 229*b843c749SSergey Zigachev uint32_t ucode_size; 230*b843c749SSergey Zigachev /* starting tmr mc address */ 231*b843c749SSergey Zigachev uint32_t tmr_mc_addr_lo; 232*b843c749SSergey Zigachev uint32_t tmr_mc_addr_hi; 233*b843c749SSergey Zigachev }; 234*b843c749SSergey Zigachev 235*b843c749SSergey Zigachev void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr); 236*b843c749SSergey Zigachev void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr); 237*b843c749SSergey Zigachev void amdgpu_ucode_print_gfx_hdr(const struct common_firmware_header *hdr); 238*b843c749SSergey Zigachev void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr); 239*b843c749SSergey Zigachev void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr); 240*b843c749SSergey Zigachev void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr); 241*b843c749SSergey Zigachev int amdgpu_ucode_validate(const struct firmware *fw); 242*b843c749SSergey Zigachev bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr, 243*b843c749SSergey Zigachev uint16_t hdr_major, uint16_t hdr_minor); 244*b843c749SSergey Zigachev int amdgpu_ucode_init_bo(struct amdgpu_device *adev); 245*b843c749SSergey Zigachev int amdgpu_ucode_fini_bo(struct amdgpu_device *adev); 246*b843c749SSergey Zigachev 247*b843c749SSergey Zigachev enum amdgpu_firmware_load_type 248*b843c749SSergey Zigachev amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type); 249*b843c749SSergey Zigachev 250*b843c749SSergey Zigachev #endif 251