1926deccbSFrançois Tigeot /* 2926deccbSFrançois Tigeot * Copyright 2008 Advanced Micro Devices, Inc. 3926deccbSFrançois Tigeot * Copyright 2008 Red Hat Inc. 4926deccbSFrançois Tigeot * Copyright 2009 Jerome Glisse. 5926deccbSFrançois Tigeot * 6926deccbSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 7926deccbSFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 8926deccbSFrançois Tigeot * to deal in the Software without restriction, including without limitation 9926deccbSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10926deccbSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 11926deccbSFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 12926deccbSFrançois Tigeot * 13926deccbSFrançois Tigeot * The above copyright notice and this permission notice shall be included in 14926deccbSFrançois Tigeot * all copies or substantial portions of the Software. 15926deccbSFrançois Tigeot * 16926deccbSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17926deccbSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18926deccbSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19926deccbSFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20926deccbSFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21926deccbSFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22926deccbSFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE. 23926deccbSFrançois Tigeot * 24926deccbSFrançois Tigeot * Authors: Dave Airlie 25926deccbSFrançois Tigeot * Alex Deucher 26926deccbSFrançois Tigeot * Jerome Glisse 27926deccbSFrançois Tigeot */ 28926deccbSFrançois Tigeot #include <drm/drmP.h> 2983b4b9b9SFrançois Tigeot #include <drm/radeon_drm.h> 30926deccbSFrançois Tigeot #include "radeon_reg.h" 31926deccbSFrançois Tigeot #include "radeon.h" 32926deccbSFrançois Tigeot #include "radeon_asic.h" 33926deccbSFrançois Tigeot 34926deccbSFrançois Tigeot #include "r100d.h" 35926deccbSFrançois Tigeot #include "r200_reg_safe.h" 36926deccbSFrançois Tigeot 37926deccbSFrançois Tigeot #include "r100_track.h" 38926deccbSFrançois Tigeot 39926deccbSFrançois Tigeot static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) 40926deccbSFrançois Tigeot { 41926deccbSFrançois Tigeot int vtx_size, i; 42926deccbSFrançois Tigeot vtx_size = 2; 43926deccbSFrançois Tigeot 44926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_Z0) 45926deccbSFrançois Tigeot vtx_size++; 46926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_W0) 47926deccbSFrançois Tigeot vtx_size++; 48926deccbSFrançois Tigeot /* blend weight */ 49926deccbSFrançois Tigeot if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) 50926deccbSFrançois Tigeot vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; 51926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) 52926deccbSFrançois Tigeot vtx_size++; 53926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_N0) 54926deccbSFrançois Tigeot vtx_size += 3; 55926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_POINT_SIZE) 56926deccbSFrançois Tigeot vtx_size++; 57926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) 58926deccbSFrançois Tigeot vtx_size++; 59926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_SHININESS_0) 60926deccbSFrançois Tigeot vtx_size++; 61926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_SHININESS_1) 62926deccbSFrançois Tigeot vtx_size++; 63926deccbSFrançois Tigeot for (i = 0; i < 8; i++) { 64926deccbSFrançois Tigeot int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; 65926deccbSFrançois Tigeot switch (color_size) { 66926deccbSFrançois Tigeot case 0: break; 67926deccbSFrançois Tigeot case 1: vtx_size++; break; 68926deccbSFrançois Tigeot case 2: vtx_size += 3; break; 69926deccbSFrançois Tigeot case 3: vtx_size += 4; break; 70926deccbSFrançois Tigeot } 71926deccbSFrançois Tigeot } 72926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_XY1) 73926deccbSFrançois Tigeot vtx_size += 2; 74926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_Z1) 75926deccbSFrançois Tigeot vtx_size++; 76926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_W1) 77926deccbSFrançois Tigeot vtx_size++; 78926deccbSFrançois Tigeot if (vtx_fmt_0 & R200_VTX_N1) 79926deccbSFrançois Tigeot vtx_size += 3; 80926deccbSFrançois Tigeot return vtx_size; 81926deccbSFrançois Tigeot } 82926deccbSFrançois Tigeot 83*1cfef1a5SFrançois Tigeot struct radeon_fence *r200_copy_dma(struct radeon_device *rdev, 84926deccbSFrançois Tigeot uint64_t src_offset, 85926deccbSFrançois Tigeot uint64_t dst_offset, 86926deccbSFrançois Tigeot unsigned num_gpu_pages, 87*1cfef1a5SFrançois Tigeot struct reservation_object *resv) 88926deccbSFrançois Tigeot { 89926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 90*1cfef1a5SFrançois Tigeot struct radeon_fence *fence; 91926deccbSFrançois Tigeot uint32_t size; 92926deccbSFrançois Tigeot uint32_t cur_size; 93926deccbSFrançois Tigeot int i, num_loops; 94926deccbSFrançois Tigeot int r = 0; 95926deccbSFrançois Tigeot 96926deccbSFrançois Tigeot /* radeon pitch is /64 */ 97926deccbSFrançois Tigeot size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; 98926deccbSFrançois Tigeot num_loops = DIV_ROUND_UP(size, 0x1FFFFF); 99926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); 100926deccbSFrançois Tigeot if (r) { 101926deccbSFrançois Tigeot DRM_ERROR("radeon: moving bo (%d).\n", r); 102*1cfef1a5SFrançois Tigeot return ERR_PTR(r); 103926deccbSFrançois Tigeot } 104926deccbSFrançois Tigeot /* Must wait for 2D idle & clean before DMA or hangs might happen */ 105926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 106926deccbSFrançois Tigeot radeon_ring_write(ring, (1 << 16)); 107926deccbSFrançois Tigeot for (i = 0; i < num_loops; i++) { 108926deccbSFrançois Tigeot cur_size = size; 109926deccbSFrançois Tigeot if (cur_size > 0x1FFFFF) { 110926deccbSFrançois Tigeot cur_size = 0x1FFFFF; 111926deccbSFrançois Tigeot } 112926deccbSFrançois Tigeot size -= cur_size; 113926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(0x720, 2)); 114926deccbSFrançois Tigeot radeon_ring_write(ring, src_offset); 115926deccbSFrançois Tigeot radeon_ring_write(ring, dst_offset); 116926deccbSFrançois Tigeot radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30)); 117926deccbSFrançois Tigeot src_offset += cur_size; 118926deccbSFrançois Tigeot dst_offset += cur_size; 119926deccbSFrançois Tigeot } 120926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 121926deccbSFrançois Tigeot radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); 122*1cfef1a5SFrançois Tigeot r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); 123*1cfef1a5SFrançois Tigeot if (r) { 124*1cfef1a5SFrançois Tigeot radeon_ring_unlock_undo(rdev, ring); 125*1cfef1a5SFrançois Tigeot return ERR_PTR(r); 126926deccbSFrançois Tigeot } 127c6f73aabSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring, false); 128*1cfef1a5SFrançois Tigeot return fence; 129926deccbSFrançois Tigeot } 130926deccbSFrançois Tigeot 131926deccbSFrançois Tigeot 132926deccbSFrançois Tigeot static int r200_get_vtx_size_1(uint32_t vtx_fmt_1) 133926deccbSFrançois Tigeot { 134926deccbSFrançois Tigeot int vtx_size, i, tex_size; 135926deccbSFrançois Tigeot vtx_size = 0; 136926deccbSFrançois Tigeot for (i = 0; i < 6; i++) { 137926deccbSFrançois Tigeot tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; 138926deccbSFrançois Tigeot if (tex_size > 4) 139926deccbSFrançois Tigeot continue; 140926deccbSFrançois Tigeot vtx_size += tex_size; 141926deccbSFrançois Tigeot } 142926deccbSFrançois Tigeot return vtx_size; 143926deccbSFrançois Tigeot } 144926deccbSFrançois Tigeot 145926deccbSFrançois Tigeot int r200_packet0_check(struct radeon_cs_parser *p, 146926deccbSFrançois Tigeot struct radeon_cs_packet *pkt, 147926deccbSFrançois Tigeot unsigned idx, unsigned reg) 148926deccbSFrançois Tigeot { 149ee479021SImre Vadász struct radeon_cs_reloc *reloc; 150926deccbSFrançois Tigeot struct r100_cs_track *track; 151926deccbSFrançois Tigeot volatile uint32_t *ib; 152926deccbSFrançois Tigeot uint32_t tmp; 153926deccbSFrançois Tigeot int r; 154926deccbSFrançois Tigeot int i; 155926deccbSFrançois Tigeot int face; 156926deccbSFrançois Tigeot u32 tile_flags = 0; 157926deccbSFrançois Tigeot u32 idx_value; 158926deccbSFrançois Tigeot 159926deccbSFrançois Tigeot ib = p->ib.ptr; 160926deccbSFrançois Tigeot track = (struct r100_cs_track *)p->track; 161926deccbSFrançois Tigeot idx_value = radeon_get_ib_value(p, idx); 162926deccbSFrançois Tigeot switch (reg) { 163926deccbSFrançois Tigeot case RADEON_CRTC_GUI_TRIG_VLINE: 164926deccbSFrançois Tigeot r = r100_cs_packet_parse_vline(p); 165926deccbSFrançois Tigeot if (r) { 166926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 167926deccbSFrançois Tigeot idx, reg); 168b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 169926deccbSFrançois Tigeot return r; 170926deccbSFrançois Tigeot } 171926deccbSFrançois Tigeot break; 172926deccbSFrançois Tigeot /* FIXME: only allow PACKET3 blit? easier to check for out of 173926deccbSFrançois Tigeot * range access */ 174926deccbSFrançois Tigeot case RADEON_DST_PITCH_OFFSET: 175926deccbSFrançois Tigeot case RADEON_SRC_PITCH_OFFSET: 176926deccbSFrançois Tigeot r = r100_reloc_pitch_offset(p, pkt, idx, reg); 177926deccbSFrançois Tigeot if (r) 178926deccbSFrançois Tigeot return r; 179926deccbSFrançois Tigeot break; 180926deccbSFrançois Tigeot case RADEON_RB3D_DEPTHOFFSET: 181b403bed8SMichael Neumann r = radeon_cs_packet_next_reloc(p, &reloc, 0); 182926deccbSFrançois Tigeot if (r) { 183926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 184926deccbSFrançois Tigeot idx, reg); 185b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 186926deccbSFrançois Tigeot return r; 187926deccbSFrançois Tigeot } 188926deccbSFrançois Tigeot track->zb.robj = reloc->robj; 189926deccbSFrançois Tigeot track->zb.offset = idx_value; 190926deccbSFrançois Tigeot track->zb_dirty = true; 191c6f73aabSFrançois Tigeot ib[idx] = idx_value + ((u32)reloc->gpu_offset); 192926deccbSFrançois Tigeot break; 193926deccbSFrançois Tigeot case RADEON_RB3D_COLOROFFSET: 194b403bed8SMichael Neumann r = radeon_cs_packet_next_reloc(p, &reloc, 0); 195926deccbSFrançois Tigeot if (r) { 196926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 197926deccbSFrançois Tigeot idx, reg); 198b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 199926deccbSFrançois Tigeot return r; 200926deccbSFrançois Tigeot } 201926deccbSFrançois Tigeot track->cb[0].robj = reloc->robj; 202926deccbSFrançois Tigeot track->cb[0].offset = idx_value; 203926deccbSFrançois Tigeot track->cb_dirty = true; 204c6f73aabSFrançois Tigeot ib[idx] = idx_value + ((u32)reloc->gpu_offset); 205926deccbSFrançois Tigeot break; 206926deccbSFrançois Tigeot case R200_PP_TXOFFSET_0: 207926deccbSFrançois Tigeot case R200_PP_TXOFFSET_1: 208926deccbSFrançois Tigeot case R200_PP_TXOFFSET_2: 209926deccbSFrançois Tigeot case R200_PP_TXOFFSET_3: 210926deccbSFrançois Tigeot case R200_PP_TXOFFSET_4: 211926deccbSFrançois Tigeot case R200_PP_TXOFFSET_5: 212926deccbSFrançois Tigeot i = (reg - R200_PP_TXOFFSET_0) / 24; 213b403bed8SMichael Neumann r = radeon_cs_packet_next_reloc(p, &reloc, 0); 214926deccbSFrançois Tigeot if (r) { 215926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 216926deccbSFrançois Tigeot idx, reg); 217b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 218926deccbSFrançois Tigeot return r; 219926deccbSFrançois Tigeot } 220926deccbSFrançois Tigeot if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 221c6f73aabSFrançois Tigeot if (reloc->tiling_flags & RADEON_TILING_MACRO) 222926deccbSFrançois Tigeot tile_flags |= R200_TXO_MACRO_TILE; 223c6f73aabSFrançois Tigeot if (reloc->tiling_flags & RADEON_TILING_MICRO) 224926deccbSFrançois Tigeot tile_flags |= R200_TXO_MICRO_TILE; 225926deccbSFrançois Tigeot 226926deccbSFrançois Tigeot tmp = idx_value & ~(0x7 << 2); 227926deccbSFrançois Tigeot tmp |= tile_flags; 228c6f73aabSFrançois Tigeot ib[idx] = tmp + ((u32)reloc->gpu_offset); 229926deccbSFrançois Tigeot } else 230c6f73aabSFrançois Tigeot ib[idx] = idx_value + ((u32)reloc->gpu_offset); 231926deccbSFrançois Tigeot track->textures[i].robj = reloc->robj; 232926deccbSFrançois Tigeot track->tex_dirty = true; 233926deccbSFrançois Tigeot break; 234926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F1_0: 235926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F2_0: 236926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F3_0: 237926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F4_0: 238926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F5_0: 239926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F1_1: 240926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F2_1: 241926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F3_1: 242926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F4_1: 243926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F5_1: 244926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F1_2: 245926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F2_2: 246926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F3_2: 247926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F4_2: 248926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F5_2: 249926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F1_3: 250926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F2_3: 251926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F3_3: 252926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F4_3: 253926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F5_3: 254926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F1_4: 255926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F2_4: 256926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F3_4: 257926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F4_4: 258926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F5_4: 259926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F1_5: 260926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F2_5: 261926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F3_5: 262926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F4_5: 263926deccbSFrançois Tigeot case R200_PP_CUBIC_OFFSET_F5_5: 264926deccbSFrançois Tigeot i = (reg - R200_PP_TXOFFSET_0) / 24; 265926deccbSFrançois Tigeot face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; 266b403bed8SMichael Neumann r = radeon_cs_packet_next_reloc(p, &reloc, 0); 267926deccbSFrançois Tigeot if (r) { 268926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 269926deccbSFrançois Tigeot idx, reg); 270b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 271926deccbSFrançois Tigeot return r; 272926deccbSFrançois Tigeot } 273926deccbSFrançois Tigeot track->textures[i].cube_info[face - 1].offset = idx_value; 274c6f73aabSFrançois Tigeot ib[idx] = idx_value + ((u32)reloc->gpu_offset); 275926deccbSFrançois Tigeot track->textures[i].cube_info[face - 1].robj = reloc->robj; 276926deccbSFrançois Tigeot track->tex_dirty = true; 277926deccbSFrançois Tigeot break; 278926deccbSFrançois Tigeot case RADEON_RE_WIDTH_HEIGHT: 279926deccbSFrançois Tigeot track->maxy = ((idx_value >> 16) & 0x7FF); 280926deccbSFrançois Tigeot track->cb_dirty = true; 281926deccbSFrançois Tigeot track->zb_dirty = true; 282926deccbSFrançois Tigeot break; 283926deccbSFrançois Tigeot case RADEON_RB3D_COLORPITCH: 284b403bed8SMichael Neumann r = radeon_cs_packet_next_reloc(p, &reloc, 0); 285926deccbSFrançois Tigeot if (r) { 286926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 287926deccbSFrançois Tigeot idx, reg); 288b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 289926deccbSFrançois Tigeot return r; 290926deccbSFrançois Tigeot } 291926deccbSFrançois Tigeot 292926deccbSFrançois Tigeot if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 293c6f73aabSFrançois Tigeot if (reloc->tiling_flags & RADEON_TILING_MACRO) 294926deccbSFrançois Tigeot tile_flags |= RADEON_COLOR_TILE_ENABLE; 295c6f73aabSFrançois Tigeot if (reloc->tiling_flags & RADEON_TILING_MICRO) 296926deccbSFrançois Tigeot tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; 297926deccbSFrançois Tigeot 298926deccbSFrançois Tigeot tmp = idx_value & ~(0x7 << 16); 299926deccbSFrançois Tigeot tmp |= tile_flags; 300926deccbSFrançois Tigeot ib[idx] = tmp; 301926deccbSFrançois Tigeot } else 302926deccbSFrançois Tigeot ib[idx] = idx_value; 303926deccbSFrançois Tigeot 304926deccbSFrançois Tigeot track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; 305926deccbSFrançois Tigeot track->cb_dirty = true; 306926deccbSFrançois Tigeot break; 307926deccbSFrançois Tigeot case RADEON_RB3D_DEPTHPITCH: 308926deccbSFrançois Tigeot track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; 309926deccbSFrançois Tigeot track->zb_dirty = true; 310926deccbSFrançois Tigeot break; 311926deccbSFrançois Tigeot case RADEON_RB3D_CNTL: 312926deccbSFrançois Tigeot switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { 313926deccbSFrançois Tigeot case 7: 314926deccbSFrançois Tigeot case 8: 315926deccbSFrançois Tigeot case 9: 316926deccbSFrançois Tigeot case 11: 317926deccbSFrançois Tigeot case 12: 318926deccbSFrançois Tigeot track->cb[0].cpp = 1; 319926deccbSFrançois Tigeot break; 320926deccbSFrançois Tigeot case 3: 321926deccbSFrançois Tigeot case 4: 322926deccbSFrançois Tigeot case 15: 323926deccbSFrançois Tigeot track->cb[0].cpp = 2; 324926deccbSFrançois Tigeot break; 325926deccbSFrançois Tigeot case 6: 326926deccbSFrançois Tigeot track->cb[0].cpp = 4; 327926deccbSFrançois Tigeot break; 328926deccbSFrançois Tigeot default: 329926deccbSFrançois Tigeot DRM_ERROR("Invalid color buffer format (%d) !\n", 330926deccbSFrançois Tigeot ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); 331926deccbSFrançois Tigeot return -EINVAL; 332926deccbSFrançois Tigeot } 333926deccbSFrançois Tigeot if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { 334926deccbSFrançois Tigeot DRM_ERROR("No support for depth xy offset in kms\n"); 335926deccbSFrançois Tigeot return -EINVAL; 336926deccbSFrançois Tigeot } 337926deccbSFrançois Tigeot 338926deccbSFrançois Tigeot track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); 339926deccbSFrançois Tigeot track->cb_dirty = true; 340926deccbSFrançois Tigeot track->zb_dirty = true; 341926deccbSFrançois Tigeot break; 342926deccbSFrançois Tigeot case RADEON_RB3D_ZSTENCILCNTL: 343926deccbSFrançois Tigeot switch (idx_value & 0xf) { 344926deccbSFrançois Tigeot case 0: 345926deccbSFrançois Tigeot track->zb.cpp = 2; 346926deccbSFrançois Tigeot break; 347926deccbSFrançois Tigeot case 2: 348926deccbSFrançois Tigeot case 3: 349926deccbSFrançois Tigeot case 4: 350926deccbSFrançois Tigeot case 5: 351926deccbSFrançois Tigeot case 9: 352926deccbSFrançois Tigeot case 11: 353926deccbSFrançois Tigeot track->zb.cpp = 4; 354926deccbSFrançois Tigeot break; 355926deccbSFrançois Tigeot default: 356926deccbSFrançois Tigeot break; 357926deccbSFrançois Tigeot } 358926deccbSFrançois Tigeot track->zb_dirty = true; 359926deccbSFrançois Tigeot break; 360926deccbSFrançois Tigeot case RADEON_RB3D_ZPASS_ADDR: 361b403bed8SMichael Neumann r = radeon_cs_packet_next_reloc(p, &reloc, 0); 362926deccbSFrançois Tigeot if (r) { 363926deccbSFrançois Tigeot DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 364926deccbSFrançois Tigeot idx, reg); 365b403bed8SMichael Neumann radeon_cs_dump_packet(p, pkt); 366926deccbSFrançois Tigeot return r; 367926deccbSFrançois Tigeot } 368c6f73aabSFrançois Tigeot ib[idx] = idx_value + ((u32)reloc->gpu_offset); 369926deccbSFrançois Tigeot break; 370926deccbSFrançois Tigeot case RADEON_PP_CNTL: 371926deccbSFrançois Tigeot { 372926deccbSFrançois Tigeot uint32_t temp = idx_value >> 4; 373926deccbSFrançois Tigeot for (i = 0; i < track->num_texture; i++) 374926deccbSFrançois Tigeot track->textures[i].enabled = !!(temp & (1 << i)); 375926deccbSFrançois Tigeot track->tex_dirty = true; 376926deccbSFrançois Tigeot } 377926deccbSFrançois Tigeot break; 378926deccbSFrançois Tigeot case RADEON_SE_VF_CNTL: 379926deccbSFrançois Tigeot track->vap_vf_cntl = idx_value; 380926deccbSFrançois Tigeot break; 381926deccbSFrançois Tigeot case 0x210c: 382926deccbSFrançois Tigeot /* VAP_VF_MAX_VTX_INDX */ 383926deccbSFrançois Tigeot track->max_indx = idx_value & 0x00FFFFFFUL; 384926deccbSFrançois Tigeot break; 385926deccbSFrançois Tigeot case R200_SE_VTX_FMT_0: 386926deccbSFrançois Tigeot track->vtx_size = r200_get_vtx_size_0(idx_value); 387926deccbSFrançois Tigeot break; 388926deccbSFrançois Tigeot case R200_SE_VTX_FMT_1: 389926deccbSFrançois Tigeot track->vtx_size += r200_get_vtx_size_1(idx_value); 390926deccbSFrançois Tigeot break; 391926deccbSFrançois Tigeot case R200_PP_TXSIZE_0: 392926deccbSFrançois Tigeot case R200_PP_TXSIZE_1: 393926deccbSFrançois Tigeot case R200_PP_TXSIZE_2: 394926deccbSFrançois Tigeot case R200_PP_TXSIZE_3: 395926deccbSFrançois Tigeot case R200_PP_TXSIZE_4: 396926deccbSFrançois Tigeot case R200_PP_TXSIZE_5: 397926deccbSFrançois Tigeot i = (reg - R200_PP_TXSIZE_0) / 32; 398926deccbSFrançois Tigeot track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; 399926deccbSFrançois Tigeot track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; 400926deccbSFrançois Tigeot track->tex_dirty = true; 401926deccbSFrançois Tigeot break; 402926deccbSFrançois Tigeot case R200_PP_TXPITCH_0: 403926deccbSFrançois Tigeot case R200_PP_TXPITCH_1: 404926deccbSFrançois Tigeot case R200_PP_TXPITCH_2: 405926deccbSFrançois Tigeot case R200_PP_TXPITCH_3: 406926deccbSFrançois Tigeot case R200_PP_TXPITCH_4: 407926deccbSFrançois Tigeot case R200_PP_TXPITCH_5: 408926deccbSFrançois Tigeot i = (reg - R200_PP_TXPITCH_0) / 32; 409926deccbSFrançois Tigeot track->textures[i].pitch = idx_value + 32; 410926deccbSFrançois Tigeot track->tex_dirty = true; 411926deccbSFrançois Tigeot break; 412926deccbSFrançois Tigeot case R200_PP_TXFILTER_0: 413926deccbSFrançois Tigeot case R200_PP_TXFILTER_1: 414926deccbSFrançois Tigeot case R200_PP_TXFILTER_2: 415926deccbSFrançois Tigeot case R200_PP_TXFILTER_3: 416926deccbSFrançois Tigeot case R200_PP_TXFILTER_4: 417926deccbSFrançois Tigeot case R200_PP_TXFILTER_5: 418926deccbSFrançois Tigeot i = (reg - R200_PP_TXFILTER_0) / 32; 419926deccbSFrançois Tigeot track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) 420926deccbSFrançois Tigeot >> R200_MAX_MIP_LEVEL_SHIFT); 421926deccbSFrançois Tigeot tmp = (idx_value >> 23) & 0x7; 422926deccbSFrançois Tigeot if (tmp == 2 || tmp == 6) 423926deccbSFrançois Tigeot track->textures[i].roundup_w = false; 424926deccbSFrançois Tigeot tmp = (idx_value >> 27) & 0x7; 425926deccbSFrançois Tigeot if (tmp == 2 || tmp == 6) 426926deccbSFrançois Tigeot track->textures[i].roundup_h = false; 427926deccbSFrançois Tigeot track->tex_dirty = true; 428926deccbSFrançois Tigeot break; 429926deccbSFrançois Tigeot case R200_PP_TXMULTI_CTL_0: 430926deccbSFrançois Tigeot case R200_PP_TXMULTI_CTL_1: 431926deccbSFrançois Tigeot case R200_PP_TXMULTI_CTL_2: 432926deccbSFrançois Tigeot case R200_PP_TXMULTI_CTL_3: 433926deccbSFrançois Tigeot case R200_PP_TXMULTI_CTL_4: 434926deccbSFrançois Tigeot case R200_PP_TXMULTI_CTL_5: 435926deccbSFrançois Tigeot i = (reg - R200_PP_TXMULTI_CTL_0) / 32; 436926deccbSFrançois Tigeot break; 437926deccbSFrançois Tigeot case R200_PP_TXFORMAT_X_0: 438926deccbSFrançois Tigeot case R200_PP_TXFORMAT_X_1: 439926deccbSFrançois Tigeot case R200_PP_TXFORMAT_X_2: 440926deccbSFrançois Tigeot case R200_PP_TXFORMAT_X_3: 441926deccbSFrançois Tigeot case R200_PP_TXFORMAT_X_4: 442926deccbSFrançois Tigeot case R200_PP_TXFORMAT_X_5: 443926deccbSFrançois Tigeot i = (reg - R200_PP_TXFORMAT_X_0) / 32; 444926deccbSFrançois Tigeot track->textures[i].txdepth = idx_value & 0x7; 445926deccbSFrançois Tigeot tmp = (idx_value >> 16) & 0x3; 446926deccbSFrançois Tigeot /* 2D, 3D, CUBE */ 447926deccbSFrançois Tigeot switch (tmp) { 448926deccbSFrançois Tigeot case 0: 449926deccbSFrançois Tigeot case 3: 450926deccbSFrançois Tigeot case 4: 451926deccbSFrançois Tigeot case 5: 452926deccbSFrançois Tigeot case 6: 453926deccbSFrançois Tigeot case 7: 454926deccbSFrançois Tigeot /* 1D/2D */ 455926deccbSFrançois Tigeot track->textures[i].tex_coord_type = 0; 456926deccbSFrançois Tigeot break; 457926deccbSFrançois Tigeot case 1: 458926deccbSFrançois Tigeot /* CUBE */ 459926deccbSFrançois Tigeot track->textures[i].tex_coord_type = 2; 460926deccbSFrançois Tigeot break; 461926deccbSFrançois Tigeot case 2: 462926deccbSFrançois Tigeot /* 3D */ 463926deccbSFrançois Tigeot track->textures[i].tex_coord_type = 1; 464926deccbSFrançois Tigeot break; 465926deccbSFrançois Tigeot } 466926deccbSFrançois Tigeot track->tex_dirty = true; 467926deccbSFrançois Tigeot break; 468926deccbSFrançois Tigeot case R200_PP_TXFORMAT_0: 469926deccbSFrançois Tigeot case R200_PP_TXFORMAT_1: 470926deccbSFrançois Tigeot case R200_PP_TXFORMAT_2: 471926deccbSFrançois Tigeot case R200_PP_TXFORMAT_3: 472926deccbSFrançois Tigeot case R200_PP_TXFORMAT_4: 473926deccbSFrançois Tigeot case R200_PP_TXFORMAT_5: 474926deccbSFrançois Tigeot i = (reg - R200_PP_TXFORMAT_0) / 32; 475926deccbSFrançois Tigeot if (idx_value & R200_TXFORMAT_NON_POWER2) { 476926deccbSFrançois Tigeot track->textures[i].use_pitch = 1; 477926deccbSFrançois Tigeot } else { 478926deccbSFrançois Tigeot track->textures[i].use_pitch = 0; 479926deccbSFrançois Tigeot track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); 480926deccbSFrançois Tigeot track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); 481926deccbSFrançois Tigeot } 482926deccbSFrançois Tigeot if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) 483926deccbSFrançois Tigeot track->textures[i].lookup_disable = true; 484926deccbSFrançois Tigeot switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { 485926deccbSFrançois Tigeot case R200_TXFORMAT_I8: 486926deccbSFrançois Tigeot case R200_TXFORMAT_RGB332: 487926deccbSFrançois Tigeot case R200_TXFORMAT_Y8: 488926deccbSFrançois Tigeot track->textures[i].cpp = 1; 489926deccbSFrançois Tigeot track->textures[i].compress_format = R100_TRACK_COMP_NONE; 490926deccbSFrançois Tigeot break; 491926deccbSFrançois Tigeot case R200_TXFORMAT_AI88: 492926deccbSFrançois Tigeot case R200_TXFORMAT_ARGB1555: 493926deccbSFrançois Tigeot case R200_TXFORMAT_RGB565: 494926deccbSFrançois Tigeot case R200_TXFORMAT_ARGB4444: 495926deccbSFrançois Tigeot case R200_TXFORMAT_VYUY422: 496926deccbSFrançois Tigeot case R200_TXFORMAT_YVYU422: 497926deccbSFrançois Tigeot case R200_TXFORMAT_LDVDU655: 498926deccbSFrançois Tigeot case R200_TXFORMAT_DVDU88: 499926deccbSFrançois Tigeot case R200_TXFORMAT_AVYU4444: 500926deccbSFrançois Tigeot track->textures[i].cpp = 2; 501926deccbSFrançois Tigeot track->textures[i].compress_format = R100_TRACK_COMP_NONE; 502926deccbSFrançois Tigeot break; 503926deccbSFrançois Tigeot case R200_TXFORMAT_ARGB8888: 504926deccbSFrançois Tigeot case R200_TXFORMAT_RGBA8888: 505926deccbSFrançois Tigeot case R200_TXFORMAT_ABGR8888: 506926deccbSFrançois Tigeot case R200_TXFORMAT_BGR111110: 507926deccbSFrançois Tigeot case R200_TXFORMAT_LDVDU8888: 508926deccbSFrançois Tigeot track->textures[i].cpp = 4; 509926deccbSFrançois Tigeot track->textures[i].compress_format = R100_TRACK_COMP_NONE; 510926deccbSFrançois Tigeot break; 511926deccbSFrançois Tigeot case R200_TXFORMAT_DXT1: 512926deccbSFrançois Tigeot track->textures[i].cpp = 1; 513926deccbSFrançois Tigeot track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 514926deccbSFrançois Tigeot break; 515926deccbSFrançois Tigeot case R200_TXFORMAT_DXT23: 516926deccbSFrançois Tigeot case R200_TXFORMAT_DXT45: 517926deccbSFrançois Tigeot track->textures[i].cpp = 1; 518926deccbSFrançois Tigeot track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 519926deccbSFrançois Tigeot break; 520926deccbSFrançois Tigeot } 521926deccbSFrançois Tigeot track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); 522926deccbSFrançois Tigeot track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); 523926deccbSFrançois Tigeot track->tex_dirty = true; 524926deccbSFrançois Tigeot break; 525926deccbSFrançois Tigeot case R200_PP_CUBIC_FACES_0: 526926deccbSFrançois Tigeot case R200_PP_CUBIC_FACES_1: 527926deccbSFrançois Tigeot case R200_PP_CUBIC_FACES_2: 528926deccbSFrançois Tigeot case R200_PP_CUBIC_FACES_3: 529926deccbSFrançois Tigeot case R200_PP_CUBIC_FACES_4: 530926deccbSFrançois Tigeot case R200_PP_CUBIC_FACES_5: 531926deccbSFrançois Tigeot tmp = idx_value; 532926deccbSFrançois Tigeot i = (reg - R200_PP_CUBIC_FACES_0) / 32; 533926deccbSFrançois Tigeot for (face = 0; face < 4; face++) { 534926deccbSFrançois Tigeot track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); 535926deccbSFrançois Tigeot track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); 536926deccbSFrançois Tigeot } 537926deccbSFrançois Tigeot track->tex_dirty = true; 538926deccbSFrançois Tigeot break; 539926deccbSFrançois Tigeot default: 540c4ef309bSzrj printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", 541926deccbSFrançois Tigeot reg, idx); 542926deccbSFrançois Tigeot return -EINVAL; 543926deccbSFrançois Tigeot } 544926deccbSFrançois Tigeot return 0; 545926deccbSFrançois Tigeot } 546926deccbSFrançois Tigeot 547926deccbSFrançois Tigeot void r200_set_safe_registers(struct radeon_device *rdev) 548926deccbSFrançois Tigeot { 549926deccbSFrançois Tigeot rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; 550c4ef309bSzrj rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); 551926deccbSFrançois Tigeot } 552