r128_state.c revision 139749
195584Sanholt/* r128_state.c -- State support for r128 -*- linux-c -*- 2139749Simp * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com */ 3139749Simp/*- 495584Sanholt * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 595584Sanholt * All Rights Reserved. 695584Sanholt * 795584Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 895584Sanholt * copy of this software and associated documentation files (the "Software"), 995584Sanholt * to deal in the Software without restriction, including without limitation 1095584Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1195584Sanholt * and/or sell copies of the Software, and to permit persons to whom the 1295584Sanholt * Software is furnished to do so, subject to the following conditions: 1395584Sanholt * 1495584Sanholt * The above copyright notice and this permission notice (including the next 1595584Sanholt * paragraph) shall be included in all copies or substantial portions of the 1695584Sanholt * Software. 1795584Sanholt * 1895584Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1995584Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2095584Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2195584Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 2295584Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2395584Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2495584Sanholt * DEALINGS IN THE SOFTWARE. 2595584Sanholt * 2695584Sanholt * Authors: 2795584Sanholt * Gareth Hughes <gareth@valinux.com> 2895584Sanholt * 2995584Sanholt * $FreeBSD: head/sys/dev/drm/r128_state.c 139749 2005-01-06 01:43:34Z imp $ 3095584Sanholt */ 3195584Sanholt 3295584Sanholt#include "dev/drm/r128.h" 3395584Sanholt#include "dev/drm/drmP.h" 34112015Sanholt#include "dev/drm/drm.h" 3595746Sanholt#include "dev/drm/r128_drm.h" 3695584Sanholt#include "dev/drm/r128_drv.h" 3795584Sanholt 3895584Sanholt 3995584Sanholt/* ================================================================ 4095584Sanholt * CCE hardware state programming functions 4195584Sanholt */ 4295584Sanholt 4395584Sanholtstatic void r128_emit_clip_rects( drm_r128_private_t *dev_priv, 4495584Sanholt drm_clip_rect_t *boxes, int count ) 4595584Sanholt{ 4695584Sanholt u32 aux_sc_cntl = 0x00000000; 4795584Sanholt RING_LOCALS; 48112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 4995584Sanholt 50121447Sanholt BEGIN_RING( (count < 3? count: 3) * 5 + 2 ); 5195584Sanholt 5295584Sanholt if ( count >= 1 ) { 5395584Sanholt OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) ); 5495584Sanholt OUT_RING( boxes[0].x1 ); 5595584Sanholt OUT_RING( boxes[0].x2 - 1 ); 5695584Sanholt OUT_RING( boxes[0].y1 ); 5795584Sanholt OUT_RING( boxes[0].y2 - 1 ); 5895584Sanholt 5995584Sanholt aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); 6095584Sanholt } 6195584Sanholt if ( count >= 2 ) { 6295584Sanholt OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) ); 6395584Sanholt OUT_RING( boxes[1].x1 ); 6495584Sanholt OUT_RING( boxes[1].x2 - 1 ); 6595584Sanholt OUT_RING( boxes[1].y1 ); 6695584Sanholt OUT_RING( boxes[1].y2 - 1 ); 6795584Sanholt 6895584Sanholt aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); 6995584Sanholt } 7095584Sanholt if ( count >= 3 ) { 7195584Sanholt OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) ); 7295584Sanholt OUT_RING( boxes[2].x1 ); 7395584Sanholt OUT_RING( boxes[2].x2 - 1 ); 7495584Sanholt OUT_RING( boxes[2].y1 ); 7595584Sanholt OUT_RING( boxes[2].y2 - 1 ); 7695584Sanholt 7795584Sanholt aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); 7895584Sanholt } 7995584Sanholt 8095584Sanholt OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) ); 8195584Sanholt OUT_RING( aux_sc_cntl ); 8295584Sanholt 8395584Sanholt ADVANCE_RING(); 8495584Sanholt} 8595584Sanholt 8695584Sanholtstatic __inline__ void r128_emit_core( drm_r128_private_t *dev_priv ) 8795584Sanholt{ 8895584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 8995584Sanholt drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 9095584Sanholt RING_LOCALS; 91112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 9295584Sanholt 9395584Sanholt BEGIN_RING( 2 ); 9495584Sanholt 9595584Sanholt OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) ); 9695584Sanholt OUT_RING( ctx->scale_3d_cntl ); 9795584Sanholt 9895584Sanholt ADVANCE_RING(); 9995584Sanholt} 10095584Sanholt 10195584Sanholtstatic __inline__ void r128_emit_context( drm_r128_private_t *dev_priv ) 10295584Sanholt{ 10395584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 10495584Sanholt drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 10595584Sanholt RING_LOCALS; 106112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 10795584Sanholt 10895584Sanholt BEGIN_RING( 13 ); 10995584Sanholt 11095584Sanholt OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) ); 11195584Sanholt OUT_RING( ctx->dst_pitch_offset_c ); 11295584Sanholt OUT_RING( ctx->dp_gui_master_cntl_c ); 11395584Sanholt OUT_RING( ctx->sc_top_left_c ); 11495584Sanholt OUT_RING( ctx->sc_bottom_right_c ); 11595584Sanholt OUT_RING( ctx->z_offset_c ); 11695584Sanholt OUT_RING( ctx->z_pitch_c ); 11795584Sanholt OUT_RING( ctx->z_sten_cntl_c ); 11895584Sanholt OUT_RING( ctx->tex_cntl_c ); 11995584Sanholt OUT_RING( ctx->misc_3d_state_cntl_reg ); 12095584Sanholt OUT_RING( ctx->texture_clr_cmp_clr_c ); 12195584Sanholt OUT_RING( ctx->texture_clr_cmp_msk_c ); 12295584Sanholt OUT_RING( ctx->fog_color_c ); 12395584Sanholt 12495584Sanholt ADVANCE_RING(); 12595584Sanholt} 12695584Sanholt 12795584Sanholtstatic __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv ) 12895584Sanholt{ 12995584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 13095584Sanholt drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 13195584Sanholt RING_LOCALS; 132112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 13395584Sanholt 13495584Sanholt BEGIN_RING( 3 ); 13595584Sanholt 13695584Sanholt OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) ); 13795584Sanholt OUT_RING( ctx->setup_cntl ); 13895584Sanholt OUT_RING( ctx->pm4_vc_fpu_setup ); 13995584Sanholt 14095584Sanholt ADVANCE_RING(); 14195584Sanholt} 14295584Sanholt 14395584Sanholtstatic __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv ) 14495584Sanholt{ 14595584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 14695584Sanholt drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 14795584Sanholt RING_LOCALS; 148112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 14995584Sanholt 15095584Sanholt BEGIN_RING( 5 ); 15195584Sanholt 15295584Sanholt OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); 15395584Sanholt OUT_RING( ctx->dp_write_mask ); 15495584Sanholt 15595584Sanholt OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) ); 15695584Sanholt OUT_RING( ctx->sten_ref_mask_c ); 15795584Sanholt OUT_RING( ctx->plane_3d_mask_c ); 15895584Sanholt 15995584Sanholt ADVANCE_RING(); 16095584Sanholt} 16195584Sanholt 16295584Sanholtstatic __inline__ void r128_emit_window( drm_r128_private_t *dev_priv ) 16395584Sanholt{ 16495584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 16595584Sanholt drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 16695584Sanholt RING_LOCALS; 167112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 16895584Sanholt 16995584Sanholt BEGIN_RING( 2 ); 17095584Sanholt 17195584Sanholt OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) ); 17295584Sanholt OUT_RING( ctx->window_xy_offset ); 17395584Sanholt 17495584Sanholt ADVANCE_RING(); 17595584Sanholt} 17695584Sanholt 17795584Sanholtstatic __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv ) 17895584Sanholt{ 17995584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 18095584Sanholt drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 18195584Sanholt drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; 18295584Sanholt int i; 18395584Sanholt RING_LOCALS; 184112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 18595584Sanholt 18695584Sanholt BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS ); 18795584Sanholt 18895584Sanholt OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C, 18995584Sanholt 2 + R128_MAX_TEXTURE_LEVELS ) ); 19095584Sanholt OUT_RING( tex->tex_cntl ); 19195584Sanholt OUT_RING( tex->tex_combine_cntl ); 19295584Sanholt OUT_RING( ctx->tex_size_pitch_c ); 19395584Sanholt for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { 19495584Sanholt OUT_RING( tex->tex_offset[i] ); 19595584Sanholt } 19695584Sanholt 19795584Sanholt OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) ); 19895584Sanholt OUT_RING( ctx->constant_color_c ); 19995584Sanholt OUT_RING( tex->tex_border_color ); 20095584Sanholt 20195584Sanholt ADVANCE_RING(); 20295584Sanholt} 20395584Sanholt 20495584Sanholtstatic __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv ) 20595584Sanholt{ 20695584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 20795584Sanholt drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; 20895584Sanholt int i; 20995584Sanholt RING_LOCALS; 210112015Sanholt DRM_DEBUG( " %s\n", __FUNCTION__ ); 21195584Sanholt 21295584Sanholt BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS ); 21395584Sanholt 21495584Sanholt OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C, 21595584Sanholt 1 + R128_MAX_TEXTURE_LEVELS ) ); 21695584Sanholt OUT_RING( tex->tex_cntl ); 21795584Sanholt OUT_RING( tex->tex_combine_cntl ); 21895584Sanholt for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { 21995584Sanholt OUT_RING( tex->tex_offset[i] ); 22095584Sanholt } 22195584Sanholt 22295584Sanholt OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) ); 22395584Sanholt OUT_RING( tex->tex_border_color ); 22495584Sanholt 22595584Sanholt ADVANCE_RING(); 22695584Sanholt} 22795584Sanholt 22895584Sanholtstatic __inline__ void r128_emit_state( drm_r128_private_t *dev_priv ) 22995584Sanholt{ 23095584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 23195584Sanholt unsigned int dirty = sarea_priv->dirty; 23295584Sanholt 233112015Sanholt DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); 23495584Sanholt 23595584Sanholt if ( dirty & R128_UPLOAD_CORE ) { 23695584Sanholt r128_emit_core( dev_priv ); 23795584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_CORE; 23895584Sanholt } 23995584Sanholt 24095584Sanholt if ( dirty & R128_UPLOAD_CONTEXT ) { 24195584Sanholt r128_emit_context( dev_priv ); 24295584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; 24395584Sanholt } 24495584Sanholt 24595584Sanholt if ( dirty & R128_UPLOAD_SETUP ) { 24695584Sanholt r128_emit_setup( dev_priv ); 24795584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_SETUP; 24895584Sanholt } 24995584Sanholt 25095584Sanholt if ( dirty & R128_UPLOAD_MASKS ) { 25195584Sanholt r128_emit_masks( dev_priv ); 25295584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_MASKS; 25395584Sanholt } 25495584Sanholt 25595584Sanholt if ( dirty & R128_UPLOAD_WINDOW ) { 25695584Sanholt r128_emit_window( dev_priv ); 25795584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; 25895584Sanholt } 25995584Sanholt 26095584Sanholt if ( dirty & R128_UPLOAD_TEX0 ) { 26195584Sanholt r128_emit_tex0( dev_priv ); 26295584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_TEX0; 26395584Sanholt } 26495584Sanholt 26595584Sanholt if ( dirty & R128_UPLOAD_TEX1 ) { 26695584Sanholt r128_emit_tex1( dev_priv ); 26795584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_TEX1; 26895584Sanholt } 26995584Sanholt 27095584Sanholt /* Turn off the texture cache flushing */ 27195584Sanholt sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; 27295584Sanholt 27395584Sanholt sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; 27495584Sanholt} 27595584Sanholt 27695584Sanholt 27795584Sanholt#if R128_PERFORMANCE_BOXES 27895584Sanholt/* ================================================================ 27995584Sanholt * Performance monitoring functions 28095584Sanholt */ 28195584Sanholt 28295584Sanholtstatic void r128_clear_box( drm_r128_private_t *dev_priv, 28395584Sanholt int x, int y, int w, int h, 28495584Sanholt int r, int g, int b ) 28595584Sanholt{ 28695584Sanholt u32 pitch, offset; 28795584Sanholt u32 fb_bpp, color; 28895584Sanholt RING_LOCALS; 28995584Sanholt 29095584Sanholt switch ( dev_priv->fb_bpp ) { 29195584Sanholt case 16: 29295584Sanholt fb_bpp = R128_GMC_DST_16BPP; 29395584Sanholt color = (((r & 0xf8) << 8) | 29495584Sanholt ((g & 0xfc) << 3) | 29595584Sanholt ((b & 0xf8) >> 3)); 29695584Sanholt break; 29795584Sanholt case 24: 29895584Sanholt fb_bpp = R128_GMC_DST_24BPP; 29995584Sanholt color = ((r << 16) | (g << 8) | b); 30095584Sanholt break; 30195584Sanholt case 32: 30295584Sanholt fb_bpp = R128_GMC_DST_32BPP; 30395584Sanholt color = (((0xff) << 24) | (r << 16) | (g << 8) | b); 30495584Sanholt break; 30595584Sanholt default: 30695584Sanholt return; 30795584Sanholt } 30895584Sanholt 30995584Sanholt offset = dev_priv->back_offset; 31095584Sanholt pitch = dev_priv->back_pitch >> 3; 31195584Sanholt 31295584Sanholt BEGIN_RING( 6 ); 31395584Sanholt 31495584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 31595584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 31695584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 31795584Sanholt fb_bpp | 31895584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 31995584Sanholt R128_ROP3_P | 32095584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 32195584Sanholt R128_GMC_AUX_CLIP_DIS ); 32295584Sanholt 32395584Sanholt OUT_RING( (pitch << 21) | (offset >> 5) ); 32495584Sanholt OUT_RING( color ); 32595584Sanholt 32695584Sanholt OUT_RING( (x << 16) | y ); 32795584Sanholt OUT_RING( (w << 16) | h ); 32895584Sanholt 32995584Sanholt ADVANCE_RING(); 33095584Sanholt} 33195584Sanholt 33295584Sanholtstatic void r128_cce_performance_boxes( drm_r128_private_t *dev_priv ) 33395584Sanholt{ 33495584Sanholt if ( atomic_read( &dev_priv->idle_count ) == 0 ) { 33595584Sanholt r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); 33695584Sanholt } else { 33795584Sanholt atomic_set( &dev_priv->idle_count, 0 ); 33895584Sanholt } 33995584Sanholt} 34095584Sanholt 34195584Sanholt#endif 34295584Sanholt 34395584Sanholt 34495584Sanholt/* ================================================================ 34595584Sanholt * CCE command dispatch functions 34695584Sanholt */ 34795584Sanholt 34895584Sanholtstatic void r128_print_dirty( const char *msg, unsigned int flags ) 34995584Sanholt{ 35095584Sanholt DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", 35195584Sanholt msg, 35295584Sanholt flags, 35395584Sanholt (flags & R128_UPLOAD_CORE) ? "core, " : "", 35495584Sanholt (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", 35595584Sanholt (flags & R128_UPLOAD_SETUP) ? "setup, " : "", 35695584Sanholt (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", 35795584Sanholt (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", 35895584Sanholt (flags & R128_UPLOAD_MASKS) ? "masks, " : "", 35995584Sanholt (flags & R128_UPLOAD_WINDOW) ? "window, " : "", 36095584Sanholt (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", 36195584Sanholt (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); 36295584Sanholt} 36395584Sanholt 36495584Sanholtstatic void r128_cce_dispatch_clear( drm_device_t *dev, 36595584Sanholt drm_r128_clear_t *clear ) 36695584Sanholt{ 36795584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 36895584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 36995584Sanholt int nbox = sarea_priv->nbox; 37095584Sanholt drm_clip_rect_t *pbox = sarea_priv->boxes; 37195584Sanholt unsigned int flags = clear->flags; 37295584Sanholt int i; 37395584Sanholt RING_LOCALS; 374112015Sanholt DRM_DEBUG( "%s\n", __FUNCTION__ ); 37595584Sanholt 37695584Sanholt if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 37795584Sanholt unsigned int tmp = flags; 37895584Sanholt 37995584Sanholt flags &= ~(R128_FRONT | R128_BACK); 38095584Sanholt if ( tmp & R128_FRONT ) flags |= R128_BACK; 38195584Sanholt if ( tmp & R128_BACK ) flags |= R128_FRONT; 38295584Sanholt } 38395584Sanholt 38495584Sanholt for ( i = 0 ; i < nbox ; i++ ) { 38595584Sanholt int x = pbox[i].x1; 38695584Sanholt int y = pbox[i].y1; 38795584Sanholt int w = pbox[i].x2 - x; 38895584Sanholt int h = pbox[i].y2 - y; 38995584Sanholt 39095584Sanholt DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", 39195584Sanholt pbox[i].x1, pbox[i].y1, pbox[i].x2, 39295584Sanholt pbox[i].y2, flags ); 39395584Sanholt 39495584Sanholt if ( flags & (R128_FRONT | R128_BACK) ) { 39595584Sanholt BEGIN_RING( 2 ); 39695584Sanholt 39795584Sanholt OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); 39895584Sanholt OUT_RING( clear->color_mask ); 39995584Sanholt 40095584Sanholt ADVANCE_RING(); 40195584Sanholt } 40295584Sanholt 40395584Sanholt if ( flags & R128_FRONT ) { 40495584Sanholt BEGIN_RING( 6 ); 40595584Sanholt 40695584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 40795584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 40895584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 40995584Sanholt (dev_priv->color_fmt << 8) | 41095584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 41195584Sanholt R128_ROP3_P | 41295584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 41395584Sanholt R128_GMC_AUX_CLIP_DIS ); 41495584Sanholt 41595584Sanholt OUT_RING( dev_priv->front_pitch_offset_c ); 41695584Sanholt OUT_RING( clear->clear_color ); 41795584Sanholt 41895584Sanholt OUT_RING( (x << 16) | y ); 41995584Sanholt OUT_RING( (w << 16) | h ); 42095584Sanholt 42195584Sanholt ADVANCE_RING(); 42295584Sanholt } 42395584Sanholt 42495584Sanholt if ( flags & R128_BACK ) { 42595584Sanholt BEGIN_RING( 6 ); 42695584Sanholt 42795584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 42895584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 42995584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 43095584Sanholt (dev_priv->color_fmt << 8) | 43195584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 43295584Sanholt R128_ROP3_P | 43395584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 43495584Sanholt R128_GMC_AUX_CLIP_DIS ); 43595584Sanholt 43695584Sanholt OUT_RING( dev_priv->back_pitch_offset_c ); 43795584Sanholt OUT_RING( clear->clear_color ); 43895584Sanholt 43995584Sanholt OUT_RING( (x << 16) | y ); 44095584Sanholt OUT_RING( (w << 16) | h ); 44195584Sanholt 44295584Sanholt ADVANCE_RING(); 44395584Sanholt } 44495584Sanholt 44595584Sanholt if ( flags & R128_DEPTH ) { 44695584Sanholt BEGIN_RING( 6 ); 44795584Sanholt 44895584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 44995584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 45095584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 45195584Sanholt (dev_priv->depth_fmt << 8) | 45295584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 45395584Sanholt R128_ROP3_P | 45495584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 45595584Sanholt R128_GMC_AUX_CLIP_DIS | 45695584Sanholt R128_GMC_WR_MSK_DIS ); 45795584Sanholt 45895584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 45995584Sanholt OUT_RING( clear->clear_depth ); 46095584Sanholt 46195584Sanholt OUT_RING( (x << 16) | y ); 46295584Sanholt OUT_RING( (w << 16) | h ); 46395584Sanholt 46495584Sanholt ADVANCE_RING(); 46595584Sanholt } 46695584Sanholt } 46795584Sanholt} 46895584Sanholt 46995584Sanholtstatic void r128_cce_dispatch_swap( drm_device_t *dev ) 47095584Sanholt{ 47195584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 47295584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 47395584Sanholt int nbox = sarea_priv->nbox; 47495584Sanholt drm_clip_rect_t *pbox = sarea_priv->boxes; 47595584Sanholt int i; 47695584Sanholt RING_LOCALS; 477112015Sanholt DRM_DEBUG( "%s\n", __FUNCTION__ ); 47895584Sanholt 47995584Sanholt#if R128_PERFORMANCE_BOXES 48095584Sanholt /* Do some trivial performance monitoring... 48195584Sanholt */ 48295584Sanholt r128_cce_performance_boxes( dev_priv ); 48395584Sanholt#endif 48495584Sanholt 48595584Sanholt for ( i = 0 ; i < nbox ; i++ ) { 48695584Sanholt int x = pbox[i].x1; 48795584Sanholt int y = pbox[i].y1; 48895584Sanholt int w = pbox[i].x2 - x; 48995584Sanholt int h = pbox[i].y2 - y; 49095584Sanholt 49195584Sanholt BEGIN_RING( 7 ); 49295584Sanholt 49395584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); 49495584Sanholt OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | 49595584Sanholt R128_GMC_DST_PITCH_OFFSET_CNTL | 49695584Sanholt R128_GMC_BRUSH_NONE | 49795584Sanholt (dev_priv->color_fmt << 8) | 49895584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 49995584Sanholt R128_ROP3_S | 50095584Sanholt R128_DP_SRC_SOURCE_MEMORY | 50195584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 50295584Sanholt R128_GMC_AUX_CLIP_DIS | 50395584Sanholt R128_GMC_WR_MSK_DIS ); 50495584Sanholt 505119098Sanholt /* Make this work even if front & back are flipped: 506119098Sanholt */ 507119098Sanholt if (dev_priv->current_page == 0) { 508119098Sanholt OUT_RING( dev_priv->back_pitch_offset_c ); 509119098Sanholt OUT_RING( dev_priv->front_pitch_offset_c ); 510119098Sanholt } 511119098Sanholt else { 512119098Sanholt OUT_RING( dev_priv->front_pitch_offset_c ); 513119098Sanholt OUT_RING( dev_priv->back_pitch_offset_c ); 514119098Sanholt } 51595584Sanholt 51695584Sanholt OUT_RING( (x << 16) | y ); 51795584Sanholt OUT_RING( (x << 16) | y ); 51895584Sanholt OUT_RING( (w << 16) | h ); 51995584Sanholt 52095584Sanholt ADVANCE_RING(); 52195584Sanholt } 52295584Sanholt 52395584Sanholt /* Increment the frame counter. The client-side 3D driver must 52495584Sanholt * throttle the framerate by waiting for this value before 52595584Sanholt * performing the swapbuffer ioctl. 52695584Sanholt */ 52795584Sanholt dev_priv->sarea_priv->last_frame++; 52895584Sanholt 52995584Sanholt BEGIN_RING( 2 ); 53095584Sanholt 53195584Sanholt OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); 53295584Sanholt OUT_RING( dev_priv->sarea_priv->last_frame ); 53395584Sanholt 53495584Sanholt ADVANCE_RING(); 53595584Sanholt} 53695584Sanholt 53795584Sanholtstatic void r128_cce_dispatch_flip( drm_device_t *dev ) 53895584Sanholt{ 53995584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 54095584Sanholt RING_LOCALS; 541119098Sanholt DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 542119098Sanholt __FUNCTION__, 543119098Sanholt dev_priv->current_page, 544119098Sanholt dev_priv->sarea_priv->pfCurrentPage); 54595584Sanholt 54695584Sanholt#if R128_PERFORMANCE_BOXES 54795584Sanholt /* Do some trivial performance monitoring... 54895584Sanholt */ 54995584Sanholt r128_cce_performance_boxes( dev_priv ); 55095584Sanholt#endif 55195584Sanholt 55295584Sanholt BEGIN_RING( 4 ); 55395584Sanholt 55495584Sanholt R128_WAIT_UNTIL_PAGE_FLIPPED(); 55595584Sanholt OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) ); 55695584Sanholt 55795584Sanholt if ( dev_priv->current_page == 0 ) { 55895584Sanholt OUT_RING( dev_priv->back_offset ); 55995584Sanholt } else { 56095584Sanholt OUT_RING( dev_priv->front_offset ); 56195584Sanholt } 56295584Sanholt 56395584Sanholt ADVANCE_RING(); 56495584Sanholt 56595584Sanholt /* Increment the frame counter. The client-side 3D driver must 56695584Sanholt * throttle the framerate by waiting for this value before 56795584Sanholt * performing the swapbuffer ioctl. 56895584Sanholt */ 56995584Sanholt dev_priv->sarea_priv->last_frame++; 570119098Sanholt dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = 571119098Sanholt 1 - dev_priv->current_page; 57295584Sanholt 57395584Sanholt BEGIN_RING( 2 ); 57495584Sanholt 57595584Sanholt OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); 57695584Sanholt OUT_RING( dev_priv->sarea_priv->last_frame ); 57795584Sanholt 57895584Sanholt ADVANCE_RING(); 57995584Sanholt} 58095584Sanholt 58195584Sanholtstatic void r128_cce_dispatch_vertex( drm_device_t *dev, 58295584Sanholt drm_buf_t *buf ) 58395584Sanholt{ 58495584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 58595584Sanholt drm_r128_buf_priv_t *buf_priv = buf->dev_private; 58695584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 58795584Sanholt int format = sarea_priv->vc_format; 58895584Sanholt int offset = buf->bus_address; 58995584Sanholt int size = buf->used; 59095584Sanholt int prim = buf_priv->prim; 59195584Sanholt int i = 0; 59295584Sanholt RING_LOCALS; 593112015Sanholt DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox ); 59495584Sanholt 59595584Sanholt if ( 0 ) 59695584Sanholt r128_print_dirty( "dispatch_vertex", sarea_priv->dirty ); 59795584Sanholt 59895584Sanholt if ( buf->used ) { 59995584Sanholt buf_priv->dispatched = 1; 60095584Sanholt 60195584Sanholt if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) { 60295584Sanholt r128_emit_state( dev_priv ); 60395584Sanholt } 60495584Sanholt 60595584Sanholt do { 60695584Sanholt /* Emit the next set of up to three cliprects */ 60795584Sanholt if ( i < sarea_priv->nbox ) { 60895584Sanholt r128_emit_clip_rects( dev_priv, 60995584Sanholt &sarea_priv->boxes[i], 61095584Sanholt sarea_priv->nbox - i ); 61195584Sanholt } 61295584Sanholt 61395584Sanholt /* Emit the vertex buffer rendering commands */ 61495584Sanholt BEGIN_RING( 5 ); 61595584Sanholt 61695584Sanholt OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) ); 61795584Sanholt OUT_RING( offset ); 61895584Sanholt OUT_RING( size ); 61995584Sanholt OUT_RING( format ); 62095584Sanholt OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | 62195584Sanholt (size << R128_CCE_VC_CNTL_NUM_SHIFT) ); 62295584Sanholt 62395584Sanholt ADVANCE_RING(); 62495584Sanholt 62595584Sanholt i += 3; 62695584Sanholt } while ( i < sarea_priv->nbox ); 62795584Sanholt } 62895584Sanholt 62995584Sanholt if ( buf_priv->discard ) { 63095584Sanholt buf_priv->age = dev_priv->sarea_priv->last_dispatch; 63195584Sanholt 63295584Sanholt /* Emit the vertex buffer age */ 63395584Sanholt BEGIN_RING( 2 ); 63495584Sanholt 63595584Sanholt OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); 63695584Sanholt OUT_RING( buf_priv->age ); 63795584Sanholt 63895584Sanholt ADVANCE_RING(); 63995584Sanholt 64095584Sanholt buf->pending = 1; 64195584Sanholt buf->used = 0; 64295584Sanholt /* FIXME: Check dispatched field */ 64395584Sanholt buf_priv->dispatched = 0; 64495584Sanholt } 64595584Sanholt 64695584Sanholt dev_priv->sarea_priv->last_dispatch++; 64795584Sanholt 64895584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; 64995584Sanholt sarea_priv->nbox = 0; 65095584Sanholt} 65195584Sanholt 65295584Sanholtstatic void r128_cce_dispatch_indirect( drm_device_t *dev, 65395584Sanholt drm_buf_t *buf, 65495584Sanholt int start, int end ) 65595584Sanholt{ 65695584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 65795584Sanholt drm_r128_buf_priv_t *buf_priv = buf->dev_private; 65895584Sanholt RING_LOCALS; 65995584Sanholt DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", 66095584Sanholt buf->idx, start, end ); 66195584Sanholt 66295584Sanholt if ( start != end ) { 66395584Sanholt int offset = buf->bus_address + start; 66495584Sanholt int dwords = (end - start + 3) / sizeof(u32); 66595584Sanholt 66695584Sanholt /* Indirect buffer data must be an even number of 66795584Sanholt * dwords, so if we've been given an odd number we must 66895584Sanholt * pad the data with a Type-2 CCE packet. 66995584Sanholt */ 67095584Sanholt if ( dwords & 1 ) { 67195584Sanholt u32 *data = (u32 *) 67295584Sanholt ((char *)dev_priv->buffers->handle 67395584Sanholt + buf->offset + start); 67495584Sanholt data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 ); 67595584Sanholt } 67695584Sanholt 67795584Sanholt buf_priv->dispatched = 1; 67895584Sanholt 67995584Sanholt /* Fire off the indirect buffer */ 68095584Sanholt BEGIN_RING( 3 ); 68195584Sanholt 68295584Sanholt OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) ); 68395584Sanholt OUT_RING( offset ); 68495584Sanholt OUT_RING( dwords ); 68595584Sanholt 68695584Sanholt ADVANCE_RING(); 68795584Sanholt } 68895584Sanholt 68995584Sanholt if ( buf_priv->discard ) { 69095584Sanholt buf_priv->age = dev_priv->sarea_priv->last_dispatch; 69195584Sanholt 69295584Sanholt /* Emit the indirect buffer age */ 69395584Sanholt BEGIN_RING( 2 ); 69495584Sanholt 69595584Sanholt OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); 69695584Sanholt OUT_RING( buf_priv->age ); 69795584Sanholt 69895584Sanholt ADVANCE_RING(); 69995584Sanholt 70095584Sanholt buf->pending = 1; 70195584Sanholt buf->used = 0; 70295584Sanholt /* FIXME: Check dispatched field */ 70395584Sanholt buf_priv->dispatched = 0; 70495584Sanholt } 70595584Sanholt 70695584Sanholt dev_priv->sarea_priv->last_dispatch++; 70795584Sanholt} 70895584Sanholt 70995584Sanholtstatic void r128_cce_dispatch_indices( drm_device_t *dev, 71095584Sanholt drm_buf_t *buf, 71195584Sanholt int start, int end, 71295584Sanholt int count ) 71395584Sanholt{ 71495584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 71595584Sanholt drm_r128_buf_priv_t *buf_priv = buf->dev_private; 71695584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 71795584Sanholt int format = sarea_priv->vc_format; 71895584Sanholt int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset; 71995584Sanholt int prim = buf_priv->prim; 72095584Sanholt u32 *data; 72195584Sanholt int dwords; 72295584Sanholt int i = 0; 72395584Sanholt RING_LOCALS; 72495584Sanholt DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); 72595584Sanholt 72695584Sanholt if ( 0 ) 72795584Sanholt r128_print_dirty( "dispatch_indices", sarea_priv->dirty ); 72895584Sanholt 72995584Sanholt if ( start != end ) { 73095584Sanholt buf_priv->dispatched = 1; 73195584Sanholt 73295584Sanholt if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) { 73395584Sanholt r128_emit_state( dev_priv ); 73495584Sanholt } 73595584Sanholt 73695584Sanholt dwords = (end - start + 3) / sizeof(u32); 73795584Sanholt 73895584Sanholt data = (u32 *)((char *)dev_priv->buffers->handle 73995584Sanholt + buf->offset + start); 74095584Sanholt 74195584Sanholt data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 74295584Sanholt dwords-2 ) ); 74395584Sanholt 74495584Sanholt data[1] = cpu_to_le32( offset ); 74595584Sanholt data[2] = cpu_to_le32( R128_MAX_VB_VERTS ); 74695584Sanholt data[3] = cpu_to_le32( format ); 74795584Sanholt data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | 74895584Sanholt (count << 16)) ); 74995584Sanholt 75095584Sanholt if ( count & 0x1 ) { 75195584Sanholt#ifdef __LITTLE_ENDIAN 75295584Sanholt data[dwords-1] &= 0x0000ffff; 75395584Sanholt#else 75495584Sanholt data[dwords-1] &= 0xffff0000; 75595584Sanholt#endif 75695584Sanholt } 75795584Sanholt 75895584Sanholt do { 75995584Sanholt /* Emit the next set of up to three cliprects */ 76095584Sanholt if ( i < sarea_priv->nbox ) { 76195584Sanholt r128_emit_clip_rects( dev_priv, 76295584Sanholt &sarea_priv->boxes[i], 76395584Sanholt sarea_priv->nbox - i ); 76495584Sanholt } 76595584Sanholt 76695584Sanholt r128_cce_dispatch_indirect( dev, buf, start, end ); 76795584Sanholt 76895584Sanholt i += 3; 76995584Sanholt } while ( i < sarea_priv->nbox ); 77095584Sanholt } 77195584Sanholt 77295584Sanholt if ( buf_priv->discard ) { 77395584Sanholt buf_priv->age = dev_priv->sarea_priv->last_dispatch; 77495584Sanholt 77595584Sanholt /* Emit the vertex buffer age */ 77695584Sanholt BEGIN_RING( 2 ); 77795584Sanholt 77895584Sanholt OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); 77995584Sanholt OUT_RING( buf_priv->age ); 78095584Sanholt 78195584Sanholt ADVANCE_RING(); 78295584Sanholt 78395584Sanholt buf->pending = 1; 78495584Sanholt /* FIXME: Check dispatched field */ 78595584Sanholt buf_priv->dispatched = 0; 78695584Sanholt } 78795584Sanholt 78895584Sanholt dev_priv->sarea_priv->last_dispatch++; 78995584Sanholt 79095584Sanholt sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; 79195584Sanholt sarea_priv->nbox = 0; 79295584Sanholt} 79395584Sanholt 794113995Sanholtstatic int r128_cce_dispatch_blit( DRMFILE filp, 795113995Sanholt drm_device_t *dev, 796112015Sanholt drm_r128_blit_t *blit ) 79795584Sanholt{ 79895584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 79995584Sanholt drm_device_dma_t *dma = dev->dma; 80095584Sanholt drm_buf_t *buf; 80195584Sanholt drm_r128_buf_priv_t *buf_priv; 80295584Sanholt u32 *data; 80395584Sanholt int dword_shift, dwords; 80495584Sanholt RING_LOCALS; 805112015Sanholt DRM_DEBUG( "\n" ); 80695584Sanholt 80795584Sanholt /* The compiler won't optimize away a division by a variable, 80895584Sanholt * even if the only legal values are powers of two. Thus, we'll 80995584Sanholt * use a shift instead. 81095584Sanholt */ 81195584Sanholt switch ( blit->format ) { 81295584Sanholt case R128_DATATYPE_ARGB8888: 81395584Sanholt dword_shift = 0; 81495584Sanholt break; 81595584Sanholt case R128_DATATYPE_ARGB1555: 81695584Sanholt case R128_DATATYPE_RGB565: 81795584Sanholt case R128_DATATYPE_ARGB4444: 818119098Sanholt case R128_DATATYPE_YVYU422: 819119098Sanholt case R128_DATATYPE_VYUY422: 82095584Sanholt dword_shift = 1; 82195584Sanholt break; 82295584Sanholt case R128_DATATYPE_CI8: 82395584Sanholt case R128_DATATYPE_RGB8: 82495584Sanholt dword_shift = 2; 82595584Sanholt break; 82695584Sanholt default: 82795584Sanholt DRM_ERROR( "invalid blit format %d\n", blit->format ); 828112015Sanholt return DRM_ERR(EINVAL); 82995584Sanholt } 83095584Sanholt 83195584Sanholt /* Flush the pixel cache, and mark the contents as Read Invalid. 83295584Sanholt * This ensures no pixel data gets mixed up with the texture 83395584Sanholt * data from the host data blit, otherwise part of the texture 83495584Sanholt * image may be corrupted. 83595584Sanholt */ 83695584Sanholt BEGIN_RING( 2 ); 83795584Sanholt 83895584Sanholt OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) ); 83995584Sanholt OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI ); 84095584Sanholt 84195584Sanholt ADVANCE_RING(); 84295584Sanholt 84395584Sanholt /* Dispatch the indirect buffer. 84495584Sanholt */ 84595584Sanholt buf = dma->buflist[blit->idx]; 84695584Sanholt buf_priv = buf->dev_private; 84795584Sanholt 848113995Sanholt if ( buf->filp != filp ) { 849113995Sanholt DRM_ERROR( "process %d using buffer owned by %p\n", 850113995Sanholt DRM_CURRENTPID, buf->filp ); 851112015Sanholt return DRM_ERR(EINVAL); 85295584Sanholt } 85395584Sanholt if ( buf->pending ) { 85495584Sanholt DRM_ERROR( "sending pending buffer %d\n", blit->idx ); 855112015Sanholt return DRM_ERR(EINVAL); 85695584Sanholt } 85795584Sanholt 85895584Sanholt buf_priv->discard = 1; 85995584Sanholt 86095584Sanholt dwords = (blit->width * blit->height) >> dword_shift; 86195584Sanholt 86295584Sanholt data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); 86395584Sanholt 86495584Sanholt data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) ); 86595584Sanholt data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL | 86695584Sanholt R128_GMC_BRUSH_NONE | 86795584Sanholt (blit->format << 8) | 86895584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 86995584Sanholt R128_ROP3_S | 87095584Sanholt R128_DP_SRC_SOURCE_HOST_DATA | 87195584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 87295584Sanholt R128_GMC_AUX_CLIP_DIS | 87395584Sanholt R128_GMC_WR_MSK_DIS) ); 87495584Sanholt 87595584Sanholt data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) ); 87695584Sanholt data[3] = cpu_to_le32( 0xffffffff ); 87795584Sanholt data[4] = cpu_to_le32( 0xffffffff ); 87895584Sanholt data[5] = cpu_to_le32( (blit->y << 16) | blit->x ); 87995584Sanholt data[6] = cpu_to_le32( (blit->height << 16) | blit->width ); 88095584Sanholt data[7] = cpu_to_le32( dwords ); 88195584Sanholt 88295584Sanholt buf->used = (dwords + 8) * sizeof(u32); 88395584Sanholt 88495584Sanholt r128_cce_dispatch_indirect( dev, buf, 0, buf->used ); 88595584Sanholt 88695584Sanholt /* Flush the pixel cache after the blit completes. This ensures 88795584Sanholt * the texture data is written out to memory before rendering 88895584Sanholt * continues. 88995584Sanholt */ 89095584Sanholt BEGIN_RING( 2 ); 89195584Sanholt 89295584Sanholt OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) ); 89395584Sanholt OUT_RING( R128_PC_FLUSH_GUI ); 89495584Sanholt 89595584Sanholt ADVANCE_RING(); 89695584Sanholt 89795584Sanholt return 0; 89895584Sanholt} 89995584Sanholt 90095584Sanholt 90195584Sanholt/* ================================================================ 90295584Sanholt * Tiled depth buffer management 90395584Sanholt * 90495584Sanholt * FIXME: These should all set the destination write mask for when we 90595584Sanholt * have hardware stencil support. 90695584Sanholt */ 90795584Sanholt 90895584Sanholtstatic int r128_cce_dispatch_write_span( drm_device_t *dev, 90995584Sanholt drm_r128_depth_t *depth ) 91095584Sanholt{ 91195584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 91295584Sanholt int count, x, y; 91395584Sanholt u32 *buffer; 91495584Sanholt u8 *mask; 915112015Sanholt int i, buffer_size, mask_size; 91695584Sanholt RING_LOCALS; 917112015Sanholt DRM_DEBUG( "\n" ); 91895584Sanholt 91995584Sanholt count = depth->n; 920130331Sanholt if (count > 4096 || count <= 0) 921126137Srwatson return DRM_ERR(EMSGSIZE); 922130331Sanholt 923112015Sanholt if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { 924112015Sanholt return DRM_ERR(EFAULT); 92595584Sanholt } 926112015Sanholt if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { 927112015Sanholt return DRM_ERR(EFAULT); 92895584Sanholt } 92995584Sanholt 930112015Sanholt buffer_size = depth->n * sizeof(u32); 931112015Sanholt buffer = DRM_MALLOC( buffer_size ); 93295584Sanholt if ( buffer == NULL ) 933112015Sanholt return DRM_ERR(ENOMEM); 934112015Sanholt if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { 935112015Sanholt DRM_FREE( buffer, buffer_size); 936112015Sanholt return DRM_ERR(EFAULT); 93795584Sanholt } 93895584Sanholt 939112015Sanholt mask_size = depth->n * sizeof(u8); 94095584Sanholt if ( depth->mask ) { 941112015Sanholt mask = DRM_MALLOC( mask_size ); 94295584Sanholt if ( mask == NULL ) { 943112015Sanholt DRM_FREE( buffer, buffer_size ); 944112015Sanholt return DRM_ERR(ENOMEM); 94595584Sanholt } 946112015Sanholt if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { 947112015Sanholt DRM_FREE( buffer, buffer_size ); 948112015Sanholt DRM_FREE( mask, mask_size ); 949112015Sanholt return DRM_ERR(EFAULT); 95095584Sanholt } 95195584Sanholt 95295584Sanholt for ( i = 0 ; i < count ; i++, x++ ) { 95395584Sanholt if ( mask[i] ) { 95495584Sanholt BEGIN_RING( 6 ); 95595584Sanholt 95695584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 95795584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 95895584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 95995584Sanholt (dev_priv->depth_fmt << 8) | 96095584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 96195584Sanholt R128_ROP3_P | 96295584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 96395584Sanholt R128_GMC_WR_MSK_DIS ); 96495584Sanholt 96595584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 96695584Sanholt OUT_RING( buffer[i] ); 96795584Sanholt 96895584Sanholt OUT_RING( (x << 16) | y ); 96995584Sanholt OUT_RING( (1 << 16) | 1 ); 97095584Sanholt 97195584Sanholt ADVANCE_RING(); 97295584Sanholt } 97395584Sanholt } 97495584Sanholt 975112015Sanholt DRM_FREE( mask, mask_size ); 97695584Sanholt } else { 97795584Sanholt for ( i = 0 ; i < count ; i++, x++ ) { 97895584Sanholt BEGIN_RING( 6 ); 97995584Sanholt 98095584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 98195584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 98295584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 98395584Sanholt (dev_priv->depth_fmt << 8) | 98495584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 98595584Sanholt R128_ROP3_P | 98695584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 98795584Sanholt R128_GMC_WR_MSK_DIS ); 98895584Sanholt 98995584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 99095584Sanholt OUT_RING( buffer[i] ); 99195584Sanholt 99295584Sanholt OUT_RING( (x << 16) | y ); 99395584Sanholt OUT_RING( (1 << 16) | 1 ); 99495584Sanholt 99595584Sanholt ADVANCE_RING(); 99695584Sanholt } 99795584Sanholt } 99895584Sanholt 999112015Sanholt DRM_FREE( buffer, buffer_size ); 100095584Sanholt 100195584Sanholt return 0; 100295584Sanholt} 100395584Sanholt 100495584Sanholtstatic int r128_cce_dispatch_write_pixels( drm_device_t *dev, 100595584Sanholt drm_r128_depth_t *depth ) 100695584Sanholt{ 100795584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 100895584Sanholt int count, *x, *y; 100995584Sanholt u32 *buffer; 101095584Sanholt u8 *mask; 1011112015Sanholt int i, xbuf_size, ybuf_size, buffer_size, mask_size; 101295584Sanholt RING_LOCALS; 1013112015Sanholt DRM_DEBUG( "\n" ); 101495584Sanholt 101595584Sanholt count = depth->n; 1016130331Sanholt if (count > 4096 || count <= 0) 1017126137Srwatson return DRM_ERR(EMSGSIZE); 101895584Sanholt 1019112015Sanholt xbuf_size = count * sizeof(*x); 1020112015Sanholt ybuf_size = count * sizeof(*y); 1021126137Srwatson 1022112015Sanholt x = DRM_MALLOC( xbuf_size ); 102395584Sanholt if ( x == NULL ) { 1024112015Sanholt return DRM_ERR(ENOMEM); 102595584Sanholt } 1026112015Sanholt y = DRM_MALLOC( ybuf_size ); 102795584Sanholt if ( y == NULL ) { 1028112015Sanholt DRM_FREE( x, xbuf_size ); 1029112015Sanholt return DRM_ERR(ENOMEM); 103095584Sanholt } 1031112015Sanholt if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { 1032112015Sanholt DRM_FREE( x, xbuf_size ); 1033112015Sanholt DRM_FREE( y, ybuf_size ); 1034112015Sanholt return DRM_ERR(EFAULT); 103595584Sanholt } 1036112015Sanholt if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) { 1037112015Sanholt DRM_FREE( x, xbuf_size ); 1038112015Sanholt DRM_FREE( y, ybuf_size ); 1039112015Sanholt return DRM_ERR(EFAULT); 104095584Sanholt } 104195584Sanholt 1042112015Sanholt buffer_size = depth->n * sizeof(u32); 1043112015Sanholt buffer = DRM_MALLOC( buffer_size ); 104495584Sanholt if ( buffer == NULL ) { 1045112015Sanholt DRM_FREE( x, xbuf_size ); 1046112015Sanholt DRM_FREE( y, ybuf_size ); 1047112015Sanholt return DRM_ERR(ENOMEM); 104895584Sanholt } 1049112015Sanholt if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { 1050112015Sanholt DRM_FREE( x, xbuf_size ); 1051112015Sanholt DRM_FREE( y, ybuf_size ); 1052112015Sanholt DRM_FREE( buffer, buffer_size ); 1053112015Sanholt return DRM_ERR(EFAULT); 105495584Sanholt } 105595584Sanholt 105695584Sanholt if ( depth->mask ) { 1057112015Sanholt mask_size = depth->n * sizeof(u8); 1058112015Sanholt mask = DRM_MALLOC( mask_size ); 105995584Sanholt if ( mask == NULL ) { 1060112015Sanholt DRM_FREE( x, xbuf_size ); 1061112015Sanholt DRM_FREE( y, ybuf_size ); 1062112015Sanholt DRM_FREE( buffer, buffer_size ); 1063112015Sanholt return DRM_ERR(ENOMEM); 106495584Sanholt } 1065112015Sanholt if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { 1066112015Sanholt DRM_FREE( x, xbuf_size ); 1067112015Sanholt DRM_FREE( y, ybuf_size ); 1068112015Sanholt DRM_FREE( buffer, buffer_size ); 1069112015Sanholt DRM_FREE( mask, mask_size ); 1070112015Sanholt return DRM_ERR(EFAULT); 107195584Sanholt } 107295584Sanholt 107395584Sanholt for ( i = 0 ; i < count ; i++ ) { 107495584Sanholt if ( mask[i] ) { 107595584Sanholt BEGIN_RING( 6 ); 107695584Sanholt 107795584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 107895584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 107995584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 108095584Sanholt (dev_priv->depth_fmt << 8) | 108195584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 108295584Sanholt R128_ROP3_P | 108395584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 108495584Sanholt R128_GMC_WR_MSK_DIS ); 108595584Sanholt 108695584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 108795584Sanholt OUT_RING( buffer[i] ); 108895584Sanholt 108995584Sanholt OUT_RING( (x[i] << 16) | y[i] ); 109095584Sanholt OUT_RING( (1 << 16) | 1 ); 109195584Sanholt 109295584Sanholt ADVANCE_RING(); 109395584Sanholt } 109495584Sanholt } 109595584Sanholt 1096112015Sanholt DRM_FREE( mask, mask_size ); 109795584Sanholt } else { 109895584Sanholt for ( i = 0 ; i < count ; i++ ) { 109995584Sanholt BEGIN_RING( 6 ); 110095584Sanholt 110195584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); 110295584Sanholt OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | 110395584Sanholt R128_GMC_BRUSH_SOLID_COLOR | 110495584Sanholt (dev_priv->depth_fmt << 8) | 110595584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 110695584Sanholt R128_ROP3_P | 110795584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 110895584Sanholt R128_GMC_WR_MSK_DIS ); 110995584Sanholt 111095584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 111195584Sanholt OUT_RING( buffer[i] ); 111295584Sanholt 111395584Sanholt OUT_RING( (x[i] << 16) | y[i] ); 111495584Sanholt OUT_RING( (1 << 16) | 1 ); 111595584Sanholt 111695584Sanholt ADVANCE_RING(); 111795584Sanholt } 111895584Sanholt } 111995584Sanholt 1120112015Sanholt DRM_FREE( x, xbuf_size ); 1121112015Sanholt DRM_FREE( y, ybuf_size ); 1122112015Sanholt DRM_FREE( buffer, buffer_size ); 112395584Sanholt 112495584Sanholt return 0; 112595584Sanholt} 112695584Sanholt 112795584Sanholtstatic int r128_cce_dispatch_read_span( drm_device_t *dev, 112895584Sanholt drm_r128_depth_t *depth ) 112995584Sanholt{ 113095584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 113195584Sanholt int count, x, y; 113295584Sanholt RING_LOCALS; 1133112015Sanholt DRM_DEBUG( "\n" ); 113495584Sanholt 113595584Sanholt count = depth->n; 1136130331Sanholt if (count > 4096 || count <= 0) 1137130331Sanholt return DRM_ERR(EMSGSIZE); 1138126137Srwatson 1139112015Sanholt if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { 1140112015Sanholt return DRM_ERR(EFAULT); 114195584Sanholt } 1142112015Sanholt if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { 1143112015Sanholt return DRM_ERR(EFAULT); 114495584Sanholt } 114595584Sanholt 114695584Sanholt BEGIN_RING( 7 ); 114795584Sanholt 114895584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); 114995584Sanholt OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | 115095584Sanholt R128_GMC_DST_PITCH_OFFSET_CNTL | 115195584Sanholt R128_GMC_BRUSH_NONE | 115295584Sanholt (dev_priv->depth_fmt << 8) | 115395584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 115495584Sanholt R128_ROP3_S | 115595584Sanholt R128_DP_SRC_SOURCE_MEMORY | 115695584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 115795584Sanholt R128_GMC_WR_MSK_DIS ); 115895584Sanholt 115995584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 116095584Sanholt OUT_RING( dev_priv->span_pitch_offset_c ); 116195584Sanholt 116295584Sanholt OUT_RING( (x << 16) | y ); 116395584Sanholt OUT_RING( (0 << 16) | 0 ); 116495584Sanholt OUT_RING( (count << 16) | 1 ); 116595584Sanholt 116695584Sanholt ADVANCE_RING(); 116795584Sanholt 116895584Sanholt return 0; 116995584Sanholt} 117095584Sanholt 117195584Sanholtstatic int r128_cce_dispatch_read_pixels( drm_device_t *dev, 117295584Sanholt drm_r128_depth_t *depth ) 117395584Sanholt{ 117495584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 117595584Sanholt int count, *x, *y; 1176112015Sanholt int i, xbuf_size, ybuf_size; 117795584Sanholt RING_LOCALS; 1178112015Sanholt DRM_DEBUG( "%s\n", __FUNCTION__ ); 117995584Sanholt 118095584Sanholt count = depth->n; 1181130331Sanholt if (count > 4096 || count <= 0) 1182130331Sanholt return DRM_ERR(EMSGSIZE); 1183130331Sanholt 118495584Sanholt if ( count > dev_priv->depth_pitch ) { 118595584Sanholt count = dev_priv->depth_pitch; 118695584Sanholt } 118795584Sanholt 1188112015Sanholt xbuf_size = count * sizeof(*x); 1189112015Sanholt ybuf_size = count * sizeof(*y); 1190112015Sanholt x = DRM_MALLOC( xbuf_size ); 119195584Sanholt if ( x == NULL ) { 1192112015Sanholt return DRM_ERR(ENOMEM); 119395584Sanholt } 1194112015Sanholt y = DRM_MALLOC( ybuf_size ); 119595584Sanholt if ( y == NULL ) { 1196112015Sanholt DRM_FREE( x, xbuf_size ); 1197112015Sanholt return DRM_ERR(ENOMEM); 119895584Sanholt } 1199112015Sanholt if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { 1200112015Sanholt DRM_FREE( x, xbuf_size ); 1201112015Sanholt DRM_FREE( y, ybuf_size ); 1202112015Sanholt return DRM_ERR(EFAULT); 120395584Sanholt } 1204112015Sanholt if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) { 1205112015Sanholt DRM_FREE( x, xbuf_size ); 1206112015Sanholt DRM_FREE( y, ybuf_size ); 1207112015Sanholt return DRM_ERR(EFAULT); 120895584Sanholt } 120995584Sanholt 121095584Sanholt for ( i = 0 ; i < count ; i++ ) { 121195584Sanholt BEGIN_RING( 7 ); 121295584Sanholt 121395584Sanholt OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); 121495584Sanholt OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | 121595584Sanholt R128_GMC_DST_PITCH_OFFSET_CNTL | 121695584Sanholt R128_GMC_BRUSH_NONE | 121795584Sanholt (dev_priv->depth_fmt << 8) | 121895584Sanholt R128_GMC_SRC_DATATYPE_COLOR | 121995584Sanholt R128_ROP3_S | 122095584Sanholt R128_DP_SRC_SOURCE_MEMORY | 122195584Sanholt R128_GMC_CLR_CMP_CNTL_DIS | 122295584Sanholt R128_GMC_WR_MSK_DIS ); 122395584Sanholt 122495584Sanholt OUT_RING( dev_priv->depth_pitch_offset_c ); 122595584Sanholt OUT_RING( dev_priv->span_pitch_offset_c ); 122695584Sanholt 122795584Sanholt OUT_RING( (x[i] << 16) | y[i] ); 122895584Sanholt OUT_RING( (i << 16) | 0 ); 122995584Sanholt OUT_RING( (1 << 16) | 1 ); 123095584Sanholt 123195584Sanholt ADVANCE_RING(); 123295584Sanholt } 123395584Sanholt 1234112015Sanholt DRM_FREE( x, xbuf_size ); 1235112015Sanholt DRM_FREE( y, ybuf_size ); 123695584Sanholt 123795584Sanholt return 0; 123895584Sanholt} 123995584Sanholt 124095584Sanholt 124195584Sanholt/* ================================================================ 124295584Sanholt * Polygon stipple 124395584Sanholt */ 124495584Sanholt 124595584Sanholtstatic void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) 124695584Sanholt{ 124795584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 124895584Sanholt int i; 124995584Sanholt RING_LOCALS; 1250112015Sanholt DRM_DEBUG( "%s\n", __FUNCTION__ ); 125195584Sanholt 125295584Sanholt BEGIN_RING( 33 ); 125395584Sanholt 125495584Sanholt OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); 125595584Sanholt for ( i = 0 ; i < 32 ; i++ ) { 125695584Sanholt OUT_RING( stipple[i] ); 125795584Sanholt } 125895584Sanholt 125995584Sanholt ADVANCE_RING(); 126095584Sanholt} 126195584Sanholt 126295584Sanholt 126395584Sanholt/* ================================================================ 126495584Sanholt * IOCTL functions 126595584Sanholt */ 126695584Sanholt 1267112015Sanholtint r128_cce_clear( DRM_IOCTL_ARGS ) 126895584Sanholt{ 1269112015Sanholt DRM_DEVICE; 127095584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 127195584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 127295584Sanholt drm_r128_clear_t clear; 1273112015Sanholt DRM_DEBUG( "\n" ); 127495584Sanholt 1275113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 127695584Sanholt 1277112015Sanholt DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data, 127895584Sanholt sizeof(clear) ); 127995584Sanholt 128095584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 128195584Sanholt 128295584Sanholt if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) 128395584Sanholt sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; 128495584Sanholt 128595584Sanholt r128_cce_dispatch_clear( dev, &clear ); 1286121447Sanholt COMMIT_RING(); 128795584Sanholt 128895584Sanholt /* Make sure we restore the 3D state next time. 128995584Sanholt */ 129095584Sanholt dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; 129195584Sanholt 129295584Sanholt return 0; 129395584Sanholt} 129495584Sanholt 1295119098Sanholtstatic int r128_do_init_pageflip( drm_device_t *dev ) 1296119098Sanholt{ 1297119098Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 1298119098Sanholt DRM_DEBUG( "\n" ); 1299119098Sanholt 1300119098Sanholt dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); 1301119098Sanholt dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); 1302119098Sanholt 1303119098Sanholt R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); 1304119098Sanholt R128_WRITE( R128_CRTC_OFFSET_CNTL, 1305119098Sanholt dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); 1306119098Sanholt 1307119098Sanholt dev_priv->page_flipping = 1; 1308119098Sanholt dev_priv->current_page = 0; 1309119098Sanholt dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; 1310119098Sanholt 1311119098Sanholt return 0; 1312119098Sanholt} 1313119098Sanholt 1314119098Sanholtint r128_do_cleanup_pageflip( drm_device_t *dev ) 1315119098Sanholt{ 1316119098Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 1317119098Sanholt DRM_DEBUG( "\n" ); 1318119098Sanholt 1319119098Sanholt R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); 1320119098Sanholt R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); 1321119098Sanholt 1322121447Sanholt if (dev_priv->current_page != 0) { 1323119098Sanholt r128_cce_dispatch_flip( dev ); 1324121447Sanholt COMMIT_RING(); 1325121447Sanholt } 1326119098Sanholt 1327119098Sanholt dev_priv->page_flipping = 0; 1328119098Sanholt return 0; 1329119098Sanholt} 1330119098Sanholt 1331119098Sanholt/* Swapping and flipping are different operations, need different ioctls. 1332119098Sanholt * They can & should be intermixed to support multiple 3d windows. 1333119098Sanholt */ 1334119098Sanholt 1335119098Sanholtint r128_cce_flip( DRM_IOCTL_ARGS ) 1336119098Sanholt{ 1337119098Sanholt DRM_DEVICE; 1338119098Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 1339119098Sanholt DRM_DEBUG( "%s\n", __FUNCTION__ ); 1340119098Sanholt 1341119098Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 1342119098Sanholt 1343119098Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 1344119098Sanholt 1345119098Sanholt if (!dev_priv->page_flipping) 1346119098Sanholt r128_do_init_pageflip( dev ); 1347119098Sanholt 1348119098Sanholt r128_cce_dispatch_flip( dev ); 1349119098Sanholt 1350121447Sanholt COMMIT_RING(); 1351119098Sanholt return 0; 1352119098Sanholt} 1353119098Sanholt 1354112015Sanholtint r128_cce_swap( DRM_IOCTL_ARGS ) 135595584Sanholt{ 1356112015Sanholt DRM_DEVICE; 135795584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 135895584Sanholt drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1359112015Sanholt DRM_DEBUG( "%s\n", __FUNCTION__ ); 136095584Sanholt 1361113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 136295584Sanholt 136395584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 136495584Sanholt 136595584Sanholt if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) 136695584Sanholt sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; 136795584Sanholt 1368119098Sanholt r128_cce_dispatch_swap( dev ); 1369119098Sanholt dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | 1370119098Sanholt R128_UPLOAD_MASKS); 137195584Sanholt 1372121447Sanholt COMMIT_RING(); 137395584Sanholt return 0; 137495584Sanholt} 137595584Sanholt 1376112015Sanholtint r128_cce_vertex( DRM_IOCTL_ARGS ) 137795584Sanholt{ 1378112015Sanholt DRM_DEVICE; 137995584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 138095584Sanholt drm_device_dma_t *dma = dev->dma; 138195584Sanholt drm_buf_t *buf; 138295584Sanholt drm_r128_buf_priv_t *buf_priv; 138395584Sanholt drm_r128_vertex_t vertex; 138495584Sanholt 1385113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 138695584Sanholt 138795584Sanholt if ( !dev_priv ) { 1388112015Sanholt DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1389112015Sanholt return DRM_ERR(EINVAL); 139095584Sanholt } 139195584Sanholt 1392112015Sanholt DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t *) data, 139395584Sanholt sizeof(vertex) ); 139495584Sanholt 1395112015Sanholt DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", 1396112015Sanholt DRM_CURRENTPID, 139795584Sanholt vertex.idx, vertex.count, vertex.discard ); 139895584Sanholt 139995584Sanholt if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { 140095584Sanholt DRM_ERROR( "buffer index %d (of %d max)\n", 140195584Sanholt vertex.idx, dma->buf_count - 1 ); 1402112015Sanholt return DRM_ERR(EINVAL); 140395584Sanholt } 140495584Sanholt if ( vertex.prim < 0 || 140595584Sanholt vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { 140695584Sanholt DRM_ERROR( "buffer prim %d\n", vertex.prim ); 1407112015Sanholt return DRM_ERR(EINVAL); 140895584Sanholt } 140995584Sanholt 141095584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 141195584Sanholt VB_AGE_TEST_WITH_RETURN( dev_priv ); 141295584Sanholt 141395584Sanholt buf = dma->buflist[vertex.idx]; 141495584Sanholt buf_priv = buf->dev_private; 141595584Sanholt 1416113995Sanholt if ( buf->filp != filp ) { 1417113995Sanholt DRM_ERROR( "process %d using buffer owned by %p\n", 1418113995Sanholt DRM_CURRENTPID, buf->filp ); 1419112015Sanholt return DRM_ERR(EINVAL); 142095584Sanholt } 142195584Sanholt if ( buf->pending ) { 142295584Sanholt DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); 1423112015Sanholt return DRM_ERR(EINVAL); 142495584Sanholt } 142595584Sanholt 142695584Sanholt buf->used = vertex.count; 142795584Sanholt buf_priv->prim = vertex.prim; 142895584Sanholt buf_priv->discard = vertex.discard; 142995584Sanholt 143095584Sanholt r128_cce_dispatch_vertex( dev, buf ); 143195584Sanholt 1432121447Sanholt COMMIT_RING(); 143395584Sanholt return 0; 143495584Sanholt} 143595584Sanholt 1436112015Sanholtint r128_cce_indices( DRM_IOCTL_ARGS ) 143795584Sanholt{ 1438112015Sanholt DRM_DEVICE; 143995584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 144095584Sanholt drm_device_dma_t *dma = dev->dma; 144195584Sanholt drm_buf_t *buf; 144295584Sanholt drm_r128_buf_priv_t *buf_priv; 144395584Sanholt drm_r128_indices_t elts; 144495584Sanholt int count; 144595584Sanholt 1446113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 144795584Sanholt 144895584Sanholt if ( !dev_priv ) { 1449112015Sanholt DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1450112015Sanholt return DRM_ERR(EINVAL); 145195584Sanholt } 145295584Sanholt 1453112015Sanholt DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t *) data, 145495584Sanholt sizeof(elts) ); 145595584Sanholt 1456112015Sanholt DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, 145795584Sanholt elts.idx, elts.start, elts.end, elts.discard ); 145895584Sanholt 145995584Sanholt if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { 146095584Sanholt DRM_ERROR( "buffer index %d (of %d max)\n", 146195584Sanholt elts.idx, dma->buf_count - 1 ); 1462112015Sanholt return DRM_ERR(EINVAL); 146395584Sanholt } 146495584Sanholt if ( elts.prim < 0 || 146595584Sanholt elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { 146695584Sanholt DRM_ERROR( "buffer prim %d\n", elts.prim ); 1467112015Sanholt return DRM_ERR(EINVAL); 146895584Sanholt } 146995584Sanholt 147095584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 147195584Sanholt VB_AGE_TEST_WITH_RETURN( dev_priv ); 147295584Sanholt 147395584Sanholt buf = dma->buflist[elts.idx]; 147495584Sanholt buf_priv = buf->dev_private; 147595584Sanholt 1476113995Sanholt if ( buf->filp != filp ) { 1477113995Sanholt DRM_ERROR( "process %d using buffer owned by %p\n", 1478113995Sanholt DRM_CURRENTPID, buf->filp ); 1479112015Sanholt return DRM_ERR(EINVAL); 148095584Sanholt } 148195584Sanholt if ( buf->pending ) { 148295584Sanholt DRM_ERROR( "sending pending buffer %d\n", elts.idx ); 1483112015Sanholt return DRM_ERR(EINVAL); 148495584Sanholt } 148595584Sanholt 148695584Sanholt count = (elts.end - elts.start) / sizeof(u16); 148795584Sanholt elts.start -= R128_INDEX_PRIM_OFFSET; 148895584Sanholt 148995584Sanholt if ( elts.start & 0x7 ) { 149095584Sanholt DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); 1491112015Sanholt return DRM_ERR(EINVAL); 149295584Sanholt } 149395584Sanholt if ( elts.start < buf->used ) { 149495584Sanholt DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); 1495112015Sanholt return DRM_ERR(EINVAL); 149695584Sanholt } 149795584Sanholt 149895584Sanholt buf->used = elts.end; 149995584Sanholt buf_priv->prim = elts.prim; 150095584Sanholt buf_priv->discard = elts.discard; 150195584Sanholt 150295584Sanholt r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); 150395584Sanholt 1504121447Sanholt COMMIT_RING(); 150595584Sanholt return 0; 150695584Sanholt} 150795584Sanholt 1508112015Sanholtint r128_cce_blit( DRM_IOCTL_ARGS ) 150995584Sanholt{ 1510112015Sanholt DRM_DEVICE; 151195584Sanholt drm_device_dma_t *dma = dev->dma; 151295584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 151395584Sanholt drm_r128_blit_t blit; 1514121447Sanholt int ret; 151595584Sanholt 1516113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 151795584Sanholt 1518112015Sanholt DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data, 151995584Sanholt sizeof(blit) ); 152095584Sanholt 1521112015Sanholt DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx ); 152295584Sanholt 152395584Sanholt if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { 152495584Sanholt DRM_ERROR( "buffer index %d (of %d max)\n", 152595584Sanholt blit.idx, dma->buf_count - 1 ); 1526112015Sanholt return DRM_ERR(EINVAL); 152795584Sanholt } 152895584Sanholt 152995584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 153095584Sanholt VB_AGE_TEST_WITH_RETURN( dev_priv ); 153195584Sanholt 1532121447Sanholt ret = r128_cce_dispatch_blit( filp, dev, &blit ); 1533121447Sanholt 1534121447Sanholt COMMIT_RING(); 1535121447Sanholt return ret; 153695584Sanholt} 153795584Sanholt 1538112015Sanholtint r128_cce_depth( DRM_IOCTL_ARGS ) 153995584Sanholt{ 1540112015Sanholt DRM_DEVICE; 154195584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 154295584Sanholt drm_r128_depth_t depth; 1543121447Sanholt int ret; 154495584Sanholt 1545113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 154695584Sanholt 1547112015Sanholt DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data, 154895584Sanholt sizeof(depth) ); 154995584Sanholt 155095584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 155195584Sanholt 1552121447Sanholt ret = DRM_ERR(EINVAL); 155395584Sanholt switch ( depth.func ) { 155495584Sanholt case R128_WRITE_SPAN: 1555121447Sanholt ret = r128_cce_dispatch_write_span( dev, &depth ); 155695584Sanholt case R128_WRITE_PIXELS: 1557121447Sanholt ret = r128_cce_dispatch_write_pixels( dev, &depth ); 155895584Sanholt case R128_READ_SPAN: 1559121447Sanholt ret = r128_cce_dispatch_read_span( dev, &depth ); 156095584Sanholt case R128_READ_PIXELS: 1561121447Sanholt ret = r128_cce_dispatch_read_pixels( dev, &depth ); 156295584Sanholt } 156395584Sanholt 1564121447Sanholt COMMIT_RING(); 1565121447Sanholt return ret; 156695584Sanholt} 156795584Sanholt 1568112015Sanholtint r128_cce_stipple( DRM_IOCTL_ARGS ) 156995584Sanholt{ 1570112015Sanholt DRM_DEVICE; 157195584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 157295584Sanholt drm_r128_stipple_t stipple; 157395584Sanholt u32 mask[32]; 157495584Sanholt 1575113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 157695584Sanholt 1577112015Sanholt DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data, 157895584Sanholt sizeof(stipple) ); 157995584Sanholt 1580112015Sanholt if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 158195584Sanholt 32 * sizeof(u32) ) ) 1582112015Sanholt return DRM_ERR( EFAULT ); 158395584Sanholt 158495584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 158595584Sanholt 158695584Sanholt r128_cce_dispatch_stipple( dev, mask ); 158795584Sanholt 1588121447Sanholt COMMIT_RING(); 158995584Sanholt return 0; 159095584Sanholt} 159195584Sanholt 1592112015Sanholtint r128_cce_indirect( DRM_IOCTL_ARGS ) 159395584Sanholt{ 1594112015Sanholt DRM_DEVICE; 159595584Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 159695584Sanholt drm_device_dma_t *dma = dev->dma; 159795584Sanholt drm_buf_t *buf; 159895584Sanholt drm_r128_buf_priv_t *buf_priv; 159995584Sanholt drm_r128_indirect_t indirect; 160095584Sanholt#if 0 160195584Sanholt RING_LOCALS; 160295584Sanholt#endif 160395584Sanholt 1604113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 160595584Sanholt 160695584Sanholt if ( !dev_priv ) { 1607112015Sanholt DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1608112015Sanholt return DRM_ERR(EINVAL); 160995584Sanholt } 161095584Sanholt 1611112015Sanholt DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t *) data, 161295584Sanholt sizeof(indirect) ); 161395584Sanholt 161495584Sanholt DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", 161595584Sanholt indirect.idx, indirect.start, 161695584Sanholt indirect.end, indirect.discard ); 161795584Sanholt 161895584Sanholt if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { 161995584Sanholt DRM_ERROR( "buffer index %d (of %d max)\n", 162095584Sanholt indirect.idx, dma->buf_count - 1 ); 1621112015Sanholt return DRM_ERR(EINVAL); 162295584Sanholt } 162395584Sanholt 162495584Sanholt buf = dma->buflist[indirect.idx]; 162595584Sanholt buf_priv = buf->dev_private; 162695584Sanholt 1627113995Sanholt if ( buf->filp != filp ) { 1628113995Sanholt DRM_ERROR( "process %d using buffer owned by %p\n", 1629113995Sanholt DRM_CURRENTPID, buf->filp ); 1630112015Sanholt return DRM_ERR(EINVAL); 163195584Sanholt } 163295584Sanholt if ( buf->pending ) { 163395584Sanholt DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); 1634112015Sanholt return DRM_ERR(EINVAL); 163595584Sanholt } 163695584Sanholt 163795584Sanholt if ( indirect.start < buf->used ) { 163895584Sanholt DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", 163995584Sanholt indirect.start, buf->used ); 1640112015Sanholt return DRM_ERR(EINVAL); 164195584Sanholt } 164295584Sanholt 164395584Sanholt RING_SPACE_TEST_WITH_RETURN( dev_priv ); 164495584Sanholt VB_AGE_TEST_WITH_RETURN( dev_priv ); 164595584Sanholt 164695584Sanholt buf->used = indirect.end; 164795584Sanholt buf_priv->discard = indirect.discard; 164895584Sanholt 164995584Sanholt#if 0 165095584Sanholt /* Wait for the 3D stream to idle before the indirect buffer 165195584Sanholt * containing 2D acceleration commands is processed. 165295584Sanholt */ 165395584Sanholt BEGIN_RING( 2 ); 165495584Sanholt RADEON_WAIT_UNTIL_3D_IDLE(); 165595584Sanholt ADVANCE_RING(); 165695584Sanholt#endif 165795584Sanholt 165895584Sanholt /* Dispatch the indirect buffer full of commands from the 165995584Sanholt * X server. This is insecure and is thus only available to 166095584Sanholt * privileged clients. 166195584Sanholt */ 166295584Sanholt r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); 166395584Sanholt 1664121447Sanholt COMMIT_RING(); 166595584Sanholt return 0; 166695584Sanholt} 1667112015Sanholt 1668112015Sanholtint r128_getparam( DRM_IOCTL_ARGS ) 1669112015Sanholt{ 1670112015Sanholt DRM_DEVICE; 1671112015Sanholt drm_r128_private_t *dev_priv = dev->dev_private; 1672112015Sanholt drm_r128_getparam_t param; 1673112015Sanholt int value; 1674112015Sanholt 1675112015Sanholt if ( !dev_priv ) { 1676112015Sanholt DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 1677112015Sanholt return DRM_ERR(EINVAL); 1678112015Sanholt } 1679112015Sanholt 1680112015Sanholt DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t *)data, 1681112015Sanholt sizeof(param) ); 1682112015Sanholt 1683112015Sanholt DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); 1684112015Sanholt 1685112015Sanholt switch( param.param ) { 1686112015Sanholt case R128_PARAM_IRQ_NR: 1687112015Sanholt value = dev->irq; 1688112015Sanholt break; 1689112015Sanholt default: 1690112015Sanholt return DRM_ERR(EINVAL); 1691112015Sanholt } 1692112015Sanholt 1693112015Sanholt if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { 1694112015Sanholt DRM_ERROR( "copy_to_user\n" ); 1695112015Sanholt return DRM_ERR(EFAULT); 1696112015Sanholt } 1697112015Sanholt 1698112015Sanholt return 0; 1699112015Sanholt} 1700