summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index e42e23d..6f0103b 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -18233,6 +18233,13 @@ static void svc_push_raw_dump(const u8 *buf, u32 len, u64 push_va,
static u64 svc_notify2d_done;
static u32 svc_notify2d_log;
+/*
+ * r1608 A/B: the X DDX's IMMD class-2d NOTIFY ack (the nvFermiSync
+ * completion). Enabled by default; set 0 to reproduce the pre-r1608
+ * dropped-NOTIFY behaviour (the Xorg mode-set WAIT) without a rebuild.
+ */
+static bool gsp_sema_2d_notify_immd = true;
+module_param_named(sema_2d_notify_immd, gsp_sema_2d_notify_immd, bool, 0644);
static bool svc_notify2d_write(struct nv_vgpu_device *vgpu,
struct svc_channel *ch, bool completion)
@@ -18509,6 +18516,29 @@ static void svc_twod_method(struct nv_vgpu_device *vgpu,
case 0x2ac:
tw->operation = v;
break;
+ /*
+ * r1608: the X DDX's nvFermiSync (nvFermiXAASync) queues the
+ * class-2d completion as IMMD_DATA methods: SET_NOTIFY_A/B name
+ * the NvNotification VA and NOTIFY (0x10c, payload 0 =
+ * WRITE_ONLY) must author the zeroed 16-byte notification. The
+ * watchdog path below has handled the run-shaped form since r828;
+ * the IMMD form previously fell into the default case and was
+ * dropped, so the X server's post-selection 2D sync spun in
+ * "NVIDIA(GPU-0): WAIT (0, 8, 0x8000, ...)" forever (the status
+ * word stayed IN_PROGRESS 0x8000). The mode-set never completed,
+ * glsStartServer/glsDeviceHandle never ran, and the GL client's
+ * physical-device init (class/gpuGartSize/+0x18e0) stayed empty.
+ */
+ case SVC_2D_SET_NOTIFY_A:
+ ch->notify2d_va = (u64)(v & 0x1ffffff) << 32;
+ break;
+ case SVC_2D_SET_NOTIFY_B:
+ ch->notify2d_va |= (u64)v;
+ break;
+ case SVC_2D_NOTIFY:
+ if (v == 0 && gsp_sema_2d_notify_immd)
+ svc_notify2d_write(vgpu, ch, true);
+ break;
case 0x2a0:
tw->rop = v;
break;
@@ -18622,7 +18652,13 @@ static void svc_notify2d_keepalive(struct nv_vgpu_device *vgpu,
u16 st;
memcpy(&st, slots + slot * 16 + 14, 2);
- if (st != 0xffff)
+ /*
+ * r1608: the 2D completion notifier is armed with
+ * NV9097_NOTIFICATION_STATUS_IN_PROGRESS (0x8000) while the
+ * GPU works on it (the X DDX's nvFermiSync waits for it to
+ * become 0); the older watchdog slots use 0xffff. Ack both.
+ */
+ if (st != 0xffff && !(st & 0x8000))
continue; /* not armed - nothing to ack */
if (svc_write_ap(vgpu, ch->notifier_pa + slot * 16,
ch->notifier_as, zero, sizeof(zero)))