xref: /openbsd-src/sys/dev/pci/drm/radeon/r200.c (revision c349dbc7938c71a30e13c1be4acc1976165f4630)
11099013bSjsg /*
21099013bSjsg  * Copyright 2008 Advanced Micro Devices, Inc.
31099013bSjsg  * Copyright 2008 Red Hat Inc.
41099013bSjsg  * Copyright 2009 Jerome Glisse.
51099013bSjsg  *
61099013bSjsg  * Permission is hereby granted, free of charge, to any person obtaining a
71099013bSjsg  * copy of this software and associated documentation files (the "Software"),
81099013bSjsg  * to deal in the Software without restriction, including without limitation
91099013bSjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
101099013bSjsg  * and/or sell copies of the Software, and to permit persons to whom the
111099013bSjsg  * Software is furnished to do so, subject to the following conditions:
121099013bSjsg  *
131099013bSjsg  * The above copyright notice and this permission notice shall be included in
141099013bSjsg  * all copies or substantial portions of the Software.
151099013bSjsg  *
161099013bSjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171099013bSjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181099013bSjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
191099013bSjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
201099013bSjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
211099013bSjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
221099013bSjsg  * OTHER DEALINGS IN THE SOFTWARE.
231099013bSjsg  *
241099013bSjsg  * Authors: Dave Airlie
251099013bSjsg  *          Alex Deucher
261099013bSjsg  *          Jerome Glisse
271099013bSjsg  */
28*c349dbc7Sjsg 
297f4dd379Sjsg #include <drm/radeon_drm.h>
301099013bSjsg #include "radeon_reg.h"
311099013bSjsg #include "radeon.h"
321099013bSjsg #include "radeon_asic.h"
331099013bSjsg 
341099013bSjsg #include "r100d.h"
351099013bSjsg #include "r200_reg_safe.h"
361099013bSjsg 
371099013bSjsg #include "r100_track.h"
381099013bSjsg 
r200_get_vtx_size_0(uint32_t vtx_fmt_0)391099013bSjsg static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
401099013bSjsg {
411099013bSjsg 	int vtx_size, i;
421099013bSjsg 	vtx_size = 2;
431099013bSjsg 
441099013bSjsg 	if (vtx_fmt_0 & R200_VTX_Z0)
451099013bSjsg 		vtx_size++;
461099013bSjsg 	if (vtx_fmt_0 & R200_VTX_W0)
471099013bSjsg 		vtx_size++;
481099013bSjsg 	/* blend weight */
491099013bSjsg 	if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
501099013bSjsg 		vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
511099013bSjsg 	if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
521099013bSjsg 		vtx_size++;
531099013bSjsg 	if (vtx_fmt_0 & R200_VTX_N0)
541099013bSjsg 		vtx_size += 3;
551099013bSjsg 	if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
561099013bSjsg 		vtx_size++;
571099013bSjsg 	if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
581099013bSjsg 		vtx_size++;
591099013bSjsg 	if (vtx_fmt_0 & R200_VTX_SHININESS_0)
601099013bSjsg 		vtx_size++;
611099013bSjsg 	if (vtx_fmt_0 & R200_VTX_SHININESS_1)
621099013bSjsg 		vtx_size++;
631099013bSjsg 	for (i = 0; i < 8; i++) {
641099013bSjsg 		int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
651099013bSjsg 		switch (color_size) {
661099013bSjsg 		case 0: break;
671099013bSjsg 		case 1: vtx_size++; break;
681099013bSjsg 		case 2: vtx_size += 3; break;
691099013bSjsg 		case 3: vtx_size += 4; break;
701099013bSjsg 		}
711099013bSjsg 	}
721099013bSjsg 	if (vtx_fmt_0 & R200_VTX_XY1)
731099013bSjsg 		vtx_size += 2;
741099013bSjsg 	if (vtx_fmt_0 & R200_VTX_Z1)
751099013bSjsg 		vtx_size++;
761099013bSjsg 	if (vtx_fmt_0 & R200_VTX_W1)
771099013bSjsg 		vtx_size++;
781099013bSjsg 	if (vtx_fmt_0 & R200_VTX_N1)
791099013bSjsg 		vtx_size += 3;
801099013bSjsg 	return vtx_size;
811099013bSjsg }
821099013bSjsg 
r200_copy_dma(struct radeon_device * rdev,uint64_t src_offset,uint64_t dst_offset,unsigned num_gpu_pages,struct dma_resv * resv)837ccd5a2cSjsg struct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
841099013bSjsg 				   uint64_t src_offset,
851099013bSjsg 				   uint64_t dst_offset,
861099013bSjsg 				   unsigned num_gpu_pages,
87*c349dbc7Sjsg 				   struct dma_resv *resv)
881099013bSjsg {
891099013bSjsg 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
907ccd5a2cSjsg 	struct radeon_fence *fence;
911099013bSjsg 	uint32_t size;
921099013bSjsg 	uint32_t cur_size;
931099013bSjsg 	int i, num_loops;
941099013bSjsg 	int r = 0;
951099013bSjsg 
961099013bSjsg 	/* radeon pitch is /64 */
971099013bSjsg 	size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
98a99ede96Sjsg 	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
991099013bSjsg 	r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
1001099013bSjsg 	if (r) {
1011099013bSjsg 		DRM_ERROR("radeon: moving bo (%d).\n", r);
1027ccd5a2cSjsg 		return ERR_PTR(r);
1031099013bSjsg 	}
1041099013bSjsg 	/* Must wait for 2D idle & clean before DMA or hangs might happen */
1051099013bSjsg 	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
1061099013bSjsg 	radeon_ring_write(ring, (1 << 16));
1071099013bSjsg 	for (i = 0; i < num_loops; i++) {
1081099013bSjsg 		cur_size = size;
1091099013bSjsg 		if (cur_size > 0x1FFFFF) {
1101099013bSjsg 			cur_size = 0x1FFFFF;
1111099013bSjsg 		}
1121099013bSjsg 		size -= cur_size;
1131099013bSjsg 		radeon_ring_write(ring, PACKET0(0x720, 2));
1141099013bSjsg 		radeon_ring_write(ring, src_offset);
1151099013bSjsg 		radeon_ring_write(ring, dst_offset);
1161099013bSjsg 		radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30));
1171099013bSjsg 		src_offset += cur_size;
1181099013bSjsg 		dst_offset += cur_size;
1191099013bSjsg 	}
1201099013bSjsg 	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
1211099013bSjsg 	radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
1227ccd5a2cSjsg 	r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
1237ccd5a2cSjsg 	if (r) {
1247ccd5a2cSjsg 		radeon_ring_unlock_undo(rdev, ring);
1257ccd5a2cSjsg 		return ERR_PTR(r);
1261099013bSjsg 	}
1277ccd5a2cSjsg 	radeon_ring_unlock_commit(rdev, ring, false);
1287ccd5a2cSjsg 	return fence;
1291099013bSjsg }
1301099013bSjsg 
1311099013bSjsg 
r200_get_vtx_size_1(uint32_t vtx_fmt_1)1321099013bSjsg static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
1331099013bSjsg {
1341099013bSjsg 	int vtx_size, i, tex_size;
1351099013bSjsg 	vtx_size = 0;
1361099013bSjsg 	for (i = 0; i < 6; i++) {
1371099013bSjsg 		tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
1381099013bSjsg 		if (tex_size > 4)
1391099013bSjsg 			continue;
1401099013bSjsg 		vtx_size += tex_size;
1411099013bSjsg 	}
1421099013bSjsg 	return vtx_size;
1431099013bSjsg }
1441099013bSjsg 
r200_packet0_check(struct radeon_cs_parser * p,struct radeon_cs_packet * pkt,unsigned idx,unsigned reg)1451099013bSjsg int r200_packet0_check(struct radeon_cs_parser *p,
1461099013bSjsg 		       struct radeon_cs_packet *pkt,
1471099013bSjsg 		       unsigned idx, unsigned reg)
1481099013bSjsg {
1497ccd5a2cSjsg 	struct radeon_bo_list *reloc;
1501099013bSjsg 	struct r100_cs_track *track;
1511099013bSjsg 	volatile uint32_t *ib;
1521099013bSjsg 	uint32_t tmp;
1531099013bSjsg 	int r;
1541099013bSjsg 	int i;
1551099013bSjsg 	int face;
1561099013bSjsg 	u32 tile_flags = 0;
1571099013bSjsg 	u32 idx_value;
1581099013bSjsg 
1591099013bSjsg 	ib = p->ib.ptr;
1601099013bSjsg 	track = (struct r100_cs_track *)p->track;
1611099013bSjsg 	idx_value = radeon_get_ib_value(p, idx);
1621099013bSjsg 	switch (reg) {
1631099013bSjsg 	case RADEON_CRTC_GUI_TRIG_VLINE:
1641099013bSjsg 		r = r100_cs_packet_parse_vline(p);
1651099013bSjsg 		if (r) {
1661099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1671099013bSjsg 				  idx, reg);
1687ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
1691099013bSjsg 			return r;
1701099013bSjsg 		}
1711099013bSjsg 		break;
1721099013bSjsg 		/* FIXME: only allow PACKET3 blit? easier to check for out of
1731099013bSjsg 		 * range access */
1741099013bSjsg 	case RADEON_DST_PITCH_OFFSET:
1751099013bSjsg 	case RADEON_SRC_PITCH_OFFSET:
1761099013bSjsg 		r = r100_reloc_pitch_offset(p, pkt, idx, reg);
1771099013bSjsg 		if (r)
1781099013bSjsg 			return r;
1791099013bSjsg 		break;
1801099013bSjsg 	case RADEON_RB3D_DEPTHOFFSET:
1817ccd5a2cSjsg 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
1821099013bSjsg 		if (r) {
1831099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1841099013bSjsg 				  idx, reg);
1857ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
1861099013bSjsg 			return r;
1871099013bSjsg 		}
1881099013bSjsg 		track->zb.robj = reloc->robj;
1891099013bSjsg 		track->zb.offset = idx_value;
1901099013bSjsg 		track->zb_dirty = true;
1917ccd5a2cSjsg 		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
1921099013bSjsg 		break;
1931099013bSjsg 	case RADEON_RB3D_COLOROFFSET:
1947ccd5a2cSjsg 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
1951099013bSjsg 		if (r) {
1961099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1971099013bSjsg 				  idx, reg);
1987ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
1991099013bSjsg 			return r;
2001099013bSjsg 		}
2011099013bSjsg 		track->cb[0].robj = reloc->robj;
2021099013bSjsg 		track->cb[0].offset = idx_value;
2031099013bSjsg 		track->cb_dirty = true;
2047ccd5a2cSjsg 		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
2051099013bSjsg 		break;
2061099013bSjsg 	case R200_PP_TXOFFSET_0:
2071099013bSjsg 	case R200_PP_TXOFFSET_1:
2081099013bSjsg 	case R200_PP_TXOFFSET_2:
2091099013bSjsg 	case R200_PP_TXOFFSET_3:
2101099013bSjsg 	case R200_PP_TXOFFSET_4:
2111099013bSjsg 	case R200_PP_TXOFFSET_5:
2121099013bSjsg 		i = (reg - R200_PP_TXOFFSET_0) / 24;
2137ccd5a2cSjsg 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2141099013bSjsg 		if (r) {
2151099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
2161099013bSjsg 				  idx, reg);
2177ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
2181099013bSjsg 			return r;
2191099013bSjsg 		}
2201099013bSjsg 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
2217ccd5a2cSjsg 			if (reloc->tiling_flags & RADEON_TILING_MACRO)
2221099013bSjsg 				tile_flags |= R200_TXO_MACRO_TILE;
2237ccd5a2cSjsg 			if (reloc->tiling_flags & RADEON_TILING_MICRO)
2241099013bSjsg 				tile_flags |= R200_TXO_MICRO_TILE;
2251099013bSjsg 
2261099013bSjsg 			tmp = idx_value & ~(0x7 << 2);
2271099013bSjsg 			tmp |= tile_flags;
2287ccd5a2cSjsg 			ib[idx] = tmp + ((u32)reloc->gpu_offset);
2291099013bSjsg 		} else
2307ccd5a2cSjsg 			ib[idx] = idx_value + ((u32)reloc->gpu_offset);
2311099013bSjsg 		track->textures[i].robj = reloc->robj;
2321099013bSjsg 		track->tex_dirty = true;
2331099013bSjsg 		break;
2341099013bSjsg 	case R200_PP_CUBIC_OFFSET_F1_0:
2351099013bSjsg 	case R200_PP_CUBIC_OFFSET_F2_0:
2361099013bSjsg 	case R200_PP_CUBIC_OFFSET_F3_0:
2371099013bSjsg 	case R200_PP_CUBIC_OFFSET_F4_0:
2381099013bSjsg 	case R200_PP_CUBIC_OFFSET_F5_0:
2391099013bSjsg 	case R200_PP_CUBIC_OFFSET_F1_1:
2401099013bSjsg 	case R200_PP_CUBIC_OFFSET_F2_1:
2411099013bSjsg 	case R200_PP_CUBIC_OFFSET_F3_1:
2421099013bSjsg 	case R200_PP_CUBIC_OFFSET_F4_1:
2431099013bSjsg 	case R200_PP_CUBIC_OFFSET_F5_1:
2441099013bSjsg 	case R200_PP_CUBIC_OFFSET_F1_2:
2451099013bSjsg 	case R200_PP_CUBIC_OFFSET_F2_2:
2461099013bSjsg 	case R200_PP_CUBIC_OFFSET_F3_2:
2471099013bSjsg 	case R200_PP_CUBIC_OFFSET_F4_2:
2481099013bSjsg 	case R200_PP_CUBIC_OFFSET_F5_2:
2491099013bSjsg 	case R200_PP_CUBIC_OFFSET_F1_3:
2501099013bSjsg 	case R200_PP_CUBIC_OFFSET_F2_3:
2511099013bSjsg 	case R200_PP_CUBIC_OFFSET_F3_3:
2521099013bSjsg 	case R200_PP_CUBIC_OFFSET_F4_3:
2531099013bSjsg 	case R200_PP_CUBIC_OFFSET_F5_3:
2541099013bSjsg 	case R200_PP_CUBIC_OFFSET_F1_4:
2551099013bSjsg 	case R200_PP_CUBIC_OFFSET_F2_4:
2561099013bSjsg 	case R200_PP_CUBIC_OFFSET_F3_4:
2571099013bSjsg 	case R200_PP_CUBIC_OFFSET_F4_4:
2581099013bSjsg 	case R200_PP_CUBIC_OFFSET_F5_4:
2591099013bSjsg 	case R200_PP_CUBIC_OFFSET_F1_5:
2601099013bSjsg 	case R200_PP_CUBIC_OFFSET_F2_5:
2611099013bSjsg 	case R200_PP_CUBIC_OFFSET_F3_5:
2621099013bSjsg 	case R200_PP_CUBIC_OFFSET_F4_5:
2631099013bSjsg 	case R200_PP_CUBIC_OFFSET_F5_5:
2641099013bSjsg 		i = (reg - R200_PP_TXOFFSET_0) / 24;
2651099013bSjsg 		face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
2667ccd5a2cSjsg 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2671099013bSjsg 		if (r) {
2681099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
2691099013bSjsg 				  idx, reg);
2707ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
2711099013bSjsg 			return r;
2721099013bSjsg 		}
2731099013bSjsg 		track->textures[i].cube_info[face - 1].offset = idx_value;
2747ccd5a2cSjsg 		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
2751099013bSjsg 		track->textures[i].cube_info[face - 1].robj = reloc->robj;
2761099013bSjsg 		track->tex_dirty = true;
2771099013bSjsg 		break;
2781099013bSjsg 	case RADEON_RE_WIDTH_HEIGHT:
2791099013bSjsg 		track->maxy = ((idx_value >> 16) & 0x7FF);
2801099013bSjsg 		track->cb_dirty = true;
2811099013bSjsg 		track->zb_dirty = true;
2821099013bSjsg 		break;
2831099013bSjsg 	case RADEON_RB3D_COLORPITCH:
2847ccd5a2cSjsg 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2851099013bSjsg 		if (r) {
2861099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
2871099013bSjsg 				  idx, reg);
2887ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
2891099013bSjsg 			return r;
2901099013bSjsg 		}
2911099013bSjsg 
2921099013bSjsg 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
2937ccd5a2cSjsg 			if (reloc->tiling_flags & RADEON_TILING_MACRO)
2941099013bSjsg 				tile_flags |= RADEON_COLOR_TILE_ENABLE;
2957ccd5a2cSjsg 			if (reloc->tiling_flags & RADEON_TILING_MICRO)
2961099013bSjsg 				tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
2971099013bSjsg 
2981099013bSjsg 			tmp = idx_value & ~(0x7 << 16);
2991099013bSjsg 			tmp |= tile_flags;
3001099013bSjsg 			ib[idx] = tmp;
3011099013bSjsg 		} else
3021099013bSjsg 			ib[idx] = idx_value;
3031099013bSjsg 
3041099013bSjsg 		track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
3051099013bSjsg 		track->cb_dirty = true;
3061099013bSjsg 		break;
3071099013bSjsg 	case RADEON_RB3D_DEPTHPITCH:
3081099013bSjsg 		track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
3091099013bSjsg 		track->zb_dirty = true;
3101099013bSjsg 		break;
3111099013bSjsg 	case RADEON_RB3D_CNTL:
3121099013bSjsg 		switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
3131099013bSjsg 		case 7:
3141099013bSjsg 		case 8:
3151099013bSjsg 		case 9:
3161099013bSjsg 		case 11:
3171099013bSjsg 		case 12:
3181099013bSjsg 			track->cb[0].cpp = 1;
3191099013bSjsg 			break;
3201099013bSjsg 		case 3:
3211099013bSjsg 		case 4:
3221099013bSjsg 		case 15:
3231099013bSjsg 			track->cb[0].cpp = 2;
3241099013bSjsg 			break;
3251099013bSjsg 		case 6:
3261099013bSjsg 			track->cb[0].cpp = 4;
3271099013bSjsg 			break;
3281099013bSjsg 		default:
3291099013bSjsg 			DRM_ERROR("Invalid color buffer format (%d) !\n",
3301099013bSjsg 				  ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
3311099013bSjsg 			return -EINVAL;
3321099013bSjsg 		}
3331099013bSjsg 		if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) {
3341099013bSjsg 			DRM_ERROR("No support for depth xy offset in kms\n");
3351099013bSjsg 			return -EINVAL;
3361099013bSjsg 		}
3371099013bSjsg 
3381099013bSjsg 		track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
3391099013bSjsg 		track->cb_dirty = true;
3401099013bSjsg 		track->zb_dirty = true;
3411099013bSjsg 		break;
3421099013bSjsg 	case RADEON_RB3D_ZSTENCILCNTL:
3431099013bSjsg 		switch (idx_value & 0xf) {
3441099013bSjsg 		case 0:
3451099013bSjsg 			track->zb.cpp = 2;
3461099013bSjsg 			break;
3471099013bSjsg 		case 2:
3481099013bSjsg 		case 3:
3491099013bSjsg 		case 4:
3501099013bSjsg 		case 5:
3511099013bSjsg 		case 9:
3521099013bSjsg 		case 11:
3531099013bSjsg 			track->zb.cpp = 4;
3541099013bSjsg 			break;
3551099013bSjsg 		default:
3561099013bSjsg 			break;
3571099013bSjsg 		}
3581099013bSjsg 		track->zb_dirty = true;
3591099013bSjsg 		break;
3601099013bSjsg 	case RADEON_RB3D_ZPASS_ADDR:
3617ccd5a2cSjsg 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
3621099013bSjsg 		if (r) {
3631099013bSjsg 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
3641099013bSjsg 				  idx, reg);
3657ccd5a2cSjsg 			radeon_cs_dump_packet(p, pkt);
3661099013bSjsg 			return r;
3671099013bSjsg 		}
3687ccd5a2cSjsg 		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
3691099013bSjsg 		break;
3701099013bSjsg 	case RADEON_PP_CNTL:
3711099013bSjsg 		{
3721099013bSjsg 			uint32_t temp = idx_value >> 4;
3731099013bSjsg 			for (i = 0; i < track->num_texture; i++)
3741099013bSjsg 				track->textures[i].enabled = !!(temp & (1 << i));
3751099013bSjsg 			track->tex_dirty = true;
3761099013bSjsg 		}
3771099013bSjsg 		break;
3781099013bSjsg 	case RADEON_SE_VF_CNTL:
3791099013bSjsg 		track->vap_vf_cntl = idx_value;
3801099013bSjsg 		break;
3811099013bSjsg 	case 0x210c:
3821099013bSjsg 		/* VAP_VF_MAX_VTX_INDX */
3831099013bSjsg 		track->max_indx = idx_value & 0x00FFFFFFUL;
3841099013bSjsg 		break;
3851099013bSjsg 	case R200_SE_VTX_FMT_0:
3861099013bSjsg 		track->vtx_size = r200_get_vtx_size_0(idx_value);
3871099013bSjsg 		break;
3881099013bSjsg 	case R200_SE_VTX_FMT_1:
3891099013bSjsg 		track->vtx_size += r200_get_vtx_size_1(idx_value);
3901099013bSjsg 		break;
3911099013bSjsg 	case R200_PP_TXSIZE_0:
3921099013bSjsg 	case R200_PP_TXSIZE_1:
3931099013bSjsg 	case R200_PP_TXSIZE_2:
3941099013bSjsg 	case R200_PP_TXSIZE_3:
3951099013bSjsg 	case R200_PP_TXSIZE_4:
3961099013bSjsg 	case R200_PP_TXSIZE_5:
3971099013bSjsg 		i = (reg - R200_PP_TXSIZE_0) / 32;
3981099013bSjsg 		track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
3991099013bSjsg 		track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
4001099013bSjsg 		track->tex_dirty = true;
4011099013bSjsg 		break;
4021099013bSjsg 	case R200_PP_TXPITCH_0:
4031099013bSjsg 	case R200_PP_TXPITCH_1:
4041099013bSjsg 	case R200_PP_TXPITCH_2:
4051099013bSjsg 	case R200_PP_TXPITCH_3:
4061099013bSjsg 	case R200_PP_TXPITCH_4:
4071099013bSjsg 	case R200_PP_TXPITCH_5:
4081099013bSjsg 		i = (reg - R200_PP_TXPITCH_0) / 32;
4091099013bSjsg 		track->textures[i].pitch = idx_value + 32;
4101099013bSjsg 		track->tex_dirty = true;
4111099013bSjsg 		break;
4121099013bSjsg 	case R200_PP_TXFILTER_0:
4131099013bSjsg 	case R200_PP_TXFILTER_1:
4141099013bSjsg 	case R200_PP_TXFILTER_2:
4151099013bSjsg 	case R200_PP_TXFILTER_3:
4161099013bSjsg 	case R200_PP_TXFILTER_4:
4171099013bSjsg 	case R200_PP_TXFILTER_5:
4181099013bSjsg 		i = (reg - R200_PP_TXFILTER_0) / 32;
4191099013bSjsg 		track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK)
4201099013bSjsg 						 >> R200_MAX_MIP_LEVEL_SHIFT);
4211099013bSjsg 		tmp = (idx_value >> 23) & 0x7;
4221099013bSjsg 		if (tmp == 2 || tmp == 6)
4231099013bSjsg 			track->textures[i].roundup_w = false;
4241099013bSjsg 		tmp = (idx_value >> 27) & 0x7;
4251099013bSjsg 		if (tmp == 2 || tmp == 6)
4261099013bSjsg 			track->textures[i].roundup_h = false;
4271099013bSjsg 		track->tex_dirty = true;
4281099013bSjsg 		break;
4291099013bSjsg 	case R200_PP_TXMULTI_CTL_0:
4301099013bSjsg 	case R200_PP_TXMULTI_CTL_1:
4311099013bSjsg 	case R200_PP_TXMULTI_CTL_2:
4321099013bSjsg 	case R200_PP_TXMULTI_CTL_3:
4331099013bSjsg 	case R200_PP_TXMULTI_CTL_4:
4341099013bSjsg 	case R200_PP_TXMULTI_CTL_5:
4351099013bSjsg 		i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
4361099013bSjsg 		break;
4371099013bSjsg 	case R200_PP_TXFORMAT_X_0:
4381099013bSjsg 	case R200_PP_TXFORMAT_X_1:
4391099013bSjsg 	case R200_PP_TXFORMAT_X_2:
4401099013bSjsg 	case R200_PP_TXFORMAT_X_3:
4411099013bSjsg 	case R200_PP_TXFORMAT_X_4:
4421099013bSjsg 	case R200_PP_TXFORMAT_X_5:
4431099013bSjsg 		i = (reg - R200_PP_TXFORMAT_X_0) / 32;
4441099013bSjsg 		track->textures[i].txdepth = idx_value & 0x7;
4451099013bSjsg 		tmp = (idx_value >> 16) & 0x3;
4461099013bSjsg 		/* 2D, 3D, CUBE */
4471099013bSjsg 		switch (tmp) {
4481099013bSjsg 		case 0:
4491099013bSjsg 		case 3:
4501099013bSjsg 		case 4:
4511099013bSjsg 		case 5:
4521099013bSjsg 		case 6:
4531099013bSjsg 		case 7:
4541099013bSjsg 			/* 1D/2D */
4551099013bSjsg 			track->textures[i].tex_coord_type = 0;
4561099013bSjsg 			break;
4571099013bSjsg 		case 1:
4581099013bSjsg 			/* CUBE */
4591099013bSjsg 			track->textures[i].tex_coord_type = 2;
4601099013bSjsg 			break;
4611099013bSjsg 		case 2:
4621099013bSjsg 			/* 3D */
4631099013bSjsg 			track->textures[i].tex_coord_type = 1;
4641099013bSjsg 			break;
4651099013bSjsg 		}
4661099013bSjsg 		track->tex_dirty = true;
4671099013bSjsg 		break;
4681099013bSjsg 	case R200_PP_TXFORMAT_0:
4691099013bSjsg 	case R200_PP_TXFORMAT_1:
4701099013bSjsg 	case R200_PP_TXFORMAT_2:
4711099013bSjsg 	case R200_PP_TXFORMAT_3:
4721099013bSjsg 	case R200_PP_TXFORMAT_4:
4731099013bSjsg 	case R200_PP_TXFORMAT_5:
4741099013bSjsg 		i = (reg - R200_PP_TXFORMAT_0) / 32;
4751099013bSjsg 		if (idx_value & R200_TXFORMAT_NON_POWER2) {
4761099013bSjsg 			track->textures[i].use_pitch = 1;
4771099013bSjsg 		} else {
4781099013bSjsg 			track->textures[i].use_pitch = 0;
4792a441e6dSjsg 			track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
4802a441e6dSjsg 			track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
4811099013bSjsg 		}
4821099013bSjsg 		if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
4831099013bSjsg 			track->textures[i].lookup_disable = true;
4841099013bSjsg 		switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
4851099013bSjsg 		case R200_TXFORMAT_I8:
4861099013bSjsg 		case R200_TXFORMAT_RGB332:
4871099013bSjsg 		case R200_TXFORMAT_Y8:
4881099013bSjsg 			track->textures[i].cpp = 1;
4891099013bSjsg 			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
4901099013bSjsg 			break;
4911099013bSjsg 		case R200_TXFORMAT_AI88:
4921099013bSjsg 		case R200_TXFORMAT_ARGB1555:
4931099013bSjsg 		case R200_TXFORMAT_RGB565:
4941099013bSjsg 		case R200_TXFORMAT_ARGB4444:
4951099013bSjsg 		case R200_TXFORMAT_VYUY422:
4961099013bSjsg 		case R200_TXFORMAT_YVYU422:
4971099013bSjsg 		case R200_TXFORMAT_LDVDU655:
4981099013bSjsg 		case R200_TXFORMAT_DVDU88:
4991099013bSjsg 		case R200_TXFORMAT_AVYU4444:
5001099013bSjsg 			track->textures[i].cpp = 2;
5011099013bSjsg 			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
5021099013bSjsg 			break;
5031099013bSjsg 		case R200_TXFORMAT_ARGB8888:
5041099013bSjsg 		case R200_TXFORMAT_RGBA8888:
5051099013bSjsg 		case R200_TXFORMAT_ABGR8888:
5061099013bSjsg 		case R200_TXFORMAT_BGR111110:
5071099013bSjsg 		case R200_TXFORMAT_LDVDU8888:
5081099013bSjsg 			track->textures[i].cpp = 4;
5091099013bSjsg 			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
5101099013bSjsg 			break;
5111099013bSjsg 		case R200_TXFORMAT_DXT1:
5121099013bSjsg 			track->textures[i].cpp = 1;
5131099013bSjsg 			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
5141099013bSjsg 			break;
5151099013bSjsg 		case R200_TXFORMAT_DXT23:
5161099013bSjsg 		case R200_TXFORMAT_DXT45:
5171099013bSjsg 			track->textures[i].cpp = 1;
5181099013bSjsg 			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
5191099013bSjsg 			break;
5201099013bSjsg 		}
5211099013bSjsg 		track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
5221099013bSjsg 		track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
5231099013bSjsg 		track->tex_dirty = true;
5241099013bSjsg 		break;
5251099013bSjsg 	case R200_PP_CUBIC_FACES_0:
5261099013bSjsg 	case R200_PP_CUBIC_FACES_1:
5271099013bSjsg 	case R200_PP_CUBIC_FACES_2:
5281099013bSjsg 	case R200_PP_CUBIC_FACES_3:
5291099013bSjsg 	case R200_PP_CUBIC_FACES_4:
5301099013bSjsg 	case R200_PP_CUBIC_FACES_5:
5311099013bSjsg 		tmp = idx_value;
5321099013bSjsg 		i = (reg - R200_PP_CUBIC_FACES_0) / 32;
5331099013bSjsg 		for (face = 0; face < 4; face++) {
5341099013bSjsg 			track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
5351099013bSjsg 			track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
5361099013bSjsg 		}
5371099013bSjsg 		track->tex_dirty = true;
5381099013bSjsg 		break;
5391099013bSjsg 	default:
5407f4dd379Sjsg 		pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx);
5411099013bSjsg 		return -EINVAL;
5421099013bSjsg 	}
5431099013bSjsg 	return 0;
5441099013bSjsg }
5451099013bSjsg 
r200_set_safe_registers(struct radeon_device * rdev)5461099013bSjsg void r200_set_safe_registers(struct radeon_device *rdev)
5471099013bSjsg {
5481099013bSjsg 	rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
5491099013bSjsg 	rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
5501099013bSjsg }
551