1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2008 Advanced Micro Devices, Inc. 3254885Sdumbbell * Copyright 2008 Red Hat Inc. 4254885Sdumbbell * Copyright 2009 Jerome Glisse. 5254885Sdumbbell * 6254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 7254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 8254885Sdumbbell * to deal in the Software without restriction, including without limitation 9254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 11254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 12254885Sdumbbell * 13254885Sdumbbell * The above copyright notice and this permission notice shall be included in 14254885Sdumbbell * all copies or substantial portions of the Software. 15254885Sdumbbell * 16254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 23254885Sdumbbell * 24254885Sdumbbell * Authors: Dave Airlie 25254885Sdumbbell * Alex Deucher 26254885Sdumbbell * Jerome Glisse 27254885Sdumbbell */ 28254885Sdumbbell 29254885Sdumbbell#include <sys/cdefs.h> 30254885Sdumbbell__FBSDID("$FreeBSD: releng/10.3/sys/dev/drm2/radeon/r200.c 282199 2015-04-28 19:35:05Z dumbbell $"); 31254885Sdumbbell 32254885Sdumbbell#include <dev/drm2/drmP.h> 33254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 34254885Sdumbbell#include "radeon_reg.h" 35254885Sdumbbell#include "radeon.h" 36254885Sdumbbell#include "radeon_asic.h" 37254885Sdumbbell 38254885Sdumbbell#include "r100d.h" 39254885Sdumbbell#include "r200_reg_safe.h" 40254885Sdumbbell 41254885Sdumbbell#include "r100_track.h" 42254885Sdumbbell 43254885Sdumbbellstatic int r200_get_vtx_size_0(uint32_t vtx_fmt_0) 44254885Sdumbbell{ 45254885Sdumbbell int vtx_size, i; 46254885Sdumbbell vtx_size = 2; 47254885Sdumbbell 48254885Sdumbbell if (vtx_fmt_0 & R200_VTX_Z0) 49254885Sdumbbell vtx_size++; 50254885Sdumbbell if (vtx_fmt_0 & R200_VTX_W0) 51254885Sdumbbell vtx_size++; 52254885Sdumbbell /* blend weight */ 53254885Sdumbbell if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) 54254885Sdumbbell vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; 55254885Sdumbbell if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) 56254885Sdumbbell vtx_size++; 57254885Sdumbbell if (vtx_fmt_0 & R200_VTX_N0) 58254885Sdumbbell vtx_size += 3; 59254885Sdumbbell if (vtx_fmt_0 & R200_VTX_POINT_SIZE) 60254885Sdumbbell vtx_size++; 61254885Sdumbbell if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) 62254885Sdumbbell vtx_size++; 63254885Sdumbbell if (vtx_fmt_0 & R200_VTX_SHININESS_0) 64254885Sdumbbell vtx_size++; 65254885Sdumbbell if (vtx_fmt_0 & R200_VTX_SHININESS_1) 66254885Sdumbbell vtx_size++; 67254885Sdumbbell for (i = 0; i < 8; i++) { 68254885Sdumbbell int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; 69254885Sdumbbell switch (color_size) { 70254885Sdumbbell case 0: break; 71254885Sdumbbell case 1: vtx_size++; break; 72254885Sdumbbell case 2: vtx_size += 3; break; 73254885Sdumbbell case 3: vtx_size += 4; break; 74254885Sdumbbell } 75254885Sdumbbell } 76254885Sdumbbell if (vtx_fmt_0 & R200_VTX_XY1) 77254885Sdumbbell vtx_size += 2; 78254885Sdumbbell if (vtx_fmt_0 & R200_VTX_Z1) 79254885Sdumbbell vtx_size++; 80254885Sdumbbell if (vtx_fmt_0 & R200_VTX_W1) 81254885Sdumbbell vtx_size++; 82254885Sdumbbell if (vtx_fmt_0 & R200_VTX_N1) 83254885Sdumbbell vtx_size += 3; 84254885Sdumbbell return vtx_size; 85254885Sdumbbell} 86254885Sdumbbell 87254885Sdumbbellint r200_copy_dma(struct radeon_device *rdev, 88254885Sdumbbell uint64_t src_offset, 89254885Sdumbbell uint64_t dst_offset, 90254885Sdumbbell unsigned num_gpu_pages, 91254885Sdumbbell struct radeon_fence **fence) 92254885Sdumbbell{ 93254885Sdumbbell struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 94254885Sdumbbell uint32_t size; 95254885Sdumbbell uint32_t cur_size; 96254885Sdumbbell int i, num_loops; 97254885Sdumbbell int r = 0; 98254885Sdumbbell 99254885Sdumbbell /* radeon pitch is /64 */ 100254885Sdumbbell size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; 101254885Sdumbbell num_loops = DIV_ROUND_UP(size, 0x1FFFFF); 102254885Sdumbbell r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); 103254885Sdumbbell if (r) { 104254885Sdumbbell DRM_ERROR("radeon: moving bo (%d).\n", r); 105254885Sdumbbell return r; 106254885Sdumbbell } 107254885Sdumbbell /* Must wait for 2D idle & clean before DMA or hangs might happen */ 108254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 109254885Sdumbbell radeon_ring_write(ring, (1 << 16)); 110254885Sdumbbell for (i = 0; i < num_loops; i++) { 111254885Sdumbbell cur_size = size; 112254885Sdumbbell if (cur_size > 0x1FFFFF) { 113254885Sdumbbell cur_size = 0x1FFFFF; 114254885Sdumbbell } 115254885Sdumbbell size -= cur_size; 116254885Sdumbbell radeon_ring_write(ring, PACKET0(0x720, 2)); 117254885Sdumbbell radeon_ring_write(ring, src_offset); 118254885Sdumbbell radeon_ring_write(ring, dst_offset); 119261455Seadler radeon_ring_write(ring, cur_size | (1U << 31) | (1 << 30)); 120254885Sdumbbell src_offset += cur_size; 121254885Sdumbbell dst_offset += cur_size; 122254885Sdumbbell } 123254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 124254885Sdumbbell radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); 125254885Sdumbbell if (fence) { 126254885Sdumbbell r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); 127254885Sdumbbell } 128254885Sdumbbell radeon_ring_unlock_commit(rdev, ring); 129254885Sdumbbell return r; 130254885Sdumbbell} 131254885Sdumbbell 132254885Sdumbbell 133254885Sdumbbellstatic int r200_get_vtx_size_1(uint32_t vtx_fmt_1) 134254885Sdumbbell{ 135254885Sdumbbell int vtx_size, i, tex_size; 136254885Sdumbbell vtx_size = 0; 137254885Sdumbbell for (i = 0; i < 6; i++) { 138254885Sdumbbell tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; 139254885Sdumbbell if (tex_size > 4) 140254885Sdumbbell continue; 141254885Sdumbbell vtx_size += tex_size; 142254885Sdumbbell } 143254885Sdumbbell return vtx_size; 144254885Sdumbbell} 145254885Sdumbbell 146254885Sdumbbellint r200_packet0_check(struct radeon_cs_parser *p, 147254885Sdumbbell struct radeon_cs_packet *pkt, 148254885Sdumbbell unsigned idx, unsigned reg) 149254885Sdumbbell{ 150254885Sdumbbell struct radeon_cs_reloc *reloc; 151254885Sdumbbell struct r100_cs_track *track; 152254885Sdumbbell volatile uint32_t *ib; 153254885Sdumbbell uint32_t tmp; 154254885Sdumbbell int r; 155254885Sdumbbell int i; 156254885Sdumbbell int face; 157254885Sdumbbell u32 tile_flags = 0; 158254885Sdumbbell u32 idx_value; 159254885Sdumbbell 160254885Sdumbbell ib = p->ib.ptr; 161254885Sdumbbell track = (struct r100_cs_track *)p->track; 162254885Sdumbbell idx_value = radeon_get_ib_value(p, idx); 163254885Sdumbbell switch (reg) { 164254885Sdumbbell case RADEON_CRTC_GUI_TRIG_VLINE: 165254885Sdumbbell r = r100_cs_packet_parse_vline(p); 166254885Sdumbbell if (r) { 167254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 168254885Sdumbbell idx, reg); 169254885Sdumbbell r100_cs_dump_packet(p, pkt); 170254885Sdumbbell return r; 171254885Sdumbbell } 172254885Sdumbbell break; 173254885Sdumbbell /* FIXME: only allow PACKET3 blit? easier to check for out of 174254885Sdumbbell * range access */ 175254885Sdumbbell case RADEON_DST_PITCH_OFFSET: 176254885Sdumbbell case RADEON_SRC_PITCH_OFFSET: 177254885Sdumbbell r = r100_reloc_pitch_offset(p, pkt, idx, reg); 178254885Sdumbbell if (r) 179254885Sdumbbell return r; 180254885Sdumbbell break; 181254885Sdumbbell case RADEON_RB3D_DEPTHOFFSET: 182254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 183254885Sdumbbell if (r) { 184254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 185254885Sdumbbell idx, reg); 186254885Sdumbbell r100_cs_dump_packet(p, pkt); 187254885Sdumbbell return r; 188254885Sdumbbell } 189254885Sdumbbell track->zb.robj = reloc->robj; 190254885Sdumbbell track->zb.offset = idx_value; 191254885Sdumbbell track->zb_dirty = true; 192254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 193254885Sdumbbell break; 194254885Sdumbbell case RADEON_RB3D_COLOROFFSET: 195254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 196254885Sdumbbell if (r) { 197254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 198254885Sdumbbell idx, reg); 199254885Sdumbbell r100_cs_dump_packet(p, pkt); 200254885Sdumbbell return r; 201254885Sdumbbell } 202254885Sdumbbell track->cb[0].robj = reloc->robj; 203254885Sdumbbell track->cb[0].offset = idx_value; 204254885Sdumbbell track->cb_dirty = true; 205254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 206254885Sdumbbell break; 207254885Sdumbbell case R200_PP_TXOFFSET_0: 208254885Sdumbbell case R200_PP_TXOFFSET_1: 209254885Sdumbbell case R200_PP_TXOFFSET_2: 210254885Sdumbbell case R200_PP_TXOFFSET_3: 211254885Sdumbbell case R200_PP_TXOFFSET_4: 212254885Sdumbbell case R200_PP_TXOFFSET_5: 213254885Sdumbbell i = (reg - R200_PP_TXOFFSET_0) / 24; 214254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 215254885Sdumbbell if (r) { 216254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 217254885Sdumbbell idx, reg); 218254885Sdumbbell r100_cs_dump_packet(p, pkt); 219254885Sdumbbell return r; 220254885Sdumbbell } 221254885Sdumbbell if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 222254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 223254885Sdumbbell tile_flags |= R200_TXO_MACRO_TILE; 224254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 225254885Sdumbbell tile_flags |= R200_TXO_MICRO_TILE; 226254885Sdumbbell 227254885Sdumbbell tmp = idx_value & ~(0x7 << 2); 228254885Sdumbbell tmp |= tile_flags; 229254885Sdumbbell ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); 230254885Sdumbbell } else 231254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 232254885Sdumbbell track->textures[i].robj = reloc->robj; 233254885Sdumbbell track->tex_dirty = true; 234254885Sdumbbell break; 235254885Sdumbbell case R200_PP_CUBIC_OFFSET_F1_0: 236254885Sdumbbell case R200_PP_CUBIC_OFFSET_F2_0: 237254885Sdumbbell case R200_PP_CUBIC_OFFSET_F3_0: 238254885Sdumbbell case R200_PP_CUBIC_OFFSET_F4_0: 239254885Sdumbbell case R200_PP_CUBIC_OFFSET_F5_0: 240254885Sdumbbell case R200_PP_CUBIC_OFFSET_F1_1: 241254885Sdumbbell case R200_PP_CUBIC_OFFSET_F2_1: 242254885Sdumbbell case R200_PP_CUBIC_OFFSET_F3_1: 243254885Sdumbbell case R200_PP_CUBIC_OFFSET_F4_1: 244254885Sdumbbell case R200_PP_CUBIC_OFFSET_F5_1: 245254885Sdumbbell case R200_PP_CUBIC_OFFSET_F1_2: 246254885Sdumbbell case R200_PP_CUBIC_OFFSET_F2_2: 247254885Sdumbbell case R200_PP_CUBIC_OFFSET_F3_2: 248254885Sdumbbell case R200_PP_CUBIC_OFFSET_F4_2: 249254885Sdumbbell case R200_PP_CUBIC_OFFSET_F5_2: 250254885Sdumbbell case R200_PP_CUBIC_OFFSET_F1_3: 251254885Sdumbbell case R200_PP_CUBIC_OFFSET_F2_3: 252254885Sdumbbell case R200_PP_CUBIC_OFFSET_F3_3: 253254885Sdumbbell case R200_PP_CUBIC_OFFSET_F4_3: 254254885Sdumbbell case R200_PP_CUBIC_OFFSET_F5_3: 255254885Sdumbbell case R200_PP_CUBIC_OFFSET_F1_4: 256254885Sdumbbell case R200_PP_CUBIC_OFFSET_F2_4: 257254885Sdumbbell case R200_PP_CUBIC_OFFSET_F3_4: 258254885Sdumbbell case R200_PP_CUBIC_OFFSET_F4_4: 259254885Sdumbbell case R200_PP_CUBIC_OFFSET_F5_4: 260254885Sdumbbell case R200_PP_CUBIC_OFFSET_F1_5: 261254885Sdumbbell case R200_PP_CUBIC_OFFSET_F2_5: 262254885Sdumbbell case R200_PP_CUBIC_OFFSET_F3_5: 263254885Sdumbbell case R200_PP_CUBIC_OFFSET_F4_5: 264254885Sdumbbell case R200_PP_CUBIC_OFFSET_F5_5: 265254885Sdumbbell i = (reg - R200_PP_TXOFFSET_0) / 24; 266254885Sdumbbell face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; 267254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 268254885Sdumbbell if (r) { 269254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 270254885Sdumbbell idx, reg); 271254885Sdumbbell r100_cs_dump_packet(p, pkt); 272254885Sdumbbell return r; 273254885Sdumbbell } 274254885Sdumbbell track->textures[i].cube_info[face - 1].offset = idx_value; 275254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 276254885Sdumbbell track->textures[i].cube_info[face - 1].robj = reloc->robj; 277254885Sdumbbell track->tex_dirty = true; 278254885Sdumbbell break; 279254885Sdumbbell case RADEON_RE_WIDTH_HEIGHT: 280254885Sdumbbell track->maxy = ((idx_value >> 16) & 0x7FF); 281254885Sdumbbell track->cb_dirty = true; 282254885Sdumbbell track->zb_dirty = true; 283254885Sdumbbell break; 284254885Sdumbbell case RADEON_RB3D_COLORPITCH: 285254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 286254885Sdumbbell if (r) { 287254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 288254885Sdumbbell idx, reg); 289254885Sdumbbell r100_cs_dump_packet(p, pkt); 290254885Sdumbbell return r; 291254885Sdumbbell } 292254885Sdumbbell 293254885Sdumbbell if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 294254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 295254885Sdumbbell tile_flags |= RADEON_COLOR_TILE_ENABLE; 296254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 297254885Sdumbbell tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; 298254885Sdumbbell 299254885Sdumbbell tmp = idx_value & ~(0x7 << 16); 300254885Sdumbbell tmp |= tile_flags; 301254885Sdumbbell ib[idx] = tmp; 302254885Sdumbbell } else 303254885Sdumbbell ib[idx] = idx_value; 304254885Sdumbbell 305254885Sdumbbell track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; 306254885Sdumbbell track->cb_dirty = true; 307254885Sdumbbell break; 308254885Sdumbbell case RADEON_RB3D_DEPTHPITCH: 309254885Sdumbbell track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; 310254885Sdumbbell track->zb_dirty = true; 311254885Sdumbbell break; 312254885Sdumbbell case RADEON_RB3D_CNTL: 313254885Sdumbbell switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { 314254885Sdumbbell case 7: 315254885Sdumbbell case 8: 316254885Sdumbbell case 9: 317254885Sdumbbell case 11: 318254885Sdumbbell case 12: 319254885Sdumbbell track->cb[0].cpp = 1; 320254885Sdumbbell break; 321254885Sdumbbell case 3: 322254885Sdumbbell case 4: 323254885Sdumbbell case 15: 324254885Sdumbbell track->cb[0].cpp = 2; 325254885Sdumbbell break; 326254885Sdumbbell case 6: 327254885Sdumbbell track->cb[0].cpp = 4; 328254885Sdumbbell break; 329254885Sdumbbell default: 330254885Sdumbbell DRM_ERROR("Invalid color buffer format (%d) !\n", 331254885Sdumbbell ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); 332254885Sdumbbell return -EINVAL; 333254885Sdumbbell } 334254885Sdumbbell if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { 335254885Sdumbbell DRM_ERROR("No support for depth xy offset in kms\n"); 336254885Sdumbbell return -EINVAL; 337254885Sdumbbell } 338254885Sdumbbell 339254885Sdumbbell track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); 340254885Sdumbbell track->cb_dirty = true; 341254885Sdumbbell track->zb_dirty = true; 342254885Sdumbbell break; 343254885Sdumbbell case RADEON_RB3D_ZSTENCILCNTL: 344254885Sdumbbell switch (idx_value & 0xf) { 345254885Sdumbbell case 0: 346254885Sdumbbell track->zb.cpp = 2; 347254885Sdumbbell break; 348254885Sdumbbell case 2: 349254885Sdumbbell case 3: 350254885Sdumbbell case 4: 351254885Sdumbbell case 5: 352254885Sdumbbell case 9: 353254885Sdumbbell case 11: 354254885Sdumbbell track->zb.cpp = 4; 355254885Sdumbbell break; 356254885Sdumbbell default: 357254885Sdumbbell break; 358254885Sdumbbell } 359254885Sdumbbell track->zb_dirty = true; 360254885Sdumbbell break; 361254885Sdumbbell case RADEON_RB3D_ZPASS_ADDR: 362254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 363254885Sdumbbell if (r) { 364254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 365254885Sdumbbell idx, reg); 366254885Sdumbbell r100_cs_dump_packet(p, pkt); 367254885Sdumbbell return r; 368254885Sdumbbell } 369254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 370254885Sdumbbell break; 371254885Sdumbbell case RADEON_PP_CNTL: 372254885Sdumbbell { 373254885Sdumbbell uint32_t temp = idx_value >> 4; 374254885Sdumbbell for (i = 0; i < track->num_texture; i++) 375254885Sdumbbell track->textures[i].enabled = !!(temp & (1 << i)); 376254885Sdumbbell track->tex_dirty = true; 377254885Sdumbbell } 378254885Sdumbbell break; 379254885Sdumbbell case RADEON_SE_VF_CNTL: 380254885Sdumbbell track->vap_vf_cntl = idx_value; 381254885Sdumbbell break; 382254885Sdumbbell case 0x210c: 383254885Sdumbbell /* VAP_VF_MAX_VTX_INDX */ 384254885Sdumbbell track->max_indx = idx_value & 0x00FFFFFFUL; 385254885Sdumbbell break; 386254885Sdumbbell case R200_SE_VTX_FMT_0: 387254885Sdumbbell track->vtx_size = r200_get_vtx_size_0(idx_value); 388254885Sdumbbell break; 389254885Sdumbbell case R200_SE_VTX_FMT_1: 390254885Sdumbbell track->vtx_size += r200_get_vtx_size_1(idx_value); 391254885Sdumbbell break; 392254885Sdumbbell case R200_PP_TXSIZE_0: 393254885Sdumbbell case R200_PP_TXSIZE_1: 394254885Sdumbbell case R200_PP_TXSIZE_2: 395254885Sdumbbell case R200_PP_TXSIZE_3: 396254885Sdumbbell case R200_PP_TXSIZE_4: 397254885Sdumbbell case R200_PP_TXSIZE_5: 398254885Sdumbbell i = (reg - R200_PP_TXSIZE_0) / 32; 399254885Sdumbbell track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; 400254885Sdumbbell track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; 401254885Sdumbbell track->tex_dirty = true; 402254885Sdumbbell break; 403254885Sdumbbell case R200_PP_TXPITCH_0: 404254885Sdumbbell case R200_PP_TXPITCH_1: 405254885Sdumbbell case R200_PP_TXPITCH_2: 406254885Sdumbbell case R200_PP_TXPITCH_3: 407254885Sdumbbell case R200_PP_TXPITCH_4: 408254885Sdumbbell case R200_PP_TXPITCH_5: 409254885Sdumbbell i = (reg - R200_PP_TXPITCH_0) / 32; 410254885Sdumbbell track->textures[i].pitch = idx_value + 32; 411254885Sdumbbell track->tex_dirty = true; 412254885Sdumbbell break; 413254885Sdumbbell case R200_PP_TXFILTER_0: 414254885Sdumbbell case R200_PP_TXFILTER_1: 415254885Sdumbbell case R200_PP_TXFILTER_2: 416254885Sdumbbell case R200_PP_TXFILTER_3: 417254885Sdumbbell case R200_PP_TXFILTER_4: 418254885Sdumbbell case R200_PP_TXFILTER_5: 419254885Sdumbbell i = (reg - R200_PP_TXFILTER_0) / 32; 420254885Sdumbbell track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) 421254885Sdumbbell >> R200_MAX_MIP_LEVEL_SHIFT); 422254885Sdumbbell tmp = (idx_value >> 23) & 0x7; 423254885Sdumbbell if (tmp == 2 || tmp == 6) 424254885Sdumbbell track->textures[i].roundup_w = false; 425254885Sdumbbell tmp = (idx_value >> 27) & 0x7; 426254885Sdumbbell if (tmp == 2 || tmp == 6) 427254885Sdumbbell track->textures[i].roundup_h = false; 428254885Sdumbbell track->tex_dirty = true; 429254885Sdumbbell break; 430254885Sdumbbell case R200_PP_TXMULTI_CTL_0: 431254885Sdumbbell case R200_PP_TXMULTI_CTL_1: 432254885Sdumbbell case R200_PP_TXMULTI_CTL_2: 433254885Sdumbbell case R200_PP_TXMULTI_CTL_3: 434254885Sdumbbell case R200_PP_TXMULTI_CTL_4: 435254885Sdumbbell case R200_PP_TXMULTI_CTL_5: 436254885Sdumbbell i = (reg - R200_PP_TXMULTI_CTL_0) / 32; 437254885Sdumbbell break; 438254885Sdumbbell case R200_PP_TXFORMAT_X_0: 439254885Sdumbbell case R200_PP_TXFORMAT_X_1: 440254885Sdumbbell case R200_PP_TXFORMAT_X_2: 441254885Sdumbbell case R200_PP_TXFORMAT_X_3: 442254885Sdumbbell case R200_PP_TXFORMAT_X_4: 443254885Sdumbbell case R200_PP_TXFORMAT_X_5: 444254885Sdumbbell i = (reg - R200_PP_TXFORMAT_X_0) / 32; 445254885Sdumbbell track->textures[i].txdepth = idx_value & 0x7; 446254885Sdumbbell tmp = (idx_value >> 16) & 0x3; 447254885Sdumbbell /* 2D, 3D, CUBE */ 448254885Sdumbbell switch (tmp) { 449254885Sdumbbell case 0: 450254885Sdumbbell case 3: 451254885Sdumbbell case 4: 452254885Sdumbbell case 5: 453254885Sdumbbell case 6: 454254885Sdumbbell case 7: 455254885Sdumbbell /* 1D/2D */ 456254885Sdumbbell track->textures[i].tex_coord_type = 0; 457254885Sdumbbell break; 458254885Sdumbbell case 1: 459254885Sdumbbell /* CUBE */ 460254885Sdumbbell track->textures[i].tex_coord_type = 2; 461254885Sdumbbell break; 462254885Sdumbbell case 2: 463254885Sdumbbell /* 3D */ 464254885Sdumbbell track->textures[i].tex_coord_type = 1; 465254885Sdumbbell break; 466254885Sdumbbell } 467254885Sdumbbell track->tex_dirty = true; 468254885Sdumbbell break; 469254885Sdumbbell case R200_PP_TXFORMAT_0: 470254885Sdumbbell case R200_PP_TXFORMAT_1: 471254885Sdumbbell case R200_PP_TXFORMAT_2: 472254885Sdumbbell case R200_PP_TXFORMAT_3: 473254885Sdumbbell case R200_PP_TXFORMAT_4: 474254885Sdumbbell case R200_PP_TXFORMAT_5: 475254885Sdumbbell i = (reg - R200_PP_TXFORMAT_0) / 32; 476254885Sdumbbell if (idx_value & R200_TXFORMAT_NON_POWER2) { 477254885Sdumbbell track->textures[i].use_pitch = 1; 478254885Sdumbbell } else { 479254885Sdumbbell track->textures[i].use_pitch = 0; 480254885Sdumbbell track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); 481254885Sdumbbell track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); 482254885Sdumbbell } 483254885Sdumbbell if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) 484254885Sdumbbell track->textures[i].lookup_disable = true; 485254885Sdumbbell switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { 486254885Sdumbbell case R200_TXFORMAT_I8: 487254885Sdumbbell case R200_TXFORMAT_RGB332: 488254885Sdumbbell case R200_TXFORMAT_Y8: 489254885Sdumbbell track->textures[i].cpp = 1; 490254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 491254885Sdumbbell break; 492254885Sdumbbell case R200_TXFORMAT_AI88: 493254885Sdumbbell case R200_TXFORMAT_ARGB1555: 494254885Sdumbbell case R200_TXFORMAT_RGB565: 495254885Sdumbbell case R200_TXFORMAT_ARGB4444: 496254885Sdumbbell case R200_TXFORMAT_VYUY422: 497254885Sdumbbell case R200_TXFORMAT_YVYU422: 498254885Sdumbbell case R200_TXFORMAT_LDVDU655: 499254885Sdumbbell case R200_TXFORMAT_DVDU88: 500254885Sdumbbell case R200_TXFORMAT_AVYU4444: 501254885Sdumbbell track->textures[i].cpp = 2; 502254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 503254885Sdumbbell break; 504254885Sdumbbell case R200_TXFORMAT_ARGB8888: 505254885Sdumbbell case R200_TXFORMAT_RGBA8888: 506254885Sdumbbell case R200_TXFORMAT_ABGR8888: 507254885Sdumbbell case R200_TXFORMAT_BGR111110: 508254885Sdumbbell case R200_TXFORMAT_LDVDU8888: 509254885Sdumbbell track->textures[i].cpp = 4; 510254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 511254885Sdumbbell break; 512254885Sdumbbell case R200_TXFORMAT_DXT1: 513254885Sdumbbell track->textures[i].cpp = 1; 514254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 515254885Sdumbbell break; 516254885Sdumbbell case R200_TXFORMAT_DXT23: 517254885Sdumbbell case R200_TXFORMAT_DXT45: 518254885Sdumbbell track->textures[i].cpp = 1; 519254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 520254885Sdumbbell break; 521254885Sdumbbell } 522254885Sdumbbell track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); 523254885Sdumbbell track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); 524254885Sdumbbell track->tex_dirty = true; 525254885Sdumbbell break; 526254885Sdumbbell case R200_PP_CUBIC_FACES_0: 527254885Sdumbbell case R200_PP_CUBIC_FACES_1: 528254885Sdumbbell case R200_PP_CUBIC_FACES_2: 529254885Sdumbbell case R200_PP_CUBIC_FACES_3: 530254885Sdumbbell case R200_PP_CUBIC_FACES_4: 531254885Sdumbbell case R200_PP_CUBIC_FACES_5: 532254885Sdumbbell tmp = idx_value; 533254885Sdumbbell i = (reg - R200_PP_CUBIC_FACES_0) / 32; 534254885Sdumbbell for (face = 0; face < 4; face++) { 535254885Sdumbbell track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); 536254885Sdumbbell track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); 537254885Sdumbbell } 538254885Sdumbbell track->tex_dirty = true; 539254885Sdumbbell break; 540254885Sdumbbell default: 541254885Sdumbbell DRM_ERROR("Forbidden register 0x%04X in cs at %d\n", 542254885Sdumbbell reg, idx); 543254885Sdumbbell return -EINVAL; 544254885Sdumbbell } 545254885Sdumbbell return 0; 546254885Sdumbbell} 547254885Sdumbbell 548254885Sdumbbellvoid r200_set_safe_registers(struct radeon_device *rdev) 549254885Sdumbbell{ 550254885Sdumbbell rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; 551282199Sdumbbell rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); 552254885Sdumbbell} 553