The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/r128_cce.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 278b33c0794a4eb0cc4cfff50213594d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.