Commit 19a1e477 authored by Ben Skeggs's avatar Ben Skeggs

drm/nva3/pm: another few magic regs, and slightly better 0x004018 handling

Not entirely convinced 0x004018 transitions are correct yet, but, it's
an improvement.

The 750MHz value comes from fiddling with the binary driver + coolbits on
two different DDR3 NVA8 chipsets (T510 NVS3100M, and NVS300), not a clue
where this number comes from.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2b20fd0a
...@@ -248,6 +248,8 @@ struct nva3_pm_state { ...@@ -248,6 +248,8 @@ struct nva3_pm_state {
u8 rammap_len; u8 rammap_len;
u8 *ramcfg; u8 *ramcfg;
u8 ramcfg_len; u8 ramcfg_len;
u32 r004018;
u32 r100760;
}; };
void * void *
...@@ -383,19 +385,19 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) ...@@ -383,19 +385,19 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec)
if (!(ctrl & 0x00000008) && info->mclk.pll) { if (!(ctrl & 0x00000008) && info->mclk.pll) {
nv_wr32(dev, 0x004000, (ctrl |= 0x00000008)); nv_wr32(dev, 0x004000, (ctrl |= 0x00000008));
nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000); nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000);
nv_wr32(dev, 0x004018, 0x00001000); /*XXX*/ nv_wr32(dev, 0x004018, 0x00001000);
nv_wr32(dev, 0x004000, (ctrl &= ~0x00000001)); nv_wr32(dev, 0x004000, (ctrl &= ~0x00000001));
nv_wr32(dev, 0x004004, info->mclk.pll); nv_wr32(dev, 0x004004, info->mclk.pll);
nv_wr32(dev, 0x004000, (ctrl |= 0x00000001)); nv_wr32(dev, 0x004000, (ctrl |= 0x00000001));
udelay(64); udelay(64);
nv_wr32(dev, 0x004018, 0x10005000); /*XXX*/ nv_wr32(dev, 0x004018, 0x00005000 | info->r004018);
udelay(20); udelay(20);
} else } else
if (!info->mclk.pll) { if (!info->mclk.pll) {
nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk); nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk);
nv_wr32(dev, 0x004000, (ctrl |= 0x00000008)); nv_wr32(dev, 0x004000, (ctrl |= 0x00000008));
nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000); nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000);
nv_wr32(dev, 0x004018, 0x1000d000); /*XXX*/ nv_wr32(dev, 0x004018, 0x0000d000 | info->r004018);
} }
if (info->rammap) { if (info->rammap) {
...@@ -414,6 +416,9 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) ...@@ -414,6 +416,9 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec)
} else { } else {
nv_mask(dev, 0x10053c, 0x00001000, 0x00001000); nv_mask(dev, 0x10053c, 0x00001000, 0x00001000);
nv_mask(dev, 0x10f804, 0x80000000, 0x00000000); nv_mask(dev, 0x10f804, 0x80000000, 0x00000000);
nv_mask(dev, 0x100760, 0x22222222, info->r100760);
nv_mask(dev, 0x1007a0, 0x22222222, info->r100760);
nv_mask(dev, 0x1007e0, 0x22222222, info->r100760);
} }
} }
...@@ -480,6 +485,12 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info) ...@@ -480,6 +485,12 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info)
}; };
u32 ctrl; u32 ctrl;
/* XXX: where the fuck does 750MHz come from? */
if (info->perflvl->memory <= 750000) {
info->r004018 = 0x10000000;
info->r100760 = 0x22222222;
}
ctrl = nv_rd32(dev, 0x004000); ctrl = nv_rd32(dev, 0x004000);
if (ctrl & 0x00000008) { if (ctrl & 0x00000008) {
if (info->mclk.pll) { if (info->mclk.pll) {
...@@ -489,7 +500,7 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info) ...@@ -489,7 +500,7 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info)
nv_wr32(dev, 0x004000, (ctrl &= 0xffffffef)); nv_wr32(dev, 0x004000, (ctrl &= 0xffffffef));
nv_wait(dev, 0x004000, 0x00020000, 0x00020000); nv_wait(dev, 0x004000, 0x00020000, 0x00020000);
nv_wr32(dev, 0x004000, (ctrl |= 0x00000010)); nv_wr32(dev, 0x004000, (ctrl |= 0x00000010));
nv_wr32(dev, 0x004018, 0x00005000); /*XXX*/ nv_wr32(dev, 0x004018, 0x00005000 | info->r004018);
nv_wr32(dev, 0x004000, (ctrl |= 0x00000004)); nv_wr32(dev, 0x004000, (ctrl |= 0x00000004));
} }
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment