18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2008 Advanced Micro Devices, Inc.
38c2ecf20Sopenharmony_ci * Copyright 2008 Red Hat Inc.
48c2ecf20Sopenharmony_ci * Copyright 2009 Jerome Glisse.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
78c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
88c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
98c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
108c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
118c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
148c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
198c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
208c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
218c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
228c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * Authors: Dave Airlie
258c2ecf20Sopenharmony_ci *          Alex Deucher
268c2ecf20Sopenharmony_ci *          Jerome Glisse
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h>
308c2ecf20Sopenharmony_ci#include "radeon_reg.h"
318c2ecf20Sopenharmony_ci#include "radeon.h"
328c2ecf20Sopenharmony_ci#include "radeon_asic.h"
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#include "r100d.h"
358c2ecf20Sopenharmony_ci#include "r200_reg_safe.h"
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include "r100_track.h"
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	int vtx_size, i;
428c2ecf20Sopenharmony_ci	vtx_size = 2;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_Z0)
458c2ecf20Sopenharmony_ci		vtx_size++;
468c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_W0)
478c2ecf20Sopenharmony_ci		vtx_size++;
488c2ecf20Sopenharmony_ci	/* blend weight */
498c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
508c2ecf20Sopenharmony_ci		vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
518c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
528c2ecf20Sopenharmony_ci		vtx_size++;
538c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_N0)
548c2ecf20Sopenharmony_ci		vtx_size += 3;
558c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
568c2ecf20Sopenharmony_ci		vtx_size++;
578c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
588c2ecf20Sopenharmony_ci		vtx_size++;
598c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_SHININESS_0)
608c2ecf20Sopenharmony_ci		vtx_size++;
618c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_SHININESS_1)
628c2ecf20Sopenharmony_ci		vtx_size++;
638c2ecf20Sopenharmony_ci	for (i = 0; i < 8; i++) {
648c2ecf20Sopenharmony_ci		int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
658c2ecf20Sopenharmony_ci		switch (color_size) {
668c2ecf20Sopenharmony_ci		case 0: break;
678c2ecf20Sopenharmony_ci		case 1: vtx_size++; break;
688c2ecf20Sopenharmony_ci		case 2: vtx_size += 3; break;
698c2ecf20Sopenharmony_ci		case 3: vtx_size += 4; break;
708c2ecf20Sopenharmony_ci		}
718c2ecf20Sopenharmony_ci	}
728c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_XY1)
738c2ecf20Sopenharmony_ci		vtx_size += 2;
748c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_Z1)
758c2ecf20Sopenharmony_ci		vtx_size++;
768c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_W1)
778c2ecf20Sopenharmony_ci		vtx_size++;
788c2ecf20Sopenharmony_ci	if (vtx_fmt_0 & R200_VTX_N1)
798c2ecf20Sopenharmony_ci		vtx_size += 3;
808c2ecf20Sopenharmony_ci	return vtx_size;
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistruct radeon_fence *r200_copy_dma(struct radeon_device *rdev,
848c2ecf20Sopenharmony_ci				   uint64_t src_offset,
858c2ecf20Sopenharmony_ci				   uint64_t dst_offset,
868c2ecf20Sopenharmony_ci				   unsigned num_gpu_pages,
878c2ecf20Sopenharmony_ci				   struct dma_resv *resv)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
908c2ecf20Sopenharmony_ci	struct radeon_fence *fence;
918c2ecf20Sopenharmony_ci	uint32_t size;
928c2ecf20Sopenharmony_ci	uint32_t cur_size;
938c2ecf20Sopenharmony_ci	int i, num_loops;
948c2ecf20Sopenharmony_ci	int r = 0;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	/* radeon pitch is /64 */
978c2ecf20Sopenharmony_ci	size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
988c2ecf20Sopenharmony_ci	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
998c2ecf20Sopenharmony_ci	r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64);
1008c2ecf20Sopenharmony_ci	if (r) {
1018c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: moving bo (%d).\n", r);
1028c2ecf20Sopenharmony_ci		return ERR_PTR(r);
1038c2ecf20Sopenharmony_ci	}
1048c2ecf20Sopenharmony_ci	/* Must wait for 2D idle & clean before DMA or hangs might happen */
1058c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
1068c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (1 << 16));
1078c2ecf20Sopenharmony_ci	for (i = 0; i < num_loops; i++) {
1088c2ecf20Sopenharmony_ci		cur_size = size;
1098c2ecf20Sopenharmony_ci		if (cur_size > 0x1FFFFF) {
1108c2ecf20Sopenharmony_ci			cur_size = 0x1FFFFF;
1118c2ecf20Sopenharmony_ci		}
1128c2ecf20Sopenharmony_ci		size -= cur_size;
1138c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET0(0x720, 2));
1148c2ecf20Sopenharmony_ci		radeon_ring_write(ring, src_offset);
1158c2ecf20Sopenharmony_ci		radeon_ring_write(ring, dst_offset);
1168c2ecf20Sopenharmony_ci		radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30));
1178c2ecf20Sopenharmony_ci		src_offset += cur_size;
1188c2ecf20Sopenharmony_ci		dst_offset += cur_size;
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
1218c2ecf20Sopenharmony_ci	radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE);
1228c2ecf20Sopenharmony_ci	r = radeon_fence_emit(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
1238c2ecf20Sopenharmony_ci	if (r) {
1248c2ecf20Sopenharmony_ci		radeon_ring_unlock_undo(rdev, ring);
1258c2ecf20Sopenharmony_ci		return ERR_PTR(r);
1268c2ecf20Sopenharmony_ci	}
1278c2ecf20Sopenharmony_ci	radeon_ring_unlock_commit(rdev, ring, false);
1288c2ecf20Sopenharmony_ci	return fence;
1298c2ecf20Sopenharmony_ci}
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_cistatic int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
1338c2ecf20Sopenharmony_ci{
1348c2ecf20Sopenharmony_ci	int vtx_size, i, tex_size;
1358c2ecf20Sopenharmony_ci	vtx_size = 0;
1368c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
1378c2ecf20Sopenharmony_ci		tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
1388c2ecf20Sopenharmony_ci		if (tex_size > 4)
1398c2ecf20Sopenharmony_ci			continue;
1408c2ecf20Sopenharmony_ci		vtx_size += tex_size;
1418c2ecf20Sopenharmony_ci	}
1428c2ecf20Sopenharmony_ci	return vtx_size;
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ciint r200_packet0_check(struct radeon_cs_parser *p,
1468c2ecf20Sopenharmony_ci		       struct radeon_cs_packet *pkt,
1478c2ecf20Sopenharmony_ci		       unsigned idx, unsigned reg)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	struct radeon_bo_list *reloc;
1508c2ecf20Sopenharmony_ci	struct r100_cs_track *track;
1518c2ecf20Sopenharmony_ci	volatile uint32_t *ib;
1528c2ecf20Sopenharmony_ci	uint32_t tmp;
1538c2ecf20Sopenharmony_ci	int r;
1548c2ecf20Sopenharmony_ci	int i;
1558c2ecf20Sopenharmony_ci	int face;
1568c2ecf20Sopenharmony_ci	u32 tile_flags = 0;
1578c2ecf20Sopenharmony_ci	u32 idx_value;
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	ib = p->ib.ptr;
1608c2ecf20Sopenharmony_ci	track = (struct r100_cs_track *)p->track;
1618c2ecf20Sopenharmony_ci	idx_value = radeon_get_ib_value(p, idx);
1628c2ecf20Sopenharmony_ci	switch (reg) {
1638c2ecf20Sopenharmony_ci	case RADEON_CRTC_GUI_TRIG_VLINE:
1648c2ecf20Sopenharmony_ci		r = r100_cs_packet_parse_vline(p);
1658c2ecf20Sopenharmony_ci		if (r) {
1668c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1678c2ecf20Sopenharmony_ci				  idx, reg);
1688c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
1698c2ecf20Sopenharmony_ci			return r;
1708c2ecf20Sopenharmony_ci		}
1718c2ecf20Sopenharmony_ci		break;
1728c2ecf20Sopenharmony_ci		/* FIXME: only allow PACKET3 blit? easier to check for out of
1738c2ecf20Sopenharmony_ci		 * range access */
1748c2ecf20Sopenharmony_ci	case RADEON_DST_PITCH_OFFSET:
1758c2ecf20Sopenharmony_ci	case RADEON_SRC_PITCH_OFFSET:
1768c2ecf20Sopenharmony_ci		r = r100_reloc_pitch_offset(p, pkt, idx, reg);
1778c2ecf20Sopenharmony_ci		if (r)
1788c2ecf20Sopenharmony_ci			return r;
1798c2ecf20Sopenharmony_ci		break;
1808c2ecf20Sopenharmony_ci	case RADEON_RB3D_DEPTHOFFSET:
1818c2ecf20Sopenharmony_ci		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
1828c2ecf20Sopenharmony_ci		if (r) {
1838c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1848c2ecf20Sopenharmony_ci				  idx, reg);
1858c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
1868c2ecf20Sopenharmony_ci			return r;
1878c2ecf20Sopenharmony_ci		}
1888c2ecf20Sopenharmony_ci		track->zb.robj = reloc->robj;
1898c2ecf20Sopenharmony_ci		track->zb.offset = idx_value;
1908c2ecf20Sopenharmony_ci		track->zb_dirty = true;
1918c2ecf20Sopenharmony_ci		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
1928c2ecf20Sopenharmony_ci		break;
1938c2ecf20Sopenharmony_ci	case RADEON_RB3D_COLOROFFSET:
1948c2ecf20Sopenharmony_ci		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
1958c2ecf20Sopenharmony_ci		if (r) {
1968c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1978c2ecf20Sopenharmony_ci				  idx, reg);
1988c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
1998c2ecf20Sopenharmony_ci			return r;
2008c2ecf20Sopenharmony_ci		}
2018c2ecf20Sopenharmony_ci		track->cb[0].robj = reloc->robj;
2028c2ecf20Sopenharmony_ci		track->cb[0].offset = idx_value;
2038c2ecf20Sopenharmony_ci		track->cb_dirty = true;
2048c2ecf20Sopenharmony_ci		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
2058c2ecf20Sopenharmony_ci		break;
2068c2ecf20Sopenharmony_ci	case R200_PP_TXOFFSET_0:
2078c2ecf20Sopenharmony_ci	case R200_PP_TXOFFSET_1:
2088c2ecf20Sopenharmony_ci	case R200_PP_TXOFFSET_2:
2098c2ecf20Sopenharmony_ci	case R200_PP_TXOFFSET_3:
2108c2ecf20Sopenharmony_ci	case R200_PP_TXOFFSET_4:
2118c2ecf20Sopenharmony_ci	case R200_PP_TXOFFSET_5:
2128c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXOFFSET_0) / 24;
2138c2ecf20Sopenharmony_ci		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2148c2ecf20Sopenharmony_ci		if (r) {
2158c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
2168c2ecf20Sopenharmony_ci				  idx, reg);
2178c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
2188c2ecf20Sopenharmony_ci			return r;
2198c2ecf20Sopenharmony_ci		}
2208c2ecf20Sopenharmony_ci		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
2218c2ecf20Sopenharmony_ci			if (reloc->tiling_flags & RADEON_TILING_MACRO)
2228c2ecf20Sopenharmony_ci				tile_flags |= R200_TXO_MACRO_TILE;
2238c2ecf20Sopenharmony_ci			if (reloc->tiling_flags & RADEON_TILING_MICRO)
2248c2ecf20Sopenharmony_ci				tile_flags |= R200_TXO_MICRO_TILE;
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci			tmp = idx_value & ~(0x7 << 2);
2278c2ecf20Sopenharmony_ci			tmp |= tile_flags;
2288c2ecf20Sopenharmony_ci			ib[idx] = tmp + ((u32)reloc->gpu_offset);
2298c2ecf20Sopenharmony_ci		} else
2308c2ecf20Sopenharmony_ci			ib[idx] = idx_value + ((u32)reloc->gpu_offset);
2318c2ecf20Sopenharmony_ci		track->textures[i].robj = reloc->robj;
2328c2ecf20Sopenharmony_ci		track->tex_dirty = true;
2338c2ecf20Sopenharmony_ci		break;
2348c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F1_0:
2358c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F2_0:
2368c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F3_0:
2378c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F4_0:
2388c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F5_0:
2398c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F1_1:
2408c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F2_1:
2418c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F3_1:
2428c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F4_1:
2438c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F5_1:
2448c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F1_2:
2458c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F2_2:
2468c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F3_2:
2478c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F4_2:
2488c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F5_2:
2498c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F1_3:
2508c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F2_3:
2518c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F3_3:
2528c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F4_3:
2538c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F5_3:
2548c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F1_4:
2558c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F2_4:
2568c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F3_4:
2578c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F4_4:
2588c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F5_4:
2598c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F1_5:
2608c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F2_5:
2618c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F3_5:
2628c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F4_5:
2638c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_OFFSET_F5_5:
2648c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXOFFSET_0) / 24;
2658c2ecf20Sopenharmony_ci		face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
2668c2ecf20Sopenharmony_ci		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2678c2ecf20Sopenharmony_ci		if (r) {
2688c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
2698c2ecf20Sopenharmony_ci				  idx, reg);
2708c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
2718c2ecf20Sopenharmony_ci			return r;
2728c2ecf20Sopenharmony_ci		}
2738c2ecf20Sopenharmony_ci		track->textures[i].cube_info[face - 1].offset = idx_value;
2748c2ecf20Sopenharmony_ci		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
2758c2ecf20Sopenharmony_ci		track->textures[i].cube_info[face - 1].robj = reloc->robj;
2768c2ecf20Sopenharmony_ci		track->tex_dirty = true;
2778c2ecf20Sopenharmony_ci		break;
2788c2ecf20Sopenharmony_ci	case RADEON_RE_WIDTH_HEIGHT:
2798c2ecf20Sopenharmony_ci		track->maxy = ((idx_value >> 16) & 0x7FF);
2808c2ecf20Sopenharmony_ci		track->cb_dirty = true;
2818c2ecf20Sopenharmony_ci		track->zb_dirty = true;
2828c2ecf20Sopenharmony_ci		break;
2838c2ecf20Sopenharmony_ci	case RADEON_RB3D_COLORPITCH:
2848c2ecf20Sopenharmony_ci		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2858c2ecf20Sopenharmony_ci		if (r) {
2868c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
2878c2ecf20Sopenharmony_ci				  idx, reg);
2888c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
2898c2ecf20Sopenharmony_ci			return r;
2908c2ecf20Sopenharmony_ci		}
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
2938c2ecf20Sopenharmony_ci			if (reloc->tiling_flags & RADEON_TILING_MACRO)
2948c2ecf20Sopenharmony_ci				tile_flags |= RADEON_COLOR_TILE_ENABLE;
2958c2ecf20Sopenharmony_ci			if (reloc->tiling_flags & RADEON_TILING_MICRO)
2968c2ecf20Sopenharmony_ci				tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci			tmp = idx_value & ~(0x7 << 16);
2998c2ecf20Sopenharmony_ci			tmp |= tile_flags;
3008c2ecf20Sopenharmony_ci			ib[idx] = tmp;
3018c2ecf20Sopenharmony_ci		} else
3028c2ecf20Sopenharmony_ci			ib[idx] = idx_value;
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci		track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
3058c2ecf20Sopenharmony_ci		track->cb_dirty = true;
3068c2ecf20Sopenharmony_ci		break;
3078c2ecf20Sopenharmony_ci	case RADEON_RB3D_DEPTHPITCH:
3088c2ecf20Sopenharmony_ci		track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
3098c2ecf20Sopenharmony_ci		track->zb_dirty = true;
3108c2ecf20Sopenharmony_ci		break;
3118c2ecf20Sopenharmony_ci	case RADEON_RB3D_CNTL:
3128c2ecf20Sopenharmony_ci		switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
3138c2ecf20Sopenharmony_ci		case 7:
3148c2ecf20Sopenharmony_ci		case 8:
3158c2ecf20Sopenharmony_ci		case 9:
3168c2ecf20Sopenharmony_ci		case 11:
3178c2ecf20Sopenharmony_ci		case 12:
3188c2ecf20Sopenharmony_ci			track->cb[0].cpp = 1;
3198c2ecf20Sopenharmony_ci			break;
3208c2ecf20Sopenharmony_ci		case 3:
3218c2ecf20Sopenharmony_ci		case 4:
3228c2ecf20Sopenharmony_ci		case 15:
3238c2ecf20Sopenharmony_ci			track->cb[0].cpp = 2;
3248c2ecf20Sopenharmony_ci			break;
3258c2ecf20Sopenharmony_ci		case 6:
3268c2ecf20Sopenharmony_ci			track->cb[0].cpp = 4;
3278c2ecf20Sopenharmony_ci			break;
3288c2ecf20Sopenharmony_ci		default:
3298c2ecf20Sopenharmony_ci			DRM_ERROR("Invalid color buffer format (%d) !\n",
3308c2ecf20Sopenharmony_ci				  ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
3318c2ecf20Sopenharmony_ci			return -EINVAL;
3328c2ecf20Sopenharmony_ci		}
3338c2ecf20Sopenharmony_ci		if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) {
3348c2ecf20Sopenharmony_ci			DRM_ERROR("No support for depth xy offset in kms\n");
3358c2ecf20Sopenharmony_ci			return -EINVAL;
3368c2ecf20Sopenharmony_ci		}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci		track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
3398c2ecf20Sopenharmony_ci		track->cb_dirty = true;
3408c2ecf20Sopenharmony_ci		track->zb_dirty = true;
3418c2ecf20Sopenharmony_ci		break;
3428c2ecf20Sopenharmony_ci	case RADEON_RB3D_ZSTENCILCNTL:
3438c2ecf20Sopenharmony_ci		switch (idx_value & 0xf) {
3448c2ecf20Sopenharmony_ci		case 0:
3458c2ecf20Sopenharmony_ci			track->zb.cpp = 2;
3468c2ecf20Sopenharmony_ci			break;
3478c2ecf20Sopenharmony_ci		case 2:
3488c2ecf20Sopenharmony_ci		case 3:
3498c2ecf20Sopenharmony_ci		case 4:
3508c2ecf20Sopenharmony_ci		case 5:
3518c2ecf20Sopenharmony_ci		case 9:
3528c2ecf20Sopenharmony_ci		case 11:
3538c2ecf20Sopenharmony_ci			track->zb.cpp = 4;
3548c2ecf20Sopenharmony_ci			break;
3558c2ecf20Sopenharmony_ci		default:
3568c2ecf20Sopenharmony_ci			break;
3578c2ecf20Sopenharmony_ci		}
3588c2ecf20Sopenharmony_ci		track->zb_dirty = true;
3598c2ecf20Sopenharmony_ci		break;
3608c2ecf20Sopenharmony_ci	case RADEON_RB3D_ZPASS_ADDR:
3618c2ecf20Sopenharmony_ci		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
3628c2ecf20Sopenharmony_ci		if (r) {
3638c2ecf20Sopenharmony_ci			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
3648c2ecf20Sopenharmony_ci				  idx, reg);
3658c2ecf20Sopenharmony_ci			radeon_cs_dump_packet(p, pkt);
3668c2ecf20Sopenharmony_ci			return r;
3678c2ecf20Sopenharmony_ci		}
3688c2ecf20Sopenharmony_ci		ib[idx] = idx_value + ((u32)reloc->gpu_offset);
3698c2ecf20Sopenharmony_ci		break;
3708c2ecf20Sopenharmony_ci	case RADEON_PP_CNTL:
3718c2ecf20Sopenharmony_ci		{
3728c2ecf20Sopenharmony_ci			uint32_t temp = idx_value >> 4;
3738c2ecf20Sopenharmony_ci			for (i = 0; i < track->num_texture; i++)
3748c2ecf20Sopenharmony_ci				track->textures[i].enabled = !!(temp & (1 << i));
3758c2ecf20Sopenharmony_ci			track->tex_dirty = true;
3768c2ecf20Sopenharmony_ci		}
3778c2ecf20Sopenharmony_ci		break;
3788c2ecf20Sopenharmony_ci	case RADEON_SE_VF_CNTL:
3798c2ecf20Sopenharmony_ci		track->vap_vf_cntl = idx_value;
3808c2ecf20Sopenharmony_ci		break;
3818c2ecf20Sopenharmony_ci	case 0x210c:
3828c2ecf20Sopenharmony_ci		/* VAP_VF_MAX_VTX_INDX */
3838c2ecf20Sopenharmony_ci		track->max_indx = idx_value & 0x00FFFFFFUL;
3848c2ecf20Sopenharmony_ci		break;
3858c2ecf20Sopenharmony_ci	case R200_SE_VTX_FMT_0:
3868c2ecf20Sopenharmony_ci		track->vtx_size = r200_get_vtx_size_0(idx_value);
3878c2ecf20Sopenharmony_ci		break;
3888c2ecf20Sopenharmony_ci	case R200_SE_VTX_FMT_1:
3898c2ecf20Sopenharmony_ci		track->vtx_size += r200_get_vtx_size_1(idx_value);
3908c2ecf20Sopenharmony_ci		break;
3918c2ecf20Sopenharmony_ci	case R200_PP_TXSIZE_0:
3928c2ecf20Sopenharmony_ci	case R200_PP_TXSIZE_1:
3938c2ecf20Sopenharmony_ci	case R200_PP_TXSIZE_2:
3948c2ecf20Sopenharmony_ci	case R200_PP_TXSIZE_3:
3958c2ecf20Sopenharmony_ci	case R200_PP_TXSIZE_4:
3968c2ecf20Sopenharmony_ci	case R200_PP_TXSIZE_5:
3978c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXSIZE_0) / 32;
3988c2ecf20Sopenharmony_ci		track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
3998c2ecf20Sopenharmony_ci		track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
4008c2ecf20Sopenharmony_ci		track->tex_dirty = true;
4018c2ecf20Sopenharmony_ci		break;
4028c2ecf20Sopenharmony_ci	case R200_PP_TXPITCH_0:
4038c2ecf20Sopenharmony_ci	case R200_PP_TXPITCH_1:
4048c2ecf20Sopenharmony_ci	case R200_PP_TXPITCH_2:
4058c2ecf20Sopenharmony_ci	case R200_PP_TXPITCH_3:
4068c2ecf20Sopenharmony_ci	case R200_PP_TXPITCH_4:
4078c2ecf20Sopenharmony_ci	case R200_PP_TXPITCH_5:
4088c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXPITCH_0) / 32;
4098c2ecf20Sopenharmony_ci		track->textures[i].pitch = idx_value + 32;
4108c2ecf20Sopenharmony_ci		track->tex_dirty = true;
4118c2ecf20Sopenharmony_ci		break;
4128c2ecf20Sopenharmony_ci	case R200_PP_TXFILTER_0:
4138c2ecf20Sopenharmony_ci	case R200_PP_TXFILTER_1:
4148c2ecf20Sopenharmony_ci	case R200_PP_TXFILTER_2:
4158c2ecf20Sopenharmony_ci	case R200_PP_TXFILTER_3:
4168c2ecf20Sopenharmony_ci	case R200_PP_TXFILTER_4:
4178c2ecf20Sopenharmony_ci	case R200_PP_TXFILTER_5:
4188c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXFILTER_0) / 32;
4198c2ecf20Sopenharmony_ci		track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK)
4208c2ecf20Sopenharmony_ci						 >> R200_MAX_MIP_LEVEL_SHIFT);
4218c2ecf20Sopenharmony_ci		tmp = (idx_value >> 23) & 0x7;
4228c2ecf20Sopenharmony_ci		if (tmp == 2 || tmp == 6)
4238c2ecf20Sopenharmony_ci			track->textures[i].roundup_w = false;
4248c2ecf20Sopenharmony_ci		tmp = (idx_value >> 27) & 0x7;
4258c2ecf20Sopenharmony_ci		if (tmp == 2 || tmp == 6)
4268c2ecf20Sopenharmony_ci			track->textures[i].roundup_h = false;
4278c2ecf20Sopenharmony_ci		track->tex_dirty = true;
4288c2ecf20Sopenharmony_ci		break;
4298c2ecf20Sopenharmony_ci	case R200_PP_TXMULTI_CTL_0:
4308c2ecf20Sopenharmony_ci	case R200_PP_TXMULTI_CTL_1:
4318c2ecf20Sopenharmony_ci	case R200_PP_TXMULTI_CTL_2:
4328c2ecf20Sopenharmony_ci	case R200_PP_TXMULTI_CTL_3:
4338c2ecf20Sopenharmony_ci	case R200_PP_TXMULTI_CTL_4:
4348c2ecf20Sopenharmony_ci	case R200_PP_TXMULTI_CTL_5:
4358c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
4368c2ecf20Sopenharmony_ci		break;
4378c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_X_0:
4388c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_X_1:
4398c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_X_2:
4408c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_X_3:
4418c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_X_4:
4428c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_X_5:
4438c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXFORMAT_X_0) / 32;
4448c2ecf20Sopenharmony_ci		track->textures[i].txdepth = idx_value & 0x7;
4458c2ecf20Sopenharmony_ci		tmp = (idx_value >> 16) & 0x3;
4468c2ecf20Sopenharmony_ci		/* 2D, 3D, CUBE */
4478c2ecf20Sopenharmony_ci		switch (tmp) {
4488c2ecf20Sopenharmony_ci		case 0:
4498c2ecf20Sopenharmony_ci		case 3:
4508c2ecf20Sopenharmony_ci		case 4:
4518c2ecf20Sopenharmony_ci		case 5:
4528c2ecf20Sopenharmony_ci		case 6:
4538c2ecf20Sopenharmony_ci		case 7:
4548c2ecf20Sopenharmony_ci			/* 1D/2D */
4558c2ecf20Sopenharmony_ci			track->textures[i].tex_coord_type = 0;
4568c2ecf20Sopenharmony_ci			break;
4578c2ecf20Sopenharmony_ci		case 1:
4588c2ecf20Sopenharmony_ci			/* CUBE */
4598c2ecf20Sopenharmony_ci			track->textures[i].tex_coord_type = 2;
4608c2ecf20Sopenharmony_ci			break;
4618c2ecf20Sopenharmony_ci		case 2:
4628c2ecf20Sopenharmony_ci			/* 3D */
4638c2ecf20Sopenharmony_ci			track->textures[i].tex_coord_type = 1;
4648c2ecf20Sopenharmony_ci			break;
4658c2ecf20Sopenharmony_ci		}
4668c2ecf20Sopenharmony_ci		track->tex_dirty = true;
4678c2ecf20Sopenharmony_ci		break;
4688c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_0:
4698c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_1:
4708c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_2:
4718c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_3:
4728c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_4:
4738c2ecf20Sopenharmony_ci	case R200_PP_TXFORMAT_5:
4748c2ecf20Sopenharmony_ci		i = (reg - R200_PP_TXFORMAT_0) / 32;
4758c2ecf20Sopenharmony_ci		if (idx_value & R200_TXFORMAT_NON_POWER2) {
4768c2ecf20Sopenharmony_ci			track->textures[i].use_pitch = 1;
4778c2ecf20Sopenharmony_ci		} else {
4788c2ecf20Sopenharmony_ci			track->textures[i].use_pitch = 0;
4798c2ecf20Sopenharmony_ci			track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT);
4808c2ecf20Sopenharmony_ci			track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT);
4818c2ecf20Sopenharmony_ci		}
4828c2ecf20Sopenharmony_ci		if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
4838c2ecf20Sopenharmony_ci			track->textures[i].lookup_disable = true;
4848c2ecf20Sopenharmony_ci		switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
4858c2ecf20Sopenharmony_ci		case R200_TXFORMAT_I8:
4868c2ecf20Sopenharmony_ci		case R200_TXFORMAT_RGB332:
4878c2ecf20Sopenharmony_ci		case R200_TXFORMAT_Y8:
4888c2ecf20Sopenharmony_ci			track->textures[i].cpp = 1;
4898c2ecf20Sopenharmony_ci			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
4908c2ecf20Sopenharmony_ci			break;
4918c2ecf20Sopenharmony_ci		case R200_TXFORMAT_AI88:
4928c2ecf20Sopenharmony_ci		case R200_TXFORMAT_ARGB1555:
4938c2ecf20Sopenharmony_ci		case R200_TXFORMAT_RGB565:
4948c2ecf20Sopenharmony_ci		case R200_TXFORMAT_ARGB4444:
4958c2ecf20Sopenharmony_ci		case R200_TXFORMAT_VYUY422:
4968c2ecf20Sopenharmony_ci		case R200_TXFORMAT_YVYU422:
4978c2ecf20Sopenharmony_ci		case R200_TXFORMAT_LDVDU655:
4988c2ecf20Sopenharmony_ci		case R200_TXFORMAT_DVDU88:
4998c2ecf20Sopenharmony_ci		case R200_TXFORMAT_AVYU4444:
5008c2ecf20Sopenharmony_ci			track->textures[i].cpp = 2;
5018c2ecf20Sopenharmony_ci			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
5028c2ecf20Sopenharmony_ci			break;
5038c2ecf20Sopenharmony_ci		case R200_TXFORMAT_ARGB8888:
5048c2ecf20Sopenharmony_ci		case R200_TXFORMAT_RGBA8888:
5058c2ecf20Sopenharmony_ci		case R200_TXFORMAT_ABGR8888:
5068c2ecf20Sopenharmony_ci		case R200_TXFORMAT_BGR111110:
5078c2ecf20Sopenharmony_ci		case R200_TXFORMAT_LDVDU8888:
5088c2ecf20Sopenharmony_ci			track->textures[i].cpp = 4;
5098c2ecf20Sopenharmony_ci			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
5108c2ecf20Sopenharmony_ci			break;
5118c2ecf20Sopenharmony_ci		case R200_TXFORMAT_DXT1:
5128c2ecf20Sopenharmony_ci			track->textures[i].cpp = 1;
5138c2ecf20Sopenharmony_ci			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
5148c2ecf20Sopenharmony_ci			break;
5158c2ecf20Sopenharmony_ci		case R200_TXFORMAT_DXT23:
5168c2ecf20Sopenharmony_ci		case R200_TXFORMAT_DXT45:
5178c2ecf20Sopenharmony_ci			track->textures[i].cpp = 1;
5188c2ecf20Sopenharmony_ci			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
5198c2ecf20Sopenharmony_ci			break;
5208c2ecf20Sopenharmony_ci		}
5218c2ecf20Sopenharmony_ci		track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
5228c2ecf20Sopenharmony_ci		track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
5238c2ecf20Sopenharmony_ci		track->tex_dirty = true;
5248c2ecf20Sopenharmony_ci		break;
5258c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_FACES_0:
5268c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_FACES_1:
5278c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_FACES_2:
5288c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_FACES_3:
5298c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_FACES_4:
5308c2ecf20Sopenharmony_ci	case R200_PP_CUBIC_FACES_5:
5318c2ecf20Sopenharmony_ci		tmp = idx_value;
5328c2ecf20Sopenharmony_ci		i = (reg - R200_PP_CUBIC_FACES_0) / 32;
5338c2ecf20Sopenharmony_ci		for (face = 0; face < 4; face++) {
5348c2ecf20Sopenharmony_ci			track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
5358c2ecf20Sopenharmony_ci			track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
5368c2ecf20Sopenharmony_ci		}
5378c2ecf20Sopenharmony_ci		track->tex_dirty = true;
5388c2ecf20Sopenharmony_ci		break;
5398c2ecf20Sopenharmony_ci	default:
5408c2ecf20Sopenharmony_ci		pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx);
5418c2ecf20Sopenharmony_ci		return -EINVAL;
5428c2ecf20Sopenharmony_ci	}
5438c2ecf20Sopenharmony_ci	return 0;
5448c2ecf20Sopenharmony_ci}
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_civoid r200_set_safe_registers(struct radeon_device *rdev)
5478c2ecf20Sopenharmony_ci{
5488c2ecf20Sopenharmony_ci	rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
5498c2ecf20Sopenharmony_ci	rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
5508c2ecf20Sopenharmony_ci}
551