[Nouveau] [PATCH 7/8] fb/sddr3: Expand MR generation

Roy Spliet rspliet at eclipso.eu
Thu Sep 4 07:58:54 PDT 2014


Signed-off-by: Roy Spliet <rspliet at eclipso.eu>
---
 drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c | 43 ++++++++++++++++++++------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
index ebd4cd9..f84c654 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
@@ -20,6 +20,7 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors: Ben Skeggs <bskeggs at redhat.com>
+ * 	    Roy Spliet <rspliet at eclipso.eu>
  */
 
 #include <subdev/bios.h>
@@ -70,30 +71,52 @@ int
 nouveau_sddr3_calc(struct nouveau_ram *ram)
 {
 	struct nouveau_bios *bios = nouveau_bios(ram);
-	int WL, CL, WR;
+	int CWL, CL, WR, DLL = 0, ODT = 0;
 
 	switch (!!ram->timing.data * ram->timing.version) {
+	case 0x10:
+		if (ram->timing.size < 0x17) {
+			/* XXX: NV50: Get CWL from the timing register */
+			return -ENOSYS;
+		}
+		CWL =   nv_ro08(bios, ram->timing.data + 0x13);
+		CL  =   nv_ro08(bios, ram->timing.data + 0x02);
+		WR  =   nv_ro08(bios, ram->timing.data + 0x00);
+		DLL = !(nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x40);
+		ODT =   nv_ro08(bios, ram->timing.data + 0x0e) & 0x07;
+		break;
 	case 0x20:
-		WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
-		CL =  nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
-		WR =  nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+		CWL =  (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
+		CL  =   nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
+		WR  =   nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+		/* XXX: Get these values from the VBIOS instead */
+		DLL = !(ram->mr[1] & 0x1);
+		ODT =   (ram->mr[1] & 0x004) >> 2 |
+			(ram->mr[1] & 0x040) >> 5 |
+		        (ram->mr[1] & 0x200) >> 7;
 		break;
 	default:
 		return -ENOSYS;
 	}
 
-	WL = ramxlat(ramddr3_cwl, WL);
-	CL = ramxlat(ramddr3_cl, CL);
-	WR = ramxlat(ramddr3_wr, WR);
-	if (WL < 0 || CL < 0 || WR < 0)
+	CWL = ramxlat(ramddr3_cwl, CWL);
+	CL  = ramxlat(ramddr3_cl, CL);
+	WR  = ramxlat(ramddr3_wr, WR);
+	if (CL < 0 || CWL < 0 || WR < 0)
 		return -EINVAL;
 
-	ram->mr[0] &= ~0xe74;
+	ram->mr[0] &= ~0xf74;
 	ram->mr[0] |= (WR & 0x07) << 9;
 	ram->mr[0] |= (CL & 0x0e) << 3;
 	ram->mr[0] |= (CL & 0x01) << 2;
 
+	ram->mr[1] &= ~0x245;
+	ram->mr[1] |= (ODT & 0x1) << 2;
+	ram->mr[1] |= (ODT & 0x2) << 5;
+	ram->mr[1] |= (ODT & 0x4) << 7;
+	ram->mr[1] |= !DLL;
+
 	ram->mr[2] &= ~0x038;
-	ram->mr[2] |= (WL & 0x07) << 3;
+	ram->mr[2] |= (CWL & 0x07) << 3;
 	return 0;
 }
-- 
1.9.3





More information about the Nouveau mailing list