r200.c 15.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Copyright 2008 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 * Copyright 2009 Jerome Glisse.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Dave Airlie
 *          Alex Deucher
 *          Jerome Glisse
 */
28 29
#include <drm/drmP.h>
#include <drm/radeon_drm.h>
30 31
#include "radeon_reg.h"
#include "radeon.h"
32
#include "radeon_asic.h"
33

34
#include "r100d.h"
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#include "r200_reg_safe.h"

#include "r100_track.h"

static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
{
	int vtx_size, i;
	vtx_size = 2;

	if (vtx_fmt_0 & R200_VTX_Z0)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_W0)
		vtx_size++;
	/* blend weight */
	if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
		vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
	if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_N0)
		vtx_size += 3;
	if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_SHININESS_0)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_SHININESS_1)
		vtx_size++;
	for (i = 0; i < 8; i++) {
		int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
		switch (color_size) {
		case 0: break;
		case 1: vtx_size++; break;
		case 2: vtx_size += 3; break;
		case 3: vtx_size += 4; break;
		}
	}
	if (vtx_fmt_0 & R200_VTX_XY1)
		vtx_size += 2;
	if (vtx_fmt_0 & R200_VTX_Z1)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_W1)
		vtx_size++;
	if (vtx_fmt_0 & R200_VTX_N1)
		vtx_size += 3;
	return vtx_size;
}

83 84 85 86 87
struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
				   uint64_t src_offset,
				   uint64_t dst_offset,
				   unsigned num_gpu_pages,
				   struct reservation_object *resv)
88
{
89
	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
90
	struct radeon_fence *fence;
91 92 93 94 95 96
	uint32_t size;
	uint32_t cur_size;
	int i, num_loops;
	int r = 0;

	/* radeon pitch is /64 */
97
	size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
98
	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
99
	r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
100 101
	if (r) {
		DRM_ERROR("radeon: moving bo (%d).\n", r);
102
		return ERR_PTR(r);
103 104
	}
	/* Must wait for 2D idle & clean before DMA or hangs might happen */
105 106
	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
	radeon_ring_write(ring, (1 << 16));
107 108 109 110 111 112
	for (i = 0; i < num_loops; i++) {
		cur_size = size;
		if (cur_size > 0x1FFFFF) {
			cur_size = 0x1FFFFF;
		}
		size -= cur_size;
113 114 115 116
		radeon_ring_write(ring, PACKET0(0x720, 2));
		radeon_ring_write(ring, src_offset);
		radeon_ring_write(ring, dst_offset);
		radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30));
117 118 119
		src_offset += cur_size;
		dst_offset += cur_size;
	}
120 121
	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
	radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
122 123 124 125
	r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
	if (r) {
		radeon_ring_unlock_undo(rdev, ring);
		return ERR_PTR(r);
126
	}
127
	radeon_ring_unlock_commit(rdev, ring, false);
128
	return fence;
129 130 131
}


132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
{
	int vtx_size, i, tex_size;
	vtx_size = 0;
	for (i = 0; i < 6; i++) {
		tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
		if (tex_size > 4)
			continue;
		vtx_size += tex_size;
	}
	return vtx_size;
}

int r200_packet0_check(struct radeon_cs_parser *p,
		       struct radeon_cs_packet *pkt,
		       unsigned idx, unsigned reg)
{
149
	struct radeon_bo_list *reloc;
150 151 152 153 154 155 156
	struct r100_cs_track *track;
	volatile uint32_t *ib;
	uint32_t tmp;
	int r;
	int i;
	int face;
	u32 tile_flags = 0;
157
	u32 idx_value;
158

159
	ib = p->ib.ptr;
160
	track = (struct r100_cs_track *)p->track;
161
	idx_value = radeon_get_ib_value(p, idx);
162 163 164 165 166 167
	switch (reg) {
	case RADEON_CRTC_GUI_TRIG_VLINE:
		r = r100_cs_packet_parse_vline(p);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
168
			radeon_cs_dump_packet(p, pkt);
169 170 171 172 173 174 175 176 177 178 179 180
			return r;
		}
		break;
		/* FIXME: only allow PACKET3 blit? easier to check for out of
		 * range access */
	case RADEON_DST_PITCH_OFFSET:
	case RADEON_SRC_PITCH_OFFSET:
		r = r100_reloc_pitch_offset(p, pkt, idx, reg);
		if (r)
			return r;
		break;
	case RADEON_RB3D_DEPTHOFFSET:
181
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
182 183 184
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
185
			radeon_cs_dump_packet(p, pkt);
186 187 188
			return r;
		}
		track->zb.robj = reloc->robj;
189
		track->zb.offset = idx_value;
190
		track->zb_dirty = true;
191
		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
192 193
		break;
	case RADEON_RB3D_COLOROFFSET:
194
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
195 196 197
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
198
			radeon_cs_dump_packet(p, pkt);
199 200 201
			return r;
		}
		track->cb[0].robj = reloc->robj;
202
		track->cb[0].offset = idx_value;
203
		track->cb_dirty = true;
204
		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
205 206 207 208 209 210 211 212
		break;
	case R200_PP_TXOFFSET_0:
	case R200_PP_TXOFFSET_1:
	case R200_PP_TXOFFSET_2:
	case R200_PP_TXOFFSET_3:
	case R200_PP_TXOFFSET_4:
	case R200_PP_TXOFFSET_5:
		i = (reg - R200_PP_TXOFFSET_0) / 24;
213
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
214 215 216
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
217
			radeon_cs_dump_packet(p, pkt);
218 219
			return r;
		}
220
		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
221
			if (reloc->tiling_flags & RADEON_TILING_MACRO)
222
				tile_flags |= R200_TXO_MACRO_TILE;
223
			if (reloc->tiling_flags & RADEON_TILING_MICRO)
224 225 226 227
				tile_flags |= R200_TXO_MICRO_TILE;

			tmp = idx_value & ~(0x7 << 2);
			tmp |= tile_flags;
228
			ib[idx] = tmp + ((u32)reloc->gpu_offset);
229
		} else
230
			ib[idx] = idx_value + ((u32)reloc->gpu_offset);
231
		track->textures[i].robj = reloc->robj;
232
		track->tex_dirty = true;
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
		break;
	case R200_PP_CUBIC_OFFSET_F1_0:
	case R200_PP_CUBIC_OFFSET_F2_0:
	case R200_PP_CUBIC_OFFSET_F3_0:
	case R200_PP_CUBIC_OFFSET_F4_0:
	case R200_PP_CUBIC_OFFSET_F5_0:
	case R200_PP_CUBIC_OFFSET_F1_1:
	case R200_PP_CUBIC_OFFSET_F2_1:
	case R200_PP_CUBIC_OFFSET_F3_1:
	case R200_PP_CUBIC_OFFSET_F4_1:
	case R200_PP_CUBIC_OFFSET_F5_1:
	case R200_PP_CUBIC_OFFSET_F1_2:
	case R200_PP_CUBIC_OFFSET_F2_2:
	case R200_PP_CUBIC_OFFSET_F3_2:
	case R200_PP_CUBIC_OFFSET_F4_2:
	case R200_PP_CUBIC_OFFSET_F5_2:
	case R200_PP_CUBIC_OFFSET_F1_3:
	case R200_PP_CUBIC_OFFSET_F2_3:
	case R200_PP_CUBIC_OFFSET_F3_3:
	case R200_PP_CUBIC_OFFSET_F4_3:
	case R200_PP_CUBIC_OFFSET_F5_3:
	case R200_PP_CUBIC_OFFSET_F1_4:
	case R200_PP_CUBIC_OFFSET_F2_4:
	case R200_PP_CUBIC_OFFSET_F3_4:
	case R200_PP_CUBIC_OFFSET_F4_4:
	case R200_PP_CUBIC_OFFSET_F5_4:
	case R200_PP_CUBIC_OFFSET_F1_5:
	case R200_PP_CUBIC_OFFSET_F2_5:
	case R200_PP_CUBIC_OFFSET_F3_5:
	case R200_PP_CUBIC_OFFSET_F4_5:
	case R200_PP_CUBIC_OFFSET_F5_5:
		i = (reg - R200_PP_TXOFFSET_0) / 24;
		face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
266
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
267 268 269
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
270
			radeon_cs_dump_packet(p, pkt);
271 272
			return r;
		}
273
		track->textures[i].cube_info[face - 1].offset = idx_value;
274
		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
275
		track->textures[i].cube_info[face - 1].robj = reloc->robj;
276
		track->tex_dirty = true;
277 278
		break;
	case RADEON_RE_WIDTH_HEIGHT:
279
		track->maxy = ((idx_value >> 16) & 0x7FF);
280 281
		track->cb_dirty = true;
		track->zb_dirty = true;
282 283
		break;
	case RADEON_RB3D_COLORPITCH:
284
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
285 286 287
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
288
			radeon_cs_dump_packet(p, pkt);
289 290 291
			return r;
		}

292
		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
293
			if (reloc->tiling_flags & RADEON_TILING_MACRO)
294
				tile_flags |= RADEON_COLOR_TILE_ENABLE;
295
			if (reloc->tiling_flags & RADEON_TILING_MICRO)
296
				tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
297

298 299 300 301 302
			tmp = idx_value & ~(0x7 << 16);
			tmp |= tile_flags;
			ib[idx] = tmp;
		} else
			ib[idx] = idx_value;
303

304
		track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
305
		track->cb_dirty = true;
306 307
		break;
	case RADEON_RB3D_DEPTHPITCH:
308
		track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
309
		track->zb_dirty = true;
310 311
		break;
	case RADEON_RB3D_CNTL:
312
		switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
		case 7:
		case 8:
		case 9:
		case 11:
		case 12:
			track->cb[0].cpp = 1;
			break;
		case 3:
		case 4:
		case 15:
			track->cb[0].cpp = 2;
			break;
		case 6:
			track->cb[0].cpp = 4;
			break;
		default:
			DRM_ERROR("Invalid color buffer format (%d) !\n",
330
				  ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
331 332
			return -EINVAL;
		}
333
		if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) {
334 335 336 337
			DRM_ERROR("No support for depth xy offset in kms\n");
			return -EINVAL;
		}

338
		track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
339 340
		track->cb_dirty = true;
		track->zb_dirty = true;
341 342
		break;
	case RADEON_RB3D_ZSTENCILCNTL:
343
		switch (idx_value & 0xf) {
344 345 346 347 348 349 350 351 352 353 354 355 356 357
		case 0:
			track->zb.cpp = 2;
			break;
		case 2:
		case 3:
		case 4:
		case 5:
		case 9:
		case 11:
			track->zb.cpp = 4;
			break;
		default:
			break;
		}
358
		track->zb_dirty = true;
359 360
		break;
	case RADEON_RB3D_ZPASS_ADDR:
361
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
362 363 364
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
365
			radeon_cs_dump_packet(p, pkt);
366 367
			return r;
		}
368
		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
369 370 371
		break;
	case RADEON_PP_CNTL:
		{
372
			uint32_t temp = idx_value >> 4;
373 374
			for (i = 0; i < track->num_texture; i++)
				track->textures[i].enabled = !!(temp & (1 << i));
375
			track->tex_dirty = true;
376 377 378
		}
		break;
	case RADEON_SE_VF_CNTL:
379
		track->vap_vf_cntl = idx_value;
380 381 382
		break;
	case 0x210c:
		/* VAP_VF_MAX_VTX_INDX */
383
		track->max_indx = idx_value & 0x00FFFFFFUL;
384 385
		break;
	case R200_SE_VTX_FMT_0:
386
		track->vtx_size = r200_get_vtx_size_0(idx_value);
387 388
		break;
	case R200_SE_VTX_FMT_1:
389
		track->vtx_size += r200_get_vtx_size_1(idx_value);
390 391 392 393 394 395 396 397
		break;
	case R200_PP_TXSIZE_0:
	case R200_PP_TXSIZE_1:
	case R200_PP_TXSIZE_2:
	case R200_PP_TXSIZE_3:
	case R200_PP_TXSIZE_4:
	case R200_PP_TXSIZE_5:
		i = (reg - R200_PP_TXSIZE_0) / 32;
398 399
		track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
		track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
400
		track->tex_dirty = true;
401 402 403 404 405 406 407 408
		break;
	case R200_PP_TXPITCH_0:
	case R200_PP_TXPITCH_1:
	case R200_PP_TXPITCH_2:
	case R200_PP_TXPITCH_3:
	case R200_PP_TXPITCH_4:
	case R200_PP_TXPITCH_5:
		i = (reg - R200_PP_TXPITCH_0) / 32;
409
		track->textures[i].pitch = idx_value + 32;
410
		track->tex_dirty = true;
411 412 413 414 415 416 417 418
		break;
	case R200_PP_TXFILTER_0:
	case R200_PP_TXFILTER_1:
	case R200_PP_TXFILTER_2:
	case R200_PP_TXFILTER_3:
	case R200_PP_TXFILTER_4:
	case R200_PP_TXFILTER_5:
		i = (reg - R200_PP_TXFILTER_0) / 32;
419
		track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK)
420
						 >> R200_MAX_MIP_LEVEL_SHIFT);
421
		tmp = (idx_value >> 23) & 0x7;
422 423
		if (tmp == 2 || tmp == 6)
			track->textures[i].roundup_w = false;
424
		tmp = (idx_value >> 27) & 0x7;
425 426
		if (tmp == 2 || tmp == 6)
			track->textures[i].roundup_h = false;
427
		track->tex_dirty = true;
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
		break;
	case R200_PP_TXMULTI_CTL_0:
	case R200_PP_TXMULTI_CTL_1:
	case R200_PP_TXMULTI_CTL_2:
	case R200_PP_TXMULTI_CTL_3:
	case R200_PP_TXMULTI_CTL_4:
	case R200_PP_TXMULTI_CTL_5:
		i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
		break;
	case R200_PP_TXFORMAT_X_0:
	case R200_PP_TXFORMAT_X_1:
	case R200_PP_TXFORMAT_X_2:
	case R200_PP_TXFORMAT_X_3:
	case R200_PP_TXFORMAT_X_4:
	case R200_PP_TXFORMAT_X_5:
		i = (reg - R200_PP_TXFORMAT_X_0) / 32;
444 445
		track->textures[i].txdepth = idx_value & 0x7;
		tmp = (idx_value >> 16) & 0x3;
446 447 448
		/* 2D, 3D, CUBE */
		switch (tmp) {
		case 0:
449 450
		case 3:
		case 4:
451 452 453
		case 5:
		case 6:
		case 7:
454
			/* 1D/2D */
455 456 457
			track->textures[i].tex_coord_type = 0;
			break;
		case 1:
458 459
			/* CUBE */
			track->textures[i].tex_coord_type = 2;
460 461
			break;
		case 2:
462 463
			/* 3D */
			track->textures[i].tex_coord_type = 1;
464 465
			break;
		}
466
		track->tex_dirty = true;
467 468 469 470 471 472 473 474
		break;
	case R200_PP_TXFORMAT_0:
	case R200_PP_TXFORMAT_1:
	case R200_PP_TXFORMAT_2:
	case R200_PP_TXFORMAT_3:
	case R200_PP_TXFORMAT_4:
	case R200_PP_TXFORMAT_5:
		i = (reg - R200_PP_TXFORMAT_0) / 32;
475
		if (idx_value & R200_TXFORMAT_NON_POWER2) {
476 477 478
			track->textures[i].use_pitch = 1;
		} else {
			track->textures[i].use_pitch = 0;
479 480
			track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
			track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
481
		}
482 483
		if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
			track->textures[i].lookup_disable = true;
484
		switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
485 486 487 488
		case R200_TXFORMAT_I8:
		case R200_TXFORMAT_RGB332:
		case R200_TXFORMAT_Y8:
			track->textures[i].cpp = 1;
489
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
490 491 492 493 494 495 496 497 498 499 500
			break;
		case R200_TXFORMAT_AI88:
		case R200_TXFORMAT_ARGB1555:
		case R200_TXFORMAT_RGB565:
		case R200_TXFORMAT_ARGB4444:
		case R200_TXFORMAT_VYUY422:
		case R200_TXFORMAT_YVYU422:
		case R200_TXFORMAT_LDVDU655:
		case R200_TXFORMAT_DVDU88:
		case R200_TXFORMAT_AVYU4444:
			track->textures[i].cpp = 2;
501
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
502 503 504 505 506 507
			break;
		case R200_TXFORMAT_ARGB8888:
		case R200_TXFORMAT_RGBA8888:
		case R200_TXFORMAT_ABGR8888:
		case R200_TXFORMAT_BGR111110:
		case R200_TXFORMAT_LDVDU8888:
508
			track->textures[i].cpp = 4;
509
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
510 511 512 513 514
			break;
		case R200_TXFORMAT_DXT1:
			track->textures[i].cpp = 1;
			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
			break;
515 516
		case R200_TXFORMAT_DXT23:
		case R200_TXFORMAT_DXT45:
517 518
			track->textures[i].cpp = 1;
			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
519 520
			break;
		}
521 522
		track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
		track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
523
		track->tex_dirty = true;
524 525 526 527 528 529 530
		break;
	case R200_PP_CUBIC_FACES_0:
	case R200_PP_CUBIC_FACES_1:
	case R200_PP_CUBIC_FACES_2:
	case R200_PP_CUBIC_FACES_3:
	case R200_PP_CUBIC_FACES_4:
	case R200_PP_CUBIC_FACES_5:
531
		tmp = idx_value;
532 533 534 535 536
		i = (reg - R200_PP_CUBIC_FACES_0) / 32;
		for (face = 0; face < 4; face++) {
			track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
			track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
		}
537
		track->tex_dirty = true;
538 539
		break;
	default:
540
		pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx);
541 542 543 544 545
		return -EINVAL;
	}
	return 0;
}

546
void r200_set_safe_registers(struct radeon_device *rdev)
547 548 549 550
{
	rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
	rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
}