drm/nouveau/bios/rammap: Identify DLLoff for >= GF100
authorRoy Spliet <rspliet@eclipso.eu>
Tue, 29 Sep 2015 23:23:44 +0000 (00:23 +0100)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 3 Nov 2015 05:02:18 +0000 (15:02 +1000)
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c

index 3a9abd3..dd48db7 100644 (file)
@@ -78,7 +78,6 @@ 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_20:1;
                        unsigned ramcfg_11_01_40:1;
                        unsigned ramcfg_11_01_80:1;
                        unsigned ramcfg_11_02_03:2;
index f0e1fc7..3bbb1a7 100644 (file)
@@ -219,7 +219,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
                p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2;
                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_11_01_20 = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5;
+               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_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0;
index 24f83b0..2cc074d 100644 (file)
@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
        int WL, CL, WR, at[2], dt, ds;
        int rq = ram->freq < 1000000; /* XXX */
 
+       xd = !ram->next->bios.ramcfg_DLLoff;
+
        switch (ram->next->bios.ramcfg_ver) {
        case 0x11:
                pd =  ram->next->bios.ramcfg_11_01_80;
                lf =  ram->next->bios.ramcfg_11_01_40;
-               xd = !ram->next->bios.ramcfg_11_01_20;
                vh =  ram->next->bios.ramcfg_11_02_10;
                vr =  ram->next->bios.ramcfg_11_02_04;
                vo =  ram->next->bios.ramcfg_11_06;
index 9893556..0d20563 100644 (file)
@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct gk104_ram *ram, u32 freq)
  * DDR3
  ******************************************************************************/
 
+static void
+nvkm_sddr3_dll_reset(struct gk104_ramfuc *fuc)
+{
+       ram_nuke(fuc, mr[0]);
+       ram_mask(fuc, mr[0], 0x100, 0x100);
+       ram_mask(fuc, mr[0], 0x100, 0x000);
+}
+
+static void
+nvkm_sddr3_dll_disable(struct gk104_ramfuc *fuc)
+{
+       u32 mr1_old = ram_rd32(fuc, mr[1]);
+
+       if (!(mr1_old & 0x1)) {
+               ram_mask(fuc, mr[1], 0x1, 0x1);
+               ram_nsec(fuc, 1000);
+       }
+}
+
 static int
 gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
 {
@@ -702,6 +721,10 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
                ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
 
        ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
+
+       if (next->bios.ramcfg_DLLoff)
+               nvkm_sddr3_dll_disable(fuc);
+
        ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
        ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
        ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
@@ -879,17 +902,20 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
        ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
        ram_nsec(fuc, 1000);
 
-       ram_nuke(fuc, mr[0]);
-       ram_mask(fuc, mr[0], 0x100, 0x100);
-       ram_mask(fuc, mr[0], 0x100, 0x000);
+       if (!next->bios.ramcfg_DLLoff) {
+               ram_mask(fuc, mr[1], 0x1, 0x0);
+               nvkm_sddr3_dll_reset(fuc);
+       }
 
-       ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
+       ram_mask(fuc, mr[2], 0x00000fff, ram->base.mr[2]);
+       ram_mask(fuc, mr[1], 0xffffffff, ram->base.mr[1]);
        ram_wr32(fuc, mr[0], ram->base.mr[0]);
        ram_nsec(fuc, 1000);
 
-       ram_nuke(fuc, mr[0]);
-       ram_mask(fuc, mr[0], 0x100, 0x100);
-       ram_mask(fuc, mr[0], 0x100, 0x000);
+       if (!next->bios.ramcfg_DLLoff) {
+               nvkm_sddr3_dll_reset(fuc);
+               ram_nsec(fuc, 1000);
+       }
 
        if (vc == 0 && ram_have(fuc, gpio2E)) {
                u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
@@ -1600,6 +1626,7 @@ gk104_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
                break;
        case NVKM_RAM_TYPE_DDR3:
                ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
+               ram->fuc.r_mr[1] = ramfuc_reg(0x10f304);
                ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
                break;
        default:
index b4edc97..2690033 100644 (file)
@@ -70,6 +70,8 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
 {
        int CWL, CL, WR, DLL = 0, ODT = 0;
 
+       DLL = !ram->next->bios.ramcfg_DLLoff;
+
        switch (ram->next->bios.timing_ver) {
        case 0x10:
                if (ram->next->bios.timing_hdr < 0x17) {
@@ -79,7 +81,6 @@ 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_DLLoff;
                ODT = ram->next->bios.timing_10_ODT;
                break;
        case 0x20:
@@ -87,7 +88,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
                CL  = (ram->next->bios.timing[1] & 0x0000001f) >> 0;
                WR  = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
                /* 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;