drm/nve0/fb/gddr5: found LP3 setting

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
index 1427ae3..f2bbe9e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
@@ -29,7 +29,7 @@
 nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts)
 {
 	struct nouveau_bios *bios = nouveau_bios(ram);
-	int pd, lf, xd, vh, vr, vo;
+	int pd, lf, xd, vh, vr, vo, l3;
 	int WL, CL, WR, at[2], dt, ds;
 	int rq = ram->freq < 1000000; /* XXX */
 
@@ -41,6 +41,7 @@
 		vh =  (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x10) >> 4;
 		vr =  (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x04) >> 2;
 		vo =   nv_ro08(bios, ram->ramcfg.data + 0x06) & 0xff;
+		l3 = !(nv_ro08(bios, ram->ramcfg.data + 0x07) & 0x02);
 		break;
 	default:
 		return -ENOSYS;
@@ -88,8 +89,8 @@
 	ram->mr[3] &= ~0x020;
 	ram->mr[3] |= (rq & 0x01) << 5;
 
-	/*XXX: LP3, where's the bit?  Let's hardcode to off for now */
 	ram->mr[5] &= ~0x004;
+	ram->mr[5] |= (l3 << 2);
 
 	if (!vo)
 		vo = (ram->mr[6] & 0xff0) >> 4;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
index e0d63af..6682ec0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
@@ -638,16 +638,16 @@
 		data = 0xa40e0000;
 	}
 	nve0_ram_train(fuc, 0xbc0f0000, data);
-	ram_nsec(fuc, 1000);
+	if (1) /* XXX: not always? */
+		ram_nsec(fuc, 1000);
 
 	if (ram->mode == 2) { /*XXX*/
 		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000004);
 	}
 
-	/* MR5: (re)enable LP3 if necessary
-	 * XXX: need to find the switch, keeping off for now
-	 */
-	ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5]);
+	/* LP3 */
+	if (ram_mask(fuc, mr[5], 0x004, ram->base.mr[5]) != ram->base.mr[5])
+		ram_nsec(fuc, 1000);
 
 	if (ram->mode != 2) {
 		ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);