summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorJerome Glisse <glisse@freedesktop.org>2008-11-05 15:59:37 +0100
committerJerome Glisse <glisse@freedesktop.org>2008-11-05 15:59:37 +0100
commitddfb12b32e64d00d302f7fbb36fb079deec3646f (patch)
tree5caeade40ef88936a88e47060b6090aa44d38b94 /shared-core
parent7651b4c424aa6c6ac6c47b2d07c8f65d0b9d0191 (diff)
parent68fcb7770efc20b9e27b1724e2fb5ac112a5330e (diff)
Merge branch 'modesetting-gem' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-gem
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/r300_cmdbuf.c3
-rw-r--r--shared-core/r300_reg.h2
-rw-r--r--shared-core/radeon_cp.c121
-rw-r--r--shared-core/radeon_cs.c369
-rw-r--r--shared-core/radeon_drm.h31
-rw-r--r--shared-core/radeon_drv.h67
-rw-r--r--shared-core/radeon_irq.c17
-rw-r--r--shared-core/radeon_mem.c2
-rw-r--r--shared-core/radeon_state.c6
9 files changed, 457 insertions, 161 deletions
diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c
index b15e8928..f39a7afd 100644
--- a/shared-core/r300_cmdbuf.c
+++ b/shared-core/r300_cmdbuf.c
@@ -356,6 +356,9 @@ void r300_init_reg_flags(struct drm_device *dev)
} else {
+ ADD_RANGE(RADEON_SE_COORD_FMT, 1);
+ ADD_RANGE(RADEON_SE_CNTL_STATUS, 1);
+
ADD_RANGE(RADEON_PP_TXFILTER_0, 1);
ADD_RANGE(RADEON_PP_TXFORMAT_0, 1);
ADD_RANGE(RADEON_PP_TEX_SIZE_0, 1);
diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h
index 9e9cb526..1e4631db 100644
--- a/shared-core/r300_reg.h
+++ b/shared-core/r300_reg.h
@@ -1353,7 +1353,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
-#define R300_RB3D_AARESOLVE_CTL 0x4E88
+//#define R300_RB3D_AARESOLVE_CTL 0x4E88
/* gap */
/* Guess by Vladimir.
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 190b1432..9a1e0e02 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -120,7 +120,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *
*agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT);
*agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP);
} else if (dev_priv->chip_family == CHIP_RV515) {
- *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_FB_LOCATION);
+ *agp_lo = radeon_read_mc_reg(dev_priv, RV515_MC_AGP_LOCATION);
*agp_hi = 0;
} else if (dev_priv->chip_family == CHIP_RS600) {
*agp_lo = 0;
@@ -133,7 +133,7 @@ void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *
*agp_lo = radeon_read_mc_reg(dev_priv, R520_MC_AGP_LOCATION);
*agp_hi = 0;
} else {
- *agp_lo = RADEON_READ(RADEON_MC_FB_LOCATION);
+ *agp_lo = RADEON_READ(RADEON_MC_AGP_LOCATION);
*agp_hi = 0;
}
}
@@ -194,6 +194,24 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
}
}
+void radeon_enable_bm(struct drm_radeon_private *dev_priv)
+{
+ u32 tmp;
+ /* Turn on bus mastering */
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
+ /* rs600/rs690/rs740 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
+ /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } /* PCIE cards appears to not need this */
+}
void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv)
{
@@ -573,10 +591,15 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
BEGIN_RING(8);
/* isync can only be written through cp on r5xx write it here */
OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
+ if (dev_priv->chip_family > CHIP_RV280)
+ OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
+ RADEON_ISYNC_ANY3D_IDLE2D |
+ RADEON_ISYNC_WAIT_IDLEGUI |
+ dev_priv->mm_enabled ? 0 : RADEON_ISYNC_CPSCRATCH_IDLEGUI);
+ else
OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
RADEON_ISYNC_ANY3D_IDLE2D |
- RADEON_ISYNC_WAIT_IDLEGUI |
- RADEON_ISYNC_CPSCRATCH_IDLEGUI);
+ RADEON_ISYNC_WAIT_IDLEGUI);
RADEON_PURGE_CACHE();
RADEON_PURGE_ZCACHE();
RADEON_WAIT_UNTIL_IDLE();
@@ -686,7 +709,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
drm_radeon_private_t * dev_priv)
{
u32 ring_start, cur_read_ptr;
- u32 tmp;
/* Initialize the memory controller. With new memory map, the fb location
* is not changed, it should have been properly initialized already. Part
@@ -791,11 +813,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
dev_priv->ring_rptr->handle +
(RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
- RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
+ if (dev_priv->chip_family >= CHIP_R300)
+ RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7f);
+ else
+ RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f);
- /* Turn on bus mastering */
- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
- RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ radeon_enable_bm(dev_priv);
dev_priv->scratch[0] = 0;
RADEON_WRITE(RADEON_LAST_FRAME_REG, 0);
@@ -806,6 +829,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
dev_priv->scratch[2] = 0;
RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
+ dev_priv->scratch[3] = 0;
+ RADEON_WRITE(RADEON_LAST_SWI_REG, 0);
+
+ dev_priv->scratch[4] = 0;
+ RADEON_WRITE(RADEON_SCRATCH_REG4, 0);
+
+ dev_priv->scratch[6] = 0;
+ RADEON_WRITE(RADEON_SCRATCH_REG6, 0);
+
radeon_do_wait_for_idle(dev_priv);
/* Sync everything up */
@@ -825,7 +857,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
{
- u32 tmp;
+ u32 tmp, scratch1_store;
void *ring_read_ptr;
if (dev_priv->mm.ring_read.bo)
@@ -833,6 +865,7 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
else
ring_read_ptr = dev_priv->ring_rptr->handle;
+ scratch1_store = RADEON_READ(RADEON_SCRATCH_REG1);
/* Writeback doesn't seem to work everywhere, test it here and possibly
* enable it if it appears to work
*/
@@ -858,6 +891,9 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
DRM_INFO("writeback forced off\n");
}
+ /* write back previous value */
+ RADEON_WRITE(RADEON_SCRATCH_REG1, scratch1_store);
+
if (!dev_priv->writeback_works) {
/* Disable writeback to avoid unnecessary bus master transfers */
RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE);
@@ -2353,6 +2389,8 @@ int radeon_modeset_cp_resume(struct drm_device *dev)
radeon_do_engine_reset(dev);
+ radeon_test_writeback(dev_priv);
+
radeon_do_cp_start(dev_priv);
return 0;
}
@@ -2434,16 +2472,22 @@ int radeon_modeset_agp_init(struct drm_device *dev)
ret = drm_agp_enable(dev, mode);
if (ret) {
- DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode);
+ DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
return ret;
}
/* workaround some hw issues */
- if (dev_priv->chip_family <= CHIP_R200) {
+ if (dev_priv->chip_family < CHIP_R200) {
RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000);
}
return 0;
}
+
+void radeon_modeset_agp_destroy(struct drm_device *dev)
+{
+ if (dev->agp->acquired)
+ drm_agp_release(dev);
+}
#endif
int radeon_modeset_cp_init(struct drm_device *dev)
@@ -2457,7 +2501,7 @@ int radeon_modeset_cp_init(struct drm_device *dev)
dev_priv->writeback_works = 0;
if (dev_priv->chip_family > CHIP_R600)
- return;
+ return 0;
dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT;
dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE;
@@ -2562,15 +2606,23 @@ int radeon_static_clocks_init(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) {
- radeon_set_dynamic_clock(dev, radeon_dynclks);
- } else if (radeon_is_avivo(dev_priv)) {
- if (radeon_dynclks) {
- radeon_atom_static_pwrmgt_setup(dev, 1);
- radeon_atom_dyn_clk_setup(dev, 1);
+ if (radeon_dynclks != -1) {
+
+ if (dev_priv->chip_family == CHIP_RS400 ||
+ dev_priv->chip_family == CHIP_RS480)
+ radeon_dynclks = 0;
+
+ if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) {
+ radeon_set_dynamic_clock(dev, radeon_dynclks);
+ } else if (radeon_is_avivo(dev_priv)) {
+ if (radeon_dynclks) {
+ radeon_atom_static_pwrmgt_setup(dev, 1);
+ radeon_atom_dyn_clk_setup(dev, 1);
+ }
}
}
- radeon_force_some_clocks(dev);
+ if (radeon_is_r300(dev_priv) || radeon_is_rv100(dev_priv))
+ radeon_force_some_clocks(dev);
return 0;
}
@@ -2617,9 +2669,16 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
DRM_DEBUG("%s card detected\n",
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
- if ((dev_priv->flags & RADEON_IS_AGP) && (radeon_agpmode == -1)) {
- DRM_INFO("Forcing AGP to PCI mode\n");
- dev_priv->flags &= ~RADEON_IS_AGP;
+ if (dev_priv->flags & RADEON_IS_AGP) {
+
+ /* disable AGP for any chips after RV280 if not specified */
+ if ((dev_priv->chip_family > CHIP_RV280) && (radeon_agpmode == 0))
+ radeon_agpmode = -1;
+
+ if (radeon_agpmode == -1) {
+ DRM_INFO("Forcing AGP to PCI mode\n");
+ dev_priv->flags &= ~RADEON_IS_AGP;
+ }
}
@@ -2709,7 +2768,6 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master)
void radeon_master_destroy(struct drm_device *dev, struct drm_master *master)
{
struct drm_radeon_master_private *master_priv = master->driver_priv;
- struct drm_radeon_private *dev_priv = dev->dev_private;
if (!master_priv)
return;
@@ -2731,21 +2789,10 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master)
*/
int radeon_driver_firstopen(struct drm_device *dev)
{
- int ret;
- drm_local_map_t *map;
drm_radeon_private_t *dev_priv = dev->dev_private;
dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
- if (!drm_core_check_feature(dev, DRIVER_MODESET))
- radeon_gem_mm_init(dev);
-
- ret = drm_addmap(dev, dev_priv->fb_aper_offset,
- drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
- _DRM_WRITE_COMBINING, &map);
- if (ret != 0)
- return ret;
-
return 0;
}
@@ -2757,6 +2804,10 @@ int radeon_driver_unload(struct drm_device *dev)
drm_irq_uninstall(dev);
radeon_modeset_cleanup(dev);
radeon_gem_mm_fini(dev);
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP)
+ radeon_modeset_agp_destroy(dev);
+#endif
}
drm_bo_driver_finish(dev);
diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c
index f9147136..3dde321d 100644
--- a/shared-core/radeon_cs.c
+++ b/shared-core/radeon_cs.c
@@ -29,21 +29,165 @@
#include "radeon_drv.h"
#include "r300_reg.h"
+int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
+{
+ struct drm_radeon_cs_parser parser;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct drm_radeon_cs2 *cs = data;
+ uint32_t cs_id;
+ struct drm_radeon_cs_chunk __user **chunk_ptr = NULL;
+ uint64_t *chunk_array;
+ uint64_t *chunk_array_ptr;
+ long size;
+ int r, i;
+
+ /* set command stream id to 0 which is fake id */
+ cs_id = 0;
+ cs->cs_id = cs_id;
+
+ if (dev_priv == NULL) {
+ DRM_ERROR("called with no initialization\n");
+ return -EINVAL;
+ }
+ if (!cs->num_chunks) {
+ return 0;
+ }
+
+
+ chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER);
+ if (!chunk_array) {
+ return -ENOMEM;
+ }
+
+ chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
+
+ if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) {
+ r = -EFAULT;
+ goto out;
+ }
+
+ parser.dev = dev;
+ parser.file_priv = fpriv;
+ parser.reloc_index = -1;
+ parser.ib_index = -1;
+ parser.num_chunks = cs->num_chunks;
+ /* copy out the chunk headers */
+ parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER);
+ if (!parser.chunks) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < parser.num_chunks; i++) {
+ struct drm_radeon_cs_chunk user_chunk;
+
+ chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
+
+ if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){
+ r = -EFAULT;
+ goto out;
+ }
+ parser.chunks[i].chunk_id = user_chunk.chunk_id;
+
+ if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS)
+ parser.reloc_index = i;
+
+ if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB)
+ parser.ib_index = i;
+
+ if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) {
+ parser.ib_index = i;
+ parser.reloc_index = -1;
+ }
+
+ parser.chunks[i].length_dw = user_chunk.length_dw;
+ parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data;
+
+ parser.chunks[i].kdata = NULL;
+ size = parser.chunks[i].length_dw * sizeof(uint32_t);
+
+ switch(parser.chunks[i].chunk_id) {
+ case RADEON_CHUNK_ID_IB:
+ case RADEON_CHUNK_ID_OLD:
+ if (size == 0) {
+ r = -EINVAL;
+ goto out;
+ }
+ case RADEON_CHUNK_ID_RELOCS:
+ if (size) {
+ parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER);
+ if (!parser.chunks[i].kdata) {
+ r = -ENOMEM;
+ goto out;
+ }
+
+ if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) {
+ r = -EFAULT;
+ goto out;
+ }
+ } else
+ parser.chunks[i].kdata = NULL;
+ break;
+ default:
+ break;
+ }
+ DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw,
+ parser.chunks[i].chunk_data);
+ }
+
+
+ if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) {
+ DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw);
+ r = -EINVAL;
+ goto out;
+ }
+
+ /* get ib */
+ r = dev_priv->cs.ib_get(&parser);
+ if (r) {
+ DRM_ERROR("ib_get failed\n");
+ goto out;
+ }
+
+ /* now parse command stream */
+ r = dev_priv->cs.parse(&parser);
+ if (r) {
+ goto out;
+ }
+
+ /* emit cs id sequence */
+ dev_priv->cs.id_emit(&parser, &cs_id);
+
+ cs->cs_id = cs_id;
+
+out:
+ dev_priv->cs.ib_free(&parser);
+
+ for (i = 0; i < parser.num_chunks; i++) {
+ if (parser.chunks[i].kdata)
+ drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER);
+ }
+
+ drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER);
+ drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER);
+
+ return r;
+}
+
int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
{
+ struct drm_radeon_cs_parser parser;
struct drm_radeon_private *dev_priv = dev->dev_private;
struct drm_radeon_cs *cs = data;
uint32_t *packets = NULL;
uint32_t cs_id;
uint32_t card_offset;
- void *ib = NULL;
long size;
int r;
- RING_LOCALS;
+ struct drm_radeon_kernel_chunk chunk_fake[1];
/* set command stream id to 0 which is fake id */
cs_id = 0;
- DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
+ cs->cs_id = cs_id;
if (dev_priv == NULL) {
DRM_ERROR("called with no initialization\n");
@@ -69,68 +213,89 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
r = -EFAULT;
goto out;
}
+
+ chunk_fake[0].chunk_id = RADEON_CHUNK_ID_OLD;
+ chunk_fake[0].length_dw = cs->dwords;
+ chunk_fake[0].kdata = packets;
+
+ parser.dev = dev;
+ parser.file_priv = fpriv;
+ parser.num_chunks = 1;
+ parser.chunks = chunk_fake;
+ parser.ib_index = 0;
+ parser.reloc_index = -1;
+
/* get ib */
- r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset);
+ r = dev_priv->cs.ib_get(&parser);
if (r) {
goto out;
}
/* now parse command stream */
- r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords);
+ r = dev_priv->cs.parse(&parser);
if (r) {
goto out;
}
- BEGIN_RING(4);
- OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
- OUT_RING(card_offset);
- OUT_RING(cs->dwords);
- OUT_RING(CP_PACKET2());
- ADVANCE_RING();
-
/* emit cs id sequence */
- dev_priv->cs.id_emit(dev, &cs_id);
+ dev_priv->cs.id_emit(&parser, &cs_id);
COMMIT_RING();
- DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
+ cs->cs_id = cs_id;
out:
- dev_priv->cs.ib_free(dev, ib, cs->dwords);
+ dev_priv->cs.ib_free(&parser);
drm_free(packets, size, DRM_MEM_DRIVER);
return r;
}
/* for non-mm */
-static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset)
+static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint32_t *offset)
{
*offset = reloc[1];
return 0;
}
#define RELOC_SIZE 2
+#define RELOC_SIZE_NEW 0
#define RADEON_2D_OFFSET_MASK 0x3fffff
-static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv,
- uint32_t *packets, uint32_t offset_dw)
+static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
{
+ struct drm_device *dev = parser->dev;
drm_radeon_private_t *dev_priv = dev->dev_private;
- uint32_t hdr = packets[offset_dw];
- uint32_t reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
- uint32_t val = packets[offset_dw + 1];
- uint32_t packet3_hdr = packets[offset_dw+2];
+ uint32_t hdr, reg, val, packet3_hdr;
uint32_t tmp, offset;
+ struct drm_radeon_kernel_chunk *ib_chunk;
int ret;
+ ib_chunk = &parser->chunks[parser->ib_index];
+// if (parser->reloc_index == -1)
+// is_old = 1;
+
+ hdr = ib_chunk->kdata[offset_dw];
+ reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
+ val = ib_chunk->kdata[offset_dw + 1];
+ packet3_hdr = ib_chunk->kdata[offset_dw + 2];
+
/* this is too strict we may want to expand the length in the future and have
old kernels ignore it. */
- if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
- DRM_ERROR("Packet 3 was %x should have been %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16));
- return -EINVAL;
+ if (parser->reloc_index == -1) {
+ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
+ DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg);
+ return -EINVAL;
+ }
+ } else {
+ if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16))) {
+ DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg);
+ return -EINVAL;
+
+ }
}
switch(reg) {
case RADEON_DST_PITCH_OFFSET:
case RADEON_SRC_PITCH_OFFSET:
/* pass in the start of the reloc */
- ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
+ ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset);
if (ret)
return ret;
tmp = (val & RADEON_2D_OFFSET_MASK) << 10;
@@ -148,7 +313,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
case R200_PP_TXOFFSET_1:
case RADEON_PP_TXOFFSET_0:
case RADEON_PP_TXOFFSET_1:
- ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
+ ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset);
if (ret)
return ret;
@@ -159,25 +324,32 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
break;
}
- packets[offset_dw + 1] = val;
+ ib_chunk->kdata[offset_dw + 1] = val;
return 0;
}
-static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv,
- uint32_t *packets, uint32_t offset_dw)
+static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser,
+ uint32_t offset_dw)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- uint32_t hdr = packets[offset_dw];
- int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
- uint32_t reg = hdr & 0xff00;
+ drm_radeon_private_t *dev_priv = parser->dev->dev_private;
+ uint32_t hdr, num_dw, reg;
uint32_t offset, val, tmp;
int ret;
+ struct drm_radeon_kernel_chunk *ib_chunk;
+
+ ib_chunk = &parser->chunks[parser->ib_index];
+// if (parser->reloc_index == -1)
+// is_old = 1;
+
+ hdr = ib_chunk->kdata[offset_dw];
+ num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
+ reg = hdr & 0xff00;
switch(reg) {
case RADEON_CNTL_HOSTDATA_BLT:
{
- val = packets[offset_dw + 2];
- ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset);
+ val = ib_chunk->kdata[offset_dw + 2];
+ ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + num_dw + 2, &offset);
if (ret)
return ret;
@@ -187,7 +359,7 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f
offset >>= 10;
val |= offset;
- packets[offset_dw + 2] = val;
+ ib_chunk->kdata[offset_dw + 2] = val;
}
default:
return -EINVAL;
@@ -195,41 +367,16 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f
return 0;
}
-static __inline__ int radeon_cs_check_offset(struct drm_device *dev,
- uint32_t reg, uint32_t val)
+int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
{
- uint32_t offset;
-
- switch(reg) {
- case RADEON_DST_PITCH_OFFSET:
- case RADEON_SRC_PITCH_OFFSET:
- offset = val & ((1 << 22) - 1);
- offset <<= 10;
- break;
- case R300_RB3D_COLOROFFSET0:
- case R300_ZB_DEPTHOFFSET:
- offset = val;
- break;
- case R300_TX_OFFSET_0:
- case R300_TX_OFFSET_0+4:
- offset = val & 0xffffffe0;
- break;
- }
-
- return 0;
-}
-
-int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
- uint32_t *packets, uint32_t offset_dw)
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- uint32_t hdr = packets[offset_dw];
- int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
- int need_reloc = 0;
- int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
+ uint32_t hdr, num_dw, reg;
int count_dw = 1;
int ret;
+ hdr = parser->chunks[parser->ib_index].kdata[offset_dw];
+ num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
+ reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
+
while (count_dw < num_dw) {
/* need to have something like the r300 validation here -
list of allowed registers */
@@ -250,7 +397,7 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
return -EINVAL;
}
- ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw);
+ ret = radeon_cs_relocate_packet0(parser, offset_dw);
if (ret)
return ret;
DRM_DEBUG("need to relocate %x %d\n", reg, flags);
@@ -269,24 +416,25 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
return 0;
}
-int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
- void *ib, uint32_t *packets, uint32_t dwords)
+int radeon_cs_parse(struct drm_radeon_cs_parser *parser)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
volatile int rb;
- int size_dw = dwords;
+ struct drm_radeon_kernel_chunk *ib_chunk;
/* scan the packet for various things */
- int count_dw = 0;
+ int count_dw = 0, size_dw;
int ret = 0;
+ ib_chunk = &parser->chunks[parser->ib_index];
+ size_dw = ib_chunk->length_dw;
+
while (count_dw < size_dw && ret == 0) {
- int hdr = packets[count_dw];
+ int hdr = ib_chunk->kdata[count_dw];
int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
int reg;
switch (hdr & RADEON_CP_PACKET_MASK) {
case RADEON_CP_PACKET0:
- ret = radeon_cs_packet0(dev, file_priv, packets, count_dw);
+ ret = radeon_cs_packet0(parser, count_dw);
break;
case RADEON_CP_PACKET1:
case RADEON_CP_PACKET2:
@@ -299,7 +447,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
switch(reg) {
case RADEON_CNTL_HOSTDATA_BLT:
- radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw);
+ radeon_cs_relocate_packet3(parser, count_dw);
break;
case RADEON_CNTL_BITBLT_MULTI:
@@ -308,6 +456,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
DRM_ERROR("need relocate packet 3 for %x\n", reg);
break;
+ case RADEON_3D_DRAW_IMMD: /* triggers drawing using in-packet vertex data */
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
@@ -329,10 +478,10 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
/* copy the packet into the IB */
- memcpy(ib, packets, dwords * sizeof(uint32_t));
+ memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t));
/* read back last byte to flush WC buffers */
- rb = readl((ib + (dwords-1) * sizeof(uint32_t)));
+ rb = readl((parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t)));
return 0;
}
@@ -351,51 +500,89 @@ uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon)
return (radeon->cs.id_scnt | radeon->cs.id_wcnt);
}
-void r100_cs_id_emit(struct drm_device *dev, uint32_t *id)
+void r100_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_private_t *dev_priv = parser->dev->dev_private;
RING_LOCALS;
+ dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev);
/* ISYNC_CNTL should have CPSCRACTH bit set */
*id = radeon_cs_id_get(dev_priv);
/* emit id in SCRATCH4 (not used yet in old drm) */
- BEGIN_RING(2);
+ BEGIN_RING(10);
+ OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
+ OUT_RING(parser->card_offset);
+ OUT_RING(parser->chunks[parser->ib_index].length_dw);
+ OUT_RING(CP_PACKET2());
OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG4, 0));
OUT_RING(*id);
+ OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted);
+ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
ADVANCE_RING();
+ COMMIT_RING();
+
}
-void r300_cs_id_emit(struct drm_device *dev, uint32_t *id)
+void r300_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_private_t *dev_priv = parser->dev->dev_private;
+ int i;
RING_LOCALS;
+ dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev);
+
/* ISYNC_CNTL should not have CPSCRACTH bit set */
*id = radeon_cs_id_get(dev_priv);
+
/* emit id in SCRATCH6 */
- BEGIN_RING(8);
- OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 0));
+ BEGIN_RING(16);
+ OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
+ OUT_RING(parser->card_offset);
+ OUT_RING(parser->chunks[parser->ib_index].length_dw);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(0);
+ for (i = 0; i < 11; i++) /* emit fillers like fglrx */
+ OUT_RING(CP_PACKET2());
+ ADVANCE_RING();
+ COMMIT_RING();
+
+ BEGIN_RING(16);
+ OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH);
+ OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
OUT_RING(6);
- OUT_RING(CP_PACKET0(R300_CP_RESYNC_DATA, 0));
OUT_RING(*id);
- OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
- OUT_RING(R300_RB3D_DC_FINISH);
+ OUT_RING_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FINISH|R300_RB3D_DC_FLUSH);
+ /* emit inline breadcrumb for TTM fencing */
+#if 1
RADEON_WAIT_UNTIL_3D_IDLE();
+ OUT_RING_REG(RADEON_LAST_SWI_REG, dev_priv->irq_emitted);
+#else
+ OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
+ OUT_RING(3); /* breadcrumb register */
+ OUT_RING(dev_priv->irq_emitted);
+ OUT_RING(CP_PACKET2());
+#endif
+ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
+ OUT_RING(CP_PACKET2());
+ OUT_RING(CP_PACKET2());
+ OUT_RING(CP_PACKET2());
ADVANCE_RING();
+ COMMIT_RING();
+
}
uint32_t r100_cs_id_last_get(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- return RADEON_READ(RADEON_SCRATCH_REG4);
+ return GET_SCRATCH(4);
}
uint32_t r300_cs_id_last_get(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- return RADEON_READ(RADEON_SCRATCH_REG6);
+ return GET_SCRATCH(6);
}
int radeon_cs_init(struct drm_device *dev)
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index c924c689..002e4004 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -511,9 +511,10 @@ typedef struct {
#define DRM_RADEON_GEM_PREAD 0x21
#define DRM_RADEON_GEM_PWRITE 0x22
#define DRM_RADEON_GEM_SET_DOMAIN 0x23
-#define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server
+#define DRM_RADEON_GEM_WAIT_RENDERING 0x24
#define DRM_RADEON_CS 0x25
+#define DRM_RADEON_CS2 0x26
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -551,9 +552,9 @@ typedef struct {
#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
-#define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect)
-
+#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering)
#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
+#define DRM_IOCTL_RADEON_CS2 DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS2, struct drm_radeon_cs2)
typedef struct drm_radeon_init {
@@ -820,7 +821,8 @@ struct drm_radeon_gem_set_domain {
uint32_t write_domain;
};
-struct drm_radeon_gem_exec_buffer {
+struct drm_radeon_gem_wait_rendering {
+ uint32_t handle;
};
struct drm_radeon_gem_pin {
@@ -864,21 +866,32 @@ struct drm_radeon_gem_pwrite {
uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
};
-struct drm_radeon_gem_indirect {
- uint32_t handle;
- uint32_t used;
-};
/* New interface which obsolete all previous interface.
*/
struct drm_radeon_cs {
-// uint32_t __user *packets;
uint32_t dwords;
uint32_t cs_id;
uint64_t packets;
+};
+
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB 0x02
+#define RADEON_CHUNK_ID_OLD 0xff
+
+struct drm_radeon_cs_chunk {
+ uint32_t chunk_id;
+ uint32_t length_dw;
+ uint64_t chunk_data;
+};
+struct drm_radeon_cs2 {
+ uint32_t num_chunks;
+ uint32_t cs_id;
+ uint64_t chunks; /* this points to uint64_t * which point to
+ cs chunks */
};
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index a6ce129d..a95ab152 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -124,6 +124,7 @@ enum radeon_family {
CHIP_RV350,
CHIP_RV380,
CHIP_R420,
+ CHIP_R423,
CHIP_RV410,
CHIP_RS400,
CHIP_RS480,
@@ -294,6 +295,24 @@ struct drm_radeon_master_private {
#define RADEON_FLUSH_EMITED (1 < 0)
#define RADEON_PURGE_EMITED (1 < 1)
+struct drm_radeon_kernel_chunk {
+ uint32_t chunk_id;
+ uint32_t length_dw;
+ uint32_t __user *chunk_data;
+ uint32_t *kdata;
+};
+
+struct drm_radeon_cs_parser {
+ struct drm_device *dev;
+ struct drm_file *file_priv;
+ uint32_t num_chunks;
+ struct drm_radeon_kernel_chunk *chunks;
+ int ib_index;
+ int reloc_index;
+ uint32_t card_offset;
+ void *ib;
+};
+
/* command submission struct */
struct drm_radeon_cs_priv {
uint32_t id_wcnt;
@@ -301,21 +320,22 @@ struct drm_radeon_cs_priv {
uint32_t id_last_wcnt;
uint32_t id_last_scnt;
- int (*parse)(struct drm_device *dev, struct drm_file *file_priv,
- void *ib, uint32_t *packets, uint32_t dwords);
- void (*id_emit)(struct drm_device *dev, uint32_t *id);
+ int (*parse)(struct drm_radeon_cs_parser *parser);
+ void (*id_emit)(struct drm_radeon_cs_parser *parser, uint32_t *id);
uint32_t (*id_last_get)(struct drm_device *dev);
/* this ib handling callback are for hidding memory manager drm
* from memory manager less drm, free have to emit ib discard
* sequence into the ring */
- int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset);
+ int (*ib_get)(struct drm_radeon_cs_parser *parser);
uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib);
- void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords);
+ void (*ib_free)(struct drm_radeon_cs_parser *parser);
/* do a relocation either MM or non-MM */
- int (*relocate)(struct drm_device *dev, struct drm_file *file_priv,
- uint32_t *reloc, uint32_t *offset);
+ int (*relocate)(struct drm_radeon_cs_parser *parser,
+ uint32_t *reloc, uint32_t *offset);
};
+
+
struct radeon_pm_regs {
uint32_t crtc_ext_cntl;
uint32_t bios_scratch[8];
@@ -441,6 +461,11 @@ typedef struct drm_radeon_private {
struct drm_radeon_cs_priv cs;
struct radeon_pm_regs pmregs;
+ int irq_emitted;
+ atomic_t irq_received;
+
+ uint32_t aper_size;
+ int vram_mtrr;
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -460,6 +485,7 @@ extern int radeon_r4xx_atom;
extern struct drm_ioctl_desc radeon_ioctls[];
extern int radeon_max_ioctl;
extern int radeon_agpmode;
+extern int radeon_modeset;
/* Check whether the given hardware address is inside the framebuffer or the
* GART area.
@@ -572,7 +598,11 @@ int radeon_resume(struct drm_device *dev);
# define RADEON_SCISSOR_2_ENABLE (1 << 30)
#define RADEON_BUS_CNTL 0x0030
+/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
# define RADEON_BUS_MASTER_DIS (1 << 6)
+/* rs600/rs690/rs740 */
+# define RS600_BUS_MASTER_DIS (1 << 14)
+# define RS600_MSI_REARM (1 << 20)
#define RADEON_CLOCK_CNTL_DATA 0x000c
# define RADEON_PLL_WR_EN (1 << 7)
@@ -732,11 +762,11 @@ int radeon_resume(struct drm_device *dev);
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
-#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \
- (dev_priv->mm.ring_read.bo ? \
- readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \
- DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \
- RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x)))
+#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \
+ (dev_priv->mm.ring_read.bo ? \
+ readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(x)) : \
+ DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \
+ RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x)))
#define RADEON_CRTC_CRNT_FRAME 0x0214
#define RADEON_CRTC2_CRNT_FRAME 0x0314
@@ -1034,6 +1064,7 @@ int radeon_resume(struct drm_device *dev);
#define RADEON_AIC_CNTL 0x01d0
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
+# define RS400_MSI_REARM (1 << 3)
#define RADEON_AIC_STAT 0x01d4
#define RADEON_AIC_PT_BASE 0x01d8
#define RADEON_AIC_LO_ADDR 0x01dc
@@ -1606,7 +1637,7 @@ extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo);
#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
/* Breadcrumb - swi irq */
-#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG)
+#define READ_BREADCRUMB(dev_priv) GET_SCRATCH(3)
static inline int radeon_update_breadcrumb(struct drm_device *dev)
{
@@ -1643,6 +1674,7 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev)
(dev_priv->chip_family == CHIP_R350) || \
(dev_priv->chip_family == CHIP_RV380) || \
(dev_priv->chip_family == CHIP_R420) || \
+ (dev_priv->chip_family == CHIP_R423) || \
(dev_priv->chip_family == CHIP_RV410) || \
(dev_priv->chip_family == CHIP_RS400) || \
(dev_priv->chip_family == CHIP_RS480))
@@ -1668,10 +1700,10 @@ extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
int radeon_gem_object_pin(struct drm_gem_object *obj,
uint32_t alignment, uint32_t pin_domain);
int radeon_gem_object_unpin(struct drm_gem_object *obj);
-int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int radeon_gem_wait_rendering(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment,
int initial_domain, bool discardable);
int radeon_modeset_init(struct drm_device *dev);
@@ -1687,11 +1719,14 @@ extern int radeon_master_create(struct drm_device *dev, struct drm_master *maste
extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master);
extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master);
extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
+extern int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
extern int radeon_cs_init(struct drm_device *dev);
void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master);
void radeon_init_memory_map(struct drm_device *dev);
+void radeon_enable_bm(struct drm_radeon_private *dev_priv);
-
+extern int radeon_gem_proc_init(struct drm_minor *minor);
+extern void radeon_gem_proc_cleanup(struct drm_minor *minor);
#define MARK_SAFE 1
#define MARK_CHECK_OFFSET 2
#define MARK_CHECK_SCISSOR 3
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index dcf58e43..46a27943 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -195,6 +195,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
if (!stat)
return IRQ_NONE;
+ atomic_inc(&dev_priv->irq_received);
stat &= dev_priv->irq_enable_reg;
/* SW interrupt */
@@ -222,15 +223,19 @@ int radeon_emit_irq(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
unsigned int ret;
+ int i;
RING_LOCALS;
- ret = radeon_update_breadcrumb(dev);
+ if (!dev_priv->irq_emitted) {
+ ret = radeon_update_breadcrumb(dev);
- BEGIN_RING(4);
- OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
- OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
- ADVANCE_RING();
- COMMIT_RING();
+ BEGIN_RING(4);
+ OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
+ OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
+ ADVANCE_RING();
+ COMMIT_RING();
+ } else
+ ret = dev_priv->irq_emitted;
return ret;
}
diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c
index dbd73c50..2622cf3c 100644
--- a/shared-core/radeon_mem.c
+++ b/shared-core/radeon_mem.c
@@ -294,7 +294,7 @@ int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *fi
return -EFAULT;
if (*heap) {
- DRM_ERROR("heap already initialized?");
+ DRM_DEBUG("heap already initialized?");
return -EFAULT;
}
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 7262b2aa..e0a00f02 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -1884,10 +1884,11 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
OUT_RING((image->width << 16) | height);
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
- COMMIT_RING();
radeon_cp_discard_buffer(dev, file_priv->master, buf);
+ COMMIT_RING();
+
/* Update the input parameters for next time */
image->y += height;
image->height -= height;
@@ -3288,8 +3289,9 @@ struct drm_ioctl_desc radeon_ioctls[] = {
DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_RENDERING, radeon_gem_wait_rendering, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH),
};
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);