xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/radeon/radeon_ucode.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2014 Advanced Micro Devices, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun  * all copies or substantial portions of the Software.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*4882a593Smuzhiyun  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun  * OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #include <linux/firmware.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/module.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include "radeon.h"
29*4882a593Smuzhiyun #include "radeon_ucode.h"
30*4882a593Smuzhiyun 
radeon_ucode_print_common_hdr(const struct common_firmware_header * hdr)31*4882a593Smuzhiyun static void radeon_ucode_print_common_hdr(const struct common_firmware_header *hdr)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	DRM_DEBUG("size_bytes: %u\n", le32_to_cpu(hdr->size_bytes));
34*4882a593Smuzhiyun 	DRM_DEBUG("header_size_bytes: %u\n", le32_to_cpu(hdr->header_size_bytes));
35*4882a593Smuzhiyun 	DRM_DEBUG("header_version_major: %u\n", le16_to_cpu(hdr->header_version_major));
36*4882a593Smuzhiyun 	DRM_DEBUG("header_version_minor: %u\n", le16_to_cpu(hdr->header_version_minor));
37*4882a593Smuzhiyun 	DRM_DEBUG("ip_version_major: %u\n", le16_to_cpu(hdr->ip_version_major));
38*4882a593Smuzhiyun 	DRM_DEBUG("ip_version_minor: %u\n", le16_to_cpu(hdr->ip_version_minor));
39*4882a593Smuzhiyun 	DRM_DEBUG("ucode_version: 0x%08x\n", le32_to_cpu(hdr->ucode_version));
40*4882a593Smuzhiyun 	DRM_DEBUG("ucode_size_bytes: %u\n", le32_to_cpu(hdr->ucode_size_bytes));
41*4882a593Smuzhiyun 	DRM_DEBUG("ucode_array_offset_bytes: %u\n",
42*4882a593Smuzhiyun 		  le32_to_cpu(hdr->ucode_array_offset_bytes));
43*4882a593Smuzhiyun 	DRM_DEBUG("crc32: 0x%08x\n", le32_to_cpu(hdr->crc32));
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun 
radeon_ucode_print_mc_hdr(const struct common_firmware_header * hdr)46*4882a593Smuzhiyun void radeon_ucode_print_mc_hdr(const struct common_firmware_header *hdr)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
49*4882a593Smuzhiyun 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	DRM_DEBUG("MC\n");
52*4882a593Smuzhiyun 	radeon_ucode_print_common_hdr(hdr);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	if (version_major == 1) {
55*4882a593Smuzhiyun 		const struct mc_firmware_header_v1_0 *mc_hdr =
56*4882a593Smuzhiyun 			container_of(hdr, struct mc_firmware_header_v1_0, header);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 		DRM_DEBUG("io_debug_size_bytes: %u\n",
59*4882a593Smuzhiyun 			  le32_to_cpu(mc_hdr->io_debug_size_bytes));
60*4882a593Smuzhiyun 		DRM_DEBUG("io_debug_array_offset_bytes: %u\n",
61*4882a593Smuzhiyun 			  le32_to_cpu(mc_hdr->io_debug_array_offset_bytes));
62*4882a593Smuzhiyun 	} else {
63*4882a593Smuzhiyun 		DRM_ERROR("Unknown MC ucode version: %u.%u\n", version_major, version_minor);
64*4882a593Smuzhiyun 	}
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
radeon_ucode_print_smc_hdr(const struct common_firmware_header * hdr)67*4882a593Smuzhiyun void radeon_ucode_print_smc_hdr(const struct common_firmware_header *hdr)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
70*4882a593Smuzhiyun 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	DRM_DEBUG("SMC\n");
73*4882a593Smuzhiyun 	radeon_ucode_print_common_hdr(hdr);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	if (version_major == 1) {
76*4882a593Smuzhiyun 		const struct smc_firmware_header_v1_0 *smc_hdr =
77*4882a593Smuzhiyun 			container_of(hdr, struct smc_firmware_header_v1_0, header);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 		DRM_DEBUG("ucode_start_addr: %u\n", le32_to_cpu(smc_hdr->ucode_start_addr));
80*4882a593Smuzhiyun 	} else {
81*4882a593Smuzhiyun 		DRM_ERROR("Unknown SMC ucode version: %u.%u\n", version_major, version_minor);
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
radeon_ucode_print_gfx_hdr(const struct common_firmware_header * hdr)85*4882a593Smuzhiyun void radeon_ucode_print_gfx_hdr(const struct common_firmware_header *hdr)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
88*4882a593Smuzhiyun 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	DRM_DEBUG("GFX\n");
91*4882a593Smuzhiyun 	radeon_ucode_print_common_hdr(hdr);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	if (version_major == 1) {
94*4882a593Smuzhiyun 		const struct gfx_firmware_header_v1_0 *gfx_hdr =
95*4882a593Smuzhiyun 			container_of(hdr, struct gfx_firmware_header_v1_0, header);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 		DRM_DEBUG("ucode_feature_version: %u\n",
98*4882a593Smuzhiyun 			  le32_to_cpu(gfx_hdr->ucode_feature_version));
99*4882a593Smuzhiyun 		DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(gfx_hdr->jt_offset));
100*4882a593Smuzhiyun 		DRM_DEBUG("jt_size: %u\n", le32_to_cpu(gfx_hdr->jt_size));
101*4882a593Smuzhiyun 	} else {
102*4882a593Smuzhiyun 		DRM_ERROR("Unknown GFX ucode version: %u.%u\n", version_major, version_minor);
103*4882a593Smuzhiyun 	}
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
radeon_ucode_print_rlc_hdr(const struct common_firmware_header * hdr)106*4882a593Smuzhiyun void radeon_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
109*4882a593Smuzhiyun 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	DRM_DEBUG("RLC\n");
112*4882a593Smuzhiyun 	radeon_ucode_print_common_hdr(hdr);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	if (version_major == 1) {
115*4882a593Smuzhiyun 		const struct rlc_firmware_header_v1_0 *rlc_hdr =
116*4882a593Smuzhiyun 			container_of(hdr, struct rlc_firmware_header_v1_0, header);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 		DRM_DEBUG("ucode_feature_version: %u\n",
119*4882a593Smuzhiyun 			  le32_to_cpu(rlc_hdr->ucode_feature_version));
120*4882a593Smuzhiyun 		DRM_DEBUG("save_and_restore_offset: %u\n",
121*4882a593Smuzhiyun 			  le32_to_cpu(rlc_hdr->save_and_restore_offset));
122*4882a593Smuzhiyun 		DRM_DEBUG("clear_state_descriptor_offset: %u\n",
123*4882a593Smuzhiyun 			  le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
124*4882a593Smuzhiyun 		DRM_DEBUG("avail_scratch_ram_locations: %u\n",
125*4882a593Smuzhiyun 			  le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
126*4882a593Smuzhiyun 		DRM_DEBUG("master_pkt_description_offset: %u\n",
127*4882a593Smuzhiyun 			  le32_to_cpu(rlc_hdr->master_pkt_description_offset));
128*4882a593Smuzhiyun 	} else {
129*4882a593Smuzhiyun 		DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor);
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
radeon_ucode_print_sdma_hdr(const struct common_firmware_header * hdr)133*4882a593Smuzhiyun void radeon_ucode_print_sdma_hdr(const struct common_firmware_header *hdr)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	uint16_t version_major = le16_to_cpu(hdr->header_version_major);
136*4882a593Smuzhiyun 	uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	DRM_DEBUG("SDMA\n");
139*4882a593Smuzhiyun 	radeon_ucode_print_common_hdr(hdr);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	if (version_major == 1) {
142*4882a593Smuzhiyun 		const struct sdma_firmware_header_v1_0 *sdma_hdr =
143*4882a593Smuzhiyun 			container_of(hdr, struct sdma_firmware_header_v1_0, header);
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 		DRM_DEBUG("ucode_feature_version: %u\n",
146*4882a593Smuzhiyun 			  le32_to_cpu(sdma_hdr->ucode_feature_version));
147*4882a593Smuzhiyun 		DRM_DEBUG("ucode_change_version: %u\n",
148*4882a593Smuzhiyun 			  le32_to_cpu(sdma_hdr->ucode_change_version));
149*4882a593Smuzhiyun 		DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(sdma_hdr->jt_offset));
150*4882a593Smuzhiyun 		DRM_DEBUG("jt_size: %u\n", le32_to_cpu(sdma_hdr->jt_size));
151*4882a593Smuzhiyun 	} else {
152*4882a593Smuzhiyun 		DRM_ERROR("Unknown SDMA ucode version: %u.%u\n",
153*4882a593Smuzhiyun 			  version_major, version_minor);
154*4882a593Smuzhiyun 	}
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
radeon_ucode_validate(const struct firmware * fw)157*4882a593Smuzhiyun int radeon_ucode_validate(const struct firmware *fw)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	const struct common_firmware_header *hdr =
160*4882a593Smuzhiyun 		(const struct common_firmware_header *)fw->data;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	if (fw->size == le32_to_cpu(hdr->size_bytes))
163*4882a593Smuzhiyun 		return 0;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	return -EINVAL;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
168