* Reclocking support for NVA0
@ 2015-05-22 22:33 Roy Spliet
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
0 siblings, 1 reply; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Adds reclocking for NVA0, and a whole lot of work for other cards. Had these
patches collecting dust for a little, but tested them with both my NVA0,
and Martin's a while back. Success not guaranteed, but should be quite a
leap forward.
Happy reviewing and testing. Cheers,
Roy
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/9] nvkm/clk/gt215: u32->s32 for difference in req. and set clock
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
@ 2015-05-22 22:33 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 2/9] nvkm/bios/rammap: Pull DLLoff bit out of version 0x10 struct Roy Spliet
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
This difference can of course be negative too...
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
index 822d32a..065e9f5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
@@ -180,7 +180,8 @@ gt215_clk_info(struct nvkm_clk *clock, int clk, u32 khz,
struct gt215_clk_info *info)
{
struct gt215_clk_priv *priv = (void *)clock;
- u32 oclk, sclk, sdiv, diff;
+ u32 oclk, sclk, sdiv;
+ s32 diff;
info->clk = 0;
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/9] nvkm/bios/rammap: Pull DLLoff bit out of version 0x10 struct
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:33 ` [PATCH 1/9] nvkm/clk/gt215: u32->s32 for difference in req. and set clock Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 3/9] nvkm/fb/ramnv50: Make 0x100da0 per-partition Roy Spliet
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
In preparation of NV50 reclocking, where there is no version
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 2 +-
drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 2 +-
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c | 2 +-
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 6 +++---
drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c | 2 +-
drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c | 2 +-
6 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 4204267..c6fb6aa 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -32,6 +32,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_ver;
unsigned ramcfg_hdr;
unsigned ramcfg_timing;
+ unsigned ramcfg_DLLoff;
union {
struct {
unsigned ramcfg_10_02_01:1;
@@ -40,7 +41,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_10_02_08:1;
unsigned ramcfg_10_02_10:1;
unsigned ramcfg_10_02_20:1;
- unsigned ramcfg_10_DLLoff:1;
unsigned ramcfg_10_03_0f:4;
unsigned ramcfg_10_04_01:1;
unsigned ramcfg_10_05:8;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 8b17bb4..a688d3b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -157,7 +157,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_02_08 = (nv_ro08(bios, data + 0x02) & 0x08) >> 3;
p->ramcfg_10_02_10 = (nv_ro08(bios, data + 0x02) & 0x10) >> 4;
p->ramcfg_10_02_20 = (nv_ro08(bios, data + 0x02) & 0x20) >> 5;
- p->ramcfg_10_DLLoff = (nv_ro08(bios, data + 0x02) & 0x40) >> 6;
+ p->ramcfg_DLLoff = (nv_ro08(bios, data + 0x02) & 0x40) >> 6;
p->ramcfg_10_03_0f = (nv_ro08(bios, data + 0x03) & 0x0f) >> 0;
p->ramcfg_10_04_01 = (nv_ro08(bios, data + 0x04) & 0x01) >> 0;
p->ramcfg_10_05 = (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 15b462a..e1d11f7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -77,7 +77,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
CWL = ram->next->bios.timing_10_CWL;
CL = ram->next->bios.timing_10_CL;
WR = ram->next->bios.timing_10_WR;
- DLL = !ram->next->bios.ramcfg_10_DLLoff;
+ DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT;
break;
case 0x20:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 2417640..47d53ed 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -590,7 +590,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
r100da0 = 0x00000000;
}
- if (!next->bios.ramcfg_10_DLLoff)
+ if (!next->bios.ramcfg_DLLoff)
r004018 |= 0x00004000;
/* pll2pll requires to switch to a safe clock first */
@@ -630,7 +630,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
}
/* If we're disabling the DLL, do it now */
- switch (next->bios.ramcfg_10_DLLoff * ram->base.type) {
+ switch (next->bios.ramcfg_DLLoff * ram->base.type) {
case NV_MEM_TYPE_DDR3:
nvkm_sddr3_dll_disable(fuc, ram->base.mr);
break;
@@ -810,7 +810,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
gt215_ram_fbvref(fuc, 1);
/* Reset DLL */
- if (!next->bios.ramcfg_10_DLLoff)
+ if (!next->bios.ramcfg_DLLoff)
nvkm_sddr2_dll_reset(fuc);
if (ram->base.type == NV_MEM_TYPE_GDDR3) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
index afab42d..86bf674 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
@@ -65,7 +65,7 @@ nvkm_sddr2_calc(struct nvkm_ram *ram)
case 0x10:
CL = ram->next->bios.timing_10_CL;
WR = ram->next->bios.timing_10_WR;
- DLL = !ram->next->bios.ramcfg_10_DLLoff;
+ DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT & 3;
break;
case 0x20:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
index 1084435..77c53f9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
@@ -79,7 +79,7 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
CWL = ram->next->bios.timing_10_CWL;
CL = ram->next->bios.timing_10_CL;
WR = ram->next->bios.timing_10_WR;
- DLL = !ram->next->bios.ramcfg_10_DLLoff;
+ DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT;
break;
case 0x20:
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/9] nvkm/fb/ramnv50: Make 0x100da0 per-partition
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:33 ` [PATCH 1/9] nvkm/clk/gt215: u32->s32 for difference in req. and set clock Roy Spliet
2015-05-22 22:33 ` [PATCH 2/9] nvkm/bios/rammap: Pull DLLoff bit out of version 0x10 struct Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
[not found] ` <1432334028-15234-4-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:33 ` [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers Roy Spliet
` (5 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
Like on GT215
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index d2c81dd..a96e512 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -42,7 +42,7 @@ struct nv50_ramseq {
struct hwsq_reg r_0x1002d0;
struct hwsq_reg r_0x1002d4;
struct hwsq_reg r_0x1002dc;
- struct hwsq_reg r_0x100da0[8];
+ struct hwsq_reg r_0x100da0;
struct hwsq_reg r_0x100e20;
struct hwsq_reg r_0x100e24;
struct hwsq_reg r_0x611200;
@@ -70,6 +70,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
u8 size;
} ramcfg, timing;
u8 ver, hdr, cnt, len, strap;
+ u32 r100da0;
int N1, M1, N2, M2, P;
int ret, i;
@@ -109,6 +110,13 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
timing.data = 0;
}
+ /* XXX: where the fuck does 750MHz come from? */
+ if (freq <= 750000) {
+ r100da0 = 0x00000010;
+ } else {
+ r100da0 = 0x00000000;
+ }
+
ret = ram_init(hwsq, nv_subdev(pfb));
if (ret)
return ret;
@@ -144,10 +152,9 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
ram_mask(hwsq, 0x004008, 0x81ff0000, 0x80000000 | (mpll.bias_p << 19) |
(P << 22) | (P << 16));
-#if QFX5800NVA0
- for (i = 0; i < 8; i++)
- ram_mask(hwsq, 0x100da0[i], 0x00000000, 0x00000000); /*XXX*/
-#endif
+
+ if (nv_device(pfb)->chipset == 0xa0)
+ ram_wr32(hwsq, 0x100da0, r100da0); /*XXX: here?*/
ram_nsec(hwsq, 96000); /*XXX*/
ram_mask(hwsq, 0x004008, 0x00002200, 0x00002000);
@@ -430,8 +437,7 @@ nv50_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0);
ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4);
ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc);
- for (i = 0; i < 8; i++)
- ram->hwsq.r_0x100da0[i] = hwsq_reg(0x100da0 + (i * 0x04));
+ ram->hwsq.r_0x100da0 = hwsq_stride(0x100da0, 4, ram->base.part_mask);
ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20);
ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24);
ram->hwsq.r_0x611200 = hwsq_reg(0x611200);
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (2 preceding siblings ...)
2015-05-22 22:33 ` [PATCH 3/9] nvkm/fb/ramnv50: Make 0x100da0 per-partition Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
[not found] ` <1432334028-15234-5-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:33 ` [PATCH 5/9] nvkm/bios/rammap: Parse perf mode as if it's a rammap entry Roy Spliet
` (4 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
Might need some generalisation to < GT200. For those: use at your own risk!
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
.../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 16 ++
.../drm/nouveau/include/nvkm/subdev/bios/rammap.h | 2 +
drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 29 ++++
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 167 +++++++++++++++++----
4 files changed, 181 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index c6fb6aa..f09b6bf 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -35,6 +35,22 @@ struct nvbios_ramcfg {
unsigned ramcfg_DLLoff;
union {
struct {
+ unsigned ramcfg_00_03_01:1;
+ unsigned ramcfg_00_03_02:1;
+ unsigned ramcfg_00_03_08:1;
+ unsigned ramcfg_00_03_10:1;
+ unsigned ramcfg_00_04_02:1;
+ unsigned ramcfg_00_04_04:1;
+ unsigned ramcfg_00_04_20:1;
+ unsigned ramcfg_00_05:8;
+ unsigned ramcfg_00_06:8;
+ unsigned ramcfg_00_07:8;
+ unsigned ramcfg_00_08:8;
+ unsigned ramcfg_00_09:8;
+ unsigned ramcfg_00_0a_0f:4;
+ unsigned ramcfg_00_0a_f0:4;
+ };
+ struct {
unsigned ramcfg_10_02_01:1;
unsigned ramcfg_10_02_02:1;
unsigned ramcfg_10_02_04:1;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
index 609a905..2044fc9 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -15,6 +15,8 @@ u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr);
+u32 nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
+ struct nvbios_ramcfg *p);
u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index a688d3b..4ec376a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -141,6 +141,35 @@ nvbios_rammapSe(struct nvkm_bios *bios, u32 data,
}
u32
+nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
+ struct nvbios_ramcfg *p)
+{
+ data += (idx * size);
+
+ if (size < 11)
+ return NULL;
+
+ p->ramcfg_timing = nv_ro08(bios, data + 0x01);
+ p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
+ p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
+ p->ramcfg_DLLoff = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
+ p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
+ p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
+ p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
+ p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
+ p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
+ p->ramcfg_00_05 = (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
+ p->ramcfg_00_06 = (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
+ p->ramcfg_00_07 = (nv_ro08(bios, data + 0x07) & 0xff) >> 0;
+ p->ramcfg_00_08 = (nv_ro08(bios, data + 0x08) & 0xff) >> 0;
+ p->ramcfg_00_09 = (nv_ro08(bios, data + 0x09) & 0xff) >> 0;
+ p->ramcfg_00_0a_0f = (nv_ro08(bios, data + 0x0a) & 0x0f) >> 0;
+ p->ramcfg_00_0a_f0 = (nv_ro08(bios, data + 0x0a) & 0xf0) >> 4;
+
+ return data;
+}
+
+u32
nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index a96e512..51f93a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -29,6 +29,7 @@
#include <subdev/bios.h>
#include <subdev/bios/perf.h>
#include <subdev/bios/pll.h>
+#include <subdev/bios/rammap.h>
#include <subdev/bios/timing.h>
#include <subdev/clk/pll.h>
@@ -55,6 +56,84 @@ struct nv50_ram {
struct nv50_ramseq hwsq;
};
+#define T(t) cfg->timing_10_##t
+static int
+nv50_ram_timing_calc(struct nvkm_fb *pfb, u32 *timing)
+{
+ struct nv50_ram *ram = (void *)pfb->ram;
+ struct nvbios_ramcfg *cfg = &ram->base.target.bios;
+ u32 cur2, cur3, cur4, cur7, cur8;
+ u8 unkt3b;
+
+ cur2 = nv_rd32(pfb, 0x100228);
+ cur3 = nv_rd32(pfb, 0x10022c);
+ cur4 = nv_rd32(pfb, 0x100230);
+ cur7 = nv_rd32(pfb, 0x10023c);
+ cur8 = nv_rd32(pfb, 0x100240);
+
+ switch ((!T(CWL)) * ram->base.type) {
+ case NV_MEM_TYPE_DDR2:
+ T(CWL) = T(CL) - 1;
+ break;
+ case NV_MEM_TYPE_GDDR3:
+ T(CWL) = ((cur2 & 0xff000000) >> 24) + 1;
+ break;
+ }
+
+ /* XXX: N=1 is not proper statistics */
+ if (nv_device(pfb)->chipset == 0xa0) {
+ unkt3b = 0x19 + ram->base.next->bios.rammap_00_16_40;
+ timing[6] = (0x2d + T(CL) - T(CWL) + ram->base.next->bios.rammap_00_16_40) << 16 |
+ T(CWL) << 8 |
+ (0x2f + T(CL) - T(CWL));
+ } else {
+ unkt3b = 0x16;
+ timing[6] = (0x2b + T(CL) - T(CWL)) << 16 |
+ max_t(s8, T(CWL) - 2, 1) << 8 |
+ (0x2e + T(CL) - T(CWL));
+ }
+
+ timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) << 8 | T(RC));
+ timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
+ max_t(u8, T(18), 1) << 16 |
+ (T(WTR) + 1 + T(CWL)) << 8 |
+ (3 + T(CL) - T(CWL));
+ timing[2] = (T(CWL) - 1) << 24 |
+ (T(RRD) << 16) |
+ (T(RCDWR) << 8) |
+ T(RCDRD);
+ timing[3] = (unkt3b - 2 + T(CL)) << 24 |
+ unkt3b << 16 |
+ (T(CL) - 1) << 8 |
+ (T(CL) - 1);
+ timing[4] = (cur4 & 0xffff0000) |
+ T(13) << 8 |
+ T(13);
+ timing[5] = T(RFC) << 24 |
+ max_t(u8, T(RCDRD), T(RCDWR)) << 16 |
+ T(RP);
+ /* Timing 6 is already done above */
+ timing[7] = (cur7 & 0xff00ffff) | (T(CL) - 1) << 16;
+ timing[8] = (cur8 & 0xffffff00);
+
+ /* XXX: P.version == 1 only has DDR2 and GDDR3? */
+ if (pfb->ram->type == NV_MEM_TYPE_DDR2) {
+ timing[5] |= (T(CL) + 3) << 8;
+ timing[8] |= (T(CL) - 4);
+ } else {
+ timing[5] |= (T(CL) + 2) << 8;
+ timing[8] |= (T(CL) - 2);
+ }
+
+ nv_debug(pfb, " 220: %08x %08x %08x %08x\n",
+ timing[0], timing[1], timing[2], timing[3]);
+ nv_debug(pfb, " 230: %08x %08x %08x %08x\n",
+ timing[4], timing[5], timing[6], timing[7]);
+ nv_debug(pfb, " 240: %08x\n", timing[8]);
+ return 0;
+}
+#undef T
+
#define QFX5800NVA0 1
static int
@@ -65,22 +144,25 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
struct nv50_ramseq *hwsq = &ram->hwsq;
struct nvbios_perfE perfE;
struct nvbios_pll mpll;
- struct {
- u32 data;
- u8 size;
- } ramcfg, timing;
- u8 ver, hdr, cnt, len, strap;
+ struct nvkm_ram_data *next;
+ u8 ver, hdr, cnt, len, strap, size;
+ u32 data;
u32 r100da0;
int N1, M1, N2, M2, P;
int ret, i;
+ u32 timing[9];
+
+ next = &ram->base.target;
+ next->freq = freq;
+ ram->base.next = next;
/* lookup closest matching performance table entry for frequency */
i = 0;
do {
- ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
- &ramcfg.size, &perfE);
- if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) ||
- (ramcfg.size < 2)) {
+ data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
+ &size, &perfE);
+ if (!data || (ver < 0x25 || ver >= 0x40) ||
+ (size < 2)) {
nv_error(pfb, "invalid/missing perftab entry\n");
return -EINVAL;
}
@@ -93,23 +175,48 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
return -EINVAL;
}
- ramcfg.data += hdr + (strap * ramcfg.size);
+ data = nvbios_rammapSp_from_perf(bios, data + hdr, size, strap,
+ &next->bios);
+ if (!data) {
+ nv_error(pfb, "invalid/missing rammap entry ");
+ return -EINVAL;
+ }
/* lookup memory timings, if bios says they're present */
- strap = nv_ro08(bios, ramcfg.data + 0x01);
- if (strap != 0xff) {
- timing.data = nvbios_timingEe(bios, strap, &ver, &hdr,
- &cnt, &len);
- if (!timing.data || ver != 0x10 || hdr < 0x12) {
+ if (next->bios.ramcfg_timing != 0xff) {
+ data = nvbios_timingEp(bios, next->bios.ramcfg_timing,
+ &ver, &hdr, &cnt, &len, &next->bios);
+ if (!data || ver != 0x10 || hdr < 0x12) {
nv_error(pfb, "invalid/missing timing entry "
"%02x %04x %02x %02x\n",
- strap, timing.data, ver, hdr);
+ strap, data, ver, hdr);
return -EINVAL;
}
- } else {
- timing.data = 0;
}
+ nv50_ram_timing_calc(pfb, timing);
+
+ ret = ram_init(hwsq, nv_subdev(pfb));
+ if (ret)
+ return ret;
+
+ /* Determine ram-specific MR values */
+ ram->base.mr[0] = ram_rd32(hwsq, mr[0]);
+ ram->base.mr[1] = ram_rd32(hwsq, mr[1]);
+ ram->base.mr[2] = ram_rd32(hwsq, mr[2]);
+
+ switch (ram->base.type) {
+ case NV_MEM_TYPE_GDDR3:
+ ret = nvkm_gddr3_calc(&ram->base);
+ break;
+ default:
+ ret = -ENOSYS;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
/* XXX: where the fuck does 750MHz come from? */
if (freq <= 750000) {
r100da0 = 0x00000010;
@@ -117,10 +224,6 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
r100da0 = 0x00000000;
}
- ret = ram_init(hwsq, nv_subdev(pfb));
- if (ret)
- return ret;
-
ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
ram_wr32(hwsq, 0x611200, 0x00003300);
@@ -177,17 +280,15 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
break;
}
- ram_mask(hwsq, timing[3], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[1], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[6], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[7], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[8], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[2], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[4], 0x00000000, 0x00000000); /*XXX*/
- ram_mask(hwsq, timing[5], 0x00000000, 0x00000000); /*XXX*/
-
- ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
+ ram_mask(hwsq, timing[3], 0xffffffff, timing[3]);
+ ram_mask(hwsq, timing[1], 0xffffffff, timing[1]);
+ ram_mask(hwsq, timing[6], 0xffffffff, timing[6]);
+ ram_mask(hwsq, timing[7], 0xffffffff, timing[7]);
+ ram_mask(hwsq, timing[8], 0xffffffff, timing[8]);
+ ram_mask(hwsq, timing[0], 0xffffffff, timing[0]);
+ ram_mask(hwsq, timing[2], 0xffffffff, timing[2]);
+ ram_mask(hwsq, timing[4], 0xffffffff, timing[4]);
+ ram_mask(hwsq, timing[5], 0xffffffff, timing[5]);
#if QFX5800NVA0
ram_nuke(hwsq, 0x100e24);
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/9] nvkm/bios/rammap: Parse perf mode as if it's a rammap entry
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (3 preceding siblings ...)
2015-05-22 22:33 ` [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 6/9] nvkm/bios/ramcfg: Separate out RON pull value Roy Spliet
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
Some of the bits in there are similar to the bits in the gt215 rammap.
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 5 +++++
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h | 2 ++
drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 15 +++++++++++++++
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 2 ++
4 files changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index f09b6bf..26e233a 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -7,6 +7,11 @@ struct nvbios_ramcfg {
unsigned rammap_max;
union {
struct {
+ unsigned rammap_00_16_20:1;
+ unsigned rammap_00_16_40:1;
+ unsigned rammap_00_17_02:1;
+ };
+ struct {
unsigned rammap_10_04_02:1;
unsigned rammap_10_04_08:1;
};
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
index 2044fc9..8d8ee13 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -7,6 +7,8 @@ u32 nvbios_rammapTe(struct nvkm_bios *, u8 *ver, u8 *hdr,
u32 nvbios_rammapEe(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size,
+ struct nvbios_ramcfg *p);
u32 nvbios_rammapEp(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 4ec376a..8da8b26 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -72,6 +72,21 @@ nvbios_rammapEe(struct nvkm_bios *bios, int idx,
return 0x0000;
}
+/* Pretend a performance mode is also a rammap entry, helps coalesce entries
+ * later on */
+u32
+nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size,
+ struct nvbios_ramcfg *p)
+{
+ memset(p, 0x00, sizeof(*p));
+
+ p->rammap_00_16_20 = (nv_ro08(bios, data + 0x16) & 0x20) >> 5;
+ p->rammap_00_16_40 = (nv_ro08(bios, data + 0x16) & 0x40) >> 6;
+ p->rammap_00_17_02 = (nv_ro08(bios, data + 0x17) & 0x02) >> 1;
+
+ return data;
+}
+
u32
nvbios_rammapEp(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 51f93a0..e720842 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -168,6 +168,8 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
}
} while (perfE.memory < freq);
+ nvbios_rammapEp_from_perf(bios, data, hdr, &next->bios);
+
/* locate specific data set for the attached memory */
strap = nvbios_ramcfg_index(nv_subdev(pfb));
if (strap >= cnt) {
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/9] nvkm/bios/ramcfg: Separate out RON pull value
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (4 preceding siblings ...)
2015-05-22 22:33 ` [PATCH 5/9] nvkm/bios/rammap: Parse perf mode as if it's a rammap entry Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 7/9] nvkm/fb/ramnv50: GDDR3 script for NVA0 Roy Spliet
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 1 +
drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 3 ++-
drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c | 2 ++
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c | 6 ++++--
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 26e233a..3a9abd3 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -38,6 +38,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_hdr;
unsigned ramcfg_timing;
unsigned ramcfg_DLLoff;
+ unsigned ramcfg_RON;
union {
struct {
unsigned ramcfg_00_03_01:1;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 8da8b26..5815f42 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -164,12 +164,13 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
if (size < 11)
return NULL;
+ p->ramcfg_ver = 0;
p->ramcfg_timing = nv_ro08(bios, data + 0x01);
p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
p->ramcfg_DLLoff = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
- p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
+ p->ramcfg_RON = (nv_ro08(bios, data + 0x03) & 0x10) >> 3;
p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
index 763fd29..bacd433 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
@@ -102,6 +102,8 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
p->timing_10_RRD = nv_ro08(bios, data + 0x0c);
p->timing_10_13 = nv_ro08(bios, data + 0x0d);
p->timing_10_ODT = nv_ro08(bios, data + 0x0e) & 0x07;
+ if (p->ramcfg_ver >= 0x10)
+ p->ramcfg_RON = nv_ro08(bios, data + 0x0e) & 0x07;
p->timing_10_24 = 0xff;
p->timing_10_21 = 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index e1d11f7..8d759f8a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -70,7 +70,7 @@ ramgddr3_wr_lo[] = {
int
nvkm_gddr3_calc(struct nvkm_ram *ram)
{
- int CL, WR, CWL, DLL = 0, ODT = 0, hi;
+ int CL, WR, CWL, DLL = 0, ODT = 0, RON, hi;
switch (ram->next->bios.timing_ver) {
case 0x10:
@@ -79,6 +79,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
WR = ram->next->bios.timing_10_WR;
DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT;
+ RON = ram->next->bios.ramcfg_RON;
break;
case 0x20:
CWL = (ram->next->bios.timing[1] & 0x00000f80) >> 7;
@@ -89,6 +90,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
ODT = (ram->mr[1] & 0x004) >> 2 |
(ram->mr[1] & 0x040) >> 5 |
(ram->mr[1] & 0x200) >> 7;
+ RON = !(ram->mr[1] & 0x300) >> 8;
break;
default:
return -ENOSYS;
@@ -107,7 +109,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
ram->mr[1] &= ~0x3fc;
ram->mr[1] |= (ODT & 0x03) << 2;
- ram->mr[1] |= (ODT & 0x03) << 8;
+ ram->mr[1] |= (RON & 0x03) << 8;
ram->mr[1] |= (WR & 0x03) << 4;
ram->mr[1] |= (WR & 0x04) << 5;
ram->mr[1] |= !DLL << 6;
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/9] nvkm/fb/ramnv50: GDDR3 script for NVA0
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (5 preceding siblings ...)
2015-05-22 22:33 ` [PATCH 6/9] nvkm/bios/ramcfg: Separate out RON pull value Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 8/9] nvkm/fb/gddr3: Add a few CL and WR entries observed on GTX260 Roy Spliet
2015-05-22 22:33 ` [PATCH 9/9] nvkm/clk/nv50: Enable user reclocking for NVA0 Roy Spliet
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
This looks surprisingly similar to scripts on earlier cards as well
but they don't seem to work just yet. That... and I don't have any, which
makes it a tough job to reverse engineer.
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 129 ++++++++++++++++++-----
1 file changed, 104 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index e720842..03ee6b6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -39,10 +39,19 @@ struct nv50_ramseq {
struct hwsq_reg r_0x004008;
struct hwsq_reg r_0x00400c;
struct hwsq_reg r_0x00c040;
+ struct hwsq_reg r_0x100200;
struct hwsq_reg r_0x100210;
+ struct hwsq_reg r_0x10021c;
struct hwsq_reg r_0x1002d0;
struct hwsq_reg r_0x1002d4;
struct hwsq_reg r_0x1002dc;
+ struct hwsq_reg r_0x10053c;
+ struct hwsq_reg r_0x1005a0;
+ struct hwsq_reg r_0x1005a4;
+ struct hwsq_reg r_0x100710;
+ struct hwsq_reg r_0x100714;
+ struct hwsq_reg r_0x100718;
+ struct hwsq_reg r_0x10071c;
struct hwsq_reg r_0x100da0;
struct hwsq_reg r_0x100e20;
struct hwsq_reg r_0x100e24;
@@ -134,7 +143,13 @@ nv50_ram_timing_calc(struct nvkm_fb *pfb, u32 *timing)
}
#undef T
-#define QFX5800NVA0 1
+static void
+nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq)
+{
+ ram_mask(hwsq, mr[0], 0x100, 0x100);
+ ram_mask(hwsq, mr[0], 0x100, 0x000);
+ ram_nsec(hwsq, 24000);
+}
static int
nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
@@ -147,7 +162,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
struct nvkm_ram_data *next;
u8 ver, hdr, cnt, len, strap, size;
u32 data;
- u32 r100da0;
+ u32 r100da0, r004008, unk710, unk714, unk718, unk71c;
int N1, M1, N2, M2, P;
int ret, i;
u32 timing[9];
@@ -219,12 +234,8 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
if (ret)
return ret;
- /* XXX: where the fuck does 750MHz come from? */
- if (freq <= 750000) {
- r100da0 = 0x00000010;
- } else {
- r100da0 = 0x00000000;
- }
+ /* Always disable this bit during reclock */
+ ram_mask(hwsq, 0x100200, 0x00000800, 0x00000000);
ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
@@ -233,6 +244,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_nsec(hwsq, 8000);
ram_setf(hwsq, 0x10, 0x00); /* disable fb */
ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
+ ram_nsec(hwsq, 2000);
ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */
ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
@@ -252,18 +264,33 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
if (ret < 0)
return ret;
+ /* XXX: where the fuck does 750MHz come from? */
+ if (freq <= 750000) {
+ r100da0 = 0x00000010;
+ r004008 = 0x90000000;
+ } else {
+ r100da0 = 0x00000000;
+ r004008 = 0x80000000;
+ }
+
+ r004008 |= (mpll.bias_p << 19) | (P << 22) | (P << 16);
+
ram_mask(hwsq, 0x00c040, 0xc000c000, 0x0000c000);
- ram_mask(hwsq, 0x004008, 0x00000200, 0x00000200);
+ /* XXX: Is rammap_00_16_40 the DLL bit we've seen in GT215? Why does
+ * it have a different rammap bit from DLLoff? */
+ ram_mask(hwsq, 0x004008, 0x00004200, 0x00000200 |
+ next->bios.rammap_00_16_40 << 14);
ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
- ram_mask(hwsq, 0x004008, 0x81ff0000, 0x80000000 | (mpll.bias_p << 19) |
- (P << 22) | (P << 16));
+ ram_mask(hwsq, 0x004008, 0x91ff0000, r004008);
+ if (nv_device(pfb)->chipset >= 0x96)
+ ram_wr32(hwsq, 0x100da0, r100da0);
+ ram_nsec(hwsq, 64000); /*XXX*/
+ ram_nsec(hwsq, 32000); /*XXX*/
- if (nv_device(pfb)->chipset == 0xa0)
- ram_wr32(hwsq, 0x100da0, r100da0); /*XXX: here?*/
- ram_nsec(hwsq, 96000); /*XXX*/
ram_mask(hwsq, 0x004008, 0x00002200, 0x00002000);
ram_wr32(hwsq, 0x1002dc, 0x00000000); /* disable self-refresh */
+ ram_wr32(hwsq, 0x1002d4, 0x00000001); /* disable self-refresh */
ram_wr32(hwsq, 0x100210, 0x80000000); /* enable auto-refresh */
ram_nsec(hwsq, 12000);
@@ -274,9 +301,10 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_mask(hwsq, mr[0], 0x000, 0x000);
break;
case NV_MEM_TYPE_GDDR3:
- ram_mask(hwsq, mr[2], 0x000, 0x000);
+ ram_nuke(hwsq, mr[1]); /* force update */
+ ram_wr32(hwsq, mr[1], ram->base.mr[1]);
ram_nuke(hwsq, mr[0]); /* force update */
- ram_mask(hwsq, mr[0], 0x000, 0x000);
+ ram_wr32(hwsq, mr[0], ram->base.mr[0]);
break;
default:
break;
@@ -292,20 +320,62 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_mask(hwsq, timing[4], 0xffffffff, timing[4]);
ram_mask(hwsq, timing[5], 0xffffffff, timing[5]);
-#if QFX5800NVA0
- ram_nuke(hwsq, 0x100e24);
- ram_mask(hwsq, 0x100e24, 0x00000000, 0x00000000);
- ram_nuke(hwsq, 0x100e20);
- ram_mask(hwsq, 0x100e20, 0x00000000, 0x00000000);
-#endif
+ if (!next->bios.ramcfg_00_03_02)
+ ram_mask(hwsq, 0x10021c, 0x00010000, 0x00000000);
+ ram_mask(hwsq, 0x100200, 0x00001000, !next->bios.ramcfg_00_04_02 << 12);
+
+ /* XXX: A lot of this could be "chipset"/"ram type" specific stuff */
+ unk710 = ram_rd32(hwsq, 0x100710) & ~0x00000101;
+ unk714 = ram_rd32(hwsq, 0x100714) & ~0xf0000020;
+ unk718 = ram_rd32(hwsq, 0x100718) & ~0x00000100;
+ unk71c = ram_rd32(hwsq, 0x10071c) & ~0x00000100;
+
+ if ( next->bios.ramcfg_00_03_01)
+ unk71c |= 0x00000100;
+ if ( next->bios.ramcfg_00_03_02)
+ unk710 |= 0x00000100;
+ if (!next->bios.ramcfg_00_03_08) {
+ unk710 |= 0x1;
+ unk714 |= 0x20;
+ }
+ if ( next->bios.ramcfg_00_04_04)
+ unk714 |= 0x70000000;
+ if ( next->bios.ramcfg_00_04_20)
+ unk718 |= 0x00000100;
+
+ ram_mask(hwsq, 0x100714, 0xffffffff, unk714);
+ ram_mask(hwsq, 0x10071c, 0xffffffff, unk71c);
+ ram_mask(hwsq, 0x100718, 0xffffffff, unk718);
+ ram_mask(hwsq, 0x100710, 0xffffffff, unk710);
+
+ if (next->bios.rammap_00_16_20) {
+ ram_wr32(hwsq, 0x1005a0, next->bios.ramcfg_00_07 << 16 |
+ next->bios.ramcfg_00_06 << 8 |
+ next->bios.ramcfg_00_05);
+ ram_wr32(hwsq, 0x1005a4, next->bios.ramcfg_00_09 << 8 |
+ next->bios.ramcfg_00_08);
+ ram_mask(hwsq, 0x10053c, 0x00001000, 0x00000000);
+ } else {
+ ram_mask(hwsq, 0x10053c, 0x00001000, 0x00001000);
+ }
+ ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]);
- ram_mask(hwsq, mr[0], 0x100, 0x100);
- ram_mask(hwsq, mr[0], 0x100, 0x000);
+ /* Reset DLL */
+ if (!next->bios.ramcfg_DLLoff)
+ nvkm_sddr2_dll_reset(hwsq);
ram_setf(hwsq, 0x10, 0x01); /* enable fb */
ram_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */
ram_wr32(hwsq, 0x611200, 0x00003330);
ram_wr32(hwsq, 0x002504, 0x00000000); /* un-block fifo */
+
+ if (next->bios.rammap_00_17_02)
+ ram_mask(hwsq, 0x100200, 0x00000800, 0x00000800);
+ if (!next->bios.rammap_00_16_40)
+ ram_mask(hwsq, 0x004008, 0x00004000, 0x00000000);
+ if (next->bios.ramcfg_00_03_02)
+ ram_mask(hwsq, 0x10021c, 0x00010000, 0x00010000);
+
return 0;
}
@@ -521,12 +591,12 @@ nv50_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
return ret;
switch (ram->base.type) {
- case NV_MEM_TYPE_DDR2:
case NV_MEM_TYPE_GDDR3:
ram->base.calc = nv50_ram_calc;
ram->base.prog = nv50_ram_prog;
ram->base.tidy = nv50_ram_tidy;
break;
+ case NV_MEM_TYPE_DDR2:
default:
nv_warn(ram, "reclocking of this ram type unsupported\n");
return 0;
@@ -536,10 +606,19 @@ nv50_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
ram->hwsq.r_0x00c040 = hwsq_reg(0x00c040);
ram->hwsq.r_0x004008 = hwsq_reg(0x004008);
ram->hwsq.r_0x00400c = hwsq_reg(0x00400c);
+ ram->hwsq.r_0x100200 = hwsq_reg(0x100200);
ram->hwsq.r_0x100210 = hwsq_reg(0x100210);
+ ram->hwsq.r_0x10021c = hwsq_reg(0x10021c);
ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0);
ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4);
ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc);
+ ram->hwsq.r_0x10053c = hwsq_reg(0x10053c);
+ ram->hwsq.r_0x1005a0 = hwsq_reg(0x1005a0);
+ ram->hwsq.r_0x1005a4 = hwsq_reg(0x1005a4);
+ ram->hwsq.r_0x100710 = hwsq_reg(0x100710);
+ ram->hwsq.r_0x100714 = hwsq_reg(0x100714);
+ ram->hwsq.r_0x100718 = hwsq_reg(0x100718);
+ ram->hwsq.r_0x10071c = hwsq_reg(0x10071c);
ram->hwsq.r_0x100da0 = hwsq_stride(0x100da0, 4, ram->base.part_mask);
ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20);
ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24);
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 8/9] nvkm/fb/gddr3: Add a few CL and WR entries observed on GTX260
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (6 preceding siblings ...)
2015-05-22 22:33 ` [PATCH 7/9] nvkm/fb/ramnv50: GDDR3 script for NVA0 Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 9/9] nvkm/clk/nv50: Enable user reclocking for NVA0 Roy Spliet
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 8d759f8a..4465446 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -42,9 +42,9 @@ ramxlat(const struct ramxlat *xlat, int id)
static const struct ramxlat
ramgddr3_cl_lo[] = {
- { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 },
+ { 5, 5 }, { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 }, { 12, 8 },
/* the below are mentioned in some, but not all, gddr3 docs */
- { 12, 4 }, { 13, 5 }, { 14, 6 },
+ { 13, 9 }, { 14, 6 },
/* XXX: Per Samsung docs, are these used? They overlap with Qimonda */
/* { 4, 4 }, { 5, 5 }, { 6, 6 }, { 12, 8 }, { 13, 9 }, { 14, 10 },
* { 15, 11 }, */
@@ -61,9 +61,9 @@ ramgddr3_cl_hi[] = {
static const struct ramxlat
ramgddr3_wr_lo[] = {
{ 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
- { 11, 0 },
+ { 11, 0 }, { 13 , 1 },
/* the below are mentioned in some, but not all, gddr3 docs */
- { 4, 1 }, { 6, 3 }, { 12, 1 }, { 13 , 2 },
+ { 4, 1 }, { 6, 3 }, { 12, 1 },
{ -1 }
};
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 9/9] nvkm/clk/nv50: Enable user reclocking for NVA0
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
` (7 preceding siblings ...)
2015-05-22 22:33 ` [PATCH 8/9] nvkm/fb/gddr3: Add a few CL and WR entries observed on GTX260 Roy Spliet
@ 2015-05-22 22:33 ` Roy Spliet
8 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-22 22:33 UTC (permalink / raw)
To: Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ, "Mailinglist <nouveau",
Ben Skeggs
Cc: Roy Spliet
Tested on a few cards. Probably works quite well for most, given they should
all be GDDR3.
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
---
drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
index 9b4ffd6..89c5d88 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
@@ -509,7 +509,8 @@ nv50_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
int ret;
ret = nvkm_clk_create(parent, engine, oclass, pclass->domains,
- NULL, 0, false, &priv);
+ NULL, 0, nv_device(parent)->chipset == 0xa0,
+ &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
--
2.1.0
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/9] nvkm/fb/ramnv50: Make 0x100da0 per-partition
[not found] ` <1432334028-15234-4-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
@ 2015-05-22 22:44 ` Ilia Mirkin
0 siblings, 0 replies; 13+ messages in thread
From: Ilia Mirkin @ 2015-05-22 22:44 UTC (permalink / raw)
To: Roy Spliet
Cc: "Mailinglist <nouveau", Ben Skeggs,
Nouveau-CC+yJ3UmIYqDUpFQwHEjaQ
On Fri, May 22, 2015 at 6:33 PM, Roy Spliet <rspliet@eclipso.eu> wrote:
> Like on GT215
>
> Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
> ---
> drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 20 +++++++++++++-------
> 1 file changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> index d2c81dd..a96e512 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> @@ -42,7 +42,7 @@ struct nv50_ramseq {
> struct hwsq_reg r_0x1002d0;
> struct hwsq_reg r_0x1002d4;
> struct hwsq_reg r_0x1002dc;
> - struct hwsq_reg r_0x100da0[8];
> + struct hwsq_reg r_0x100da0;
> struct hwsq_reg r_0x100e20;
> struct hwsq_reg r_0x100e24;
> struct hwsq_reg r_0x611200;
> @@ -70,6 +70,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> u8 size;
> } ramcfg, timing;
> u8 ver, hdr, cnt, len, strap;
> + u32 r100da0;
> int N1, M1, N2, M2, P;
> int ret, i;
>
> @@ -109,6 +110,13 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> timing.data = 0;
> }
>
> + /* XXX: where the fuck does 750MHz come from? */
s/the fuck//
> + if (freq <= 750000) {
> + r100da0 = 0x00000010;
> + } else {
> + r100da0 = 0x00000000;
> + }
> +
> ret = ram_init(hwsq, nv_subdev(pfb));
> if (ret)
> return ret;
> @@ -144,10 +152,9 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
> ram_mask(hwsq, 0x004008, 0x81ff0000, 0x80000000 | (mpll.bias_p << 19) |
> (P << 22) | (P << 16));
> -#if QFX5800NVA0
> - for (i = 0; i < 8; i++)
> - ram_mask(hwsq, 0x100da0[i], 0x00000000, 0x00000000); /*XXX*/
> -#endif
> +
> + if (nv_device(pfb)->chipset == 0xa0)
Don't think this is quite right... probably more like vram == GDDR3. I
definitely remember seeing non-nva0 cards writing 100da0 in the
scripts.
> + ram_wr32(hwsq, 0x100da0, r100da0); /*XXX: here?*/
> ram_nsec(hwsq, 96000); /*XXX*/
> ram_mask(hwsq, 0x004008, 0x00002200, 0x00002000);
>
> @@ -430,8 +437,7 @@ nv50_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
> ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0);
> ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4);
> ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc);
> - for (i = 0; i < 8; i++)
> - ram->hwsq.r_0x100da0[i] = hwsq_reg(0x100da0 + (i * 0x04));
> + ram->hwsq.r_0x100da0 = hwsq_stride(0x100da0, 4, ram->base.part_mask);
> ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20);
> ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24);
> ram->hwsq.r_0x611200 = hwsq_reg(0x611200);
> --
> 2.1.0
>
>
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers
[not found] ` <1432334028-15234-5-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
@ 2015-05-22 23:00 ` Tobias Klausmann
[not found] ` <555FB501.4010206-AqjdNwhu20eELgA04lAiVw@public.gmane.org>
0 siblings, 1 reply; 13+ messages in thread
From: Tobias Klausmann @ 2015-05-22 23:00 UTC (permalink / raw)
To: Roy Spliet, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
On 23.05.2015 00:33, Roy Spliet wrote:
> Might need some generalisation to < GT200. For those: use at your own risk!
>
> Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
> ---
> .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 16 ++
> .../drm/nouveau/include/nvkm/subdev/bios/rammap.h | 2 +
> drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 29 ++++
> drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 167 +++++++++++++++++----
> 4 files changed, 181 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> index c6fb6aa..f09b6bf 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> @@ -35,6 +35,22 @@ struct nvbios_ramcfg {
> unsigned ramcfg_DLLoff;
> union {
> struct {
> + unsigned ramcfg_00_03_01:1;
> + unsigned ramcfg_00_03_02:1;
> + unsigned ramcfg_00_03_08:1;
> + unsigned ramcfg_00_03_10:1;
> + unsigned ramcfg_00_04_02:1;
> + unsigned ramcfg_00_04_04:1;
> + unsigned ramcfg_00_04_20:1;
> + unsigned ramcfg_00_05:8;
> + unsigned ramcfg_00_06:8;
> + unsigned ramcfg_00_07:8;
> + unsigned ramcfg_00_08:8;
> + unsigned ramcfg_00_09:8;
> + unsigned ramcfg_00_0a_0f:4;
> + unsigned ramcfg_00_0a_f0:4;
> + };
> + struct {
> unsigned ramcfg_10_02_01:1;
> unsigned ramcfg_10_02_02:1;
> unsigned ramcfg_10_02_04:1;
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
> index 609a905..2044fc9 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
> @@ -15,6 +15,8 @@ u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
> u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
> u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
> u8 *ver, u8 *hdr);
> +u32 nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
> + struct nvbios_ramcfg *p);
> u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
> u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
> u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
> index a688d3b..4ec376a 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
> @@ -141,6 +141,35 @@ nvbios_rammapSe(struct nvkm_bios *bios, u32 data,
> }
>
> u32
> +nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
> + struct nvbios_ramcfg *p)
> +{
> + data += (idx * size);
> +
> + if (size < 11)
> + return NULL;
> +
> + p->ramcfg_timing = nv_ro08(bios, data + 0x01);
> + p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
> + p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
> + p->ramcfg_DLLoff = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
> + p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
> + p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
> + p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
> + p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
> + p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
> + p->ramcfg_00_05 = (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
> + p->ramcfg_00_06 = (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
> + p->ramcfg_00_07 = (nv_ro08(bios, data + 0x07) & 0xff) >> 0;
> + p->ramcfg_00_08 = (nv_ro08(bios, data + 0x08) & 0xff) >> 0;
> + p->ramcfg_00_09 = (nv_ro08(bios, data + 0x09) & 0xff) >> 0;
> + p->ramcfg_00_0a_0f = (nv_ro08(bios, data + 0x0a) & 0x0f) >> 0;
> + p->ramcfg_00_0a_f0 = (nv_ro08(bios, data + 0x0a) & 0xf0) >> 4;
> +
> + return data;
> +}
> +
> +u32
> nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
> u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
> u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> index a96e512..51f93a0 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> @@ -29,6 +29,7 @@
> #include <subdev/bios.h>
> #include <subdev/bios/perf.h>
> #include <subdev/bios/pll.h>
> +#include <subdev/bios/rammap.h>
> #include <subdev/bios/timing.h>
> #include <subdev/clk/pll.h>
>
> @@ -55,6 +56,84 @@ struct nv50_ram {
> struct nv50_ramseq hwsq;
> };
>
> +#define T(t) cfg->timing_10_##t
> +static int
> +nv50_ram_timing_calc(struct nvkm_fb *pfb, u32 *timing)
> +{
> + struct nv50_ram *ram = (void *)pfb->ram;
> + struct nvbios_ramcfg *cfg = &ram->base.target.bios;
> + u32 cur2, cur3, cur4, cur7, cur8;
> + u8 unkt3b;
> +
> + cur2 = nv_rd32(pfb, 0x100228);
> + cur3 = nv_rd32(pfb, 0x10022c);
> + cur4 = nv_rd32(pfb, 0x100230);
> + cur7 = nv_rd32(pfb, 0x10023c);
> + cur8 = nv_rd32(pfb, 0x100240);
> +
> + switch ((!T(CWL)) * ram->base.type) {
> + case NV_MEM_TYPE_DDR2:
> + T(CWL) = T(CL) - 1;
> + break;
> + case NV_MEM_TYPE_GDDR3:
> + T(CWL) = ((cur2 & 0xff000000) >> 24) + 1;
> + break;
> + }
> +
> + /* XXX: N=1 is not proper statistics */
> + if (nv_device(pfb)->chipset == 0xa0) {
> + unkt3b = 0x19 + ram->base.next->bios.rammap_00_16_40;
> + timing[6] = (0x2d + T(CL) - T(CWL) + ram->base.next->bios.rammap_00_16_40) << 16 |
> + T(CWL) << 8 |
> + (0x2f + T(CL) - T(CWL));
> + } else {
> + unkt3b = 0x16;
> + timing[6] = (0x2b + T(CL) - T(CWL)) << 16 |
> + max_t(s8, T(CWL) - 2, 1) << 8 |
> + (0x2e + T(CL) - T(CWL));
> + }
> +
> + timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) << 8 | T(RC));
> + timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
> + max_t(u8, T(18), 1) << 16 |
> + (T(WTR) + 1 + T(CWL)) << 8 |
> + (3 + T(CL) - T(CWL));
> + timing[2] = (T(CWL) - 1) << 24 |
> + (T(RRD) << 16) |
> + (T(RCDWR) << 8) |
> + T(RCDRD);
> + timing[3] = (unkt3b - 2 + T(CL)) << 24 |
> + unkt3b << 16 |
> + (T(CL) - 1) << 8 |
> + (T(CL) - 1);
> + timing[4] = (cur4 & 0xffff0000) |
> + T(13) << 8 |
> + T(13);
> + timing[5] = T(RFC) << 24 |
> + max_t(u8, T(RCDRD), T(RCDWR)) << 16 |
> + T(RP);
> + /* Timing 6 is already done above */
> + timing[7] = (cur7 & 0xff00ffff) | (T(CL) - 1) << 16;
> + timing[8] = (cur8 & 0xffffff00);
> +
> + /* XXX: P.version == 1 only has DDR2 and GDDR3? */
mh can you state both (DDR2/GDDR3) here and bail out on default as well?
> + if (pfb->ram->type == NV_MEM_TYPE_DDR2) {
> + timing[5] |= (T(CL) + 3) << 8;
> + timing[8] |= (T(CL) - 4);
> + } else {
> + timing[5] |= (T(CL) + 2) << 8;
> + timing[8] |= (T(CL) - 2);
> + }
> +
> + nv_debug(pfb, " 220: %08x %08x %08x %08x\n",
> + timing[0], timing[1], timing[2], timing[3]);
> + nv_debug(pfb, " 230: %08x %08x %08x %08x\n",
> + timing[4], timing[5], timing[6], timing[7]);
> + nv_debug(pfb, " 240: %08x\n", timing[8]);
> + return 0;
> +}
> +#undef T
> +
> #define QFX5800NVA0 1
>
> static int
> @@ -65,22 +144,25 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> struct nv50_ramseq *hwsq = &ram->hwsq;
> struct nvbios_perfE perfE;
> struct nvbios_pll mpll;
> - struct {
> - u32 data;
> - u8 size;
> - } ramcfg, timing;
> - u8 ver, hdr, cnt, len, strap;
> + struct nvkm_ram_data *next;
> + u8 ver, hdr, cnt, len, strap, size;
> + u32 data;
> u32 r100da0;
> int N1, M1, N2, M2, P;
> int ret, i;
> + u32 timing[9];
> +
> + next = &ram->base.target;
> + next->freq = freq;
> + ram->base.next = next;
>
> /* lookup closest matching performance table entry for frequency */
> i = 0;
> do {
> - ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
> - &ramcfg.size, &perfE);
> - if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) ||
> - (ramcfg.size < 2)) {
> + data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
> + &size, &perfE);
> + if (!data || (ver < 0x25 || ver >= 0x40) ||
> + (size < 2)) {
> nv_error(pfb, "invalid/missing perftab entry\n");
> return -EINVAL;
> }
> @@ -93,23 +175,48 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> return -EINVAL;
> }
>
> - ramcfg.data += hdr + (strap * ramcfg.size);
> + data = nvbios_rammapSp_from_perf(bios, data + hdr, size, strap,
> + &next->bios);
> + if (!data) {
> + nv_error(pfb, "invalid/missing rammap entry ");
> + return -EINVAL;
> + }
>
> /* lookup memory timings, if bios says they're present */
> - strap = nv_ro08(bios, ramcfg.data + 0x01);
> - if (strap != 0xff) {
> - timing.data = nvbios_timingEe(bios, strap, &ver, &hdr,
> - &cnt, &len);
> - if (!timing.data || ver != 0x10 || hdr < 0x12) {
> + if (next->bios.ramcfg_timing != 0xff) {
> + data = nvbios_timingEp(bios, next->bios.ramcfg_timing,
> + &ver, &hdr, &cnt, &len, &next->bios);
> + if (!data || ver != 0x10 || hdr < 0x12) {
> nv_error(pfb, "invalid/missing timing entry "
> "%02x %04x %02x %02x\n",
> - strap, timing.data, ver, hdr);
> + strap, data, ver, hdr);
> return -EINVAL;
> }
> - } else {
> - timing.data = 0;
> }
>
> + nv50_ram_timing_calc(pfb, timing);
> +
> + ret = ram_init(hwsq, nv_subdev(pfb));
> + if (ret)
> + return ret;
> +
> + /* Determine ram-specific MR values */
> + ram->base.mr[0] = ram_rd32(hwsq, mr[0]);
> + ram->base.mr[1] = ram_rd32(hwsq, mr[1]);
> + ram->base.mr[2] = ram_rd32(hwsq, mr[2]);
> +
> + switch (ram->base.type) {
> + case NV_MEM_TYPE_GDDR3:
> + ret = nvkm_gddr3_calc(&ram->base);
> + break;
> + default:
> + ret = -ENOSYS;
> + break;
> + }
> +
> + if (ret)
> + return ret;
> +
> /* XXX: where the fuck does 750MHz come from? */
get rid of that swearing...
> if (freq <= 750000) {
> r100da0 = 0x00000010;
> @@ -117,10 +224,6 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> r100da0 = 0x00000000;
> }
>
> - ret = ram_init(hwsq, nv_subdev(pfb));
> - if (ret)
> - return ret;
> -
> ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
> ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
> ram_wr32(hwsq, 0x611200, 0x00003300);
> @@ -177,17 +280,15 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
> break;
> }
>
> - ram_mask(hwsq, timing[3], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[1], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[6], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[7], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[8], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[2], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[4], 0x00000000, 0x00000000); /*XXX*/
> - ram_mask(hwsq, timing[5], 0x00000000, 0x00000000); /*XXX*/
> -
> - ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
> + ram_mask(hwsq, timing[3], 0xffffffff, timing[3]);
> + ram_mask(hwsq, timing[1], 0xffffffff, timing[1]);
> + ram_mask(hwsq, timing[6], 0xffffffff, timing[6]);
> + ram_mask(hwsq, timing[7], 0xffffffff, timing[7]);
> + ram_mask(hwsq, timing[8], 0xffffffff, timing[8]);
> + ram_mask(hwsq, timing[0], 0xffffffff, timing[0]);
> + ram_mask(hwsq, timing[2], 0xffffffff, timing[2]);
> + ram_mask(hwsq, timing[4], 0xffffffff, timing[4]);
> + ram_mask(hwsq, timing[5], 0xffffffff, timing[5]);
>
> #if QFX5800NVA0
> ram_nuke(hwsq, 0x100e24);
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers
[not found] ` <555FB501.4010206-AqjdNwhu20eELgA04lAiVw@public.gmane.org>
@ 2015-05-23 8:35 ` Roy Spliet
0 siblings, 0 replies; 13+ messages in thread
From: Roy Spliet @ 2015-05-23 8:35 UTC (permalink / raw)
To: Tobias Klausmann; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Hello Tobias,
Reply inline.
--- original message ---
From: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Date: 01:00:17 23-05-2015
To: Roy Spliet <rspliet@eclipso.eu>, nouveau@lists.freedesktop.org
Subject: Re: [Nouveau] [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers
> On 23.05.2015 00:33, Roy Spliet wrote:
> > Might need some generalisation to < GT200. For those: use at your
> own risk!
> >
> > Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
> > ---
> > .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 16 ++
> > .../drm/nouveau/include/nvkm/subdev/bios/rammap.h | 2 +
> > drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 29 ++++
> > drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 167 +++++++++++++++++----
>
> > 4 files changed, 181 insertions(+), 33 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> > index c6fb6aa..f09b6bf 100644
[...]
> > + timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) <<
> 8 | T(RC));
> > + timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
> > + max_t(u8, T(18), 1) << 16 |
> > + (T(WTR) + 1 + T(CWL)) << 8 |
> > + (3 + T(CL) - T(CWL));
> > + timing[2] = (T(CWL) - 1) << 24 |
> > + (T(RRD) << 16) |
> > + (T(RCDWR) << 8) |
> > + T(RCDRD);
> > + timing[3] = (unkt3b - 2 + T(CL)) << 24 |
> > + unkt3b << 16 |
> > + (T(CL) - 1) << 8 |
> > + (T(CL) - 1);
> > + timing[4] = (cur4 & 0xffff0000) |
> > + T(13) << 8 |
> > + T(13);
> > + timing[5] = T(RFC) << 24 |
> > + max_t(u8, T(RCDRD), T(RCDWR)) << 16 |
> > + T(RP);
> > + /* Timing 6 is already done above */
> > + timing[7] = (cur7 & 0xff00ffff) | (T(CL) - 1) << 16;
> > + timing[8] = (cur8 & 0xffffff00);
> > +
> > + /* XXX: P.version == 1 only has DDR2 and GDDR3? */
>
> mh can you state both (DDR2/GDDR3) here and bail out on default as well?
This type of error checking is way earlier, in nv50_ram_ctor(). Hence, this code will
currently only be executed with GDDR3 cards, I just didn't feel it's justified to remove
DDR2 conditional code that I investigated years ago, otherwise it would have been even
slightly cleaner.
Roy
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2015-05-23 8:35 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-22 22:33 Reclocking support for NVA0 Roy Spliet
[not found] ` <1432334028-15234-1-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:33 ` [PATCH 1/9] nvkm/clk/gt215: u32->s32 for difference in req. and set clock Roy Spliet
2015-05-22 22:33 ` [PATCH 2/9] nvkm/bios/rammap: Pull DLLoff bit out of version 0x10 struct Roy Spliet
2015-05-22 22:33 ` [PATCH 3/9] nvkm/fb/ramnv50: Make 0x100da0 per-partition Roy Spliet
[not found] ` <1432334028-15234-4-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 22:44 ` Ilia Mirkin
2015-05-22 22:33 ` [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers Roy Spliet
[not found] ` <1432334028-15234-5-git-send-email-rspliet-pPYjZ15w/Xhulxpn9UvDqw@public.gmane.org>
2015-05-22 23:00 ` Tobias Klausmann
[not found] ` <555FB501.4010206-AqjdNwhu20eELgA04lAiVw@public.gmane.org>
2015-05-23 8:35 ` Roy Spliet
2015-05-22 22:33 ` [PATCH 5/9] nvkm/bios/rammap: Parse perf mode as if it's a rammap entry Roy Spliet
2015-05-22 22:33 ` [PATCH 6/9] nvkm/bios/ramcfg: Separate out RON pull value Roy Spliet
2015-05-22 22:33 ` [PATCH 7/9] nvkm/fb/ramnv50: GDDR3 script for NVA0 Roy Spliet
2015-05-22 22:33 ` [PATCH 8/9] nvkm/fb/gddr3: Add a few CL and WR entries observed on GTX260 Roy Spliet
2015-05-22 22:33 ` [PATCH 9/9] nvkm/clk/nv50: Enable user reclocking for NVA0 Roy Spliet
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.