aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-07-11 05:05:01 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:12:49 -0400
commit861d21074bbb141b0cc165a61c11f571571cda12 (patch)
treefd5755cab318f77276044a40bcc274a6f8fe1ec1 /drivers/gpu/drm/nouveau
parent0134a97979a0abc1c756b0fe491e074693c2bdf5 (diff)
drm/nouveau/fb: merge fb/vram and port to subdev interfaces
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/Makefile5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv10.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv20.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h137
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/vm.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv04.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv10.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv20.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv30.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv40.c17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv50.c15
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c18
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nve0.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/base.c130
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c139
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c186
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c208
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c114
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c261
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c384
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c243
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c252
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c167
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c91
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_compat.c106
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_compat.h20
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_debugfs.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h146
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fb.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c90
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c87
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_util.c43
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_util.h16
-rw-r--r--drivers/gpu/drm/nouveau/nv50_evo.c14
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c5
-rw-r--r--drivers/gpu/drm/nouveau/nva3_pm.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_pm.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c6
49 files changed, 1691 insertions, 1345 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 0615e954d238..5e18a53e2c0c 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -8,6 +8,7 @@ ccflags-y += -I$(src)
8 8
9nouveau-y := core/core/client.o 9nouveau-y := core/core/client.o
10nouveau-y += core/core/engine.o 10nouveau-y += core/core/engine.o
11nouveau-y += core/core/enum.o
11nouveau-y += core/core/handle.o 12nouveau-y += core/core/handle.o
12nouveau-y += core/core/mm.o 13nouveau-y += core/core/mm.o
13nouveau-y += core/core/namedb.o 14nouveau-y += core/core/namedb.o
@@ -50,6 +51,7 @@ nouveau-y += core/subdev/devinit/nv10.o
50nouveau-y += core/subdev/devinit/nv1a.o 51nouveau-y += core/subdev/devinit/nv1a.o
51nouveau-y += core/subdev/devinit/nv20.o 52nouveau-y += core/subdev/devinit/nv20.o
52nouveau-y += core/subdev/devinit/nv50.o 53nouveau-y += core/subdev/devinit/nv50.o
54nouveau-y += core/subdev/fb/base.o
53nouveau-y += core/subdev/fb/nv04.o 55nouveau-y += core/subdev/fb/nv04.o
54nouveau-y += core/subdev/fb/nv10.o 56nouveau-y += core/subdev/fb/nv10.o
55nouveau-y += core/subdev/fb/nv20.o 57nouveau-y += core/subdev/fb/nv20.o
@@ -57,8 +59,6 @@ nouveau-y += core/subdev/fb/nv30.o
57nouveau-y += core/subdev/fb/nv40.o 59nouveau-y += core/subdev/fb/nv40.o
58nouveau-y += core/subdev/fb/nv50.o 60nouveau-y += core/subdev/fb/nv50.o
59nouveau-y += core/subdev/fb/nvc0.o 61nouveau-y += core/subdev/fb/nvc0.o
60nouveau-y += core/subdev/fb/nv50_vram.o
61nouveau-y += core/subdev/fb/nvc0_vram.o
62nouveau-y += core/subdev/gpio/base.o 62nouveau-y += core/subdev/gpio/base.o
63nouveau-y += core/subdev/gpio/nv10.o 63nouveau-y += core/subdev/gpio/nv10.o
64nouveau-y += core/subdev/gpio/nv50.o 64nouveau-y += core/subdev/gpio/nv50.o
@@ -69,6 +69,7 @@ nouveau-y += core/subdev/i2c/bit.o
69nouveau-y += core/subdev/instmem/nv04.o 69nouveau-y += core/subdev/instmem/nv04.o
70nouveau-y += core/subdev/instmem/nv50.o 70nouveau-y += core/subdev/instmem/nv50.o
71nouveau-y += core/subdev/instmem/nvc0.o 71nouveau-y += core/subdev/instmem/nvc0.o
72nouveau-y += core/subdev/ltcg/nvc0.o
72nouveau-y += core/subdev/mc/base.o 73nouveau-y += core/subdev/mc/base.o
73nouveau-y += core/subdev/mc/nv04.o 74nouveau-y += core/subdev/mc/nv04.o
74nouveau-y += core/subdev/mc/nv44.o 75nouveau-y += core/subdev/mc/nv44.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
index 3079f080d40e..23ae4591b7bd 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
@@ -163,7 +163,7 @@ nv40_fifo_init(struct drm_device *dev, int engine)
163 break; 163 break;
164 default: 164 default:
165 nv_wr32(dev, 0x002230, 0x00000000); 165 nv_wr32(dev, 0x002230, 0x00000000);
166 nv_wr32(dev, 0x002220, ((dev_priv->vram_size - 512 * 1024 + 166 nv_wr32(dev, 0x002220, ((nvfb_vram_size(dev) - 512 * 1024 +
167 dev_priv->ramfc->pinst) >> 16) | 167 dev_priv->ramfc->pinst) >> 16) |
168 0x00030000); 168 0x00030000);
169 break; 169 break;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
index 19e303b423af..d006658e6468 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
@@ -895,9 +895,7 @@ nv10_graph_context_del(struct nouveau_channel *chan, int engine)
895static void 895static void
896nv10_graph_set_tile_region(struct drm_device *dev, int i) 896nv10_graph_set_tile_region(struct drm_device *dev, int i)
897{ 897{
898 struct drm_nouveau_private *dev_priv = dev->dev_private; 898 struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
899 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
900
901 nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit); 899 nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit);
902 nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch); 900 nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch);
903 nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr); 901 nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
index 718ecf761823..dd31156e3029 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
@@ -472,7 +472,7 @@ static void
472nv20_graph_set_tile_region(struct drm_device *dev, int i) 472nv20_graph_set_tile_region(struct drm_device *dev, int i)
473{ 473{
474 struct drm_nouveau_private *dev_priv = dev->dev_private; 474 struct drm_nouveau_private *dev_priv = dev->dev_private;
475 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 475 struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
476 476
477 nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); 477 nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit);
478 nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); 478 nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
index 4ad9759f821e..ab3af6d15381 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
@@ -125,7 +125,7 @@ static void
125nv40_graph_set_tile_region(struct drm_device *dev, int i) 125nv40_graph_set_tile_region(struct drm_device *dev, int i)
126{ 126{
127 struct drm_nouveau_private *dev_priv = dev->dev_private; 127 struct drm_nouveau_private *dev_priv = dev->dev_private;
128 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 128 struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
129 129
130 switch (dev_priv->chipset) { 130 switch (dev_priv->chipset) {
131 case 0x40: 131 case 0x40:
@@ -178,7 +178,6 @@ nv40_graph_init(struct drm_device *dev, int engine)
178{ 178{
179 struct nv40_graph_engine *pgraph = nv_engine(dev, engine); 179 struct nv40_graph_engine *pgraph = nv_engine(dev, engine);
180 struct drm_nouveau_private *dev_priv = dev->dev_private; 180 struct drm_nouveau_private *dev_priv = dev->dev_private;
181 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
182 uint32_t vramsz; 181 uint32_t vramsz;
183 int i, j; 182 int i, j;
184 183
@@ -280,7 +279,7 @@ nv40_graph_init(struct drm_device *dev, int engine)
280 } 279 }
281 280
282 /* Turn all the tiling regions off. */ 281 /* Turn all the tiling regions off. */
283 for (i = 0; i < pfb->num_tiles; i++) 282 for (i = 0; i < nvfb_tile_nr(dev); i++)
284 nv40_graph_set_tile_region(dev, i); 283 nv40_graph_set_tile_region(dev, i);
285 284
286 /* begin RAM config */ 285 /* begin RAM config */
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
index 4a14a6763dac..eb5455fed1bf 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -128,7 +128,6 @@ nv31_mpeg_object_new(struct nouveau_channel *chan, int engine,
128static int 128static int
129nv31_mpeg_init(struct drm_device *dev, int engine) 129nv31_mpeg_init(struct drm_device *dev, int engine)
130{ 130{
131 struct drm_nouveau_private *dev_priv = dev->dev_private;
132 struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine); 131 struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine);
133 int i; 132 int i;
134 133
@@ -138,7 +137,7 @@ nv31_mpeg_init(struct drm_device *dev, int engine)
138 nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */ 137 nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
139 nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */ 138 nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
140 139
141 for (i = 0; i < dev_priv->engine.fb.num_tiles; i++) 140 for (i = 0; i < nvfb_tile_nr(dev); i++)
142 pmpeg->base.set_tile_region(dev, i); 141 pmpeg->base.set_tile_region(dev, i);
143 142
144 /* PMPEG init */ 143 /* PMPEG init */
@@ -235,9 +234,7 @@ nv31_mpeg_isr_chid(struct drm_device *dev, u32 inst)
235static void 234static void
236nv31_vpe_set_tile_region(struct drm_device *dev, int i) 235nv31_vpe_set_tile_region(struct drm_device *dev, int i)
237{ 236{
238 struct drm_nouveau_private *dev_priv = dev->dev_private; 237 struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
239 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
240
241 nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch); 238 nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch);
242 nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit); 239 nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit);
243 nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr); 240 nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr);
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
new file mode 100644
index 000000000000..91dbdc16ac94
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -0,0 +1,137 @@
1#ifndef __NOUVEAU_FB_H__
2#define __NOUVEAU_FB_H__
3
4#ifndef XXX_THIS_IS_A_HACK
5#include <core/subdev.h>
6#include <core/device.h>
7#endif
8#include <core/mm.h>
9#include <subdev/vm.h>
10
11/* memory type/access flags, do not match hardware values */
12#define NV_MEM_ACCESS_RO 1
13#define NV_MEM_ACCESS_WO 2
14#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
15#define NV_MEM_ACCESS_SYS 4
16#define NV_MEM_ACCESS_VM 8
17#define NV_MEM_ACCESS_NOSNOOP 16
18
19#define NV_MEM_TARGET_VRAM 0
20#define NV_MEM_TARGET_PCI 1
21#define NV_MEM_TARGET_PCI_NOSNOOP 2
22#define NV_MEM_TARGET_VM 3
23#define NV_MEM_TARGET_GART 4
24
25#define NV_MEM_TYPE_VM 0x7f
26#define NV_MEM_COMP_VM 0x03
27
28struct nouveau_mem {
29 struct drm_device *dev;
30
31 struct nouveau_vma bar_vma;
32 struct nouveau_vma vma[2];
33 u8 page_shift;
34
35 struct nouveau_mm_node *tag;
36 struct list_head regions;
37 dma_addr_t *pages;
38 u32 memtype;
39 u64 offset;
40 u64 size;
41 struct sg_table *sg;
42};
43
44struct nouveau_fb_tile {
45 struct nouveau_mm_node *tag;
46 u32 addr;
47 u32 limit;
48 u32 pitch;
49 u32 zcomp;
50};
51
52#ifndef XXX_THIS_IS_A_HACK
53struct nouveau_fb {
54 struct nouveau_subdev base;
55
56 bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);
57
58 struct {
59 enum {
60 NV_MEM_TYPE_UNKNOWN = 0,
61 NV_MEM_TYPE_STOLEN,
62 NV_MEM_TYPE_SGRAM,
63 NV_MEM_TYPE_SDRAM,
64 NV_MEM_TYPE_DDR1,
65 NV_MEM_TYPE_DDR2,
66 NV_MEM_TYPE_DDR3,
67 NV_MEM_TYPE_GDDR2,
68 NV_MEM_TYPE_GDDR3,
69 NV_MEM_TYPE_GDDR4,
70 NV_MEM_TYPE_GDDR5
71 } type;
72 u64 stolen;
73 u64 size;
74 int ranks;
75
76 int (*get)(struct nouveau_fb *, u64 size, u32 align,
77 u32 size_nc, u32 type, struct nouveau_mem **);
78 void (*put)(struct nouveau_fb *, struct nouveau_mem **);
79 } ram;
80
81 struct nouveau_mm vram;
82 struct nouveau_mm tags;
83
84 struct {
85 struct nouveau_fb_tile region[16];
86 int regions;
87 void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size,
88 u32 pitch, u32 flags, struct nouveau_fb_tile *);
89 void (*fini)(struct nouveau_fb *, int i,
90 struct nouveau_fb_tile *);
91 void (*prog)(struct nouveau_fb *, int i,
92 struct nouveau_fb_tile *);
93 } tile;
94};
95
96static inline struct nouveau_fb *
97nouveau_fb(void *obj)
98{
99 return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
100}
101
102#define nouveau_fb_create(p,e,c,d) \
103 nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d))
104int nouveau_fb_created(struct nouveau_fb *);
105void nouveau_fb_destroy(struct nouveau_fb *);
106int nouveau_fb_init(struct nouveau_fb *);
107#define nouveau_fb_fini(p,s) \
108 nouveau_subdev_fini(&(p)->base, (s))
109
110void _nouveau_fb_dtor(struct nouveau_object *);
111int _nouveau_fb_init(struct nouveau_object *);
112#define _nouveau_fb_fini _nouveau_subdev_fini
113
114extern struct nouveau_oclass nv04_fb_oclass;
115extern struct nouveau_oclass nv10_fb_oclass;
116extern struct nouveau_oclass nv20_fb_oclass;
117extern struct nouveau_oclass nv30_fb_oclass;
118extern struct nouveau_oclass nv40_fb_oclass;
119extern struct nouveau_oclass nv50_fb_oclass;
120extern struct nouveau_oclass nvc0_fb_oclass;
121
122struct nouveau_bios;
123int nouveau_fb_bios_memtype(struct nouveau_bios *);
124
125bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
126
127void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
128
129void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
130 u32 pitch, u32 flags, struct nouveau_fb_tile *);
131void nv30_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
132
133void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **);
134void nv50_fb_trap(struct nouveau_fb *, int display);
135#endif
136
137#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
new file mode 100644
index 000000000000..f351f63bc654
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
@@ -0,0 +1,33 @@
1#ifndef __NOUVEAU_LTCG_H__
2#define __NOUVEAU_LTCG_H__
3
4#include <core/subdev.h>
5#include <core/device.h>
6
7struct nouveau_ltcg {
8 struct nouveau_subdev base;
9};
10
11static inline struct nouveau_ltcg *
12nouveau_ltcg(void *obj)
13{
14 return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_LTCG];
15}
16
17#define nouveau_ltcg_create(p,e,o,d) \
18 nouveau_subdev_create_((p), (e), (o), 0, "PLTCG", "level2", \
19 sizeof(**d), (void **)d)
20#define nouveau_ltcg_destroy(p) \
21 nouveau_subdev_destroy(&(p)->base)
22#define nouveau_ltcg_init(p) \
23 nouveau_subdev_init(&(p)->base)
24#define nouveau_ltcg_fini(p,s) \
25 nouveau_subdev_fini(&(p)->base, (s))
26
27#define _nouveau_ltcg_dtor _nouveau_subdev_dtor
28#define _nouveau_ltcg_init _nouveau_subdev_init
29#define _nouveau_ltcg_fini _nouveau_subdev_fini
30
31extern struct nouveau_oclass nvc0_ltcg_oclass;
32
33#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
index 7c1fc2114fec..6d3764b416f4 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
@@ -25,11 +25,10 @@
25#ifndef __NOUVEAU_VM_H__ 25#ifndef __NOUVEAU_VM_H__
26#define __NOUVEAU_VM_H__ 26#define __NOUVEAU_VM_H__
27 27
28#include "drmP.h"
29
30#include "nouveau_drv.h"
31#include <core/mm.h> 28#include <core/mm.h>
32 29
30struct nouveau_mem;
31
33struct nouveau_vm_pgt { 32struct nouveau_vm_pgt {
34 struct nouveau_gpuobj *obj[2]; 33 struct nouveau_gpuobj *obj[2];
35 u32 refcount[2]; 34 u32 refcount[2];
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
index aa43bd5c2374..66b7156281c9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
@@ -29,6 +29,7 @@
29#include <subdev/devinit.h> 29#include <subdev/devinit.h>
30#include <subdev/mc.h> 30#include <subdev/mc.h>
31#include <subdev/timer.h> 31#include <subdev/timer.h>
32#include <subdev/fb.h>
32 33
33int 34int
34nv04_identify(struct nouveau_device *device) 35nv04_identify(struct nouveau_device *device)
@@ -41,6 +42,7 @@ nv04_identify(struct nouveau_device *device)
41 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass; 42 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass;
42 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 43 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
43 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 44 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
45 device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass;
44 break; 46 break;
45 case 0x05: 47 case 0x05:
46 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -49,6 +51,7 @@ nv04_identify(struct nouveau_device *device)
49 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass; 51 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass;
50 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 52 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
51 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 53 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
54 device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass;
52 break; 55 break;
53 default: 56 default:
54 nv_fatal(device, "unknown RIVA chipset\n"); 57 nv_fatal(device, "unknown RIVA chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
index 1926c33fb6f8..cf81479725ad 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
@@ -30,6 +30,7 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
33 34
34int 35int
35nv10_identify(struct nouveau_device *device) 36nv10_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv10_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 44 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 45 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 46 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
47 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
46 break; 48 break;
47 case 0x15: 49 case 0x15:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 50 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv10_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 54 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 55 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 56 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
57 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
55 break; 58 break;
56 case 0x16: 59 case 0x16:
57 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 60 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv10_identify(struct nouveau_device *device)
61 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 64 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
62 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 65 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
63 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 66 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
67 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
64 break; 68 break;
65 case 0x1a: 69 case 0x1a:
66 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 70 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv10_identify(struct nouveau_device *device)
70 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 74 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
71 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 75 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
72 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 76 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
77 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
73 break; 78 break;
74 case 0x11: 79 case 0x11:
75 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 80 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv10_identify(struct nouveau_device *device)
79 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 84 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
80 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 85 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
81 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 86 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
87 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
82 break; 88 break;
83 case 0x17: 89 case 0x17:
84 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 90 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -88,6 +94,7 @@ nv10_identify(struct nouveau_device *device)
88 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 94 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
89 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 95 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
90 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 96 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
97 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
91 break; 98 break;
92 case 0x1f: 99 case 0x1f:
93 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 100 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -97,6 +104,7 @@ nv10_identify(struct nouveau_device *device)
97 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 104 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
98 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 105 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
99 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 106 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
107 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
100 break; 108 break;
101 case 0x18: 109 case 0x18:
102 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 110 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -106,6 +114,7 @@ nv10_identify(struct nouveau_device *device)
106 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 114 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
107 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 115 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
108 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 116 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
117 device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
109 break; 118 break;
110 default: 119 default:
111 nv_fatal(device, "unknown Celsius chipset\n"); 120 nv_fatal(device, "unknown Celsius chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
index 88729c308565..e97280cd43b0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
@@ -30,6 +30,7 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
33 34
34int 35int
35nv20_identify(struct nouveau_device *device) 36nv20_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv20_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 44 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 45 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 46 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
47 device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
46 break; 48 break;
47 case 0x25: 49 case 0x25:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 50 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv20_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 54 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 55 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 56 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
57 device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
55 break; 58 break;
56 case 0x28: 59 case 0x28:
57 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 60 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv20_identify(struct nouveau_device *device)
61 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 64 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
62 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 65 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
63 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 66 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
67 device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
64 break; 68 break;
65 case 0x2a: 69 case 0x2a:
66 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 70 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv20_identify(struct nouveau_device *device)
70 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 74 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
71 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 75 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
72 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 76 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
77 device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
73 break; 78 break;
74 default: 79 default:
75 nv_fatal(device, "unknown Kelvin chipset\n"); 80 nv_fatal(device, "unknown Kelvin chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
index 4feea8804a78..ddd3ab6cb733 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
@@ -30,6 +30,7 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
33 34
34int 35int
35nv30_identify(struct nouveau_device *device) 36nv30_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv30_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 44 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 45 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 46 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
47 device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
46 break; 48 break;
47 case 0x35: 49 case 0x35:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 50 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv30_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 54 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 55 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 56 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
57 device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
55 break; 58 break;
56 case 0x31: 59 case 0x31:
57 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 60 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv30_identify(struct nouveau_device *device)
61 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 64 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
62 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 65 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
63 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 66 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
67 device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
64 break; 68 break;
65 case 0x36: 69 case 0x36:
66 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 70 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv30_identify(struct nouveau_device *device)
70 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; 74 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
71 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 75 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
72 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 76 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
77 device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
73 break; 78 break;
74 case 0x34: 79 case 0x34:
75 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 80 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv30_identify(struct nouveau_device *device)
79 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; 84 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
80 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 85 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
81 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 86 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
87 device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
82 break; 88 break;
83 default: 89 default:
84 nv_fatal(device, "unknown Rankine chipset\n"); 90 nv_fatal(device, "unknown Rankine chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
index 8f683613788d..c7ea921e0309 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
@@ -30,6 +30,7 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
33 34
34int 35int
35nv40_identify(struct nouveau_device *device) 36nv40_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv40_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 44 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 45 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 46 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
47 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
46 break; 48 break;
47 case 0x41: 49 case 0x41:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 50 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv40_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 54 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 55 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 56 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
57 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
55 break; 58 break;
56 case 0x42: 59 case 0x42:
57 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 60 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv40_identify(struct nouveau_device *device)
61 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 64 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
62 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 65 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
63 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 66 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
67 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
64 break; 68 break;
65 case 0x43: 69 case 0x43:
66 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 70 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv40_identify(struct nouveau_device *device)
70 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 74 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
71 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 75 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
72 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 76 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
77 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
73 break; 78 break;
74 case 0x45: 79 case 0x45:
75 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 80 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv40_identify(struct nouveau_device *device)
79 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 84 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
80 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 85 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
81 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 86 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
87 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
82 break; 88 break;
83 case 0x47: 89 case 0x47:
84 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 90 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -88,6 +94,7 @@ nv40_identify(struct nouveau_device *device)
88 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 94 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
89 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 95 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
90 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 96 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
97 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
91 break; 98 break;
92 case 0x49: 99 case 0x49:
93 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 100 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -97,6 +104,7 @@ nv40_identify(struct nouveau_device *device)
97 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 104 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
98 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 105 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
99 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 106 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
107 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
100 break; 108 break;
101 case 0x4b: 109 case 0x4b:
102 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 110 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -106,6 +114,7 @@ nv40_identify(struct nouveau_device *device)
106 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 114 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
107 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; 115 device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
108 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 116 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
117 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
109 break; 118 break;
110 case 0x44: 119 case 0x44:
111 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 120 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -115,6 +124,7 @@ nv40_identify(struct nouveau_device *device)
115 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 124 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
116 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 125 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
117 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 126 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
127 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
118 break; 128 break;
119 case 0x46: 129 case 0x46:
120 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 130 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -124,6 +134,7 @@ nv40_identify(struct nouveau_device *device)
124 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 134 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
125 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 135 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
126 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 136 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
137 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
127 break; 138 break;
128 case 0x4a: 139 case 0x4a:
129 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 140 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -133,6 +144,7 @@ nv40_identify(struct nouveau_device *device)
133 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 144 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
134 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 145 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
135 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 146 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
147 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
136 break; 148 break;
137 case 0x4c: 149 case 0x4c:
138 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 150 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -142,6 +154,7 @@ nv40_identify(struct nouveau_device *device)
142 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 154 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
143 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 155 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
144 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 156 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
157 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
145 break; 158 break;
146 case 0x4e: 159 case 0x4e:
147 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 160 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -151,6 +164,7 @@ nv40_identify(struct nouveau_device *device)
151 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 164 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
152 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 165 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
153 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 166 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
167 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
154 break; 168 break;
155 case 0x63: 169 case 0x63:
156 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 170 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -160,6 +174,7 @@ nv40_identify(struct nouveau_device *device)
160 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 174 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
161 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 175 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
162 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 176 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
177 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
163 break; 178 break;
164 case 0x67: 179 case 0x67:
165 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 180 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -169,6 +184,7 @@ nv40_identify(struct nouveau_device *device)
169 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 184 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
170 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 185 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
171 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 186 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
187 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
172 break; 188 break;
173 case 0x68: 189 case 0x68:
174 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 190 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -178,6 +194,7 @@ nv40_identify(struct nouveau_device *device)
178 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; 194 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
179 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; 195 device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
180 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 196 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
197 device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
181 break; 198 break;
182 default: 199 default:
183 nv_fatal(device, "unknown Curie chipset\n"); 200 nv_fatal(device, "unknown Curie chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
index e844525d5694..e60cdf26ebf9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
@@ -30,6 +30,7 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
33 34
34int 35int
35nv50_identify(struct nouveau_device *device) 36nv50_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv50_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 44 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 45 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 46 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
47 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
46 break; 48 break;
47 case 0x84: 49 case 0x84:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 50 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv50_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 54 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 55 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 56 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
57 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
55 break; 58 break;
56 case 0x86: 59 case 0x86:
57 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 60 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv50_identify(struct nouveau_device *device)
61 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 64 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
62 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 65 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
63 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 66 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
67 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
64 break; 68 break;
65 case 0x92: 69 case 0x92:
66 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 70 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv50_identify(struct nouveau_device *device)
70 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 74 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
71 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 75 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
72 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 76 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
77 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
73 break; 78 break;
74 case 0x94: 79 case 0x94:
75 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 80 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv50_identify(struct nouveau_device *device)
79 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 84 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
80 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 85 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
81 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 86 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
87 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
82 break; 88 break;
83 case 0x96: 89 case 0x96:
84 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 90 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -88,6 +94,7 @@ nv50_identify(struct nouveau_device *device)
88 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 94 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
89 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 95 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
90 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 96 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
97 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
91 break; 98 break;
92 case 0x98: 99 case 0x98:
93 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 100 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -97,6 +104,7 @@ nv50_identify(struct nouveau_device *device)
97 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 104 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
98 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 105 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
99 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 106 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
107 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
100 break; 108 break;
101 case 0xa0: 109 case 0xa0:
102 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 110 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -106,6 +114,7 @@ nv50_identify(struct nouveau_device *device)
106 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 114 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
107 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 115 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
108 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 116 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
117 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
109 break; 118 break;
110 case 0xaa: 119 case 0xaa:
111 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 120 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -115,6 +124,7 @@ nv50_identify(struct nouveau_device *device)
115 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 124 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
116 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 125 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
117 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 126 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
127 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
118 break; 128 break;
119 case 0xac: 129 case 0xac:
120 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 130 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -124,6 +134,7 @@ nv50_identify(struct nouveau_device *device)
124 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 134 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
125 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 135 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
126 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 136 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
137 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
127 break; 138 break;
128 case 0xa3: 139 case 0xa3:
129 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 140 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -133,6 +144,7 @@ nv50_identify(struct nouveau_device *device)
133 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 144 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
134 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 145 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
135 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 146 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
147 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
136 break; 148 break;
137 case 0xa5: 149 case 0xa5:
138 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 150 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -142,6 +154,7 @@ nv50_identify(struct nouveau_device *device)
142 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 154 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
143 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 155 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
144 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 156 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
157 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
145 break; 158 break;
146 case 0xa8: 159 case 0xa8:
147 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 160 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -151,6 +164,7 @@ nv50_identify(struct nouveau_device *device)
151 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 164 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
152 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 165 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
153 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 166 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
167 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
154 break; 168 break;
155 case 0xaf: 169 case 0xaf:
156 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 170 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -160,6 +174,7 @@ nv50_identify(struct nouveau_device *device)
160 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 174 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
161 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 175 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
162 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 176 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
177 device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
163 break; 178 break;
164 default: 179 default:
165 nv_fatal(device, "unknown Tesla chipset\n"); 180 nv_fatal(device, "unknown Tesla chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
index 56d1950c9b77..8de67307eea7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
@@ -30,6 +30,8 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
34#include <subdev/ltcg.h>
33 35
34int 36int
35nvc0_identify(struct nouveau_device *device) 37nvc0_identify(struct nouveau_device *device)
@@ -43,6 +45,8 @@ nvc0_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 45 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 46 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 47 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
48 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
49 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
46 break; 50 break;
47 case 0xc4: 51 case 0xc4:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 52 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +56,8 @@ nvc0_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 56 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 57 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 58 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
59 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
60 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
55 break; 61 break;
56 case 0xc3: 62 case 0xc3:
57 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 63 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -61,6 +67,8 @@ nvc0_identify(struct nouveau_device *device)
61 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 67 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
62 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 68 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
63 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 69 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
70 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
71 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
64 break; 72 break;
65 case 0xce: 73 case 0xce:
66 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 74 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -70,6 +78,8 @@ nvc0_identify(struct nouveau_device *device)
70 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 78 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
71 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 79 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
72 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 80 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
81 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
82 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
73 break; 83 break;
74 case 0xcf: 84 case 0xcf:
75 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 85 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -79,6 +89,8 @@ nvc0_identify(struct nouveau_device *device)
79 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 89 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
80 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 90 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
81 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 91 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
92 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
93 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
82 break; 94 break;
83 case 0xc1: 95 case 0xc1:
84 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 96 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -88,6 +100,8 @@ nvc0_identify(struct nouveau_device *device)
88 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 100 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
89 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 101 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
90 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 102 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
103 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
104 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
91 break; 105 break;
92 case 0xc8: 106 case 0xc8:
93 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 107 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -97,6 +111,8 @@ nvc0_identify(struct nouveau_device *device)
97 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 111 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
98 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 112 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
99 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 113 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
114 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
115 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
100 break; 116 break;
101 case 0xd9: 117 case 0xd9:
102 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 118 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -106,6 +122,8 @@ nvc0_identify(struct nouveau_device *device)
106 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 122 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
107 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 123 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
108 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 124 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
125 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
126 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
109 break; 127 break;
110 default: 128 default:
111 nv_fatal(device, "unknown Fermi chipset\n"); 129 nv_fatal(device, "unknown Fermi chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
index ab5e05291465..919a10280d7e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
@@ -30,6 +30,8 @@
30#include <subdev/devinit.h> 30#include <subdev/devinit.h>
31#include <subdev/mc.h> 31#include <subdev/mc.h>
32#include <subdev/timer.h> 32#include <subdev/timer.h>
33#include <subdev/fb.h>
34#include <subdev/ltcg.h>
33 35
34int 36int
35nve0_identify(struct nouveau_device *device) 37nve0_identify(struct nouveau_device *device)
@@ -43,6 +45,8 @@ nve0_identify(struct nouveau_device *device)
43 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 45 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
44 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 46 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
45 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 47 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
48 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
49 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
46 break; 50 break;
47 case 0xe7: 51 case 0xe7:
48 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 52 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -52,6 +56,8 @@ nve0_identify(struct nouveau_device *device)
52 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 56 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
53 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; 57 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
54 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; 58 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
59 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
60 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
55 break; 61 break;
56 default: 62 default:
57 nv_fatal(device, "unknown Kepler chipset\n"); 63 nv_fatal(device, "unknown Kepler chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
new file mode 100644
index 000000000000..f0086de8af31
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
@@ -0,0 +1,130 @@
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 "subdev/fb.h"
26#include "subdev/bios.h"
27#include "subdev/bios/bit.h"
28
29int
30nouveau_fb_bios_memtype(struct nouveau_bios *bios)
31{
32 struct bit_entry M;
33 u8 ramcfg;
34
35 ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
36 if (!bit_entry(bios, 'M', &M) && M.version == 2 && M.length >= 5) {
37 u16 table = nv_ro16(bios, M.offset + 3);
38 u8 version = nv_ro08(bios, table + 0);
39 u8 header = nv_ro08(bios, table + 1);
40 u8 record = nv_ro08(bios, table + 2);
41 u8 entries = nv_ro08(bios, table + 3);
42 if (table && version == 0x10 && ramcfg < entries) {
43 u16 entry = table + header + (ramcfg * record);
44 switch (nv_ro08(bios, entry) & 0x0f) {
45 case 0: return NV_MEM_TYPE_DDR2;
46 case 1: return NV_MEM_TYPE_DDR3;
47 case 2: return NV_MEM_TYPE_GDDR3;
48 case 3: return NV_MEM_TYPE_GDDR5;
49 default:
50 break;
51 }
52
53 }
54 }
55
56 return NV_MEM_TYPE_UNKNOWN;
57}
58
59int
60nouveau_fb_init(struct nouveau_fb *pfb)
61{
62 int ret, i;
63
64 ret = nouveau_subdev_init(&pfb->base);
65 if (ret)
66 return ret;
67
68 for (i = 0; i < pfb->tile.regions; i++)
69 pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
70
71 return 0;
72}
73
74int
75_nouveau_fb_init(struct nouveau_object *object)
76{
77 struct nouveau_fb *pfb = (void *)object;
78 return nouveau_fb_init(pfb);
79}
80
81void
82nouveau_fb_destroy(struct nouveau_fb *pfb)
83{
84 int i;
85
86 for (i = 0; i < pfb->tile.regions; i++)
87 pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
88
89 if (pfb->tags.block_size)
90 nouveau_mm_fini(&pfb->tags);
91
92 if (pfb->vram.block_size)
93 nouveau_mm_fini(&pfb->vram);
94
95 nouveau_subdev_destroy(&pfb->base);
96}
97
98void
99_nouveau_fb_dtor(struct nouveau_object *object)
100{
101 struct nouveau_fb *pfb = (void *)object;
102 nouveau_fb_destroy(pfb);
103}
104
105int
106nouveau_fb_created(struct nouveau_fb *pfb)
107{
108 static const char *name[] = {
109 [NV_MEM_TYPE_UNKNOWN] = "unknown",
110 [NV_MEM_TYPE_STOLEN ] = "stolen system memory",
111 [NV_MEM_TYPE_SGRAM ] = "SGRAM",
112 [NV_MEM_TYPE_SDRAM ] = "SDRAM",
113 [NV_MEM_TYPE_DDR1 ] = "DDR1",
114 [NV_MEM_TYPE_DDR2 ] = "DDR2",
115 [NV_MEM_TYPE_DDR3 ] = "DDR3",
116 [NV_MEM_TYPE_GDDR2 ] = "GDDR2",
117 [NV_MEM_TYPE_GDDR3 ] = "GDDR3",
118 [NV_MEM_TYPE_GDDR4 ] = "GDDR4",
119 [NV_MEM_TYPE_GDDR5 ] = "GDDR5",
120 };
121
122 if (pfb->ram.size == 0) {
123 nv_fatal(pfb, "no vram detected!!\n");
124 return -ERANGE;
125 }
126
127 nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
128 nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
129 return 0;
130}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
index eef48440fbec..eb06836b69f7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
@@ -1,55 +1,130 @@
1#include "drmP.h" 1/*
2#include "drm.h" 2 * Copyright 2012 Red Hat Inc.
3#include "nouveau_drv.h" 3 *
4#include <nouveau_drm.h> 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 */
5 24
6int 25#include <subdev/fb.h>
7nv04_fb_vram_init(struct drm_device *dev) 26
27#define NV04_PFB_BOOT_0 0x00100000
28# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
29# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
30# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
31# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
32# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
33# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
34# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
35# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
36# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
37# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
38# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
39# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
40# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
41# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
42# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
43#define NV04_PFB_CFG0 0x00100200
44
45struct nv04_fb_priv {
46 struct nouveau_fb base;
47};
48
49bool
50nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
51{
52 if (!(tile_flags & 0xff00))
53 return true;
54
55 return false;
56}
57
58static int
59nv04_fb_init(struct nouveau_object *object)
8{ 60{
9 struct drm_nouveau_private *dev_priv = dev->dev_private; 61 struct nv04_fb_priv *priv = (void *)object;
10 u32 boot0 = nv_rd32(dev, NV04_PFB_BOOT_0); 62 int ret;
63
64 ret = nouveau_fb_init(&priv->base);
65 if (ret)
66 return ret;
67
68 /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
69 * nvidia reading PFB_CFG_0, then writing back its original value.
70 * (which was 0x701114 in this case)
71 */
72 nv_wr32(priv, NV04_PFB_CFG0, 0x1114);
73 return 0;
74}
11 75
76static int
77nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
78 struct nouveau_oclass *oclass, void *data, u32 size,
79 struct nouveau_object **pobject)
80{
81 struct nv04_fb_priv *priv;
82 u32 boot0;
83 int ret;
84
85 ret = nouveau_fb_create(parent, engine, oclass, &priv);
86 *pobject = nv_object(priv);
87 if (ret)
88 return ret;
89
90 boot0 = nv_rd32(priv, NV04_PFB_BOOT_0);
12 if (boot0 & 0x00000100) { 91 if (boot0 & 0x00000100) {
13 dev_priv->vram_size = ((boot0 >> 12) & 0xf) * 2 + 2; 92 priv->base.ram.size = ((boot0 >> 12) & 0xf) * 2 + 2;
14 dev_priv->vram_size *= 1024 * 1024; 93 priv->base.ram.size *= 1024 * 1024;
15 } else { 94 } else {
16 switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) { 95 switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
17 case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB: 96 case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
18 dev_priv->vram_size = 32 * 1024 * 1024; 97 priv->base.ram.size = 32 * 1024 * 1024;
19 break; 98 break;
20 case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB: 99 case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
21 dev_priv->vram_size = 16 * 1024 * 1024; 100 priv->base.ram.size = 16 * 1024 * 1024;
22 break; 101 break;
23 case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB: 102 case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
24 dev_priv->vram_size = 8 * 1024 * 1024; 103 priv->base.ram.size = 8 * 1024 * 1024;
25 break; 104 break;
26 case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB: 105 case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
27 dev_priv->vram_size = 4 * 1024 * 1024; 106 priv->base.ram.size = 4 * 1024 * 1024;
28 break; 107 break;
29 } 108 }
30 } 109 }
31 110
32 if ((boot0 & 0x00000038) <= 0x10) 111 if ((boot0 & 0x00000038) <= 0x10)
33 dev_priv->vram_type = NV_MEM_TYPE_SGRAM; 112 priv->base.ram.type = NV_MEM_TYPE_SGRAM;
34 else 113 else
35 dev_priv->vram_type = NV_MEM_TYPE_SDRAM; 114 priv->base.ram.type = NV_MEM_TYPE_SDRAM;
36 115
37 return 0;
38}
39
40int
41nv04_fb_init(struct drm_device *dev)
42{
43 /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
44 * nvidia reading PFB_CFG_0, then writing back its original value.
45 * (which was 0x701114 in this case)
46 */
47 116
48 nv_wr32(dev, NV04_PFB_CFG0, 0x1114); 117 priv->base.memtype_valid = nv04_fb_memtype_valid;
49 return 0; 118 return nouveau_fb_created(&priv->base);
50} 119}
51 120
52void 121struct nouveau_oclass
53nv04_fb_takedown(struct drm_device *dev) 122nv04_fb_oclass = {
54{ 123 .handle = NV_SUBDEV(FB, 0x04),
55} 124 .ofuncs = &(struct nouveau_ofuncs) {
125 .ctor = nv04_fb_ctor,
126 .dtor = _nouveau_fb_dtor,
127 .init = nv04_fb_init,
128 .fini = _nouveau_fb_fini,
129 },
130};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
index 09af63b55f59..f037a422d2f4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
@@ -1,104 +1,120 @@
1#include "drmP.h" 1/*
2#include "drm.h" 2 * Copyright (C) 2010 Francisco Jerez.
3#include "nouveau_drv.h" 3 * All Rights Reserved.
4#include <nouveau_drm.h> 4 *
5 5 * Permission is hereby granted, free of charge, to any person obtaining
6void 6 * a copy of this software and associated documentation files (the
7nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, 7 * "Software"), to deal in the Software without restriction, including
8 uint32_t size, uint32_t pitch, uint32_t flags) 8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include <subdev/fb.h>
28
29struct nv10_fb_priv {
30 struct nouveau_fb base;
31};
32
33static void
34nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
35 u32 flags, struct nouveau_fb_tile *tile)
9{ 36{
10 struct drm_nouveau_private *dev_priv = dev->dev_private;
11 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
12
13 tile->addr = 0x80000000 | addr; 37 tile->addr = 0x80000000 | addr;
14 tile->limit = max(1u, addr + size) - 1; 38 tile->limit = max(1u, addr + size) - 1;
15 tile->pitch = pitch; 39 tile->pitch = pitch;
16} 40}
17 41
18void 42static void
19nv10_fb_free_tile_region(struct drm_device *dev, int i) 43nv10_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
20{ 44{
21 struct drm_nouveau_private *dev_priv = dev->dev_private; 45 tile->addr = 0;
22 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 46 tile->limit = 0;
23 47 tile->pitch = 0;
24 tile->addr = tile->limit = tile->pitch = tile->zcomp = 0; 48 tile->zcomp = 0;
25} 49}
26 50
27void 51void
28nv10_fb_set_tile_region(struct drm_device *dev, int i) 52nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
29{ 53{
30 struct drm_nouveau_private *dev_priv = dev->dev_private; 54 nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
31 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 55 nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
32 56 nv_wr32(pfb, 0x100240 + (i * 0x10), tile->addr);
33 nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
34 nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
35 nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
36} 57}
37 58
38int 59static int
39nv1a_fb_vram_init(struct drm_device *dev) 60nv10_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
61 struct nouveau_oclass *oclass, void *data, u32 size,
62 struct nouveau_object **pobject)
40{ 63{
41 struct drm_nouveau_private *dev_priv = dev->dev_private; 64 struct nouveau_device *device = nv_device(parent);
42 struct pci_dev *bridge; 65 struct nv10_fb_priv *priv;
43 uint32_t mem, mib; 66 int ret;
44 67
45 bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1)); 68 ret = nouveau_fb_create(parent, engine, oclass, &priv);
46 if (!bridge) { 69 *pobject = nv_object(priv);
47 NV_ERROR(dev, "no bridge device\n"); 70 if (ret)
48 return 0; 71 return ret;
49 } 72
50 73 if (device->chipset == 0x1a || device->chipset == 0x1f) {
51 if (dev_priv->chipset == 0x1a) { 74 struct pci_dev *bridge;
52 pci_read_config_dword(bridge, 0x7c, &mem); 75 u32 mem, mib;
53 mib = ((mem >> 6) & 31) + 1; 76
77 bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
78 if (!bridge) {
79 nv_fatal(device, "no bridge device\n");
80 return 0;
81 }
82
83 if (device->chipset == 0x1a) {
84 pci_read_config_dword(bridge, 0x7c, &mem);
85 mib = ((mem >> 6) & 31) + 1;
86 } else {
87 pci_read_config_dword(bridge, 0x84, &mem);
88 mib = ((mem >> 4) & 127) + 1;
89 }
90
91 priv->base.ram.type = NV_MEM_TYPE_STOLEN;
92 priv->base.ram.size = mib * 1024 * 1024;
54 } else { 93 } else {
55 pci_read_config_dword(bridge, 0x84, &mem); 94 u32 cfg0 = nv_rd32(priv, 0x100200);
56 mib = ((mem >> 4) & 127) + 1; 95 if (cfg0 & 0x00000001)
57 } 96 priv->base.ram.type = NV_MEM_TYPE_DDR1;
97 else
98 priv->base.ram.type = NV_MEM_TYPE_SDRAM;
58 99
59 dev_priv->vram_size = mib * 1024 * 1024; 100 priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
60 return 0; 101 }
61}
62
63int
64nv10_fb_vram_init(struct drm_device *dev)
65{
66 struct drm_nouveau_private *dev_priv = dev->dev_private;
67 u32 fifo_data = nv_rd32(dev, NV04_PFB_FIFO_DATA);
68 u32 cfg0 = nv_rd32(dev, 0x100200);
69
70 dev_priv->vram_size = fifo_data & NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
71
72 if (cfg0 & 0x00000001)
73 dev_priv->vram_type = NV_MEM_TYPE_DDR1;
74 else
75 dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
76
77 return 0;
78}
79
80int
81nv10_fb_init(struct drm_device *dev)
82{
83 struct drm_nouveau_private *dev_priv = dev->dev_private;
84 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
85 int i;
86
87 /* Turn all the tiling regions off. */
88 pfb->num_tiles = NV10_PFB_TILE__SIZE;
89 for (i = 0; i < pfb->num_tiles; i++)
90 pfb->set_tile_region(dev, i);
91 102
92 return 0; 103 priv->base.memtype_valid = nv04_fb_memtype_valid;
104 priv->base.tile.regions = 8;
105 priv->base.tile.init = nv10_fb_tile_init;
106 priv->base.tile.fini = nv10_fb_tile_fini;
107 priv->base.tile.prog = nv10_fb_tile_prog;
108 return nouveau_fb_created(&priv->base);
93} 109}
94 110
95void 111struct nouveau_oclass
96nv10_fb_takedown(struct drm_device *dev) 112nv10_fb_oclass = {
97{ 113 .handle = NV_SUBDEV(FB, 0x10),
98 struct drm_nouveau_private *dev_priv = dev->dev_private; 114 .ofuncs = &(struct nouveau_ofuncs) {
99 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 115 .ctor = nv10_fb_ctor,
100 int i; 116 .dtor = _nouveau_fb_dtor,
101 117 .init = _nouveau_fb_init,
102 for (i = 0; i < pfb->num_tiles; i++) 118 .fini = _nouveau_fb_fini,
103 pfb->free_tile_region(dev, i); 119 },
104} 120};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
index a7f056c367e4..4b3578fcb7fb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
@@ -1,49 +1,41 @@
1#include "drmP.h" 1/*
2#include "drm.h" 2 * Copyright (C) 2010 Francisco Jerez.
3#include "nouveau_drv.h" 3 * All Rights Reserved.
4#include <nouveau_drm.h> 4 *
5 5 * Permission is hereby granted, free of charge, to any person obtaining
6static struct drm_mm_node * 6 * a copy of this software and associated documentation files (the
7nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size) 7 * "Software"), to deal in the Software without restriction, including
8{ 8 * without limitation the rights to use, copy, modify, merge, publish,
9 struct drm_nouveau_private *dev_priv = dev->dev_private; 9 * distribute, sublicense, and/or sell copies of the Software, and to
10 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 10 * permit persons to whom the Software is furnished to do so, subject to
11 struct drm_mm_node *mem; 11 * the following conditions:
12 int ret; 12 *
13 13 * The above copyright notice and this permission notice (including the
14 ret = drm_mm_pre_get(&pfb->tag_heap); 14 * next paragraph) shall be included in all copies or substantial
15 if (ret) 15 * portions of the Software.
16 return NULL; 16 *
17 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 spin_lock(&dev_priv->tile.lock); 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0); 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 if (mem) 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 mem = drm_mm_get_block_atomic(mem, size, 0); 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 spin_unlock(&dev_priv->tile.lock); 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 return mem; 24 *
25} 25 */
26
27#include <subdev/fb.h>
28
29struct nv20_fb_priv {
30 struct nouveau_fb base;
31};
26 32
27static void 33static void
28nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node **pmem) 34nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
35 u32 flags, struct nouveau_fb_tile *tile)
29{ 36{
30 struct drm_nouveau_private *dev_priv = dev->dev_private; 37 struct nouveau_device *device = nv_device(pfb);
31 struct drm_mm_node *mem = *pmem; 38 int bpp = (flags & 2) ? 32 : 16;
32 if (mem) {
33 spin_lock(&dev_priv->tile.lock);
34 drm_mm_put_block(mem);
35 spin_unlock(&dev_priv->tile.lock);
36 *pmem = NULL;
37 }
38}
39
40void
41nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
42 uint32_t size, uint32_t pitch, uint32_t flags)
43{
44 struct drm_nouveau_private *dev_priv = dev->dev_private;
45 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
46 int bpp = (flags & NOUVEAU_GEM_TILE_32BPP ? 32 : 16);
47 39
48 tile->addr = 0x00000001 | addr; 40 tile->addr = 0x00000001 | addr;
49 tile->limit = max(1u, addr + size) - 1; 41 tile->limit = max(1u, addr + size) - 1;
@@ -53,20 +45,20 @@ nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
53 * compression meta-data (most likely just a bitmap determining 45 * compression meta-data (most likely just a bitmap determining
54 * if a given tile is compressed or not). 46 * if a given tile is compressed or not).
55 */ 47 */
56 if (flags & NOUVEAU_GEM_TILE_ZETA) { 48 size /= 256;
57 tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256); 49 if (flags & 4) {
58 if (tile->tag_mem) { 50 if (!nouveau_mm_head(&pfb->tags, 1, size, size, 1, &tile->tag)) {
59 /* Enable Z compression */ 51 /* Enable Z compression */
60 tile->zcomp = tile->tag_mem->start; 52 tile->zcomp = tile->tag->offset;
61 if (dev_priv->chipset >= 0x25) { 53 if (device->chipset >= 0x25) {
62 if (bpp == 16) 54 if (bpp == 16)
63 tile->zcomp |= NV25_PFB_ZCOMP_MODE_16; 55 tile->zcomp |= 0x00100000;
64 else 56 else
65 tile->zcomp |= NV25_PFB_ZCOMP_MODE_32; 57 tile->zcomp |= 0x00200000;
66 } else { 58 } else {
67 tile->zcomp |= NV20_PFB_ZCOMP_EN; 59 tile->zcomp |= 0x80000000;
68 if (bpp != 16) 60 if (bpp != 16)
69 tile->zcomp |= NV20_PFB_ZCOMP_MODE_32; 61 tile->zcomp |= 0x04000000;
70 } 62 }
71 } 63 }
72 64
@@ -74,75 +66,71 @@ nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
74 } 66 }
75} 67}
76 68
77void 69static void
78nv20_fb_free_tile_region(struct drm_device *dev, int i) 70nv20_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
79{ 71{
80 struct drm_nouveau_private *dev_priv = dev->dev_private; 72 tile->addr = 0;
81 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 73 tile->limit = 0;
82 74 tile->pitch = 0;
83 tile->addr = tile->limit = tile->pitch = tile->zcomp = 0; 75 tile->zcomp = 0;
84 nv20_fb_free_tag(dev, &tile->tag_mem); 76 nouveau_mm_free(&pfb->tags, &tile->tag);
85} 77}
86 78
87void 79static void
88nv20_fb_set_tile_region(struct drm_device *dev, int i) 80nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
89{ 81{
90 struct drm_nouveau_private *dev_priv = dev->dev_private; 82 nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
91 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 83 nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
92 84 nv_wr32(pfb, 0x100240 + (i * 0x10), tile->addr);
93 nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); 85 nv_wr32(pfb, 0x100300 + (i * 0x04), tile->zcomp);
94 nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
95 nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
96 nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp);
97} 86}
98 87
99int 88static int
100nv20_fb_vram_init(struct drm_device *dev) 89nv20_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
90 struct nouveau_oclass *oclass, void *data, u32 size,
91 struct nouveau_object **pobject)
101{ 92{
102 struct drm_nouveau_private *dev_priv = dev->dev_private; 93 struct nouveau_device *device = nv_device(parent);
103 u32 mem_size = nv_rd32(dev, 0x10020c); 94 struct nv20_fb_priv *priv;
104 u32 pbus1218 = nv_rd32(dev, 0x001218); 95 u32 pbus1218;
96 int ret;
97
98 ret = nouveau_fb_create(parent, engine, oclass, &priv);
99 *pobject = nv_object(priv);
100 if (ret)
101 return ret;
105 102
106 dev_priv->vram_size = mem_size & 0xff000000; 103 pbus1218 = nv_rd32(priv, 0x001218);
107 switch (pbus1218 & 0x00000300) { 104 switch (pbus1218 & 0x00000300) {
108 case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; 105 case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
109 case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; 106 case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
110 case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; 107 case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
111 case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_GDDR2; break; 108 case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_GDDR2; break;
112 } 109 }
110 priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
113 111
114 return 0; 112 if (device->chipset >= 0x25)
115} 113 ret = nouveau_mm_init(&priv->base.tags, 0, 64 * 1024, 1);
116
117int
118nv20_fb_init(struct drm_device *dev)
119{
120 struct drm_nouveau_private *dev_priv = dev->dev_private;
121 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
122 int i;
123
124 if (dev_priv->chipset >= 0x25)
125 drm_mm_init(&pfb->tag_heap, 0, 64 * 1024);
126 else 114 else
127 drm_mm_init(&pfb->tag_heap, 0, 32 * 1024); 115 ret = nouveau_mm_init(&priv->base.tags, 0, 32 * 1024, 1);
128 116 if (ret)
129 /* Turn all the tiling regions off. */ 117 return ret;
130 pfb->num_tiles = NV10_PFB_TILE__SIZE; 118
131 for (i = 0; i < pfb->num_tiles; i++) 119 priv->base.memtype_valid = nv04_fb_memtype_valid;
132 pfb->set_tile_region(dev, i); 120 priv->base.tile.regions = 8;
133 121 priv->base.tile.init = nv20_fb_tile_init;
134 return 0; 122 priv->base.tile.fini = nv20_fb_tile_fini;
123 priv->base.tile.prog = nv20_fb_tile_prog;
124 return nouveau_fb_created(&priv->base);
135} 125}
136 126
137void 127struct nouveau_oclass
138nv20_fb_takedown(struct drm_device *dev) 128nv20_fb_oclass = {
139{ 129 .handle = NV_SUBDEV(FB, 0x20),
140 struct drm_nouveau_private *dev_priv = dev->dev_private; 130 .ofuncs = &(struct nouveau_ofuncs) {
141 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 131 .ctor = nv20_fb_ctor,
142 int i; 132 .dtor = _nouveau_fb_dtor,
143 133 .init = _nouveau_fb_init,
144 for (i = 0; i < pfb->num_tiles; i++) 134 .fini = _nouveau_fb_fini,
145 pfb->free_tile_region(dev, i); 135 },
146 136};
147 drm_mm_takedown(&pfb->tag_heap);
148}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
index 30639a065273..cba67bc91390 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
@@ -24,50 +24,47 @@
24 * 24 *
25 */ 25 */
26 26
27#include "drmP.h" 27#include <subdev/fb.h>
28#include "drm.h" 28
29#include "nouveau_drv.h" 29struct nv30_fb_priv {
30#include <nouveau_drm.h> 30 struct nouveau_fb base;
31};
31 32
32void 33void
33nv30_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, 34nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
34 uint32_t size, uint32_t pitch, uint32_t flags) 35 u32 flags, struct nouveau_fb_tile *tile)
35{ 36{
36 struct drm_nouveau_private *dev_priv = dev->dev_private;
37 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
38
39 tile->addr = addr | 1; 37 tile->addr = addr | 1;
40 tile->limit = max(1u, addr + size) - 1; 38 tile->limit = max(1u, addr + size) - 1;
41 tile->pitch = pitch; 39 tile->pitch = pitch;
42} 40}
43 41
44void 42void
45nv30_fb_free_tile_region(struct drm_device *dev, int i) 43nv30_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
46{ 44{
47 struct drm_nouveau_private *dev_priv = dev->dev_private; 45 tile->addr = 0;
48 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 46 tile->limit = 0;
49 47 tile->pitch = 0;
50 tile->addr = tile->limit = tile->pitch = 0;
51} 48}
52 49
53static int 50static int
54calc_bias(struct drm_device *dev, int k, int i, int j) 51calc_bias(struct nv30_fb_priv *priv, int k, int i, int j)
55{ 52{
56 struct drm_nouveau_private *dev_priv = dev->dev_private; 53 struct nouveau_device *device = nv_device(priv);
57 int b = (dev_priv->chipset > 0x30 ? 54 int b = (device->chipset > 0x30 ?
58 nv_rd32(dev, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) : 55 nv_rd32(priv, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
59 0) & 0xf; 56 0) & 0xf;
60 57
61 return 2 * (b & 0x8 ? b - 0x10 : b); 58 return 2 * (b & 0x8 ? b - 0x10 : b);
62} 59}
63 60
64static int 61static int
65calc_ref(struct drm_device *dev, int l, int k, int i) 62calc_ref(struct nv30_fb_priv *priv, int l, int k, int i)
66{ 63{
67 int j, x = 0; 64 int j, x = 0;
68 65
69 for (j = 0; j < 4; j++) { 66 for (j = 0; j < 4; j++) {
70 int m = (l >> (8 * i) & 0xff) + calc_bias(dev, k, i, j); 67 int m = (l >> (8 * i) & 0xff) + calc_bias(priv, k, i, j);
71 68
72 x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j); 69 x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j);
73 } 70 }
@@ -75,42 +72,77 @@ calc_ref(struct drm_device *dev, int l, int k, int i)
75 return x; 72 return x;
76} 73}
77 74
78int 75static int
79nv30_fb_init(struct drm_device *dev) 76nv30_fb_init(struct nouveau_object *object)
80{ 77{
81 struct drm_nouveau_private *dev_priv = dev->dev_private; 78 struct nouveau_device *device = nv_device(object);
82 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 79 struct nv30_fb_priv *priv = (void *)object;
83 int i, j; 80 int ret, i, j;
84
85 pfb->num_tiles = NV10_PFB_TILE__SIZE;
86 81
87 /* Turn all the tiling regions off. */ 82 ret = nouveau_fb_init(&priv->base);
88 for (i = 0; i < pfb->num_tiles; i++) 83 if (ret)
89 pfb->set_tile_region(dev, i); 84 return ret;
90 85
91 /* Init the memory timing regs at 0x10037c/0x1003ac */ 86 /* Init the memory timing regs at 0x10037c/0x1003ac */
92 if (dev_priv->chipset == 0x30 || 87 if (device->chipset == 0x30 ||
93 dev_priv->chipset == 0x31 || 88 device->chipset == 0x31 ||
94 dev_priv->chipset == 0x35) { 89 device->chipset == 0x35) {
95 /* Related to ROP count */ 90 /* Related to ROP count */
96 int n = (dev_priv->chipset == 0x31 ? 2 : 4); 91 int n = (device->chipset == 0x31 ? 2 : 4);
97 int l = nv_rd32(dev, 0x1003d0); 92 int l = nv_rd32(priv, 0x1003d0);
98 93
99 for (i = 0; i < n; i++) { 94 for (i = 0; i < n; i++) {
100 for (j = 0; j < 3; j++) 95 for (j = 0; j < 3; j++)
101 nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j, 96 nv_wr32(priv, 0x10037c + 0xc * i + 0x4 * j,
102 calc_ref(dev, l, 0, j)); 97 calc_ref(priv, l, 0, j));
103 98
104 for (j = 0; j < 2; j++) 99 for (j = 0; j < 2; j++)
105 nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j, 100 nv_wr32(priv, 0x1003ac + 0x8 * i + 0x4 * j,
106 calc_ref(dev, l, 1, j)); 101 calc_ref(priv, l, 1, j));
107 } 102 }
108 } 103 }
109 104
110 return 0; 105 return 0;
111} 106}
112 107
113void 108static int
114nv30_fb_takedown(struct drm_device *dev) 109nv30_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
110 struct nouveau_oclass *oclass, void *data, u32 size,
111 struct nouveau_object **pobject)
115{ 112{
113 struct nv30_fb_priv *priv;
114 u32 pbus1218;
115 int ret;
116
117 ret = nouveau_fb_create(parent, engine, oclass, &priv);
118 *pobject = nv_object(priv);
119 if (ret)
120 return ret;
121
122 pbus1218 = nv_rd32(priv, 0x001218);
123 switch (pbus1218 & 0x00000300) {
124 case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
125 case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
126 case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
127 case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_GDDR2; break;
128 }
129 priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
130
131 priv->base.memtype_valid = nv04_fb_memtype_valid;
132 priv->base.tile.regions = 8;
133 priv->base.tile.init = nv30_fb_tile_init;
134 priv->base.tile.fini = nv30_fb_tile_fini;
135 priv->base.tile.prog = nv10_fb_tile_prog;
136 return nouveau_fb_created(&priv->base);
116} 137}
138
139struct nouveau_oclass
140nv30_fb_oclass = {
141 .handle = NV_SUBDEV(FB, 0x30),
142 .ofuncs = &(struct nouveau_ofuncs) {
143 .ctor = nv30_fb_ctor,
144 .dtor = _nouveau_fb_dtor,
145 .init = nv30_fb_init,
146 .fini = _nouveau_fb_fini,
147 },
148};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
index e08c2e1c8f1f..84aa71c47128 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
@@ -1,55 +1,83 @@
1#include "drmP.h" 1/*
2#include "drm.h" 2 * Copyright (C) 2010 Francisco Jerez.
3#include "nouveau_drv.h" 3 * All Rights Reserved.
4#include <nouveau_drm.h> 4 *
5 5 * Permission is hereby granted, free of charge, to any person obtaining
6void 6 * a copy of this software and associated documentation files (the
7nv40_fb_set_tile_region(struct drm_device *dev, int i) 7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include <subdev/fb.h>
28
29struct nv40_fb_priv {
30 struct nouveau_fb base;
31};
32
33static inline int
34nv44_graph_class(struct nouveau_device *device)
8{ 35{
9 struct drm_nouveau_private *dev_priv = dev->dev_private; 36 if ((device->chipset & 0xf0) == 0x60)
10 struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; 37 return 1;
11 38
12 switch (dev_priv->chipset) { 39 return !(0x0baf & (1 << (device->chipset & 0x0f)));
13 case 0x40: 40}
14 nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
15 nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
16 nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
17 break;
18 41
19 default: 42static void
20 nv_wr32(dev, NV40_PFB_TLIMIT(i), tile->limit); 43nv40_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
21 nv_wr32(dev, NV40_PFB_TSIZE(i), tile->pitch); 44{
22 nv_wr32(dev, NV40_PFB_TILE(i), tile->addr); 45 nv_wr32(pfb, 0x100604 + (i * 0x10), tile->limit);
23 break; 46 nv_wr32(pfb, 0x100608 + (i * 0x10), tile->pitch);
24 } 47 nv_wr32(pfb, 0x100600 + (i * 0x10), tile->addr);
25} 48}
26 49
27static void 50static void
28nv40_fb_init_gart(struct drm_device *dev) 51nv40_fb_init_gart(struct nv40_fb_priv *priv)
29{ 52{
30 struct drm_nouveau_private *dev_priv = dev->dev_private; 53#if 0
31 struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; 54 struct nouveau_gpuobj *gart = ndev->gart_info.sg_ctxdma;
32 55
33 if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { 56 if (ndev->gart_info.type != NOUVEAU_GART_HW) {
34 nv_wr32(dev, 0x100800, 0x00000001); 57#endif
58 nv_wr32(priv, 0x100800, 0x00000001);
59#if 0
35 return; 60 return;
36 } 61 }
37 62
38 nv_wr32(dev, 0x100800, gart->pinst | 0x00000002); 63 nv_wr32(ndev, 0x100800, gart->pinst | 0x00000002);
39 nv_mask(dev, 0x10008c, 0x00000100, 0x00000100); 64 nv_mask(ndev, 0x10008c, 0x00000100, 0x00000100);
40 nv_wr32(dev, 0x100820, 0x00000000); 65 nv_wr32(ndev, 0x100820, 0x00000000);
66#endif
41} 67}
42 68
43static void 69static void
44nv44_fb_init_gart(struct drm_device *dev) 70nv44_fb_init_gart(struct nv40_fb_priv *priv)
45{ 71{
46 struct drm_nouveau_private *dev_priv = dev->dev_private; 72#if 0
47 struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; 73 struct nouveau_gpuobj *gart = ndev->gart_info.sg_ctxdma;
48 u32 vinst; 74 u32 vinst;
49 75
50 if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { 76 if (ndev->gart_info.type != NOUVEAU_GART_HW) {
51 nv_wr32(dev, 0x100850, 0x80000000); 77#endif
52 nv_wr32(dev, 0x100800, 0x00000001); 78 nv_wr32(priv, 0x100850, 0x80000000);
79 nv_wr32(priv, 0x100800, 0x00000001);
80#if 0
53 return; 81 return;
54 } 82 }
55 83
@@ -57,24 +85,60 @@ nv44_fb_init_gart(struct drm_device *dev)
57 * must be allocated on 512KiB alignment, and not exceed 85 * must be allocated on 512KiB alignment, and not exceed
58 * a total size of 512KiB for this to work correctly 86 * a total size of 512KiB for this to work correctly
59 */ 87 */
60 vinst = nv_rd32(dev, 0x10020c); 88 vinst = nv_rd32(ndev, 0x10020c);
61 vinst -= ((gart->pinst >> 19) + 1) << 19; 89 vinst -= ((gart->pinst >> 19) + 1) << 19;
62 90
63 nv_wr32(dev, 0x100850, 0x80000000); 91 nv_wr32(ndev, 0x100850, 0x80000000);
64 nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr); 92 nv_wr32(ndev, 0x100818, ndev->gart_info.dummy.addr);
93
94 nv_wr32(ndev, 0x100804, ndev->gart_info.aper_size);
95 nv_wr32(ndev, 0x100850, 0x00008000);
96 nv_mask(ndev, 0x10008c, 0x00000200, 0x00000200);
97 nv_wr32(ndev, 0x100820, 0x00000000);
98 nv_wr32(ndev, 0x10082c, 0x00000001);
99 nv_wr32(ndev, 0x100800, vinst | 0x00000010);
100#endif
101}
102
103static int
104nv40_fb_init(struct nouveau_object *object)
105{
106 struct nv40_fb_priv *priv = (void *)object;
107 int ret;
108
109 ret = nouveau_fb_init(&priv->base);
110 if (ret)
111 return ret;
112
113 switch (nv_device(priv)->chipset) {
114 case 0x40:
115 case 0x45:
116 nv_mask(priv, 0x10033c, 0x00008000, 0x00000000);
117 break;
118 default:
119 if (nv44_graph_class(nv_device(priv)))
120 nv44_fb_init_gart(priv);
121 else
122 nv40_fb_init_gart(priv);
123 break;
124 }
65 125
66 nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size); 126 return 0;
67 nv_wr32(dev, 0x100850, 0x00008000);
68 nv_mask(dev, 0x10008c, 0x00000200, 0x00000200);
69 nv_wr32(dev, 0x100820, 0x00000000);
70 nv_wr32(dev, 0x10082c, 0x00000001);
71 nv_wr32(dev, 0x100800, vinst | 0x00000010);
72} 127}
73 128
74int 129static int
75nv40_fb_vram_init(struct drm_device *dev) 130nv40_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
131 struct nouveau_oclass *oclass, void *data, u32 size,
132 struct nouveau_object **pobject)
76{ 133{
77 struct drm_nouveau_private *dev_priv = dev->dev_private; 134 struct nouveau_device *device = nv_device(parent);
135 struct nv40_fb_priv *priv;
136 int ret;
137
138 ret = nouveau_fb_create(parent, engine, oclass, &priv);
139 *pobject = nv_object(priv);
140 if (ret)
141 return ret;
78 142
79 /* 0x001218 is actually present on a few other NV4X I looked at, 143 /* 0x001218 is actually present on a few other NV4X I looked at,
80 * and even contains sane values matching 0x100474. From looking 144 * and even contains sane values matching 0x100474. From looking
@@ -82,82 +146,73 @@ nv40_fb_vram_init(struct drm_device *dev)
82 * So, I chose to use the same regs I've seen NVIDIA reading around 146 * So, I chose to use the same regs I've seen NVIDIA reading around
83 * the memory detection, hopefully that'll get us the right numbers 147 * the memory detection, hopefully that'll get us the right numbers
84 */ 148 */
85 if (dev_priv->chipset == 0x40) { 149 if (device->chipset == 0x40) {
86 u32 pbus1218 = nv_rd32(dev, 0x001218); 150 u32 pbus1218 = nv_rd32(priv, 0x001218);
87 switch (pbus1218 & 0x00000300) { 151 switch (pbus1218 & 0x00000300) {
88 case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; 152 case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
89 case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; 153 case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
90 case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; 154 case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
91 case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; 155 case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_DDR2; break;
92 } 156 }
93 } else 157 } else
94 if (dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { 158 if (device->chipset == 0x49 || device->chipset == 0x4b) {
95 u32 pfb914 = nv_rd32(dev, 0x100914); 159 u32 pfb914 = nv_rd32(priv, 0x100914);
96 switch (pfb914 & 0x00000003) { 160 switch (pfb914 & 0x00000003) {
97 case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; 161 case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
98 case 0x00000001: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; 162 case 0x00000001: priv->base.ram.type = NV_MEM_TYPE_DDR2; break;
99 case 0x00000002: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; 163 case 0x00000002: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
100 case 0x00000003: break; 164 case 0x00000003: break;
101 } 165 }
102 } else 166 } else
103 if (dev_priv->chipset != 0x4e) { 167 if (device->chipset != 0x4e) {
104 u32 pfb474 = nv_rd32(dev, 0x100474); 168 u32 pfb474 = nv_rd32(priv, 0x100474);
105 if (pfb474 & 0x00000004) 169 if (pfb474 & 0x00000004)
106 dev_priv->vram_type = NV_MEM_TYPE_GDDR3; 170 priv->base.ram.type = NV_MEM_TYPE_GDDR3;
107 if (pfb474 & 0x00000002) 171 if (pfb474 & 0x00000002)
108 dev_priv->vram_type = NV_MEM_TYPE_DDR2; 172 priv->base.ram.type = NV_MEM_TYPE_DDR2;
109 if (pfb474 & 0x00000001) 173 if (pfb474 & 0x00000001)
110 dev_priv->vram_type = NV_MEM_TYPE_DDR1; 174 priv->base.ram.type = NV_MEM_TYPE_DDR1;
111 } else { 175 } else {
112 dev_priv->vram_type = NV_MEM_TYPE_STOLEN; 176 priv->base.ram.type = NV_MEM_TYPE_STOLEN;
113 } 177 }
114 178
115 dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000; 179 priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
116 return 0;
117}
118
119int
120nv40_fb_init(struct drm_device *dev)
121{
122 struct drm_nouveau_private *dev_priv = dev->dev_private;
123 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
124 uint32_t tmp;
125 int i;
126
127 if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) {
128 if (nv44_graph_class(dev))
129 nv44_fb_init_gart(dev);
130 else
131 nv40_fb_init_gart(dev);
132 }
133 180
134 switch (dev_priv->chipset) { 181 priv->base.memtype_valid = nv04_fb_memtype_valid;
182 switch (device->chipset) {
135 case 0x40: 183 case 0x40:
136 case 0x45: 184 case 0x45:
137 tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); 185 priv->base.tile.regions = 8;
138 nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
139 pfb->num_tiles = NV10_PFB_TILE__SIZE;
140 break; 186 break;
141 case 0x46: /* G72 */ 187 case 0x46:
142 case 0x47: /* G70 */ 188 case 0x47:
143 case 0x49: /* G71 */ 189 case 0x49:
144 case 0x4b: /* G73 */ 190 case 0x4b:
145 case 0x4c: /* C51 (G7X version) */ 191 case 0x4c:
146 pfb->num_tiles = NV40_PFB_TILE__SIZE_1; 192 priv->base.tile.regions = 15;
147 break; 193 break;
148 default: 194 default:
149 pfb->num_tiles = NV40_PFB_TILE__SIZE_0; 195 priv->base.tile.regions = 12;
150 break; 196 break;
151 } 197 }
152 198 priv->base.tile.init = nv30_fb_tile_init;
153 /* Turn all the tiling regions off. */ 199 priv->base.tile.fini = nv30_fb_tile_fini;
154 for (i = 0; i < pfb->num_tiles; i++) 200 if (device->chipset == 0x40)
155 pfb->set_tile_region(dev, i); 201 priv->base.tile.prog = nv10_fb_tile_prog;
156 202 else
157 return 0; 203 priv->base.tile.prog = nv40_fb_tile_prog;
204
205 return nouveau_fb_created(&priv->base);
158} 206}
159 207
160void 208
161nv40_fb_takedown(struct drm_device *dev) 209struct nouveau_oclass
162{ 210nv40_fb_oclass = {
163} 211 .handle = NV_SUBDEV(FB, 0x40),
212 .ofuncs = &(struct nouveau_ofuncs) {
213 .ctor = nv40_fb_ctor,
214 .dtor = _nouveau_fb_dtor,
215 .init = nv40_fb_init,
216 .fini = _nouveau_fb_fini,
217 },
218};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
index a145b1c81ecb..eaf18fb2c306 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
@@ -1,119 +1,335 @@
1#include "drmP.h" 1/*
2#include "drm.h" 2 * Copyright 2012 Red Hat Inc.
3#include "nouveau_drv.h" 3 *
4#include <nouveau_drm.h> 4 * Permission is hereby granted, free of charge, to any person obtaining a
5#include <engine/fifo.h> 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 <core/object.h>
26#include <core/enum.h>
27
28#include <subdev/fb.h>
29#include <subdev/bios.h>
6 30
7struct nv50_fb_priv { 31struct nv50_fb_priv {
32 struct nouveau_fb base;
8 struct page *r100c08_page; 33 struct page *r100c08_page;
9 dma_addr_t r100c08; 34 dma_addr_t r100c08;
10}; 35};
11 36
12static void 37static int types[0x80] = {
13nv50_fb_destroy(struct drm_device *dev) 38 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
40 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
43 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
45 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
46};
47
48static bool
49nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
14{ 50{
15 struct drm_nouveau_private *dev_priv = dev->dev_private; 51 return types[(memtype & 0xff00) >> 8] != 0;
16 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 52}
17 struct nv50_fb_priv *priv = pfb->priv;
18 53
19 if (drm_mm_initialized(&pfb->tag_heap)) 54static int
20 drm_mm_takedown(&pfb->tag_heap); 55nv50_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
56 u32 memtype, struct nouveau_mem **pmem)
57{
58 struct nv50_fb_priv *priv = (void *)pfb;
59 struct nouveau_mm *heap = &priv->base.vram;
60 struct nouveau_mm *tags = &priv->base.tags;
61 struct nouveau_mm_node *r;
62 struct nouveau_mem *mem;
63 int comp = (memtype & 0x300) >> 8;
64 int type = (memtype & 0x07f);
65 int back = (memtype & 0x800);
66 int min, max, ret;
67
68 max = (size >> 12);
69 min = ncmin ? (ncmin >> 12) : max;
70 align >>= 12;
71
72 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
73 if (!mem)
74 return -ENOMEM;
21 75
22 if (priv->r100c08_page) { 76 mutex_lock(&pfb->base.mutex);
23 pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, 77 if (comp) {
24 PCI_DMA_BIDIRECTIONAL); 78 if (align == 16) {
25 __free_page(priv->r100c08_page); 79 int n = (max >> 4) * comp;
80
81 ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
82 if (ret)
83 mem->tag = NULL;
84 }
85
86 if (unlikely(!mem->tag))
87 comp = 0;
26 } 88 }
27 89
28 kfree(priv); 90 INIT_LIST_HEAD(&mem->regions);
29 pfb->priv = NULL; 91 mem->memtype = (comp << 7) | type;
92 mem->size = max;
93
94 type = types[type];
95 do {
96 if (back)
97 ret = nouveau_mm_tail(heap, type, max, min, align, &r);
98 else
99 ret = nouveau_mm_head(heap, type, max, min, align, &r);
100 if (ret) {
101 mutex_unlock(&pfb->base.mutex);
102 pfb->ram.put(pfb, &mem);
103 return ret;
104 }
105
106 list_add_tail(&r->rl_entry, &mem->regions);
107 max -= r->length;
108 } while (max);
109 mutex_unlock(&pfb->base.mutex);
110
111 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
112 mem->offset = (u64)r->offset << 12;
113 *pmem = mem;
114 return 0;
30} 115}
31 116
32static int 117void
33nv50_fb_create(struct drm_device *dev) 118nv50_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
34{ 119{
35 struct drm_nouveau_private *dev_priv = dev->dev_private; 120 struct nv50_fb_priv *priv = (void *)pfb;
36 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 121 struct nouveau_mm_node *this;
37 struct nv50_fb_priv *priv; 122 struct nouveau_mem *mem;
38 u32 tagmem;
39 int ret;
40 123
41 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 124 mem = *pmem;
42 if (!priv) 125 *pmem = NULL;
43 return -ENOMEM; 126 if (unlikely(mem == NULL))
44 pfb->priv = priv; 127 return;
45 128
46 priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); 129 mutex_lock(&pfb->base.mutex);
47 if (!priv->r100c08_page) { 130 while (!list_empty(&mem->regions)) {
48 nv50_fb_destroy(dev); 131 this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
49 return -ENOMEM; 132
133 list_del(&this->rl_entry);
134 nouveau_mm_free(&priv->base.vram, &this);
50 } 135 }
51 136
52 priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0, 137 nouveau_mm_free(&priv->base.tags, &mem->tag);
53 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 138 mutex_unlock(&pfb->base.mutex);
54 if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) { 139
55 nv50_fb_destroy(dev); 140 kfree(mem);
56 return -EFAULT; 141}
142
143static u32
144nv50_vram_rblock(struct nv50_fb_priv *priv)
145{
146 int i, parts, colbits, rowbitsa, rowbitsb, banks;
147 u64 rowsize, predicted;
148 u32 r0, r4, rt, ru, rblock_size;
149
150 r0 = nv_rd32(priv, 0x100200);
151 r4 = nv_rd32(priv, 0x100204);
152 rt = nv_rd32(priv, 0x100250);
153 ru = nv_rd32(priv, 0x001540);
154 nv_debug(priv, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
155
156 for (i = 0, parts = 0; i < 8; i++) {
157 if (ru & (0x00010000 << i))
158 parts++;
57 } 159 }
58 160
59 tagmem = nv_rd32(dev, 0x100320); 161 colbits = (r4 & 0x0000f000) >> 12;
60 NV_DEBUG(dev, "%d tags available\n", tagmem); 162 rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
61 ret = drm_mm_init(&pfb->tag_heap, 0, tagmem); 163 rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
62 if (ret) { 164 banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
63 nv50_fb_destroy(dev); 165
64 return ret; 166 rowsize = parts * banks * (1 << colbits) * 8;
167 predicted = rowsize << rowbitsa;
168 if (r0 & 0x00000004)
169 predicted += rowsize << rowbitsb;
170
171 if (predicted != priv->base.ram.size) {
172 nv_warn(priv, "memory controller reports %d MiB VRAM\n",
173 (u32)(priv->base.ram.size >> 20));
65 } 174 }
66 175
67 return 0; 176 rblock_size = rowsize;
177 if (rt & 1)
178 rblock_size *= 3;
179
180 nv_debug(priv, "rblock %d bytes\n", rblock_size);
181 return rblock_size;
68} 182}
69 183
70int 184static int
71nv50_fb_init(struct drm_device *dev) 185nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
186 struct nouveau_oclass *oclass, void *data, u32 size,
187 struct nouveau_object **pobject)
72{ 188{
73 struct drm_nouveau_private *dev_priv = dev->dev_private; 189 struct nouveau_device *device = nv_device(parent);
190 struct nouveau_bios *bios = nouveau_bios(device);
191 const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
192 const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
74 struct nv50_fb_priv *priv; 193 struct nv50_fb_priv *priv;
194 u32 tags;
75 int ret; 195 int ret;
76 196
77 if (!dev_priv->engine.fb.priv) { 197 ret = nouveau_fb_create(parent, engine, oclass, &priv);
78 ret = nv50_fb_create(dev); 198 *pobject = nv_object(priv);
199 if (ret)
200 return ret;
201
202 switch (nv_rd32(priv, 0x100714) & 0x00000007) {
203 case 0: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
204 case 1:
205 if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
206 priv->base.ram.type = NV_MEM_TYPE_DDR3;
207 else
208 priv->base.ram.type = NV_MEM_TYPE_DDR2;
209 break;
210 case 2: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
211 case 3: priv->base.ram.type = NV_MEM_TYPE_GDDR4; break;
212 case 4: priv->base.ram.type = NV_MEM_TYPE_GDDR5; break;
213 default:
214 break;
215 }
216
217 priv->base.ram.size = nv_rd32(priv, 0x10020c);
218 priv->base.ram.size = (priv->base.ram.size & 0xffffff00) |
219 ((priv->base.ram.size & 0x000000ff) << 32);
220
221 tags = nv_rd32(priv, 0x100320);
222 if (tags) {
223 ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
79 if (ret) 224 if (ret)
80 return ret; 225 return ret;
226
227 nv_debug(priv, "%d compression tags\n", tags);
228 }
229
230 size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
231 switch (device->chipset) {
232 case 0xaa:
233 case 0xac:
234 case 0xaf: /* IGPs, no reordering, no real VRAM */
235 ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, 1);
236 if (ret)
237 return ret;
238
239 priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
240 break;
241 default:
242 ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
243 nv50_vram_rblock(priv) >> 12);
244 if (ret)
245 return ret;
246
247 priv->base.ram.ranks = (nv_rd32(priv, 0x100200) & 0x4) ? 2 : 1;
248 break;
249 }
250
251 priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
252 if (priv->r100c08_page) {
253 priv->r100c08 = pci_map_page(device->pdev, priv->r100c08_page,
254 0, PAGE_SIZE,
255 PCI_DMA_BIDIRECTIONAL);
256 if (pci_dma_mapping_error(device->pdev, priv->r100c08))
257 nv_warn(priv, "failed 0x100c08 page map\n");
258 } else {
259 nv_warn(priv, "failed 0x100c08 page alloc\n");
81 } 260 }
82 priv = dev_priv->engine.fb.priv; 261
262 priv->base.memtype_valid = nv50_fb_memtype_valid;
263 priv->base.ram.get = nv50_fb_vram_new;
264 priv->base.ram.put = nv50_fb_vram_del;
265 return nouveau_fb_created(&priv->base);
266}
267
268static void
269nv50_fb_dtor(struct nouveau_object *object)
270{
271 struct nouveau_device *device = nv_device(object);
272 struct nv50_fb_priv *priv = (void *)object;
273
274 if (priv->r100c08_page) {
275 pci_unmap_page(device->pdev, priv->r100c08, PAGE_SIZE,
276 PCI_DMA_BIDIRECTIONAL);
277 __free_page(priv->r100c08_page);
278 }
279
280 nouveau_mm_fini(&priv->base.vram);
281 nouveau_fb_destroy(&priv->base);
282}
283
284static int
285nv50_fb_init(struct nouveau_object *object)
286{
287 struct nouveau_device *device = nv_device(object);
288 struct nv50_fb_priv *priv = (void *)object;
289 int ret;
290
291 ret = nouveau_fb_init(&priv->base);
292 if (ret)
293 return ret;
83 294
84 /* Not a clue what this is exactly. Without pointing it at a 295 /* Not a clue what this is exactly. Without pointing it at a
85 * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) 296 * scratch page, VRAM->GART blits with M2MF (as in DDX DFS)
86 * cause IOMMU "read from address 0" errors (rh#561267) 297 * cause IOMMU "read from address 0" errors (rh#561267)
87 */ 298 */
88 nv_wr32(dev, 0x100c08, priv->r100c08 >> 8); 299 nv_wr32(priv, 0x100c08, priv->r100c08 >> 8);
89 300
90 /* This is needed to get meaningful information from 100c90 301 /* This is needed to get meaningful information from 100c90
91 * on traps. No idea what these values mean exactly. */ 302 * on traps. No idea what these values mean exactly. */
92 switch (dev_priv->chipset) { 303 switch (device->chipset) {
93 case 0x50: 304 case 0x50:
94 nv_wr32(dev, 0x100c90, 0x000707ff); 305 nv_wr32(priv, 0x100c90, 0x000707ff);
95 break; 306 break;
96 case 0xa3: 307 case 0xa3:
97 case 0xa5: 308 case 0xa5:
98 case 0xa8: 309 case 0xa8:
99 nv_wr32(dev, 0x100c90, 0x000d0fff); 310 nv_wr32(priv, 0x100c90, 0x000d0fff);
100 break; 311 break;
101 case 0xaf: 312 case 0xaf:
102 nv_wr32(dev, 0x100c90, 0x089d1fff); 313 nv_wr32(priv, 0x100c90, 0x089d1fff);
103 break; 314 break;
104 default: 315 default:
105 nv_wr32(dev, 0x100c90, 0x001d07ff); 316 nv_wr32(priv, 0x100c90, 0x001d07ff);
106 break; 317 break;
107 } 318 }
108 319
109 return 0; 320 return 0;
110} 321}
111 322
112void 323struct nouveau_oclass
113nv50_fb_takedown(struct drm_device *dev) 324nv50_fb_oclass = {
114{ 325 .handle = NV_SUBDEV(FB, 0x50),
115 nv50_fb_destroy(dev); 326 .ofuncs = &(struct nouveau_ofuncs) {
116} 327 .ctor = nv50_fb_ctor,
328 .dtor = nv50_fb_dtor,
329 .init = nv50_fb_init,
330 .fini = _nouveau_fb_fini,
331 },
332};
117 333
118static struct nouveau_enum vm_dispatch_subclients[] = { 334static struct nouveau_enum vm_dispatch_subclients[] = {
119 { 0x00000000, "GRCTX", NULL }, 335 { 0x00000000, "GRCTX", NULL },
@@ -211,47 +427,32 @@ static struct nouveau_enum vm_fault[] = {
211}; 427};
212 428
213void 429void
214nv50_fb_vm_trap(struct drm_device *dev, int display) 430nv50_fb_trap(struct nouveau_fb *pfb, int display)
215{ 431{
216 struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); 432 struct nouveau_device *device = nv_device(pfb);
217 struct drm_nouveau_private *dev_priv = dev->dev_private; 433 struct nv50_fb_priv *priv = (void *)pfb;
218 const struct nouveau_enum *en, *cl; 434 const struct nouveau_enum *en, *cl;
219 unsigned long flags; 435 u32 trap[6], idx, chan;
220 u32 trap[6], idx, chinst;
221 u8 st0, st1, st2, st3; 436 u8 st0, st1, st2, st3;
222 int i, ch; 437 int i;
223 438
224 idx = nv_rd32(dev, 0x100c90); 439 idx = nv_rd32(priv, 0x100c90);
225 if (!(idx & 0x80000000)) 440 if (!(idx & 0x80000000))
226 return; 441 return;
227 idx &= 0x00ffffff; 442 idx &= 0x00ffffff;
228 443
229 for (i = 0; i < 6; i++) { 444 for (i = 0; i < 6; i++) {
230 nv_wr32(dev, 0x100c90, idx | i << 24); 445 nv_wr32(priv, 0x100c90, idx | i << 24);
231 trap[i] = nv_rd32(dev, 0x100c94); 446 trap[i] = nv_rd32(priv, 0x100c94);
232 } 447 }
233 nv_wr32(dev, 0x100c90, idx | 0x80000000); 448 nv_wr32(priv, 0x100c90, idx | 0x80000000);
234 449
235 if (!display) 450 if (!display)
236 return; 451 return;
237 452
238 /* lookup channel id */
239 chinst = (trap[2] << 16) | trap[1];
240 spin_lock_irqsave(&dev_priv->channels.lock, flags);
241 for (ch = 0; ch < pfifo->channels; ch++) {
242 struct nouveau_channel *chan = dev_priv->channels.ptr[ch];
243
244 if (!chan || !chan->ramin)
245 continue;
246
247 if (chinst == chan->ramin->vinst >> 12)
248 break;
249 }
250 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
251
252 /* decode status bits into something more useful */ 453 /* decode status bits into something more useful */
253 if (dev_priv->chipset < 0xa3 || 454 if (device->chipset < 0xa3 ||
254 dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { 455 device->chipset == 0xaa || device->chipset == 0xac) {
255 st0 = (trap[0] & 0x0000000f) >> 0; 456 st0 = (trap[0] & 0x0000000f) >> 0;
256 st1 = (trap[0] & 0x000000f0) >> 4; 457 st1 = (trap[0] & 0x000000f0) >> 4;
257 st2 = (trap[0] & 0x00000f00) >> 8; 458 st2 = (trap[0] & 0x00000f00) >> 8;
@@ -262,10 +463,11 @@ nv50_fb_vm_trap(struct drm_device *dev, int display)
262 st2 = (trap[0] & 0x00ff0000) >> 16; 463 st2 = (trap[0] & 0x00ff0000) >> 16;
263 st3 = (trap[0] & 0xff000000) >> 24; 464 st3 = (trap[0] & 0xff000000) >> 24;
264 } 465 }
466 chan = (trap[2] << 16) | trap[1];
265 467
266 NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ", 468 nv_error(priv, "trapped %s at 0x%02x%04x%04x on channel 0x%08x ",
267 (trap[5] & 0x00000100) ? "read" : "write", 469 (trap[5] & 0x00000100) ? "read" : "write",
268 trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst); 470 trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, chan);
269 471
270 en = nouveau_enum_find(vm_engine, st0); 472 en = nouveau_enum_find(vm_engine, st0);
271 if (en) 473 if (en)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c
deleted file mode 100644
index 84b99b608b2b..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c
+++ /dev/null
@@ -1,243 +0,0 @@
1/*
2 * Copyright 2010 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 "drmP.h"
26#include "nouveau_drv.h"
27#include <core/mm.h>
28
29static int types[0x80] = {
30 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
32 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
35 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
37 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
38};
39
40bool
41nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
42{
43 int type = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
44
45 if (likely(type < ARRAY_SIZE(types) && types[type]))
46 return true;
47 return false;
48}
49
50void
51nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem)
52{
53 struct drm_nouveau_private *dev_priv = dev->dev_private;
54 struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
55 struct nouveau_mm_node *this;
56 struct nouveau_mem *mem;
57
58 mem = *pmem;
59 *pmem = NULL;
60 if (unlikely(mem == NULL))
61 return;
62
63 mutex_lock(&mm->mutex);
64 while (!list_empty(&mem->regions)) {
65 this = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
66
67 list_del(&this->rl_entry);
68 nouveau_mm_free(mm, &this);
69 }
70
71 if (mem->tag) {
72 drm_mm_put_block(mem->tag);
73 mem->tag = NULL;
74 }
75 mutex_unlock(&mm->mutex);
76
77 kfree(mem);
78}
79
80int
81nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
82 u32 memtype, struct nouveau_mem **pmem)
83{
84 struct drm_nouveau_private *dev_priv = dev->dev_private;
85 struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
86 struct nouveau_mm_node *r;
87 struct nouveau_mem *mem;
88 int comp = (memtype & 0x300) >> 8;
89 int type = (memtype & 0x07f);
90 int back = (memtype & 0x800);
91 int ret;
92
93 size >>= 12;
94 align >>= 12;
95 ncmin >>= 12;
96 if (!ncmin)
97 ncmin = size;
98
99 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
100 if (!mem)
101 return -ENOMEM;
102
103 mutex_lock(&mm->mutex);
104 if (comp) {
105 if (align == 16) {
106 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
107 int n = (size >> 4) * comp;
108
109 mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0);
110 if (mem->tag)
111 mem->tag = drm_mm_get_block(mem->tag, n, 0);
112 }
113
114 if (unlikely(!mem->tag))
115 comp = 0;
116 }
117
118 INIT_LIST_HEAD(&mem->regions);
119 mem->dev = dev_priv->dev;
120 mem->memtype = (comp << 7) | type;
121 mem->size = size;
122
123 type = types[type];
124 do {
125 if (back)
126 ret = nouveau_mm_tail(mm, type, size, ncmin, align, &r);
127 else
128 ret = nouveau_mm_head(mm, type, size, ncmin, align, &r);
129
130 if (ret) {
131 mutex_unlock(&mm->mutex);
132 nv50_vram_del(dev, &mem);
133 return ret;
134 }
135
136 list_add_tail(&r->rl_entry, &mem->regions);
137 size -= r->length;
138 } while (size);
139 mutex_unlock(&mm->mutex);
140
141 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
142 mem->offset = (u64)r->offset << 12;
143 *pmem = mem;
144 return 0;
145}
146
147static u32
148nv50_vram_rblock(struct drm_device *dev)
149{
150 struct drm_nouveau_private *dev_priv = dev->dev_private;
151 int i, parts, colbits, rowbitsa, rowbitsb, banks;
152 u64 rowsize, predicted;
153 u32 r0, r4, rt, ru, rblock_size;
154
155 r0 = nv_rd32(dev, 0x100200);
156 r4 = nv_rd32(dev, 0x100204);
157 rt = nv_rd32(dev, 0x100250);
158 ru = nv_rd32(dev, 0x001540);
159 NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
160
161 for (i = 0, parts = 0; i < 8; i++) {
162 if (ru & (0x00010000 << i))
163 parts++;
164 }
165
166 colbits = (r4 & 0x0000f000) >> 12;
167 rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
168 rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
169 banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
170
171 rowsize = parts * banks * (1 << colbits) * 8;
172 predicted = rowsize << rowbitsa;
173 if (r0 & 0x00000004)
174 predicted += rowsize << rowbitsb;
175
176 if (predicted != dev_priv->vram_size) {
177 NV_WARN(dev, "memory controller reports %dMiB VRAM\n",
178 (u32)(dev_priv->vram_size >> 20));
179 NV_WARN(dev, "we calculated %dMiB VRAM\n",
180 (u32)(predicted >> 20));
181 }
182
183 rblock_size = rowsize;
184 if (rt & 1)
185 rblock_size *= 3;
186
187 NV_DEBUG(dev, "rblock %d bytes\n", rblock_size);
188 return rblock_size;
189}
190
191int
192nv50_vram_init(struct drm_device *dev)
193{
194 struct drm_nouveau_private *dev_priv = dev->dev_private;
195 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
196 const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
197 const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
198 u32 pfb714 = nv_rd32(dev, 0x100714);
199 u32 rblock, length;
200
201 switch (pfb714 & 0x00000007) {
202 case 0: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
203 case 1:
204 if (nouveau_mem_vbios_type(dev) == NV_MEM_TYPE_DDR3)
205 dev_priv->vram_type = NV_MEM_TYPE_DDR3;
206 else
207 dev_priv->vram_type = NV_MEM_TYPE_DDR2;
208 break;
209 case 2: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
210 case 3: dev_priv->vram_type = NV_MEM_TYPE_GDDR4; break;
211 case 4: dev_priv->vram_type = NV_MEM_TYPE_GDDR5; break;
212 default:
213 break;
214 }
215
216 dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x100200) & 0x4);
217 dev_priv->vram_size = nv_rd32(dev, 0x10020c);
218 dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
219 dev_priv->vram_size &= 0xffffffff00ULL;
220
221 /* IGPs, no funky reordering happens here, they don't have VRAM */
222 if (dev_priv->chipset == 0xaa ||
223 dev_priv->chipset == 0xac ||
224 dev_priv->chipset == 0xaf) {
225 dev_priv->vram_sys_base = (u64)nv_rd32(dev, 0x100e10) << 12;
226 rblock = 4096 >> 12;
227 } else {
228 rblock = nv50_vram_rblock(dev) >> 12;
229 }
230
231 length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
232
233 return nouveau_mm_init(&vram->mm, rsvd_head, length, rblock);
234}
235
236void
237nv50_vram_fini(struct drm_device *dev)
238{
239 struct drm_nouveau_private *dev_priv = dev->dev_private;
240 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
241
242 nouveau_mm_fini(&vram->mm);
243}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index f054331e37d8..9f59f2bf0079 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Red Hat Inc. 2 * Copyright 2012 Red Hat Inc.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -22,114 +22,224 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "drmP.h" 25#include <subdev/fb.h>
26#include "drm.h" 26#include <subdev/bios.h>
27#include "nouveau_drv.h"
28#include <nouveau_drm.h>
29 27
30struct nvc0_fb_priv { 28struct nvc0_fb_priv {
29 struct nouveau_fb base;
31 struct page *r100c10_page; 30 struct page *r100c10_page;
32 dma_addr_t r100c10; 31 dma_addr_t r100c10;
33}; 32};
34 33
35static inline void 34/* 0 = unsupported
36nvc0_mfb_subp_isr(struct drm_device *dev, int unit, int subp) 35 * 1 = non-compressed
36 * 3 = compressed
37 */
38static const u8 types[256] = {
39 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
40 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
43 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
51 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
52 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
53 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
54 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
55};
56
57static bool
58nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
37{ 59{
38 u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400); 60 u8 memtype = (tile_flags & 0x0000ff00) >> 8;
39 u32 stat = nv_rd32(dev, subp_base + 0x020); 61 return likely((types[memtype] == 1));
62}
40 63
41 if (stat) { 64static int
42 NV_INFO(dev, "PMFB%d_SUBP%d: 0x%08x\n", unit, subp, stat); 65nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
43 nv_wr32(dev, subp_base + 0x020, stat); 66 u32 memtype, struct nouveau_mem **pmem)
44 } 67{
68 struct nouveau_mm *mm = &pfb->vram;
69 struct nouveau_mm_node *r;
70 struct nouveau_mem *mem;
71 int type = (memtype & 0x0ff);
72 int back = (memtype & 0x800);
73 int ret;
74
75 size >>= 12;
76 align >>= 12;
77 ncmin >>= 12;
78 if (!ncmin)
79 ncmin = size;
80
81 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
82 if (!mem)
83 return -ENOMEM;
84
85 INIT_LIST_HEAD(&mem->regions);
86 mem->memtype = type;
87 mem->size = size;
88
89 mutex_lock(&mm->mutex);
90 do {
91 if (back)
92 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
93 else
94 ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
95 if (ret) {
96 mutex_unlock(&mm->mutex);
97 pfb->ram.put(pfb, &mem);
98 return ret;
99 }
100
101 list_add_tail(&r->rl_entry, &mem->regions);
102 size -= r->length;
103 } while (size);
104 mutex_unlock(&mm->mutex);
105
106 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
107 mem->offset = (u64)r->offset << 12;
108 *pmem = mem;
109 return 0;
45} 110}
46 111
47static void 112static int
48nvc0_mfb_isr(struct drm_device *dev) 113nvc0_fb_init(struct nouveau_object *object)
49{ 114{
50 u32 units = nv_rd32(dev, 0x00017c); 115 struct nvc0_fb_priv *priv = (void *)object;
51 while (units) { 116 int ret;
52 u32 subp, unit = ffs(units) - 1; 117
53 for (subp = 0; subp < 2; subp++) 118 ret = nouveau_fb_init(&priv->base);
54 nvc0_mfb_subp_isr(dev, unit, subp); 119 if (ret)
55 units &= ~(1 << unit); 120 return ret;
56 }
57 121
58 /* we do something horribly wrong and upset PMFB a lot, so mask off 122 nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
59 * interrupts from it after the first one until it's fixed 123 return 0;
60 */
61 nv_mask(dev, 0x000640, 0x02000000, 0x00000000);
62} 124}
63 125
64static void 126static void
65nvc0_fb_destroy(struct drm_device *dev) 127nvc0_fb_dtor(struct nouveau_object *object)
66{ 128{
67 struct drm_nouveau_private *dev_priv = dev->dev_private; 129 struct nouveau_device *device = nv_device(object);
68 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 130 struct nvc0_fb_priv *priv = (void *)object;
69 struct nvc0_fb_priv *priv = pfb->priv;
70
71 nouveau_irq_unregister(dev, 25);
72 131
73 if (priv->r100c10_page) { 132 if (priv->r100c10_page) {
74 pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE, 133 pci_unmap_page(device->pdev, priv->r100c10, PAGE_SIZE,
75 PCI_DMA_BIDIRECTIONAL); 134 PCI_DMA_BIDIRECTIONAL);
76 __free_page(priv->r100c10_page); 135 __free_page(priv->r100c10_page);
77 } 136 }
78 137
79 kfree(priv); 138 nouveau_fb_destroy(&priv->base);
80 pfb->priv = NULL;
81} 139}
82 140
83static int 141static int
84nvc0_fb_create(struct drm_device *dev) 142nvc0_vram_detect(struct nvc0_fb_priv *priv)
85{ 143{
86 struct drm_nouveau_private *dev_priv = dev->dev_private; 144 struct nouveau_bios *bios = nouveau_bios(priv);
87 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 145 struct nouveau_fb *pfb = &priv->base;
88 struct nvc0_fb_priv *priv; 146 const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
89 147 const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
90 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 148 u32 parts = nv_rd32(priv, 0x022438);
91 if (!priv) 149 u32 pmask = nv_rd32(priv, 0x022554);
92 return -ENOMEM; 150 u32 bsize = nv_rd32(priv, 0x10f20c);
93 pfb->priv = priv; 151 u32 offset, length;
152 bool uniform = true;
153 int ret, part;
154
155 nv_debug(priv, "0x100800: 0x%08x\n", nv_rd32(priv, 0x100800));
156 nv_debug(priv, "parts 0x%08x mask 0x%08x\n", parts, pmask);
157
158 priv->base.ram.type = nouveau_fb_bios_memtype(bios);
159 priv->base.ram.ranks = (nv_rd32(priv, 0x10f200) & 0x00000004) ? 2 : 1;
160
161 /* read amount of vram attached to each memory controller */
162 for (part = 0; part < parts; part++) {
163 if (!(pmask & (1 << part))) {
164 u32 psize = nv_rd32(priv, 0x11020c + (part * 0x1000));
165 if (psize != bsize) {
166 if (psize < bsize)
167 bsize = psize;
168 uniform = false;
169 }
170
171 nv_debug(priv, "%d: mem_amount 0x%08x\n", part, psize);
172 priv->base.ram.size += (u64)psize << 20;
173 }
174 }
94 175
95 priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); 176 /* if all controllers have the same amount attached, there's no holes */
96 if (!priv->r100c10_page) { 177 if (uniform) {
97 nvc0_fb_destroy(dev); 178 offset = rsvd_head;
98 return -ENOMEM; 179 length = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
180 return nouveau_mm_init(&pfb->vram, offset, length, 1);
99 } 181 }
100 182
101 priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0, 183 /* otherwise, address lowest common amount from 0GiB */
102 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 184 ret = nouveau_mm_init(&pfb->vram, rsvd_head, (bsize << 8) * parts, 1);
103 if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) { 185 if (ret)
104 nvc0_fb_destroy(dev); 186 return ret;
105 return -EFAULT; 187
188 /* and the rest starting from (8GiB + common_size) */
189 offset = (0x0200000000ULL >> 12) + (bsize << 8);
190 length = (priv->base.ram.size >> 12) - (bsize << 8) - rsvd_tail;
191
192 ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
193 if (ret) {
194 nouveau_mm_fini(&pfb->vram);
195 return ret;
106 } 196 }
107 197
108 nouveau_irq_register(dev, 25, nvc0_mfb_isr);
109 return 0; 198 return 0;
110} 199}
111 200
112int 201static int
113nvc0_fb_init(struct drm_device *dev) 202nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
203 struct nouveau_oclass *oclass, void *data, u32 size,
204 struct nouveau_object **pobject)
114{ 205{
115 struct drm_nouveau_private *dev_priv = dev->dev_private; 206 struct nouveau_device *device = nv_device(parent);
116 struct nvc0_fb_priv *priv; 207 struct nvc0_fb_priv *priv;
117 int ret; 208 int ret;
118 209
119 if (!dev_priv->engine.fb.priv) { 210 ret = nouveau_fb_create(parent, engine, oclass, &priv);
120 ret = nvc0_fb_create(dev); 211 *pobject = nv_object(priv);
121 if (ret) 212 if (ret)
122 return ret; 213 return ret;
123 }
124 priv = dev_priv->engine.fb.priv;
125 214
126 nv_wr32(dev, 0x100c10, priv->r100c10 >> 8); 215 priv->base.memtype_valid = nvc0_fb_memtype_valid;
127 nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */ 216 priv->base.ram.get = nvc0_fb_vram_new;
128 return 0; 217 priv->base.ram.put = nv50_fb_vram_del;
129}
130 218
131void 219 ret = nvc0_vram_detect(priv);
132nvc0_fb_takedown(struct drm_device *dev) 220 if (ret)
133{ 221 return ret;
134 nvc0_fb_destroy(dev); 222
223 priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
224 if (!priv->r100c10_page)
225 return -ENOMEM;
226
227 priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, 0,
228 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
229 if (pci_dma_mapping_error(device->pdev, priv->r100c10))
230 return -EFAULT;
231
232 return nouveau_fb_created(&priv->base);
135} 233}
234
235
236struct nouveau_oclass
237nvc0_fb_oclass = {
238 .handle = NV_SUBDEV(FB, 0xc0),
239 .ofuncs = &(struct nouveau_ofuncs) {
240 .ctor = nvc0_fb_ctor,
241 .dtor = nvc0_fb_dtor,
242 .init = nvc0_fb_init,
243 .fini = _nouveau_fb_fini,
244 },
245};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c
deleted file mode 100644
index f363234a3f44..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c
+++ /dev/null
@@ -1,167 +0,0 @@
1/*
2 * Copyright 2010 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 "drmP.h"
26#include "nouveau_drv.h"
27#include <core/mm.h>
28
29/* 0 = unsupported
30 * 1 = non-compressed
31 * 3 = compressed
32 */
33static const u8 types[256] = {
34 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
35 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
38 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
46 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
47 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
48 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
49 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
50};
51
52bool
53nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
54{
55 u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
56 return likely((types[memtype] == 1));
57}
58
59int
60nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
61 u32 memtype, struct nouveau_mem **pmem)
62{
63 struct drm_nouveau_private *dev_priv = dev->dev_private;
64 struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
65 struct nouveau_mm_node *r;
66 struct nouveau_mem *mem;
67 int type = (memtype & 0x0ff);
68 int back = (memtype & 0x800);
69 int ret;
70
71 size >>= 12;
72 align >>= 12;
73 ncmin >>= 12;
74 if (!ncmin)
75 ncmin = size;
76
77 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
78 if (!mem)
79 return -ENOMEM;
80
81 INIT_LIST_HEAD(&mem->regions);
82 mem->dev = dev_priv->dev;
83 mem->memtype = type;
84 mem->size = size;
85
86 mutex_lock(&mm->mutex);
87 do {
88 if (back)
89 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
90 else
91 ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
92 if (ret) {
93 mutex_unlock(&mm->mutex);
94 nv50_vram_del(dev, &mem);
95 return ret;
96 }
97
98 list_add_tail(&r->rl_entry, &mem->regions);
99 size -= r->length;
100 } while (size);
101 mutex_unlock(&mm->mutex);
102
103 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
104 mem->offset = (u64)r->offset << 12;
105 *pmem = mem;
106 return 0;
107}
108
109int
110nvc0_vram_init(struct drm_device *dev)
111{
112 struct drm_nouveau_private *dev_priv = dev->dev_private;
113 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
114 const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
115 const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
116 u32 parts = nv_rd32(dev, 0x022438);
117 u32 pmask = nv_rd32(dev, 0x022554);
118 u32 bsize = nv_rd32(dev, 0x10f20c);
119 u32 offset, length;
120 bool uniform = true;
121 int ret, part;
122
123 NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
124 NV_DEBUG(dev, "parts 0x%08x mask 0x%08x\n", parts, pmask);
125
126 dev_priv->vram_type = nouveau_mem_vbios_type(dev);
127 dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x10f200) & 0x00000004);
128
129 /* read amount of vram attached to each memory controller */
130 for (part = 0; part < parts; part++) {
131 if (!(pmask & (1 << part))) {
132 u32 psize = nv_rd32(dev, 0x11020c + (part * 0x1000));
133 if (psize != bsize) {
134 if (psize < bsize)
135 bsize = psize;
136 uniform = false;
137 }
138
139 NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
140 dev_priv->vram_size += (u64)psize << 20;
141 }
142 }
143
144 /* if all controllers have the same amount attached, there's no holes */
145 if (uniform) {
146 offset = rsvd_head;
147 length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
148 return nouveau_mm_init(&vram->mm, offset, length, 1);
149 }
150
151 /* otherwise, address lowest common amount from 0GiB */
152 ret = nouveau_mm_init(&vram->mm, rsvd_head, (bsize << 8) * parts, 1);
153 if (ret)
154 return ret;
155
156 /* and the rest starting from (8GiB + common_size) */
157 offset = (0x0200000000ULL >> 12) + (bsize << 8);
158 length = (dev_priv->vram_size >> 12) - (bsize << 8) - rsvd_tail;
159
160 ret = nouveau_mm_init(&vram->mm, offset, length, 0);
161 if (ret) {
162 nouveau_mm_fini(&vram->mm);
163 return ret;
164 }
165
166 return 0;
167}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
index 5965eb7cf390..24d077a1d842 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
@@ -310,8 +310,6 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
310 u32 size, u32 align) 310 u32 size, u32 align)
311{ 311{
312 struct drm_device *dev = gpuobj->dev; 312 struct drm_device *dev = gpuobj->dev;
313 struct drm_nouveau_private *dev_priv = dev->dev_private;
314 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
315 struct nv50_gpuobj_node *node = NULL; 313 struct nv50_gpuobj_node *node = NULL;
316 int ret; 314 int ret;
317 315
@@ -323,7 +321,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
323 size = (size + 4095) & ~4095; 321 size = (size + 4095) & ~4095;
324 align = max(align, (u32)4096); 322 align = max(align, (u32)4096);
325 323
326 ret = vram->get(dev, size, align, 0, 0x800, &node->vram); 324 ret = nvfb_vram_get(dev, size, align, 0, 0x800, &node->vram);
327 if (ret) { 325 if (ret) {
328 kfree(node); 326 kfree(node);
329 return ret; 327 return ret;
@@ -339,7 +337,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
339 ret = nouveau_vm_get(chan->vm, size, 12, flags, 337 ret = nouveau_vm_get(chan->vm, size, 12, flags,
340 &node->chan_vma); 338 &node->chan_vma);
341 if (ret) { 339 if (ret) {
342 vram->put(dev, &node->vram); 340 nvfb_vram_put(dev, &node->vram);
343 kfree(node); 341 kfree(node);
344 return ret; 342 return ret;
345 } 343 }
@@ -357,8 +355,6 @@ void
357nv50_instmem_put(struct nouveau_gpuobj *gpuobj) 355nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
358{ 356{
359 struct drm_device *dev = gpuobj->dev; 357 struct drm_device *dev = gpuobj->dev;
360 struct drm_nouveau_private *dev_priv = dev->dev_private;
361 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
362 struct nv50_gpuobj_node *node; 358 struct nv50_gpuobj_node *node;
363 359
364 node = gpuobj->node; 360 node = gpuobj->node;
@@ -368,7 +364,7 @@ nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
368 nouveau_vm_unmap(&node->chan_vma); 364 nouveau_vm_unmap(&node->chan_vma);
369 nouveau_vm_put(&node->chan_vma); 365 nouveau_vm_put(&node->chan_vma);
370 } 366 }
371 vram->put(dev, &node->vram); 367 nvfb_vram_put(dev, &node->vram);
372 kfree(node); 368 kfree(node);
373} 369}
374 370
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
new file mode 100644
index 000000000000..7c2840cc2bbf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
@@ -0,0 +1,91 @@
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 <subdev/ltcg.h>
26
27struct nvc0_ltcg_priv {
28 struct nouveau_ltcg base;
29};
30
31static void
32nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp)
33{
34 u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400);
35 u32 stat = nv_rd32(priv, subp_base + 0x020);
36
37 if (stat) {
38 nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat);
39 nv_wr32(priv, subp_base + 0x020, stat);
40 }
41}
42
43static void
44nvc0_ltcg_intr(struct nouveau_subdev *subdev)
45{
46 struct nvc0_ltcg_priv *priv = (void *)subdev;
47 u32 units;
48
49 units = nv_rd32(priv, 0x00017c);
50 while (units) {
51 u32 subp, unit = ffs(units) - 1;
52 for (subp = 0; subp < 2; subp++)
53 nvc0_ltcg_subp_isr(priv, unit, subp);
54 units &= ~(1 << unit);
55 }
56
57 /* we do something horribly wrong and upset PMFB a lot, so mask off
58 * interrupts from it after the first one until it's fixed
59 */
60 nv_mask(priv, 0x000640, 0x02000000, 0x00000000);
61}
62
63static int
64nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
65 struct nouveau_oclass *oclass, void *data, u32 size,
66 struct nouveau_object **pobject)
67{
68 struct nvc0_ltcg_priv *priv;
69 int ret;
70
71 ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
72 *pobject = nv_object(priv);
73 if (ret)
74 return ret;
75
76 nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
77
78 nv_subdev(priv)->intr = nvc0_ltcg_intr;
79 return 0;
80}
81
82struct nouveau_oclass
83nvc0_ltcg_oclass = {
84 .handle = NV_SUBDEV(LTCG, 0xc0),
85 .ofuncs = &(struct nouveau_ofuncs) {
86 .ctor = nvc0_ltcg_ctor,
87 .dtor = _nouveau_ltcg_dtor,
88 .init = _nouveau_ltcg_init,
89 .fini = _nouveau_ltcg_fini,
90 },
91};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
index 3fa39bb9a724..bd9e99463ff7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -38,6 +38,7 @@ nvc0_mc_intr[] = {
38 { 0x00008000, NVDEV_ENGINE_BSP }, 38 { 0x00008000, NVDEV_ENGINE_BSP },
39 { 0x00100000, NVDEV_SUBDEV_TIMER }, 39 { 0x00100000, NVDEV_SUBDEV_TIMER },
40 { 0x00200000, NVDEV_SUBDEV_GPIO }, 40 { 0x00200000, NVDEV_SUBDEV_GPIO },
41 { 0x02000000, NVDEV_SUBDEV_LTCG },
41 { 0x04000000, NVDEV_ENGINE_DISP }, 42 { 0x04000000, NVDEV_ENGINE_DISP },
42 { 0x80000000, NVDEV_ENGINE_SW }, 43 { 0x80000000, NVDEV_ENGINE_SW },
43 {}, 44 {},
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
index eeac72f40201..7e46826de0e9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
@@ -80,8 +80,8 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
80 80
81 /* IGPs don't have real VRAM, re-target to stolen system memory */ 81 /* IGPs don't have real VRAM, re-target to stolen system memory */
82 target = 0; 82 target = 0;
83 if (dev_priv->vram_sys_base) { 83 if (nvfb_vram_sys_base(dev_priv->dev)) {
84 phys += dev_priv->vram_sys_base; 84 phys += nvfb_vram_sys_base(dev_priv->dev);
85 target = 3; 85 target = 3;
86 } 86 }
87 87
@@ -103,7 +103,7 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
103 phys += block << (vma->node->type - 3); 103 phys += block << (vma->node->type - 3);
104 cnt -= block; 104 cnt -= block;
105 if (comp) { 105 if (comp) {
106 u32 tag = mem->tag->start + ((delta >> 16) * comp); 106 u32 tag = mem->tag->offset + ((delta >> 16) * comp);
107 offset_h |= (tag << 17); 107 offset_h |= (tag << 17);
108 delta += block << (vma->node->type - 3); 108 delta += block << (vma->node->type - 3);
109 } 109 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index d95275437a4b..f63785c2aae0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -156,7 +156,7 @@ static void
156set_placement_range(struct nouveau_bo *nvbo, uint32_t type) 156set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
157{ 157{
158 struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); 158 struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
159 int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; 159 int vram_pages = nvfb_vram_size(dev_priv->dev) >> PAGE_SHIFT;
160 160
161 if (dev_priv->card_type == NV_10 && 161 if (dev_priv->card_type == NV_10 &&
162 nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && 162 nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
diff --git a/drivers/gpu/drm/nouveau/nouveau_compat.c b/drivers/gpu/drm/nouveau/nouveau_compat.c
index 7880ebb9a7d9..3d65c1763311 100644
--- a/drivers/gpu/drm/nouveau/nouveau_compat.c
+++ b/drivers/gpu/drm/nouveau/nouveau_compat.c
@@ -10,6 +10,7 @@
10#include <subdev/clock.h> 10#include <subdev/clock.h>
11#include <subdev/mc.h> 11#include <subdev/mc.h>
12#include <subdev/timer.h> 12#include <subdev/timer.h>
13#include <subdev/fb.h>
13 14
14void *nouveau_newpriv(struct drm_device *); 15void *nouveau_newpriv(struct drm_device *);
15 16
@@ -332,3 +333,108 @@ nv_timer_read(struct drm_device *dev)
332 struct nouveau_timer *ptimer = nouveau_timer(drm->device); 333 struct nouveau_timer *ptimer = nouveau_timer(drm->device);
333 return ptimer->read(ptimer); 334 return ptimer->read(ptimer);
334} 335}
336
337int
338nvfb_tile_nr(struct drm_device *dev)
339{
340 struct nouveau_drm *drm = nouveau_newpriv(dev);
341 struct nouveau_fb *pfb = nouveau_fb(drm->device);
342 return pfb->tile.regions;
343}
344
345struct nouveau_fb_tile *
346nvfb_tile(struct drm_device *dev, int i)
347{
348 struct nouveau_drm *drm = nouveau_newpriv(dev);
349 struct nouveau_fb *pfb = nouveau_fb(drm->device);
350 return &pfb->tile.region[i];
351}
352
353void
354nvfb_tile_init(struct drm_device *dev, int i, u32 a, u32 b, u32 c, u32 d)
355{
356 struct nouveau_drm *drm = nouveau_newpriv(dev);
357 struct nouveau_fb *pfb = nouveau_fb(drm->device);
358 pfb->tile.init(pfb, i, a, b, c, d, &pfb->tile.region[i]);
359}
360
361void
362nvfb_tile_fini(struct drm_device *dev, int i)
363{
364 struct nouveau_drm *drm = nouveau_newpriv(dev);
365 struct nouveau_fb *pfb = nouveau_fb(drm->device);
366 pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
367}
368
369void
370nvfb_tile_prog(struct drm_device *dev, int i)
371{
372 struct nouveau_drm *drm = nouveau_newpriv(dev);
373 struct nouveau_fb *pfb = nouveau_fb(drm->device);
374 pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
375}
376
377bool
378nvfb_flags_valid(struct drm_device *dev, u32 flags)
379{
380 struct nouveau_drm *drm = nouveau_newpriv(dev);
381 struct nouveau_fb *pfb = nouveau_fb(drm->device);
382 return pfb->memtype_valid(pfb, flags);
383}
384
385int
386nvfb_vram_get(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
387 u32 memtype, struct nouveau_mem **pmem)
388{
389 struct nouveau_drm *drm = nouveau_newpriv(dev);
390 struct nouveau_fb *pfb = nouveau_fb(drm->device);
391 int ret = pfb->ram.get(pfb, size, align, ncmin, memtype, pmem);
392 if (ret)
393 return ret;
394 (*pmem)->dev = dev;
395 return 0;
396}
397
398void
399nvfb_vram_put(struct drm_device *dev, struct nouveau_mem **pmem)
400{
401 struct nouveau_drm *drm = nouveau_newpriv(dev);
402 struct nouveau_fb *pfb = nouveau_fb(drm->device);
403 pfb->ram.put(pfb, pmem);
404}
405
406
407u64 nvfb_vram_sys_base(struct drm_device *dev)
408{
409 struct nouveau_drm *drm = nouveau_newpriv(dev);
410 struct nouveau_fb *pfb = nouveau_fb(drm->device);
411 return pfb->ram.stolen;
412}
413
414u64 nvfb_vram_size(struct drm_device *dev)
415{
416 struct nouveau_drm *drm = nouveau_newpriv(dev);
417 struct nouveau_fb *pfb = nouveau_fb(drm->device);
418 return pfb->ram.size;
419}
420
421int nvfb_vram_type(struct drm_device *dev)
422{
423 struct nouveau_drm *drm = nouveau_newpriv(dev);
424 struct nouveau_fb *pfb = nouveau_fb(drm->device);
425 return pfb->ram.type;
426}
427
428int nvfb_vram_rank_B(struct drm_device *dev)
429{
430 struct nouveau_drm *drm = nouveau_newpriv(dev);
431 struct nouveau_fb *pfb = nouveau_fb(drm->device);
432 return pfb->ram.ranks > 1;
433}
434
435void
436nv50_fb_vm_trap(struct drm_device *dev, int disp)
437{
438 struct nouveau_drm *drm = nouveau_newpriv(dev);
439 nv50_fb_trap(nouveau_fb(drm->device), disp);
440}
diff --git a/drivers/gpu/drm/nouveau/nouveau_compat.h b/drivers/gpu/drm/nouveau/nouveau_compat.h
index c9622ebf5cbe..d047a2046959 100644
--- a/drivers/gpu/drm/nouveau/nouveau_compat.h
+++ b/drivers/gpu/drm/nouveau/nouveau_compat.h
@@ -62,4 +62,24 @@ bool nouveau_wait_cb(struct drm_device *, u64 timeout,
62 62
63u64 nv_timer_read(struct drm_device *); 63u64 nv_timer_read(struct drm_device *);
64 64
65int nvfb_tile_nr(struct drm_device *);
66void nvfb_tile_init(struct drm_device *, int, u32, u32, u32, u32);
67void nvfb_tile_fini(struct drm_device *, int);
68void nvfb_tile_prog(struct drm_device *, int);
69
70struct nouveau_fb_tile *nvfb_tile(struct drm_device *, int);
71
72struct nouveau_mem;
73int nvfb_vram_get(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
74 u32 memtype, struct nouveau_mem **pmem);
75void nvfb_vram_put(struct drm_device *dev, struct nouveau_mem **pmem);
76bool nvfb_flags_valid(struct drm_device *dev, u32);
77
78u64 nvfb_vram_sys_base(struct drm_device *);
79u64 nvfb_vram_size(struct drm_device *);
80int nvfb_vram_type(struct drm_device *);
81int nvfb_vram_rank_B(struct drm_device *);
82
83void nv50_fb_vm_trap(struct drm_device *, int);
84
65#endif 85#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index 188c92b327e2..6564b547973e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -137,9 +137,8 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
137{ 137{
138 struct drm_info_node *node = (struct drm_info_node *) m->private; 138 struct drm_info_node *node = (struct drm_info_node *) m->private;
139 struct drm_minor *minor = node->minor; 139 struct drm_minor *minor = node->minor;
140 struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
141 140
142 seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10)); 141 seq_printf(m, "VRAM total: %dKiB\n", (int)(nvfb_vram_size(minor->dev) >> 10));
143 return 0; 142 return 0;
144} 143}
145 144
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 7223a4f69231..3f660a94dd18 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -252,7 +252,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
252 252
253 NV_INFO(dev, "Reinitialising engines...\n"); 253 NV_INFO(dev, "Reinitialising engines...\n");
254 engine->instmem.resume(dev); 254 engine->instmem.resume(dev);
255 engine->fb.init(dev);
256 for (i = 0; i < NVOBJ_ENGINE_NR; i++) { 255 for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
257 if (dev_priv->eng[i]) 256 if (dev_priv->eng[i])
258 dev_priv->eng[i]->init(dev, i); 257 dev_priv->eng[i]->init(dev, i);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index b4595990f5e8..c7bc6ecad601 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -45,6 +45,23 @@
45#include "ttm/ttm_memory.h" 45#include "ttm/ttm_memory.h"
46#include "ttm/ttm_module.h" 46#include "ttm/ttm_module.h"
47 47
48#define XXX_THIS_IS_A_HACK
49#include <subdev/fb.h>
50
51enum blah {
52 NV_MEM_TYPE_UNKNOWN = 0,
53 NV_MEM_TYPE_STOLEN,
54 NV_MEM_TYPE_SGRAM,
55 NV_MEM_TYPE_SDRAM,
56 NV_MEM_TYPE_DDR1,
57 NV_MEM_TYPE_DDR2,
58 NV_MEM_TYPE_DDR3,
59 NV_MEM_TYPE_GDDR2,
60 NV_MEM_TYPE_GDDR3,
61 NV_MEM_TYPE_GDDR4,
62 NV_MEM_TYPE_GDDR5
63};
64
48struct nouveau_fpriv { 65struct nouveau_fpriv {
49 spinlock_t lock; 66 spinlock_t lock;
50 struct list_head channels; 67 struct list_head channels;
@@ -76,29 +93,8 @@ struct nouveau_mem;
76#define NOUVEAU_MAX_CHANNEL_NR 4096 93#define NOUVEAU_MAX_CHANNEL_NR 4096
77#define NOUVEAU_MAX_TILE_NR 15 94#define NOUVEAU_MAX_TILE_NR 15
78 95
79struct nouveau_mem {
80 struct drm_device *dev;
81
82 struct nouveau_vma bar_vma;
83 struct nouveau_vma vma[2];
84 u8 page_shift;
85
86 struct drm_mm_node *tag;
87 struct list_head regions;
88 dma_addr_t *pages;
89 u32 memtype;
90 u64 offset;
91 u64 size;
92 struct sg_table *sg;
93};
94
95struct nouveau_tile_reg { 96struct nouveau_tile_reg {
96 bool used; 97 bool used;
97 uint32_t addr;
98 uint32_t limit;
99 uint32_t pitch;
100 uint32_t zcomp;
101 struct drm_mm_node *tag_mem;
102 struct nouveau_fence *fence; 98 struct nouveau_fence *fence;
103}; 99};
104 100
@@ -324,21 +320,6 @@ struct nouveau_instmem_engine {
324 void (*flush)(struct drm_device *); 320 void (*flush)(struct drm_device *);
325}; 321};
326 322
327struct nouveau_fb_engine {
328 int num_tiles;
329 struct drm_mm tag_heap;
330 void *priv;
331
332 int (*init)(struct drm_device *dev);
333 void (*takedown)(struct drm_device *dev);
334
335 void (*init_tile_region)(struct drm_device *dev, int i,
336 uint32_t addr, uint32_t size,
337 uint32_t pitch, uint32_t flags);
338 void (*set_tile_region)(struct drm_device *dev, int i);
339 void (*free_tile_region)(struct drm_device *dev, int i);
340};
341
342struct nouveau_display_engine { 323struct nouveau_display_engine {
343 void *priv; 324 void *priv;
344 int (*early_init)(struct drm_device *); 325 int (*early_init)(struct drm_device *);
@@ -519,24 +500,10 @@ struct nouveau_pm_engine {
519 int (*temp_get)(struct drm_device *); 500 int (*temp_get)(struct drm_device *);
520}; 501};
521 502
522struct nouveau_vram_engine {
523 struct nouveau_mm mm;
524
525 int (*init)(struct drm_device *);
526 void (*takedown)(struct drm_device *dev);
527 int (*get)(struct drm_device *, u64, u32 align, u32 size_nc,
528 u32 type, struct nouveau_mem **);
529 void (*put)(struct drm_device *, struct nouveau_mem **);
530
531 bool (*flags_valid)(struct drm_device *, u32 tile_flags);
532};
533
534struct nouveau_engine { 503struct nouveau_engine {
535 struct nouveau_instmem_engine instmem; 504 struct nouveau_instmem_engine instmem;
536 struct nouveau_fb_engine fb;
537 struct nouveau_display_engine display; 505 struct nouveau_display_engine display;
538 struct nouveau_pm_engine pm; 506 struct nouveau_pm_engine pm;
539 struct nouveau_vram_engine vram;
540}; 507};
541 508
542enum nv04_fp_display_regs { 509enum nv04_fp_display_regs {
@@ -714,24 +681,6 @@ struct drm_nouveau_private {
714 spinlock_t lock; 681 spinlock_t lock;
715 } tile; 682 } tile;
716 683
717 /* VRAM/fb configuration */
718 enum {
719 NV_MEM_TYPE_UNKNOWN = 0,
720 NV_MEM_TYPE_STOLEN,
721 NV_MEM_TYPE_SGRAM,
722 NV_MEM_TYPE_SDRAM,
723 NV_MEM_TYPE_DDR1,
724 NV_MEM_TYPE_DDR2,
725 NV_MEM_TYPE_DDR3,
726 NV_MEM_TYPE_GDDR2,
727 NV_MEM_TYPE_GDDR3,
728 NV_MEM_TYPE_GDDR4,
729 NV_MEM_TYPE_GDDR5
730 } vram_type;
731 uint64_t vram_size;
732 uint64_t vram_sys_base;
733 bool vram_rank_B;
734
735 uint64_t fb_available_size; 684 uint64_t fb_available_size;
736 uint64_t fb_mappable_pages; 685 uint64_t fb_mappable_pages;
737 uint64_t fb_aper_free; 686 uint64_t fb_aper_free;
@@ -1047,55 +996,6 @@ int nouveau_ttm_mmap(struct file *, struct vm_area_struct *);
1047/* nouveau_hdmi.c */ 996/* nouveau_hdmi.c */
1048void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *); 997void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *);
1049 998
1050/* nv04_fb.c */
1051extern int nv04_fb_vram_init(struct drm_device *);
1052extern int nv04_fb_init(struct drm_device *);
1053extern void nv04_fb_takedown(struct drm_device *);
1054
1055/* nv10_fb.c */
1056extern int nv10_fb_vram_init(struct drm_device *dev);
1057extern int nv1a_fb_vram_init(struct drm_device *dev);
1058extern int nv10_fb_init(struct drm_device *);
1059extern void nv10_fb_takedown(struct drm_device *);
1060extern void nv10_fb_init_tile_region(struct drm_device *dev, int i,
1061 uint32_t addr, uint32_t size,
1062 uint32_t pitch, uint32_t flags);
1063extern void nv10_fb_set_tile_region(struct drm_device *dev, int i);
1064extern void nv10_fb_free_tile_region(struct drm_device *dev, int i);
1065
1066/* nv20_fb.c */
1067extern int nv20_fb_vram_init(struct drm_device *dev);
1068extern int nv20_fb_init(struct drm_device *);
1069extern void nv20_fb_takedown(struct drm_device *);
1070extern void nv20_fb_init_tile_region(struct drm_device *dev, int i,
1071 uint32_t addr, uint32_t size,
1072 uint32_t pitch, uint32_t flags);
1073extern void nv20_fb_set_tile_region(struct drm_device *dev, int i);
1074extern void nv20_fb_free_tile_region(struct drm_device *dev, int i);
1075
1076/* nv30_fb.c */
1077extern int nv30_fb_init(struct drm_device *);
1078extern void nv30_fb_takedown(struct drm_device *);
1079extern void nv30_fb_init_tile_region(struct drm_device *dev, int i,
1080 uint32_t addr, uint32_t size,
1081 uint32_t pitch, uint32_t flags);
1082extern void nv30_fb_free_tile_region(struct drm_device *dev, int i);
1083
1084/* nv40_fb.c */
1085extern int nv40_fb_vram_init(struct drm_device *dev);
1086extern int nv40_fb_init(struct drm_device *);
1087extern void nv40_fb_takedown(struct drm_device *);
1088extern void nv40_fb_set_tile_region(struct drm_device *dev, int i);
1089
1090/* nv50_fb.c */
1091extern int nv50_fb_init(struct drm_device *);
1092extern void nv50_fb_takedown(struct drm_device *);
1093extern void nv50_fb_vm_trap(struct drm_device *, int display);
1094
1095/* nvc0_fb.c */
1096extern int nvc0_fb_init(struct drm_device *);
1097extern void nvc0_fb_takedown(struct drm_device *);
1098
1099/* nv04_graph.c */ 999/* nv04_graph.c */
1100extern int nv04_graph_create(struct drm_device *); 1000extern int nv04_graph_create(struct drm_device *);
1101extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16); 1001extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16);
@@ -1488,18 +1388,6 @@ nv44_graph_class(struct drm_device *dev)
1488 return !(0x0baf & (1 << (dev_priv->chipset & 0x0f))); 1388 return !(0x0baf & (1 << (dev_priv->chipset & 0x0f)));
1489} 1389}
1490 1390
1491int nv50_vram_init(struct drm_device *);
1492void nv50_vram_fini(struct drm_device *);
1493int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc,
1494 u32 memtype, struct nouveau_mem **);
1495void nv50_vram_del(struct drm_device *, struct nouveau_mem **);
1496bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags);
1497
1498int nvc0_vram_init(struct drm_device *);
1499int nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin,
1500 u32 memtype, struct nouveau_mem **);
1501bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags);
1502
1503/* memory type/access flags, do not match hardware values */ 1391/* memory type/access flags, do not match hardware values */
1504#define NV_MEM_ACCESS_RO 1 1392#define NV_MEM_ACCESS_RO 1
1505#define NV_MEM_ACCESS_WO 2 1393#define NV_MEM_ACCESS_WO 2
diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h
index f3fb649fe454..d767567977ee 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fb.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fb.h
@@ -24,8 +24,8 @@
24 * 24 *
25 */ 25 */
26 26
27#ifndef __NOUVEAU_FB_H__ 27#ifndef __NOUVEAU_FRB_H__
28#define __NOUVEAU_FB_H__ 28#define __NOUVEAU_FRB_H__
29 29
30struct nouveau_framebuffer { 30struct nouveau_framebuffer {
31 struct drm_framebuffer base; 31 struct drm_framebuffer base;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 9b078033ec19..f3f0b4c362cb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -475,9 +475,9 @@ int nouveau_fbcon_init(struct drm_device *dev)
475 475
476 drm_fb_helper_single_add_all_connectors(&nfbdev->helper); 476 drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
477 477
478 if (dev_priv->vram_size <= 32 * 1024 * 1024) 478 if (nvfb_vram_size(dev) <= 32 * 1024 * 1024)
479 preferred_bpp = 8; 479 preferred_bpp = 8;
480 else if (dev_priv->vram_size <= 64 * 1024 * 1024) 480 else if (nvfb_vram_size(dev) <= 64 * 1024 * 1024)
481 preferred_bpp = 16; 481 preferred_bpp = 16;
482 else 482 else
483 preferred_bpp = 32; 483 preferred_bpp = 32;
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index c8bb9f230222..96a34bce54ce 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -209,7 +209,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
209 209
210 dev_priv->ttm.bdev.dev_mapping = dev->dev_mapping; 210 dev_priv->ttm.bdev.dev_mapping = dev->dev_mapping;
211 211
212 if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) { 212 if (!nvfb_flags_valid(dev, req->info.tile_flags)) {
213 NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags); 213 NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags);
214 return -EINVAL; 214 return -EINVAL;
215 } 215 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 689d3e708057..4aea1c4c46ef 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -48,21 +48,21 @@
48 48
49static void 49static void
50nv10_mem_update_tile_region(struct drm_device *dev, 50nv10_mem_update_tile_region(struct drm_device *dev,
51 struct nouveau_tile_reg *tile, uint32_t addr, 51 struct nouveau_tile_reg *tilereg, uint32_t addr,
52 uint32_t size, uint32_t pitch, uint32_t flags) 52 uint32_t size, uint32_t pitch, uint32_t flags)
53{ 53{
54 struct drm_nouveau_private *dev_priv = dev->dev_private; 54 struct drm_nouveau_private *dev_priv = dev->dev_private;
55 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; 55 int i = tilereg - dev_priv->tile.reg, j;
56 int i = tile - dev_priv->tile.reg, j; 56 struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
57 unsigned long save; 57 unsigned long save;
58 58
59 nouveau_fence_unref(&tile->fence); 59 nouveau_fence_unref(&tilereg->fence);
60 60
61 if (tile->pitch) 61 if (tile->pitch)
62 pfb->free_tile_region(dev, i); 62 nvfb_tile_fini(dev, i);
63 63
64 if (pitch) 64 if (pitch)
65 pfb->init_tile_region(dev, i, addr, size, pitch, flags); 65 nvfb_tile_init(dev, i, addr, size, pitch, flags);
66 66
67 spin_lock_irqsave(&dev_priv->context_switch_lock, save); 67 spin_lock_irqsave(&dev_priv->context_switch_lock, save);
68 nv_wr32(dev, NV03_PFIFO_CACHES, 0); 68 nv_wr32(dev, NV03_PFIFO_CACHES, 0);
@@ -70,7 +70,7 @@ nv10_mem_update_tile_region(struct drm_device *dev,
70 70
71 nouveau_wait_for_idle(dev); 71 nouveau_wait_for_idle(dev);
72 72
73 pfb->set_tile_region(dev, i); 73 nvfb_tile_prog(dev, i);
74 for (j = 0; j < NVOBJ_ENGINE_NR; j++) { 74 for (j = 0; j < NVOBJ_ENGINE_NR; j++) {
75 if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region) 75 if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region)
76 dev_priv->eng[j]->set_tile_region(dev, i); 76 dev_priv->eng[j]->set_tile_region(dev, i);
@@ -122,19 +122,17 @@ struct nouveau_tile_reg *
122nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, 122nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size,
123 uint32_t pitch, uint32_t flags) 123 uint32_t pitch, uint32_t flags)
124{ 124{
125 struct drm_nouveau_private *dev_priv = dev->dev_private;
126 struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
127 struct nouveau_tile_reg *tile, *found = NULL; 125 struct nouveau_tile_reg *tile, *found = NULL;
128 int i; 126 int i;
129 127
130 for (i = 0; i < pfb->num_tiles; i++) { 128 for (i = 0; i < nvfb_tile_nr(dev); i++) {
131 tile = nv10_mem_get_tile_region(dev, i); 129 tile = nv10_mem_get_tile_region(dev, i);
132 130
133 if (pitch && !found) { 131 if (pitch && !found) {
134 found = tile; 132 found = tile;
135 continue; 133 continue;
136 134
137 } else if (tile && tile->pitch) { 135 } else if (tile && nvfb_tile(dev, i)->pitch) {
138 /* Kill an unused tile region. */ 136 /* Kill an unused tile region. */
139 nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0); 137 nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0);
140 } 138 }
@@ -174,38 +172,11 @@ nouveau_mem_gart_fini(struct drm_device *dev)
174 nouveau_sgdma_takedown(dev); 172 nouveau_sgdma_takedown(dev);
175} 173}
176 174
177bool
178nouveau_mem_flags_valid(struct drm_device *dev, u32 tile_flags)
179{
180 if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))
181 return true;
182
183 return false;
184}
185
186static const struct vram_types {
187 int value;
188 const char *name;
189} vram_type_map[] = {
190 { NV_MEM_TYPE_STOLEN , "stolen system memory" },
191 { NV_MEM_TYPE_SGRAM , "SGRAM" },
192 { NV_MEM_TYPE_SDRAM , "SDRAM" },
193 { NV_MEM_TYPE_DDR1 , "DDR1" },
194 { NV_MEM_TYPE_DDR2 , "DDR2" },
195 { NV_MEM_TYPE_DDR3 , "DDR3" },
196 { NV_MEM_TYPE_GDDR2 , "GDDR2" },
197 { NV_MEM_TYPE_GDDR3 , "GDDR3" },
198 { NV_MEM_TYPE_GDDR4 , "GDDR4" },
199 { NV_MEM_TYPE_GDDR5 , "GDDR5" },
200 { NV_MEM_TYPE_UNKNOWN, "unknown type" }
201};
202
203int 175int
204nouveau_mem_vram_init(struct drm_device *dev) 176nouveau_mem_vram_init(struct drm_device *dev)
205{ 177{
206 struct drm_nouveau_private *dev_priv = dev->dev_private; 178 struct drm_nouveau_private *dev_priv = dev->dev_private;
207 struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; 179 struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
208 const struct vram_types *vram_type;
209 int ret, dma_bits; 180 int ret, dma_bits;
210 181
211 dma_bits = 32; 182 dma_bits = 32;
@@ -243,27 +214,7 @@ nouveau_mem_vram_init(struct drm_device *dev)
243 return ret; 214 return ret;
244 } 215 }
245 216
246 vram_type = vram_type_map; 217 dev_priv->fb_available_size = nvfb_vram_size(dev);
247 while (vram_type->value != NV_MEM_TYPE_UNKNOWN) {
248 if (nouveau_vram_type) {
249 if (!strcasecmp(nouveau_vram_type, vram_type->name))
250 break;
251 dev_priv->vram_type = vram_type->value;
252 } else {
253 if (vram_type->value == dev_priv->vram_type)
254 break;
255 }
256 vram_type++;
257 }
258
259 NV_INFO(dev, "Detected %dMiB VRAM (%s)\n",
260 (int)(dev_priv->vram_size >> 20), vram_type->name);
261 if (dev_priv->vram_sys_base) {
262 NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
263 dev_priv->vram_sys_base);
264 }
265
266 dev_priv->fb_available_size = dev_priv->vram_size;
267 dev_priv->fb_mappable_pages = dev_priv->fb_available_size; 218 dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
268 if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) 219 if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1))
269 dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1); 220 dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1);
@@ -364,7 +315,6 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
364 struct nouveau_pm_memtiming *boot, 315 struct nouveau_pm_memtiming *boot,
365 struct nouveau_pm_memtiming *t) 316 struct nouveau_pm_memtiming *t)
366{ 317{
367 struct drm_nouveau_private *dev_priv = dev->dev_private;
368 struct bit_entry P; 318 struct bit_entry P;
369 uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3; 319 uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3;
370 320
@@ -418,7 +368,7 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
418 t->reg[7] = 0x4000202 | (e->tCL - 1) << 16; 368 t->reg[7] = 0x4000202 | (e->tCL - 1) << 16;
419 369
420 /* XXX: P.version == 1 only has DDR2 and GDDR3? */ 370 /* XXX: P.version == 1 only has DDR2 and GDDR3? */
421 if (dev_priv->vram_type == NV_MEM_TYPE_DDR2) { 371 if (nvfb_vram_type(dev) == NV_MEM_TYPE_DDR2) {
422 t->reg[5] |= (e->tCL + 3) << 8; 372 t->reg[5] |= (e->tCL + 3) << 8;
423 t->reg[6] |= (t->tCWL - 2) << 8; 373 t->reg[6] |= (t->tCWL - 2) << 8;
424 t->reg[8] |= (e->tCL - 4); 374 t->reg[8] |= (e->tCL - 4);
@@ -711,7 +661,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
711 break; 661 break;
712 } 662 }
713 663
714 switch (dev_priv->vram_type * !ret) { 664 switch (nvfb_vram_type(dev) * !ret) {
715 case NV_MEM_TYPE_GDDR3: 665 case NV_MEM_TYPE_GDDR3:
716 ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t); 666 ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
717 break; 667 break;
@@ -738,7 +688,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
738 else 688 else
739 dll_off = !!(ramcfg[2] & 0x40); 689 dll_off = !!(ramcfg[2] & 0x40);
740 690
741 switch (dev_priv->vram_type) { 691 switch (nvfb_vram_type(dev)) {
742 case NV_MEM_TYPE_GDDR3: 692 case NV_MEM_TYPE_GDDR3:
743 t->mr[1] &= ~0x00000040; 693 t->mr[1] &= ~0x00000040;
744 t->mr[1] |= 0x00000040 * dll_off; 694 t->mr[1] |= 0x00000040 * dll_off;
@@ -804,7 +754,7 @@ nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
804 t->odt = 0; 754 t->odt = 0;
805 t->drive_strength = 0; 755 t->drive_strength = 0;
806 756
807 switch (dev_priv->vram_type) { 757 switch (nvfb_vram_type(dev)) {
808 case NV_MEM_TYPE_DDR3: 758 case NV_MEM_TYPE_DDR3:
809 t->odt |= (t->mr[1] & 0x200) >> 7; 759 t->odt |= (t->mr[1] & 0x200) >> 7;
810 case NV_MEM_TYPE_DDR2: 760 case NV_MEM_TYPE_DDR2:
@@ -831,7 +781,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
831 u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] }; 781 u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
832 u32 mr1_dlloff; 782 u32 mr1_dlloff;
833 783
834 switch (dev_priv->vram_type) { 784 switch (nvfb_vram_type(dev_priv->dev)) {
835 case NV_MEM_TYPE_DDR2: 785 case NV_MEM_TYPE_DDR2:
836 tDLLK = 2000; 786 tDLLK = 2000;
837 mr1_dlloff = 0x00000001; 787 mr1_dlloff = 0x00000001;
@@ -852,7 +802,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
852 } 802 }
853 803
854 /* fetch current MRs */ 804 /* fetch current MRs */
855 switch (dev_priv->vram_type) { 805 switch (nvfb_vram_type(dev_priv->dev)) {
856 case NV_MEM_TYPE_GDDR3: 806 case NV_MEM_TYPE_GDDR3:
857 case NV_MEM_TYPE_DDR3: 807 case NV_MEM_TYPE_DDR3:
858 mr[2] = exec->mrg(exec, 2); 808 mr[2] = exec->mrg(exec, 2);
@@ -919,7 +869,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
919 exec->mrs (exec, 0, info->mr[0] | 0x00000000); 869 exec->mrs (exec, 0, info->mr[0] | 0x00000000);
920 exec->wait(exec, tMRD); 870 exec->wait(exec, tMRD);
921 exec->wait(exec, tDLLK); 871 exec->wait(exec, tDLLK);
922 if (dev_priv->vram_type == NV_MEM_TYPE_GDDR3) 872 if (nvfb_vram_type(dev_priv->dev) == NV_MEM_TYPE_GDDR3)
923 exec->precharge(exec); 873 exec->precharge(exec);
924 } 874 }
925 875
@@ -982,11 +932,10 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
982 struct ttm_mem_reg *mem) 932 struct ttm_mem_reg *mem)
983{ 933{
984 struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); 934 struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
985 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
986 struct drm_device *dev = dev_priv->dev; 935 struct drm_device *dev = dev_priv->dev;
987 936
988 nouveau_mem_node_cleanup(mem->mm_node); 937 nouveau_mem_node_cleanup(mem->mm_node);
989 vram->put(dev, (struct nouveau_mem **)&mem->mm_node); 938 nvfb_vram_put(dev, (struct nouveau_mem **)&mem->mm_node);
990} 939}
991 940
992static int 941static int
@@ -996,7 +945,6 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
996 struct ttm_mem_reg *mem) 945 struct ttm_mem_reg *mem)
997{ 946{
998 struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); 947 struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
999 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
1000 struct drm_device *dev = dev_priv->dev; 948 struct drm_device *dev = dev_priv->dev;
1001 struct nouveau_bo *nvbo = nouveau_bo(bo); 949 struct nouveau_bo *nvbo = nouveau_bo(bo);
1002 struct nouveau_mem *node; 950 struct nouveau_mem *node;
@@ -1006,7 +954,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
1006 if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) 954 if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
1007 size_nc = 1 << nvbo->page_shift; 955 size_nc = 1 << nvbo->page_shift;
1008 956
1009 ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, 957 ret = nvfb_vram_get(dev, mem->num_pages << PAGE_SHIFT,
1010 mem->page_alignment << PAGE_SHIFT, size_nc, 958 mem->page_alignment << PAGE_SHIFT, size_nc,
1011 (nvbo->tile_flags >> 8) & 0x3ff, &node); 959 (nvbo->tile_flags >> 8) & 0x3ff, &node);
1012 if (ret) { 960 if (ret) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 3b11962d7d6d..d8d9e5c527a4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -61,8 +61,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
61 engine->instmem.map = nv04_instmem_map; 61 engine->instmem.map = nv04_instmem_map;
62 engine->instmem.unmap = nv04_instmem_unmap; 62 engine->instmem.unmap = nv04_instmem_unmap;
63 engine->instmem.flush = nv04_instmem_flush; 63 engine->instmem.flush = nv04_instmem_flush;
64 engine->fb.init = nv04_fb_init;
65 engine->fb.takedown = nv04_fb_takedown;
66 engine->display.early_init = nv04_display_early_init; 64 engine->display.early_init = nv04_display_early_init;
67 engine->display.late_takedown = nv04_display_late_takedown; 65 engine->display.late_takedown = nv04_display_late_takedown;
68 engine->display.create = nv04_display_create; 66 engine->display.create = nv04_display_create;
@@ -72,9 +70,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
72 engine->pm.clocks_get = nv04_pm_clocks_get; 70 engine->pm.clocks_get = nv04_pm_clocks_get;
73 engine->pm.clocks_pre = nv04_pm_clocks_pre; 71 engine->pm.clocks_pre = nv04_pm_clocks_pre;
74 engine->pm.clocks_set = nv04_pm_clocks_set; 72 engine->pm.clocks_set = nv04_pm_clocks_set;
75 engine->vram.init = nv04_fb_vram_init;
76 engine->vram.takedown = nouveau_stub_takedown;
77 engine->vram.flags_valid = nouveau_mem_flags_valid;
78 break; 73 break;
79 case 0x10: 74 case 0x10:
80 engine->instmem.init = nv04_instmem_init; 75 engine->instmem.init = nv04_instmem_init;
@@ -86,11 +81,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
86 engine->instmem.map = nv04_instmem_map; 81 engine->instmem.map = nv04_instmem_map;
87 engine->instmem.unmap = nv04_instmem_unmap; 82 engine->instmem.unmap = nv04_instmem_unmap;
88 engine->instmem.flush = nv04_instmem_flush; 83 engine->instmem.flush = nv04_instmem_flush;
89 engine->fb.init = nv10_fb_init;
90 engine->fb.takedown = nv10_fb_takedown;
91 engine->fb.init_tile_region = nv10_fb_init_tile_region;
92 engine->fb.set_tile_region = nv10_fb_set_tile_region;
93 engine->fb.free_tile_region = nv10_fb_free_tile_region;
94 engine->display.early_init = nv04_display_early_init; 84 engine->display.early_init = nv04_display_early_init;
95 engine->display.late_takedown = nv04_display_late_takedown; 85 engine->display.late_takedown = nv04_display_late_takedown;
96 engine->display.create = nv04_display_create; 86 engine->display.create = nv04_display_create;
@@ -100,13 +90,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
100 engine->pm.clocks_get = nv04_pm_clocks_get; 90 engine->pm.clocks_get = nv04_pm_clocks_get;
101 engine->pm.clocks_pre = nv04_pm_clocks_pre; 91 engine->pm.clocks_pre = nv04_pm_clocks_pre;
102 engine->pm.clocks_set = nv04_pm_clocks_set; 92 engine->pm.clocks_set = nv04_pm_clocks_set;
103 if (dev_priv->chipset == 0x1a ||
104 dev_priv->chipset == 0x1f)
105 engine->vram.init = nv1a_fb_vram_init;
106 else
107 engine->vram.init = nv10_fb_vram_init;
108 engine->vram.takedown = nouveau_stub_takedown;
109 engine->vram.flags_valid = nouveau_mem_flags_valid;
110 break; 93 break;
111 case 0x20: 94 case 0x20:
112 engine->instmem.init = nv04_instmem_init; 95 engine->instmem.init = nv04_instmem_init;
@@ -118,11 +101,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
118 engine->instmem.map = nv04_instmem_map; 101 engine->instmem.map = nv04_instmem_map;
119 engine->instmem.unmap = nv04_instmem_unmap; 102 engine->instmem.unmap = nv04_instmem_unmap;
120 engine->instmem.flush = nv04_instmem_flush; 103 engine->instmem.flush = nv04_instmem_flush;
121 engine->fb.init = nv20_fb_init;
122 engine->fb.takedown = nv20_fb_takedown;
123 engine->fb.init_tile_region = nv20_fb_init_tile_region;
124 engine->fb.set_tile_region = nv20_fb_set_tile_region;
125 engine->fb.free_tile_region = nv20_fb_free_tile_region;
126 engine->display.early_init = nv04_display_early_init; 104 engine->display.early_init = nv04_display_early_init;
127 engine->display.late_takedown = nv04_display_late_takedown; 105 engine->display.late_takedown = nv04_display_late_takedown;
128 engine->display.create = nv04_display_create; 106 engine->display.create = nv04_display_create;
@@ -132,9 +110,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
132 engine->pm.clocks_get = nv04_pm_clocks_get; 110 engine->pm.clocks_get = nv04_pm_clocks_get;
133 engine->pm.clocks_pre = nv04_pm_clocks_pre; 111 engine->pm.clocks_pre = nv04_pm_clocks_pre;
134 engine->pm.clocks_set = nv04_pm_clocks_set; 112 engine->pm.clocks_set = nv04_pm_clocks_set;
135 engine->vram.init = nv20_fb_vram_init;
136 engine->vram.takedown = nouveau_stub_takedown;
137 engine->vram.flags_valid = nouveau_mem_flags_valid;
138 break; 113 break;
139 case 0x30: 114 case 0x30:
140 engine->instmem.init = nv04_instmem_init; 115 engine->instmem.init = nv04_instmem_init;
@@ -146,11 +121,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
146 engine->instmem.map = nv04_instmem_map; 121 engine->instmem.map = nv04_instmem_map;
147 engine->instmem.unmap = nv04_instmem_unmap; 122 engine->instmem.unmap = nv04_instmem_unmap;
148 engine->instmem.flush = nv04_instmem_flush; 123 engine->instmem.flush = nv04_instmem_flush;
149 engine->fb.init = nv30_fb_init;
150 engine->fb.takedown = nv30_fb_takedown;
151 engine->fb.init_tile_region = nv30_fb_init_tile_region;
152 engine->fb.set_tile_region = nv10_fb_set_tile_region;
153 engine->fb.free_tile_region = nv30_fb_free_tile_region;
154 engine->display.early_init = nv04_display_early_init; 124 engine->display.early_init = nv04_display_early_init;
155 engine->display.late_takedown = nv04_display_late_takedown; 125 engine->display.late_takedown = nv04_display_late_takedown;
156 engine->display.create = nv04_display_create; 126 engine->display.create = nv04_display_create;
@@ -162,9 +132,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
162 engine->pm.clocks_set = nv04_pm_clocks_set; 132 engine->pm.clocks_set = nv04_pm_clocks_set;
163 engine->pm.voltage_get = nouveau_voltage_gpio_get; 133 engine->pm.voltage_get = nouveau_voltage_gpio_get;
164 engine->pm.voltage_set = nouveau_voltage_gpio_set; 134 engine->pm.voltage_set = nouveau_voltage_gpio_set;
165 engine->vram.init = nv20_fb_vram_init;
166 engine->vram.takedown = nouveau_stub_takedown;
167 engine->vram.flags_valid = nouveau_mem_flags_valid;
168 break; 135 break;
169 case 0x40: 136 case 0x40:
170 case 0x60: 137 case 0x60:
@@ -177,11 +144,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
177 engine->instmem.map = nv04_instmem_map; 144 engine->instmem.map = nv04_instmem_map;
178 engine->instmem.unmap = nv04_instmem_unmap; 145 engine->instmem.unmap = nv04_instmem_unmap;
179 engine->instmem.flush = nv04_instmem_flush; 146 engine->instmem.flush = nv04_instmem_flush;
180 engine->fb.init = nv40_fb_init;
181 engine->fb.takedown = nv40_fb_takedown;
182 engine->fb.init_tile_region = nv30_fb_init_tile_region;
183 engine->fb.set_tile_region = nv40_fb_set_tile_region;
184 engine->fb.free_tile_region = nv30_fb_free_tile_region;
185 engine->display.early_init = nv04_display_early_init; 147 engine->display.early_init = nv04_display_early_init;
186 engine->display.late_takedown = nv04_display_late_takedown; 148 engine->display.late_takedown = nv04_display_late_takedown;
187 engine->display.create = nv04_display_create; 149 engine->display.create = nv04_display_create;
@@ -196,9 +158,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
196 engine->pm.temp_get = nv40_temp_get; 158 engine->pm.temp_get = nv40_temp_get;
197 engine->pm.pwm_get = nv40_pm_pwm_get; 159 engine->pm.pwm_get = nv40_pm_pwm_get;
198 engine->pm.pwm_set = nv40_pm_pwm_set; 160 engine->pm.pwm_set = nv40_pm_pwm_set;
199 engine->vram.init = nv40_fb_vram_init;
200 engine->vram.takedown = nouveau_stub_takedown;
201 engine->vram.flags_valid = nouveau_mem_flags_valid;
202 break; 161 break;
203 case 0x50: 162 case 0x50:
204 case 0x80: /* gotta love NVIDIA's consistency.. */ 163 case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -216,8 +175,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
216 engine->instmem.flush = nv50_instmem_flush; 175 engine->instmem.flush = nv50_instmem_flush;
217 else 176 else
218 engine->instmem.flush = nv84_instmem_flush; 177 engine->instmem.flush = nv84_instmem_flush;
219 engine->fb.init = nv50_fb_init;
220 engine->fb.takedown = nv50_fb_takedown;
221 engine->display.early_init = nv50_display_early_init; 178 engine->display.early_init = nv50_display_early_init;
222 engine->display.late_takedown = nv50_display_late_takedown; 179 engine->display.late_takedown = nv50_display_late_takedown;
223 engine->display.create = nv50_display_create; 180 engine->display.create = nv50_display_create;
@@ -253,11 +210,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
253 engine->pm.temp_get = nv40_temp_get; 210 engine->pm.temp_get = nv40_temp_get;
254 engine->pm.pwm_get = nv50_pm_pwm_get; 211 engine->pm.pwm_get = nv50_pm_pwm_get;
255 engine->pm.pwm_set = nv50_pm_pwm_set; 212 engine->pm.pwm_set = nv50_pm_pwm_set;
256 engine->vram.init = nv50_vram_init;
257 engine->vram.takedown = nv50_vram_fini;
258 engine->vram.get = nv50_vram_new;
259 engine->vram.put = nv50_vram_del;
260 engine->vram.flags_valid = nv50_vram_flags_valid;
261 break; 213 break;
262 case 0xc0: 214 case 0xc0:
263 engine->instmem.init = nvc0_instmem_init; 215 engine->instmem.init = nvc0_instmem_init;
@@ -269,19 +221,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
269 engine->instmem.map = nv50_instmem_map; 221 engine->instmem.map = nv50_instmem_map;
270 engine->instmem.unmap = nv50_instmem_unmap; 222 engine->instmem.unmap = nv50_instmem_unmap;
271 engine->instmem.flush = nv84_instmem_flush; 223 engine->instmem.flush = nv84_instmem_flush;
272 engine->fb.init = nvc0_fb_init;
273 engine->fb.takedown = nvc0_fb_takedown;
274 engine->display.early_init = nv50_display_early_init; 224 engine->display.early_init = nv50_display_early_init;
275 engine->display.late_takedown = nv50_display_late_takedown; 225 engine->display.late_takedown = nv50_display_late_takedown;
276 engine->display.create = nv50_display_create; 226 engine->display.create = nv50_display_create;
277 engine->display.destroy = nv50_display_destroy; 227 engine->display.destroy = nv50_display_destroy;
278 engine->display.init = nv50_display_init; 228 engine->display.init = nv50_display_init;
279 engine->display.fini = nv50_display_fini; 229 engine->display.fini = nv50_display_fini;
280 engine->vram.init = nvc0_vram_init;
281 engine->vram.takedown = nv50_vram_fini;
282 engine->vram.get = nvc0_vram_new;
283 engine->vram.put = nv50_vram_del;
284 engine->vram.flags_valid = nvc0_vram_flags_valid;
285 engine->pm.temp_get = nv84_temp_get; 230 engine->pm.temp_get = nv84_temp_get;
286 engine->pm.clocks_get = nvc0_pm_clocks_get; 231 engine->pm.clocks_get = nvc0_pm_clocks_get;
287 engine->pm.clocks_pre = nvc0_pm_clocks_pre; 232 engine->pm.clocks_pre = nvc0_pm_clocks_pre;
@@ -301,19 +246,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
301 engine->instmem.map = nv50_instmem_map; 246 engine->instmem.map = nv50_instmem_map;
302 engine->instmem.unmap = nv50_instmem_unmap; 247 engine->instmem.unmap = nv50_instmem_unmap;
303 engine->instmem.flush = nv84_instmem_flush; 248 engine->instmem.flush = nv84_instmem_flush;
304 engine->fb.init = nvc0_fb_init;
305 engine->fb.takedown = nvc0_fb_takedown;
306 engine->display.early_init = nouveau_stub_init; 249 engine->display.early_init = nouveau_stub_init;
307 engine->display.late_takedown = nouveau_stub_takedown; 250 engine->display.late_takedown = nouveau_stub_takedown;
308 engine->display.create = nvd0_display_create; 251 engine->display.create = nvd0_display_create;
309 engine->display.destroy = nvd0_display_destroy; 252 engine->display.destroy = nvd0_display_destroy;
310 engine->display.init = nvd0_display_init; 253 engine->display.init = nvd0_display_init;
311 engine->display.fini = nvd0_display_fini; 254 engine->display.fini = nvd0_display_fini;
312 engine->vram.init = nvc0_vram_init;
313 engine->vram.takedown = nv50_vram_fini;
314 engine->vram.get = nvc0_vram_new;
315 engine->vram.put = nv50_vram_del;
316 engine->vram.flags_valid = nvc0_vram_flags_valid;
317 engine->pm.temp_get = nv84_temp_get; 255 engine->pm.temp_get = nv84_temp_get;
318 engine->pm.clocks_get = nvc0_pm_clocks_get; 256 engine->pm.clocks_get = nvc0_pm_clocks_get;
319 engine->pm.clocks_pre = nvc0_pm_clocks_pre; 257 engine->pm.clocks_pre = nvc0_pm_clocks_pre;
@@ -331,19 +269,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
331 engine->instmem.map = nv50_instmem_map; 269 engine->instmem.map = nv50_instmem_map;
332 engine->instmem.unmap = nv50_instmem_unmap; 270 engine->instmem.unmap = nv50_instmem_unmap;
333 engine->instmem.flush = nv84_instmem_flush; 271 engine->instmem.flush = nv84_instmem_flush;
334 engine->fb.init = nvc0_fb_init;
335 engine->fb.takedown = nvc0_fb_takedown;
336 engine->display.early_init = nouveau_stub_init; 272 engine->display.early_init = nouveau_stub_init;
337 engine->display.late_takedown = nouveau_stub_takedown; 273 engine->display.late_takedown = nouveau_stub_takedown;
338 engine->display.create = nvd0_display_create; 274 engine->display.create = nvd0_display_create;
339 engine->display.destroy = nvd0_display_destroy; 275 engine->display.destroy = nvd0_display_destroy;
340 engine->display.init = nvd0_display_init; 276 engine->display.init = nvd0_display_init;
341 engine->display.fini = nvd0_display_fini; 277 engine->display.fini = nvd0_display_fini;
342 engine->vram.init = nvc0_vram_init;
343 engine->vram.takedown = nv50_vram_fini;
344 engine->vram.get = nvc0_vram_new;
345 engine->vram.put = nv50_vram_del;
346 engine->vram.flags_valid = nvc0_vram_flags_valid;
347 break; 278 break;
348 default: 279 default:
349 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); 280 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -488,18 +419,9 @@ nouveau_card_init(struct drm_device *dev)
488 nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); 419 nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
489 } 420 }
490 421
491 /* PFB */
492 ret = engine->fb.init(dev);
493 if (ret)
494 goto out_bios;
495
496 ret = engine->vram.init(dev);
497 if (ret)
498 goto out_fb;
499
500 ret = nouveau_gpuobj_init(dev); 422 ret = nouveau_gpuobj_init(dev);
501 if (ret) 423 if (ret)
502 goto out_vram; 424 goto out_bios;
503 425
504 ret = engine->instmem.init(dev); 426 ret = engine->instmem.init(dev);
505 if (ret) 427 if (ret)
@@ -734,10 +656,6 @@ out_instmem:
734 engine->instmem.takedown(dev); 656 engine->instmem.takedown(dev);
735out_gpuobj: 657out_gpuobj:
736 nouveau_gpuobj_takedown(dev); 658 nouveau_gpuobj_takedown(dev);
737out_vram:
738 engine->vram.takedown(dev);
739out_fb:
740 engine->fb.takedown(dev);
741out_bios: 659out_bios:
742 nouveau_bios_takedown(dev); 660 nouveau_bios_takedown(dev);
743out_display_early: 661out_display_early:
@@ -788,9 +706,6 @@ static void nouveau_card_takedown(struct drm_device *dev)
788 engine->instmem.takedown(dev); 706 engine->instmem.takedown(dev);
789 nouveau_gpuobj_takedown(dev); 707 nouveau_gpuobj_takedown(dev);
790 708
791 engine->vram.takedown(dev);
792 engine->fb.takedown(dev);
793
794 nouveau_bios_takedown(dev); 709 nouveau_bios_takedown(dev);
795 engine->display.late_takedown(dev); 710 engine->display.late_takedown(dev);
796 711
diff --git a/drivers/gpu/drm/nouveau/nouveau_util.c b/drivers/gpu/drm/nouveau/nouveau_util.c
index e51b51503baa..6bff634c95fe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_util.c
+++ b/drivers/gpu/drm/nouveau/nouveau_util.c
@@ -26,50 +26,11 @@
26 */ 26 */
27 27
28#include <linux/ratelimit.h> 28#include <linux/ratelimit.h>
29
30#include "nouveau_util.h" 29#include "nouveau_util.h"
31 30
32static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); 31#include <core/enum.h>
33
34void
35nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
36{
37 while (bf->name) {
38 if (value & bf->mask) {
39 printk(" %s", bf->name);
40 value &= ~bf->mask;
41 }
42
43 bf++;
44 }
45
46 if (value)
47 printk(" (unknown bits 0x%08x)", value);
48}
49 32
50const struct nouveau_enum * 33static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
51nouveau_enum_find(const struct nouveau_enum *en, u32 value)
52{
53 while (en->name) {
54 if (en->value == value)
55 return en;
56 en++;
57 }
58
59 return NULL;
60}
61
62void
63nouveau_enum_print(const struct nouveau_enum *en, u32 value)
64{
65 en = nouveau_enum_find(en, value);
66 if (en) {
67 printk("%s", en->name);
68 return;
69 }
70
71 printk("(unknown enum 0x%08x)", value);
72}
73 34
74int 35int
75nouveau_ratelimit(void) 36nouveau_ratelimit(void)
diff --git a/drivers/gpu/drm/nouveau/nouveau_util.h b/drivers/gpu/drm/nouveau/nouveau_util.h
index b97719fbb739..114293758f8c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_util.h
+++ b/drivers/gpu/drm/nouveau/nouveau_util.h
@@ -28,21 +28,7 @@
28#ifndef __NOUVEAU_UTIL_H__ 28#ifndef __NOUVEAU_UTIL_H__
29#define __NOUVEAU_UTIL_H__ 29#define __NOUVEAU_UTIL_H__
30 30
31struct nouveau_bitfield { 31#include <core/enum.h>
32 u32 mask;
33 const char *name;
34};
35
36struct nouveau_enum {
37 u32 value;
38 const char *name;
39 void *data;
40};
41
42void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
43void nouveau_enum_print(const struct nouveau_enum *, u32 value);
44const struct nouveau_enum *
45nouveau_enum_find(const struct nouveau_enum *, u32 value);
46 32
47int nouveau_ratelimit(void); 33int nouveau_ratelimit(void);
48 34
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c
index 5731cb3df67f..7a1424243665 100644
--- a/drivers/gpu/drm/nouveau/nv50_evo.c
+++ b/drivers/gpu/drm/nouveau/nv50_evo.c
@@ -300,24 +300,24 @@ nv50_evo_create(struct drm_device *dev)
300 300
301 /* create some default objects for the scanout memtypes we support */ 301 /* create some default objects for the scanout memtypes we support */
302 ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000, 302 ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000,
303 0, dev_priv->vram_size, NULL); 303 0, nvfb_vram_size(dev), NULL);
304 if (ret) 304 if (ret)
305 goto err; 305 goto err;
306 306
307 ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000, 307 ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000,
308 0, dev_priv->vram_size, NULL); 308 0, nvfb_vram_size(dev), NULL);
309 if (ret) 309 if (ret)
310 goto err; 310 goto err;
311 311
312 ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 | 312 ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 |
313 (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00), 313 (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00),
314 0, dev_priv->vram_size, NULL); 314 0, nvfb_vram_size(dev), NULL);
315 if (ret) 315 if (ret)
316 goto err; 316 goto err;
317 317
318 ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 | 318 ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 |
319 (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00), 319 (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00),
320 0, dev_priv->vram_size, NULL); 320 0, nvfb_vram_size(dev), NULL);
321 if (ret) 321 if (ret)
322 goto err; 322 goto err;
323 323
@@ -352,21 +352,21 @@ nv50_evo_create(struct drm_device *dev)
352 goto err; 352 goto err;
353 353
354 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000, 354 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000,
355 0, dev_priv->vram_size, NULL); 355 0, nvfb_vram_size(dev), NULL);
356 if (ret) 356 if (ret)
357 goto err; 357 goto err;
358 358
359 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 | 359 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 |
360 (dev_priv->chipset < 0xc0 ? 360 (dev_priv->chipset < 0xc0 ?
361 0x7a00 : 0xfe00), 361 0x7a00 : 0xfe00),
362 0, dev_priv->vram_size, NULL); 362 0, nvfb_vram_size(dev), NULL);
363 if (ret) 363 if (ret)
364 goto err; 364 goto err;
365 365
366 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 | 366 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 |
367 (dev_priv->chipset < 0xc0 ? 367 (dev_priv->chipset < 0xc0 ?
368 0x7000 : 0xfe00), 368 0x7000 : 0xfe00),
369 0, dev_priv->vram_size, NULL); 369 0, nvfb_vram_size(dev), NULL);
370 if (ret) 370 if (ret)
371 goto err; 371 goto err;
372 372
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index 378ca8ca9d6a..142cd4e83767 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -471,17 +471,16 @@ mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
471static void 471static void
472mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) 472mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
473{ 473{
474 struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
475 struct nv50_pm_state *info = exec->priv; 474 struct nv50_pm_state *info = exec->priv;
476 struct hwsq_ucode *hwsq = &info->mclk_hwsq; 475 struct hwsq_ucode *hwsq = &info->mclk_hwsq;
477 476
478 if (mr <= 1) { 477 if (mr <= 1) {
479 if (dev_priv->vram_rank_B) 478 if (nvfb_vram_rank_B(exec->dev))
480 hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data); 479 hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data);
481 hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data); 480 hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data);
482 } else 481 } else
483 if (mr <= 3) { 482 if (mr <= 3) {
484 if (dev_priv->vram_rank_B) 483 if (nvfb_vram_rank_B(exec->dev))
485 hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data); 484 hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
486 hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data); 485 hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
487 } 486 }
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c
index 847c616de12f..2f7ee50440ae 100644
--- a/drivers/gpu/drm/nouveau/nva3_pm.c
+++ b/drivers/gpu/drm/nouveau/nva3_pm.c
@@ -361,15 +361,13 @@ mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
361static void 361static void
362mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) 362mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
363{ 363{
364 struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
365
366 if (mr <= 1) { 364 if (mr <= 1) {
367 if (dev_priv->vram_rank_B) 365 if (nvfb_vram_rank_B(exec->dev))
368 nv_wr32(exec->dev, 0x1002c8 + ((mr - 0) * 4), data); 366 nv_wr32(exec->dev, 0x1002c8 + ((mr - 0) * 4), data);
369 nv_wr32(exec->dev, 0x1002c0 + ((mr - 0) * 4), data); 367 nv_wr32(exec->dev, 0x1002c0 + ((mr - 0) * 4), data);
370 } else 368 } else
371 if (mr <= 3) { 369 if (mr <= 3) {
372 if (dev_priv->vram_rank_B) 370 if (nvfb_vram_rank_B(exec->dev))
373 nv_wr32(exec->dev, 0x1002e8 + ((mr - 2) * 4), data); 371 nv_wr32(exec->dev, 0x1002e8 + ((mr - 2) * 4), data);
374 nv_wr32(exec->dev, 0x1002e0 + ((mr - 2) * 4), data); 372 nv_wr32(exec->dev, 0x1002e0 + ((mr - 2) * 4), data);
375 } 373 }
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c
index 4a21a7264c3c..a14711c25176 100644
--- a/drivers/gpu/drm/nouveau/nvc0_pm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_pm.c
@@ -459,8 +459,7 @@ static u32
459mclk_mrg(struct nouveau_mem_exec_func *exec, int mr) 459mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
460{ 460{
461 struct drm_device *dev = exec->dev; 461 struct drm_device *dev = exec->dev;
462 struct drm_nouveau_private *dev_priv = dev->dev_private; 462 if (nvfb_vram_type(dev) != NV_MEM_TYPE_GDDR5) {
463 if (dev_priv->vram_type != NV_MEM_TYPE_GDDR5) {
464 if (mr <= 1) 463 if (mr <= 1)
465 return nv_rd32(dev, 0x10f300 + ((mr - 0) * 4)); 464 return nv_rd32(dev, 0x10f300 + ((mr - 0) * 4));
466 return nv_rd32(dev, 0x10f320 + ((mr - 2) * 4)); 465 return nv_rd32(dev, 0x10f320 + ((mr - 2) * 4));
@@ -478,16 +477,15 @@ static void
478mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) 477mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
479{ 478{
480 struct drm_device *dev = exec->dev; 479 struct drm_device *dev = exec->dev;
481 struct drm_nouveau_private *dev_priv = dev->dev_private; 480 if (nvfb_vram_type(dev) != NV_MEM_TYPE_GDDR5) {
482 if (dev_priv->vram_type != NV_MEM_TYPE_GDDR5) {
483 if (mr <= 1) { 481 if (mr <= 1) {
484 nv_wr32(dev, 0x10f300 + ((mr - 0) * 4), data); 482 nv_wr32(dev, 0x10f300 + ((mr - 0) * 4), data);
485 if (dev_priv->vram_rank_B) 483 if (nvfb_vram_rank_B(dev))
486 nv_wr32(dev, 0x10f308 + ((mr - 0) * 4), data); 484 nv_wr32(dev, 0x10f308 + ((mr - 0) * 4), data);
487 } else 485 } else
488 if (mr <= 3) { 486 if (mr <= 3) {
489 nv_wr32(dev, 0x10f320 + ((mr - 2) * 4), data); 487 nv_wr32(dev, 0x10f320 + ((mr - 2) * 4), data);
490 if (dev_priv->vram_rank_B) 488 if (nvfb_vram_rank_B(dev))
491 nv_wr32(dev, 0x10f328 + ((mr - 2) * 4), data); 489 nv_wr32(dev, 0x10f328 + ((mr - 2) * 4), data);
492 } 490 }
493 } else { 491 } else {
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index d26dd02f3d13..8d9fc00718f0 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -2077,7 +2077,7 @@ nvd0_display_create(struct drm_device *dev)
2077 2077
2078 nv_wo32(disp->mem, dmao + 0x20, 0x00000049); 2078 nv_wo32(disp->mem, dmao + 0x20, 0x00000049);
2079 nv_wo32(disp->mem, dmao + 0x24, 0x00000000); 2079 nv_wo32(disp->mem, dmao + 0x24, 0x00000000);
2080 nv_wo32(disp->mem, dmao + 0x28, (dev_priv->vram_size - 1) >> 8); 2080 nv_wo32(disp->mem, dmao + 0x28, (nvfb_vram_size(dev) - 1) >> 8);
2081 nv_wo32(disp->mem, dmao + 0x2c, 0x00000000); 2081 nv_wo32(disp->mem, dmao + 0x2c, 0x00000000);
2082 nv_wo32(disp->mem, dmao + 0x30, 0x00000000); 2082 nv_wo32(disp->mem, dmao + 0x30, 0x00000000);
2083 nv_wo32(disp->mem, dmao + 0x34, 0x00000000); 2083 nv_wo32(disp->mem, dmao + 0x34, 0x00000000);
@@ -2087,7 +2087,7 @@ nvd0_display_create(struct drm_device *dev)
2087 2087
2088 nv_wo32(disp->mem, dmao + 0x40, 0x00000009); 2088 nv_wo32(disp->mem, dmao + 0x40, 0x00000009);
2089 nv_wo32(disp->mem, dmao + 0x44, 0x00000000); 2089 nv_wo32(disp->mem, dmao + 0x44, 0x00000000);
2090 nv_wo32(disp->mem, dmao + 0x48, (dev_priv->vram_size - 1) >> 8); 2090 nv_wo32(disp->mem, dmao + 0x48, (nvfb_vram_size(dev) - 1) >> 8);
2091 nv_wo32(disp->mem, dmao + 0x4c, 0x00000000); 2091 nv_wo32(disp->mem, dmao + 0x4c, 0x00000000);
2092 nv_wo32(disp->mem, dmao + 0x50, 0x00000000); 2092 nv_wo32(disp->mem, dmao + 0x50, 0x00000000);
2093 nv_wo32(disp->mem, dmao + 0x54, 0x00000000); 2093 nv_wo32(disp->mem, dmao + 0x54, 0x00000000);
@@ -2097,7 +2097,7 @@ nvd0_display_create(struct drm_device *dev)
2097 2097
2098 nv_wo32(disp->mem, dmao + 0x60, 0x0fe00009); 2098 nv_wo32(disp->mem, dmao + 0x60, 0x0fe00009);
2099 nv_wo32(disp->mem, dmao + 0x64, 0x00000000); 2099 nv_wo32(disp->mem, dmao + 0x64, 0x00000000);
2100 nv_wo32(disp->mem, dmao + 0x68, (dev_priv->vram_size - 1) >> 8); 2100 nv_wo32(disp->mem, dmao + 0x68, (nvfb_vram_size(dev) - 1) >> 8);
2101 nv_wo32(disp->mem, dmao + 0x6c, 0x00000000); 2101 nv_wo32(disp->mem, dmao + 0x6c, 0x00000000);
2102 nv_wo32(disp->mem, dmao + 0x70, 0x00000000); 2102 nv_wo32(disp->mem, dmao + 0x70, 0x00000000);
2103 nv_wo32(disp->mem, dmao + 0x74, 0x00000000); 2103 nv_wo32(disp->mem, dmao + 0x74, 0x00000000);