@@ -182,6 +182,7 @@ nvkm_falcon_v1_read_dmem(struct nvkm_falcon *falcon, u32 start, u32 size,
182
182
static void
183
183
nvkm_falcon_v1_bind_context (struct nvkm_falcon * falcon , struct nvkm_memory * ctx )
184
184
{
185
+ struct nvkm_device * device = falcon -> owner -> device ;
185
186
u32 inst_loc ;
186
187
u32 fbif ;
187
188
@@ -233,6 +234,41 @@ nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_memory *ctx)
233
234
234
235
nvkm_falcon_mask (falcon , 0x090 , 0x10000 , 0x10000 );
235
236
nvkm_falcon_mask (falcon , 0x0a4 , 0x8 , 0x8 );
237
+
238
+ /* Not sure if this is a WAR for a HW issue, or some additional
239
+ * programming sequence that's needed to properly complete the
240
+ * context switch we trigger above.
241
+ *
242
+ * Fixes unreliability of booting the SEC2 RTOS on Quadro P620,
243
+ * particularly when resuming from suspend.
244
+ *
245
+ * Also removes the need for an odd workaround where we needed
246
+ * to program SEC2's FALCON_CPUCTL_ALIAS_STARTCPU twice before
247
+ * the SEC2 RTOS would begin executing.
248
+ */
249
+ switch (falcon -> owner -> index ) {
250
+ case NVKM_SUBDEV_GSP :
251
+ case NVKM_ENGINE_SEC2 :
252
+ nvkm_msec (device , 10 ,
253
+ u32 irqstat = nvkm_falcon_rd32 (falcon , 0x008 );
254
+ u32 flcn0dc = nvkm_falcon_rd32 (falcon , 0x0dc );
255
+ if ((irqstat & 0x00000008 ) &&
256
+ (flcn0dc & 0x00007000 ) == 0x00005000 )
257
+ break ;
258
+ );
259
+
260
+ nvkm_falcon_mask (falcon , 0x004 , 0x00000008 , 0x00000008 );
261
+ nvkm_falcon_mask (falcon , 0x058 , 0x00000002 , 0x00000002 );
262
+
263
+ nvkm_msec (device , 10 ,
264
+ u32 flcn0dc = nvkm_falcon_rd32 (falcon , 0x0dc );
265
+ if ((flcn0dc & 0x00007000 ) == 0x00000000 )
266
+ break ;
267
+ );
268
+ break ;
269
+ default :
270
+ break ;
271
+ }
236
272
}
237
273
238
274
static void
0 commit comments