Todo: - Determine source of R[10f298] & 0x11 Signed-off-by: Roy Spliet <nouv...@spliet.org> --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 115 ++++++++++++++-------- 1 file changed, 76 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index fffd01a..6ebdc4c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -48,11 +48,7 @@ struct gf100_ramfuc { struct ramfuc_reg r_0x137390; - struct ramfuc_reg r_0x10f290; - struct ramfuc_reg r_0x10f294; - struct ramfuc_reg r_0x10f298; - struct ramfuc_reg r_0x10f29c; - struct ramfuc_reg r_0x10f2a0; + struct ramfuc_reg r_0x10f290[5]; struct ramfuc_reg r_0x10f300; struct ramfuc_reg r_0x10f338; @@ -104,6 +100,50 @@ struct gf100_ram { struct nvbios_pll mempll; }; +#define T(t) cfg->timing_10_##t +static int +gf100_ram_timing_calc(struct gf100_ram *ram, u32 *timing) +{ + struct nvbios_ramcfg *cfg = &ram->base.target.bios; + struct nvkm_subdev *subdev = &ram->base.fb->subdev; + struct nvkm_device *device = subdev->device; + u32 cur1, cur2, cur4; + + cur1 = nvkm_rd32(device, 0x10f294); + cur2 = nvkm_rd32(device, 0x10f298); + cur4 = nvkm_rd32(device, 0x10f2a0); + + /* XXX: (G)DDR3? */ + switch ((!T(CWL)) * ram->base.type) { + case NVKM_RAM_TYPE_GDDR5: + T(CWL) = (cur1 & 0x00000380) >> 7; + break; + } + + timing[0] = (T(RP) << 24 | T(RAS) << 17 | T(RFC) << 8 | T(RC)); + timing[1] = (cur1 & ~0x03ffc07f) | + (T(RCDWR) << 20) | + (T(RCDRD) << 14) | + (T(CWL) << 7) | + (T(CL)); + /* XXX: lower 8 bytes are two bits indicating "feature(s) X" */ + timing[2] = (cur2 & ~0x00ffffff) | + (T(WR) << 16) | + (T(WTR) << 8); + timing[3] = (T(FAW)) << 9 | + (T(CKE)) << 5 | + (T(XPDLL)); + timing[4] = (cur4 & ~0x001f8000) | + (T(RRD) << 15); + + nvkm_debug(subdev, "Entry: 290: %08x %08x %08x %08x\n", + timing[0], timing[1], timing[2], timing[3]); + nvkm_debug(subdev, " 2a0: %08x\n", + timing[4]); + return 0; +} +#undef T + static void gf100_ram_train(struct gf100_ramfuc *fuc, u32 magic) { @@ -136,10 +176,11 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq) struct nvkm_ram_data *next; u8 ver, hdr, cnt, len, strap; u32 data; + u32 timing[5]; int ref, div, out; int from, mode; int N1, M1, P; - int ret; + int i, ret; next = &ram->base.target; next->freq = freq; @@ -179,6 +220,8 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq) } } + gf100_ram_timing_calc(ram, timing); + ret = ram_init(fuc, ram->base.fb); if (ret) return ret; @@ -314,28 +357,6 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq) ram_wr32(fuc, 0x10f338, 0x00300220); ram_wr32(fuc, 0x10f300, 0x0000011d); ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f290, 0x02060505); - ram_wr32(fuc, 0x10f294, 0x34208288); - ram_wr32(fuc, 0x10f298, 0x44050411); - ram_wr32(fuc, 0x10f29c, 0x0000114c); - ram_wr32(fuc, 0x10f2a0, 0x42e10069); - ram_wr32(fuc, 0x10f614, 0x40044f77); - ram_wr32(fuc, 0x10f610, 0x40044f77); - ram_wr32(fuc, 0x10f344, 0x00600009); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f348, 0x00700008); - ram_wr32(fuc, 0x61c140, 0x19240000); - ram_wr32(fuc, 0x10f830, 0x00300017); - gf100_ram_train(fuc, 0x80021001); - gf100_ram_train(fuc, 0x80081001); - ram_wr32(fuc, 0x10f340, 0x00500004); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f830, 0x01300017); - ram_wr32(fuc, 0x10f830, 0x00300017); -// 0x00030020 // 0x00000000 // 0x00000000 -// 0x00020034 // 0x0000000b - ram_wr32(fuc, 0x100b0c, 0x00080028); - ram_wr32(fuc, 0x611200, 0x00003330); } else { ram_wr32(fuc, 0x10f800, 0x00001800); ram_wr32(fuc, 0x13d8f4, 0x00000000); @@ -364,11 +385,30 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq) ram_wr32(fuc, 0x10f338, 0x00300200); ram_wr32(fuc, 0x10f300, 0x0000084d); ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f290, 0x0b343825); - ram_wr32(fuc, 0x10f294, 0x3483028e); - ram_wr32(fuc, 0x10f298, 0x440c0600); - ram_wr32(fuc, 0x10f29c, 0x0000214c); - ram_wr32(fuc, 0x10f2a0, 0x42e20069); + } + + for (i = 0; i < 5; i++) + ram_wr32(fuc, 0x10f290[i], timing[i]); + + if (mode == 0) { + ram_wr32(fuc, 0x10f614, 0x40044f77); + ram_wr32(fuc, 0x10f610, 0x40044f77); + ram_wr32(fuc, 0x10f344, 0x00600009); + ram_nsec(fuc, 1000); + ram_wr32(fuc, 0x10f348, 0x00700008); + ram_wr32(fuc, 0x61c140, 0x19240000); + ram_wr32(fuc, 0x10f830, 0x00300017); + gf100_ram_train(fuc, 0x80021001); + gf100_ram_train(fuc, 0x80081001); + ram_wr32(fuc, 0x10f340, 0x00500004); + ram_nsec(fuc, 1000); + ram_wr32(fuc, 0x10f830, 0x01300017); + ram_wr32(fuc, 0x10f830, 0x00300017); +// 0x00030020 // 0x00000000 // 0x00000000 +// 0x00020034 // 0x0000000b + ram_wr32(fuc, 0x100b0c, 0x00080028); + ram_wr32(fuc, 0x611200, 0x00003330); + } else { ram_wr32(fuc, 0x10f200, 0x00ce0000); ram_wr32(fuc, 0x10f614, 0x60044e77); ram_wr32(fuc, 0x10f610, 0x60044e77); @@ -630,7 +670,7 @@ gf100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct nvkm_subdev *subdev = &fb->subdev; struct nvkm_bios *bios = subdev->device->bios; struct gf100_ram *ram; - int ret; + int i, ret; if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) return -ENOMEM; @@ -663,11 +703,8 @@ gf100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) ram->fuc.r_0x137390 = ramfuc_reg(0x137390); - ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290); - ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294); - ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298); - ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c); - ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0); + for (i = 0; i < 5; i++) + ram->fuc.r_0x10f290[i] = ramfuc_reg(0x10f290 + (i * 4)); ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300); ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338); -- 2.9.3 _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/nouveau