drm/nouveau/bios: parse freq ranges and timing id into ramcfg struct
authorBen Skeggs <bskeggs@redhat.com>
Mon, 8 Sep 2014 02:48:31 +0000 (12:48 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 15 Sep 2014 12:25:08 +0000 (22:25 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h
drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h
drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c

index c086ac6d677d5badd33542e1c7a87047325e883e..bae3ba2dfa1dee81380b4d5f1c6d66e6d6117ddf 100644 (file)
@@ -4,11 +4,18 @@
 struct nouveau_bios;
 
 struct nvbios_ramcfg {
+       unsigned rammap_ver;
+       unsigned rammap_hdr;
+       unsigned rammap_min;
+       unsigned rammap_max;
        unsigned rammap_11_08_01:1;
        unsigned rammap_11_08_0c:2;
        unsigned rammap_11_08_10:1;
        unsigned rammap_11_11_0c:2;
 
+       unsigned ramcfg_ver;
+       unsigned ramcfg_hdr;
+       unsigned ramcfg_timing;
        unsigned ramcfg_11_01_01:1;
        unsigned ramcfg_11_01_02:1;
        unsigned ramcfg_11_01_04:1;
@@ -43,6 +50,8 @@ struct nvbios_ramcfg {
        unsigned ramcfg_11_08_20:1;
        unsigned ramcfg_11_09:8;
 
+       unsigned timing_ver;
+       unsigned timing_hdr;
        unsigned timing[11];
        unsigned timing_20_2e_03:2;
        unsigned timing_20_2e_30:2;
index 5bdf8e4db40a137df8b00f4a0183424929ad828c..47e021d3e20dd34ee76912bb2b717d4640bbe32b 100644 (file)
@@ -8,9 +8,10 @@ u32 nvbios_rammapTe(struct nouveau_bios *, u8 *ver, u8 *hdr,
 
 u32 nvbios_rammapEe(struct nouveau_bios *, int idx,
                    u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_rammapEp(struct nouveau_bios *, int idx,
+                   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+                   struct nvbios_ramcfg *);
 u32 nvbios_rammapEm(struct nouveau_bios *, u16 mhz,
-                   u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_rammapEp(struct nouveau_bios *, u16 mhz,
                    u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
                    struct nvbios_ramcfg *);
 
index 1811b2cb047276ead557d6d1025568667a1fbc24..775f7735e0bd337591a251f5ce8b4cc7f63e2f3e 100644 (file)
@@ -75,28 +75,18 @@ nvbios_rammapEe(struct nouveau_bios *bios, int idx,
 }
 
 u32
-nvbios_rammapEm(struct nouveau_bios *bios, u16 khz,
-               u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
-{
-       int idx = 0;
-       u32 data;
-       while ((data = nvbios_rammapEe(bios, idx++, ver, hdr, cnt, len))) {
-               if (khz >= nv_ro16(bios, data + 0x00) &&
-                   khz <= nv_ro16(bios, data + 0x02))
-                       break;
-       }
-       return data;
-}
-
-u32
-nvbios_rammapEp(struct nouveau_bios *bios, u16 khz,
+nvbios_rammapEp(struct nouveau_bios *bios, int idx,
                u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
                struct nvbios_ramcfg *p)
 {
-       u32 data = nvbios_rammapEm(bios, khz, ver, hdr, cnt, len);
+       u32 data = nvbios_rammapEe(bios, idx, ver, hdr, cnt, len);
        memset(p, 0x00, sizeof(*p));
+       p->rammap_ver = *ver;
+       p->rammap_hdr = *hdr;
        switch (!!data * *ver) {
        case 0x11:
+               p->rammap_min      =  nv_ro16(bios, data + 0x00);
+               p->rammap_max      =  nv_ro16(bios, data + 0x02);
                p->rammap_11_08_01 = (nv_ro08(bios, data + 0x08) & 0x01) >> 0;
                p->rammap_11_08_0c = (nv_ro08(bios, data + 0x08) & 0x0c) >> 2;
                p->rammap_11_08_10 = (nv_ro08(bios, data + 0x08) & 0x10) >> 4;
@@ -109,6 +99,20 @@ nvbios_rammapEp(struct nouveau_bios *bios, u16 khz,
        return data;
 }
 
+u32
+nvbios_rammapEm(struct nouveau_bios *bios, u16 mhz,
+               u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+               struct nvbios_ramcfg *info)
+{
+       int idx = 0;
+       u32 data;
+       while ((data = nvbios_rammapEp(bios, idx++, ver, hdr, cnt, len, info))) {
+               if (mhz >= info->rammap_min && mhz <= info->rammap_max)
+                       break;
+       }
+       return data;
+}
+
 u32
 nvbios_rammapSe(struct nouveau_bios *bios, u32 data,
                u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
@@ -129,8 +133,11 @@ nvbios_rammapSp(struct nouveau_bios *bios, u32 data,
                u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
 {
        data = nvbios_rammapSe(bios, data, ever, ehdr, ecnt, elen, idx, ver, hdr);
+       p->ramcfg_ver = *ver;
+       p->ramcfg_hdr = *hdr;
        switch (!!data * *ver) {
        case 0x11:
+               p->ramcfg_timing   =  nv_ro08(bios, data + 0x00);
                p->ramcfg_11_01_01 = (nv_ro08(bios, data + 0x01) & 0x01) >> 0;
                p->ramcfg_11_01_02 = (nv_ro08(bios, data + 0x01) & 0x02) >> 1;
                p->ramcfg_11_01_04 = (nv_ro08(bios, data + 0x01) & 0x04) >> 2;
index 350d44ab2ba24b9e56a9dbf178a86497159cc326..c320bfdd1102a946b24bb5937822aacfb07bb88f 100644 (file)
@@ -89,6 +89,8 @@ nvbios_timingEp(struct nouveau_bios *bios, int idx,
                struct nvbios_ramcfg *p)
 {
        u16 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp;
+       p->timing_ver = *ver;
+       p->timing_hdr = *hdr;
        switch (!!data * *ver) {
        case 0x20:
                p->timing[0] = nv_ro32(bios, data + 0x00);
index 686e0d679d173084ce99a44eb8d8e4e749f169a8..b3c53d6dd82a8b6c919e958361adc053e48a91c6 100644 (file)
@@ -79,6 +79,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
        struct nva3_ram *ram = (void *)pfb->ram;
        struct nva3_ramfuc *fuc = &ram->fuc;
        struct nva3_clock_info mclk;
+       struct nvbios_ramcfg cfg;
        u8  ver, cnt, len, strap;
        u32 data;
        struct {
@@ -91,7 +92,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
 
        /* lookup memory config data relevant to the target frequency */
        rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
-                                    &cnt, &ramcfg.size);
+                                    &cnt, &ramcfg.size, &cfg);
        if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
                nv_error(pfb, "invalid/missing rammap entry\n");
                return -EINVAL;
index fc9de888fa8193416e7cf6bbaaca4ecf16f084ef..735cb9580abe88330efe78b8718378b619d4d66d 100644 (file)
@@ -133,6 +133,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
        struct nouveau_bios *bios = nouveau_bios(pfb);
        struct nvc0_ram *ram = (void *)pfb->ram;
        struct nvc0_ramfuc *fuc = &ram->fuc;
+       struct nvbios_ramcfg cfg;
        u8  ver, cnt, len, strap;
        struct {
                u32 data;
@@ -145,7 +146,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
 
        /* lookup memory config data relevant to the target frequency */
        rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
-                                    &cnt, &ramcfg.size);
+                                    &cnt, &ramcfg.size, &cfg);
        if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
                nv_error(pfb, "invalid/missing rammap entry\n");
                return -EINVAL;
index 51aa29e8f7eb610713a2cddf2d4c5a8c87a50482..1fa45c5e50d75b83c59505b1b0911b13aa957104 100644 (file)
@@ -942,7 +942,7 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq,
        u8 strap, cnt, len;
 
        /* lookup memory config data relevant to the target frequency */
-       ram->base.rammap.data = nvbios_rammapEp(bios, freq / 1000,
+       ram->base.rammap.data = nvbios_rammapEm(bios, freq / 1000,
                                               &ram->base.rammap.version,
                                               &ram->base.rammap.size,
                                               &cnt, &len, &data->bios);
@@ -968,12 +968,12 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq,
        }
 
        /* lookup memory timings, if bios says they're present */
-       strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
-       if (strap != 0xff) {
+       if (data->bios.ramcfg_timing != 0xff) {
                ram->base.timing.data =
-                       nvbios_timingEp(bios, strap, &ram->base.timing.version,
-                                      &ram->base.timing.size, &cnt, &len,
-                                      &data->bios);
+                       nvbios_timingEp(bios, data->bios.ramcfg_timing,
+                                       &ram->base.timing.version,
+                                       &ram->base.timing.size, &cnt, &len,
+                                       &data->bios);
                if (!ram->base.timing.data ||
                     ram->base.timing.version != 0x20 ||
                     ram->base.timing.size < 0x33) {