r128_cce.c revision 95693
1/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- 2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com 3 * 4 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the next 16 * paragraph) shall be included in all copies or substantial portions of the 17 * Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 * DEALINGS IN THE SOFTWARE. 26 * 27 * Authors: 28 * Gareth Hughes <gareth@valinux.com> 29 * 30 * $FreeBSD: head/sys/dev/drm/r128_cce.c 95693 2002-04-29 00:25:10Z anholt $ 31 */ 32 33#define __NO_VERSION__ 34#include "dev/drm/r128.h" 35#include "dev/drm/drmP.h" 36#include "dev/drm/r128_drv.h" 37 38#ifdef __linux__ 39#include <linux/interrupt.h> /* For task queue support */ 40#include <linux/delay.h> 41#endif /* __linux__ */ 42 43#define R128_FIFO_DEBUG 0 44 45int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ); 46 47/* CCE microcode (from ATI) */ 48static u32 r128_cce_microcode[] = { 49 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 50 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, 51 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1, 52 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11, 53 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28, 54 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, 55 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, 56 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, 57 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071, 58 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2, 59 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1, 60 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, 61 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, 62 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, 63 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1, 64 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82, 65 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729, 66 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008, 67 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, 68 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, 69 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, 70 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0, 71 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370, 72 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1, 73 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793, 74 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, 75 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, 76 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1, 77 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1, 78 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894, 79 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14, 80 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1, 81 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, 82 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, 83 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 90}; 91 92 93int R128_READ_PLL(drm_device_t *dev, int addr) 94{ 95 drm_r128_private_t *dev_priv = dev->dev_private; 96 97 R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); 98 return R128_READ(R128_CLOCK_CNTL_DATA); 99} 100 101#if R128_FIFO_DEBUG 102static void r128_status( drm_r128_private_t *dev_priv ) 103{ 104 printk( "GUI_STAT = 0x%08x\n", 105 (unsigned int)R128_READ( R128_GUI_STAT ) ); 106 printk( "PM4_STAT = 0x%08x\n", 107 (unsigned int)R128_READ( R128_PM4_STAT ) ); 108 printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n", 109 (unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) ); 110 printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n", 111 (unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) ); 112 printk( "PM4_MICRO_CNTL = 0x%08x\n", 113 (unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) ); 114 printk( "PM4_BUFFER_CNTL = 0x%08x\n", 115 (unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) ); 116} 117#endif 118 119 120/* ================================================================ 121 * Engine, FIFO control 122 */ 123 124static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv ) 125{ 126 u32 tmp; 127 int i; 128 129 tmp = R128_READ( R128_PC_NGUI_CTLSTAT ) | R128_PC_FLUSH_ALL; 130 R128_WRITE( R128_PC_NGUI_CTLSTAT, tmp ); 131 132 for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 133 if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) { 134 return 0; 135 } 136 DRM_OS_DELAY( 1 ); 137 } 138 139#if R128_FIFO_DEBUG 140 DRM_ERROR( "%s failed!\n", __FUNCTION__ ); 141#endif 142 return DRM_OS_ERR(EBUSY); 143} 144 145static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries ) 146{ 147 int i; 148 149 for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 150 int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK; 151 if ( slots >= entries ) return 0; 152 DRM_OS_DELAY( 1 ); 153 } 154 155#if R128_FIFO_DEBUG 156 DRM_ERROR( "%s failed!\n", __FUNCTION__ ); 157#endif 158 return DRM_OS_ERR(EBUSY); 159} 160 161int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ) 162{ 163 int i, ret; 164 165 ret = r128_do_wait_for_fifo( dev_priv, 64 ); 166#ifdef __linux__ 167 if ( ret < 0 ) return ret; 168#endif /* __linux__ */ 169#ifdef __FreeBSD__ 170 if ( ret ) return ret; 171#endif /* __FreeBSD__ */ 172 173 for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 174 if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { 175 r128_do_pixcache_flush( dev_priv ); 176 return 0; 177 } 178 DRM_OS_DELAY( 1 ); 179 } 180 181#if R128_FIFO_DEBUG 182 DRM_ERROR( "%s failed!\n", __FUNCTION__ ); 183#endif 184 return DRM_OS_ERR(EBUSY); 185} 186 187 188/* ================================================================ 189 * CCE control, initialization 190 */ 191 192/* Load the microcode for the CCE */ 193static void r128_cce_load_microcode( drm_r128_private_t *dev_priv ) 194{ 195 int i; 196 197 DRM_DEBUG( "%s\n", __FUNCTION__ ); 198 199 r128_do_wait_for_idle( dev_priv ); 200 201 R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 ); 202 for ( i = 0 ; i < 256 ; i++ ) { 203 R128_WRITE( R128_PM4_MICROCODE_DATAH, 204 r128_cce_microcode[i * 2] ); 205 R128_WRITE( R128_PM4_MICROCODE_DATAL, 206 r128_cce_microcode[i * 2 + 1] ); 207 } 208} 209 210/* Flush any pending commands to the CCE. This should only be used just 211 * prior to a wait for idle, as it informs the engine that the command 212 * stream is ending. 213 */ 214static void r128_do_cce_flush( drm_r128_private_t *dev_priv ) 215{ 216 u32 tmp; 217 218 tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE; 219 R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp ); 220} 221 222/* Wait for the CCE to go idle. 223 */ 224int r128_do_cce_idle( drm_r128_private_t *dev_priv ) 225{ 226 int i; 227 228 for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 229 if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) { 230 int pm4stat = R128_READ( R128_PM4_STAT ); 231 if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= 232 dev_priv->cce_fifo_size ) && 233 !(pm4stat & (R128_PM4_BUSY | 234 R128_PM4_GUI_ACTIVE)) ) { 235 return r128_do_pixcache_flush( dev_priv ); 236 } 237 } 238 DRM_OS_DELAY( 1 ); 239 } 240 241#if R128_FIFO_DEBUG 242 DRM_ERROR( "failed!\n" ); 243 r128_status( dev_priv ); 244#endif 245 return DRM_OS_ERR(EBUSY); 246} 247 248/* Start the Concurrent Command Engine. 249 */ 250static void r128_do_cce_start( drm_r128_private_t *dev_priv ) 251{ 252 r128_do_wait_for_idle( dev_priv ); 253 254 R128_WRITE( R128_PM4_BUFFER_CNTL, 255 dev_priv->cce_mode | dev_priv->ring.size_l2qw ); 256 R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */ 257 R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN ); 258 259 dev_priv->cce_running = 1; 260} 261 262/* Reset the Concurrent Command Engine. This will not flush any pending 263 * commands, so you must wait for the CCE command stream to complete 264 * before calling this routine. 265 */ 266static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) 267{ 268 R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); 269 R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); 270 SET_RING_HEAD( &dev_priv->ring, 0 ); 271 dev_priv->ring.tail = 0; 272} 273 274/* Stop the Concurrent Command Engine. This will not flush any pending 275 * commands, so you must flush the command stream and wait for the CCE 276 * to go idle before calling this routine. 277 */ 278static void r128_do_cce_stop( drm_r128_private_t *dev_priv ) 279{ 280 R128_WRITE( R128_PM4_MICRO_CNTL, 0 ); 281 R128_WRITE( R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4 ); 282 283 dev_priv->cce_running = 0; 284} 285 286/* Reset the engine. This will stop the CCE if it is running. 287 */ 288static int r128_do_engine_reset( drm_device_t *dev ) 289{ 290 drm_r128_private_t *dev_priv = dev->dev_private; 291 u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; 292 293 r128_do_pixcache_flush( dev_priv ); 294 295 clock_cntl_index = R128_READ( R128_CLOCK_CNTL_INDEX ); 296 mclk_cntl = R128_READ_PLL( dev, R128_MCLK_CNTL ); 297 298 R128_WRITE_PLL( R128_MCLK_CNTL, 299 mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP ); 300 301 gen_reset_cntl = R128_READ( R128_GEN_RESET_CNTL ); 302 303 /* Taken from the sample code - do not change */ 304 R128_WRITE( R128_GEN_RESET_CNTL, 305 gen_reset_cntl | R128_SOFT_RESET_GUI ); 306 R128_READ( R128_GEN_RESET_CNTL ); 307 R128_WRITE( R128_GEN_RESET_CNTL, 308 gen_reset_cntl & ~R128_SOFT_RESET_GUI ); 309 R128_READ( R128_GEN_RESET_CNTL ); 310 311 R128_WRITE_PLL( R128_MCLK_CNTL, mclk_cntl ); 312 R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index ); 313 R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl ); 314 315 /* Reset the CCE ring */ 316 r128_do_cce_reset( dev_priv ); 317 318 /* The CCE is no longer running after an engine reset */ 319 dev_priv->cce_running = 0; 320 321 /* Reset any pending vertex, indirect buffers */ 322 r128_freelist_reset( dev ); 323 324 return 0; 325} 326 327static void r128_cce_init_ring_buffer( drm_device_t *dev, 328 drm_r128_private_t *dev_priv ) 329{ 330 u32 ring_start; 331 u32 tmp; 332 333 DRM_DEBUG( "%s\n", __FUNCTION__ ); 334 335 /* The manual (p. 2) says this address is in "VM space". This 336 * means it's an offset from the start of AGP space. 337 */ 338#if __REALLY_HAVE_AGP 339 if ( !dev_priv->is_pci ) 340 ring_start = dev_priv->cce_ring->offset - dev->agp->base; 341 else 342#endif 343 ring_start = dev_priv->cce_ring->offset - dev->sg->handle; 344 345 R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET ); 346 347 R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); 348 R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); 349 350 /* DL_RPTR_ADDR is a physical address in AGP space. */ 351 SET_RING_HEAD( &dev_priv->ring, 0 ); 352 353#if __REALLY_HAVE_SG 354 if ( !dev_priv->is_pci ) { 355#endif 356 R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, 357 dev_priv->ring_rptr->offset ); 358#if __REALLY_HAVE_SG 359 } else { 360 drm_sg_mem_t *entry = dev->sg; 361 unsigned long tmp_ofs, page_ofs; 362 363 tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; 364 page_ofs = tmp_ofs >> PAGE_SHIFT; 365 366 R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, 367 entry->busaddr[page_ofs]); 368 DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", 369 entry->busaddr[page_ofs], 370 entry->handle + tmp_ofs ); 371 } 372#endif 373 374 /* Set watermark control */ 375 R128_WRITE( R128_PM4_BUFFER_WM_CNTL, 376 ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) 377 | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT) 378 | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT) 379 | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) ); 380 381 /* Force read. Why? Because it's in the examples... */ 382 R128_READ( R128_PM4_BUFFER_ADDR ); 383 384 /* Turn on bus mastering */ 385 tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS; 386 R128_WRITE( R128_BUS_CNTL, tmp ); 387} 388 389static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) 390{ 391 drm_r128_private_t *dev_priv; 392#ifdef __linux__ 393 struct list_head *list; 394#endif /* __linux__ */ 395#ifdef __FreeBSD__ 396 drm_map_list_entry_t *listentry; 397#endif /* __FreeBSD__ */ 398 399 DRM_DEBUG( "%s\n", __FUNCTION__ ); 400 401 dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); 402 if ( dev_priv == NULL ) 403 return DRM_OS_ERR(ENOMEM); 404 405 memset( dev_priv, 0, sizeof(drm_r128_private_t) ); 406 407 dev_priv->is_pci = init->is_pci; 408 409 if ( dev_priv->is_pci && !dev->sg ) { 410 DRM_ERROR( "PCI GART memory not allocated!\n" ); 411 dev->dev_private = (void *)dev_priv; 412 r128_do_cleanup_cce( dev ); 413 return DRM_OS_ERR(EINVAL); 414 } 415 416 dev_priv->usec_timeout = init->usec_timeout; 417 if ( dev_priv->usec_timeout < 1 || 418 dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) { 419 DRM_DEBUG( "TIMEOUT problem!\n" ); 420 dev->dev_private = (void *)dev_priv; 421 r128_do_cleanup_cce( dev ); 422 return DRM_OS_ERR(EINVAL); 423 } 424 425 dev_priv->cce_mode = init->cce_mode; 426 427 /* GH: Simple idle check. 428 */ 429 atomic_set( &dev_priv->idle_count, 0 ); 430 431 /* We don't support anything other than bus-mastering ring mode, 432 * but the ring can be in either AGP or PCI space for the ring 433 * read pointer. 434 */ 435 if ( ( init->cce_mode != R128_PM4_192BM ) && 436 ( init->cce_mode != R128_PM4_128BM_64INDBM ) && 437 ( init->cce_mode != R128_PM4_64BM_128INDBM ) && 438 ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) { 439 DRM_DEBUG( "Bad cce_mode!\n" ); 440 dev->dev_private = (void *)dev_priv; 441 r128_do_cleanup_cce( dev ); 442 return DRM_OS_ERR(EINVAL); 443 } 444 445 switch ( init->cce_mode ) { 446 case R128_PM4_NONPM4: 447 dev_priv->cce_fifo_size = 0; 448 break; 449 case R128_PM4_192PIO: 450 case R128_PM4_192BM: 451 dev_priv->cce_fifo_size = 192; 452 break; 453 case R128_PM4_128PIO_64INDBM: 454 case R128_PM4_128BM_64INDBM: 455 dev_priv->cce_fifo_size = 128; 456 break; 457 case R128_PM4_64PIO_128INDBM: 458 case R128_PM4_64BM_128INDBM: 459 case R128_PM4_64PIO_64VCBM_64INDBM: 460 case R128_PM4_64BM_64VCBM_64INDBM: 461 case R128_PM4_64PIO_64VCPIO_64INDPIO: 462 dev_priv->cce_fifo_size = 64; 463 break; 464 } 465 466 switch ( init->fb_bpp ) { 467 case 16: 468 dev_priv->color_fmt = R128_DATATYPE_RGB565; 469 break; 470 case 32: 471 default: 472 dev_priv->color_fmt = R128_DATATYPE_ARGB8888; 473 break; 474 } 475 dev_priv->front_offset = init->front_offset; 476 dev_priv->front_pitch = init->front_pitch; 477 dev_priv->back_offset = init->back_offset; 478 dev_priv->back_pitch = init->back_pitch; 479 480 switch ( init->depth_bpp ) { 481 case 16: 482 dev_priv->depth_fmt = R128_DATATYPE_RGB565; 483 break; 484 case 24: 485 case 32: 486 default: 487 dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; 488 break; 489 } 490 dev_priv->depth_offset = init->depth_offset; 491 dev_priv->depth_pitch = init->depth_pitch; 492 dev_priv->span_offset = init->span_offset; 493 494 dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) | 495 (dev_priv->front_offset >> 5)); 496 dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) | 497 (dev_priv->back_offset >> 5)); 498 dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | 499 (dev_priv->depth_offset >> 5) | 500 R128_DST_TILE); 501 dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | 502 (dev_priv->span_offset >> 5)); 503 504#ifdef __linux__ 505 list_for_each(list, &dev->maplist->head) { 506 drm_map_list_t *r_list = (drm_map_list_t *)list; 507 if( r_list->map && 508 r_list->map->type == _DRM_SHM && 509 r_list->map->flags & _DRM_CONTAINS_LOCK ) { 510 dev_priv->sarea = r_list->map; 511 break; 512 } 513 } 514#endif /* __linux__ */ 515#ifdef __FreeBSD__ 516 TAILQ_FOREACH(listentry, dev->maplist, link) { 517 drm_map_t *map = listentry->map; 518 if (map->type == _DRM_SHM && 519 map->flags & _DRM_CONTAINS_LOCK) { 520 dev_priv->sarea = map; 521 break; 522 } 523 } 524#endif /* __FreeBSD__ */ 525 526 if(!dev_priv->sarea) { 527 DRM_ERROR("could not find sarea!\n"); 528 dev->dev_private = (void *)dev_priv; 529 r128_do_cleanup_cce( dev ); 530 return DRM_OS_ERR(EINVAL); 531 } 532 533 DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); 534 if(!dev_priv->fb) { 535 DRM_ERROR("could not find framebuffer!\n"); 536 dev->dev_private = (void *)dev_priv; 537 r128_do_cleanup_cce( dev ); 538 return DRM_OS_ERR(EINVAL); 539 } 540 DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 541 if(!dev_priv->mmio) { 542 DRM_ERROR("could not find mmio region!\n"); 543 dev->dev_private = (void *)dev_priv; 544 r128_do_cleanup_cce( dev ); 545 return DRM_OS_ERR(EINVAL); 546 } 547 DRM_FIND_MAP( dev_priv->cce_ring, init->ring_offset ); 548 if(!dev_priv->cce_ring) { 549 DRM_ERROR("could not find cce ring region!\n"); 550 dev->dev_private = (void *)dev_priv; 551 r128_do_cleanup_cce( dev ); 552 return DRM_OS_ERR(EINVAL); 553 } 554 DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); 555 if(!dev_priv->ring_rptr) { 556 DRM_ERROR("could not find ring read pointer!\n"); 557 dev->dev_private = (void *)dev_priv; 558 r128_do_cleanup_cce( dev ); 559 return DRM_OS_ERR(EINVAL); 560 } 561 DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); 562 if(!dev_priv->buffers) { 563 DRM_ERROR("could not find dma buffer region!\n"); 564 dev->dev_private = (void *)dev_priv; 565 r128_do_cleanup_cce( dev ); 566 return DRM_OS_ERR(EINVAL); 567 } 568 569 if ( !dev_priv->is_pci ) { 570 DRM_FIND_MAP( dev_priv->agp_textures, 571 init->agp_textures_offset ); 572 if(!dev_priv->agp_textures) { 573 DRM_ERROR("could not find agp texture region!\n"); 574 dev->dev_private = (void *)dev_priv; 575 r128_do_cleanup_cce( dev ); 576 return DRM_OS_ERR(EINVAL); 577 } 578 } 579 580 dev_priv->sarea_priv = 581 (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + 582 init->sarea_priv_offset); 583 584 if ( !dev_priv->is_pci ) { 585 DRM_IOREMAP( dev_priv->cce_ring ); 586 DRM_IOREMAP( dev_priv->ring_rptr ); 587 DRM_IOREMAP( dev_priv->buffers ); 588 if(!dev_priv->cce_ring->handle || 589 !dev_priv->ring_rptr->handle || 590 !dev_priv->buffers->handle) { 591 DRM_ERROR("Could not ioremap agp regions!\n"); 592 dev->dev_private = (void *)dev_priv; 593 r128_do_cleanup_cce( dev ); 594 return DRM_OS_ERR(ENOMEM); 595 } 596 } else { 597 dev_priv->cce_ring->handle = 598 (void *)dev_priv->cce_ring->offset; 599 dev_priv->ring_rptr->handle = 600 (void *)dev_priv->ring_rptr->offset; 601 dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; 602 } 603 604#if __REALLY_HAVE_AGP 605 if ( !dev_priv->is_pci ) 606 dev_priv->cce_buffers_offset = dev->agp->base; 607 else 608#endif 609 dev_priv->cce_buffers_offset = dev->sg->handle; 610 611 dev_priv->ring.head = ((__volatile__ u32 *) 612 dev_priv->ring_rptr->handle); 613 614 dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; 615 dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle 616 + init->ring_size / sizeof(u32)); 617 dev_priv->ring.size = init->ring_size; 618 dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); 619 620 dev_priv->ring.tail_mask = 621 (dev_priv->ring.size / sizeof(u32)) - 1; 622 623 dev_priv->ring.high_mark = 128; 624 625 dev_priv->sarea_priv->last_frame = 0; 626 R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); 627 628 dev_priv->sarea_priv->last_dispatch = 0; 629 R128_WRITE( R128_LAST_DISPATCH_REG, 630 dev_priv->sarea_priv->last_dispatch ); 631 632#if __REALLY_HAVE_SG 633 if ( dev_priv->is_pci ) { 634 if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, 635 &dev_priv->bus_pci_gart) ) { 636 DRM_ERROR( "failed to init PCI GART!\n" ); 637 dev->dev_private = (void *)dev_priv; 638 r128_do_cleanup_cce( dev ); 639 return DRM_OS_ERR(ENOMEM); 640 } 641 R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); 642 } 643#endif 644 645 r128_cce_init_ring_buffer( dev, dev_priv ); 646 r128_cce_load_microcode( dev_priv ); 647 648 dev->dev_private = (void *)dev_priv; 649 650 r128_do_engine_reset( dev ); 651 652 return 0; 653} 654 655int r128_do_cleanup_cce( drm_device_t *dev ) 656{ 657 if ( dev->dev_private ) { 658 drm_r128_private_t *dev_priv = dev->dev_private; 659 660#if __REALLY_HAVE_SG 661 if ( !dev_priv->is_pci ) { 662#endif 663 DRM_IOREMAPFREE( dev_priv->cce_ring ); 664 DRM_IOREMAPFREE( dev_priv->ring_rptr ); 665 DRM_IOREMAPFREE( dev_priv->buffers ); 666#if __REALLY_HAVE_SG 667 } else { 668 if (!DRM(ati_pcigart_cleanup)( dev, 669 dev_priv->phys_pci_gart, 670 dev_priv->bus_pci_gart )) 671 DRM_ERROR( "failed to cleanup PCI GART!\n" ); 672 } 673#endif 674 675 DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), 676 DRM_MEM_DRIVER ); 677 dev->dev_private = NULL; 678 } 679 680 return 0; 681} 682 683int r128_cce_init( DRM_OS_IOCTL ) 684{ 685 DRM_OS_DEVICE; 686 drm_r128_init_t init; 687 688 DRM_DEBUG( "%s\n", __FUNCTION__ ); 689 690 DRM_OS_KRNFROMUSR( init, (drm_r128_init_t *)data, sizeof(init) ); 691 692 switch ( init.func ) { 693 case R128_INIT_CCE: 694 return r128_do_init_cce( dev, &init ); 695 case R128_CLEANUP_CCE: 696 return r128_do_cleanup_cce( dev ); 697 } 698 699 return DRM_OS_ERR(EINVAL); 700} 701 702int r128_cce_start( DRM_OS_IOCTL ) 703{ 704 DRM_OS_DEVICE; 705 drm_r128_private_t *dev_priv = dev->dev_private; 706 DRM_DEBUG( "%s\n", __FUNCTION__ ); 707 708 LOCK_TEST_WITH_RETURN( dev ); 709 710 if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { 711 DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ ); 712 return 0; 713 } 714 715 r128_do_cce_start( dev_priv ); 716 717 return 0; 718} 719 720/* Stop the CCE. The engine must have been idled before calling this 721 * routine. 722 */ 723int r128_cce_stop( DRM_OS_IOCTL ) 724{ 725 DRM_OS_DEVICE; 726 drm_r128_private_t *dev_priv = dev->dev_private; 727 drm_r128_cce_stop_t stop; 728 int ret; 729 DRM_DEBUG( "%s\n", __FUNCTION__ ); 730 731 LOCK_TEST_WITH_RETURN( dev ); 732 733 DRM_OS_KRNFROMUSR(stop, (drm_r128_cce_stop_t *)data, sizeof(stop) ); 734 735 /* Flush any pending CCE commands. This ensures any outstanding 736 * commands are exectuted by the engine before we turn it off. 737 */ 738 if ( stop.flush ) { 739 r128_do_cce_flush( dev_priv ); 740 } 741 742 /* If we fail to make the engine go idle, we return an error 743 * code so that the DRM ioctl wrapper can try again. 744 */ 745 if ( stop.idle ) { 746 ret = r128_do_cce_idle( dev_priv ); 747#ifdef __linux__ 748 if ( ret < 0 ) return ret; 749#endif /* __linux__ */ 750#ifdef __FreeBSD__ 751 if ( ret ) return ret; 752#endif /* __FreeBSD__ */ 753 } 754 755 /* Finally, we can turn off the CCE. If the engine isn't idle, 756 * we will get some dropped triangles as they won't be fully 757 * rendered before the CCE is shut down. 758 */ 759 r128_do_cce_stop( dev_priv ); 760 761 /* Reset the engine */ 762 r128_do_engine_reset( dev ); 763 764 return 0; 765} 766 767/* Just reset the CCE ring. Called as part of an X Server engine reset. 768 */ 769int r128_cce_reset( DRM_OS_IOCTL ) 770{ 771 DRM_OS_DEVICE; 772 drm_r128_private_t *dev_priv = dev->dev_private; 773 DRM_DEBUG( "%s\n", __FUNCTION__ ); 774 775 LOCK_TEST_WITH_RETURN( dev ); 776 777 if ( !dev_priv ) { 778 DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); 779 return DRM_OS_ERR(EINVAL); 780 } 781 782 r128_do_cce_reset( dev_priv ); 783 784 /* The CCE is no longer running after an engine reset */ 785 dev_priv->cce_running = 0; 786 787 return 0; 788} 789 790int r128_cce_idle( DRM_OS_IOCTL ) 791{ 792 DRM_OS_DEVICE; 793 drm_r128_private_t *dev_priv = dev->dev_private; 794 DRM_DEBUG( "%s\n", __FUNCTION__ ); 795 796 LOCK_TEST_WITH_RETURN( dev ); 797 798 if ( dev_priv->cce_running ) { 799 r128_do_cce_flush( dev_priv ); 800 } 801 802 return r128_do_cce_idle( dev_priv ); 803} 804 805int r128_engine_reset( DRM_OS_IOCTL ) 806{ 807 DRM_OS_DEVICE; 808 DRM_DEBUG( "%s\n", __FUNCTION__ ); 809 810 LOCK_TEST_WITH_RETURN( dev ); 811 812 return r128_do_engine_reset( dev ); 813} 814 815 816/* ================================================================ 817 * Fullscreen mode 818 */ 819 820static int r128_do_init_pageflip( drm_device_t *dev ) 821{ 822 drm_r128_private_t *dev_priv = dev->dev_private; 823 DRM_DEBUG( "%s\n", __FUNCTION__ ); 824 825 dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); 826 dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); 827 828 R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); 829 R128_WRITE( R128_CRTC_OFFSET_CNTL, 830 dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); 831 832 dev_priv->page_flipping = 1; 833 dev_priv->current_page = 0; 834 835 return 0; 836} 837 838int r128_do_cleanup_pageflip( drm_device_t *dev ) 839{ 840 drm_r128_private_t *dev_priv = dev->dev_private; 841 DRM_DEBUG( "%s\n", __FUNCTION__ ); 842 843 R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); 844 R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); 845 846 dev_priv->page_flipping = 0; 847 dev_priv->current_page = 0; 848 849 return 0; 850} 851 852int r128_fullscreen( DRM_OS_IOCTL ) 853{ 854 DRM_OS_DEVICE; 855 drm_r128_fullscreen_t fs; 856 857 LOCK_TEST_WITH_RETURN( dev ); 858 859 DRM_OS_KRNFROMUSR( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) ); 860 861 switch ( fs.func ) { 862 case R128_INIT_FULLSCREEN: 863 return r128_do_init_pageflip( dev ); 864 case R128_CLEANUP_FULLSCREEN: 865 return r128_do_cleanup_pageflip( dev ); 866 } 867 868 return DRM_OS_ERR(EINVAL); 869} 870 871 872/* ================================================================ 873 * Freelist management 874 */ 875#define R128_BUFFER_USED 0xffffffff 876#define R128_BUFFER_FREE 0 877 878#if 0 879static int r128_freelist_init( drm_device_t *dev ) 880{ 881 drm_device_dma_t *dma = dev->dma; 882 drm_r128_private_t *dev_priv = dev->dev_private; 883 drm_buf_t *buf; 884 drm_r128_buf_priv_t *buf_priv; 885 drm_r128_freelist_t *entry; 886 int i; 887 888 dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t), 889 DRM_MEM_DRIVER ); 890 if ( dev_priv->head == NULL ) 891 return DRM_OS_ERR(ENOMEM); 892 893 memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) ); 894 dev_priv->head->age = R128_BUFFER_USED; 895 896 for ( i = 0 ; i < dma->buf_count ; i++ ) { 897 buf = dma->buflist[i]; 898 buf_priv = buf->dev_private; 899 900 entry = DRM(alloc)( sizeof(drm_r128_freelist_t), 901 DRM_MEM_DRIVER ); 902 if ( !entry ) return DRM_OS_ERR(ENOMEM); 903 904 entry->age = R128_BUFFER_FREE; 905 entry->buf = buf; 906 entry->prev = dev_priv->head; 907 entry->next = dev_priv->head->next; 908 if ( !entry->next ) 909 dev_priv->tail = entry; 910 911 buf_priv->discard = 0; 912 buf_priv->dispatched = 0; 913 buf_priv->list_entry = entry; 914 915 dev_priv->head->next = entry; 916 917 if ( dev_priv->head->next ) 918 dev_priv->head->next->prev = entry; 919 } 920 921 return 0; 922 923} 924#endif 925 926drm_buf_t *r128_freelist_get( drm_device_t *dev ) 927{ 928 drm_device_dma_t *dma = dev->dma; 929 drm_r128_private_t *dev_priv = dev->dev_private; 930 drm_r128_buf_priv_t *buf_priv; 931 drm_buf_t *buf; 932 int i, t; 933 934 /* FIXME: Optimize -- use freelist code */ 935 936 for ( i = 0 ; i < dma->buf_count ; i++ ) { 937 buf = dma->buflist[i]; 938 buf_priv = buf->dev_private; 939 if ( buf->pid == 0 ) 940 return buf; 941 } 942 943 for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { 944 u32 done_age = R128_READ( R128_LAST_DISPATCH_REG ); 945 946 for ( i = 0 ; i < dma->buf_count ; i++ ) { 947 buf = dma->buflist[i]; 948 buf_priv = buf->dev_private; 949 if ( buf->pending && buf_priv->age <= done_age ) { 950 /* The buffer has been processed, so it 951 * can now be used. 952 */ 953 buf->pending = 0; 954 return buf; 955 } 956 } 957 DRM_OS_DELAY( 1 ); 958 } 959 960 DRM_ERROR( "returning NULL!\n" ); 961 return NULL; 962} 963 964void r128_freelist_reset( drm_device_t *dev ) 965{ 966 drm_device_dma_t *dma = dev->dma; 967 int i; 968 969 for ( i = 0 ; i < dma->buf_count ; i++ ) { 970 drm_buf_t *buf = dma->buflist[i]; 971 drm_r128_buf_priv_t *buf_priv = buf->dev_private; 972 buf_priv->age = 0; 973 } 974} 975 976 977/* ================================================================ 978 * CCE command submission 979 */ 980 981int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) 982{ 983 drm_r128_ring_buffer_t *ring = &dev_priv->ring; 984 int i; 985 986 for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 987 r128_update_ring_snapshot( ring ); 988 if ( ring->space >= n ) 989 return 0; 990 DRM_OS_DELAY( 1 ); 991 } 992 993 /* FIXME: This is being ignored... */ 994 DRM_ERROR( "failed!\n" ); 995 return DRM_OS_ERR(EBUSY); 996} 997 998static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d) 999{ 1000 int i; 1001 drm_buf_t *buf; 1002 1003 for ( i = d->granted_count ; i < d->request_count ; i++ ) { 1004 buf = r128_freelist_get( dev ); 1005 if ( !buf ) return DRM_OS_ERR(EAGAIN); 1006 1007 buf->pid = DRM_OS_CURRENTPID; 1008 1009 if ( DRM_OS_COPYTOUSR( &d->request_indices[i], &buf->idx, 1010 sizeof(buf->idx) ) ) 1011 return DRM_OS_ERR(EFAULT); 1012 if ( DRM_OS_COPYTOUSR( &d->request_sizes[i], &buf->total, 1013 sizeof(buf->total) ) ) 1014 return DRM_OS_ERR(EFAULT); 1015 d->granted_count++; 1016 } 1017 return 0; 1018} 1019 1020int r128_cce_buffers( DRM_OS_IOCTL ) 1021{ 1022 DRM_OS_DEVICE; 1023 drm_device_dma_t *dma = dev->dma; 1024 int ret = 0; 1025 drm_dma_t d; 1026 1027 LOCK_TEST_WITH_RETURN( dev ); 1028 1029 DRM_OS_KRNFROMUSR( d, (drm_dma_t *) data, sizeof(d) ); 1030 1031 /* Please don't send us buffers. 1032 */ 1033 if ( d.send_count != 0 ) { 1034 DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", 1035 DRM_OS_CURRENTPID, d.send_count ); 1036 return DRM_OS_ERR(EINVAL); 1037 } 1038 1039 /* We'll send you buffers. 1040 */ 1041 if ( d.request_count < 0 || d.request_count > dma->buf_count ) { 1042 DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", 1043 DRM_OS_CURRENTPID, d.request_count, dma->buf_count ); 1044 return DRM_OS_ERR(EINVAL); 1045 } 1046 1047 d.granted_count = 0; 1048 1049 if ( d.request_count ) { 1050 ret = r128_cce_get_buffers( dev, &d ); 1051 } 1052 1053 DRM_OS_KRNTOUSR((drm_dma_t *) data, d, sizeof(d) ); 1054 1055 return ret; 1056} 1057