Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: add new firmware header definitions (v3)

These are needed to properly handle more frequently
updated firmware.

v2: add new firmware helper functions as well.
v3: update to latest format

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+239 -1
+1 -1
drivers/gpu/drm/radeon/Makefile
··· 80 80 r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ 81 81 rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ 82 82 trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ 83 - ci_dpm.o dce6_afmt.o radeon_vm.o 83 + ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o 84 84 85 85 # add async DMA block 86 86 radeon-y += \
+167
drivers/gpu/drm/radeon/radeon_ucode.c
··· 1 + /* 2 + * Copyright 2014 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + */ 23 + 24 + #include <linux/firmware.h> 25 + #include <linux/slab.h> 26 + #include <linux/module.h> 27 + #include <drm/drmP.h> 28 + #include "radeon.h" 29 + #include "radeon_ucode.h" 30 + 31 + static void radeon_ucode_print_common_hdr(const struct common_firmware_header *hdr) 32 + { 33 + DRM_DEBUG("size_bytes: %u\n", le32_to_cpu(hdr->size_bytes)); 34 + DRM_DEBUG("header_size_bytes: %u\n", le32_to_cpu(hdr->header_size_bytes)); 35 + DRM_DEBUG("header_version_major: %u\n", le16_to_cpu(hdr->header_version_major)); 36 + DRM_DEBUG("header_version_minor: %u\n", le16_to_cpu(hdr->header_version_minor)); 37 + DRM_DEBUG("ip_version_major: %u\n", le16_to_cpu(hdr->ip_version_major)); 38 + DRM_DEBUG("ip_version_minor: %u\n", le16_to_cpu(hdr->ip_version_minor)); 39 + DRM_DEBUG("ucode_version: 0x%08x\n", le32_to_cpu(hdr->ucode_version)); 40 + DRM_DEBUG("ucode_size_bytes: %u\n", le32_to_cpu(hdr->ucode_size_bytes)); 41 + DRM_DEBUG("ucode_array_offset_bytes: %u\n", 42 + le32_to_cpu(hdr->ucode_array_offset_bytes)); 43 + DRM_DEBUG("crc32: 0x%08x\n", le32_to_cpu(hdr->crc32)); 44 + } 45 + 46 + void radeon_ucode_print_mc_hdr(const struct common_firmware_header *hdr) 47 + { 48 + uint16_t version_major = le16_to_cpu(hdr->header_version_major); 49 + uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); 50 + 51 + DRM_DEBUG("MC\n"); 52 + radeon_ucode_print_common_hdr(hdr); 53 + 54 + if (version_major == 1) { 55 + const struct mc_firmware_header_v1_0 *mc_hdr = 56 + container_of(hdr, struct mc_firmware_header_v1_0, header); 57 + 58 + DRM_DEBUG("io_debug_size_bytes: %u\n", 59 + le32_to_cpu(mc_hdr->io_debug_size_bytes)); 60 + DRM_DEBUG("io_debug_array_offset_bytes: %u\n", 61 + le32_to_cpu(mc_hdr->io_debug_array_offset_bytes)); 62 + } else { 63 + DRM_ERROR("Unknown MC ucode version: %u.%u\n", version_major, version_minor); 64 + } 65 + } 66 + 67 + void radeon_ucode_print_smc_hdr(const struct common_firmware_header *hdr) 68 + { 69 + uint16_t version_major = le16_to_cpu(hdr->header_version_major); 70 + uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); 71 + 72 + DRM_DEBUG("SMC\n"); 73 + radeon_ucode_print_common_hdr(hdr); 74 + 75 + if (version_major == 1) { 76 + const struct smc_firmware_header_v1_0 *smc_hdr = 77 + container_of(hdr, struct smc_firmware_header_v1_0, header); 78 + 79 + DRM_DEBUG("ucode_start_addr: %u\n", le32_to_cpu(smc_hdr->ucode_start_addr)); 80 + } else { 81 + DRM_ERROR("Unknown SMC ucode version: %u.%u\n", version_major, version_minor); 82 + } 83 + } 84 + 85 + void radeon_ucode_print_gfx_hdr(const struct common_firmware_header *hdr) 86 + { 87 + uint16_t version_major = le16_to_cpu(hdr->header_version_major); 88 + uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); 89 + 90 + DRM_DEBUG("GFX\n"); 91 + radeon_ucode_print_common_hdr(hdr); 92 + 93 + if (version_major == 1) { 94 + const struct gfx_firmware_header_v1_0 *gfx_hdr = 95 + container_of(hdr, struct gfx_firmware_header_v1_0, header); 96 + 97 + DRM_DEBUG("ucode_feature_version: %u\n", 98 + le32_to_cpu(gfx_hdr->ucode_feature_version)); 99 + DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(gfx_hdr->jt_offset)); 100 + DRM_DEBUG("jt_size: %u\n", le32_to_cpu(gfx_hdr->jt_size)); 101 + } else { 102 + DRM_ERROR("Unknown GFX ucode version: %u.%u\n", version_major, version_minor); 103 + } 104 + } 105 + 106 + void radeon_ucode_print_rlc_hdr(const struct common_firmware_header *hdr) 107 + { 108 + uint16_t version_major = le16_to_cpu(hdr->header_version_major); 109 + uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); 110 + 111 + DRM_DEBUG("RLC\n"); 112 + radeon_ucode_print_common_hdr(hdr); 113 + 114 + if (version_major == 1) { 115 + const struct rlc_firmware_header_v1_0 *rlc_hdr = 116 + container_of(hdr, struct rlc_firmware_header_v1_0, header); 117 + 118 + DRM_DEBUG("ucode_feature_version: %u\n", 119 + le32_to_cpu(rlc_hdr->ucode_feature_version)); 120 + DRM_DEBUG("save_and_restore_offset: %u\n", 121 + le32_to_cpu(rlc_hdr->save_and_restore_offset)); 122 + DRM_DEBUG("clear_state_descriptor_offset: %u\n", 123 + le32_to_cpu(rlc_hdr->clear_state_descriptor_offset)); 124 + DRM_DEBUG("avail_scratch_ram_locations: %u\n", 125 + le32_to_cpu(rlc_hdr->avail_scratch_ram_locations)); 126 + DRM_DEBUG("master_pkt_description_offset: %u\n", 127 + le32_to_cpu(rlc_hdr->master_pkt_description_offset)); 128 + } else { 129 + DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor); 130 + } 131 + } 132 + 133 + void radeon_ucode_print_sdma_hdr(const struct common_firmware_header *hdr) 134 + { 135 + uint16_t version_major = le16_to_cpu(hdr->header_version_major); 136 + uint16_t version_minor = le16_to_cpu(hdr->header_version_minor); 137 + 138 + DRM_DEBUG("SDMA\n"); 139 + radeon_ucode_print_common_hdr(hdr); 140 + 141 + if (version_major == 1) { 142 + const struct sdma_firmware_header_v1_0 *sdma_hdr = 143 + container_of(hdr, struct sdma_firmware_header_v1_0, header); 144 + 145 + DRM_DEBUG("ucode_feature_version: %u\n", 146 + le32_to_cpu(sdma_hdr->ucode_feature_version)); 147 + DRM_DEBUG("ucode_change_version: %u\n", 148 + le32_to_cpu(sdma_hdr->ucode_change_version)); 149 + DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(sdma_hdr->jt_offset)); 150 + DRM_DEBUG("jt_size: %u\n", le32_to_cpu(sdma_hdr->jt_size)); 151 + } else { 152 + DRM_ERROR("Unknown SDMA ucode version: %u.%u\n", 153 + version_major, version_minor); 154 + } 155 + } 156 + 157 + int radeon_ucode_validate(const struct firmware *fw) 158 + { 159 + const struct common_firmware_header *hdr = 160 + (const struct common_firmware_header *)fw->data; 161 + 162 + if (fw->size == le32_to_cpu(hdr->size_bytes)) 163 + return 0; 164 + 165 + return -EINVAL; 166 + } 167 +
+71
drivers/gpu/drm/radeon/radeon_ucode.h
··· 153 153 #define HAWAII_SMC_UCODE_START 0x20000 154 154 #define HAWAII_SMC_UCODE_SIZE 0x1FDEC 155 155 156 + struct common_firmware_header { 157 + uint32_t size_bytes; /* size of the entire header+image(s) in bytes */ 158 + uint32_t header_size_bytes; /* size of just the header in bytes */ 159 + uint16_t header_version_major; /* header version */ 160 + uint16_t header_version_minor; /* header version */ 161 + uint16_t ip_version_major; /* IP version */ 162 + uint16_t ip_version_minor; /* IP version */ 163 + uint32_t ucode_version; 164 + uint32_t ucode_size_bytes; /* size of ucode in bytes */ 165 + uint32_t ucode_array_offset_bytes; /* payload offset from the start of the header */ 166 + uint32_t crc32; /* crc32 checksum of the payload */ 167 + }; 168 + 169 + /* version_major=1, version_minor=0 */ 170 + struct mc_firmware_header_v1_0 { 171 + struct common_firmware_header header; 172 + uint32_t io_debug_size_bytes; /* size of debug array in dwords */ 173 + uint32_t io_debug_array_offset_bytes; /* payload offset from the start of the header */ 174 + }; 175 + 176 + /* version_major=1, version_minor=0 */ 177 + struct smc_firmware_header_v1_0 { 178 + struct common_firmware_header header; 179 + uint32_t ucode_start_addr; 180 + }; 181 + 182 + /* version_major=1, version_minor=0 */ 183 + struct gfx_firmware_header_v1_0 { 184 + struct common_firmware_header header; 185 + uint32_t ucode_feature_version; 186 + uint32_t jt_offset; /* jt location */ 187 + uint32_t jt_size; /* size of jt */ 188 + }; 189 + 190 + /* version_major=1, version_minor=0 */ 191 + struct rlc_firmware_header_v1_0 { 192 + struct common_firmware_header header; 193 + uint32_t ucode_feature_version; 194 + uint32_t save_and_restore_offset; 195 + uint32_t clear_state_descriptor_offset; 196 + uint32_t avail_scratch_ram_locations; 197 + uint32_t master_pkt_description_offset; 198 + }; 199 + 200 + /* version_major=1, version_minor=0 */ 201 + struct sdma_firmware_header_v1_0 { 202 + struct common_firmware_header header; 203 + uint32_t ucode_feature_version; 204 + uint32_t ucode_change_version; 205 + uint32_t jt_offset; /* jt location */ 206 + uint32_t jt_size; /* size of jt */ 207 + }; 208 + 209 + /* header is fixed size */ 210 + union radeon_firmware_header { 211 + struct common_firmware_header common; 212 + struct mc_firmware_header_v1_0 mc; 213 + struct smc_firmware_header_v1_0 smc; 214 + struct gfx_firmware_header_v1_0 gfx; 215 + struct rlc_firmware_header_v1_0 rlc; 216 + struct sdma_firmware_header_v1_0 sdma; 217 + uint8_t raw[0x100]; 218 + }; 219 + 220 + void radeon_ucode_print_mc_hdr(const struct common_firmware_header *hdr); 221 + void radeon_ucode_print_smc_hdr(const struct common_firmware_header *hdr); 222 + void radeon_ucode_print_gfx_hdr(const struct common_firmware_header *hdr); 223 + void radeon_ucode_print_rlc_hdr(const struct common_firmware_header *hdr); 224 + void radeon_ucode_print_sdma_hdr(const struct common_firmware_header *hdr); 225 + int radeon_ucode_validate(const struct firmware *fw); 226 + 156 227 #endif