xref: /openbsd-src/sys/dev/pci/drm/amd/amdgpu/amdgpu_ucode.c (revision 9fce72ccdf71aff3a9753dcbc97cb2647807e0bd)
1fb4d8502Sjsg /*
2fb4d8502Sjsg  * Copyright 2014 Advanced Micro Devices, Inc.
3fb4d8502Sjsg  *
4fb4d8502Sjsg  * Permission is hereby granted, free of charge, to any person obtaining a
5fb4d8502Sjsg  * copy of this software and associated documentation files (the "Software"),
6fb4d8502Sjsg  * to deal in the Software without restriction, including without limitation
7fb4d8502Sjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fb4d8502Sjsg  * and/or sell copies of the Software, and to permit persons to whom the
9fb4d8502Sjsg  * Software is furnished to do so, subject to the following conditions:
10fb4d8502Sjsg  *
11fb4d8502Sjsg  * The above copyright notice and this permission notice shall be included in
12fb4d8502Sjsg  * all copies or substantial portions of the Software.
13fb4d8502Sjsg  *
14fb4d8502Sjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15fb4d8502Sjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16fb4d8502Sjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17fb4d8502Sjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18fb4d8502Sjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19fb4d8502Sjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20fb4d8502Sjsg  * OTHER DEALINGS IN THE SOFTWARE.
21fb4d8502Sjsg  *
22fb4d8502Sjsg  */
23fb4d8502Sjsg 
24fb4d8502Sjsg #include <linux/firmware.h>
25fb4d8502Sjsg #include <linux/slab.h>
26fb4d8502Sjsg #include <linux/module.h>
27c349dbc7Sjsg 
28fb4d8502Sjsg #include "amdgpu.h"
29fb4d8502Sjsg #include "amdgpu_ucode.h"
30fb4d8502Sjsg 
amdgpu_ucode_print_common_hdr(const struct common_firmware_header * hdr)31fb4d8502Sjsg static void amdgpu_ucode_print_common_hdr(const struct common_firmware_header *hdr)
32fb4d8502Sjsg {
33fb4d8502Sjsg 	DRM_DEBUG("size_bytes: %u\n", le32_to_cpu(hdr->size_bytes));
34fb4d8502Sjsg 	DRM_DEBUG("header_size_bytes: %u\n", le32_to_cpu(hdr->header_size_bytes));
35fb4d8502Sjsg 	DRM_DEBUG("header_version_major: %u\n", le16_to_cpu(hdr->header_version_major));
36fb4d8502Sjsg 	DRM_DEBUG("header_version_minor: %u\n", le16_to_cpu(hdr->header_version_minor));
37fb4d8502Sjsg 	DRM_DEBUG("ip_version_major: %u\n", le16_to_cpu(hdr->ip_version_major));
38fb4d8502Sjsg 	DRM_DEBUG("ip_version_minor: %u\n", le16_to_cpu(hdr->ip_version_minor));
39fb4d8502Sjsg 	DRM_DEBUG("ucode_version: 0x%08x\n", le32_to_cpu(hdr->ucode_version));
40fb4d8502Sjsg 	DRM_DEBUG("ucode_size_bytes: %u\n", le32_to_cpu(hdr->ucode_size_bytes));
41fb4d8502Sjsg 	DRM_DEBUG("ucode_array_offset_bytes: %u\n",
42fb4d8502Sjsg 		  le32_to_cpu(hdr->ucode_array_offset_bytes));
43fb4d8502Sjsg 	DRM_DEBUG("crc32: 0x%08x\n", le32_to_cpu(hdr->crc32));
44fb4d8502Sjsg }
45fb4d8502Sjsg 
amdgpu_ucode_print_mc_hdr(const struct common_firmware_header * hdr)46fb4d8502Sjsg void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr)
47fb4d8502Sjsg {
48fb4d8502Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
49fb4d8502Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
50fb4d8502Sjsg 
51fb4d8502Sjsg 	DRM_DEBUG("MC\n");
52fb4d8502Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
53fb4d8502Sjsg 
54fb4d8502Sjsg 	if (version_major == 1) {
55fb4d8502Sjsg 		const struct mc_firmware_header_v1_0 *mc_hdr =
56fb4d8502Sjsg 			container_of(hdr, struct mc_firmware_header_v1_0, header);
57fb4d8502Sjsg 
58fb4d8502Sjsg 		DRM_DEBUG("io_debug_size_bytes: %u\n",
59fb4d8502Sjsg 			  le32_to_cpu(mc_hdr->io_debug_size_bytes));
60fb4d8502Sjsg 		DRM_DEBUG("io_debug_array_offset_bytes: %u\n",
61fb4d8502Sjsg 			  le32_to_cpu(mc_hdr->io_debug_array_offset_bytes));
62fb4d8502Sjsg 	} else {
63fb4d8502Sjsg 		DRM_ERROR("Unknown MC ucode version: %u.%u\n", version_major, version_minor);
64fb4d8502Sjsg 	}
65fb4d8502Sjsg }
66fb4d8502Sjsg 
amdgpu_ucode_print_smc_hdr(const struct common_firmware_header * hdr)67fb4d8502Sjsg void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr)
68fb4d8502Sjsg {
69fb4d8502Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
70fb4d8502Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
715ca02815Sjsg 	const struct smc_firmware_header_v1_0 *v1_0_hdr;
725ca02815Sjsg 	const struct smc_firmware_header_v2_0 *v2_0_hdr;
735ca02815Sjsg 	const struct smc_firmware_header_v2_1 *v2_1_hdr;
74fb4d8502Sjsg 
75fb4d8502Sjsg 	DRM_DEBUG("SMC\n");
76fb4d8502Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
77fb4d8502Sjsg 
78fb4d8502Sjsg 	if (version_major == 1) {
795ca02815Sjsg 		v1_0_hdr = container_of(hdr, struct smc_firmware_header_v1_0, header);
805ca02815Sjsg 		DRM_DEBUG("ucode_start_addr: %u\n", le32_to_cpu(v1_0_hdr->ucode_start_addr));
81c349dbc7Sjsg 	} else if (version_major == 2) {
825ca02815Sjsg 		switch (version_minor) {
835ca02815Sjsg 		case 0:
845ca02815Sjsg 			v2_0_hdr = container_of(hdr, struct smc_firmware_header_v2_0, v1_0.header);
855ca02815Sjsg 			DRM_DEBUG("ppt_offset_bytes: %u\n", le32_to_cpu(v2_0_hdr->ppt_offset_bytes));
865ca02815Sjsg 			DRM_DEBUG("ppt_size_bytes: %u\n", le32_to_cpu(v2_0_hdr->ppt_size_bytes));
875ca02815Sjsg 			break;
885ca02815Sjsg 		case 1:
895ca02815Sjsg 			v2_1_hdr = container_of(hdr, struct smc_firmware_header_v2_1, v1_0.header);
905ca02815Sjsg 			DRM_DEBUG("pptable_count: %u\n", le32_to_cpu(v2_1_hdr->pptable_count));
915ca02815Sjsg 			DRM_DEBUG("pptable_entry_offset: %u\n", le32_to_cpu(v2_1_hdr->pptable_entry_offset));
925ca02815Sjsg 			break;
935ca02815Sjsg 		default:
945ca02815Sjsg 			break;
955ca02815Sjsg 		}
96c349dbc7Sjsg 
97fb4d8502Sjsg 	} else {
98fb4d8502Sjsg 		DRM_ERROR("Unknown SMC ucode version: %u.%u\n", version_major, version_minor);
99fb4d8502Sjsg 	}
100fb4d8502Sjsg }
101fb4d8502Sjsg 
amdgpu_ucode_print_gfx_hdr(const struct common_firmware_header * hdr)102fb4d8502Sjsg void amdgpu_ucode_print_gfx_hdr(const struct common_firmware_header *hdr)
103fb4d8502Sjsg {
104fb4d8502Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
105fb4d8502Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
106fb4d8502Sjsg 
107fb4d8502Sjsg 	DRM_DEBUG("GFX\n");
108fb4d8502Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
109fb4d8502Sjsg 
110fb4d8502Sjsg 	if (version_major == 1) {
111fb4d8502Sjsg 		const struct gfx_firmware_header_v1_0 *gfx_hdr =
112fb4d8502Sjsg 			container_of(hdr, struct gfx_firmware_header_v1_0, header);
113fb4d8502Sjsg 
114fb4d8502Sjsg 		DRM_DEBUG("ucode_feature_version: %u\n",
115fb4d8502Sjsg 			  le32_to_cpu(gfx_hdr->ucode_feature_version));
116fb4d8502Sjsg 		DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(gfx_hdr->jt_offset));
117fb4d8502Sjsg 		DRM_DEBUG("jt_size: %u\n", le32_to_cpu(gfx_hdr->jt_size));
1181bb76ff1Sjsg 	} else if (version_major == 2) {
1191bb76ff1Sjsg 		const struct gfx_firmware_header_v2_0 *gfx_hdr =
1201bb76ff1Sjsg 			container_of(hdr, struct gfx_firmware_header_v2_0, header);
1211bb76ff1Sjsg 
1221bb76ff1Sjsg 		DRM_DEBUG("ucode_feature_version: %u\n",
1231bb76ff1Sjsg 			  le32_to_cpu(gfx_hdr->ucode_feature_version));
124fb4d8502Sjsg 	} else {
125fb4d8502Sjsg 		DRM_ERROR("Unknown GFX ucode version: %u.%u\n", version_major, version_minor);
126fb4d8502Sjsg 	}
127fb4d8502Sjsg }
128fb4d8502Sjsg 
amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header * hdr)129fb4d8502Sjsg void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
130fb4d8502Sjsg {
131fb4d8502Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
132fb4d8502Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
133fb4d8502Sjsg 
134fb4d8502Sjsg 	DRM_DEBUG("RLC\n");
135fb4d8502Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
136fb4d8502Sjsg 
137fb4d8502Sjsg 	if (version_major == 1) {
138fb4d8502Sjsg 		const struct rlc_firmware_header_v1_0 *rlc_hdr =
139fb4d8502Sjsg 			container_of(hdr, struct rlc_firmware_header_v1_0, header);
140fb4d8502Sjsg 
141fb4d8502Sjsg 		DRM_DEBUG("ucode_feature_version: %u\n",
142fb4d8502Sjsg 			  le32_to_cpu(rlc_hdr->ucode_feature_version));
143fb4d8502Sjsg 		DRM_DEBUG("save_and_restore_offset: %u\n",
144fb4d8502Sjsg 			  le32_to_cpu(rlc_hdr->save_and_restore_offset));
145fb4d8502Sjsg 		DRM_DEBUG("clear_state_descriptor_offset: %u\n",
146fb4d8502Sjsg 			  le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
147fb4d8502Sjsg 		DRM_DEBUG("avail_scratch_ram_locations: %u\n",
148fb4d8502Sjsg 			  le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
149fb4d8502Sjsg 		DRM_DEBUG("master_pkt_description_offset: %u\n",
150fb4d8502Sjsg 			  le32_to_cpu(rlc_hdr->master_pkt_description_offset));
151fb4d8502Sjsg 	} else if (version_major == 2) {
152fb4d8502Sjsg 		const struct rlc_firmware_header_v2_0 *rlc_hdr =
153fb4d8502Sjsg 			container_of(hdr, struct rlc_firmware_header_v2_0, header);
1541bb76ff1Sjsg 		const struct rlc_firmware_header_v2_1 *rlc_hdr_v2_1 =
1551bb76ff1Sjsg 			container_of(rlc_hdr, struct rlc_firmware_header_v2_1, v2_0);
1561bb76ff1Sjsg 		const struct rlc_firmware_header_v2_2 *rlc_hdr_v2_2 =
1571bb76ff1Sjsg 			container_of(rlc_hdr_v2_1, struct rlc_firmware_header_v2_2, v2_1);
1581bb76ff1Sjsg 		const struct rlc_firmware_header_v2_3 *rlc_hdr_v2_3 =
1591bb76ff1Sjsg 			container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_3, v2_2);
1601bb76ff1Sjsg 		const struct rlc_firmware_header_v2_4 *rlc_hdr_v2_4 =
1611bb76ff1Sjsg 			container_of(rlc_hdr_v2_3, struct rlc_firmware_header_v2_4, v2_3);
162fb4d8502Sjsg 
1631bb76ff1Sjsg 		switch (version_minor) {
1641bb76ff1Sjsg 		case 0:
1651bb76ff1Sjsg 			/* rlc_hdr v2_0 */
166fb4d8502Sjsg 			DRM_DEBUG("ucode_feature_version: %u\n",
167fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->ucode_feature_version));
168fb4d8502Sjsg 			DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(rlc_hdr->jt_offset));
169fb4d8502Sjsg 			DRM_DEBUG("jt_size: %u\n", le32_to_cpu(rlc_hdr->jt_size));
170fb4d8502Sjsg 			DRM_DEBUG("save_and_restore_offset: %u\n",
171fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->save_and_restore_offset));
172fb4d8502Sjsg 			DRM_DEBUG("clear_state_descriptor_offset: %u\n",
173fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
174fb4d8502Sjsg 			DRM_DEBUG("avail_scratch_ram_locations: %u\n",
175fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
176fb4d8502Sjsg 			DRM_DEBUG("reg_restore_list_size: %u\n",
177fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_restore_list_size));
178fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_start: %u\n",
179fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_format_start));
180fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_separate_start: %u\n",
181fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_format_separate_start));
182fb4d8502Sjsg 			DRM_DEBUG("starting_offsets_start: %u\n",
183fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->starting_offsets_start));
184fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_size_bytes: %u\n",
185fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_format_size_bytes));
186fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_array_offset_bytes: %u\n",
187fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
188fb4d8502Sjsg 			DRM_DEBUG("reg_list_size_bytes: %u\n",
189fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_size_bytes));
190fb4d8502Sjsg 			DRM_DEBUG("reg_list_array_offset_bytes: %u\n",
191fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
192fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_separate_size_bytes: %u\n",
193fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_format_separate_size_bytes));
194fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_separate_array_offset_bytes: %u\n",
195fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes));
196fb4d8502Sjsg 			DRM_DEBUG("reg_list_separate_size_bytes: %u\n",
197fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes));
198fb4d8502Sjsg 			DRM_DEBUG("reg_list_separate_array_offset_bytes: %u\n",
199fb4d8502Sjsg 				  le32_to_cpu(rlc_hdr->reg_list_separate_array_offset_bytes));
2001bb76ff1Sjsg 			break;
2011bb76ff1Sjsg 		case 1:
2021bb76ff1Sjsg 			/* rlc_hdr v2_1 */
203fb4d8502Sjsg 			DRM_DEBUG("reg_list_format_direct_reg_list_length: %u\n",
2041bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->reg_list_format_direct_reg_list_length));
205fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_cntl_ucode_ver: %u\n",
2061bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_ucode_ver));
207fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_cntl_feature_ver: %u\n",
2081bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_feature_ver));
209fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_cntl_size_bytes %u\n",
2101bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_size_bytes));
211fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_cntl_offset_bytes: %u\n",
2121bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_offset_bytes));
213fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_gpm_ucode_ver: %u\n",
2141bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_ucode_ver));
215fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_gpm_feature_ver: %u\n",
2161bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_feature_ver));
217fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_gpm_size_bytes %u\n",
2181bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_size_bytes));
219fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_gpm_offset_bytes: %u\n",
2201bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_offset_bytes));
221fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_srm_ucode_ver: %u\n",
2221bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_ucode_ver));
223fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_srm_feature_ver: %u\n",
2241bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_feature_ver));
225fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_srm_size_bytes %u\n",
2261bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_size_bytes));
227fb4d8502Sjsg 			DRM_DEBUG("save_restore_list_srm_offset_bytes: %u\n",
2281bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_offset_bytes));
2291bb76ff1Sjsg 			break;
2301bb76ff1Sjsg 		case 2:
2311bb76ff1Sjsg 			/* rlc_hdr v2_2 */
2321bb76ff1Sjsg 			DRM_DEBUG("rlc_iram_ucode_size_bytes: %u\n",
2331bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_2->rlc_iram_ucode_size_bytes));
2341bb76ff1Sjsg 			DRM_DEBUG("rlc_iram_ucode_offset_bytes: %u\n",
2351bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_2->rlc_iram_ucode_offset_bytes));
2361bb76ff1Sjsg 			DRM_DEBUG("rlc_dram_ucode_size_bytes: %u\n",
2371bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_2->rlc_dram_ucode_size_bytes));
2381bb76ff1Sjsg 			DRM_DEBUG("rlc_dram_ucode_offset_bytes: %u\n",
2391bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_2->rlc_dram_ucode_offset_bytes));
2401bb76ff1Sjsg 			break;
2411bb76ff1Sjsg 		case 3:
2421bb76ff1Sjsg 			/* rlc_hdr v2_3 */
2431bb76ff1Sjsg 			DRM_DEBUG("rlcp_ucode_version: %u\n",
2441bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_version));
2451bb76ff1Sjsg 			DRM_DEBUG("rlcp_ucode_feature_version: %u\n",
2461bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_feature_version));
2471bb76ff1Sjsg 			DRM_DEBUG("rlcp_ucode_size_bytes: %u\n",
2481bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_size_bytes));
2491bb76ff1Sjsg 			DRM_DEBUG("rlcp_ucode_offset_bytes: %u\n",
2501bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_offset_bytes));
2511bb76ff1Sjsg 			DRM_DEBUG("rlcv_ucode_version: %u\n",
2521bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_version));
2531bb76ff1Sjsg 			DRM_DEBUG("rlcv_ucode_feature_version: %u\n",
2541bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_feature_version));
2551bb76ff1Sjsg 			DRM_DEBUG("rlcv_ucode_size_bytes: %u\n",
2561bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_size_bytes));
2571bb76ff1Sjsg 			DRM_DEBUG("rlcv_ucode_offset_bytes: %u\n",
2581bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_offset_bytes));
2591bb76ff1Sjsg 			break;
2601bb76ff1Sjsg 		case 4:
2611bb76ff1Sjsg 			/* rlc_hdr v2_4 */
2621bb76ff1Sjsg 			DRM_DEBUG("global_tap_delays_ucode_size_bytes :%u\n",
2631bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->global_tap_delays_ucode_size_bytes));
2641bb76ff1Sjsg 			DRM_DEBUG("global_tap_delays_ucode_offset_bytes: %u\n",
2651bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->global_tap_delays_ucode_offset_bytes));
2661bb76ff1Sjsg 			DRM_DEBUG("se0_tap_delays_ucode_size_bytes :%u\n",
2671bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se0_tap_delays_ucode_size_bytes));
2681bb76ff1Sjsg 			DRM_DEBUG("se0_tap_delays_ucode_offset_bytes: %u\n",
2691bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se0_tap_delays_ucode_offset_bytes));
2701bb76ff1Sjsg 			DRM_DEBUG("se1_tap_delays_ucode_size_bytes :%u\n",
2711bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se1_tap_delays_ucode_size_bytes));
2721bb76ff1Sjsg 			DRM_DEBUG("se1_tap_delays_ucode_offset_bytes: %u\n",
2731bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se1_tap_delays_ucode_offset_bytes));
2741bb76ff1Sjsg 			DRM_DEBUG("se2_tap_delays_ucode_size_bytes :%u\n",
2751bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se2_tap_delays_ucode_size_bytes));
2761bb76ff1Sjsg 			DRM_DEBUG("se2_tap_delays_ucode_offset_bytes: %u\n",
2771bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se2_tap_delays_ucode_offset_bytes));
2781bb76ff1Sjsg 			DRM_DEBUG("se3_tap_delays_ucode_size_bytes :%u\n",
2791bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_size_bytes));
2801bb76ff1Sjsg 			DRM_DEBUG("se3_tap_delays_ucode_offset_bytes: %u\n",
2811bb76ff1Sjsg 				  le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_offset_bytes));
2821bb76ff1Sjsg 			break;
2831bb76ff1Sjsg 		default:
2841bb76ff1Sjsg 			DRM_ERROR("Unknown RLC v2 ucode: v2.%u\n", version_minor);
2851bb76ff1Sjsg 			break;
286fb4d8502Sjsg 		}
287fb4d8502Sjsg 	} else {
288fb4d8502Sjsg 		DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor);
289fb4d8502Sjsg 	}
290fb4d8502Sjsg }
291fb4d8502Sjsg 
amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header * hdr)292fb4d8502Sjsg void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr)
293fb4d8502Sjsg {
294fb4d8502Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
295fb4d8502Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
296fb4d8502Sjsg 
297fb4d8502Sjsg 	DRM_DEBUG("SDMA\n");
298fb4d8502Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
299fb4d8502Sjsg 
300fb4d8502Sjsg 	if (version_major == 1) {
301fb4d8502Sjsg 		const struct sdma_firmware_header_v1_0 *sdma_hdr =
302fb4d8502Sjsg 			container_of(hdr, struct sdma_firmware_header_v1_0, header);
303fb4d8502Sjsg 
304fb4d8502Sjsg 		DRM_DEBUG("ucode_feature_version: %u\n",
305fb4d8502Sjsg 			  le32_to_cpu(sdma_hdr->ucode_feature_version));
306fb4d8502Sjsg 		DRM_DEBUG("ucode_change_version: %u\n",
307fb4d8502Sjsg 			  le32_to_cpu(sdma_hdr->ucode_change_version));
308fb4d8502Sjsg 		DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(sdma_hdr->jt_offset));
309fb4d8502Sjsg 		DRM_DEBUG("jt_size: %u\n", le32_to_cpu(sdma_hdr->jt_size));
310fb4d8502Sjsg 		if (version_minor >= 1) {
311fb4d8502Sjsg 			const struct sdma_firmware_header_v1_1 *sdma_v1_1_hdr =
312fb4d8502Sjsg 				container_of(sdma_hdr, struct sdma_firmware_header_v1_1, v1_0);
313fb4d8502Sjsg 			DRM_DEBUG("digest_size: %u\n", le32_to_cpu(sdma_v1_1_hdr->digest_size));
314fb4d8502Sjsg 		}
3151bb76ff1Sjsg 	} else if (version_major == 2) {
3161bb76ff1Sjsg 		const struct sdma_firmware_header_v2_0 *sdma_hdr =
3171bb76ff1Sjsg 			container_of(hdr, struct sdma_firmware_header_v2_0, header);
3181bb76ff1Sjsg 
3191bb76ff1Sjsg 		DRM_DEBUG("ucode_feature_version: %u\n",
3201bb76ff1Sjsg 			  le32_to_cpu(sdma_hdr->ucode_feature_version));
3211bb76ff1Sjsg 		DRM_DEBUG("ctx_jt_offset: %u\n", le32_to_cpu(sdma_hdr->ctx_jt_offset));
3221bb76ff1Sjsg 		DRM_DEBUG("ctx_jt_size: %u\n", le32_to_cpu(sdma_hdr->ctx_jt_size));
3231bb76ff1Sjsg 		DRM_DEBUG("ctl_ucode_offset: %u\n", le32_to_cpu(sdma_hdr->ctl_ucode_offset));
3241bb76ff1Sjsg 		DRM_DEBUG("ctl_jt_offset: %u\n", le32_to_cpu(sdma_hdr->ctl_jt_offset));
3251bb76ff1Sjsg 		DRM_DEBUG("ctl_jt_size: %u\n", le32_to_cpu(sdma_hdr->ctl_jt_size));
326fb4d8502Sjsg 	} else {
327fb4d8502Sjsg 		DRM_ERROR("Unknown SDMA ucode version: %u.%u\n",
328fb4d8502Sjsg 			  version_major, version_minor);
329fb4d8502Sjsg 	}
330fb4d8502Sjsg }
331fb4d8502Sjsg 
amdgpu_ucode_print_psp_hdr(const struct common_firmware_header * hdr)332c349dbc7Sjsg void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr)
333c349dbc7Sjsg {
334c349dbc7Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
335c349dbc7Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
3361bb76ff1Sjsg 	uint32_t fw_index;
3371bb76ff1Sjsg 	const struct psp_fw_bin_desc *desc;
338c349dbc7Sjsg 
339c349dbc7Sjsg 	DRM_DEBUG("PSP\n");
340c349dbc7Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
341c349dbc7Sjsg 
342c349dbc7Sjsg 	if (version_major == 1) {
343c349dbc7Sjsg 		const struct psp_firmware_header_v1_0 *psp_hdr =
344c349dbc7Sjsg 			container_of(hdr, struct psp_firmware_header_v1_0, header);
345c349dbc7Sjsg 
346c349dbc7Sjsg 		DRM_DEBUG("ucode_feature_version: %u\n",
3475ca02815Sjsg 			  le32_to_cpu(psp_hdr->sos.fw_version));
348c349dbc7Sjsg 		DRM_DEBUG("sos_offset_bytes: %u\n",
3495ca02815Sjsg 			  le32_to_cpu(psp_hdr->sos.offset_bytes));
350c349dbc7Sjsg 		DRM_DEBUG("sos_size_bytes: %u\n",
3515ca02815Sjsg 			  le32_to_cpu(psp_hdr->sos.size_bytes));
352c349dbc7Sjsg 		if (version_minor == 1) {
353c349dbc7Sjsg 			const struct psp_firmware_header_v1_1 *psp_hdr_v1_1 =
354c349dbc7Sjsg 				container_of(psp_hdr, struct psp_firmware_header_v1_1, v1_0);
355c349dbc7Sjsg 			DRM_DEBUG("toc_header_version: %u\n",
3565ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_1->toc.fw_version));
357c349dbc7Sjsg 			DRM_DEBUG("toc_offset_bytes: %u\n",
3585ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_1->toc.offset_bytes));
359c349dbc7Sjsg 			DRM_DEBUG("toc_size_bytes: %u\n",
3605ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_1->toc.size_bytes));
361c349dbc7Sjsg 			DRM_DEBUG("kdb_header_version: %u\n",
3625ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_1->kdb.fw_version));
363c349dbc7Sjsg 			DRM_DEBUG("kdb_offset_bytes: %u\n",
3645ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_1->kdb.offset_bytes));
365c349dbc7Sjsg 			DRM_DEBUG("kdb_size_bytes: %u\n",
3665ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_1->kdb.size_bytes));
367c349dbc7Sjsg 		}
368c349dbc7Sjsg 		if (version_minor == 2) {
369c349dbc7Sjsg 			const struct psp_firmware_header_v1_2 *psp_hdr_v1_2 =
370c349dbc7Sjsg 				container_of(psp_hdr, struct psp_firmware_header_v1_2, v1_0);
371c349dbc7Sjsg 			DRM_DEBUG("kdb_header_version: %u\n",
3725ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_2->kdb.fw_version));
373c349dbc7Sjsg 			DRM_DEBUG("kdb_offset_bytes: %u\n",
3745ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_2->kdb.offset_bytes));
375c349dbc7Sjsg 			DRM_DEBUG("kdb_size_bytes: %u\n",
3765ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_2->kdb.size_bytes));
377c349dbc7Sjsg 		}
378ad8b1aafSjsg 		if (version_minor == 3) {
379ad8b1aafSjsg 			const struct psp_firmware_header_v1_1 *psp_hdr_v1_1 =
380ad8b1aafSjsg 				container_of(psp_hdr, struct psp_firmware_header_v1_1, v1_0);
381ad8b1aafSjsg 			const struct psp_firmware_header_v1_3 *psp_hdr_v1_3 =
382ad8b1aafSjsg 				container_of(psp_hdr_v1_1, struct psp_firmware_header_v1_3, v1_1);
383ad8b1aafSjsg 			DRM_DEBUG("toc_header_version: %u\n",
3845ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->v1_1.toc.fw_version));
385ad8b1aafSjsg 			DRM_DEBUG("toc_offset_bytes: %u\n",
3865ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->v1_1.toc.offset_bytes));
387ad8b1aafSjsg 			DRM_DEBUG("toc_size_bytes: %u\n",
3885ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->v1_1.toc.size_bytes));
389ad8b1aafSjsg 			DRM_DEBUG("kdb_header_version: %u\n",
3905ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->v1_1.kdb.fw_version));
391ad8b1aafSjsg 			DRM_DEBUG("kdb_offset_bytes: %u\n",
3925ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->v1_1.kdb.offset_bytes));
393ad8b1aafSjsg 			DRM_DEBUG("kdb_size_bytes: %u\n",
3945ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->v1_1.kdb.size_bytes));
395ad8b1aafSjsg 			DRM_DEBUG("spl_header_version: %u\n",
3965ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->spl.fw_version));
397ad8b1aafSjsg 			DRM_DEBUG("spl_offset_bytes: %u\n",
3985ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->spl.offset_bytes));
399ad8b1aafSjsg 			DRM_DEBUG("spl_size_bytes: %u\n",
4005ca02815Sjsg 				  le32_to_cpu(psp_hdr_v1_3->spl.size_bytes));
401ad8b1aafSjsg 		}
4021bb76ff1Sjsg 	} else if (version_major == 2) {
4031bb76ff1Sjsg 		const struct psp_firmware_header_v2_0 *psp_hdr_v2_0 =
4041bb76ff1Sjsg 			 container_of(hdr, struct psp_firmware_header_v2_0, header);
4051bb76ff1Sjsg 		for (fw_index = 0; fw_index < le32_to_cpu(psp_hdr_v2_0->psp_fw_bin_count); fw_index++) {
4061bb76ff1Sjsg 			desc = &(psp_hdr_v2_0->psp_fw_bin[fw_index]);
4071bb76ff1Sjsg 			switch (desc->fw_type) {
4081bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_SOS:
4091bb76ff1Sjsg 				DRM_DEBUG("psp_sos_version: %u\n",
4101bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4111bb76ff1Sjsg 				DRM_DEBUG("psp_sos_size_bytes: %u\n",
4121bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4131bb76ff1Sjsg 				break;
4141bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_SYS_DRV:
4151bb76ff1Sjsg 				DRM_DEBUG("psp_sys_drv_version: %u\n",
4161bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4171bb76ff1Sjsg 				DRM_DEBUG("psp_sys_drv_size_bytes: %u\n",
4181bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4191bb76ff1Sjsg 				break;
4201bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_KDB:
4211bb76ff1Sjsg 				DRM_DEBUG("psp_kdb_version: %u\n",
4221bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4231bb76ff1Sjsg 				DRM_DEBUG("psp_kdb_size_bytes: %u\n",
4241bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4251bb76ff1Sjsg 				break;
4261bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_TOC:
4271bb76ff1Sjsg 				DRM_DEBUG("psp_toc_version: %u\n",
4281bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4291bb76ff1Sjsg 				DRM_DEBUG("psp_toc_size_bytes: %u\n",
4301bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4311bb76ff1Sjsg 				break;
4321bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_SPL:
4331bb76ff1Sjsg 				DRM_DEBUG("psp_spl_version: %u\n",
4341bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4351bb76ff1Sjsg 				DRM_DEBUG("psp_spl_size_bytes: %u\n",
4361bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4371bb76ff1Sjsg 				break;
4381bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_RL:
4391bb76ff1Sjsg 				DRM_DEBUG("psp_rl_version: %u\n",
4401bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4411bb76ff1Sjsg 				DRM_DEBUG("psp_rl_size_bytes: %u\n",
4421bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4431bb76ff1Sjsg 				break;
4441bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_SOC_DRV:
4451bb76ff1Sjsg 				DRM_DEBUG("psp_soc_drv_version: %u\n",
4461bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4471bb76ff1Sjsg 				DRM_DEBUG("psp_soc_drv_size_bytes: %u\n",
4481bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4491bb76ff1Sjsg 				break;
4501bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_INTF_DRV:
4511bb76ff1Sjsg 				DRM_DEBUG("psp_intf_drv_version: %u\n",
4521bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4531bb76ff1Sjsg 				DRM_DEBUG("psp_intf_drv_size_bytes: %u\n",
4541bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4551bb76ff1Sjsg 				break;
4561bb76ff1Sjsg 			case PSP_FW_TYPE_PSP_DBG_DRV:
4571bb76ff1Sjsg 				DRM_DEBUG("psp_dbg_drv_version: %u\n",
4581bb76ff1Sjsg 					  le32_to_cpu(desc->fw_version));
4591bb76ff1Sjsg 				DRM_DEBUG("psp_dbg_drv_size_bytes: %u\n",
4601bb76ff1Sjsg 					  le32_to_cpu(desc->size_bytes));
4611bb76ff1Sjsg 				break;
462f005ef32Sjsg 			case PSP_FW_TYPE_PSP_RAS_DRV:
463f005ef32Sjsg 				DRM_DEBUG("psp_ras_drv_version: %u\n",
464f005ef32Sjsg 					  le32_to_cpu(desc->fw_version));
465f005ef32Sjsg 				DRM_DEBUG("psp_ras_drv_size_bytes: %u\n",
466f005ef32Sjsg 					  le32_to_cpu(desc->size_bytes));
467f005ef32Sjsg 				break;
4681bb76ff1Sjsg 			default:
4691bb76ff1Sjsg 				DRM_DEBUG("Unsupported PSP fw type: %d\n", desc->fw_type);
4701bb76ff1Sjsg 				break;
4711bb76ff1Sjsg 			}
4721bb76ff1Sjsg 		}
473c349dbc7Sjsg 	} else {
474c349dbc7Sjsg 		DRM_ERROR("Unknown PSP ucode version: %u.%u\n",
475c349dbc7Sjsg 			  version_major, version_minor);
476c349dbc7Sjsg 	}
477c349dbc7Sjsg }
478c349dbc7Sjsg 
amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header * hdr)479fb4d8502Sjsg void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr)
480fb4d8502Sjsg {
481fb4d8502Sjsg 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
482fb4d8502Sjsg 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
483fb4d8502Sjsg 
484fb4d8502Sjsg 	DRM_DEBUG("GPU_INFO\n");
485fb4d8502Sjsg 	amdgpu_ucode_print_common_hdr(hdr);
486fb4d8502Sjsg 
487fb4d8502Sjsg 	if (version_major == 1) {
488fb4d8502Sjsg 		const struct gpu_info_firmware_header_v1_0 *gpu_info_hdr =
489fb4d8502Sjsg 			container_of(hdr, struct gpu_info_firmware_header_v1_0, header);
490fb4d8502Sjsg 
491fb4d8502Sjsg 		DRM_DEBUG("version_major: %u\n",
492fb4d8502Sjsg 			  le16_to_cpu(gpu_info_hdr->version_major));
493fb4d8502Sjsg 		DRM_DEBUG("version_minor: %u\n",
494fb4d8502Sjsg 			  le16_to_cpu(gpu_info_hdr->version_minor));
495fb4d8502Sjsg 	} else {
496fb4d8502Sjsg 		DRM_ERROR("Unknown gpu_info ucode version: %u.%u\n", version_major, version_minor);
497fb4d8502Sjsg 	}
498fb4d8502Sjsg }
499fb4d8502Sjsg 
amdgpu_ucode_validate(const struct firmware * fw)500f005ef32Sjsg static int amdgpu_ucode_validate(const struct firmware *fw)
501fb4d8502Sjsg {
502fb4d8502Sjsg 	const struct common_firmware_header *hdr =
503fb4d8502Sjsg 		(const struct common_firmware_header *)fw->data;
504fb4d8502Sjsg 
505fb4d8502Sjsg 	if (fw->size == le32_to_cpu(hdr->size_bytes))
506fb4d8502Sjsg 		return 0;
507fb4d8502Sjsg 
508fb4d8502Sjsg 	return -EINVAL;
509fb4d8502Sjsg }
510fb4d8502Sjsg 
amdgpu_ucode_hdr_version(union amdgpu_firmware_header * hdr,uint16_t hdr_major,uint16_t hdr_minor)511fb4d8502Sjsg bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
512fb4d8502Sjsg 				uint16_t hdr_major, uint16_t hdr_minor)
513fb4d8502Sjsg {
514fb4d8502Sjsg 	if ((hdr->common.header_version_major == hdr_major) &&
515fb4d8502Sjsg 		(hdr->common.header_version_minor == hdr_minor))
516fb4d8502Sjsg 		return true;
5171bb76ff1Sjsg 	return false;
518fb4d8502Sjsg }
519fb4d8502Sjsg 
520fb4d8502Sjsg enum amdgpu_firmware_load_type
amdgpu_ucode_get_load_type(struct amdgpu_device * adev,int load_type)521fb4d8502Sjsg amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
522fb4d8502Sjsg {
523fb4d8502Sjsg 	switch (adev->asic_type) {
524fb4d8502Sjsg #ifdef CONFIG_DRM_AMDGPU_SI
525fb4d8502Sjsg 	case CHIP_TAHITI:
526fb4d8502Sjsg 	case CHIP_PITCAIRN:
527fb4d8502Sjsg 	case CHIP_VERDE:
528fb4d8502Sjsg 	case CHIP_OLAND:
529fb4d8502Sjsg 	case CHIP_HAINAN:
530fb4d8502Sjsg 		return AMDGPU_FW_LOAD_DIRECT;
531fb4d8502Sjsg #endif
532fb4d8502Sjsg #ifdef CONFIG_DRM_AMDGPU_CIK
533fb4d8502Sjsg 	case CHIP_BONAIRE:
534fb4d8502Sjsg 	case CHIP_KAVERI:
535fb4d8502Sjsg 	case CHIP_KABINI:
536fb4d8502Sjsg 	case CHIP_HAWAII:
537fb4d8502Sjsg 	case CHIP_MULLINS:
538fb4d8502Sjsg 		return AMDGPU_FW_LOAD_DIRECT;
539fb4d8502Sjsg #endif
540fb4d8502Sjsg 	case CHIP_TOPAZ:
541fb4d8502Sjsg 	case CHIP_TONGA:
542fb4d8502Sjsg 	case CHIP_FIJI:
543fb4d8502Sjsg 	case CHIP_CARRIZO:
544fb4d8502Sjsg 	case CHIP_STONEY:
545fb4d8502Sjsg 	case CHIP_POLARIS10:
546fb4d8502Sjsg 	case CHIP_POLARIS11:
547fb4d8502Sjsg 	case CHIP_POLARIS12:
548fb4d8502Sjsg 	case CHIP_VEGAM:
549fb4d8502Sjsg 		return AMDGPU_FW_LOAD_SMU;
5505ca02815Sjsg 	case CHIP_CYAN_SKILLFISH:
5515ca02815Sjsg 		if (!(load_type &&
5525ca02815Sjsg 		      adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2))
5535ca02815Sjsg 			return AMDGPU_FW_LOAD_DIRECT;
5545ca02815Sjsg 		else
5555ca02815Sjsg 			return AMDGPU_FW_LOAD_PSP;
556fb4d8502Sjsg 	default:
5571bb76ff1Sjsg 		if (!load_type)
558fb4d8502Sjsg 			return AMDGPU_FW_LOAD_DIRECT;
5591bb76ff1Sjsg 		else
5601bb76ff1Sjsg 			return AMDGPU_FW_LOAD_PSP;
5611bb76ff1Sjsg 	}
562fb4d8502Sjsg }
563fb4d8502Sjsg 
amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)5645ca02815Sjsg const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)
5655ca02815Sjsg {
5665ca02815Sjsg 	switch (ucode_id) {
5675ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA0:
5685ca02815Sjsg 		return "SDMA0";
5695ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA1:
5705ca02815Sjsg 		return "SDMA1";
5715ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA2:
5725ca02815Sjsg 		return "SDMA2";
5735ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA3:
5745ca02815Sjsg 		return "SDMA3";
5755ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA4:
5765ca02815Sjsg 		return "SDMA4";
5775ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA5:
5785ca02815Sjsg 		return "SDMA5";
5795ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA6:
5805ca02815Sjsg 		return "SDMA6";
5815ca02815Sjsg 	case AMDGPU_UCODE_ID_SDMA7:
5825ca02815Sjsg 		return "SDMA7";
5831bb76ff1Sjsg 	case AMDGPU_UCODE_ID_SDMA_UCODE_TH0:
5841bb76ff1Sjsg 		return "SDMA_CTX";
5851bb76ff1Sjsg 	case AMDGPU_UCODE_ID_SDMA_UCODE_TH1:
5861bb76ff1Sjsg 		return "SDMA_CTL";
5875ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_CE:
5885ca02815Sjsg 		return "CP_CE";
5895ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_PFP:
5905ca02815Sjsg 		return "CP_PFP";
5915ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_ME:
5925ca02815Sjsg 		return "CP_ME";
5935ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_MEC1:
5945ca02815Sjsg 		return "CP_MEC1";
5955ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_MEC1_JT:
5965ca02815Sjsg 		return "CP_MEC1_JT";
5975ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_MEC2:
5985ca02815Sjsg 		return "CP_MEC2";
5995ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_MEC2_JT:
6005ca02815Sjsg 		return "CP_MEC2_JT";
6015ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_MES:
6025ca02815Sjsg 		return "CP_MES";
6035ca02815Sjsg 	case AMDGPU_UCODE_ID_CP_MES_DATA:
6045ca02815Sjsg 		return "CP_MES_DATA";
6051bb76ff1Sjsg 	case AMDGPU_UCODE_ID_CP_MES1:
6061bb76ff1Sjsg 		return "CP_MES_KIQ";
6071bb76ff1Sjsg 	case AMDGPU_UCODE_ID_CP_MES1_DATA:
6081bb76ff1Sjsg 		return "CP_MES_KIQ_DATA";
6095ca02815Sjsg 	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
6105ca02815Sjsg 		return "RLC_RESTORE_LIST_CNTL";
6115ca02815Sjsg 	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
6125ca02815Sjsg 		return "RLC_RESTORE_LIST_GPM_MEM";
6135ca02815Sjsg 	case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
6145ca02815Sjsg 		return "RLC_RESTORE_LIST_SRM_MEM";
6155ca02815Sjsg 	case AMDGPU_UCODE_ID_RLC_IRAM:
6165ca02815Sjsg 		return "RLC_IRAM";
6175ca02815Sjsg 	case AMDGPU_UCODE_ID_RLC_DRAM:
6185ca02815Sjsg 		return "RLC_DRAM";
6195ca02815Sjsg 	case AMDGPU_UCODE_ID_RLC_G:
6205ca02815Sjsg 		return "RLC_G";
6211bb76ff1Sjsg 	case AMDGPU_UCODE_ID_RLC_P:
6221bb76ff1Sjsg 		return "RLC_P";
6231bb76ff1Sjsg 	case AMDGPU_UCODE_ID_RLC_V:
6241bb76ff1Sjsg 		return "RLC_V";
6251bb76ff1Sjsg 	case AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS:
6261bb76ff1Sjsg 		return "GLOBAL_TAP_DELAYS";
6271bb76ff1Sjsg 	case AMDGPU_UCODE_ID_SE0_TAP_DELAYS:
6281bb76ff1Sjsg 		return "SE0_TAP_DELAYS";
6291bb76ff1Sjsg 	case AMDGPU_UCODE_ID_SE1_TAP_DELAYS:
6301bb76ff1Sjsg 		return "SE1_TAP_DELAYS";
6311bb76ff1Sjsg 	case AMDGPU_UCODE_ID_SE2_TAP_DELAYS:
6321bb76ff1Sjsg 		return "SE2_TAP_DELAYS";
6331bb76ff1Sjsg 	case AMDGPU_UCODE_ID_SE3_TAP_DELAYS:
6341bb76ff1Sjsg 		return "SE3_TAP_DELAYS";
6351bb76ff1Sjsg 	case AMDGPU_UCODE_ID_IMU_I:
6361bb76ff1Sjsg 		return "IMU_I";
6371bb76ff1Sjsg 	case AMDGPU_UCODE_ID_IMU_D:
6381bb76ff1Sjsg 		return "IMU_D";
6395ca02815Sjsg 	case AMDGPU_UCODE_ID_STORAGE:
6405ca02815Sjsg 		return "STORAGE";
6415ca02815Sjsg 	case AMDGPU_UCODE_ID_SMC:
6425ca02815Sjsg 		return "SMC";
6431bb76ff1Sjsg 	case AMDGPU_UCODE_ID_PPTABLE:
6441bb76ff1Sjsg 		return "PPTABLE";
6455ca02815Sjsg 	case AMDGPU_UCODE_ID_UVD:
6465ca02815Sjsg 		return "UVD";
6475ca02815Sjsg 	case AMDGPU_UCODE_ID_UVD1:
6485ca02815Sjsg 		return "UVD1";
6495ca02815Sjsg 	case AMDGPU_UCODE_ID_VCE:
6505ca02815Sjsg 		return "VCE";
6515ca02815Sjsg 	case AMDGPU_UCODE_ID_VCN:
6525ca02815Sjsg 		return "VCN";
6535ca02815Sjsg 	case AMDGPU_UCODE_ID_VCN1:
6545ca02815Sjsg 		return "VCN1";
6555ca02815Sjsg 	case AMDGPU_UCODE_ID_DMCU_ERAM:
6565ca02815Sjsg 		return "DMCU_ERAM";
6575ca02815Sjsg 	case AMDGPU_UCODE_ID_DMCU_INTV:
6585ca02815Sjsg 		return "DMCU_INTV";
6595ca02815Sjsg 	case AMDGPU_UCODE_ID_VCN0_RAM:
6605ca02815Sjsg 		return "VCN0_RAM";
6615ca02815Sjsg 	case AMDGPU_UCODE_ID_VCN1_RAM:
6625ca02815Sjsg 		return "VCN1_RAM";
6635ca02815Sjsg 	case AMDGPU_UCODE_ID_DMCUB:
6645ca02815Sjsg 		return "DMCUB";
665f005ef32Sjsg 	case AMDGPU_UCODE_ID_CAP:
666f005ef32Sjsg 		return "CAP";
6675ca02815Sjsg 	default:
6685ca02815Sjsg 		return "UNKNOWN UCODE";
6695ca02815Sjsg 	}
6705ca02815Sjsg }
6715ca02815Sjsg 
672c349dbc7Sjsg #ifdef __linux__
673c349dbc7Sjsg 
674c349dbc7Sjsg #define FW_VERSION_ATTR(name, mode, field)				\
675c349dbc7Sjsg static ssize_t show_##name(struct device *dev,				\
676c349dbc7Sjsg 			  struct device_attribute *attr,		\
677c349dbc7Sjsg 			  char *buf)					\
678c349dbc7Sjsg {									\
679c349dbc7Sjsg 	struct drm_device *ddev = dev_get_drvdata(dev);			\
680ad8b1aafSjsg 	struct amdgpu_device *adev = drm_to_adev(ddev);			\
681c349dbc7Sjsg 									\
6821bb76ff1Sjsg 	return sysfs_emit(buf, "0x%08x\n", adev->field);	\
683c349dbc7Sjsg }									\
684c349dbc7Sjsg static DEVICE_ATTR(name, mode, show_##name, NULL)
685c349dbc7Sjsg 
686c349dbc7Sjsg FW_VERSION_ATTR(vce_fw_version, 0444, vce.fw_version);
687c349dbc7Sjsg FW_VERSION_ATTR(uvd_fw_version, 0444, uvd.fw_version);
688c349dbc7Sjsg FW_VERSION_ATTR(mc_fw_version, 0444, gmc.fw_version);
689c349dbc7Sjsg FW_VERSION_ATTR(me_fw_version, 0444, gfx.me_fw_version);
690c349dbc7Sjsg FW_VERSION_ATTR(pfp_fw_version, 0444, gfx.pfp_fw_version);
691c349dbc7Sjsg FW_VERSION_ATTR(ce_fw_version, 0444, gfx.ce_fw_version);
692c349dbc7Sjsg FW_VERSION_ATTR(rlc_fw_version, 0444, gfx.rlc_fw_version);
693c349dbc7Sjsg FW_VERSION_ATTR(rlc_srlc_fw_version, 0444, gfx.rlc_srlc_fw_version);
694c349dbc7Sjsg FW_VERSION_ATTR(rlc_srlg_fw_version, 0444, gfx.rlc_srlg_fw_version);
695c349dbc7Sjsg FW_VERSION_ATTR(rlc_srls_fw_version, 0444, gfx.rlc_srls_fw_version);
696c349dbc7Sjsg FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
697c349dbc7Sjsg FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
6981bb76ff1Sjsg FW_VERSION_ATTR(imu_fw_version, 0444, gfx.imu_fw_version);
6995ca02815Sjsg FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version);
7001bb76ff1Sjsg FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version);
7011bb76ff1Sjsg FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version);
7021bb76ff1Sjsg FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi_context.context.bin_desc.fw_version);
703c349dbc7Sjsg FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version);
704c349dbc7Sjsg FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version);
705c349dbc7Sjsg FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version);
706c349dbc7Sjsg FW_VERSION_ATTR(vcn_fw_version, 0444, vcn.fw_version);
707c349dbc7Sjsg FW_VERSION_ATTR(dmcu_fw_version, 0444, dm.dmcu_fw_version);
708f005ef32Sjsg FW_VERSION_ATTR(mes_fw_version, 0444, mes.sched_version & AMDGPU_MES_VERSION_MASK);
709f005ef32Sjsg FW_VERSION_ATTR(mes_kiq_fw_version, 0444, mes.kiq_version & AMDGPU_MES_VERSION_MASK);
710c349dbc7Sjsg 
711c349dbc7Sjsg static struct attribute *fw_attrs[] = {
712c349dbc7Sjsg 	&dev_attr_vce_fw_version.attr, &dev_attr_uvd_fw_version.attr,
713c349dbc7Sjsg 	&dev_attr_mc_fw_version.attr, &dev_attr_me_fw_version.attr,
714c349dbc7Sjsg 	&dev_attr_pfp_fw_version.attr, &dev_attr_ce_fw_version.attr,
715c349dbc7Sjsg 	&dev_attr_rlc_fw_version.attr, &dev_attr_rlc_srlc_fw_version.attr,
716c349dbc7Sjsg 	&dev_attr_rlc_srlg_fw_version.attr, &dev_attr_rlc_srls_fw_version.attr,
717c349dbc7Sjsg 	&dev_attr_mec_fw_version.attr, &dev_attr_mec2_fw_version.attr,
718c349dbc7Sjsg 	&dev_attr_sos_fw_version.attr, &dev_attr_asd_fw_version.attr,
719c349dbc7Sjsg 	&dev_attr_ta_ras_fw_version.attr, &dev_attr_ta_xgmi_fw_version.attr,
720c349dbc7Sjsg 	&dev_attr_smc_fw_version.attr, &dev_attr_sdma_fw_version.attr,
721c349dbc7Sjsg 	&dev_attr_sdma2_fw_version.attr, &dev_attr_vcn_fw_version.attr,
7221bb76ff1Sjsg 	&dev_attr_dmcu_fw_version.attr, &dev_attr_imu_fw_version.attr,
723f005ef32Sjsg 	&dev_attr_mes_fw_version.attr, &dev_attr_mes_kiq_fw_version.attr,
7241bb76ff1Sjsg 	NULL
725c349dbc7Sjsg };
726c349dbc7Sjsg 
727c349dbc7Sjsg static const struct attribute_group fw_attr_group = {
728c349dbc7Sjsg 	.name = "fw_version",
729c349dbc7Sjsg 	.attrs = fw_attrs
730c349dbc7Sjsg };
731c349dbc7Sjsg 
732c349dbc7Sjsg #endif /* __linux__ */
733c349dbc7Sjsg 
amdgpu_ucode_sysfs_init(struct amdgpu_device * adev)734c349dbc7Sjsg int amdgpu_ucode_sysfs_init(struct amdgpu_device *adev)
735c349dbc7Sjsg {
736c349dbc7Sjsg 	return sysfs_create_group(&adev->dev->kobj, &fw_attr_group);
737c349dbc7Sjsg }
738c349dbc7Sjsg 
amdgpu_ucode_sysfs_fini(struct amdgpu_device * adev)739c349dbc7Sjsg void amdgpu_ucode_sysfs_fini(struct amdgpu_device *adev)
740c349dbc7Sjsg {
741c349dbc7Sjsg 	sysfs_remove_group(&adev->dev->kobj, &fw_attr_group);
742c349dbc7Sjsg }
743c349dbc7Sjsg 
amdgpu_ucode_init_single_fw(struct amdgpu_device * adev,struct amdgpu_firmware_info * ucode,uint64_t mc_addr,void * kptr)744fb4d8502Sjsg static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
745fb4d8502Sjsg 				       struct amdgpu_firmware_info *ucode,
746fb4d8502Sjsg 				       uint64_t mc_addr, void *kptr)
747fb4d8502Sjsg {
748fb4d8502Sjsg 	const struct common_firmware_header *header = NULL;
749fb4d8502Sjsg 	const struct gfx_firmware_header_v1_0 *cp_hdr = NULL;
7501bb76ff1Sjsg 	const struct gfx_firmware_header_v2_0 *cpv2_hdr = NULL;
7512c4a196eSkettenis 	const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL;
752c349dbc7Sjsg 	const struct dmcub_firmware_header_v1_0 *dmcub_hdr = NULL;
753ad8b1aafSjsg 	const struct mes_firmware_header_v1_0 *mes_hdr = NULL;
7541bb76ff1Sjsg 	const struct sdma_firmware_header_v2_0 *sdma_hdr = NULL;
7551bb76ff1Sjsg 	const struct imu_firmware_header_v1_0 *imu_hdr = NULL;
7561bb76ff1Sjsg 	u8 *ucode_addr;
757fb4d8502Sjsg 
758f005ef32Sjsg 	if (!ucode->fw)
759fb4d8502Sjsg 		return 0;
760fb4d8502Sjsg 
761fb4d8502Sjsg 	ucode->mc_addr = mc_addr;
762fb4d8502Sjsg 	ucode->kaddr = kptr;
763fb4d8502Sjsg 
764fb4d8502Sjsg 	if (ucode->ucode_id == AMDGPU_UCODE_ID_STORAGE)
765fb4d8502Sjsg 		return 0;
766fb4d8502Sjsg 
767fb4d8502Sjsg 	header = (const struct common_firmware_header *)ucode->fw->data;
768fb4d8502Sjsg 	cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
7691bb76ff1Sjsg 	cpv2_hdr = (const struct gfx_firmware_header_v2_0 *)ucode->fw->data;
7702c4a196eSkettenis 	dmcu_hdr = (const struct dmcu_firmware_header_v1_0 *)ucode->fw->data;
771c349dbc7Sjsg 	dmcub_hdr = (const struct dmcub_firmware_header_v1_0 *)ucode->fw->data;
772ad8b1aafSjsg 	mes_hdr = (const struct mes_firmware_header_v1_0 *)ucode->fw->data;
7731bb76ff1Sjsg 	sdma_hdr = (const struct sdma_firmware_header_v2_0 *)ucode->fw->data;
7741bb76ff1Sjsg 	imu_hdr = (const struct imu_firmware_header_v1_0 *)ucode->fw->data;
775fb4d8502Sjsg 
7761bb76ff1Sjsg 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
7771bb76ff1Sjsg 		switch (ucode->ucode_id) {
7781bb76ff1Sjsg 		case AMDGPU_UCODE_ID_SDMA_UCODE_TH0:
7791bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(sdma_hdr->ctx_ucode_size_bytes);
7801bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
7811bb76ff1Sjsg 				le32_to_cpu(sdma_hdr->header.ucode_array_offset_bytes);
7821bb76ff1Sjsg 			break;
7831bb76ff1Sjsg 		case AMDGPU_UCODE_ID_SDMA_UCODE_TH1:
7841bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes);
7851bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
7861bb76ff1Sjsg 				le32_to_cpu(sdma_hdr->ctl_ucode_offset);
7871bb76ff1Sjsg 			break;
7881bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MEC1:
7891bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MEC2:
790fb4d8502Sjsg 			ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
791fb4d8502Sjsg 				le32_to_cpu(cp_hdr->jt_size) * 4;
7921bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
7931bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
7941bb76ff1Sjsg 			break;
7951bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MEC1_JT:
7961bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MEC2_JT:
797fb4d8502Sjsg 			ucode->ucode_size = le32_to_cpu(cp_hdr->jt_size) * 4;
7981bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
799fb4d8502Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes) +
8001bb76ff1Sjsg 				le32_to_cpu(cp_hdr->jt_offset) * 4;
8011bb76ff1Sjsg 			break;
8021bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
8031bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes;
8041bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.save_restore_list_cntl;
8051bb76ff1Sjsg 			break;
8061bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
8071bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes;
8081bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.save_restore_list_gpm;
8091bb76ff1Sjsg 			break;
8101bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
8111bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes;
8121bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.save_restore_list_srm;
8131bb76ff1Sjsg 			break;
8141bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_IRAM:
8151bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.rlc_iram_ucode_size_bytes;
8161bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.rlc_iram_ucode;
8171bb76ff1Sjsg 			break;
8181bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_DRAM:
8191bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes;
8201bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.rlc_dram_ucode;
8211bb76ff1Sjsg 			break;
8221bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_P:
8231bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.rlcp_ucode_size_bytes;
8241bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.rlcp_ucode;
8251bb76ff1Sjsg 			break;
8261bb76ff1Sjsg 		case AMDGPU_UCODE_ID_RLC_V:
8271bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.rlcv_ucode_size_bytes;
8281bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.rlcv_ucode;
8291bb76ff1Sjsg 			break;
8301bb76ff1Sjsg 		case AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS:
8311bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.global_tap_delays_ucode_size_bytes;
8321bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.global_tap_delays_ucode;
8331bb76ff1Sjsg 			break;
8341bb76ff1Sjsg 		case AMDGPU_UCODE_ID_SE0_TAP_DELAYS:
8351bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.se0_tap_delays_ucode_size_bytes;
8361bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.se0_tap_delays_ucode;
8371bb76ff1Sjsg 			break;
8381bb76ff1Sjsg 		case AMDGPU_UCODE_ID_SE1_TAP_DELAYS:
8391bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.se1_tap_delays_ucode_size_bytes;
8401bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.se1_tap_delays_ucode;
8411bb76ff1Sjsg 			break;
8421bb76ff1Sjsg 		case AMDGPU_UCODE_ID_SE2_TAP_DELAYS:
8431bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.se2_tap_delays_ucode_size_bytes;
8441bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.se2_tap_delays_ucode;
8451bb76ff1Sjsg 			break;
8461bb76ff1Sjsg 		case AMDGPU_UCODE_ID_SE3_TAP_DELAYS:
8471bb76ff1Sjsg 			ucode->ucode_size = adev->gfx.rlc.se3_tap_delays_ucode_size_bytes;
8481bb76ff1Sjsg 			ucode_addr = adev->gfx.rlc.se3_tap_delays_ucode;
8491bb76ff1Sjsg 			break;
8501bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MES:
8511bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);
8521bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8531bb76ff1Sjsg 				le32_to_cpu(mes_hdr->mes_ucode_offset_bytes);
8541bb76ff1Sjsg 			break;
8551bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MES_DATA:
8561bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);
8571bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8581bb76ff1Sjsg 				le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes);
8591bb76ff1Sjsg 			break;
8601bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MES1:
8611bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);
8621bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8631bb76ff1Sjsg 				le32_to_cpu(mes_hdr->mes_ucode_offset_bytes);
8641bb76ff1Sjsg 			break;
8651bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_MES1_DATA:
8661bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);
8671bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8681bb76ff1Sjsg 				le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes);
8691bb76ff1Sjsg 			break;
8701bb76ff1Sjsg 		case AMDGPU_UCODE_ID_DMCU_ERAM:
8712c4a196eSkettenis 			ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
8722c4a196eSkettenis 				le32_to_cpu(dmcu_hdr->intv_size_bytes);
8731bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8741bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
8751bb76ff1Sjsg 			break;
8761bb76ff1Sjsg 		case AMDGPU_UCODE_ID_DMCU_INTV:
8772c4a196eSkettenis 			ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes);
8781bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8792c4a196eSkettenis 				le32_to_cpu(header->ucode_array_offset_bytes) +
8801bb76ff1Sjsg 				le32_to_cpu(dmcu_hdr->intv_offset_bytes);
8811bb76ff1Sjsg 			break;
8821bb76ff1Sjsg 		case AMDGPU_UCODE_ID_DMCUB:
883c349dbc7Sjsg 			ucode->ucode_size = le32_to_cpu(dmcub_hdr->inst_const_bytes);
8841bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8851bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
8861bb76ff1Sjsg 			break;
8871bb76ff1Sjsg 		case AMDGPU_UCODE_ID_PPTABLE:
8881bb76ff1Sjsg 			ucode->ucode_size = ucode->fw->size;
8891bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data;
8901bb76ff1Sjsg 			break;
8911bb76ff1Sjsg 		case AMDGPU_UCODE_ID_IMU_I:
8921bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(imu_hdr->imu_iram_ucode_size_bytes);
8931bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8941bb76ff1Sjsg 				le32_to_cpu(imu_hdr->header.ucode_array_offset_bytes);
8951bb76ff1Sjsg 			break;
8961bb76ff1Sjsg 		case AMDGPU_UCODE_ID_IMU_D:
8971bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(imu_hdr->imu_dram_ucode_size_bytes);
8981bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
8991bb76ff1Sjsg 				le32_to_cpu(imu_hdr->header.ucode_array_offset_bytes) +
9001bb76ff1Sjsg 				le32_to_cpu(imu_hdr->imu_iram_ucode_size_bytes);
9011bb76ff1Sjsg 			break;
9021bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_PFP:
9031bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes);
9041bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9051bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
9061bb76ff1Sjsg 			break;
9071bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK:
9081bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9091bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9101bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9111bb76ff1Sjsg 			break;
9121bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK:
9131bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9141bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9151bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9161bb76ff1Sjsg 			break;
9171bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_ME:
9181bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes);
9191bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9201bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
9211bb76ff1Sjsg 			break;
9221bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK:
9231bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9241bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9251bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9261bb76ff1Sjsg 			break;
9271bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK:
9281bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9291bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9301bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9311bb76ff1Sjsg 			break;
9321bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_MEC:
9331bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes);
9341bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9351bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
9361bb76ff1Sjsg 			break;
9371bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK:
9381bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9391bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9401bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9411bb76ff1Sjsg 			break;
9421bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK:
9431bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9441bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9451bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9461bb76ff1Sjsg 			break;
9471bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK:
9481bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9491bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9501bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9511bb76ff1Sjsg 			break;
9521bb76ff1Sjsg 		case AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK:
9531bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
9541bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9551bb76ff1Sjsg 				le32_to_cpu(cpv2_hdr->data_offset_bytes);
9561bb76ff1Sjsg 			break;
9571bb76ff1Sjsg 		default:
9581bb76ff1Sjsg 			ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
9591bb76ff1Sjsg 			ucode_addr = (u8 *)ucode->fw->data +
9601bb76ff1Sjsg 				le32_to_cpu(header->ucode_array_offset_bytes);
9611bb76ff1Sjsg 			break;
962fb4d8502Sjsg 		}
9631bb76ff1Sjsg 	} else {
9641bb76ff1Sjsg 		ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
9651bb76ff1Sjsg 		ucode_addr = (u8 *)ucode->fw->data +
9661bb76ff1Sjsg 			le32_to_cpu(header->ucode_array_offset_bytes);
9671bb76ff1Sjsg 	}
9681bb76ff1Sjsg 
9691bb76ff1Sjsg 	memcpy(ucode->kaddr, ucode_addr, ucode->ucode_size);
970fb4d8502Sjsg 
971fb4d8502Sjsg 	return 0;
972fb4d8502Sjsg }
973fb4d8502Sjsg 
amdgpu_ucode_patch_jt(struct amdgpu_firmware_info * ucode,uint64_t mc_addr,void * kptr)974fb4d8502Sjsg static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode,
975fb4d8502Sjsg 				uint64_t mc_addr, void *kptr)
976fb4d8502Sjsg {
977fb4d8502Sjsg 	const struct gfx_firmware_header_v1_0 *header = NULL;
978fb4d8502Sjsg 	const struct common_firmware_header *comm_hdr = NULL;
979fb4d8502Sjsg 	uint8_t *src_addr = NULL;
980fb4d8502Sjsg 	uint8_t *dst_addr = NULL;
981fb4d8502Sjsg 
982f005ef32Sjsg 	if (!ucode->fw)
983fb4d8502Sjsg 		return 0;
984fb4d8502Sjsg 
985fb4d8502Sjsg 	comm_hdr = (const struct common_firmware_header *)ucode->fw->data;
986fb4d8502Sjsg 	header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
987fb4d8502Sjsg 	dst_addr = ucode->kaddr +
988f005ef32Sjsg 			   ALIGN(le32_to_cpu(comm_hdr->ucode_size_bytes),
989fb4d8502Sjsg 			   PAGE_SIZE);
990fb4d8502Sjsg 	src_addr = (uint8_t *)ucode->fw->data +
991fb4d8502Sjsg 			   le32_to_cpu(comm_hdr->ucode_array_offset_bytes) +
992fb4d8502Sjsg 			   (le32_to_cpu(header->jt_offset) * 4);
993fb4d8502Sjsg 	memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4);
994fb4d8502Sjsg 
995fb4d8502Sjsg 	return 0;
996fb4d8502Sjsg }
997fb4d8502Sjsg 
amdgpu_ucode_create_bo(struct amdgpu_device * adev)998c349dbc7Sjsg int amdgpu_ucode_create_bo(struct amdgpu_device *adev)
999fb4d8502Sjsg {
1000c349dbc7Sjsg 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) {
1001c349dbc7Sjsg 		amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE,
1002fb4d8502Sjsg 			amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
1003fb4d8502Sjsg 			&adev->firmware.fw_buf,
1004fb4d8502Sjsg 			&adev->firmware.fw_buf_mc,
1005fb4d8502Sjsg 			&adev->firmware.fw_buf_ptr);
1006c349dbc7Sjsg 		if (!adev->firmware.fw_buf) {
1007fb4d8502Sjsg 			dev_err(adev->dev, "failed to create kernel buffer for firmware.fw_buf\n");
1008c349dbc7Sjsg 			return -ENOMEM;
1009c349dbc7Sjsg 		} else if (amdgpu_sriov_vf(adev)) {
1010fb4d8502Sjsg 			memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size);
1011c349dbc7Sjsg 		}
1012c349dbc7Sjsg 	}
1013c349dbc7Sjsg 	return 0;
1014c349dbc7Sjsg }
1015fb4d8502Sjsg 
amdgpu_ucode_free_bo(struct amdgpu_device * adev)1016c349dbc7Sjsg void amdgpu_ucode_free_bo(struct amdgpu_device *adev)
1017c349dbc7Sjsg {
1018c349dbc7Sjsg 	amdgpu_bo_free_kernel(&adev->firmware.fw_buf,
1019c349dbc7Sjsg 		&adev->firmware.fw_buf_mc,
1020c349dbc7Sjsg 		&adev->firmware.fw_buf_ptr);
1021c349dbc7Sjsg }
1022c349dbc7Sjsg 
amdgpu_ucode_init_bo(struct amdgpu_device * adev)1023c349dbc7Sjsg int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
1024c349dbc7Sjsg {
1025c349dbc7Sjsg 	uint64_t fw_offset = 0;
1026c349dbc7Sjsg 	int i;
1027c349dbc7Sjsg 	struct amdgpu_firmware_info *ucode = NULL;
1028c349dbc7Sjsg 
1029c349dbc7Sjsg  /* for baremetal, the ucode is allocated in gtt, so don't need to fill the bo when reset/suspend */
1030ad8b1aafSjsg 	if (!amdgpu_sriov_vf(adev) && (amdgpu_in_reset(adev) || adev->in_suspend))
1031c349dbc7Sjsg 		return 0;
1032fb4d8502Sjsg 	/*
1033fb4d8502Sjsg 	 * if SMU loaded firmware, it needn't add SMC, UVD, and VCE
1034fb4d8502Sjsg 	 * ucode info here
1035fb4d8502Sjsg 	 */
1036fb4d8502Sjsg 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
1037fb4d8502Sjsg 		if (amdgpu_sriov_vf(adev))
1038fb4d8502Sjsg 			adev->firmware.max_ucodes = AMDGPU_UCODE_ID_MAXIMUM - 3;
1039fb4d8502Sjsg 		else
1040fb4d8502Sjsg 			adev->firmware.max_ucodes = AMDGPU_UCODE_ID_MAXIMUM - 4;
1041fb4d8502Sjsg 	} else {
1042fb4d8502Sjsg 		adev->firmware.max_ucodes = AMDGPU_UCODE_ID_MAXIMUM;
1043fb4d8502Sjsg 	}
1044fb4d8502Sjsg 
1045fb4d8502Sjsg 	for (i = 0; i < adev->firmware.max_ucodes; i++) {
1046fb4d8502Sjsg 		ucode = &adev->firmware.ucode[i];
1047fb4d8502Sjsg 		if (ucode->fw) {
1048fb4d8502Sjsg 			amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset,
1049fb4d8502Sjsg 						    adev->firmware.fw_buf_ptr + fw_offset);
1050fb4d8502Sjsg 			if (i == AMDGPU_UCODE_ID_CP_MEC1 &&
1051fb4d8502Sjsg 			    adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
1052fb4d8502Sjsg 				const struct gfx_firmware_header_v1_0 *cp_hdr;
1053f005ef32Sjsg 
1054fb4d8502Sjsg 				cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
1055fb4d8502Sjsg 				amdgpu_ucode_patch_jt(ucode,  adev->firmware.fw_buf_mc + fw_offset,
1056fb4d8502Sjsg 						    adev->firmware.fw_buf_ptr + fw_offset);
1057f005ef32Sjsg 				fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE);
1058fb4d8502Sjsg 			}
1059f005ef32Sjsg 			fw_offset += ALIGN(ucode->ucode_size, PAGE_SIZE);
1060fb4d8502Sjsg 		}
1061fb4d8502Sjsg 	}
1062fb4d8502Sjsg 	return 0;
1063fb4d8502Sjsg }
10641bb76ff1Sjsg 
amdgpu_ucode_legacy_naming(struct amdgpu_device * adev,int block_type)1065f005ef32Sjsg static const char *amdgpu_ucode_legacy_naming(struct amdgpu_device *adev, int block_type)
1066f005ef32Sjsg {
1067f005ef32Sjsg 	if (block_type == MP0_HWIP) {
1068f005ef32Sjsg 		switch (adev->ip_versions[MP0_HWIP][0]) {
1069f005ef32Sjsg 		case IP_VERSION(9, 0, 0):
1070f005ef32Sjsg 			switch (adev->asic_type) {
1071f005ef32Sjsg 			case CHIP_VEGA10:
1072f005ef32Sjsg 				return "vega10";
1073f005ef32Sjsg 			case CHIP_VEGA12:
1074f005ef32Sjsg 				return "vega12";
1075f005ef32Sjsg 			default:
1076f005ef32Sjsg 				return NULL;
1077f005ef32Sjsg 			}
1078f005ef32Sjsg 		case IP_VERSION(10, 0, 0):
1079f005ef32Sjsg 		case IP_VERSION(10, 0, 1):
1080f005ef32Sjsg 			if (adev->asic_type == CHIP_RAVEN) {
1081f005ef32Sjsg 				if (adev->apu_flags & AMD_APU_IS_RAVEN2)
1082f005ef32Sjsg 					return "raven2";
1083f005ef32Sjsg 				else if (adev->apu_flags & AMD_APU_IS_PICASSO)
1084f005ef32Sjsg 					return "picasso";
1085f005ef32Sjsg 				return "raven";
1086f005ef32Sjsg 			}
1087f005ef32Sjsg 			break;
1088f005ef32Sjsg 		case IP_VERSION(11, 0, 0):
1089f005ef32Sjsg 			return "navi10";
1090f005ef32Sjsg 		case IP_VERSION(11, 0, 2):
1091f005ef32Sjsg 			return "vega20";
1092f005ef32Sjsg 		case IP_VERSION(11, 0, 3):
1093f005ef32Sjsg 			return "renoir";
1094f005ef32Sjsg 		case IP_VERSION(11, 0, 4):
1095f005ef32Sjsg 			return "arcturus";
1096f005ef32Sjsg 		case IP_VERSION(11, 0, 5):
1097f005ef32Sjsg 			return "navi14";
1098f005ef32Sjsg 		case IP_VERSION(11, 0, 7):
1099f005ef32Sjsg 			return "sienna_cichlid";
1100f005ef32Sjsg 		case IP_VERSION(11, 0, 9):
1101f005ef32Sjsg 			return "navi12";
1102f005ef32Sjsg 		case IP_VERSION(11, 0, 11):
1103f005ef32Sjsg 			return "navy_flounder";
1104f005ef32Sjsg 		case IP_VERSION(11, 0, 12):
1105f005ef32Sjsg 			return "dimgrey_cavefish";
1106f005ef32Sjsg 		case IP_VERSION(11, 0, 13):
1107f005ef32Sjsg 			return "beige_goby";
1108f005ef32Sjsg 		case IP_VERSION(11, 5, 0):
1109f005ef32Sjsg 			return "vangogh";
1110f005ef32Sjsg 		case IP_VERSION(12, 0, 1):
1111f005ef32Sjsg 			return "green_sardine";
1112f005ef32Sjsg 		case IP_VERSION(13, 0, 2):
1113f005ef32Sjsg 			return "aldebaran";
1114f005ef32Sjsg 		case IP_VERSION(13, 0, 1):
1115f005ef32Sjsg 		case IP_VERSION(13, 0, 3):
1116f005ef32Sjsg 			return "yellow_carp";
1117f005ef32Sjsg 		}
1118f005ef32Sjsg 	} else if (block_type == MP1_HWIP) {
1119f005ef32Sjsg 		switch (adev->ip_versions[MP1_HWIP][0]) {
1120f005ef32Sjsg 		case IP_VERSION(9, 0, 0):
1121f005ef32Sjsg 		case IP_VERSION(10, 0, 0):
1122f005ef32Sjsg 		case IP_VERSION(10, 0, 1):
1123f005ef32Sjsg 		case IP_VERSION(11, 0, 2):
1124f005ef32Sjsg 			if (adev->asic_type == CHIP_ARCTURUS)
1125f005ef32Sjsg 				return "arcturus_smc";
1126f005ef32Sjsg 			return NULL;
1127f005ef32Sjsg 		case IP_VERSION(11, 0, 0):
1128f005ef32Sjsg 			return "navi10_smc";
1129f005ef32Sjsg 		case IP_VERSION(11, 0, 5):
1130f005ef32Sjsg 			return "navi14_smc";
1131f005ef32Sjsg 		case IP_VERSION(11, 0, 9):
1132f005ef32Sjsg 			return "navi12_smc";
1133f005ef32Sjsg 		case IP_VERSION(11, 0, 7):
1134f005ef32Sjsg 			return "sienna_cichlid_smc";
1135f005ef32Sjsg 		case IP_VERSION(11, 0, 11):
1136f005ef32Sjsg 			return "navy_flounder_smc";
1137f005ef32Sjsg 		case IP_VERSION(11, 0, 12):
1138f005ef32Sjsg 			return "dimgrey_cavefish_smc";
1139f005ef32Sjsg 		case IP_VERSION(11, 0, 13):
1140f005ef32Sjsg 			return "beige_goby_smc";
1141f005ef32Sjsg 		case IP_VERSION(13, 0, 2):
1142f005ef32Sjsg 			return "aldebaran_smc";
1143f005ef32Sjsg 		}
1144f005ef32Sjsg 	} else if (block_type == SDMA0_HWIP) {
1145f005ef32Sjsg 		switch (adev->ip_versions[SDMA0_HWIP][0]) {
1146f005ef32Sjsg 		case IP_VERSION(4, 0, 0):
1147f005ef32Sjsg 			return "vega10_sdma";
1148f005ef32Sjsg 		case IP_VERSION(4, 0, 1):
1149f005ef32Sjsg 			return "vega12_sdma";
1150f005ef32Sjsg 		case IP_VERSION(4, 1, 0):
1151f005ef32Sjsg 		case IP_VERSION(4, 1, 1):
1152f005ef32Sjsg 			if (adev->apu_flags & AMD_APU_IS_RAVEN2)
1153f005ef32Sjsg 				return "raven2_sdma";
1154f005ef32Sjsg 			else if (adev->apu_flags & AMD_APU_IS_PICASSO)
1155f005ef32Sjsg 				return "picasso_sdma";
1156f005ef32Sjsg 			return "raven_sdma";
1157f005ef32Sjsg 		case IP_VERSION(4, 1, 2):
1158f005ef32Sjsg 			if (adev->apu_flags & AMD_APU_IS_RENOIR)
1159f005ef32Sjsg 				return "renoir_sdma";
1160f005ef32Sjsg 			return "green_sardine_sdma";
1161f005ef32Sjsg 		case IP_VERSION(4, 2, 0):
1162f005ef32Sjsg 			return "vega20_sdma";
1163f005ef32Sjsg 		case IP_VERSION(4, 2, 2):
1164f005ef32Sjsg 			return "arcturus_sdma";
1165f005ef32Sjsg 		case IP_VERSION(4, 4, 0):
1166f005ef32Sjsg 			return "aldebaran_sdma";
1167f005ef32Sjsg 		case IP_VERSION(5, 0, 0):
1168f005ef32Sjsg 			return "navi10_sdma";
1169f005ef32Sjsg 		case IP_VERSION(5, 0, 1):
1170f005ef32Sjsg 			return "cyan_skillfish2_sdma";
1171f005ef32Sjsg 		case IP_VERSION(5, 0, 2):
1172f005ef32Sjsg 			return "navi14_sdma";
1173f005ef32Sjsg 		case IP_VERSION(5, 0, 5):
1174f005ef32Sjsg 			return "navi12_sdma";
1175f005ef32Sjsg 		case IP_VERSION(5, 2, 0):
1176f005ef32Sjsg 			return "sienna_cichlid_sdma";
1177f005ef32Sjsg 		case IP_VERSION(5, 2, 2):
1178f005ef32Sjsg 			return "navy_flounder_sdma";
1179f005ef32Sjsg 		case IP_VERSION(5, 2, 4):
1180f005ef32Sjsg 			return "dimgrey_cavefish_sdma";
1181f005ef32Sjsg 		case IP_VERSION(5, 2, 5):
1182f005ef32Sjsg 			return "beige_goby_sdma";
1183f005ef32Sjsg 		case IP_VERSION(5, 2, 3):
1184f005ef32Sjsg 			return "yellow_carp_sdma";
1185f005ef32Sjsg 		case IP_VERSION(5, 2, 1):
1186f005ef32Sjsg 			return "vangogh_sdma";
1187f005ef32Sjsg 		}
1188f005ef32Sjsg 	} else if (block_type == UVD_HWIP) {
1189f005ef32Sjsg 		switch (adev->ip_versions[UVD_HWIP][0]) {
1190f005ef32Sjsg 		case IP_VERSION(1, 0, 0):
1191f005ef32Sjsg 		case IP_VERSION(1, 0, 1):
1192f005ef32Sjsg 			if (adev->apu_flags & AMD_APU_IS_RAVEN2)
1193f005ef32Sjsg 				return "raven2_vcn";
1194f005ef32Sjsg 			else if (adev->apu_flags & AMD_APU_IS_PICASSO)
1195f005ef32Sjsg 				return "picasso_vcn";
1196f005ef32Sjsg 			return "raven_vcn";
1197f005ef32Sjsg 		case IP_VERSION(2, 5, 0):
1198f005ef32Sjsg 			return "arcturus_vcn";
1199f005ef32Sjsg 		case IP_VERSION(2, 2, 0):
1200f005ef32Sjsg 			if (adev->apu_flags & AMD_APU_IS_RENOIR)
1201f005ef32Sjsg 				return "renoir_vcn";
1202f005ef32Sjsg 			return "green_sardine_vcn";
1203f005ef32Sjsg 		case IP_VERSION(2, 6, 0):
1204f005ef32Sjsg 			return "aldebaran_vcn";
1205f005ef32Sjsg 		case IP_VERSION(2, 0, 0):
1206f005ef32Sjsg 			return "navi10_vcn";
1207f005ef32Sjsg 		case IP_VERSION(2, 0, 2):
1208f005ef32Sjsg 			if (adev->asic_type == CHIP_NAVI12)
1209f005ef32Sjsg 				return "navi12_vcn";
1210f005ef32Sjsg 			return "navi14_vcn";
1211f005ef32Sjsg 		case IP_VERSION(3, 0, 0):
1212f005ef32Sjsg 		case IP_VERSION(3, 0, 64):
1213f005ef32Sjsg 		case IP_VERSION(3, 0, 192):
1214f005ef32Sjsg 			if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0))
1215f005ef32Sjsg 				return "sienna_cichlid_vcn";
1216f005ef32Sjsg 			return "navy_flounder_vcn";
1217f005ef32Sjsg 		case IP_VERSION(3, 0, 2):
1218f005ef32Sjsg 			return "vangogh_vcn";
1219f005ef32Sjsg 		case IP_VERSION(3, 0, 16):
1220f005ef32Sjsg 			return "dimgrey_cavefish_vcn";
1221f005ef32Sjsg 		case IP_VERSION(3, 0, 33):
1222f005ef32Sjsg 			return "beige_goby_vcn";
1223f005ef32Sjsg 		case IP_VERSION(3, 1, 1):
1224f005ef32Sjsg 			return "yellow_carp_vcn";
1225f005ef32Sjsg 		}
1226f005ef32Sjsg 	} else if (block_type == GC_HWIP) {
1227f005ef32Sjsg 		switch (adev->ip_versions[GC_HWIP][0]) {
1228f005ef32Sjsg 		case IP_VERSION(9, 0, 1):
1229f005ef32Sjsg 			return "vega10";
1230f005ef32Sjsg 		case IP_VERSION(9, 2, 1):
1231f005ef32Sjsg 			return "vega12";
1232f005ef32Sjsg 		case IP_VERSION(9, 4, 0):
1233f005ef32Sjsg 			return "vega20";
1234f005ef32Sjsg 		case IP_VERSION(9, 2, 2):
1235f005ef32Sjsg 		case IP_VERSION(9, 1, 0):
1236f005ef32Sjsg 			if (adev->apu_flags & AMD_APU_IS_RAVEN2)
1237f005ef32Sjsg 				return "raven2";
1238f005ef32Sjsg 			else if (adev->apu_flags & AMD_APU_IS_PICASSO)
1239f005ef32Sjsg 				return "picasso";
1240f005ef32Sjsg 			return "raven";
1241f005ef32Sjsg 		case IP_VERSION(9, 4, 1):
1242f005ef32Sjsg 			return "arcturus";
1243f005ef32Sjsg 		case IP_VERSION(9, 3, 0):
1244f005ef32Sjsg 			if (adev->apu_flags & AMD_APU_IS_RENOIR)
1245f005ef32Sjsg 				return "renoir";
1246f005ef32Sjsg 			return "green_sardine";
1247f005ef32Sjsg 		case IP_VERSION(9, 4, 2):
1248f005ef32Sjsg 			return "aldebaran";
1249f005ef32Sjsg 		case IP_VERSION(10, 1, 10):
1250f005ef32Sjsg 			return "navi10";
1251f005ef32Sjsg 		case IP_VERSION(10, 1, 1):
1252f005ef32Sjsg 			return "navi14";
1253f005ef32Sjsg 		case IP_VERSION(10, 1, 2):
1254f005ef32Sjsg 			return "navi12";
1255f005ef32Sjsg 		case IP_VERSION(10, 3, 0):
1256f005ef32Sjsg 			return "sienna_cichlid";
1257f005ef32Sjsg 		case IP_VERSION(10, 3, 2):
1258f005ef32Sjsg 			return "navy_flounder";
1259f005ef32Sjsg 		case IP_VERSION(10, 3, 1):
1260f005ef32Sjsg 			return "vangogh";
1261f005ef32Sjsg 		case IP_VERSION(10, 3, 4):
1262f005ef32Sjsg 			return "dimgrey_cavefish";
1263f005ef32Sjsg 		case IP_VERSION(10, 3, 5):
1264f005ef32Sjsg 			return "beige_goby";
1265f005ef32Sjsg 		case IP_VERSION(10, 3, 3):
1266f005ef32Sjsg 			return "yellow_carp";
1267f005ef32Sjsg 		case IP_VERSION(10, 1, 3):
1268f005ef32Sjsg 		case IP_VERSION(10, 1, 4):
1269f005ef32Sjsg 			return "cyan_skillfish2";
1270f005ef32Sjsg 		}
1271f005ef32Sjsg 	}
1272f005ef32Sjsg 	return NULL;
1273f005ef32Sjsg }
1274f005ef32Sjsg 
amdgpu_ucode_ip_version_decode(struct amdgpu_device * adev,int block_type,char * ucode_prefix,int len)12751bb76ff1Sjsg void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len)
12761bb76ff1Sjsg {
12771bb76ff1Sjsg 	int maj, min, rev;
12781bb76ff1Sjsg 	char *ip_name;
1279f005ef32Sjsg 	const char *legacy;
12801bb76ff1Sjsg 	uint32_t version = adev->ip_versions[block_type][0];
12811bb76ff1Sjsg 
1282f005ef32Sjsg 	legacy = amdgpu_ucode_legacy_naming(adev, block_type);
1283f005ef32Sjsg 	if (legacy) {
1284f005ef32Sjsg 		snprintf(ucode_prefix, len, "%s", legacy);
1285f005ef32Sjsg 		return;
1286f005ef32Sjsg 	}
1287f005ef32Sjsg 
12881bb76ff1Sjsg 	switch (block_type) {
12891bb76ff1Sjsg 	case GC_HWIP:
12901bb76ff1Sjsg 		ip_name = "gc";
12911bb76ff1Sjsg 		break;
12921bb76ff1Sjsg 	case SDMA0_HWIP:
12931bb76ff1Sjsg 		ip_name = "sdma";
12941bb76ff1Sjsg 		break;
12951bb76ff1Sjsg 	case MP0_HWIP:
12961bb76ff1Sjsg 		ip_name = "psp";
12971bb76ff1Sjsg 		break;
12981bb76ff1Sjsg 	case MP1_HWIP:
12991bb76ff1Sjsg 		ip_name = "smu";
13001bb76ff1Sjsg 		break;
13011bb76ff1Sjsg 	case UVD_HWIP:
13021bb76ff1Sjsg 		ip_name = "vcn";
13031bb76ff1Sjsg 		break;
13041bb76ff1Sjsg 	default:
13051bb76ff1Sjsg 		BUG();
13061bb76ff1Sjsg 	}
13071bb76ff1Sjsg 
13081bb76ff1Sjsg 	maj = IP_VERSION_MAJ(version);
13091bb76ff1Sjsg 	min = IP_VERSION_MIN(version);
13101bb76ff1Sjsg 	rev = IP_VERSION_REV(version);
13111bb76ff1Sjsg 
13121bb76ff1Sjsg 	snprintf(ucode_prefix, len, "%s_%d_%d_%d", ip_name, maj, min, rev);
13131bb76ff1Sjsg }
131436022db4Sjsg 
131536022db4Sjsg /*
131636022db4Sjsg  * amdgpu_ucode_request - Fetch and validate amdgpu microcode
131736022db4Sjsg  *
131836022db4Sjsg  * @adev: amdgpu device
131936022db4Sjsg  * @fw: pointer to load firmware to
132036022db4Sjsg  * @fw_name: firmware to load
132136022db4Sjsg  *
132236022db4Sjsg  * This is a helper that will use request_firmware and amdgpu_ucode_validate
132336022db4Sjsg  * to load and run basic validation on firmware. If the load fails, remap
132436022db4Sjsg  * the error code to -ENODEV, so that early_init functions will fail to load.
132536022db4Sjsg  */
amdgpu_ucode_request(struct amdgpu_device * adev,const struct firmware ** fw,const char * fw_name)132636022db4Sjsg int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw,
132736022db4Sjsg 			 const char *fw_name)
132836022db4Sjsg {
132936022db4Sjsg 	int err = request_firmware(fw, fw_name, adev->dev);
133036022db4Sjsg 
133136022db4Sjsg 	if (err)
133236022db4Sjsg 		return -ENODEV;
1333*9fce72ccSjsg 
133436022db4Sjsg 	err = amdgpu_ucode_validate(*fw);
1335*9fce72ccSjsg 	if (err) {
133636022db4Sjsg 		dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name);
1337*9fce72ccSjsg 		release_firmware(*fw);
1338*9fce72ccSjsg 		*fw = NULL;
1339*9fce72ccSjsg 	}
134036022db4Sjsg 
134136022db4Sjsg 	return err;
134236022db4Sjsg }
134336022db4Sjsg 
134436022db4Sjsg /*
134536022db4Sjsg  * amdgpu_ucode_release - Release firmware microcode
134636022db4Sjsg  *
134736022db4Sjsg  * @fw: pointer to firmware to release
134836022db4Sjsg  */
amdgpu_ucode_release(const struct firmware ** fw)134936022db4Sjsg void amdgpu_ucode_release(const struct firmware **fw)
135036022db4Sjsg {
135136022db4Sjsg 	release_firmware(*fw);
135236022db4Sjsg 	*fw = NULL;
135336022db4Sjsg }
1354