aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-07-13 02:14:25 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:12:49 -0400
commitaf7afbd2e1409168698bde2f2846848b07d05d12 (patch)
tree7d5bcd5f71b17fdf06b365b0f8b86b560df663d4 /drivers
parent861d21074bbb141b0cc165a61c11f571571cda12 (diff)
drm/nv04-nv40/instmem: duplicate nv04 code as nv40, remove alternate paths
A ton of duplication for the moment, will go away when they become subdevs. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/Makefile1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h11
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c167
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c18
6 files changed, 202 insertions, 54 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 5e18a53e2c0..68043a40d9e 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -67,6 +67,7 @@ nouveau-y += core/subdev/i2c/base.o
67nouveau-y += core/subdev/i2c/aux.o 67nouveau-y += core/subdev/i2c/aux.o
68nouveau-y += core/subdev/i2c/bit.o 68nouveau-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/nv40.o
70nouveau-y += core/subdev/instmem/nv50.o 71nouveau-y += core/subdev/instmem/nv50.o
71nouveau-y += core/subdev/instmem/nvc0.o 72nouveau-y += core/subdev/instmem/nvc0.o
72nouveau-y += core/subdev/ltcg/nvc0.o 73nouveau-y += core/subdev/ltcg/nvc0.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
index f01063c078e..8265ca8adf3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
@@ -11,9 +11,6 @@ nouveau_fifo_ctx_size(struct drm_device *dev)
11{ 11{
12 struct drm_nouveau_private *dev_priv = dev->dev_private; 12 struct drm_nouveau_private *dev_priv = dev->dev_private;
13 13
14 if (dev_priv->chipset >= 0x40)
15 return 128 * 32;
16 else
17 if (dev_priv->chipset >= 0x17) 14 if (dev_priv->chipset >= 0x17)
18 return 64 * 32; 15 return 64 * 32;
19 else 16 else
@@ -32,27 +29,7 @@ int nv04_instmem_init(struct drm_device *dev)
32 29
33 /* RAMIN always available */ 30 /* RAMIN always available */
34 dev_priv->ramin_available = true; 31 dev_priv->ramin_available = true;
35 32 dev_priv->ramin_rsvd_vram = 512 * 1024;
36 /* Reserve space at end of VRAM for PRAMIN */
37 if (dev_priv->card_type >= NV_40) {
38 u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
39 u32 rsvd;
40
41 /* estimate grctx size, the magics come from nv40_grctx.c */
42 if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
43 else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs;
44 else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs;
45 else rsvd = 0x4a40 * vs;
46 rsvd += 16 * 1024;
47 rsvd *= 32; /* per-channel */
48
49 rsvd += 512 * 1024; /* pci(e)gart table */
50 rsvd += 512 * 1024; /* object storage */
51
52 dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
53 } else {
54 dev_priv->ramin_rsvd_vram = 512 * 1024;
55 }
56 33
57 /* Setup shared RAMHT */ 34 /* Setup shared RAMHT */
58 ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096, 35 ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
@@ -73,14 +50,7 @@ int nv04_instmem_init(struct drm_device *dev)
73 50
74 /* And RAMFC */ 51 /* And RAMFC */
75 length = nouveau_fifo_ctx_size(dev); 52 length = nouveau_fifo_ctx_size(dev);
76 switch (dev_priv->card_type) { 53 offset = 0x11400;
77 case NV_40:
78 offset = 0x20000;
79 break;
80 default:
81 offset = 0x11400;
82 break;
83 }
84 54
85 ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length, 55 ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
86 NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc); 56 NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
@@ -90,19 +60,6 @@ int nv04_instmem_init(struct drm_device *dev)
90 /* Only allow space after RAMFC to be used for object allocation */ 60 /* Only allow space after RAMFC to be used for object allocation */
91 offset += length; 61 offset += length;
92 62
93 /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
94 * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0
95 * ("new style" control) the upper 16-bits of 0x2220 points at this
96 * other mysterious table that's clobbering important things.
97 *
98 * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
99 * smashed to pieces on us, so reserve 0x30000-0x40000 too..
100 */
101 if (dev_priv->card_type >= NV_40) {
102 if (offset < 0x40000)
103 offset = 0x40000;
104 }
105
106 ret = drm_mm_init(&dev_priv->ramin_heap, offset, 63 ret = drm_mm_init(&dev_priv->ramin_heap, offset,
107 dev_priv->ramin_rsvd_vram - offset); 64 dev_priv->ramin_rsvd_vram - offset);
108 if (ret) { 65 if (ret) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
new file mode 100644
index 00000000000..a8c1104a83d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
@@ -0,0 +1,11 @@
1#ifndef __NV04_INSTMEM_H__
2#define __NV04_INSTMEM_H__
3
4struct nv04_instmem_priv {
5 struct nouveau_gpuobj *vbios;
6 struct nouveau_gpuobj *ramht;
7 struct nouveau_gpuobj *ramro;
8 struct nouveau_gpuobj *ramfc;
9};
10
11#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
new file mode 100644
index 00000000000..91abf0beb07
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
@@ -0,0 +1,167 @@
1#include "drmP.h"
2#include "drm.h"
3
4#include "nouveau_drv.h"
5#include <engine/fifo.h>
6#include <core/ramht.h>
7
8/* returns the size of fifo context */
9static int
10nouveau_fifo_ctx_size(struct drm_device *dev)
11{
12 return 128 * 32;
13}
14
15int nv40_instmem_init(struct drm_device *dev)
16{
17 struct drm_nouveau_private *dev_priv = dev->dev_private;
18 struct nouveau_gpuobj *ramht = NULL;
19 u32 offset, length, vs, rsvd;
20 int ret;
21
22 /* RAMIN always available */
23 dev_priv->ramin_available = true;
24
25 /* Reserve space at end of VRAM for PRAMIN */
26 /* estimate grctx size, the magics come from nv40_grctx.c */
27 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
28 if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
29 else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs;
30 else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs;
31 else rsvd = 0x4a40 * vs;
32 rsvd += 16 * 1024;
33 rsvd *= 32; /* per-channel */
34
35 rsvd += 512 * 1024; /* pci(e)gart table */
36 rsvd += 512 * 1024; /* object storage */
37
38 dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
39
40 /* Setup shared RAMHT */
41 ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
42 NVOBJ_FLAG_ZERO_ALLOC, &ramht);
43 if (ret)
44 return ret;
45
46 ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht);
47 nouveau_gpuobj_ref(NULL, &ramht);
48 if (ret)
49 return ret;
50
51 /* And RAMRO */
52 ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512,
53 NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro);
54 if (ret)
55 return ret;
56
57 /* And RAMFC */
58 length = nouveau_fifo_ctx_size(dev);
59 offset = 0x20000;
60
61 ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
62 NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
63 if (ret)
64 return ret;
65
66 /* Only allow space after RAMFC to be used for object allocation */
67 offset += length;
68
69 /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
70 * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0
71 * ("new style" control) the upper 16-bits of 0x2220 points at this
72 * other mysterious table that's clobbering important things.
73 *
74 * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
75 * smashed to pieces on us, so reserve 0x30000-0x40000 too..
76 */
77 if (offset < 0x40000)
78 offset = 0x40000;
79
80 ret = drm_mm_init(&dev_priv->ramin_heap, offset,
81 dev_priv->ramin_rsvd_vram - offset);
82 if (ret) {
83 NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
84 return ret;
85 }
86
87 return 0;
88}
89
90void
91nv40_instmem_takedown(struct drm_device *dev)
92{
93 struct drm_nouveau_private *dev_priv = dev->dev_private;
94
95 nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
96 nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
97 nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
98
99 if (drm_mm_initialized(&dev_priv->ramin_heap))
100 drm_mm_takedown(&dev_priv->ramin_heap);
101}
102
103int
104nv40_instmem_suspend(struct drm_device *dev)
105{
106 return 0;
107}
108
109void
110nv40_instmem_resume(struct drm_device *dev)
111{
112}
113
114int
115nv40_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
116 u32 size, u32 align)
117{
118 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
119 struct drm_mm_node *ramin = NULL;
120
121 do {
122 if (drm_mm_pre_get(&dev_priv->ramin_heap))
123 return -ENOMEM;
124
125 spin_lock(&dev_priv->ramin_lock);
126 ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0);
127 if (ramin == NULL) {
128 spin_unlock(&dev_priv->ramin_lock);
129 return -ENOMEM;
130 }
131
132 ramin = drm_mm_get_block_atomic(ramin, size, align);
133 spin_unlock(&dev_priv->ramin_lock);
134 } while (ramin == NULL);
135
136 gpuobj->node = ramin;
137 gpuobj->vinst = ramin->start;
138 return 0;
139}
140
141void
142nv40_instmem_put(struct nouveau_gpuobj *gpuobj)
143{
144 struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
145
146 spin_lock(&dev_priv->ramin_lock);
147 drm_mm_put_block(gpuobj->node);
148 gpuobj->node = NULL;
149 spin_unlock(&dev_priv->ramin_lock);
150}
151
152int
153nv40_instmem_map(struct nouveau_gpuobj *gpuobj)
154{
155 gpuobj->pinst = gpuobj->vinst;
156 return 0;
157}
158
159void
160nv40_instmem_unmap(struct nouveau_gpuobj *gpuobj)
161{
162}
163
164void
165nv40_instmem_flush(struct drm_device *dev)
166{
167}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index c7bc6ecad60..ca88403be3f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1072,6 +1072,18 @@ extern int nv04_instmem_map(struct nouveau_gpuobj *);
1072extern void nv04_instmem_unmap(struct nouveau_gpuobj *); 1072extern void nv04_instmem_unmap(struct nouveau_gpuobj *);
1073extern void nv04_instmem_flush(struct drm_device *); 1073extern void nv04_instmem_flush(struct drm_device *);
1074 1074
1075/* nv40_instmem.c */
1076extern int nv40_instmem_init(struct drm_device *);
1077extern void nv40_instmem_takedown(struct drm_device *);
1078extern int nv40_instmem_suspend(struct drm_device *);
1079extern void nv40_instmem_resume(struct drm_device *);
1080extern int nv40_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *,
1081 u32 size, u32 align);
1082extern void nv40_instmem_put(struct nouveau_gpuobj *);
1083extern int nv40_instmem_map(struct nouveau_gpuobj *);
1084extern void nv40_instmem_unmap(struct nouveau_gpuobj *);
1085extern void nv40_instmem_flush(struct drm_device *);
1086
1075/* nv50_instmem.c */ 1087/* nv50_instmem.c */
1076extern int nv50_instmem_init(struct drm_device *); 1088extern int nv50_instmem_init(struct drm_device *);
1077extern void nv50_instmem_takedown(struct drm_device *); 1089extern void nv50_instmem_takedown(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index d8d9e5c527a..14998ee89c9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -135,15 +135,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
135 break; 135 break;
136 case 0x40: 136 case 0x40:
137 case 0x60: 137 case 0x60:
138 engine->instmem.init = nv04_instmem_init; 138 engine->instmem.init = nv40_instmem_init;
139 engine->instmem.takedown = nv04_instmem_takedown; 139 engine->instmem.takedown = nv40_instmem_takedown;
140 engine->instmem.suspend = nv04_instmem_suspend; 140 engine->instmem.suspend = nv40_instmem_suspend;
141 engine->instmem.resume = nv04_instmem_resume; 141 engine->instmem.resume = nv40_instmem_resume;
142 engine->instmem.get = nv04_instmem_get; 142 engine->instmem.get = nv40_instmem_get;
143 engine->instmem.put = nv04_instmem_put; 143 engine->instmem.put = nv40_instmem_put;
144 engine->instmem.map = nv04_instmem_map; 144 engine->instmem.map = nv40_instmem_map;
145 engine->instmem.unmap = nv04_instmem_unmap; 145 engine->instmem.unmap = nv40_instmem_unmap;
146 engine->instmem.flush = nv04_instmem_flush; 146 engine->instmem.flush = nv40_instmem_flush;
147 engine->display.early_init = nv04_display_early_init; 147 engine->display.early_init = nv04_display_early_init;
148 engine->display.late_takedown = nv04_display_late_takedown; 148 engine->display.late_takedown = nv04_display_late_takedown;
149 engine->display.create = nv04_display_create; 149 engine->display.create = nv04_display_create;