aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-03-04 00:01:37 -0500
committerBen Skeggs <bskeggs@redhat.com>2013-11-08 00:40:19 -0500
commitaae95ca708140307813e49af6d0d4a7205509129 (patch)
tree20acced9f1a88e7be22f8f1c85c8bc610a2932b1
parent26fdd78cce3f51a49e1f2d3ad27ee893a28d220e (diff)
drm/nouveau/fb: implement various bits of work towards memory reclocking
Not even remotely ready for the vast majority of the world. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/Makefile4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h29
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/priv.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h118
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c168
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c15
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c245
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c396
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c568
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c1264
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h18
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c99
21 files changed, 3093 insertions, 60 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 64b4691b294a..edcf801613e6 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -94,6 +94,7 @@ nouveau-y += core/subdev/fb/nva3.o
94nouveau-y += core/subdev/fb/nvaa.o 94nouveau-y += core/subdev/fb/nvaa.o
95nouveau-y += core/subdev/fb/nvaf.o 95nouveau-y += core/subdev/fb/nvaf.o
96nouveau-y += core/subdev/fb/nvc0.o 96nouveau-y += core/subdev/fb/nvc0.o
97nouveau-y += core/subdev/fb/nve0.o
97nouveau-y += core/subdev/fb/ramnv04.o 98nouveau-y += core/subdev/fb/ramnv04.o
98nouveau-y += core/subdev/fb/ramnv10.o 99nouveau-y += core/subdev/fb/ramnv10.o
99nouveau-y += core/subdev/fb/ramnv1a.o 100nouveau-y += core/subdev/fb/ramnv1a.o
@@ -107,6 +108,9 @@ nouveau-y += core/subdev/fb/ramnv50.o
107nouveau-y += core/subdev/fb/ramnva3.o 108nouveau-y += core/subdev/fb/ramnva3.o
108nouveau-y += core/subdev/fb/ramnvaa.o 109nouveau-y += core/subdev/fb/ramnvaa.o
109nouveau-y += core/subdev/fb/ramnvc0.o 110nouveau-y += core/subdev/fb/ramnvc0.o
111nouveau-y += core/subdev/fb/ramnve0.o
112nouveau-y += core/subdev/fb/sddr3.o
113nouveau-y += core/subdev/fb/gddr5.o
110nouveau-y += core/subdev/gpio/base.o 114nouveau-y += core/subdev/gpio/base.o
111nouveau-y += core/subdev/gpio/nv10.o 115nouveau-y += core/subdev/gpio/nv10.o
112nouveau-y += core/subdev/gpio/nv50.o 116nouveau-y += core/subdev/gpio/nv50.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index 33f3c92a180c..3900104976fc 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -69,7 +69,7 @@ nve0_identify(struct nouveau_device *device)
69 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; 69 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
70 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; 70 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
71 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 71 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
72 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; 72 device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
73 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 73 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
74 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; 74 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
75 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 75 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
@@ -102,7 +102,7 @@ nve0_identify(struct nouveau_device *device)
102 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; 102 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
103 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; 103 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
104 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 104 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
105 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; 105 device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
106 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 106 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
107 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; 107 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
108 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 108 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
@@ -135,7 +135,7 @@ nve0_identify(struct nouveau_device *device)
135 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; 135 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
136 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; 136 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
137 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 137 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
138 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; 138 device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
139 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 139 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
140 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; 140 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
141 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 141 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
@@ -168,7 +168,7 @@ nve0_identify(struct nouveau_device *device)
168 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; 168 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
169 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; 169 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
170 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 170 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
171 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; 171 device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
172 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 172 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
173 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; 173 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
174 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 174 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
@@ -203,7 +203,7 @@ nve0_identify(struct nouveau_device *device)
203 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; 203 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
204 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; 204 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
205 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 205 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
206 device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; 206 device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
207 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; 207 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
208 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; 208 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
209 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; 209 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
index 33cae4882e73..8541aa382ff2 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -99,6 +99,7 @@ extern struct nouveau_oclass *nva3_fb_oclass;
99extern struct nouveau_oclass *nvaa_fb_oclass; 99extern struct nouveau_oclass *nvaa_fb_oclass;
100extern struct nouveau_oclass *nvaf_fb_oclass; 100extern struct nouveau_oclass *nvaf_fb_oclass;
101extern struct nouveau_oclass *nvc0_fb_oclass; 101extern struct nouveau_oclass *nvc0_fb_oclass;
102extern struct nouveau_oclass *nve0_fb_oclass;
102 103
103struct nouveau_ram { 104struct nouveau_ram {
104 struct nouveau_object base; 105 struct nouveau_object base;
@@ -125,9 +126,17 @@ struct nouveau_ram {
125 int (*get)(struct nouveau_fb *, u64 size, u32 align, 126 int (*get)(struct nouveau_fb *, u64 size, u32 align,
126 u32 size_nc, u32 type, struct nouveau_mem **); 127 u32 size_nc, u32 type, struct nouveau_mem **);
127 void (*put)(struct nouveau_fb *, struct nouveau_mem **); 128 void (*put)(struct nouveau_fb *, struct nouveau_mem **);
129
128 int (*calc)(struct nouveau_fb *, u32 freq); 130 int (*calc)(struct nouveau_fb *, u32 freq);
129 int (*prog)(struct nouveau_fb *); 131 int (*prog)(struct nouveau_fb *);
130 void (*tidy)(struct nouveau_fb *); 132 void (*tidy)(struct nouveau_fb *);
133 struct {
134 u8 version;
135 u32 data;
136 u8 size;
137 } rammap, ramcfg, timing;
138 u32 freq;
139 u32 mr[16];
131}; 140};
132 141
133#endif 142#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
index 2fe1f712eefa..8eca457c2814 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
@@ -45,6 +45,7 @@ nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
45 lM = max(lM, (int)info->vco1.min_m); 45 lM = max(lM, (int)info->vco1.min_m);
46 hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq; 46 hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq;
47 hM = min(hM, (int)info->vco1.max_m); 47 hM = min(hM, (int)info->vco1.max_m);
48 lM = min(lM, hM);
48 49
49 for (M = lM; M <= hM; M++) { 50 for (M = lM; M <= hM; M++) {
50 u32 tmp = freq * *P * M; 51 u32 tmp = freq * *P * M;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
new file mode 100644
index 000000000000..34f9605ffee6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
@@ -0,0 +1,96 @@
1/*
2 * Copyright 2013 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include <subdev/bios.h>
26#include "priv.h"
27
28int
29nouveau_gddr5_calc(struct nouveau_ram *ram)
30{
31 struct nouveau_bios *bios = nouveau_bios(ram);
32 int pd, lf, xd, vh, vr, vo;
33 int WL, CL, WR, at, dt, ds;
34 int rq = ram->freq < 1000000; /* XXX */
35
36 switch (!!ram->ramcfg.data * ram->ramcfg.version) {
37 case 0x11:
38 pd = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x80) >> 7;
39 lf = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x40) >> 6;
40 xd = !(nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x20);
41 vh = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x10) >> 4;
42 vr = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x04) >> 2;
43 vo = nv_ro08(bios, ram->ramcfg.data + 0x06) & 0xff;
44 break;
45 default:
46 return -ENOSYS;
47 }
48
49 switch (!!ram->timing.data * ram->timing.version) {
50 case 0x20:
51 WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
52 CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
53 WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
54 at = (nv_ro08(bios, ram->timing.data + 0x2e) & 0xc0) >> 6;
55 dt = nv_ro08(bios, ram->timing.data + 0x2e) & 0x03;
56 ds = nv_ro08(bios, ram->timing.data + 0x2f) & 0x03;
57 break;
58 default:
59 return -ENOSYS;
60 }
61
62 if (WL < 1 || WL > 7 || CL < 5 || CL > 36 || WR < 4 || WR > 35)
63 return -EINVAL;
64 CL -= 5;
65 WR -= 4;
66
67 ram->mr[0] &= ~0xf7f;
68 ram->mr[0] |= (WR & 0x0f) << 8;
69 ram->mr[0] |= (CL & 0x0f) << 3;
70 ram->mr[0] |= (WL & 0x07) << 0;
71
72 ram->mr[1] &= ~0x0bf;
73 ram->mr[1] |= (xd & 0x01) << 7;
74 ram->mr[1] |= (at & 0x03) << 4;
75 ram->mr[1] |= (dt & 0x03) << 2;
76 ram->mr[1] |= (ds & 0x03) << 0;
77
78 ram->mr[3] &= ~0x020;
79 ram->mr[3] |= (rq & 0x01) << 5;
80
81 if (!vo)
82 vo = (ram->mr[6] & 0xff0) >> 4;
83 if (ram->mr[6] & 0x001)
84 pd = 1; /* binary driver does this.. bug? */
85 ram->mr[6] &= ~0xff1;
86 ram->mr[6] |= (vo & 0xff) << 4;
87 ram->mr[6] |= (pd & 0x01) << 0;
88
89 if (!(ram->mr[7] & 0x100))
90 vr = 0; /* binary driver does this.. bug? */
91 ram->mr[7] &= ~0x188;
92 ram->mr[7] |= (vr & 0x01) << 8;
93 ram->mr[7] |= (vh & 0x01) << 7;
94 ram->mr[7] |= (lf & 0x01) << 3;
95 return 0;
96}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
new file mode 100644
index 000000000000..581f808527f2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
@@ -0,0 +1,17 @@
1#ifndef __NVKM_FB_NV40_H__
2#define __NVKM_FB_NV40_H__
3
4#include "priv.h"
5
6struct nv40_ram {
7 struct nouveau_ram base;
8 u32 ctrl;
9 u32 coef;
10};
11
12
13int nv40_ram_calc(struct nouveau_fb *, u32);
14int nv40_ram_prog(struct nouveau_fb *);
15void nv40_ram_tidy(struct nouveau_fb *);
16
17#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index 7fa6a91a5866..e5fc37c4caac 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -22,24 +22,18 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "nv04.h" 25#include "nvc0.h"
26
27struct nvc0_fb_priv {
28 struct nouveau_fb base;
29 struct page *r100c10_page;
30 dma_addr_t r100c10;
31};
32 26
33extern const u8 nvc0_pte_storage_type_map[256]; 27extern const u8 nvc0_pte_storage_type_map[256];
34 28
35static bool 29bool
36nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags) 30nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
37{ 31{
38 u8 memtype = (tile_flags & 0x0000ff00) >> 8; 32 u8 memtype = (tile_flags & 0x0000ff00) >> 8;
39 return likely((nvc0_pte_storage_type_map[memtype] != 0xff)); 33 return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
40} 34}
41 35
42static int 36int
43nvc0_fb_init(struct nouveau_object *object) 37nvc0_fb_init(struct nouveau_object *object)
44{ 38{
45 struct nvc0_fb_priv *priv = (void *)object; 39 struct nvc0_fb_priv *priv = (void *)object;
@@ -54,7 +48,7 @@ nvc0_fb_init(struct nouveau_object *object)
54 return 0; 48 return 0;
55} 49}
56 50
57static void 51void
58nvc0_fb_dtor(struct nouveau_object *object) 52nvc0_fb_dtor(struct nouveau_object *object)
59{ 53{
60 struct nouveau_device *device = nv_device(object); 54 struct nouveau_device *device = nv_device(object);
@@ -69,7 +63,7 @@ nvc0_fb_dtor(struct nouveau_object *object)
69 nouveau_fb_destroy(&priv->base); 63 nouveau_fb_destroy(&priv->base);
70} 64}
71 65
72static int 66int
73nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 67nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
74 struct nouveau_oclass *oclass, void *data, u32 size, 68 struct nouveau_oclass *oclass, void *data, u32 size,
75 struct nouveau_object **pobject) 69 struct nouveau_object **pobject)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
new file mode 100644
index 000000000000..9e1931eb746f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
@@ -0,0 +1,29 @@
1#ifndef __NVKM_RAM_NVC0_H__
2#define __NVKM_RAM_NVC0_H__
3
4#include "priv.h"
5#include "nv50.h"
6
7struct nvc0_fb_priv {
8 struct nouveau_fb base;
9 struct page *r100c10_page;
10 dma_addr_t r100c10;
11};
12
13int nvc0_fb_ctor(struct nouveau_object *, struct nouveau_object *,
14 struct nouveau_oclass *, void *, u32,
15 struct nouveau_object **);
16void nvc0_fb_dtor(struct nouveau_object *);
17int nvc0_fb_init(struct nouveau_object *);
18bool nvc0_fb_memtype_valid(struct nouveau_fb *, u32);
19
20
21#define nvc0_ram_create(p,e,o,d) \
22 nvc0_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
23int nvc0_ram_create_(struct nouveau_object *, struct nouveau_object *,
24 struct nouveau_oclass *, int, void **);
25int nvc0_ram_get(struct nouveau_fb *, u64, u32, u32, u32,
26 struct nouveau_mem **);
27void nvc0_ram_put(struct nouveau_fb *, struct nouveau_mem **);
28
29#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c
new file mode 100644
index 000000000000..595db50cfef3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include "nvc0.h"
26
27struct nouveau_oclass *
28nve0_fb_oclass = &(struct nouveau_fb_impl) {
29 .base.handle = NV_SUBDEV(FB, 0xe0),
30 .base.ofuncs = &(struct nouveau_ofuncs) {
31 .ctor = nvc0_fb_ctor,
32 .dtor = nvc0_fb_dtor,
33 .init = nvc0_fb_init,
34 .fini = _nouveau_fb_fini,
35 },
36 .memtype = nvc0_fb_memtype_valid,
37 .ram = &nve0_ram_oclass,
38}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
index eaf379567a63..493125214e88 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -31,6 +31,10 @@ extern struct nouveau_oclass nv50_ram_oclass;
31extern struct nouveau_oclass nva3_ram_oclass; 31extern struct nouveau_oclass nva3_ram_oclass;
32extern struct nouveau_oclass nvaa_ram_oclass; 32extern struct nouveau_oclass nvaa_ram_oclass;
33extern struct nouveau_oclass nvc0_ram_oclass; 33extern struct nouveau_oclass nvc0_ram_oclass;
34extern struct nouveau_oclass nve0_ram_oclass;
35
36int nouveau_sddr3_calc(struct nouveau_ram *ram);
37int nouveau_gddr5_calc(struct nouveau_ram *ram);
34 38
35#define nouveau_fb_create(p,e,c,d) \ 39#define nouveau_fb_create(p,e,c,d) \
36 nouveau_fb_create_((p), (e), (c), sizeof(**d), (void **)d) 40 nouveau_fb_create_((p), (e), (c), sizeof(**d), (void **)d)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
new file mode 100644
index 000000000000..0f57fcfe0bbf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
@@ -0,0 +1,118 @@
1#ifndef __NVKM_FBRAM_FUC_H__
2#define __NVKM_FBRAM_FUC_H__
3
4#include <subdev/pwr.h>
5
6struct ramfuc {
7 struct nouveau_memx *memx;
8 struct nouveau_fb *pfb;
9 int sequence;
10};
11
12struct ramfuc_reg {
13 int sequence;
14 bool force;
15 u32 addr[2];
16 u32 data;
17};
18
19static inline struct ramfuc_reg
20ramfuc_reg2(u32 addr1, u32 addr2)
21{
22 return (struct ramfuc_reg) {
23 .sequence = 0,
24 .addr = { addr1, addr2 },
25 .data = 0xdeadbeef,
26 };
27}
28
29static inline struct ramfuc_reg
30ramfuc_reg(u32 addr)
31{
32 return ramfuc_reg2(addr, addr);
33}
34
35static inline int
36ramfuc_init(struct ramfuc *ram, struct nouveau_fb *pfb)
37{
38 struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
39 int ret;
40
41 ret = nouveau_memx_init(ppwr, &ram->memx);
42 if (ret)
43 return ret;
44
45 ram->sequence++;
46 ram->pfb = pfb;
47 return 0;
48}
49
50static inline int
51ramfuc_exec(struct ramfuc *ram, bool exec)
52{
53 int ret = 0;
54 if (ram->pfb) {
55 ret = nouveau_memx_fini(&ram->memx, exec);
56 ram->pfb = NULL;
57 }
58 return ret;
59}
60
61static inline u32
62ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg)
63{
64 if (reg->sequence != ram->sequence)
65 reg->data = nv_rd32(ram->pfb, reg->addr[0]);
66 return reg->data;
67}
68
69static inline void
70ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data)
71{
72 reg->sequence = ram->sequence;
73 reg->data = data;
74 if (reg->addr[0] != reg->addr[1])
75 nouveau_memx_wr32(ram->memx, reg->addr[1], reg->data);
76 nouveau_memx_wr32(ram->memx, reg->addr[0], reg->data);
77}
78
79static inline void
80ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg)
81{
82 reg->force = true;
83}
84
85static inline u32
86ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data)
87{
88 u32 temp = ramfuc_rd32(ram, reg);
89 if (temp != ((temp & ~mask) | data) || reg->force) {
90 ramfuc_wr32(ram, reg, (temp & ~mask) | data);
91 reg->force = false;
92 }
93 return temp;
94}
95
96static inline void
97ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec)
98{
99 nouveau_memx_wait(ram->memx, addr, mask, data, nsec);
100}
101
102static inline void
103ramfuc_nsec(struct ramfuc *ram, u32 nsec)
104{
105 nouveau_memx_nsec(ram->memx, nsec);
106}
107
108#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
109#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
110#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
111#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
112#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
113#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
114#define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))
115#define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n))
116#define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n))
117
118#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
index ee49ac4dbdb6..7648beb11199 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
@@ -22,7 +22,154 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "priv.h" 25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/pll.h>
28#include <subdev/bios/init.h>
29#include <subdev/clock.h>
30#include <subdev/clock/pll.h>
31#include <subdev/timer.h>
32
33#include <engine/fifo.h>
34
35#include "nv40.h"
36
37int
38nv40_ram_calc(struct nouveau_fb *pfb, u32 freq)
39{
40 struct nouveau_bios *bios = nouveau_bios(pfb);
41 struct nv40_ram *ram = (void *)pfb->ram;
42 struct nvbios_pll pll;
43 int N1, M1, N2, M2;
44 int log2P, ret;
45
46 ret = nvbios_pll_parse(bios, 0x04, &pll);
47 if (ret) {
48 nv_error(pfb, "mclk pll data not found\n");
49 return ret;
50 }
51
52 ret = nv04_pll_calc(nv_subdev(pfb), &pll, freq,
53 &N1, &M1, &N2, &M2, &log2P);
54 if (ret < 0)
55 return ret;
56
57 ram->ctrl = 0x80000000 | (log2P << 16);
58 ram->ctrl |= min(pll.bias_p + log2P, (int)pll.max_p) << 20;
59 if (N2 == M2) {
60 ram->ctrl |= 0x00000100;
61 ram->coef = (N1 << 8) | M1;
62 } else {
63 ram->ctrl |= 0x40000000;
64 ram->coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1;
65 }
66
67 return 0;
68}
69
70int
71nv40_ram_prog(struct nouveau_fb *pfb)
72{
73 struct nouveau_bios *bios = nouveau_bios(pfb);
74 struct nv40_ram *ram = (void *)pfb->ram;
75 struct bit_entry M;
76 u32 crtc_mask = 0;
77 u8 sr1[2];
78 int i;
79
80 /* determine which CRTCs are active, fetch VGA_SR1 for each */
81 for (i = 0; i < 2; i++) {
82 u32 vbl = nv_rd32(pfb, 0x600808 + (i * 0x2000));
83 u32 cnt = 0;
84 do {
85 if (vbl != nv_rd32(pfb, 0x600808 + (i * 0x2000))) {
86 nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
87 sr1[i] = nv_rd08(pfb, 0x0c03c5 + (i * 0x2000));
88 if (!(sr1[i] & 0x20))
89 crtc_mask |= (1 << i);
90 break;
91 }
92 udelay(1);
93 } while (cnt++ < 32);
94 }
95
96 /* wait for vblank start on active crtcs, disable memory access */
97 for (i = 0; i < 2; i++) {
98 if (!(crtc_mask & (1 << i)))
99 continue;
100 nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000);
101 nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
102 nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
103 nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
104 }
105
106 /* prepare ram for reclocking */
107 nv_wr32(pfb, 0x1002d4, 0x00000001); /* precharge */
108 nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */
109 nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */
110 nv_mask(pfb, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
111 nv_wr32(pfb, 0x1002dc, 0x00000001); /* enable self-refresh */
112
113 /* change the PLL of each memory partition */
114 nv_mask(pfb, 0x00c040, 0x0000c000, 0x00000000);
115 switch (nv_device(pfb)->chipset) {
116 case 0x40:
117 case 0x45:
118 case 0x41:
119 case 0x42:
120 case 0x47:
121 nv_mask(pfb, 0x004044, 0xc0771100, ram->ctrl);
122 nv_mask(pfb, 0x00402c, 0xc0771100, ram->ctrl);
123 nv_wr32(pfb, 0x004048, ram->coef);
124 nv_wr32(pfb, 0x004030, ram->coef);
125 case 0x43:
126 case 0x49:
127 case 0x4b:
128 nv_mask(pfb, 0x004038, 0xc0771100, ram->ctrl);
129 nv_wr32(pfb, 0x00403c, ram->coef);
130 default:
131 nv_mask(pfb, 0x004020, 0xc0771100, ram->ctrl);
132 nv_wr32(pfb, 0x004024, ram->coef);
133 break;
134 }
135 udelay(100);
136 nv_mask(pfb, 0x00c040, 0x0000c000, 0x0000c000);
137
138 /* re-enable normal operation of memory controller */
139 nv_wr32(pfb, 0x1002dc, 0x00000000);
140 nv_mask(pfb, 0x100210, 0x80000000, 0x80000000);
141 udelay(100);
142
143 /* execute memory reset script from vbios */
144 if (!bit_entry(bios, 'M', &M)) {
145 struct nvbios_init init = {
146 .subdev = nv_subdev(pfb),
147 .bios = bios,
148 .offset = nv_ro16(bios, M.offset + 0x00),
149 .execute = 1,
150 };
151
152 nvbios_exec(&init);
153 }
154
155 /* make sure we're in vblank (hopefully the same one as before), and
156 * then re-enable crtc memory access
157 */
158 for (i = 0; i < 2; i++) {
159 if (!(crtc_mask & (1 << i)))
160 continue;
161 nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
162 nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
163 nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i]);
164 }
165
166 return 0;
167}
168
169void
170nv40_ram_tidy(struct nouveau_fb *pfb)
171{
172}
26 173
27static int 174static int
28nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, 175nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +177,7 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
30 struct nouveau_object **pobject) 177 struct nouveau_object **pobject)
31{ 178{
32 struct nouveau_fb *pfb = nouveau_fb(parent); 179 struct nouveau_fb *pfb = nouveau_fb(parent);
33 struct nouveau_ram *ram; 180 struct nv40_ram *ram;
34 u32 pbus1218 = nv_rd32(pfb, 0x001218); 181 u32 pbus1218 = nv_rd32(pfb, 0x001218);
35 int ret; 182 int ret;
36 183
@@ -40,15 +187,18 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
40 return ret; 187 return ret;
41 188
42 switch (pbus1218 & 0x00000300) { 189 switch (pbus1218 & 0x00000300) {
43 case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break; 190 case 0x00000000: ram->base.type = NV_MEM_TYPE_SDRAM; break;
44 case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break; 191 case 0x00000100: ram->base.type = NV_MEM_TYPE_DDR1; break;
45 case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break; 192 case 0x00000200: ram->base.type = NV_MEM_TYPE_GDDR3; break;
46 case 0x00000300: ram->type = NV_MEM_TYPE_DDR2; break; 193 case 0x00000300: ram->base.type = NV_MEM_TYPE_DDR2; break;
47 } 194 }
48 195
49 ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; 196 ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
50 ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; 197 ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
51 ram->tags = nv_rd32(pfb, 0x100320); 198 ram->base.tags = nv_rd32(pfb, 0x100320);
199 ram->base.calc = nv40_ram_calc;
200 ram->base.prog = nv40_ram_prog;
201 ram->base.tidy = nv40_ram_tidy;
52 return 0; 202 return 0;
53} 203}
54 204
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
index 1dab7e12abab..d64498a4d9ee 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
@@ -22,7 +22,7 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "priv.h" 25#include "nv40.h"
26 26
27static int 27static int
28nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, 28nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +30,7 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
30 struct nouveau_object **pobject) 30 struct nouveau_object **pobject)
31{ 31{
32 struct nouveau_fb *pfb = nouveau_fb(parent); 32 struct nouveau_fb *pfb = nouveau_fb(parent);
33 struct nouveau_ram *ram; 33 struct nv40_ram *ram;
34 u32 pfb474 = nv_rd32(pfb, 0x100474); 34 u32 pfb474 = nv_rd32(pfb, 0x100474);
35 int ret; 35 int ret;
36 36
@@ -40,15 +40,18 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
40 return ret; 40 return ret;
41 41
42 if (pfb474 & 0x00000004) 42 if (pfb474 & 0x00000004)
43 ram->type = NV_MEM_TYPE_GDDR3; 43 ram->base.type = NV_MEM_TYPE_GDDR3;
44 if (pfb474 & 0x00000002) 44 if (pfb474 & 0x00000002)
45 ram->type = NV_MEM_TYPE_DDR2; 45 ram->base.type = NV_MEM_TYPE_DDR2;
46 if (pfb474 & 0x00000001) 46 if (pfb474 & 0x00000001)
47 ram->type = NV_MEM_TYPE_DDR1; 47 ram->base.type = NV_MEM_TYPE_DDR1;
48 48
49 ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; 49 ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
50 ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; 50 ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
51 ram->tags = nv_rd32(pfb, 0x100320); 51 ram->base.tags = nv_rd32(pfb, 0x100320);
52 ram->base.calc = nv40_ram_calc;
53 ram->base.prog = nv40_ram_prog;
54 ram->base.tidy = nv40_ram_tidy;
52 return 0; 55 return 0;
53} 56}
54 57
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
index 25fff842e5c1..089acac810c5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
@@ -22,7 +22,7 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "priv.h" 25#include "nv40.h"
26 26
27static int 27static int
28nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, 28nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +30,7 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
30 struct nouveau_object **pobject) 30 struct nouveau_object **pobject)
31{ 31{
32 struct nouveau_fb *pfb = nouveau_fb(parent); 32 struct nouveau_fb *pfb = nouveau_fb(parent);
33 struct nouveau_ram *ram; 33 struct nv40_ram *ram;
34 u32 pfb474 = nv_rd32(pfb, 0x100474); 34 u32 pfb474 = nv_rd32(pfb, 0x100474);
35 int ret; 35 int ret;
36 36
@@ -40,13 +40,16 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
40 return ret; 40 return ret;
41 41
42 if (pfb474 & 0x00000004) 42 if (pfb474 & 0x00000004)
43 ram->type = NV_MEM_TYPE_GDDR3; 43 ram->base.type = NV_MEM_TYPE_GDDR3;
44 if (pfb474 & 0x00000002) 44 if (pfb474 & 0x00000002)
45 ram->type = NV_MEM_TYPE_DDR2; 45 ram->base.type = NV_MEM_TYPE_DDR2;
46 if (pfb474 & 0x00000001) 46 if (pfb474 & 0x00000001)
47 ram->type = NV_MEM_TYPE_DDR1; 47 ram->base.type = NV_MEM_TYPE_DDR1;
48 48
49 ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; 49 ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
50 ram->base.calc = nv40_ram_calc;
51 ram->base.prog = nv40_ram_prog;
52 ram->base.tidy = nv40_ram_tidy;
50 return 0; 53 return 0;
51} 54}
52 55
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
index ab7ef0ac9e34..baa013afa57b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
@@ -22,7 +22,7 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "priv.h" 25#include "nv40.h"
26 26
27static int 27static int
28nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, 28nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
@@ -30,7 +30,7 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
30 struct nouveau_object **pobject) 30 struct nouveau_object **pobject)
31{ 31{
32 struct nouveau_fb *pfb = nouveau_fb(parent); 32 struct nouveau_fb *pfb = nouveau_fb(parent);
33 struct nouveau_ram *ram; 33 struct nv40_ram *ram;
34 u32 pfb914 = nv_rd32(pfb, 0x100914); 34 u32 pfb914 = nv_rd32(pfb, 0x100914);
35 int ret; 35 int ret;
36 36
@@ -40,15 +40,18 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
40 return ret; 40 return ret;
41 41
42 switch (pfb914 & 0x00000003) { 42 switch (pfb914 & 0x00000003) {
43 case 0x00000000: ram->type = NV_MEM_TYPE_DDR1; break; 43 case 0x00000000: ram->base.type = NV_MEM_TYPE_DDR1; break;
44 case 0x00000001: ram->type = NV_MEM_TYPE_DDR2; break; 44 case 0x00000001: ram->base.type = NV_MEM_TYPE_DDR2; break;
45 case 0x00000002: ram->type = NV_MEM_TYPE_GDDR3; break; 45 case 0x00000002: ram->base.type = NV_MEM_TYPE_GDDR3; break;
46 case 0x00000003: break; 46 case 0x00000003: break;
47 } 47 }
48 48
49 ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; 49 ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
50 ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; 50 ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
51 ram->tags = nv_rd32(pfb, 0x100320); 51 ram->base.tags = nv_rd32(pfb, 0x100320);
52 ram->base.calc = nv40_ram_calc;
53 ram->base.prog = nv40_ram_prog;
54 ram->base.tidy = nv40_ram_tidy;
52 return 0; 55 return 0;
53} 56}
54 57
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
index 2315a2195a89..76762a17d89c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
@@ -23,14 +23,216 @@
23 */ 23 */
24 24
25#include <subdev/bios.h> 25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/pll.h>
28#include <subdev/bios/perf.h>
29#include <subdev/bios/timing.h>
30#include <subdev/clock/pll.h>
31#include <subdev/fb.h>
32
33#include <core/option.h>
26#include <core/mm.h> 34#include <core/mm.h>
27 35
36#include "ramseq.h"
37
28#include "nv50.h" 38#include "nv50.h"
29 39
40struct nv50_ramseq {
41 struct hwsq base;
42 struct hwsq_reg r_0x002504;
43 struct hwsq_reg r_0x004008;
44 struct hwsq_reg r_0x00400c;
45 struct hwsq_reg r_0x00c040;
46 struct hwsq_reg r_0x100210;
47 struct hwsq_reg r_0x1002d0;
48 struct hwsq_reg r_0x1002d4;
49 struct hwsq_reg r_0x1002dc;
50 struct hwsq_reg r_0x100da0[8];
51 struct hwsq_reg r_0x100e20;
52 struct hwsq_reg r_0x100e24;
53 struct hwsq_reg r_0x611200;
54 struct hwsq_reg r_timing[9];
55 struct hwsq_reg r_mr[4];
56};
57
30struct nv50_ram { 58struct nv50_ram {
31 struct nouveau_ram base; 59 struct nouveau_ram base;
60 struct nv50_ramseq hwsq;
32}; 61};
33 62
63#define QFX5800NVA0 1
64
65static int
66nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
67{
68 struct nouveau_bios *bios = nouveau_bios(pfb);
69 struct nv50_ram *ram = (void *)pfb->ram;
70 struct nv50_ramseq *hwsq = &ram->hwsq;
71 struct nvbios_perfE perfE;
72 struct nvbios_pll mpll;
73 struct bit_entry M;
74 struct {
75 u32 data;
76 u8 size;
77 } ramcfg, timing;
78 u8 ver, hdr, cnt, strap;
79 u32 data;
80 int N1, M1, N2, M2, P;
81 int ret, i;
82
83 /* lookup closest matching performance table entry for frequency */
84 i = 0;
85 do {
86 ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
87 &ramcfg.size, &perfE);
88 if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) ||
89 (ramcfg.size < 2)) {
90 nv_error(pfb, "invalid/missing perftab entry\n");
91 return -EINVAL;
92 }
93 } while (perfE.memory < freq);
94
95 /* locate specific data set for the attached memory */
96 if (bit_entry(bios, 'M', &M) || M.version != 1 || M.length < 5) {
97 nv_error(pfb, "invalid/missing memory table\n");
98 return -EINVAL;
99 }
100
101 strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
102 data = nv_ro16(bios, M.offset + 3);
103 if (data)
104 strap = nv_ro08(bios, data + strap);
105
106 if (strap >= cnt) {
107 nv_error(pfb, "invalid ramcfg strap\n");
108 return -EINVAL;
109 }
110
111 ramcfg.data += hdr + (strap * ramcfg.size);
112
113 /* lookup memory timings, if bios says they're present */
114 strap = nv_ro08(bios, ramcfg.data + 0x01);
115 if (strap != 0xff) {
116 timing.data = nvbios_timing_entry(bios, strap, &ver, &hdr);
117 if (!timing.data || ver != 0x10 || hdr < 0x12) {
118 nv_error(pfb, "invalid/missing timing entry "
119 "%02x %04x %02x %02x\n",
120 strap, timing.data, ver, hdr);
121 return -EINVAL;
122 }
123 } else {
124 timing.data = 0;
125 }
126
127 ret = ram_init(hwsq, nv_subdev(pfb));
128 if (ret)
129 return ret;
130
131 ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
132 ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
133 ram_wr32(hwsq, 0x611200, 0x00003300);
134 ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */
135 ram_nsec(hwsq, 8000);
136 ram_setf(hwsq, 0x10, 0x00); /* disable fb */
137 ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
138
139 ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */
140 ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
141 ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
142 ram_wr32(hwsq, 0x100210, 0x00000000); /* disable auto-refresh */
143 ram_wr32(hwsq, 0x1002dc, 0x00000001); /* enable self-refresh */
144
145 ret = nvbios_pll_parse(bios, 0x004008, &mpll);
146 mpll.vco2.max_freq = 0;
147 if (ret == 0) {
148 ret = nv04_pll_calc(nv_subdev(pfb), &mpll, freq,
149 &N1, &M1, &N2, &M2, &P);
150 if (ret == 0)
151 ret = -EINVAL;
152 }
153
154 if (ret < 0)
155 return ret;
156
157 ram_mask(hwsq, 0x00c040, 0xc000c000, 0x0000c000);
158 ram_mask(hwsq, 0x004008, 0x00000200, 0x00000200);
159 ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
160 ram_mask(hwsq, 0x004008, 0x81ff0000, 0x80000000 | (mpll.bias_p << 19) |
161 (P << 22) | (P << 16));
162#if QFX5800NVA0
163 for (i = 0; i < 8; i++)
164 ram_mask(hwsq, 0x100da0[i], 0x00000000, 0x00000000); /*XXX*/
165#endif
166 ram_nsec(hwsq, 96000); /*XXX*/
167 ram_mask(hwsq, 0x004008, 0x00002200, 0x00002000);
168
169 ram_wr32(hwsq, 0x1002dc, 0x00000000); /* disable self-refresh */
170 ram_wr32(hwsq, 0x100210, 0x80000000); /* enable auto-refresh */
171
172 ram_nsec(hwsq, 12000);
173
174 switch (ram->base.type) {
175 case NV_MEM_TYPE_DDR2:
176 ram_nuke(hwsq, mr[0]); /* force update */
177 ram_mask(hwsq, mr[0], 0x000, 0x000);
178 break;
179 case NV_MEM_TYPE_GDDR3:
180 ram_mask(hwsq, mr[2], 0x000, 0x000);
181 ram_nuke(hwsq, mr[0]); /* force update */
182 ram_mask(hwsq, mr[0], 0x000, 0x000);
183 break;
184 default:
185 break;
186 }
187
188 ram_mask(hwsq, timing[3], 0x00000000, 0x00000000); /*XXX*/
189 ram_mask(hwsq, timing[1], 0x00000000, 0x00000000); /*XXX*/
190 ram_mask(hwsq, timing[6], 0x00000000, 0x00000000); /*XXX*/
191 ram_mask(hwsq, timing[7], 0x00000000, 0x00000000); /*XXX*/
192 ram_mask(hwsq, timing[8], 0x00000000, 0x00000000); /*XXX*/
193 ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
194 ram_mask(hwsq, timing[2], 0x00000000, 0x00000000); /*XXX*/
195 ram_mask(hwsq, timing[4], 0x00000000, 0x00000000); /*XXX*/
196 ram_mask(hwsq, timing[5], 0x00000000, 0x00000000); /*XXX*/
197
198 ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/
199
200#if QFX5800NVA0
201 ram_nuke(hwsq, 0x100e24);
202 ram_mask(hwsq, 0x100e24, 0x00000000, 0x00000000);
203 ram_nuke(hwsq, 0x100e20);
204 ram_mask(hwsq, 0x100e20, 0x00000000, 0x00000000);
205#endif
206
207 ram_mask(hwsq, mr[0], 0x100, 0x100);
208 ram_mask(hwsq, mr[0], 0x100, 0x000);
209
210 ram_setf(hwsq, 0x10, 0x01); /* enable fb */
211 ram_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */
212 ram_wr32(hwsq, 0x611200, 0x00003330);
213 ram_wr32(hwsq, 0x002504, 0x00000000); /* un-block fifo */
214 return 0;
215}
216
217static int
218nv50_ram_prog(struct nouveau_fb *pfb)
219{
220 struct nouveau_device *device = nv_device(pfb);
221 struct nv50_ram *ram = (void *)pfb->ram;
222 struct nv50_ramseq *hwsq = &ram->hwsq;
223
224 ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
225 return 0;
226}
227
228static void
229nv50_ram_tidy(struct nouveau_fb *pfb)
230{
231 struct nv50_ram *ram = (void *)pfb->ram;
232 struct nv50_ramseq *hwsq = &ram->hwsq;
233 ram_exec(hwsq, false);
234}
235
34void 236void
35__nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem) 237__nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem)
36{ 238{
@@ -218,13 +420,54 @@ nv50_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
218 struct nouveau_object **pobject) 420 struct nouveau_object **pobject)
219{ 421{
220 struct nv50_ram *ram; 422 struct nv50_ram *ram;
221 int ret; 423 int ret, i;
222 424
223 ret = nv50_ram_create(parent, engine, oclass, &ram); 425 ret = nv50_ram_create(parent, engine, oclass, &ram);
224 *pobject = nv_object(ram); 426 *pobject = nv_object(ram);
225 if (ret) 427 if (ret)
226 return ret; 428 return ret;
227 429
430 switch (ram->base.type) {
431 case NV_MEM_TYPE_DDR2:
432 case NV_MEM_TYPE_GDDR3:
433 ram->base.calc = nv50_ram_calc;
434 ram->base.prog = nv50_ram_prog;
435 ram->base.tidy = nv50_ram_tidy;
436 break;
437 default:
438 nv_warn(ram, "reclocking of this ram type unsupported\n");
439 return 0;
440 }
441
442 ram->hwsq.r_0x002504 = hwsq_reg(0x002504);
443 ram->hwsq.r_0x00c040 = hwsq_reg(0x00c040);
444 ram->hwsq.r_0x004008 = hwsq_reg(0x004008);
445 ram->hwsq.r_0x00400c = hwsq_reg(0x00400c);
446 ram->hwsq.r_0x100210 = hwsq_reg(0x100210);
447 ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0);
448 ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4);
449 ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc);
450 for (i = 0; i < 8; i++)
451 ram->hwsq.r_0x100da0[i] = hwsq_reg(0x100da0 + (i * 0x04));
452 ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20);
453 ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24);
454 ram->hwsq.r_0x611200 = hwsq_reg(0x611200);
455
456 for (i = 0; i < 9; i++)
457 ram->hwsq.r_timing[i] = hwsq_reg(0x100220 + (i * 0x04));
458
459 if (ram->base.ranks > 1) {
460 ram->hwsq.r_mr[0] = hwsq_reg2(0x1002c0, 0x1002c8);
461 ram->hwsq.r_mr[1] = hwsq_reg2(0x1002c4, 0x1002cc);
462 ram->hwsq.r_mr[2] = hwsq_reg2(0x1002e0, 0x1002e8);
463 ram->hwsq.r_mr[3] = hwsq_reg2(0x1002e4, 0x1002ec);
464 } else {
465 ram->hwsq.r_mr[0] = hwsq_reg(0x1002c0);
466 ram->hwsq.r_mr[1] = hwsq_reg(0x1002c4);
467 ram->hwsq.r_mr[2] = hwsq_reg(0x1002e0);
468 ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4);
469 }
470
228 return 0; 471 return 0;
229} 472}
230 473
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
index b40b79370823..f6292cd9207c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
@@ -22,25 +22,417 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/pll.h>
28#include <subdev/bios/rammap.h>
29#include <subdev/bios/timing.h>
30
31#include <subdev/clock/nva3.h>
32#include <subdev/clock/pll.h>
33
34#include <core/option.h>
35
36#include "ramfuc.h"
37
25#include "nv50.h" 38#include "nv50.h"
26 39
40struct nva3_ramfuc {
41 struct ramfuc base;
42 struct ramfuc_reg r_0x004000;
43 struct ramfuc_reg r_0x004004;
44 struct ramfuc_reg r_0x004018;
45 struct ramfuc_reg r_0x004128;
46 struct ramfuc_reg r_0x004168;
47 struct ramfuc_reg r_0x100200;
48 struct ramfuc_reg r_0x100210;
49 struct ramfuc_reg r_0x100220[9];
50 struct ramfuc_reg r_0x1002d0;
51 struct ramfuc_reg r_0x1002d4;
52 struct ramfuc_reg r_0x1002dc;
53 struct ramfuc_reg r_0x10053c;
54 struct ramfuc_reg r_0x1005a0;
55 struct ramfuc_reg r_0x1005a4;
56 struct ramfuc_reg r_0x100714;
57 struct ramfuc_reg r_0x100718;
58 struct ramfuc_reg r_0x10071c;
59 struct ramfuc_reg r_0x100760;
60 struct ramfuc_reg r_0x1007a0;
61 struct ramfuc_reg r_0x1007e0;
62 struct ramfuc_reg r_0x10f804;
63 struct ramfuc_reg r_0x1110e0;
64 struct ramfuc_reg r_0x111100;
65 struct ramfuc_reg r_0x111104;
66 struct ramfuc_reg r_0x611200;
67 struct ramfuc_reg r_mr[4];
68};
69
27struct nva3_ram { 70struct nva3_ram {
28 struct nouveau_ram base; 71 struct nouveau_ram base;
72 struct nva3_ramfuc fuc;
29}; 73};
30 74
31static int 75static int
76nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
77{
78 struct nouveau_bios *bios = nouveau_bios(pfb);
79 struct nva3_ram *ram = (void *)pfb->ram;
80 struct nva3_ramfuc *fuc = &ram->fuc;
81 struct nva3_clock_info mclk;
82 struct bit_entry M;
83 u8 ver, cnt, strap;
84 u32 data;
85 struct {
86 u32 data;
87 u8 size;
88 } rammap, ramcfg, timing;
89 u32 r004018, r100760, ctrl;
90 u32 unk714, unk718, unk71c;
91 int ret;
92
93 /* lookup memory config data relevant to the target frequency */
94 rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size,
95 &cnt, &ramcfg.size);
96 if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
97 nv_error(pfb, "invalid/missing rammap entry\n");
98 return -EINVAL;
99 }
100
101 /* locate specific data set for the attached memory */
102 if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
103 nv_error(pfb, "invalid/missing memory table\n");
104 return -EINVAL;
105 }
106
107 strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
108 data = nv_ro16(bios, M.offset + 1);
109 if (data)
110 strap = nv_ro08(bios, data + strap);
111
112 if (strap >= cnt) {
113 nv_error(pfb, "invalid ramcfg strap\n");
114 return -EINVAL;
115 }
116
117 ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
118 if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
119 nv_error(pfb, "invalid/missing ramcfg entry\n");
120 return -EINVAL;
121 }
122
123 /* lookup memory timings, if bios says they're present */
124 strap = nv_ro08(bios, ramcfg.data + 0x01);
125 if (strap != 0xff) {
126 timing.data = nvbios_timing_entry(bios, strap, &ver,
127 &timing.size);
128 if (!timing.data || ver != 0x10 || timing.size < 0x19) {
129 nv_error(pfb, "invalid/missing timing entry\n");
130 return -EINVAL;
131 }
132 } else {
133 timing.data = 0;
134 }
135
136 ret = nva3_clock_info(nouveau_clock(pfb), 0x12, 0x4000, freq, &mclk);
137 if (ret < 0) {
138 nv_error(pfb, "failed mclk calculation\n");
139 return ret;
140 }
141
142 ret = ram_init(fuc, pfb);
143 if (ret)
144 return ret;
145
146 /* XXX: where the fuck does 750MHz come from? */
147 if (freq <= 750000) {
148 r004018 = 0x10000000;
149 r100760 = 0x22222222;
150 } else {
151 r004018 = 0x00000000;
152 r100760 = 0x00000000;
153 }
154
155 ctrl = ram_rd32(fuc, 0x004000);
156 if (ctrl & 0x00000008) {
157 if (mclk.pll) {
158 ram_mask(fuc, 0x004128, 0x00000101, 0x00000101);
159 ram_wr32(fuc, 0x004004, mclk.pll);
160 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001));
161 ram_wr32(fuc, 0x004000, (ctrl &= 0xffffffef));
162 ram_wait(fuc, 0x004000, 0x00020000, 0x00020000, 64000);
163 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000010));
164 ram_wr32(fuc, 0x004018, 0x00005000 | r004018);
165 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000004));
166 }
167 } else {
168 u32 ssel = 0x00000101;
169 if (mclk.clk)
170 ssel |= mclk.clk;
171 else
172 ssel |= 0x00080000; /* 324MHz, shouldn't matter... */
173 ram_mask(fuc, 0x004168, 0x003f3141, ctrl);
174 }
175
176 if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) {
177 ram_mask(fuc, 0x111104, 0x00000600, 0x00000000);
178 } else {
179 ram_mask(fuc, 0x111100, 0x40000000, 0x40000000);
180 ram_mask(fuc, 0x111104, 0x00000180, 0x00000000);
181 }
182
183 if (!(nv_ro08(bios, rammap.data + 0x04) & 0x02))
184 ram_mask(fuc, 0x100200, 0x00000800, 0x00000000);
185 ram_wr32(fuc, 0x611200, 0x00003300);
186 if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x10))
187 ram_wr32(fuc, 0x111100, 0x4c020000); /*XXX*/
188
189 ram_wr32(fuc, 0x1002d4, 0x00000001);
190 ram_wr32(fuc, 0x1002d0, 0x00000001);
191 ram_wr32(fuc, 0x1002d0, 0x00000001);
192 ram_wr32(fuc, 0x100210, 0x00000000);
193 ram_wr32(fuc, 0x1002dc, 0x00000001);
194 ram_nsec(fuc, 2000);
195
196 ctrl = ram_rd32(fuc, 0x004000);
197 if (!(ctrl & 0x00000008) && mclk.pll) {
198 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008));
199 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
200 ram_wr32(fuc, 0x004018, 0x00001000);
201 ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000001));
202 ram_wr32(fuc, 0x004004, mclk.pll);
203 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001));
204 udelay(64);
205 ram_wr32(fuc, 0x004018, 0x00005000 | r004018);
206 udelay(20);
207 } else
208 if (!mclk.pll) {
209 ram_mask(fuc, 0x004168, 0x003f3040, mclk.clk);
210 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008));
211 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
212 ram_wr32(fuc, 0x004018, 0x0000d000 | r004018);
213 }
214
215 if ( (nv_ro08(bios, rammap.data + 0x04) & 0x08)) {
216 u32 unk5a0 = (nv_ro16(bios, ramcfg.data + 0x05) << 8) |
217 nv_ro08(bios, ramcfg.data + 0x05);
218 u32 unk5a4 = (nv_ro16(bios, ramcfg.data + 0x07));
219 u32 unk804 = (nv_ro08(bios, ramcfg.data + 0x09) & 0xf0) << 16 |
220 (nv_ro08(bios, ramcfg.data + 0x03) & 0x0f) << 16 |
221 (nv_ro08(bios, ramcfg.data + 0x09) & 0x0f) |
222 0x80000000;
223 ram_wr32(fuc, 0x1005a0, unk5a0);
224 ram_wr32(fuc, 0x1005a4, unk5a4);
225 ram_wr32(fuc, 0x10f804, unk804);
226 ram_mask(fuc, 0x10053c, 0x00001000, 0x00000000);
227 } else {
228 ram_mask(fuc, 0x10053c, 0x00001000, 0x00001000);
229 ram_mask(fuc, 0x10f804, 0x80000000, 0x00000000);
230 ram_mask(fuc, 0x100760, 0x22222222, r100760);
231 ram_mask(fuc, 0x1007a0, 0x22222222, r100760);
232 ram_mask(fuc, 0x1007e0, 0x22222222, r100760);
233 }
234
235 if (mclk.pll) {
236 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00011000);
237 ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000008));
238 }
239
240 /*XXX: LEAVE */
241 ram_wr32(fuc, 0x1002dc, 0x00000000);
242 ram_wr32(fuc, 0x1002d4, 0x00000001);
243 ram_wr32(fuc, 0x100210, 0x80000000);
244 ram_nsec(fuc, 1000);
245 ram_nsec(fuc, 1000);
246
247 ram_mask(fuc, mr[2], 0x00000000, 0x00000000);
248 ram_nsec(fuc, 1000);
249 ram_nuke(fuc, mr[0]);
250 ram_mask(fuc, mr[0], 0x00000000, 0x00000000);
251 ram_nsec(fuc, 1000);
252
253 ram_mask(fuc, 0x100220[3], 0x00000000, 0x00000000);
254 ram_mask(fuc, 0x100220[1], 0x00000000, 0x00000000);
255 ram_mask(fuc, 0x100220[6], 0x00000000, 0x00000000);
256 ram_mask(fuc, 0x100220[7], 0x00000000, 0x00000000);
257 ram_mask(fuc, 0x100220[2], 0x00000000, 0x00000000);
258 ram_mask(fuc, 0x100220[4], 0x00000000, 0x00000000);
259 ram_mask(fuc, 0x100220[5], 0x00000000, 0x00000000);
260 ram_mask(fuc, 0x100220[0], 0x00000000, 0x00000000);
261 ram_mask(fuc, 0x100220[8], 0x00000000, 0x00000000);
262
263 data = (nv_ro08(bios, ramcfg.data + 0x02) & 0x08) ? 0x00000000 : 0x00001000;
264 ram_mask(fuc, 0x100200, 0x00001000, data);
265
266 unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000010;
267 unk718 = ram_rd32(fuc, 0x100718) & ~0x00000100;
268 unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100;
269 if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x20))
270 unk714 |= 0xf0000000;
271 if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x04))
272 unk714 |= 0x00000010;
273 ram_wr32(fuc, 0x100714, unk714);
274
275 if (nv_ro08(bios, ramcfg.data + 0x02) & 0x01)
276 unk71c |= 0x00000100;
277 ram_wr32(fuc, 0x10071c, unk71c);
278
279 if (nv_ro08(bios, ramcfg.data + 0x02) & 0x02)
280 unk718 |= 0x00000100;
281 ram_wr32(fuc, 0x100718, unk718);
282
283 if (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)
284 ram_wr32(fuc, 0x111100, 0x48000000); /*XXX*/
285
286 ram_mask(fuc, mr[0], 0x100, 0x100);
287 ram_nsec(fuc, 1000);
288 ram_mask(fuc, mr[0], 0x100, 0x000);
289 ram_nsec(fuc, 1000);
290
291 ram_nsec(fuc, 2000);
292 ram_nsec(fuc, 12000);
293
294 ram_wr32(fuc, 0x611200, 0x00003330);
295 if ( (nv_ro08(bios, rammap.data + 0x04) & 0x02))
296 ram_mask(fuc, 0x100200, 0x00000800, 0x00000800);
297 if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) {
298 ram_mask(fuc, 0x111104, 0x00000180, 0x00000180);
299 ram_mask(fuc, 0x111100, 0x40000000, 0x00000000);
300 } else {
301 ram_mask(fuc, 0x111104, 0x00000600, 0x00000600);
302 }
303
304 if (mclk.pll) {
305 ram_mask(fuc, 0x004168, 0x00000001, 0x00000000);
306 ram_mask(fuc, 0x004168, 0x00000100, 0x00000000);
307 } else {
308 ram_mask(fuc, 0x004000, 0x00000001, 0x00000000);
309 ram_mask(fuc, 0x004128, 0x00000001, 0x00000000);
310 ram_mask(fuc, 0x004128, 0x00000100, 0x00000000);
311 }
312
313 return 0;
314}
315
316static int
317nva3_ram_prog(struct nouveau_fb *pfb)
318{
319 struct nouveau_device *device = nv_device(pfb);
320 struct nva3_ram *ram = (void *)pfb->ram;
321 struct nva3_ramfuc *fuc = &ram->fuc;
322 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
323 return 0;
324}
325
326static void
327nva3_ram_tidy(struct nouveau_fb *pfb)
328{
329 struct nva3_ram *ram = (void *)pfb->ram;
330 struct nva3_ramfuc *fuc = &ram->fuc;
331 ram_exec(fuc, false);
332}
333
334static int
335nva3_ram_init(struct nouveau_object *object)
336{
337 struct nouveau_fb *pfb = (void *)object->parent;
338 struct nva3_ram *ram = (void *)object;
339 int ret, i;
340
341 ret = nouveau_ram_init(&ram->base);
342 if (ret)
343 return ret;
344
345 /* prepare for ddr link training, and load training patterns */
346 switch (ram->base.type) {
347 case NV_MEM_TYPE_DDR3: {
348 static const u32 pattern[16] = {
349 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee,
350 0x00000000, 0x11111111, 0x44444444, 0xdddddddd,
351 0x33333333, 0x55555555, 0x77777777, 0x66666666,
352 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb,
353 };
354
355 nv_wr32(pfb, 0x100538, 0x10001ff6); /*XXX*/
356 nv_wr32(pfb, 0x1005a8, 0x0000ffff);
357 nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001);
358 for (i = 0; i < 0x30; i++) {
359 nv_wr32(pfb, 0x10f8c0, (i << 8) | i);
360 nv_wr32(pfb, 0x10f8e0, (i << 8) | i);
361 nv_wr32(pfb, 0x10f900, pattern[i % 16]);
362 nv_wr32(pfb, 0x10f920, pattern[i % 16]);
363 }
364 }
365 break;
366 default:
367 break;
368 }
369
370 return 0;
371}
372
373static int
32nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 374nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
33 struct nouveau_oclass *oclass, void *data, u32 datasize, 375 struct nouveau_oclass *oclass, void *data, u32 datasize,
34 struct nouveau_object **pobject) 376 struct nouveau_object **pobject)
35{ 377{
36 struct nva3_ram *ram; 378 struct nva3_ram *ram;
37 int ret; 379 int ret, i;
38 380
39 ret = nv50_ram_create(parent, engine, oclass, &ram); 381 ret = nv50_ram_create(parent, engine, oclass, &ram);
40 *pobject = nv_object(ram); 382 *pobject = nv_object(ram);
41 if (ret) 383 if (ret)
42 return ret; 384 return ret;
43 385
386 switch (ram->base.type) {
387 case NV_MEM_TYPE_DDR3:
388 ram->base.calc = nva3_ram_calc;
389 ram->base.prog = nva3_ram_prog;
390 ram->base.tidy = nva3_ram_tidy;
391 break;
392 default:
393 nv_warn(ram, "reclocking of this ram type unsupported\n");
394 return 0;
395 }
396
397 ram->fuc.r_0x004000 = ramfuc_reg(0x004000);
398 ram->fuc.r_0x004004 = ramfuc_reg(0x004004);
399 ram->fuc.r_0x004018 = ramfuc_reg(0x004018);
400 ram->fuc.r_0x004128 = ramfuc_reg(0x004128);
401 ram->fuc.r_0x004168 = ramfuc_reg(0x004168);
402 ram->fuc.r_0x100200 = ramfuc_reg(0x100200);
403 ram->fuc.r_0x100210 = ramfuc_reg(0x100210);
404 for (i = 0; i < 9; i++)
405 ram->fuc.r_0x100220[i] = ramfuc_reg(0x100220 + (i * 4));
406 ram->fuc.r_0x1002d0 = ramfuc_reg(0x1002d0);
407 ram->fuc.r_0x1002d4 = ramfuc_reg(0x1002d4);
408 ram->fuc.r_0x1002dc = ramfuc_reg(0x1002dc);
409 ram->fuc.r_0x10053c = ramfuc_reg(0x10053c);
410 ram->fuc.r_0x1005a0 = ramfuc_reg(0x1005a0);
411 ram->fuc.r_0x1005a4 = ramfuc_reg(0x1005a4);
412 ram->fuc.r_0x100714 = ramfuc_reg(0x100714);
413 ram->fuc.r_0x100718 = ramfuc_reg(0x100718);
414 ram->fuc.r_0x10071c = ramfuc_reg(0x10071c);
415 ram->fuc.r_0x100760 = ramfuc_reg(0x100760);
416 ram->fuc.r_0x1007a0 = ramfuc_reg(0x1007a0);
417 ram->fuc.r_0x1007e0 = ramfuc_reg(0x1007e0);
418 ram->fuc.r_0x10f804 = ramfuc_reg(0x10f804);
419 ram->fuc.r_0x1110e0 = ramfuc_reg(0x1110e0);
420 ram->fuc.r_0x111100 = ramfuc_reg(0x111100);
421 ram->fuc.r_0x111104 = ramfuc_reg(0x111104);
422 ram->fuc.r_0x611200 = ramfuc_reg(0x611200);
423
424 if (ram->base.ranks > 1) {
425 ram->fuc.r_mr[0] = ramfuc_reg2(0x1002c0, 0x1002c8);
426 ram->fuc.r_mr[1] = ramfuc_reg2(0x1002c4, 0x1002cc);
427 ram->fuc.r_mr[2] = ramfuc_reg2(0x1002e0, 0x1002e8);
428 ram->fuc.r_mr[3] = ramfuc_reg2(0x1002e4, 0x1002ec);
429 } else {
430 ram->fuc.r_mr[0] = ramfuc_reg(0x1002c0);
431 ram->fuc.r_mr[1] = ramfuc_reg(0x1002c4);
432 ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0);
433 ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4);
434 }
435
44 return 0; 436 return 0;
45} 437}
46 438
@@ -49,7 +441,7 @@ nva3_ram_oclass = {
49 .ofuncs = &(struct nouveau_ofuncs) { 441 .ofuncs = &(struct nouveau_ofuncs) {
50 .ctor = nva3_ram_ctor, 442 .ctor = nva3_ram_ctor,
51 .dtor = _nouveau_ram_dtor, 443 .dtor = _nouveau_ram_dtor,
52 .init = _nouveau_ram_init, 444 .init = nva3_ram_init,
53 .fini = _nouveau_ram_fini, 445 .fini = _nouveau_ram_fini,
54 }, 446 },
55}; 447};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
index f81afb83a163..f464547c6bab 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
@@ -23,10 +23,414 @@
23 */ 23 */
24 24
25#include <subdev/bios.h> 25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/pll.h>
28#include <subdev/bios/rammap.h>
29#include <subdev/bios/timing.h>
26#include <subdev/ltcg.h> 30#include <subdev/ltcg.h>
27 31
28#include "priv.h" 32#include <subdev/clock.h>
29#include "nv50.h" 33#include <subdev/clock/pll.h>
34
35#include <core/option.h>
36
37#include "ramfuc.h"
38
39#include "nvc0.h"
40
41struct nvc0_ramfuc {
42 struct ramfuc base;
43
44 struct ramfuc_reg r_0x10fe20;
45 struct ramfuc_reg r_0x10fe24;
46 struct ramfuc_reg r_0x137320;
47 struct ramfuc_reg r_0x137330;
48
49 struct ramfuc_reg r_0x132000;
50 struct ramfuc_reg r_0x132004;
51 struct ramfuc_reg r_0x132100;
52
53 struct ramfuc_reg r_0x137390;
54
55 struct ramfuc_reg r_0x10f290;
56 struct ramfuc_reg r_0x10f294;
57 struct ramfuc_reg r_0x10f298;
58 struct ramfuc_reg r_0x10f29c;
59 struct ramfuc_reg r_0x10f2a0;
60
61 struct ramfuc_reg r_0x10f300;
62 struct ramfuc_reg r_0x10f338;
63 struct ramfuc_reg r_0x10f340;
64 struct ramfuc_reg r_0x10f344;
65 struct ramfuc_reg r_0x10f348;
66
67 struct ramfuc_reg r_0x10f910;
68 struct ramfuc_reg r_0x10f914;
69
70 struct ramfuc_reg r_0x100b0c;
71 struct ramfuc_reg r_0x10f050;
72 struct ramfuc_reg r_0x10f090;
73 struct ramfuc_reg r_0x10f200;
74 struct ramfuc_reg r_0x10f210;
75 struct ramfuc_reg r_0x10f310;
76 struct ramfuc_reg r_0x10f314;
77 struct ramfuc_reg r_0x10f610;
78 struct ramfuc_reg r_0x10f614;
79 struct ramfuc_reg r_0x10f800;
80 struct ramfuc_reg r_0x10f808;
81 struct ramfuc_reg r_0x10f824;
82 struct ramfuc_reg r_0x10f830;
83 struct ramfuc_reg r_0x10f988;
84 struct ramfuc_reg r_0x10f98c;
85 struct ramfuc_reg r_0x10f990;
86 struct ramfuc_reg r_0x10f998;
87 struct ramfuc_reg r_0x10f9b0;
88 struct ramfuc_reg r_0x10f9b4;
89 struct ramfuc_reg r_0x10fb04;
90 struct ramfuc_reg r_0x10fb08;
91 struct ramfuc_reg r_0x137300;
92 struct ramfuc_reg r_0x137310;
93 struct ramfuc_reg r_0x137360;
94 struct ramfuc_reg r_0x1373ec;
95 struct ramfuc_reg r_0x1373f0;
96 struct ramfuc_reg r_0x1373f8;
97
98 struct ramfuc_reg r_0x61c140;
99 struct ramfuc_reg r_0x611200;
100
101 struct ramfuc_reg r_0x13d8f4;
102};
103
104struct nvc0_ram {
105 struct nouveau_ram base;
106 struct nvc0_ramfuc fuc;
107 struct nvbios_pll refpll;
108 struct nvbios_pll mempll;
109};
110
111static void
112nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic)
113{
114 struct nvc0_ram *ram = container_of(fuc, typeof(*ram), fuc);
115 struct nouveau_fb *pfb = nouveau_fb(ram);
116 u32 part = nv_rd32(pfb, 0x022438), i;
117 u32 mask = nv_rd32(pfb, 0x022554);
118 u32 addr = 0x110974;
119
120 ram_wr32(fuc, 0x10f910, magic);
121 ram_wr32(fuc, 0x10f914, magic);
122
123 for (i = 0; (magic & 0x80000000) && i < part; addr += 0x1000, i++) {
124 if (mask & (1 << i))
125 continue;
126 ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
127 }
128}
129
130static int
131nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
132{
133 struct nouveau_clock *clk = nouveau_clock(pfb);
134 struct nouveau_bios *bios = nouveau_bios(pfb);
135 struct nvc0_ram *ram = (void *)pfb->ram;
136 struct nvc0_ramfuc *fuc = &ram->fuc;
137 struct bit_entry M;
138 u8 ver, cnt, strap;
139 u32 data;
140 struct {
141 u32 data;
142 u8 size;
143 } rammap, ramcfg, timing;
144 int ref, div, out;
145 int from, mode;
146 int N1, M1, P;
147 int ret;
148
149 /* lookup memory config data relevant to the target frequency */
150 rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size,
151 &cnt, &ramcfg.size);
152 if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
153 nv_error(pfb, "invalid/missing rammap entry\n");
154 return -EINVAL;
155 }
156
157 /* locate specific data set for the attached memory */
158 if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
159 nv_error(pfb, "invalid/missing memory table\n");
160 return -EINVAL;
161 }
162
163 strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
164 data = nv_ro16(bios, M.offset + 1);
165 if (data)
166 strap = nv_ro08(bios, data + strap);
167
168 if (strap >= cnt) {
169 nv_error(pfb, "invalid ramcfg strap\n");
170 return -EINVAL;
171 }
172
173 ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
174 if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
175 nv_error(pfb, "invalid/missing ramcfg entry\n");
176 return -EINVAL;
177 }
178
179 /* lookup memory timings, if bios says they're present */
180 strap = nv_ro08(bios, ramcfg.data + 0x01);
181 if (strap != 0xff) {
182 timing.data = nvbios_timing_entry(bios, strap, &ver,
183 &timing.size);
184 if (!timing.data || ver != 0x10 || timing.size < 0x19) {
185 nv_error(pfb, "invalid/missing timing entry\n");
186 return -EINVAL;
187 }
188 } else {
189 timing.data = 0;
190 }
191
192 ret = ram_init(fuc, pfb);
193 if (ret)
194 return ret;
195
196 /* determine current mclk configuration */
197 from = !!(ram_rd32(fuc, 0x1373f0) & 0x00000002); /*XXX: ok? */
198
199 /* determine target mclk configuration */
200 if (!(ram_rd32(fuc, 0x137300) & 0x00000100))
201 ref = clk->read(clk, nv_clk_src_sppll0);
202 else
203 ref = clk->read(clk, nv_clk_src_sppll1);
204 div = max(min((ref * 2) / freq, (u32)65), (u32)2) - 2;
205 out = (ref * 2) / (div + 2);
206 mode = freq != out;
207
208 ram_mask(fuc, 0x137360, 0x00000002, 0x00000000);
209
210 if ((ram_rd32(fuc, 0x132000) & 0x00000002) || 0 /*XXX*/) {
211 ram_nuke(fuc, 0x132000);
212 ram_mask(fuc, 0x132000, 0x00000002, 0x00000002);
213 ram_mask(fuc, 0x132000, 0x00000002, 0x00000000);
214 }
215
216 if (mode == 1) {
217 ram_nuke(fuc, 0x10fe20);
218 ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000002);
219 ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000000);
220 }
221
222// 0x00020034 // 0x0000000a
223 ram_wr32(fuc, 0x132100, 0x00000001);
224
225 if (mode == 1 && from == 0) {
226 /* calculate refpll */
227 ret = nva3_pll_calc(nv_subdev(pfb), &ram->refpll,
228 ram->mempll.refclk, &N1, NULL, &M1, &P);
229 if (ret <= 0) {
230 nv_error(pfb, "unable to calc refpll\n");
231 return ret ? ret : -ERANGE;
232 }
233
234 ram_wr32(fuc, 0x10fe20, 0x20010000);
235 ram_wr32(fuc, 0x137320, 0x00000003);
236 ram_wr32(fuc, 0x137330, 0x81200006);
237 ram_wr32(fuc, 0x10fe24, (P << 16) | (N1 << 8) | M1);
238 ram_wr32(fuc, 0x10fe20, 0x20010001);
239 ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
240
241 /* calculate mempll */
242 ret = nva3_pll_calc(nv_subdev(pfb), &ram->mempll, freq,
243 &N1, NULL, &M1, &P);
244 if (ret <= 0) {
245 nv_error(pfb, "unable to calc refpll\n");
246 return ret ? ret : -ERANGE;
247 }
248
249 ram_wr32(fuc, 0x10fe20, 0x20010005);
250 ram_wr32(fuc, 0x132004, (P << 16) | (N1 << 8) | M1);
251 ram_wr32(fuc, 0x132000, 0x18010101);
252 ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
253 } else
254 if (mode == 0) {
255 ram_wr32(fuc, 0x137300, 0x00000003);
256 }
257
258 if (from == 0) {
259 ram_nuke(fuc, 0x10fb04);
260 ram_mask(fuc, 0x10fb04, 0x0000ffff, 0x00000000);
261 ram_nuke(fuc, 0x10fb08);
262 ram_mask(fuc, 0x10fb08, 0x0000ffff, 0x00000000);
263 ram_wr32(fuc, 0x10f988, 0x2004ff00);
264 ram_wr32(fuc, 0x10f98c, 0x003fc040);
265 ram_wr32(fuc, 0x10f990, 0x20012001);
266 ram_wr32(fuc, 0x10f998, 0x00011a00);
267 ram_wr32(fuc, 0x13d8f4, 0x00000000);
268 } else {
269 ram_wr32(fuc, 0x10f988, 0x20010000);
270 ram_wr32(fuc, 0x10f98c, 0x00000000);
271 ram_wr32(fuc, 0x10f990, 0x20012001);
272 ram_wr32(fuc, 0x10f998, 0x00010a00);
273 }
274
275 if (from == 0) {
276// 0x00020039 // 0x000000ba
277 }
278
279// 0x0002003a // 0x00000002
280 ram_wr32(fuc, 0x100b0c, 0x00080012);
281// 0x00030014 // 0x00000000 // 0x02b5f070
282// 0x00030014 // 0x00010000 // 0x02b5f070
283 ram_wr32(fuc, 0x611200, 0x00003300);
284// 0x00020034 // 0x0000000a
285// 0x00030020 // 0x00000001 // 0x00000000
286
287 ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
288 ram_wr32(fuc, 0x10f210, 0x00000000);
289 ram_nsec(fuc, 1000);
290 if (mode == 0)
291 nvc0_ram_train(fuc, 0x000c1001);
292 ram_wr32(fuc, 0x10f310, 0x00000001);
293 ram_nsec(fuc, 1000);
294 ram_wr32(fuc, 0x10f090, 0x00000061);
295 ram_wr32(fuc, 0x10f090, 0xc000007f);
296 ram_nsec(fuc, 1000);
297
298 if (from == 0) {
299 ram_wr32(fuc, 0x10f824, 0x00007fd4);
300 } else {
301 ram_wr32(fuc, 0x1373ec, 0x00020404);
302 }
303
304 if (mode == 0) {
305 ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
306 ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000);
307 ram_wr32(fuc, 0x10f830, 0x41500010);
308 ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
309 ram_mask(fuc, 0x132100, 0x00000100, 0x00000100);
310 ram_wr32(fuc, 0x10f050, 0xff000090);
311 ram_wr32(fuc, 0x1373ec, 0x00020f0f);
312 ram_wr32(fuc, 0x1373f0, 0x00000003);
313 ram_wr32(fuc, 0x137310, 0x81201616);
314 ram_wr32(fuc, 0x132100, 0x00000001);
315// 0x00020039 // 0x000000ba
316 ram_wr32(fuc, 0x10f830, 0x00300017);
317 ram_wr32(fuc, 0x1373f0, 0x00000001);
318 ram_wr32(fuc, 0x10f824, 0x00007e77);
319 ram_wr32(fuc, 0x132000, 0x18030001);
320 ram_wr32(fuc, 0x10f090, 0x4000007e);
321 ram_nsec(fuc, 2000);
322 ram_wr32(fuc, 0x10f314, 0x00000001);
323 ram_wr32(fuc, 0x10f210, 0x80000000);
324 ram_wr32(fuc, 0x10f338, 0x00300220);
325 ram_wr32(fuc, 0x10f300, 0x0000011d);
326 ram_nsec(fuc, 1000);
327 ram_wr32(fuc, 0x10f290, 0x02060505);
328 ram_wr32(fuc, 0x10f294, 0x34208288);
329 ram_wr32(fuc, 0x10f298, 0x44050411);
330 ram_wr32(fuc, 0x10f29c, 0x0000114c);
331 ram_wr32(fuc, 0x10f2a0, 0x42e10069);
332 ram_wr32(fuc, 0x10f614, 0x40044f77);
333 ram_wr32(fuc, 0x10f610, 0x40044f77);
334 ram_wr32(fuc, 0x10f344, 0x00600009);
335 ram_nsec(fuc, 1000);
336 ram_wr32(fuc, 0x10f348, 0x00700008);
337 ram_wr32(fuc, 0x61c140, 0x19240000);
338 ram_wr32(fuc, 0x10f830, 0x00300017);
339 nvc0_ram_train(fuc, 0x80021001);
340 nvc0_ram_train(fuc, 0x80081001);
341 ram_wr32(fuc, 0x10f340, 0x00500004);
342 ram_nsec(fuc, 1000);
343 ram_wr32(fuc, 0x10f830, 0x01300017);
344 ram_wr32(fuc, 0x10f830, 0x00300017);
345// 0x00030020 // 0x00000000 // 0x00000000
346// 0x00020034 // 0x0000000b
347 ram_wr32(fuc, 0x100b0c, 0x00080028);
348 ram_wr32(fuc, 0x611200, 0x00003330);
349 } else {
350 ram_wr32(fuc, 0x10f800, 0x00001800);
351 ram_wr32(fuc, 0x13d8f4, 0x00000000);
352 ram_wr32(fuc, 0x1373ec, 0x00020404);
353 ram_wr32(fuc, 0x1373f0, 0x00000003);
354 ram_wr32(fuc, 0x10f830, 0x40700010);
355 ram_wr32(fuc, 0x10f830, 0x40500010);
356 ram_wr32(fuc, 0x13d8f4, 0x00000000);
357 ram_wr32(fuc, 0x1373f8, 0x00000000);
358 ram_wr32(fuc, 0x132100, 0x00000101);
359 ram_wr32(fuc, 0x137310, 0x89201616);
360 ram_wr32(fuc, 0x10f050, 0xff000090);
361 ram_wr32(fuc, 0x1373ec, 0x00030404);
362 ram_wr32(fuc, 0x1373f0, 0x00000002);
363 // 0x00020039 // 0x00000011
364 ram_wr32(fuc, 0x132100, 0x00000001);
365 ram_wr32(fuc, 0x1373f8, 0x00002000);
366 ram_nsec(fuc, 2000);
367 ram_wr32(fuc, 0x10f808, 0x7aaa0050);
368 ram_wr32(fuc, 0x10f830, 0x00500010);
369 ram_wr32(fuc, 0x10f200, 0x00ce1000);
370 ram_wr32(fuc, 0x10f090, 0x4000007e);
371 ram_nsec(fuc, 2000);
372 ram_wr32(fuc, 0x10f314, 0x00000001);
373 ram_wr32(fuc, 0x10f210, 0x80000000);
374 ram_wr32(fuc, 0x10f338, 0x00300200);
375 ram_wr32(fuc, 0x10f300, 0x0000084d);
376 ram_nsec(fuc, 1000);
377 ram_wr32(fuc, 0x10f290, 0x0b343825);
378 ram_wr32(fuc, 0x10f294, 0x3483028e);
379 ram_wr32(fuc, 0x10f298, 0x440c0600);
380 ram_wr32(fuc, 0x10f29c, 0x0000214c);
381 ram_wr32(fuc, 0x10f2a0, 0x42e20069);
382 ram_wr32(fuc, 0x10f200, 0x00ce0000);
383 ram_wr32(fuc, 0x10f614, 0x60044e77);
384 ram_wr32(fuc, 0x10f610, 0x60044e77);
385 ram_wr32(fuc, 0x10f340, 0x00500000);
386 ram_nsec(fuc, 1000);
387 ram_wr32(fuc, 0x10f344, 0x00600228);
388 ram_nsec(fuc, 1000);
389 ram_wr32(fuc, 0x10f348, 0x00700000);
390 ram_wr32(fuc, 0x13d8f4, 0x00000000);
391 ram_wr32(fuc, 0x61c140, 0x09a40000);
392
393 nvc0_ram_train(fuc, 0x800e1008);
394
395 ram_nsec(fuc, 1000);
396 ram_wr32(fuc, 0x10f800, 0x00001804);
397 // 0x00030020 // 0x00000000 // 0x00000000
398 // 0x00020034 // 0x0000000b
399 ram_wr32(fuc, 0x13d8f4, 0x00000000);
400 ram_wr32(fuc, 0x100b0c, 0x00080028);
401 ram_wr32(fuc, 0x611200, 0x00003330);
402 ram_nsec(fuc, 100000);
403 ram_wr32(fuc, 0x10f9b0, 0x05313f41);
404 ram_wr32(fuc, 0x10f9b4, 0x00002f50);
405
406 nvc0_ram_train(fuc, 0x010c1001);
407 }
408
409 ram_mask(fuc, 0x10f200, 0x00000800, 0x00000800);
410// 0x00020016 // 0x00000000
411
412 if (mode == 0)
413 ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
414 return 0;
415}
416
417static int
418nvc0_ram_prog(struct nouveau_fb *pfb)
419{
420 struct nouveau_device *device = nv_device(pfb);
421 struct nvc0_ram *ram = (void *)pfb->ram;
422 struct nvc0_ramfuc *fuc = &ram->fuc;
423 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
424 return 0;
425}
426
427static void
428nvc0_ram_tidy(struct nouveau_fb *pfb)
429{
430 struct nvc0_ram *ram = (void *)pfb->ram;
431 struct nvc0_ramfuc *fuc = &ram->fuc;
432 ram_exec(fuc, false);
433}
30 434
31extern const u8 nvc0_pte_storage_type_map[256]; 435extern const u8 nvc0_pte_storage_type_map[256];
32 436
@@ -111,10 +515,9 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
111 return 0; 515 return 0;
112} 516}
113 517
114static int 518int
115nvc0_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, 519nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
116 struct nouveau_oclass *oclass, void *data, u32 size, 520 struct nouveau_oclass *oclass, int size, void **pobject)
117 struct nouveau_object **pobject)
118{ 521{
119 struct nouveau_fb *pfb = nouveau_fb(parent); 522 struct nouveau_fb *pfb = nouveau_fb(parent);
120 struct nouveau_bios *bios = nouveau_bios(pfb); 523 struct nouveau_bios *bios = nouveau_bios(pfb);
@@ -128,8 +531,8 @@ nvc0_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
128 bool uniform = true; 531 bool uniform = true;
129 int ret, part; 532 int ret, part;
130 533
131 ret = nouveau_ram_create(parent, engine, oclass, &ram); 534 ret = nouveau_ram_create_(parent, engine, oclass, size, pobject);
132 *pobject = nv_object(ram); 535 ram = *pobject;
133 if (ret) 536 if (ret)
134 return ret; 537 return ret;
135 538
@@ -183,13 +586,158 @@ nvc0_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
183 return 0; 586 return 0;
184} 587}
185 588
589static int
590nvc0_ram_init(struct nouveau_object *object)
591{
592 struct nouveau_fb *pfb = (void *)object->parent;
593 struct nvc0_ram *ram = (void *)object;
594 int ret, i;
595
596 ret = nouveau_ram_init(&ram->base);
597 if (ret)
598 return ret;
599
600 /* prepare for ddr link training, and load training patterns */
601 switch (ram->base.type) {
602 case NV_MEM_TYPE_GDDR5: {
603 static const u8 train0[] = {
604 0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
605 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
606 };
607 static const u32 train1[] = {
608 0x00000000, 0xffffffff,
609 0x55555555, 0xaaaaaaaa,
610 0x33333333, 0xcccccccc,
611 0xf0f0f0f0, 0x0f0f0f0f,
612 0x00ff00ff, 0xff00ff00,
613 0x0000ffff, 0xffff0000,
614 };
615
616 for (i = 0; i < 0x30; i++) {
617 nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8));
618 nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8));
619 nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]);
620 nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]);
621 nv_wr32(pfb, 0x10f918, train1[i % 12]);
622 nv_wr32(pfb, 0x10f91c, train1[i % 12]);
623 nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]);
624 nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]);
625 nv_wr32(pfb, 0x10f918, train1[i % 12]);
626 nv_wr32(pfb, 0x10f91c, train1[i % 12]);
627 }
628 } break;
629 default:
630 break;
631 }
632
633 return 0;
634}
635
636static int
637nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
638 struct nouveau_oclass *oclass, void *data, u32 size,
639 struct nouveau_object **pobject)
640{
641 struct nouveau_bios *bios = nouveau_bios(parent);
642 struct nvc0_ram *ram;
643 int ret;
644
645 ret = nvc0_ram_create(parent, engine, oclass, &ram);
646 *pobject = nv_object(ram);
647 if (ret)
648 return ret;
649
650 ret = nvbios_pll_parse(bios, 0x0c, &ram->refpll);
651 if (ret) {
652 nv_error(ram, "mclk refpll data not found\n");
653 return ret;
654 }
655
656 ret = nvbios_pll_parse(bios, 0x04, &ram->mempll);
657 if (ret) {
658 nv_error(ram, "mclk pll data not found\n");
659 return ret;
660 }
661
662 switch (ram->base.type) {
663 case NV_MEM_TYPE_GDDR5:
664 ram->base.calc = nvc0_ram_calc;
665 ram->base.prog = nvc0_ram_prog;
666 ram->base.tidy = nvc0_ram_tidy;
667 break;
668 default:
669 nv_warn(ram, "reclocking of this ram type unsupported\n");
670 return 0;
671 }
672
673 ram->fuc.r_0x10fe20 = ramfuc_reg(0x10fe20);
674 ram->fuc.r_0x10fe24 = ramfuc_reg(0x10fe24);
675 ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
676 ram->fuc.r_0x137330 = ramfuc_reg(0x137330);
677
678 ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
679 ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
680 ram->fuc.r_0x132100 = ramfuc_reg(0x132100);
681
682 ram->fuc.r_0x137390 = ramfuc_reg(0x137390);
683
684 ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
685 ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
686 ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
687 ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
688 ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
689
690 ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300);
691 ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338);
692 ram->fuc.r_0x10f340 = ramfuc_reg(0x10f340);
693 ram->fuc.r_0x10f344 = ramfuc_reg(0x10f344);
694 ram->fuc.r_0x10f348 = ramfuc_reg(0x10f348);
695
696 ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
697 ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
698
699 ram->fuc.r_0x100b0c = ramfuc_reg(0x100b0c);
700 ram->fuc.r_0x10f050 = ramfuc_reg(0x10f050);
701 ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
702 ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
703 ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
704 ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
705 ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
706 ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
707 ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
708 ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
709 ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
710 ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
711 ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
712 ram->fuc.r_0x10f988 = ramfuc_reg(0x10f988);
713 ram->fuc.r_0x10f98c = ramfuc_reg(0x10f98c);
714 ram->fuc.r_0x10f990 = ramfuc_reg(0x10f990);
715 ram->fuc.r_0x10f998 = ramfuc_reg(0x10f998);
716 ram->fuc.r_0x10f9b0 = ramfuc_reg(0x10f9b0);
717 ram->fuc.r_0x10f9b4 = ramfuc_reg(0x10f9b4);
718 ram->fuc.r_0x10fb04 = ramfuc_reg(0x10fb04);
719 ram->fuc.r_0x10fb08 = ramfuc_reg(0x10fb08);
720 ram->fuc.r_0x137310 = ramfuc_reg(0x137300);
721 ram->fuc.r_0x137310 = ramfuc_reg(0x137310);
722 ram->fuc.r_0x137360 = ramfuc_reg(0x137360);
723 ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
724 ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
725 ram->fuc.r_0x1373f8 = ramfuc_reg(0x1373f8);
726
727 ram->fuc.r_0x61c140 = ramfuc_reg(0x61c140);
728 ram->fuc.r_0x611200 = ramfuc_reg(0x611200);
729
730 ram->fuc.r_0x13d8f4 = ramfuc_reg(0x13d8f4);
731 return 0;
732}
733
186struct nouveau_oclass 734struct nouveau_oclass
187nvc0_ram_oclass = { 735nvc0_ram_oclass = {
188 .handle = 0, 736 .handle = 0,
189 .ofuncs = &(struct nouveau_ofuncs) { 737 .ofuncs = &(struct nouveau_ofuncs) {
190 .ctor = nvc0_ram_create, 738 .ctor = nvc0_ram_ctor,
191 .dtor = _nouveau_ram_dtor, 739 .dtor = _nouveau_ram_dtor,
192 .init = _nouveau_ram_init, 740 .init = nvc0_ram_init,
193 .fini = _nouveau_ram_fini, 741 .fini = _nouveau_ram_fini,
194 } 742 }
195}; 743};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
new file mode 100644
index 000000000000..bc86cfd084f6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
@@ -0,0 +1,1264 @@
1/*
2 * Copyright 2013 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <subdev/gpio.h>
26
27#include <subdev/bios.h>
28#include <subdev/bios/bit.h>
29#include <subdev/bios/pll.h>
30#include <subdev/bios/init.h>
31#include <subdev/bios/rammap.h>
32#include <subdev/bios/timing.h>
33
34#include <subdev/clock.h>
35#include <subdev/clock/pll.h>
36
37#include <subdev/timer.h>
38
39#include <core/option.h>
40
41#include "nvc0.h"
42
43#include "ramfuc.h"
44
45struct nve0_ramfuc {
46 struct ramfuc base;
47
48 struct nvbios_pll refpll;
49 struct nvbios_pll mempll;
50
51 struct ramfuc_reg r_gpioMV;
52 u32 r_funcMV[2];
53 struct ramfuc_reg r_gpio2E;
54 u32 r_func2E[2];
55 struct ramfuc_reg r_gpiotrig;
56
57 struct ramfuc_reg r_0x132020;
58 struct ramfuc_reg r_0x132028;
59 struct ramfuc_reg r_0x132024;
60 struct ramfuc_reg r_0x132030;
61 struct ramfuc_reg r_0x132034;
62 struct ramfuc_reg r_0x132000;
63 struct ramfuc_reg r_0x132004;
64 struct ramfuc_reg r_0x132040;
65
66 struct ramfuc_reg r_0x10f248;
67 struct ramfuc_reg r_0x10f290;
68 struct ramfuc_reg r_0x10f294;
69 struct ramfuc_reg r_0x10f298;
70 struct ramfuc_reg r_0x10f29c;
71 struct ramfuc_reg r_0x10f2a0;
72 struct ramfuc_reg r_0x10f2a4;
73 struct ramfuc_reg r_0x10f2a8;
74 struct ramfuc_reg r_0x10f2ac;
75 struct ramfuc_reg r_0x10f2cc;
76 struct ramfuc_reg r_0x10f2e8;
77 struct ramfuc_reg r_0x10f250;
78 struct ramfuc_reg r_0x10f24c;
79 struct ramfuc_reg r_0x10fec4;
80 struct ramfuc_reg r_0x10fec8;
81 struct ramfuc_reg r_0x10f604;
82 struct ramfuc_reg r_0x10f614;
83 struct ramfuc_reg r_0x10f610;
84 struct ramfuc_reg r_0x100770;
85 struct ramfuc_reg r_0x100778;
86 struct ramfuc_reg r_0x10f224;
87
88 struct ramfuc_reg r_0x10f870;
89 struct ramfuc_reg r_0x10f698;
90 struct ramfuc_reg r_0x10f694;
91 struct ramfuc_reg r_0x10f6b8;
92 struct ramfuc_reg r_0x10f808;
93 struct ramfuc_reg r_0x10f670;
94 struct ramfuc_reg r_0x10f60c;
95 struct ramfuc_reg r_0x10f830;
96 struct ramfuc_reg r_0x1373ec;
97 struct ramfuc_reg r_0x10f800;
98 struct ramfuc_reg r_0x10f82c;
99
100 struct ramfuc_reg r_0x10f978;
101 struct ramfuc_reg r_0x10f910;
102 struct ramfuc_reg r_0x10f914;
103
104 struct ramfuc_reg r_mr[16]; /* MR0 - MR8, MR15 */
105
106 struct ramfuc_reg r_0x62c000;
107 struct ramfuc_reg r_0x10f200;
108 struct ramfuc_reg r_0x10f210;
109 struct ramfuc_reg r_0x10f310;
110 struct ramfuc_reg r_0x10f314;
111 struct ramfuc_reg r_0x10f318;
112 struct ramfuc_reg r_0x10f090;
113 struct ramfuc_reg r_0x10f69c;
114 struct ramfuc_reg r_0x10f824;
115 struct ramfuc_reg r_0x1373f0;
116 struct ramfuc_reg r_0x1373f4;
117 struct ramfuc_reg r_0x137320;
118 struct ramfuc_reg r_0x10f65c;
119 struct ramfuc_reg r_0x10f6bc;
120 struct ramfuc_reg r_0x100710;
121 struct ramfuc_reg r_0x10f750;
122};
123
124struct nve0_ram {
125 struct nouveau_ram base;
126 struct nve0_ramfuc fuc;
127 int from;
128 int mode;
129 int N1, fN1, M1, P1;
130 int N2, M2, P2;
131};
132
133/*******************************************************************************
134 * GDDR5
135 ******************************************************************************/
136static void
137train(struct nve0_ramfuc *fuc, u32 magic)
138{
139 struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
140 struct nouveau_fb *pfb = nouveau_fb(ram);
141 const int mc = nv_rd32(pfb, 0x02243c);
142 int i;
143
144 ram_mask(fuc, 0x10f910, 0xbc0e0000, magic);
145 ram_mask(fuc, 0x10f914, 0xbc0e0000, magic);
146 for (i = 0; i < mc; i++) {
147 const u32 addr = 0x110974 + (i * 0x1000);
148 ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
149 }
150}
151
152static void
153r1373f4_init(struct nve0_ramfuc *fuc)
154{
155 struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
156 const u32 mcoef = ((--ram->P2 << 28) | (ram->N2 << 8) | ram->M2);
157 const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
158 const u32 runk0 = ram->fN1 << 16;
159 const u32 runk1 = ram->fN1;
160
161 if (ram->from == 2) {
162 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
163 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
164 } else {
165 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
166 }
167
168 ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
169 ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
170
171 /* (re)program refpll, if required */
172 if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
173 (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
174 ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
175 ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
176 ram_wr32(fuc, 0x137320, 0x00000000);
177 ram_mask(fuc, 0x132030, 0xffff0000, runk0);
178 ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
179 ram_wr32(fuc, 0x132024, rcoef);
180 ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
181 ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
182 ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
183 ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
184 }
185
186 /* (re)program mempll, if required */
187 if (ram->mode == 2) {
188 ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
189 ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
190 ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
191 ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
192 ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
193 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100);
194 } else {
195 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010100);
196 }
197
198 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010);
199}
200
201static void
202r1373f4_fini(struct nve0_ramfuc *fuc, u32 ramcfg)
203{
204 struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
205 struct nouveau_bios *bios = nouveau_bios(ram);
206 u8 v0 = (nv_ro08(bios, ramcfg + 0x03) & 0xc0) >> 6;
207 u8 v1 = (nv_ro08(bios, ramcfg + 0x03) & 0x30) >> 4;
208 u32 tmp;
209
210 tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
211 ram_wr32(fuc, 0x1373ec, tmp | (v1 << 16));
212 ram_mask(fuc, 0x1373f0, (~ram->mode & 3), 0x00000000);
213 if (ram->mode == 2) {
214 ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000002);
215 ram_mask(fuc, 0x1373f4, 0x00001100, 0x000000000);
216 } else {
217 ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000001);
218 ram_mask(fuc, 0x1373f4, 0x00010000, 0x000000000);
219 }
220 ram_mask(fuc, 0x10f800, 0x00000030, (v0 ^ v1) << 4);
221}
222
223static int
224nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
225{
226 struct nouveau_bios *bios = nouveau_bios(pfb);
227 struct nve0_ram *ram = (void *)pfb->ram;
228 struct nve0_ramfuc *fuc = &ram->fuc;
229 const u32 rammap = ram->base.rammap.data;
230 const u32 ramcfg = ram->base.ramcfg.data;
231 const u32 timing = ram->base.timing.data;
232 int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
233 int mv = 1; /*XXX*/
234 u32 mask, data;
235
236 ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
237 ram_wr32(fuc, 0x62c000, 0x0f0f0000);
238
239 /* MR1: turn termination on early, for some reason.. */
240 if ((ram->base.mr[1] & 0x03c) != 0x030)
241 ram_mask(fuc, mr[1], 0x03c, ram->base.mr[1] & 0x03c);
242
243 if (vc == 1 && ram_have(fuc, gpio2E)) {
244 u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
245 if (temp != ram_rd32(fuc, gpio2E)) {
246 ram_wr32(fuc, gpiotrig, 1);
247 ram_nsec(fuc, 20000);
248 }
249 }
250
251 ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
252
253 ram_mask(fuc, 0x10f914, 0x01020000, 0x000c0000);
254 ram_mask(fuc, 0x10f910, 0x01020000, 0x000c0000);
255
256 ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
257 ram_nsec(fuc, 1000);
258 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
259 ram_nsec(fuc, 1000);
260
261 ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
262 ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
263 ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
264 ram_wr32(fuc, 0x10f090, 0x00000061);
265 ram_wr32(fuc, 0x10f090, 0xc000007f);
266 ram_nsec(fuc, 1000);
267
268 ram_wr32(fuc, 0x10f698, 0x00000000);
269 ram_wr32(fuc, 0x10f69c, 0x00000000);
270
271 /*XXX: there does appear to be some kind of condition here, simply
272 * modifying these bits in the vbios from the default pl0
273 * entries shows no change. however, the data does appear to
274 * be correct and may be required for the transition back
275 */
276 mask = 0x800f07e0;
277 data = 0x00030000;
278 if (ram_rd32(fuc, 0x10f978) & 0x00800000)
279 data |= 0x00040000;
280
281 if (1) {
282 data |= 0x800807e0;
283 switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) {
284 case 0xc0: data &= ~0x00000040; break;
285 case 0x80: data &= ~0x00000100; break;
286 case 0x40: data &= ~0x80000000; break;
287 case 0x00: data &= ~0x00000400; break;
288 }
289
290 switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) {
291 case 0x30: data &= ~0x00000020; break;
292 case 0x20: data &= ~0x00000080; break;
293 case 0x10: data &= ~0x00080000; break;
294 case 0x00: data &= ~0x00000200; break;
295 }
296 }
297
298 if (nv_ro08(bios, ramcfg + 0x02) & 0x80)
299 mask |= 0x03000000;
300 if (nv_ro08(bios, ramcfg + 0x02) & 0x40)
301 mask |= 0x00002000;
302 if (nv_ro08(bios, ramcfg + 0x07) & 0x10)
303 mask |= 0x00004000;
304 if (nv_ro08(bios, ramcfg + 0x07) & 0x08)
305 mask |= 0x00000003;
306 else {
307 mask |= 0x34000000;
308 if (ram_rd32(fuc, 0x10f978) & 0x00800000)
309 mask |= 0x40000000;
310 }
311 ram_mask(fuc, 0x10f824, mask, data);
312
313 ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
314
315 if (ram->from == 2 && ram->mode != 2) {
316 ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
317 ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000);
318 ram_mask(fuc, 0x10f800, 0x00000000, 0x00000004);
319 ram_mask(fuc, 0x10f830, 0x00008000, 0x01040010);
320 ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
321 r1373f4_init(fuc);
322 ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001);
323 r1373f4_fini(fuc, ramcfg);
324 ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001);
325 } else
326 if (ram->from != 2 && ram->mode != 2) {
327 r1373f4_init(fuc);
328 r1373f4_fini(fuc, ramcfg);
329 }
330
331 if (ram_have(fuc, gpioMV)) {
332 u32 temp = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
333 if (temp != ram_rd32(fuc, gpioMV)) {
334 ram_wr32(fuc, gpiotrig, 1);
335 ram_nsec(fuc, 64000);
336 }
337 }
338
339 if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) ||
340 (nv_ro08(bios, ramcfg + 0x07) & 0x10)) {
341 ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
342 ram_nsec(fuc, 20000);
343 }
344
345 if (ram->from != 2 && ram->mode == 2) {
346 ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
347 ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002);
348 ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010);
349 r1373f4_init(fuc);
350 r1373f4_fini(fuc, ramcfg);
351 ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000);
352 ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000);
353 } else
354 if (ram->from == 2 && ram->mode == 2) {
355 ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
356 r1373f4_init(fuc);
357 r1373f4_fini(fuc, ramcfg);
358 }
359
360 if (ram->mode != 2) /*XXX*/ {
361 if (nv_ro08(bios, ramcfg + 0x07) & 0x40)
362 ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
363 }
364
365 data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2;
366 ram_wr32(fuc, 0x10f65c, 0x00000011 * data);
367 ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
368 ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
369
370 data = nv_ro08(bios, ramcfg + 0x04);
371 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
372 ram_wr32(fuc, 0x10f698, 0x01010101 * data);
373 ram_wr32(fuc, 0x10f69c, 0x01010101 * data);
374 }
375
376 if (ram->mode != 2) {
377 u32 temp = ram_rd32(fuc, 0x10f694) & ~0xff00ff00;
378 ram_wr32(fuc, 0x10f694, temp | (0x01000100 * data));
379 }
380
381 if (ram->mode == 2 && (nv_ro08(bios, ramcfg + 0x08) & 0x10))
382 data = 0x00000080;
383 else
384 data = 0x00000000;
385 ram_mask(fuc, 0x10f60c, 0x00000080, data);
386
387 mask = 0x00070000;
388 data = 0x00000000;
389 if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80))
390 data |= 0x03000000;
391 if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40))
392 data |= 0x00002000;
393 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10))
394 data |= 0x00004000;
395 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08))
396 data |= 0x00000003;
397 else
398 data |= 0x74000000;
399 ram_mask(fuc, 0x10f824, mask, data);
400
401 if (nv_ro08(bios, ramcfg + 0x01) & 0x08)
402 data = 0x00000000;
403 else
404 data = 0x00001000;
405 ram_mask(fuc, 0x10f200, 0x00001000, data);
406
407 if (ram_rd32(fuc, 0x10f670) & 0x80000000) {
408 ram_nsec(fuc, 10000);
409 ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000);
410 }
411
412 if (nv_ro08(bios, ramcfg + 0x08) & 0x01)
413 data = 0x00100000;
414 else
415 data = 0x00000000;
416 ram_mask(fuc, 0x10f82c, 0x00100000, data);
417
418 data = 0x00000000;
419 if (nv_ro08(bios, ramcfg + 0x08) & 0x08)
420 data |= 0x00002000;
421 if (nv_ro08(bios, ramcfg + 0x08) & 0x04)
422 data |= 0x00001000;
423 if (nv_ro08(bios, ramcfg + 0x08) & 0x02)
424 data |= 0x00004000;
425 ram_mask(fuc, 0x10f830, 0x00007000, data);
426
427 /* PFB timing */
428 ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28));
429 ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00));
430 ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04));
431 ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08));
432 ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c));
433 ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10));
434 ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14));
435 ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18));
436 ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c));
437 ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20));
438 ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24));
439
440 data = (nv_ro08(bios, ramcfg + 0x02) & 0x03) << 8;
441 if (nv_ro08(bios, ramcfg + 0x01) & 0x10)
442 data |= 0x70000000;
443 ram_mask(fuc, 0x10f604, 0x70000300, data);
444
445 data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28;
446 if (nv_ro08(bios, ramcfg + 0x01) & 0x01)
447 data |= 0x00000100;
448 ram_mask(fuc, 0x10f614, 0x70000000, data);
449
450 data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28;
451 if (nv_ro08(bios, ramcfg + 0x01) & 0x02)
452 data |= 0x00000100;
453 ram_mask(fuc, 0x10f610, 0x70000000, data);
454
455 mask = 0x33f00000;
456 data = 0x00000000;
457 if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04))
458 data |= 0x20200000;
459 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
460 data |= 0x12800000;
461 /*XXX: see note above about there probably being some condition
462 * for the 10f824 stuff that uses ramcfg 3...
463 */
464 if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) {
465 if (nv_ro08(bios, rammap + 0x08) & 0x0c) {
466 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
467 mask |= 0x00000020;
468 else
469 data |= 0x00000020;
470 mask |= 0x00000004;
471 }
472 } else {
473 mask |= 0x40000020;
474 data |= 0x00000004;
475 }
476
477 ram_mask(fuc, 0x10f808, mask, data);
478
479 data = nv_ro08(bios, ramcfg + 0x03) & 0x0f;
480 ram_wr32(fuc, 0x10f870, 0x11111111 * data);
481
482 data = nv_ro08(bios, ramcfg + 0x02) & 0x03;
483 if (nv_ro08(bios, ramcfg + 0x01) & 0x10)
484 data |= 0x00000004;
485 if ((nv_rd32(bios, 0x100770) & 0x00000004) != (data & 0x00000004)) {
486 ram_wr32(fuc, 0x10f750, 0x04000009);
487 ram_wr32(fuc, 0x100710, 0x00000000);
488 ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000);
489 }
490 ram_mask(fuc, 0x100770, 0x00000007, data);
491
492 data = (nv_ro08(bios, timing + 0x30) & 0x07) << 8;
493 if (nv_ro08(bios, ramcfg + 0x01) & 0x01)
494 data |= 0x80000000;
495 ram_mask(fuc, 0x100778, 0x00000700, data);
496
497 data = nv_ro16(bios, timing + 0x2c);
498 ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4);
499 ram_mask(fuc, 0x10f24c, 0x7f000000, (data & 0x1fc0) << 18);
500
501 data = nv_ro08(bios, timing + 0x30);
502 ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
503
504 data = nv_ro16(bios, timing + 0x31);
505 ram_mask(fuc, 0x10fec4, 0x041e0f07, (data & 0x0800) << 15 |
506 (data & 0x0780) << 10 |
507 (data & 0x0078) << 5 |
508 (data & 0x0007));
509 ram_mask(fuc, 0x10fec8, 0x00000027, (data & 0x8000) >> 10 |
510 (data & 0x7000) >> 12);
511
512 ram_wr32(fuc, 0x10f090, 0x4000007e);
513 ram_nsec(fuc, 1000);
514 ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
515 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
516 ram_nsec(fuc, 2000);
517 ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
518
519 if ((nv_ro08(bios, ramcfg + 0x08) & 0x10) && (ram->mode == 2) /*XXX*/) {
520 u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
521 train(fuc, 0xa4010000); /*XXX*/
522 ram_nsec(fuc, 1000);
523 ram_wr32(fuc, 0x10f294, temp);
524 }
525
526 ram_mask(fuc, mr[3], 0xfff, ram->base.mr[3]);
527 ram_wr32(fuc, mr[0], ram->base.mr[0]);
528 ram_mask(fuc, mr[8], 0xfff, ram->base.mr[8]);
529 ram_nsec(fuc, 1000);
530 ram_mask(fuc, mr[1], 0xfff, ram->base.mr[1]);
531 ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5]);
532 ram_mask(fuc, mr[6], 0xfff, ram->base.mr[6]);
533 ram_mask(fuc, mr[7], 0xfff, ram->base.mr[7]);
534
535 if (vc == 0 && ram_have(fuc, gpio2E)) {
536 u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
537 if (temp != ram_rd32(fuc, gpio2E)) {
538 ram_wr32(fuc, gpiotrig, 1);
539 ram_nsec(fuc, 20000);
540 }
541 }
542
543 ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
544 ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
545 ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
546 ram_nsec(fuc, 1000);
547
548 data = ram_rd32(fuc, 0x10f978);
549 data &= ~0x00046144;
550 data |= 0x0000000b;
551 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
552 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x04))
553 data |= 0x0000200c;
554 else
555 data |= 0x00000000;
556 } else {
557 data |= 0x00040044;
558 }
559 ram_wr32(fuc, 0x10f978, data);
560
561 if (ram->mode == 1) {
562 data = ram_rd32(fuc, 0x10f830) | 0x00000001;
563 ram_wr32(fuc, 0x10f830, data);
564 }
565
566 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) {
567 data = 0x88020000;
568 if ( (nv_ro08(bios, ramcfg + 0x07) & 0x04))
569 data |= 0x10000000;
570 if (!(nv_ro08(bios, rammap + 0x08) & 0x10))
571 data |= 0x00080000;
572 } else {
573 data = 0xa40e0000;
574 }
575 train(fuc, data);
576 ram_nsec(fuc, 1000);
577
578 if (ram->mode == 2) { /*XXX*/
579 ram_mask(fuc, 0x10f800, 0x00000004, 0x00000004);
580 }
581
582 /* MR5: (re)enable LP3 if necessary
583 * XXX: need to find the switch, keeping off for now
584 */
585 ram_mask(fuc, mr[5], 0x00000004, 0x00000000);
586
587 if (ram->mode != 2) {
588 ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
589 ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
590 }
591
592 if (nv_ro08(bios, ramcfg + 0x07) & 0x02) {
593 ram_mask(fuc, 0x10f910, 0x80020000, 0x01000000);
594 ram_mask(fuc, 0x10f914, 0x80020000, 0x01000000);
595 }
596
597 ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
598
599 if (nv_ro08(bios, rammap + 0x08) & 0x01)
600 data = 0x00000800;
601 else
602 data = 0x00000000;
603 ram_mask(fuc, 0x10f200, 0x00000800, data);
604 return 0;
605}
606
607/*******************************************************************************
608 * DDR3
609 ******************************************************************************/
610
611static int
612nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
613{
614 struct nouveau_bios *bios = nouveau_bios(pfb);
615 struct nve0_ram *ram = (void *)pfb->ram;
616 struct nve0_ramfuc *fuc = &ram->fuc;
617 const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
618 const u32 runk0 = ram->fN1 << 16;
619 const u32 runk1 = ram->fN1;
620 const u32 rammap = ram->base.rammap.data;
621 const u32 ramcfg = ram->base.ramcfg.data;
622 const u32 timing = ram->base.timing.data;
623 int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
624 int mv = 1; /*XXX*/
625 u32 mask, data;
626
627 ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
628 ram_wr32(fuc, 0x62c000, 0x0f0f0000);
629
630 if (vc == 1 && ram_have(fuc, gpio2E)) {
631 u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]);
632 if (temp != ram_rd32(fuc, gpio2E)) {
633 ram_wr32(fuc, gpiotrig, 1);
634 ram_nsec(fuc, 20000);
635 }
636 }
637
638 ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
639 if ((nv_ro08(bios, ramcfg + 0x03) & 0xf0))
640 ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
641
642 ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
643 ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
644 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
645 ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
646 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
647 ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
648 ram_nsec(fuc, 1000);
649
650 ram_wr32(fuc, 0x10f090, 0x00000060);
651 ram_wr32(fuc, 0x10f090, 0xc000007e);
652
653 /*XXX: there does appear to be some kind of condition here, simply
654 * modifying these bits in the vbios from the default pl0
655 * entries shows no change. however, the data does appear to
656 * be correct and may be required for the transition back
657 */
658 mask = 0x00010000;
659 data = 0x00010000;
660
661 if (1) {
662 mask |= 0x800807e0;
663 data |= 0x800807e0;
664 switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) {
665 case 0xc0: data &= ~0x00000040; break;
666 case 0x80: data &= ~0x00000100; break;
667 case 0x40: data &= ~0x80000000; break;
668 case 0x00: data &= ~0x00000400; break;
669 }
670
671 switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) {
672 case 0x30: data &= ~0x00000020; break;
673 case 0x20: data &= ~0x00000080; break;
674 case 0x10: data &= ~0x00080000; break;
675 case 0x00: data &= ~0x00000200; break;
676 }
677 }
678
679 if (nv_ro08(bios, ramcfg + 0x02) & 0x80)
680 mask |= 0x03000000;
681 if (nv_ro08(bios, ramcfg + 0x02) & 0x40)
682 mask |= 0x00002000;
683 if (nv_ro08(bios, ramcfg + 0x07) & 0x10)
684 mask |= 0x00004000;
685 if (nv_ro08(bios, ramcfg + 0x07) & 0x08)
686 mask |= 0x00000003;
687 else
688 mask |= 0x14000000;
689 ram_mask(fuc, 0x10f824, mask, data);
690
691 ram_mask(fuc, 0x132040, 0x00010000, 0x00000000);
692
693 ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
694 data = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
695 data |= (nv_ro08(bios, ramcfg + 0x03) & 0x30) << 12;
696 ram_wr32(fuc, 0x1373ec, data);
697 ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
698 ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
699
700 /* (re)program refpll, if required */
701 if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef ||
702 (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) {
703 ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
704 ram_mask(fuc, 0x132020, 0x00000001, 0x00000000);
705 ram_wr32(fuc, 0x137320, 0x00000000);
706 ram_mask(fuc, 0x132030, 0xffff0000, runk0);
707 ram_mask(fuc, 0x132034, 0x0000ffff, runk1);
708 ram_wr32(fuc, 0x132024, rcoef);
709 ram_mask(fuc, 0x132028, 0x00080000, 0x00080000);
710 ram_mask(fuc, 0x132020, 0x00000001, 0x00000001);
711 ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
712 ram_mask(fuc, 0x132028, 0x00080000, 0x00000000);
713 }
714
715 ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000010);
716 ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000001);
717 ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
718
719 if (ram_have(fuc, gpioMV)) {
720 u32 temp = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]);
721 if (temp != ram_rd32(fuc, gpioMV)) {
722 ram_wr32(fuc, gpiotrig, 1);
723 ram_nsec(fuc, 64000);
724 }
725 }
726
727 if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) ||
728 (nv_ro08(bios, ramcfg + 0x07) & 0x10)) {
729 ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
730 ram_nsec(fuc, 20000);
731 }
732
733 if (ram->mode != 2) /*XXX*/ {
734 if (nv_ro08(bios, ramcfg + 0x07) & 0x40)
735 ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
736 }
737
738 data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2;
739 ram_wr32(fuc, 0x10f65c, 0x00000011 * data);
740 ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
741 ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
742
743 mask = 0x00010000;
744 data = 0x00000000;
745 if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80))
746 data |= 0x03000000;
747 if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40))
748 data |= 0x00002000;
749 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10))
750 data |= 0x00004000;
751 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08))
752 data |= 0x00000003;
753 else
754 data |= 0x14000000;
755 ram_mask(fuc, 0x10f824, mask, data);
756 ram_nsec(fuc, 1000);
757
758 if (nv_ro08(bios, ramcfg + 0x08) & 0x01)
759 data = 0x00100000;
760 else
761 data = 0x00000000;
762 ram_mask(fuc, 0x10f82c, 0x00100000, data);
763
764 /* PFB timing */
765 ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28));
766 ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00));
767 ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04));
768 ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08));
769 ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c));
770 ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10));
771 ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14));
772 ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18));
773 ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c));
774 ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20));
775 ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24));
776
777 mask = 0x33f00000;
778 data = 0x00000000;
779 if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04))
780 data |= 0x20200000;
781 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
782 data |= 0x12800000;
783 /*XXX: see note above about there probably being some condition
784 * for the 10f824 stuff that uses ramcfg 3...
785 */
786 if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) {
787 if (nv_ro08(bios, rammap + 0x08) & 0x0c) {
788 if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80))
789 mask |= 0x00000020;
790 else
791 data |= 0x00000020;
792 mask |= 0x08000004;
793 }
794 data |= 0x04000000;
795 } else {
796 mask |= 0x44000020;
797 data |= 0x08000004;
798 }
799
800 ram_mask(fuc, 0x10f808, mask, data);
801
802 data = nv_ro08(bios, ramcfg + 0x03) & 0x0f;
803 ram_wr32(fuc, 0x10f870, 0x11111111 * data);
804
805 data = nv_ro16(bios, timing + 0x2c);
806 ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4);
807
808 if (((nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6) >
809 ((nv_ro32(bios, timing + 0x28) & 0x7f000000) >> 24))
810 data = (nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6;
811 else
812 data = (nv_ro32(bios, timing + 0x28) & 0x1f000000) >> 24;
813 ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
814
815 data = nv_ro08(bios, timing + 0x30);
816 ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
817
818 ram_wr32(fuc, 0x10f090, 0x4000007f);
819 ram_nsec(fuc, 1000);
820
821 ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
822 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
823 ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
824 ram_nsec(fuc, 1000);
825
826 ram_nuke(fuc, mr[0]);
827 ram_mask(fuc, mr[0], 0x100, 0x100);
828 ram_mask(fuc, mr[0], 0x100, 0x000);
829
830 ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
831 ram_wr32(fuc, mr[0], ram->base.mr[0]);
832 ram_nsec(fuc, 1000);
833
834 ram_nuke(fuc, mr[0]);
835 ram_mask(fuc, mr[0], 0x100, 0x100);
836 ram_mask(fuc, mr[0], 0x100, 0x000);
837
838 if (vc == 0 && ram_have(fuc, gpio2E)) {
839 u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
840 if (temp != ram_rd32(fuc, gpio2E)) {
841 ram_wr32(fuc, gpiotrig, 1);
842 ram_nsec(fuc, 20000);
843 }
844 }
845
846 if (ram->mode != 2) {
847 ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000);
848 ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
849 }
850
851 ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
852 ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */
853 ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000);
854 ram_nsec(fuc, 1000);
855
856 ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
857
858 if (nv_ro08(bios, rammap + 0x08) & 0x01)
859 data = 0x00000800;
860 else
861 data = 0x00000000;
862 ram_mask(fuc, 0x10f200, 0x00000800, data);
863 return 0;
864}
865
866/*******************************************************************************
867 * main hooks
868 ******************************************************************************/
869
870static int
871nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
872{
873 struct nouveau_bios *bios = nouveau_bios(pfb);
874 struct nve0_ram *ram = (void *)pfb->ram;
875 struct nve0_ramfuc *fuc = &ram->fuc;
876 struct bit_entry M;
877 int ret, refclk, strap, i;
878 u32 data;
879 u8 cnt;
880
881 /* lookup memory config data relevant to the target frequency */
882 ram->base.rammap.data = nvbios_rammap_match(bios, freq / 1000,
883 &ram->base.rammap.version,
884 &ram->base.rammap.size, &cnt,
885 &ram->base.ramcfg.size);
886 if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 ||
887 ram->base.rammap.size < 0x09) {
888 nv_error(pfb, "invalid/missing rammap entry\n");
889 return -EINVAL;
890 }
891
892 /* locate specific data set for the attached memory */
893 if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) {
894 nv_error(pfb, "invalid/missing memory table\n");
895 return -EINVAL;
896 }
897
898 strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2;
899 data = nv_ro16(bios, M.offset + 1);
900 if (data)
901 strap = nv_ro08(bios, data + strap);
902
903 if (strap >= cnt) {
904 nv_error(pfb, "invalid ramcfg strap\n");
905 return -EINVAL;
906 }
907
908 ram->base.ramcfg.version = ram->base.rammap.version;
909 ram->base.ramcfg.data = ram->base.rammap.data + ram->base.rammap.size +
910 (ram->base.ramcfg.size * strap);
911 if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 ||
912 ram->base.ramcfg.size < 0x08) {
913 nv_error(pfb, "invalid/missing ramcfg entry\n");
914 return -EINVAL;
915 }
916
917 /* lookup memory timings, if bios says they're present */
918 strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
919 if (strap != 0xff) {
920 ram->base.timing.data =
921 nvbios_timing_entry(bios, strap,
922 &ram->base.timing.version,
923 &ram->base.timing.size);
924 if (!ram->base.timing.data ||
925 ram->base.timing.version != 0x20 ||
926 ram->base.timing.size < 0x33) {
927 nv_error(pfb, "invalid/missing timing entry\n");
928 return -EINVAL;
929 }
930 } else {
931 ram->base.timing.data = 0;
932 }
933
934 ret = ram_init(fuc, pfb);
935 if (ret)
936 return ret;
937
938 ram->mode = (freq > fuc->refpll.vco1.max_freq) ? 2 : 1;
939 ram->from = ram_rd32(fuc, 0x1373f4) & 0x0000000f;
940
941 /* XXX: this is *not* what nvidia do. on fermi nvidia generally
942 * select, based on some unknown condition, one of the two possible
943 * reference frequencies listed in the vbios table for mempll and
944 * program refpll to that frequency.
945 *
946 * so far, i've seen very weird values being chosen by nvidia on
947 * kepler boards, no idea how/why they're chosen.
948 */
949 refclk = freq;
950 if (ram->mode == 2)
951 refclk = fuc->mempll.refclk;
952
953 /* calculate refpll coefficients */
954 ret = nva3_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1,
955 &ram->fN1, &ram->M1, &ram->P1);
956 fuc->mempll.refclk = ret;
957 if (ret <= 0) {
958 nv_error(pfb, "unable to calc refpll\n");
959 return -EINVAL;
960 }
961
962 /* calculate mempll coefficients, if we're using it */
963 if (ram->mode == 2) {
964 /* post-divider doesn't work... the reg takes the values but
965 * appears to completely ignore it. there *is* a bit at
966 * bit 28 that appears to divide the clock by 2 if set.
967 */
968 fuc->mempll.min_p = 1;
969 fuc->mempll.max_p = 2;
970
971 ret = nva3_pll_calc(nv_subdev(pfb), &fuc->mempll, freq,
972 &ram->N2, NULL, &ram->M2, &ram->P2);
973 if (ret <= 0) {
974 nv_error(pfb, "unable to calc mempll\n");
975 return -EINVAL;
976 }
977 }
978
979 for (i = 0; i < ARRAY_SIZE(fuc->r_mr); i++) {
980 if (ram_have(fuc, mr[i]))
981 ram->base.mr[i] = ram_rd32(fuc, mr[i]);
982 }
983
984 switch (ram->base.type) {
985 case NV_MEM_TYPE_DDR3:
986 ret = nouveau_sddr3_calc(&ram->base);
987 if (ret == 0)
988 ret = nve0_ram_calc_sddr3(pfb, freq);
989 break;
990 case NV_MEM_TYPE_GDDR5:
991 ret = nouveau_gddr5_calc(&ram->base);
992 if (ret == 0)
993 ret = nve0_ram_calc_gddr5(pfb, freq);
994 break;
995 default:
996 ret = -ENOSYS;
997 break;
998 }
999
1000 return ret;
1001}
1002
1003static int
1004nve0_ram_prog(struct nouveau_fb *pfb)
1005{
1006 struct nouveau_device *device = nv_device(pfb);
1007 struct nve0_ram *ram = (void *)pfb->ram;
1008 struct nve0_ramfuc *fuc = &ram->fuc;
1009 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
1010 return 0;
1011}
1012
1013static void
1014nve0_ram_tidy(struct nouveau_fb *pfb)
1015{
1016 struct nve0_ram *ram = (void *)pfb->ram;
1017 struct nve0_ramfuc *fuc = &ram->fuc;
1018 ram_exec(fuc, false);
1019}
1020
1021static int
1022nve0_ram_init(struct nouveau_object *object)
1023{
1024 struct nouveau_fb *pfb = (void *)object->parent;
1025 struct nve0_ram *ram = (void *)object;
1026 struct nouveau_bios *bios = nouveau_bios(pfb);
1027 static const u8 train0[] = {
1028 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
1029 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
1030 };
1031 static const u32 train1[] = {
1032 0x00000000, 0xffffffff,
1033 0x55555555, 0xaaaaaaaa,
1034 0x33333333, 0xcccccccc,
1035 0xf0f0f0f0, 0x0f0f0f0f,
1036 0x00ff00ff, 0xff00ff00,
1037 0x0000ffff, 0xffff0000,
1038 };
1039 u8 ver, hdr, cnt, len, snr, ssz;
1040 u32 data, save;
1041 int ret, i;
1042
1043 ret = nouveau_ram_init(&ram->base);
1044 if (ret)
1045 return ret;
1046
1047 /* run a bunch of tables from rammap table. there's actually
1048 * individual pointers for each rammap entry too, but, nvidia
1049 * seem to just run the last two entries' scripts early on in
1050 * their init, and never again.. we'll just run 'em all once
1051 * for now.
1052 *
1053 * i strongly suspect that each script is for a separate mode
1054 * (likely selected by 0x10f65c's lower bits?), and the
1055 * binary driver skips the one that's already been setup by
1056 * the init tables.
1057 */
1058 data = nvbios_rammap_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
1059 if (!data || hdr < 0x15)
1060 return -EINVAL;
1061
1062 cnt = nv_ro08(bios, data + 0x14); /* guess at count */
1063 data = nv_ro32(bios, data + 0x10); /* guess u32... */
1064 save = nv_rd32(pfb, 0x10f65c);
1065 for (i = 0; i < cnt; i++) {
1066 nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4);
1067 nvbios_exec(&(struct nvbios_init) {
1068 .subdev = nv_subdev(pfb),
1069 .bios = bios,
1070 .offset = nv_ro32(bios, data), /* guess u32 */
1071 .execute = 1,
1072 });
1073 data += 4;
1074 }
1075 nv_wr32(pfb, 0x10f65c, save);
1076
1077 switch (ram->base.type) {
1078 case NV_MEM_TYPE_GDDR5:
1079 for (i = 0; i < 0x30; i++) {
1080 nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8));
1081 nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]);
1082 nv_wr32(pfb, 0x10f918, train1[i % 12]);
1083 nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]);
1084 nv_wr32(pfb, 0x10f918, train1[i % 12]);
1085
1086 nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8));
1087 nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]);
1088 nv_wr32(pfb, 0x10f91c, train1[i % 12]);
1089 nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]);
1090 nv_wr32(pfb, 0x10f91c, train1[i % 12]);
1091 }
1092
1093 for (i = 0; i < 0x100; i++) {
1094 nv_wr32(pfb, 0x10f968, i);
1095 nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]);
1096 }
1097
1098 for (i = 0; i < 0x100; i++) {
1099 nv_wr32(pfb, 0x10f96c, i);
1100 nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]);
1101 }
1102 break;
1103 default:
1104 break;
1105 }
1106
1107 return 0;
1108}
1109
1110static int
1111nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1112 struct nouveau_oclass *oclass, void *data, u32 size,
1113 struct nouveau_object **pobject)
1114{
1115 struct nouveau_fb *pfb = nouveau_fb(parent);
1116 struct nouveau_bios *bios = nouveau_bios(pfb);
1117 struct nouveau_gpio *gpio = nouveau_gpio(pfb);
1118 struct dcb_gpio_func func;
1119 struct nve0_ram *ram;
1120 int ret;
1121
1122 ret = nvc0_ram_create(parent, engine, oclass, &ram);
1123 *pobject = nv_object(ram);
1124 if (ret)
1125 return ret;
1126
1127 switch (ram->base.type) {
1128 case NV_MEM_TYPE_DDR3:
1129 case NV_MEM_TYPE_GDDR5:
1130 ram->base.calc = nve0_ram_calc;
1131 ram->base.prog = nve0_ram_prog;
1132 ram->base.tidy = nve0_ram_tidy;
1133 break;
1134 default:
1135 nv_warn(pfb, "reclocking of this RAM type is unsupported\n");
1136 break;
1137 }
1138
1139 // parse bios data for both pll's
1140 ret = nvbios_pll_parse(bios, 0x0c, &ram->fuc.refpll);
1141 if (ret) {
1142 nv_error(pfb, "mclk refpll data not found\n");
1143 return ret;
1144 }
1145
1146 ret = nvbios_pll_parse(bios, 0x04, &ram->fuc.mempll);
1147 if (ret) {
1148 nv_error(pfb, "mclk pll data not found\n");
1149 return ret;
1150 }
1151
1152 ret = gpio->find(gpio, 0, 0x18, DCB_GPIO_UNUSED, &func);
1153 if (ret == 0) {
1154 ram->fuc.r_gpioMV = ramfuc_reg(0x00d610 + (func.line * 0x04));
1155 ram->fuc.r_funcMV[0] = (func.log[0] ^ 2) << 12;
1156 ram->fuc.r_funcMV[1] = (func.log[1] ^ 2) << 12;
1157 }
1158
1159 ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
1160 if (ret == 0) {
1161 ram->fuc.r_gpio2E = ramfuc_reg(0x00d610 + (func.line * 0x04));
1162 ram->fuc.r_func2E[0] = (func.log[0] ^ 2) << 12;
1163 ram->fuc.r_func2E[1] = (func.log[1] ^ 2) << 12;
1164 }
1165
1166 ram->fuc.r_gpiotrig = ramfuc_reg(0x00d604);
1167
1168 ram->fuc.r_0x132020 = ramfuc_reg(0x132020);
1169 ram->fuc.r_0x132028 = ramfuc_reg(0x132028);
1170 ram->fuc.r_0x132024 = ramfuc_reg(0x132024);
1171 ram->fuc.r_0x132030 = ramfuc_reg(0x132030);
1172 ram->fuc.r_0x132034 = ramfuc_reg(0x132034);
1173 ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
1174 ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
1175 ram->fuc.r_0x132040 = ramfuc_reg(0x132040);
1176
1177 ram->fuc.r_0x10f248 = ramfuc_reg(0x10f248);
1178 ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
1179 ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
1180 ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
1181 ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
1182 ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
1183 ram->fuc.r_0x10f2a4 = ramfuc_reg(0x10f2a4);
1184 ram->fuc.r_0x10f2a8 = ramfuc_reg(0x10f2a8);
1185 ram->fuc.r_0x10f2ac = ramfuc_reg(0x10f2ac);
1186 ram->fuc.r_0x10f2cc = ramfuc_reg(0x10f2cc);
1187 ram->fuc.r_0x10f2e8 = ramfuc_reg(0x10f2e8);
1188 ram->fuc.r_0x10f250 = ramfuc_reg(0x10f250);
1189 ram->fuc.r_0x10f24c = ramfuc_reg(0x10f24c);
1190 ram->fuc.r_0x10fec4 = ramfuc_reg(0x10fec4);
1191 ram->fuc.r_0x10fec8 = ramfuc_reg(0x10fec8);
1192 ram->fuc.r_0x10f604 = ramfuc_reg(0x10f604);
1193 ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
1194 ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
1195 ram->fuc.r_0x100770 = ramfuc_reg(0x100770);
1196 ram->fuc.r_0x100778 = ramfuc_reg(0x100778);
1197 ram->fuc.r_0x10f224 = ramfuc_reg(0x10f224);
1198
1199 ram->fuc.r_0x10f870 = ramfuc_reg(0x10f870);
1200 ram->fuc.r_0x10f698 = ramfuc_reg(0x10f698);
1201 ram->fuc.r_0x10f694 = ramfuc_reg(0x10f694);
1202 ram->fuc.r_0x10f6b8 = ramfuc_reg(0x10f6b8);
1203 ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
1204 ram->fuc.r_0x10f670 = ramfuc_reg(0x10f670);
1205 ram->fuc.r_0x10f60c = ramfuc_reg(0x10f60c);
1206 ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
1207 ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
1208 ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
1209 ram->fuc.r_0x10f82c = ramfuc_reg(0x10f82c);
1210
1211 ram->fuc.r_0x10f978 = ramfuc_reg(0x10f978);
1212 ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
1213 ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
1214
1215 switch (ram->base.type) {
1216 case NV_MEM_TYPE_GDDR5:
1217 ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1218 ram->fuc.r_mr[1] = ramfuc_reg(0x10f330);
1219 ram->fuc.r_mr[2] = ramfuc_reg(0x10f334);
1220 ram->fuc.r_mr[3] = ramfuc_reg(0x10f338);
1221 ram->fuc.r_mr[4] = ramfuc_reg(0x10f33c);
1222 ram->fuc.r_mr[5] = ramfuc_reg(0x10f340);
1223 ram->fuc.r_mr[6] = ramfuc_reg(0x10f344);
1224 ram->fuc.r_mr[7] = ramfuc_reg(0x10f348);
1225 ram->fuc.r_mr[8] = ramfuc_reg(0x10f354);
1226 ram->fuc.r_mr[15] = ramfuc_reg(0x10f34c);
1227 break;
1228 case NV_MEM_TYPE_DDR3:
1229 ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1230 ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
1231 break;
1232 default:
1233 break;
1234 }
1235
1236 ram->fuc.r_0x62c000 = ramfuc_reg(0x62c000);
1237 ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
1238 ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
1239 ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
1240 ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
1241 ram->fuc.r_0x10f318 = ramfuc_reg(0x10f318);
1242 ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
1243 ram->fuc.r_0x10f69c = ramfuc_reg(0x10f69c);
1244 ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
1245 ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
1246 ram->fuc.r_0x1373f4 = ramfuc_reg(0x1373f4);
1247 ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
1248 ram->fuc.r_0x10f65c = ramfuc_reg(0x10f65c);
1249 ram->fuc.r_0x10f6bc = ramfuc_reg(0x10f6bc);
1250 ram->fuc.r_0x100710 = ramfuc_reg(0x100710);
1251 ram->fuc.r_0x10f750 = ramfuc_reg(0x10f750);
1252 return 0;
1253}
1254
1255struct nouveau_oclass
1256nve0_ram_oclass = {
1257 .handle = 0,
1258 .ofuncs = &(struct nouveau_ofuncs) {
1259 .ctor = nve0_ram_ctor,
1260 .dtor = _nouveau_ram_dtor,
1261 .init = nve0_ram_init,
1262 .fini = _nouveau_ram_fini,
1263 }
1264};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h
new file mode 100644
index 000000000000..571077e39071
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h
@@ -0,0 +1,18 @@
1#ifndef __NVKM_FBRAM_SEQ_H__
2#define __NVKM_FBRAM_SEQ_H__
3
4#include <subdev/bus.h>
5#include <subdev/bus/hwsq.h>
6
7#define ram_init(s,p) hwsq_init(&(s)->base, (p))
8#define ram_exec(s,e) hwsq_exec(&(s)->base, (e))
9#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
10#define ram_rd32(s,r) hwsq_rd32(&(s)->base, &(s)->r_##r)
11#define ram_wr32(s,r,d) hwsq_wr32(&(s)->base, &(s)->r_##r, (d))
12#define ram_nuke(s,r) hwsq_nuke(&(s)->base, &(s)->r_##r)
13#define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d))
14#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
15#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
16#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n))
17
18#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
new file mode 100644
index 000000000000..ebd4cd9c35d9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright 2013 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include <subdev/bios.h>
26#include "priv.h"
27
28struct ramxlat {
29 int id;
30 u8 enc;
31};
32
33static inline int
34ramxlat(const struct ramxlat *xlat, int id)
35{
36 while (xlat->id >= 0) {
37 if (xlat->id == id)
38 return xlat->enc;
39 xlat++;
40 }
41 return -EINVAL;
42}
43
44static const struct ramxlat
45ramddr3_cl[] = {
46 { 5, 2 }, { 6, 4 }, { 7, 6 }, { 8, 8 }, { 9, 10 }, { 10, 12 },
47 { 11, 14 },
48 /* the below are mentioned in some, but not all, ddr3 docs */
49 { 12, 1 }, { 13, 3 }, { 14, 5 },
50 { -1 }
51};
52
53static const struct ramxlat
54ramddr3_wr[] = {
55 { 5, 1 }, { 6, 2 }, { 7, 3 }, { 8, 4 }, { 10, 5 }, { 12, 6 },
56 /* the below are mentioned in some, but not all, ddr3 docs */
57 { 14, 7 }, { 16, 0 },
58 { -1 }
59};
60
61static const struct ramxlat
62ramddr3_cwl[] = {
63 { 5, 0 }, { 6, 1 }, { 7, 2 }, { 8, 3 },
64 /* the below are mentioned in some, but not all, ddr3 docs */
65 { 9, 4 },
66 { -1 }
67};
68
69int
70nouveau_sddr3_calc(struct nouveau_ram *ram)
71{
72 struct nouveau_bios *bios = nouveau_bios(ram);
73 int WL, CL, WR;
74
75 switch (!!ram->timing.data * ram->timing.version) {
76 case 0x20:
77 WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7;
78 CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f;
79 WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f;
80 break;
81 default:
82 return -ENOSYS;
83 }
84
85 WL = ramxlat(ramddr3_cwl, WL);
86 CL = ramxlat(ramddr3_cl, CL);
87 WR = ramxlat(ramddr3_wr, WR);
88 if (WL < 0 || CL < 0 || WR < 0)
89 return -EINVAL;
90
91 ram->mr[0] &= ~0xe74;
92 ram->mr[0] |= (WR & 0x07) << 9;
93 ram->mr[0] |= (CL & 0x0e) << 3;
94 ram->mr[0] |= (CL & 0x01) << 2;
95
96 ram->mr[2] &= ~0x038;
97 ram->mr[2] |= (WL & 0x07) << 3;
98 return 0;
99}