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_state.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_state.c -- State support for r128 -*- linux-c -*-
    2  * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com */
    3 /*-
    4  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
    5  * All Rights Reserved.
    6  *
    7  * Permission is hereby granted, free of charge, to any person obtaining a
    8  * copy of this software and associated documentation files (the "Software"),
    9  * to deal in the Software without restriction, including without limitation
   10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   11  * and/or sell copies of the Software, and to permit persons to whom the
   12  * Software is furnished to do so, subject to the following conditions:
   13  *
   14  * The above copyright notice and this permission notice (including the next
   15  * paragraph) shall be included in all copies or substantial portions of the
   16  * Software.
   17  *
   18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   21  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   24  * DEALINGS IN THE SOFTWARE.
   25  *
   26  * Authors:
   27  *    Gareth Hughes <gareth@valinux.com>
   28  *
   29  * $FreeBSD$
   30  */
   31 
   32 #include "dev/drm/r128.h"
   33 #include "dev/drm/drmP.h"
   34 #include "dev/drm/drm.h"
   35 #include "dev/drm/r128_drm.h"
   36 #include "dev/drm/r128_drv.h"
   37 
   38 
   39 /* ================================================================
   40  * CCE hardware state programming functions
   41  */
   42 
   43 static void r128_emit_clip_rects( drm_r128_private_t *dev_priv,
   44                                   drm_clip_rect_t *boxes, int count )
   45 {
   46         u32 aux_sc_cntl = 0x00000000;
   47         RING_LOCALS;
   48         DRM_DEBUG( "    %s\n", __FUNCTION__ );
   49 
   50         BEGIN_RING( (count < 3? count: 3) * 5 + 2 );
   51 
   52         if ( count >= 1 ) {
   53                 OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) );
   54                 OUT_RING( boxes[0].x1 );
   55                 OUT_RING( boxes[0].x2 - 1 );
   56                 OUT_RING( boxes[0].y1 );
   57                 OUT_RING( boxes[0].y2 - 1 );
   58 
   59                 aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
   60         }
   61         if ( count >= 2 ) {
   62                 OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) );
   63                 OUT_RING( boxes[1].x1 );
   64                 OUT_RING( boxes[1].x2 - 1 );
   65                 OUT_RING( boxes[1].y1 );
   66                 OUT_RING( boxes[1].y2 - 1 );
   67 
   68                 aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
   69         }
   70         if ( count >= 3 ) {
   71                 OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) );
   72                 OUT_RING( boxes[2].x1 );
   73                 OUT_RING( boxes[2].x2 - 1 );
   74                 OUT_RING( boxes[2].y1 );
   75                 OUT_RING( boxes[2].y2 - 1 );
   76 
   77                 aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
   78         }
   79 
   80         OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) );
   81         OUT_RING( aux_sc_cntl );
   82 
   83         ADVANCE_RING();
   84 }
   85 
   86 static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv )
   87 {
   88         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
   89         drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
   90         RING_LOCALS;
   91         DRM_DEBUG( "    %s\n", __FUNCTION__ );
   92 
   93         BEGIN_RING( 2 );
   94 
   95         OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) );
   96         OUT_RING( ctx->scale_3d_cntl );
   97 
   98         ADVANCE_RING();
   99 }
  100 
  101 static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv )
  102 {
  103         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  104         drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
  105         RING_LOCALS;
  106         DRM_DEBUG( "    %s\n", __FUNCTION__ );
  107 
  108         BEGIN_RING( 13 );
  109 
  110         OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) );
  111         OUT_RING( ctx->dst_pitch_offset_c );
  112         OUT_RING( ctx->dp_gui_master_cntl_c );
  113         OUT_RING( ctx->sc_top_left_c );
  114         OUT_RING( ctx->sc_bottom_right_c );
  115         OUT_RING( ctx->z_offset_c );
  116         OUT_RING( ctx->z_pitch_c );
  117         OUT_RING( ctx->z_sten_cntl_c );
  118         OUT_RING( ctx->tex_cntl_c );
  119         OUT_RING( ctx->misc_3d_state_cntl_reg );
  120         OUT_RING( ctx->texture_clr_cmp_clr_c );
  121         OUT_RING( ctx->texture_clr_cmp_msk_c );
  122         OUT_RING( ctx->fog_color_c );
  123 
  124         ADVANCE_RING();
  125 }
  126 
  127 static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv )
  128 {
  129         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  130         drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
  131         RING_LOCALS;
  132         DRM_DEBUG( "    %s\n", __FUNCTION__ );
  133 
  134         BEGIN_RING( 3 );
  135 
  136         OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) );
  137         OUT_RING( ctx->setup_cntl );
  138         OUT_RING( ctx->pm4_vc_fpu_setup );
  139 
  140         ADVANCE_RING();
  141 }
  142 
  143 static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv )
  144 {
  145         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  146         drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
  147         RING_LOCALS;
  148         DRM_DEBUG( "    %s\n", __FUNCTION__ );
  149 
  150         BEGIN_RING( 5 );
  151 
  152         OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
  153         OUT_RING( ctx->dp_write_mask );
  154 
  155         OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) );
  156         OUT_RING( ctx->sten_ref_mask_c );
  157         OUT_RING( ctx->plane_3d_mask_c );
  158 
  159         ADVANCE_RING();
  160 }
  161 
  162 static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv )
  163 {
  164         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  165         drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
  166         RING_LOCALS;
  167         DRM_DEBUG( "    %s\n", __FUNCTION__ );
  168 
  169         BEGIN_RING( 2 );
  170 
  171         OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) );
  172         OUT_RING( ctx->window_xy_offset );
  173 
  174         ADVANCE_RING();
  175 }
  176 
  177 static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv )
  178 {
  179         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  180         drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
  181         drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
  182         int i;
  183         RING_LOCALS;
  184         DRM_DEBUG( "    %s\n", __FUNCTION__ );
  185 
  186         BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
  187 
  188         OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
  189                                2 + R128_MAX_TEXTURE_LEVELS ) );
  190         OUT_RING( tex->tex_cntl );
  191         OUT_RING( tex->tex_combine_cntl );
  192         OUT_RING( ctx->tex_size_pitch_c );
  193         for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
  194                 OUT_RING( tex->tex_offset[i] );
  195         }
  196 
  197         OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) );
  198         OUT_RING( ctx->constant_color_c );
  199         OUT_RING( tex->tex_border_color );
  200 
  201         ADVANCE_RING();
  202 }
  203 
  204 static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv )
  205 {
  206         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  207         drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
  208         int i;
  209         RING_LOCALS;
  210         DRM_DEBUG( "    %s\n", __FUNCTION__ );
  211 
  212         BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
  213 
  214         OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
  215                                1 + R128_MAX_TEXTURE_LEVELS ) );
  216         OUT_RING( tex->tex_cntl );
  217         OUT_RING( tex->tex_combine_cntl );
  218         for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
  219                 OUT_RING( tex->tex_offset[i] );
  220         }
  221 
  222         OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) );
  223         OUT_RING( tex->tex_border_color );
  224 
  225         ADVANCE_RING();
  226 }
  227 
  228 static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv )
  229 {
  230         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  231         unsigned int dirty = sarea_priv->dirty;
  232 
  233         DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
  234 
  235         if ( dirty & R128_UPLOAD_CORE ) {
  236                 r128_emit_core( dev_priv );
  237                 sarea_priv->dirty &= ~R128_UPLOAD_CORE;
  238         }
  239 
  240         if ( dirty & R128_UPLOAD_CONTEXT ) {
  241                 r128_emit_context( dev_priv );
  242                 sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
  243         }
  244 
  245         if ( dirty & R128_UPLOAD_SETUP ) {
  246                 r128_emit_setup( dev_priv );
  247                 sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
  248         }
  249 
  250         if ( dirty & R128_UPLOAD_MASKS ) {
  251                 r128_emit_masks( dev_priv );
  252                 sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
  253         }
  254 
  255         if ( dirty & R128_UPLOAD_WINDOW ) {
  256                 r128_emit_window( dev_priv );
  257                 sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
  258         }
  259 
  260         if ( dirty & R128_UPLOAD_TEX0 ) {
  261                 r128_emit_tex0( dev_priv );
  262                 sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
  263         }
  264 
  265         if ( dirty & R128_UPLOAD_TEX1 ) {
  266                 r128_emit_tex1( dev_priv );
  267                 sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
  268         }
  269 
  270         /* Turn off the texture cache flushing */
  271         sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
  272 
  273         sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
  274 }
  275 
  276 
  277 #if R128_PERFORMANCE_BOXES
  278 /* ================================================================
  279  * Performance monitoring functions
  280  */
  281 
  282 static void r128_clear_box( drm_r128_private_t *dev_priv,
  283                             int x, int y, int w, int h,
  284                             int r, int g, int b )
  285 {
  286         u32 pitch, offset;
  287         u32 fb_bpp, color;
  288         RING_LOCALS;
  289 
  290         switch ( dev_priv->fb_bpp ) {
  291         case 16:
  292                 fb_bpp = R128_GMC_DST_16BPP;
  293                 color = (((r & 0xf8) << 8) |
  294                          ((g & 0xfc) << 3) |
  295                          ((b & 0xf8) >> 3));
  296                 break;
  297         case 24:
  298                 fb_bpp = R128_GMC_DST_24BPP;
  299                 color = ((r << 16) | (g << 8) | b);
  300                 break;
  301         case 32:
  302                 fb_bpp = R128_GMC_DST_32BPP;
  303                 color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);
  304                 break;
  305         default:
  306                 return;
  307         }
  308 
  309         offset = dev_priv->back_offset;
  310         pitch = dev_priv->back_pitch >> 3;
  311 
  312         BEGIN_RING( 6 );
  313 
  314         OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
  315         OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
  316                   R128_GMC_BRUSH_SOLID_COLOR |
  317                   fb_bpp |
  318                   R128_GMC_SRC_DATATYPE_COLOR |
  319                   R128_ROP3_P |
  320                   R128_GMC_CLR_CMP_CNTL_DIS |
  321                   R128_GMC_AUX_CLIP_DIS );
  322 
  323         OUT_RING( (pitch << 21) | (offset >> 5) );
  324         OUT_RING( color );
  325 
  326         OUT_RING( (x << 16) | y );
  327         OUT_RING( (w << 16) | h );
  328 
  329         ADVANCE_RING();
  330 }
  331 
  332 static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv )
  333 {
  334         if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
  335                 r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
  336         } else {
  337                 atomic_set( &dev_priv->idle_count, 0 );
  338         }
  339 }
  340 
  341 #endif
  342 
  343 
  344 /* ================================================================
  345  * CCE command dispatch functions
  346  */
  347 
  348 static void r128_print_dirty( const char *msg, unsigned int flags )
  349 {
  350         DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
  351                   msg,
  352                   flags,
  353                   (flags & R128_UPLOAD_CORE)        ? "core, " : "",
  354                   (flags & R128_UPLOAD_CONTEXT)     ? "context, " : "",
  355                   (flags & R128_UPLOAD_SETUP)       ? "setup, " : "",
  356                   (flags & R128_UPLOAD_TEX0)        ? "tex0, " : "",
  357                   (flags & R128_UPLOAD_TEX1)        ? "tex1, " : "",
  358                   (flags & R128_UPLOAD_MASKS)       ? "masks, " : "",
  359                   (flags & R128_UPLOAD_WINDOW)      ? "window, " : "",
  360                   (flags & R128_UPLOAD_CLIPRECTS)   ? "cliprects, " : "",
  361                   (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
  362 }
  363 
  364 static void r128_cce_dispatch_clear( drm_device_t *dev,
  365                                      drm_r128_clear_t *clear )
  366 {
  367         drm_r128_private_t *dev_priv = dev->dev_private;
  368         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  369         int nbox = sarea_priv->nbox;
  370         drm_clip_rect_t *pbox = sarea_priv->boxes;
  371         unsigned int flags = clear->flags;
  372         int i;
  373         RING_LOCALS;
  374         DRM_DEBUG( "%s\n", __FUNCTION__ );
  375 
  376         if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
  377                 unsigned int tmp = flags;
  378 
  379                 flags &= ~(R128_FRONT | R128_BACK);
  380                 if ( tmp & R128_FRONT ) flags |= R128_BACK;
  381                 if ( tmp & R128_BACK )  flags |= R128_FRONT;
  382         }
  383 
  384         for ( i = 0 ; i < nbox ; i++ ) {
  385                 int x = pbox[i].x1;
  386                 int y = pbox[i].y1;
  387                 int w = pbox[i].x2 - x;
  388                 int h = pbox[i].y2 - y;
  389 
  390                 DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
  391                            pbox[i].x1, pbox[i].y1, pbox[i].x2,
  392                            pbox[i].y2, flags );
  393 
  394                 if ( flags & (R128_FRONT | R128_BACK) ) {
  395                         BEGIN_RING( 2 );
  396 
  397                         OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
  398                         OUT_RING( clear->color_mask );
  399 
  400                         ADVANCE_RING();
  401                 }
  402 
  403                 if ( flags & R128_FRONT ) {
  404                         BEGIN_RING( 6 );
  405 
  406                         OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
  407                         OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
  408                                   R128_GMC_BRUSH_SOLID_COLOR |
  409                                   (dev_priv->color_fmt << 8) |
  410                                   R128_GMC_SRC_DATATYPE_COLOR |
  411                                   R128_ROP3_P |
  412                                   R128_GMC_CLR_CMP_CNTL_DIS |
  413                                   R128_GMC_AUX_CLIP_DIS );
  414 
  415                         OUT_RING( dev_priv->front_pitch_offset_c );
  416                         OUT_RING( clear->clear_color );
  417 
  418                         OUT_RING( (x << 16) | y );
  419                         OUT_RING( (w << 16) | h );
  420 
  421                         ADVANCE_RING();
  422                 }
  423 
  424                 if ( flags & R128_BACK ) {
  425                         BEGIN_RING( 6 );
  426 
  427                         OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
  428                         OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
  429                                   R128_GMC_BRUSH_SOLID_COLOR |
  430                                   (dev_priv->color_fmt << 8) |
  431                                   R128_GMC_SRC_DATATYPE_COLOR |
  432                                   R128_ROP3_P |
  433                                   R128_GMC_CLR_CMP_CNTL_DIS |
  434                                   R128_GMC_AUX_CLIP_DIS );
  435 
  436                         OUT_RING( dev_priv->back_pitch_offset_c );
  437                         OUT_RING( clear->clear_color );
  438 
  439                         OUT_RING( (x << 16) | y );
  440                         OUT_RING( (w << 16) | h );
  441 
  442                         ADVANCE_RING();
  443                 }
  444 
  445                 if ( flags & R128_DEPTH ) {
  446                         BEGIN_RING( 6 );
  447 
  448                         OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
  449                         OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
  450                                   R128_GMC_BRUSH_SOLID_COLOR |
  451                                   (dev_priv->depth_fmt << 8) |
  452                                   R128_GMC_SRC_DATATYPE_COLOR |
  453                                   R128_ROP3_P |
  454                                   R128_GMC_CLR_CMP_CNTL_DIS |
  455                                   R128_GMC_AUX_CLIP_DIS |
  456                                   R128_GMC_WR_MSK_DIS );
  457 
  458                         OUT_RING( dev_priv->depth_pitch_offset_c );
  459                         OUT_RING( clear->clear_depth );
  460 
  461                         OUT_RING( (x << 16) | y );
  462                         OUT_RING( (w << 16) | h );
  463 
  464                         ADVANCE_RING();
  465                 }
  466         }
  467 }
  468 
  469 static void r128_cce_dispatch_swap( drm_device_t *dev )
  470 {
  471         drm_r128_private_t *dev_priv = dev->dev_private;
  472         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  473         int nbox = sarea_priv->nbox;
  474         drm_clip_rect_t *pbox = sarea_priv->boxes;
  475         int i;
  476         RING_LOCALS;
  477         DRM_DEBUG( "%s\n", __FUNCTION__ );
  478 
  479 #if R128_PERFORMANCE_BOXES
  480         /* Do some trivial performance monitoring...
  481          */
  482         r128_cce_performance_boxes( dev_priv );
  483 #endif
  484 
  485         for ( i = 0 ; i < nbox ; i++ ) {
  486                 int x = pbox[i].x1;
  487                 int y = pbox[i].y1;
  488                 int w = pbox[i].x2 - x;
  489                 int h = pbox[i].y2 - y;
  490 
  491                 BEGIN_RING( 7 );
  492 
  493                 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
  494                 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
  495                           R128_GMC_DST_PITCH_OFFSET_CNTL |
  496                           R128_GMC_BRUSH_NONE |
  497                           (dev_priv->color_fmt << 8) |
  498                           R128_GMC_SRC_DATATYPE_COLOR |
  499                           R128_ROP3_S |
  500                           R128_DP_SRC_SOURCE_MEMORY |
  501                           R128_GMC_CLR_CMP_CNTL_DIS |
  502                           R128_GMC_AUX_CLIP_DIS |
  503                           R128_GMC_WR_MSK_DIS );
  504 
  505                 /* Make this work even if front & back are flipped:
  506                  */
  507                 if (dev_priv->current_page == 0) {
  508                         OUT_RING( dev_priv->back_pitch_offset_c );
  509                         OUT_RING( dev_priv->front_pitch_offset_c );
  510                 } 
  511                 else {
  512                         OUT_RING( dev_priv->front_pitch_offset_c );
  513                         OUT_RING( dev_priv->back_pitch_offset_c );
  514                 }
  515 
  516                 OUT_RING( (x << 16) | y );
  517                 OUT_RING( (x << 16) | y );
  518                 OUT_RING( (w << 16) | h );
  519 
  520                 ADVANCE_RING();
  521         }
  522 
  523         /* Increment the frame counter.  The client-side 3D driver must
  524          * throttle the framerate by waiting for this value before
  525          * performing the swapbuffer ioctl.
  526          */
  527         dev_priv->sarea_priv->last_frame++;
  528 
  529         BEGIN_RING( 2 );
  530 
  531         OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
  532         OUT_RING( dev_priv->sarea_priv->last_frame );
  533 
  534         ADVANCE_RING();
  535 }
  536 
  537 static void r128_cce_dispatch_flip( drm_device_t *dev )
  538 {
  539         drm_r128_private_t *dev_priv = dev->dev_private;
  540         RING_LOCALS;
  541         DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 
  542                 __FUNCTION__,
  543                 dev_priv->current_page,
  544                 dev_priv->sarea_priv->pfCurrentPage);
  545 
  546 #if R128_PERFORMANCE_BOXES
  547         /* Do some trivial performance monitoring...
  548          */
  549         r128_cce_performance_boxes( dev_priv );
  550 #endif
  551 
  552         BEGIN_RING( 4 );
  553 
  554         R128_WAIT_UNTIL_PAGE_FLIPPED();
  555         OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
  556 
  557         if ( dev_priv->current_page == 0 ) {
  558                 OUT_RING( dev_priv->back_offset );
  559         } else {
  560                 OUT_RING( dev_priv->front_offset );
  561         }
  562 
  563         ADVANCE_RING();
  564 
  565         /* Increment the frame counter.  The client-side 3D driver must
  566          * throttle the framerate by waiting for this value before
  567          * performing the swapbuffer ioctl.
  568          */
  569         dev_priv->sarea_priv->last_frame++;
  570         dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
  571                                               1 - dev_priv->current_page;
  572 
  573         BEGIN_RING( 2 );
  574 
  575         OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
  576         OUT_RING( dev_priv->sarea_priv->last_frame );
  577 
  578         ADVANCE_RING();
  579 }
  580 
  581 static void r128_cce_dispatch_vertex( drm_device_t *dev,
  582                                       drm_buf_t *buf )
  583 {
  584         drm_r128_private_t *dev_priv = dev->dev_private;
  585         drm_r128_buf_priv_t *buf_priv = buf->dev_private;
  586         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  587         int format = sarea_priv->vc_format;
  588         int offset = buf->bus_address;
  589         int size = buf->used;
  590         int prim = buf_priv->prim;
  591         int i = 0;
  592         RING_LOCALS;
  593         DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox );
  594 
  595         if ( 0 )
  596                 r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
  597 
  598         if ( buf->used ) {
  599                 buf_priv->dispatched = 1;
  600 
  601                 if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
  602                         r128_emit_state( dev_priv );
  603                 }
  604 
  605                 do {
  606                         /* Emit the next set of up to three cliprects */
  607                         if ( i < sarea_priv->nbox ) {
  608                                 r128_emit_clip_rects( dev_priv,
  609                                                       &sarea_priv->boxes[i],
  610                                                       sarea_priv->nbox - i );
  611                         }
  612 
  613                         /* Emit the vertex buffer rendering commands */
  614                         BEGIN_RING( 5 );
  615 
  616                         OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) );
  617                         OUT_RING( offset );
  618                         OUT_RING( size );
  619                         OUT_RING( format );
  620                         OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
  621                                   (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
  622 
  623                         ADVANCE_RING();
  624 
  625                         i += 3;
  626                 } while ( i < sarea_priv->nbox );
  627         }
  628 
  629         if ( buf_priv->discard ) {
  630                 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
  631 
  632                 /* Emit the vertex buffer age */
  633                 BEGIN_RING( 2 );
  634 
  635                 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
  636                 OUT_RING( buf_priv->age );
  637 
  638                 ADVANCE_RING();
  639 
  640                 buf->pending = 1;
  641                 buf->used = 0;
  642                 /* FIXME: Check dispatched field */
  643                 buf_priv->dispatched = 0;
  644         }
  645 
  646         dev_priv->sarea_priv->last_dispatch++;
  647 
  648         sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
  649         sarea_priv->nbox = 0;
  650 }
  651 
  652 static void r128_cce_dispatch_indirect( drm_device_t *dev,
  653                                         drm_buf_t *buf,
  654                                         int start, int end )
  655 {
  656         drm_r128_private_t *dev_priv = dev->dev_private;
  657         drm_r128_buf_priv_t *buf_priv = buf->dev_private;
  658         RING_LOCALS;
  659         DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
  660                    buf->idx, start, end );
  661 
  662         if ( start != end ) {
  663                 int offset = buf->bus_address + start;
  664                 int dwords = (end - start + 3) / sizeof(u32);
  665 
  666                 /* Indirect buffer data must be an even number of
  667                  * dwords, so if we've been given an odd number we must
  668                  * pad the data with a Type-2 CCE packet.
  669                  */
  670                 if ( dwords & 1 ) {
  671                         u32 *data = (u32 *)
  672                                 ((char *)dev_priv->buffers->handle
  673                                  + buf->offset + start);
  674                         data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
  675                 }
  676 
  677                 buf_priv->dispatched = 1;
  678 
  679                 /* Fire off the indirect buffer */
  680                 BEGIN_RING( 3 );
  681 
  682                 OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );
  683                 OUT_RING( offset );
  684                 OUT_RING( dwords );
  685 
  686                 ADVANCE_RING();
  687         }
  688 
  689         if ( buf_priv->discard ) {
  690                 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
  691 
  692                 /* Emit the indirect buffer age */
  693                 BEGIN_RING( 2 );
  694 
  695                 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
  696                 OUT_RING( buf_priv->age );
  697 
  698                 ADVANCE_RING();
  699 
  700                 buf->pending = 1;
  701                 buf->used = 0;
  702                 /* FIXME: Check dispatched field */
  703                 buf_priv->dispatched = 0;
  704         }
  705 
  706         dev_priv->sarea_priv->last_dispatch++;
  707 }
  708 
  709 static void r128_cce_dispatch_indices( drm_device_t *dev,
  710                                        drm_buf_t *buf,
  711                                        int start, int end,
  712                                        int count )
  713 {
  714         drm_r128_private_t *dev_priv = dev->dev_private;
  715         drm_r128_buf_priv_t *buf_priv = buf->dev_private;
  716         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
  717         int format = sarea_priv->vc_format;
  718         int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
  719         int prim = buf_priv->prim;
  720         u32 *data;
  721         int dwords;
  722         int i = 0;
  723         RING_LOCALS;
  724         DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
  725 
  726         if ( 0 )
  727                 r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
  728 
  729         if ( start != end ) {
  730                 buf_priv->dispatched = 1;
  731 
  732                 if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
  733                         r128_emit_state( dev_priv );
  734                 }
  735 
  736                 dwords = (end - start + 3) / sizeof(u32);
  737 
  738                 data = (u32 *)((char *)dev_priv->buffers->handle
  739                                + buf->offset + start);
  740 
  741                 data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
  742                                                     dwords-2 ) );
  743 
  744                 data[1] = cpu_to_le32( offset );
  745                 data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
  746                 data[3] = cpu_to_le32( format );
  747                 data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
  748                                         (count << 16)) );
  749 
  750                 if ( count & 0x1 ) {
  751 #ifdef __LITTLE_ENDIAN
  752                         data[dwords-1] &= 0x0000ffff;
  753 #else
  754                         data[dwords-1] &= 0xffff0000;
  755 #endif
  756                 }
  757 
  758                 do {
  759                         /* Emit the next set of up to three cliprects */
  760                         if ( i < sarea_priv->nbox ) {
  761                                 r128_emit_clip_rects( dev_priv,
  762                                                       &sarea_priv->boxes[i],
  763                                                       sarea_priv->nbox - i );
  764                         }
  765 
  766                         r128_cce_dispatch_indirect( dev, buf, start, end );
  767 
  768                         i += 3;
  769                 } while ( i < sarea_priv->nbox );
  770         }
  771 
  772         if ( buf_priv->discard ) {
  773                 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
  774 
  775                 /* Emit the vertex buffer age */
  776                 BEGIN_RING( 2 );
  777 
  778                 OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
  779                 OUT_RING( buf_priv->age );
  780 
  781                 ADVANCE_RING();
  782 
  783                 buf->pending = 1;
  784                 /* FIXME: Check dispatched field */
  785                 buf_priv->dispatched = 0;
  786         }
  787 
  788         dev_priv->sarea_priv->last_dispatch++;
  789 
  790         sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
  791         sarea_priv->nbox = 0;
  792 }
  793 
  794 static int r128_cce_dispatch_blit( DRMFILE filp,
  795                                    drm_device_t *dev,
  796                                    drm_r128_blit_t *blit )
  797 {
  798         drm_r128_private_t *dev_priv = dev->dev_private;
  799         drm_device_dma_t *dma = dev->dma;
  800         drm_buf_t *buf;
  801         drm_r128_buf_priv_t *buf_priv;
  802         u32 *data;
  803         int dword_shift, dwords;
  804         RING_LOCALS;
  805         DRM_DEBUG( "\n" );
  806 
  807         /* The compiler won't optimize away a division by a variable,
  808          * even if the only legal values are powers of two.  Thus, we'll
  809          * use a shift instead.
  810          */
  811         switch ( blit->format ) {
  812         case R128_DATATYPE_ARGB8888:
  813                 dword_shift = 0;
  814                 break;
  815         case R128_DATATYPE_ARGB1555:
  816         case R128_DATATYPE_RGB565:
  817         case R128_DATATYPE_ARGB4444:
  818         case R128_DATATYPE_YVYU422:
  819         case R128_DATATYPE_VYUY422:
  820                 dword_shift = 1;
  821                 break;
  822         case R128_DATATYPE_CI8:
  823         case R128_DATATYPE_RGB8:
  824                 dword_shift = 2;
  825                 break;
  826         default:
  827                 DRM_ERROR( "invalid blit format %d\n", blit->format );
  828                 return DRM_ERR(EINVAL);
  829         }
  830 
  831         /* Flush the pixel cache, and mark the contents as Read Invalid.
  832          * This ensures no pixel data gets mixed up with the texture
  833          * data from the host data blit, otherwise part of the texture
  834          * image may be corrupted.
  835          */
  836         BEGIN_RING( 2 );
  837 
  838         OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
  839         OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );
  840 
  841         ADVANCE_RING();
  842 
  843         /* Dispatch the indirect buffer.
  844          */
  845         buf = dma->buflist[blit->idx];
  846         buf_priv = buf->dev_private;
  847 
  848         if ( buf->filp != filp ) {
  849                 DRM_ERROR( "process %d using buffer owned by %p\n",
  850                            DRM_CURRENTPID, buf->filp );
  851                 return DRM_ERR(EINVAL);
  852         }
  853         if ( buf->pending ) {
  854                 DRM_ERROR( "sending pending buffer %d\n", blit->idx );
  855                 return DRM_ERR(EINVAL);
  856         }
  857 
  858         buf_priv->discard = 1;
  859 
  860         dwords = (blit->width * blit->height) >> dword_shift;
  861 
  862         data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
  863 
  864         data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
  865         data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
  866                                 R128_GMC_BRUSH_NONE |
  867                                 (blit->format << 8) |
  868                                 R128_GMC_SRC_DATATYPE_COLOR |
  869                                 R128_ROP3_S |
  870                                 R128_DP_SRC_SOURCE_HOST_DATA |
  871                                 R128_GMC_CLR_CMP_CNTL_DIS |
  872                                 R128_GMC_AUX_CLIP_DIS |
  873                                 R128_GMC_WR_MSK_DIS) );
  874 
  875         data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
  876         data[3] = cpu_to_le32( 0xffffffff );
  877         data[4] = cpu_to_le32( 0xffffffff );
  878         data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
  879         data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
  880         data[7] = cpu_to_le32( dwords );
  881 
  882         buf->used = (dwords + 8) * sizeof(u32);
  883 
  884         r128_cce_dispatch_indirect( dev, buf, 0, buf->used );
  885 
  886         /* Flush the pixel cache after the blit completes.  This ensures
  887          * the texture data is written out to memory before rendering
  888          * continues.
  889          */
  890         BEGIN_RING( 2 );
  891 
  892         OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
  893         OUT_RING( R128_PC_FLUSH_GUI );
  894 
  895         ADVANCE_RING();
  896 
  897         return 0;
  898 }
  899 
  900 
  901 /* ================================================================
  902  * Tiled depth buffer management
  903  *
  904  * FIXME: These should all set the destination write mask for when we
  905  * have hardware stencil support.
  906  */
  907 
  908 static int r128_cce_dispatch_write_span( drm_device_t *dev,
  909                                          drm_r128_depth_t *depth )
  910 {
  911         drm_r128_private_t *dev_priv = dev->dev_private;
  912         int count, x, y;
  913         u32 *buffer;
  914         u8 *mask;
  915         int i, buffer_size, mask_size;
  916         RING_LOCALS;
  917         DRM_DEBUG( "\n" );
  918 
  919         count = depth->n;
  920         if (count > 4096 || count <= 0)
  921                 return DRM_ERR(EMSGSIZE);
  922 
  923         if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
  924                 return DRM_ERR(EFAULT);
  925         }
  926         if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
  927                 return DRM_ERR(EFAULT);
  928         }
  929 
  930         buffer_size = depth->n * sizeof(u32);
  931         buffer = DRM_MALLOC( buffer_size );
  932         if ( buffer == NULL )
  933                 return DRM_ERR(ENOMEM);
  934         if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
  935                 DRM_FREE( buffer, buffer_size);
  936                 return DRM_ERR(EFAULT);
  937         }
  938 
  939         mask_size = depth->n * sizeof(u8);
  940         if ( depth->mask ) {
  941                 mask = DRM_MALLOC( mask_size );
  942                 if ( mask == NULL ) {
  943                         DRM_FREE( buffer, buffer_size );
  944                         return DRM_ERR(ENOMEM);
  945                 }
  946                 if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
  947                         DRM_FREE( buffer, buffer_size );
  948                         DRM_FREE( mask, mask_size );
  949                         return DRM_ERR(EFAULT);
  950                 }
  951 
  952                 for ( i = 0 ; i < count ; i++, x++ ) {
  953                         if ( mask[i] ) {
  954                                 BEGIN_RING( 6 );
  955 
  956                                 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
  957                                 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
  958                                           R128_GMC_BRUSH_SOLID_COLOR |
  959                                           (dev_priv->depth_fmt << 8) |
  960                                           R128_GMC_SRC_DATATYPE_COLOR |
  961                                           R128_ROP3_P |
  962                                           R128_GMC_CLR_CMP_CNTL_DIS |
  963                                           R128_GMC_WR_MSK_DIS );
  964 
  965                                 OUT_RING( dev_priv->depth_pitch_offset_c );
  966                                 OUT_RING( buffer[i] );
  967 
  968                                 OUT_RING( (x << 16) | y );
  969                                 OUT_RING( (1 << 16) | 1 );
  970 
  971                                 ADVANCE_RING();
  972                         }
  973                 }
  974 
  975                 DRM_FREE( mask, mask_size );
  976         } else {
  977                 for ( i = 0 ; i < count ; i++, x++ ) {
  978                         BEGIN_RING( 6 );
  979 
  980                         OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
  981                         OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
  982                                   R128_GMC_BRUSH_SOLID_COLOR |
  983                                   (dev_priv->depth_fmt << 8) |
  984                                   R128_GMC_SRC_DATATYPE_COLOR |
  985                                   R128_ROP3_P |
  986                                   R128_GMC_CLR_CMP_CNTL_DIS |
  987                                   R128_GMC_WR_MSK_DIS );
  988 
  989                         OUT_RING( dev_priv->depth_pitch_offset_c );
  990                         OUT_RING( buffer[i] );
  991 
  992                         OUT_RING( (x << 16) | y );
  993                         OUT_RING( (1 << 16) | 1 );
  994 
  995                         ADVANCE_RING();
  996                 }
  997         }
  998 
  999         DRM_FREE( buffer, buffer_size );
 1000 
 1001         return 0;
 1002 }
 1003 
 1004 static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
 1005                                            drm_r128_depth_t *depth )
 1006 {
 1007         drm_r128_private_t *dev_priv = dev->dev_private;
 1008         int count, *x, *y;
 1009         u32 *buffer;
 1010         u8 *mask;
 1011         int i, xbuf_size, ybuf_size, buffer_size, mask_size;
 1012         RING_LOCALS;
 1013         DRM_DEBUG( "\n" );
 1014 
 1015         count = depth->n;
 1016         if (count > 4096 || count <= 0)
 1017                 return DRM_ERR(EMSGSIZE);
 1018 
 1019         xbuf_size = count * sizeof(*x);
 1020         ybuf_size = count * sizeof(*y);
 1021 
 1022         x = DRM_MALLOC( xbuf_size );
 1023         if ( x == NULL ) {
 1024                 return DRM_ERR(ENOMEM);
 1025         }
 1026         y = DRM_MALLOC( ybuf_size );
 1027         if ( y == NULL ) {
 1028                 DRM_FREE( x, xbuf_size );
 1029                 return DRM_ERR(ENOMEM);
 1030         }
 1031         if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
 1032                 DRM_FREE( x, xbuf_size );
 1033                 DRM_FREE( y, ybuf_size );
 1034                 return DRM_ERR(EFAULT);
 1035         }
 1036         if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
 1037                 DRM_FREE( x, xbuf_size );
 1038                 DRM_FREE( y, ybuf_size );
 1039                 return DRM_ERR(EFAULT);
 1040         }
 1041 
 1042         buffer_size = depth->n * sizeof(u32);
 1043         buffer = DRM_MALLOC( buffer_size );
 1044         if ( buffer == NULL ) {
 1045                 DRM_FREE( x, xbuf_size );
 1046                 DRM_FREE( y, ybuf_size );
 1047                 return DRM_ERR(ENOMEM);
 1048         }
 1049         if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
 1050                 DRM_FREE( x, xbuf_size );
 1051                 DRM_FREE( y, ybuf_size );
 1052                 DRM_FREE( buffer, buffer_size );
 1053                 return DRM_ERR(EFAULT);
 1054         }
 1055 
 1056         if ( depth->mask ) {
 1057                 mask_size = depth->n * sizeof(u8);
 1058                 mask = DRM_MALLOC( mask_size );
 1059                 if ( mask == NULL ) {
 1060                         DRM_FREE( x, xbuf_size );
 1061                         DRM_FREE( y, ybuf_size );
 1062                         DRM_FREE( buffer, buffer_size );
 1063                         return DRM_ERR(ENOMEM);
 1064                 }
 1065                 if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
 1066                         DRM_FREE( x, xbuf_size );
 1067                         DRM_FREE( y, ybuf_size );
 1068                         DRM_FREE( buffer, buffer_size );
 1069                         DRM_FREE( mask, mask_size );
 1070                         return DRM_ERR(EFAULT);
 1071                 }
 1072 
 1073                 for ( i = 0 ; i < count ; i++ ) {
 1074                         if ( mask[i] ) {
 1075                                 BEGIN_RING( 6 );
 1076 
 1077                                 OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
 1078                                 OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
 1079                                           R128_GMC_BRUSH_SOLID_COLOR |
 1080                                           (dev_priv->depth_fmt << 8) |
 1081                                           R128_GMC_SRC_DATATYPE_COLOR |
 1082                                           R128_ROP3_P |
 1083                                           R128_GMC_CLR_CMP_CNTL_DIS |
 1084                                           R128_GMC_WR_MSK_DIS );
 1085 
 1086                                 OUT_RING( dev_priv->depth_pitch_offset_c );
 1087                                 OUT_RING( buffer[i] );
 1088 
 1089                                 OUT_RING( (x[i] << 16) | y[i] );
 1090                                 OUT_RING( (1 << 16) | 1 );
 1091 
 1092                                 ADVANCE_RING();
 1093                         }
 1094                 }
 1095 
 1096                 DRM_FREE( mask, mask_size );
 1097         } else {
 1098                 for ( i = 0 ; i < count ; i++ ) {
 1099                         BEGIN_RING( 6 );
 1100 
 1101                         OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
 1102                         OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
 1103                                   R128_GMC_BRUSH_SOLID_COLOR |
 1104                                   (dev_priv->depth_fmt << 8) |
 1105                                   R128_GMC_SRC_DATATYPE_COLOR |
 1106                                   R128_ROP3_P |
 1107                                   R128_GMC_CLR_CMP_CNTL_DIS |
 1108                                   R128_GMC_WR_MSK_DIS );
 1109 
 1110                         OUT_RING( dev_priv->depth_pitch_offset_c );
 1111                         OUT_RING( buffer[i] );
 1112 
 1113                         OUT_RING( (x[i] << 16) | y[i] );
 1114                         OUT_RING( (1 << 16) | 1 );
 1115 
 1116                         ADVANCE_RING();
 1117                 }
 1118         }
 1119 
 1120         DRM_FREE( x, xbuf_size );
 1121         DRM_FREE( y, ybuf_size );
 1122         DRM_FREE( buffer, buffer_size );
 1123 
 1124         return 0;
 1125 }
 1126 
 1127 static int r128_cce_dispatch_read_span( drm_device_t *dev,
 1128                                         drm_r128_depth_t *depth )
 1129 {
 1130         drm_r128_private_t *dev_priv = dev->dev_private;
 1131         int count, x, y;
 1132         RING_LOCALS;
 1133         DRM_DEBUG( "\n" );
 1134 
 1135         count = depth->n;
 1136         if (count > 4096 || count <= 0)
 1137                 return DRM_ERR(EMSGSIZE);
 1138 
 1139         if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
 1140                 return DRM_ERR(EFAULT);
 1141         }
 1142         if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
 1143                 return DRM_ERR(EFAULT);
 1144         }
 1145 
 1146         BEGIN_RING( 7 );
 1147 
 1148         OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
 1149         OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
 1150                   R128_GMC_DST_PITCH_OFFSET_CNTL |
 1151                   R128_GMC_BRUSH_NONE |
 1152                   (dev_priv->depth_fmt << 8) |
 1153                   R128_GMC_SRC_DATATYPE_COLOR |
 1154                   R128_ROP3_S |
 1155                   R128_DP_SRC_SOURCE_MEMORY |
 1156                   R128_GMC_CLR_CMP_CNTL_DIS |
 1157                   R128_GMC_WR_MSK_DIS );
 1158 
 1159         OUT_RING( dev_priv->depth_pitch_offset_c );
 1160         OUT_RING( dev_priv->span_pitch_offset_c );
 1161 
 1162         OUT_RING( (x << 16) | y );
 1163         OUT_RING( (0 << 16) | 0 );
 1164         OUT_RING( (count << 16) | 1 );
 1165 
 1166         ADVANCE_RING();
 1167 
 1168         return 0;
 1169 }
 1170 
 1171 static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 1172                                           drm_r128_depth_t *depth )
 1173 {
 1174         drm_r128_private_t *dev_priv = dev->dev_private;
 1175         int count, *x, *y;
 1176         int i, xbuf_size, ybuf_size;
 1177         RING_LOCALS;
 1178         DRM_DEBUG( "%s\n", __FUNCTION__ );
 1179 
 1180         count = depth->n;
 1181         if (count > 4096 || count <= 0)
 1182                 return DRM_ERR(EMSGSIZE);
 1183 
 1184         if ( count > dev_priv->depth_pitch ) {
 1185                 count = dev_priv->depth_pitch;
 1186         }
 1187 
 1188         xbuf_size = count * sizeof(*x);
 1189         ybuf_size = count * sizeof(*y);
 1190         x = DRM_MALLOC( xbuf_size );
 1191         if ( x == NULL ) {
 1192                 return DRM_ERR(ENOMEM);
 1193         }
 1194         y = DRM_MALLOC( ybuf_size );
 1195         if ( y == NULL ) {
 1196                 DRM_FREE( x, xbuf_size );
 1197                 return DRM_ERR(ENOMEM);
 1198         }
 1199         if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
 1200                 DRM_FREE( x, xbuf_size );
 1201                 DRM_FREE( y, ybuf_size );
 1202                 return DRM_ERR(EFAULT);
 1203         }
 1204         if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
 1205                 DRM_FREE( x, xbuf_size );
 1206                 DRM_FREE( y, ybuf_size );
 1207                 return DRM_ERR(EFAULT);
 1208         }
 1209 
 1210         for ( i = 0 ; i < count ; i++ ) {
 1211                 BEGIN_RING( 7 );
 1212 
 1213                 OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
 1214                 OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
 1215                           R128_GMC_DST_PITCH_OFFSET_CNTL |
 1216                           R128_GMC_BRUSH_NONE |
 1217                           (dev_priv->depth_fmt << 8) |
 1218                           R128_GMC_SRC_DATATYPE_COLOR |
 1219                           R128_ROP3_S |
 1220                           R128_DP_SRC_SOURCE_MEMORY |
 1221                           R128_GMC_CLR_CMP_CNTL_DIS |
 1222                           R128_GMC_WR_MSK_DIS );
 1223 
 1224                 OUT_RING( dev_priv->depth_pitch_offset_c );
 1225                 OUT_RING( dev_priv->span_pitch_offset_c );
 1226 
 1227                 OUT_RING( (x[i] << 16) | y[i] );
 1228                 OUT_RING( (i << 16) | 0 );
 1229                 OUT_RING( (1 << 16) | 1 );
 1230 
 1231                 ADVANCE_RING();
 1232         }
 1233 
 1234         DRM_FREE( x, xbuf_size );
 1235         DRM_FREE( y, ybuf_size );
 1236 
 1237         return 0;
 1238 }
 1239 
 1240 
 1241 /* ================================================================
 1242  * Polygon stipple
 1243  */
 1244 
 1245 static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
 1246 {
 1247         drm_r128_private_t *dev_priv = dev->dev_private;
 1248         int i;
 1249         RING_LOCALS;
 1250         DRM_DEBUG( "%s\n", __FUNCTION__ );
 1251 
 1252         BEGIN_RING( 33 );
 1253 
 1254         OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
 1255         for ( i = 0 ; i < 32 ; i++ ) {
 1256                 OUT_RING( stipple[i] );
 1257         }
 1258 
 1259         ADVANCE_RING();
 1260 }
 1261 
 1262 
 1263 /* ================================================================
 1264  * IOCTL functions
 1265  */
 1266 
 1267 int r128_cce_clear( DRM_IOCTL_ARGS )
 1268 {
 1269         DRM_DEVICE;
 1270         drm_r128_private_t *dev_priv = dev->dev_private;
 1271         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 1272         drm_r128_clear_t clear;
 1273         DRM_DEBUG( "\n" );
 1274 
 1275         LOCK_TEST_WITH_RETURN( dev, filp );
 1276 
 1277         DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data,
 1278                              sizeof(clear) );
 1279 
 1280         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1281 
 1282         if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
 1283                 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 1284 
 1285         r128_cce_dispatch_clear( dev, &clear );
 1286         COMMIT_RING();
 1287 
 1288         /* Make sure we restore the 3D state next time.
 1289          */
 1290         dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
 1291 
 1292         return 0;
 1293 }
 1294 
 1295 static int r128_do_init_pageflip( drm_device_t *dev )
 1296 {
 1297         drm_r128_private_t *dev_priv = dev->dev_private;
 1298         DRM_DEBUG( "\n" );
 1299 
 1300         dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
 1301         dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
 1302 
 1303         R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
 1304         R128_WRITE( R128_CRTC_OFFSET_CNTL,
 1305                     dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
 1306 
 1307         dev_priv->page_flipping = 1;
 1308         dev_priv->current_page = 0;
 1309         dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
 1310 
 1311         return 0;
 1312 }
 1313 
 1314 int r128_do_cleanup_pageflip( drm_device_t *dev )
 1315 {
 1316         drm_r128_private_t *dev_priv = dev->dev_private;
 1317         DRM_DEBUG( "\n" );
 1318 
 1319         R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
 1320         R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
 1321 
 1322         if (dev_priv->current_page != 0) {
 1323                 r128_cce_dispatch_flip( dev );
 1324                 COMMIT_RING();
 1325         }
 1326 
 1327         dev_priv->page_flipping = 0;
 1328         return 0;
 1329 }
 1330 
 1331 /* Swapping and flipping are different operations, need different ioctls.
 1332  * They can & should be intermixed to support multiple 3d windows.  
 1333  */
 1334 
 1335 int r128_cce_flip( DRM_IOCTL_ARGS )
 1336 {
 1337         DRM_DEVICE;
 1338         drm_r128_private_t *dev_priv = dev->dev_private;
 1339         DRM_DEBUG( "%s\n", __FUNCTION__ );
 1340 
 1341         LOCK_TEST_WITH_RETURN( dev, filp );
 1342 
 1343         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1344 
 1345         if (!dev_priv->page_flipping) 
 1346                 r128_do_init_pageflip( dev );
 1347 
 1348         r128_cce_dispatch_flip( dev );
 1349 
 1350         COMMIT_RING();
 1351         return 0;
 1352 }
 1353 
 1354 int r128_cce_swap( DRM_IOCTL_ARGS )
 1355 {
 1356         DRM_DEVICE;
 1357         drm_r128_private_t *dev_priv = dev->dev_private;
 1358         drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 1359         DRM_DEBUG( "%s\n", __FUNCTION__ );
 1360 
 1361         LOCK_TEST_WITH_RETURN( dev, filp );
 1362 
 1363         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1364 
 1365         if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
 1366                 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 1367 
 1368         r128_cce_dispatch_swap( dev );
 1369         dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
 1370                                         R128_UPLOAD_MASKS);
 1371 
 1372         COMMIT_RING();
 1373         return 0;
 1374 }
 1375 
 1376 int r128_cce_vertex( DRM_IOCTL_ARGS )
 1377 {
 1378         DRM_DEVICE;
 1379         drm_r128_private_t *dev_priv = dev->dev_private;
 1380         drm_device_dma_t *dma = dev->dma;
 1381         drm_buf_t *buf;
 1382         drm_r128_buf_priv_t *buf_priv;
 1383         drm_r128_vertex_t vertex;
 1384 
 1385         LOCK_TEST_WITH_RETURN( dev, filp );
 1386 
 1387         if ( !dev_priv ) {
 1388                 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
 1389                 return DRM_ERR(EINVAL);
 1390         }
 1391 
 1392         DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t *) data,
 1393                              sizeof(vertex) );
 1394 
 1395         DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
 1396                    DRM_CURRENTPID,
 1397                    vertex.idx, vertex.count, vertex.discard );
 1398 
 1399         if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
 1400                 DRM_ERROR( "buffer index %d (of %d max)\n",
 1401                            vertex.idx, dma->buf_count - 1 );
 1402                 return DRM_ERR(EINVAL);
 1403         }
 1404         if ( vertex.prim < 0 ||
 1405              vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
 1406                 DRM_ERROR( "buffer prim %d\n", vertex.prim );
 1407                 return DRM_ERR(EINVAL);
 1408         }
 1409 
 1410         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1411         VB_AGE_TEST_WITH_RETURN( dev_priv );
 1412 
 1413         buf = dma->buflist[vertex.idx];
 1414         buf_priv = buf->dev_private;
 1415 
 1416         if ( buf->filp != filp ) {
 1417                 DRM_ERROR( "process %d using buffer owned by %p\n",
 1418                            DRM_CURRENTPID, buf->filp );
 1419                 return DRM_ERR(EINVAL);
 1420         }
 1421         if ( buf->pending ) {
 1422                 DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
 1423                 return DRM_ERR(EINVAL);
 1424         }
 1425 
 1426         buf->used = vertex.count;
 1427         buf_priv->prim = vertex.prim;
 1428         buf_priv->discard = vertex.discard;
 1429 
 1430         r128_cce_dispatch_vertex( dev, buf );
 1431 
 1432         COMMIT_RING();
 1433         return 0;
 1434 }
 1435 
 1436 int r128_cce_indices( DRM_IOCTL_ARGS )
 1437 {
 1438         DRM_DEVICE;
 1439         drm_r128_private_t *dev_priv = dev->dev_private;
 1440         drm_device_dma_t *dma = dev->dma;
 1441         drm_buf_t *buf;
 1442         drm_r128_buf_priv_t *buf_priv;
 1443         drm_r128_indices_t elts;
 1444         int count;
 1445 
 1446         LOCK_TEST_WITH_RETURN( dev, filp );
 1447 
 1448         if ( !dev_priv ) {
 1449                 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
 1450                 return DRM_ERR(EINVAL);
 1451         }
 1452 
 1453         DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t *) data,
 1454                              sizeof(elts) );
 1455 
 1456         DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
 1457                    elts.idx, elts.start, elts.end, elts.discard );
 1458 
 1459         if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
 1460                 DRM_ERROR( "buffer index %d (of %d max)\n",
 1461                            elts.idx, dma->buf_count - 1 );
 1462                 return DRM_ERR(EINVAL);
 1463         }
 1464         if ( elts.prim < 0 ||
 1465              elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
 1466                 DRM_ERROR( "buffer prim %d\n", elts.prim );
 1467                 return DRM_ERR(EINVAL);
 1468         }
 1469 
 1470         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1471         VB_AGE_TEST_WITH_RETURN( dev_priv );
 1472 
 1473         buf = dma->buflist[elts.idx];
 1474         buf_priv = buf->dev_private;
 1475 
 1476         if ( buf->filp != filp ) {
 1477                 DRM_ERROR( "process %d using buffer owned by %p\n",
 1478                            DRM_CURRENTPID, buf->filp );
 1479                 return DRM_ERR(EINVAL);
 1480         }
 1481         if ( buf->pending ) {
 1482                 DRM_ERROR( "sending pending buffer %d\n", elts.idx );
 1483                 return DRM_ERR(EINVAL);
 1484         }
 1485 
 1486         count = (elts.end - elts.start) / sizeof(u16);
 1487         elts.start -= R128_INDEX_PRIM_OFFSET;
 1488 
 1489         if ( elts.start & 0x7 ) {
 1490                 DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
 1491                 return DRM_ERR(EINVAL);
 1492         }
 1493         if ( elts.start < buf->used ) {
 1494                 DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
 1495                 return DRM_ERR(EINVAL);
 1496         }
 1497 
 1498         buf->used = elts.end;
 1499         buf_priv->prim = elts.prim;
 1500         buf_priv->discard = elts.discard;
 1501 
 1502         r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count );
 1503 
 1504         COMMIT_RING();
 1505         return 0;
 1506 }
 1507 
 1508 int r128_cce_blit( DRM_IOCTL_ARGS )
 1509 {
 1510         DRM_DEVICE;
 1511         drm_device_dma_t *dma = dev->dma;
 1512         drm_r128_private_t *dev_priv = dev->dev_private;
 1513         drm_r128_blit_t blit;
 1514         int ret;
 1515 
 1516         LOCK_TEST_WITH_RETURN( dev, filp );
 1517 
 1518         DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data,
 1519                              sizeof(blit) );
 1520 
 1521         DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx );
 1522 
 1523         if ( blit.idx < 0 || blit.idx >= dma->buf_count ) {
 1524                 DRM_ERROR( "buffer index %d (of %d max)\n",
 1525                            blit.idx, dma->buf_count - 1 );
 1526                 return DRM_ERR(EINVAL);
 1527         }
 1528 
 1529         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1530         VB_AGE_TEST_WITH_RETURN( dev_priv );
 1531 
 1532         ret = r128_cce_dispatch_blit( filp, dev, &blit );
 1533 
 1534         COMMIT_RING();
 1535         return ret;
 1536 }
 1537 
 1538 int r128_cce_depth( DRM_IOCTL_ARGS )
 1539 {
 1540         DRM_DEVICE;
 1541         drm_r128_private_t *dev_priv = dev->dev_private;
 1542         drm_r128_depth_t depth;
 1543         int ret;
 1544 
 1545         LOCK_TEST_WITH_RETURN( dev, filp );
 1546 
 1547         DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data,
 1548                              sizeof(depth) );
 1549 
 1550         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1551 
 1552         ret = DRM_ERR(EINVAL);
 1553         switch ( depth.func ) {
 1554         case R128_WRITE_SPAN:
 1555                 ret = r128_cce_dispatch_write_span( dev, &depth );
 1556         case R128_WRITE_PIXELS:
 1557                 ret = r128_cce_dispatch_write_pixels( dev, &depth );
 1558         case R128_READ_SPAN:
 1559                 ret = r128_cce_dispatch_read_span( dev, &depth );
 1560         case R128_READ_PIXELS:
 1561                 ret = r128_cce_dispatch_read_pixels( dev, &depth );
 1562         }
 1563 
 1564         COMMIT_RING();
 1565         return ret;
 1566 }
 1567 
 1568 int r128_cce_stipple( DRM_IOCTL_ARGS )
 1569 {
 1570         DRM_DEVICE;
 1571         drm_r128_private_t *dev_priv = dev->dev_private;
 1572         drm_r128_stipple_t stipple;
 1573         u32 mask[32];
 1574 
 1575         LOCK_TEST_WITH_RETURN( dev, filp );
 1576 
 1577         DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data,
 1578                              sizeof(stipple) );
 1579 
 1580         if ( DRM_COPY_FROM_USER( &mask, stipple.mask,
 1581                              32 * sizeof(u32) ) )
 1582                 return DRM_ERR( EFAULT );
 1583 
 1584         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1585 
 1586         r128_cce_dispatch_stipple( dev, mask );
 1587 
 1588         COMMIT_RING();
 1589         return 0;
 1590 }
 1591 
 1592 int r128_cce_indirect( DRM_IOCTL_ARGS )
 1593 {
 1594         DRM_DEVICE;
 1595         drm_r128_private_t *dev_priv = dev->dev_private;
 1596         drm_device_dma_t *dma = dev->dma;
 1597         drm_buf_t *buf;
 1598         drm_r128_buf_priv_t *buf_priv;
 1599         drm_r128_indirect_t indirect;
 1600 #if 0
 1601         RING_LOCALS;
 1602 #endif
 1603 
 1604         LOCK_TEST_WITH_RETURN( dev, filp );
 1605 
 1606         if ( !dev_priv ) {
 1607                 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
 1608                 return DRM_ERR(EINVAL);
 1609         }
 1610 
 1611         DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t *) data,
 1612                              sizeof(indirect) );
 1613 
 1614         DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
 1615                    indirect.idx, indirect.start,
 1616                    indirect.end, indirect.discard );
 1617 
 1618         if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
 1619                 DRM_ERROR( "buffer index %d (of %d max)\n",
 1620                            indirect.idx, dma->buf_count - 1 );
 1621                 return DRM_ERR(EINVAL);
 1622         }
 1623 
 1624         buf = dma->buflist[indirect.idx];
 1625         buf_priv = buf->dev_private;
 1626 
 1627         if ( buf->filp != filp ) {
 1628                 DRM_ERROR( "process %d using buffer owned by %p\n",
 1629                            DRM_CURRENTPID, buf->filp );
 1630                 return DRM_ERR(EINVAL);
 1631         }
 1632         if ( buf->pending ) {
 1633                 DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
 1634                 return DRM_ERR(EINVAL);
 1635         }
 1636 
 1637         if ( indirect.start < buf->used ) {
 1638                 DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
 1639                            indirect.start, buf->used );
 1640                 return DRM_ERR(EINVAL);
 1641         }
 1642 
 1643         RING_SPACE_TEST_WITH_RETURN( dev_priv );
 1644         VB_AGE_TEST_WITH_RETURN( dev_priv );
 1645 
 1646         buf->used = indirect.end;
 1647         buf_priv->discard = indirect.discard;
 1648 
 1649 #if 0
 1650         /* Wait for the 3D stream to idle before the indirect buffer
 1651          * containing 2D acceleration commands is processed.
 1652          */
 1653         BEGIN_RING( 2 );
 1654         RADEON_WAIT_UNTIL_3D_IDLE();
 1655         ADVANCE_RING();
 1656 #endif
 1657 
 1658         /* Dispatch the indirect buffer full of commands from the
 1659          * X server.  This is insecure and is thus only available to
 1660          * privileged clients.
 1661          */
 1662         r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end );
 1663 
 1664         COMMIT_RING();
 1665         return 0;
 1666 }
 1667 
 1668 int r128_getparam( DRM_IOCTL_ARGS )
 1669 {
 1670         DRM_DEVICE;
 1671         drm_r128_private_t *dev_priv = dev->dev_private;
 1672         drm_r128_getparam_t param;
 1673         int value;
 1674 
 1675         if ( !dev_priv ) {
 1676                 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
 1677                 return DRM_ERR(EINVAL);
 1678         }
 1679 
 1680         DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t *)data,
 1681                              sizeof(param) );
 1682 
 1683         DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
 1684 
 1685         switch( param.param ) {
 1686         case R128_PARAM_IRQ_NR:
 1687                 value = dev->irq;
 1688                 break;
 1689         default:
 1690                 return DRM_ERR(EINVAL);
 1691         }
 1692 
 1693         if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
 1694                 DRM_ERROR( "copy_to_user\n" );
 1695                 return DRM_ERR(EFAULT);
 1696         }
 1697         
 1698         return 0;
 1699 }

Cache object: 36975e63707db9b57a207baf64aaa696


[ 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.