* [PATCH 1/8] nv50/display: Set VBLANK time in modeset script
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
@ 2014-09-04 14:58 ` Roy Spliet
[not found] ` <1409842735-7361-2-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2014-09-04 14:58 ` [PATCH 2/8] pwr/memx/nva3: Implement "wait for VBLANK" Roy Spliet
` (6 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
Solves blinking on reclocking memory. The value set is an underestimate, but with non-reduced vblanking this should give us plenty of time
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/nv50_display.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 4c534b7..cfa7ecf 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1070,7 +1070,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
u32 vscan = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1;
u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks;
u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks;
- u32 vblan2e = 0, vblan2s = 1;
+ u32 vblan2e = 0, vblan2s = 1, vblankus;
u32 *push;
int ret;
@@ -1087,6 +1087,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
vblanke = vsynce + vbackp;
vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace;
vblanks = vactive - vfrontp - 1;
+
if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
vblan2e = vactive + vsynce + vbackp;
vblan2s = vblan2e + (mode->vdisplay * vscan / ilace);
@@ -1100,17 +1101,22 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
push = evo_wait(mast, 64);
if (push) {
if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
+ /* XXX: Safe underestimate, even "0" works */
+ vblankus = (vactive - mode->vdisplay - 2) * hactive;
+ vblankus *= 1000;
+ vblankus /= mode->clock;
+
evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2);
evo_data(push, 0x00800000 | mode->clock);
evo_data(push, (ilace == 2) ? 2 : 0);
- evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6);
+ evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 8);
evo_data(push, 0x00000000);
evo_data(push, (vactive << 16) | hactive);
evo_data(push, ( vsynce << 16) | hsynce);
evo_data(push, (vblanke << 16) | hblanke);
evo_data(push, (vblanks << 16) | hblanks);
evo_data(push, (vblan2e << 16) | vblan2s);
- evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1);
+ evo_data(push, vblankus);
evo_data(push, 0x00000000);
evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2);
evo_data(push, 0x00000311);
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/8] pwr/memx/nva3: Implement "wait for VBLANK"
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2014-09-04 14:58 ` [PATCH 1/8] nv50/display: Set VBLANK time in modeset script Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
2014-09-04 14:58 ` [PATCH 3/8] pwr/memx: Make FB disable and enable explicit Roy Spliet
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/include/subdev/pwr.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h | 25 +++++----
.../gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc | 60 ++++++++++++++++++++--
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c | 35 ++++++++++++-
5 files changed, 107 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
index c5c92cb..b5286b3 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
@@ -76,5 +76,6 @@ void nouveau_memx_wr32(struct nouveau_memx *, u32 addr, u32 data);
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 *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
index 2af9cfd..76290bb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
@@ -105,14 +105,21 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec)
nouveau_memx_nsec(ram->memx, nsec);
}
-#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)
-#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
-#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
-#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
-#define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))
-#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))
+static inline void
+ramfuc_wait_vblank(struct ramfuc *ram)
+{
+ nouveau_memx_wait_vblank(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)
+#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
+#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
+#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
+#define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))
+#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)
#endif
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 d43741e..228ee0d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
@@ -43,12 +43,13 @@ process(PROC_MEMX, #memx_init, #memx_recv)
*/ .b32 func
memx_func_head:
-handler(ENTER , 0x0001, 0x0000, #memx_func_enter)
+handler(ENTER , 0x0000, 0x0000, #memx_func_enter)
memx_func_next:
handler(LEAVE , 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)
+handler(VBLANK, 0x0001, 0x0000, #memx_func_wait_vblank)
memx_func_tail:
.equ #memx_func_size #memx_func_next - #memx_func_head
@@ -67,7 +68,6 @@ memx_data_tail:
//
// $r15 - current (memx)
// $r4 - packet length
-// +00: bitmask of heads to wait for vblank on
// $r3 - opcode desciption
// $r0 - zero
memx_func_enter:
@@ -77,9 +77,7 @@ memx_func_enter:
nv_iord($r6, NV_PPWR_OUTPUT)
and $r6 NV_PPWR_OUTPUT_FB_PAUSE
bra z #memx_func_enter_wait
- //XXX: TODO
- ld b32 $r6 D[$r1 + 0x00]
- add b32 $r1 0x04
+
ret
// description
@@ -97,6 +95,58 @@ memx_func_leave:
bra nz #memx_func_leave_wait
ret
+#if NVKM_PPWR_CHIPSET < GF119
+// description
+//
+// $r15 - current (memx)
+// $r4 - packet length
+// +00: head to wait for vblank on
+// $r3 - opcode desciption
+// $r0 - zero
+memx_func_wait_vblank:
+ ld b32 $r6 D[$r1 + 0x00]
+ cmp b32 $r6 0x0
+ bra z #memx_func_wait_vblank_head0
+ cmp b32 $r6 0x1
+ bra z #memx_func_wait_vblank_head1
+ bra #memx_func_wait_vblank_fini
+
+ memx_func_wait_vblank_head1:
+ movw $r7 0x20
+ bra #memx_func_wait_vblank_0
+
+ memx_func_wait_vblank_head0:
+ movw $r7 0x8
+
+ memx_func_wait_vblank_0:
+ nv_iord($r6, NV_PPWR_INPUT)
+ and $r6 $r7
+ bra nz #memx_func_wait_vblank_0
+
+ memx_func_wait_vblank_1:
+ nv_iord($r6, NV_PPWR_INPUT)
+ and $r6 $r7
+ bra z #memx_func_wait_vblank_1
+
+ memx_func_wait_vblank_fini:
+ add b32 $r1 0x4
+ ret
+
+#else
+
+// XXX: currently no-op
+//
+// $r15 - current (memx)
+// $r4 - packet length
+// +00: head to wait for vblank on
+// $r3 - opcode desciption
+// $r0 - zero
+memx_func_wait_vblank:
+ add b32 $r1 0x4
+ ret
+
+#endif
+
// description
//
// $r15 - current (memx)
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 574acfa..80f8328 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
@@ -24,6 +24,7 @@
#define MEMX_WR32 2
#define MEMX_WAIT 3
#define MEMX_DELAY 4
+#define MEMX_VBLANK 5
/* I2C_: message identifiers */
#define I2C__MSG_RD08 0
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
index 03de310..bcdc00f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
@@ -64,7 +64,7 @@ nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx)
} while (nv_rd32(ppwr, 0x10a580) != 0x00000003);
nv_wr32(ppwr, 0x10a1c0, 0x01000000 | memx->base);
nv_wr32(ppwr, 0x10a1c4, 0x00010000 | MEMX_ENTER);
- nv_wr32(ppwr, 0x10a1c4, 0x00000000);
+
return 0;
}
@@ -118,4 +118,37 @@ nouveau_memx_nsec(struct nouveau_memx *memx, u32 nsec)
memx_out(memx); /* fuc can't handle multiple */
}
+void
+nouveau_memx_wait_vblank(struct nouveau_memx *memx)
+{
+ struct nouveau_pwr *ppwr = memx->ppwr;
+ u32 heads, x, y, px = 0;
+ int i, head_sync;
+
+ if (nv_device(ppwr)->chipset < 0xd0) {
+ heads = nv_rd32(ppwr, 0x610050);
+ for (i = 0; i < 2; i++) {
+ /* Heuristic: sync to head with biggest resolution */
+ if (heads & (2 << (i << 3))) {
+ x = nv_rd32(ppwr, 0x610b40 + (0x540 * i));
+ y = (x & 0xffff0000) >> 16;
+ x &= 0x0000ffff;
+ if ((x * y) > px) {
+ px = (x * y);
+ head_sync = i;
+ }
+ }
+ }
+ }
+
+ if (px == 0) {
+ nv_debug(memx->ppwr, "WAIT VBLANK !NO ACTIVE HEAD\n");
+ return;
+ }
+
+ nv_debug(memx->ppwr, "WAIT VBLANK HEAD%d\n", head_sync);
+ memx_cmd(memx, MEMX_VBLANK, 1, (u32[]){ head_sync });
+ memx_out(memx); /* fuc can't handle multiple */
+}
+
#endif
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/8] pwr/memx: Make FB disable and enable explicit
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2014-09-04 14:58 ` [PATCH 1/8] nv50/display: Set VBLANK time in modeset script Roy Spliet
2014-09-04 14:58 ` [PATCH 2/8] pwr/memx/nva3: Implement "wait for VBLANK" Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
2014-09-04 14:58 ` [PATCH 4/8] fb/ramnve0: Disable FB before reclocking Roy Spliet
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
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.
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/include/subdev/pwr.h | 2 ++
drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h | 14 ++++++++++++++
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc | 4 ++--
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h | 4 ++--
drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c | 20 ++++++++++++++++++--
5 files changed, 38 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 b5286b3..94f8629 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
@@ -77,5 +77,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 76290bb..430261a 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/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
index 228ee0d..9f2f57c 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 80f8328..50f9a38 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 bcdc00f..060bbd2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
@@ -63,7 +63,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;
}
@@ -79,7 +78,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);
@@ -151,4 +149,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
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/8] fb/ramnve0: Disable FB before reclocking
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (2 preceding siblings ...)
2014-09-04 14:58 ` [PATCH 3/8] pwr/memx: Make FB disable and enable explicit Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
[not found] ` <1409842735-7361-5-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2014-09-04 14:58 ` [PATCH 5/8] pwr/memx: Return debugging information Roy Spliet
` (3 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
This used to be done implicitly
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
index c5b46e3..9764792 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;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/8] pwr/memx: Return debugging information
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (3 preceding siblings ...)
2014-09-04 14:58 ` [PATCH 4/8] fb/ramnve0: Disable FB before reclocking Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
2014-09-04 14:58 ` [PATCH 6/8] pwr/memx: Match blobs behaviour Roy Spliet
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
Time measured from disabling FB to re-enabling, PPWR_IN reveals status of heads at the end of script. Helps debug various issues (like flicker).
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc | 16 ++++++++++++++++
drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c | 2 ++
2 files changed, 18 insertions(+)
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 9f2f57c..989fdc1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
@@ -55,6 +55,11 @@ memx_func_tail:
.equ #memx_func_size #memx_func_next - #memx_func_head
.equ #memx_func_num (#memx_func_tail - #memx_func_head) / #memx_func_size
+memx_ts_start:
+.b32 0
+memx_ts_end:
+.b32 0
+
memx_data_head:
.skip 0x0800
memx_data_tail:
@@ -78,6 +83,9 @@ memx_func_enter:
and $r6 NV_PPWR_OUTPUT_FB_PAUSE
bra z #memx_func_enter_wait
+ nv_iord($r6, NV_PPWR_TIMER_LOW)
+ st b32 D[$r0 + #memx_ts_start] $r6
+
ret
// description
@@ -87,6 +95,9 @@ memx_func_enter:
// $r3 - opcode desciption
// $r0 - zero
memx_func_leave:
+ nv_iord($r6, NV_PPWR_TIMER_LOW)
+ st b32 D[$r0 + #memx_ts_end] $r6
+
mov $r6 NV_PPWR_OUTPUT_CLR_FB_PAUSE
nv_iowr(NV_PPWR_OUTPUT_CLR, $r6)
memx_func_leave_wait:
@@ -210,6 +221,7 @@ memx_exec:
push $r13
mov b32 $r1 $r12
mov b32 $r2 $r11
+
memx_exec_next:
// fetch the packet header, and locate opcode info
ld b32 $r3 D[$r1]
@@ -226,6 +238,10 @@ memx_exec:
bra l #memx_exec_next
// send completion reply
+ ld b32 $r11 D[$r0 + #memx_ts_start]
+ ld b32 $r12 D[$r0 + #memx_ts_end]
+ sub b32 $r12 $r11
+ nv_iord($r11, NV_PPWR_INPUT)
pop $r13
pop $r14
call(send)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
index 060bbd2..c20669b9e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
@@ -87,6 +87,8 @@ nouveau_memx_fini(struct nouveau_memx **pmemx, bool exec)
memx->base, finish);
}
+ nv_debug(memx->ppwr, "Exec took %uns, PPWR_IN %08x", reply[0], reply[1]);
+
kfree(memx);
return 0;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/8] pwr/memx: Match blobs behaviour
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (4 preceding siblings ...)
2014-09-04 14:58 ` [PATCH 5/8] pwr/memx: Return debugging information Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
2014-09-04 14:58 ` [PATCH 7/8] fb/sddr3: Expand MR generation Roy Spliet
2014-09-04 14:58 ` [PATCH 8/8] fb/sddr2: Generate MR values Roy Spliet
7 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
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 989fdc1..744f2e9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
@@ -76,6 +76,16 @@ memx_data_tail:
// $r3 - opcode desciption
// $r0 - zero
memx_func_enter:
+#if NVKM_PPWR_CHIPSET == GT215
+ movw $r8 0x1610
+ nv_rd32($r7, $r8)
+ imm32($r6, 0xfffffffc)
+ and $r7 $r6
+ movw $r6 0x2
+ or $r7 $r6
+ nv_wr32($r8, $r7)
+#endif
+
mov $r6 NV_PPWR_OUTPUT_SET_FB_PAUSE
nv_iowr(NV_PPWR_OUTPUT_SET, $r6)
memx_func_enter_wait:
@@ -104,6 +114,15 @@ memx_func_leave:
nv_iord($r6, NV_PPWR_OUTPUT)
and $r6 NV_PPWR_OUTPUT_FB_PAUSE
bra nz #memx_func_leave_wait
+
+#if NVKM_PPWR_CHIPSET == GT215
+ movw $r8 0x1610
+ nv_rd32($r7, $r8)
+ imm32($r6, 0xffffffcc)
+ and $r7 $r6
+ nv_wr32($r8, $r7)
+#endif
+
ret
#if NVKM_PPWR_CHIPSET < GF119
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/8] fb/sddr3: Expand MR generation
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (5 preceding siblings ...)
2014-09-04 14:58 ` [PATCH 6/8] pwr/memx: Match blobs behaviour Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
2014-09-04 14:58 ` [PATCH 8/8] fb/sddr2: Generate MR values Roy Spliet
7 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c | 43 ++++++++++++++++++++------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
index ebd4cd9..f84c654 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
@@ -20,6 +20,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ * Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
*/
#include <subdev/bios.h>
@@ -70,30 +71,52 @@ int
nouveau_sddr3_calc(struct nouveau_ram *ram)
{
struct nouveau_bios *bios = nouveau_bios(ram);
- int WL, CL, WR;
+ int CWL, CL, WR, DLL = 0, ODT = 0;
switch (!!ram->timing.data * ram->timing.version) {
+ case 0x10:
+ if (ram->timing.size < 0x17) {
+ /* XXX: NV50: Get CWL from the timing register */
+ return -ENOSYS;
+ }
+ CWL = nv_ro08(bios, ram->timing.data + 0x13);
+ CL = nv_ro08(bios, ram->timing.data + 0x02);
+ WR = nv_ro08(bios, ram->timing.data + 0x00);
+ DLL = !(nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x40);
+ ODT = nv_ro08(bios, ram->timing.data + 0x0e) & 0x07;
+ break;
case 0x20:
- WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
- CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
- WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+ CWL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
+ CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
+ WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+ /* XXX: Get these values from the VBIOS instead */
+ DLL = !(ram->mr[1] & 0x1);
+ ODT = (ram->mr[1] & 0x004) >> 2 |
+ (ram->mr[1] & 0x040) >> 5 |
+ (ram->mr[1] & 0x200) >> 7;
break;
default:
return -ENOSYS;
}
- WL = ramxlat(ramddr3_cwl, WL);
- CL = ramxlat(ramddr3_cl, CL);
- WR = ramxlat(ramddr3_wr, WR);
- if (WL < 0 || CL < 0 || WR < 0)
+ CWL = ramxlat(ramddr3_cwl, CWL);
+ CL = ramxlat(ramddr3_cl, CL);
+ WR = ramxlat(ramddr3_wr, WR);
+ if (CL < 0 || CWL < 0 || WR < 0)
return -EINVAL;
- ram->mr[0] &= ~0xe74;
+ ram->mr[0] &= ~0xf74;
ram->mr[0] |= (WR & 0x07) << 9;
ram->mr[0] |= (CL & 0x0e) << 3;
ram->mr[0] |= (CL & 0x01) << 2;
+ ram->mr[1] &= ~0x245;
+ ram->mr[1] |= (ODT & 0x1) << 2;
+ ram->mr[1] |= (ODT & 0x2) << 5;
+ ram->mr[1] |= (ODT & 0x4) << 7;
+ ram->mr[1] |= !DLL;
+
ram->mr[2] &= ~0x038;
- ram->mr[2] |= (WL & 0x07) << 3;
+ ram->mr[2] |= (CWL & 0x07) << 3;
return 0;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 8/8] fb/sddr2: Generate MR values
[not found] ` <1409842735-7361-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (6 preceding siblings ...)
2014-09-04 14:58 ` [PATCH 7/8] fb/sddr3: Expand MR generation Roy Spliet
@ 2014-09-04 14:58 ` Roy Spliet
7 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2014-09-04 14:58 UTC (permalink / raw)
To: Nouveau Mailinglist; +Cc: Roy Spliet
Signed-off-by: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
---
drivers/gpu/drm/nouveau/Makefile | 1 +
drivers/gpu/drm/nouveau/core/subdev/fb/priv.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c | 96 ++++++++++++++++++++++++++
3 files changed, 98 insertions(+)
create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 8b307e1..8228e05 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -120,6 +120,7 @@ nouveau-y += core/subdev/fb/ramnvc0.o
nouveau-y += core/subdev/fb/ramnve0.o
nouveau-y += core/subdev/fb/ramgk20a.o
nouveau-y += core/subdev/fb/ramgm107.o
+nouveau-y += core/subdev/fb/sddr2.o
nouveau-y += core/subdev/fb/sddr3.o
nouveau-y += core/subdev/fb/gddr5.o
nouveau-y += core/subdev/gpio/base.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
index 82273f8..60322e9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -35,6 +35,7 @@ extern struct nouveau_oclass nve0_ram_oclass;
extern struct nouveau_oclass gk20a_ram_oclass;
extern struct nouveau_oclass gm107_ram_oclass;
+int nouveau_sddr2_calc(struct nouveau_ram *ram);
int nouveau_sddr3_calc(struct nouveau_ram *ram);
int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
new file mode 100644
index 0000000..f2f5f12
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014 Roy Spliet
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Roy Spliet <rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
+ * Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include "priv.h"
+
+struct ramxlat {
+ int id;
+ u8 enc;
+};
+
+static inline int
+ramxlat(const struct ramxlat *xlat, int id)
+{
+ while (xlat->id >= 0) {
+ if (xlat->id == id)
+ return xlat->enc;
+ xlat++;
+ }
+ return -EINVAL;
+}
+
+static const struct ramxlat
+ramddr2_cl[] = {
+ { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 },
+ /* The following are available in some, but not all DDR2 docs */
+ { 7, 7 },
+ { -1 }
+};
+
+static const struct ramxlat
+ramddr2_wr[] = {
+ { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 4 }, { 6, 5 },
+ /* The following are available in some, but not all DDR2 docs */
+ { 7, 6 },
+ { -1 }
+};
+
+int
+nouveau_sddr2_calc(struct nouveau_ram *ram)
+{
+ struct nouveau_bios *bios = nouveau_bios(ram);
+ int CL, WR, DLL = 0, ODT = 0;
+
+ switch (!!ram->timing.data * ram->timing.version) {
+ case 0x10:
+ CL = nv_ro08(bios, ram->timing.data + 0x02);
+ WR = nv_ro08(bios, ram->timing.data + 0x00);
+ DLL = !(nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x40);
+ ODT = nv_ro08(bios, ram->timing.data + 0x0e) & 0x03;
+ break;
+ case 0x20:
+ CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
+ WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+ break;
+ default:
+ return -ENOSYS;
+ }
+
+ CL = ramxlat(ramddr2_cl, CL);
+ WR = ramxlat(ramddr2_wr, WR);
+ if (CL < 0 || WR < 0)
+ return -EINVAL;
+
+ ram->mr[0] &= ~0xe70;
+ ram->mr[0] |= (WR & 0x07) << 9;
+ ram->mr[0] |= (CL & 0x07) << 4;
+
+ ram->mr[1] &= ~0x045;
+ ram->mr[1] |= (ODT & 0x1) << 2;
+ ram->mr[1] |= (ODT & 0x2) << 5;
+ ram->mr[1] |= !DLL;
+ return 0;
+}
--
1.9.3
^ permalink raw reply related [flat|nested] 13+ messages in thread