From d93e996aed6e48c87dc5703a21b0e9368d4cc1f9 Mon Sep 17 00:00:00 2001 From: Roy Spliet Date: Thu, 4 Sep 2014 16:58:50 +0200 Subject: [PATCH] drm/nouveau/pwr/memx: Make FB disable and enable explicit 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 Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/core/include/subdev/pwr.h | 2 ++ .../gpu/drm/nouveau/core/subdev/fb/ramfuc.h | 14 +++++++++++++ .../gpu/drm/nouveau/core/subdev/fb/ramnve0.c | 5 +++++ .../drm/nouveau/core/subdev/pwr/fuc/memx.fuc | 4 ++-- .../gpu/drm/nouveau/core/subdev/pwr/fuc/os.h | 4 ++-- .../gpu/drm/nouveau/core/subdev/pwr/memx.c | 20 +++++++++++++++++-- 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h index 209e2e42b3a5..1c4668505970 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h @@ -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 diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h index 76290bb4bf07..430261a307a4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h @@ -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 diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c index c5b46e302319..9764792c3222 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c @@ -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; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc index 228ee0d8194e..9f2f57c6c828 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc @@ -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) diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h index 80f8328fa6da..50f9a38a0924 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h @@ -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 diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c index 68baa7283736..fa6aae3c29e9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c @@ -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 -- 2.45.2