]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drm/nouveau/fb/sddr3: Expand MR generation
authorRoy Spliet <rspliet@eclipso.eu>
Thu, 4 Sep 2014 14:58:54 +0000 (16:58 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 15 Sep 2014 12:25:04 +0000 (22:25 +1000)
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c

index ebd4cd9c35d905eefc1adf51295fa0dfbafa5f1f..f84c6542c3c3d33bb603ac3b097fe5de4c82a887 100644 (file)
@@ -20,6 +20,7 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors: Ben Skeggs <bskeggs@redhat.com>
+ *         Roy Spliet <rspliet@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;
 }