diff options
| author | Dave Airlie <airlied@starflyer.(none)> | 2006-01-24 23:31:43 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@linux.ie> | 2006-01-24 23:31:43 -0500 |
| commit | de227f5f32775d86e5c780a7cffdd2e08574f7fb (patch) | |
| tree | b1f866fdf54c42d4bc1370f6b529f81c1e4ccf24 | |
| parent | 507d256bae9eef7acd5049af6e3f67c24904a1e4 (diff) | |
drm: i915 patches from Tungsten Graphics
Fix CMDBUFFER path, add heap destroy and flesh out sarea for rotation
(Tungsten Graphics)
From: Alan Hourihane <alanh@tungstengraphics.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
| -rw-r--r-- | drivers/char/drm/i915_dma.c | 42 | ||||
| -rw-r--r-- | drivers/char/drm/i915_drm.h | 33 | ||||
| -rw-r--r-- | drivers/char/drm/i915_drv.h | 6 | ||||
| -rw-r--r-- | drivers/char/drm/i915_mem.c | 31 |
4 files changed, 98 insertions, 14 deletions
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 9140703da1ba..1ff4c7ca0bff 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
| @@ -344,18 +344,20 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) | |||
| 344 | int i; | 344 | int i; |
| 345 | RING_LOCALS; | 345 | RING_LOCALS; |
| 346 | 346 | ||
| 347 | if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) | ||
| 348 | return DRM_ERR(EINVAL); | ||
| 349 | |||
| 350 | BEGIN_LP_RING(((dwords+1)&~1)); | ||
| 351 | |||
| 347 | for (i = 0; i < dwords;) { | 352 | for (i = 0; i < dwords;) { |
| 348 | int cmd, sz; | 353 | int cmd, sz; |
| 349 | 354 | ||
| 350 | if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) | 355 | if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) |
| 351 | return DRM_ERR(EINVAL); | 356 | return DRM_ERR(EINVAL); |
| 352 | 357 | ||
| 353 | /* printk("%d/%d ", i, dwords); */ | ||
| 354 | |||
| 355 | if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) | 358 | if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) |
| 356 | return DRM_ERR(EINVAL); | 359 | return DRM_ERR(EINVAL); |
| 357 | 360 | ||
| 358 | BEGIN_LP_RING(sz); | ||
| 359 | OUT_RING(cmd); | 361 | OUT_RING(cmd); |
| 360 | 362 | ||
| 361 | while (++i, --sz) { | 363 | while (++i, --sz) { |
| @@ -365,9 +367,13 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) | |||
| 365 | } | 367 | } |
| 366 | OUT_RING(cmd); | 368 | OUT_RING(cmd); |
| 367 | } | 369 | } |
| 368 | ADVANCE_LP_RING(); | ||
| 369 | } | 370 | } |
| 370 | 371 | ||
| 372 | if (dwords & 1) | ||
| 373 | OUT_RING(0); | ||
| 374 | |||
| 375 | ADVANCE_LP_RING(); | ||
| 376 | |||
| 371 | return 0; | 377 | return 0; |
| 372 | } | 378 | } |
| 373 | 379 | ||
| @@ -401,6 +407,21 @@ static int i915_emit_box(drm_device_t * dev, | |||
| 401 | return 0; | 407 | return 0; |
| 402 | } | 408 | } |
| 403 | 409 | ||
| 410 | static void i915_emit_breadcrumb(drm_device_t *dev) | ||
| 411 | { | ||
| 412 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 413 | RING_LOCALS; | ||
| 414 | |||
| 415 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | ||
| 416 | |||
| 417 | BEGIN_LP_RING(4); | ||
| 418 | OUT_RING(CMD_STORE_DWORD_IDX); | ||
| 419 | OUT_RING(20); | ||
| 420 | OUT_RING(dev_priv->counter); | ||
| 421 | OUT_RING(0); | ||
| 422 | ADVANCE_LP_RING(); | ||
| 423 | } | ||
| 424 | |||
| 404 | static int i915_dispatch_cmdbuffer(drm_device_t * dev, | 425 | static int i915_dispatch_cmdbuffer(drm_device_t * dev, |
| 405 | drm_i915_cmdbuffer_t * cmd) | 426 | drm_i915_cmdbuffer_t * cmd) |
| 406 | { | 427 | { |
| @@ -429,6 +450,7 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev, | |||
| 429 | return ret; | 450 | return ret; |
| 430 | } | 451 | } |
| 431 | 452 | ||
| 453 | i915_emit_breadcrumb(dev); | ||
| 432 | return 0; | 454 | return 0; |
| 433 | } | 455 | } |
| 434 | 456 | ||
| @@ -475,12 +497,7 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, | |||
| 475 | 497 | ||
| 476 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 498 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
| 477 | 499 | ||
| 478 | BEGIN_LP_RING(4); | 500 | i915_emit_breadcrumb(dev); |
| 479 | OUT_RING(CMD_STORE_DWORD_IDX); | ||
| 480 | OUT_RING(20); | ||
| 481 | OUT_RING(dev_priv->counter); | ||
| 482 | OUT_RING(0); | ||
| 483 | ADVANCE_LP_RING(); | ||
| 484 | 501 | ||
| 485 | return 0; | 502 | return 0; |
| 486 | } | 503 | } |
| @@ -657,7 +674,7 @@ static int i915_getparam(DRM_IOCTL_ARGS) | |||
| 657 | value = READ_BREADCRUMB(dev_priv); | 674 | value = READ_BREADCRUMB(dev_priv); |
| 658 | break; | 675 | break; |
| 659 | default: | 676 | default: |
| 660 | DRM_ERROR("Unkown parameter %d\n", param.param); | 677 | DRM_ERROR("Unknown parameter %d\n", param.param); |
| 661 | return DRM_ERR(EINVAL); | 678 | return DRM_ERR(EINVAL); |
| 662 | } | 679 | } |
| 663 | 680 | ||
| @@ -742,7 +759,8 @@ drm_ioctl_desc_t i915_ioctls[] = { | |||
| 742 | [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, | 759 | [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, |
| 743 | [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, | 760 | [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, |
| 744 | [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 761 | [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
| 745 | [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} | 762 | [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, |
| 763 | [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY } | ||
| 746 | }; | 764 | }; |
| 747 | 765 | ||
| 748 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 766 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 77412ddac007..4cb3da578330 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h | |||
| @@ -74,6 +74,30 @@ typedef struct _drm_i915_sarea { | |||
| 74 | int pf_active; | 74 | int pf_active; |
| 75 | int pf_current_page; /* which buffer is being displayed? */ | 75 | int pf_current_page; /* which buffer is being displayed? */ |
| 76 | int perf_boxes; /* performance boxes to be displayed */ | 76 | int perf_boxes; /* performance boxes to be displayed */ |
| 77 | int width, height; /* screen size in pixels */ | ||
| 78 | |||
| 79 | drm_handle_t front_handle; | ||
| 80 | int front_offset; | ||
| 81 | int front_size; | ||
| 82 | |||
| 83 | drm_handle_t back_handle; | ||
| 84 | int back_offset; | ||
| 85 | int back_size; | ||
| 86 | |||
| 87 | drm_handle_t depth_handle; | ||
| 88 | int depth_offset; | ||
| 89 | int depth_size; | ||
| 90 | |||
| 91 | drm_handle_t tex_handle; | ||
| 92 | int tex_offset; | ||
| 93 | int tex_size; | ||
| 94 | int log_tex_granularity; | ||
| 95 | int pitch; | ||
| 96 | int rotation; /* 0, 90, 180 or 270 */ | ||
| 97 | int rotated_offset; | ||
| 98 | int rotated_size; | ||
| 99 | int rotated_pitch; | ||
| 100 | int virtualX, virtualY; | ||
| 77 | } drm_i915_sarea_t; | 101 | } drm_i915_sarea_t; |
| 78 | 102 | ||
| 79 | /* Flags for perf_boxes | 103 | /* Flags for perf_boxes |
| @@ -99,6 +123,7 @@ typedef struct _drm_i915_sarea { | |||
| 99 | #define DRM_I915_FREE 0x09 | 123 | #define DRM_I915_FREE 0x09 |
| 100 | #define DRM_I915_INIT_HEAP 0x0a | 124 | #define DRM_I915_INIT_HEAP 0x0a |
| 101 | #define DRM_I915_CMDBUFFER 0x0b | 125 | #define DRM_I915_CMDBUFFER 0x0b |
| 126 | #define DRM_I915_DESTROY_HEAP 0x0c | ||
| 102 | 127 | ||
| 103 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 128 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
| 104 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 129 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
| @@ -112,6 +137,7 @@ typedef struct _drm_i915_sarea { | |||
| 112 | #define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) | 137 | #define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) |
| 113 | #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) | 138 | #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) |
| 114 | #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) | 139 | #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) |
| 140 | #define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) | ||
| 115 | 141 | ||
| 116 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 142 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
| 117 | * on the security mechanisms provided by hardware. | 143 | * on the security mechanisms provided by hardware. |
| @@ -191,4 +217,11 @@ typedef struct drm_i915_mem_init_heap { | |||
| 191 | int start; | 217 | int start; |
| 192 | } drm_i915_mem_init_heap_t; | 218 | } drm_i915_mem_init_heap_t; |
| 193 | 219 | ||
| 220 | /* Allow memory manager to be torn down and re-initialized (eg on | ||
| 221 | * rotate): | ||
| 222 | */ | ||
| 223 | typedef struct drm_i915_mem_destroy_heap { | ||
| 224 | int region; | ||
| 225 | } drm_i915_mem_destroy_heap_t; | ||
| 226 | |||
| 194 | #endif /* _I915_DRM_H_ */ | 227 | #endif /* _I915_DRM_H_ */ |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index c6c71b45f101..7a65666899e4 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
| @@ -37,16 +37,17 @@ | |||
| 37 | 37 | ||
| 38 | #define DRIVER_NAME "i915" | 38 | #define DRIVER_NAME "i915" |
| 39 | #define DRIVER_DESC "Intel Graphics" | 39 | #define DRIVER_DESC "Intel Graphics" |
| 40 | #define DRIVER_DATE "20051209" | 40 | #define DRIVER_DATE "20060119" |
| 41 | 41 | ||
| 42 | /* Interface history: | 42 | /* Interface history: |
| 43 | * | 43 | * |
| 44 | * 1.1: Original. | 44 | * 1.1: Original. |
| 45 | * 1.2: Add Power Management | 45 | * 1.2: Add Power Management |
| 46 | * 1.3: Add vblank support | 46 | * 1.3: Add vblank support |
| 47 | * 1.4: Fix cmdbuffer path, add heap destroy | ||
| 47 | */ | 48 | */ |
| 48 | #define DRIVER_MAJOR 1 | 49 | #define DRIVER_MAJOR 1 |
| 49 | #define DRIVER_MINOR 3 | 50 | #define DRIVER_MINOR 4 |
| 50 | #define DRIVER_PATCHLEVEL 0 | 51 | #define DRIVER_PATCHLEVEL 0 |
| 51 | 52 | ||
| 52 | typedef struct _drm_i915_ring_buffer { | 53 | typedef struct _drm_i915_ring_buffer { |
| @@ -123,6 +124,7 @@ extern void i915_driver_irq_uninstall(drm_device_t * dev); | |||
| 123 | extern int i915_mem_alloc(DRM_IOCTL_ARGS); | 124 | extern int i915_mem_alloc(DRM_IOCTL_ARGS); |
| 124 | extern int i915_mem_free(DRM_IOCTL_ARGS); | 125 | extern int i915_mem_free(DRM_IOCTL_ARGS); |
| 125 | extern int i915_mem_init_heap(DRM_IOCTL_ARGS); | 126 | extern int i915_mem_init_heap(DRM_IOCTL_ARGS); |
| 127 | extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS); | ||
| 126 | extern void i915_mem_takedown(struct mem_block **heap); | 128 | extern void i915_mem_takedown(struct mem_block **heap); |
| 127 | extern void i915_mem_release(drm_device_t * dev, | 129 | extern void i915_mem_release(drm_device_t * dev, |
| 128 | DRMFILE filp, struct mem_block *heap); | 130 | DRMFILE filp, struct mem_block *heap); |
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c index ba87ff17ff64..52c67324df58 100644 --- a/drivers/char/drm/i915_mem.c +++ b/drivers/char/drm/i915_mem.c | |||
| @@ -365,3 +365,34 @@ int i915_mem_init_heap(DRM_IOCTL_ARGS) | |||
| 365 | 365 | ||
| 366 | return init_heap(heap, initheap.start, initheap.size); | 366 | return init_heap(heap, initheap.start, initheap.size); |
| 367 | } | 367 | } |
| 368 | |||
| 369 | int i915_mem_destroy_heap( DRM_IOCTL_ARGS ) | ||
| 370 | { | ||
| 371 | DRM_DEVICE; | ||
| 372 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 373 | drm_i915_mem_destroy_heap_t destroyheap; | ||
| 374 | struct mem_block **heap; | ||
| 375 | |||
| 376 | if ( !dev_priv ) { | ||
| 377 | DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); | ||
| 378 | return DRM_ERR(EINVAL); | ||
| 379 | } | ||
| 380 | |||
| 381 | DRM_COPY_FROM_USER_IOCTL( destroyheap, (drm_i915_mem_destroy_heap_t *)data, | ||
| 382 | sizeof(destroyheap) ); | ||
| 383 | |||
| 384 | heap = get_heap( dev_priv, destroyheap.region ); | ||
| 385 | if (!heap) { | ||
| 386 | DRM_ERROR("get_heap failed"); | ||
| 387 | return DRM_ERR(EFAULT); | ||
| 388 | } | ||
| 389 | |||
| 390 | if (!*heap) { | ||
| 391 | DRM_ERROR("heap not initialized?"); | ||
| 392 | return DRM_ERR(EFAULT); | ||
| 393 | } | ||
| 394 | |||
| 395 | i915_mem_takedown( heap ); | ||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
