diff -dur a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c 2014-03-09 20:01:39.000000000 +0400 +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c 2014-03-09 20:01:07.000000000 +0400 @@ -363,6 +363,69 @@ } } break; + case NV_MEM_TYPE_GDDR5: { + static const u32 offsets[] = { + 0x00, 0x20, 0x04, 0x24, + }; + int o; + printk("NV_MEM_TYPE_GDDR5 patch in use!\n"); + /* XXX this algorithm is insane, find some sanity to it. */ + /* [1] MMIO32 R 0x100268 0x30030200 PFB.SUBPART_CONFIG => { SELECT_MASK = 0x2 | UNK16 = 0x3 | ENABLE_MASK = 0x3 } */ + nv_wr32(pfb, 0x10fcac, 0x00001f01); + for (o = 0; o < 4; o++) { + int off = offsets[o]; + for (i = 0; i < 0x80; ++i) { + nv_wr32(pfb, 0x10f8c0 + off, (i << 8) | i); + + if (i < 0x30) { + switch (i) { + case 0x00: case 0x02: case 0x05: case 0x07: case 0x08: case 0x0a: case 0x0f: + case 0x12: case 0x14: case 0x16: case 0x1b: case 0x1e: + case 0x20: case 0x22: case 0x24: case 0x26: case 0x29: case 0x2b: case 0x2f: + nv_wr32(pfb, 0x10f940 + off, 0xf0); + nv_wr32(pfb, 0x10f900 + off, 0x56565656); + nv_wr32(pfb, 0x10f940 + off, 0x1f0); + nv_wr32(pfb, 0x10f900 + off, 0x56565656); + break; + case 0x09: + case 0x11: case 0x15: case 0x1d: + nv_wr32(pfb, 0x10f940 + off, 0xf0); + nv_wr32(pfb, 0x10f900 + off, 0xa9a9a9a9); + nv_wr32(pfb, 0x10f940 + off, 0x1f0); + nv_wr32(pfb, 0x10f900 + off, 0xa9a9a9a9); + break; + case 0x01: case 0x03: case 0x04: case 0x06: case 0x0b: case 0x0c: case 0x0e: + case 0x13: case 0x17: case 0x18: case 0x1a: case 0x1f: + case 0x21: case 0x23: case 0x25: case 0x27: case 0x28: case 0x2a: case 0x2c: case 0x2e: + nv_wr32(pfb, 0x10f940 + off, 0x0f); + nv_wr32(pfb, 0x10f900 + off, 0xa9a9a9a9); + nv_wr32(pfb, 0x10f940 + off, 0x10f); + nv_wr32(pfb, 0x10f900 + off, 0xa9a9a9a9); + break; + case 0x0d: + case 0x10: case 0x19: case 0x1c: + case 0x2d: + nv_wr32(pfb, 0x10f940 + off, 0x0f); + nv_wr32(pfb, 0x10f900 + off, 0x56565656); + nv_wr32(pfb, 0x10f940 + off, 0x10f); + nv_wr32(pfb, 0x10f900 + off, 0x56565656); + break; + } + } + + nv_wr32(pfb, 0x10f840 + off, i); + nv_wr32(pfb, 0x10f840 + off, 0x1000000 | i); + } + } + + nv_wr32(pfb, 0x10fc20, 0x00010c04); + nv_wr32(pfb, 0x10fc40, 0x00012585); + nv_wr32(pfb, 0x10fc80, 0x00000100); + nv_wr32(pfb, 0x10f810, 0x20012001); + nv_wr32(pfb, 0x10fcac, 0x00001e01); + nv_wr32(pfb, 0x10fc60, 0x00010808); + } + break; default: break; }