r200.c revision 256281
1228692Sdes/* 2141098Sdes * Copyright 2008 Advanced Micro Devices, Inc. 3117610Sdes * Copyright 2008 Red Hat Inc. 4141098Sdes * Copyright 2009 Jerome Glisse. 5228692Sdes * 6228692Sdes * Permission is hereby granted, free of charge, to any person obtaining a 7117610Sdes * copy of this software and associated documentation files (the "Software"), 8117610Sdes * to deal in the Software without restriction, including without limitation 9117610Sdes * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10117610Sdes * and/or sell copies of the Software, and to permit persons to whom the 11117610Sdes * Software is furnished to do so, subject to the following conditions: 12117610Sdes * 13117610Sdes * The above copyright notice and this permission notice shall be included in 14117610Sdes * all copies or substantial portions of the Software. 15117610Sdes * 16117610Sdes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17147455Sdes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18174832Sdes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19117610Sdes * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20117610Sdes * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21228692Sdes * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22117610Sdes * OTHER DEALINGS IN THE SOFTWARE. 23228692Sdes * 24141098Sdes * Authors: Dave Airlie 25141098Sdes * Alex Deucher 26141098Sdes * Jerome Glisse 27141098Sdes */ 28117610Sdes 29141098Sdes#include <sys/cdefs.h> 30117610Sdes__FBSDID("$FreeBSD: stable/10/sys/dev/drm2/radeon/r200.c 254885 2013-08-25 19:37:15Z dumbbell $"); 31117610Sdes 32117610Sdes#include <dev/drm2/drmP.h> 33117610Sdes#include <dev/drm2/radeon/radeon_drm.h> 34117610Sdes#include "radeon_reg.h" 35117610Sdes#include "radeon.h" 36117610Sdes#include "radeon_asic.h" 37117610Sdes 38141098Sdes#include "r100d.h" 39141098Sdes#include "r200_reg_safe.h" 40141098Sdes 41141098Sdes#include "r100_track.h" 42141098Sdes 43141098Sdesstatic int r200_get_vtx_size_0(uint32_t vtx_fmt_0) 44174832Sdes{ 45141098Sdes int vtx_size, i; 46141098Sdes vtx_size = 2; 47228692Sdes 48141098Sdes if (vtx_fmt_0 & R200_VTX_Z0) 49141098Sdes vtx_size++; 50141098Sdes if (vtx_fmt_0 & R200_VTX_W0) 51141098Sdes vtx_size++; 52228692Sdes /* blend weight */ 53228692Sdes if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) 54228692Sdes vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; 55228692Sdes if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) 56228692Sdes vtx_size++; 57228692Sdes if (vtx_fmt_0 & R200_VTX_N0) 58228692Sdes vtx_size += 3; 59228692Sdes if (vtx_fmt_0 & R200_VTX_POINT_SIZE) 60228692Sdes vtx_size++; 61228692Sdes if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) 62141098Sdes vtx_size++; 63141098Sdes if (vtx_fmt_0 & R200_VTX_SHININESS_0) 64141098Sdes vtx_size++; 65141098Sdes if (vtx_fmt_0 & R200_VTX_SHININESS_1) 66228692Sdes vtx_size++; 67228692Sdes for (i = 0; i < 8; i++) { 68228692Sdes int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; 69228692Sdes switch (color_size) { 70228692Sdes case 0: break; 71228692Sdes case 1: vtx_size++; break; 72228692Sdes case 2: vtx_size += 3; break; 73228692Sdes case 3: vtx_size += 4; break; 74228692Sdes } 75228692Sdes } 76228692Sdes if (vtx_fmt_0 & R200_VTX_XY1) 77228692Sdes vtx_size += 2; 78228692Sdes if (vtx_fmt_0 & R200_VTX_Z1) 79228692Sdes vtx_size++; 80228692Sdes if (vtx_fmt_0 & R200_VTX_W1) 81228692Sdes vtx_size++; 82228692Sdes if (vtx_fmt_0 & R200_VTX_N1) 83228692Sdes vtx_size += 3; 84228692Sdes return vtx_size; 85228692Sdes} 86228692Sdes 87228692Sdesint r200_copy_dma(struct radeon_device *rdev, 88228692Sdes uint64_t src_offset, 89228692Sdes uint64_t dst_offset, 90228692Sdes unsigned num_gpu_pages, 91141098Sdes struct radeon_fence **fence) 92117610Sdes{ 93141098Sdes struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 94141098Sdes uint32_t size; 95141098Sdes uint32_t cur_size; 96141098Sdes int i, num_loops; 97117610Sdes int r = 0; 98117610Sdes 99141098Sdes /* radeon pitch is /64 */ 100117610Sdes size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; 101141098Sdes num_loops = DIV_ROUND_UP(size, 0x1FFFFF); 102117610Sdes r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); 103117610Sdes if (r) { 104141098Sdes DRM_ERROR("radeon: moving bo (%d).\n", r); 105141098Sdes return r; 106117610Sdes } 107228692Sdes /* Must wait for 2D idle & clean before DMA or hangs might happen */ 108117610Sdes radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 109228692Sdes radeon_ring_write(ring, (1 << 16)); 110228692Sdes for (i = 0; i < num_loops; i++) { 111141098Sdes cur_size = size; 112141098Sdes if (cur_size > 0x1FFFFF) { 113141098Sdes cur_size = 0x1FFFFF; 114141098Sdes } 115117610Sdes size -= cur_size; 116228692Sdes radeon_ring_write(ring, PACKET0(0x720, 2)); 117174832Sdes radeon_ring_write(ring, src_offset); 118228692Sdes radeon_ring_write(ring, dst_offset); 119141098Sdes radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30)); 120141098Sdes src_offset += cur_size; 121141098Sdes dst_offset += cur_size; 122117610Sdes } 123228692Sdes radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 124141098Sdes radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); 125141098Sdes if (fence) { 126141098Sdes r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); 127117610Sdes } 128117610Sdes radeon_ring_unlock_commit(rdev, ring); 129228692Sdes return r; 130117610Sdes} 131141098Sdes 132141098Sdes 133228692Sdesstatic int r200_get_vtx_size_1(uint32_t vtx_fmt_1) 134228692Sdes{ 135228692Sdes int vtx_size, i, tex_size; 136228692Sdes vtx_size = 0; 137228692Sdes for (i = 0; i < 6; i++) { 138117610Sdes tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; 139117610Sdes if (tex_size > 4) 140228692Sdes continue; 141228692Sdes vtx_size += tex_size; 142117610Sdes } 143141098Sdes return vtx_size; 144141098Sdes} 145141098Sdes 146141098Sdesint r200_packet0_check(struct radeon_cs_parser *p, 147228692Sdes struct radeon_cs_packet *pkt, 148141098Sdes unsigned idx, unsigned reg) 149141098Sdes{ 150117610Sdes struct radeon_cs_reloc *reloc; 151174832Sdes struct r100_cs_track *track; 152141098Sdes volatile uint32_t *ib; 153141098Sdes uint32_t tmp; 154141098Sdes int r; 155117610Sdes int i; 156228692Sdes int face; 157228692Sdes u32 tile_flags = 0; 158228692Sdes u32 idx_value; 159228692Sdes 160228692Sdes ib = p->ib.ptr; 161141098Sdes track = (struct r100_cs_track *)p->track; 162228692Sdes idx_value = radeon_get_ib_value(p, idx); 163117610Sdes switch (reg) { 164141098Sdes case RADEON_CRTC_GUI_TRIG_VLINE: 165117610Sdes r = r100_cs_packet_parse_vline(p); 166174832Sdes if (r) { 167174832Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 168141098Sdes idx, reg); 169141098Sdes r100_cs_dump_packet(p, pkt); 170141098Sdes return r; 171141098Sdes } 172141098Sdes break; 173141098Sdes /* FIXME: only allow PACKET3 blit? easier to check for out of 174228692Sdes * range access */ 175141098Sdes case RADEON_DST_PITCH_OFFSET: 176174832Sdes case RADEON_SRC_PITCH_OFFSET: 177174832Sdes r = r100_reloc_pitch_offset(p, pkt, idx, reg); 178174832Sdes if (r) 179141098Sdes return r; 180141098Sdes break; 181141098Sdes case RADEON_RB3D_DEPTHOFFSET: 182141098Sdes r = r100_cs_packet_next_reloc(p, &reloc); 183141098Sdes if (r) { 184141098Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 185174832Sdes idx, reg); 186141098Sdes r100_cs_dump_packet(p, pkt); 187141098Sdes return r; 188117610Sdes } 189141098Sdes track->zb.robj = reloc->robj; 190141098Sdes track->zb.offset = idx_value; 191174832Sdes track->zb_dirty = true; 192141098Sdes ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 193141098Sdes break; 194141098Sdes case RADEON_RB3D_COLOROFFSET: 195141098Sdes r = r100_cs_packet_next_reloc(p, &reloc); 196174832Sdes if (r) { 197141098Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 198141098Sdes idx, reg); 199174832Sdes r100_cs_dump_packet(p, pkt); 200141098Sdes return r; 201141098Sdes } 202228692Sdes track->cb[0].robj = reloc->robj; 203141098Sdes track->cb[0].offset = idx_value; 204141098Sdes track->cb_dirty = true; 205228692Sdes ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 206228692Sdes break; 207228692Sdes case R200_PP_TXOFFSET_0: 208117610Sdes case R200_PP_TXOFFSET_1: 209117610Sdes case R200_PP_TXOFFSET_2: 210117610Sdes case R200_PP_TXOFFSET_3: 211117610Sdes case R200_PP_TXOFFSET_4: 212141098Sdes case R200_PP_TXOFFSET_5: 213141098Sdes i = (reg - R200_PP_TXOFFSET_0) / 24; 214141098Sdes r = r100_cs_packet_next_reloc(p, &reloc); 215141098Sdes if (r) { 216228692Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 217228692Sdes idx, reg); 218141098Sdes r100_cs_dump_packet(p, pkt); 219141098Sdes return r; 220141098Sdes } 221228692Sdes if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 222228692Sdes if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 223228692Sdes tile_flags |= R200_TXO_MACRO_TILE; 224141098Sdes if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 225141098Sdes tile_flags |= R200_TXO_MICRO_TILE; 226141098Sdes 227141098Sdes tmp = idx_value & ~(0x7 << 2); 228141098Sdes tmp |= tile_flags; 229141098Sdes ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); 230141098Sdes } else 231141098Sdes ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 232141098Sdes track->textures[i].robj = reloc->robj; 233117610Sdes track->tex_dirty = true; 234141098Sdes break; 235141098Sdes case R200_PP_CUBIC_OFFSET_F1_0: 236141098Sdes case R200_PP_CUBIC_OFFSET_F2_0: 237141098Sdes case R200_PP_CUBIC_OFFSET_F3_0: 238141098Sdes case R200_PP_CUBIC_OFFSET_F4_0: 239141098Sdes case R200_PP_CUBIC_OFFSET_F5_0: 240141098Sdes case R200_PP_CUBIC_OFFSET_F1_1: 241228692Sdes case R200_PP_CUBIC_OFFSET_F2_1: 242141098Sdes case R200_PP_CUBIC_OFFSET_F3_1: 243117610Sdes case R200_PP_CUBIC_OFFSET_F4_1: 244117610Sdes case R200_PP_CUBIC_OFFSET_F5_1: 245117610Sdes case R200_PP_CUBIC_OFFSET_F1_2: 246117610Sdes case R200_PP_CUBIC_OFFSET_F2_2: 247117610Sdes case R200_PP_CUBIC_OFFSET_F3_2: 248117610Sdes case R200_PP_CUBIC_OFFSET_F4_2: 249117610Sdes case R200_PP_CUBIC_OFFSET_F5_2: 250117610Sdes case R200_PP_CUBIC_OFFSET_F1_3: 251117610Sdes case R200_PP_CUBIC_OFFSET_F2_3: 252117610Sdes case R200_PP_CUBIC_OFFSET_F3_3: 253117610Sdes case R200_PP_CUBIC_OFFSET_F4_3: 254117610Sdes case R200_PP_CUBIC_OFFSET_F5_3: 255117610Sdes case R200_PP_CUBIC_OFFSET_F1_4: 256228692Sdes case R200_PP_CUBIC_OFFSET_F2_4: 257174832Sdes case R200_PP_CUBIC_OFFSET_F3_4: 258174832Sdes case R200_PP_CUBIC_OFFSET_F4_4: 259174832Sdes case R200_PP_CUBIC_OFFSET_F5_4: 260174832Sdes case R200_PP_CUBIC_OFFSET_F1_5: 261174832Sdes case R200_PP_CUBIC_OFFSET_F2_5: 262174832Sdes case R200_PP_CUBIC_OFFSET_F3_5: 263117610Sdes case R200_PP_CUBIC_OFFSET_F4_5: 264117610Sdes case R200_PP_CUBIC_OFFSET_F5_5: 265117610Sdes i = (reg - R200_PP_TXOFFSET_0) / 24; 266117610Sdes face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; 267117610Sdes r = r100_cs_packet_next_reloc(p, &reloc); 268117610Sdes if (r) { 269117610Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 270117610Sdes idx, reg); 271117610Sdes r100_cs_dump_packet(p, pkt); 272117610Sdes return r; 273228692Sdes } 274174832Sdes track->textures[i].cube_info[face - 1].offset = idx_value; 275117610Sdes ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 276117610Sdes track->textures[i].cube_info[face - 1].robj = reloc->robj; 277117610Sdes track->tex_dirty = true; 278117610Sdes break; 279117610Sdes case RADEON_RE_WIDTH_HEIGHT: 280228692Sdes track->maxy = ((idx_value >> 16) & 0x7FF); 281228692Sdes track->cb_dirty = true; 282174832Sdes track->zb_dirty = true; 283174832Sdes break; 284174832Sdes case RADEON_RB3D_COLORPITCH: 285174832Sdes r = r100_cs_packet_next_reloc(p, &reloc); 286174832Sdes if (r) { 287174832Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 288117610Sdes idx, reg); 289117610Sdes r100_cs_dump_packet(p, pkt); 290117610Sdes return r; 291117610Sdes } 292117610Sdes 293117610Sdes if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 294117610Sdes if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 295117610Sdes tile_flags |= RADEON_COLOR_TILE_ENABLE; 296117610Sdes if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 297117610Sdes tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; 298117610Sdes 299117610Sdes tmp = idx_value & ~(0x7 << 16); 300117610Sdes tmp |= tile_flags; 301117610Sdes ib[idx] = tmp; 302117610Sdes } else 303117610Sdes ib[idx] = idx_value; 304117610Sdes 305117610Sdes track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; 306117610Sdes track->cb_dirty = true; 307228692Sdes break; 308174832Sdes case RADEON_RB3D_DEPTHPITCH: 309117610Sdes track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; 310117610Sdes track->zb_dirty = true; 311117610Sdes break; 312228692Sdes case RADEON_RB3D_CNTL: 313117610Sdes switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { 314141098Sdes case 7: 315141098Sdes case 8: 316228692Sdes case 9: 317141098Sdes case 11: 318117610Sdes case 12: 319117610Sdes track->cb[0].cpp = 1; 320141098Sdes break; 321117610Sdes case 3: 322117610Sdes case 4: 323117610Sdes case 15: 324228692Sdes track->cb[0].cpp = 2; 325228692Sdes break; 326141098Sdes case 6: 327141098Sdes track->cb[0].cpp = 4; 328117610Sdes break; 329117610Sdes default: 330117610Sdes DRM_ERROR("Invalid color buffer format (%d) !\n", 331228692Sdes ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); 332117610Sdes return -EINVAL; 333141098Sdes } 334141098Sdes if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { 335141098Sdes DRM_ERROR("No support for depth xy offset in kms\n"); 336141098Sdes return -EINVAL; 337141098Sdes } 338141098Sdes 339141098Sdes track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); 340117610Sdes track->cb_dirty = true; 341117610Sdes track->zb_dirty = true; 342141098Sdes break; 343228692Sdes case RADEON_RB3D_ZSTENCILCNTL: 344117610Sdes switch (idx_value & 0xf) { 345117610Sdes case 0: 346141098Sdes track->zb.cpp = 2; 347117610Sdes break; 348117610Sdes case 2: 349117610Sdes case 3: 350228692Sdes case 4: 351228692Sdes case 5: 352228692Sdes case 9: 353228692Sdes case 11: 354141098Sdes track->zb.cpp = 4; 355228692Sdes break; 356228692Sdes default: 357228692Sdes break; 358228692Sdes } 359228692Sdes track->zb_dirty = true; 360228692Sdes break; 361228692Sdes case RADEON_RB3D_ZPASS_ADDR: 362141098Sdes r = r100_cs_packet_next_reloc(p, &reloc); 363141098Sdes if (r) { 364141098Sdes DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 365141098Sdes idx, reg); 366141098Sdes r100_cs_dump_packet(p, pkt); 367141098Sdes return r; 368141098Sdes } 369141098Sdes ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 370228692Sdes break; 371228692Sdes case RADEON_PP_CNTL: 372228692Sdes { 373141098Sdes uint32_t temp = idx_value >> 4; 374228692Sdes for (i = 0; i < track->num_texture; i++) 375117610Sdes track->textures[i].enabled = !!(temp & (1 << i)); 376117610Sdes track->tex_dirty = true; 377141098Sdes } 378228692Sdes break; 379228692Sdes case RADEON_SE_VF_CNTL: 380117610Sdes track->vap_vf_cntl = idx_value; 381117610Sdes break; 382141098Sdes case 0x210c: 383117610Sdes /* VAP_VF_MAX_VTX_INDX */ 384117610Sdes track->max_indx = idx_value & 0x00FFFFFFUL; 385228692Sdes break; 386228692Sdes case R200_SE_VTX_FMT_0: 387228692Sdes track->vtx_size = r200_get_vtx_size_0(idx_value); 388228692Sdes break; 389228692Sdes case R200_SE_VTX_FMT_1: 390228692Sdes track->vtx_size += r200_get_vtx_size_1(idx_value); 391228692Sdes break; 392228692Sdes case R200_PP_TXSIZE_0: 393228692Sdes case R200_PP_TXSIZE_1: 394228692Sdes case R200_PP_TXSIZE_2: 395228692Sdes case R200_PP_TXSIZE_3: 396228692Sdes case R200_PP_TXSIZE_4: 397141098Sdes case R200_PP_TXSIZE_5: 398117610Sdes i = (reg - R200_PP_TXSIZE_0) / 32; 399228692Sdes track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; 400228692Sdes track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; 401228692Sdes track->tex_dirty = true; 402228692Sdes break; 403141098Sdes case R200_PP_TXPITCH_0: 404228692Sdes case R200_PP_TXPITCH_1: 405228692Sdes case R200_PP_TXPITCH_2: 406141098Sdes case R200_PP_TXPITCH_3: 407228692Sdes case R200_PP_TXPITCH_4: 408117610Sdes case R200_PP_TXPITCH_5: 409228692Sdes i = (reg - R200_PP_TXPITCH_0) / 32; 410228692Sdes track->textures[i].pitch = idx_value + 32; 411117610Sdes track->tex_dirty = true; 412117610Sdes break; 413117610Sdes case R200_PP_TXFILTER_0: 414228692Sdes case R200_PP_TXFILTER_1: 415117610Sdes case R200_PP_TXFILTER_2: 416141098Sdes case R200_PP_TXFILTER_3: 417228692Sdes case R200_PP_TXFILTER_4: 418117610Sdes case R200_PP_TXFILTER_5: 419228692Sdes i = (reg - R200_PP_TXFILTER_0) / 32; 420228692Sdes track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) 421228692Sdes >> R200_MAX_MIP_LEVEL_SHIFT); 422228692Sdes tmp = (idx_value >> 23) & 0x7; 423228692Sdes if (tmp == 2 || tmp == 6) 424228692Sdes track->textures[i].roundup_w = false; 425228692Sdes tmp = (idx_value >> 27) & 0x7; 426228692Sdes if (tmp == 2 || tmp == 6) 427228692Sdes track->textures[i].roundup_h = false; 428228692Sdes track->tex_dirty = true; 429228692Sdes break; 430228692Sdes case R200_PP_TXMULTI_CTL_0: 431228692Sdes case R200_PP_TXMULTI_CTL_1: 432117610Sdes case R200_PP_TXMULTI_CTL_2: 433228692Sdes case R200_PP_TXMULTI_CTL_3: 434228692Sdes case R200_PP_TXMULTI_CTL_4: 435228692Sdes case R200_PP_TXMULTI_CTL_5: 436228692Sdes i = (reg - R200_PP_TXMULTI_CTL_0) / 32; 437228692Sdes break; 438117610Sdes case R200_PP_TXFORMAT_X_0: 439117610Sdes case R200_PP_TXFORMAT_X_1: 440117610Sdes case R200_PP_TXFORMAT_X_2: 441117610Sdes case R200_PP_TXFORMAT_X_3: 442117610Sdes case R200_PP_TXFORMAT_X_4: 443117610Sdes case R200_PP_TXFORMAT_X_5: 444117610Sdes i = (reg - R200_PP_TXFORMAT_X_0) / 32; 445117610Sdes track->textures[i].txdepth = idx_value & 0x7; 446117610Sdes tmp = (idx_value >> 16) & 0x3; 447117610Sdes /* 2D, 3D, CUBE */ 448117610Sdes switch (tmp) { 449117610Sdes case 0: 450117610Sdes case 3: 451117610Sdes case 4: 452117610Sdes case 5: 453117610Sdes case 6: 454117610Sdes case 7: 455117610Sdes /* 1D/2D */ 456117610Sdes track->textures[i].tex_coord_type = 0; 457117610Sdes break; 458141098Sdes case 1: 459117610Sdes /* CUBE */ 460117610Sdes track->textures[i].tex_coord_type = 2; 461117610Sdes break; 462117610Sdes case 2: 463117610Sdes /* 3D */ 464117610Sdes track->textures[i].tex_coord_type = 1; 465117610Sdes break; 466174832Sdes } 467228692Sdes track->tex_dirty = true; 468117610Sdes break; 469117610Sdes case R200_PP_TXFORMAT_0: 470117610Sdes case R200_PP_TXFORMAT_1: 471117610Sdes case R200_PP_TXFORMAT_2: 472117610Sdes case R200_PP_TXFORMAT_3: 473117610Sdes case R200_PP_TXFORMAT_4: 474117610Sdes case R200_PP_TXFORMAT_5: 475117610Sdes i = (reg - R200_PP_TXFORMAT_0) / 32; 476117610Sdes if (idx_value & R200_TXFORMAT_NON_POWER2) { 477141098Sdes track->textures[i].use_pitch = 1; 478228692Sdes } else { 479117610Sdes track->textures[i].use_pitch = 0; 480117610Sdes track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); 481117610Sdes track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); 482117610Sdes } 483117610Sdes if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) 484141098Sdes track->textures[i].lookup_disable = true; 485141098Sdes switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { 486228692Sdes case R200_TXFORMAT_I8: 487228692Sdes case R200_TXFORMAT_RGB332: 488117610Sdes case R200_TXFORMAT_Y8: 489117610Sdes track->textures[i].cpp = 1; 490117610Sdes track->textures[i].compress_format = R100_TRACK_COMP_NONE; 491117610Sdes break; 492117610Sdes case R200_TXFORMAT_AI88: 493117610Sdes case R200_TXFORMAT_ARGB1555: 494228692Sdes case R200_TXFORMAT_RGB565: 495228692Sdes case R200_TXFORMAT_ARGB4444: 496228692Sdes case R200_TXFORMAT_VYUY422: 497228692Sdes case R200_TXFORMAT_YVYU422: 498117610Sdes case R200_TXFORMAT_LDVDU655: 499117610Sdes case R200_TXFORMAT_DVDU88: 500228692Sdes case R200_TXFORMAT_AVYU4444: 501228692Sdes track->textures[i].cpp = 2; 502228692Sdes track->textures[i].compress_format = R100_TRACK_COMP_NONE; 503228692Sdes break; 504117610Sdes case R200_TXFORMAT_ARGB8888: 505117610Sdes case R200_TXFORMAT_RGBA8888: 506228692Sdes case R200_TXFORMAT_ABGR8888: 507228692Sdes case R200_TXFORMAT_BGR111110: 508117610Sdes case R200_TXFORMAT_LDVDU8888: 509117610Sdes track->textures[i].cpp = 4; 510228692Sdes track->textures[i].compress_format = R100_TRACK_COMP_NONE; 511228692Sdes break; 512228692Sdes case R200_TXFORMAT_DXT1: 513228692Sdes track->textures[i].cpp = 1; 514228692Sdes track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 515228692Sdes break; 516228692Sdes case R200_TXFORMAT_DXT23: 517228692Sdes case R200_TXFORMAT_DXT45: 518117610Sdes track->textures[i].cpp = 1; 519117610Sdes track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 520117610Sdes break; 521141098Sdes } 522117610Sdes track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); 523117610Sdes track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); 524117610Sdes track->tex_dirty = true; 525117610Sdes break; 526117610Sdes case R200_PP_CUBIC_FACES_0: 527117610Sdes case R200_PP_CUBIC_FACES_1: 528141098Sdes case R200_PP_CUBIC_FACES_2: 529141098Sdes case R200_PP_CUBIC_FACES_3: 530141098Sdes case R200_PP_CUBIC_FACES_4: 531141098Sdes case R200_PP_CUBIC_FACES_5: 532141098Sdes tmp = idx_value; 533141098Sdes i = (reg - R200_PP_CUBIC_FACES_0) / 32; 534141098Sdes for (face = 0; face < 4; face++) { 535141098Sdes track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); 536228692Sdes track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); 537117610Sdes } 538228692Sdes track->tex_dirty = true; 539228692Sdes break; 540117610Sdes default: 541228692Sdes DRM_ERROR("Forbidden register 0x%04X in cs at %d\n", 542228692Sdes reg, idx); 543228692Sdes return -EINVAL; 544228692Sdes } 545141098Sdes return 0; 546228692Sdes} 547228692Sdes 548228692Sdesvoid r200_set_safe_registers(struct radeon_device *rdev) 549228692Sdes{ 550141098Sdes rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; 551228692Sdes rdev->config.r100.reg_safe_bm_size = DRM_ARRAY_SIZE(r200_reg_safe_bm); 552228692Sdes} 553228692Sdes