[Nouveau] [PATCH 05/13] nvkm/gddr5: MR calculation for timing table v1.0
Roy Spliet
nouveau at spliet.org
Mon Apr 10 19:50:42 UTC 2017
Merges in skeggsb's:
"fb/ram/gf10x: timing_10_0e_30"
Todo:
- find l3, rq
- triple-check
Signed-off-by: Roy Spliet <nouveau at spliet.org>
---
.../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 12 +++---
drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 22 ++++++++--
drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c | 2 +
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c | 21 ++++++++--
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 49 ++++++++++++----------
5 files changed, 71 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 4560a52..44e4ca2 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -40,6 +40,10 @@ struct nvbios_ramcfg {
unsigned ramcfg_DLLoff;
unsigned ramcfg_RON;
unsigned ramcfg_FBVDDQ;
+ unsigned ramcfg_LowFreq;
+ unsigned ramcfg_WCKPin;
+ unsigned ramcfg_Hf_VREF;
+ unsigned ramcfg_VREFD_off;
union {
struct {
unsigned ramcfg_00_03_01:1;
@@ -82,12 +86,9 @@ 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_40:1;
- unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
unsigned ramcfg_11_02_04:1;
unsigned ramcfg_11_02_08:1;
- unsigned ramcfg_11_02_10:1;
unsigned ramcfg_11_02_40:1;
unsigned ramcfg_11_02_80:1;
unsigned ramcfg_11_03_0f:4;
@@ -95,7 +96,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_03_c0:2;
unsigned ramcfg_11_03_f0:4;
unsigned ramcfg_11_04:8;
- unsigned ramcfg_11_06:8;
unsigned ramcfg_11_07_02:1;
unsigned ramcfg_11_07_04:1;
unsigned ramcfg_11_07_08:1;
@@ -132,6 +132,7 @@ struct nvbios_ramcfg {
unsigned timing_10_RRD:8;
unsigned timing_10_XPDLL:8;
unsigned timing_10_ODT:3;
+ unsigned timing_10_DS:2;
/* empty: 15 */
unsigned timing_10_10:8;
/* empty: 17 */
@@ -139,7 +140,8 @@ struct nvbios_ramcfg {
unsigned timing_10_CWL:8;
unsigned timing_10_FAW:8;
unsigned timing_10_CKE:8;
- /* empty: 22, 23 */
+ unsigned timing_10_ADRCMD_T:8; /* XXX: [3:2]? */
+ /* empty: 23 */
unsigned timing_10_18:8;
};
struct {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 131d967..0d517a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -205,8 +205,11 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_02_20 = (nvbios_rd08(bios, data + 0x02) & 0x20) >> 5;
p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
+ p->ramcfg_LowFreq = (nvbios_rd08(bios, data + 0x03) & 0x20) >> 5;
+ p->ramcfg_WCKPin = (nvbios_rd08(bios, data + 0x03) & 0x40) >> 6;
p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0;
p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3;
+ p->ramcfg_Hf_VREF = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
p->ramcfg_10_05_0f = (nvbios_rd08(bios, data + 0x05) & 0x0f) >> 0;
p->ramcfg_10_05_f0 = (nvbios_rd08(bios, data + 0x05) & 0xf0) >> 4;
p->ramcfg_10_06_0f = (nvbios_rd08(bios, data + 0x06) & 0x0f) >> 0;
@@ -216,6 +219,17 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_08 = (nvbios_rd08(bios, data + 0x08) & 0xff) >> 0;
p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 0;
p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 4;
+
+ switch (elen) {
+ case 0xe:
+ case 0xd:
+ p->ramcfg_VREFD_off = nvbios_rd08(bios, data + 0x0c);
+ case 0xc:
+ case 0xb:
+ default:
+ break;
+ }
+
break;
case 0x11:
p->ramcfg_timing = nvbios_rd08(bios, data + 0x00);
@@ -225,12 +239,12 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
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_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_LowFreq = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6;
+ p->ramcfg_WCKPin = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7;
p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0;
p->ramcfg_11_02_04 = (nvbios_rd08(bios, data + 0x02) & 0x04) >> 2;
p->ramcfg_11_02_08 = (nvbios_rd08(bios, data + 0x02) & 0x08) >> 3;
- p->ramcfg_11_02_10 = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4;
+ p->ramcfg_Hf_VREF = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4;
p->ramcfg_11_02_40 = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
p->ramcfg_11_02_80 = (nvbios_rd08(bios, data + 0x02) & 0x80) >> 7;
p->ramcfg_11_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
@@ -238,7 +252,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_11_03_c0 = (nvbios_rd08(bios, data + 0x03) & 0xc0) >> 6;
p->ramcfg_11_03_f0 = (nvbios_rd08(bios, data + 0x03) & 0xf0) >> 4;
p->ramcfg_11_04 = (nvbios_rd08(bios, data + 0x04) & 0xff) >> 0;
- p->ramcfg_11_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
+ p->ramcfg_VREFD_off = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
p->ramcfg_11_07_02 = (nvbios_rd08(bios, data + 0x07) & 0x02) >> 1;
p->ramcfg_11_07_04 = (nvbios_rd08(bios, data + 0x07) & 0x04) >> 2;
p->ramcfg_11_07_08 = (nvbios_rd08(bios, data + 0x07) & 0x08) >> 3;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
index c36be13..f1999e3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
@@ -104,6 +104,7 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
p->timing_10_ODT = nvbios_rd08(bios, data + 0x0e) & 0x07;
if (p->ramcfg_ver >= 0x10)
p->ramcfg_RON = nvbios_rd08(bios, data + 0x0e) & 0x07;
+ p->timing_10_DS = nvbios_rd08(bios, data + 0xe) & 0x30 >> 4;
p->timing_10_18 = 0xff;
p->timing_10_CKE = 0;
@@ -117,6 +118,7 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
p->timing_10_18 = nvbios_rd08(bios, data + 0x18);
case 0x18:
case 0x17:
+ p->timing_10_ADRCMD_T = nvbios_rd08(bios, data + 0x16);
case 0x16:
p->timing_10_CKE = nvbios_rd08(bios, data + 0x15);
case 0x15:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index 2cc074d..22e1e0b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -39,14 +39,18 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
int rq = ram->freq < 1000000; /* XXX */
xd = !ram->next->bios.ramcfg_DLLoff;
+ lf = ram->next->bios.ramcfg_LowFreq;
+ pd = ram->next->bios.ramcfg_WCKPin;
+ vh = ram->next->bios.ramcfg_Hf_VREF;
+ vo = ram->next->bios.ramcfg_VREFD_off;
switch (ram->next->bios.ramcfg_ver) {
+ case 0x10:
+ vr = 0;
+ l3 = (ram->mr[5] & 0x4) >> 2;
+ break;
case 0x11:
- pd = ram->next->bios.ramcfg_11_01_80;
- lf = ram->next->bios.ramcfg_11_01_40;
- vh = ram->next->bios.ramcfg_11_02_10;
vr = ram->next->bios.ramcfg_11_02_04;
- vo = ram->next->bios.ramcfg_11_06;
l3 = !ram->next->bios.ramcfg_11_07_02;
break;
default:
@@ -54,6 +58,15 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
}
switch (ram->next->bios.timing_ver) {
+ case 0x10:
+ WL = ram->next->bios.timing_10_CWL;
+ CL = ram->next->bios.timing_10_CL;
+ WR = ram->next->bios.timing_10_WR;
+ at[0] = ram->next->bios.timing_10_ADRCMD_T & 0x3;
+ at[1] = 0;
+ dt = ram->next->bios.timing_10_ODT;
+ ds = ram->next->bios.timing_10_DS;
+ break;
case 0x20:
WL = (ram->next->bios.timing[1] & 0x00000f80) >> 7;
CL = (ram->next->bios.timing[1] & 0x0000001f);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 6ebdc4c..b4fe3bb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -50,11 +50,7 @@ struct gf100_ramfuc {
struct ramfuc_reg r_0x10f290[5];
- struct ramfuc_reg r_0x10f300;
- struct ramfuc_reg r_0x10f338;
- struct ramfuc_reg r_0x10f340;
- struct ramfuc_reg r_0x10f344;
- struct ramfuc_reg r_0x10f348;
+ struct ramfuc_reg r_mr[9];
struct ramfuc_reg r_0x10f910;
struct ramfuc_reg r_0x10f914;
@@ -226,6 +222,19 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
if (ret)
return ret;
+ /* Determine ram-specific MR values */
+ for (i = 0; i < 9; i++)
+ ram->base.mr[i] = ram_rd32(fuc, mr[i]);
+
+ switch (ram->base.type) {
+ case NVKM_RAM_TYPE_GDDR5:
+ ret = nvkm_gddr5_calc(&ram->base, false);
+ break;
+ default:
+ ret = -ENOSYS;
+ break;
+ }
+
/* determine current mclk configuration */
from = !!(ram_rd32(fuc, 0x1373f0) & 0x00000002); /*XXX: ok? */
@@ -354,9 +363,6 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_nsec(fuc, 2000);
ram_wr32(fuc, 0x10f314, 0x00000001);
ram_wr32(fuc, 0x10f210, 0x80000000);
- ram_wr32(fuc, 0x10f338, 0x00300220);
- ram_wr32(fuc, 0x10f300, 0x0000011d);
- ram_nsec(fuc, 1000);
} else {
ram_wr32(fuc, 0x10f800, 0x00001800);
ram_wr32(fuc, 0x13d8f4, 0x00000000);
@@ -382,25 +388,26 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_nsec(fuc, 2000);
ram_wr32(fuc, 0x10f314, 0x00000001);
ram_wr32(fuc, 0x10f210, 0x80000000);
- ram_wr32(fuc, 0x10f338, 0x00300200);
- ram_wr32(fuc, 0x10f300, 0x0000084d);
- ram_nsec(fuc, 1000);
}
+ ram_wr32(fuc, mr[3], ram->base.mr[3]);
+ ram_wr32(fuc, mr[0], ram->base.mr[0]);
+ ram_nsec(fuc, 1000);
+
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_wr32(fuc, mr[6], 0x00600009);
ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f348, 0x00700008);
+ ram_wr32(fuc, mr[7], 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_wr32(fuc, mr[5], 0x00500004);
ram_nsec(fuc, 1000);
ram_wr32(fuc, 0x10f830, 0x01300017);
ram_wr32(fuc, 0x10f830, 0x00300017);
@@ -412,11 +419,11 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wr32(fuc, 0x10f200, 0x00ce0000);
ram_wr32(fuc, 0x10f614, 0x60044e77);
ram_wr32(fuc, 0x10f610, 0x60044e77);
- ram_wr32(fuc, 0x10f340, 0x00500000);
+ ram_wr32(fuc, mr[5], 0x00500000);
ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f344, 0x00600228);
+ ram_wr32(fuc, mr[6], 0x00600228);
ram_nsec(fuc, 1000);
- ram_wr32(fuc, 0x10f348, 0x00700000);
+ ram_wr32(fuc, mr[7], 0x00700000);
ram_wr32(fuc, 0x13d8f4, 0x00000000);
ram_wr32(fuc, 0x61c140, 0x09a40000);
@@ -706,11 +713,9 @@ gf100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
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);
- ram->fuc.r_0x10f340 = ramfuc_reg(0x10f340);
- ram->fuc.r_0x10f344 = ramfuc_reg(0x10f344);
- ram->fuc.r_0x10f348 = ramfuc_reg(0x10f348);
+ ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
+ for (i = 1; i < 9; i++)
+ ram->fuc.r_mr[i] = ramfuc_reg(0x10f330 + ((i - 1) * 4));
ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
--
2.9.3
More information about the Nouveau
mailing list