ramnve0.c revision b6f97a089b6d0e7463a5062fb29a002fc9b1d025
1aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*
2aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * Copyright 2013 Red Hat Inc.
3aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs *
4aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining a
5aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * copy of this software and associated documentation files (the "Software"),
6aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * to deal in the Software without restriction, including without limitation
7aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * and/or sell copies of the Software, and to permit persons to whom the
9aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * Software is furnished to do so, subject to the following conditions:
10aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs *
11aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * The above copyright notice and this permission notice shall be included in
12aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * all copies or substantial portions of the Software.
13aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs *
14aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * OTHER DEALINGS IN THE SOFTWARE.
21aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs *
22aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * Authors: Ben Skeggs
23aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs */
24aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
25aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/gpio.h>
26aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
27aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios.h>
28aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/pll.h>
29aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/init.h>
30aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/rammap.h>
31aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/timing.h>
326b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs#include <subdev/bios/M0205.h>
336b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs#include <subdev/bios/M0209.h>
34aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
35aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/clock.h>
36aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/clock/pll.h>
37aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
38aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/timer.h>
39aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
40aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <core/option.h>
41aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
42aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include "nvc0.h"
43aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
44aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include "ramfuc.h"
45aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
46aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstruct nve0_ramfuc {
47aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc base;
48aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
49aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nvbios_pll refpll;
50aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nvbios_pll mempll;
51aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
52aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_gpioMV;
53aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 r_funcMV[2];
54aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_gpio2E;
55aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 r_func2E[2];
56aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_gpiotrig;
57aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
58aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132020;
59aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132028;
60aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132024;
61aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132030;
62aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132034;
63aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132000;
64aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132004;
65aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132040;
66aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
67aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f248;
68aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f290;
69aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f294;
70aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f298;
71aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f29c;
72aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2a0;
73aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2a4;
74aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2a8;
75aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2ac;
76aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2cc;
77aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2e8;
78aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f250;
79aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f24c;
80aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10fec4;
81aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10fec8;
82aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f604;
83aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f614;
84aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f610;
85aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x100770;
86aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x100778;
87aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f224;
88aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
89aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f870;
90aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f698;
91aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f694;
92aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f6b8;
93aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f808;
94aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f670;
95aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f60c;
96aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f830;
97aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x1373ec;
98aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f800;
99aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f82c;
100aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
101aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f978;
102aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f910;
103aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f914;
104aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
105aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_mr[16]; /* MR0 - MR8, MR15 */
106aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
107aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x62c000;
108d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
109aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f200;
110d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
111aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f210;
112aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f310;
113aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f314;
114aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f318;
115aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f090;
116aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f69c;
117aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f824;
118aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x1373f0;
119aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x1373f4;
120aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x137320;
121aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f65c;
122aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f6bc;
123aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x100710;
124dd95c8f782a053db361855298778a7d31de04a48Ben Skeggs	struct ramfuc_reg r_0x100750;
125aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs};
126aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
127aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstruct nve0_ram {
128aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_ram base;
129aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc fuc;
130d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
131d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct list_head cfg;
132d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 parts;
133d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 pmask;
134d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 pnuts;
135d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
13691e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	struct nvbios_ramcfg diff;
137aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int from;
138aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int mode;
139aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int N1, fN1, M1, P1;
140aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int N2, M2, P2;
141aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs};
142aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
143aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*******************************************************************************
144aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * GDDR5
145aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs ******************************************************************************/
146aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
14701891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggsnve0_ram_train(struct nve0_ramfuc *fuc, u32 mask, u32 data)
148aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
149aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
150d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 addr = 0x110974, i;
151aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
15201891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggs	ram_mask(fuc, 0x10f910, mask, data);
15301891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggs	ram_mask(fuc, 0x10f914, mask, data);
1545905439224043465309e9989bfd9369efb9220abBen Skeggs
15501891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggs	for (i = 0; (data & 0x80000000) && i < ram->parts; addr += 0x1000, i++) {
156d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		if (ram->pmask & (1 << i))
1575905439224043465309e9989bfd9369efb9220abBen Skeggs			continue;
158aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
159aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
160aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
161aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
162aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
163aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsr1373f4_init(struct nve0_ramfuc *fuc)
164aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
165aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
166aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 mcoef = ((--ram->P2 << 28) | (ram->N2 << 8) | ram->M2);
167aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 rcoef = ((  ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
168aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk0 = ram->fN1 << 16;
169aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk1 = ram->fN1;
170aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
171aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from == 2) {
172aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
173aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
174aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
175aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
176aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
177aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
178aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
179aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
180aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
181aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* (re)program refpll, if required */
182aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
183aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	    (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
184aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
185aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
186aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x137320, 0x00000000);
187aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132030, 0xffff0000, runk0);
188aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
189aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x132024, rcoef);
190aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
191aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
192aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
193aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
194aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
195aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
196aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* (re)program mempll, if required */
197aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) {
198aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
199797a816221655d7204c6a5536d1400c022b01939Ben Skeggs		ram_mask(fuc, 0x132000, 0x80000000, 0x80000000);
200aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
201aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
202aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
203aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
204aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
205aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
206aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010100);
207aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
208aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
209aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
210aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
211aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
212aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
213b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggsr1373f4_fini(struct nve0_ramfuc *fuc)
214aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
215aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
216b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	struct nouveau_ram_data *next = ram->base.next;
217b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	u8 v0 = next->bios.ramcfg_11_03_c0;
218b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	u8 v1 = next->bios.ramcfg_11_03_30;
219aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 tmp;
220aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
221aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
222aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x1373ec, tmp | (v1 << 16));
223aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f0, (~ram->mode & 3), 0x00000000);
224aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) {
225aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000002);
226aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00001100, 0x000000000);
227aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
228aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000001);
229aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00010000, 0x000000000);
230aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
231aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f800, 0x00000030, (v0 ^ v1) << 4);
232aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
233aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
234d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggsstatic void
235d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggsnve0_ram_nuts(struct nve0_ram *ram, struct ramfuc_reg *reg,
236d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	      u32 _mask, u32 _data, u32 _copy)
237d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs{
238d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	struct nve0_fb_priv *priv = (void *)nouveau_fb(ram);
239d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	struct ramfuc *fuc = &ram->fuc.base;
240d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 addr = 0x110000 + (reg->addr[0] & 0xfff);
241d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 mask = _mask | _copy;
242d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 data = (_data & _mask) | (reg->data & _copy);
243d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 i;
244d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
245d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	for (i = 0; i < 16; i++, addr += 0x1000) {
246d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		if (ram->pnuts & (1 << i)) {
247d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			u32 prev = nv_rd32(priv, addr);
248d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			u32 next = (prev & ~mask) | data;
249d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			nouveau_memx_wr32(fuc->memx, addr, next);
250d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		}
251d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	}
252d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs}
253d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs#define ram_nuts(s,r,m,d,c)                                                    \
254d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	nve0_ram_nuts((s), &(s)->fuc.r_##r, (m), (d), (c))
255d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
256aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
257aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
258aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
259aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
260aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
261b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	struct nouveau_ram_data *next = ram->base.next;
26286899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	int vc = !next->bios.ramcfg_11_02_08;
26386899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	int mv = !next->bios.ramcfg_11_02_04;
264b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	u32 mask, data;
265aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
266aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
267aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0000);
268aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
269aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* MR1: turn termination on early, for some reason.. */
270d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	if ((ram->base.mr[1] & 0x03c) != 0x030) {
271aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, mr[1], 0x03c, ram->base.mr[1] & 0x03c);
272d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		ram_nuts(ram, mr[1], 0x03c, ram->base.mr1_nuts & 0x03c, 0x000);
273d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	}
274aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
275aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 1 && ram_have(fuc, gpio2E)) {
276aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
277aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
278aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
279aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
280aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
281aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
282aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
283aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
284aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
28501891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggs	nve0_ram_train(fuc, 0x01020000, 0x000c0000);
286aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
287aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
288aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
289aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
290aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
291aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
292aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
293aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
294aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
295aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x00000061);
296aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0xc000007f);
297aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
298aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
299aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f698, 0x00000000);
300aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f69c, 0x00000000);
301aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
302aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: there does appear to be some kind of condition here, simply
303aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     modifying these bits in the vbios from the default pl0
304aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     entries shows no change.  however, the data does appear to
305aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     be correct and may be required for the transition back
306aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
307aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x800f07e0;
308aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00030000;
309aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_rd32(fuc, 0x10f978) & 0x00800000)
310aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00040000;
311aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
312aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (1) {
313aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x800807e0;
314b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		switch (next->bios.ramcfg_11_03_c0) {
315b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 3: data &= ~0x00000040; break;
316b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 2: data &= ~0x00000100; break;
317b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 1: data &= ~0x80000000; break;
318b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 0: data &= ~0x00000400; break;
319aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
320aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
321b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		switch (next->bios.ramcfg_11_03_30) {
322b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 3: data &= ~0x00000020; break;
323b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 2: data &= ~0x00000080; break;
324b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 1: data &= ~0x00080000; break;
325b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 0: data &= ~0x00000200; break;
326aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
327aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
328aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
329b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_02_80)
330aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x03000000;
331b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_02_40)
332aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00002000;
333b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_07_10)
334aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00004000;
335b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_07_08)
336aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00000003;
337aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else {
338aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x34000000;
339aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ram_rd32(fuc, 0x10f978) & 0x00800000)
340aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			mask |= 0x40000000;
341aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
342aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
343aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
344aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
345aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
346aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from == 2 && ram->mode != 2) {
347aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
3487f39e597726774cb3fee71f4b605a5499f7c3a8aBen Skeggs		ram_mask(fuc, 0x10f200, 0x18008000, 0x00008000);
349aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000000, 0x00000004);
350aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x00008000, 0x01040010);
351aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
352aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
353aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001);
354b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		r1373f4_fini(fuc);
355aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001);
356aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else
357aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from != 2 && ram->mode != 2) {
358aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
359b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		r1373f4_fini(fuc);
360aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
361aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
362aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_have(fuc, gpioMV)) {
363aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
364aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpioMV)) {
365aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
366aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 64000);
367aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
368aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
369aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
37086899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (next->bios.ramcfg_11_02_40 ||
37186899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	    next->bios.ramcfg_11_07_10) {
372aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
373aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 20000);
374aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
375aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
376aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from != 2 && ram->mode == 2) {
3777f39e597726774cb3fee71f4b605a5499f7c3a8aBen Skeggs		if (0 /*XXX: Titan */)
3787f39e597726774cb3fee71f4b605a5499f7c3a8aBen Skeggs			ram_mask(fuc, 0x10f200, 0x18000000, 0x18000000);
379aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
380aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002);
381aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010);
382aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
383b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		r1373f4_fini(fuc);
384aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000);
385aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000);
386aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else
387aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from == 2 && ram->mode == 2) {
388aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
389aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
390b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		r1373f4_fini(fuc);
391aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
392aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
393aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) /*XXX*/ {
394b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.ramcfg_11_07_40)
395aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
396aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
397aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
398b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f65c, 0x00000011 * next->bios.rammap_11_11_0c);
399b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f6b8, 0x01010101 * next->bios.ramcfg_11_09);
400b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f6bc, 0x01010101 * next->bios.ramcfg_11_09);
401aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
402a8ccbb7701d41a772d839acb3d81d7f9ac84c678Ben Skeggs	if (!next->bios.ramcfg_11_07_08 && !next->bios.ramcfg_11_07_04) {
403b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		ram_wr32(fuc, 0x10f698, 0x01010101 * next->bios.ramcfg_11_04);
404b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		ram_wr32(fuc, 0x10f69c, 0x01010101 * next->bios.ramcfg_11_04);
405a8ccbb7701d41a772d839acb3d81d7f9ac84c678Ben Skeggs	} else
406a8ccbb7701d41a772d839acb3d81d7f9ac84c678Ben Skeggs	if (!next->bios.ramcfg_11_07_08) {
407a8ccbb7701d41a772d839acb3d81d7f9ac84c678Ben Skeggs		ram_wr32(fuc, 0x10f698, 0x00000000);
408a8ccbb7701d41a772d839acb3d81d7f9ac84c678Ben Skeggs		ram_wr32(fuc, 0x10f69c, 0x00000000);
409aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
410aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
411aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) {
412b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		u32 data = 0x01000100 * next->bios.ramcfg_11_04;
413b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		ram_nuke(fuc, 0x10f694);
414b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		ram_mask(fuc, 0x10f694, 0xff00ff00, data);
415aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
416aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
41786899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (ram->mode == 2 && next->bios.ramcfg_11_08_10)
418aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000080;
419aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
420aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
421aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f60c, 0x00000080, data);
422aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
423aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x00070000;
424aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
42586899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_02_80)
426aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x03000000;
42786899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_02_40)
428aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00002000;
42986899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_10)
430aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00004000;
43186899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_08)
432aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000003;
433aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
434aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x74000000;
435aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
436aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
437b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_01_08)
438aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
439aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
440aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00001000;
441aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00001000, data);
442aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
443aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_rd32(fuc, 0x10f670) & 0x80000000) {
444aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 10000);
445aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000);
446aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
447aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
448b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_08_01)
449aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00100000;
450aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
451aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
452aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f82c, 0x00100000, data);
453aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
454aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
455b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_08_08)
456aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00002000;
457b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_08_04)
458aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00001000;
459b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_08_02)
460aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00004000;
461aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f830, 0x00007000, data);
462aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
463aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* PFB timing */
464b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f248, 0xffffffff, next->bios.timing[10]);
465b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f290, 0xffffffff, next->bios.timing[0]);
466b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f294, 0xffffffff, next->bios.timing[1]);
467b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f298, 0xffffffff, next->bios.timing[2]);
468b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f29c, 0xffffffff, next->bios.timing[3]);
469b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2a0, 0xffffffff, next->bios.timing[4]);
470b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2a4, 0xffffffff, next->bios.timing[5]);
471b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2a8, 0xffffffff, next->bios.timing[6]);
472b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2ac, 0xffffffff, next->bios.timing[7]);
473b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2cc, 0xffffffff, next->bios.timing[8]);
474b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2e8, 0xffffffff, next->bios.timing[9]);
475aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
476db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	data = mask = 0x00000000;
47791e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_08_20) {
478b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs		if (next->bios.ramcfg_11_08_20)
479b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs			data |= 0x01000000;
480b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs		mask |= 0x01000000;
481b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs	}
482b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs	ram_mask(fuc, 0x10f200, mask, data);
483b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs
484b13d0e4a9323939c4051eda9e7d1623298bb2102Ben Skeggs	data = mask = 0x00000000;
48591e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_02_03) {
48686899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs		data |= next->bios.ramcfg_11_02_03 << 8;
487db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x00000300;
488db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
48991e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_01_10) {
490b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.ramcfg_11_01_10)
49109692e5b4efb1ed1d91b4e9e4c7a31b7dbe06f03Ben Skeggs			data |= 0x70000000;
492db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x70000000;
493db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
494db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	ram_mask(fuc, 0x10f604, mask, data);
49509692e5b4efb1ed1d91b4e9e4c7a31b7dbe06f03Ben Skeggs
496db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	data = mask = 0x00000000;
49791e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.timing_20_30_07) {
49886899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs		data |= next->bios.timing_20_30_07 << 28;
499db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x70000000;
500db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
50191e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_01_01) {
502b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.ramcfg_11_01_01)
50309692e5b4efb1ed1d91b4e9e4c7a31b7dbe06f03Ben Skeggs			data |= 0x00000100;
504db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x00000100;
505db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
506db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	ram_mask(fuc, 0x10f614, mask, data);
50709692e5b4efb1ed1d91b4e9e4c7a31b7dbe06f03Ben Skeggs
508db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	data = mask = 0x00000000;
50991e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.timing_20_30_07) {
51086899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs		data |= next->bios.timing_20_30_07 << 28;
511db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x70000000;
512db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
51391e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_01_02) {
514b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.ramcfg_11_01_02)
51509692e5b4efb1ed1d91b4e9e4c7a31b7dbe06f03Ben Skeggs			data |= 0x00000100;
516db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x00000100;
51709692e5b4efb1ed1d91b4e9e4c7a31b7dbe06f03Ben Skeggs	}
518db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	ram_mask(fuc, 0x10f610, mask, data);
519aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
520aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x33f00000;
521aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
52286899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_01_04)
523aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x20200000;
52486899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_80)
525aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x12800000;
526aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: see note above about there probably being some condition
527aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     for the 10f824 stuff that uses ramcfg 3...
528aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
52986899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (next->bios.ramcfg_11_03_f0) {
530b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.rammap_11_08_0c) {
53186899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs			if (!next->bios.ramcfg_11_07_80)
532aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				mask |= 0x00000020;
533aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			else
534aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				data |= 0x00000020;
535aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			mask |= 0x00000004;
536aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
537aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
538aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x40000020;
539aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000004;
540aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
541aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
542aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, mask, data);
543aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
544b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f870, 0x11111111 * next->bios.ramcfg_11_03_0f);
545aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
546db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	data = mask = 0x00000000;
54791e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_02_03) {
548b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		data |= next->bios.ramcfg_11_02_03;
549db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x00000003;
550db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
55191e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ram->diff.ramcfg_11_01_10) {
552b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.ramcfg_11_01_10)
553db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs			data |= 0x00000004;
554db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		mask |= 0x00000004;
555db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	}
556db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs
557db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs	if ((ram_mask(fuc, 0x100770, mask, data) & mask & 4) != (data & 4)) {
558db6735cab2b0f12a824f04b1d8fb4da2ea978c8dBen Skeggs		ram_mask(fuc, 0x100750, 0x00000008, 0x00000008);
559aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x100710, 0x00000000);
560aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000);
561aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
562aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
56386899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	data = next->bios.timing_20_30_07 << 8;
564b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_01_01)
565aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x80000000;
566aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x100778, 0x00000700, data);
567aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
568b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f250, 0x000003f0, next->bios.timing_20_2c_003f << 4);
569cb54dd2f8e88d39842c338ad0041d9d528dfd6eeBen Skeggs	data = (next->bios.timing[10] & 0x7f000000) >> 24;
570cb54dd2f8e88d39842c338ad0041d9d528dfd6eeBen Skeggs	if (data < next->bios.timing_20_2c_1fc0)
571cb54dd2f8e88d39842c338ad0041d9d528dfd6eeBen Skeggs		data = next->bios.timing_20_2c_1fc0;
572cb54dd2f8e88d39842c338ad0041d9d528dfd6eeBen Skeggs	ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
573b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8 << 16);
574aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
575b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10fec4, 0x041e0f07, next->bios.timing_20_31_0800 << 26 |
576b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs					    next->bios.timing_20_31_0780 << 17 |
577b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs					    next->bios.timing_20_31_0078 << 8 |
578b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs					    next->bios.timing_20_31_0007);
579b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10fec8, 0x00000027, next->bios.timing_20_31_8000 << 5 |
580b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs					    next->bios.timing_20_31_7000);
581aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
582aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x4000007e);
583f4aa2c6677be2f0046a7431f23d4c76baba5ecc8Ben Skeggs	ram_nsec(fuc, 2000);
584aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
585aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
586aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
587aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
58886899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (next->bios.ramcfg_11_08_10 && (ram->mode == 2) /*XXX*/) {
589aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
59001891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggs		nve0_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/
591aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 1000);
592aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f294, temp);
593aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
594aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
595aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[3], 0xfff, ram->base.mr[3]);
596aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, mr[0], ram->base.mr[0]);
597aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[8], 0xfff, ram->base.mr[8]);
598aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
599aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[1], 0xfff, ram->base.mr[1]);
6002daaf5b0e4fbed1fa9524881272c9a956a0aaf78Ben Skeggs	ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5] & ~0x004); /* LP3 later */
601aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[6], 0xfff, ram->base.mr[6]);
602aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[7], 0xfff, ram->base.mr[7]);
603aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
604aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 0 && ram_have(fuc, gpio2E)) {
605aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
606aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
607aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
608aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
609aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
610aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
611aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
612aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
613aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
614aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
615aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
6167f39e597726774cb3fee71f4b605a5499f7c3a8aBen Skeggs	ram_nuts(ram, 0x10f200, 0x18808800, 0x00000000, 0x18808800);
617aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
618aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data  = ram_rd32(fuc, 0x10f978);
619aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data &= ~0x00046144;
620aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data |=  0x0000000b;
62186899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_08) {
62286899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs		if (!next->bios.ramcfg_11_07_04)
623aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x0000200c;
624aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		else
625aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x00000000;
626aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
627aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00040044;
628aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
629aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f978, data);
630aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
631aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 1) {
632aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = ram_rd32(fuc, 0x10f830) | 0x00000001;
633aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f830, data);
634aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
635aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
63686899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_08) {
637aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x88020000;
63886899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs		if ( next->bios.ramcfg_11_07_04)
639aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x10000000;
64086899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs		if (!next->bios.rammap_11_08_10)
641aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x00080000;
642aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
643aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0xa40e0000;
644aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
645334565abfea84d424d7721d9c9f9ca1227d14bd8Ben Skeggs	nve0_ram_train(fuc, 0xbc0f0000, data);
646ea8b4a380d46795610d17afcdec1067b0ff5f1c3Ben Skeggs	if (1) /* XXX: not always? */
647ea8b4a380d46795610d17afcdec1067b0ff5f1c3Ben Skeggs		ram_nsec(fuc, 1000);
648aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
649aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) { /*XXX*/
650aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000004);
651aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
652aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
653ea8b4a380d46795610d17afcdec1067b0ff5f1c3Ben Skeggs	/* LP3 */
654ea8b4a380d46795610d17afcdec1067b0ff5f1c3Ben Skeggs	if (ram_mask(fuc, mr[5], 0x004, ram->base.mr[5]) != ram->base.mr[5])
655ea8b4a380d46795610d17afcdec1067b0ff5f1c3Ben Skeggs		ram_nsec(fuc, 1000);
656aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
657aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) {
658aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
659aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
660aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
661aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
662b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_07_02)
66301891690e8e0d1230b8b3d96a42810b3ab8b38c1Ben Skeggs		nve0_ram_train(fuc, 0x80020000, 0x01000000);
664aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
665aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
666aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
667b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.rammap_11_08_01)
668aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000800;
669aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
670aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
671aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, data);
6727f39e597726774cb3fee71f4b605a5499f7c3a8aBen Skeggs	ram_nuts(ram, 0x10f200, 0x18808800, data, 0x18808800);
673aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
674aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
675aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
676aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*******************************************************************************
677aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * DDR3
678aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs ******************************************************************************/
679aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
680aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
681aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
682aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
683aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
684aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
685aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 rcoef = ((  ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
686aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk0 = ram->fN1 << 16;
687aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk1 = ram->fN1;
688b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	struct nouveau_ram_data *next = ram->base.next;
68986899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	int vc = !next->bios.ramcfg_11_02_08;
69086899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	int mv = !next->bios.ramcfg_11_02_04;
691aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 mask, data;
692aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
693aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
694aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0000);
695aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
696aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 1 && ram_have(fuc, gpio2E)) {
697aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
698aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
699aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
700aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
701aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
702aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
703aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
704aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
70586899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (next->bios.ramcfg_11_03_f0)
706aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
707aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
708aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
709aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
710aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
711aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
712aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
713aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
714aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
715aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
716aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x00000060);
717aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0xc000007e);
718aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
719aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: there does appear to be some kind of condition here, simply
720aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     modifying these bits in the vbios from the default pl0
721aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     entries shows no change.  however, the data does appear to
722aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     be correct and may be required for the transition back
723aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
724aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x00010000;
725aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00010000;
726aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
727aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (1) {
728aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x800807e0;
729aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x800807e0;
730b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		switch (next->bios.ramcfg_11_03_c0) {
731b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 3: data &= ~0x00000040; break;
732b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 2: data &= ~0x00000100; break;
733b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 1: data &= ~0x80000000; break;
734b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 0: data &= ~0x00000400; break;
735aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
736aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
737b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		switch (next->bios.ramcfg_11_03_30) {
738b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 3: data &= ~0x00000020; break;
739b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 2: data &= ~0x00000080; break;
740b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 1: data &= ~0x00080000; break;
741b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		case 0: data &= ~0x00000200; break;
742aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
743aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
744aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
745b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_02_80)
746aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x03000000;
747b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_02_40)
748aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00002000;
749b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_07_10)
750aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00004000;
751b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_07_08)
752aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00000003;
753aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
754aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x14000000;
755aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
756aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
757aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
758aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
759aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
760aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data  = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
76186899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	data |= next->bios.ramcfg_11_03_30 << 16;
762aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x1373ec, data);
763aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
764aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
765aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
766aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* (re)program refpll, if required */
767aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
768aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	    (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
769aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
770aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
771aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x137320, 0x00000000);
772aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132030, 0xffff0000, runk0);
773aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
774aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x132024, rcoef);
775aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
776aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
777aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
778aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
779aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
780aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
781aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000010);
782aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000001);
783aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
784aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
785aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_have(fuc, gpioMV)) {
786aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
787aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpioMV)) {
788aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
789aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 64000);
790aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
791aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
792aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
79386899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (next->bios.ramcfg_11_02_40 ||
79486899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	    next->bios.ramcfg_11_07_10) {
795aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
796aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 20000);
797aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
798aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
799aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) /*XXX*/ {
800b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.ramcfg_11_07_40)
801aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
802aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
803aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
804b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f65c, 0x00000011 * next->bios.rammap_11_11_0c);
805b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f6b8, 0x01010101 * next->bios.ramcfg_11_09);
806b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f6bc, 0x01010101 * next->bios.ramcfg_11_09);
807aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
808aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x00010000;
809aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
81086899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_02_80)
811aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x03000000;
81286899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_02_40)
813aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00002000;
81486899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_10)
815aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00004000;
81686899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_08)
817aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000003;
818aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
819aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x14000000;
820aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
821aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
822aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
823b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.ramcfg_11_08_01)
824aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00100000;
825aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
826aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
827aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f82c, 0x00100000, data);
828aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
829aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* PFB timing */
830b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f248, 0xffffffff, next->bios.timing[10]);
831b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f290, 0xffffffff, next->bios.timing[0]);
832b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f294, 0xffffffff, next->bios.timing[1]);
833b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f298, 0xffffffff, next->bios.timing[2]);
834b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f29c, 0xffffffff, next->bios.timing[3]);
835b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2a0, 0xffffffff, next->bios.timing[4]);
836b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2a4, 0xffffffff, next->bios.timing[5]);
837b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2a8, 0xffffffff, next->bios.timing[6]);
838b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2ac, 0xffffffff, next->bios.timing[7]);
839b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2cc, 0xffffffff, next->bios.timing[8]);
840b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f2e8, 0xffffffff, next->bios.timing[9]);
841aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
842aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x33f00000;
843aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
84486899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_01_04)
845aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x20200000;
84686899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (!next->bios.ramcfg_11_07_80)
847aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x12800000;
848aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: see note above about there probably being some condition
849aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     for the 10f824 stuff that uses ramcfg 3...
850aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
85186899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	if (next->bios.ramcfg_11_03_f0) {
852b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		if (next->bios.rammap_11_08_0c) {
85386899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs			if (!next->bios.ramcfg_11_07_80)
854aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				mask |= 0x00000020;
855aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			else
856aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				data |= 0x00000020;
857aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			mask |= 0x08000004;
858aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
859aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x04000000;
860aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
861aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x44000020;
862aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x08000004;
863aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
864aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
865aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, mask, data);
866aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
867b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_wr32(fuc, 0x10f870, 0x11111111 * next->bios.ramcfg_11_03_0f);
868aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
869b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	ram_mask(fuc, 0x10f250, 0x000003f0, next->bios.timing_20_2c_003f << 4);
870aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
871b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	data = (next->bios.timing[10] & 0x7f000000) >> 24;
872cb54dd2f8e88d39842c338ad0041d9d528dfd6eeBen Skeggs	if (data < next->bios.timing_20_2c_1fc0)
873b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs		data = next->bios.timing_20_2c_1fc0;
874aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
875aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
87686899b39b53bfcfb0c01151c52d4b1272306fc92Ben Skeggs	ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8 << 16);
877aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
878aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x4000007f);
879aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
880aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
881aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
882aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
883aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
884aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
885aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
886aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nuke(fuc, mr[0]);
887aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x100);
888aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x000);
889aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
890aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
891aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, mr[0], ram->base.mr[0]);
892aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
893aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
894aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nuke(fuc, mr[0]);
895aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x100);
896aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x000);
897aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
898aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 0 && ram_have(fuc, gpio2E)) {
899aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
900aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
901aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
902aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
903aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
904aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
905aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
906aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) {
907aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
908aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
909aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
910aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
911aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
912aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
913aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
914aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
915aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
916aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
917aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
918b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	if (next->bios.rammap_11_08_01)
919aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000800;
920aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
921aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
922aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, data);
923aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
924aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
925aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
926aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*******************************************************************************
927aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * main hooks
928aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs ******************************************************************************/
929aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
930aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
931d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggsnve0_ram_calc_data(struct nouveau_fb *pfb, u32 khz,
93246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		   struct nouveau_ram_data *data)
933aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
934aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
935d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct nouveau_ram_data *cfg;
936d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	u32 mhz = khz / 1000;
937d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
938d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	list_for_each_entry(cfg, &ram->cfg, head) {
939d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		if (mhz >= cfg->bios.rammap_min &&
940d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		    mhz <= cfg->bios.rammap_max) {
941d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			*data = *cfg;
942d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			data->freq = khz;
943d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			return 0;
944aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
945aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
946aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
947d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	nv_error(ram, "ramcfg data for %dMHz not found\n", mhz);
948d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	return -EINVAL;
94946bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs}
95046bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
95146bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggsstatic int
95246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggsnve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
95346bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs{
95446bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
95546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
95646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	int refclk, i;
95746bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	int ret;
958b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs
959aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = ram_init(fuc, pfb);
960aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret)
961aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
962aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
963d93e996aed6e48c87dc5703a21b0e9368d4cc1f9Roy Spliet	ram_fb_disable(fuc);
964d93e996aed6e48c87dc5703a21b0e9368d4cc1f9Roy Spliet
96546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	ram->mode = (next->freq > fuc->refpll.vco1.max_freq) ? 2 : 1;
966aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->from = ram_rd32(fuc, 0x1373f4) & 0x0000000f;
967aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
968aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* XXX: this is *not* what nvidia do.  on fermi nvidia generally
969aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * select, based on some unknown condition, one of the two possible
970aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * reference frequencies listed in the vbios table for mempll and
971aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * program refpll to that frequency.
972aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *
973aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * so far, i've seen very weird values being chosen by nvidia on
974aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * kepler boards, no idea how/why they're chosen.
975aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
97646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	refclk = next->freq;
977aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2)
978aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		refclk = fuc->mempll.refclk;
979aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
980aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* calculate refpll coefficients */
981aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nva3_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1,
982aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			   &ram->fN1, &ram->M1, &ram->P1);
983aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	fuc->mempll.refclk = ret;
984aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret <= 0) {
985aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "unable to calc refpll\n");
986aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
987aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
988aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
989aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* calculate mempll coefficients, if we're using it */
990aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) {
991aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		/* post-divider doesn't work... the reg takes the values but
992aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		 * appears to completely ignore it.  there *is* a bit at
993aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		 * bit 28 that appears to divide the clock by 2 if set.
994aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		 */
995aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		fuc->mempll.min_p = 1;
996aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		fuc->mempll.max_p = 2;
997aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
99846bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		ret = nva3_pll_calc(nv_subdev(pfb), &fuc->mempll, next->freq,
999aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				   &ram->N2, NULL, &ram->M2, &ram->P2);
1000aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ret <= 0) {
1001aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_error(pfb, "unable to calc mempll\n");
1002aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			return -EINVAL;
1003aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
1004aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1005aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1006aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	for (i = 0; i < ARRAY_SIZE(fuc->r_mr); i++) {
1007aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ram_have(fuc, mr[i]))
1008aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram->base.mr[i] = ram_rd32(fuc, mr[i]);
1009aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
101046bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	ram->base.freq = next->freq;
1011aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1012aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
1013aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_DDR3:
1014aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ret = nouveau_sddr3_calc(&ram->base);
1015aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ret == 0)
101646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			ret = nve0_ram_calc_sddr3(pfb, next->freq);
1017aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1018aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
1019d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		ret = nouveau_gddr5_calc(&ram->base, ram->pnuts != 0);
1020aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ret == 0)
102146bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			ret = nve0_ram_calc_gddr5(pfb, next->freq);
1022aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1023aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
1024aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ret = -ENOSYS;
1025aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1026aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1027aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1028d93e996aed6e48c87dc5703a21b0e9368d4cc1f9Roy Spliet	if (!ret)
1029d93e996aed6e48c87dc5703a21b0e9368d4cc1f9Roy Spliet		ram_fb_enable(fuc);
1030d93e996aed6e48c87dc5703a21b0e9368d4cc1f9Roy Spliet
1031aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return ret;
1032aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1033aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1034aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
103546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggsnve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
103646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs{
103746bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	struct nouveau_clock *clk = nouveau_clock(pfb);
103846bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
103946bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	struct nouveau_ram_data *xits = &ram->base.xition;
104046bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	struct nouveau_ram_data *copy;
104146bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	int ret;
104246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
104346bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	if (ram->base.next == NULL) {
104446bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		ret = nve0_ram_calc_data(pfb, clk->read(clk, nv_clk_src_mem),
104546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs					&ram->base.former);
104646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		if (ret)
104746bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			return ret;
104846bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
104946bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		ret = nve0_ram_calc_data(pfb, freq, &ram->base.target);
105046bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		if (ret)
105146bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			return ret;
105246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
105346bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		if (ram->base.target.freq < ram->base.former.freq) {
105446bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			*xits = ram->base.target;
105546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			copy = &ram->base.former;
105646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		} else {
105746bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			*xits = ram->base.former;
105846bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			copy = &ram->base.target;
105946bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		}
106046bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
106146bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		xits->bios.ramcfg_11_02_04 = copy->bios.ramcfg_11_02_04;
106246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		xits->bios.ramcfg_11_02_03 = copy->bios.ramcfg_11_02_03;
106346bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		xits->bios.timing_20_30_07 = copy->bios.timing_20_30_07;
106446bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
106546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		ram->base.next = &ram->base.target;
106646bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		if (memcmp(xits, &ram->base.former, sizeof(xits->bios)))
106746bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs			ram->base.next = &ram->base.xition;
106846bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	} else {
106946bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		BUG_ON(ram->base.next != &ram->base.xition);
107046bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs		ram->base.next = &ram->base.target;
107146bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	}
107246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
107346bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	return nve0_ram_calc_xits(pfb, ram->base.next);
107446bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs}
107546bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs
1076b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggsstatic void
1077b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggsnve0_ram_prog_0(struct nouveau_fb *pfb, u32 freq)
1078b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs{
1079b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
1080b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	struct nouveau_ram_data *cfg;
1081b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	u32 mhz = freq / 1000;
1082b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	u32 mask, data;
1083b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1084b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	list_for_each_entry(cfg, &ram->cfg, head) {
1085b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		if (mhz >= cfg->bios.rammap_min &&
1086b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		    mhz <= cfg->bios.rammap_max)
1087b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs			break;
1088b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1089b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1090b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (&cfg->head == &ram->cfg)
1091b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		return;
1092b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1093b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0a_03fe) {
1094b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0a_03fe << 12;
1095b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x001ff000;
1096b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1097b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (ram->diff.rammap_11_09_01ff) {
1098b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_09_01ff;
1099b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x000001ff;
1100b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1101b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f468, mask, data);
1102b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1103b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0a_0400) {
1104b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0a_0400;
1105b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x00000001;
1106b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1107b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f420, mask, data);
1108b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1109b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0a_0800) {
1110b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0a_0800;
1111b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x00000001;
1112b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1113b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f430, mask, data);
1114b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1115b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0b_01f0) {
1116b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0b_01f0;
1117b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x0000001f;
1118b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1119b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f400, mask, data);
1120b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1121b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0b_0200) {
1122b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0b_0200 << 9;
1123b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x00000200;
1124b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1125b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f410, mask, data);
1126b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1127b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0d) {
1128b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0d << 16;
1129b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x00ff0000;
1130b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1131b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (ram->diff.rammap_11_0f) {
1132b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0f << 8;
1133b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x0000ff00;
1134b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1135b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f440, mask, data);
1136b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1137b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (mask = 0, data = 0, ram->diff.rammap_11_0e) {
1138b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0e << 8;
1139b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x0000ff00;
1140b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1141b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (ram->diff.rammap_11_0b_0800) {
1142b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0b_0800 << 7;
1143b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x00000080;
1144b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1145b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (ram->diff.rammap_11_0b_0400) {
1146b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		data |= cfg->bios.rammap_11_0b_0400 << 5;
1147b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		mask |= 0x00000020;
1148b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1149b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nv_mask(pfb, 0x10f444, mask, data);
1150b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs}
1151b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
115246bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggsstatic int
1153aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_prog(struct nouveau_fb *pfb)
1154aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1155aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_device *device = nv_device(pfb);
1156aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
1157aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
1158b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	struct nouveau_ram_data *next = ram->base.next;
1159b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1160b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	if (!nouveau_boolopt(device->cfgopt, "NvMemExec", true)) {
1161b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		ram_exec(fuc, false);
1162b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs		return (ram->base.next == &ram->base.xition);
1163b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	}
1164b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
1165b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nve0_ram_prog_0(pfb, 1000);
1166b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	ram_exec(fuc, true);
1167b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	nve0_ram_prog_0(pfb, next->freq);
1168b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs
116946bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	return (ram->base.next == &ram->base.xition);
1170aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1171aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1172aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
1173aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_tidy(struct nouveau_fb *pfb)
1174aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1175aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
1176aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
117746bf1c389f7fb4f3d1bba1543088d66523670cacBen Skeggs	ram->base.next = NULL;
1178aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_exec(fuc, false);
1179aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1180aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
11816b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsstruct nve0_ram_train {
11826b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	u16 mask;
11836b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S remap;
11846b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type00;
11856b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type01;
11866b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type04;
11876b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type06;
11886b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type07;
11896b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type08;
11906b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S type09;
11916b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs};
11926b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
11936b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsstatic int
11946b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsnve0_ram_train_type(struct nouveau_fb *pfb, int i, u8 ramcfg,
11956b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		    struct nve0_ram_train *train)
11966b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs{
11976b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
11986b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0205E M0205E;
11996b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0205S M0205S;
12006b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209E M0209E;
12016b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S *remap = &train->remap;
12026b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nvbios_M0209S *value;
12036b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	u8  ver, hdr, cnt, len;
12046b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	u32 data;
12056b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12066b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	/* determine type of data for this index */
12076b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if (!(data = nvbios_M0205Ep(bios, i, &ver, &hdr, &cnt, &len, &M0205E)))
12086b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return -ENOENT;
12096b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12106b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	switch (M0205E.type) {
12116b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x00: value = &train->type00; break;
12126b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x01: value = &train->type01; break;
12136b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x04: value = &train->type04; break;
12146b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x06: value = &train->type06; break;
12156b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x07: value = &train->type07; break;
12166b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x08: value = &train->type08; break;
12176b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case 0x09: value = &train->type09; break;
12186b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	default:
12196b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return 0;
12206b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	}
12216b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12226b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	/* training data index determined by ramcfg strap */
12236b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if (!(data = nvbios_M0205Sp(bios, i, ramcfg, &ver, &hdr, &M0205S)))
12246b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return -EINVAL;
12256b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	i = M0205S.data;
12266b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12276b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	/* training data format information */
12286b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if (!(data = nvbios_M0209Ep(bios, i, &ver, &hdr, &cnt, &len, &M0209E)))
12296b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return -EINVAL;
12306b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12316b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	/* ... and the raw data */
12326b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if (!(data = nvbios_M0209Sp(bios, i, 0, &ver, &hdr, value)))
12336b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return -EINVAL;
12346b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12356b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if (M0209E.v02_07 == 2) {
12366b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		/* of course! why wouldn't we have a pointer to another entry
12376b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		 * in the same table, and use the first one as an array of
12386b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		 * remap indices...
12396b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		 */
12406b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		if (!(data = nvbios_M0209Sp(bios, M0209E.v03, 0, &ver, &hdr,
12416b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs					    remap)))
12426b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			return -EINVAL;
12436b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12446b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		for (i = 0; i < ARRAY_SIZE(value->data); i++)
12456b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			value->data[i] = remap->data[value->data[i]];
12466b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	} else
12476b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if (M0209E.v02_07 != 1)
12486b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return -EINVAL;
12496b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12506b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	train->mask |= 1 << M0205E.type;
12516b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	return 0;
12526b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs}
12536b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12546b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsstatic int
12556b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsnve0_ram_train_init_0(struct nouveau_fb *pfb, struct nve0_ram_train *train)
12566b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs{
12576b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	int i, j;
12586b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12596b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if ((train->mask & 0x03d3) != 0x03d3) {
12606b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		nv_warn(pfb, "missing link training data\n");
12616b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		return -EINVAL;
12626b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	}
12636b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12646b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	for (i = 0; i < 0x30; i++) {
12656b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		for (j = 0; j < 8; j += 4) {
12666b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f968 + j, 0x00000000 | (i << 8));
12676b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f920 + j, 0x00000000 |
12686b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs						   train->type08.data[i] << 4 |
12696b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs						   train->type06.data[i]);
12706b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f918 + j, train->type00.data[i]);
12716b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f920 + j, 0x00000100 |
12726b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs						   train->type09.data[i] << 4 |
12736b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs						   train->type07.data[i]);
12746b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f918 + j, train->type01.data[i]);
12756b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		}
12766b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	}
12776b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12786b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	for (j = 0; j < 8; j += 4) {
12796b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		for (i = 0; i < 0x100; i++) {
12806b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f968 + j, i);
12816b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			nv_wr32(pfb, 0x10f900 + j, train->type04.data[i]);
12826b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		}
12836b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	}
12846b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12856b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	return 0;
12866b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs}
12876b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12886b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsstatic int
12896b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggsnve0_ram_train_init(struct nouveau_fb *pfb)
12906b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs{
12916b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	u8 ramcfg = nvbios_ramcfg_index(nv_subdev(pfb));
12926b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	struct nve0_ram_train *train;
12936b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	int ret = -ENOMEM, i;
12946b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
12956b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	if ((train = kzalloc(sizeof(*train), GFP_KERNEL))) {
12966b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		for (i = 0; i < 0x100; i++) {
12976b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			ret = nve0_ram_train_type(pfb, i, ramcfg, train);
12986b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs			if (ret && ret != -ENOENT)
12996b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs				break;
13006b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		}
13016b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	}
13026b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
13036b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	switch (pfb->ram->type) {
13046b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	case NV_MEM_TYPE_GDDR5:
13056b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		ret = nve0_ram_train_init_0(pfb, train);
13066b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		break;
13076b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	default:
13086b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		ret = 0;
13096b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs		break;
13106b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	}
13116b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
13126b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	kfree(train);
13136b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	return ret;
13146b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs}
13156b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs
1316267dcb66437df958a6c2a30b3582ef76ba3bbb88Ben Skeggsint
1317aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_init(struct nouveau_object *object)
1318aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1319aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_fb *pfb = (void *)object->parent;
1320aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram   = (void *)object;
1321aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
1322aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u8  ver, hdr, cnt, len, snr, ssz;
1323aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 data, save;
1324aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int ret, i;
1325aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1326aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nouveau_ram_init(&ram->base);
1327aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret)
1328aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1329aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1330aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* run a bunch of tables from rammap table.  there's actually
1331aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * individual pointers for each rammap entry too, but, nvidia
1332aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * seem to just run the last two entries' scripts early on in
1333aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * their init, and never again.. we'll just run 'em all once
1334aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * for now.
1335aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *
1336aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * i strongly suspect that each script is for a separate mode
1337aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * (likely selected by 0x10f65c's lower bits?), and the
1338aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * binary driver skips the one that's already been setup by
1339aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * the init tables.
1340aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
1341b655f2bb77b49a3dc69d13b3daa392ea641bec86Ben Skeggs	data = nvbios_rammapTe(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
1342aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!data || hdr < 0x15)
1343aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
1344aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1345aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	cnt  = nv_ro08(bios, data + 0x14); /* guess at count */
1346aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro32(bios, data + 0x10); /* guess u32... */
13474cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs	save = nv_rd32(pfb, 0x10f65c) & 0x000000f0;
13484cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs	for (i = 0; i < cnt; i++, data += 4) {
13494cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs		if (i != save >> 4) {
13504cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs			nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4);
13514cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs			nvbios_exec(&(struct nvbios_init) {
13524cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs					.subdev = nv_subdev(pfb),
13534cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs					.bios = bios,
13544cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs					.offset = nv_ro32(bios, data),
13554cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs					.execute = 1,
13564cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs				    });
13574cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs		}
1358aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
13594cc6c3fe391b9a5869e3ca08f3619963064f079cBen Skeggs	nv_mask(pfb, 0x10f65c, 0x000000f0, save);
136073216231caf184439c5f6163d01145bdbdfcd00bBen Skeggs	nv_mask(pfb, 0x10f584, 0x11000000, 0x00000000);
1361a6a4df96104f8db36e2365aabbfeb94653227cacBen Skeggs	nv_wr32(pfb, 0x10ecc0, 0xffffffff);
1362a6a4df96104f8db36e2365aabbfeb94653227cacBen Skeggs	nv_mask(pfb, 0x10f160, 0x00000010, 0x00000010);
1363aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
13646b07c6cfd1530e39a6e5e81e63b59953b3f35eeaBen Skeggs	return nve0_ram_train_init(pfb);
1365aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1366aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1367aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
1368d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggsnve0_ram_ctor_data(struct nve0_ram *ram, u8 ramcfg, int i)
1369d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs{
1370d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct nouveau_fb *pfb = (void *)nv_object(ram)->parent;
1371d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
1372d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct nouveau_ram_data *cfg;
137391e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	struct nvbios_ramcfg *d = &ram->diff;
137491e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	struct nvbios_ramcfg *p, *n;
1375d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	u8  ver, hdr, cnt, len;
1376d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	u32 data;
1377d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	int ret;
1378d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1379d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (!(cfg = kmalloc(sizeof(*cfg), GFP_KERNEL)))
1380d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		return -ENOMEM;
138191e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	p = &list_last_entry(&ram->cfg, typeof(*cfg), head)->bios;
138291e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	n = &cfg->bios;
1383d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1384d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	/* memory config data for a range of target frequencies */
1385d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	data = nvbios_rammapEp(bios, i, &ver, &hdr, &cnt, &len, &cfg->bios);
1386d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (ret = -ENOENT, !data)
1387d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		goto done;
1388d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (ret = -ENOSYS, ver != 0x11 || hdr < 0x12)
1389d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		goto done;
1390d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1391d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	/* ... and a portion specific to the attached memory */
1392d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, ramcfg,
1393d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			       &ver, &hdr, &cfg->bios);
1394d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (ret = -EINVAL, !data)
1395d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		goto done;
1396d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (ret = -ENOSYS, ver != 0x11 || hdr < 0x0a)
1397d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		goto done;
1398d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1399d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	/* lookup memory timings, if bios says they're present */
1400d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (cfg->bios.ramcfg_timing != 0xff) {
1401d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		data = nvbios_timingEp(bios, cfg->bios.ramcfg_timing,
1402d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs				       &ver, &hdr, &cnt, &len,
1403d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs				       &cfg->bios);
1404d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		if (ret = -EINVAL, !data)
1405d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			goto done;
1406d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		if (ret = -ENOSYS, ver != 0x20 || hdr < 0x33)
1407d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			goto done;
1408d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	}
1409d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1410d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	list_add_tail(&cfg->head, &ram->cfg);
141191e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	if (ret = 0, i == 0)
141291e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs		goto done;
141391e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs
1414b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0a_03fe |= p->rammap_11_0a_03fe != n->rammap_11_0a_03fe;
1415b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_09_01ff |= p->rammap_11_09_01ff != n->rammap_11_09_01ff;
1416b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0a_0400 |= p->rammap_11_0a_0400 != n->rammap_11_0a_0400;
1417b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0a_0800 |= p->rammap_11_0a_0800 != n->rammap_11_0a_0800;
1418b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0b_01f0 |= p->rammap_11_0b_01f0 != n->rammap_11_0b_01f0;
1419b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0b_0200 |= p->rammap_11_0b_0200 != n->rammap_11_0b_0200;
1420b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0d |= p->rammap_11_0d != n->rammap_11_0d;
1421b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0f |= p->rammap_11_0f != n->rammap_11_0f;
1422b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0e |= p->rammap_11_0e != n->rammap_11_0e;
1423b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0b_0800 |= p->rammap_11_0b_0800 != n->rammap_11_0b_0800;
1424b6f97a089b6d0e7463a5062fb29a002fc9b1d025Ben Skeggs	d->rammap_11_0b_0400 |= p->rammap_11_0b_0400 != n->rammap_11_0b_0400;
142591e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	d->ramcfg_11_01_01 |= p->ramcfg_11_01_01 != n->ramcfg_11_01_01;
142691e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	d->ramcfg_11_01_02 |= p->ramcfg_11_01_02 != n->ramcfg_11_01_02;
142791e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	d->ramcfg_11_01_10 |= p->ramcfg_11_01_10 != n->ramcfg_11_01_10;
142891e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	d->ramcfg_11_02_03 |= p->ramcfg_11_02_03 != n->ramcfg_11_02_03;
142991e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	d->ramcfg_11_08_20 |= p->ramcfg_11_08_20 != n->ramcfg_11_08_20;
143091e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	d->timing_20_30_07 |= p->timing_20_30_07 != n->timing_20_30_07;
1431d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggsdone:
1432d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	if (ret)
1433d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		kfree(cfg);
1434d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	return ret;
1435d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs}
1436d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1437d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggsstatic void
1438d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggsnve0_ram_dtor(struct nouveau_object *object)
1439d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs{
1440d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct nve0_ram *ram = (void *)object;
1441d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	struct nouveau_ram_data *cfg, *tmp;
1442d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1443d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	list_for_each_entry_safe(cfg, tmp, &ram->cfg, head) {
1444d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		kfree(cfg);
1445d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	}
1446d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1447d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	nouveau_ram_destroy(&ram->base);
1448d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs}
1449d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1450d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggsstatic int
1451aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1452aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	      struct nouveau_oclass *oclass, void *data, u32 size,
1453aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	      struct nouveau_object **pobject)
1454aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1455aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_fb *pfb = nouveau_fb(parent);
1456aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
1457aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_gpio *gpio = nouveau_gpio(pfb);
1458aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct dcb_gpio_func func;
1459aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram;
1460d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	int ret, i;
1461d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	u8  ramcfg = nvbios_ramcfg_index(nv_subdev(pfb));
1462d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	u32 tmp;
1463aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1464267dcb66437df958a6c2a30b3582ef76ba3bbb88Ben Skeggs	ret = nvc0_ram_create(parent, engine, oclass, 0x022554, &ram);
1465aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	*pobject = nv_object(ram);
1466aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret)
1467aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1468aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1469d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	INIT_LIST_HEAD(&ram->cfg);
1470d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1471aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
1472aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_DDR3:
1473aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
1474aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.calc = nve0_ram_calc;
1475aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.prog = nve0_ram_prog;
1476aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.tidy = nve0_ram_tidy;
1477aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1478aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
1479aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_warn(pfb, "reclocking of this RAM type is unsupported\n");
1480aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1481aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1482aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1483d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	/* calculate a mask of differently configured memory partitions,
1484d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	 * because, of course reclocking wasn't complicated enough
1485d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	 * already without having to treat some of them differently to
1486d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	 * the others....
1487d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	 */
1488d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	ram->parts = nv_rd32(pfb, 0x022438);
1489d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	ram->pmask = nv_rd32(pfb, 0x022554);
1490d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	ram->pnuts = 0;
1491d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	for (i = 0, tmp = 0; i < ram->parts; i++) {
1492d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		if (!(ram->pmask & (1 << i))) {
1493d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			u32 cfg1 = nv_rd32(pfb, 0x110204 + (i * 0x1000));
1494d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			if (tmp && tmp != cfg1) {
1495d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs				ram->pnuts |= (1 << i);
1496d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs				continue;
1497d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			}
1498d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs			tmp = cfg1;
1499d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs		}
1500d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs	}
1501d394fb12eca4cb9f42f922d7ae2bc8d7e1ed9272Ben Skeggs
150291e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	/* parse bios data for all rammap table entries up-front, and
150391e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * build information on whether certain fields differ between
150491e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * any of the entries.
150591e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 *
150691e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * the binary driver appears to completely ignore some fields
150791e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * when all entries contain the same value.  at first, it was
150891e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * hoped that these were mere optimisations and the bios init
150991e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * tables had configured as per the values here, but there is
151091e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * evidence now to suggest that this isn't the case and we do
151191e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 * need to treat this condition as a "don't touch" indicator.
151291e4611ddc97c13ee66edfcd94974e6450d03726Ben Skeggs	 */
1513d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	for (i = 0; !ret; i++) {
1514d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		ret = nve0_ram_ctor_data(ram, ramcfg, i);
1515d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		if (ret && ret != -ENOENT) {
1516d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			nv_error(pfb, "failed to parse ramcfg data\n");
1517d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs			return ret;
1518d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		}
1519d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	}
1520d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs
1521d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	/* parse bios data for both pll's */
1522aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nvbios_pll_parse(bios, 0x0c, &ram->fuc.refpll);
1523aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret) {
1524aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "mclk refpll data not found\n");
1525aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1526aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1527aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1528aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nvbios_pll_parse(bios, 0x04, &ram->fuc.mempll);
1529aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret) {
1530aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "mclk pll data not found\n");
1531aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1532aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1533aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1534d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs	/* lookup memory voltage gpios */
1535aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = gpio->find(gpio, 0, 0x18, DCB_GPIO_UNUSED, &func);
1536aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret == 0) {
1537aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_gpioMV = ramfuc_reg(0x00d610 + (func.line * 0x04));
1538aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_funcMV[0] = (func.log[0] ^ 2) << 12;
1539aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_funcMV[1] = (func.log[1] ^ 2) << 12;
1540aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1541aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1542aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
1543aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret == 0) {
1544aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_gpio2E = ramfuc_reg(0x00d610 + (func.line * 0x04));
1545aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_func2E[0] = (func.log[0] ^ 2) << 12;
1546aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_func2E[1] = (func.log[1] ^ 2) << 12;
1547aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1548aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1549aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_gpiotrig = ramfuc_reg(0x00d604);
1550aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1551aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132020 = ramfuc_reg(0x132020);
1552aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132028 = ramfuc_reg(0x132028);
1553aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132024 = ramfuc_reg(0x132024);
1554aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132030 = ramfuc_reg(0x132030);
1555aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132034 = ramfuc_reg(0x132034);
1556aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
1557aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
1558aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132040 = ramfuc_reg(0x132040);
1559aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1560aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f248 = ramfuc_reg(0x10f248);
1561aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
1562aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
1563aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
1564aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
1565aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
1566aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2a4 = ramfuc_reg(0x10f2a4);
1567aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2a8 = ramfuc_reg(0x10f2a8);
1568aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2ac = ramfuc_reg(0x10f2ac);
1569aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2cc = ramfuc_reg(0x10f2cc);
1570aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2e8 = ramfuc_reg(0x10f2e8);
1571aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f250 = ramfuc_reg(0x10f250);
1572aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f24c = ramfuc_reg(0x10f24c);
1573aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10fec4 = ramfuc_reg(0x10fec4);
1574aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10fec8 = ramfuc_reg(0x10fec8);
1575aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f604 = ramfuc_reg(0x10f604);
1576aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
1577aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
1578aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x100770 = ramfuc_reg(0x100770);
1579aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x100778 = ramfuc_reg(0x100778);
1580aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f224 = ramfuc_reg(0x10f224);
1581aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1582aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f870 = ramfuc_reg(0x10f870);
1583aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f698 = ramfuc_reg(0x10f698);
1584aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f694 = ramfuc_reg(0x10f694);
1585aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f6b8 = ramfuc_reg(0x10f6b8);
1586aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
1587aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f670 = ramfuc_reg(0x10f670);
1588aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f60c = ramfuc_reg(0x10f60c);
1589aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
1590aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
1591aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
1592aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f82c = ramfuc_reg(0x10f82c);
1593aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1594aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f978 = ramfuc_reg(0x10f978);
1595aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
1596aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
1597aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1598aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
1599aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
1600aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1601aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[1] = ramfuc_reg(0x10f330);
1602aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[2] = ramfuc_reg(0x10f334);
1603aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[3] = ramfuc_reg(0x10f338);
1604aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[4] = ramfuc_reg(0x10f33c);
1605aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[5] = ramfuc_reg(0x10f340);
1606aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[6] = ramfuc_reg(0x10f344);
1607aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[7] = ramfuc_reg(0x10f348);
1608aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[8] = ramfuc_reg(0x10f354);
1609aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[15] = ramfuc_reg(0x10f34c);
1610aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1611aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_DDR3:
1612aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1613aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
1614aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1615aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
1616aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1617aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1618aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1619aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x62c000 = ramfuc_reg(0x62c000);
1620aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
1621aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
1622aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
1623aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
1624aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f318 = ramfuc_reg(0x10f318);
1625aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
1626aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f69c = ramfuc_reg(0x10f69c);
1627aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
1628aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
1629aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x1373f4 = ramfuc_reg(0x1373f4);
1630aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
1631aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f65c = ramfuc_reg(0x10f65c);
1632aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f6bc = ramfuc_reg(0x10f6bc);
1633aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x100710 = ramfuc_reg(0x100710);
1634dd95c8f782a053db361855298778a7d31de04a48Ben Skeggs	ram->fuc.r_0x100750 = ramfuc_reg(0x100750);
1635aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
1636aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1637aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1638aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstruct nouveau_oclass
1639aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_oclass = {
1640aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	.handle = 0,
1641aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	.ofuncs = &(struct nouveau_ofuncs) {
1642aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.ctor = nve0_ram_ctor,
1643d26e74895f500a67091d6e93814f4889b94ce7ffBen Skeggs		.dtor = nve0_ram_dtor,
1644aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.init = nve0_ram_init,
1645aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.fini = _nouveau_ram_fini,
1646aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1647aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs};
1648