ramnve0.c revision 2daaf5b0e4fbed1fa9524881272c9a956a0aaf78
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/bit.h>
29aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/pll.h>
30aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/init.h>
31aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/rammap.h>
32aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/bios/timing.h>
33aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
34aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/clock.h>
35aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/clock/pll.h>
36aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
37aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <subdev/timer.h>
38aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
39aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include <core/option.h>
40aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
41aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include "nvc0.h"
42aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
43aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs#include "ramfuc.h"
44aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
45aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstruct nve0_ramfuc {
46aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc base;
47aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
48aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nvbios_pll refpll;
49aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nvbios_pll mempll;
50aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
51aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_gpioMV;
52aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 r_funcMV[2];
53aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_gpio2E;
54aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 r_func2E[2];
55aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_gpiotrig;
56aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
57aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132020;
58aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132028;
59aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132024;
60aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132030;
61aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132034;
62aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132000;
63aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132004;
64aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x132040;
65aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
66aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f248;
67aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f290;
68aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f294;
69aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f298;
70aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f29c;
71aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2a0;
72aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2a4;
73aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2a8;
74aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2ac;
75aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2cc;
76aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f2e8;
77aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f250;
78aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f24c;
79aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10fec4;
80aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10fec8;
81aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f604;
82aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f614;
83aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f610;
84aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x100770;
85aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x100778;
86aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f224;
87aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
88aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f870;
89aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f698;
90aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f694;
91aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f6b8;
92aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f808;
93aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f670;
94aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f60c;
95aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f830;
96aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x1373ec;
97aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f800;
98aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f82c;
99aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
100aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f978;
101aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f910;
102aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f914;
103aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
104aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_mr[16]; /* MR0 - MR8, MR15 */
105aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
106aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x62c000;
107aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f200;
108aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f210;
109aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f310;
110aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f314;
111aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f318;
112aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f090;
113aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f69c;
114aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f824;
115aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x1373f0;
116aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x1373f4;
117aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x137320;
118aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f65c;
119aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f6bc;
120aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x100710;
121aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct ramfuc_reg r_0x10f750;
122aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs};
123aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
124aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstruct nve0_ram {
125aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_ram base;
126aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc fuc;
127aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int from;
128aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int mode;
129aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int N1, fN1, M1, P1;
130aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int N2, M2, P2;
131aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs};
132aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
133aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*******************************************************************************
134aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * GDDR5
135aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs ******************************************************************************/
136aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
137aae95ca708140307813e49af6d0d4a7205509129Ben Skeggstrain(struct nve0_ramfuc *fuc, u32 magic)
138aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
139aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
140aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_fb *pfb = nouveau_fb(ram);
141aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const int mc = nv_rd32(pfb, 0x02243c);
142aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int i;
143aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
144aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f910, 0xbc0e0000, magic);
145aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f914, 0xbc0e0000, magic);
146aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	for (i = 0; i < mc; i++) {
147aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		const u32 addr = 0x110974 + (i * 0x1000);
148aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
149aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
150aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
151aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
152aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
153aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsr1373f4_init(struct nve0_ramfuc *fuc)
154aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
155aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
156aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 mcoef = ((--ram->P2 << 28) | (ram->N2 << 8) | ram->M2);
157aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 rcoef = ((  ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
158aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk0 = ram->fN1 << 16;
159aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk1 = ram->fN1;
160aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
161aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from == 2) {
162aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
163aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
164aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
165aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
166aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
167aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
168aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
169aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
170aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
171aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* (re)program refpll, if required */
172aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
173aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	    (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
174aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
175aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
176aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x137320, 0x00000000);
177aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132030, 0xffff0000, runk0);
178aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
179aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x132024, rcoef);
180aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
181aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
182aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
183aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
184aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
185aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
186aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* (re)program mempll, if required */
187aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) {
188aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
189aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
190aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
191aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
192aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
193aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
194aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
195aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010100);
196aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
197aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
198aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
199aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
200aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
201aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
202aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsr1373f4_fini(struct nve0_ramfuc *fuc, u32 ramcfg)
203aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
204aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
205aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(ram);
206aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u8 v0 = (nv_ro08(bios, ramcfg + 0x03) & 0xc0) >> 6;
207aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u8 v1 = (nv_ro08(bios, ramcfg + 0x03) & 0x30) >> 4;
208aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 tmp;
209aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
210aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
211aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x1373ec, tmp | (v1 << 16));
212aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f0, (~ram->mode & 3), 0x00000000);
213aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) {
214aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000002);
215aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00001100, 0x000000000);
216aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
217aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000001);
218aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f4, 0x00010000, 0x000000000);
219aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
220aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f800, 0x00000030, (v0 ^ v1) << 4);
221aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
222aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
223aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
224aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
225aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
226aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
227aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
228aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
229aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 rammap = ram->base.rammap.data;
230aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 ramcfg = ram->base.ramcfg.data;
231aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 timing = ram->base.timing.data;
232aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
233aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int mv = 1; /*XXX*/
234aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 mask, data;
235aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
236aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
237aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0000);
238aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
239aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* MR1: turn termination on early, for some reason.. */
240aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((ram->base.mr[1] & 0x03c) != 0x030)
241aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, mr[1], 0x03c, ram->base.mr[1] & 0x03c);
242aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
243aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 1 && ram_have(fuc, gpio2E)) {
244aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
245aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
246aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
247aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
248aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
249aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
250aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
251aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
252aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
253aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f914, 0x01020000, 0x000c0000);
254aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f910, 0x01020000, 0x000c0000);
255aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
256aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
257aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
258aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
259aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
260aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
261aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
262aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
263aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
264aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x00000061);
265aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0xc000007f);
266aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
267aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
268aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f698, 0x00000000);
269aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f69c, 0x00000000);
270aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
271aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: there does appear to be some kind of condition here, simply
272aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     modifying these bits in the vbios from the default pl0
273aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     entries shows no change.  however, the data does appear to
274aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     be correct and may be required for the transition back
275aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
276aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x800f07e0;
277aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00030000;
278aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_rd32(fuc, 0x10f978) & 0x00800000)
279aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00040000;
280aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
281aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (1) {
282aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x800807e0;
283aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) {
284aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0xc0: data &= ~0x00000040; break;
285aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x80: data &= ~0x00000100; break;
286aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x40: data &= ~0x80000000; break;
287aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x00: data &= ~0x00000400; break;
288aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
289aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
290aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) {
291aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x30: data &= ~0x00000020; break;
292aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x20: data &= ~0x00000080; break;
293aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x10: data &= ~0x00080000; break;
294aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x00: data &= ~0x00000200; break;
295aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
296aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
297aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
298aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x02) & 0x80)
299aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x03000000;
300aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x02) & 0x40)
301aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00002000;
302aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x07) & 0x10)
303aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00004000;
304aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x07) & 0x08)
305aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00000003;
306aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else {
307aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x34000000;
308aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ram_rd32(fuc, 0x10f978) & 0x00800000)
309aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			mask |= 0x40000000;
310aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
311aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
312aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
313aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
314aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
315aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from == 2 && ram->mode != 2) {
316aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
317aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000);
318aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000000, 0x00000004);
319aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x00008000, 0x01040010);
320aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
321aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
322aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001);
323aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_fini(fuc, ramcfg);
324aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001);
325aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else
326aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from != 2 && ram->mode != 2) {
327aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
328aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_fini(fuc, ramcfg);
329aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
330aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
331aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_have(fuc, gpioMV)) {
332aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
333aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpioMV)) {
334aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
335aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 64000);
336aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
337aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
338aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
339aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) ||
340aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	     (nv_ro08(bios, ramcfg + 0x07) & 0x10)) {
341aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
342aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 20000);
343aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
344aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
345aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from != 2 && ram->mode == 2) {
346aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
347aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002);
348aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010);
349aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
350aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_fini(fuc, ramcfg);
351aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000);
352aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000);
353aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else
354aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->from == 2 && ram->mode == 2) {
355aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
356aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_init(fuc);
357aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		r1373f4_fini(fuc, ramcfg);
358aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
359aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
360aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) /*XXX*/ {
361aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (nv_ro08(bios, ramcfg + 0x07) & 0x40)
362aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
363aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
364aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
365aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2;
366aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f65c, 0x00000011 * data);
367aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
368aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
369aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
370aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro08(bios, ramcfg + 0x04);
371aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
372aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f698, 0x01010101 * data);
373aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f69c, 0x01010101 * data);
374aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
375aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
376aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) {
377aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp = ram_rd32(fuc, 0x10f694) & ~0xff00ff00;
378aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f694, temp | (0x01000100 * data));
379aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
380aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
381aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2 && (nv_ro08(bios, ramcfg + 0x08) & 0x10))
382aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000080;
383aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
384aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
385aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f60c, 0x00000080, data);
386aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
387aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x00070000;
388aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
389aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80))
390aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x03000000;
391aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40))
392aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00002000;
393aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10))
394aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00004000;
395aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08))
396aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000003;
397aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
398aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x74000000;
399aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
400aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
401aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x01) & 0x08)
402aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
403aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
404aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00001000;
405aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00001000, data);
406aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
407aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_rd32(fuc, 0x10f670) & 0x80000000) {
408aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 10000);
409aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000);
410aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
411aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
412aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x08) & 0x01)
413aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00100000;
414aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
415aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
416aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f82c, 0x00100000, data);
417aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
418aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
419aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x08) & 0x08)
420aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00002000;
421aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x08) & 0x04)
422aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00001000;
423aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x08) & 0x02)
424aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00004000;
425aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f830, 0x00007000, data);
426aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
427aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* PFB timing */
428aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28));
429aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00));
430aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04));
431aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08));
432aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c));
433aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10));
434aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14));
435aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18));
436aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c));
437aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20));
438aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24));
439aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
440aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = (nv_ro08(bios, ramcfg + 0x02) & 0x03) << 8;
441aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x01) & 0x10)
442aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x70000000;
443aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f604, 0x70000300, data);
444aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
445aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28;
446aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x01) & 0x01)
447aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000100;
448aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f614, 0x70000000, data);
449aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
450aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28;
451aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x01) & 0x02)
452aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000100;
453aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f610, 0x70000000, data);
454aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
455aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x33f00000;
456aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
457aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04))
458aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x20200000;
459aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
460aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x12800000;
461aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: see note above about there probably being some condition
462aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     for the 10f824 stuff that uses ramcfg 3...
463aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
464aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) {
465aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (nv_ro08(bios, rammap + 0x08) & 0x0c) {
466aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
467aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				mask |= 0x00000020;
468aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			else
469aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				data |= 0x00000020;
470aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			mask |= 0x00000004;
471aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
472aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
473aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x40000020;
474aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000004;
475aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
476aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
477aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, mask, data);
478aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
479aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro08(bios, ramcfg + 0x03) & 0x0f;
480aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f870, 0x11111111 * data);
481aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
482aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro08(bios, ramcfg + 0x02) & 0x03;
483aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x01) & 0x10)
484aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000004;
485aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((nv_rd32(bios, 0x100770) & 0x00000004) != (data & 0x00000004)) {
486aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f750, 0x04000009);
487aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x100710, 0x00000000);
488aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000);
489aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
490aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x100770, 0x00000007, data);
491aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
492aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = (nv_ro08(bios, timing + 0x30) & 0x07) << 8;
493aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x01) & 0x01)
494aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x80000000;
495aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x100778, 0x00000700, data);
496aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
497aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro16(bios, timing + 0x2c);
498aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) <<  4);
499aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f24c, 0x7f000000, (data & 0x1fc0) << 18);
500aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
501aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro08(bios, timing + 0x30);
502aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
503aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
504aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro16(bios, timing + 0x31);
505aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10fec4, 0x041e0f07, (data & 0x0800) << 15 |
506aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs					    (data & 0x0780) << 10 |
507aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs					    (data & 0x0078) <<  5 |
508aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs					    (data & 0x0007));
509aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10fec8, 0x00000027, (data & 0x8000) >> 10 |
510aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs					    (data & 0x7000) >> 12);
511aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
512aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x4000007e);
513aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
514aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
515aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
516aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 2000);
517aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
518aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
519aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((nv_ro08(bios, ramcfg + 0x08) & 0x10) && (ram->mode == 2) /*XXX*/) {
520aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
521aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		train(fuc, 0xa4010000); /*XXX*/
522aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 1000);
523aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f294, temp);
524aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
525aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
526aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[3], 0xfff, ram->base.mr[3]);
527aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, mr[0], ram->base.mr[0]);
528aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[8], 0xfff, ram->base.mr[8]);
529aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
530aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[1], 0xfff, ram->base.mr[1]);
5312daaf5b0e4fbed1fa9524881272c9a956a0aaf78Ben Skeggs	ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5] & ~0x004); /* LP3 later */
532aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[6], 0xfff, ram->base.mr[6]);
533aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[7], 0xfff, ram->base.mr[7]);
534aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
535aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 0 && ram_have(fuc, gpio2E)) {
536aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
537aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
538aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
539aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
540aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
541aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
542aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
543aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
544aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
545aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
546aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
547aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
548aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data  = ram_rd32(fuc, 0x10f978);
549aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data &= ~0x00046144;
550aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data |=  0x0000000b;
551aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
552aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (!(nv_ro08(bios, ramcfg + 0x07) & 0x04))
553aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x0000200c;
554aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		else
555aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x00000000;
556aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
557aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00040044;
558aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
559aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f978, data);
560aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
561aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 1) {
562aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = ram_rd32(fuc, 0x10f830) | 0x00000001;
563aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x10f830, data);
564aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
565aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
566aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
567aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x88020000;
568aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if ( (nv_ro08(bios, ramcfg + 0x07) & 0x04))
569aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x10000000;
570aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (!(nv_ro08(bios, rammap + 0x08) & 0x10))
571aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			data |= 0x00080000;
572aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
573aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0xa40e0000;
574aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
575aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	train(fuc, data);
576aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
577aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
578aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) { /*XXX*/
579aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f800, 0x00000004, 0x00000004);
580aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
581aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
582aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* MR5: (re)enable LP3 if necessary
583aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * XXX: need to find the switch, keeping off for now
584aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
5852daaf5b0e4fbed1fa9524881272c9a956a0aaf78Ben Skeggs	ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5]);
586aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
587aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) {
588aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
589aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
590aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
591aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
592aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x07) & 0x02) {
593aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f910, 0x80020000, 0x01000000);
594aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f914, 0x80020000, 0x01000000);
595aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
596aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
597aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
598aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
599aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, rammap + 0x08) & 0x01)
600aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000800;
601aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
602aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
603aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, data);
604aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
605aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
606aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
607aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*******************************************************************************
608aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * DDR3
609aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs ******************************************************************************/
610aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
611aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
612aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
613aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
614aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
615aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
616aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
617aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 rcoef = ((  ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
618aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk0 = ram->fN1 << 16;
619aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 runk1 = ram->fN1;
620aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 rammap = ram->base.rammap.data;
621aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 ramcfg = ram->base.ramcfg.data;
622aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	const u32 timing = ram->base.timing.data;
623aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
624aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int mv = 1; /*XXX*/
625aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 mask, data;
626aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
627aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
628aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0000);
629aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
630aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 1 && ram_have(fuc, gpio2E)) {
631aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
632aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
633aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
634aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
635aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
636aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
637aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
638aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
639aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((nv_ro08(bios, ramcfg + 0x03) & 0xf0))
640aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
641aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
642aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
643aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
644aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
645aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
646aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
647aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
648aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
649aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
650aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x00000060);
651aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0xc000007e);
652aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
653aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: there does appear to be some kind of condition here, simply
654aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     modifying these bits in the vbios from the default pl0
655aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     entries shows no change.  however, the data does appear to
656aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     be correct and may be required for the transition back
657aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
658aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x00010000;
659aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00010000;
660aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
661aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (1) {
662aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x800807e0;
663aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x800807e0;
664aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) {
665aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0xc0: data &= ~0x00000040; break;
666aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x80: data &= ~0x00000100; break;
667aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x40: data &= ~0x80000000; break;
668aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x00: data &= ~0x00000400; break;
669aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
670aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
671aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) {
672aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x30: data &= ~0x00000020; break;
673aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x20: data &= ~0x00000080; break;
674aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x10: data &= ~0x00080000; break;
675aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		case 0x00: data &= ~0x00000200; break;
676aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
677aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
678aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
679aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x02) & 0x80)
680aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x03000000;
681aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x02) & 0x40)
682aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00002000;
683aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x07) & 0x10)
684aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00004000;
685aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x07) & 0x08)
686aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x00000003;
687aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
688aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x14000000;
689aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
690aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
691aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
692aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
693aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
694aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data  = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
695aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data |= (nv_ro08(bios, ramcfg + 0x03) & 0x30) << 12;
696aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x1373ec, data);
697aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
698aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
699aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
700aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* (re)program refpll, if required */
701aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
702aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	    (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
703aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
704aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
705aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x137320, 0x00000000);
706aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132030, 0xffff0000, runk0);
707aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
708aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wr32(fuc, 0x132024, rcoef);
709aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
710aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
711aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
712aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
713aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
714aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
715aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000010);
716aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000001);
717aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
718aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
719aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram_have(fuc, gpioMV)) {
720aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
721aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpioMV)) {
722aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
723aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 64000);
724aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
725aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
726aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
727aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) ||
728aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	     (nv_ro08(bios, ramcfg + 0x07) & 0x10)) {
729aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
730aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_nsec(fuc, 20000);
731aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
732aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
733aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) /*XXX*/ {
734aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (nv_ro08(bios, ramcfg + 0x07) & 0x40)
735aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
736aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
737aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
738aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2;
739aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f65c, 0x00000011 * data);
740aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
741aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
742aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
743aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x00010000;
744aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
745aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80))
746aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x03000000;
747aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40))
748aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00002000;
749aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10))
750aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00004000;
751aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08))
752aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x00000003;
753aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
754aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x14000000;
755aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f824, mask, data);
756aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
757aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
758aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, ramcfg + 0x08) & 0x01)
759aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00100000;
760aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
761aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
762aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f82c, 0x00100000, data);
763aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
764aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* PFB timing */
765aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28));
766aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00));
767aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04));
768aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08));
769aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c));
770aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10));
771aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14));
772aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18));
773aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c));
774aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20));
775aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24));
776aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
777aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	mask = 0x33f00000;
778aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = 0x00000000;
779aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04))
780aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x20200000;
781aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
782aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x12800000;
783aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/*XXX: see note above about there probably being some condition
784aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *     for the 10f824 stuff that uses ramcfg 3...
785aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
786aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) {
787aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (nv_ro08(bios, rammap + 0x08) & 0x0c) {
788aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
789aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				mask |= 0x00000020;
790aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			else
791aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				data |= 0x00000020;
792aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			mask |= 0x08000004;
793aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
794aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x04000000;
795aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
796aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		mask |= 0x44000020;
797aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data |= 0x08000004;
798aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
799aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
800aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f808, mask, data);
801aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
802aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro08(bios, ramcfg + 0x03) & 0x0f;
803aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f870, 0x11111111 * data);
804aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
805aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro16(bios, timing + 0x2c);
806aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) <<  4);
807aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
808aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (((nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >>  6) >
809aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	    ((nv_ro32(bios, timing + 0x28) & 0x7f000000) >> 24))
810aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = (nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >>  6;
811aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
812aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = (nv_ro32(bios, timing + 0x28) & 0x1f000000) >> 24;
813aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
814aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
815aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro08(bios, timing + 0x30);
816aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
817aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
818aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f090, 0x4000007f);
819aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
820aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
821aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
822aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
823aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
824aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
825aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
826aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nuke(fuc, mr[0]);
827aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x100);
828aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x000);
829aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
830aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
831aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, mr[0], ram->base.mr[0]);
832aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
833aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
834aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nuke(fuc, mr[0]);
835aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x100);
836aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, mr[0], 0x100, 0x000);
837aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
838aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (vc == 0 && ram_have(fuc, gpio2E)) {
839aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		u32 temp  = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
840aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (temp != ram_rd32(fuc, gpio2E)) {
841aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_wr32(fuc, gpiotrig, 1);
842aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram_nsec(fuc, 20000);
843aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
844aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
845aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
846aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode != 2) {
847aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
848aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
849aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
850aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
851aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
852aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
853aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
854aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_nsec(fuc, 1000);
855aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
856aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
857aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
858aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (nv_ro08(bios, rammap + 0x08) & 0x01)
859aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000800;
860aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	else
861aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data = 0x00000000;
862aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_mask(fuc, 0x10f200, 0x00000800, data);
863aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
864aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
865aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
866aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs/*******************************************************************************
867aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs * main hooks
868aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs ******************************************************************************/
869aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
870aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
871aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
872aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
873aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
874aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
875aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
876aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct bit_entry M;
877aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int ret, refclk, strap, i;
878aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 data;
879aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u8  cnt;
880aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
881aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* lookup memory config data relevant to the target frequency */
882aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->base.rammap.data = nvbios_rammap_match(bios, freq / 1000,
883aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs						   &ram->base.rammap.version,
884aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs						   &ram->base.rammap.size, &cnt,
885aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs						   &ram->base.ramcfg.size);
886aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 ||
887aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	     ram->base.rammap.size < 0x09) {
888aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "invalid/missing rammap entry\n");
889aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
890aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
891aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
892aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* locate specific data set for the attached memory */
893aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
894aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "invalid/missing memory table\n");
895aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
896aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
897aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
898aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
899aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro16(bios, M.offset + 1);
900aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (data)
901aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		strap = nv_ro08(bios, data + strap);
902aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
903aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (strap >= cnt) {
904aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "invalid ramcfg strap\n");
905aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
906aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
907aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
908aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->base.ramcfg.version = ram->base.rammap.version;
909aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->base.ramcfg.data = ram->base.rammap.data + ram->base.rammap.size +
910aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			       (ram->base.ramcfg.size * strap);
911aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 ||
912aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	     ram->base.ramcfg.size < 0x08) {
913aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "invalid/missing ramcfg entry\n");
914aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
915aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
916aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
917aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* lookup memory timings, if bios says they're present */
918aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
919aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (strap != 0xff) {
920aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.timing.data =
921aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nvbios_timing_entry(bios, strap,
922aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs					   &ram->base.timing.version,
923aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs					   &ram->base.timing.size);
924aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (!ram->base.timing.data ||
925aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		     ram->base.timing.version != 0x20 ||
926aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		     ram->base.timing.size < 0x33) {
927aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_error(pfb, "invalid/missing timing entry\n");
928aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			return -EINVAL;
929aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
930aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	} else {
931aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.timing.data = 0;
932aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
933aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
934aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = ram_init(fuc, pfb);
935aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret)
936aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
937aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
938aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->mode = (freq > fuc->refpll.vco1.max_freq) ? 2 : 1;
939aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->from = ram_rd32(fuc, 0x1373f4) & 0x0000000f;
940aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
941aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* XXX: this is *not* what nvidia do.  on fermi nvidia generally
942aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * select, based on some unknown condition, one of the two possible
943aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * reference frequencies listed in the vbios table for mempll and
944aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * program refpll to that frequency.
945aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *
946aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * so far, i've seen very weird values being chosen by nvidia on
947aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * kepler boards, no idea how/why they're chosen.
948aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
949aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	refclk = freq;
950aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2)
951aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		refclk = fuc->mempll.refclk;
952aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
953aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* calculate refpll coefficients */
954aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nva3_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1,
955aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			   &ram->fN1, &ram->M1, &ram->P1);
956aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	fuc->mempll.refclk = ret;
957aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret <= 0) {
958aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "unable to calc refpll\n");
959aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
960aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
961aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
962aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* calculate mempll coefficients, if we're using it */
963aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ram->mode == 2) {
964aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		/* post-divider doesn't work... the reg takes the values but
965aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		 * appears to completely ignore it.  there *is* a bit at
966aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		 * bit 28 that appears to divide the clock by 2 if set.
967aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		 */
968aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		fuc->mempll.min_p = 1;
969aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		fuc->mempll.max_p = 2;
970aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
971aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ret = nva3_pll_calc(nv_subdev(pfb), &fuc->mempll, freq,
972aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				   &ram->N2, NULL, &ram->M2, &ram->P2);
973aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ret <= 0) {
974aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_error(pfb, "unable to calc mempll\n");
975aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			return -EINVAL;
976aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
977aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
978aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
979aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	for (i = 0; i < ARRAY_SIZE(fuc->r_mr); i++) {
980aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ram_have(fuc, mr[i]))
981aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ram->base.mr[i] = ram_rd32(fuc, mr[i]);
982aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
983aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
984aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
985aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_DDR3:
986aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ret = nouveau_sddr3_calc(&ram->base);
987aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ret == 0)
988aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ret = nve0_ram_calc_sddr3(pfb, freq);
989aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
990aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
991aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ret = nouveau_gddr5_calc(&ram->base);
992aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		if (ret == 0)
993aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			ret = nve0_ram_calc_gddr5(pfb, freq);
994aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
995aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
996aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ret = -ENOSYS;
997aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
998aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
999aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1000aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return ret;
1001aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1002aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1003aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
1004aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_prog(struct nouveau_fb *pfb)
1005aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1006aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_device *device = nv_device(pfb);
1007aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
1008aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
1009aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
1010aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
1011aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1012aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1013aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic void
1014aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_tidy(struct nouveau_fb *pfb)
1015aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1016aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram = (void *)pfb->ram;
1017aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ramfuc *fuc = &ram->fuc;
1018aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram_exec(fuc, false);
1019aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1020aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1021aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
1022aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_init(struct nouveau_object *object)
1023aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1024aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_fb *pfb = (void *)object->parent;
1025aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram   = (void *)object;
1026aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
1027aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	static const u8  train0[] = {
1028aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
1029aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
1030aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	};
1031aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	static const u32 train1[] = {
1032aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x00000000, 0xffffffff,
1033aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x55555555, 0xaaaaaaaa,
1034aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x33333333, 0xcccccccc,
1035aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0xf0f0f0f0, 0x0f0f0f0f,
1036aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x00ff00ff, 0xff00ff00,
1037aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		0x0000ffff, 0xffff0000,
1038aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	};
1039aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u8  ver, hdr, cnt, len, snr, ssz;
1040aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	u32 data, save;
1041aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int ret, i;
1042aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1043aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nouveau_ram_init(&ram->base);
1044aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret)
1045aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1046aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1047aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	/* run a bunch of tables from rammap table.  there's actually
1048aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * individual pointers for each rammap entry too, but, nvidia
1049aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * seem to just run the last two entries' scripts early on in
1050aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * their init, and never again.. we'll just run 'em all once
1051aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * for now.
1052aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 *
1053aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * i strongly suspect that each script is for a separate mode
1054aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * (likely selected by 0x10f65c's lower bits?), and the
1055aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * binary driver skips the one that's already been setup by
1056aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 * the init tables.
1057aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	 */
1058aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nvbios_rammap_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
1059aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (!data || hdr < 0x15)
1060aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return -EINVAL;
1061aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1062aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	cnt  = nv_ro08(bios, data + 0x14); /* guess at count */
1063aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	data = nv_ro32(bios, data + 0x10); /* guess u32... */
1064aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	save = nv_rd32(pfb, 0x10f65c);
1065aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	for (i = 0; i < cnt; i++) {
1066aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4);
1067aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nvbios_exec(&(struct nvbios_init) {
1068aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				.subdev = nv_subdev(pfb),
1069aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				.bios = bios,
1070aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				.offset = nv_ro32(bios, data), /* guess u32 */
1071aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs				.execute = 1,
1072aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			    });
1073aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		data += 4;
1074aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1075aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	nv_wr32(pfb, 0x10f65c, save);
1076aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1077aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
1078aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
1079aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		for (i = 0; i < 0x30; i++) {
1080aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8));
1081aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]);
1082aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f918,              train1[i % 12]);
1083aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]);
1084aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f918,              train1[i % 12]);
1085aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1086aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8));
1087aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]);
1088aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f91c,              train1[i % 12]);
1089aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]);
1090aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f91c,              train1[i % 12]);
1091aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
1092aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1093aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		for (i = 0; i < 0x100; i++) {
1094aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f968, i);
1095aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]);
1096aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
1097aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1098aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		for (i = 0; i < 0x100; i++) {
1099aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f96c, i);
1100aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs			nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]);
1101aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		}
1102aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1103aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
1104aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1105aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1106aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1107aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
1108aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1109aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1110aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstatic int
1111aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1112aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	      struct nouveau_oclass *oclass, void *data, u32 size,
1113aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	      struct nouveau_object **pobject)
1114aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs{
1115aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_fb *pfb = nouveau_fb(parent);
1116aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_bios *bios = nouveau_bios(pfb);
1117aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nouveau_gpio *gpio = nouveau_gpio(pfb);
1118aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct dcb_gpio_func func;
1119aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	struct nve0_ram *ram;
1120aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	int ret;
1121aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1122aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nvc0_ram_create(parent, engine, oclass, &ram);
1123aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	*pobject = nv_object(ram);
1124aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret)
1125aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1126aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1127aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
1128aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_DDR3:
1129aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
1130aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.calc = nve0_ram_calc;
1131aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.prog = nve0_ram_prog;
1132aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->base.tidy = nve0_ram_tidy;
1133aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1134aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
1135aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_warn(pfb, "reclocking of this RAM type is unsupported\n");
1136aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1137aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1138aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1139aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	// parse bios data for both pll's
1140aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nvbios_pll_parse(bios, 0x0c, &ram->fuc.refpll);
1141aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret) {
1142aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "mclk refpll data not found\n");
1143aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1144aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1145aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1146aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = nvbios_pll_parse(bios, 0x04, &ram->fuc.mempll);
1147aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret) {
1148aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		nv_error(pfb, "mclk pll data not found\n");
1149aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		return ret;
1150aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1151aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1152aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = gpio->find(gpio, 0, 0x18, DCB_GPIO_UNUSED, &func);
1153aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret == 0) {
1154aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_gpioMV = ramfuc_reg(0x00d610 + (func.line * 0x04));
1155aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_funcMV[0] = (func.log[0] ^ 2) << 12;
1156aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_funcMV[1] = (func.log[1] ^ 2) << 12;
1157aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1158aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1159aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
1160aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	if (ret == 0) {
1161aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_gpio2E = ramfuc_reg(0x00d610 + (func.line * 0x04));
1162aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_func2E[0] = (func.log[0] ^ 2) << 12;
1163aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_func2E[1] = (func.log[1] ^ 2) << 12;
1164aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1165aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1166aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_gpiotrig = ramfuc_reg(0x00d604);
1167aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1168aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132020 = ramfuc_reg(0x132020);
1169aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132028 = ramfuc_reg(0x132028);
1170aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132024 = ramfuc_reg(0x132024);
1171aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132030 = ramfuc_reg(0x132030);
1172aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132034 = ramfuc_reg(0x132034);
1173aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
1174aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
1175aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x132040 = ramfuc_reg(0x132040);
1176aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1177aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f248 = ramfuc_reg(0x10f248);
1178aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
1179aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
1180aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
1181aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
1182aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
1183aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2a4 = ramfuc_reg(0x10f2a4);
1184aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2a8 = ramfuc_reg(0x10f2a8);
1185aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2ac = ramfuc_reg(0x10f2ac);
1186aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2cc = ramfuc_reg(0x10f2cc);
1187aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f2e8 = ramfuc_reg(0x10f2e8);
1188aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f250 = ramfuc_reg(0x10f250);
1189aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f24c = ramfuc_reg(0x10f24c);
1190aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10fec4 = ramfuc_reg(0x10fec4);
1191aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10fec8 = ramfuc_reg(0x10fec8);
1192aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f604 = ramfuc_reg(0x10f604);
1193aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
1194aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
1195aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x100770 = ramfuc_reg(0x100770);
1196aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x100778 = ramfuc_reg(0x100778);
1197aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f224 = ramfuc_reg(0x10f224);
1198aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1199aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f870 = ramfuc_reg(0x10f870);
1200aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f698 = ramfuc_reg(0x10f698);
1201aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f694 = ramfuc_reg(0x10f694);
1202aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f6b8 = ramfuc_reg(0x10f6b8);
1203aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
1204aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f670 = ramfuc_reg(0x10f670);
1205aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f60c = ramfuc_reg(0x10f60c);
1206aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
1207aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
1208aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
1209aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f82c = ramfuc_reg(0x10f82c);
1210aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1211aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f978 = ramfuc_reg(0x10f978);
1212aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
1213aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
1214aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1215aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	switch (ram->base.type) {
1216aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_GDDR5:
1217aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1218aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[1] = ramfuc_reg(0x10f330);
1219aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[2] = ramfuc_reg(0x10f334);
1220aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[3] = ramfuc_reg(0x10f338);
1221aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[4] = ramfuc_reg(0x10f33c);
1222aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[5] = ramfuc_reg(0x10f340);
1223aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[6] = ramfuc_reg(0x10f344);
1224aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[7] = ramfuc_reg(0x10f348);
1225aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[8] = ramfuc_reg(0x10f354);
1226aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[15] = ramfuc_reg(0x10f34c);
1227aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1228aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	case NV_MEM_TYPE_DDR3:
1229aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1230aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
1231aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1232aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	default:
1233aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		break;
1234aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1235aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1236aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x62c000 = ramfuc_reg(0x62c000);
1237aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
1238aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
1239aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
1240aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
1241aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f318 = ramfuc_reg(0x10f318);
1242aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
1243aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f69c = ramfuc_reg(0x10f69c);
1244aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
1245aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
1246aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x1373f4 = ramfuc_reg(0x1373f4);
1247aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
1248aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f65c = ramfuc_reg(0x10f65c);
1249aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f6bc = ramfuc_reg(0x10f6bc);
1250aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x100710 = ramfuc_reg(0x100710);
1251aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	ram->fuc.r_0x10f750 = ramfuc_reg(0x10f750);
1252aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	return 0;
1253aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs}
1254aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs
1255aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsstruct nouveau_oclass
1256aae95ca708140307813e49af6d0d4a7205509129Ben Skeggsnve0_ram_oclass = {
1257aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	.handle = 0,
1258aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	.ofuncs = &(struct nouveau_ofuncs) {
1259aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.ctor = nve0_ram_ctor,
1260aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.dtor = _nouveau_ram_dtor,
1261aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.init = nve0_ram_init,
1262aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs		.fini = _nouveau_ram_fini,
1263aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs	}
1264aae95ca708140307813e49af6d0d4a7205509129Ben Skeggs};
1265