18c2ecf20Sopenharmony_ci/* r128_state.c -- State support for r128 -*- linux-c -*- 28c2ecf20Sopenharmony_ci * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com 38c2ecf20Sopenharmony_ci */ 48c2ecf20Sopenharmony_ci/* 58c2ecf20Sopenharmony_ci * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 68c2ecf20Sopenharmony_ci * All Rights Reserved. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 98c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 108c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 118c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 128c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 138c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the next 168c2ecf20Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 178c2ecf20Sopenharmony_ci * Software. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 208c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 218c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 228c2ecf20Sopenharmony_ci * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 238c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 248c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 258c2ecf20Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * Authors: 288c2ecf20Sopenharmony_ci * Gareth Hughes <gareth@valinux.com> 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include <linux/pci.h> 328c2ecf20Sopenharmony_ci#include <linux/slab.h> 338c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <drm/drm_device.h> 368c2ecf20Sopenharmony_ci#include <drm/drm_file.h> 378c2ecf20Sopenharmony_ci#include <drm/drm_print.h> 388c2ecf20Sopenharmony_ci#include <drm/r128_drm.h> 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#include "r128_drv.h" 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* ================================================================ 438c2ecf20Sopenharmony_ci * CCE hardware state programming functions 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic void r128_emit_clip_rects(drm_r128_private_t *dev_priv, 478c2ecf20Sopenharmony_ci struct drm_clip_rect *boxes, int count) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci u32 aux_sc_cntl = 0x00000000; 508c2ecf20Sopenharmony_ci RING_LOCALS; 518c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci BEGIN_RING((count < 3 ? count : 3) * 5 + 2); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci if (count >= 1) { 568c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3)); 578c2ecf20Sopenharmony_ci OUT_RING(boxes[0].x1); 588c2ecf20Sopenharmony_ci OUT_RING(boxes[0].x2 - 1); 598c2ecf20Sopenharmony_ci OUT_RING(boxes[0].y1); 608c2ecf20Sopenharmony_ci OUT_RING(boxes[0].y2 - 1); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); 638c2ecf20Sopenharmony_ci } 648c2ecf20Sopenharmony_ci if (count >= 2) { 658c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3)); 668c2ecf20Sopenharmony_ci OUT_RING(boxes[1].x1); 678c2ecf20Sopenharmony_ci OUT_RING(boxes[1].x2 - 1); 688c2ecf20Sopenharmony_ci OUT_RING(boxes[1].y1); 698c2ecf20Sopenharmony_ci OUT_RING(boxes[1].y2 - 1); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci if (count >= 3) { 748c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3)); 758c2ecf20Sopenharmony_ci OUT_RING(boxes[2].x1); 768c2ecf20Sopenharmony_ci OUT_RING(boxes[2].x2 - 1); 778c2ecf20Sopenharmony_ci OUT_RING(boxes[2].y1); 788c2ecf20Sopenharmony_ci OUT_RING(boxes[2].y2 - 1); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0)); 848c2ecf20Sopenharmony_ci OUT_RING(aux_sc_cntl); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci ADVANCE_RING(); 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_core(drm_r128_private_t *dev_priv) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 928c2ecf20Sopenharmony_ci drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 938c2ecf20Sopenharmony_ci RING_LOCALS; 948c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci BEGIN_RING(2); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0)); 998c2ecf20Sopenharmony_ci OUT_RING(ctx->scale_3d_cntl); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci ADVANCE_RING(); 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_context(drm_r128_private_t *dev_priv) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1078c2ecf20Sopenharmony_ci drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 1088c2ecf20Sopenharmony_ci RING_LOCALS; 1098c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci BEGIN_RING(13); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11)); 1148c2ecf20Sopenharmony_ci OUT_RING(ctx->dst_pitch_offset_c); 1158c2ecf20Sopenharmony_ci OUT_RING(ctx->dp_gui_master_cntl_c); 1168c2ecf20Sopenharmony_ci OUT_RING(ctx->sc_top_left_c); 1178c2ecf20Sopenharmony_ci OUT_RING(ctx->sc_bottom_right_c); 1188c2ecf20Sopenharmony_ci OUT_RING(ctx->z_offset_c); 1198c2ecf20Sopenharmony_ci OUT_RING(ctx->z_pitch_c); 1208c2ecf20Sopenharmony_ci OUT_RING(ctx->z_sten_cntl_c); 1218c2ecf20Sopenharmony_ci OUT_RING(ctx->tex_cntl_c); 1228c2ecf20Sopenharmony_ci OUT_RING(ctx->misc_3d_state_cntl_reg); 1238c2ecf20Sopenharmony_ci OUT_RING(ctx->texture_clr_cmp_clr_c); 1248c2ecf20Sopenharmony_ci OUT_RING(ctx->texture_clr_cmp_msk_c); 1258c2ecf20Sopenharmony_ci OUT_RING(ctx->fog_color_c); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci ADVANCE_RING(); 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv) 1318c2ecf20Sopenharmony_ci{ 1328c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1338c2ecf20Sopenharmony_ci drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 1348c2ecf20Sopenharmony_ci RING_LOCALS; 1358c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci BEGIN_RING(3); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP)); 1408c2ecf20Sopenharmony_ci OUT_RING(ctx->setup_cntl); 1418c2ecf20Sopenharmony_ci OUT_RING(ctx->pm4_vc_fpu_setup); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci ADVANCE_RING(); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1498c2ecf20Sopenharmony_ci drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 1508c2ecf20Sopenharmony_ci RING_LOCALS; 1518c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci BEGIN_RING(5); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); 1568c2ecf20Sopenharmony_ci OUT_RING(ctx->dp_write_mask); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1)); 1598c2ecf20Sopenharmony_ci OUT_RING(ctx->sten_ref_mask_c); 1608c2ecf20Sopenharmony_ci OUT_RING(ctx->plane_3d_mask_c); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci ADVANCE_RING(); 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_window(drm_r128_private_t *dev_priv) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1688c2ecf20Sopenharmony_ci drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 1698c2ecf20Sopenharmony_ci RING_LOCALS; 1708c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci BEGIN_RING(2); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0)); 1758c2ecf20Sopenharmony_ci OUT_RING(ctx->window_xy_offset); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci ADVANCE_RING(); 1788c2ecf20Sopenharmony_ci} 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1838c2ecf20Sopenharmony_ci drm_r128_context_regs_t *ctx = &sarea_priv->context_state; 1848c2ecf20Sopenharmony_ci drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; 1858c2ecf20Sopenharmony_ci int i; 1868c2ecf20Sopenharmony_ci RING_LOCALS; 1878c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 1928c2ecf20Sopenharmony_ci 2 + R128_MAX_TEXTURE_LEVELS)); 1938c2ecf20Sopenharmony_ci OUT_RING(tex->tex_cntl); 1948c2ecf20Sopenharmony_ci OUT_RING(tex->tex_combine_cntl); 1958c2ecf20Sopenharmony_ci OUT_RING(ctx->tex_size_pitch_c); 1968c2ecf20Sopenharmony_ci for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) 1978c2ecf20Sopenharmony_ci OUT_RING(tex->tex_offset[i]); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); 2008c2ecf20Sopenharmony_ci OUT_RING(ctx->constant_color_c); 2018c2ecf20Sopenharmony_ci OUT_RING(tex->tex_border_color); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci ADVANCE_RING(); 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 2098c2ecf20Sopenharmony_ci drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; 2108c2ecf20Sopenharmony_ci int i; 2118c2ecf20Sopenharmony_ci RING_LOCALS; 2128c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); 2178c2ecf20Sopenharmony_ci OUT_RING(tex->tex_cntl); 2188c2ecf20Sopenharmony_ci OUT_RING(tex->tex_combine_cntl); 2198c2ecf20Sopenharmony_ci for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) 2208c2ecf20Sopenharmony_ci OUT_RING(tex->tex_offset[i]); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); 2238c2ecf20Sopenharmony_ci OUT_RING(tex->tex_border_color); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci ADVANCE_RING(); 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistatic void r128_emit_state(drm_r128_private_t *dev_priv) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 2318c2ecf20Sopenharmony_ci unsigned int dirty = sarea_priv->dirty; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci DRM_DEBUG("dirty=0x%08x\n", dirty); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_CORE) { 2368c2ecf20Sopenharmony_ci r128_emit_core(dev_priv); 2378c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_CORE; 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_CONTEXT) { 2418c2ecf20Sopenharmony_ci r128_emit_context(dev_priv); 2428c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_SETUP) { 2468c2ecf20Sopenharmony_ci r128_emit_setup(dev_priv); 2478c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_SETUP; 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_MASKS) { 2518c2ecf20Sopenharmony_ci r128_emit_masks(dev_priv); 2528c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_MASKS; 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_WINDOW) { 2568c2ecf20Sopenharmony_ci r128_emit_window(dev_priv); 2578c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_TEX0) { 2618c2ecf20Sopenharmony_ci r128_emit_tex0(dev_priv); 2628c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_TEX0; 2638c2ecf20Sopenharmony_ci } 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (dirty & R128_UPLOAD_TEX1) { 2668c2ecf20Sopenharmony_ci r128_emit_tex1(dev_priv); 2678c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_TEX1; 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci /* Turn off the texture cache flushing */ 2718c2ecf20Sopenharmony_ci sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci#if R128_PERFORMANCE_BOXES 2778c2ecf20Sopenharmony_ci/* ================================================================ 2788c2ecf20Sopenharmony_ci * Performance monitoring functions 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_cistatic void r128_clear_box(drm_r128_private_t *dev_priv, 2828c2ecf20Sopenharmony_ci int x, int y, int w, int h, int r, int g, int b) 2838c2ecf20Sopenharmony_ci{ 2848c2ecf20Sopenharmony_ci u32 pitch, offset; 2858c2ecf20Sopenharmony_ci u32 fb_bpp, color; 2868c2ecf20Sopenharmony_ci RING_LOCALS; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci switch (dev_priv->fb_bpp) { 2898c2ecf20Sopenharmony_ci case 16: 2908c2ecf20Sopenharmony_ci fb_bpp = R128_GMC_DST_16BPP; 2918c2ecf20Sopenharmony_ci color = (((r & 0xf8) << 8) | 2928c2ecf20Sopenharmony_ci ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); 2938c2ecf20Sopenharmony_ci break; 2948c2ecf20Sopenharmony_ci case 24: 2958c2ecf20Sopenharmony_ci fb_bpp = R128_GMC_DST_24BPP; 2968c2ecf20Sopenharmony_ci color = ((r << 16) | (g << 8) | b); 2978c2ecf20Sopenharmony_ci break; 2988c2ecf20Sopenharmony_ci case 32: 2998c2ecf20Sopenharmony_ci fb_bpp = R128_GMC_DST_32BPP; 3008c2ecf20Sopenharmony_ci color = (((0xff) << 24) | (r << 16) | (g << 8) | b); 3018c2ecf20Sopenharmony_ci break; 3028c2ecf20Sopenharmony_ci default: 3038c2ecf20Sopenharmony_ci return; 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci offset = dev_priv->back_offset; 3078c2ecf20Sopenharmony_ci pitch = dev_priv->back_pitch >> 3; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci BEGIN_RING(6); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 3128c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 3138c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 3148c2ecf20Sopenharmony_ci fb_bpp | 3158c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 3168c2ecf20Sopenharmony_ci R128_ROP3_P | 3178c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci OUT_RING((pitch << 21) | (offset >> 5)); 3208c2ecf20Sopenharmony_ci OUT_RING(color); 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 3238c2ecf20Sopenharmony_ci OUT_RING((w << 16) | h); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci ADVANCE_RING(); 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_cistatic void r128_cce_performance_boxes(drm_r128_private_t *dev_priv) 3298c2ecf20Sopenharmony_ci{ 3308c2ecf20Sopenharmony_ci if (atomic_read(&dev_priv->idle_count) == 0) 3318c2ecf20Sopenharmony_ci r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); 3328c2ecf20Sopenharmony_ci else 3338c2ecf20Sopenharmony_ci atomic_set(&dev_priv->idle_count, 0); 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci#endif 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci/* ================================================================ 3398c2ecf20Sopenharmony_ci * CCE command dispatch functions 3408c2ecf20Sopenharmony_ci */ 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_cistatic void r128_print_dirty(const char *msg, unsigned int flags) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", 3458c2ecf20Sopenharmony_ci msg, 3468c2ecf20Sopenharmony_ci flags, 3478c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_CORE) ? "core, " : "", 3488c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", 3498c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_SETUP) ? "setup, " : "", 3508c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", 3518c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", 3528c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_MASKS) ? "masks, " : "", 3538c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_WINDOW) ? "window, " : "", 3548c2ecf20Sopenharmony_ci (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", 3558c2ecf20Sopenharmony_ci (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_clear(struct drm_device *dev, 3598c2ecf20Sopenharmony_ci drm_r128_clear_t *clear) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 3628c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 3638c2ecf20Sopenharmony_ci int nbox = sarea_priv->nbox; 3648c2ecf20Sopenharmony_ci struct drm_clip_rect *pbox = sarea_priv->boxes; 3658c2ecf20Sopenharmony_ci unsigned int flags = clear->flags; 3668c2ecf20Sopenharmony_ci int i; 3678c2ecf20Sopenharmony_ci RING_LOCALS; 3688c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci if (dev_priv->page_flipping && dev_priv->current_page == 1) { 3718c2ecf20Sopenharmony_ci unsigned int tmp = flags; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci flags &= ~(R128_FRONT | R128_BACK); 3748c2ecf20Sopenharmony_ci if (tmp & R128_FRONT) 3758c2ecf20Sopenharmony_ci flags |= R128_BACK; 3768c2ecf20Sopenharmony_ci if (tmp & R128_BACK) 3778c2ecf20Sopenharmony_ci flags |= R128_FRONT; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci for (i = 0; i < nbox; i++) { 3818c2ecf20Sopenharmony_ci int x = pbox[i].x1; 3828c2ecf20Sopenharmony_ci int y = pbox[i].y1; 3838c2ecf20Sopenharmony_ci int w = pbox[i].x2 - x; 3848c2ecf20Sopenharmony_ci int h = pbox[i].y2 - y; 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", 3878c2ecf20Sopenharmony_ci pbox[i].x1, pbox[i].y1, pbox[i].x2, 3888c2ecf20Sopenharmony_ci pbox[i].y2, flags); 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci if (flags & (R128_FRONT | R128_BACK)) { 3918c2ecf20Sopenharmony_ci BEGIN_RING(2); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); 3948c2ecf20Sopenharmony_ci OUT_RING(clear->color_mask); 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci ADVANCE_RING(); 3978c2ecf20Sopenharmony_ci } 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci if (flags & R128_FRONT) { 4008c2ecf20Sopenharmony_ci BEGIN_RING(6); 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 4038c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 4048c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 4058c2ecf20Sopenharmony_ci (dev_priv->color_fmt << 8) | 4068c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 4078c2ecf20Sopenharmony_ci R128_ROP3_P | 4088c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 4098c2ecf20Sopenharmony_ci R128_GMC_AUX_CLIP_DIS); 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci OUT_RING(dev_priv->front_pitch_offset_c); 4128c2ecf20Sopenharmony_ci OUT_RING(clear->clear_color); 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 4158c2ecf20Sopenharmony_ci OUT_RING((w << 16) | h); 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci ADVANCE_RING(); 4188c2ecf20Sopenharmony_ci } 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if (flags & R128_BACK) { 4218c2ecf20Sopenharmony_ci BEGIN_RING(6); 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 4248c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 4258c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 4268c2ecf20Sopenharmony_ci (dev_priv->color_fmt << 8) | 4278c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 4288c2ecf20Sopenharmony_ci R128_ROP3_P | 4298c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 4308c2ecf20Sopenharmony_ci R128_GMC_AUX_CLIP_DIS); 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci OUT_RING(dev_priv->back_pitch_offset_c); 4338c2ecf20Sopenharmony_ci OUT_RING(clear->clear_color); 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 4368c2ecf20Sopenharmony_ci OUT_RING((w << 16) | h); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci ADVANCE_RING(); 4398c2ecf20Sopenharmony_ci } 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci if (flags & R128_DEPTH) { 4428c2ecf20Sopenharmony_ci BEGIN_RING(6); 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 4458c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 4468c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 4478c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 4488c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 4498c2ecf20Sopenharmony_ci R128_ROP3_P | 4508c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 4518c2ecf20Sopenharmony_ci R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 4548c2ecf20Sopenharmony_ci OUT_RING(clear->clear_depth); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 4578c2ecf20Sopenharmony_ci OUT_RING((w << 16) | h); 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci ADVANCE_RING(); 4608c2ecf20Sopenharmony_ci } 4618c2ecf20Sopenharmony_ci } 4628c2ecf20Sopenharmony_ci} 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_swap(struct drm_device *dev) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 4678c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 4688c2ecf20Sopenharmony_ci int nbox = sarea_priv->nbox; 4698c2ecf20Sopenharmony_ci struct drm_clip_rect *pbox = sarea_priv->boxes; 4708c2ecf20Sopenharmony_ci int i; 4718c2ecf20Sopenharmony_ci RING_LOCALS; 4728c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci#if R128_PERFORMANCE_BOXES 4758c2ecf20Sopenharmony_ci /* Do some trivial performance monitoring... 4768c2ecf20Sopenharmony_ci */ 4778c2ecf20Sopenharmony_ci r128_cce_performance_boxes(dev_priv); 4788c2ecf20Sopenharmony_ci#endif 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci for (i = 0; i < nbox; i++) { 4818c2ecf20Sopenharmony_ci int x = pbox[i].x1; 4828c2ecf20Sopenharmony_ci int y = pbox[i].y1; 4838c2ecf20Sopenharmony_ci int w = pbox[i].x2 - x; 4848c2ecf20Sopenharmony_ci int h = pbox[i].y2 - y; 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci BEGIN_RING(7); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); 4898c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | 4908c2ecf20Sopenharmony_ci R128_GMC_DST_PITCH_OFFSET_CNTL | 4918c2ecf20Sopenharmony_ci R128_GMC_BRUSH_NONE | 4928c2ecf20Sopenharmony_ci (dev_priv->color_fmt << 8) | 4938c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 4948c2ecf20Sopenharmony_ci R128_ROP3_S | 4958c2ecf20Sopenharmony_ci R128_DP_SRC_SOURCE_MEMORY | 4968c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 4978c2ecf20Sopenharmony_ci R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci /* Make this work even if front & back are flipped: 5008c2ecf20Sopenharmony_ci */ 5018c2ecf20Sopenharmony_ci if (dev_priv->current_page == 0) { 5028c2ecf20Sopenharmony_ci OUT_RING(dev_priv->back_pitch_offset_c); 5038c2ecf20Sopenharmony_ci OUT_RING(dev_priv->front_pitch_offset_c); 5048c2ecf20Sopenharmony_ci } else { 5058c2ecf20Sopenharmony_ci OUT_RING(dev_priv->front_pitch_offset_c); 5068c2ecf20Sopenharmony_ci OUT_RING(dev_priv->back_pitch_offset_c); 5078c2ecf20Sopenharmony_ci } 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 5108c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 5118c2ecf20Sopenharmony_ci OUT_RING((w << 16) | h); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci ADVANCE_RING(); 5148c2ecf20Sopenharmony_ci } 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci /* Increment the frame counter. The client-side 3D driver must 5178c2ecf20Sopenharmony_ci * throttle the framerate by waiting for this value before 5188c2ecf20Sopenharmony_ci * performing the swapbuffer ioctl. 5198c2ecf20Sopenharmony_ci */ 5208c2ecf20Sopenharmony_ci dev_priv->sarea_priv->last_frame++; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci BEGIN_RING(2); 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); 5258c2ecf20Sopenharmony_ci OUT_RING(dev_priv->sarea_priv->last_frame); 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci ADVANCE_RING(); 5288c2ecf20Sopenharmony_ci} 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_flip(struct drm_device *dev) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 5338c2ecf20Sopenharmony_ci RING_LOCALS; 5348c2ecf20Sopenharmony_ci DRM_DEBUG("page=%d pfCurrentPage=%d\n", 5358c2ecf20Sopenharmony_ci dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci#if R128_PERFORMANCE_BOXES 5388c2ecf20Sopenharmony_ci /* Do some trivial performance monitoring... 5398c2ecf20Sopenharmony_ci */ 5408c2ecf20Sopenharmony_ci r128_cce_performance_boxes(dev_priv); 5418c2ecf20Sopenharmony_ci#endif 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci BEGIN_RING(4); 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci R128_WAIT_UNTIL_PAGE_FLIPPED(); 5468c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci if (dev_priv->current_page == 0) 5498c2ecf20Sopenharmony_ci OUT_RING(dev_priv->back_offset); 5508c2ecf20Sopenharmony_ci else 5518c2ecf20Sopenharmony_ci OUT_RING(dev_priv->front_offset); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci ADVANCE_RING(); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci /* Increment the frame counter. The client-side 3D driver must 5568c2ecf20Sopenharmony_ci * throttle the framerate by waiting for this value before 5578c2ecf20Sopenharmony_ci * performing the swapbuffer ioctl. 5588c2ecf20Sopenharmony_ci */ 5598c2ecf20Sopenharmony_ci dev_priv->sarea_priv->last_frame++; 5608c2ecf20Sopenharmony_ci dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = 5618c2ecf20Sopenharmony_ci 1 - dev_priv->current_page; 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci BEGIN_RING(2); 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); 5668c2ecf20Sopenharmony_ci OUT_RING(dev_priv->sarea_priv->last_frame); 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci ADVANCE_RING(); 5698c2ecf20Sopenharmony_ci} 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) 5728c2ecf20Sopenharmony_ci{ 5738c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 5748c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv = buf->dev_private; 5758c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 5768c2ecf20Sopenharmony_ci int format = sarea_priv->vc_format; 5778c2ecf20Sopenharmony_ci int offset = buf->bus_address; 5788c2ecf20Sopenharmony_ci int size = buf->used; 5798c2ecf20Sopenharmony_ci int prim = buf_priv->prim; 5808c2ecf20Sopenharmony_ci int i = 0; 5818c2ecf20Sopenharmony_ci RING_LOCALS; 5828c2ecf20Sopenharmony_ci DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci if (0) 5858c2ecf20Sopenharmony_ci r128_print_dirty("dispatch_vertex", sarea_priv->dirty); 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci if (buf->used) { 5888c2ecf20Sopenharmony_ci buf_priv->dispatched = 1; 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) 5918c2ecf20Sopenharmony_ci r128_emit_state(dev_priv); 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci do { 5948c2ecf20Sopenharmony_ci /* Emit the next set of up to three cliprects */ 5958c2ecf20Sopenharmony_ci if (i < sarea_priv->nbox) { 5968c2ecf20Sopenharmony_ci r128_emit_clip_rects(dev_priv, 5978c2ecf20Sopenharmony_ci &sarea_priv->boxes[i], 5988c2ecf20Sopenharmony_ci sarea_priv->nbox - i); 5998c2ecf20Sopenharmony_ci } 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci /* Emit the vertex buffer rendering commands */ 6028c2ecf20Sopenharmony_ci BEGIN_RING(5); 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3)); 6058c2ecf20Sopenharmony_ci OUT_RING(offset); 6068c2ecf20Sopenharmony_ci OUT_RING(size); 6078c2ecf20Sopenharmony_ci OUT_RING(format); 6088c2ecf20Sopenharmony_ci OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | 6098c2ecf20Sopenharmony_ci (size << R128_CCE_VC_CNTL_NUM_SHIFT)); 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci ADVANCE_RING(); 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci i += 3; 6148c2ecf20Sopenharmony_ci } while (i < sarea_priv->nbox); 6158c2ecf20Sopenharmony_ci } 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci if (buf_priv->discard) { 6188c2ecf20Sopenharmony_ci buf_priv->age = dev_priv->sarea_priv->last_dispatch; 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci /* Emit the vertex buffer age */ 6218c2ecf20Sopenharmony_ci BEGIN_RING(2); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); 6248c2ecf20Sopenharmony_ci OUT_RING(buf_priv->age); 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci ADVANCE_RING(); 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci buf->pending = 1; 6298c2ecf20Sopenharmony_ci buf->used = 0; 6308c2ecf20Sopenharmony_ci /* FIXME: Check dispatched field */ 6318c2ecf20Sopenharmony_ci buf_priv->dispatched = 0; 6328c2ecf20Sopenharmony_ci } 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci dev_priv->sarea_priv->last_dispatch++; 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; 6378c2ecf20Sopenharmony_ci sarea_priv->nbox = 0; 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_indirect(struct drm_device *dev, 6418c2ecf20Sopenharmony_ci struct drm_buf *buf, int start, int end) 6428c2ecf20Sopenharmony_ci{ 6438c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 6448c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv = buf->dev_private; 6458c2ecf20Sopenharmony_ci RING_LOCALS; 6468c2ecf20Sopenharmony_ci DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci if (start != end) { 6498c2ecf20Sopenharmony_ci int offset = buf->bus_address + start; 6508c2ecf20Sopenharmony_ci int dwords = (end - start + 3) / sizeof(u32); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci /* Indirect buffer data must be an even number of 6538c2ecf20Sopenharmony_ci * dwords, so if we've been given an odd number we must 6548c2ecf20Sopenharmony_ci * pad the data with a Type-2 CCE packet. 6558c2ecf20Sopenharmony_ci */ 6568c2ecf20Sopenharmony_ci if (dwords & 1) { 6578c2ecf20Sopenharmony_ci u32 *data = (u32 *) 6588c2ecf20Sopenharmony_ci ((char *)dev->agp_buffer_map->handle 6598c2ecf20Sopenharmony_ci + buf->offset + start); 6608c2ecf20Sopenharmony_ci data[dwords++] = cpu_to_le32(R128_CCE_PACKET2); 6618c2ecf20Sopenharmony_ci } 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci buf_priv->dispatched = 1; 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci /* Fire off the indirect buffer */ 6668c2ecf20Sopenharmony_ci BEGIN_RING(3); 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1)); 6698c2ecf20Sopenharmony_ci OUT_RING(offset); 6708c2ecf20Sopenharmony_ci OUT_RING(dwords); 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci ADVANCE_RING(); 6738c2ecf20Sopenharmony_ci } 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci if (buf_priv->discard) { 6768c2ecf20Sopenharmony_ci buf_priv->age = dev_priv->sarea_priv->last_dispatch; 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci /* Emit the indirect buffer age */ 6798c2ecf20Sopenharmony_ci BEGIN_RING(2); 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); 6828c2ecf20Sopenharmony_ci OUT_RING(buf_priv->age); 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci ADVANCE_RING(); 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ci buf->pending = 1; 6878c2ecf20Sopenharmony_ci buf->used = 0; 6888c2ecf20Sopenharmony_ci /* FIXME: Check dispatched field */ 6898c2ecf20Sopenharmony_ci buf_priv->dispatched = 0; 6908c2ecf20Sopenharmony_ci } 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci dev_priv->sarea_priv->last_dispatch++; 6938c2ecf20Sopenharmony_ci} 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_indices(struct drm_device *dev, 6968c2ecf20Sopenharmony_ci struct drm_buf *buf, 6978c2ecf20Sopenharmony_ci int start, int end, int count) 6988c2ecf20Sopenharmony_ci{ 6998c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 7008c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv = buf->dev_private; 7018c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 7028c2ecf20Sopenharmony_ci int format = sarea_priv->vc_format; 7038c2ecf20Sopenharmony_ci int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset; 7048c2ecf20Sopenharmony_ci int prim = buf_priv->prim; 7058c2ecf20Sopenharmony_ci u32 *data; 7068c2ecf20Sopenharmony_ci int dwords; 7078c2ecf20Sopenharmony_ci int i = 0; 7088c2ecf20Sopenharmony_ci RING_LOCALS; 7098c2ecf20Sopenharmony_ci DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count); 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci if (0) 7128c2ecf20Sopenharmony_ci r128_print_dirty("dispatch_indices", sarea_priv->dirty); 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci if (start != end) { 7158c2ecf20Sopenharmony_ci buf_priv->dispatched = 1; 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) 7188c2ecf20Sopenharmony_ci r128_emit_state(dev_priv); 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci dwords = (end - start + 3) / sizeof(u32); 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci data = (u32 *) ((char *)dev->agp_buffer_map->handle 7238c2ecf20Sopenharmony_ci + buf->offset + start); 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 7268c2ecf20Sopenharmony_ci dwords - 2)); 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci data[1] = cpu_to_le32(offset); 7298c2ecf20Sopenharmony_ci data[2] = cpu_to_le32(R128_MAX_VB_VERTS); 7308c2ecf20Sopenharmony_ci data[3] = cpu_to_le32(format); 7318c2ecf20Sopenharmony_ci data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | 7328c2ecf20Sopenharmony_ci (count << 16))); 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci if (count & 0x1) { 7358c2ecf20Sopenharmony_ci#ifdef __LITTLE_ENDIAN 7368c2ecf20Sopenharmony_ci data[dwords - 1] &= 0x0000ffff; 7378c2ecf20Sopenharmony_ci#else 7388c2ecf20Sopenharmony_ci data[dwords - 1] &= 0xffff0000; 7398c2ecf20Sopenharmony_ci#endif 7408c2ecf20Sopenharmony_ci } 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci do { 7438c2ecf20Sopenharmony_ci /* Emit the next set of up to three cliprects */ 7448c2ecf20Sopenharmony_ci if (i < sarea_priv->nbox) { 7458c2ecf20Sopenharmony_ci r128_emit_clip_rects(dev_priv, 7468c2ecf20Sopenharmony_ci &sarea_priv->boxes[i], 7478c2ecf20Sopenharmony_ci sarea_priv->nbox - i); 7488c2ecf20Sopenharmony_ci } 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci r128_cce_dispatch_indirect(dev, buf, start, end); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci i += 3; 7538c2ecf20Sopenharmony_ci } while (i < sarea_priv->nbox); 7548c2ecf20Sopenharmony_ci } 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_ci if (buf_priv->discard) { 7578c2ecf20Sopenharmony_ci buf_priv->age = dev_priv->sarea_priv->last_dispatch; 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci /* Emit the vertex buffer age */ 7608c2ecf20Sopenharmony_ci BEGIN_RING(2); 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); 7638c2ecf20Sopenharmony_ci OUT_RING(buf_priv->age); 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci ADVANCE_RING(); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci buf->pending = 1; 7688c2ecf20Sopenharmony_ci /* FIXME: Check dispatched field */ 7698c2ecf20Sopenharmony_ci buf_priv->dispatched = 0; 7708c2ecf20Sopenharmony_ci } 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci dev_priv->sarea_priv->last_dispatch++; 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_ci sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; 7758c2ecf20Sopenharmony_ci sarea_priv->nbox = 0; 7768c2ecf20Sopenharmony_ci} 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_cistatic int r128_cce_dispatch_blit(struct drm_device *dev, 7798c2ecf20Sopenharmony_ci struct drm_file *file_priv, 7808c2ecf20Sopenharmony_ci drm_r128_blit_t *blit) 7818c2ecf20Sopenharmony_ci{ 7828c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 7838c2ecf20Sopenharmony_ci struct drm_device_dma *dma = dev->dma; 7848c2ecf20Sopenharmony_ci struct drm_buf *buf; 7858c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv; 7868c2ecf20Sopenharmony_ci u32 *data; 7878c2ecf20Sopenharmony_ci int dword_shift, dwords; 7888c2ecf20Sopenharmony_ci RING_LOCALS; 7898c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci /* The compiler won't optimize away a division by a variable, 7928c2ecf20Sopenharmony_ci * even if the only legal values are powers of two. Thus, we'll 7938c2ecf20Sopenharmony_ci * use a shift instead. 7948c2ecf20Sopenharmony_ci */ 7958c2ecf20Sopenharmony_ci switch (blit->format) { 7968c2ecf20Sopenharmony_ci case R128_DATATYPE_ARGB8888: 7978c2ecf20Sopenharmony_ci dword_shift = 0; 7988c2ecf20Sopenharmony_ci break; 7998c2ecf20Sopenharmony_ci case R128_DATATYPE_ARGB1555: 8008c2ecf20Sopenharmony_ci case R128_DATATYPE_RGB565: 8018c2ecf20Sopenharmony_ci case R128_DATATYPE_ARGB4444: 8028c2ecf20Sopenharmony_ci case R128_DATATYPE_YVYU422: 8038c2ecf20Sopenharmony_ci case R128_DATATYPE_VYUY422: 8048c2ecf20Sopenharmony_ci dword_shift = 1; 8058c2ecf20Sopenharmony_ci break; 8068c2ecf20Sopenharmony_ci case R128_DATATYPE_CI8: 8078c2ecf20Sopenharmony_ci case R128_DATATYPE_RGB8: 8088c2ecf20Sopenharmony_ci dword_shift = 2; 8098c2ecf20Sopenharmony_ci break; 8108c2ecf20Sopenharmony_ci default: 8118c2ecf20Sopenharmony_ci DRM_ERROR("invalid blit format %d\n", blit->format); 8128c2ecf20Sopenharmony_ci return -EINVAL; 8138c2ecf20Sopenharmony_ci } 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci /* Flush the pixel cache, and mark the contents as Read Invalid. 8168c2ecf20Sopenharmony_ci * This ensures no pixel data gets mixed up with the texture 8178c2ecf20Sopenharmony_ci * data from the host data blit, otherwise part of the texture 8188c2ecf20Sopenharmony_ci * image may be corrupted. 8198c2ecf20Sopenharmony_ci */ 8208c2ecf20Sopenharmony_ci BEGIN_RING(2); 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); 8238c2ecf20Sopenharmony_ci OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI); 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci ADVANCE_RING(); 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_ci /* Dispatch the indirect buffer. 8288c2ecf20Sopenharmony_ci */ 8298c2ecf20Sopenharmony_ci buf = dma->buflist[blit->idx]; 8308c2ecf20Sopenharmony_ci buf_priv = buf->dev_private; 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci if (buf->file_priv != file_priv) { 8338c2ecf20Sopenharmony_ci DRM_ERROR("process %d using buffer owned by %p\n", 8348c2ecf20Sopenharmony_ci task_pid_nr(current), buf->file_priv); 8358c2ecf20Sopenharmony_ci return -EINVAL; 8368c2ecf20Sopenharmony_ci } 8378c2ecf20Sopenharmony_ci if (buf->pending) { 8388c2ecf20Sopenharmony_ci DRM_ERROR("sending pending buffer %d\n", blit->idx); 8398c2ecf20Sopenharmony_ci return -EINVAL; 8408c2ecf20Sopenharmony_ci } 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci buf_priv->discard = 1; 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci dwords = (blit->width * blit->height) >> dword_shift; 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_ci data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6)); 8498c2ecf20Sopenharmony_ci data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL | 8508c2ecf20Sopenharmony_ci R128_GMC_BRUSH_NONE | 8518c2ecf20Sopenharmony_ci (blit->format << 8) | 8528c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 8538c2ecf20Sopenharmony_ci R128_ROP3_S | 8548c2ecf20Sopenharmony_ci R128_DP_SRC_SOURCE_HOST_DATA | 8558c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 8568c2ecf20Sopenharmony_ci R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS)); 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5)); 8598c2ecf20Sopenharmony_ci data[3] = cpu_to_le32(0xffffffff); 8608c2ecf20Sopenharmony_ci data[4] = cpu_to_le32(0xffffffff); 8618c2ecf20Sopenharmony_ci data[5] = cpu_to_le32((blit->y << 16) | blit->x); 8628c2ecf20Sopenharmony_ci data[6] = cpu_to_le32((blit->height << 16) | blit->width); 8638c2ecf20Sopenharmony_ci data[7] = cpu_to_le32(dwords); 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci buf->used = (dwords + 8) * sizeof(u32); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci r128_cce_dispatch_indirect(dev, buf, 0, buf->used); 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci /* Flush the pixel cache after the blit completes. This ensures 8708c2ecf20Sopenharmony_ci * the texture data is written out to memory before rendering 8718c2ecf20Sopenharmony_ci * continues. 8728c2ecf20Sopenharmony_ci */ 8738c2ecf20Sopenharmony_ci BEGIN_RING(2); 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); 8768c2ecf20Sopenharmony_ci OUT_RING(R128_PC_FLUSH_GUI); 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci ADVANCE_RING(); 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_ci return 0; 8818c2ecf20Sopenharmony_ci} 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_ci/* ================================================================ 8848c2ecf20Sopenharmony_ci * Tiled depth buffer management 8858c2ecf20Sopenharmony_ci * 8868c2ecf20Sopenharmony_ci * FIXME: These should all set the destination write mask for when we 8878c2ecf20Sopenharmony_ci * have hardware stencil support. 8888c2ecf20Sopenharmony_ci */ 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_cistatic int r128_cce_dispatch_write_span(struct drm_device *dev, 8918c2ecf20Sopenharmony_ci drm_r128_depth_t *depth) 8928c2ecf20Sopenharmony_ci{ 8938c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 8948c2ecf20Sopenharmony_ci int count, x, y; 8958c2ecf20Sopenharmony_ci u32 *buffer; 8968c2ecf20Sopenharmony_ci u8 *mask; 8978c2ecf20Sopenharmony_ci int i, buffer_size, mask_size; 8988c2ecf20Sopenharmony_ci RING_LOCALS; 8998c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci count = depth->n; 9028c2ecf20Sopenharmony_ci if (count > 4096 || count <= 0) 9038c2ecf20Sopenharmony_ci return -EMSGSIZE; 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci if (copy_from_user(&x, depth->x, sizeof(x))) 9068c2ecf20Sopenharmony_ci return -EFAULT; 9078c2ecf20Sopenharmony_ci if (copy_from_user(&y, depth->y, sizeof(y))) 9088c2ecf20Sopenharmony_ci return -EFAULT; 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci buffer_size = depth->n * sizeof(u32); 9118c2ecf20Sopenharmony_ci buffer = memdup_user(depth->buffer, buffer_size); 9128c2ecf20Sopenharmony_ci if (IS_ERR(buffer)) 9138c2ecf20Sopenharmony_ci return PTR_ERR(buffer); 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci mask_size = depth->n; 9168c2ecf20Sopenharmony_ci if (depth->mask) { 9178c2ecf20Sopenharmony_ci mask = memdup_user(depth->mask, mask_size); 9188c2ecf20Sopenharmony_ci if (IS_ERR(mask)) { 9198c2ecf20Sopenharmony_ci kfree(buffer); 9208c2ecf20Sopenharmony_ci return PTR_ERR(mask); 9218c2ecf20Sopenharmony_ci } 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci for (i = 0; i < count; i++, x++) { 9248c2ecf20Sopenharmony_ci if (mask[i]) { 9258c2ecf20Sopenharmony_ci BEGIN_RING(6); 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 9288c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 9298c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 9308c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 9318c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 9328c2ecf20Sopenharmony_ci R128_ROP3_P | 9338c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 9348c2ecf20Sopenharmony_ci R128_GMC_WR_MSK_DIS); 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 9378c2ecf20Sopenharmony_ci OUT_RING(buffer[i]); 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 9408c2ecf20Sopenharmony_ci OUT_RING((1 << 16) | 1); 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci ADVANCE_RING(); 9438c2ecf20Sopenharmony_ci } 9448c2ecf20Sopenharmony_ci } 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_ci kfree(mask); 9478c2ecf20Sopenharmony_ci } else { 9488c2ecf20Sopenharmony_ci for (i = 0; i < count; i++, x++) { 9498c2ecf20Sopenharmony_ci BEGIN_RING(6); 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 9528c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 9538c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 9548c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 9558c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 9568c2ecf20Sopenharmony_ci R128_ROP3_P | 9578c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 9588c2ecf20Sopenharmony_ci R128_GMC_WR_MSK_DIS); 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 9618c2ecf20Sopenharmony_ci OUT_RING(buffer[i]); 9628c2ecf20Sopenharmony_ci 9638c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 9648c2ecf20Sopenharmony_ci OUT_RING((1 << 16) | 1); 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci ADVANCE_RING(); 9678c2ecf20Sopenharmony_ci } 9688c2ecf20Sopenharmony_ci } 9698c2ecf20Sopenharmony_ci 9708c2ecf20Sopenharmony_ci kfree(buffer); 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci return 0; 9738c2ecf20Sopenharmony_ci} 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_cistatic int r128_cce_dispatch_write_pixels(struct drm_device *dev, 9768c2ecf20Sopenharmony_ci drm_r128_depth_t *depth) 9778c2ecf20Sopenharmony_ci{ 9788c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 9798c2ecf20Sopenharmony_ci int count, *x, *y; 9808c2ecf20Sopenharmony_ci u32 *buffer; 9818c2ecf20Sopenharmony_ci u8 *mask; 9828c2ecf20Sopenharmony_ci int i, xbuf_size, ybuf_size, buffer_size, mask_size; 9838c2ecf20Sopenharmony_ci RING_LOCALS; 9848c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci count = depth->n; 9878c2ecf20Sopenharmony_ci if (count > 4096 || count <= 0) 9888c2ecf20Sopenharmony_ci return -EMSGSIZE; 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci xbuf_size = count * sizeof(*x); 9918c2ecf20Sopenharmony_ci ybuf_size = count * sizeof(*y); 9928c2ecf20Sopenharmony_ci x = memdup_user(depth->x, xbuf_size); 9938c2ecf20Sopenharmony_ci if (IS_ERR(x)) 9948c2ecf20Sopenharmony_ci return PTR_ERR(x); 9958c2ecf20Sopenharmony_ci y = memdup_user(depth->y, ybuf_size); 9968c2ecf20Sopenharmony_ci if (IS_ERR(y)) { 9978c2ecf20Sopenharmony_ci kfree(x); 9988c2ecf20Sopenharmony_ci return PTR_ERR(y); 9998c2ecf20Sopenharmony_ci } 10008c2ecf20Sopenharmony_ci buffer_size = depth->n * sizeof(u32); 10018c2ecf20Sopenharmony_ci buffer = memdup_user(depth->buffer, buffer_size); 10028c2ecf20Sopenharmony_ci if (IS_ERR(buffer)) { 10038c2ecf20Sopenharmony_ci kfree(x); 10048c2ecf20Sopenharmony_ci kfree(y); 10058c2ecf20Sopenharmony_ci return PTR_ERR(buffer); 10068c2ecf20Sopenharmony_ci } 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci if (depth->mask) { 10098c2ecf20Sopenharmony_ci mask_size = depth->n; 10108c2ecf20Sopenharmony_ci mask = memdup_user(depth->mask, mask_size); 10118c2ecf20Sopenharmony_ci if (IS_ERR(mask)) { 10128c2ecf20Sopenharmony_ci kfree(x); 10138c2ecf20Sopenharmony_ci kfree(y); 10148c2ecf20Sopenharmony_ci kfree(buffer); 10158c2ecf20Sopenharmony_ci return PTR_ERR(mask); 10168c2ecf20Sopenharmony_ci } 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) { 10198c2ecf20Sopenharmony_ci if (mask[i]) { 10208c2ecf20Sopenharmony_ci BEGIN_RING(6); 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 10238c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 10248c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 10258c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 10268c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 10278c2ecf20Sopenharmony_ci R128_ROP3_P | 10288c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 10298c2ecf20Sopenharmony_ci R128_GMC_WR_MSK_DIS); 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 10328c2ecf20Sopenharmony_ci OUT_RING(buffer[i]); 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci OUT_RING((x[i] << 16) | y[i]); 10358c2ecf20Sopenharmony_ci OUT_RING((1 << 16) | 1); 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci ADVANCE_RING(); 10388c2ecf20Sopenharmony_ci } 10398c2ecf20Sopenharmony_ci } 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci kfree(mask); 10428c2ecf20Sopenharmony_ci } else { 10438c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) { 10448c2ecf20Sopenharmony_ci BEGIN_RING(6); 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); 10478c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | 10488c2ecf20Sopenharmony_ci R128_GMC_BRUSH_SOLID_COLOR | 10498c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 10508c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 10518c2ecf20Sopenharmony_ci R128_ROP3_P | 10528c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | 10538c2ecf20Sopenharmony_ci R128_GMC_WR_MSK_DIS); 10548c2ecf20Sopenharmony_ci 10558c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 10568c2ecf20Sopenharmony_ci OUT_RING(buffer[i]); 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci OUT_RING((x[i] << 16) | y[i]); 10598c2ecf20Sopenharmony_ci OUT_RING((1 << 16) | 1); 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci ADVANCE_RING(); 10628c2ecf20Sopenharmony_ci } 10638c2ecf20Sopenharmony_ci } 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ci kfree(x); 10668c2ecf20Sopenharmony_ci kfree(y); 10678c2ecf20Sopenharmony_ci kfree(buffer); 10688c2ecf20Sopenharmony_ci 10698c2ecf20Sopenharmony_ci return 0; 10708c2ecf20Sopenharmony_ci} 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_cistatic int r128_cce_dispatch_read_span(struct drm_device *dev, 10738c2ecf20Sopenharmony_ci drm_r128_depth_t *depth) 10748c2ecf20Sopenharmony_ci{ 10758c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 10768c2ecf20Sopenharmony_ci int count, x, y; 10778c2ecf20Sopenharmony_ci RING_LOCALS; 10788c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ci count = depth->n; 10818c2ecf20Sopenharmony_ci if (count > 4096 || count <= 0) 10828c2ecf20Sopenharmony_ci return -EMSGSIZE; 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci if (copy_from_user(&x, depth->x, sizeof(x))) 10858c2ecf20Sopenharmony_ci return -EFAULT; 10868c2ecf20Sopenharmony_ci if (copy_from_user(&y, depth->y, sizeof(y))) 10878c2ecf20Sopenharmony_ci return -EFAULT; 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci BEGIN_RING(7); 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); 10928c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | 10938c2ecf20Sopenharmony_ci R128_GMC_DST_PITCH_OFFSET_CNTL | 10948c2ecf20Sopenharmony_ci R128_GMC_BRUSH_NONE | 10958c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 10968c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 10978c2ecf20Sopenharmony_ci R128_ROP3_S | 10988c2ecf20Sopenharmony_ci R128_DP_SRC_SOURCE_MEMORY | 10998c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); 11008c2ecf20Sopenharmony_ci 11018c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 11028c2ecf20Sopenharmony_ci OUT_RING(dev_priv->span_pitch_offset_c); 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci OUT_RING((x << 16) | y); 11058c2ecf20Sopenharmony_ci OUT_RING((0 << 16) | 0); 11068c2ecf20Sopenharmony_ci OUT_RING((count << 16) | 1); 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci ADVANCE_RING(); 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_ci return 0; 11118c2ecf20Sopenharmony_ci} 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_cistatic int r128_cce_dispatch_read_pixels(struct drm_device *dev, 11148c2ecf20Sopenharmony_ci drm_r128_depth_t *depth) 11158c2ecf20Sopenharmony_ci{ 11168c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 11178c2ecf20Sopenharmony_ci int count, *x, *y; 11188c2ecf20Sopenharmony_ci int i, xbuf_size, ybuf_size; 11198c2ecf20Sopenharmony_ci RING_LOCALS; 11208c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_ci count = depth->n; 11238c2ecf20Sopenharmony_ci if (count > 4096 || count <= 0) 11248c2ecf20Sopenharmony_ci return -EMSGSIZE; 11258c2ecf20Sopenharmony_ci 11268c2ecf20Sopenharmony_ci if (count > dev_priv->depth_pitch) 11278c2ecf20Sopenharmony_ci count = dev_priv->depth_pitch; 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ci xbuf_size = count * sizeof(*x); 11308c2ecf20Sopenharmony_ci ybuf_size = count * sizeof(*y); 11318c2ecf20Sopenharmony_ci x = kmalloc(xbuf_size, GFP_KERNEL); 11328c2ecf20Sopenharmony_ci if (x == NULL) 11338c2ecf20Sopenharmony_ci return -ENOMEM; 11348c2ecf20Sopenharmony_ci y = kmalloc(ybuf_size, GFP_KERNEL); 11358c2ecf20Sopenharmony_ci if (y == NULL) { 11368c2ecf20Sopenharmony_ci kfree(x); 11378c2ecf20Sopenharmony_ci return -ENOMEM; 11388c2ecf20Sopenharmony_ci } 11398c2ecf20Sopenharmony_ci if (copy_from_user(x, depth->x, xbuf_size)) { 11408c2ecf20Sopenharmony_ci kfree(x); 11418c2ecf20Sopenharmony_ci kfree(y); 11428c2ecf20Sopenharmony_ci return -EFAULT; 11438c2ecf20Sopenharmony_ci } 11448c2ecf20Sopenharmony_ci if (copy_from_user(y, depth->y, ybuf_size)) { 11458c2ecf20Sopenharmony_ci kfree(x); 11468c2ecf20Sopenharmony_ci kfree(y); 11478c2ecf20Sopenharmony_ci return -EFAULT; 11488c2ecf20Sopenharmony_ci } 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) { 11518c2ecf20Sopenharmony_ci BEGIN_RING(7); 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); 11548c2ecf20Sopenharmony_ci OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | 11558c2ecf20Sopenharmony_ci R128_GMC_DST_PITCH_OFFSET_CNTL | 11568c2ecf20Sopenharmony_ci R128_GMC_BRUSH_NONE | 11578c2ecf20Sopenharmony_ci (dev_priv->depth_fmt << 8) | 11588c2ecf20Sopenharmony_ci R128_GMC_SRC_DATATYPE_COLOR | 11598c2ecf20Sopenharmony_ci R128_ROP3_S | 11608c2ecf20Sopenharmony_ci R128_DP_SRC_SOURCE_MEMORY | 11618c2ecf20Sopenharmony_ci R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); 11628c2ecf20Sopenharmony_ci 11638c2ecf20Sopenharmony_ci OUT_RING(dev_priv->depth_pitch_offset_c); 11648c2ecf20Sopenharmony_ci OUT_RING(dev_priv->span_pitch_offset_c); 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci OUT_RING((x[i] << 16) | y[i]); 11678c2ecf20Sopenharmony_ci OUT_RING((i << 16) | 0); 11688c2ecf20Sopenharmony_ci OUT_RING((1 << 16) | 1); 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_ci ADVANCE_RING(); 11718c2ecf20Sopenharmony_ci } 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci kfree(x); 11748c2ecf20Sopenharmony_ci kfree(y); 11758c2ecf20Sopenharmony_ci 11768c2ecf20Sopenharmony_ci return 0; 11778c2ecf20Sopenharmony_ci} 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci/* ================================================================ 11808c2ecf20Sopenharmony_ci * Polygon stipple 11818c2ecf20Sopenharmony_ci */ 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_cistatic void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple) 11848c2ecf20Sopenharmony_ci{ 11858c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 11868c2ecf20Sopenharmony_ci int i; 11878c2ecf20Sopenharmony_ci RING_LOCALS; 11888c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci BEGIN_RING(33); 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_ci OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); 11938c2ecf20Sopenharmony_ci for (i = 0; i < 32; i++) 11948c2ecf20Sopenharmony_ci OUT_RING(stipple[i]); 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci ADVANCE_RING(); 11978c2ecf20Sopenharmony_ci} 11988c2ecf20Sopenharmony_ci 11998c2ecf20Sopenharmony_ci/* ================================================================ 12008c2ecf20Sopenharmony_ci * IOCTL functions 12018c2ecf20Sopenharmony_ci */ 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_cistatic int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) 12048c2ecf20Sopenharmony_ci{ 12058c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 12068c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv; 12078c2ecf20Sopenharmony_ci drm_r128_clear_t *clear = data; 12088c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 12138c2ecf20Sopenharmony_ci 12148c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci sarea_priv = dev_priv->sarea_priv; 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) 12198c2ecf20Sopenharmony_ci sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci r128_cce_dispatch_clear(dev, clear); 12228c2ecf20Sopenharmony_ci COMMIT_RING(); 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci /* Make sure we restore the 3D state next time. 12258c2ecf20Sopenharmony_ci */ 12268c2ecf20Sopenharmony_ci dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci return 0; 12298c2ecf20Sopenharmony_ci} 12308c2ecf20Sopenharmony_ci 12318c2ecf20Sopenharmony_cistatic int r128_do_init_pageflip(struct drm_device *dev) 12328c2ecf20Sopenharmony_ci{ 12338c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 12348c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET); 12378c2ecf20Sopenharmony_ci dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL); 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset); 12408c2ecf20Sopenharmony_ci R128_WRITE(R128_CRTC_OFFSET_CNTL, 12418c2ecf20Sopenharmony_ci dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL); 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci dev_priv->page_flipping = 1; 12448c2ecf20Sopenharmony_ci dev_priv->current_page = 0; 12458c2ecf20Sopenharmony_ci dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci return 0; 12488c2ecf20Sopenharmony_ci} 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_cistatic int r128_do_cleanup_pageflip(struct drm_device *dev) 12518c2ecf20Sopenharmony_ci{ 12528c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 12538c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 12548c2ecf20Sopenharmony_ci 12558c2ecf20Sopenharmony_ci R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset); 12568c2ecf20Sopenharmony_ci R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl); 12578c2ecf20Sopenharmony_ci 12588c2ecf20Sopenharmony_ci if (dev_priv->current_page != 0) { 12598c2ecf20Sopenharmony_ci r128_cce_dispatch_flip(dev); 12608c2ecf20Sopenharmony_ci COMMIT_RING(); 12618c2ecf20Sopenharmony_ci } 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci dev_priv->page_flipping = 0; 12648c2ecf20Sopenharmony_ci return 0; 12658c2ecf20Sopenharmony_ci} 12668c2ecf20Sopenharmony_ci 12678c2ecf20Sopenharmony_ci/* Swapping and flipping are different operations, need different ioctls. 12688c2ecf20Sopenharmony_ci * They can & should be intermixed to support multiple 3d windows. 12698c2ecf20Sopenharmony_ci */ 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_cistatic int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) 12728c2ecf20Sopenharmony_ci{ 12738c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 12748c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 12818c2ecf20Sopenharmony_ci 12828c2ecf20Sopenharmony_ci if (!dev_priv->page_flipping) 12838c2ecf20Sopenharmony_ci r128_do_init_pageflip(dev); 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_ci r128_cce_dispatch_flip(dev); 12868c2ecf20Sopenharmony_ci 12878c2ecf20Sopenharmony_ci COMMIT_RING(); 12888c2ecf20Sopenharmony_ci return 0; 12898c2ecf20Sopenharmony_ci} 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_cistatic int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) 12928c2ecf20Sopenharmony_ci{ 12938c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 12948c2ecf20Sopenharmony_ci drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 12958c2ecf20Sopenharmony_ci DRM_DEBUG("\n"); 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 12988c2ecf20Sopenharmony_ci 12998c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_ci if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) 13048c2ecf20Sopenharmony_ci sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci r128_cce_dispatch_swap(dev); 13078c2ecf20Sopenharmony_ci dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | 13088c2ecf20Sopenharmony_ci R128_UPLOAD_MASKS); 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci COMMIT_RING(); 13118c2ecf20Sopenharmony_ci return 0; 13128c2ecf20Sopenharmony_ci} 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_cistatic int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) 13158c2ecf20Sopenharmony_ci{ 13168c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 13178c2ecf20Sopenharmony_ci struct drm_device_dma *dma = dev->dma; 13188c2ecf20Sopenharmony_ci struct drm_buf *buf; 13198c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv; 13208c2ecf20Sopenharmony_ci drm_r128_vertex_t *vertex = data; 13218c2ecf20Sopenharmony_ci 13228c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_ci DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", 13278c2ecf20Sopenharmony_ci task_pid_nr(current), vertex->idx, vertex->count, vertex->discard); 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_ci if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { 13308c2ecf20Sopenharmony_ci DRM_ERROR("buffer index %d (of %d max)\n", 13318c2ecf20Sopenharmony_ci vertex->idx, dma->buf_count - 1); 13328c2ecf20Sopenharmony_ci return -EINVAL; 13338c2ecf20Sopenharmony_ci } 13348c2ecf20Sopenharmony_ci if (vertex->prim < 0 || 13358c2ecf20Sopenharmony_ci vertex->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { 13368c2ecf20Sopenharmony_ci DRM_ERROR("buffer prim %d\n", vertex->prim); 13378c2ecf20Sopenharmony_ci return -EINVAL; 13388c2ecf20Sopenharmony_ci } 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 13418c2ecf20Sopenharmony_ci VB_AGE_TEST_WITH_RETURN(dev_priv); 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci buf = dma->buflist[vertex->idx]; 13448c2ecf20Sopenharmony_ci buf_priv = buf->dev_private; 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci if (buf->file_priv != file_priv) { 13478c2ecf20Sopenharmony_ci DRM_ERROR("process %d using buffer owned by %p\n", 13488c2ecf20Sopenharmony_ci task_pid_nr(current), buf->file_priv); 13498c2ecf20Sopenharmony_ci return -EINVAL; 13508c2ecf20Sopenharmony_ci } 13518c2ecf20Sopenharmony_ci if (buf->pending) { 13528c2ecf20Sopenharmony_ci DRM_ERROR("sending pending buffer %d\n", vertex->idx); 13538c2ecf20Sopenharmony_ci return -EINVAL; 13548c2ecf20Sopenharmony_ci } 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci buf->used = vertex->count; 13578c2ecf20Sopenharmony_ci buf_priv->prim = vertex->prim; 13588c2ecf20Sopenharmony_ci buf_priv->discard = vertex->discard; 13598c2ecf20Sopenharmony_ci 13608c2ecf20Sopenharmony_ci r128_cce_dispatch_vertex(dev, buf); 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci COMMIT_RING(); 13638c2ecf20Sopenharmony_ci return 0; 13648c2ecf20Sopenharmony_ci} 13658c2ecf20Sopenharmony_ci 13668c2ecf20Sopenharmony_cistatic int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) 13678c2ecf20Sopenharmony_ci{ 13688c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 13698c2ecf20Sopenharmony_ci struct drm_device_dma *dma = dev->dma; 13708c2ecf20Sopenharmony_ci struct drm_buf *buf; 13718c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv; 13728c2ecf20Sopenharmony_ci drm_r128_indices_t *elts = data; 13738c2ecf20Sopenharmony_ci int count; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_ci DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", task_pid_nr(current), 13808c2ecf20Sopenharmony_ci elts->idx, elts->start, elts->end, elts->discard); 13818c2ecf20Sopenharmony_ci 13828c2ecf20Sopenharmony_ci if (elts->idx < 0 || elts->idx >= dma->buf_count) { 13838c2ecf20Sopenharmony_ci DRM_ERROR("buffer index %d (of %d max)\n", 13848c2ecf20Sopenharmony_ci elts->idx, dma->buf_count - 1); 13858c2ecf20Sopenharmony_ci return -EINVAL; 13868c2ecf20Sopenharmony_ci } 13878c2ecf20Sopenharmony_ci if (elts->prim < 0 || 13888c2ecf20Sopenharmony_ci elts->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { 13898c2ecf20Sopenharmony_ci DRM_ERROR("buffer prim %d\n", elts->prim); 13908c2ecf20Sopenharmony_ci return -EINVAL; 13918c2ecf20Sopenharmony_ci } 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 13948c2ecf20Sopenharmony_ci VB_AGE_TEST_WITH_RETURN(dev_priv); 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci buf = dma->buflist[elts->idx]; 13978c2ecf20Sopenharmony_ci buf_priv = buf->dev_private; 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci if (buf->file_priv != file_priv) { 14008c2ecf20Sopenharmony_ci DRM_ERROR("process %d using buffer owned by %p\n", 14018c2ecf20Sopenharmony_ci task_pid_nr(current), buf->file_priv); 14028c2ecf20Sopenharmony_ci return -EINVAL; 14038c2ecf20Sopenharmony_ci } 14048c2ecf20Sopenharmony_ci if (buf->pending) { 14058c2ecf20Sopenharmony_ci DRM_ERROR("sending pending buffer %d\n", elts->idx); 14068c2ecf20Sopenharmony_ci return -EINVAL; 14078c2ecf20Sopenharmony_ci } 14088c2ecf20Sopenharmony_ci 14098c2ecf20Sopenharmony_ci count = (elts->end - elts->start) / sizeof(u16); 14108c2ecf20Sopenharmony_ci elts->start -= R128_INDEX_PRIM_OFFSET; 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci if (elts->start & 0x7) { 14138c2ecf20Sopenharmony_ci DRM_ERROR("misaligned buffer 0x%x\n", elts->start); 14148c2ecf20Sopenharmony_ci return -EINVAL; 14158c2ecf20Sopenharmony_ci } 14168c2ecf20Sopenharmony_ci if (elts->start < buf->used) { 14178c2ecf20Sopenharmony_ci DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); 14188c2ecf20Sopenharmony_ci return -EINVAL; 14198c2ecf20Sopenharmony_ci } 14208c2ecf20Sopenharmony_ci 14218c2ecf20Sopenharmony_ci buf->used = elts->end; 14228c2ecf20Sopenharmony_ci buf_priv->prim = elts->prim; 14238c2ecf20Sopenharmony_ci buf_priv->discard = elts->discard; 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_ci r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count); 14268c2ecf20Sopenharmony_ci 14278c2ecf20Sopenharmony_ci COMMIT_RING(); 14288c2ecf20Sopenharmony_ci return 0; 14298c2ecf20Sopenharmony_ci} 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_cistatic int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) 14328c2ecf20Sopenharmony_ci{ 14338c2ecf20Sopenharmony_ci struct drm_device_dma *dma = dev->dma; 14348c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 14358c2ecf20Sopenharmony_ci drm_r128_blit_t *blit = data; 14368c2ecf20Sopenharmony_ci int ret; 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_ci DRM_DEBUG("pid=%d index=%d\n", task_pid_nr(current), blit->idx); 14438c2ecf20Sopenharmony_ci 14448c2ecf20Sopenharmony_ci if (blit->idx < 0 || blit->idx >= dma->buf_count) { 14458c2ecf20Sopenharmony_ci DRM_ERROR("buffer index %d (of %d max)\n", 14468c2ecf20Sopenharmony_ci blit->idx, dma->buf_count - 1); 14478c2ecf20Sopenharmony_ci return -EINVAL; 14488c2ecf20Sopenharmony_ci } 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 14518c2ecf20Sopenharmony_ci VB_AGE_TEST_WITH_RETURN(dev_priv); 14528c2ecf20Sopenharmony_ci 14538c2ecf20Sopenharmony_ci ret = r128_cce_dispatch_blit(dev, file_priv, blit); 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_ci COMMIT_RING(); 14568c2ecf20Sopenharmony_ci return ret; 14578c2ecf20Sopenharmony_ci} 14588c2ecf20Sopenharmony_ci 14598c2ecf20Sopenharmony_ciint r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv) 14608c2ecf20Sopenharmony_ci{ 14618c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 14628c2ecf20Sopenharmony_ci drm_r128_depth_t *depth = data; 14638c2ecf20Sopenharmony_ci int ret; 14648c2ecf20Sopenharmony_ci 14658c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 14688c2ecf20Sopenharmony_ci 14698c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_ci ret = -EINVAL; 14728c2ecf20Sopenharmony_ci switch (depth->func) { 14738c2ecf20Sopenharmony_ci case R128_WRITE_SPAN: 14748c2ecf20Sopenharmony_ci ret = r128_cce_dispatch_write_span(dev, depth); 14758c2ecf20Sopenharmony_ci break; 14768c2ecf20Sopenharmony_ci case R128_WRITE_PIXELS: 14778c2ecf20Sopenharmony_ci ret = r128_cce_dispatch_write_pixels(dev, depth); 14788c2ecf20Sopenharmony_ci break; 14798c2ecf20Sopenharmony_ci case R128_READ_SPAN: 14808c2ecf20Sopenharmony_ci ret = r128_cce_dispatch_read_span(dev, depth); 14818c2ecf20Sopenharmony_ci break; 14828c2ecf20Sopenharmony_ci case R128_READ_PIXELS: 14838c2ecf20Sopenharmony_ci ret = r128_cce_dispatch_read_pixels(dev, depth); 14848c2ecf20Sopenharmony_ci break; 14858c2ecf20Sopenharmony_ci } 14868c2ecf20Sopenharmony_ci 14878c2ecf20Sopenharmony_ci COMMIT_RING(); 14888c2ecf20Sopenharmony_ci return ret; 14898c2ecf20Sopenharmony_ci} 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ciint r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) 14928c2ecf20Sopenharmony_ci{ 14938c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 14948c2ecf20Sopenharmony_ci drm_r128_stipple_t *stipple = data; 14958c2ecf20Sopenharmony_ci u32 mask[32]; 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 14988c2ecf20Sopenharmony_ci 14998c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 15008c2ecf20Sopenharmony_ci 15018c2ecf20Sopenharmony_ci if (copy_from_user(&mask, stipple->mask, 32 * sizeof(u32))) 15028c2ecf20Sopenharmony_ci return -EFAULT; 15038c2ecf20Sopenharmony_ci 15048c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci r128_cce_dispatch_stipple(dev, mask); 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci COMMIT_RING(); 15098c2ecf20Sopenharmony_ci return 0; 15108c2ecf20Sopenharmony_ci} 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_cistatic int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) 15138c2ecf20Sopenharmony_ci{ 15148c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 15158c2ecf20Sopenharmony_ci struct drm_device_dma *dma = dev->dma; 15168c2ecf20Sopenharmony_ci struct drm_buf *buf; 15178c2ecf20Sopenharmony_ci drm_r128_buf_priv_t *buf_priv; 15188c2ecf20Sopenharmony_ci drm_r128_indirect_t *indirect = data; 15198c2ecf20Sopenharmony_ci#if 0 15208c2ecf20Sopenharmony_ci RING_LOCALS; 15218c2ecf20Sopenharmony_ci#endif 15228c2ecf20Sopenharmony_ci 15238c2ecf20Sopenharmony_ci LOCK_TEST_WITH_RETURN(dev, file_priv); 15248c2ecf20Sopenharmony_ci 15258c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 15268c2ecf20Sopenharmony_ci 15278c2ecf20Sopenharmony_ci DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", 15288c2ecf20Sopenharmony_ci indirect->idx, indirect->start, indirect->end, 15298c2ecf20Sopenharmony_ci indirect->discard); 15308c2ecf20Sopenharmony_ci 15318c2ecf20Sopenharmony_ci if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { 15328c2ecf20Sopenharmony_ci DRM_ERROR("buffer index %d (of %d max)\n", 15338c2ecf20Sopenharmony_ci indirect->idx, dma->buf_count - 1); 15348c2ecf20Sopenharmony_ci return -EINVAL; 15358c2ecf20Sopenharmony_ci } 15368c2ecf20Sopenharmony_ci 15378c2ecf20Sopenharmony_ci buf = dma->buflist[indirect->idx]; 15388c2ecf20Sopenharmony_ci buf_priv = buf->dev_private; 15398c2ecf20Sopenharmony_ci 15408c2ecf20Sopenharmony_ci if (buf->file_priv != file_priv) { 15418c2ecf20Sopenharmony_ci DRM_ERROR("process %d using buffer owned by %p\n", 15428c2ecf20Sopenharmony_ci task_pid_nr(current), buf->file_priv); 15438c2ecf20Sopenharmony_ci return -EINVAL; 15448c2ecf20Sopenharmony_ci } 15458c2ecf20Sopenharmony_ci if (buf->pending) { 15468c2ecf20Sopenharmony_ci DRM_ERROR("sending pending buffer %d\n", indirect->idx); 15478c2ecf20Sopenharmony_ci return -EINVAL; 15488c2ecf20Sopenharmony_ci } 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_ci if (indirect->start < buf->used) { 15518c2ecf20Sopenharmony_ci DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", 15528c2ecf20Sopenharmony_ci indirect->start, buf->used); 15538c2ecf20Sopenharmony_ci return -EINVAL; 15548c2ecf20Sopenharmony_ci } 15558c2ecf20Sopenharmony_ci 15568c2ecf20Sopenharmony_ci RING_SPACE_TEST_WITH_RETURN(dev_priv); 15578c2ecf20Sopenharmony_ci VB_AGE_TEST_WITH_RETURN(dev_priv); 15588c2ecf20Sopenharmony_ci 15598c2ecf20Sopenharmony_ci buf->used = indirect->end; 15608c2ecf20Sopenharmony_ci buf_priv->discard = indirect->discard; 15618c2ecf20Sopenharmony_ci 15628c2ecf20Sopenharmony_ci#if 0 15638c2ecf20Sopenharmony_ci /* Wait for the 3D stream to idle before the indirect buffer 15648c2ecf20Sopenharmony_ci * containing 2D acceleration commands is processed. 15658c2ecf20Sopenharmony_ci */ 15668c2ecf20Sopenharmony_ci BEGIN_RING(2); 15678c2ecf20Sopenharmony_ci RADEON_WAIT_UNTIL_3D_IDLE(); 15688c2ecf20Sopenharmony_ci ADVANCE_RING(); 15698c2ecf20Sopenharmony_ci#endif 15708c2ecf20Sopenharmony_ci 15718c2ecf20Sopenharmony_ci /* Dispatch the indirect buffer full of commands from the 15728c2ecf20Sopenharmony_ci * X server. This is insecure and is thus only available to 15738c2ecf20Sopenharmony_ci * privileged clients. 15748c2ecf20Sopenharmony_ci */ 15758c2ecf20Sopenharmony_ci r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end); 15768c2ecf20Sopenharmony_ci 15778c2ecf20Sopenharmony_ci COMMIT_RING(); 15788c2ecf20Sopenharmony_ci return 0; 15798c2ecf20Sopenharmony_ci} 15808c2ecf20Sopenharmony_ci 15818c2ecf20Sopenharmony_ciint r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) 15828c2ecf20Sopenharmony_ci{ 15838c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 15848c2ecf20Sopenharmony_ci drm_r128_getparam_t *param = data; 15858c2ecf20Sopenharmony_ci int value; 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_ci DEV_INIT_TEST_WITH_RETURN(dev_priv); 15888c2ecf20Sopenharmony_ci 15898c2ecf20Sopenharmony_ci DRM_DEBUG("pid=%d\n", task_pid_nr(current)); 15908c2ecf20Sopenharmony_ci 15918c2ecf20Sopenharmony_ci switch (param->param) { 15928c2ecf20Sopenharmony_ci case R128_PARAM_IRQ_NR: 15938c2ecf20Sopenharmony_ci value = dev->pdev->irq; 15948c2ecf20Sopenharmony_ci break; 15958c2ecf20Sopenharmony_ci default: 15968c2ecf20Sopenharmony_ci return -EINVAL; 15978c2ecf20Sopenharmony_ci } 15988c2ecf20Sopenharmony_ci 15998c2ecf20Sopenharmony_ci if (copy_to_user(param->value, &value, sizeof(int))) { 16008c2ecf20Sopenharmony_ci DRM_ERROR("copy_to_user\n"); 16018c2ecf20Sopenharmony_ci return -EFAULT; 16028c2ecf20Sopenharmony_ci } 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci return 0; 16058c2ecf20Sopenharmony_ci} 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_civoid r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) 16088c2ecf20Sopenharmony_ci{ 16098c2ecf20Sopenharmony_ci if (dev->dev_private) { 16108c2ecf20Sopenharmony_ci drm_r128_private_t *dev_priv = dev->dev_private; 16118c2ecf20Sopenharmony_ci if (dev_priv->page_flipping) 16128c2ecf20Sopenharmony_ci r128_do_cleanup_pageflip(dev); 16138c2ecf20Sopenharmony_ci } 16148c2ecf20Sopenharmony_ci} 16158c2ecf20Sopenharmony_civoid r128_driver_lastclose(struct drm_device *dev) 16168c2ecf20Sopenharmony_ci{ 16178c2ecf20Sopenharmony_ci r128_do_cleanup_cce(dev); 16188c2ecf20Sopenharmony_ci} 16198c2ecf20Sopenharmony_ci 16208c2ecf20Sopenharmony_ciconst struct drm_ioctl_desc r128_ioctls[] = { 16218c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 16228c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 16238c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 16248c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 16258c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), 16268c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH), 16278c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), 16288c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH), 16298c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH), 16308c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH), 16318c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH), 16328c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH), 16338c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH), 16348c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH), 16358c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH), 16368c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 16378c2ecf20Sopenharmony_ci DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), 16388c2ecf20Sopenharmony_ci}; 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_ciint r128_max_ioctl = ARRAY_SIZE(r128_ioctls); 1641