From: Walter Alejandro Iglesias Subject: Re: Intel GPU, ghosting after zzz or ZZZ To: tech@openbsd.org Date: Mon, 25 May 2026 11:51:32 +0200 I'll explain what I did and why. In a first diff I tried to imitate what kettenis@ did for amdgpu: https://cvsweb.openbsd.org/diff/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c?rev=1.68&prev=1.67 I have no amdgpu machine, I have no way to know if the problem solved by that diff is the same. The only I can say for sure is that calling memset() or rasops_show_screen() *before* drm_client_dev_restore() (as kettenis did for amdgpu) didn't work in my intel machine in the case I described. Besides, obviously, limiting them to S4 didn't solve the issue for S3. In a discussion I had with jsg@ in private I was asked to not use memset() with S3 and S0, I think I get why. Anyways, after trying this and that, at some point I realized that memset wasn't necessary (at least for my case), rasops_show_screen() was enough. As far as my knowledge goes, I'm no expert, and the little I've investigated, I'll explain the possible reason why these resets don't work if you put them before drm_client_dev_restore(). I'll appreciate to be corrected if I'm wrong in the following argument. If you take a look to i915_driver.c, you'll see that besides inteldrm_activate there are two more functions where rasops_show_screen is called: void inteldrm_doswitch(void *v) { struct drm_i915_private *dev_priv = v; struct drm_device *dev = &dev_priv->drm; struct rasops_info *ri = &dev_priv->ro; rasops_show_screen(ri, dev_priv->switchcookie, 0, NULL, NULL); drm_client_dev_restore(dev); if (dev_priv->switchcb) (*dev_priv->switchcb)(dev_priv->switchcbarg, 0, 0); } void inteldrm_enter_ddb(void *v, void *cookie) { struct drm_i915_private *dev_priv = v; struct drm_device *dev = &dev_priv->drm; struct rasops_info *ri = &dev_priv->ro; if (cookie == ri->ri_active) return; rasops_show_screen(ri, cookie, 0, NULL, NULL); drm_client_dev_restore(dev); } As you see, in both cases it's called *before* drm_client_dev_restore(). But, in those cases we're switching between active states, where the GPU translation tables and power are already there. Not the case in DVACT_WAKEUP in inteldrm_activate(), the hardware is coming from an uninitialized state. If we call rasops_show_screen before drm_client_dev_restore during resume, we risk writing to the framebuffer before the DRM client has fully restablished the correct hardware plane and GTT state. This causes a desync between the rasops backing store and the physical VRAM. -- Walter