When we're cold, vblank interrupts don't happen, so we would wait
forever. I added a short-circuit for this case, but apparently some
output connector detection code in inteldrm(4) relies on a delay here
to reliably detect whether something is connected or not.
I tried fixing this in our Linux compat code, but I didn't come up
with a working solution. So this adds an #ifdef __OpenBSD__ block in
the drm_wait_one_vblank() implementations that we hopefully won't miss
when updating the drm code in the future.
Thanks to Philippe Meunier for figuring out the root cause of the
problem. And sorry for the delay...
ok?
Index: dev/pci/drm/drm_irq.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_irq.c,v
retrieving revision 1.70
diff -u -p -r1.70 drm_irq.c
--- dev/pci/drm/drm_irq.c 28 Mar 2018 05:27:28 -0000 1.70
+++ dev/pci/drm/drm_irq.c 10 Sep 2018 18:45:33 -0000
@@ -1317,8 +1317,21 @@ void drm_wait_one_vblank(struct drm_devi
int ret;
u32 last;
- if (WARN_ON(pipe >= dev->num_crtcs) || cold)
+ if (WARN_ON(pipe >= dev->num_crtcs))
return;
+
+#ifdef __OpenBSD__
+ /*
+ * If we're cold, vblank interrupts won't happen even if
+ * they're turned on by the driver. Just stall long enough
+ * for a vblank to pass. This assumes a vrefresh of at least
+ * 25 Hz.
+ */
+ if (cold) {
+ delay(40000);
+ return;
+ }
+#endif
ret = drm_vblank_get(dev, pipe);
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", pipe, ret))