drm/nouveau/pwr/memx: Make FB disable and enable explicit
authorRoy Spliet <rspliet@eclipso.eu>
Thu, 4 Sep 2014 14:58:50 +0000 (16:58 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 15 Sep 2014 12:25:03 +0000 (22:25 +1000)
Needs to be done after wait-for-VBLANK, and NVA3 requires register writes
in between.

Rather than hard-coding register writes, just split out fb_disable and
fb_enable.

v2. Squashed "fb/ramnve0: disable fb before reclocking"

Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c

index 209e2e42b3a5263d67916d08b99d06c84d9f1d74..1c4668505970659637344b3285f500ad2d1057b9 100644 (file)
@@ -48,5 +48,7 @@ void nouveau_memx_wait(struct nouveau_memx *,
                       u32 addr, u32 mask, u32 data, u32 nsec);
 void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec);
 void nouveau_memx_wait_vblank(struct nouveau_memx *);
+void nouveau_memx_fb_disable(struct nouveau_memx *);
+void nouveau_memx_fb_enable(struct nouveau_memx *);
 
 #endif
index 76290bb4bf07a3cdfdb2022fda3b42f4c682ec9c..430261a307a471974c0abc6694142ee254a232ba 100644 (file)
@@ -111,6 +111,18 @@ ramfuc_wait_vblank(struct ramfuc *ram)
        nouveau_memx_wait_vblank(ram->memx);
 }
 
+static inline void
+ramfuc_fb_disable(struct ramfuc *ram)
+{
+       nouveau_memx_fb_disable(ram->memx);
+}
+
+static inline void
+ramfuc_fb_enable(struct ramfuc *ram)
+{
+       nouveau_memx_fb_enable(ram->memx);
+}
+
 #define ram_init(s,p)        ramfuc_init(&(s)->base, (p))
 #define ram_exec(s,e)        ramfuc_exec(&(s)->base, (e))
 #define ram_have(s,r)        ((s)->r_##r.addr[0] != 0x000000)
@@ -121,5 +133,7 @@ ramfuc_wait_vblank(struct ramfuc *ram)
 #define ram_wait(s,r,m,d,n)  ramfuc_wait(&(s)->base, (r), (m), (d), (n))
 #define ram_nsec(s,n)        ramfuc_nsec(&(s)->base, (n))
 #define ram_wait_vblank(s)   ramfuc_wait_vblank(&(s)->base)
+#define ram_fb_disable(s)    ramfuc_fb_disable(&(s)->base)
+#define ram_fb_enable(s)     ramfuc_fb_enable(&(s)->base)
 
 #endif
index c5b46e3023199299362f68181ef98ec9f4db7644..9764792c3222bdc7c29f4fb495b77107e6f81833 100644 (file)
@@ -998,6 +998,8 @@ nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
        if (ret)
                return ret;
 
+       ram_fb_disable(fuc);
+
        ram->mode = (next->freq > fuc->refpll.vco1.max_freq) ? 2 : 1;
        ram->from = ram_rd32(fuc, 0x1373f4) & 0x0000000f;
 
@@ -1061,6 +1063,9 @@ nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
                break;
        }
 
+       if (!ret)
+               ram_fb_enable(fuc);
+
        return ret;
 }
 
index 228ee0d8194e50b34d6fe0c18c2c622ff28091a8..9f2f57c6c8284c6a776a0a4635d7d9e06ba09528 100644 (file)
@@ -43,9 +43,9 @@ process(PROC_MEMX, #memx_init, #memx_recv)
 */     .b32 func
 
 memx_func_head:
-handler(ENTER , 0x0000, 0x0000, #memx_func_enter)
+handler(FB_OFF, 0x0000, 0x0000, #memx_func_enter)
 memx_func_next:
-handler(LEAVE , 0x0000, 0x0000, #memx_func_leave)
+handler(FB_ON , 0x0000, 0x0000, #memx_func_leave)
 handler(WR32  , 0x0000, 0x0002, #memx_func_wr32)
 handler(WAIT  , 0x0004, 0x0000, #memx_func_wait)
 handler(DELAY , 0x0001, 0x0000, #memx_func_delay)
index 80f8328fa6da359552f838336e7950adc19b7360..50f9a38a0924fe6de21340d5b79a4dae02f07b5f 100644 (file)
@@ -19,8 +19,8 @@
 #define MEMX_MSG_EXEC 1
 
 /* MEMX: script opcode definitions */
-#define MEMX_ENTER  0
-#define MEMX_LEAVE  1
+#define MEMX_FB_OFF 0
+#define MEMX_FB_ON  1
 #define MEMX_WR32   2
 #define MEMX_WAIT   3
 #define MEMX_DELAY  4
index 68baa7283736ed615fc5332a4f519041adec4d48..fa6aae3c29e95cd3cebb45e0f4c4c7e351cae5eb 100644 (file)
@@ -62,7 +62,6 @@ nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx)
                nv_wr32(ppwr, 0x10a580, 0x00000003);
        } while (nv_rd32(ppwr, 0x10a580) != 0x00000003);
        nv_wr32(ppwr, 0x10a1c0, 0x01000000 | memx->base);
-       nv_wr32(ppwr, 0x10a1c4, 0x00010000 | MEMX_ENTER);
 
        return 0;
 }
@@ -78,7 +77,6 @@ nouveau_memx_fini(struct nouveau_memx **pmemx, bool exec)
        memx_out(memx);
 
        /* release data segment access */
-       nv_wr32(ppwr, 0x10a1c4, 0x00000000 | MEMX_LEAVE);
        finish = nv_rd32(ppwr, 0x10a1c0) & 0x00ffffff;
        nv_wr32(ppwr, 0x10a580, 0x00000000);
 
@@ -150,4 +148,22 @@ nouveau_memx_wait_vblank(struct nouveau_memx *memx)
        memx_out(memx); /* fuc can't handle multiple */
 }
 
+void
+nouveau_memx_fb_disable(struct nouveau_memx *memx)
+{
+       struct nouveau_pwr *ppwr = memx->ppwr;
+
+       nv_debug(memx->ppwr, "   FB OFF\n");
+       nv_wr32(ppwr, 0x10a1c4, MEMX_FB_OFF);
+}
+
+void
+nouveau_memx_fb_enable(struct nouveau_memx *memx)
+{
+       struct nouveau_pwr *ppwr = memx->ppwr;
+
+       nv_debug(memx->ppwr, "   FB  ON\n");
+       nv_wr32(ppwr, 0x10a1c4, MEMX_FB_ON);
+}
+
 #endif