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

Merge branch 'linux-5.2' of git://github.com/skeggsb/linux into drm-fixes

" This is a bit more than I'd like to be pushing at this point in a
cycle, but it's a fairly important issue. There's been numerous
reports of more recent GP10[2467] boards failing to load, and I've
worked with NVIDIA FW engineers and tracked this down to the FW we've
been using not properly supporting the boards in question.

I've pushed an update to linux-firmware with the new FW version, which
unfortunately contains API changes vs the older firmware.

This series teaches the ACR subsystem inside nouveau enough to be able
to deal with supporting multiple incompatible FW revisions, and adds
support to the relevant chipsets for loading the newer FW revision, if
it's available."

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv7pG+vur0Kn_TyU3ainnkvJVw07upnnaQNOToF+kzQtDQ@mail.gmail.com

+244 -100
+7 -7
drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #ifndef __NVKM_FIRMWARE_H__ 3 3 #define __NVKM_FIRMWARE_H__ 4 + #include <core/subdev.h> 4 5 5 - #include <core/device.h> 6 - 7 - int nvkm_firmware_get(struct nvkm_device *device, const char *fwname, 8 - const struct firmware **fw); 9 - 10 - void nvkm_firmware_put(const struct firmware *fw); 11 - 6 + int nvkm_firmware_get_version(const struct nvkm_subdev *, const char *fwname, 7 + int min_version, int max_version, 8 + const struct firmware **); 9 + int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, 10 + const struct firmware **); 11 + void nvkm_firmware_put(const struct firmware *); 12 12 #endif
+28 -5
drivers/gpu/drm/nouveau/nvkm/core/firmware.c
··· 24 24 25 25 /** 26 26 * nvkm_firmware_get - load firmware from the official nvidia/chip/ directory 27 - * @device device that will use that firmware 27 + * @subdev subdevice that will use that firmware 28 28 * @fwname name of firmware file to load 29 29 * @fw firmware structure to load to 30 30 * ··· 32 32 * Firmware files released by NVIDIA will always follow this format. 33 33 */ 34 34 int 35 - nvkm_firmware_get(struct nvkm_device *device, const char *fwname, 36 - const struct firmware **fw) 35 + nvkm_firmware_get_version(const struct nvkm_subdev *subdev, const char *fwname, 36 + int min_version, int max_version, 37 + const struct firmware **fw) 37 38 { 39 + struct nvkm_device *device = subdev->device; 38 40 char f[64]; 39 41 char cname[16]; 40 42 int i; ··· 50 48 cname[i] = tolower(cname[i]); 51 49 } 52 50 53 - snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname); 54 - return request_firmware(fw, f, device->dev); 51 + for (i = max_version; i >= min_version; i--) { 52 + if (i != 0) 53 + snprintf(f, sizeof(f), "nvidia/%s/%s-%d.bin", cname, fwname, i); 54 + else 55 + snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname); 56 + 57 + if (!firmware_request_nowarn(fw, f, device->dev)) { 58 + nvkm_debug(subdev, "firmware \"%s\" loaded\n", f); 59 + return i; 60 + } 61 + 62 + nvkm_debug(subdev, "firmware \"%s\" unavailable\n", f); 63 + } 64 + 65 + nvkm_error(subdev, "failed to load firmware \"%s\"", fwname); 66 + return -ENOENT; 67 + } 68 + 69 + int 70 + nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname, 71 + const struct firmware **fw) 72 + { 73 + return nvkm_firmware_get_version(subdev, fwname, 0, 0, fw); 55 74 } 56 75 57 76 /**
+1 -3
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
··· 2115 2115 gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname, 2116 2116 struct gf100_gr_fuc *fuc) 2117 2117 { 2118 - struct nvkm_subdev *subdev = &gr->base.engine.subdev; 2119 - struct nvkm_device *device = subdev->device; 2120 2118 const struct firmware *fw; 2121 2119 int ret; 2122 2120 2123 - ret = nvkm_firmware_get(device, fwname, &fw); 2121 + ret = nvkm_firmware_get(&gr->base.engine.subdev, fwname, &fw); 2124 2122 if (ret) { 2125 2123 ret = gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret); 2126 2124 if (ret)
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.c
··· 36 36 void *blob; 37 37 int ret; 38 38 39 - ret = nvkm_firmware_get(subdev->device, name, &fw); 39 + ret = nvkm_firmware_get(subdev, name, &fw); 40 40 if (ret) 41 41 return ERR_PTR(ret); 42 42 if (fw->size < min_size) {
+42 -16
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
··· 229 229 struct ls_ucode_img_r352 { 230 230 struct ls_ucode_img base; 231 231 232 + const struct acr_r352_lsf_func *func; 233 + 232 234 struct acr_r352_lsf_wpr_header wpr_header; 233 235 struct acr_r352_lsf_lsb_header lsb_header; 234 236 }; ··· 245 243 enum nvkm_secboot_falcon falcon_id) 246 244 { 247 245 const struct nvkm_subdev *subdev = acr->base.subdev; 246 + const struct acr_r352_ls_func *func = acr->func->ls_func[falcon_id]; 248 247 struct ls_ucode_img_r352 *img; 249 248 int ret; 250 249 ··· 255 252 256 253 img->base.falcon_id = falcon_id; 257 254 258 - ret = acr->func->ls_func[falcon_id]->load(sb, &img->base); 259 - 260 - if (ret) { 255 + ret = func->load(sb, func->version_max, &img->base); 256 + if (ret < 0) { 261 257 kfree(img->base.ucode_data); 262 258 kfree(img->base.sig); 263 259 kfree(img); 264 260 return ERR_PTR(ret); 265 261 } 262 + 263 + img->func = func->version[ret]; 266 264 267 265 /* Check that the signature size matches our expectations... */ 268 266 if (img->base.sig_size != sizeof(img->lsb_header.signature)) { ··· 306 302 struct acr_r352_lsf_wpr_header *whdr = &img->wpr_header; 307 303 struct acr_r352_lsf_lsb_header *lhdr = &img->lsb_header; 308 304 struct ls_ucode_img_desc *desc = &_img->ucode_desc; 309 - const struct acr_r352_ls_func *func = 310 - acr->func->ls_func[_img->falcon_id]; 305 + const struct acr_r352_lsf_func *func = img->func; 311 306 312 307 /* Fill WPR header */ 313 308 whdr->falcon_id = _img->falcon_id; ··· 422 419 423 420 /* Figure out how large we need gdesc to be. */ 424 421 list_for_each_entry(_img, imgs, node) { 425 - const struct acr_r352_ls_func *ls_func = 426 - acr->func->ls_func[_img->falcon_id]; 422 + struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); 423 + const struct acr_r352_lsf_func *ls_func = img->func; 427 424 428 425 max_desc_size = max(max_desc_size, ls_func->bl_desc_size); 429 426 } ··· 436 433 437 434 list_for_each_entry(_img, imgs, node) { 438 435 struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); 439 - const struct acr_r352_ls_func *ls_func = 440 - acr->func->ls_func[_img->falcon_id]; 436 + const struct acr_r352_lsf_func *ls_func = img->func; 441 437 442 438 nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, 443 439 sizeof(img->wpr_header)); ··· 1065 1063 kfree(acr); 1066 1064 } 1067 1065 1068 - const struct acr_r352_ls_func 1069 - acr_r352_ls_fecs_func = { 1070 - .load = acr_ls_ucode_load_fecs, 1066 + static const struct acr_r352_lsf_func 1067 + acr_r352_ls_fecs_func_0 = { 1071 1068 .generate_bl_desc = acr_r352_generate_flcn_bl_desc, 1072 1069 .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc), 1073 1070 }; 1074 1071 1075 1072 const struct acr_r352_ls_func 1076 - acr_r352_ls_gpccs_func = { 1077 - .load = acr_ls_ucode_load_gpccs, 1073 + acr_r352_ls_fecs_func = { 1074 + .load = acr_ls_ucode_load_fecs, 1075 + .version_max = 0, 1076 + .version = { 1077 + &acr_r352_ls_fecs_func_0, 1078 + } 1079 + }; 1080 + 1081 + static const struct acr_r352_lsf_func 1082 + acr_r352_ls_gpccs_func_0 = { 1078 1083 .generate_bl_desc = acr_r352_generate_flcn_bl_desc, 1079 1084 .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc), 1080 1085 /* GPCCS will be loaded using PRI */ 1081 1086 .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, 1087 + }; 1088 + 1089 + const struct acr_r352_ls_func 1090 + acr_r352_ls_gpccs_func = { 1091 + .load = acr_ls_ucode_load_gpccs, 1092 + .version_max = 0, 1093 + .version = { 1094 + &acr_r352_ls_gpccs_func_0, 1095 + } 1082 1096 }; 1083 1097 1084 1098 ··· 1168 1150 desc->argv = addr_args; 1169 1151 } 1170 1152 1153 + static const struct acr_r352_lsf_func 1154 + acr_r352_ls_pmu_func_0 = { 1155 + .generate_bl_desc = acr_r352_generate_pmu_bl_desc, 1156 + .bl_desc_size = sizeof(struct acr_r352_pmu_bl_desc), 1157 + }; 1158 + 1171 1159 static const struct acr_r352_ls_func 1172 1160 acr_r352_ls_pmu_func = { 1173 1161 .load = acr_ls_ucode_load_pmu, 1174 - .generate_bl_desc = acr_r352_generate_pmu_bl_desc, 1175 - .bl_desc_size = sizeof(struct acr_r352_pmu_bl_desc), 1176 1162 .post_run = acr_ls_pmu_post_run, 1163 + .version_max = 0, 1164 + .version = { 1165 + &acr_r352_ls_pmu_func_0, 1166 + } 1177 1167 }; 1178 1168 1179 1169 const struct acr_r352_func
+16 -6
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
··· 47 47 } 48 48 49 49 /** 50 - * struct acr_r352_ls_func - manages a single LS firmware 50 + * struct acr_r352_lsf_func - manages a specific LS firmware version 51 51 * 52 - * @load: load the external firmware into a ls_ucode_img 53 52 * @generate_bl_desc: function called on a block of bl_desc_size to generate the 54 53 * proper bootloader descriptor for this LS firmware 55 54 * @bl_desc_size: size of the bootloader descriptor 56 - * @post_run: hook called right after the ACR is executed 57 55 * @lhdr_flags: LS flags 58 56 */ 59 - struct acr_r352_ls_func { 60 - int (*load)(const struct nvkm_secboot *, struct ls_ucode_img *); 57 + struct acr_r352_lsf_func { 61 58 void (*generate_bl_desc)(const struct nvkm_acr *, 62 59 const struct ls_ucode_img *, u64, void *); 63 60 u32 bl_desc_size; 64 - int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *); 65 61 u32 lhdr_flags; 62 + }; 63 + 64 + /** 65 + * struct acr_r352_ls_func - manages a single LS falcon 66 + * 67 + * @load: load the external firmware into a ls_ucode_img 68 + * @post_run: hook called right after the ACR is executed 69 + */ 70 + struct acr_r352_ls_func { 71 + int (*load)(const struct nvkm_secboot *, int maxver, 72 + struct ls_ucode_img *); 73 + int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *); 74 + int version_max; 75 + const struct acr_r352_lsf_func *version[]; 66 76 }; 67 77 68 78 struct acr_r352;
+42 -10
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c
··· 66 66 bl_desc->data_size = hdr->data_size; 67 67 } 68 68 69 - const struct acr_r352_ls_func 70 - acr_r361_ls_fecs_func = { 71 - .load = acr_ls_ucode_load_fecs, 69 + static const struct acr_r352_lsf_func 70 + acr_r361_ls_fecs_func_0 = { 72 71 .generate_bl_desc = acr_r361_generate_flcn_bl_desc, 73 72 .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc), 74 73 }; 75 74 76 75 const struct acr_r352_ls_func 77 - acr_r361_ls_gpccs_func = { 78 - .load = acr_ls_ucode_load_gpccs, 76 + acr_r361_ls_fecs_func = { 77 + .load = acr_ls_ucode_load_fecs, 78 + .version_max = 0, 79 + .version = { 80 + &acr_r361_ls_fecs_func_0, 81 + } 82 + }; 83 + 84 + static const struct acr_r352_lsf_func 85 + acr_r361_ls_gpccs_func_0 = { 79 86 .generate_bl_desc = acr_r361_generate_flcn_bl_desc, 80 87 .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc), 81 88 /* GPCCS will be loaded using PRI */ 82 89 .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, 90 + }; 91 + 92 + const struct acr_r352_ls_func 93 + acr_r361_ls_gpccs_func = { 94 + .load = acr_ls_ucode_load_gpccs, 95 + .version_max = 0, 96 + .version = { 97 + &acr_r361_ls_gpccs_func_0, 98 + } 83 99 }; 84 100 85 101 struct acr_r361_pmu_bl_desc { ··· 141 125 desc->argv = addr_args; 142 126 } 143 127 128 + static const struct acr_r352_lsf_func 129 + acr_r361_ls_pmu_func_0 = { 130 + .generate_bl_desc = acr_r361_generate_pmu_bl_desc, 131 + .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc), 132 + }; 133 + 144 134 const struct acr_r352_ls_func 145 135 acr_r361_ls_pmu_func = { 146 136 .load = acr_ls_ucode_load_pmu, 147 - .generate_bl_desc = acr_r361_generate_pmu_bl_desc, 148 - .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc), 149 137 .post_run = acr_ls_pmu_post_run, 138 + .version_max = 0, 139 + .version = { 140 + &acr_r361_ls_pmu_func_0, 141 + } 150 142 }; 151 143 152 144 static void ··· 188 164 desc->argv = 0x01000000; 189 165 } 190 166 191 - const struct acr_r352_ls_func 192 - acr_r361_ls_sec2_func = { 193 - .load = acr_ls_ucode_load_sec2, 167 + const struct acr_r352_lsf_func 168 + acr_r361_ls_sec2_func_0 = { 194 169 .generate_bl_desc = acr_r361_generate_sec2_bl_desc, 195 170 .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc), 171 + }; 172 + 173 + static const struct acr_r352_ls_func 174 + acr_r361_ls_sec2_func = { 175 + .load = acr_ls_ucode_load_sec2, 196 176 .post_run = acr_ls_sec2_post_run, 177 + .version_max = 0, 178 + .version = { 179 + &acr_r361_ls_sec2_func_0, 180 + } 197 181 }; 198 182 199 183
+1 -2
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.h
··· 67 67 extern const struct acr_r352_ls_func acr_r361_ls_fecs_func; 68 68 extern const struct acr_r352_ls_func acr_r361_ls_gpccs_func; 69 69 extern const struct acr_r352_ls_func acr_r361_ls_pmu_func; 70 - extern const struct acr_r352_ls_func acr_r361_ls_sec2_func; 71 - 70 + extern const struct acr_r352_lsf_func acr_r361_ls_sec2_func_0; 72 71 #endif
+24 -9
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c
··· 22 22 23 23 #include "acr_r367.h" 24 24 #include "acr_r361.h" 25 + #include "acr_r370.h" 25 26 26 27 #include <core/gpuobj.h> 27 28 ··· 101 100 struct ls_ucode_img_r367 { 102 101 struct ls_ucode_img base; 103 102 103 + const struct acr_r352_lsf_func *func; 104 + 104 105 struct acr_r367_lsf_wpr_header wpr_header; 105 106 struct acr_r367_lsf_lsb_header lsb_header; 106 107 }; ··· 114 111 enum nvkm_secboot_falcon falcon_id) 115 112 { 116 113 const struct nvkm_subdev *subdev = acr->base.subdev; 114 + const struct acr_r352_ls_func *func = acr->func->ls_func[falcon_id]; 117 115 struct ls_ucode_img_r367 *img; 118 116 int ret; 119 117 ··· 124 120 125 121 img->base.falcon_id = falcon_id; 126 122 127 - ret = acr->func->ls_func[falcon_id]->load(sb, &img->base); 128 - if (ret) { 123 + ret = func->load(sb, func->version_max, &img->base); 124 + if (ret < 0) { 129 125 kfree(img->base.ucode_data); 130 126 kfree(img->base.sig); 131 127 kfree(img); 132 128 return ERR_PTR(ret); 133 129 } 130 + 131 + img->func = func->version[ret]; 134 132 135 133 /* Check that the signature size matches our expectations... */ 136 134 if (img->base.sig_size != sizeof(img->lsb_header.signature)) { ··· 164 158 struct acr_r367_lsf_wpr_header *whdr = &img->wpr_header; 165 159 struct acr_r367_lsf_lsb_header *lhdr = &img->lsb_header; 166 160 struct ls_ucode_img_desc *desc = &_img->ucode_desc; 167 - const struct acr_r352_ls_func *func = 168 - acr->func->ls_func[_img->falcon_id]; 161 + const struct acr_r352_lsf_func *func = img->func; 169 162 170 163 /* Fill WPR header */ 171 164 whdr->falcon_id = _img->falcon_id; ··· 274 269 u8 *gdesc; 275 270 276 271 list_for_each_entry(_img, imgs, node) { 277 - const struct acr_r352_ls_func *ls_func = 278 - acr->func->ls_func[_img->falcon_id]; 272 + struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img); 273 + const struct acr_r352_lsf_func *ls_func = img->func; 279 274 280 275 max_desc_size = max(max_desc_size, ls_func->bl_desc_size); 281 276 } ··· 288 283 289 284 list_for_each_entry(_img, imgs, node) { 290 285 struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img); 291 - const struct acr_r352_ls_func *ls_func = 292 - acr->func->ls_func[_img->falcon_id]; 286 + const struct acr_r352_lsf_func *ls_func = img->func; 293 287 294 288 nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, 295 289 sizeof(img->wpr_header)); ··· 382 378 } 383 379 } 384 380 381 + static const struct acr_r352_ls_func 382 + acr_r367_ls_sec2_func = { 383 + .load = acr_ls_ucode_load_sec2, 384 + .post_run = acr_ls_sec2_post_run, 385 + .version_max = 1, 386 + .version = { 387 + &acr_r361_ls_sec2_func_0, 388 + &acr_r370_ls_sec2_func_0, 389 + } 390 + }; 391 + 385 392 const struct acr_r352_func 386 393 acr_r367_func = { 387 394 .fixup_hs_desc = acr_r367_fixup_hs_desc, ··· 406 391 [NVKM_SECBOOT_FALCON_FECS] = &acr_r361_ls_fecs_func, 407 392 [NVKM_SECBOOT_FALCON_GPCCS] = &acr_r361_ls_gpccs_func, 408 393 [NVKM_SECBOOT_FALCON_PMU] = &acr_r361_ls_pmu_func, 409 - [NVKM_SECBOOT_FALCON_SEC2] = &acr_r361_ls_sec2_func, 394 + [NVKM_SECBOOT_FALCON_SEC2] = &acr_r367_ls_sec2_func, 410 395 }, 411 396 }; 412 397
+31 -7
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.c
··· 49 49 desc->data_size = pdesc->app_resident_data_size; 50 50 } 51 51 52 - const struct acr_r352_ls_func 53 - acr_r370_ls_fecs_func = { 54 - .load = acr_ls_ucode_load_fecs, 52 + static const struct acr_r352_lsf_func 53 + acr_r370_ls_fecs_func_0 = { 55 54 .generate_bl_desc = acr_r370_generate_flcn_bl_desc, 56 55 .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 57 56 }; 58 57 59 58 const struct acr_r352_ls_func 60 - acr_r370_ls_gpccs_func = { 61 - .load = acr_ls_ucode_load_gpccs, 59 + acr_r370_ls_fecs_func = { 60 + .load = acr_ls_ucode_load_fecs, 61 + .version_max = 0, 62 + .version = { 63 + &acr_r370_ls_fecs_func_0, 64 + } 65 + }; 66 + 67 + static const struct acr_r352_lsf_func 68 + acr_r370_ls_gpccs_func_0 = { 62 69 .generate_bl_desc = acr_r370_generate_flcn_bl_desc, 63 70 .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 64 71 /* GPCCS will be loaded using PRI */ 65 72 .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, 73 + }; 74 + 75 + const struct acr_r352_ls_func 76 + acr_r370_ls_gpccs_func = { 77 + .load = acr_ls_ucode_load_gpccs, 78 + .version_max = 0, 79 + .version = { 80 + &acr_r370_ls_gpccs_func_0, 81 + } 66 82 }; 67 83 68 84 static void ··· 111 95 desc->argv = 0x01000000; 112 96 } 113 97 98 + const struct acr_r352_lsf_func 99 + acr_r370_ls_sec2_func_0 = { 100 + .generate_bl_desc = acr_r370_generate_sec2_bl_desc, 101 + .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 102 + }; 103 + 114 104 const struct acr_r352_ls_func 115 105 acr_r370_ls_sec2_func = { 116 106 .load = acr_ls_ucode_load_sec2, 117 - .generate_bl_desc = acr_r370_generate_sec2_bl_desc, 118 - .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 119 107 .post_run = acr_ls_sec2_post_run, 108 + .version_max = 0, 109 + .version = { 110 + &acr_r370_ls_sec2_func_0, 111 + } 120 112 }; 121 113 122 114 void
+1
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.h
··· 46 46 void acr_r370_generate_hs_bl_desc(const struct hsf_load_header *, void *, u64); 47 47 extern const struct acr_r352_ls_func acr_r370_ls_fecs_func; 48 48 extern const struct acr_r352_ls_func acr_r370_ls_gpccs_func; 49 + extern const struct acr_r352_lsf_func acr_r370_ls_sec2_func_0; 49 50 #endif
+10 -2
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c
··· 54 54 desc->argv = addr_args; 55 55 } 56 56 57 + static const struct acr_r352_lsf_func 58 + acr_r375_ls_pmu_func_0 = { 59 + .generate_bl_desc = acr_r375_generate_pmu_bl_desc, 60 + .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 61 + }; 62 + 57 63 const struct acr_r352_ls_func 58 64 acr_r375_ls_pmu_func = { 59 65 .load = acr_ls_ucode_load_pmu, 60 - .generate_bl_desc = acr_r375_generate_pmu_bl_desc, 61 - .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 62 66 .post_run = acr_ls_pmu_post_run, 67 + .version_max = 0, 68 + .version = { 69 + &acr_r375_ls_pmu_func_0, 70 + } 63 71 }; 64 72 65 73 const struct acr_r352_func
+8 -4
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h
··· 147 147 u32 data_size; 148 148 }; 149 149 150 - int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, struct ls_ucode_img *); 151 - int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, struct ls_ucode_img *); 152 - int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, struct ls_ucode_img *); 150 + int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, int, 151 + struct ls_ucode_img *); 152 + int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, int, 153 + struct ls_ucode_img *); 154 + int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, int, 155 + struct ls_ucode_img *); 153 156 int acr_ls_pmu_post_run(const struct nvkm_acr *, const struct nvkm_secboot *); 154 - int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, struct ls_ucode_img *); 157 + int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, int, 158 + struct ls_ucode_img *); 155 159 int acr_ls_sec2_post_run(const struct nvkm_acr *, const struct nvkm_secboot *); 156 160 157 161 #endif
+12 -10
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
··· 90 90 * blob. Also generate the corresponding ucode descriptor. 91 91 */ 92 92 static int 93 - ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img, 94 - const char *falcon_name) 93 + ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, int maxver, 94 + struct ls_ucode_img *img, const char *falcon_name) 95 95 { 96 96 const struct firmware *bl, *code, *data, *sig; 97 97 char f[64]; 98 98 int ret; 99 99 100 100 snprintf(f, sizeof(f), "gr/%s_bl", falcon_name); 101 - ret = nvkm_firmware_get(subdev->device, f, &bl); 101 + ret = nvkm_firmware_get(subdev, f, &bl); 102 102 if (ret) 103 103 goto error; 104 104 105 105 snprintf(f, sizeof(f), "gr/%s_inst", falcon_name); 106 - ret = nvkm_firmware_get(subdev->device, f, &code); 106 + ret = nvkm_firmware_get(subdev, f, &code); 107 107 if (ret) 108 108 goto free_bl; 109 109 110 110 snprintf(f, sizeof(f), "gr/%s_data", falcon_name); 111 - ret = nvkm_firmware_get(subdev->device, f, &data); 111 + ret = nvkm_firmware_get(subdev, f, &data); 112 112 if (ret) 113 113 goto free_inst; 114 114 115 115 snprintf(f, sizeof(f), "gr/%s_sig", falcon_name); 116 - ret = nvkm_firmware_get(subdev->device, f, &sig); 116 + ret = nvkm_firmware_get(subdev, f, &sig); 117 117 if (ret) 118 118 goto free_data; 119 119 ··· 146 146 } 147 147 148 148 int 149 - acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 149 + acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, int maxver, 150 + struct ls_ucode_img *img) 150 151 { 151 - return ls_ucode_img_load_gr(&sb->subdev, img, "fecs"); 152 + return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "fecs"); 152 153 } 153 154 154 155 int 155 - acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 156 + acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, int maxver, 157 + struct ls_ucode_img *img) 156 158 { 157 - return ls_ucode_img_load_gr(&sb->subdev, img, "gpccs"); 159 + return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "gpccs"); 158 160 }
+20 -18
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
··· 39 39 */ 40 40 static int 41 41 acr_ls_ucode_load_msgqueue(const struct nvkm_subdev *subdev, const char *name, 42 - struct ls_ucode_img *img) 42 + int maxver, struct ls_ucode_img *img) 43 43 { 44 44 const struct firmware *image, *desc, *sig; 45 45 char f[64]; 46 - int ret; 46 + int ver, ret; 47 47 48 48 snprintf(f, sizeof(f), "%s/image", name); 49 - ret = nvkm_firmware_get(subdev->device, f, &image); 50 - if (ret) 51 - return ret; 49 + ver = nvkm_firmware_get_version(subdev, f, 0, maxver, &image); 50 + if (ver < 0) 51 + return ver; 52 52 img->ucode_data = kmemdup(image->data, image->size, GFP_KERNEL); 53 53 nvkm_firmware_put(image); 54 54 if (!img->ucode_data) 55 55 return -ENOMEM; 56 56 57 57 snprintf(f, sizeof(f), "%s/desc", name); 58 - ret = nvkm_firmware_get(subdev->device, f, &desc); 59 - if (ret) 58 + ret = nvkm_firmware_get_version(subdev, f, ver, ver, &desc); 59 + if (ret < 0) 60 60 return ret; 61 61 memcpy(&img->ucode_desc, desc->data, sizeof(img->ucode_desc)); 62 62 img->ucode_size = ALIGN(img->ucode_desc.app_start_offset + img->ucode_desc.app_size, 256); 63 63 nvkm_firmware_put(desc); 64 64 65 65 snprintf(f, sizeof(f), "%s/sig", name); 66 - ret = nvkm_firmware_get(subdev->device, f, &sig); 67 - if (ret) 66 + ret = nvkm_firmware_get_version(subdev, f, ver, ver, &sig); 67 + if (ret < 0) 68 68 return ret; 69 69 img->sig_size = sig->size; 70 70 img->sig = kmemdup(sig->data, sig->size, GFP_KERNEL); ··· 72 72 if (!img->sig) 73 73 return -ENOMEM; 74 74 75 - return 0; 75 + return ver; 76 76 } 77 77 78 78 static int ··· 99 99 } 100 100 101 101 int 102 - acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 102 + acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, int maxver, 103 + struct ls_ucode_img *img) 103 104 { 104 105 struct nvkm_pmu *pmu = sb->subdev.device->pmu; 105 106 int ret; 106 107 107 - ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", img); 108 + ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", maxver, img); 108 109 if (ret) 109 110 return ret; 110 111 ··· 137 136 } 138 137 139 138 int 140 - acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 139 + acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, int maxver, 140 + struct ls_ucode_img *img) 141 141 { 142 142 struct nvkm_sec2 *sec = sb->subdev.device->sec2; 143 - int ret; 143 + int ver, ret; 144 144 145 - ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", img); 146 - if (ret) 147 - return ret; 145 + ver = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", maxver, img); 146 + if (ver < 0) 147 + return ver; 148 148 149 149 /* Allocate the PMU queue corresponding to the FW version */ 150 150 ret = nvkm_msgqueue_new(img->ucode_desc.app_version, sec->falcon, ··· 153 151 if (ret) 154 152 return ret; 155 153 156 - return 0; 154 + return ver; 157 155 } 158 156 159 157 int