1 /* $NetBSD: nouveau_nvkm_subdev_acr_tu102.c,v 1.2 2021/12/18 23:45:38 riastradh Exp $ */ 2 3 /* 4 * Copyright 2019 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 #include <sys/cdefs.h> 25 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_acr_tu102.c,v 1.2 2021/12/18 23:45:38 riastradh Exp $"); 26 27 #include "priv.h" 28 29 #include <core/firmware.h> 30 #include <core/memory.h> 31 #include <subdev/gsp.h> 32 #include <subdev/pmu.h> 33 #include <engine/sec2.h> 34 35 #include <nvfw/acr.h> 36 37 static int 38 tu102_acr_init(struct nvkm_acr *acr) 39 { 40 int ret = nvkm_acr_hsf_boot(acr, "AHESASC"); 41 if (ret) 42 return ret; 43 44 return nvkm_acr_hsf_boot(acr, "ASB"); 45 } 46 47 static int 48 tu102_acr_wpr_build(struct nvkm_acr *acr, struct nvkm_acr_lsf *rtos) 49 { 50 struct nvkm_acr_lsfw *lsfw; 51 u32 offset = 0; 52 int ret; 53 54 /*XXX: shared sub-WPR headers, fill terminator for now. */ 55 nvkm_wo32(acr->wpr, 0x200, 0xffffffff); 56 57 /* Fill per-LSF structures. */ 58 list_for_each_entry(lsfw, &acr->lsfw, head) { 59 struct lsf_signature_v1 *sig = (void *)lsfw->sig->data; 60 struct wpr_header_v1 hdr = { 61 .falcon_id = lsfw->id, 62 .lsb_offset = lsfw->offset.lsb, 63 .bootstrap_owner = NVKM_ACR_LSF_GSPLITE, 64 .lazy_bootstrap = 1, 65 .bin_version = sig->version, 66 .status = WPR_HEADER_V1_STATUS_COPY, 67 }; 68 69 /* Write WPR header. */ 70 nvkm_wobj(acr->wpr, offset, &hdr, sizeof(hdr)); 71 offset += sizeof(hdr); 72 73 /* Write LSB header. */ 74 ret = gp102_acr_wpr_build_lsb(acr, lsfw); 75 if (ret) 76 return ret; 77 78 /* Write ucode image. */ 79 nvkm_wobj(acr->wpr, lsfw->offset.img, 80 lsfw->img.data, 81 lsfw->img.size); 82 83 /* Write bootloader data. */ 84 lsfw->func->bld_write(acr, lsfw->offset.bld, lsfw); 85 } 86 87 /* Finalise WPR. */ 88 nvkm_wo32(acr->wpr, offset, WPR_HEADER_V1_FALCON_ID_INVALID); 89 return 0; 90 } 91 92 static int 93 tu102_acr_hsfw_boot(struct nvkm_acr *acr, struct nvkm_acr_hsf *hsf) 94 { 95 return gm200_acr_hsfw_boot(acr, hsf, 0, 0); 96 } 97 98 static int 99 tu102_acr_hsfw_nofw(struct nvkm_acr *acr, const char *bl, const char *fw, 100 const char *name, int version, 101 const struct nvkm_acr_hsf_fwif *fwif) 102 { 103 return 0; 104 } 105 106 MODULE_FIRMWARE("nvidia/tu102/acr/unload_bl.bin"); 107 MODULE_FIRMWARE("nvidia/tu102/acr/ucode_unload.bin"); 108 109 MODULE_FIRMWARE("nvidia/tu104/acr/unload_bl.bin"); 110 MODULE_FIRMWARE("nvidia/tu104/acr/ucode_unload.bin"); 111 112 MODULE_FIRMWARE("nvidia/tu106/acr/unload_bl.bin"); 113 MODULE_FIRMWARE("nvidia/tu106/acr/ucode_unload.bin"); 114 115 MODULE_FIRMWARE("nvidia/tu116/acr/unload_bl.bin"); 116 MODULE_FIRMWARE("nvidia/tu116/acr/ucode_unload.bin"); 117 118 MODULE_FIRMWARE("nvidia/tu117/acr/unload_bl.bin"); 119 MODULE_FIRMWARE("nvidia/tu117/acr/ucode_unload.bin"); 120 121 static const struct nvkm_acr_hsf_fwif 122 tu102_acr_unload_fwif[] = { 123 { 0, nvkm_acr_hsfw_load, &gp108_acr_unload_0 }, 124 { -1, tu102_acr_hsfw_nofw }, 125 {} 126 }; 127 128 static int 129 tu102_acr_asb_load(struct nvkm_acr *acr, struct nvkm_acr_hsfw *hsfw) 130 { 131 return gm200_acr_hsfw_load(acr, hsfw, &acr->subdev.device->gsp->falcon); 132 } 133 134 static const struct nvkm_acr_hsf_func 135 tu102_acr_asb_0 = { 136 .load = tu102_acr_asb_load, 137 .boot = tu102_acr_hsfw_boot, 138 .bld = gp108_acr_hsfw_bld, 139 }; 140 141 MODULE_FIRMWARE("nvidia/tu102/acr/ucode_asb.bin"); 142 MODULE_FIRMWARE("nvidia/tu104/acr/ucode_asb.bin"); 143 MODULE_FIRMWARE("nvidia/tu106/acr/ucode_asb.bin"); 144 MODULE_FIRMWARE("nvidia/tu116/acr/ucode_asb.bin"); 145 MODULE_FIRMWARE("nvidia/tu117/acr/ucode_asb.bin"); 146 147 static const struct nvkm_acr_hsf_fwif 148 tu102_acr_asb_fwif[] = { 149 { 0, nvkm_acr_hsfw_load, &tu102_acr_asb_0 }, 150 { -1, tu102_acr_hsfw_nofw }, 151 {} 152 }; 153 154 static const struct nvkm_acr_hsf_func 155 tu102_acr_ahesasc_0 = { 156 .load = gp102_acr_load_load, 157 .boot = tu102_acr_hsfw_boot, 158 .bld = gp108_acr_hsfw_bld, 159 }; 160 161 MODULE_FIRMWARE("nvidia/tu102/acr/bl.bin"); 162 MODULE_FIRMWARE("nvidia/tu102/acr/ucode_ahesasc.bin"); 163 164 MODULE_FIRMWARE("nvidia/tu104/acr/bl.bin"); 165 MODULE_FIRMWARE("nvidia/tu104/acr/ucode_ahesasc.bin"); 166 167 MODULE_FIRMWARE("nvidia/tu106/acr/bl.bin"); 168 MODULE_FIRMWARE("nvidia/tu106/acr/ucode_ahesasc.bin"); 169 170 MODULE_FIRMWARE("nvidia/tu116/acr/bl.bin"); 171 MODULE_FIRMWARE("nvidia/tu116/acr/ucode_ahesasc.bin"); 172 173 MODULE_FIRMWARE("nvidia/tu117/acr/bl.bin"); 174 MODULE_FIRMWARE("nvidia/tu117/acr/ucode_ahesasc.bin"); 175 176 static const struct nvkm_acr_hsf_fwif 177 tu102_acr_ahesasc_fwif[] = { 178 { 0, nvkm_acr_hsfw_load, &tu102_acr_ahesasc_0 }, 179 { -1, tu102_acr_hsfw_nofw }, 180 {} 181 }; 182 183 static const struct nvkm_acr_func 184 tu102_acr = { 185 .ahesasc = tu102_acr_ahesasc_fwif, 186 .asb = tu102_acr_asb_fwif, 187 .unload = tu102_acr_unload_fwif, 188 .wpr_parse = gp102_acr_wpr_parse, 189 .wpr_layout = gp102_acr_wpr_layout, 190 .wpr_alloc = gp102_acr_wpr_alloc, 191 .wpr_patch = gp102_acr_wpr_patch, 192 .wpr_build = tu102_acr_wpr_build, 193 .wpr_check = gm200_acr_wpr_check, 194 .init = tu102_acr_init, 195 }; 196 197 static int 198 tu102_acr_load(struct nvkm_acr *acr, int version, 199 const struct nvkm_acr_fwif *fwif) 200 { 201 struct nvkm_subdev *subdev = &acr->subdev; 202 const struct nvkm_acr_hsf_fwif *hsfwif; 203 204 hsfwif = nvkm_firmware_load(subdev, fwif->func->ahesasc, "AcrAHESASC", 205 acr, "acr/bl", "acr/ucode_ahesasc", 206 "AHESASC"); 207 if (IS_ERR(hsfwif)) 208 return PTR_ERR(hsfwif); 209 210 hsfwif = nvkm_firmware_load(subdev, fwif->func->asb, "AcrASB", 211 acr, "acr/bl", "acr/ucode_asb", "ASB"); 212 if (IS_ERR(hsfwif)) 213 return PTR_ERR(hsfwif); 214 215 hsfwif = nvkm_firmware_load(subdev, fwif->func->unload, "AcrUnload", 216 acr, "acr/unload_bl", "acr/ucode_unload", 217 "unload"); 218 if (IS_ERR(hsfwif)) 219 return PTR_ERR(hsfwif); 220 221 return 0; 222 } 223 224 static const struct nvkm_acr_fwif 225 tu102_acr_fwif[] = { 226 { 0, tu102_acr_load, &tu102_acr }, 227 {} 228 }; 229 230 int 231 tu102_acr_new(struct nvkm_device *device, int index, struct nvkm_acr **pacr) 232 { 233 return nvkm_acr_new_(tu102_acr_fwif, device, index, pacr); 234 } 235