18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2008 Advanced Micro Devices, Inc. 38c2ecf20Sopenharmony_ci * Copyright 2008 Red Hat Inc. 48c2ecf20Sopenharmony_ci * Copyright 2009 Jerome Glisse. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 78c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 88c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 98c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 108c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 118c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 148c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 198c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 208c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 218c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 228c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * Authors: Dave Airlie 258c2ecf20Sopenharmony_ci * Alex Deucher 268c2ecf20Sopenharmony_ci * Jerome Glisse 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h> 308c2ecf20Sopenharmony_ci#include "radeon_reg.h" 318c2ecf20Sopenharmony_ci#include "radeon.h" 328c2ecf20Sopenharmony_ci#include "radeon_asic.h" 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include "r100d.h" 358c2ecf20Sopenharmony_ci#include "r200_reg_safe.h" 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include "r100_track.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic int r200_get_vtx_size_0(uint32_t vtx_fmt_0) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci int vtx_size, i; 428c2ecf20Sopenharmony_ci vtx_size = 2; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_Z0) 458c2ecf20Sopenharmony_ci vtx_size++; 468c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_W0) 478c2ecf20Sopenharmony_ci vtx_size++; 488c2ecf20Sopenharmony_ci /* blend weight */ 498c2ecf20Sopenharmony_ci if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) 508c2ecf20Sopenharmony_ci vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; 518c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) 528c2ecf20Sopenharmony_ci vtx_size++; 538c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_N0) 548c2ecf20Sopenharmony_ci vtx_size += 3; 558c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_POINT_SIZE) 568c2ecf20Sopenharmony_ci vtx_size++; 578c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) 588c2ecf20Sopenharmony_ci vtx_size++; 598c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_SHININESS_0) 608c2ecf20Sopenharmony_ci vtx_size++; 618c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_SHININESS_1) 628c2ecf20Sopenharmony_ci vtx_size++; 638c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) { 648c2ecf20Sopenharmony_ci int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; 658c2ecf20Sopenharmony_ci switch (color_size) { 668c2ecf20Sopenharmony_ci case 0: break; 678c2ecf20Sopenharmony_ci case 1: vtx_size++; break; 688c2ecf20Sopenharmony_ci case 2: vtx_size += 3; break; 698c2ecf20Sopenharmony_ci case 3: vtx_size += 4; break; 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_XY1) 738c2ecf20Sopenharmony_ci vtx_size += 2; 748c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_Z1) 758c2ecf20Sopenharmony_ci vtx_size++; 768c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_W1) 778c2ecf20Sopenharmony_ci vtx_size++; 788c2ecf20Sopenharmony_ci if (vtx_fmt_0 & R200_VTX_N1) 798c2ecf20Sopenharmony_ci vtx_size += 3; 808c2ecf20Sopenharmony_ci return vtx_size; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistruct radeon_fence *r200_copy_dma(struct radeon_device *rdev, 848c2ecf20Sopenharmony_ci uint64_t src_offset, 858c2ecf20Sopenharmony_ci uint64_t dst_offset, 868c2ecf20Sopenharmony_ci unsigned num_gpu_pages, 878c2ecf20Sopenharmony_ci struct dma_resv *resv) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 908c2ecf20Sopenharmony_ci struct radeon_fence *fence; 918c2ecf20Sopenharmony_ci uint32_t size; 928c2ecf20Sopenharmony_ci uint32_t cur_size; 938c2ecf20Sopenharmony_ci int i, num_loops; 948c2ecf20Sopenharmony_ci int r = 0; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci /* radeon pitch is /64 */ 978c2ecf20Sopenharmony_ci size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; 988c2ecf20Sopenharmony_ci num_loops = DIV_ROUND_UP(size, 0x1FFFFF); 998c2ecf20Sopenharmony_ci r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); 1008c2ecf20Sopenharmony_ci if (r) { 1018c2ecf20Sopenharmony_ci DRM_ERROR("radeon: moving bo (%d).\n", r); 1028c2ecf20Sopenharmony_ci return ERR_PTR(r); 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci /* Must wait for 2D idle & clean before DMA or hangs might happen */ 1058c2ecf20Sopenharmony_ci radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 1068c2ecf20Sopenharmony_ci radeon_ring_write(ring, (1 << 16)); 1078c2ecf20Sopenharmony_ci for (i = 0; i < num_loops; i++) { 1088c2ecf20Sopenharmony_ci cur_size = size; 1098c2ecf20Sopenharmony_ci if (cur_size > 0x1FFFFF) { 1108c2ecf20Sopenharmony_ci cur_size = 0x1FFFFF; 1118c2ecf20Sopenharmony_ci } 1128c2ecf20Sopenharmony_ci size -= cur_size; 1138c2ecf20Sopenharmony_ci radeon_ring_write(ring, PACKET0(0x720, 2)); 1148c2ecf20Sopenharmony_ci radeon_ring_write(ring, src_offset); 1158c2ecf20Sopenharmony_ci radeon_ring_write(ring, dst_offset); 1168c2ecf20Sopenharmony_ci radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30)); 1178c2ecf20Sopenharmony_ci src_offset += cur_size; 1188c2ecf20Sopenharmony_ci dst_offset += cur_size; 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 1218c2ecf20Sopenharmony_ci radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); 1228c2ecf20Sopenharmony_ci r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); 1238c2ecf20Sopenharmony_ci if (r) { 1248c2ecf20Sopenharmony_ci radeon_ring_unlock_undo(rdev, ring); 1258c2ecf20Sopenharmony_ci return ERR_PTR(r); 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 1288c2ecf20Sopenharmony_ci return fence; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic int r200_get_vtx_size_1(uint32_t vtx_fmt_1) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci int vtx_size, i, tex_size; 1358c2ecf20Sopenharmony_ci vtx_size = 0; 1368c2ecf20Sopenharmony_ci for (i = 0; i < 6; i++) { 1378c2ecf20Sopenharmony_ci tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; 1388c2ecf20Sopenharmony_ci if (tex_size > 4) 1398c2ecf20Sopenharmony_ci continue; 1408c2ecf20Sopenharmony_ci vtx_size += tex_size; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci return vtx_size; 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ciint r200_packet0_check(struct radeon_cs_parser *p, 1468c2ecf20Sopenharmony_ci struct radeon_cs_packet *pkt, 1478c2ecf20Sopenharmony_ci unsigned idx, unsigned reg) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci struct radeon_bo_list *reloc; 1508c2ecf20Sopenharmony_ci struct r100_cs_track *track; 1518c2ecf20Sopenharmony_ci volatile uint32_t *ib; 1528c2ecf20Sopenharmony_ci uint32_t tmp; 1538c2ecf20Sopenharmony_ci int r; 1548c2ecf20Sopenharmony_ci int i; 1558c2ecf20Sopenharmony_ci int face; 1568c2ecf20Sopenharmony_ci u32 tile_flags = 0; 1578c2ecf20Sopenharmony_ci u32 idx_value; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci ib = p->ib.ptr; 1608c2ecf20Sopenharmony_ci track = (struct r100_cs_track *)p->track; 1618c2ecf20Sopenharmony_ci idx_value = radeon_get_ib_value(p, idx); 1628c2ecf20Sopenharmony_ci switch (reg) { 1638c2ecf20Sopenharmony_ci case RADEON_CRTC_GUI_TRIG_VLINE: 1648c2ecf20Sopenharmony_ci r = r100_cs_packet_parse_vline(p); 1658c2ecf20Sopenharmony_ci if (r) { 1668c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1678c2ecf20Sopenharmony_ci idx, reg); 1688c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 1698c2ecf20Sopenharmony_ci return r; 1708c2ecf20Sopenharmony_ci } 1718c2ecf20Sopenharmony_ci break; 1728c2ecf20Sopenharmony_ci /* FIXME: only allow PACKET3 blit? easier to check for out of 1738c2ecf20Sopenharmony_ci * range access */ 1748c2ecf20Sopenharmony_ci case RADEON_DST_PITCH_OFFSET: 1758c2ecf20Sopenharmony_ci case RADEON_SRC_PITCH_OFFSET: 1768c2ecf20Sopenharmony_ci r = r100_reloc_pitch_offset(p, pkt, idx, reg); 1778c2ecf20Sopenharmony_ci if (r) 1788c2ecf20Sopenharmony_ci return r; 1798c2ecf20Sopenharmony_ci break; 1808c2ecf20Sopenharmony_ci case RADEON_RB3D_DEPTHOFFSET: 1818c2ecf20Sopenharmony_ci r = radeon_cs_packet_next_reloc(p, &reloc, 0); 1828c2ecf20Sopenharmony_ci if (r) { 1838c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1848c2ecf20Sopenharmony_ci idx, reg); 1858c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 1868c2ecf20Sopenharmony_ci return r; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci track->zb.robj = reloc->robj; 1898c2ecf20Sopenharmony_ci track->zb.offset = idx_value; 1908c2ecf20Sopenharmony_ci track->zb_dirty = true; 1918c2ecf20Sopenharmony_ci ib[idx] = idx_value + ((u32)reloc->gpu_offset); 1928c2ecf20Sopenharmony_ci break; 1938c2ecf20Sopenharmony_ci case RADEON_RB3D_COLOROFFSET: 1948c2ecf20Sopenharmony_ci r = radeon_cs_packet_next_reloc(p, &reloc, 0); 1958c2ecf20Sopenharmony_ci if (r) { 1968c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1978c2ecf20Sopenharmony_ci idx, reg); 1988c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 1998c2ecf20Sopenharmony_ci return r; 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci track->cb[0].robj = reloc->robj; 2028c2ecf20Sopenharmony_ci track->cb[0].offset = idx_value; 2038c2ecf20Sopenharmony_ci track->cb_dirty = true; 2048c2ecf20Sopenharmony_ci ib[idx] = idx_value + ((u32)reloc->gpu_offset); 2058c2ecf20Sopenharmony_ci break; 2068c2ecf20Sopenharmony_ci case R200_PP_TXOFFSET_0: 2078c2ecf20Sopenharmony_ci case R200_PP_TXOFFSET_1: 2088c2ecf20Sopenharmony_ci case R200_PP_TXOFFSET_2: 2098c2ecf20Sopenharmony_ci case R200_PP_TXOFFSET_3: 2108c2ecf20Sopenharmony_ci case R200_PP_TXOFFSET_4: 2118c2ecf20Sopenharmony_ci case R200_PP_TXOFFSET_5: 2128c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXOFFSET_0) / 24; 2138c2ecf20Sopenharmony_ci r = radeon_cs_packet_next_reloc(p, &reloc, 0); 2148c2ecf20Sopenharmony_ci if (r) { 2158c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 2168c2ecf20Sopenharmony_ci idx, reg); 2178c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 2188c2ecf20Sopenharmony_ci return r; 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 2218c2ecf20Sopenharmony_ci if (reloc->tiling_flags & RADEON_TILING_MACRO) 2228c2ecf20Sopenharmony_ci tile_flags |= R200_TXO_MACRO_TILE; 2238c2ecf20Sopenharmony_ci if (reloc->tiling_flags & RADEON_TILING_MICRO) 2248c2ecf20Sopenharmony_ci tile_flags |= R200_TXO_MICRO_TILE; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci tmp = idx_value & ~(0x7 << 2); 2278c2ecf20Sopenharmony_ci tmp |= tile_flags; 2288c2ecf20Sopenharmony_ci ib[idx] = tmp + ((u32)reloc->gpu_offset); 2298c2ecf20Sopenharmony_ci } else 2308c2ecf20Sopenharmony_ci ib[idx] = idx_value + ((u32)reloc->gpu_offset); 2318c2ecf20Sopenharmony_ci track->textures[i].robj = reloc->robj; 2328c2ecf20Sopenharmony_ci track->tex_dirty = true; 2338c2ecf20Sopenharmony_ci break; 2348c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F1_0: 2358c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F2_0: 2368c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F3_0: 2378c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F4_0: 2388c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F5_0: 2398c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F1_1: 2408c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F2_1: 2418c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F3_1: 2428c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F4_1: 2438c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F5_1: 2448c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F1_2: 2458c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F2_2: 2468c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F3_2: 2478c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F4_2: 2488c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F5_2: 2498c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F1_3: 2508c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F2_3: 2518c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F3_3: 2528c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F4_3: 2538c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F5_3: 2548c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F1_4: 2558c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F2_4: 2568c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F3_4: 2578c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F4_4: 2588c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F5_4: 2598c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F1_5: 2608c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F2_5: 2618c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F3_5: 2628c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F4_5: 2638c2ecf20Sopenharmony_ci case R200_PP_CUBIC_OFFSET_F5_5: 2648c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXOFFSET_0) / 24; 2658c2ecf20Sopenharmony_ci face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; 2668c2ecf20Sopenharmony_ci r = radeon_cs_packet_next_reloc(p, &reloc, 0); 2678c2ecf20Sopenharmony_ci if (r) { 2688c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 2698c2ecf20Sopenharmony_ci idx, reg); 2708c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 2718c2ecf20Sopenharmony_ci return r; 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci track->textures[i].cube_info[face - 1].offset = idx_value; 2748c2ecf20Sopenharmony_ci ib[idx] = idx_value + ((u32)reloc->gpu_offset); 2758c2ecf20Sopenharmony_ci track->textures[i].cube_info[face - 1].robj = reloc->robj; 2768c2ecf20Sopenharmony_ci track->tex_dirty = true; 2778c2ecf20Sopenharmony_ci break; 2788c2ecf20Sopenharmony_ci case RADEON_RE_WIDTH_HEIGHT: 2798c2ecf20Sopenharmony_ci track->maxy = ((idx_value >> 16) & 0x7FF); 2808c2ecf20Sopenharmony_ci track->cb_dirty = true; 2818c2ecf20Sopenharmony_ci track->zb_dirty = true; 2828c2ecf20Sopenharmony_ci break; 2838c2ecf20Sopenharmony_ci case RADEON_RB3D_COLORPITCH: 2848c2ecf20Sopenharmony_ci r = radeon_cs_packet_next_reloc(p, &reloc, 0); 2858c2ecf20Sopenharmony_ci if (r) { 2868c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 2878c2ecf20Sopenharmony_ci idx, reg); 2888c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 2898c2ecf20Sopenharmony_ci return r; 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 2938c2ecf20Sopenharmony_ci if (reloc->tiling_flags & RADEON_TILING_MACRO) 2948c2ecf20Sopenharmony_ci tile_flags |= RADEON_COLOR_TILE_ENABLE; 2958c2ecf20Sopenharmony_ci if (reloc->tiling_flags & RADEON_TILING_MICRO) 2968c2ecf20Sopenharmony_ci tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci tmp = idx_value & ~(0x7 << 16); 2998c2ecf20Sopenharmony_ci tmp |= tile_flags; 3008c2ecf20Sopenharmony_ci ib[idx] = tmp; 3018c2ecf20Sopenharmony_ci } else 3028c2ecf20Sopenharmony_ci ib[idx] = idx_value; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; 3058c2ecf20Sopenharmony_ci track->cb_dirty = true; 3068c2ecf20Sopenharmony_ci break; 3078c2ecf20Sopenharmony_ci case RADEON_RB3D_DEPTHPITCH: 3088c2ecf20Sopenharmony_ci track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; 3098c2ecf20Sopenharmony_ci track->zb_dirty = true; 3108c2ecf20Sopenharmony_ci break; 3118c2ecf20Sopenharmony_ci case RADEON_RB3D_CNTL: 3128c2ecf20Sopenharmony_ci switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { 3138c2ecf20Sopenharmony_ci case 7: 3148c2ecf20Sopenharmony_ci case 8: 3158c2ecf20Sopenharmony_ci case 9: 3168c2ecf20Sopenharmony_ci case 11: 3178c2ecf20Sopenharmony_ci case 12: 3188c2ecf20Sopenharmony_ci track->cb[0].cpp = 1; 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci case 3: 3218c2ecf20Sopenharmony_ci case 4: 3228c2ecf20Sopenharmony_ci case 15: 3238c2ecf20Sopenharmony_ci track->cb[0].cpp = 2; 3248c2ecf20Sopenharmony_ci break; 3258c2ecf20Sopenharmony_ci case 6: 3268c2ecf20Sopenharmony_ci track->cb[0].cpp = 4; 3278c2ecf20Sopenharmony_ci break; 3288c2ecf20Sopenharmony_ci default: 3298c2ecf20Sopenharmony_ci DRM_ERROR("Invalid color buffer format (%d) !\n", 3308c2ecf20Sopenharmony_ci ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); 3318c2ecf20Sopenharmony_ci return -EINVAL; 3328c2ecf20Sopenharmony_ci } 3338c2ecf20Sopenharmony_ci if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { 3348c2ecf20Sopenharmony_ci DRM_ERROR("No support for depth xy offset in kms\n"); 3358c2ecf20Sopenharmony_ci return -EINVAL; 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); 3398c2ecf20Sopenharmony_ci track->cb_dirty = true; 3408c2ecf20Sopenharmony_ci track->zb_dirty = true; 3418c2ecf20Sopenharmony_ci break; 3428c2ecf20Sopenharmony_ci case RADEON_RB3D_ZSTENCILCNTL: 3438c2ecf20Sopenharmony_ci switch (idx_value & 0xf) { 3448c2ecf20Sopenharmony_ci case 0: 3458c2ecf20Sopenharmony_ci track->zb.cpp = 2; 3468c2ecf20Sopenharmony_ci break; 3478c2ecf20Sopenharmony_ci case 2: 3488c2ecf20Sopenharmony_ci case 3: 3498c2ecf20Sopenharmony_ci case 4: 3508c2ecf20Sopenharmony_ci case 5: 3518c2ecf20Sopenharmony_ci case 9: 3528c2ecf20Sopenharmony_ci case 11: 3538c2ecf20Sopenharmony_ci track->zb.cpp = 4; 3548c2ecf20Sopenharmony_ci break; 3558c2ecf20Sopenharmony_ci default: 3568c2ecf20Sopenharmony_ci break; 3578c2ecf20Sopenharmony_ci } 3588c2ecf20Sopenharmony_ci track->zb_dirty = true; 3598c2ecf20Sopenharmony_ci break; 3608c2ecf20Sopenharmony_ci case RADEON_RB3D_ZPASS_ADDR: 3618c2ecf20Sopenharmony_ci r = radeon_cs_packet_next_reloc(p, &reloc, 0); 3628c2ecf20Sopenharmony_ci if (r) { 3638c2ecf20Sopenharmony_ci DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 3648c2ecf20Sopenharmony_ci idx, reg); 3658c2ecf20Sopenharmony_ci radeon_cs_dump_packet(p, pkt); 3668c2ecf20Sopenharmony_ci return r; 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci ib[idx] = idx_value + ((u32)reloc->gpu_offset); 3698c2ecf20Sopenharmony_ci break; 3708c2ecf20Sopenharmony_ci case RADEON_PP_CNTL: 3718c2ecf20Sopenharmony_ci { 3728c2ecf20Sopenharmony_ci uint32_t temp = idx_value >> 4; 3738c2ecf20Sopenharmony_ci for (i = 0; i < track->num_texture; i++) 3748c2ecf20Sopenharmony_ci track->textures[i].enabled = !!(temp & (1 << i)); 3758c2ecf20Sopenharmony_ci track->tex_dirty = true; 3768c2ecf20Sopenharmony_ci } 3778c2ecf20Sopenharmony_ci break; 3788c2ecf20Sopenharmony_ci case RADEON_SE_VF_CNTL: 3798c2ecf20Sopenharmony_ci track->vap_vf_cntl = idx_value; 3808c2ecf20Sopenharmony_ci break; 3818c2ecf20Sopenharmony_ci case 0x210c: 3828c2ecf20Sopenharmony_ci /* VAP_VF_MAX_VTX_INDX */ 3838c2ecf20Sopenharmony_ci track->max_indx = idx_value & 0x00FFFFFFUL; 3848c2ecf20Sopenharmony_ci break; 3858c2ecf20Sopenharmony_ci case R200_SE_VTX_FMT_0: 3868c2ecf20Sopenharmony_ci track->vtx_size = r200_get_vtx_size_0(idx_value); 3878c2ecf20Sopenharmony_ci break; 3888c2ecf20Sopenharmony_ci case R200_SE_VTX_FMT_1: 3898c2ecf20Sopenharmony_ci track->vtx_size += r200_get_vtx_size_1(idx_value); 3908c2ecf20Sopenharmony_ci break; 3918c2ecf20Sopenharmony_ci case R200_PP_TXSIZE_0: 3928c2ecf20Sopenharmony_ci case R200_PP_TXSIZE_1: 3938c2ecf20Sopenharmony_ci case R200_PP_TXSIZE_2: 3948c2ecf20Sopenharmony_ci case R200_PP_TXSIZE_3: 3958c2ecf20Sopenharmony_ci case R200_PP_TXSIZE_4: 3968c2ecf20Sopenharmony_ci case R200_PP_TXSIZE_5: 3978c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXSIZE_0) / 32; 3988c2ecf20Sopenharmony_ci track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; 3998c2ecf20Sopenharmony_ci track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; 4008c2ecf20Sopenharmony_ci track->tex_dirty = true; 4018c2ecf20Sopenharmony_ci break; 4028c2ecf20Sopenharmony_ci case R200_PP_TXPITCH_0: 4038c2ecf20Sopenharmony_ci case R200_PP_TXPITCH_1: 4048c2ecf20Sopenharmony_ci case R200_PP_TXPITCH_2: 4058c2ecf20Sopenharmony_ci case R200_PP_TXPITCH_3: 4068c2ecf20Sopenharmony_ci case R200_PP_TXPITCH_4: 4078c2ecf20Sopenharmony_ci case R200_PP_TXPITCH_5: 4088c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXPITCH_0) / 32; 4098c2ecf20Sopenharmony_ci track->textures[i].pitch = idx_value + 32; 4108c2ecf20Sopenharmony_ci track->tex_dirty = true; 4118c2ecf20Sopenharmony_ci break; 4128c2ecf20Sopenharmony_ci case R200_PP_TXFILTER_0: 4138c2ecf20Sopenharmony_ci case R200_PP_TXFILTER_1: 4148c2ecf20Sopenharmony_ci case R200_PP_TXFILTER_2: 4158c2ecf20Sopenharmony_ci case R200_PP_TXFILTER_3: 4168c2ecf20Sopenharmony_ci case R200_PP_TXFILTER_4: 4178c2ecf20Sopenharmony_ci case R200_PP_TXFILTER_5: 4188c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXFILTER_0) / 32; 4198c2ecf20Sopenharmony_ci track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) 4208c2ecf20Sopenharmony_ci >> R200_MAX_MIP_LEVEL_SHIFT); 4218c2ecf20Sopenharmony_ci tmp = (idx_value >> 23) & 0x7; 4228c2ecf20Sopenharmony_ci if (tmp == 2 || tmp == 6) 4238c2ecf20Sopenharmony_ci track->textures[i].roundup_w = false; 4248c2ecf20Sopenharmony_ci tmp = (idx_value >> 27) & 0x7; 4258c2ecf20Sopenharmony_ci if (tmp == 2 || tmp == 6) 4268c2ecf20Sopenharmony_ci track->textures[i].roundup_h = false; 4278c2ecf20Sopenharmony_ci track->tex_dirty = true; 4288c2ecf20Sopenharmony_ci break; 4298c2ecf20Sopenharmony_ci case R200_PP_TXMULTI_CTL_0: 4308c2ecf20Sopenharmony_ci case R200_PP_TXMULTI_CTL_1: 4318c2ecf20Sopenharmony_ci case R200_PP_TXMULTI_CTL_2: 4328c2ecf20Sopenharmony_ci case R200_PP_TXMULTI_CTL_3: 4338c2ecf20Sopenharmony_ci case R200_PP_TXMULTI_CTL_4: 4348c2ecf20Sopenharmony_ci case R200_PP_TXMULTI_CTL_5: 4358c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXMULTI_CTL_0) / 32; 4368c2ecf20Sopenharmony_ci break; 4378c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_X_0: 4388c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_X_1: 4398c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_X_2: 4408c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_X_3: 4418c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_X_4: 4428c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_X_5: 4438c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXFORMAT_X_0) / 32; 4448c2ecf20Sopenharmony_ci track->textures[i].txdepth = idx_value & 0x7; 4458c2ecf20Sopenharmony_ci tmp = (idx_value >> 16) & 0x3; 4468c2ecf20Sopenharmony_ci /* 2D, 3D, CUBE */ 4478c2ecf20Sopenharmony_ci switch (tmp) { 4488c2ecf20Sopenharmony_ci case 0: 4498c2ecf20Sopenharmony_ci case 3: 4508c2ecf20Sopenharmony_ci case 4: 4518c2ecf20Sopenharmony_ci case 5: 4528c2ecf20Sopenharmony_ci case 6: 4538c2ecf20Sopenharmony_ci case 7: 4548c2ecf20Sopenharmony_ci /* 1D/2D */ 4558c2ecf20Sopenharmony_ci track->textures[i].tex_coord_type = 0; 4568c2ecf20Sopenharmony_ci break; 4578c2ecf20Sopenharmony_ci case 1: 4588c2ecf20Sopenharmony_ci /* CUBE */ 4598c2ecf20Sopenharmony_ci track->textures[i].tex_coord_type = 2; 4608c2ecf20Sopenharmony_ci break; 4618c2ecf20Sopenharmony_ci case 2: 4628c2ecf20Sopenharmony_ci /* 3D */ 4638c2ecf20Sopenharmony_ci track->textures[i].tex_coord_type = 1; 4648c2ecf20Sopenharmony_ci break; 4658c2ecf20Sopenharmony_ci } 4668c2ecf20Sopenharmony_ci track->tex_dirty = true; 4678c2ecf20Sopenharmony_ci break; 4688c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_0: 4698c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_1: 4708c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_2: 4718c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_3: 4728c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_4: 4738c2ecf20Sopenharmony_ci case R200_PP_TXFORMAT_5: 4748c2ecf20Sopenharmony_ci i = (reg - R200_PP_TXFORMAT_0) / 32; 4758c2ecf20Sopenharmony_ci if (idx_value & R200_TXFORMAT_NON_POWER2) { 4768c2ecf20Sopenharmony_ci track->textures[i].use_pitch = 1; 4778c2ecf20Sopenharmony_ci } else { 4788c2ecf20Sopenharmony_ci track->textures[i].use_pitch = 0; 4798c2ecf20Sopenharmony_ci track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); 4808c2ecf20Sopenharmony_ci track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); 4818c2ecf20Sopenharmony_ci } 4828c2ecf20Sopenharmony_ci if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) 4838c2ecf20Sopenharmony_ci track->textures[i].lookup_disable = true; 4848c2ecf20Sopenharmony_ci switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { 4858c2ecf20Sopenharmony_ci case R200_TXFORMAT_I8: 4868c2ecf20Sopenharmony_ci case R200_TXFORMAT_RGB332: 4878c2ecf20Sopenharmony_ci case R200_TXFORMAT_Y8: 4888c2ecf20Sopenharmony_ci track->textures[i].cpp = 1; 4898c2ecf20Sopenharmony_ci track->textures[i].compress_format = R100_TRACK_COMP_NONE; 4908c2ecf20Sopenharmony_ci break; 4918c2ecf20Sopenharmony_ci case R200_TXFORMAT_AI88: 4928c2ecf20Sopenharmony_ci case R200_TXFORMAT_ARGB1555: 4938c2ecf20Sopenharmony_ci case R200_TXFORMAT_RGB565: 4948c2ecf20Sopenharmony_ci case R200_TXFORMAT_ARGB4444: 4958c2ecf20Sopenharmony_ci case R200_TXFORMAT_VYUY422: 4968c2ecf20Sopenharmony_ci case R200_TXFORMAT_YVYU422: 4978c2ecf20Sopenharmony_ci case R200_TXFORMAT_LDVDU655: 4988c2ecf20Sopenharmony_ci case R200_TXFORMAT_DVDU88: 4998c2ecf20Sopenharmony_ci case R200_TXFORMAT_AVYU4444: 5008c2ecf20Sopenharmony_ci track->textures[i].cpp = 2; 5018c2ecf20Sopenharmony_ci track->textures[i].compress_format = R100_TRACK_COMP_NONE; 5028c2ecf20Sopenharmony_ci break; 5038c2ecf20Sopenharmony_ci case R200_TXFORMAT_ARGB8888: 5048c2ecf20Sopenharmony_ci case R200_TXFORMAT_RGBA8888: 5058c2ecf20Sopenharmony_ci case R200_TXFORMAT_ABGR8888: 5068c2ecf20Sopenharmony_ci case R200_TXFORMAT_BGR111110: 5078c2ecf20Sopenharmony_ci case R200_TXFORMAT_LDVDU8888: 5088c2ecf20Sopenharmony_ci track->textures[i].cpp = 4; 5098c2ecf20Sopenharmony_ci track->textures[i].compress_format = R100_TRACK_COMP_NONE; 5108c2ecf20Sopenharmony_ci break; 5118c2ecf20Sopenharmony_ci case R200_TXFORMAT_DXT1: 5128c2ecf20Sopenharmony_ci track->textures[i].cpp = 1; 5138c2ecf20Sopenharmony_ci track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci case R200_TXFORMAT_DXT23: 5168c2ecf20Sopenharmony_ci case R200_TXFORMAT_DXT45: 5178c2ecf20Sopenharmony_ci track->textures[i].cpp = 1; 5188c2ecf20Sopenharmony_ci track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 5198c2ecf20Sopenharmony_ci break; 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); 5228c2ecf20Sopenharmony_ci track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); 5238c2ecf20Sopenharmony_ci track->tex_dirty = true; 5248c2ecf20Sopenharmony_ci break; 5258c2ecf20Sopenharmony_ci case R200_PP_CUBIC_FACES_0: 5268c2ecf20Sopenharmony_ci case R200_PP_CUBIC_FACES_1: 5278c2ecf20Sopenharmony_ci case R200_PP_CUBIC_FACES_2: 5288c2ecf20Sopenharmony_ci case R200_PP_CUBIC_FACES_3: 5298c2ecf20Sopenharmony_ci case R200_PP_CUBIC_FACES_4: 5308c2ecf20Sopenharmony_ci case R200_PP_CUBIC_FACES_5: 5318c2ecf20Sopenharmony_ci tmp = idx_value; 5328c2ecf20Sopenharmony_ci i = (reg - R200_PP_CUBIC_FACES_0) / 32; 5338c2ecf20Sopenharmony_ci for (face = 0; face < 4; face++) { 5348c2ecf20Sopenharmony_ci track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); 5358c2ecf20Sopenharmony_ci track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); 5368c2ecf20Sopenharmony_ci } 5378c2ecf20Sopenharmony_ci track->tex_dirty = true; 5388c2ecf20Sopenharmony_ci break; 5398c2ecf20Sopenharmony_ci default: 5408c2ecf20Sopenharmony_ci pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx); 5418c2ecf20Sopenharmony_ci return -EINVAL; 5428c2ecf20Sopenharmony_ci } 5438c2ecf20Sopenharmony_ci return 0; 5448c2ecf20Sopenharmony_ci} 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_civoid r200_set_safe_registers(struct radeon_device *rdev) 5478c2ecf20Sopenharmony_ci{ 5488c2ecf20Sopenharmony_ci rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; 5498c2ecf20Sopenharmony_ci rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); 5508c2ecf20Sopenharmony_ci} 551