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>

authored by Dave Airlie and committed by Dave Airlie de227f5f 507d256b

+98 -14
+30 -12
drivers/char/drm/i915_dma.c
··· 344 int i; 345 RING_LOCALS; 346 347 for (i = 0; i < dwords;) { 348 int cmd, sz; 349 350 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 351 return DRM_ERR(EINVAL); 352 353 - /* printk("%d/%d ", i, dwords); */ 354 - 355 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 356 return DRM_ERR(EINVAL); 357 358 - BEGIN_LP_RING(sz); 359 OUT_RING(cmd); 360 361 while (++i, --sz) { ··· 367 } 368 OUT_RING(cmd); 369 } 370 - ADVANCE_LP_RING(); 371 } 372 373 return 0; 374 } ··· 407 return 0; 408 } 409 410 static int i915_dispatch_cmdbuffer(drm_device_t * dev, 411 drm_i915_cmdbuffer_t * cmd) 412 { ··· 450 return ret; 451 } 452 453 return 0; 454 } 455 ··· 497 498 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 499 500 - BEGIN_LP_RING(4); 501 - OUT_RING(CMD_STORE_DWORD_IDX); 502 - OUT_RING(20); 503 - OUT_RING(dev_priv->counter); 504 - OUT_RING(0); 505 - ADVANCE_LP_RING(); 506 507 return 0; 508 } ··· 674 value = READ_BREADCRUMB(dev_priv); 675 break; 676 default: 677 - DRM_ERROR("Unkown parameter %d\n", param.param); 678 return DRM_ERR(EINVAL); 679 } 680 ··· 759 [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, 760 [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, 761 [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 762 - [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} 763 }; 764 765 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
··· 344 int i; 345 RING_LOCALS; 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 + 352 for (i = 0; i < dwords;) { 353 int cmd, sz; 354 355 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 356 return DRM_ERR(EINVAL); 357 358 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 359 return DRM_ERR(EINVAL); 360 361 OUT_RING(cmd); 362 363 while (++i, --sz) { ··· 365 } 366 OUT_RING(cmd); 367 } 368 } 369 + 370 + if (dwords & 1) 371 + OUT_RING(0); 372 + 373 + ADVANCE_LP_RING(); 374 375 return 0; 376 } ··· 401 return 0; 402 } 403 404 + static void i915_emit_breadcrumb(drm_device_t *dev) 405 + { 406 + drm_i915_private_t *dev_priv = dev->dev_private; 407 + RING_LOCALS; 408 + 409 + dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 410 + 411 + BEGIN_LP_RING(4); 412 + OUT_RING(CMD_STORE_DWORD_IDX); 413 + OUT_RING(20); 414 + OUT_RING(dev_priv->counter); 415 + OUT_RING(0); 416 + ADVANCE_LP_RING(); 417 + } 418 + 419 static int i915_dispatch_cmdbuffer(drm_device_t * dev, 420 drm_i915_cmdbuffer_t * cmd) 421 { ··· 429 return ret; 430 } 431 432 + i915_emit_breadcrumb(dev); 433 return 0; 434 } 435 ··· 475 476 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 477 478 + i915_emit_breadcrumb(dev); 479 480 return 0; 481 } ··· 657 value = READ_BREADCRUMB(dev_priv); 658 break; 659 default: 660 + DRM_ERROR("Unknown parameter %d\n", param.param); 661 return DRM_ERR(EINVAL); 662 } 663 ··· 742 [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, 743 [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}, 745 + [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, 746 + [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY } 747 }; 748 749 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
+33
drivers/char/drm/i915_drm.h
··· 74 int pf_active; 75 int pf_current_page; /* which buffer is being displayed? */ 76 int perf_boxes; /* performance boxes to be displayed */ 77 } drm_i915_sarea_t; 78 79 /* Flags for perf_boxes ··· 123 #define DRM_I915_FREE 0x09 124 #define DRM_I915_INIT_HEAP 0x0a 125 #define DRM_I915_CMDBUFFER 0x0b 126 127 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 128 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) ··· 137 #define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) 138 #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) 139 #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) 140 141 /* Allow drivers to submit batchbuffers directly to hardware, relying 142 * on the security mechanisms provided by hardware. ··· 216 int size; 217 int start; 218 } drm_i915_mem_init_heap_t; 219 220 #endif /* _I915_DRM_H_ */
··· 74 int pf_active; 75 int pf_current_page; /* which buffer is being 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; 101 } drm_i915_sarea_t; 102 103 /* Flags for perf_boxes ··· 99 #define DRM_I915_FREE 0x09 100 #define DRM_I915_INIT_HEAP 0x0a 101 #define DRM_I915_CMDBUFFER 0x0b 102 + #define DRM_I915_DESTROY_HEAP 0x0c 103 104 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 105 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) ··· 112 #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) 114 #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) 115 + #define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) 116 117 /* Allow drivers to submit batchbuffers directly to hardware, relying 118 * on the security mechanisms provided by hardware. ··· 190 int size; 191 int start; 192 } drm_i915_mem_init_heap_t; 193 + 194 + /* Allow memory manager to be torn down and re-initialized (eg on 195 + * rotate): 196 + */ 197 + typedef struct drm_i915_mem_destroy_heap { 198 + int region; 199 + } drm_i915_mem_destroy_heap_t; 200 201 #endif /* _I915_DRM_H_ */
+4 -2
drivers/char/drm/i915_drv.h
··· 37 38 #define DRIVER_NAME "i915" 39 #define DRIVER_DESC "Intel Graphics" 40 - #define DRIVER_DATE "20051209" 41 42 /* Interface history: 43 * 44 * 1.1: Original. 45 * 1.2: Add Power Management 46 * 1.3: Add vblank support 47 */ 48 #define DRIVER_MAJOR 1 49 - #define DRIVER_MINOR 3 50 #define DRIVER_PATCHLEVEL 0 51 52 typedef struct _drm_i915_ring_buffer { ··· 124 extern int i915_mem_alloc(DRM_IOCTL_ARGS); 125 extern int i915_mem_free(DRM_IOCTL_ARGS); 126 extern int i915_mem_init_heap(DRM_IOCTL_ARGS); 127 extern void i915_mem_takedown(struct mem_block **heap); 128 extern void i915_mem_release(drm_device_t * dev, 129 DRMFILE filp, struct mem_block *heap);
··· 37 38 #define DRIVER_NAME "i915" 39 #define DRIVER_DESC "Intel Graphics" 40 + #define DRIVER_DATE "20060119" 41 42 /* Interface history: 43 * 44 * 1.1: Original. 45 * 1.2: Add Power Management 46 * 1.3: Add vblank support 47 + * 1.4: Fix cmdbuffer path, add heap destroy 48 */ 49 #define DRIVER_MAJOR 1 50 + #define DRIVER_MINOR 4 51 #define DRIVER_PATCHLEVEL 0 52 53 typedef struct _drm_i915_ring_buffer { ··· 123 extern int i915_mem_alloc(DRM_IOCTL_ARGS); 124 extern int i915_mem_free(DRM_IOCTL_ARGS); 125 extern int i915_mem_init_heap(DRM_IOCTL_ARGS); 126 + extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS); 127 extern void i915_mem_takedown(struct mem_block **heap); 128 extern void i915_mem_release(drm_device_t * dev, 129 DRMFILE filp, struct mem_block *heap);
+31
drivers/char/drm/i915_mem.c
··· 365 366 return init_heap(heap, initheap.start, initheap.size); 367 }
··· 365 366 return init_heap(heap, initheap.start, initheap.size); 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 +