aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/Makefile15
-rw-r--r--drivers/gpu/drm/radeon/r100.c811
-rw-r--r--drivers/gpu/drm/radeon/r100_track.h124
-rw-r--r--drivers/gpu/drm/radeon/r200.c456
-rw-r--r--drivers/gpu/drm/radeon/r300.c363
-rw-r--r--drivers/gpu/drm/radeon/radeon.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_reg.h57
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r100105
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r200184
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/rn5030
11 files changed, 1712 insertions, 440 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index b2213a576a85..6fb842962490 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -11,6 +11,15 @@ hostprogs-y := mkregtable
quiet_cmd_mkregtable = MKREGTABLE $@
cmd_mkregtable = $(obj)/mkregtable $< > $@
+$(obj)/rn50_reg_safe.h: $(src)/reg_srcs/rn50 $(obj)/mkregtable
+ $(call if_changed,mkregtable)
+
+$(obj)/r100_reg_safe.h: $(src)/reg_srcs/r100 $(obj)/mkregtable
+ $(call if_changed,mkregtable)
+
+$(obj)/r200_reg_safe.h: $(src)/reg_srcs/r200 $(obj)/mkregtable
+ $(call if_changed,mkregtable)
+
$(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable
$(call if_changed,mkregtable)
@@ -20,6 +29,10 @@ $(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable
$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
$(call if_changed,mkregtable)
+$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
+
+$(obj)/r200.o: $(obj)/r200_reg_safe.h
+
$(obj)/rv515.o: $(obj)/rv515_reg_safe.h
$(obj)/r300.o: $(obj)/r300_reg_safe.h
@@ -34,7 +47,7 @@ radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \
radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \
radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \
- radeon_test.o
+ radeon_test.o r200.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 44f34f8e2b32..ee3ab62417e2 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -34,6 +34,9 @@
#include <linux/firmware.h>
#include <linux/platform_device.h>
+#include "r100_reg_safe.h"
+#include "rn50_reg_safe.h"
+
/* Firmware Names */
#define FIRMWARE_R100 "radeon/R100_cp.bin"
#define FIRMWARE_R200 "radeon/R200_cp.bin"
@@ -51,11 +54,14 @@ MODULE_FIRMWARE(FIRMWARE_RS690);
MODULE_FIRMWARE(FIRMWARE_RS600);
MODULE_FIRMWARE(FIRMWARE_R520);
+#include "r100_track.h"
+
/* This files gather functions specifics to:
* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
*
* Some of these functions might be used by newer ASICs.
*/
+int r200_init(struct radeon_device *rdev);
void r100_hdp_reset(struct radeon_device *rdev);
void r100_gpu_init(struct radeon_device *rdev);
int r100_gui_wait_for_idle(struct radeon_device *rdev);
@@ -1017,147 +1023,356 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
return 0;
}
+static int r100_get_vtx_size(uint32_t vtx_fmt)
+{
+ int vtx_size;
+ vtx_size = 2;
+ /* ordered according to bits in spec */
+ if (vtx_fmt & RADEON_SE_VTX_FMT_W0)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR)
+ vtx_size += 3;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC)
+ vtx_size += 3;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST0)
+ vtx_size += 2;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST1)
+ vtx_size += 2;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q1)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST2)
+ vtx_size += 2;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q2)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST3)
+ vtx_size += 2;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q3)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q0)
+ vtx_size++;
+ /* blend weight */
+ if (vtx_fmt & (0x7 << 15))
+ vtx_size += (vtx_fmt >> 15) & 0x7;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_N0)
+ vtx_size += 3;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_XY1)
+ vtx_size += 2;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_Z1)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_W1)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_N1)
+ vtx_size++;
+ if (vtx_fmt & RADEON_SE_VTX_FMT_Z)
+ vtx_size++;
+ return vtx_size;
+}
+
static int r100_packet0_check(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt)
+ struct radeon_cs_packet *pkt,
+ unsigned idx, unsigned reg)
{
struct radeon_cs_chunk *ib_chunk;
struct radeon_cs_reloc *reloc;
+ struct r100_cs_track *track;
volatile uint32_t *ib;
uint32_t tmp;
- unsigned reg;
- unsigned i;
- unsigned idx;
- bool onereg;
int r;
+ int i, face;
u32 tile_flags = 0;
ib = p->ib->ptr;
ib_chunk = &p->chunks[p->chunk_ib_idx];
- idx = pkt->idx + 1;
- reg = pkt->reg;
- onereg = false;
- if (CP_PACKET0_GET_ONE_REG_WR(ib_chunk->kdata[pkt->idx])) {
- onereg = true;
- }
- for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
- 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);
- r100_cs_dump_packet(p, pkt);
- return r;
- }
- break;
+ track = (struct r100_cs_track *)p->track;
+
+ 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);
+ r100_cs_dump_packet(p, pkt);
+ 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_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;
- }
- tmp = ib_chunk->kdata[idx] & 0x003fffff;
- tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
-
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
- tile_flags |= RADEON_DST_TILE_MACRO;
- if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
- if (reg == RADEON_SRC_PITCH_OFFSET) {
- DRM_ERROR("Cannot src blit from microtiled surface\n");
- r100_cs_dump_packet(p, pkt);
- return -EINVAL;
- }
- tile_flags |= RADEON_DST_TILE_MICRO;
- }
+ 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:
+ 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 = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ break;
+ case RADEON_RB3D_COLOROFFSET:
+ 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[0].robj = reloc->robj;
+ track->cb[0].offset = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ break;
+ case RADEON_PP_TXOFFSET_0:
+ case RADEON_PP_TXOFFSET_1:
+ case RADEON_PP_TXOFFSET_2:
+ i = (reg - RADEON_PP_TXOFFSET_0) / 24;
+ 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] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->textures[i].robj = reloc->robj;
+ break;
+ case RADEON_PP_CUBIC_OFFSET_T0_0:
+ case RADEON_PP_CUBIC_OFFSET_T0_1:
+ case RADEON_PP_CUBIC_OFFSET_T0_2:
+ case RADEON_PP_CUBIC_OFFSET_T0_3:
+ case RADEON_PP_CUBIC_OFFSET_T0_4:
+ i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4;
+ 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->textures[0].cube_info[i].offset = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->textures[0].cube_info[i].robj = reloc->robj;
+ break;
+ case RADEON_PP_CUBIC_OFFSET_T1_0:
+ case RADEON_PP_CUBIC_OFFSET_T1_1:
+ case RADEON_PP_CUBIC_OFFSET_T1_2:
+ case RADEON_PP_CUBIC_OFFSET_T1_3:
+ case RADEON_PP_CUBIC_OFFSET_T1_4:
+ i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4;
+ 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->textures[1].cube_info[i].offset = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->textures[1].cube_info[i].robj = reloc->robj;
+ break;
+ case RADEON_PP_CUBIC_OFFSET_T2_0:
+ case RADEON_PP_CUBIC_OFFSET_T2_1:
+ case RADEON_PP_CUBIC_OFFSET_T2_2:
+ case RADEON_PP_CUBIC_OFFSET_T2_3:
+ case RADEON_PP_CUBIC_OFFSET_T2_4:
+ i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4;
+ 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->textures[2].cube_info[i].offset = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->textures[2].cube_info[i].robj = reloc->robj;
+ break;
+ case RADEON_RE_WIDTH_HEIGHT:
+ track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
+ break;
+ case RADEON_RB3D_COLORPITCH:
+ 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;
+ }
- tmp |= tile_flags;
- ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
- break;
- case RADEON_RB3D_DEPTHOFFSET:
- case RADEON_RB3D_COLOROFFSET:
- case R300_RB3D_COLOROFFSET0:
- case R300_ZB_DEPTHOFFSET:
- 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:
- case RADEON_PP_TXOFFSET_0:
- case RADEON_PP_TXOFFSET_1:
- case RADEON_PP_TXOFFSET_2:
- 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:
- /* rn50 has no 3D engine so fail on any 3d setup */
- if (ASIC_IS_RN50(p->rdev)) {
- DRM_ERROR("attempt to use RN50 3D engine failed\n");
- return -EINVAL;
- }
- 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] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
- break;
- case R300_RB3D_COLORPITCH0:
- case RADEON_RB3D_COLORPITCH:
- 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 |= RADEON_COLOR_TILE_ENABLE;
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+ tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
- tile_flags |= RADEON_COLOR_TILE_ENABLE;
- if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
- tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
+ tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
+ tmp |= tile_flags;
+ ib[idx] = tmp;
- tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
- tmp |= tile_flags;
- ib[idx] = tmp;
+ track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
+ break;
+ case RADEON_RB3D_DEPTHPITCH:
+ track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
+ break;
+ case RADEON_RB3D_CNTL:
+ switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
+ case 7:
+ case 8:
+ case 9:
+ case 11:
+ case 12:
+ track->cb[0].cpp = 1;
break;
- case RADEON_RB3D_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] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ 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",
+ ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
+ return -EINVAL;
+ }
+ track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
+ break;
+ case RADEON_RB3D_ZSTENCILCNTL:
+ switch (ib_chunk->kdata[idx] & 0xf) {
+ 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:
- /* FIXME: we don't want to allow anyothers packet */
break;
}
- if (onereg) {
- /* FIXME: forbid onereg write to register on relocate */
+ break;
+ case RADEON_RB3D_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] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ break;
+ case RADEON_PP_CNTL:
+ {
+ uint32_t temp = ib_chunk->kdata[idx] >> 4;
+ for (i = 0; i < track->num_texture; i++)
+ track->textures[i].enabled = !!(temp & (1 << i));
+ }
+ break;
+ case RADEON_SE_VF_CNTL:
+ track->vap_vf_cntl = ib_chunk->kdata[idx];
+ break;
+ case RADEON_SE_VTX_FMT:
+ track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]);
+ break;
+ case RADEON_PP_TEX_SIZE_0:
+ case RADEON_PP_TEX_SIZE_1:
+ case RADEON_PP_TEX_SIZE_2:
+ i = (reg - RADEON_PP_TEX_SIZE_0) / 8;
+ track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
+ track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
+ break;
+ case RADEON_PP_TEX_PITCH_0:
+ case RADEON_PP_TEX_PITCH_1:
+ case RADEON_PP_TEX_PITCH_2:
+ i = (reg - RADEON_PP_TEX_PITCH_0) / 8;
+ track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
+ break;
+ case RADEON_PP_TXFILTER_0:
+ case RADEON_PP_TXFILTER_1:
+ case RADEON_PP_TXFILTER_2:
+ i = (reg - RADEON_PP_TXFILTER_0) / 24;
+ track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK)
+ >> RADEON_MAX_MIP_LEVEL_SHIFT);
+ tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
+ if (tmp == 2 || tmp == 6)
+ track->textures[i].roundup_w = false;
+ tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
+ if (tmp == 2 || tmp == 6)
+ track->textures[i].roundup_h = false;
+ break;
+ case RADEON_PP_TXFORMAT_0:
+ case RADEON_PP_TXFORMAT_1:
+ case RADEON_PP_TXFORMAT_2:
+ i = (reg - RADEON_PP_TXFORMAT_0) / 24;
+ if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) {
+ track->textures[i].use_pitch = 1;
+ } else {
+ track->textures[i].use_pitch = 0;
+ track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
+ track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+ }
+ if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
+ track->textures[i].tex_coord_type = 2;
+ switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
+ case RADEON_TXFORMAT_I8:
+ case RADEON_TXFORMAT_RGB332:
+ case RADEON_TXFORMAT_Y8:
+ track->textures[i].cpp = 1;
+ break;
+ case RADEON_TXFORMAT_AI88:
+ case RADEON_TXFORMAT_ARGB1555:
+ case RADEON_TXFORMAT_RGB565:
+ case RADEON_TXFORMAT_ARGB4444:
+ case RADEON_TXFORMAT_VYUY422:
+ case RADEON_TXFORMAT_YVYU422:
+ case RADEON_TXFORMAT_DXT1:
+ case RADEON_TXFORMAT_SHADOW16:
+ case RADEON_TXFORMAT_LDUDV655:
+ case RADEON_TXFORMAT_DUDV88:
+ track->textures[i].cpp = 2;
break;
+ case RADEON_TXFORMAT_ARGB8888:
+ case RADEON_TXFORMAT_RGBA8888:
+ case RADEON_TXFORMAT_DXT23:
+ case RADEON_TXFORMAT_DXT45:
+ case RADEON_TXFORMAT_SHADOW32:
+ case RADEON_TXFORMAT_LDUDUV8888:
+ track->textures[i].cpp = 4;
+ break;
+ }
+ track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
+ track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
+ break;
+ case RADEON_PP_CUBIC_FACES_0:
+ case RADEON_PP_CUBIC_FACES_1:
+ case RADEON_PP_CUBIC_FACES_2:
+ tmp = ib_chunk->kdata[idx];
+ i = (reg - RADEON_PP_CUBIC_FACES_0) / 4;
+ 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);
}
+ break;
+ default:
+ printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+ reg, idx);
+ return -EINVAL;
}
return 0;
}
@@ -1186,6 +1401,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
{
struct radeon_cs_chunk *ib_chunk;
struct radeon_cs_reloc *reloc;
+ struct r100_cs_track *track;
unsigned idx;
unsigned i, c;
volatile uint32_t *ib;
@@ -1194,9 +1410,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
ib = p->ib->ptr;
ib_chunk = &p->chunks[p->chunk_ib_idx];
idx = pkt->idx + 1;
+ track = (struct r100_cs_track *)p->track;
switch (pkt->opcode) {
case PACKET3_3D_LOAD_VBPNTR:
c = ib_chunk->kdata[idx++];
+ track->num_arrays = c;
for (i = 0; i < (c - 1); i += 2, idx += 3) {
r = r100_cs_packet_next_reloc(p, &reloc);
if (r) {
@@ -1206,6 +1424,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
return r;
}
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
+ track->arrays[i + 0].robj = reloc->robj;
+ track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
+ track->arrays[i + 0].esize &= 0x7F;
r = r100_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("No reloc for packet3 %d\n",
@@ -1214,6 +1435,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
return r;
}
ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset);
+ track->arrays[i + 1].robj = reloc->robj;
+ track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24;
+ track->arrays[i + 1].esize &= 0x7F;
}
if (c & 1) {
r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1224,6 +1448,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
return r;
}
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
+ track->arrays[i + 0].robj = reloc->robj;
+ track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
+ track->arrays[i + 0].esize &= 0x7F;
}
break;
case PACKET3_INDX_BUFFER:
@@ -1240,7 +1467,6 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
}
break;
case 0x23:
- /* FIXME: cleanup */
/* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */
r = r100_cs_packet_next_reloc(p, &reloc);
if (r) {
@@ -1249,18 +1475,71 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
return r;
}
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->num_arrays = 1;
+ track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]);
+
+ track->arrays[0].robj = reloc->robj;
+ track->arrays[0].esize = track->vtx_size;
+
+ track->max_indx = ib_chunk->kdata[idx+1];
+
+ track->vap_vf_cntl = ib_chunk->kdata[idx+3];
+ track->immd_dwords = pkt->count - 1;
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
break;
case PACKET3_3D_DRAW_IMMD:
+ if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) {
+ DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
+ return -EINVAL;
+ }
+ track->vap_vf_cntl = ib_chunk->kdata[idx+1];
+ track->immd_dwords = pkt->count - 1;
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
+ break;
/* triggers drawing using in-packet vertex data */
case PACKET3_3D_DRAW_IMMD_2:
+ if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) {
+ DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
+ return -EINVAL;
+ }
+ track->vap_vf_cntl = ib_chunk->kdata[idx];
+ track->immd_dwords = pkt->count;
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
+ break;
/* triggers drawing using in-packet vertex data */
case PACKET3_3D_DRAW_VBUF_2:
+ track->vap_vf_cntl = ib_chunk->kdata[idx];
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
+ break;
/* triggers drawing of vertex buffers setup elsewhere */
case PACKET3_3D_DRAW_INDX_2:
+ track->vap_vf_cntl = ib_chunk->kdata[idx];
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
+ break;
/* triggers drawing using indices to vertex buffer */
case PACKET3_3D_DRAW_VBUF:
+ track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
+ break;
/* triggers drawing of vertex buffers setup elsewhere */
case PACKET3_3D_DRAW_INDX:
+ track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
+ r = r100_cs_track_check(p->rdev, track);
+ if (r)
+ return r;
+ break;
/* triggers drawing using indices to vertex buffer */
case PACKET3_NOP:
break;
@@ -1274,8 +1553,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
int r100_cs_parse(struct radeon_cs_parser *p)
{
struct radeon_cs_packet pkt;
+ struct r100_cs_track track;
int r;
+ r100_cs_track_clear(p->rdev, &track);
+ p->track = &track;
do {
r = r100_cs_packet_parse(p, &pkt, p->idx);
if (r) {
@@ -1284,7 +1566,16 @@ int r100_cs_parse(struct radeon_cs_parser *p)
p->idx += pkt.count + 2;
switch (pkt.type) {
case PACKET_TYPE0:
- r = r100_packet0_check(p, &pkt);
+ if (p->rdev->family >= CHIP_R200)
+ r = r100_cs_parse_packet0(p, &pkt,
+ p->rdev->config.r100.reg_safe_bm,
+ p->rdev->config.r100.reg_safe_bm_size,
+ &r200_packet0_check);
+ else
+ r = r100_cs_parse_packet0(p, &pkt,
+ p->rdev->config.r100.reg_safe_bm,
+ p->rdev->config.r100.reg_safe_bm_size,
+ &r100_packet0_check);
break;
case PACKET_TYPE2:
break;
@@ -1683,6 +1974,15 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
int r100_init(struct radeon_device *rdev)
{
+ if (ASIC_IS_RN50(rdev)) {
+ rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
+ rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm);
+ } else if (rdev->family < CHIP_R200) {
+ rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
+ rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
+ } else {
+ return r200_init(rdev);
+ }
return 0;
}
@@ -2383,3 +2683,274 @@ void r100_bandwidth_update(struct radeon_device *rdev)
(unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
}
}
+
+static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
+{
+ DRM_ERROR("pitch %d\n", t->pitch);
+ DRM_ERROR("width %d\n", t->width);
+ DRM_ERROR("height %d\n", t->height);
+ DRM_ERROR("num levels %d\n", t->num_levels);
+ DRM_ERROR("depth %d\n", t->txdepth);
+ DRM_ERROR("bpp %d\n", t->cpp);
+ DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
+ DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
+ DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
+}
+
+static int r100_cs_track_cube(struct radeon_device *rdev,
+ struct r100_cs_track *track, unsigned idx)
+{
+ unsigned face, w, h;
+ struct radeon_object *cube_robj;
+ unsigned long size;
+
+ for (face = 0; face < 5; face++) {
+ cube_robj = track->textures[idx].cube_info[face].robj;
+ w = track->textures[idx].cube_info[face].width;
+ h = track->textures[idx].cube_info[face].height;
+
+ size = w * h;
+ size *= track->textures[idx].cpp;
+
+ size += track->textures[idx].cube_info[face].offset;
+
+ if (size > radeon_object_size(cube_robj)) {
+ DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
+ size, radeon_object_size(cube_robj));
+ r100_cs_track_texture_print(&track->textures[idx]);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int r100_cs_track_texture_check(struct radeon_device *rdev,
+ struct r100_cs_track *track)
+{
+ struct radeon_object *robj;
+ unsigned long size;
+ unsigned u, i, w, h;
+ int ret;
+
+ for (u = 0; u < track->num_texture; u++) {
+ if (!track->textures[u].enabled)
+ continue;
+ robj = track->textures[u].robj;
+ if (robj == NULL) {
+ DRM_ERROR("No texture bound to unit %u\n", u);
+ return -EINVAL;
+ }
+ size = 0;
+ for (i = 0; i <= track->textures[u].num_levels; i++) {
+ if (track->textures[u].use_pitch) {
+ if (rdev->family < CHIP_R300)
+ w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i);
+ else
+ w = track->textures[u].pitch / (1 << i);
+ } else {
+ w = track->textures[u].width / (1 << i);
+ if (rdev->family >= CHIP_RV515)
+ w |= track->textures[u].width_11;
+ if (track->textures[u].roundup_w)
+ w = roundup_pow_of_two(w);
+ }
+ h = track->textures[u].height / (1 << i);
+ if (rdev->family >= CHIP_RV515)
+ h |= track->textures[u].height_11;
+ if (track->textures[u].roundup_h)
+ h = roundup_pow_of_two(h);
+ size += w * h;
+ }
+ size *= track->textures[u].cpp;
+ switch (track->textures[u].tex_coord_type) {
+ case 0:
+ break;
+ case 1:
+ size *= (1 << track->textures[u].txdepth);
+ break;
+ case 2:
+ if (track->separate_cube) {
+ ret = r100_cs_track_cube(rdev, track, u);
+ if (ret)
+ return ret;
+ } else
+ size *= 6;
+ break;
+ default:
+ DRM_ERROR("Invalid texture coordinate type %u for unit "
+ "%u\n", track->textures[u].tex_coord_type, u);
+ return -EINVAL;
+ }
+ if (size > radeon_object_size(robj)) {
+ DRM_ERROR("Texture of unit %u needs %lu bytes but is "
+ "%lu\n", u, size, radeon_object_size(robj));
+ r100_cs_track_texture_print(&track->textures[u]);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
+{
+ unsigned i;
+ unsigned long size;
+ unsigned prim_walk;
+ unsigned nverts;
+
+ for (i = 0; i < track->num_cb; i++) {
+ if (track->cb[i].robj == NULL) {
+ DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
+ return -EINVAL;
+ }
+ size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
+ size += track->cb[i].offset;
+ if (size > radeon_object_size(track->cb[i].robj)) {
+ DRM_ERROR("[drm] Buffer too small for color buffer %d "
+ "(need %lu have %lu) !\n", i, size,
+ radeon_object_size(track->cb[i].robj));
+ DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
+ i, track->cb[i].pitch, track->cb[i].cpp,
+ track->cb[i].offset, track->maxy);
+ return -EINVAL;
+ }
+ }
+ if (track->z_enabled) {
+ if (track->zb.robj == NULL) {
+ DRM_ERROR("[drm] No buffer for z buffer !\n");
+ return -EINVAL;
+ }
+ size = track->zb.pitch * track->zb.cpp * track->maxy;
+ size += track->zb.offset;
+ if (size > radeon_object_size(track->zb.robj)) {
+ DRM_ERROR("[drm] Buffer too small for z buffer "
+ "(need %lu have %lu) !\n", size,
+ radeon_object_size(track->zb.robj));
+ DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
+ track->zb.pitch, track->zb.cpp,
+ track->zb.offset, track->maxy);
+ return -EINVAL;
+ }
+ }
+ prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
+ nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+ switch (prim_walk) {
+ case 1:
+ for (i = 0; i < track->num_arrays; i++) {
+ size = track->arrays[i].esize * track->max_indx * 4;
+ if (track->arrays[i].robj == NULL) {
+ DRM_ERROR("(PW %u) Vertex array %u no buffer "
+ "bound\n", prim_walk, i);
+ return -EINVAL;
+ }
+ if (size > radeon_object_size(track->arrays[i].robj)) {
+ DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
+ "have %lu dwords\n", prim_walk, i,
+ size >> 2,
+ radeon_object_size(track->arrays[i].robj) >> 2);
+ DRM_ERROR("Max indices %u\n", track->max_indx);
+ return -EINVAL;
+ }
+ }
+ break;
+ case 2:
+ for (i = 0; i < track->num_arrays; i++) {
+ size = track->arrays[i].esize * (nverts - 1) * 4;
+ if (track->arrays[i].robj == NULL) {
+ DRM_ERROR("(PW %u) Vertex array %u no buffer "
+ "bound\n", prim_walk, i);
+ return -EINVAL;
+ }
+ if (size > radeon_object_size(track->arrays[i].robj)) {
+ DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
+ "have %lu dwords\n", prim_walk, i, size >> 2,
+ radeon_object_size(track->arrays[i].robj) >> 2);
+ return -EINVAL;
+ }
+ }
+ break;
+ case 3:
+ size = track->vtx_size * nverts;
+ if (size != track->immd_dwords) {
+ DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
+ track->immd_dwords, size);
+ DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
+ nverts, track->vtx_size);
+ return -EINVAL;
+ }
+ break;
+ default:
+ DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
+ prim_walk);
+ return -EINVAL;
+ }
+ return r100_cs_track_texture_check(rdev, track);
+}
+
+void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track)
+{
+ unsigned i, face;
+
+ if (rdev->family < CHIP_R300) {
+ track->num_cb = 1;
+ if (rdev->family <= CHIP_RS200)
+ track->num_texture = 3;
+ else
+ track->num_texture = 6;
+ track->maxy = 2048;
+ track->separate_cube = 1;
+ } else {
+ track->num_cb = 4;
+ track->num_texture = 16;
+ track->maxy = 4096;
+ track->separate_cube = 0;
+ }
+
+ for (i = 0; i < track->num_cb; i++) {
+ track->cb[i].robj = NULL;
+ track->cb[i].pitch = 8192;
+ track->cb[i].cpp = 16;
+ track->cb[i].offset = 0;
+ }
+ track->z_enabled = true;
+ track->zb.robj = NULL;
+ track->zb.pitch = 8192;
+ track->zb.cpp = 4;
+ track->zb.offset = 0;
+ track->vtx_size = 0x7F;
+ track->immd_dwords = 0xFFFFFFFFUL;
+ track->num_arrays = 11;
+ track->max_indx = 0x00FFFFFFUL;
+ for (i = 0; i < track->num_arrays; i++) {
+ track->arrays[i].robj = NULL;
+ track->arrays[i].esize = 0x7F;
+ }
+ for (i = 0; i < track->num_texture; i++) {
+ track->textures[i].pitch = 16536;
+ track->textures[i].width = 16536;
+ track->textures[i].height = 16536;
+ track->textures[i].width_11 = 1 << 11;
+ track->textures[i].height_11 = 1 << 11;
+ track->textures[i].num_levels = 12;
+ if (rdev->family <= CHIP_RS200) {
+ track->textures[i].tex_coord_type = 0;
+ track->textures[i].txdepth = 0;
+ } else {
+ track->textures[i].txdepth = 16;
+ track->textures[i].tex_coord_type = 1;
+ }
+ track->textures[i].cpp = 64;
+ track->textures[i].robj = NULL;
+ /* CS IB emission code makes sure texture unit are disabled */
+ track->textures[i].enabled = false;
+ track->textures[i].roundup_w = true;
+ track->textures[i].roundup_h = true;
+ if (track->separate_cube)
+ for (face = 0; face < 5; face++) {
+ track->textures[i].cube_info[face].robj = NULL;
+ track->textures[i].cube_info[face].width = 16536;
+ track->textures[i].cube_info[face].height = 16536;
+ track->textures[i].cube_info[face].offset = 0;
+ }
+ }
+}
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
new file mode 100644
index 000000000000..70a82eda394a
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r100_track.h
@@ -0,0 +1,124 @@
+
+#define R100_TRACK_MAX_TEXTURE 3
+#define R200_TRACK_MAX_TEXTURE 6
+#define R300_TRACK_MAX_TEXTURE 16
+
+#define R100_MAX_CB 1
+#define R300_MAX_CB 4
+
+/*
+ * CS functions
+ */
+struct r100_cs_track_cb {
+ struct radeon_object *robj;
+ unsigned pitch;
+ unsigned cpp;
+ unsigned offset;
+};
+
+struct r100_cs_track_array {
+ struct radeon_object *robj;
+ unsigned esize;
+};
+
+struct r100_cs_cube_info {
+ struct radeon_object *robj;
+ unsigned offset;
+ unsigned width;
+ unsigned height;
+};
+
+struct r100_cs_track_texture {
+ struct radeon_object *robj;
+ struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
+ unsigned pitch;
+ unsigned width;
+ unsigned height;
+ unsigned num_levels;
+ unsigned cpp;
+ unsigned tex_coord_type;
+ unsigned txdepth;
+ unsigned width_11;
+ unsigned height_11;
+ bool use_pitch;
+ bool enabled;
+ bool roundup_w;
+ bool roundup_h;
+};
+
+struct r100_cs_track_limits {
+ unsigned num_cb;
+ unsigned num_texture;
+ unsigned max_levels;
+};
+
+struct r100_cs_track {
+ struct radeon_device *rdev;
+ unsigned num_cb;
+ unsigned num_texture;
+ unsigned maxy;
+ unsigned vtx_size;
+ unsigned vap_vf_cntl;
+ unsigned immd_dwords;
+ unsigned num_arrays;
+ unsigned max_indx;
+ struct r100_cs_track_array arrays[11];
+ struct r100_cs_track_cb cb[R300_MAX_CB];
+ struct r100_cs_track_cb zb;
+ struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE];
+ bool z_enabled;
+ bool separate_cube;
+
+};
+
+int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
+void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track);
+int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
+ struct radeon_cs_reloc **cs_reloc);
+void r100_cs_dump_packet(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt);
+
+int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
+
+int r200_packet0_check(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ unsigned idx, unsigned reg);
+
+static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ unsigned idx,
+ unsigned reg)
+{
+ int r;
+ u32 tile_flags = 0;
+ u32 tmp;
+ struct radeon_cs_reloc *reloc;
+ struct radeon_cs_chunk *ib_chunk;
+
+ ib_chunk = &p->chunks[p->chunk_ib_idx];
+
+ 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;
+ }
+ tmp = ib_chunk->kdata[idx] & 0x003fffff;
+ tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
+
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+ tile_flags |= RADEON_DST_TILE_MACRO;
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+ if (reg == RADEON_SRC_PITCH_OFFSET) {
+ DRM_ERROR("Cannot src blit from microtiled surface\n");
+ r100_cs_dump_packet(p, pkt);
+ return -EINVAL;
+ }
+ tile_flags |= RADEON_DST_TILE_MICRO;
+ }
+
+ tmp |= tile_flags;
+ p->ib->ptr[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
new file mode 100644
index 000000000000..568c74bfba3d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -0,0 +1,456 @@
+/*
+ * 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
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_reg.h"
+#include "radeon.h"
+
+#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;
+}
+
+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)
+{
+ struct radeon_cs_chunk *ib_chunk;
+ struct radeon_cs_reloc *reloc;
+ struct r100_cs_track *track;
+ volatile uint32_t *ib;
+ uint32_t tmp;
+ int r;
+ int i;
+ int face;
+ u32 tile_flags = 0;
+
+ ib = p->ib->ptr;
+ ib_chunk = &p->chunks[p->chunk_ib_idx];
+ track = (struct r100_cs_track *)p->track;
+
+ 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);
+ r100_cs_dump_packet(p, pkt);
+ 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:
+ 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 = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ break;
+ case RADEON_RB3D_COLOROFFSET:
+ 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[0].robj = reloc->robj;
+ track->cb[0].offset = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ 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;
+ 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] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->textures[i].robj = reloc->robj;
+ 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;
+ 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->textures[i].cube_info[face - 1].offset = ib_chunk->kdata[idx];
+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ track->textures[i].cube_info[face - 1].robj = reloc->robj;
+ break;
+ case RADEON_RE_WIDTH_HEIGHT:
+ track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
+ break;
+ case RADEON_RB3D_COLORPITCH:
+ 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 |= RADEON_COLOR_TILE_ENABLE;
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+ tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
+
+ tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
+ tmp |= tile_flags;
+ ib[idx] = tmp;
+
+ track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
+ break;
+ case RADEON_RB3D_DEPTHPITCH:
+ track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
+ break;
+ case RADEON_RB3D_CNTL:
+ switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
+ 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",
+ ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
+ return -EINVAL;
+ }
+ if (ib_chunk->kdata[idx] & RADEON_DEPTHXY_OFFSET_ENABLE) {
+ DRM_ERROR("No support for depth xy offset in kms\n");
+ return -EINVAL;
+ }
+
+ track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
+ break;
+ case RADEON_RB3D_ZSTENCILCNTL:
+ switch (ib_chunk->kdata[idx] & 0xf) {
+ 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;
+ }
+ break;
+ case RADEON_RB3D_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] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+ break;
+ case RADEON_PP_CNTL:
+ {
+ uint32_t temp = ib_chunk->kdata[idx] >> 4;
+ for (i = 0; i < track->num_texture; i++)
+ track->textures[i].enabled = !!(temp & (1 << i));
+ }
+ break;
+ case RADEON_SE_VF_CNTL:
+ track->vap_vf_cntl = ib_chunk->kdata[idx];
+ break;
+ case 0x210c:
+ /* VAP_VF_MAX_VTX_INDX */
+ track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL;
+ break;
+ case R200_SE_VTX_FMT_0:
+ track->vtx_size = r200_get_vtx_size_0(ib_chunk->kdata[idx]);
+ break;
+ case R200_SE_VTX_FMT_1:
+ track->vtx_size += r200_get_vtx_size_1(ib_chunk->kdata[idx]);
+ 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;
+ track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
+ track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
+ 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;
+ track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
+ 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;
+ track->textures[i].num_levels = ((ib_chunk->kdata[idx] & R200_MAX_MIP_LEVEL_MASK)
+ >> R200_MAX_MIP_LEVEL_SHIFT);
+ tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
+ if (tmp == 2 || tmp == 6)
+ track->textures[i].roundup_w = false;
+ tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
+ if (tmp == 2 || tmp == 6)
+ track->textures[i].roundup_h = false;
+ 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;
+ track->textures[i].txdepth = ib_chunk->kdata[idx] & 0x7;
+ tmp = (ib_chunk->kdata[idx] >> 16) & 0x3;
+ /* 2D, 3D, CUBE */
+ switch (tmp) {
+ case 0:
+ case 5:
+ case 6:
+ case 7:
+ track->textures[i].tex_coord_type = 0;
+ break;
+ case 1:
+ track->textures[i].tex_coord_type = 1;
+ break;
+ case 2:
+ track->textures[i].tex_coord_type = 2;
+ break;
+ }
+ 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;
+ if (ib_chunk->kdata[idx] & R200_TXFORMAT_NON_POWER2) {
+ track->textures[i].use_pitch = 1;
+ } else {
+ track->textures[i].use_pitch = 0;
+ track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
+ track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+ }
+ switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
+ case R200_TXFORMAT_I8:
+ case R200_TXFORMAT_RGB332:
+ case R200_TXFORMAT_Y8:
+ track->textures[i].cpp = 1;
+ break;
+ case R200_TXFORMAT_DXT1:
+ 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;
+ break;
+ case R200_TXFORMAT_ARGB8888:
+ case R200_TXFORMAT_RGBA8888:
+ case R200_TXFORMAT_ABGR8888:
+ case R200_TXFORMAT_BGR111110:
+ case R200_TXFORMAT_LDVDU8888:
+ case R200_TXFORMAT_DXT23:
+ case R200_TXFORMAT_DXT45:
+ track->textures[i].cpp = 4;
+ break;
+ }
+ track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
+ track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
+ 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:
+ tmp = ib_chunk->kdata[idx];
+ 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);
+ }
+ break;
+ default:
+ printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+ reg, idx);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int r200_init(struct radeon_device *rdev)
+{
+ rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
+ rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 9f2460cf9dbc..33a2c557eac4 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -32,6 +32,7 @@
#include "radeon.h"
#include "radeon_drm.h"
#include "radeon_share.h"
+#include "r100_track.h"
#include "r300_reg_safe.h"
@@ -49,14 +50,10 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx);
int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
-int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
- struct radeon_cs_reloc **cs_reloc);
int r100_cs_parse_packet0(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
const unsigned *auth, unsigned n,
radeon_packet0_check_t check);
-void r100_cs_dump_packet(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt);
int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
struct radeon_object *robj);
@@ -706,264 +703,13 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
/*
* CS functions
*/
-struct r300_cs_track_cb {
- struct radeon_object *robj;
- unsigned pitch;
- unsigned cpp;
- unsigned offset;
-};
-
-struct r300_cs_track_array {
- struct radeon_object *robj;
- unsigned esize;
-};
-
-struct r300_cs_track_texture {
- struct radeon_object *robj;
- unsigned pitch;
- unsigned width;
- unsigned height;
- unsigned num_levels;
- unsigned cpp;
- unsigned tex_coord_type;
- unsigned txdepth;
- unsigned width_11;
- unsigned height_11;
- bool use_pitch;
- bool enabled;
- bool roundup_w;
- bool roundup_h;
-};
-
-struct r300_cs_track {
- unsigned num_cb;
- unsigned maxy;
- unsigned vtx_size;
- unsigned vap_vf_cntl;
- unsigned immd_dwords;
- unsigned num_arrays;
- unsigned max_indx;
- struct r300_cs_track_array arrays[11];
- struct r300_cs_track_cb cb[4];
- struct r300_cs_track_cb zb;
- struct r300_cs_track_texture textures[16];
- bool z_enabled;
-};
-
-static inline void r300_cs_track_texture_print(struct r300_cs_track_texture *t)
-{
- DRM_ERROR("pitch %d\n", t->pitch);
- DRM_ERROR("width %d\n", t->width);
- DRM_ERROR("height %d\n", t->height);
- DRM_ERROR("num levels %d\n", t->num_levels);
- DRM_ERROR("depth %d\n", t->txdepth);
- DRM_ERROR("bpp %d\n", t->cpp);
- DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
- DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
- DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
-}
-
-static inline int r300_cs_track_texture_check(struct radeon_device *rdev,
- struct r300_cs_track *track)
-{
- struct radeon_object *robj;
- unsigned long size;
- unsigned u, i, w, h;
-
- for (u = 0; u < 16; u++) {
- if (!track->textures[u].enabled)
- continue;
- robj = track->textures[u].robj;
- if (robj == NULL) {
- DRM_ERROR("No texture bound to unit %u\n", u);
- return -EINVAL;
- }
- size = 0;
- for (i = 0; i <= track->textures[u].num_levels; i++) {
- if (track->textures[u].use_pitch) {
- w = track->textures[u].pitch / (1 << i);
- } else {
- w = track->textures[u].width / (1 << i);
- if (rdev->family >= CHIP_RV515)
- w |= track->textures[u].width_11;
- if (track->textures[u].roundup_w)
- w = roundup_pow_of_two(w);
- }
- h = track->textures[u].height / (1 << i);
- if (rdev->family >= CHIP_RV515)
- h |= track->textures[u].height_11;
- if (track->textures[u].roundup_h)
- h = roundup_pow_of_two(h);
- size += w * h;
- }
- size *= track->textures[u].cpp;
- switch (track->textures[u].tex_coord_type) {
- case 0:
- break;
- case 1:
- size *= (1 << track->textures[u].txdepth);
- break;
- case 2:
- size *= 6;
- break;
- default:
- DRM_ERROR("Invalid texture coordinate type %u for unit "
- "%u\n", track->textures[u].tex_coord_type, u);
- return -EINVAL;
- }
- if (size > radeon_object_size(robj)) {
- DRM_ERROR("Texture of unit %u needs %lu bytes but is "
- "%lu\n", u, size, radeon_object_size(robj));
- r300_cs_track_texture_print(&track->textures[u]);
- return -EINVAL;
- }
- }
- return 0;
-}
-
-int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track)
-{
- unsigned i;
- unsigned long size;
- unsigned prim_walk;
- unsigned nverts;
-
- for (i = 0; i < track->num_cb; i++) {
- if (track->cb[i].robj == NULL) {
- DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
- return -EINVAL;
- }
- size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
- size += track->cb[i].offset;
- if (size > radeon_object_size(track->cb[i].robj)) {
- DRM_ERROR("[drm] Buffer too small for color buffer %d "
- "(need %lu have %lu) !\n", i, size,
- radeon_object_size(track->cb[i].robj));
- DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
- i, track->cb[i].pitch, track->cb[i].cpp,
- track->cb[i].offset, track->maxy);
- return -EINVAL;
- }
- }
- if (track->z_enabled) {
- if (track->zb.robj == NULL) {
- DRM_ERROR("[drm] No buffer for z buffer !\n");
- return -EINVAL;
- }
- size = track->zb.pitch * track->zb.cpp * track->maxy;
- size += track->zb.offset;
- if (size > radeon_object_size(track->zb.robj)) {
- DRM_ERROR("[drm] Buffer too small for z buffer "
- "(need %lu have %lu) !\n", size,
- radeon_object_size(track->zb.robj));
- return -EINVAL;
- }
- }
- prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
- nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
- switch (prim_walk) {
- case 1:
- for (i = 0; i < track->num_arrays; i++) {
- size = track->arrays[i].esize * track->max_indx * 4;
- if (track->arrays[i].robj == NULL) {
- DRM_ERROR("(PW %u) Vertex array %u no buffer "
- "bound\n", prim_walk, i);
- return -EINVAL;
- }
- if (size > radeon_object_size(track->arrays[i].robj)) {
- DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
- "have %lu dwords\n", prim_walk, i,
- size >> 2,
- radeon_object_size(track->arrays[i].robj) >> 2);
- DRM_ERROR("Max indices %u\n", track->max_indx);
- return -EINVAL;
- }
- }
- break;
- case 2:
- for (i = 0; i < track->num_arrays; i++) {
- size = track->arrays[i].esize * (nverts - 1) * 4;
- if (track->arrays[i].robj == NULL) {
- DRM_ERROR("(PW %u) Vertex array %u no buffer "
- "bound\n", prim_walk, i);
- return -EINVAL;
- }
- if (size > radeon_object_size(track->arrays[i].robj)) {
- DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
- "have %lu dwords\n", prim_walk, i, size >> 2,
- radeon_object_size(track->arrays[i].robj) >> 2);
- return -EINVAL;
- }
- }
- break;
- case 3:
- size = track->vtx_size * nverts;
- if (size != track->immd_dwords) {
- DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
- track->immd_dwords, size);
- DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
- nverts, track->vtx_size);
- return -EINVAL;
- }
- break;
- default:
- DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
- prim_walk);
- return -EINVAL;
- }
- return r300_cs_track_texture_check(rdev, track);
-}
-
-static inline void r300_cs_track_clear(struct r300_cs_track *track)
-{
- unsigned i;
-
- track->num_cb = 4;
- track->maxy = 4096;
- for (i = 0; i < track->num_cb; i++) {
- track->cb[i].robj = NULL;
- track->cb[i].pitch = 8192;
- track->cb[i].cpp = 16;
- track->cb[i].offset = 0;
- }
- track->z_enabled = true;
- track->zb.robj = NULL;
- track->zb.pitch = 8192;
- track->zb.cpp = 4;
- track->zb.offset = 0;
- track->vtx_size = 0x7F;
- track->immd_dwords = 0xFFFFFFFFUL;
- track->num_arrays = 11;
- track->max_indx = 0x00FFFFFFUL;
- for (i = 0; i < track->num_arrays; i++) {
- track->arrays[i].robj = NULL;
- track->arrays[i].esize = 0x7F;
- }
- for (i = 0; i < 16; i++) {
- track->textures[i].pitch = 16536;
- track->textures[i].width = 16536;
- track->textures[i].height = 16536;
- track->textures[i].width_11 = 1 << 11;
- track->textures[i].height_11 = 1 << 11;
- track->textures[i].num_levels = 12;
- track->textures[i].txdepth = 16;
- track->textures[i].cpp = 64;
- track->textures[i].tex_coord_type = 1;
- track->textures[i].robj = NULL;
- /* CS IB emission code makes sure texture unit are disabled */
- track->textures[i].enabled = false;
- track->textures[i].roundup_w = true;
- track->textures[i].roundup_h = true;
- }
-}
-
static int r300_packet0_check(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx, unsigned reg)
{
struct radeon_cs_chunk *ib_chunk;
struct radeon_cs_reloc *reloc;
- struct r300_cs_track *track;
+ struct r100_cs_track *track;
volatile uint32_t *ib;
uint32_t tmp, tile_flags = 0;
unsigned i;
@@ -971,7 +717,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
ib = p->ib->ptr;
ib_chunk = &p->chunks[p->chunk_ib_idx];
- track = (struct r300_cs_track*)p->track;
+ track = (struct r100_cs_track *)p->track;
switch(reg) {
case AVIVO_D1MODE_VLINE_START_END:
case RADEON_CRTC_GUI_TRIG_VLINE:
@@ -985,28 +731,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
break;
case RADEON_DST_PITCH_OFFSET:
case RADEON_SRC_PITCH_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);
+ r = r100_reloc_pitch_offset(p, pkt, idx, reg);
+ if (r)
return r;
- }
- tmp = ib_chunk->kdata[idx] & 0x003fffff;
- tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
-
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
- tile_flags |= RADEON_DST_TILE_MACRO;
- if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
- if (reg == RADEON_SRC_PITCH_OFFSET) {
- DRM_ERROR("Cannot src blit from microtiled surface\n");
- r100_cs_dump_packet(p, pkt);
- return -EINVAL;
- }
- tile_flags |= RADEON_DST_TILE_MICRO;
- }
- tmp |= tile_flags;
- ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
break;
case R300_RB3D_COLOROFFSET0:
case R300_RB3D_COLOROFFSET1:
@@ -1215,42 +942,41 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
tmp = (ib_chunk->kdata[idx] >> 25) & 0x3;
track->textures[i].tex_coord_type = tmp;
switch ((ib_chunk->kdata[idx] & 0x1F)) {
- case 0:
- case 2:
- case 5:
- case 18:
- case 20:
- case 21:
+ case R300_TX_FORMAT_X8:
+ case R300_TX_FORMAT_Y4X4:
+ case R300_TX_FORMAT_Z3Y3X2:
track->textures[i].cpp = 1;
break;
- case 1:
- case 3:
- case 6:
- case 7:
- case 10:
- case 11:
- case 19:
- case 22:
- case 24:
+ case R300_TX_FORMAT_X16:
+ 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_DXT1:
+ case R300_TX_FORMAT_D3DMFT_CxV8U8:
+ case R300_TX_FORMAT_B8G8_B8G8:
+ case R300_TX_FORMAT_G8R8_G8B8:
track->textures[i].cpp = 2;
break;
- case 4:
- case 8:
- case 9:
- case 12:
- case 13:
- case 23:
- case 25:
- case 27:
- case 30:
+ case R300_TX_FORMAT_Y16X16:
+ 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:
+ case R300_TX_FORMAT_DXT3:
+ case R300_TX_FORMAT_DXT5:
track->textures[i].cpp = 4;
break;
- case 14:
- case 26:
- case 28:
+ case R300_TX_FORMAT_W16Z16Y16X16:
+ case R300_TX_FORMAT_FL_R16G16B16A16:
+ case R300_TX_FORMAT_FL_I32A32:
track->textures[i].cpp = 8;
break;
- case 29:
+ case R300_TX_FORMAT_FL_R32G32B32A32:
track->textures[i].cpp = 16;
break;
default:
@@ -1278,11 +1004,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case 0x443C:
/* TX_FILTER0_[0-15] */
i = (reg - 0x4400) >> 2;
- tmp = ib_chunk->kdata[idx] & 0x7;;
+ tmp = ib_chunk->kdata[idx] & 0x7;
if (tmp == 2 || tmp == 4 || tmp == 6) {
track->textures[i].roundup_w = false;
}
- tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;;
+ tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;
if (tmp == 2 || tmp == 4 || tmp == 6) {
track->textures[i].roundup_h = false;
}
@@ -1370,8 +1096,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt)
{
struct radeon_cs_chunk *ib_chunk;
+
struct radeon_cs_reloc *reloc;
- struct r300_cs_track *track;
+ struct r100_cs_track *track;
volatile uint32_t *ib;
unsigned idx;
unsigned i, c;
@@ -1380,7 +1107,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
ib = p->ib->ptr;
ib_chunk = &p->chunks[p->chunk_ib_idx];
idx = pkt->idx + 1;
- track = (struct r300_cs_track*)p->track;
+ track = (struct r100_cs_track *)p->track;
switch(pkt->opcode) {
case PACKET3_3D_LOAD_VBPNTR:
c = ib_chunk->kdata[idx++] & 0x1F;
@@ -1447,7 +1174,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
}
track->vap_vf_cntl = ib_chunk->kdata[idx+1];
track->immd_dwords = pkt->count - 1;
- r = r300_cs_track_check(p->rdev, track);
+ r = r100_cs_track_check(p->rdev, track);
if (r) {
return r;
}
@@ -1462,35 +1189,35 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
}
track->vap_vf_cntl = ib_chunk->kdata[idx];
track->immd_dwords = pkt->count;
- r = r300_cs_track_check(p->rdev, track);
+ r = r100_cs_track_check(p->rdev, track);
if (r) {
return r;
}
break;
case PACKET3_3D_DRAW_VBUF:
track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
- r = r300_cs_track_check(p->rdev, track);
+ r = r100_cs_track_check(p->rdev, track);
if (r) {
return r;
}
break;
case PACKET3_3D_DRAW_VBUF_2:
track->vap_vf_cntl = ib_chunk->kdata[idx];
- r = r300_cs_track_check(p->rdev, track);
+ r = r100_cs_track_check(p->rdev, track);
if (r) {
return r;
}
break;
case PACKET3_3D_DRAW_INDX:
track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
- r = r300_cs_track_check(p->rdev, track);
+ r = r100_cs_track_check(p->rdev, track);
if (r) {
return r;
}
break;
case PACKET3_3D_DRAW_INDX_2:
track->vap_vf_cntl = ib_chunk->kdata[idx];
- r = r300_cs_track_check(p->rdev, track);
+ r = r100_cs_track_check(p->rdev, track);
if (r) {
return r;
}
@@ -1507,10 +1234,10 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
int r300_cs_parse(struct radeon_cs_parser *p)
{
struct radeon_cs_packet pkt;
- struct r300_cs_track track;
+ struct r100_cs_track track;
int r;
- r300_cs_track_clear(&track);
+ r100_cs_track_clear(p->rdev, &track);
p->track = &track;
do {
r = r100_cs_packet_parse(p, &pkt, p->idx);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 149974d13aa2..6c35c3c29191 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -604,8 +604,14 @@ struct radeon_asic {
void (*bandwidth_update)(struct radeon_device *rdev);
};
+struct r100_asic {
+ const unsigned *reg_safe_bm;
+ unsigned reg_safe_bm_size;
+};
+
union radeon_asic_config {
struct r300_asic r300;
+ struct r100_asic r100;
};
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 8ace15156c47..c9cbd8ae1f95 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -42,6 +42,7 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
*/
int r100_init(struct radeon_device *rdev);
+int r200_init(struct radeon_device *rdev);
uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void r100_errata(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index 4df43f62c678..404b39bf3430 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -1945,6 +1945,11 @@
# define RADEON_TXFORMAT_DXT1 (12 << 0)
# define RADEON_TXFORMAT_DXT23 (14 << 0)
# define RADEON_TXFORMAT_DXT45 (15 << 0)
+# define RADEON_TXFORMAT_SHADOW16 (16 << 0)
+# define RADEON_TXFORMAT_SHADOW32 (17 << 0)
+# define RADEON_TXFORMAT_DUDV88 (18 << 0)
+# define RADEON_TXFORMAT_LDUDV655 (19 << 0)
+# define RADEON_TXFORMAT_LDUDUV8888 (20 << 0)
# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0)
# define RADEON_TXFORMAT_FORMAT_SHIFT 0
# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5)
@@ -2203,7 +2208,7 @@
# define RADEON_ROP_ENABLE (1 << 6)
# define RADEON_STENCIL_ENABLE (1 << 7)
# define RADEON_Z_ENABLE (1 << 8)
-# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9)
+# define RADEON_DEPTHXY_OFFSET_ENABLE (1 << 9)
# define RADEON_RB3D_COLOR_FORMAT_SHIFT 10
# define RADEON_COLOR_FORMAT_ARGB1555 3
@@ -2773,7 +2778,12 @@
# define R200_TXFORMAT_DXT1 (12 << 0)
# define R200_TXFORMAT_DXT23 (14 << 0)
# define R200_TXFORMAT_DXT45 (15 << 0)
+# define R200_TXFORMAT_DVDU88 (18 << 0)
+# define R200_TXFORMAT_LDVDU655 (19 << 0)
+# define R200_TXFORMAT_LDVDU8888 (20 << 0)
+# define R200_TXFORMAT_GR1616 (21 << 0)
# define R200_TXFORMAT_ABGR8888 (22 << 0)
+# define R200_TXFORMAT_BGR111110 (23 << 0)
# define R200_TXFORMAT_FORMAT_MASK (31 << 0)
# define R200_TXFORMAT_FORMAT_SHIFT 0
# define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6)
@@ -2818,6 +2828,13 @@
#define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */
#define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */
+#define R200_PP_CUBIC_FACES_0 0x2c18
+#define R200_PP_CUBIC_FACES_1 0x2c38
+#define R200_PP_CUBIC_FACES_2 0x2c58
+#define R200_PP_CUBIC_FACES_3 0x2c78
+#define R200_PP_CUBIC_FACES_4 0x2c98
+#define R200_PP_CUBIC_FACES_5 0x2cb8
+
#define R200_PP_TXOFFSET_0 0x2d00
# define R200_TXO_ENDIAN_NO_SWAP (0 << 0)
# define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0)
@@ -2829,11 +2846,44 @@
# define R200_TXO_MICRO_TILE (1 << 3)
# define R200_TXO_OFFSET_MASK 0xffffffe0
# define R200_TXO_OFFSET_SHIFT 5
+#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
+#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
+#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
+#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
+#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
+
#define R200_PP_TXOFFSET_1 0x2d18
+#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
+#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
+#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
+#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
+#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
+
#define R200_PP_TXOFFSET_2 0x2d30
+#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
+#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
+#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
+#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
+#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
+
#define R200_PP_TXOFFSET_3 0x2d48
+#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
+#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
+#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
+#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
+#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
#define R200_PP_TXOFFSET_4 0x2d60
+#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
+#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
+#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
+#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
+#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
#define R200_PP_TXOFFSET_5 0x2d78
+#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
+#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
+#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
+#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
+#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
#define R200_PP_TFACTOR_0 0x2ee0
#define R200_PP_TFACTOR_1 0x2ee4
@@ -3175,6 +3225,11 @@
# define R200_FORCE_INORDER_PROC (1<<31)
#define R200_PP_CNTL_X 0x2cc4
#define R200_PP_TXMULTI_CTL_0 0x2c1c
+#define R200_PP_TXMULTI_CTL_1 0x2c3c
+#define R200_PP_TXMULTI_CTL_2 0x2c5c
+#define R200_PP_TXMULTI_CTL_3 0x2c7c
+#define R200_PP_TXMULTI_CTL_4 0x2c9c
+#define R200_PP_TXMULTI_CTL_5 0x2cbc
#define R200_SE_VTX_STATE_CNTL 0x2180
# define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16)
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r100 b/drivers/gpu/drm/radeon/reg_srcs/r100
new file mode 100644
index 000000000000..f7ee062f1184
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r100
@@ -0,0 +1,105 @@
+r100 0x3294
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1810 FOG_3D_TABLE_START
+0x1814 FOG_3D_TABLE_END
+0x1a14 FOG_TABLE_INDEX
+0x1a18 FOG_TABLE_DATA
+0x1c14 PP_MISC
+0x1c18 PP_FOG_COLOR
+0x1c1c RE_SOLID_COLOR
+0x1c20 RB3D_BLENDCNTL
+0x1c4c SE_CNTL
+0x1c50 SE_COORD_FMT
+0x1c60 PP_TXCBLEND_0
+0x1c64 PP_TXABLEND_0
+0x1c68 PP_TFACTOR_0
+0x1c78 PP_TXCBLEND_1
+0x1c7c PP_TXABLEND_1
+0x1c80 PP_TFACTOR_1
+0x1c90 PP_TXCBLEND_2
+0x1c94 PP_TXABLEND_2
+0x1c98 PP_TFACTOR_2
+0x1cc8 RE_STIPPLE_ADDR
+0x1ccc RE_STIPPLE_DATA
+0x1cd0 RE_LINE_PATTERN
+0x1cd4 RE_LINE_STATE
+0x1d40 PP_BORDER_COLOR0
+0x1d44 PP_BORDER_COLOR1
+0x1d48 PP_BORDER_COLOR2
+0x1d7c RB3D_STENCILREFMASK
+0x1d80 RB3D_ROPCNTL
+0x1d84 RB3D_PLANEMASK
+0x1d98 VAP_VPORT_XSCALE
+0x1d9C VAP_VPORT_XOFFSET
+0x1da0 VAP_VPORT_YSCALE
+0x1da4 VAP_VPORT_YOFFSET
+0x1da8 VAP_VPORT_ZSCALE
+0x1dac VAP_VPORT_ZOFFSET
+0x1db0 SE_ZBIAS_FACTOR
+0x1db4 SE_ZBIAS_CONSTANT
+0x1db8 SE_LINE_WIDTH
+0x2140 SE_CNTL_STATUS
+0x2200 SE_TCL_VECTOR_INDX_REG
+0x2204 SE_TCL_VECTOR_DATA_REG
+0x2208 SE_TCL_SCALAR_INDX_REG
+0x220c SE_TCL_SCALAR_DATA_REG
+0x2210 SE_TCL_MATERIAL_EMISSIVE_RED
+0x2214 SE_TCL_MATERIAL_EMISSIVE_GREEN
+0x2218 SE_TCL_MATERIAL_EMISSIVE_BLUE
+0x221c SE_TCL_MATERIAL_EMISSIVE_ALPHA
+0x2220 SE_TCL_MATERIAL_AMBIENT_RED
+0x2224 SE_TCL_MATERIAL_AMBIENT_GREEN
+0x2228 SE_TCL_MATERIAL_AMBIENT_BLUE
+0x222c SE_TCL_MATERIAL_AMBIENT_ALPHA
+0x2230 SE_TCL_MATERIAL_DIFFUSE_RED
+0x2234 SE_TCL_MATERIAL_DIFFUSE_GREEN
+0x2238 SE_TCL_MATERIAL_DIFFUSE_BLUE
+0x223c SE_TCL_MATERIAL_DIFFUSE_ALPHA
+0x2240 SE_TCL_MATERIAL_SPECULAR_RED
+0x2244 SE_TCL_MATERIAL_SPECULAR_GREEN
+0x2248 SE_TCL_MATERIAL_SPECULAR_BLUE
+0x224c SE_TCL_MATERIAL_SPECULAR_ALPHA
+0x2250 SE_TCL_SHININESS
+0x2254 SE_TCL_OUTPUT_VTX_FMT
+0x2258 SE_TCL_OUTPUT_VTX_SEL
+0x225c SE_TCL_MATRIX_SELECT_0
+0x2260 SE_TCL_MATRIX_SELECT_1
+0x2264 SE_TCL_UCP_VERT_BLEND_CNTL
+0x2268 SE_TCL_TEXTURE_PROC_CTL
+0x226c SE_TCL_LIGHT_MODEL_CTL
+0x2270 SE_TCL_PER_LIGHT_CTL_0
+0x2274 SE_TCL_PER_LIGHT_CTL_1
+0x2278 SE_TCL_PER_LIGHT_CTL_2
+0x227c SE_TCL_PER_LIGHT_CTL_3
+0x2284 SE_TCL_STATE_FLUSH
+0x26c0 RE_TOP_LEFT
+0x26c4 RE_MISC
+0x3290 RB3D_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r200 b/drivers/gpu/drm/radeon/reg_srcs/r200
new file mode 100644
index 000000000000..6021c8849a16
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r200
@@ -0,0 +1,184 @@
+r200 0x3294
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1c14 PP_MISC
+0x1c18 PP_FOG_COLOR
+0x1c1c RE_SOLID_COLOR
+0x1c20 RB3D_BLENDCNTL
+0x1c4c SE_CNTL
+0x1c50 RE_CNTL
+0x1cc8 RE_STIPPLE_ADDR
+0x1ccc RE_STIPPLE_DATA
+0x1cd0 RE_LINE_PATTERN
+0x1cd4 RE_LINE_STATE
+0x1cd8 RE_SCISSOR_TL_0
+0x1cdc RE_SCISSOR_BR_0
+0x1ce0 RE_SCISSOR_TL_1
+0x1ce4 RE_SCISSOR_BR_1
+0x1ce8 RE_SCISSOR_TL_2
+0x1cec RE_SCISSOR_BR_2
+0x1d60 RB3D_DEPTHXY_OFFSET
+0x1d7c RB3D_STENCILREFMASK
+0x1d80 RB3D_ROPCNTL
+0x1d84 RB3D_PLANEMASK
+0x1d98 VAP_VPORT_XSCALE
+0x1d9c VAP_VPORT_XOFFSET
+0x1da0 VAP_VPORT_YSCALE
+0x1da4 VAP_VPORT_YOFFSET
+0x1da8 VAP_VPORT_ZSCALE
+0x1dac VAP_VPORT_ZOFFSET
+0x1db0 SE_ZBIAS_FACTOR
+0x1db4 SE_ZBIAS_CONSTANT
+0x1db8 SE_LINE_WIDTH
+0x2080 SE_VAP_CNTL
+0x2090 SE_TCL_OUTPUT_VTX_FMT_0
+0x2094 SE_TCL_OUTPUT_VTX_FMT_1
+0x20b0 SE_VTE_CNTL
+0x2140 SE_CNTL_STATUS
+0x2180 SE_VTX_STATE_CNTL
+0x2200 SE_TCL_VECTOR_INDX_REG
+0x2204 SE_TCL_VECTOR_DATA_REG
+0x2208 SE_TCL_SCALAR_INDX_REG
+0x220c SE_TCL_SCALAR_DATA_REG
+0x2230 SE_TCL_MATRIX_SEL_0
+0x2234 SE_TCL_MATRIX_SEL_1
+0x2238 SE_TCL_MATRIX_SEL_2
+0x223c SE_TCL_MATRIX_SEL_3
+0x2240 SE_TCL_MATRIX_SEL_4
+0x2250 SE_TCL_OUTPUT_VTX_COMP_SEL
+0x2254 SE_TCL_INPUT_VTX_VECTOR_ADDR_0
+0x2258 SE_TCL_INPUT_VTX_VECTOR_ADDR_1
+0x225c SE_TCL_INPUT_VTX_VECTOR_ADDR_2
+0x2260 SE_TCL_INPUT_VTX_VECTOR_ADDR_3
+0x2268 SE_TCL_LIGHT_MODEL_CTL_0
+0x226c SE_TCL_LIGHT_MODEL_CTL_1
+0x2270 SE_TCL_PER_LIGHT_CTL_0
+0x2274 SE_TCL_PER_LIGHT_CTL_1
+0x2278 SE_TCL_PER_LIGHT_CTL_2
+0x227c SE_TCL_PER_LIGHT_CTL_3
+0x2284 VAP_PVS_STATE_FLUSH_REG
+0x22a8 SE_TCL_TEX_PROC_CTL_2
+0x22ac SE_TCL_TEX_PROC_CTL_3
+0x22b0 SE_TCL_TEX_PROC_CTL_0
+0x22b4 SE_TCL_TEX_PROC_CTL_1
+0x22b8 SE_TCL_TEX_CYL_WRAP_CTL
+0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL
+0x22c4 SE_TCL_POINT_SPRITE_CNTL
+0x2648 RE_POINTSIZE
+0x26c0 RE_TOP_LEFT
+0x26c4 RE_MISC
+0x26f0 RE_AUX_SCISSOR_CNTL
+0x2c14 PP_BORDER_COLOR_0
+0x2c34 PP_BORDER_COLOR_1
+0x2c54 PP_BORDER_COLOR_2
+0x2c74 PP_BORDER_COLOR_3
+0x2c94 PP_BORDER_COLOR_4
+0x2cb4 PP_BORDER_COLOR_5
+0x2cc4 PP_CNTL_X
+0x2cf8 PP_TRI_PERF
+0x2cfc PP_PERF_CNTL
+0x2d9c PP_TAM_DEBUG3
+0x2ee0 PP_TFACTOR_0
+0x2ee4 PP_TFACTOR_1
+0x2ee8 PP_TFACTOR_2
+0x2eec PP_TFACTOR_3
+0x2ef0 PP_TFACTOR_4
+0x2ef4 PP_TFACTOR_5
+0x2ef8 PP_TFACTOR_6
+0x2efc PP_TFACTOR_7
+0x2f00 PP_TXCBLEND_0
+0x2f04 PP_TXCBLEND2_0
+0x2f08 PP_TXABLEND_0
+0x2f0c PP_TXABLEND2_0
+0x2f10 PP_TXCBLEND_1
+0x2f14 PP_TXCBLEND2_1
+0x2f18 PP_TXABLEND_1
+0x2f1c PP_TXABLEND2_1
+0x2f20 PP_TXCBLEND_2
+0x2f24 PP_TXCBLEND2_2
+0x2f28 PP_TXABLEND_2
+0x2f2c PP_TXABLEND2_2
+0x2f30 PP_TXCBLEND_3
+0x2f34 PP_TXCBLEND2_3
+0x2f38 PP_TXABLEND_3
+0x2f3c PP_TXABLEND2_3
+0x2f40 PP_TXCBLEND_4
+0x2f44 PP_TXCBLEND2_4
+0x2f48 PP_TXABLEND_4
+0x2f4c PP_TXABLEND2_4
+0x2f50 PP_TXCBLEND_5
+0x2f54 PP_TXCBLEND2_5
+0x2f58 PP_TXABLEND_5
+0x2f5c PP_TXABLEND2_5
+0x2f60 PP_TXCBLEND_6
+0x2f64 PP_TXCBLEND2_6
+0x2f68 PP_TXABLEND_6
+0x2f6c PP_TXABLEND2_6
+0x2f70 PP_TXCBLEND_7
+0x2f74 PP_TXCBLEND2_7
+0x2f78 PP_TXABLEND_7
+0x2f7c PP_TXABLEND2_7
+0x2f80 PP_TXCBLEND_8
+0x2f84 PP_TXCBLEND2_8
+0x2f88 PP_TXABLEND_8
+0x2f8c PP_TXABLEND2_8
+0x2f90 PP_TXCBLEND_9
+0x2f94 PP_TXCBLEND2_9
+0x2f98 PP_TXABLEND_9
+0x2f9c PP_TXABLEND2_9
+0x2fa0 PP_TXCBLEND_10
+0x2fa4 PP_TXCBLEND2_10
+0x2fa8 PP_TXABLEND_10
+0x2fac PP_TXABLEND2_10
+0x2fb0 PP_TXCBLEND_11
+0x2fb4 PP_TXCBLEND2_11
+0x2fb8 PP_TXABLEND_11
+0x2fbc PP_TXABLEND2_11
+0x2fc0 PP_TXCBLEND_12
+0x2fc4 PP_TXCBLEND2_12
+0x2fc8 PP_TXABLEND_12
+0x2fcc PP_TXABLEND2_12
+0x2fd0 PP_TXCBLEND_13
+0x2fd4 PP_TXCBLEND2_13
+0x2fd8 PP_TXABLEND_13
+0x2fdc PP_TXABLEND2_13
+0x2fe0 PP_TXCBLEND_14
+0x2fe4 PP_TXCBLEND2_14
+0x2fe8 PP_TXABLEND_14
+0x2fec PP_TXABLEND2_14
+0x2ff0 PP_TXCBLEND_15
+0x2ff4 PP_TXCBLEND2_15
+0x2ff8 PP_TXABLEND_15
+0x2ffc PP_TXABLEND2_15
+0x3218 RB3D_BLENCOLOR
+0x321c RB3D_ABLENDCNTL
+0x3220 RB3D_CBLENDCNTL
+0x3290 RB3D_ZPASS_DATA
+
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rn50 b/drivers/gpu/drm/radeon/reg_srcs/rn50
new file mode 100644
index 000000000000..2687b6307260
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rn50
@@ -0,0 +1,30 @@
+rn50 0x3294
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL