Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/gpu/drm/r128/r128_cce.c
15112 views
1
/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
2
* Created: Wed Apr 5 19:24:19 2000 by [email protected]
3
*/
4
/*
5
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
6
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
7
* All Rights Reserved.
8
*
9
* Permission is hereby granted, free of charge, to any person obtaining a
10
* copy of this software and associated documentation files (the "Software"),
11
* to deal in the Software without restriction, including without limitation
12
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
* and/or sell copies of the Software, and to permit persons to whom the
14
* Software is furnished to do so, subject to the following conditions:
15
*
16
* The above copyright notice and this permission notice (including the next
17
* paragraph) shall be included in all copies or substantial portions of the
18
* Software.
19
*
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
* DEALINGS IN THE SOFTWARE.
27
*
28
* Authors:
29
* Gareth Hughes <[email protected]>
30
*/
31
32
#include <linux/firmware.h>
33
#include <linux/platform_device.h>
34
#include <linux/slab.h>
35
36
#include "drmP.h"
37
#include "drm.h"
38
#include "r128_drm.h"
39
#include "r128_drv.h"
40
41
#define R128_FIFO_DEBUG 0
42
43
#define FIRMWARE_NAME "r128/r128_cce.bin"
44
45
MODULE_FIRMWARE(FIRMWARE_NAME);
46
47
static int R128_READ_PLL(struct drm_device *dev, int addr)
48
{
49
drm_r128_private_t *dev_priv = dev->dev_private;
50
51
R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
52
return R128_READ(R128_CLOCK_CNTL_DATA);
53
}
54
55
#if R128_FIFO_DEBUG
56
static void r128_status(drm_r128_private_t *dev_priv)
57
{
58
printk("GUI_STAT = 0x%08x\n",
59
(unsigned int)R128_READ(R128_GUI_STAT));
60
printk("PM4_STAT = 0x%08x\n",
61
(unsigned int)R128_READ(R128_PM4_STAT));
62
printk("PM4_BUFFER_DL_WPTR = 0x%08x\n",
63
(unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR));
64
printk("PM4_BUFFER_DL_RPTR = 0x%08x\n",
65
(unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR));
66
printk("PM4_MICRO_CNTL = 0x%08x\n",
67
(unsigned int)R128_READ(R128_PM4_MICRO_CNTL));
68
printk("PM4_BUFFER_CNTL = 0x%08x\n",
69
(unsigned int)R128_READ(R128_PM4_BUFFER_CNTL));
70
}
71
#endif
72
73
/* ================================================================
74
* Engine, FIFO control
75
*/
76
77
static int r128_do_pixcache_flush(drm_r128_private_t *dev_priv)
78
{
79
u32 tmp;
80
int i;
81
82
tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL;
83
R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
84
85
for (i = 0; i < dev_priv->usec_timeout; i++) {
86
if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
87
return 0;
88
DRM_UDELAY(1);
89
}
90
91
#if R128_FIFO_DEBUG
92
DRM_ERROR("failed!\n");
93
#endif
94
return -EBUSY;
95
}
96
97
static int r128_do_wait_for_fifo(drm_r128_private_t *dev_priv, int entries)
98
{
99
int i;
100
101
for (i = 0; i < dev_priv->usec_timeout; i++) {
102
int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
103
if (slots >= entries)
104
return 0;
105
DRM_UDELAY(1);
106
}
107
108
#if R128_FIFO_DEBUG
109
DRM_ERROR("failed!\n");
110
#endif
111
return -EBUSY;
112
}
113
114
static int r128_do_wait_for_idle(drm_r128_private_t *dev_priv)
115
{
116
int i, ret;
117
118
ret = r128_do_wait_for_fifo(dev_priv, 64);
119
if (ret)
120
return ret;
121
122
for (i = 0; i < dev_priv->usec_timeout; i++) {
123
if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
124
r128_do_pixcache_flush(dev_priv);
125
return 0;
126
}
127
DRM_UDELAY(1);
128
}
129
130
#if R128_FIFO_DEBUG
131
DRM_ERROR("failed!\n");
132
#endif
133
return -EBUSY;
134
}
135
136
/* ================================================================
137
* CCE control, initialization
138
*/
139
140
/* Load the microcode for the CCE */
141
static int r128_cce_load_microcode(drm_r128_private_t *dev_priv)
142
{
143
struct platform_device *pdev;
144
const struct firmware *fw;
145
const __be32 *fw_data;
146
int rc, i;
147
148
DRM_DEBUG("\n");
149
150
pdev = platform_device_register_simple("r128_cce", 0, NULL, 0);
151
if (IS_ERR(pdev)) {
152
printk(KERN_ERR "r128_cce: Failed to register firmware\n");
153
return PTR_ERR(pdev);
154
}
155
rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev);
156
platform_device_unregister(pdev);
157
if (rc) {
158
printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n",
159
FIRMWARE_NAME);
160
return rc;
161
}
162
163
if (fw->size != 256 * 8) {
164
printk(KERN_ERR
165
"r128_cce: Bogus length %zu in firmware \"%s\"\n",
166
fw->size, FIRMWARE_NAME);
167
rc = -EINVAL;
168
goto out_release;
169
}
170
171
r128_do_wait_for_idle(dev_priv);
172
173
fw_data = (const __be32 *)fw->data;
174
R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
175
for (i = 0; i < 256; i++) {
176
R128_WRITE(R128_PM4_MICROCODE_DATAH,
177
be32_to_cpup(&fw_data[i * 2]));
178
R128_WRITE(R128_PM4_MICROCODE_DATAL,
179
be32_to_cpup(&fw_data[i * 2 + 1]));
180
}
181
182
out_release:
183
release_firmware(fw);
184
return rc;
185
}
186
187
/* Flush any pending commands to the CCE. This should only be used just
188
* prior to a wait for idle, as it informs the engine that the command
189
* stream is ending.
190
*/
191
static void r128_do_cce_flush(drm_r128_private_t *dev_priv)
192
{
193
u32 tmp;
194
195
tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE;
196
R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp);
197
}
198
199
/* Wait for the CCE to go idle.
200
*/
201
int r128_do_cce_idle(drm_r128_private_t *dev_priv)
202
{
203
int i;
204
205
for (i = 0; i < dev_priv->usec_timeout; i++) {
206
if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) {
207
int pm4stat = R128_READ(R128_PM4_STAT);
208
if (((pm4stat & R128_PM4_FIFOCNT_MASK) >=
209
dev_priv->cce_fifo_size) &&
210
!(pm4stat & (R128_PM4_BUSY |
211
R128_PM4_GUI_ACTIVE))) {
212
return r128_do_pixcache_flush(dev_priv);
213
}
214
}
215
DRM_UDELAY(1);
216
}
217
218
#if R128_FIFO_DEBUG
219
DRM_ERROR("failed!\n");
220
r128_status(dev_priv);
221
#endif
222
return -EBUSY;
223
}
224
225
/* Start the Concurrent Command Engine.
226
*/
227
static void r128_do_cce_start(drm_r128_private_t *dev_priv)
228
{
229
r128_do_wait_for_idle(dev_priv);
230
231
R128_WRITE(R128_PM4_BUFFER_CNTL,
232
dev_priv->cce_mode | dev_priv->ring.size_l2qw
233
| R128_PM4_BUFFER_CNTL_NOUPDATE);
234
R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */
235
R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
236
237
dev_priv->cce_running = 1;
238
}
239
240
/* Reset the Concurrent Command Engine. This will not flush any pending
241
* commands, so you must wait for the CCE command stream to complete
242
* before calling this routine.
243
*/
244
static void r128_do_cce_reset(drm_r128_private_t *dev_priv)
245
{
246
R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
247
R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
248
dev_priv->ring.tail = 0;
249
}
250
251
/* Stop the Concurrent Command Engine. This will not flush any pending
252
* commands, so you must flush the command stream and wait for the CCE
253
* to go idle before calling this routine.
254
*/
255
static void r128_do_cce_stop(drm_r128_private_t *dev_priv)
256
{
257
R128_WRITE(R128_PM4_MICRO_CNTL, 0);
258
R128_WRITE(R128_PM4_BUFFER_CNTL,
259
R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE);
260
261
dev_priv->cce_running = 0;
262
}
263
264
/* Reset the engine. This will stop the CCE if it is running.
265
*/
266
static int r128_do_engine_reset(struct drm_device *dev)
267
{
268
drm_r128_private_t *dev_priv = dev->dev_private;
269
u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
270
271
r128_do_pixcache_flush(dev_priv);
272
273
clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX);
274
mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL);
275
276
R128_WRITE_PLL(R128_MCLK_CNTL,
277
mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
278
279
gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL);
280
281
/* Taken from the sample code - do not change */
282
R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
283
R128_READ(R128_GEN_RESET_CNTL);
284
R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
285
R128_READ(R128_GEN_RESET_CNTL);
286
287
R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl);
288
R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
289
R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl);
290
291
/* Reset the CCE ring */
292
r128_do_cce_reset(dev_priv);
293
294
/* The CCE is no longer running after an engine reset */
295
dev_priv->cce_running = 0;
296
297
/* Reset any pending vertex, indirect buffers */
298
r128_freelist_reset(dev);
299
300
return 0;
301
}
302
303
static void r128_cce_init_ring_buffer(struct drm_device *dev,
304
drm_r128_private_t *dev_priv)
305
{
306
u32 ring_start;
307
u32 tmp;
308
309
DRM_DEBUG("\n");
310
311
/* The manual (p. 2) says this address is in "VM space". This
312
* means it's an offset from the start of AGP space.
313
*/
314
#if __OS_HAS_AGP
315
if (!dev_priv->is_pci)
316
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
317
else
318
#endif
319
ring_start = dev_priv->cce_ring->offset -
320
(unsigned long)dev->sg->virtual;
321
322
R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET);
323
324
R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
325
R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
326
327
/* Set watermark control */
328
R128_WRITE(R128_PM4_BUFFER_WM_CNTL,
329
((R128_WATERMARK_L / 4) << R128_WMA_SHIFT)
330
| ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT)
331
| ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT)
332
| ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT));
333
334
/* Force read. Why? Because it's in the examples... */
335
R128_READ(R128_PM4_BUFFER_ADDR);
336
337
/* Turn on bus mastering */
338
tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS;
339
R128_WRITE(R128_BUS_CNTL, tmp);
340
}
341
342
static int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init)
343
{
344
drm_r128_private_t *dev_priv;
345
int rc;
346
347
DRM_DEBUG("\n");
348
349
if (dev->dev_private) {
350
DRM_DEBUG("called when already initialized\n");
351
return -EINVAL;
352
}
353
354
dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL);
355
if (dev_priv == NULL)
356
return -ENOMEM;
357
358
dev_priv->is_pci = init->is_pci;
359
360
if (dev_priv->is_pci && !dev->sg) {
361
DRM_ERROR("PCI GART memory not allocated!\n");
362
dev->dev_private = (void *)dev_priv;
363
r128_do_cleanup_cce(dev);
364
return -EINVAL;
365
}
366
367
dev_priv->usec_timeout = init->usec_timeout;
368
if (dev_priv->usec_timeout < 1 ||
369
dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
370
DRM_DEBUG("TIMEOUT problem!\n");
371
dev->dev_private = (void *)dev_priv;
372
r128_do_cleanup_cce(dev);
373
return -EINVAL;
374
}
375
376
dev_priv->cce_mode = init->cce_mode;
377
378
/* GH: Simple idle check.
379
*/
380
atomic_set(&dev_priv->idle_count, 0);
381
382
/* We don't support anything other than bus-mastering ring mode,
383
* but the ring can be in either AGP or PCI space for the ring
384
* read pointer.
385
*/
386
if ((init->cce_mode != R128_PM4_192BM) &&
387
(init->cce_mode != R128_PM4_128BM_64INDBM) &&
388
(init->cce_mode != R128_PM4_64BM_128INDBM) &&
389
(init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) {
390
DRM_DEBUG("Bad cce_mode!\n");
391
dev->dev_private = (void *)dev_priv;
392
r128_do_cleanup_cce(dev);
393
return -EINVAL;
394
}
395
396
switch (init->cce_mode) {
397
case R128_PM4_NONPM4:
398
dev_priv->cce_fifo_size = 0;
399
break;
400
case R128_PM4_192PIO:
401
case R128_PM4_192BM:
402
dev_priv->cce_fifo_size = 192;
403
break;
404
case R128_PM4_128PIO_64INDBM:
405
case R128_PM4_128BM_64INDBM:
406
dev_priv->cce_fifo_size = 128;
407
break;
408
case R128_PM4_64PIO_128INDBM:
409
case R128_PM4_64BM_128INDBM:
410
case R128_PM4_64PIO_64VCBM_64INDBM:
411
case R128_PM4_64BM_64VCBM_64INDBM:
412
case R128_PM4_64PIO_64VCPIO_64INDPIO:
413
dev_priv->cce_fifo_size = 64;
414
break;
415
}
416
417
switch (init->fb_bpp) {
418
case 16:
419
dev_priv->color_fmt = R128_DATATYPE_RGB565;
420
break;
421
case 32:
422
default:
423
dev_priv->color_fmt = R128_DATATYPE_ARGB8888;
424
break;
425
}
426
dev_priv->front_offset = init->front_offset;
427
dev_priv->front_pitch = init->front_pitch;
428
dev_priv->back_offset = init->back_offset;
429
dev_priv->back_pitch = init->back_pitch;
430
431
switch (init->depth_bpp) {
432
case 16:
433
dev_priv->depth_fmt = R128_DATATYPE_RGB565;
434
break;
435
case 24:
436
case 32:
437
default:
438
dev_priv->depth_fmt = R128_DATATYPE_ARGB8888;
439
break;
440
}
441
dev_priv->depth_offset = init->depth_offset;
442
dev_priv->depth_pitch = init->depth_pitch;
443
dev_priv->span_offset = init->span_offset;
444
445
dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) |
446
(dev_priv->front_offset >> 5));
447
dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) |
448
(dev_priv->back_offset >> 5));
449
dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
450
(dev_priv->depth_offset >> 5) |
451
R128_DST_TILE);
452
dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
453
(dev_priv->span_offset >> 5));
454
455
dev_priv->sarea = drm_getsarea(dev);
456
if (!dev_priv->sarea) {
457
DRM_ERROR("could not find sarea!\n");
458
dev->dev_private = (void *)dev_priv;
459
r128_do_cleanup_cce(dev);
460
return -EINVAL;
461
}
462
463
dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
464
if (!dev_priv->mmio) {
465
DRM_ERROR("could not find mmio region!\n");
466
dev->dev_private = (void *)dev_priv;
467
r128_do_cleanup_cce(dev);
468
return -EINVAL;
469
}
470
dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset);
471
if (!dev_priv->cce_ring) {
472
DRM_ERROR("could not find cce ring region!\n");
473
dev->dev_private = (void *)dev_priv;
474
r128_do_cleanup_cce(dev);
475
return -EINVAL;
476
}
477
dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
478
if (!dev_priv->ring_rptr) {
479
DRM_ERROR("could not find ring read pointer!\n");
480
dev->dev_private = (void *)dev_priv;
481
r128_do_cleanup_cce(dev);
482
return -EINVAL;
483
}
484
dev->agp_buffer_token = init->buffers_offset;
485
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
486
if (!dev->agp_buffer_map) {
487
DRM_ERROR("could not find dma buffer region!\n");
488
dev->dev_private = (void *)dev_priv;
489
r128_do_cleanup_cce(dev);
490
return -EINVAL;
491
}
492
493
if (!dev_priv->is_pci) {
494
dev_priv->agp_textures =
495
drm_core_findmap(dev, init->agp_textures_offset);
496
if (!dev_priv->agp_textures) {
497
DRM_ERROR("could not find agp texture region!\n");
498
dev->dev_private = (void *)dev_priv;
499
r128_do_cleanup_cce(dev);
500
return -EINVAL;
501
}
502
}
503
504
dev_priv->sarea_priv =
505
(drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle +
506
init->sarea_priv_offset);
507
508
#if __OS_HAS_AGP
509
if (!dev_priv->is_pci) {
510
drm_core_ioremap_wc(dev_priv->cce_ring, dev);
511
drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
512
drm_core_ioremap_wc(dev->agp_buffer_map, dev);
513
if (!dev_priv->cce_ring->handle ||
514
!dev_priv->ring_rptr->handle ||
515
!dev->agp_buffer_map->handle) {
516
DRM_ERROR("Could not ioremap agp regions!\n");
517
dev->dev_private = (void *)dev_priv;
518
r128_do_cleanup_cce(dev);
519
return -ENOMEM;
520
}
521
} else
522
#endif
523
{
524
dev_priv->cce_ring->handle =
525
(void *)(unsigned long)dev_priv->cce_ring->offset;
526
dev_priv->ring_rptr->handle =
527
(void *)(unsigned long)dev_priv->ring_rptr->offset;
528
dev->agp_buffer_map->handle =
529
(void *)(unsigned long)dev->agp_buffer_map->offset;
530
}
531
532
#if __OS_HAS_AGP
533
if (!dev_priv->is_pci)
534
dev_priv->cce_buffers_offset = dev->agp->base;
535
else
536
#endif
537
dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
538
539
dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle;
540
dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle
541
+ init->ring_size / sizeof(u32));
542
dev_priv->ring.size = init->ring_size;
543
dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
544
545
dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
546
547
dev_priv->ring.high_mark = 128;
548
549
dev_priv->sarea_priv->last_frame = 0;
550
R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
551
552
dev_priv->sarea_priv->last_dispatch = 0;
553
R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch);
554
555
#if __OS_HAS_AGP
556
if (dev_priv->is_pci) {
557
#endif
558
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
559
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
560
dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
561
dev_priv->gart_info.addr = NULL;
562
dev_priv->gart_info.bus_addr = 0;
563
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
564
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
565
DRM_ERROR("failed to init PCI GART!\n");
566
dev->dev_private = (void *)dev_priv;
567
r128_do_cleanup_cce(dev);
568
return -ENOMEM;
569
}
570
R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr);
571
#if __OS_HAS_AGP
572
}
573
#endif
574
575
r128_cce_init_ring_buffer(dev, dev_priv);
576
rc = r128_cce_load_microcode(dev_priv);
577
578
dev->dev_private = (void *)dev_priv;
579
580
r128_do_engine_reset(dev);
581
582
if (rc) {
583
DRM_ERROR("Failed to load firmware!\n");
584
r128_do_cleanup_cce(dev);
585
}
586
587
return rc;
588
}
589
590
int r128_do_cleanup_cce(struct drm_device *dev)
591
{
592
593
/* Make sure interrupts are disabled here because the uninstall ioctl
594
* may not have been called from userspace and after dev_private
595
* is freed, it's too late.
596
*/
597
if (dev->irq_enabled)
598
drm_irq_uninstall(dev);
599
600
if (dev->dev_private) {
601
drm_r128_private_t *dev_priv = dev->dev_private;
602
603
#if __OS_HAS_AGP
604
if (!dev_priv->is_pci) {
605
if (dev_priv->cce_ring != NULL)
606
drm_core_ioremapfree(dev_priv->cce_ring, dev);
607
if (dev_priv->ring_rptr != NULL)
608
drm_core_ioremapfree(dev_priv->ring_rptr, dev);
609
if (dev->agp_buffer_map != NULL) {
610
drm_core_ioremapfree(dev->agp_buffer_map, dev);
611
dev->agp_buffer_map = NULL;
612
}
613
} else
614
#endif
615
{
616
if (dev_priv->gart_info.bus_addr)
617
if (!drm_ati_pcigart_cleanup(dev,
618
&dev_priv->gart_info))
619
DRM_ERROR
620
("failed to cleanup PCI GART!\n");
621
}
622
623
kfree(dev->dev_private);
624
dev->dev_private = NULL;
625
}
626
627
return 0;
628
}
629
630
int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
631
{
632
drm_r128_init_t *init = data;
633
634
DRM_DEBUG("\n");
635
636
LOCK_TEST_WITH_RETURN(dev, file_priv);
637
638
switch (init->func) {
639
case R128_INIT_CCE:
640
return r128_do_init_cce(dev, init);
641
case R128_CLEANUP_CCE:
642
return r128_do_cleanup_cce(dev);
643
}
644
645
return -EINVAL;
646
}
647
648
int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv)
649
{
650
drm_r128_private_t *dev_priv = dev->dev_private;
651
DRM_DEBUG("\n");
652
653
LOCK_TEST_WITH_RETURN(dev, file_priv);
654
655
DEV_INIT_TEST_WITH_RETURN(dev_priv);
656
657
if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
658
DRM_DEBUG("while CCE running\n");
659
return 0;
660
}
661
662
r128_do_cce_start(dev_priv);
663
664
return 0;
665
}
666
667
/* Stop the CCE. The engine must have been idled before calling this
668
* routine.
669
*/
670
int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv)
671
{
672
drm_r128_private_t *dev_priv = dev->dev_private;
673
drm_r128_cce_stop_t *stop = data;
674
int ret;
675
DRM_DEBUG("\n");
676
677
LOCK_TEST_WITH_RETURN(dev, file_priv);
678
679
DEV_INIT_TEST_WITH_RETURN(dev_priv);
680
681
/* Flush any pending CCE commands. This ensures any outstanding
682
* commands are exectuted by the engine before we turn it off.
683
*/
684
if (stop->flush)
685
r128_do_cce_flush(dev_priv);
686
687
/* If we fail to make the engine go idle, we return an error
688
* code so that the DRM ioctl wrapper can try again.
689
*/
690
if (stop->idle) {
691
ret = r128_do_cce_idle(dev_priv);
692
if (ret)
693
return ret;
694
}
695
696
/* Finally, we can turn off the CCE. If the engine isn't idle,
697
* we will get some dropped triangles as they won't be fully
698
* rendered before the CCE is shut down.
699
*/
700
r128_do_cce_stop(dev_priv);
701
702
/* Reset the engine */
703
r128_do_engine_reset(dev);
704
705
return 0;
706
}
707
708
/* Just reset the CCE ring. Called as part of an X Server engine reset.
709
*/
710
int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
711
{
712
drm_r128_private_t *dev_priv = dev->dev_private;
713
DRM_DEBUG("\n");
714
715
LOCK_TEST_WITH_RETURN(dev, file_priv);
716
717
DEV_INIT_TEST_WITH_RETURN(dev_priv);
718
719
r128_do_cce_reset(dev_priv);
720
721
/* The CCE is no longer running after an engine reset */
722
dev_priv->cce_running = 0;
723
724
return 0;
725
}
726
727
int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv)
728
{
729
drm_r128_private_t *dev_priv = dev->dev_private;
730
DRM_DEBUG("\n");
731
732
LOCK_TEST_WITH_RETURN(dev, file_priv);
733
734
DEV_INIT_TEST_WITH_RETURN(dev_priv);
735
736
if (dev_priv->cce_running)
737
r128_do_cce_flush(dev_priv);
738
739
return r128_do_cce_idle(dev_priv);
740
}
741
742
int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
743
{
744
DRM_DEBUG("\n");
745
746
LOCK_TEST_WITH_RETURN(dev, file_priv);
747
748
DEV_INIT_TEST_WITH_RETURN(dev->dev_private);
749
750
return r128_do_engine_reset(dev);
751
}
752
753
int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv)
754
{
755
return -EINVAL;
756
}
757
758
/* ================================================================
759
* Freelist management
760
*/
761
#define R128_BUFFER_USED 0xffffffff
762
#define R128_BUFFER_FREE 0
763
764
#if 0
765
static int r128_freelist_init(struct drm_device *dev)
766
{
767
struct drm_device_dma *dma = dev->dma;
768
drm_r128_private_t *dev_priv = dev->dev_private;
769
struct drm_buf *buf;
770
drm_r128_buf_priv_t *buf_priv;
771
drm_r128_freelist_t *entry;
772
int i;
773
774
dev_priv->head = kzalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL);
775
if (dev_priv->head == NULL)
776
return -ENOMEM;
777
778
dev_priv->head->age = R128_BUFFER_USED;
779
780
for (i = 0; i < dma->buf_count; i++) {
781
buf = dma->buflist[i];
782
buf_priv = buf->dev_private;
783
784
entry = kmalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL);
785
if (!entry)
786
return -ENOMEM;
787
788
entry->age = R128_BUFFER_FREE;
789
entry->buf = buf;
790
entry->prev = dev_priv->head;
791
entry->next = dev_priv->head->next;
792
if (!entry->next)
793
dev_priv->tail = entry;
794
795
buf_priv->discard = 0;
796
buf_priv->dispatched = 0;
797
buf_priv->list_entry = entry;
798
799
dev_priv->head->next = entry;
800
801
if (dev_priv->head->next)
802
dev_priv->head->next->prev = entry;
803
}
804
805
return 0;
806
807
}
808
#endif
809
810
static struct drm_buf *r128_freelist_get(struct drm_device * dev)
811
{
812
struct drm_device_dma *dma = dev->dma;
813
drm_r128_private_t *dev_priv = dev->dev_private;
814
drm_r128_buf_priv_t *buf_priv;
815
struct drm_buf *buf;
816
int i, t;
817
818
/* FIXME: Optimize -- use freelist code */
819
820
for (i = 0; i < dma->buf_count; i++) {
821
buf = dma->buflist[i];
822
buf_priv = buf->dev_private;
823
if (!buf->file_priv)
824
return buf;
825
}
826
827
for (t = 0; t < dev_priv->usec_timeout; t++) {
828
u32 done_age = R128_READ(R128_LAST_DISPATCH_REG);
829
830
for (i = 0; i < dma->buf_count; i++) {
831
buf = dma->buflist[i];
832
buf_priv = buf->dev_private;
833
if (buf->pending && buf_priv->age <= done_age) {
834
/* The buffer has been processed, so it
835
* can now be used.
836
*/
837
buf->pending = 0;
838
return buf;
839
}
840
}
841
DRM_UDELAY(1);
842
}
843
844
DRM_DEBUG("returning NULL!\n");
845
return NULL;
846
}
847
848
void r128_freelist_reset(struct drm_device *dev)
849
{
850
struct drm_device_dma *dma = dev->dma;
851
int i;
852
853
for (i = 0; i < dma->buf_count; i++) {
854
struct drm_buf *buf = dma->buflist[i];
855
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
856
buf_priv->age = 0;
857
}
858
}
859
860
/* ================================================================
861
* CCE command submission
862
*/
863
864
int r128_wait_ring(drm_r128_private_t *dev_priv, int n)
865
{
866
drm_r128_ring_buffer_t *ring = &dev_priv->ring;
867
int i;
868
869
for (i = 0; i < dev_priv->usec_timeout; i++) {
870
r128_update_ring_snapshot(dev_priv);
871
if (ring->space >= n)
872
return 0;
873
DRM_UDELAY(1);
874
}
875
876
/* FIXME: This is being ignored... */
877
DRM_ERROR("failed!\n");
878
return -EBUSY;
879
}
880
881
static int r128_cce_get_buffers(struct drm_device *dev,
882
struct drm_file *file_priv,
883
struct drm_dma *d)
884
{
885
int i;
886
struct drm_buf *buf;
887
888
for (i = d->granted_count; i < d->request_count; i++) {
889
buf = r128_freelist_get(dev);
890
if (!buf)
891
return -EAGAIN;
892
893
buf->file_priv = file_priv;
894
895
if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
896
sizeof(buf->idx)))
897
return -EFAULT;
898
if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
899
sizeof(buf->total)))
900
return -EFAULT;
901
902
d->granted_count++;
903
}
904
return 0;
905
}
906
907
int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv)
908
{
909
struct drm_device_dma *dma = dev->dma;
910
int ret = 0;
911
struct drm_dma *d = data;
912
913
LOCK_TEST_WITH_RETURN(dev, file_priv);
914
915
/* Please don't send us buffers.
916
*/
917
if (d->send_count != 0) {
918
DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
919
DRM_CURRENTPID, d->send_count);
920
return -EINVAL;
921
}
922
923
/* We'll send you buffers.
924
*/
925
if (d->request_count < 0 || d->request_count > dma->buf_count) {
926
DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
927
DRM_CURRENTPID, d->request_count, dma->buf_count);
928
return -EINVAL;
929
}
930
931
d->granted_count = 0;
932
933
if (d->request_count)
934
ret = r128_cce_get_buffers(dev, file_priv, d);
935
936
return ret;
937
}
938
939