drm/nouveau/kms/nv50-: wait for FIFO space on PIO channels
authorBen Skeggs <bskeggs@redhat.com>
Mon, 17 Feb 2020 04:33:57 +0000 (14:33 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 7 Apr 2020 04:37:50 +0000 (14:37 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/curs507a.c
drivers/gpu/drm/nouveau/dispnv50/cursc37a.c
drivers/gpu/drm/nouveau/dispnv50/wndw.h

index 397143b639c64ba6dbd7c1144c0314aae954339f..8c5cf096f69bb572e714e9800e8815581e65caef 100644 (file)
 #include "head.h"
 
 #include <nvif/cl507a.h>
+#include <nvif/timer.h>
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
 
+bool
+curs507a_space(struct nv50_wndw *wndw)
+{
+       nvif_msec(&nouveau_drm(wndw->plane.dev)->client.device, 2,
+               if (nvif_rd32(&wndw->wimm.base.user, 0x0008) >= 4)
+                       return true;
+       );
+       WARN_ON(1);
+       return false;
+}
+
 static void
 curs507a_update(struct nv50_wndw *wndw, u32 *interlock)
 {
-       nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000);
+       if (curs507a_space(wndw))
+               nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000);
 }
 
 static void
 curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
-       nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 |
-                                                asyw->point.x);
+       if (curs507a_space(wndw)) {
+               nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 |
+                                                        asyw->point.x);
+       }
 }
 
 const struct nv50_wimm_func
index 23fb29d41efef21a7e5e8dab8dca3dceab4fded6..96dff4f09f57294287f24e7c40edc55d0a5ef532 100644 (file)
 static void
 cursc37a_update(struct nv50_wndw *wndw, u32 *interlock)
 {
-       nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001);
+       if (curs507a_space(wndw))
+               nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001);
 }
 
 static void
 cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
-       nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 |
-                                                asyw->point.x);
+       if (curs507a_space(wndw)) {
+               nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 |
+                                                        asyw->point.x);
+       }
 }
 
 static const struct nv50_wimm_func
index caf3974759181acc8fc652f19a68ec0675dc2dc5..a7412b9d3a982db8f3a9600d7d60b0f9fffb66ce 100644 (file)
@@ -97,6 +97,7 @@ struct nv50_wimm_func {
 };
 
 extern const struct nv50_wimm_func curs507a;
+bool curs507a_space(struct nv50_wndw *);
 
 int wndwc37e_new(struct nouveau_drm *, enum drm_plane_type, int, s32,
                 struct nv50_wndw **);