Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2008 Advanced Micro Devices, Inc.
0003  * Copyright 2008 Red Hat Inc.
0004  * Copyright 2009 Jerome Glisse.
0005  *
0006  * Permission is hereby granted, free of charge, to any person obtaining a
0007  * copy of this software and associated documentation files (the "Software"),
0008  * to deal in the Software without restriction, including without limitation
0009  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010  * and/or sell copies of the Software, and to permit persons to whom the
0011  * Software is furnished to do so, subject to the following conditions:
0012  *
0013  * The above copyright notice and this permission notice shall be included in
0014  * all copies or substantial portions of the Software.
0015  *
0016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0019  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0020  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0021  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0022  * OTHER DEALINGS IN THE SOFTWARE.
0023  *
0024  * Authors: Dave Airlie
0025  *          Alex Deucher
0026  *          Jerome Glisse
0027  */
0028 
0029 #include <drm/radeon_drm.h>
0030 #include "radeon_reg.h"
0031 #include "radeon.h"
0032 #include "radeon_asic.h"
0033 
0034 #include "r100d.h"
0035 #include "r200_reg_safe.h"
0036 
0037 #include "r100_track.h"
0038 
0039 static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
0040 {
0041     int vtx_size, i;
0042     vtx_size = 2;
0043 
0044     if (vtx_fmt_0 & R200_VTX_Z0)
0045         vtx_size++;
0046     if (vtx_fmt_0 & R200_VTX_W0)
0047         vtx_size++;
0048     /* blend weight */
0049     if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
0050         vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
0051     if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
0052         vtx_size++;
0053     if (vtx_fmt_0 & R200_VTX_N0)
0054         vtx_size += 3;
0055     if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
0056         vtx_size++;
0057     if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
0058         vtx_size++;
0059     if (vtx_fmt_0 & R200_VTX_SHININESS_0)
0060         vtx_size++;
0061     if (vtx_fmt_0 & R200_VTX_SHININESS_1)
0062         vtx_size++;
0063     for (i = 0; i < 8; i++) {
0064         int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
0065         switch (color_size) {
0066         case 0: break;
0067         case 1: vtx_size++; break;
0068         case 2: vtx_size += 3; break;
0069         case 3: vtx_size += 4; break;
0070         }
0071     }
0072     if (vtx_fmt_0 & R200_VTX_XY1)
0073         vtx_size += 2;
0074     if (vtx_fmt_0 & R200_VTX_Z1)
0075         vtx_size++;
0076     if (vtx_fmt_0 & R200_VTX_W1)
0077         vtx_size++;
0078     if (vtx_fmt_0 & R200_VTX_N1)
0079         vtx_size += 3;
0080     return vtx_size;
0081 }
0082 
0083 struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
0084                    uint64_t src_offset,
0085                    uint64_t dst_offset,
0086                    unsigned num_gpu_pages,
0087                    struct dma_resv *resv)
0088 {
0089     struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
0090     struct radeon_fence *fence;
0091     uint32_t size;
0092     uint32_t cur_size;
0093     int i, num_loops;
0094     int r = 0;
0095 
0096     /* radeon pitch is /64 */
0097     size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
0098     num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
0099     r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
0100     if (r) {
0101         DRM_ERROR("radeon: moving bo (%d).\n", r);
0102         return ERR_PTR(r);
0103     }
0104     /* Must wait for 2D idle & clean before DMA or hangs might happen */
0105     radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
0106     radeon_ring_write(ring, (1 << 16));
0107     for (i = 0; i < num_loops; i++) {
0108         cur_size = size;
0109         if (cur_size > 0x1FFFFF) {
0110             cur_size = 0x1FFFFF;
0111         }
0112         size -= cur_size;
0113         radeon_ring_write(ring, PACKET0(0x720, 2));
0114         radeon_ring_write(ring, src_offset);
0115         radeon_ring_write(ring, dst_offset);
0116         radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30));
0117         src_offset += cur_size;
0118         dst_offset += cur_size;
0119     }
0120     radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
0121     radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
0122     r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
0123     if (r) {
0124         radeon_ring_unlock_undo(rdev, ring);
0125         return ERR_PTR(r);
0126     }
0127     radeon_ring_unlock_commit(rdev, ring, false);
0128     return fence;
0129 }
0130 
0131 
0132 static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
0133 {
0134     int vtx_size, i, tex_size;
0135     vtx_size = 0;
0136     for (i = 0; i < 6; i++) {
0137         tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
0138         if (tex_size > 4)
0139             continue;
0140         vtx_size += tex_size;
0141     }
0142     return vtx_size;
0143 }
0144 
0145 int r200_packet0_check(struct radeon_cs_parser *p,
0146                struct radeon_cs_packet *pkt,
0147                unsigned idx, unsigned reg)
0148 {
0149     struct radeon_bo_list *reloc;
0150     struct r100_cs_track *track;
0151     volatile uint32_t *ib;
0152     uint32_t tmp;
0153     int r;
0154     int i;
0155     int face;
0156     u32 tile_flags = 0;
0157     u32 idx_value;
0158 
0159     ib = p->ib.ptr;
0160     track = (struct r100_cs_track *)p->track;
0161     idx_value = radeon_get_ib_value(p, idx);
0162     switch (reg) {
0163     case RADEON_CRTC_GUI_TRIG_VLINE:
0164         r = r100_cs_packet_parse_vline(p);
0165         if (r) {
0166             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0167                   idx, reg);
0168             radeon_cs_dump_packet(p, pkt);
0169             return r;
0170         }
0171         break;
0172         /* FIXME: only allow PACKET3 blit? easier to check for out of
0173          * range access */
0174     case RADEON_DST_PITCH_OFFSET:
0175     case RADEON_SRC_PITCH_OFFSET:
0176         r = r100_reloc_pitch_offset(p, pkt, idx, reg);
0177         if (r)
0178             return r;
0179         break;
0180     case RADEON_RB3D_DEPTHOFFSET:
0181         r = radeon_cs_packet_next_reloc(p, &reloc, 0);
0182         if (r) {
0183             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0184                   idx, reg);
0185             radeon_cs_dump_packet(p, pkt);
0186             return r;
0187         }
0188         track->zb.robj = reloc->robj;
0189         track->zb.offset = idx_value;
0190         track->zb_dirty = true;
0191         ib[idx] = idx_value + ((u32)reloc->gpu_offset);
0192         break;
0193     case RADEON_RB3D_COLOROFFSET:
0194         r = radeon_cs_packet_next_reloc(p, &reloc, 0);
0195         if (r) {
0196             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0197                   idx, reg);
0198             radeon_cs_dump_packet(p, pkt);
0199             return r;
0200         }
0201         track->cb[0].robj = reloc->robj;
0202         track->cb[0].offset = idx_value;
0203         track->cb_dirty = true;
0204         ib[idx] = idx_value + ((u32)reloc->gpu_offset);
0205         break;
0206     case R200_PP_TXOFFSET_0:
0207     case R200_PP_TXOFFSET_1:
0208     case R200_PP_TXOFFSET_2:
0209     case R200_PP_TXOFFSET_3:
0210     case R200_PP_TXOFFSET_4:
0211     case R200_PP_TXOFFSET_5:
0212         i = (reg - R200_PP_TXOFFSET_0) / 24;
0213         r = radeon_cs_packet_next_reloc(p, &reloc, 0);
0214         if (r) {
0215             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0216                   idx, reg);
0217             radeon_cs_dump_packet(p, pkt);
0218             return r;
0219         }
0220         if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
0221             if (reloc->tiling_flags & RADEON_TILING_MACRO)
0222                 tile_flags |= R200_TXO_MACRO_TILE;
0223             if (reloc->tiling_flags & RADEON_TILING_MICRO)
0224                 tile_flags |= R200_TXO_MICRO_TILE;
0225 
0226             tmp = idx_value & ~(0x7 << 2);
0227             tmp |= tile_flags;
0228             ib[idx] = tmp + ((u32)reloc->gpu_offset);
0229         } else
0230             ib[idx] = idx_value + ((u32)reloc->gpu_offset);
0231         track->textures[i].robj = reloc->robj;
0232         track->tex_dirty = true;
0233         break;
0234     case R200_PP_CUBIC_OFFSET_F1_0:
0235     case R200_PP_CUBIC_OFFSET_F2_0:
0236     case R200_PP_CUBIC_OFFSET_F3_0:
0237     case R200_PP_CUBIC_OFFSET_F4_0:
0238     case R200_PP_CUBIC_OFFSET_F5_0:
0239     case R200_PP_CUBIC_OFFSET_F1_1:
0240     case R200_PP_CUBIC_OFFSET_F2_1:
0241     case R200_PP_CUBIC_OFFSET_F3_1:
0242     case R200_PP_CUBIC_OFFSET_F4_1:
0243     case R200_PP_CUBIC_OFFSET_F5_1:
0244     case R200_PP_CUBIC_OFFSET_F1_2:
0245     case R200_PP_CUBIC_OFFSET_F2_2:
0246     case R200_PP_CUBIC_OFFSET_F3_2:
0247     case R200_PP_CUBIC_OFFSET_F4_2:
0248     case R200_PP_CUBIC_OFFSET_F5_2:
0249     case R200_PP_CUBIC_OFFSET_F1_3:
0250     case R200_PP_CUBIC_OFFSET_F2_3:
0251     case R200_PP_CUBIC_OFFSET_F3_3:
0252     case R200_PP_CUBIC_OFFSET_F4_3:
0253     case R200_PP_CUBIC_OFFSET_F5_3:
0254     case R200_PP_CUBIC_OFFSET_F1_4:
0255     case R200_PP_CUBIC_OFFSET_F2_4:
0256     case R200_PP_CUBIC_OFFSET_F3_4:
0257     case R200_PP_CUBIC_OFFSET_F4_4:
0258     case R200_PP_CUBIC_OFFSET_F5_4:
0259     case R200_PP_CUBIC_OFFSET_F1_5:
0260     case R200_PP_CUBIC_OFFSET_F2_5:
0261     case R200_PP_CUBIC_OFFSET_F3_5:
0262     case R200_PP_CUBIC_OFFSET_F4_5:
0263     case R200_PP_CUBIC_OFFSET_F5_5:
0264         i = (reg - R200_PP_TXOFFSET_0) / 24;
0265         face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
0266         r = radeon_cs_packet_next_reloc(p, &reloc, 0);
0267         if (r) {
0268             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0269                   idx, reg);
0270             radeon_cs_dump_packet(p, pkt);
0271             return r;
0272         }
0273         track->textures[i].cube_info[face - 1].offset = idx_value;
0274         ib[idx] = idx_value + ((u32)reloc->gpu_offset);
0275         track->textures[i].cube_info[face - 1].robj = reloc->robj;
0276         track->tex_dirty = true;
0277         break;
0278     case RADEON_RE_WIDTH_HEIGHT:
0279         track->maxy = ((idx_value >> 16) & 0x7FF);
0280         track->cb_dirty = true;
0281         track->zb_dirty = true;
0282         break;
0283     case RADEON_RB3D_COLORPITCH:
0284         r = radeon_cs_packet_next_reloc(p, &reloc, 0);
0285         if (r) {
0286             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0287                   idx, reg);
0288             radeon_cs_dump_packet(p, pkt);
0289             return r;
0290         }
0291 
0292         if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
0293             if (reloc->tiling_flags & RADEON_TILING_MACRO)
0294                 tile_flags |= RADEON_COLOR_TILE_ENABLE;
0295             if (reloc->tiling_flags & RADEON_TILING_MICRO)
0296                 tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
0297 
0298             tmp = idx_value & ~(0x7 << 16);
0299             tmp |= tile_flags;
0300             ib[idx] = tmp;
0301         } else
0302             ib[idx] = idx_value;
0303 
0304         track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
0305         track->cb_dirty = true;
0306         break;
0307     case RADEON_RB3D_DEPTHPITCH:
0308         track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
0309         track->zb_dirty = true;
0310         break;
0311     case RADEON_RB3D_CNTL:
0312         switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
0313         case 7:
0314         case 8:
0315         case 9:
0316         case 11:
0317         case 12:
0318             track->cb[0].cpp = 1;
0319             break;
0320         case 3:
0321         case 4:
0322         case 15:
0323             track->cb[0].cpp = 2;
0324             break;
0325         case 6:
0326             track->cb[0].cpp = 4;
0327             break;
0328         default:
0329             DRM_ERROR("Invalid color buffer format (%d) !\n",
0330                   ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
0331             return -EINVAL;
0332         }
0333         if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) {
0334             DRM_ERROR("No support for depth xy offset in kms\n");
0335             return -EINVAL;
0336         }
0337 
0338         track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
0339         track->cb_dirty = true;
0340         track->zb_dirty = true;
0341         break;
0342     case RADEON_RB3D_ZSTENCILCNTL:
0343         switch (idx_value & 0xf) {
0344         case 0:
0345             track->zb.cpp = 2;
0346             break;
0347         case 2:
0348         case 3:
0349         case 4:
0350         case 5:
0351         case 9:
0352         case 11:
0353             track->zb.cpp = 4;
0354             break;
0355         default:
0356             break;
0357         }
0358         track->zb_dirty = true;
0359         break;
0360     case RADEON_RB3D_ZPASS_ADDR:
0361         r = radeon_cs_packet_next_reloc(p, &reloc, 0);
0362         if (r) {
0363             DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
0364                   idx, reg);
0365             radeon_cs_dump_packet(p, pkt);
0366             return r;
0367         }
0368         ib[idx] = idx_value + ((u32)reloc->gpu_offset);
0369         break;
0370     case RADEON_PP_CNTL:
0371         {
0372             uint32_t temp = idx_value >> 4;
0373             for (i = 0; i < track->num_texture; i++)
0374                 track->textures[i].enabled = !!(temp & (1 << i));
0375             track->tex_dirty = true;
0376         }
0377         break;
0378     case RADEON_SE_VF_CNTL:
0379         track->vap_vf_cntl = idx_value;
0380         break;
0381     case 0x210c:
0382         /* VAP_VF_MAX_VTX_INDX */
0383         track->max_indx = idx_value & 0x00FFFFFFUL;
0384         break;
0385     case R200_SE_VTX_FMT_0:
0386         track->vtx_size = r200_get_vtx_size_0(idx_value);
0387         break;
0388     case R200_SE_VTX_FMT_1:
0389         track->vtx_size += r200_get_vtx_size_1(idx_value);
0390         break;
0391     case R200_PP_TXSIZE_0:
0392     case R200_PP_TXSIZE_1:
0393     case R200_PP_TXSIZE_2:
0394     case R200_PP_TXSIZE_3:
0395     case R200_PP_TXSIZE_4:
0396     case R200_PP_TXSIZE_5:
0397         i = (reg - R200_PP_TXSIZE_0) / 32;
0398         track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
0399         track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
0400         track->tex_dirty = true;
0401         break;
0402     case R200_PP_TXPITCH_0:
0403     case R200_PP_TXPITCH_1:
0404     case R200_PP_TXPITCH_2:
0405     case R200_PP_TXPITCH_3:
0406     case R200_PP_TXPITCH_4:
0407     case R200_PP_TXPITCH_5:
0408         i = (reg - R200_PP_TXPITCH_0) / 32;
0409         track->textures[i].pitch = idx_value + 32;
0410         track->tex_dirty = true;
0411         break;
0412     case R200_PP_TXFILTER_0:
0413     case R200_PP_TXFILTER_1:
0414     case R200_PP_TXFILTER_2:
0415     case R200_PP_TXFILTER_3:
0416     case R200_PP_TXFILTER_4:
0417     case R200_PP_TXFILTER_5:
0418         i = (reg - R200_PP_TXFILTER_0) / 32;
0419         track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK)
0420                          >> R200_MAX_MIP_LEVEL_SHIFT);
0421         tmp = (idx_value >> 23) & 0x7;
0422         if (tmp == 2 || tmp == 6)
0423             track->textures[i].roundup_w = false;
0424         tmp = (idx_value >> 27) & 0x7;
0425         if (tmp == 2 || tmp == 6)
0426             track->textures[i].roundup_h = false;
0427         track->tex_dirty = true;
0428         break;
0429     case R200_PP_TXMULTI_CTL_0:
0430     case R200_PP_TXMULTI_CTL_1:
0431     case R200_PP_TXMULTI_CTL_2:
0432     case R200_PP_TXMULTI_CTL_3:
0433     case R200_PP_TXMULTI_CTL_4:
0434     case R200_PP_TXMULTI_CTL_5:
0435         i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
0436         break;
0437     case R200_PP_TXFORMAT_X_0:
0438     case R200_PP_TXFORMAT_X_1:
0439     case R200_PP_TXFORMAT_X_2:
0440     case R200_PP_TXFORMAT_X_3:
0441     case R200_PP_TXFORMAT_X_4:
0442     case R200_PP_TXFORMAT_X_5:
0443         i = (reg - R200_PP_TXFORMAT_X_0) / 32;
0444         track->textures[i].txdepth = idx_value & 0x7;
0445         tmp = (idx_value >> 16) & 0x3;
0446         /* 2D, 3D, CUBE */
0447         switch (tmp) {
0448         case 0:
0449         case 3:
0450         case 4:
0451         case 5:
0452         case 6:
0453         case 7:
0454             /* 1D/2D */
0455             track->textures[i].tex_coord_type = 0;
0456             break;
0457         case 1:
0458             /* CUBE */
0459             track->textures[i].tex_coord_type = 2;
0460             break;
0461         case 2:
0462             /* 3D */
0463             track->textures[i].tex_coord_type = 1;
0464             break;
0465         }
0466         track->tex_dirty = true;
0467         break;
0468     case R200_PP_TXFORMAT_0:
0469     case R200_PP_TXFORMAT_1:
0470     case R200_PP_TXFORMAT_2:
0471     case R200_PP_TXFORMAT_3:
0472     case R200_PP_TXFORMAT_4:
0473     case R200_PP_TXFORMAT_5:
0474         i = (reg - R200_PP_TXFORMAT_0) / 32;
0475         if (idx_value & R200_TXFORMAT_NON_POWER2) {
0476             track->textures[i].use_pitch = 1;
0477         } else {
0478             track->textures[i].use_pitch = 0;
0479             track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
0480             track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
0481         }
0482         if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
0483             track->textures[i].lookup_disable = true;
0484         switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
0485         case R200_TXFORMAT_I8:
0486         case R200_TXFORMAT_RGB332:
0487         case R200_TXFORMAT_Y8:
0488             track->textures[i].cpp = 1;
0489             track->textures[i].compress_format = R100_TRACK_COMP_NONE;
0490             break;
0491         case R200_TXFORMAT_AI88:
0492         case R200_TXFORMAT_ARGB1555:
0493         case R200_TXFORMAT_RGB565:
0494         case R200_TXFORMAT_ARGB4444:
0495         case R200_TXFORMAT_VYUY422:
0496         case R200_TXFORMAT_YVYU422:
0497         case R200_TXFORMAT_LDVDU655:
0498         case R200_TXFORMAT_DVDU88:
0499         case R200_TXFORMAT_AVYU4444:
0500             track->textures[i].cpp = 2;
0501             track->textures[i].compress_format = R100_TRACK_COMP_NONE;
0502             break;
0503         case R200_TXFORMAT_ARGB8888:
0504         case R200_TXFORMAT_RGBA8888:
0505         case R200_TXFORMAT_ABGR8888:
0506         case R200_TXFORMAT_BGR111110:
0507         case R200_TXFORMAT_LDVDU8888:
0508             track->textures[i].cpp = 4;
0509             track->textures[i].compress_format = R100_TRACK_COMP_NONE;
0510             break;
0511         case R200_TXFORMAT_DXT1:
0512             track->textures[i].cpp = 1;
0513             track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
0514             break;
0515         case R200_TXFORMAT_DXT23:
0516         case R200_TXFORMAT_DXT45:
0517             track->textures[i].cpp = 1;
0518             track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
0519             break;
0520         }
0521         track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
0522         track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
0523         track->tex_dirty = true;
0524         break;
0525     case R200_PP_CUBIC_FACES_0:
0526     case R200_PP_CUBIC_FACES_1:
0527     case R200_PP_CUBIC_FACES_2:
0528     case R200_PP_CUBIC_FACES_3:
0529     case R200_PP_CUBIC_FACES_4:
0530     case R200_PP_CUBIC_FACES_5:
0531         tmp = idx_value;
0532         i = (reg - R200_PP_CUBIC_FACES_0) / 32;
0533         for (face = 0; face < 4; face++) {
0534             track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
0535             track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
0536         }
0537         track->tex_dirty = true;
0538         break;
0539     default:
0540         pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx);
0541         return -EINVAL;
0542     }
0543     return 0;
0544 }
0545 
0546 void r200_set_safe_registers(struct radeon_device *rdev)
0547 {
0548     rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
0549     rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
0550 }