Enscript Output

extractedLnx/linux-2.6.38/drivers/gpu/drm/radeon/r300.c_r300_packet0_check.c

static int r300_packet0_check(struct radeon_cs_parser *p,
		struct radeon_cs_packet *pkt,
		unsigned idx, unsigned reg)
{
	struct radeon_cs_reloc *reloc;
	struct r100_cs_track *track;
	volatile uint32_t *ib;
	uint32_t tmp, tile_flags = 0;
	unsigned i;
	int r;
	u32 idx_value;

	ib = p->ib->ptr;
	track = (struct r100_cs_track *)p->track;
	idx_value = radeon_get_ib_value(p, idx);

	switch(reg) {
	case AVIVO_D1MODE_VLINE_START_END:
	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);
			r100_cs_dump_packet(p, pkt);
			return r;
		}
		break;
	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 R300_RB3D_COLOROFFSET0:
	case R300_RB3D_COLOROFFSET1:
	case R300_RB3D_COLOROFFSET2:
	case R300_RB3D_COLOROFFSET3:
		i = (reg - R300_RB3D_COLOROFFSET0) >> 2;
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
					idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}
		track->cb[i].robj = reloc->robj;
		track->cb[i].offset = idx_value;
		track->cb_dirty = true;
		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
		break;
	case R300_ZB_DEPTHOFFSET:
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
					idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}
		track->zb.robj = reloc->robj;
		track->zb.offset = idx_value;
		track->zb_dirty = true;
		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
		break;
	case R300_TX_OFFSET_0:
	case R300_TX_OFFSET_0+4:
	case R300_TX_OFFSET_0+8:
	case R300_TX_OFFSET_0+12:
	case R300_TX_OFFSET_0+16:
	case R300_TX_OFFSET_0+20:
	case R300_TX_OFFSET_0+24:
	case R300_TX_OFFSET_0+28:
	case R300_TX_OFFSET_0+32:
	case R300_TX_OFFSET_0+36:
	case R300_TX_OFFSET_0+40:
	case R300_TX_OFFSET_0+44:
	case R300_TX_OFFSET_0+48:
	case R300_TX_OFFSET_0+52:
	case R300_TX_OFFSET_0+56:
	case R300_TX_OFFSET_0+60:
		i = (reg - R300_TX_OFFSET_0) >> 2;
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
					idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}

		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
			tile_flags |= R300_TXO_MACRO_TILE;
		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
			tile_flags |= R300_TXO_MICRO_TILE;
		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
			tile_flags |= R300_TXO_MICRO_TILE_SQUARE;

		tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
		tmp |= tile_flags;
		ib[idx] = tmp;
		track->textures[i].robj = reloc->robj;
		track->tex_dirty = true;
		break;
	/* Tracked registers */
	case 0x2084:
		/* VAP_VF_CNTL */
		track->vap_vf_cntl = idx_value;
		break;
	case 0x20B4:
		/* VAP_VTX_SIZE */
		track->vtx_size = idx_value & 0x7F;
		break;
	case 0x2134:
		/* VAP_VF_MAX_VTX_INDX */
		track->max_indx = idx_value & 0x00FFFFFFUL;
		break;
	case 0x2088:
		/* VAP_ALT_NUM_VERTICES - only valid on r500 */
		if (p->rdev->family < CHIP_RV515)
			goto fail;
		track->vap_alt_nverts = idx_value & 0xFFFFFF;
		break;
	case 0x43E4:
		/* SC_SCISSOR1 */
		track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
		if (p->rdev->family < CHIP_RV515) {
			track->maxy -= 1440;
		}
		track->cb_dirty = true;
		track->zb_dirty = true;
		break;
	case 0x4E00:
		/* RB3D_CCTL */
		if ((idx_value & (1 << 10)) && /* CMASK_ENABLE */
		    p->rdev->cmask_filp != p->filp) {
			DRM_ERROR("Invalid RB3D_CCTL: Cannot enable CMASK.\n");
			return -EINVAL;
		}
		track->num_cb = ((idx_value >> 5) & 0x3) + 1;
		track->cb_dirty = true;
		break;
	case 0x4E38:
	case 0x4E3C:
	case 0x4E40:
	case 0x4E44:
		/* RB3D_COLORPITCH0 */
		/* RB3D_COLORPITCH1 */
		/* RB3D_COLORPITCH2 */
		/* RB3D_COLORPITCH3 */
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}

		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
			tile_flags |= R300_COLOR_TILE_ENABLE;
		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
			tile_flags |= R300_COLOR_MICROTILE_ENABLE;
		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
			tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;

		tmp = idx_value & ~(0x7 << 16);
		tmp |= tile_flags;
		ib[idx] = tmp;
		i = (reg - 0x4E38) >> 2;
		track->cb[i].pitch = idx_value & 0x3FFE;
		switch (((idx_value >> 21) & 0xF)) {
		case 9:
		case 11:
		case 12:
			track->cb[i].cpp = 1;
			break;
		case 3:
		case 4:
		case 13:
		case 15:
			track->cb[i].cpp = 2;
			break;
		case 5:
			if (p->rdev->family < CHIP_RV515) {
				DRM_ERROR("Invalid color buffer format (%d)!\n",
					  ((idx_value >> 21) & 0xF));
				return -EINVAL;
			}
			/* Pass through. */
		case 6:
			track->cb[i].cpp = 4;
			break;
		case 10:
			track->cb[i].cpp = 8;
			break;
		case 7:
			track->cb[i].cpp = 16;
			break;
		default:
			DRM_ERROR("Invalid color buffer format (%d) !\n",
				  ((idx_value >> 21) & 0xF));
			return -EINVAL;
		}
		track->cb_dirty = true;
		break;
	case 0x4F00:
		/* ZB_CNTL */
		if (idx_value & 2) {
			track->z_enabled = true;
		} else {
			track->z_enabled = false;
		}
		track->zb_dirty = true;
		break;
	case 0x4F10:
		/* ZB_FORMAT */
		switch ((idx_value & 0xF)) {
		case 0:
		case 1:
			track->zb.cpp = 2;
			break;
		case 2:
			track->zb.cpp = 4;
			break;
		default:
			DRM_ERROR("Invalid z buffer format (%d) !\n",
				  (idx_value & 0xF));
			return -EINVAL;
		}
		track->zb_dirty = true;
		break;
	case 0x4F24:
		/* ZB_DEPTHPITCH */
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}

		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
			tile_flags |= R300_DEPTHMACROTILE_ENABLE;
		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
			tile_flags |= R300_DEPTHMICROTILE_TILED;
		else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
			tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;

		tmp = idx_value & ~(0x7 << 16);
		tmp |= tile_flags;
		ib[idx] = tmp;

		track->zb.pitch = idx_value & 0x3FFC;
		track->zb_dirty = true;
		break;
	case 0x4104:
		/* TX_ENABLE */
		for (i = 0; i < 16; i++) {
			bool enabled;

			enabled = !!(idx_value & (1 << i));
			track->textures[i].enabled = enabled;
		}
		track->tex_dirty = true;
		break;
	case 0x44C0:
	case 0x44C4:
	case 0x44C8:
	case 0x44CC:
	case 0x44D0:
	case 0x44D4:
	case 0x44D8:
	case 0x44DC:
	case 0x44E0:
	case 0x44E4:
	case 0x44E8:
	case 0x44EC:
	case 0x44F0:
	case 0x44F4:
	case 0x44F8:
	case 0x44FC:
		/* TX_FORMAT1_[0-15] */
		i = (reg - 0x44C0) >> 2;
		tmp = (idx_value >> 25) & 0x3;
		track->textures[i].tex_coord_type = tmp;
		switch ((idx_value & 0x1F)) {
		case R300_TX_FORMAT_X8:
		case R300_TX_FORMAT_Y4X4:
		case R300_TX_FORMAT_Z3Y3X2:
			track->textures[i].cpp = 1;
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
			break;
		case R300_TX_FORMAT_X16:
		case R300_TX_FORMAT_FL_I16:
		case R300_TX_FORMAT_Y8X8:
		case R300_TX_FORMAT_Z5Y6X5:
		case R300_TX_FORMAT_Z6Y5X5:
		case R300_TX_FORMAT_W4Z4Y4X4:
		case R300_TX_FORMAT_W1Z5Y5X5:
		case R300_TX_FORMAT_D3DMFT_CxV8U8:
		case R300_TX_FORMAT_B8G8_B8G8:
		case R300_TX_FORMAT_G8R8_G8B8:
			track->textures[i].cpp = 2;
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
			break;
		case R300_TX_FORMAT_Y16X16:
		case R300_TX_FORMAT_FL_I16A16:
		case R300_TX_FORMAT_Z11Y11X10:
		case R300_TX_FORMAT_Z10Y11X11:
		case R300_TX_FORMAT_W8Z8Y8X8:
		case R300_TX_FORMAT_W2Z10Y10X10:
		case 0x17:
		case R300_TX_FORMAT_FL_I32:
		case 0x1e:
			track->textures[i].cpp = 4;
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
			break;
		case R300_TX_FORMAT_W16Z16Y16X16:
		case R300_TX_FORMAT_FL_R16G16B16A16:
		case R300_TX_FORMAT_FL_I32A32:
			track->textures[i].cpp = 8;
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
			break;
		case R300_TX_FORMAT_FL_R32G32B32A32:
			track->textures[i].cpp = 16;
			track->textures[i].compress_format = R100_TRACK_COMP_NONE;
			break;
		case R300_TX_FORMAT_DXT1:
			track->textures[i].cpp = 1;
			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
			break;
		case R300_TX_FORMAT_ATI2N:
			if (p->rdev->family < CHIP_R420) {
				DRM_ERROR("Invalid texture format %u\n",
					  (idx_value & 0x1F));
				return -EINVAL;
			}
			/* The same rules apply as for DXT3/5. */
			/* Pass through. */
		case R300_TX_FORMAT_DXT3:
		case R300_TX_FORMAT_DXT5:
			track->textures[i].cpp = 1;
			track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
			break;
		default:
			DRM_ERROR("Invalid texture format %u\n",
				  (idx_value & 0x1F));
			return -EINVAL;
		}
		track->tex_dirty = true;
		break;
	case 0x4400:
	case 0x4404:
	case 0x4408:
	case 0x440C:
	case 0x4410:
	case 0x4414:
	case 0x4418:
	case 0x441C:
	case 0x4420:
	case 0x4424:
	case 0x4428:
	case 0x442C:
	case 0x4430:
	case 0x4434:
	case 0x4438:
	case 0x443C:
		/* TX_FILTER0_[0-15] */
		i = (reg - 0x4400) >> 2;
		tmp = idx_value & 0x7;
		if (tmp == 2 || tmp == 4 || tmp == 6) {
			track->textures[i].roundup_w = false;
		}
		tmp = (idx_value >> 3) & 0x7;
		if (tmp == 2 || tmp == 4 || tmp == 6) {
			track->textures[i].roundup_h = false;
		}
		track->tex_dirty = true;
		break;
	case 0x4500:
	case 0x4504:
	case 0x4508:
	case 0x450C:
	case 0x4510:
	case 0x4514:
	case 0x4518:
	case 0x451C:
	case 0x4520:
	case 0x4524:
	case 0x4528:
	case 0x452C:
	case 0x4530:
	case 0x4534:
	case 0x4538:
	case 0x453C:
		/* TX_FORMAT2_[0-15] */
		i = (reg - 0x4500) >> 2;
		tmp = idx_value & 0x3FFF;
		track->textures[i].pitch = tmp + 1;
		if (p->rdev->family >= CHIP_RV515) {
			tmp = ((idx_value >> 15) & 1) << 11;
			track->textures[i].width_11 = tmp;
			tmp = ((idx_value >> 16) & 1) << 11;
			track->textures[i].height_11 = tmp;

			/* ATI1N */
			if (idx_value & (1 << 14)) {
				/* The same rules apply as for DXT1. */
				track->textures[i].compress_format =
					R100_TRACK_COMP_DXT1;
			}
		} else if (idx_value & (1 << 14)) {
			DRM_ERROR("Forbidden bit TXFORMAT_MSB\n");
			return -EINVAL;
		}
		track->tex_dirty = true;
		break;
	case 0x4480:
	case 0x4484:
	case 0x4488:
	case 0x448C:
	case 0x4490:
	case 0x4494:
	case 0x4498:
	case 0x449C:
	case 0x44A0:
	case 0x44A4:
	case 0x44A8:
	case 0x44AC:
	case 0x44B0:
	case 0x44B4:
	case 0x44B8:
	case 0x44BC:
		/* TX_FORMAT0_[0-15] */
		i = (reg - 0x4480) >> 2;
		tmp = idx_value & 0x7FF;
		track->textures[i].width = tmp + 1;
		tmp = (idx_value >> 11) & 0x7FF;
		track->textures[i].height = tmp + 1;
		tmp = (idx_value >> 26) & 0xF;
		track->textures[i].num_levels = tmp;
		tmp = idx_value & (1 << 31);
		track->textures[i].use_pitch = !!tmp;
		tmp = (idx_value >> 22) & 0xF;
		track->textures[i].txdepth = tmp;
		track->tex_dirty = true;
		break;
	case R300_ZB_ZPASS_ADDR:
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
					idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}
		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
		break;
	case 0x4e0c:
		/* RB3D_COLOR_CHANNEL_MASK */
		track->color_channel_mask = idx_value;
		track->cb_dirty = true;
		break;
	case 0x43a4:
		/* SC_HYPERZ_EN */
		/* r300c emits this register - we need to disable hyperz for it
		 * without complaining */
		if (p->rdev->hyperz_filp != p->filp) {
			if (idx_value & 0x1)
				ib[idx] = idx_value & ~1;
		}
		break;
	case 0x4f1c:
		/* ZB_BW_CNTL */
		track->zb_cb_clear = !!(idx_value & (1 << 5));
		track->cb_dirty = true;
		track->zb_dirty = true;
		if (p->rdev->hyperz_filp != p->filp) {
			if (idx_value & (R300_HIZ_ENABLE |
					 R300_RD_COMP_ENABLE |
					 R300_WR_COMP_ENABLE |
					 R300_FAST_FILL_ENABLE))
				goto fail;
		}
		break;
	case 0x4e04:
		/* RB3D_BLENDCNTL */
		track->blend_read_enable = !!(idx_value & (1 << 2));
		track->cb_dirty = true;
		break;
	case R300_RB3D_AARESOLVE_OFFSET:
		r = r100_cs_packet_next_reloc(p, &reloc);
		if (r) {
			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
				  idx, reg);
			r100_cs_dump_packet(p, pkt);
			return r;
		}
		track->aa.robj = reloc->robj;
		track->aa.offset = idx_value;
		track->aa_dirty = true;
		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
		break;
	case R300_RB3D_AARESOLVE_PITCH:
		track->aa.pitch = idx_value & 0x3FFE;
		track->aa_dirty = true;
		break;
	case R300_RB3D_AARESOLVE_CTL:
		track->aaresolve = idx_value & 0x1;
		track->aa_dirty = true;
		break;
	case 0x4f30: /* ZB_MASK_OFFSET */
	case 0x4f34: /* ZB_ZMASK_PITCH */
	case 0x4f44: /* ZB_HIZ_OFFSET */
	case 0x4f54: /* ZB_HIZ_PITCH */
		if (idx_value && (p->rdev->hyperz_filp != p->filp))
			goto fail;
		break;
	case 0x4028:
		if (idx_value && (p->rdev->hyperz_filp != p->filp))
			goto fail;
		/* GB_Z_PEQ_CONFIG */
		if (p->rdev->family >= CHIP_RV350)
			break;
		goto fail;
		break;
	case 0x4be8:
		/* valid register only on RV530 */
		if (p->rdev->family == CHIP_RV530)
			break;
		/* fallthrough do not move */
	default:
		goto fail;
	}
	return 0;
fail:
	printk(KERN_ERR "Forbidden register 0x%04X in cs at %d (val=%08x)\n",
	       reg, idx, idx_value);
	return -EINVAL;
}

Generated by GNU enscript 1.6.4.