Commit 1cf688dd authored by Roy Spliet's avatar Roy Spliet Committed by Ben Skeggs

drm/nouveau/fb/ramnv50: Voltage GPIOs

Does not seem to be necessary for NVA0, hence untested by me.
Signed-off-by: default avatarRoy Spliet <rspliet@eclipso.eu>
Tested-by: default avatarPierre Moreau <pierre.morrow@free.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 0b0b78cd
...@@ -171,6 +171,7 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx, ...@@ -171,6 +171,7 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2; p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2;
p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3; p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3;
p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3; p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3;
p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x03) & 0x80) >> 7;
p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1; p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1;
p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2; p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2;
p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5; p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <subdev/bios/rammap.h> #include <subdev/bios/rammap.h>
#include <subdev/bios/timing.h> #include <subdev/bios/timing.h>
#include <subdev/clk/pll.h> #include <subdev/clk/pll.h>
#include <subdev/gpio.h>
struct nv50_ramseq { struct nv50_ramseq {
struct hwsq base; struct hwsq base;
...@@ -59,6 +60,7 @@ struct nv50_ramseq { ...@@ -59,6 +60,7 @@ struct nv50_ramseq {
struct hwsq_reg r_0x611200; struct hwsq_reg r_0x611200;
struct hwsq_reg r_timing[9]; struct hwsq_reg r_timing[9];
struct hwsq_reg r_mr[4]; struct hwsq_reg r_mr[4];
struct hwsq_reg r_gpio[4];
}; };
struct nv50_ram { struct nv50_ram {
...@@ -154,6 +156,33 @@ nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq) ...@@ -154,6 +156,33 @@ nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq)
ram_nsec(hwsq, 24000); ram_nsec(hwsq, 24000);
} }
static void
nv50_ram_gpio(struct nv50_ramseq *hwsq, u8 tag, u32 val)
{
struct nvkm_gpio *gpio = hwsq->base.subdev->device->gpio;
struct dcb_gpio_func func;
u32 reg, sh, gpio_val;
int ret;
if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
if (ret)
return;
reg = func.line >> 3;
sh = (func.line & 0x7) << 2;
gpio_val = ram_rd32(hwsq, gpio[reg]);
if (gpio_val & (8 << sh))
val = !val;
if (!(func.log[1] & 1))
val = !val;
ram_mask(hwsq, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
ram_nsec(hwsq, 20000);
}
}
static int static int
nv50_ram_calc(struct nvkm_ram *base, u32 freq) nv50_ram_calc(struct nvkm_ram *base, u32 freq)
{ {
...@@ -250,6 +279,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -250,6 +279,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */ ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
ram_nsec(hwsq, 2000); ram_nsec(hwsq, 2000);
if (next->bios.timing_10_ODT)
nv50_ram_gpio(hwsq, 0x2e, 1);
ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */ ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */
ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
...@@ -288,6 +320,7 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -288,6 +320,7 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x004008, 0x91ff0000, r004008); ram_mask(hwsq, 0x004008, 0x91ff0000, r004008);
if (subdev->device->chipset >= 0x96) if (subdev->device->chipset >= 0x96)
ram_wr32(hwsq, 0x100da0, r100da0); ram_wr32(hwsq, 0x100da0, r100da0);
nv50_ram_gpio(hwsq, 0x18, !next->bios.ramcfg_FBVDDQ);
ram_nsec(hwsq, 64000); /*XXX*/ ram_nsec(hwsq, 64000); /*XXX*/
ram_nsec(hwsq, 32000); /*XXX*/ ram_nsec(hwsq, 32000); /*XXX*/
...@@ -364,6 +397,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) ...@@ -364,6 +397,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
} }
ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]); ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]);
if (!next->bios.timing_10_ODT)
nv50_ram_gpio(hwsq, 0x2e, 0);
/* Reset DLL */ /* Reset DLL */
if (!next->bios.ramcfg_DLLoff) if (!next->bios.ramcfg_DLLoff)
nvkm_sddr2_dll_reset(hwsq); nvkm_sddr2_dll_reset(hwsq);
...@@ -634,5 +670,10 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) ...@@ -634,5 +670,10 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4); ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4);
} }
ram->hwsq.r_gpio[0] = hwsq_reg(0x00e104);
ram->hwsq.r_gpio[1] = hwsq_reg(0x00e108);
ram->hwsq.r_gpio[2] = hwsq_reg(0x00e120);
ram->hwsq.r_gpio[3] = hwsq_reg(0x00e124);
return 0; return 0;
} }
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