All of lore.kernel.org
 help / color / mirror / Atom feed
* Preparations for Fermi DRAM clock changes
@ 2017-04-10 19:37 Roy Spliet
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

No, no, these will not implement Fermi reclocking. This set of patches
contains some of the preparatory work that I deem stable enough to
move upstream. Notable changes
- Training pattern upload routines from GK104+ now shared with GT215+
- Timing calculation for Fermi
- GDDR5 MR calculation from VBIOS timing table v1.0. Also useful for that
  pesky GT 240.
- A routine to translate a VBIOS init script to a set of memx writes.
  Used by both "that GT 240" and Fermi.
- Misc clean-up

Testers should expect no changes in behaviour before/after. Keen eyes
can double-check on their Tesla and Fermi GDDR5 graphics cards that
training patterns are uploaded on boot.

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 01/11] nvkm/ramgf100: Get rid of (size, data) pairs for rammap, ramcfg, timing
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 02/11] nvkm/ramgf100: Calculate timings Roy Spliet
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

In correspondence with the other ram_calc implementations.

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 37 ++++++++++++-----------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 093223d..fffd01a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -133,21 +133,22 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 	struct nvkm_device *device = subdev->device;
 	struct nvkm_clk *clk = device->clk;
 	struct nvkm_bios *bios = device->bios;
-	struct nvbios_ramcfg cfg;
-	u8  ver, cnt, len, strap;
-	struct {
-		u32 data;
-		u8  size;
-	} rammap, ramcfg, timing;
+	struct nvkm_ram_data *next;
+	u8  ver, hdr, cnt, len, strap;
+	u32 data;
 	int ref, div, out;
 	int from, mode;
 	int N1, M1, P;
 	int ret;
 
+	next = &ram->base.target;
+	next->freq = freq;
+	ram->base.next = next;
+
 	/* lookup memory config data relevant to the target frequency */
-	rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
-				      &cnt, &ramcfg.size, &cfg);
-	if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
+	data = nvbios_rammapEm(bios, freq / 1000, &ver, &hdr,
+				      &cnt, &len, &next->bios);
+	if (!data || ver != 0x10 || len < 0x0e) {
 		nvkm_error(subdev, "invalid/missing rammap entry\n");
 		return -EINVAL;
 	}
@@ -159,23 +160,23 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		return -EINVAL;
 	}
 
-	ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
-	if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
+	data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, strap,
+				       &ver, &hdr, &next->bios);
+	if (!data || ver != 0x10 || hdr < 0x0e) {
 		nvkm_error(subdev, "invalid/missing ramcfg entry\n");
 		return -EINVAL;
 	}
 
 	/* lookup memory timings, if bios says they're present */
-	strap = nvbios_rd08(bios, ramcfg.data + 0x01);
-	if (strap != 0xff) {
-		timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
-					      &cnt, &len);
-		if (!timing.data || ver != 0x10 || timing.size < 0x19) {
+	strap = nvbios_rd08(bios, data + 0x01);
+	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 < 0x17) {
 			nvkm_error(subdev, "invalid/missing timing entry\n");
 			return -EINVAL;
 		}
-	} else {
-		timing.data = 0;
 	}
 
 	ret = ram_init(fuc, ram->base.fb);
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 02/11] nvkm/ramgf100: Calculate timings
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
  2017-04-10 19:37   ` [PATCH 01/11] nvkm/ramgf100: Get rid of (size, data) pairs for rammap, ramcfg, timing Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 03/11] nvkm/gddr5: MR calculation for timing table v1.0 Roy Spliet
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Todo:
- Determine source of R[10f298] & 0x11

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 115 ++++++++++++++--------
 1 file changed, 76 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index fffd01a..6ebdc4c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -48,11 +48,7 @@ struct gf100_ramfuc {
 
 	struct ramfuc_reg r_0x137390;
 
-	struct ramfuc_reg r_0x10f290;
-	struct ramfuc_reg r_0x10f294;
-	struct ramfuc_reg r_0x10f298;
-	struct ramfuc_reg r_0x10f29c;
-	struct ramfuc_reg r_0x10f2a0;
+	struct ramfuc_reg r_0x10f290[5];
 
 	struct ramfuc_reg r_0x10f300;
 	struct ramfuc_reg r_0x10f338;
@@ -104,6 +100,50 @@ struct gf100_ram {
 	struct nvbios_pll mempll;
 };
 
+#define T(t) cfg->timing_10_##t
+static int
+gf100_ram_timing_calc(struct gf100_ram *ram, u32 *timing)
+{
+	struct nvbios_ramcfg *cfg = &ram->base.target.bios;
+	struct nvkm_subdev *subdev = &ram->base.fb->subdev;
+	struct nvkm_device *device = subdev->device;
+	u32 cur1, cur2, cur4;
+
+	cur1 = nvkm_rd32(device, 0x10f294);
+	cur2 = nvkm_rd32(device, 0x10f298);
+	cur4 = nvkm_rd32(device, 0x10f2a0);
+
+	/* XXX: (G)DDR3? */
+	switch ((!T(CWL)) * ram->base.type) {
+	case NVKM_RAM_TYPE_GDDR5:
+		T(CWL) = (cur1 & 0x00000380) >> 7;
+		break;
+	}
+
+	timing[0] = (T(RP) << 24 | T(RAS) << 17 | T(RFC) << 8 | T(RC));
+	timing[1] = (cur1 & ~0x03ffc07f) |
+		    (T(RCDWR) << 20) |
+		    (T(RCDRD) << 14) |
+		    (T(CWL) << 7) |
+		    (T(CL));
+	/* XXX: lower 8 bytes are two bits indicating "feature(s) X" */
+	timing[2] = (cur2 & ~0x00ffffff) |
+		    (T(WR) << 16) |
+		    (T(WTR) << 8);
+	timing[3] = (T(FAW)) << 9 |
+		    (T(CKE)) << 5 |
+		    (T(XPDLL));
+	timing[4] = (cur4 & ~0x001f8000) |
+		    (T(RRD) << 15);
+
+	nvkm_debug(subdev, "Entry: 290: %08x %08x %08x %08x\n",
+		   timing[0], timing[1], timing[2], timing[3]);
+	nvkm_debug(subdev, "  2a0: %08x\n",
+		   timing[4]);
+	return 0;
+}
+#undef T
+
 static void
 gf100_ram_train(struct gf100_ramfuc *fuc, u32 magic)
 {
@@ -136,10 +176,11 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 	struct nvkm_ram_data *next;
 	u8  ver, hdr, cnt, len, strap;
 	u32 data;
+	u32 timing[5];
 	int ref, div, out;
 	int from, mode;
 	int N1, M1, P;
-	int ret;
+	int i, ret;
 
 	next = &ram->base.target;
 	next->freq = freq;
@@ -179,6 +220,8 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		}
 	}
 
+	gf100_ram_timing_calc(ram, timing);
+
 	ret = ram_init(fuc, ram->base.fb);
 	if (ret)
 		return ret;
@@ -314,28 +357,6 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		ram_wr32(fuc, 0x10f338, 0x00300220);
 		ram_wr32(fuc, 0x10f300, 0x0000011d);
 		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f290, 0x02060505);
-		ram_wr32(fuc, 0x10f294, 0x34208288);
-		ram_wr32(fuc, 0x10f298, 0x44050411);
-		ram_wr32(fuc, 0x10f29c, 0x0000114c);
-		ram_wr32(fuc, 0x10f2a0, 0x42e10069);
-		ram_wr32(fuc, 0x10f614, 0x40044f77);
-		ram_wr32(fuc, 0x10f610, 0x40044f77);
-		ram_wr32(fuc, 0x10f344, 0x00600009);
-		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f348, 0x00700008);
-		ram_wr32(fuc, 0x61c140, 0x19240000);
-		ram_wr32(fuc, 0x10f830, 0x00300017);
-		gf100_ram_train(fuc, 0x80021001);
-		gf100_ram_train(fuc, 0x80081001);
-		ram_wr32(fuc, 0x10f340, 0x00500004);
-		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f830, 0x01300017);
-		ram_wr32(fuc, 0x10f830, 0x00300017);
-// 0x00030020 // 0x00000000 // 0x00000000
-// 0x00020034 // 0x0000000b
-		ram_wr32(fuc, 0x100b0c, 0x00080028);
-		ram_wr32(fuc, 0x611200, 0x00003330);
 	} else {
 		ram_wr32(fuc, 0x10f800, 0x00001800);
 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
@@ -364,11 +385,30 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		ram_wr32(fuc, 0x10f338, 0x00300200);
 		ram_wr32(fuc, 0x10f300, 0x0000084d);
 		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f290, 0x0b343825);
-		ram_wr32(fuc, 0x10f294, 0x3483028e);
-		ram_wr32(fuc, 0x10f298, 0x440c0600);
-		ram_wr32(fuc, 0x10f29c, 0x0000214c);
-		ram_wr32(fuc, 0x10f2a0, 0x42e20069);
+	}
+
+	for (i = 0; i < 5; i++)
+		ram_wr32(fuc, 0x10f290[i], timing[i]);
+
+	if (mode == 0) {
+		ram_wr32(fuc, 0x10f614, 0x40044f77);
+		ram_wr32(fuc, 0x10f610, 0x40044f77);
+		ram_wr32(fuc, 0x10f344, 0x00600009);
+		ram_nsec(fuc, 1000);
+		ram_wr32(fuc, 0x10f348, 0x00700008);
+		ram_wr32(fuc, 0x61c140, 0x19240000);
+		ram_wr32(fuc, 0x10f830, 0x00300017);
+		gf100_ram_train(fuc, 0x80021001);
+		gf100_ram_train(fuc, 0x80081001);
+		ram_wr32(fuc, 0x10f340, 0x00500004);
+		ram_nsec(fuc, 1000);
+		ram_wr32(fuc, 0x10f830, 0x01300017);
+		ram_wr32(fuc, 0x10f830, 0x00300017);
+// 0x00030020 // 0x00000000 // 0x00000000
+// 0x00020034 // 0x0000000b
+		ram_wr32(fuc, 0x100b0c, 0x00080028);
+		ram_wr32(fuc, 0x611200, 0x00003330);
+	} else {
 		ram_wr32(fuc, 0x10f200, 0x00ce0000);
 		ram_wr32(fuc, 0x10f614, 0x60044e77);
 		ram_wr32(fuc, 0x10f610, 0x60044e77);
@@ -630,7 +670,7 @@ gf100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
 	struct nvkm_subdev *subdev = &fb->subdev;
 	struct nvkm_bios *bios = subdev->device->bios;
 	struct gf100_ram *ram;
-	int ret;
+	int i, ret;
 
 	if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
 		return -ENOMEM;
@@ -663,11 +703,8 @@ gf100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
 
 	ram->fuc.r_0x137390 = ramfuc_reg(0x137390);
 
-	ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
-	ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
-	ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
-	ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
-	ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
+	for (i = 0; i < 5; i++)
+		ram->fuc.r_0x10f290[i] = ramfuc_reg(0x10f290 + (i * 4));
 
 	ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300);
 	ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338);
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 03/11] nvkm/gddr5: MR calculation for timing table v1.0
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
  2017-04-10 19:37   ` [PATCH 01/11] nvkm/ramgf100: Get rid of (size, data) pairs for rammap, ramcfg, timing Roy Spliet
  2017-04-10 19:37   ` [PATCH 02/11] nvkm/ramgf100: Calculate timings Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 04/11] nvkm/ramgt215: Move ram training up the chain Roy Spliet
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Merges in skeggsb's:
"fb/ram/gf10x: timing_10_0e_30"

Todo:
- find l3, rq
- triple-check

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  | 12 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  | 22 ++++++++--
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c  |  2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c     | 21 ++++++++--
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c  | 49 ++++++++++++----------
 5 files changed, 71 insertions(+), 35 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 4560a52..44e4ca2 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -40,6 +40,10 @@ struct nvbios_ramcfg {
 	unsigned ramcfg_DLLoff;
 	unsigned ramcfg_RON;
 	unsigned ramcfg_FBVDDQ;
+	unsigned ramcfg_LowFreq;
+	unsigned ramcfg_WCKPin;
+	unsigned ramcfg_Hf_VREF;
+	unsigned ramcfg_VREFD_off;
 	union {
 		struct {
 			unsigned ramcfg_00_03_01:1;
@@ -82,12 +86,9 @@ struct nvbios_ramcfg {
 			unsigned ramcfg_11_01_04:1;
 			unsigned ramcfg_11_01_08:1;
 			unsigned ramcfg_11_01_10:1;
-			unsigned ramcfg_11_01_40:1;
-			unsigned ramcfg_11_01_80:1;
 			unsigned ramcfg_11_02_03:2;
 			unsigned ramcfg_11_02_04:1;
 			unsigned ramcfg_11_02_08:1;
-			unsigned ramcfg_11_02_10:1;
 			unsigned ramcfg_11_02_40:1;
 			unsigned ramcfg_11_02_80:1;
 			unsigned ramcfg_11_03_0f:4;
@@ -95,7 +96,6 @@ struct nvbios_ramcfg {
 			unsigned ramcfg_11_03_c0:2;
 			unsigned ramcfg_11_03_f0:4;
 			unsigned ramcfg_11_04:8;
-			unsigned ramcfg_11_06:8;
 			unsigned ramcfg_11_07_02:1;
 			unsigned ramcfg_11_07_04:1;
 			unsigned ramcfg_11_07_08:1;
@@ -132,6 +132,7 @@ struct nvbios_ramcfg {
 			unsigned timing_10_RRD:8;
 			unsigned timing_10_XPDLL:8;
 			unsigned timing_10_ODT:3;
+			unsigned timing_10_DS:2;
 			/* empty: 15 */
 			unsigned timing_10_10:8;
 			/* empty: 17 */
@@ -139,7 +140,8 @@ struct nvbios_ramcfg {
 			unsigned timing_10_CWL:8;
 			unsigned timing_10_FAW:8;
 			unsigned timing_10_CKE:8;
-			/* empty: 22, 23 */
+			unsigned timing_10_ADRCMD_T:8;  /* XXX: [3:2]? */
+			/* empty: 23 */
 			unsigned timing_10_18:8;
 		};
 		struct {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 131d967..0d517a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -205,8 +205,11 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
 		p->ramcfg_10_02_20 = (nvbios_rd08(bios, data + 0x02) & 0x20) >> 5;
 		p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
 		p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
+		p->ramcfg_LowFreq  = (nvbios_rd08(bios, data + 0x03) & 0x20) >> 5;
+		p->ramcfg_WCKPin   = (nvbios_rd08(bios, data + 0x03) & 0x40) >> 6;
 		p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0;
 		p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3;
+		p->ramcfg_Hf_VREF  = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
 		p->ramcfg_10_05_0f = (nvbios_rd08(bios, data + 0x05) & 0x0f) >> 0;
 		p->ramcfg_10_05_f0 = (nvbios_rd08(bios, data + 0x05) & 0xf0) >> 4;
 		p->ramcfg_10_06_0f = (nvbios_rd08(bios, data + 0x06) & 0x0f) >> 0;
@@ -216,6 +219,17 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
 		p->ramcfg_10_08    = (nvbios_rd08(bios, data + 0x08) & 0xff) >> 0;
 		p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 0;
 		p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 4;
+
+		switch (elen) {
+		case 0xe:
+		case 0xd:
+			p->ramcfg_VREFD_off = nvbios_rd08(bios, data + 0x0c);
+		case 0xc:
+		case 0xb:
+		default:
+			break;
+		}
+
 		break;
 	case 0x11:
 		p->ramcfg_timing   =  nvbios_rd08(bios, data + 0x00);
@@ -225,12 +239,12 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
 		p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3;
 		p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4;
 		p->ramcfg_DLLoff =   (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5;
-		p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6;
-		p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7;
+		p->ramcfg_LowFreq  = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6;
+		p->ramcfg_WCKPin   = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7;
 		p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0;
 		p->ramcfg_11_02_04 = (nvbios_rd08(bios, data + 0x02) & 0x04) >> 2;
 		p->ramcfg_11_02_08 = (nvbios_rd08(bios, data + 0x02) & 0x08) >> 3;
-		p->ramcfg_11_02_10 = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4;
+		p->ramcfg_Hf_VREF  = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4;
 		p->ramcfg_11_02_40 = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
 		p->ramcfg_11_02_80 = (nvbios_rd08(bios, data + 0x02) & 0x80) >> 7;
 		p->ramcfg_11_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
@@ -238,7 +252,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
 		p->ramcfg_11_03_c0 = (nvbios_rd08(bios, data + 0x03) & 0xc0) >> 6;
 		p->ramcfg_11_03_f0 = (nvbios_rd08(bios, data + 0x03) & 0xf0) >> 4;
 		p->ramcfg_11_04    = (nvbios_rd08(bios, data + 0x04) & 0xff) >> 0;
-		p->ramcfg_11_06    = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
+		p->ramcfg_VREFD_off = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
 		p->ramcfg_11_07_02 = (nvbios_rd08(bios, data + 0x07) & 0x02) >> 1;
 		p->ramcfg_11_07_04 = (nvbios_rd08(bios, data + 0x07) & 0x04) >> 2;
 		p->ramcfg_11_07_08 = (nvbios_rd08(bios, data + 0x07) & 0x08) >> 3;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
index c36be13..f1999e3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
@@ -104,6 +104,7 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
 		p->timing_10_ODT   = nvbios_rd08(bios, data + 0x0e) & 0x07;
 		if (p->ramcfg_ver >= 0x10)
 			p->ramcfg_RON = nvbios_rd08(bios, data + 0x0e) & 0x07;
+		p->timing_10_DS    = nvbios_rd08(bios, data + 0xe) & 0x30 >> 4;
 
 		p->timing_10_18  = 0xff;
 		p->timing_10_CKE = 0;
@@ -117,6 +118,7 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
 			p->timing_10_18  = nvbios_rd08(bios, data + 0x18);
 		case 0x18:
 		case 0x17:
+			p->timing_10_ADRCMD_T = nvbios_rd08(bios, data + 0x16);
 		case 0x16:
 			p->timing_10_CKE = nvbios_rd08(bios, data + 0x15);
 		case 0x15:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index 2cc074d..22e1e0b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -39,14 +39,18 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
 	int rq = ram->freq < 1000000; /* XXX */
 
 	xd = !ram->next->bios.ramcfg_DLLoff;
+	lf =  ram->next->bios.ramcfg_LowFreq;
+	pd =  ram->next->bios.ramcfg_WCKPin;
+	vh =  ram->next->bios.ramcfg_Hf_VREF;
+	vo =  ram->next->bios.ramcfg_VREFD_off;
 
 	switch (ram->next->bios.ramcfg_ver) {
+	case 0x10:
+		vr = 0;
+		l3 = (ram->mr[5] & 0x4) >> 2;
+		break;
 	case 0x11:
-		pd =  ram->next->bios.ramcfg_11_01_80;
-		lf =  ram->next->bios.ramcfg_11_01_40;
-		vh =  ram->next->bios.ramcfg_11_02_10;
 		vr =  ram->next->bios.ramcfg_11_02_04;
-		vo =  ram->next->bios.ramcfg_11_06;
 		l3 = !ram->next->bios.ramcfg_11_07_02;
 		break;
 	default:
@@ -54,6 +58,15 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
 	}
 
 	switch (ram->next->bios.timing_ver) {
+	case 0x10:
+		WL = ram->next->bios.timing_10_CWL;
+		CL = ram->next->bios.timing_10_CL;
+		WR = ram->next->bios.timing_10_WR;
+		at[0] = ram->next->bios.timing_10_ADRCMD_T & 0x3;
+		at[1] = 0;
+		dt = ram->next->bios.timing_10_ODT;
+		ds = ram->next->bios.timing_10_DS;
+		break;
 	case 0x20:
 		WL = (ram->next->bios.timing[1] & 0x00000f80) >> 7;
 		CL = (ram->next->bios.timing[1] & 0x0000001f);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 6ebdc4c..b4fe3bb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -50,11 +50,7 @@ struct gf100_ramfuc {
 
 	struct ramfuc_reg r_0x10f290[5];
 
-	struct ramfuc_reg r_0x10f300;
-	struct ramfuc_reg r_0x10f338;
-	struct ramfuc_reg r_0x10f340;
-	struct ramfuc_reg r_0x10f344;
-	struct ramfuc_reg r_0x10f348;
+	struct ramfuc_reg r_mr[9];
 
 	struct ramfuc_reg r_0x10f910;
 	struct ramfuc_reg r_0x10f914;
@@ -226,6 +222,19 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 	if (ret)
 		return ret;
 
+	/* Determine ram-specific MR values */
+	for (i = 0; i < 9; i++)
+		ram->base.mr[i] = ram_rd32(fuc, mr[i]);
+
+	switch (ram->base.type) {
+	case NVKM_RAM_TYPE_GDDR5:
+		ret = nvkm_gddr5_calc(&ram->base, false);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
 	/* determine current mclk configuration */
 	from = !!(ram_rd32(fuc, 0x1373f0) & 0x00000002); /*XXX: ok? */
 
@@ -354,9 +363,6 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		ram_nsec(fuc, 2000);
 		ram_wr32(fuc, 0x10f314, 0x00000001);
 		ram_wr32(fuc, 0x10f210, 0x80000000);
-		ram_wr32(fuc, 0x10f338, 0x00300220);
-		ram_wr32(fuc, 0x10f300, 0x0000011d);
-		ram_nsec(fuc, 1000);
 	} else {
 		ram_wr32(fuc, 0x10f800, 0x00001800);
 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
@@ -382,25 +388,26 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		ram_nsec(fuc, 2000);
 		ram_wr32(fuc, 0x10f314, 0x00000001);
 		ram_wr32(fuc, 0x10f210, 0x80000000);
-		ram_wr32(fuc, 0x10f338, 0x00300200);
-		ram_wr32(fuc, 0x10f300, 0x0000084d);
-		ram_nsec(fuc, 1000);
 	}
 
+	ram_wr32(fuc, mr[3], ram->base.mr[3]);
+	ram_wr32(fuc, mr[0], ram->base.mr[0]);
+	ram_nsec(fuc, 1000);
+
 	for (i = 0; i < 5; i++)
 		ram_wr32(fuc, 0x10f290[i], timing[i]);
 
 	if (mode == 0) {
 		ram_wr32(fuc, 0x10f614, 0x40044f77);
 		ram_wr32(fuc, 0x10f610, 0x40044f77);
-		ram_wr32(fuc, 0x10f344, 0x00600009);
+		ram_wr32(fuc, mr[6], 0x00600009);
 		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f348, 0x00700008);
+		ram_wr32(fuc, mr[7], 0x00700008);
 		ram_wr32(fuc, 0x61c140, 0x19240000);
 		ram_wr32(fuc, 0x10f830, 0x00300017);
 		gf100_ram_train(fuc, 0x80021001);
 		gf100_ram_train(fuc, 0x80081001);
-		ram_wr32(fuc, 0x10f340, 0x00500004);
+		ram_wr32(fuc, mr[5], 0x00500004);
 		ram_nsec(fuc, 1000);
 		ram_wr32(fuc, 0x10f830, 0x01300017);
 		ram_wr32(fuc, 0x10f830, 0x00300017);
@@ -412,11 +419,11 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
 		ram_wr32(fuc, 0x10f200, 0x00ce0000);
 		ram_wr32(fuc, 0x10f614, 0x60044e77);
 		ram_wr32(fuc, 0x10f610, 0x60044e77);
-		ram_wr32(fuc, 0x10f340, 0x00500000);
+		ram_wr32(fuc, mr[5], 0x00500000);
 		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f344, 0x00600228);
+		ram_wr32(fuc, mr[6], 0x00600228);
 		ram_nsec(fuc, 1000);
-		ram_wr32(fuc, 0x10f348, 0x00700000);
+		ram_wr32(fuc, mr[7], 0x00700000);
 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
 		ram_wr32(fuc, 0x61c140, 0x09a40000);
 
@@ -706,11 +713,9 @@ gf100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
 	for (i = 0; i < 5; i++)
 		ram->fuc.r_0x10f290[i] = ramfuc_reg(0x10f290 + (i * 4));
 
-	ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300);
-	ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338);
-	ram->fuc.r_0x10f340 = ramfuc_reg(0x10f340);
-	ram->fuc.r_0x10f344 = ramfuc_reg(0x10f344);
-	ram->fuc.r_0x10f348 = ramfuc_reg(0x10f348);
+	ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
+	for (i = 1; i < 9; i++)
+		ram->fuc.r_mr[i] = ramfuc_reg(0x10f330 + ((i - 1) * 4));
 
 	ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
 	ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 04/11] nvkm/ramgt215: Move ram training up the chain
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (2 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 03/11] nvkm/gddr5: MR calculation for timing table v1.0 Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 05/11] nvkm/ramgf100: Don't mandate training pattern 4 Roy Spliet
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Parts are re-used even on NVA3, others from GF100 on

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h      |  17 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c |  92 +++++++++-----
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c | 140 +---------------------
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c |  61 ++++++++++
 4 files changed, 140 insertions(+), 170 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
index b60068b..ce8a98e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -1,6 +1,7 @@
 #ifndef __NVKM_FB_RAM_PRIV_H__
 #define __NVKM_FB_RAM_PRIV_H__
 #include "priv.h"
+#include <subdev/bios/M0209.h>
 
 int  nvkm_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
 		   enum nvkm_ram_type, u64 size, u32 tags,
@@ -24,6 +25,22 @@ int  gf100_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
 int  gf100_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **);
 void gf100_ram_put(struct nvkm_ram *, struct nvkm_mem **);
 
+/* Training */
+struct gt215_ram_train {
+	u16 mask;
+	struct nvbios_M0209S remap;
+	struct nvbios_M0209S type00;
+	struct nvbios_M0209S type01;
+	struct nvbios_M0209S type04;
+	struct nvbios_M0209S type06;
+	struct nvbios_M0209S type07;
+	struct nvbios_M0209S type08;
+	struct nvbios_M0209S type09;
+};
+int gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
+		     struct gt215_ram_train *train);
+int  gf100_ram_train_init(struct nvkm_ram *ram);
+
 int  gk104_ram_ctor(struct nvkm_fb *, struct nvkm_ram **, u32);
 int  gk104_ram_init(struct nvkm_ram *ram);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index b4fe3bb..38a7e2b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -28,6 +28,7 @@
 #include <core/option.h>
 #include <subdev/bios.h>
 #include <subdev/bios/pll.h>
+#include <subdev/bios/M0205.h>
 #include <subdev/bios/rammap.h>
 #include <subdev/bios/timing.h>
 #include <subdev/clk.h>
@@ -549,45 +550,74 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
 }
 
 static int
-gf100_ram_init(struct nvkm_ram *base)
+gf100_ram_train_init_0(struct nvkm_ram *ram, struct gt215_ram_train *train)
 {
-	static const u8  train0[] = {
-		0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
-		0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
-	};
-	static const u32 train1[] = {
-		0x00000000, 0xffffffff,
-		0x55555555, 0xaaaaaaaa,
-		0x33333333, 0xcccccccc,
-		0xf0f0f0f0, 0x0f0f0f0f,
-		0x00ff00ff, 0xff00ff00,
-		0x0000ffff, 0xffff0000,
-	};
-	struct gf100_ram *ram = gf100_ram(base);
-	struct nvkm_device *device = ram->base.fb->subdev.device;
-	int i;
+	struct nvkm_subdev *subdev = &ram->fb->subdev;
+	struct nvkm_device *device = subdev->device;
+	int i, j;
 
-	switch (ram->base.type) {
+	if ((train->mask & 0x03d3) != 0x03d3) {
+		nvkm_warn(subdev, "missing link training data\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < 0x30; i++) {
+		for (j = 0; j < 8; j += 4) {
+			nvkm_wr32(device, 0x10f968 + j, 0x00000000 | (i << 8));
+			nvkm_wr32(device, 0x10f920 + j, 0x00000000 |
+						   train->type08.data[i] << 4 |
+						   train->type06.data[i]);
+			nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
+			nvkm_wr32(device, 0x10f920 + j, 0x00000100 |
+						   train->type09.data[i] << 4 |
+						   train->type07.data[i]);
+			nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
+		}
+	}
+
+	for (j = 0; j < 8; j += 4) {
+		for (i = 0; i < 0x100; i++) {
+			nvkm_wr32(device, 0x10f968 + j, i);
+			nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
+		}
+	}
+
+	return 0;
+}
+
+int
+gf100_ram_train_init(struct nvkm_ram *ram)
+{
+	u8 ramcfg = nvbios_ramcfg_index(&ram->fb->subdev);
+	struct gt215_ram_train *train;
+	int ret, i;
+
+	if (!(train = kzalloc(sizeof(*train), GFP_KERNEL)))
+		return -ENOMEM;
+
+	for (i = 0; i < 0x100; i++) {
+		ret = gt215_ram_train_type(ram, i, ramcfg, train);
+		if (ret && ret != -ENOENT)
+			break;
+	}
+
+	switch (ram->type) {
 	case NVKM_RAM_TYPE_GDDR5:
+		ret = gf100_ram_train_init_0(ram, train);
 		break;
 	default:
-		return 0;
+		ret = 0;
+		break;
 	}
 
-	/* prepare for ddr link training, and load training patterns */
-	for (i = 0; i < 0x30; i++) {
-		nvkm_wr32(device, 0x10f968, 0x00000000 | (i << 8));
-		nvkm_wr32(device, 0x10f96c, 0x00000000 | (i << 8));
-		nvkm_wr32(device, 0x10f920, 0x00000100 | train0[i % 12]);
-		nvkm_wr32(device, 0x10f924, 0x00000100 | train0[i % 12]);
-		nvkm_wr32(device, 0x10f918,              train1[i % 12]);
-		nvkm_wr32(device, 0x10f91c,              train1[i % 12]);
-		nvkm_wr32(device, 0x10f920, 0x00000000 | train0[i % 12]);
-		nvkm_wr32(device, 0x10f924, 0x00000000 | train0[i % 12]);
-		nvkm_wr32(device, 0x10f918,              train1[i % 12]);
-		nvkm_wr32(device, 0x10f91c,              train1[i % 12]);
-	}
+	kfree(train);
+	return ret;
+}
 
+static int
+gf100_ram_init(struct nvkm_ram *base)
+{
+	/* XXX: Don't hook up yet for bisectability */
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
index 7904fa4..8bf4638 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
@@ -1257,144 +1257,6 @@ gk104_ram_tidy(struct nvkm_ram *base)
 	ram_exec(&ram->fuc, false);
 }
 
-struct gk104_ram_train {
-	u16 mask;
-	struct nvbios_M0209S remap;
-	struct nvbios_M0209S type00;
-	struct nvbios_M0209S type01;
-	struct nvbios_M0209S type04;
-	struct nvbios_M0209S type06;
-	struct nvbios_M0209S type07;
-	struct nvbios_M0209S type08;
-	struct nvbios_M0209S type09;
-};
-
-static int
-gk104_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
-		     struct gk104_ram_train *train)
-{
-	struct nvkm_bios *bios = ram->fb->subdev.device->bios;
-	struct nvbios_M0205E M0205E;
-	struct nvbios_M0205S M0205S;
-	struct nvbios_M0209E M0209E;
-	struct nvbios_M0209S *remap = &train->remap;
-	struct nvbios_M0209S *value;
-	u8  ver, hdr, cnt, len;
-	u32 data;
-
-	/* determine type of data for this index */
-	if (!(data = nvbios_M0205Ep(bios, i, &ver, &hdr, &cnt, &len, &M0205E)))
-		return -ENOENT;
-
-	switch (M0205E.type) {
-	case 0x00: value = &train->type00; break;
-	case 0x01: value = &train->type01; break;
-	case 0x04: value = &train->type04; break;
-	case 0x06: value = &train->type06; break;
-	case 0x07: value = &train->type07; break;
-	case 0x08: value = &train->type08; break;
-	case 0x09: value = &train->type09; break;
-	default:
-		return 0;
-	}
-
-	/* training data index determined by ramcfg strap */
-	if (!(data = nvbios_M0205Sp(bios, i, ramcfg, &ver, &hdr, &M0205S)))
-		return -EINVAL;
-	i = M0205S.data;
-
-	/* training data format information */
-	if (!(data = nvbios_M0209Ep(bios, i, &ver, &hdr, &cnt, &len, &M0209E)))
-		return -EINVAL;
-
-	/* ... and the raw data */
-	if (!(data = nvbios_M0209Sp(bios, i, 0, &ver, &hdr, value)))
-		return -EINVAL;
-
-	if (M0209E.v02_07 == 2) {
-		/* of course! why wouldn't we have a pointer to another entry
-		 * in the same table, and use the first one as an array of
-		 * remap indices...
-		 */
-		if (!(data = nvbios_M0209Sp(bios, M0209E.v03, 0, &ver, &hdr,
-					    remap)))
-			return -EINVAL;
-
-		for (i = 0; i < ARRAY_SIZE(value->data); i++)
-			value->data[i] = remap->data[value->data[i]];
-	} else
-	if (M0209E.v02_07 != 1)
-		return -EINVAL;
-
-	train->mask |= 1 << M0205E.type;
-	return 0;
-}
-
-static int
-gk104_ram_train_init_0(struct nvkm_ram *ram, struct gk104_ram_train *train)
-{
-	struct nvkm_subdev *subdev = &ram->fb->subdev;
-	struct nvkm_device *device = subdev->device;
-	int i, j;
-
-	if ((train->mask & 0x03d3) != 0x03d3) {
-		nvkm_warn(subdev, "missing link training data\n");
-		return -EINVAL;
-	}
-
-	for (i = 0; i < 0x30; i++) {
-		for (j = 0; j < 8; j += 4) {
-			nvkm_wr32(device, 0x10f968 + j, 0x00000000 | (i << 8));
-			nvkm_wr32(device, 0x10f920 + j, 0x00000000 |
-						   train->type08.data[i] << 4 |
-						   train->type06.data[i]);
-			nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
-			nvkm_wr32(device, 0x10f920 + j, 0x00000100 |
-						   train->type09.data[i] << 4 |
-						   train->type07.data[i]);
-			nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
-		}
-	}
-
-	for (j = 0; j < 8; j += 4) {
-		for (i = 0; i < 0x100; i++) {
-			nvkm_wr32(device, 0x10f968 + j, i);
-			nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
-		}
-	}
-
-	return 0;
-}
-
-static int
-gk104_ram_train_init(struct nvkm_ram *ram)
-{
-	u8 ramcfg = nvbios_ramcfg_index(&ram->fb->subdev);
-	struct gk104_ram_train *train;
-	int ret, i;
-
-	if (!(train = kzalloc(sizeof(*train), GFP_KERNEL)))
-		return -ENOMEM;
-
-	for (i = 0; i < 0x100; i++) {
-		ret = gk104_ram_train_type(ram, i, ramcfg, train);
-		if (ret && ret != -ENOENT)
-			break;
-	}
-
-	switch (ram->type) {
-	case NVKM_RAM_TYPE_GDDR5:
-		ret = gk104_ram_train_init_0(ram, train);
-		break;
-	default:
-		ret = 0;
-		break;
-	}
-
-	kfree(train);
-	return ret;
-}
-
 int
 gk104_ram_init(struct nvkm_ram *ram)
 {
@@ -1439,7 +1301,7 @@ gk104_ram_init(struct nvkm_ram *ram)
 	nvkm_wr32(device, 0x10ecc0, 0xffffffff);
 	nvkm_mask(device, 0x10f160, 0x00000010, 0x00000010);
 
-	return gk104_ram_train_init(ram);
+	return gf100_ram_train_init(ram);
 }
 
 static int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 8454899..6abd0e3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -267,6 +267,67 @@ gt215_link_train(struct gt215_ram *ram)
 	return ret;
 }
 
+int
+gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
+		     struct gt215_ram_train *train)
+{
+	struct nvkm_bios *bios = ram->fb->subdev.device->bios;
+	struct nvbios_M0205E M0205E;
+	struct nvbios_M0205S M0205S;
+	struct nvbios_M0209E M0209E;
+	struct nvbios_M0209S *remap = &train->remap;
+	struct nvbios_M0209S *value;
+	u8  ver, hdr, cnt, len;
+	u32 data;
+
+	/* determine type of data for this index */
+	if (!(data = nvbios_M0205Ep(bios, i, &ver, &hdr, &cnt, &len, &M0205E)))
+		return -ENOENT;
+
+	switch (M0205E.type) {
+	case 0x00: value = &train->type00; break;
+	case 0x01: value = &train->type01; break;
+	case 0x04: value = &train->type04; break;
+	case 0x06: value = &train->type06; break;
+	case 0x07: value = &train->type07; break;
+	case 0x08: value = &train->type08; break;
+	case 0x09: value = &train->type09; break;
+	default:
+		return 0;
+	}
+
+	/* training data index determined by ramcfg strap */
+	if (!(data = nvbios_M0205Sp(bios, i, ramcfg, &ver, &hdr, &M0205S)))
+		return -EINVAL;
+	i = M0205S.data;
+
+	/* training data format information */
+	if (!(data = nvbios_M0209Ep(bios, i, &ver, &hdr, &cnt, &len, &M0209E)))
+		return -EINVAL;
+
+	/* ... and the raw data */
+	if (!(data = nvbios_M0209Sp(bios, i, 0, &ver, &hdr, value)))
+		return -EINVAL;
+
+	if (M0209E.v02_07 == 2) {
+		/* of course! why wouldn't we have a pointer to another entry
+		 * in the same table, and use the first one as an array of
+		 * remap indices...
+		 */
+		if (!(data = nvbios_M0209Sp(bios, M0209E.v03, 0, &ver, &hdr,
+					    remap)))
+			return -EINVAL;
+
+		for (i = 0; i < ARRAY_SIZE(value->data); i++)
+			value->data[i] = remap->data[value->data[i]];
+	} else
+	if (M0209E.v02_07 != 1)
+		return -EINVAL;
+
+	train->mask |= 1 << M0205E.type;
+	return 0;
+}
+
 static int
 gt215_link_train_init(struct gt215_ram *ram)
 {
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 05/11] nvkm/ramgf100: Don't mandate training pattern 4
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (3 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 04/11] nvkm/ramgt215: Move ram training up the chain Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 06/11] nvkm/ramgf100: Unset bit before uploading train values Roy Spliet
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

It's not found on Fermi.

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 38a7e2b..eef09bf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -556,7 +556,7 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct gt215_ram_train *train)
 	struct nvkm_device *device = subdev->device;
 	int i, j;
 
-	if ((train->mask & 0x03d3) != 0x03d3) {
+	if ((train->mask & 0x03c3) != 0x03c3) {
 		nvkm_warn(subdev, "missing link training data\n");
 		return -EINVAL;
 	}
@@ -575,10 +575,13 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct gt215_ram_train *train)
 		}
 	}
 
-	for (j = 0; j < 8; j += 4) {
-		for (i = 0; i < 0x100; i++) {
-			nvkm_wr32(device, 0x10f968 + j, i);
-			nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
+	if (train->mask & 0x10) {
+		for (j = 0; j < 8; j += 4) {
+			for (i = 0; i < 0x100; i++) {
+				nvkm_wr32(device, 0x10f968 + j, i);
+				nvkm_wr32(device, 0x10f900 + j,
+						train->type04.data[i]);
+			}
 		}
 	}
 
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 06/11] nvkm/ramgf100: Unset bit before uploading train values
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (4 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 05/11] nvkm/ramgf100: Don't mandate training pattern 4 Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 07/11] nvkm/ramgf100: Reinstate default ram train pattern Roy Spliet
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Just because the blob does it too...

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index eef09bf..62359c2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -620,6 +620,12 @@ gf100_ram_train_init(struct nvkm_ram *ram)
 static int
 gf100_ram_init(struct nvkm_ram *base)
 {
+	struct nvkm_subdev *subdev = &base->fb->subdev;
+	struct nvkm_device *device = subdev->device;
+
+	/* XXX Why does the blob do this? */
+	nvkm_mask(device, 0x137360, 0x00000002, 0x00000000);
+
 	/* XXX: Don't hook up yet for bisectability */
 	return 0;
 }
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 07/11] nvkm/ramgf100: Reinstate default ram train pattern
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (5 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 06/11] nvkm/ramgf100: Unset bit before uploading train values Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 08/11] nvkm/ramgt215: Add train ptrn upload for GDDR5 Roy Spliet
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 59 +++++++++++++++++------
 1 file changed, 43 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 62359c2..a469719 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -556,22 +556,49 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct gt215_ram_train *train)
 	struct nvkm_device *device = subdev->device;
 	int i, j;
 
-	if ((train->mask & 0x03c3) != 0x03c3) {
-		nvkm_warn(subdev, "missing link training data\n");
-		return -EINVAL;
-	}
-
-	for (i = 0; i < 0x30; i++) {
-		for (j = 0; j < 8; j += 4) {
-			nvkm_wr32(device, 0x10f968 + j, 0x00000000 | (i << 8));
-			nvkm_wr32(device, 0x10f920 + j, 0x00000000 |
-						   train->type08.data[i] << 4 |
-						   train->type06.data[i]);
-			nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
-			nvkm_wr32(device, 0x10f920 + j, 0x00000100 |
-						   train->type09.data[i] << 4 |
-						   train->type07.data[i]);
-			nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
+	static const u8  train0[] = {
+		0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
+		0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
+	};
+
+	static const u32 train1[] = {
+		0x00000000, 0xffffffff,
+		0x55555555, 0xaaaaaaaa,
+		0x33333333, 0xcccccccc,
+		0xf0f0f0f0, 0x0f0f0f0f,
+		0x00ff00ff, 0xff00ff00,
+		0x0000ffff, 0xffff0000,
+	};
+
+	if ((train->mask & 0x03c3) == 0x03c3) {
+		for (i = 0; i < 0x30; i++) {
+			for (j = 0; j < 8; j += 4) {
+				nvkm_wr32(device, 0x10f968 + j, (i << 8));
+				nvkm_wr32(device, 0x10f920 + j, 0x00000000 |
+						train->type08.data[i] << 4 |
+						train->type06.data[i]);
+				nvkm_wr32(device, 0x10f918 + j,
+						train->type00.data[i]);
+				nvkm_wr32(device, 0x10f920 + j, 0x00000100 |
+						train->type09.data[i] << 4 |
+						train->type07.data[i]);
+				nvkm_wr32(device, 0x10f918 + j,
+						train->type01.data[i]);
+			}
+		}
+	} else {
+		nvkm_info(subdev, "missing link training data, using defaults\n");
+
+		for (i = 0; i < 0x30; i++) {
+			for (j = 0; j < 8; j += 4) {
+				nvkm_wr32(device, 0x10f968 + j, (i << 8));
+				nvkm_wr32(device, 0x10f920 + j, 0x00000100 |
+								train0[i % 12]);
+				nvkm_wr32(device, 0x10f918 + j, train1[i % 12]);
+				nvkm_wr32(device, 0x10f920 + j, 0x00000000 |
+								train0[i % 12]);
+				nvkm_wr32(device, 0x10f918 + j, train1[i % 12]);
+			}
 		}
 	}
 
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 08/11] nvkm/ramgt215: Add train ptrn upload for GDDR5
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (6 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 07/11] nvkm/ramgf100: Reinstate default ram train pattern Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 09/11] nvkm/ramgf100: Hook up ram training pattern init for NVC0+ Roy Spliet
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Signed-off-by: Roy Spliet <nouveau@spliet.org>
Tested-by: Ilia Mirkin <imirkin@alum.mit.edu>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h      |   1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 128 +++++++++++++++++-----
 2 files changed, 99 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
index ce8a98e..ef9edc5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -32,6 +32,7 @@ struct gt215_ram_train {
 	struct nvbios_M0209S type00;
 	struct nvbios_M0209S type01;
 	struct nvbios_M0209S type04;
+	struct nvbios_M0209S type05;
 	struct nvbios_M0209S type06;
 	struct nvbios_M0209S type07;
 	struct nvbios_M0209S type08;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 6abd0e3..fa85942 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -75,7 +75,7 @@ struct gt215_ramfuc {
 	struct ramfuc_reg r_gpio[4];
 };
 
-struct gt215_ltrain {
+struct gt215_ram_train_ddr3 {
 	enum {
 		NVA3_TRAIN_UNKNOWN,
 		NVA3_TRAIN_UNSUPPORTED,
@@ -92,11 +92,11 @@ struct gt215_ltrain {
 struct gt215_ram {
 	struct nvkm_ram base;
 	struct gt215_ramfuc fuc;
-	struct gt215_ltrain ltrain;
+	struct gt215_ram_train_ddr3 ltrain;
 };
 
 static void
-gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
+gt215_link_train_calc(u32 *vals, struct gt215_ram_train_ddr3 *train)
 {
 	int i, lo, hi;
 	u8 median[8], bins[4] = {0, 0, 0, 0}, bin = 0, qty = 0;
@@ -152,7 +152,7 @@ gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
 static int
 gt215_link_train(struct gt215_ram *ram)
 {
-	struct gt215_ltrain *train = &ram->ltrain;
+	struct gt215_ram_train_ddr3 *train = &ram->ltrain;
 	struct gt215_ramfuc *fuc = &ram->fuc;
 	struct nvkm_subdev *subdev = &ram->base.fb->subdev;
 	struct nvkm_device *device = subdev->device;
@@ -288,6 +288,7 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
 	case 0x00: value = &train->type00; break;
 	case 0x01: value = &train->type01; break;
 	case 0x04: value = &train->type04; break;
+	case 0x05: value = &train->type05; break;
 	case 0x06: value = &train->type06; break;
 	case 0x07: value = &train->type07; break;
 	case 0x08: value = &train->type08; break;
@@ -321,7 +322,7 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
 		for (i = 0; i < ARRAY_SIZE(value->data); i++)
 			value->data[i] = remap->data[value->data[i]];
 	} else
-	if (M0209E.v02_07 != 1)
+	if (M0209E.v02_07 > 2)
 		return -EINVAL;
 
 	train->mask |= 1 << M0205E.type;
@@ -329,7 +330,47 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
 }
 
 static int
-gt215_link_train_init(struct gt215_ram *ram)
+gt215_ram_train_upload_gddr5(struct nvkm_ram *ram,
+		struct gt215_ram_train *train)
+{
+	struct nvkm_subdev *subdev = &ram->fb->subdev;
+	struct nvkm_device *device = subdev->device;
+	int i, j;
+
+	static const u32 off[] = {0x00, 0x20, 0x04, 0x24};
+
+	if ((train->mask & 0x03c3) != 0x03c3) {
+		nvkm_info(subdev,
+			"missing link training data, not uploading patterns\n");
+		return 0;
+	}
+
+	for (j = 0; j < 4; j++) {
+		for (i = 0; i < 0x80; i++) {
+			nvkm_wr32(device, 0x10f8c0 + off[j], (i << 8) | i);
+			if (i < 0x30) {
+				nvkm_wr32(device, 0x10f940 + off[j], 0x00000000 |
+						train->type08.data[i] << 4 |
+						train->type06.data[i]);
+				nvkm_wr32(device, 0x10f900 + off[j],
+						train->type00.data[i]);
+				nvkm_wr32(device, 0x10f940 + off[j], 0x00000100 |
+						train->type09.data[i] << 4 |
+						train->type07.data[i]);
+				nvkm_wr32(device, 0x10f900 + off[j],
+						train->type01.data[i]);
+			}
+			nvkm_wr32(device, 0x10f840 + off[j], 0x00000000 | i);
+			nvkm_wr32(device, 0x10f840 + off[j], 0x01000000 | i);
+		}
+	}
+
+	return 0;
+}
+
+static int
+gt215_ram_train_upload_ddr3(struct nvkm_ram *ram,
+		struct gt215_ram_train *train)
 {
 	static const u32 pattern[16] = {
 		0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee,
@@ -337,33 +378,28 @@ gt215_link_train_init(struct gt215_ram *ram)
 		0x33333333, 0x55555555, 0x77777777, 0x66666666,
 		0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb,
 	};
-	struct gt215_ltrain *train = &ram->ltrain;
-	struct nvkm_device *device = ram->base.fb->subdev.device;
-	struct nvkm_bios *bios = device->bios;
+	struct gt215_ram *gt215 = gt215_ram(ram);
+	struct gt215_ram_train_ddr3 *train_ddr3 = &gt215->ltrain;
+	struct nvkm_device *device = ram->fb->subdev.device;
 	struct nvkm_mem *mem;
-	struct nvbios_M0205E M0205E;
-	u8 ver, hdr, cnt, len;
 	u32 r001700;
 	int ret, i = 0;
 
-	train->state = NVA3_TRAIN_UNSUPPORTED;
+	train_ddr3->state = NVA3_TRAIN_UNSUPPORTED;
 
 	/* We support type "5"
 	 * XXX: training pattern table appears to be unused for this routine */
-	if (!nvbios_M0205Ep(bios, i, &ver, &hdr, &cnt, &len, &M0205E))
-		return -ENOENT;
-
-	if (M0205E.type != 5)
+	if ((train->mask & 0x0020) != 0x0020)
 		return 0;
 
-	train->state = NVA3_TRAIN_ONCE;
+	train_ddr3->state = NVA3_TRAIN_ONCE;
 
-	ret = ram->base.func->get(&ram->base, 0x8000, 0x10000, 0, 0x800,
-				  &ram->ltrain.mem);
+	ret = ram->func->get(ram, 0x8000, 0x10000, 0, 0x800,
+				  &train_ddr3->mem);
 	if (ret)
 		return ret;
 
-	mem = ram->ltrain.mem;
+	mem = train_ddr3->mem;
 
 	nvkm_wr32(device, 0x100538, 0x10000000 | (mem->offset >> 16));
 	nvkm_wr32(device, 0x1005a8, 0x0000ffff);
@@ -388,17 +424,50 @@ gt215_link_train_init(struct gt215_ram *ram)
 		nvkm_wr32(device, 0x700100 + (i << 2), pattern[i]);
 	nvkm_wr32(device, 0x1700, r001700);
 
-	train->r_100720 = nvkm_rd32(device, 0x100720);
-	train->r_1111e0 = nvkm_rd32(device, 0x1111e0);
-	train->r_111400 = nvkm_rd32(device, 0x111400);
+	train_ddr3->r_100720 = nvkm_rd32(device, 0x100720);
+	train_ddr3->r_1111e0 = nvkm_rd32(device, 0x1111e0);
+	train_ddr3->r_111400 = nvkm_rd32(device, 0x111400);
 	return 0;
 }
 
+int
+gt215_ram_train_init(struct nvkm_ram *ram)
+{
+	u8 ramcfg = nvbios_ramcfg_index(&ram->fb->subdev);
+	struct gt215_ram_train *train;
+	int ret, i;
+
+	if (!(train = kzalloc(sizeof(*train), GFP_KERNEL)))
+		return -ENOMEM;
+
+	for (i = 0; i < 0x100; i++) {
+		ret = gt215_ram_train_type(ram, i, ramcfg, train);
+		if (ret && ret != -ENOENT)
+			break;
+	}
+
+	switch (ram->type) {
+	case NVKM_RAM_TYPE_GDDR5:
+		ret = gt215_ram_train_upload_gddr5(ram, train);
+		break;
+	case NVKM_RAM_TYPE_DDR3:
+		ret = gt215_ram_train_upload_ddr3(ram, train);
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+
+	kfree(train);
+	return ret;
+}
+
 static void
-gt215_link_train_fini(struct gt215_ram *ram)
+gt215_ram_train_fini(struct nvkm_ram *ram)
 {
-	if (ram->ltrain.mem)
-		ram->base.func->put(&ram->base, &ram->ltrain.mem);
+	struct gt215_ram *gt215 = gt215_ram(ram);
+	if (gt215->ltrain.mem)
+		ram->func->put(ram, &gt215->ltrain.mem);
 }
 
 /*
@@ -554,7 +623,7 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
 {
 	struct gt215_ram *ram = gt215_ram(base);
 	struct gt215_ramfuc *fuc = &ram->fuc;
-	struct gt215_ltrain *train = &ram->ltrain;
+	struct gt215_ram_train_ddr3 *train = &ram->ltrain;
 	struct nvkm_subdev *subdev = &ram->base.fb->subdev;
 	struct nvkm_device *device = subdev->device;
 	struct nvkm_bios *bios = device->bios;
@@ -979,8 +1048,7 @@ gt215_ram_tidy(struct nvkm_ram *base)
 static int
 gt215_ram_init(struct nvkm_ram *base)
 {
-	struct gt215_ram *ram = gt215_ram(base);
-	gt215_link_train_init(ram);
+	gt215_ram_train_init(base);
 	return 0;
 }
 
@@ -988,7 +1056,7 @@ static void *
 gt215_ram_dtor(struct nvkm_ram *base)
 {
 	struct gt215_ram *ram = gt215_ram(base);
-	gt215_link_train_fini(ram);
+	gt215_ram_train_fini(base);
 	return ram;
 }
 
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 09/11] nvkm/ramgf100: Hook up ram training pattern init for NVC0+
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (7 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 08/11] nvkm/ramgt215: Add train ptrn upload for GDDR5 Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 10/11] nvkm/pmu/memx: init script -> memx translation Roy Spliet
  2017-04-10 19:37   ` [PATCH 11/11] nvkm/bios/perf: Retreive pointer to unk1c script Roy Spliet
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index a469719..eebd20b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -653,8 +653,7 @@ gf100_ram_init(struct nvkm_ram *base)
 	/* XXX Why does the blob do this? */
 	nvkm_mask(device, 0x137360, 0x00000002, 0x00000000);
 
-	/* XXX: Don't hook up yet for bisectability */
-	return 0;
+	return gf100_ram_train_init(base);
 }
 
 static const struct nvkm_ram_func
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 10/11] nvkm/pmu/memx: init script -> memx translation
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (8 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 09/11] nvkm/ramgf100: Hook up ram training pattern init for NVC0+ Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  2017-04-10 19:37   ` [PATCH 11/11] nvkm/bios/perf: Retreive pointer to unk1c script Roy Spliet
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h |  2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h   |  8 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c    | 66 +++++++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
index f37538eb..b9c46ef 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -50,4 +50,6 @@ void nvkm_memx_train(struct nvkm_memx *);
 int  nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
 void nvkm_memx_block(struct nvkm_memx *);
 void nvkm_memx_unblock(struct nvkm_memx *);
+void nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios,
+		u16 offset, u8 ramcfg);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
index 9ef9d6a..614e716 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
@@ -160,6 +160,13 @@ ramfuc_unblock(struct ramfuc *ram)
 	nvkm_memx_unblock(ram->memx);
 }
 
+static inline void
+ramfuc_init_run(struct ramfuc *ram, struct nvkm_bios *bios, u16 offset,
+		u8 ramcfg)
+{
+	nvkm_memx_init_run(ram->memx, bios, offset, ramcfg);
+}
+
 #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 != 0x000000)
@@ -174,4 +181,5 @@ ramfuc_unblock(struct ramfuc *ram)
 #define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
 #define ram_block(s)         ramfuc_block(&(s)->base)
 #define ram_unblock(s)       ramfuc_unblock(&(s)->base)
+#define ram_init_run(s,b,o,r) ramfuc_init_run(&(s)->base, (b), (o), (r))
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
index e6f7416..c58a51d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
@@ -1,6 +1,9 @@
 #ifndef __NVKM_PMU_MEMX_H__
 #define __NVKM_PMU_MEMX_H__
 #include "priv.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+#include <subdev/bios/ramcfg.h>
 
 struct nvkm_memx {
 	struct nvkm_pmu *pmu;
@@ -200,4 +203,67 @@ nvkm_memx_unblock(struct nvkm_memx *memx)
 	nvkm_debug(&memx->pmu->subdev, "   HOST UNBLOCKED\n");
 	memx_cmd(memx, MEMX_LEAVE, 0, NULL);
 }
+
+/******************************************************************************
+ * Turn VBIOS init script into memx command stream. Not-quite as feature rich
+ * as subdev/bios/init.c
+ *****************************************************************************/
+
+static void
+nvkm_memx_init_ram_restrict(struct nvkm_memx *memx, struct nvbios_init *init)
+{
+	struct nvkm_bios *bios = init->bios;
+	struct nvkm_subdev *subdev = &memx->pmu->subdev;
+        struct nvkm_device *device = subdev->device;
+	u32 addr = nvbios_rd32(bios, init->offset + 1);
+	u8  incr = nvbios_rd08(bios, init->offset + 5);
+	u8   num = nvbios_rd08(bios, init->offset + 6);
+	u8 count = nvbios_ramcfg_count(init->bios);
+	u8 index = init->ramcfg;
+	u8 i;
+	u32 oldval, newval;
+
+	init->offset += 7;
+
+	for (i = 0; i < num; i++) {
+		oldval  = nvkm_rd32(device, addr);
+		newval = nvbios_rd32(bios, init->offset + (4 * index));
+
+		if (oldval != newval) {
+			nvkm_memx_wr32(memx, addr, newval);
+		}
+		init->offset += 4 * count;
+		addr += incr;
+	}
+}
+
+void
+nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios, u16 offset,
+		u8 ramcfg)
+{
+	struct nvbios_init init = {
+		.subdev = &bios->subdev,
+		.bios = bios,
+		.offset = offset,
+		.outp = NULL,
+		.execute = 1,
+		.ramcfg = ramcfg,
+	};
+	u8 op;
+
+	while (init.offset)
+	{
+		op = nvbios_rd08(bios, init.offset);
+		switch (op)
+		{
+		case 0x8f:
+			nvkm_memx_init_ram_restrict(memx, &init);
+			break;
+		case 0x71:
+		default:
+			return;
+		}
+	}
+}
+
 #endif
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 11/11] nvkm/bios/perf: Retreive pointer to unk1c script
       [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
                     ` (9 preceding siblings ...)
  2017-04-10 19:37   ` [PATCH 10/11] nvkm/pmu/memx: init script -> memx translation Roy Spliet
@ 2017-04-10 19:37   ` Roy Spliet
  10 siblings, 0 replies; 12+ messages in thread
From: Roy Spliet @ 2017-04-10 19:37 UTC (permalink / raw)
  To: Nouveau Mailinglist; +Cc: Ben Skeggs

Signed-off-by: Roy Spliet <nouveau@spliet.org>
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c         | 14 ++++++++++++++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c       |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
index 478b1c0..28555d6 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -40,4 +40,5 @@ struct nvbios_perf_fan {
 };
 
 int nvbios_perf_fan_parse(struct nvkm_bios *, struct nvbios_perf_fan *);
+u16 nvbios_perf_script_unk1c(struct nvkm_bios *bios);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
index c306835..55c1f36 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
@@ -213,3 +213,17 @@ nvbios_perf_fan_parse(struct nvkm_bios *bios,
 
 	return 0;
 }
+
+u16
+nvbios_perf_script_unk1c(struct nvkm_bios *bios)
+{
+	struct bit_entry bit_P;
+
+	if (!bit_entry(bios, 'P', &bit_P)) {
+		if (bit_P.version == 2) {
+			return nvbios_rd16(bios, bit_P.offset + 0x1c);
+		}
+	}
+
+	return 0x0000;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index eebd20b..def119c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -31,6 +31,7 @@
 #include <subdev/bios/M0205.h>
 #include <subdev/bios/rammap.h>
 #include <subdev/bios/timing.h>
+#include <subdev/bios/perf.h>
 #include <subdev/clk.h>
 #include <subdev/clk/pll.h>
 #include <subdev/ltc.h>
-- 
2.9.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-04-10 19:37 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-10 19:37 Preparations for Fermi DRAM clock changes Roy Spliet
     [not found] ` <20170410193728.29026-1-nouveau-NQbd8FSOZ1kdnm+yROfE0A@public.gmane.org>
2017-04-10 19:37   ` [PATCH 01/11] nvkm/ramgf100: Get rid of (size, data) pairs for rammap, ramcfg, timing Roy Spliet
2017-04-10 19:37   ` [PATCH 02/11] nvkm/ramgf100: Calculate timings Roy Spliet
2017-04-10 19:37   ` [PATCH 03/11] nvkm/gddr5: MR calculation for timing table v1.0 Roy Spliet
2017-04-10 19:37   ` [PATCH 04/11] nvkm/ramgt215: Move ram training up the chain Roy Spliet
2017-04-10 19:37   ` [PATCH 05/11] nvkm/ramgf100: Don't mandate training pattern 4 Roy Spliet
2017-04-10 19:37   ` [PATCH 06/11] nvkm/ramgf100: Unset bit before uploading train values Roy Spliet
2017-04-10 19:37   ` [PATCH 07/11] nvkm/ramgf100: Reinstate default ram train pattern Roy Spliet
2017-04-10 19:37   ` [PATCH 08/11] nvkm/ramgt215: Add train ptrn upload for GDDR5 Roy Spliet
2017-04-10 19:37   ` [PATCH 09/11] nvkm/ramgf100: Hook up ram training pattern init for NVC0+ Roy Spliet
2017-04-10 19:37   ` [PATCH 10/11] nvkm/pmu/memx: init script -> memx translation Roy Spliet
2017-04-10 19:37   ` [PATCH 11/11] nvkm/bios/perf: Retreive pointer to unk1c script 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.