1 1.1 riastrad /* $NetBSD: radeon_r200.c,v 1.2 2021/12/18 23:45:43 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2008 Advanced Micro Devices, Inc. 5 1.1 riastrad * Copyright 2008 Red Hat Inc. 6 1.1 riastrad * Copyright 2009 Jerome Glisse. 7 1.1 riastrad * 8 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 9 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 10 1.1 riastrad * to deal in the Software without restriction, including without limitation 11 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 13 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 14 1.1 riastrad * 15 1.1 riastrad * The above copyright notice and this permission notice shall be included in 16 1.1 riastrad * all copies or substantial portions of the Software. 17 1.1 riastrad * 18 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 1.1 riastrad * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 1.1 riastrad * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 1.1 riastrad * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 1.1 riastrad * OTHER DEALINGS IN THE SOFTWARE. 25 1.1 riastrad * 26 1.1 riastrad * Authors: Dave Airlie 27 1.1 riastrad * Alex Deucher 28 1.1 riastrad * Jerome Glisse 29 1.1 riastrad */ 30 1.2 riastrad 31 1.1 riastrad #include <sys/cdefs.h> 32 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: radeon_r200.c,v 1.2 2021/12/18 23:45:43 riastradh Exp $"); 33 1.1 riastrad 34 1.1 riastrad #include <drm/radeon_drm.h> 35 1.1 riastrad #include "radeon_reg.h" 36 1.1 riastrad #include "radeon.h" 37 1.1 riastrad #include "radeon_asic.h" 38 1.1 riastrad 39 1.1 riastrad #include "r100d.h" 40 1.1 riastrad #include "r200_reg_safe.h" 41 1.1 riastrad 42 1.1 riastrad #include "r100_track.h" 43 1.1 riastrad 44 1.1 riastrad static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) 45 1.1 riastrad { 46 1.1 riastrad int vtx_size, i; 47 1.1 riastrad vtx_size = 2; 48 1.1 riastrad 49 1.1 riastrad if (vtx_fmt_0 & R200_VTX_Z0) 50 1.1 riastrad vtx_size++; 51 1.1 riastrad if (vtx_fmt_0 & R200_VTX_W0) 52 1.1 riastrad vtx_size++; 53 1.1 riastrad /* blend weight */ 54 1.1 riastrad if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) 55 1.1 riastrad vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; 56 1.1 riastrad if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) 57 1.1 riastrad vtx_size++; 58 1.1 riastrad if (vtx_fmt_0 & R200_VTX_N0) 59 1.1 riastrad vtx_size += 3; 60 1.1 riastrad if (vtx_fmt_0 & R200_VTX_POINT_SIZE) 61 1.1 riastrad vtx_size++; 62 1.1 riastrad if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) 63 1.1 riastrad vtx_size++; 64 1.1 riastrad if (vtx_fmt_0 & R200_VTX_SHININESS_0) 65 1.1 riastrad vtx_size++; 66 1.1 riastrad if (vtx_fmt_0 & R200_VTX_SHININESS_1) 67 1.1 riastrad vtx_size++; 68 1.1 riastrad for (i = 0; i < 8; i++) { 69 1.1 riastrad int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; 70 1.1 riastrad switch (color_size) { 71 1.1 riastrad case 0: break; 72 1.1 riastrad case 1: vtx_size++; break; 73 1.1 riastrad case 2: vtx_size += 3; break; 74 1.1 riastrad case 3: vtx_size += 4; break; 75 1.1 riastrad } 76 1.1 riastrad } 77 1.1 riastrad if (vtx_fmt_0 & R200_VTX_XY1) 78 1.1 riastrad vtx_size += 2; 79 1.1 riastrad if (vtx_fmt_0 & R200_VTX_Z1) 80 1.1 riastrad vtx_size++; 81 1.1 riastrad if (vtx_fmt_0 & R200_VTX_W1) 82 1.1 riastrad vtx_size++; 83 1.1 riastrad if (vtx_fmt_0 & R200_VTX_N1) 84 1.1 riastrad vtx_size += 3; 85 1.1 riastrad return vtx_size; 86 1.1 riastrad } 87 1.1 riastrad 88 1.1 riastrad struct radeon_fence *r200_copy_dma(struct radeon_device *rdev, 89 1.1 riastrad uint64_t src_offset, 90 1.1 riastrad uint64_t dst_offset, 91 1.1 riastrad unsigned num_gpu_pages, 92 1.2 riastrad struct dma_resv *resv) 93 1.1 riastrad { 94 1.1 riastrad struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 95 1.1 riastrad struct radeon_fence *fence; 96 1.1 riastrad uint32_t size; 97 1.1 riastrad uint32_t cur_size; 98 1.1 riastrad int i, num_loops; 99 1.1 riastrad int r = 0; 100 1.1 riastrad 101 1.1 riastrad /* radeon pitch is /64 */ 102 1.1 riastrad size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; 103 1.1 riastrad num_loops = DIV_ROUND_UP(size, 0x1FFFFF); 104 1.1 riastrad r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); 105 1.1 riastrad if (r) { 106 1.1 riastrad DRM_ERROR("radeon: moving bo (%d).\n", r); 107 1.1 riastrad return ERR_PTR(r); 108 1.1 riastrad } 109 1.1 riastrad /* Must wait for 2D idle & clean before DMA or hangs might happen */ 110 1.1 riastrad radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 111 1.1 riastrad radeon_ring_write(ring, (1 << 16)); 112 1.1 riastrad for (i = 0; i < num_loops; i++) { 113 1.1 riastrad cur_size = size; 114 1.1 riastrad if (cur_size > 0x1FFFFF) { 115 1.1 riastrad cur_size = 0x1FFFFF; 116 1.1 riastrad } 117 1.1 riastrad size -= cur_size; 118 1.1 riastrad radeon_ring_write(ring, PACKET0(0x720, 2)); 119 1.1 riastrad radeon_ring_write(ring, src_offset); 120 1.1 riastrad radeon_ring_write(ring, dst_offset); 121 1.1 riastrad radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30)); 122 1.1 riastrad src_offset += cur_size; 123 1.1 riastrad dst_offset += cur_size; 124 1.1 riastrad } 125 1.1 riastrad radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 126 1.1 riastrad radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); 127 1.1 riastrad r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); 128 1.1 riastrad if (r) { 129 1.1 riastrad radeon_ring_unlock_undo(rdev, ring); 130 1.1 riastrad return ERR_PTR(r); 131 1.1 riastrad } 132 1.1 riastrad radeon_ring_unlock_commit(rdev, ring, false); 133 1.1 riastrad return fence; 134 1.1 riastrad } 135 1.1 riastrad 136 1.1 riastrad 137 1.1 riastrad static int r200_get_vtx_size_1(uint32_t vtx_fmt_1) 138 1.1 riastrad { 139 1.1 riastrad int vtx_size, i, tex_size; 140 1.1 riastrad vtx_size = 0; 141 1.1 riastrad for (i = 0; i < 6; i++) { 142 1.1 riastrad tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; 143 1.1 riastrad if (tex_size > 4) 144 1.1 riastrad continue; 145 1.1 riastrad vtx_size += tex_size; 146 1.1 riastrad } 147 1.1 riastrad return vtx_size; 148 1.1 riastrad } 149 1.1 riastrad 150 1.1 riastrad int r200_packet0_check(struct radeon_cs_parser *p, 151 1.1 riastrad struct radeon_cs_packet *pkt, 152 1.1 riastrad unsigned idx, unsigned reg) 153 1.1 riastrad { 154 1.1 riastrad struct radeon_bo_list *reloc; 155 1.1 riastrad struct r100_cs_track *track; 156 1.1 riastrad volatile uint32_t *ib; 157 1.1 riastrad uint32_t tmp; 158 1.1 riastrad int r; 159 1.1 riastrad int i; 160 1.1 riastrad int face; 161 1.1 riastrad u32 tile_flags = 0; 162 1.1 riastrad u32 idx_value; 163 1.1 riastrad 164 1.1 riastrad ib = p->ib.ptr; 165 1.1 riastrad track = (struct r100_cs_track *)p->track; 166 1.1 riastrad idx_value = radeon_get_ib_value(p, idx); 167 1.1 riastrad switch (reg) { 168 1.1 riastrad case RADEON_CRTC_GUI_TRIG_VLINE: 169 1.1 riastrad r = r100_cs_packet_parse_vline(p); 170 1.1 riastrad if (r) { 171 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 172 1.1 riastrad idx, reg); 173 1.1 riastrad radeon_cs_dump_packet(p, pkt); 174 1.1 riastrad return r; 175 1.1 riastrad } 176 1.1 riastrad break; 177 1.1 riastrad /* FIXME: only allow PACKET3 blit? easier to check for out of 178 1.1 riastrad * range access */ 179 1.1 riastrad case RADEON_DST_PITCH_OFFSET: 180 1.1 riastrad case RADEON_SRC_PITCH_OFFSET: 181 1.1 riastrad r = r100_reloc_pitch_offset(p, pkt, idx, reg); 182 1.1 riastrad if (r) 183 1.1 riastrad return r; 184 1.1 riastrad break; 185 1.1 riastrad case RADEON_RB3D_DEPTHOFFSET: 186 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 187 1.1 riastrad if (r) { 188 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 189 1.1 riastrad idx, reg); 190 1.1 riastrad radeon_cs_dump_packet(p, pkt); 191 1.1 riastrad return r; 192 1.1 riastrad } 193 1.1 riastrad track->zb.robj = reloc->robj; 194 1.1 riastrad track->zb.offset = idx_value; 195 1.1 riastrad track->zb_dirty = true; 196 1.1 riastrad ib[idx] = idx_value + ((u32)reloc->gpu_offset); 197 1.1 riastrad break; 198 1.1 riastrad case RADEON_RB3D_COLOROFFSET: 199 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 200 1.1 riastrad if (r) { 201 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 202 1.1 riastrad idx, reg); 203 1.1 riastrad radeon_cs_dump_packet(p, pkt); 204 1.1 riastrad return r; 205 1.1 riastrad } 206 1.1 riastrad track->cb[0].robj = reloc->robj; 207 1.1 riastrad track->cb[0].offset = idx_value; 208 1.1 riastrad track->cb_dirty = true; 209 1.1 riastrad ib[idx] = idx_value + ((u32)reloc->gpu_offset); 210 1.1 riastrad break; 211 1.1 riastrad case R200_PP_TXOFFSET_0: 212 1.1 riastrad case R200_PP_TXOFFSET_1: 213 1.1 riastrad case R200_PP_TXOFFSET_2: 214 1.1 riastrad case R200_PP_TXOFFSET_3: 215 1.1 riastrad case R200_PP_TXOFFSET_4: 216 1.1 riastrad case R200_PP_TXOFFSET_5: 217 1.1 riastrad i = (reg - R200_PP_TXOFFSET_0) / 24; 218 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 219 1.1 riastrad if (r) { 220 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 221 1.1 riastrad idx, reg); 222 1.1 riastrad radeon_cs_dump_packet(p, pkt); 223 1.1 riastrad return r; 224 1.1 riastrad } 225 1.1 riastrad if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 226 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MACRO) 227 1.1 riastrad tile_flags |= R200_TXO_MACRO_TILE; 228 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MICRO) 229 1.1 riastrad tile_flags |= R200_TXO_MICRO_TILE; 230 1.1 riastrad 231 1.1 riastrad tmp = idx_value & ~(0x7 << 2); 232 1.1 riastrad tmp |= tile_flags; 233 1.1 riastrad ib[idx] = tmp + ((u32)reloc->gpu_offset); 234 1.1 riastrad } else 235 1.1 riastrad ib[idx] = idx_value + ((u32)reloc->gpu_offset); 236 1.1 riastrad track->textures[i].robj = reloc->robj; 237 1.1 riastrad track->tex_dirty = true; 238 1.1 riastrad break; 239 1.1 riastrad case R200_PP_CUBIC_OFFSET_F1_0: 240 1.1 riastrad case R200_PP_CUBIC_OFFSET_F2_0: 241 1.1 riastrad case R200_PP_CUBIC_OFFSET_F3_0: 242 1.1 riastrad case R200_PP_CUBIC_OFFSET_F4_0: 243 1.1 riastrad case R200_PP_CUBIC_OFFSET_F5_0: 244 1.1 riastrad case R200_PP_CUBIC_OFFSET_F1_1: 245 1.1 riastrad case R200_PP_CUBIC_OFFSET_F2_1: 246 1.1 riastrad case R200_PP_CUBIC_OFFSET_F3_1: 247 1.1 riastrad case R200_PP_CUBIC_OFFSET_F4_1: 248 1.1 riastrad case R200_PP_CUBIC_OFFSET_F5_1: 249 1.1 riastrad case R200_PP_CUBIC_OFFSET_F1_2: 250 1.1 riastrad case R200_PP_CUBIC_OFFSET_F2_2: 251 1.1 riastrad case R200_PP_CUBIC_OFFSET_F3_2: 252 1.1 riastrad case R200_PP_CUBIC_OFFSET_F4_2: 253 1.1 riastrad case R200_PP_CUBIC_OFFSET_F5_2: 254 1.1 riastrad case R200_PP_CUBIC_OFFSET_F1_3: 255 1.1 riastrad case R200_PP_CUBIC_OFFSET_F2_3: 256 1.1 riastrad case R200_PP_CUBIC_OFFSET_F3_3: 257 1.1 riastrad case R200_PP_CUBIC_OFFSET_F4_3: 258 1.1 riastrad case R200_PP_CUBIC_OFFSET_F5_3: 259 1.1 riastrad case R200_PP_CUBIC_OFFSET_F1_4: 260 1.1 riastrad case R200_PP_CUBIC_OFFSET_F2_4: 261 1.1 riastrad case R200_PP_CUBIC_OFFSET_F3_4: 262 1.1 riastrad case R200_PP_CUBIC_OFFSET_F4_4: 263 1.1 riastrad case R200_PP_CUBIC_OFFSET_F5_4: 264 1.1 riastrad case R200_PP_CUBIC_OFFSET_F1_5: 265 1.1 riastrad case R200_PP_CUBIC_OFFSET_F2_5: 266 1.1 riastrad case R200_PP_CUBIC_OFFSET_F3_5: 267 1.1 riastrad case R200_PP_CUBIC_OFFSET_F4_5: 268 1.1 riastrad case R200_PP_CUBIC_OFFSET_F5_5: 269 1.1 riastrad i = (reg - R200_PP_TXOFFSET_0) / 24; 270 1.1 riastrad face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; 271 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 272 1.1 riastrad if (r) { 273 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 274 1.1 riastrad idx, reg); 275 1.1 riastrad radeon_cs_dump_packet(p, pkt); 276 1.1 riastrad return r; 277 1.1 riastrad } 278 1.1 riastrad track->textures[i].cube_info[face - 1].offset = idx_value; 279 1.1 riastrad ib[idx] = idx_value + ((u32)reloc->gpu_offset); 280 1.1 riastrad track->textures[i].cube_info[face - 1].robj = reloc->robj; 281 1.1 riastrad track->tex_dirty = true; 282 1.1 riastrad break; 283 1.1 riastrad case RADEON_RE_WIDTH_HEIGHT: 284 1.1 riastrad track->maxy = ((idx_value >> 16) & 0x7FF); 285 1.1 riastrad track->cb_dirty = true; 286 1.1 riastrad track->zb_dirty = true; 287 1.1 riastrad break; 288 1.1 riastrad case RADEON_RB3D_COLORPITCH: 289 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 290 1.1 riastrad if (r) { 291 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 292 1.1 riastrad idx, reg); 293 1.1 riastrad radeon_cs_dump_packet(p, pkt); 294 1.1 riastrad return r; 295 1.1 riastrad } 296 1.1 riastrad 297 1.1 riastrad if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 298 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MACRO) 299 1.1 riastrad tile_flags |= RADEON_COLOR_TILE_ENABLE; 300 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MICRO) 301 1.1 riastrad tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; 302 1.1 riastrad 303 1.1 riastrad tmp = idx_value & ~(0x7 << 16); 304 1.1 riastrad tmp |= tile_flags; 305 1.1 riastrad ib[idx] = tmp; 306 1.1 riastrad } else 307 1.1 riastrad ib[idx] = idx_value; 308 1.1 riastrad 309 1.1 riastrad track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; 310 1.1 riastrad track->cb_dirty = true; 311 1.1 riastrad break; 312 1.1 riastrad case RADEON_RB3D_DEPTHPITCH: 313 1.1 riastrad track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; 314 1.1 riastrad track->zb_dirty = true; 315 1.1 riastrad break; 316 1.1 riastrad case RADEON_RB3D_CNTL: 317 1.1 riastrad switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { 318 1.1 riastrad case 7: 319 1.1 riastrad case 8: 320 1.1 riastrad case 9: 321 1.1 riastrad case 11: 322 1.1 riastrad case 12: 323 1.1 riastrad track->cb[0].cpp = 1; 324 1.1 riastrad break; 325 1.1 riastrad case 3: 326 1.1 riastrad case 4: 327 1.1 riastrad case 15: 328 1.1 riastrad track->cb[0].cpp = 2; 329 1.1 riastrad break; 330 1.1 riastrad case 6: 331 1.1 riastrad track->cb[0].cpp = 4; 332 1.1 riastrad break; 333 1.1 riastrad default: 334 1.1 riastrad DRM_ERROR("Invalid color buffer format (%d) !\n", 335 1.1 riastrad ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); 336 1.1 riastrad return -EINVAL; 337 1.1 riastrad } 338 1.1 riastrad if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { 339 1.1 riastrad DRM_ERROR("No support for depth xy offset in kms\n"); 340 1.1 riastrad return -EINVAL; 341 1.1 riastrad } 342 1.1 riastrad 343 1.1 riastrad track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); 344 1.1 riastrad track->cb_dirty = true; 345 1.1 riastrad track->zb_dirty = true; 346 1.1 riastrad break; 347 1.1 riastrad case RADEON_RB3D_ZSTENCILCNTL: 348 1.1 riastrad switch (idx_value & 0xf) { 349 1.1 riastrad case 0: 350 1.1 riastrad track->zb.cpp = 2; 351 1.1 riastrad break; 352 1.1 riastrad case 2: 353 1.1 riastrad case 3: 354 1.1 riastrad case 4: 355 1.1 riastrad case 5: 356 1.1 riastrad case 9: 357 1.1 riastrad case 11: 358 1.1 riastrad track->zb.cpp = 4; 359 1.1 riastrad break; 360 1.1 riastrad default: 361 1.1 riastrad break; 362 1.1 riastrad } 363 1.1 riastrad track->zb_dirty = true; 364 1.1 riastrad break; 365 1.1 riastrad case RADEON_RB3D_ZPASS_ADDR: 366 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 367 1.1 riastrad if (r) { 368 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 369 1.1 riastrad idx, reg); 370 1.1 riastrad radeon_cs_dump_packet(p, pkt); 371 1.1 riastrad return r; 372 1.1 riastrad } 373 1.1 riastrad ib[idx] = idx_value + ((u32)reloc->gpu_offset); 374 1.1 riastrad break; 375 1.1 riastrad case RADEON_PP_CNTL: 376 1.1 riastrad { 377 1.1 riastrad uint32_t temp = idx_value >> 4; 378 1.1 riastrad for (i = 0; i < track->num_texture; i++) 379 1.1 riastrad track->textures[i].enabled = !!(temp & (1 << i)); 380 1.1 riastrad track->tex_dirty = true; 381 1.1 riastrad } 382 1.1 riastrad break; 383 1.1 riastrad case RADEON_SE_VF_CNTL: 384 1.1 riastrad track->vap_vf_cntl = idx_value; 385 1.1 riastrad break; 386 1.1 riastrad case 0x210c: 387 1.1 riastrad /* VAP_VF_MAX_VTX_INDX */ 388 1.1 riastrad track->max_indx = idx_value & 0x00FFFFFFUL; 389 1.1 riastrad break; 390 1.1 riastrad case R200_SE_VTX_FMT_0: 391 1.1 riastrad track->vtx_size = r200_get_vtx_size_0(idx_value); 392 1.1 riastrad break; 393 1.1 riastrad case R200_SE_VTX_FMT_1: 394 1.1 riastrad track->vtx_size += r200_get_vtx_size_1(idx_value); 395 1.1 riastrad break; 396 1.1 riastrad case R200_PP_TXSIZE_0: 397 1.1 riastrad case R200_PP_TXSIZE_1: 398 1.1 riastrad case R200_PP_TXSIZE_2: 399 1.1 riastrad case R200_PP_TXSIZE_3: 400 1.1 riastrad case R200_PP_TXSIZE_4: 401 1.1 riastrad case R200_PP_TXSIZE_5: 402 1.1 riastrad i = (reg - R200_PP_TXSIZE_0) / 32; 403 1.1 riastrad track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; 404 1.1 riastrad track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; 405 1.1 riastrad track->tex_dirty = true; 406 1.1 riastrad break; 407 1.1 riastrad case R200_PP_TXPITCH_0: 408 1.1 riastrad case R200_PP_TXPITCH_1: 409 1.1 riastrad case R200_PP_TXPITCH_2: 410 1.1 riastrad case R200_PP_TXPITCH_3: 411 1.1 riastrad case R200_PP_TXPITCH_4: 412 1.1 riastrad case R200_PP_TXPITCH_5: 413 1.1 riastrad i = (reg - R200_PP_TXPITCH_0) / 32; 414 1.1 riastrad track->textures[i].pitch = idx_value + 32; 415 1.1 riastrad track->tex_dirty = true; 416 1.1 riastrad break; 417 1.1 riastrad case R200_PP_TXFILTER_0: 418 1.1 riastrad case R200_PP_TXFILTER_1: 419 1.1 riastrad case R200_PP_TXFILTER_2: 420 1.1 riastrad case R200_PP_TXFILTER_3: 421 1.1 riastrad case R200_PP_TXFILTER_4: 422 1.1 riastrad case R200_PP_TXFILTER_5: 423 1.1 riastrad i = (reg - R200_PP_TXFILTER_0) / 32; 424 1.1 riastrad track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) 425 1.1 riastrad >> R200_MAX_MIP_LEVEL_SHIFT); 426 1.1 riastrad tmp = (idx_value >> 23) & 0x7; 427 1.1 riastrad if (tmp == 2 || tmp == 6) 428 1.1 riastrad track->textures[i].roundup_w = false; 429 1.1 riastrad tmp = (idx_value >> 27) & 0x7; 430 1.1 riastrad if (tmp == 2 || tmp == 6) 431 1.1 riastrad track->textures[i].roundup_h = false; 432 1.1 riastrad track->tex_dirty = true; 433 1.1 riastrad break; 434 1.1 riastrad case R200_PP_TXMULTI_CTL_0: 435 1.1 riastrad case R200_PP_TXMULTI_CTL_1: 436 1.1 riastrad case R200_PP_TXMULTI_CTL_2: 437 1.1 riastrad case R200_PP_TXMULTI_CTL_3: 438 1.1 riastrad case R200_PP_TXMULTI_CTL_4: 439 1.1 riastrad case R200_PP_TXMULTI_CTL_5: 440 1.1 riastrad i = (reg - R200_PP_TXMULTI_CTL_0) / 32; 441 1.1 riastrad break; 442 1.1 riastrad case R200_PP_TXFORMAT_X_0: 443 1.1 riastrad case R200_PP_TXFORMAT_X_1: 444 1.1 riastrad case R200_PP_TXFORMAT_X_2: 445 1.1 riastrad case R200_PP_TXFORMAT_X_3: 446 1.1 riastrad case R200_PP_TXFORMAT_X_4: 447 1.1 riastrad case R200_PP_TXFORMAT_X_5: 448 1.1 riastrad i = (reg - R200_PP_TXFORMAT_X_0) / 32; 449 1.1 riastrad track->textures[i].txdepth = idx_value & 0x7; 450 1.1 riastrad tmp = (idx_value >> 16) & 0x3; 451 1.1 riastrad /* 2D, 3D, CUBE */ 452 1.1 riastrad switch (tmp) { 453 1.1 riastrad case 0: 454 1.1 riastrad case 3: 455 1.1 riastrad case 4: 456 1.1 riastrad case 5: 457 1.1 riastrad case 6: 458 1.1 riastrad case 7: 459 1.1 riastrad /* 1D/2D */ 460 1.1 riastrad track->textures[i].tex_coord_type = 0; 461 1.1 riastrad break; 462 1.1 riastrad case 1: 463 1.1 riastrad /* CUBE */ 464 1.1 riastrad track->textures[i].tex_coord_type = 2; 465 1.1 riastrad break; 466 1.1 riastrad case 2: 467 1.1 riastrad /* 3D */ 468 1.1 riastrad track->textures[i].tex_coord_type = 1; 469 1.1 riastrad break; 470 1.1 riastrad } 471 1.1 riastrad track->tex_dirty = true; 472 1.1 riastrad break; 473 1.1 riastrad case R200_PP_TXFORMAT_0: 474 1.1 riastrad case R200_PP_TXFORMAT_1: 475 1.1 riastrad case R200_PP_TXFORMAT_2: 476 1.1 riastrad case R200_PP_TXFORMAT_3: 477 1.1 riastrad case R200_PP_TXFORMAT_4: 478 1.1 riastrad case R200_PP_TXFORMAT_5: 479 1.1 riastrad i = (reg - R200_PP_TXFORMAT_0) / 32; 480 1.1 riastrad if (idx_value & R200_TXFORMAT_NON_POWER2) { 481 1.1 riastrad track->textures[i].use_pitch = 1; 482 1.1 riastrad } else { 483 1.1 riastrad track->textures[i].use_pitch = 0; 484 1.2 riastrad track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); 485 1.2 riastrad track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); 486 1.1 riastrad } 487 1.1 riastrad if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) 488 1.1 riastrad track->textures[i].lookup_disable = true; 489 1.1 riastrad switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { 490 1.1 riastrad case R200_TXFORMAT_I8: 491 1.1 riastrad case R200_TXFORMAT_RGB332: 492 1.1 riastrad case R200_TXFORMAT_Y8: 493 1.1 riastrad track->textures[i].cpp = 1; 494 1.1 riastrad track->textures[i].compress_format = R100_TRACK_COMP_NONE; 495 1.1 riastrad break; 496 1.1 riastrad case R200_TXFORMAT_AI88: 497 1.1 riastrad case R200_TXFORMAT_ARGB1555: 498 1.1 riastrad case R200_TXFORMAT_RGB565: 499 1.1 riastrad case R200_TXFORMAT_ARGB4444: 500 1.1 riastrad case R200_TXFORMAT_VYUY422: 501 1.1 riastrad case R200_TXFORMAT_YVYU422: 502 1.1 riastrad case R200_TXFORMAT_LDVDU655: 503 1.1 riastrad case R200_TXFORMAT_DVDU88: 504 1.1 riastrad case R200_TXFORMAT_AVYU4444: 505 1.1 riastrad track->textures[i].cpp = 2; 506 1.1 riastrad track->textures[i].compress_format = R100_TRACK_COMP_NONE; 507 1.1 riastrad break; 508 1.1 riastrad case R200_TXFORMAT_ARGB8888: 509 1.1 riastrad case R200_TXFORMAT_RGBA8888: 510 1.1 riastrad case R200_TXFORMAT_ABGR8888: 511 1.1 riastrad case R200_TXFORMAT_BGR111110: 512 1.1 riastrad case R200_TXFORMAT_LDVDU8888: 513 1.1 riastrad track->textures[i].cpp = 4; 514 1.1 riastrad track->textures[i].compress_format = R100_TRACK_COMP_NONE; 515 1.1 riastrad break; 516 1.1 riastrad case R200_TXFORMAT_DXT1: 517 1.1 riastrad track->textures[i].cpp = 1; 518 1.1 riastrad track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 519 1.1 riastrad break; 520 1.1 riastrad case R200_TXFORMAT_DXT23: 521 1.1 riastrad case R200_TXFORMAT_DXT45: 522 1.1 riastrad track->textures[i].cpp = 1; 523 1.1 riastrad track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 524 1.1 riastrad break; 525 1.1 riastrad } 526 1.1 riastrad track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); 527 1.1 riastrad track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); 528 1.1 riastrad track->tex_dirty = true; 529 1.1 riastrad break; 530 1.1 riastrad case R200_PP_CUBIC_FACES_0: 531 1.1 riastrad case R200_PP_CUBIC_FACES_1: 532 1.1 riastrad case R200_PP_CUBIC_FACES_2: 533 1.1 riastrad case R200_PP_CUBIC_FACES_3: 534 1.1 riastrad case R200_PP_CUBIC_FACES_4: 535 1.1 riastrad case R200_PP_CUBIC_FACES_5: 536 1.1 riastrad tmp = idx_value; 537 1.1 riastrad i = (reg - R200_PP_CUBIC_FACES_0) / 32; 538 1.1 riastrad for (face = 0; face < 4; face++) { 539 1.1 riastrad track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); 540 1.1 riastrad track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); 541 1.1 riastrad } 542 1.1 riastrad track->tex_dirty = true; 543 1.1 riastrad break; 544 1.1 riastrad default: 545 1.2 riastrad pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx); 546 1.1 riastrad return -EINVAL; 547 1.1 riastrad } 548 1.1 riastrad return 0; 549 1.1 riastrad } 550 1.1 riastrad 551 1.1 riastrad void r200_set_safe_registers(struct radeon_device *rdev) 552 1.1 riastrad { 553 1.1 riastrad rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; 554 1.1 riastrad rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); 555 1.1 riastrad } 556