diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-07-13 02:14:25 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-10-02 23:12:49 -0400 |
commit | af7afbd2e1409168698bde2f2846848b07d05d12 (patch) | |
tree | 7d5bcd5f71b17fdf06b365b0f8b86b560df663d4 /drivers | |
parent | 861d21074bbb141b0cc165a61c11f571571cda12 (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/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c | 167 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 18 |
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 | |||
67 | nouveau-y += core/subdev/i2c/aux.o | 67 | nouveau-y += core/subdev/i2c/aux.o |
68 | nouveau-y += core/subdev/i2c/bit.o | 68 | nouveau-y += core/subdev/i2c/bit.o |
69 | nouveau-y += core/subdev/instmem/nv04.o | 69 | nouveau-y += core/subdev/instmem/nv04.o |
70 | nouveau-y += core/subdev/instmem/nv40.o | ||
70 | nouveau-y += core/subdev/instmem/nv50.o | 71 | nouveau-y += core/subdev/instmem/nv50.o |
71 | nouveau-y += core/subdev/instmem/nvc0.o | 72 | nouveau-y += core/subdev/instmem/nvc0.o |
72 | nouveau-y += core/subdev/ltcg/nvc0.o | 73 | nouveau-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 | |||
4 | struct 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 */ | ||
9 | static int | ||
10 | nouveau_fifo_ctx_size(struct drm_device *dev) | ||
11 | { | ||
12 | return 128 * 32; | ||
13 | } | ||
14 | |||
15 | int 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 | |||
90 | void | ||
91 | nv40_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 | |||
103 | int | ||
104 | nv40_instmem_suspend(struct drm_device *dev) | ||
105 | { | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void | ||
110 | nv40_instmem_resume(struct drm_device *dev) | ||
111 | { | ||
112 | } | ||
113 | |||
114 | int | ||
115 | nv40_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 | |||
141 | void | ||
142 | nv40_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 | |||
152 | int | ||
153 | nv40_instmem_map(struct nouveau_gpuobj *gpuobj) | ||
154 | { | ||
155 | gpuobj->pinst = gpuobj->vinst; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | void | ||
160 | nv40_instmem_unmap(struct nouveau_gpuobj *gpuobj) | ||
161 | { | ||
162 | } | ||
163 | |||
164 | void | ||
165 | nv40_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 *); | |||
1072 | extern void nv04_instmem_unmap(struct nouveau_gpuobj *); | 1072 | extern void nv04_instmem_unmap(struct nouveau_gpuobj *); |
1073 | extern void nv04_instmem_flush(struct drm_device *); | 1073 | extern void nv04_instmem_flush(struct drm_device *); |
1074 | 1074 | ||
1075 | /* nv40_instmem.c */ | ||
1076 | extern int nv40_instmem_init(struct drm_device *); | ||
1077 | extern void nv40_instmem_takedown(struct drm_device *); | ||
1078 | extern int nv40_instmem_suspend(struct drm_device *); | ||
1079 | extern void nv40_instmem_resume(struct drm_device *); | ||
1080 | extern int nv40_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *, | ||
1081 | u32 size, u32 align); | ||
1082 | extern void nv40_instmem_put(struct nouveau_gpuobj *); | ||
1083 | extern int nv40_instmem_map(struct nouveau_gpuobj *); | ||
1084 | extern void nv40_instmem_unmap(struct nouveau_gpuobj *); | ||
1085 | extern void nv40_instmem_flush(struct drm_device *); | ||
1086 | |||
1075 | /* nv50_instmem.c */ | 1087 | /* nv50_instmem.c */ |
1076 | extern int nv50_instmem_init(struct drm_device *); | 1088 | extern int nv50_instmem_init(struct drm_device *); |
1077 | extern void nv50_instmem_takedown(struct drm_device *); | 1089 | extern 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; |