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 397143b..8c5cf09 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 23fb29d..96dff4f 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 caf3974..a7412b9 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 **);