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
tu102_acr_init(struct nvkm_acr * acr)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
tu102_acr_wpr_build(struct nvkm_acr * acr,struct nvkm_acr_lsf * rtos)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
tu102_acr_hsfw_boot(struct nvkm_acr * acr,struct nvkm_acr_hsf * hsf)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
tu102_acr_hsfw_nofw(struct nvkm_acr * acr,const char * bl,const char * fw,const char * name,int version,const struct nvkm_acr_hsf_fwif * fwif)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
tu102_acr_asb_load(struct nvkm_acr * acr,struct nvkm_acr_hsfw * hsfw)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
tu102_acr_load(struct nvkm_acr * acr,int version,const struct nvkm_acr_fwif * fwif)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
tu102_acr_new(struct nvkm_device * device,int index,struct nvkm_acr ** pacr)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