summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Spliet <rspliet@eclipso.eu>2014-09-04 16:58:54 +0200
committerBen Skeggs <bskeggs@redhat.com>2014-09-15 22:25:04 +1000
commit9c870007e9ec9a6203eaff41d3360493cc2b8d2f (patch)
treefef27982874c1f5a5f7f686ecffbe8402c818def
parent941844327cc0e96b95ce9ad11bd3b0d539eff52d (diff)
drm/nouveau/fb/sddr3: Expand MR generation
Signed-off-by: Roy Spliet <rspliet@eclipso.eu> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
index ebd4cd9c35d9..f84c6542c3c3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
@@ -20,6 +20,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
+ * Roy Spliet <rspliet@eclipso.eu>
*/
#include <subdev/bios.h>
@@ -70,30 +71,52 @@ int
nouveau_sddr3_calc(struct nouveau_ram *ram)
{
struct nouveau_bios *bios = nouveau_bios(ram);
- int WL, CL, WR;
+ int CWL, CL, WR, DLL = 0, ODT = 0;
switch (!!ram->timing.data * ram->timing.version) {
+ case 0x10:
+ if (ram->timing.size < 0x17) {
+ /* XXX: NV50: Get CWL from the timing register */
+ return -ENOSYS;
+ }
+ CWL = nv_ro08(bios, ram->timing.data + 0x13);
+ CL = nv_ro08(bios, ram->timing.data + 0x02);
+ WR = nv_ro08(bios, ram->timing.data + 0x00);
+ DLL = !(nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x40);
+ ODT = nv_ro08(bios, ram->timing.data + 0x0e) & 0x07;
+ break;
case 0x20:
- WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
- CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
- WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+ CWL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
+ CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
+ WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
+ /* XXX: Get these values from the VBIOS instead */
+ DLL = !(ram->mr[1] & 0x1);
+ ODT = (ram->mr[1] & 0x004) >> 2 |
+ (ram->mr[1] & 0x040) >> 5 |
+ (ram->mr[1] & 0x200) >> 7;
break;
default:
return -ENOSYS;
}
- WL = ramxlat(ramddr3_cwl, WL);
- CL = ramxlat(ramddr3_cl, CL);
- WR = ramxlat(ramddr3_wr, WR);
- if (WL < 0 || CL < 0 || WR < 0)
+ CWL = ramxlat(ramddr3_cwl, CWL);
+ CL = ramxlat(ramddr3_cl, CL);
+ WR = ramxlat(ramddr3_wr, WR);
+ if (CL < 0 || CWL < 0 || WR < 0)
return -EINVAL;
- ram->mr[0] &= ~0xe74;
+ ram->mr[0] &= ~0xf74;
ram->mr[0] |= (WR & 0x07) << 9;
ram->mr[0] |= (CL & 0x0e) << 3;
ram->mr[0] |= (CL & 0x01) << 2;
+ ram->mr[1] &= ~0x245;
+ ram->mr[1] |= (ODT & 0x1) << 2;
+ ram->mr[1] |= (ODT & 0x2) << 5;
+ ram->mr[1] |= (ODT & 0x4) << 7;
+ ram->mr[1] |= !DLL;
+
ram->mr[2] &= ~0x038;
- ram->mr[2] |= (WL & 0x07) << 3;
+ ram->mr[2] |= (CWL & 0x07) << 3;
return 0;
}