Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0beb2a7 authored by Dave Airlie's avatar Dave Airlie
Browse files

drm/radeon: add initial r500 support.



This contains all the command buffer processing for the r500 cards.
It doesn't yet contain vblank support.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5b92c404
Loading
Loading
Loading
Loading
+83 −10
Original line number Diff line number Diff line
@@ -189,18 +189,12 @@ void r300_init_reg_flags(struct drm_device *dev)
	ADD_RANGE(R300_RE_CULL_CNTL, 1);
	ADD_RANGE(0x42C0, 2);
	ADD_RANGE(R300_RS_CNTL_0, 2);
	ADD_RANGE(R300_RS_INTERP_0, 8);
	ADD_RANGE(R300_RS_ROUTE_0, 8);

	ADD_RANGE(0x43A4, 2);
	ADD_RANGE(0x43E8, 1);
	ADD_RANGE(R300_PFS_CNTL_0, 3);
	ADD_RANGE(R300_PFS_NODE_0, 4);
	ADD_RANGE(R300_PFS_TEXI_0, 64);

	ADD_RANGE(0x46A4, 5);
	ADD_RANGE(R300_PFS_INSTR0_0, 64);
	ADD_RANGE(R300_PFS_INSTR1_0, 64);
	ADD_RANGE(R300_PFS_INSTR2_0, 64);
	ADD_RANGE(R300_PFS_INSTR3_0, 64);

	ADD_RANGE(R300_RE_FOG_STATE, 1);
	ADD_RANGE(R300_FOG_COLOR_R, 3);
	ADD_RANGE(R300_PP_ALPHA_TEST, 2);
@@ -241,7 +235,25 @@ void r300_init_reg_flags(struct drm_device *dev)
	ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);

	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
		ADD_RANGE(0x4074, 16);
		ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
		ADD_RANGE(R500_US_CONFIG, 2);
		ADD_RANGE(R500_US_CODE_ADDR, 3);
		ADD_RANGE(R500_US_FC_CTRL, 1);
		ADD_RANGE(R500_RS_IP_0, 16);
		ADD_RANGE(R500_RS_INST_0, 16);
		ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
		ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
	} else {
		ADD_RANGE(R300_PFS_CNTL_0, 3);
		ADD_RANGE(R300_PFS_NODE_0, 4);
		ADD_RANGE(R300_PFS_TEXI_0, 64);
		ADD_RANGE(R300_PFS_INSTR0_0, 64);
		ADD_RANGE(R300_PFS_INSTR1_0, 64);
		ADD_RANGE(R300_PFS_INSTR2_0, 64);
		ADD_RANGE(R300_PFS_INSTR3_0, 64);
		ADD_RANGE(R300_RS_INTERP_0, 8);
		ADD_RANGE(R300_RS_ROUTE_0, 8);

	}
}

@@ -828,6 +840,54 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
	return 0;
}

/**
 * Uploads user-supplied vertex program instructions or parameters onto
 * the graphics card.
 * Called by r300_do_cp_cmdbuf.
 */
static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv,
				       drm_radeon_kcmd_buffer_t *cmdbuf,
				       drm_r300_cmd_header_t header)
{
	int sz;
	int addr;
	int type;
	int clamp;
	int stride;
	RING_LOCALS;

	sz = header.r500fp.count;
	/* address is 9 bits 0 - 8, bit 1 of flags is part of address */
	addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo;

	type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
	clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);

	addr |= (type << 16);
	addr |= (clamp << 17);

	stride = type ? 4 : 6;

	DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type);
	if (!sz)
		return 0;
	if (sz * stride * 4 > cmdbuf->bufsz)
		return -EINVAL;

	BEGIN_RING(3 + sz * stride);
	OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr);
	OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1));
	OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride);

	ADVANCE_RING();

	cmdbuf->buf += sz * stride * 4;
	cmdbuf->bufsz -= sz * stride * 4;

	return 0;
}


/**
 * Parses and validates a user-supplied command buffer and emits appropriate
 * commands on the DMA ring buffer.
@@ -963,6 +1023,19 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
			}
			break;

		case R300_CMD_R500FP:
			if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
				DRM_ERROR("Calling r500 command on r300 card\n");
				ret = -EINVAL;
				goto cleanup;
			}
			DRM_DEBUG("R300_CMD_R500FP\n");
			ret = r300_emit_r500fp(dev_priv, cmdbuf, header);
			if (ret) {
				DRM_ERROR("r300_emit_r500fp failed\n");
				goto cleanup;
			}
			break;
		default:
			DRM_ERROR("bad cmd_type %i at %p\n",
				  header.header.cmd_type,
+16 −0
Original line number Diff line number Diff line
@@ -1623,4 +1623,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#define R300_CP_CMD_BITBLT_MULTI	0xC0009B00

#define R500_VAP_INDEX_OFFSET		0x208c

#define R500_GA_US_VECTOR_INDEX         0x4250
#define R500_GA_US_VECTOR_DATA          0x4254

#define R500_RS_IP_0                    0x4074
#define R500_RS_INST_0                  0x4320

#define R500_US_CONFIG                  0x4600

#define R500_US_FC_CTRL			0x4624
#define R500_US_CODE_ADDR		0x4630

#define R500_RB3D_COLOR_CLEAR_VALUE_AR  0x46c0
#define R500_RB3D_CONSTANT_COLOR_AR     0x4ef8

#endif /* _R300_REG_H */
+7 −0
Original line number Diff line number Diff line
@@ -240,6 +240,7 @@ typedef union {
#	define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN	0x8

#define R300_CMD_SCRATCH		8
#define R300_CMD_R500FP                 9

typedef union {
	unsigned int u;
@@ -268,6 +269,9 @@ typedef union {
	struct {
		unsigned char cmd_type, reg, n_bufs, flags;
	} scratch;
	struct {
		unsigned char cmd_type, count, adrlo, adrhi_flags;
	} r500fp;
} drm_r300_cmd_header_t;

#define RADEON_FRONT			0x1
@@ -278,6 +282,9 @@ typedef union {
#define RADEON_USE_HIERZ		0x40000000
#define RADEON_USE_COMP_ZBUF		0x20000000

#define R500FP_CONSTANT_TYPE  (1 << 1)
#define R500FP_CONSTANT_CLAMP (1 << 2)

/* Primitive types
 */
#define RADEON_POINTS			0x1
+29 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@

#define DRIVER_NAME		"radeon"
#define DRIVER_DESC		"ATI Radeon"
#define DRIVER_DATE		"20060524"
#define DRIVER_DATE		"20080528"

/* Interface history:
 *
@@ -98,9 +98,10 @@
 * 1.26- Add support for variable size PCI(E) gart aperture
 * 1.27- Add support for IGP GART
 * 1.28- Add support for VBL on CRTC2
 * 1.29- R500 3D cmd buffer support
 */
#define DRIVER_MAJOR		1
#define DRIVER_MINOR		28
#define DRIVER_MINOR		29
#define DRIVER_PATCHLEVEL	0

/*
@@ -294,6 +295,7 @@ typedef struct drm_radeon_private {
	int vblank_crtc;
	uint32_t irq_enable_reg;
	int irq_enabled;
	uint32_t r500_disp_irq_reg;

	struct radeon_surface surfaces[RADEON_MAX_SURFACES];
	struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
@@ -1103,6 +1105,31 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,

#define R200_VAP_PVS_CNTL_1               0x22D0

#define R500_D1CRTC_STATUS 0x609c
#define R500_D2CRTC_STATUS 0x689c
#define R500_CRTC_V_BLANK (1<<0)

#define R500_D1CRTC_FRAME_COUNT 0x60a4
#define R500_D2CRTC_FRAME_COUNT 0x68a4

#define R500_D1MODE_V_COUNTER 0x6530
#define R500_D2MODE_V_COUNTER 0x6d30

#define R500_D1MODE_VBLANK_STATUS 0x6534
#define R500_D2MODE_VBLANK_STATUS 0x6d34
#define R500_VBLANK_OCCURED (1<<0)
#define R500_VBLANK_ACK     (1<<4)
#define R500_VBLANK_STAT    (1<<12)
#define R500_VBLANK_INT     (1<<16)

#define R500_DxMODE_INT_MASK 0x6540
#define R500_D1MODE_INT_MASK (1<<0)
#define R500_D2MODE_INT_MASK (1<<8)

#define R500_DISP_INTERRUPT_STATUS 0x7edc
#define R500_D1_VBLANK_INTERRUPT (1 << 4)
#define R500_D2_VBLANK_INTERRUPT (1 << 5)

/* Constants */
#define RADEON_MAX_USEC_TIMEOUT		100000	/* 100 ms */