diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-07-31 02:16:21 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-10-02 23:12:59 -0400 |
commit | 77145f1cbdf8d28b46ff8070ca749bad821e0774 (patch) | |
tree | b496d5d69ce4f5753028b07b09d8cf12025310f2 /drivers/gpu/drm/nouveau/nv50_evo.c | |
parent | 2094dd82eddc468b53ee99d92c38b23a65efac03 (diff) |
drm/nouveau: port remainder of drm code, and rip out compat layer
v2: Ben Skeggs <bskeggs@redhat.com>
- fill in nouveau_pm.dev to prevent oops
- fix ppc issues (build + OF shadow)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_evo.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_evo.c | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index d7d8080c6a14..0f534160c021 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c | |||
@@ -24,10 +24,15 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | 26 | ||
27 | #include "nouveau_drv.h" | 27 | #include "nouveau_drm.h" |
28 | #include "nouveau_dma.h" | 28 | #include "nouveau_dma.h" |
29 | #include "nv50_display.h" | 29 | #include "nv50_display.h" |
30 | 30 | ||
31 | #include <core/gpuobj.h> | ||
32 | |||
33 | #include <subdev/timer.h> | ||
34 | #include <subdev/fb.h> | ||
35 | |||
31 | static u32 | 36 | static u32 |
32 | nv50_evo_rd32(struct nouveau_object *object, u32 addr) | 37 | nv50_evo_rd32(struct nouveau_object *object, u32 addr) |
33 | { | 38 | { |
@@ -65,15 +70,15 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 handle, u32 memtype, | |||
65 | u64 base, u64 size, struct nouveau_gpuobj **pobj) | 70 | u64 base, u64 size, struct nouveau_gpuobj **pobj) |
66 | { | 71 | { |
67 | struct drm_device *dev = evo->fence; | 72 | struct drm_device *dev = evo->fence; |
68 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 73 | struct nouveau_drm *drm = nouveau_drm(dev); |
69 | struct nv50_display *disp = nv50_display(dev); | 74 | struct nv50_display *disp = nv50_display(dev); |
70 | u32 dmao = disp->dmao; | 75 | u32 dmao = disp->dmao; |
71 | u32 hash = disp->hash; | 76 | u32 hash = disp->hash; |
72 | u32 flags5; | 77 | u32 flags5; |
73 | 78 | ||
74 | if (dev_priv->chipset < 0xc0) { | 79 | if (nv_device(drm->device)->chipset < 0xc0) { |
75 | /* not supported on 0x50, specified in format mthd */ | 80 | /* not supported on 0x50, specified in format mthd */ |
76 | if (dev_priv->chipset == 0x50) | 81 | if (nv_device(drm->device)->chipset == 0x50) |
77 | memtype = 0; | 82 | memtype = 0; |
78 | flags5 = 0x00010000; | 83 | flags5 = 0x00010000; |
79 | } else { | 84 | } else { |
@@ -104,6 +109,7 @@ static int | |||
104 | nv50_evo_channel_new(struct drm_device *dev, int chid, | 109 | nv50_evo_channel_new(struct drm_device *dev, int chid, |
105 | struct nouveau_channel **pevo) | 110 | struct nouveau_channel **pevo) |
106 | { | 111 | { |
112 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
107 | struct nv50_display *disp = nv50_display(dev); | 113 | struct nv50_display *disp = nv50_display(dev); |
108 | struct nouveau_channel *evo; | 114 | struct nouveau_channel *evo; |
109 | int ret; | 115 | int ret; |
@@ -113,6 +119,7 @@ nv50_evo_channel_new(struct drm_device *dev, int chid, | |||
113 | return -ENOMEM; | 119 | return -ENOMEM; |
114 | *pevo = evo; | 120 | *pevo = evo; |
115 | 121 | ||
122 | evo->drm = drm; | ||
116 | evo->handle = chid; | 123 | evo->handle = chid; |
117 | evo->fence = dev; | 124 | evo->fence = dev; |
118 | evo->user_get = 4; | 125 | evo->user_get = 4; |
@@ -123,14 +130,14 @@ nv50_evo_channel_new(struct drm_device *dev, int chid, | |||
123 | if (ret == 0) | 130 | if (ret == 0) |
124 | ret = nouveau_bo_pin(evo->push.buffer, TTM_PL_FLAG_VRAM); | 131 | ret = nouveau_bo_pin(evo->push.buffer, TTM_PL_FLAG_VRAM); |
125 | if (ret) { | 132 | if (ret) { |
126 | NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret); | 133 | NV_ERROR(drm, "Error creating EVO DMA push buffer: %d\n", ret); |
127 | nv50_evo_channel_del(pevo); | 134 | nv50_evo_channel_del(pevo); |
128 | return ret; | 135 | return ret; |
129 | } | 136 | } |
130 | 137 | ||
131 | ret = nouveau_bo_map(evo->push.buffer); | 138 | ret = nouveau_bo_map(evo->push.buffer); |
132 | if (ret) { | 139 | if (ret) { |
133 | NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret); | 140 | NV_ERROR(drm, "Error mapping EVO DMA push buffer: %d\n", ret); |
134 | nv50_evo_channel_del(pevo); | 141 | nv50_evo_channel_del(pevo); |
135 | return ret; | 142 | return ret; |
136 | } | 143 | } |
@@ -156,39 +163,40 @@ nv50_evo_channel_new(struct drm_device *dev, int chid, | |||
156 | static int | 163 | static int |
157 | nv50_evo_channel_init(struct nouveau_channel *evo) | 164 | nv50_evo_channel_init(struct nouveau_channel *evo) |
158 | { | 165 | { |
159 | struct drm_device *dev = evo->fence; | 166 | struct nouveau_drm *drm = evo->drm; |
167 | struct nouveau_device *device = nv_device(drm->device); | ||
160 | int id = evo->handle, ret, i; | 168 | int id = evo->handle, ret, i; |
161 | u64 pushbuf = evo->push.buffer->bo.offset; | 169 | u64 pushbuf = evo->push.buffer->bo.offset; |
162 | u32 tmp; | 170 | u32 tmp; |
163 | 171 | ||
164 | tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)); | 172 | tmp = nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id)); |
165 | if ((tmp & 0x009f0000) == 0x00020000) | 173 | if ((tmp & 0x009f0000) == 0x00020000) |
166 | nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00800000); | 174 | nv_wr32(device, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00800000); |
167 | 175 | ||
168 | tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)); | 176 | tmp = nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id)); |
169 | if ((tmp & 0x003f0000) == 0x00030000) | 177 | if ((tmp & 0x003f0000) == 0x00030000) |
170 | nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00600000); | 178 | nv_wr32(device, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00600000); |
171 | 179 | ||
172 | /* initialise fifo */ | 180 | /* initialise fifo */ |
173 | nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(id), pushbuf >> 8 | | 181 | nv_wr32(device, NV50_PDISPLAY_EVO_DMA_CB(id), pushbuf >> 8 | |
174 | NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | | 182 | NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | |
175 | NV50_PDISPLAY_EVO_DMA_CB_VALID); | 183 | NV50_PDISPLAY_EVO_DMA_CB_VALID); |
176 | nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000); | 184 | nv_wr32(device, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000); |
177 | nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(id), id); | 185 | nv_wr32(device, NV50_PDISPLAY_EVO_HASH_TAG(id), id); |
178 | nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), NV50_PDISPLAY_EVO_CTRL_DMA, | 186 | nv_mask(device, NV50_PDISPLAY_EVO_CTRL(id), NV50_PDISPLAY_EVO_CTRL_DMA, |
179 | NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); | 187 | NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); |
180 | 188 | ||
181 | nv_wr32(dev, NV50_PDISPLAY_USER_PUT(id), 0x00000000); | 189 | nv_wr32(device, NV50_PDISPLAY_USER_PUT(id), 0x00000000); |
182 | nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 | | 190 | nv_wr32(device, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 | |
183 | NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); | 191 | NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); |
184 | if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) { | 192 | if (!nv_wait(device, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) { |
185 | NV_ERROR(dev, "EvoCh %d init timeout: 0x%08x\n", id, | 193 | NV_ERROR(drm, "EvoCh %d init timeout: 0x%08x\n", id, |
186 | nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); | 194 | nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id))); |
187 | return -EBUSY; | 195 | return -EBUSY; |
188 | } | 196 | } |
189 | 197 | ||
190 | /* enable error reporting on the channel */ | 198 | /* enable error reporting on the channel */ |
191 | nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); | 199 | nv_mask(device, 0x610028, 0x00000000, 0x00010001 << id); |
192 | 200 | ||
193 | evo->dma.max = (4096/4) - 2; | 201 | evo->dma.max = (4096/4) - 2; |
194 | evo->dma.max &= ~7; | 202 | evo->dma.max &= ~7; |
@@ -209,16 +217,17 @@ nv50_evo_channel_init(struct nouveau_channel *evo) | |||
209 | static void | 217 | static void |
210 | nv50_evo_channel_fini(struct nouveau_channel *evo) | 218 | nv50_evo_channel_fini(struct nouveau_channel *evo) |
211 | { | 219 | { |
212 | struct drm_device *dev = evo->fence; | 220 | struct nouveau_drm *drm = evo->drm; |
221 | struct nouveau_device *device = nv_device(drm->device); | ||
213 | int id = evo->handle; | 222 | int id = evo->handle; |
214 | 223 | ||
215 | nv_mask(dev, 0x610028, 0x00010001 << id, 0x00000000); | 224 | nv_mask(device, 0x610028, 0x00010001 << id, 0x00000000); |
216 | nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00001010, 0x00001000); | 225 | nv_mask(device, NV50_PDISPLAY_EVO_CTRL(id), 0x00001010, 0x00001000); |
217 | nv_wr32(dev, NV50_PDISPLAY_INTR_0, (1 << id)); | 226 | nv_wr32(device, NV50_PDISPLAY_INTR_0, (1 << id)); |
218 | nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00000003, 0x00000000); | 227 | nv_mask(device, NV50_PDISPLAY_EVO_CTRL(id), 0x00000003, 0x00000000); |
219 | if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x001e0000, 0x00000000)) { | 228 | if (!nv_wait(device, NV50_PDISPLAY_EVO_CTRL(id), 0x001e0000, 0x00000000)) { |
220 | NV_ERROR(dev, "EvoCh %d takedown timeout: 0x%08x\n", id, | 229 | NV_ERROR(drm, "EvoCh %d takedown timeout: 0x%08x\n", id, |
221 | nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); | 230 | nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id))); |
222 | } | 231 | } |
223 | } | 232 | } |
224 | 233 | ||
@@ -242,7 +251,8 @@ nv50_evo_destroy(struct drm_device *dev) | |||
242 | int | 251 | int |
243 | nv50_evo_create(struct drm_device *dev) | 252 | nv50_evo_create(struct drm_device *dev) |
244 | { | 253 | { |
245 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 254 | struct nouveau_drm *drm = nouveau_drm(dev); |
255 | struct nouveau_fb *pfb = nouveau_fb(drm->device); | ||
246 | struct nv50_display *disp = nv50_display(dev); | 256 | struct nv50_display *disp = nv50_display(dev); |
247 | struct nouveau_channel *evo; | 257 | struct nouveau_channel *evo; |
248 | int ret, i, j; | 258 | int ret, i, j; |
@@ -251,10 +261,10 @@ nv50_evo_create(struct drm_device *dev) | |||
251 | * use this also as there's no per-channel support on the | 261 | * use this also as there's no per-channel support on the |
252 | * hardware | 262 | * hardware |
253 | */ | 263 | */ |
254 | ret = nouveau_gpuobj_new(dev, NULL, 32768, 65536, | 264 | ret = nouveau_gpuobj_new(drm->device, NULL, 32768, 65536, |
255 | NVOBJ_FLAG_ZERO_ALLOC, &disp->ramin); | 265 | NVOBJ_FLAG_ZERO_ALLOC, &disp->ramin); |
256 | if (ret) { | 266 | if (ret) { |
257 | NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); | 267 | NV_ERROR(drm, "Error allocating EVO channel memory: %d\n", ret); |
258 | goto err; | 268 | goto err; |
259 | } | 269 | } |
260 | 270 | ||
@@ -276,24 +286,24 @@ nv50_evo_create(struct drm_device *dev) | |||
276 | 286 | ||
277 | /* create some default objects for the scanout memtypes we support */ | 287 | /* create some default objects for the scanout memtypes we support */ |
278 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000, | 288 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000, |
279 | 0, nvfb_vram_size(dev), NULL); | 289 | 0, pfb->ram.size, NULL); |
280 | if (ret) | 290 | if (ret) |
281 | goto err; | 291 | goto err; |
282 | 292 | ||
283 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000, | 293 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000, |
284 | 0, nvfb_vram_size(dev), NULL); | 294 | 0, pfb->ram.size, NULL); |
285 | if (ret) | 295 | if (ret) |
286 | goto err; | 296 | goto err; |
287 | 297 | ||
288 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 | | 298 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 | |
289 | (dev_priv->chipset < 0xc0 ? 0x7a : 0xfe), | 299 | (nv_device(drm->device)->chipset < 0xc0 ? 0x7a : 0xfe), |
290 | 0, nvfb_vram_size(dev), NULL); | 300 | 0, pfb->ram.size, NULL); |
291 | if (ret) | 301 | if (ret) |
292 | goto err; | 302 | goto err; |
293 | 303 | ||
294 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 | | 304 | ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 | |
295 | (dev_priv->chipset < 0xc0 ? 0x70 : 0xfe), | 305 | (nv_device(drm->device)->chipset < 0xc0 ? 0x70 : 0xfe), |
296 | 0, nvfb_vram_size(dev), NULL); | 306 | 0, pfb->ram.size, NULL); |
297 | if (ret) | 307 | if (ret) |
298 | goto err; | 308 | goto err; |
299 | 309 | ||
@@ -328,21 +338,21 @@ nv50_evo_create(struct drm_device *dev) | |||
328 | goto err; | 338 | goto err; |
329 | 339 | ||
330 | ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000, | 340 | ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000, |
331 | 0, nvfb_vram_size(dev), NULL); | 341 | 0, pfb->ram.size, NULL); |
332 | if (ret) | 342 | if (ret) |
333 | goto err; | 343 | goto err; |
334 | 344 | ||
335 | ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 | | 345 | ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 | |
336 | (dev_priv->chipset < 0xc0 ? | 346 | (nv_device(drm->device)->chipset < 0xc0 ? |
337 | 0x7a : 0xfe), | 347 | 0x7a : 0xfe), |
338 | 0, nvfb_vram_size(dev), NULL); | 348 | 0, pfb->ram.size, NULL); |
339 | if (ret) | 349 | if (ret) |
340 | goto err; | 350 | goto err; |
341 | 351 | ||
342 | ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 | | 352 | ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 | |
343 | (dev_priv->chipset < 0xc0 ? | 353 | (nv_device(drm->device)->chipset < 0xc0 ? |
344 | 0x70 : 0xfe), | 354 | 0x70 : 0xfe), |
345 | 0, nvfb_vram_size(dev), NULL); | 355 | 0, pfb->ram.size, NULL); |
346 | if (ret) | 356 | if (ret) |
347 | goto err; | 357 | goto err; |
348 | 358 | ||