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