summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2008-07-26 08:56:23 +1000
committerDave Airlie <airlied@linux.ie>2008-07-26 08:56:23 +1000
commitdf9871064e8b564d9ae2e56d561b64434fd004af (patch)
tree828b84ad7b50d78815ba53c0d833217ac0580e2b /shared-core
parent31da9492a4129f5255e949836c51e9dfbfb270c4 (diff)
radeon: add initial atombios modesetting and GEM -> TTM translation layer.
This is an initial import of the atom bios parser with modesetting support for r500 hw using atombios. It also includes a simple memory manager layer that translates a radeon GEM style interface onto TTM internally. So far this memory manager has only been used for pinned object allocation for the DDX to test modesetting.
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h2
-rw-r--r--shared-core/r300_cmdbuf.c11
-rw-r--r--shared-core/radeon_cp.c992
-rw-r--r--shared-core/radeon_drm.h117
-rw-r--r--shared-core/radeon_drv.h298
-rw-r--r--shared-core/radeon_irq.c14
-rw-r--r--shared-core/radeon_state.c203
7 files changed, 1369 insertions, 268 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 900bffc1..7aba2939 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -236,7 +236,7 @@ enum drm_map_type {
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
_DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
- _DRM_TTM = 6
+ _DRM_TTM = 6,
};
/**
diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c
index bff6378f..e8f18dbc 100644
--- a/shared-core/r300_cmdbuf.c
+++ b/shared-core/r300_cmdbuf.c
@@ -732,12 +732,12 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
* The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
* be careful about how this function is called.
*/
-static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
+static void r300_discard_buffer(struct drm_device * dev, struct drm_master *master, struct drm_buf * buf)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
- buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
+ buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
buf->pending = 1;
buf->used = 0;
}
@@ -898,6 +898,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
drm_radeon_kcmd_buffer_t *cmdbuf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
struct drm_device_dma *dma = dev->dma;
struct drm_buf *buf = NULL;
int emit_dispatch_age = 0;
@@ -1005,7 +1006,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
}
emit_dispatch_age = 1;
- r300_discard_buffer(dev, buf);
+ r300_discard_buffer(dev, file_priv->master, buf);
break;
case R300_CMD_WAIT:
@@ -1060,7 +1061,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
/* Emit the vertex buffer age */
BEGIN_RING(2);
- RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
+ RADEON_DISPATCH_AGE(master_priv->sarea_priv->last_dispatch);
ADVANCE_RING();
}
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 819a61ae..80951e91 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -31,6 +31,7 @@
#include "drmP.h"
#include "drm.h"
+#include "drm_sarea.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
#include "r300_reg.h"
@@ -75,6 +76,23 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
return RS480_READ_MCIND(dev_priv, addr);
}
+u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ return IGP_READ_MCIND(dev_priv, addr);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515)
+ return R500_READ_MCIND(dev_priv, addr);
+ return 0;
+}
+
+void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ IGP_WRITE_MCIND(addr, val);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515)
+ R500_WRITE_MCIND(addr, val);
+}
+
u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{
@@ -133,12 +151,57 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
}
}
-static int RADEON_READ_PLL(struct drm_device * dev, int addr)
+
+void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv)
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
+ if (!(dev_priv->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS))
+ return;
+
+ (void)RADEON_READ(RADEON_CLOCK_CNTL_DATA);
+ (void)RADEON_READ(RADEON_CRTC_GEN_CNTL);
+}
+
+void radeon_pll_errata_after_data(struct drm_radeon_private *dev_priv)
+{
+ /* This workarounds is necessary on RV100, RS100 and RS200 chips
+ * or the chip could hang on a subsequent access
+ */
+ if (dev_priv->pll_errata & CHIP_ERRATA_PLL_DELAY)
+ udelay(5000);
+
+ /* This function is required to workaround a hardware bug in some (all?)
+ * revisions of the R300. This workaround should be called after every
+ * CLOCK_CNTL_INDEX register access. If not, register reads afterward
+ * may not be correct.
+ */
+ if (dev_priv->pll_errata & CHIP_ERRATA_R300_CG) {
+ uint32_t save, tmp;
+
+ save = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
+ tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, tmp);
+ tmp = RADEON_READ(RADEON_CLOCK_CNTL_DATA);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, save);
+ }
+}
+
+int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr)
+{
+ uint32_t data;
- RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
- return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
+ RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
+ radeon_pll_errata_after_index(dev_priv);
+ data = RADEON_READ(RADEON_CLOCK_CNTL_DATA);
+ radeon_pll_errata_after_data(dev_priv);
+ return data;
+}
+
+void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data)
+{
+ RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, ((addr & 0x3f) | RADEON_PLL_WR_EN));
+ radeon_pll_errata_after_index(dev_priv);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, data);
+ radeon_pll_errata_after_data(dev_priv);
}
static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
@@ -147,6 +210,39 @@ static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
return RADEON_READ(RADEON_PCIE_DATA);
}
+/* ATOM accessor methods */
+static uint32_t cail_mc_read(struct card_info *info, uint32_t reg)
+{
+ uint32_t ret = radeon_read_mc_reg(info->dev->dev_private, reg);
+
+ // DRM_DEBUG("(%x) = %x\n", reg, ret);
+ return ret;
+}
+
+static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val)
+{
+ // DRM_DEBUG("(%x, %x)\n", reg, val);
+ radeon_write_mc_reg(info->dev->dev_private, reg, val);
+}
+
+static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val)
+{
+ drm_radeon_private_t *dev_priv = info->dev->dev_private;
+
+ // DRM_DEBUG("(%x, %x)\n", reg*4, val);
+ RADEON_WRITE(reg*4, val);
+}
+
+static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
+{
+ uint32_t ret;
+ drm_radeon_private_t *dev_priv = info->dev->dev_private;
+
+ ret = RADEON_READ(reg*4);
+ // DRM_DEBUG("(%x) = %x\n", reg*4, ret);
+ return ret;
+}
+
#if RADEON_FIFO_DEBUG
static void radeon_status(drm_radeon_private_t * dev_priv)
{
@@ -298,7 +394,7 @@ static void radeon_init_pipes(drm_radeon_private_t * dev_priv)
}
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
- RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+ RADEON_WRITE_PLL(dev_priv, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
}
RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
@@ -491,15 +587,15 @@ static int radeon_do_engine_reset(struct drm_device * dev)
if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
/* may need something similar for newer chips */
clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
- mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
-
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
- RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC |
- RADEON_FORCEON_AIC));
+ mclk_cntl = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL);
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, (mclk_cntl |
+ RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB |
+ RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC |
+ RADEON_FORCEON_AIC));
}
rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
@@ -524,7 +620,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
RADEON_READ(RADEON_RBBM_SOFT_RESET);
if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
+ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, mclk_cntl);
RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
}
@@ -540,7 +636,8 @@ static int radeon_do_engine_reset(struct drm_device * dev)
dev_priv->cp_running = 0;
/* Reset any pending vertex, indirect buffers */
- radeon_freelist_reset(dev);
+ if (dev->dma)
+ radeon_freelist_reset(dev);
return 0;
}
@@ -558,9 +655,13 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
*/
if (!dev_priv->new_memmap)
radeon_write_fb_location(dev_priv,
- ((dev_priv->gart_vm_start - 1) & 0xffff0000)
- | (dev_priv->fb_location >> 16));
-
+ ((dev_priv->gart_vm_start - 1) & 0xffff0000)
+ | (dev_priv->fb_location >> 16));
+
+ if (dev_priv->mm.ring) {
+ ring_start = dev_priv->mm.ring->offset +
+ dev_priv->gart_vm_start;
+ } else
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
radeon_write_agp_base(dev_priv, dev->agp->base);
@@ -590,6 +691,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
SET_RING_HEAD(dev_priv, cur_read_ptr);
dev_priv->ring.tail = cur_read_ptr;
+
+ if (dev_priv->mm.ring_read_ptr) {
+ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
+ dev_priv->mm.ring_read_ptr->offset +
+ dev_priv->gart_vm_start);
+ } else
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
@@ -638,9 +745,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
+ RADEON_SCRATCH_REG_OFFSET);
- dev_priv->scratch = ((__volatile__ u32 *)
- dev_priv->ring_rptr->handle +
- (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
+ if (dev_priv->mm.ring_read_ptr)
+ dev_priv->scratch = ((__volatile__ u32 *)
+ dev_priv->mm.ring_read_ptr_map.virtual +
+ (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
+ else
+ dev_priv->scratch = ((__volatile__ u32 *)
+ dev_priv->ring_rptr->handle +
+ (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
@@ -648,15 +760,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
RADEON_WRITE(RADEON_BUS_CNTL, tmp);
- dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
- RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
+ dev_priv->scratch[0] = 0;
+ RADEON_WRITE(RADEON_LAST_FRAME_REG, 0);
- dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
- RADEON_WRITE(RADEON_LAST_DISPATCH_REG,
- dev_priv->sarea_priv->last_dispatch);
+ dev_priv->scratch[1] = 0;
+ RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0);
- dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
- RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
+ dev_priv->scratch[2] = 0;
+ RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
radeon_do_wait_for_idle(dev_priv);
@@ -672,15 +783,21 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
{
u32 tmp;
+ void *ring_read_ptr;
+
+ if (dev_priv->mm.ring_read_ptr)
+ ring_read_ptr = dev_priv->mm.ring_read_ptr_map.virtual;
+ else
+ ring_read_ptr = dev_priv->ring_rptr->handle;
/* Writeback doesn't seem to work everywhere, test it here and possibly
* enable it if it appears to work
*/
- DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
+ writel(0, ring_read_ptr + RADEON_SCRATCHOFF(1));
RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
- if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
+ if (readl(ring_read_ptr + RADEON_SCRATCHOFF(1)) ==
0xdeadbeef)
break;
DRM_UDELAY(1);
@@ -813,7 +930,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
}
/* Enable or disable PCI GART on the chip */
-static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
+void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
@@ -854,9 +971,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
}
}
-static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
DRM_DEBUG("\n");
@@ -897,17 +1016,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
*/
dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
- switch(init->func) {
- case RADEON_INIT_R200_CP:
- dev_priv->microcode_version = UCODE_R200;
- break;
- case RADEON_INIT_R300_CP:
- dev_priv->microcode_version = UCODE_R300;
- break;
- default:
- dev_priv->microcode_version = UCODE_R100;
- }
-
dev_priv->do_boxes = 0;
dev_priv->cp_mode = init->cp_mode;
@@ -955,9 +1063,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
*/
dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
(dev_priv->color_fmt << 10) |
- (dev_priv->microcode_version ==
- UCODE_R100 ? RADEON_ZBLOCK16 : 0));
-
+ (dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0));
+
dev_priv->depth_clear.rb3d_zstencilcntl =
(dev_priv->depth_fmt |
RADEON_Z_TEST_ALWAYS |
@@ -984,8 +1091,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
dev_priv->buffers_offset = init->buffers_offset;
dev_priv->gart_textures_offset = init->gart_textures_offset;
- dev_priv->sarea = drm_getsarea(dev);
- if (!dev_priv->sarea) {
+ master_priv->sarea = drm_getsarea(dev);
+ if (!master_priv->sarea) {
DRM_ERROR("could not find sarea!\n");
radeon_do_cleanup_cp(dev);
return -EINVAL;
@@ -1021,10 +1128,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
}
}
- dev_priv->sarea_priv =
- (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
- init->sarea_priv_offset);
-
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
drm_core_ioremap(dev_priv->cp_ring, dev);
@@ -1155,28 +1258,41 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
/* if we have an offset set from userspace */
if (dev_priv->pcigart_offset_set) {
- dev_priv->gart_info.bus_addr =
- dev_priv->pcigart_offset + dev_priv->fb_location;
- dev_priv->gart_info.mapping.offset =
- dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
- dev_priv->gart_info.mapping.size =
- dev_priv->gart_info.table_size;
-
- drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
- dev_priv->gart_info.addr =
- dev_priv->gart_info.mapping.handle;
-
- if (dev_priv->flags & RADEON_IS_PCIE)
- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
- else
- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
- dev_priv->gart_info.gart_table_location =
- DRM_ATI_GART_FB;
- DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
- dev_priv->gart_info.addr,
- dev_priv->pcigart_offset);
+ /* if it came from userspace - remap it */
+ if (dev_priv->pcigart_offset_set == 1) {
+ dev_priv->gart_info.bus_addr =
+ dev_priv->pcigart_offset + dev_priv->fb_location;
+ dev_priv->gart_info.mapping.offset =
+ dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
+ dev_priv->gart_info.mapping.size =
+ dev_priv->gart_info.table_size;
+
+ /* this is done by the mm now */
+ drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
+ dev_priv->gart_info.addr =
+ dev_priv->gart_info.mapping.handle;
+
+ memset(dev_priv->gart_info.addr, 0, dev_priv->gart_info.table_size);
+ if (dev_priv->flags & RADEON_IS_PCIE)
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
+ else
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
+ dev_priv->gart_info.gart_table_location =
+ DRM_ATI_GART_FB;
+
+ DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
+ dev_priv->gart_info.addr,
+ dev_priv->pcigart_offset);
+ }
} else {
+
+ if (dev_priv->flags & RADEON_IS_PCIE) {
+ DRM_ERROR
+ ("Cannot use PCI Express without GART in FB memory\n");
+ radeon_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
if (dev_priv->flags & RADEON_IS_IGPGART)
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
else
@@ -1185,12 +1301,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
DRM_ATI_GART_MAIN;
dev_priv->gart_info.addr = NULL;
dev_priv->gart_info.bus_addr = 0;
- if (dev_priv->flags & RADEON_IS_PCIE) {
- DRM_ERROR
- ("Cannot use PCI Express without GART in FB memory\n");
- radeon_do_cleanup_cp(dev);
- return -EINVAL;
- }
+
}
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
@@ -1253,8 +1364,10 @@ static int radeon_do_cleanup_cp(struct drm_device * dev)
if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
{
- drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
- dev_priv->gart_info.addr = 0;
+ if (dev_priv->pcigart_offset_set == 1) {
+ drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
+ dev_priv->gart_info.addr = NULL;
+ }
}
}
/* only clear to the start of flags */
@@ -1305,6 +1418,10 @@ static int radeon_do_resume_cp(struct drm_device * dev)
int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_init_t *init = data;
+
+ /* on a modesetting driver ignore this stuff */
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1315,7 +1432,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
case RADEON_INIT_CP:
case RADEON_INIT_R200_CP:
case RADEON_INIT_R300_CP:
- return radeon_do_init_cp(dev, init);
+ return radeon_do_init_cp(dev, init, file_priv);
case RADEON_CLEANUP_CP:
return radeon_do_cleanup_cp(dev);
}
@@ -1328,6 +1445,9 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (dev_priv->cp_running) {
@@ -1355,6 +1475,9 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
int ret;
DRM_DEBUG("\n");
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv->cp_running)
@@ -1393,6 +1516,9 @@ void radeon_do_release(struct drm_device * dev)
drm_radeon_private_t *dev_priv = dev->dev_private;
int i, ret;
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
if (dev_priv) {
if (dev_priv->cp_running) {
/* Stop the cp */
@@ -1431,6 +1557,9 @@ void radeon_do_release(struct drm_device * dev)
radeon_mem_takedown(&(dev_priv->gart_heap));
radeon_mem_takedown(&(dev_priv->fb_heap));
+
+ radeon_gem_mm_fini(dev);
+
/* deallocate kernel resources */
radeon_do_cleanup_cp(dev);
}
@@ -1443,6 +1572,9 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
@@ -1463,7 +1595,9 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
- LOCK_TEST_WITH_RETURN(dev, file_priv);
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
return radeon_do_cp_idle(dev_priv);
}
@@ -1473,6 +1607,9 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
return radeon_do_resume_cp(dev);
}
@@ -1480,6 +1617,9 @@ int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *fil
{
DRM_DEBUG("\n");
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
LOCK_TEST_WITH_RETURN(dev, file_priv);
return radeon_do_engine_reset(dev);
@@ -1702,6 +1842,541 @@ int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_
return ret;
}
+static void radeon_get_vram_type(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ if (dev_priv->flags & RADEON_IS_IGP || (dev_priv->chip_family >= CHIP_R300))
+ dev_priv->is_ddr = true;
+ else if (RADEON_READ(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR)
+ dev_priv->is_ddr = true;
+ else
+ dev_priv->is_ddr = false;
+
+ if ((dev_priv->chip_family >= CHIP_R600) &&
+ (dev_priv->chip_family <= CHIP_RV635)) {
+ int chansize;
+
+ tmp = RADEON_READ(R600_RAMCFG);
+ if (tmp & R600_CHANSIZE_OVERRIDE)
+ chansize = 16;
+ else if (tmp & R600_CHANSIZE)
+ chansize = 64;
+ else
+ chansize = 32;
+
+ if (dev_priv->chip_family == CHIP_R600)
+ dev_priv->ram_width = 8 * chansize;
+ else if (dev_priv->chip_family == CHIP_RV670)
+ dev_priv->ram_width = 4 * chansize;
+ else if ((dev_priv->chip_family == CHIP_RV610) ||
+ (dev_priv->chip_family == CHIP_RV620))
+ dev_priv->ram_width = chansize;
+ else if ((dev_priv->chip_family == CHIP_RV630) ||
+ (dev_priv->chip_family == CHIP_RV635))
+ dev_priv->ram_width = 2 * chansize;
+ } else if (dev_priv->chip_family == CHIP_RV515) {
+ tmp = radeon_read_mc_reg(dev_priv, RV515_MC_CNTL);
+ tmp &= RV515_MEM_NUM_CHANNELS_MASK;
+ switch (tmp) {
+ case 0: dev_priv->ram_width = 64; break;
+ case 1: dev_priv->ram_width = 128; break;
+ default: dev_priv->ram_width = 128; break;
+ }
+ } else if ((dev_priv->chip_family >= CHIP_R520) &&
+ (dev_priv->chip_family <= CHIP_RV570)) {
+ tmp = radeon_read_mc_reg(dev_priv, R520_MC_CNTL0);
+ switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) {
+ case 0: dev_priv->ram_width = 32; break;
+ case 1: dev_priv->ram_width = 64; break;
+ case 2: dev_priv->ram_width = 128; break;
+ case 3: dev_priv->ram_width = 256; break;
+ default: dev_priv->ram_width = 128; break;
+ }
+ } else if ((dev_priv->chip_family == CHIP_RV100) ||
+ (dev_priv->chip_family == CHIP_RS100) ||
+ (dev_priv->chip_family == CHIP_RS200)) {
+ tmp = RADEON_READ(RADEON_MEM_CNTL);
+ if (tmp & RV100_HALF_MODE)
+ dev_priv->ram_width = 32;
+ else
+ dev_priv->ram_width = 64;
+
+ if (dev_priv->flags & RADEON_SINGLE_CRTC) {
+ dev_priv->ram_width /= 4;
+ dev_priv->is_ddr = true;
+ }
+ } else if (dev_priv->chip_family <= CHIP_RV280) {
+ tmp = RADEON_READ(RADEON_MEM_CNTL);
+ if (tmp & RADEON_MEM_NUM_CHANNELS_MASK)
+ dev_priv->ram_width = 128;
+ else
+ dev_priv->ram_width = 64;
+ } else {
+ /* newer IGPs */
+ dev_priv->ram_width = 128;
+ }
+ DRM_DEBUG("RAM width %d bits %cDR\n", dev_priv->ram_width, dev_priv->is_ddr ? 'D' : 'S');
+}
+
+static void radeon_force_some_clocks(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+}
+
+static void radeon_set_dynamic_clock(struct drm_device *dev, int mode)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t tmp;
+
+ switch(mode) {
+ case 0:
+ if (dev_priv->flags & RADEON_SINGLE_CRTC) {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
+ RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP |
+ RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
+ RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
+ RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
+ RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
+ RADEON_SCLK_FORCE_RB);
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+ } else if (dev_priv->chip_family == CHIP_RV350) {
+ /* for RV350/M10, no delays are required. */
+ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2);
+ tmp |= (R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
+ RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
+ R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
+ R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
+ R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
+ R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
+ tmp |= RADEON_DYN_STOP_LAT_MASK;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL);
+ tmp &= ~RADEON_SCLK_MORE_FORCEON;
+ tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL);
+ tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL);
+ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
+ R300_DVOCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ R300_PIXCLK_DVO_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb |
+ R300_PIXCLK_TRANS_ALWAYS_ONb |
+ R300_PIXCLK_TVO_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb);
+ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp);
+ } else {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
+ tmp |= RADEON_SCLK_FORCE_SE;
+
+ if ( dev_priv->flags & RADEON_SINGLE_CRTC ) {
+ tmp |= ( RADEON_SCLK_FORCE_RB |
+ RADEON_SCLK_FORCE_TDM |
+ RADEON_SCLK_FORCE_TAM |
+ RADEON_SCLK_FORCE_PB |
+ RADEON_SCLK_FORCE_RE |
+ RADEON_SCLK_FORCE_VIP |
+ RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_TOP |
+ RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_DISP2 |
+ RADEON_SCLK_FORCE_HDP );
+ } else if ((dev_priv->chip_family == CHIP_R300) ||
+ (dev_priv->chip_family == CHIP_R350)) {
+ tmp |= ( RADEON_SCLK_FORCE_HDP |
+ RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_DISP2 |
+ RADEON_SCLK_FORCE_TOP |
+ RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_VIP);
+ }
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+
+ udelay(16000);
+
+ if ((dev_priv->chip_family == CHIP_R300) ||
+ (dev_priv->chip_family == CHIP_R350)) {
+ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2);
+ tmp |= ( R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp);
+ udelay(16000);
+ }
+
+ if (dev_priv->flags & RADEON_IS_IGP) {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL);
+ tmp &= ~(RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_YCLKA);
+ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp);
+ udelay(16000);
+ }
+
+ if ((dev_priv->chip_family == CHIP_RV200) ||
+ (dev_priv->chip_family == CHIP_RV250) ||
+ (dev_priv->chip_family == CHIP_RV280)) {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL);
+ tmp |= RADEON_SCLK_MORE_FORCEON;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp);
+ udelay(16000);
+ }
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL);
+ tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb);
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp);
+ udelay(16000);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL);
+ tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp);
+ }
+ DRM_DEBUG("Dynamic Clock Scaling Disabled\n");
+ break;
+ case 1:
+ if (dev_priv->flags & RADEON_SINGLE_CRTC) {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ if ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) >
+ RADEON_CFG_ATI_REV_A13) {
+ tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB);
+ }
+ tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
+ RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
+ RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
+ RADEON_SCLK_FORCE_TDM);
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+ } else if ((dev_priv->chip_family == CHIP_R300) ||
+ (dev_priv->chip_family == CHIP_R350) ||
+ (dev_priv->chip_family == CHIP_RV350)) {
+ if (dev_priv->chip_family == CHIP_RV350) {
+ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2);
+ tmp &= ~(R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
+ R300_SCLK_GA_MAX_DYN_STOP_LAT |
+ R300_SCLK_CBA_MAX_DYN_STOP_LAT);
+ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
+ RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
+ R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
+ R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
+ R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
+ R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
+ tmp |= RADEON_DYN_STOP_LAT_MASK;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL);
+ tmp &= ~RADEON_SCLK_MORE_FORCEON;
+ tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL);
+ tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL);
+ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
+ R300_DVOCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ R300_PIXCLK_DVO_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb |
+ R300_PIXCLK_TRANS_ALWAYS_ONb |
+ R300_PIXCLK_TVO_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb);
+ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_MISC);
+ tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
+ RADEON_IO_MCLK_DYN_ENABLE);
+ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_MISC, tmp);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL);
+ tmp |= (RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB);
+
+ tmp &= ~(RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC);
+
+ /* Some releases of vbios have set DISABLE_MC_MCLKA
+ and DISABLE_MC_MCLKB bits in the vbios table. Setting these
+ bits will cause H/W hang when reading video memory with dynamic clocking
+ enabled. */
+ if ((tmp & R300_DISABLE_MC_MCLKA) &&
+ (tmp & R300_DISABLE_MC_MCLKB)) {
+ /* If both bits are set, then check the active channels */
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL);
+ if (dev_priv->ram_width == 64) {
+ if (RADEON_READ(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY)
+ tmp &= ~R300_DISABLE_MC_MCLKB;
+ else
+ tmp &= ~R300_DISABLE_MC_MCLKA;
+ } else {
+ tmp &= ~(R300_DISABLE_MC_MCLKA |
+ R300_DISABLE_MC_MCLKB);
+ }
+ }
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp);
+ } else {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ tmp &= ~(R300_SCLK_FORCE_VAP);
+ tmp |= RADEON_SCLK_FORCE_CP;
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+ udelay(15000);
+
+ tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2);
+ tmp &= ~(R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp);
+ }
+ } else {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL);
+ tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
+ RADEON_DISP_DYN_STOP_LAT_MASK |
+ RADEON_DYN_STOP_MODE_MASK);
+
+ tmp |= (RADEON_ENGIN_DYNCLK_MODE |
+ (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
+ RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL, tmp);
+ udelay(15000);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PIN_CNTL);
+ tmp |= RADEON_SCLK_DYN_START_CNTL;
+ RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PIN_CNTL, tmp);
+ udelay(15000);
+
+ /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
+ to lockup randomly, leave them as set by BIOS.
+ */
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL);
+ /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/
+ tmp &= ~RADEON_SCLK_FORCEON_MASK;
+
+ /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
+ if (((dev_priv->chip_family == CHIP_RV250) &&
+ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
+ RADEON_CFG_ATI_REV_A13)) ||
+ ((dev_priv->chip_family == CHIP_RV100) &&
+ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <=
+ RADEON_CFG_ATI_REV_A13))){
+ tmp |= RADEON_SCLK_FORCE_CP;
+ tmp |= RADEON_SCLK_FORCE_VIP;
+ }
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp);
+
+ if ((dev_priv->chip_family == CHIP_RV200) ||
+ (dev_priv->chip_family == CHIP_RV250) ||
+ (dev_priv->chip_family == CHIP_RV280)) {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL);
+ tmp &= ~RADEON_SCLK_MORE_FORCEON;
+
+ /* RV200::A11 A12 RV250::A11 A12 */
+ if (((dev_priv->chip_family == CHIP_RV200) ||
+ (dev_priv->chip_family == CHIP_RV250)) &&
+ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
+ RADEON_CFG_ATI_REV_A13)) {
+ tmp |= RADEON_SCLK_MORE_FORCEON;
+ }
+ RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp);
+ udelay(15000);
+ }
+
+ /* RV200::A11 A12, RV250::A11 A12 */
+ if (((dev_priv->chip_family == CHIP_RV200) ||
+ (dev_priv->chip_family == CHIP_RV250)) &&
+ ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
+ RADEON_CFG_ATI_REV_A13)) {
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL);
+ tmp |= RADEON_TCL_BYPASS_DISABLE;
+ RADEON_WRITE_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL, tmp);
+ }
+ udelay(15000);
+
+ /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL);
+ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb);
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp);
+ udelay(15000);
+
+ tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL);
+ tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+
+ RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp);
+ udelay(15000);
+ }
+ DRM_DEBUG("Dynamic Clock Scaling Enabled\n");
+ break;
+ default:
+ break;
+ }
+
+}
+
+int radeon_modeset_cp_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ /* allocate a ring and ring rptr bits from GART space */
+ /* these are allocated in GEM files */
+
+ dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT;
+ dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE;
+ dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM;
+
+ dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual;
+ dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual +
+ dev_priv->ring.size / sizeof(u32);
+ dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8);
+ dev_priv->ring.rptr_update = 4096;
+ dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8);
+ dev_priv->ring.fetch_size = 32;
+ dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16);
+ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
+ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+
+ dev_priv->new_memmap = 1;
+
+ radeon_cp_load_microcode(dev_priv);
+
+ DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring->offset, dev_priv->mm.ring_read_ptr->offset);
+
+ radeon_cp_init_ring_buffer(dev, dev_priv);
+
+ radeon_do_engine_reset(dev);
+ radeon_test_writeback(dev_priv);
+
+ radeon_do_cp_start(dev_priv);
+ return 0;
+}
+
+static bool radeon_get_bios(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u8 __iomem *bios;
+ size_t size;
+ uint16_t tmp;
+
+ bios = pci_map_rom(dev->pdev, &size);
+ if (!bios)
+ return -1;
+
+ dev_priv->bios = kmalloc(size, GFP_KERNEL);
+ if (!dev_priv->bios) {
+ pci_unmap_rom(dev->pdev, bios);
+ return -1;
+ }
+
+ memcpy(dev_priv->bios, bios, size);
+
+ pci_unmap_rom(dev->pdev, bios);
+
+ if (dev_priv->bios[0] != 0x55 || dev_priv->bios[1] != 0xaa)
+ goto free_bios;
+
+ dev_priv->bios_header_start = radeon_bios16(dev_priv, 0x48);
+
+ if (!dev_priv->bios_header_start)
+ goto free_bios;
+
+ tmp = dev_priv->bios_header_start + 4;
+
+ if (!memcmp(dev_priv->bios + tmp, "ATOM", 4) ||
+ !memcmp(dev_priv->bios + tmp, "MOTA", 4))
+ dev_priv->is_atom_bios = true;
+ else
+ dev_priv->is_atom_bios = false;
+
+ DRM_DEBUG("%sBIOS detected\n", dev_priv->is_atom_bios ? "ATOM" : "COM");
+ return true;
+free_bios:
+ kfree(dev_priv->bios);
+ dev_priv->bios = NULL;
+ return false;
+}
+
+int radeon_modeset_preinit(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ static struct card_info card;
+ int ret;
+
+ card.dev = dev;
+ card.reg_read = cail_reg_read;
+ card.reg_write = cail_reg_write;
+ card.mc_read = cail_mc_read;
+ card.mc_write = cail_mc_write;
+
+ ret = radeon_get_bios(dev);
+ if (!ret)
+ return -1;
+
+ if (dev_priv->is_atom_bios) {
+ dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios);
+ radeon_get_clock_info(dev);
+ }
+ return 0;
+}
+
+
int radeon_driver_load(struct drm_device *dev, unsigned long flags)
{
drm_radeon_private_t *dev_priv;
@@ -1734,6 +2409,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
break;
}
+ dev_priv->chip_family = flags & RADEON_FAMILY_MASK;
if (drm_device_is_agp(dev))
dev_priv->flags |= RADEON_IS_AGP;
else if (drm_device_is_pcie(dev))
@@ -1741,11 +2417,122 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
else
dev_priv->flags |= RADEON_IS_PCI;
+
+
DRM_DEBUG("%s card detected\n",
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
+
+ ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
+ drm_get_resource_len(dev, 2), _DRM_REGISTERS,
+ _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio);
+ if (ret != 0)
+ return ret;
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ radeon_modeset_preinit(dev);
+
+
+ radeon_get_vram_type(dev);
+
+ dev_priv->pll_errata = 0;
+
+ if (dev_priv->chip_family == CHIP_R300 &&
+ (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11)
+ dev_priv->pll_errata |= CHIP_ERRATA_R300_CG;
+
+ if (dev_priv->chip_family == CHIP_RV200 ||
+ dev_priv->chip_family == CHIP_RS200)
+ dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS;
+
+
+ if (dev_priv->chip_family == CHIP_RV100 ||
+ dev_priv->chip_family == CHIP_RS100 ||
+ dev_priv->chip_family == CHIP_RS200)
+ dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY;
+
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ 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);
+ }
+
+ /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */
+ dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
+
+ drm_bo_driver_init(dev);
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
+ dev_priv->fb_size =
+ ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
+ - dev_priv->fb_location;
+ radeon_gem_mm_init(dev);
+ radeon_modeset_init(dev);
+
+ radeon_modeset_cp_init(dev);
+ dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL);
+
+ drm_irq_install(dev);
+ }
+
+
return ret;
}
+
+int radeon_master_create(struct drm_device *dev, struct drm_master *master)
+{
+ struct drm_radeon_master_private *master_priv;
+ unsigned long sareapage;
+ int ret;
+
+ master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER);
+ if (!master_priv)
+ return -ENOMEM;
+
+ /* prebuild the SAREA */
+ sareapage = max(SAREA_MAX, PAGE_SIZE);
+ ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER,
+ &master_priv->sarea);
+ if (ret) {
+ DRM_ERROR("SAREA setup failed\n");
+ return ret;
+ }
+ master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea);
+ master_priv->sarea_priv->pfCurrentPage = 0;
+
+ master->driver_priv = master_priv;
+ return 0;
+}
+
+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;
+
+ if (master_priv->sarea_priv &&
+ master_priv->sarea_priv->pfCurrentPage != 0)
+ radeon_cp_dispatch_flip(dev, master);
+
+ master_priv->sarea_priv = NULL;
+ if (master_priv->sarea)
+ drm_rmmap(dev, master_priv->sarea);
+
+ drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER);
+
+ master->driver_priv = NULL;
+}
/* Create mappings for registers and framebuffer so userland doesn't necessarily
* have to find them.
*/
@@ -1757,13 +2544,9 @@ int radeon_driver_firstopen(struct drm_device *dev)
dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
- ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
- drm_get_resource_len(dev, 2), _DRM_REGISTERS,
- _DRM_READ_ONLY, &dev_priv->mmio);
- if (ret != 0)
- return ret;
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ radeon_gem_mm_init(dev);
- dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
ret = drm_addmap(dev, dev_priv->fb_aper_offset,
drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
_DRM_WRITE_COMBINING, &map);
@@ -1777,9 +2560,40 @@ int radeon_driver_unload(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ drm_irq_uninstall(dev);
+ radeon_modeset_cleanup(dev);
+ radeon_gem_mm_fini(dev);
+ }
+
+ drm_bo_driver_finish(dev);
+ drm_rmmap(dev, dev_priv->mmio);
+
DRM_DEBUG("\n");
drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
dev->dev_private = NULL;
return 0;
}
+
+void radeon_gart_flush(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (dev_priv->flags & RADEON_IS_IGPGART) {
+ IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
+ IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE);
+ IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
+ IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0);
+ } else if (dev_priv->flags & RADEON_IS_PCIE) {
+ u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
+ tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB;
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
+ tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB;
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
+ } else {
+
+
+ }
+
+}
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index 81944061..7fcf9305 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -457,12 +457,6 @@ typedef struct {
unsigned int last_fence;
} drm_radeon_sarea_t;
-/* The only fence class we support */
-#define DRM_RADEON_FENCE_CLASS_ACCEL 0
-/* Fence type that guarantees read-write flush */
-#define DRM_RADEON_FENCE_TYPE_RW 2
-/* cache flushes programmed just before the fence */
-#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmRadeon.h)
@@ -502,6 +496,17 @@ typedef struct {
#define DRM_RADEON_SURF_ALLOC 0x1a
#define DRM_RADEON_SURF_FREE 0x1b
+#define DRM_RADEON_GEM_INFO 0x1c
+#define DRM_RADEON_GEM_CREATE 0x1d
+#define DRM_RADEON_GEM_MMAP 0x1e
+#define DRM_RADEON_GEM_PIN 0x1f
+#define DRM_RADEON_GEM_UNPIN 0x20
+#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_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)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
@@ -530,6 +535,18 @@ typedef struct {
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
+#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
+#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
+#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
+#define DRM_IOCTL_RADEON_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin)
+#define DRM_IOCTL_RADEON_GEM_UNPIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin)
+#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)
+
+
+
typedef struct drm_radeon_init {
enum {
RADEON_INIT_CP = 0x01,
@@ -756,4 +773,92 @@ typedef struct drm_radeon_surface_free {
#define DRM_RADEON_VBLANK_CRTC1 1
#define DRM_RADEON_VBLANK_CRTC2 2
+#define RADEON_GEM_DOMAIN_CPU 0x1
+#define RADEON_GEM_DOMAIN_VRAM 0x2
+#define RADEON_GEM_DOMAIN_2D 0x4
+#define RADEON_GEM_DOMAIN_3D 0x8
+#define RADEON_GEM_DOMAIN_TEXTURE 0x10
+#define RADEON_GEM_DOMAIN_GPU 0x20 // for vertex buffers
+
+/* return to userspace start/size of gtt and vram apertures */
+struct drm_radeon_gem_info {
+ uint64_t gart_start;
+ uint64_t gart_size;
+ uint64_t vram_start;
+ uint64_t vram_size;
+ uint64_t vram_visible;
+};
+
+struct drm_radeon_gem_create {
+ uint64_t size;
+ uint64_t alignment;
+ uint32_t handle;
+ uint32_t initial_domain; // to allow VRAM to be created
+ uint32_t no_backing_store; // for VRAM objects - select whether they need backing store
+ // pretty much front/back/depth don't need it - other things do
+};
+
+struct drm_radeon_gem_mmap {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t addr_ptr;
+};
+
+struct drm_radeon_gem_set_domain {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+};
+
+struct drm_radeon_gem_exec_buffer {
+};
+
+struct drm_radeon_gem_pin {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t alignment;
+ uint64_t offset;
+};
+
+struct drm_radeon_gem_unpin {
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_radeon_gem_busy {
+ uint32_t handle;
+ uint32_t busy;
+};
+
+struct drm_radeon_gem_pread {
+ /** Handle for the object being read. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to read from */
+ uint64_t offset;
+ /** Length of data to read */
+ uint64_t size;
+ /** Pointer to write the data into. */
+ uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
+};
+
+struct drm_radeon_gem_pwrite {
+ /** Handle for the object being written to. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to write to */
+ uint64_t offset;
+ /** Length of data to write */
+ uint64_t size;
+ /** Pointer to read the data from. */
+ uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
+};
+
+struct drm_radeon_gem_indirect {
+ uint32_t handle;
+ uint32_t used;
+};
+
#endif
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index e263c610..b8f49404 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -31,6 +31,7 @@
#ifndef __RADEON_DRV_H__
#define __RADEON_DRV_H__
+#include "atom.h"
/* General customization:
*/
@@ -96,13 +97,13 @@
* 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
* new packet type)
* 1.26- Add support for variable size PCI(E) gart aperture
- * 1.27- Add support for IGP GART
+ * 1.27- Add support for IGPGART
* 1.28- Add support for VBL on CRTC2
* 1.29- R500 3D cmd buffer support
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 29
+#define DRIVER_MINOR 30
#define DRIVER_PATCHLEVEL 0
/*
@@ -124,23 +125,29 @@ enum radeon_family {
CHIP_RV380,
CHIP_R420,
CHIP_RV410,
+ CHIP_RS400,
CHIP_RS480,
+ CHIP_RS600,
CHIP_RS690,
+ CHIP_RS740,
CHIP_RV515,
CHIP_R520,
CHIP_RV530,
CHIP_RV560,
CHIP_RV570,
CHIP_R580,
+ CHIP_R600,
+ CHIP_R630,
+ CHIP_RV610,
+ CHIP_RV630,
+ CHIP_RV670,
+ CHIP_RV620,
+ CHIP_RV635,
+ CHIP_RS780,
+ CHIP_RV770,
CHIP_LAST,
};
-enum radeon_cp_microcode_version {
- UCODE_R100,
- UCODE_R200,
- UCODE_R300,
-};
-
/*
* Chip flags
*/
@@ -158,9 +165,42 @@ enum radeon_chip_flags {
RADEON_IS_IGPGART = 0x01000000UL,
};
+/*
+ * Errata workarounds
+ */
+enum radeon_pll_errata {
+ CHIP_ERRATA_R300_CG = 0x00000001,
+ CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002,
+ CHIP_ERRATA_PLL_DELAY = 0x00000004
+};
+
+enum radeon_ext_tmds_chip {
+ RADEON_DVOCHIP_NONE,
+ RADEON_SIL_164,
+ RADEON_SIL_1178
+};
+
+#if defined(__powerpc__)
+enum radeon_mac_model {
+ RADEON_MAC_NONE,
+ RADEON_MAC_IBOOK,
+ RADEON_MAC_POWERBOOK_EXTERNAL,
+ RADEON_MAC_POWERBOOK_INTERNAL,
+ RADEON_MAC_POWERBOOK_VGA,
+ RADEON_MAC_MINI_EXTERNAL,
+ RADEON_MAC_MINI_INTERNAL,
+ RADEON_MAC_IMAC_G5_ISIGHT
+};
+#endif
+
+
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
- DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
-#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
+ (dev_priv->mm.ring_read_ptr ? readl(dev_priv->mm.ring_read_ptr_map.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \
+ RADEON_READ(RADEON_CP_RB_RPTR))
+
+#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read_ptr ? \
+ writel((val), dev_priv->mm.ring_read_ptr_map.virtual) : \
+ DRM_WRITE32((dev_priv)->ring_rptr, 0, (val)))
typedef struct drm_radeon_freelist {
unsigned int age;
@@ -221,13 +261,35 @@ struct radeon_virt_surface {
struct drm_file *file_priv;
};
+struct radeon_mm_info {
+ uint64_t vram_offset; // Offset into GPU space
+ uint64_t vram_size;
+ uint64_t vram_visible;
+
+ uint64_t gart_start;
+ uint64_t gart_size;
+
+ struct drm_buffer_object *pcie_table;
+ struct drm_bo_kmap_obj pcie_table_map;
+
+ struct drm_buffer_object *ring;
+ struct drm_bo_kmap_obj ring_map;
+
+ struct drm_buffer_object *ring_read_ptr;
+ struct drm_bo_kmap_obj ring_read_ptr_map;
+};
+
+#include "radeon_mode.h"
+
+struct drm_radeon_master_private {
+ drm_local_map_t *sarea;
+ drm_radeon_sarea_t *sarea_priv;
+};
+
typedef struct drm_radeon_private {
drm_radeon_ring_buffer_t ring;
- drm_radeon_sarea_t *sarea_priv;
- u32 fb_location;
- u32 fb_size;
int new_memmap;
int gart_size;
@@ -245,8 +307,6 @@ typedef struct drm_radeon_private {
int usec_timeout;
- int microcode_version;
-
struct {
u32 boxes;
int freelist_timeouts;
@@ -282,8 +342,6 @@ typedef struct drm_radeon_private {
unsigned long buffers_offset;
unsigned long gart_textures_offset;
- drm_local_map_t *sarea;
- drm_local_map_t *mmio;
drm_local_map_t *cp_ring;
drm_local_map_t *ring_rptr;
drm_local_map_t *gart_textures;
@@ -292,8 +350,8 @@ typedef struct drm_radeon_private {
struct mem_block *fb_heap;
/* SW interrupt */
+ int counter;
wait_queue_head_t swi_queue;
- atomic_t swi_emitted;
int vblank_crtc;
uint32_t irq_enable_reg;
int irq_enabled;
@@ -302,9 +360,6 @@ typedef struct drm_radeon_private {
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
- unsigned long pcigart_offset;
- unsigned int pcigart_offset_set;
- struct drm_ati_pcigart_info gart_info;
u32 scratch_ages[5];
@@ -316,6 +371,28 @@ typedef struct drm_radeon_private {
unsigned long fb_aper_offset;
int num_gb_pipes;
+
+ struct radeon_mm_info mm;
+ drm_local_map_t *mmio;
+
+ uint32_t chip_family;
+
+ unsigned long pcigart_offset;
+ unsigned int pcigart_offset_set;
+ struct drm_ati_pcigart_info gart_info;
+
+ struct radeon_mode_info mode_info;
+
+ uint8_t *bios; /* copy of the BIOS image */
+ bool is_atom_bios;
+ uint16_t bios_header_start;
+ u32 fb_location;
+ u32 fb_size;
+ bool is_ddr;
+ u32 ram_width;
+
+ enum radeon_pll_errata pll_errata;
+
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -330,6 +407,7 @@ typedef struct drm_radeon_kcmd_buffer {
} drm_radeon_kcmd_buffer_t;
extern int radeon_no_wb;
+extern int radeon_dynclks;
extern struct drm_ioctl_desc radeon_ioctls[];
extern int radeon_max_ioctl;
@@ -417,9 +495,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_BOX_WAIT_IDLE 0x8
#define RADEON_BOX_TEXTURE_LOAD 0x10
+#define R600_CONFIG_MEMSIZE 0x5428
+#define R600_CONFIG_APER_SIZE 0x5430
/* Register definitions, register access macros and drmAddMap constants
* for Radeon kernel driver.
*/
+
+#include "radeon_reg.h"
+
#define RADEON_AGP_COMMAND 0x0f60
#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
# define RADEON_AGP_ENABLE (1<<8)
@@ -522,16 +605,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define R520_MC_IND_WR_EN (1 << 24)
#define R520_MC_IND_DATA 0x74
-#define RV515_MC_FB_LOCATION 0x01
-#define RV515_MC_AGP_LOCATION 0x02
-#define RV515_MC_AGP_BASE 0x03
-#define RV515_MC_AGP_BASE_2 0x04
-
-#define R520_MC_FB_LOCATION 0x04
-#define R520_MC_AGP_LOCATION 0x05
-#define R520_MC_AGP_BASE 0x06
-#define R520_MC_AGP_BASE_2 0x07
-
#define RADEON_MPP_TB_CONFIG 0x01c0
#define RADEON_MEM_CNTL 0x0140
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
@@ -601,9 +674,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
-#define GET_SCRATCH( x ) (dev_priv->writeback_works \
- ? 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_ptr ? \
+ readl(dev_priv->mm.ring_read_ptr_map.virtual + RADEON_SCRATCHOFF(0)) : \
+ 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
@@ -628,11 +703,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
# define RADEON_SW_INT_FIRE (1 << 26)
# define R500_DISPLAY_INT_STATUS (1 << 0)
+#define RADEON_HOST_PATH_CNTL 0x0130
+# define RADEON_HDP_SOFT_RESET (1 << 26)
+# define RADEON_HDP_APER_CNTL (1 << 23)
-#define RADEON_HOST_PATH_CNTL 0x0130
-# define RADEON_HDP_SOFT_RESET (1 << 26)
-# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
-# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28)
+#define RADEON_NB_TOM 0x15c
#define RADEON_ISYNC_CNTL 0x1724
# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
@@ -703,11 +778,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
# define R300_ZC_FREE (1 << 1)
# define R300_ZC_FLUSH_ALL 0x3
# define R300_ZC_BUSY (1 << 31)
-#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
-# define RADEON_RB3D_DC_FLUSH (3 << 0)
-# define RADEON_RB3D_DC_FREE (3 << 2)
-# define RADEON_RB3D_DC_FLUSH_ALL 0xf
-# define RADEON_RB3D_DC_BUSY (1 << 31)
#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
# define R300_RB3D_DC_FINISH (1 << 4)
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
@@ -981,27 +1051,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_NUM_VERTICES_SHIFT 16
#define RADEON_COLOR_FORMAT_CI8 2
-#define RADEON_COLOR_FORMAT_ARGB1555 3
-#define RADEON_COLOR_FORMAT_RGB565 4
-#define RADEON_COLOR_FORMAT_ARGB8888 6
-#define RADEON_COLOR_FORMAT_RGB332 7
-#define RADEON_COLOR_FORMAT_RGB8 9
-#define RADEON_COLOR_FORMAT_ARGB4444 15
-
-#define RADEON_TXFORMAT_I8 0
-#define RADEON_TXFORMAT_AI88 1
-#define RADEON_TXFORMAT_RGB332 2
-#define RADEON_TXFORMAT_ARGB1555 3
-#define RADEON_TXFORMAT_RGB565 4
-#define RADEON_TXFORMAT_ARGB4444 5
-#define RADEON_TXFORMAT_ARGB8888 6
-#define RADEON_TXFORMAT_RGBA8888 7
-#define RADEON_TXFORMAT_Y8 8
-#define RADEON_TXFORMAT_VYUY422 10
-#define RADEON_TXFORMAT_YVYU422 11
-#define RADEON_TXFORMAT_DXT1 12
-#define RADEON_TXFORMAT_DXT23 14
-#define RADEON_TXFORMAT_DXT45 15
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_1 0x2f10
@@ -1187,18 +1236,16 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_RING_HIGH_MARK 128
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
+#define RADEON_DEFAULT_RING_SIZE (1024*1024)
+#define RADEON_DEFAULT_CP_TIMEOUT 100000 /* usecs */
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
-#define RADEON_WRITE_PLL( addr, val ) \
-do { \
- RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \
- ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \
- RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
-} while (0)
+extern int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr);
+extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data);
#define RADEON_WRITE_PCIE( addr, val ) \
do { \
@@ -1311,7 +1358,7 @@ do { \
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
} else { \
- OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( CP_PACKET0( R300_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( R300_ZC_FLUSH_ALL ); \
} \
} while (0)
@@ -1333,7 +1380,8 @@ do { \
#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
do { \
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \
if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
int __ret = radeon_do_cp_idle( dev_priv ); \
if ( __ret ) return __ret; \
@@ -1439,4 +1487,110 @@ do { \
write &= mask; \
} while (0)
+/* radeon GEM->TTM munger */
+struct drm_radeon_gem_object {
+ /* wrap a TTM bo */
+ struct drm_buffer_object *bo;
+ struct drm_fence_object *fence;
+ struct drm_gem_object *obj;
+
+};
+
+extern int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+extern int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+extern int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+extern int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int radeon_gem_pread_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+extern void radeon_fence_handler(struct drm_device *dev);
+extern int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class,
+ uint32_t flags, uint32_t *sequence,
+ uint32_t *native_type);
+extern void radeon_poke_flush(struct drm_device *dev, uint32_t class);
+extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags);
+
+/* radeon_buffer.c */
+extern struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device *dev);
+extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type);
+extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
+extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
+ struct drm_mem_type_manager * man);
+extern int radeon_move(struct drm_buffer_object * bo,
+ int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
+
+extern void radeon_gart_flush(struct drm_device *dev);
+extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo);
+
+#define BREADCRUMB_BITS 31
+#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
+
+/* Breadcrumb - swi irq */
+#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG)
+
+static inline int radeon_update_breadcrumb(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv;
+
+ ++dev_priv->counter;
+ if (dev_priv->counter > BREADCRUMB_MASK)
+ dev_priv->counter = 1;
+
+ if (dev->primary->master) {
+ master_priv = dev->primary->master->driver_priv;
+
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->last_fence = dev_priv->counter;
+ }
+ return dev_priv->counter;
+}
+
+#define radeon_is_avivo(dev_priv) ((dev_priv->chip_family >= CHIP_RS600))
+
+#define radeon_is_dce3(dev_priv) ((dev_priv->chip_family >= CHIP_RV620))
+
+#define radeon_bios8(dev_priv, v) (dev_priv->bios[v])
+#define radeon_bios16(dev_priv, v) (dev_priv->bios[v] | (dev_priv->bios[(v) + 1] << 8))
+#define radeon_bios32(dev_priv, v) ((dev_priv->bios[v]) | \
+ (dev_priv->bios[(v) + 1] << 8) | \
+ (dev_priv->bios[(v) + 2] << 16) | \
+ (dev_priv->bios[(v) + 3] << 24))
+
+extern int radeon_emit_irq(struct drm_device * dev);
+
+extern void radeon_gem_free_object(struct drm_gem_object *obj);
+extern int radeon_gem_init_object(struct drm_gem_object *obj);
+extern int radeon_gem_mm_init(struct drm_device *dev);
+extern void radeon_gem_mm_fini(struct drm_device *dev);
+extern int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int radeon_gem_object_pin(struct drm_gem_object *obj,
+ uint32_t alignment);
+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);
+struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment,
+ int initial_domain);
+int radeon_modeset_init(struct drm_device *dev);
+void radeon_modeset_cleanup(struct drm_device *dev);
+extern u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr);
+extern void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val);
+
+extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on);
+#define RADEONFB_CONN_LIMIT 4
+
+extern int radeon_master_create(struct drm_device *dev, struct drm_master *master);
+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);
#endif /* __RADEON_DRV_H__ */
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index d21761fb..f5f7f75d 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -198,8 +198,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
stat &= dev_priv->irq_enable_reg;
/* SW interrupt */
- if (stat & RADEON_SW_INT_TEST)
+ if (stat & RADEON_SW_INT_TEST) {
DRM_WAKEUP(&dev_priv->swi_queue);
+ radeon_fence_handler(dev);
+ }
/* VBLANK interrupt */
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
@@ -216,14 +218,13 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_HANDLED;
}
-static int radeon_emit_irq(struct drm_device * dev)
+int radeon_emit_irq(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
unsigned int ret;
RING_LOCALS;
- atomic_inc(&dev_priv->swi_emitted);
- ret = atomic_read(&dev_priv->swi_emitted);
+ ret = radeon_update_breadcrumb(dev);
BEGIN_RING(4);
OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
@@ -240,13 +241,13 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
(drm_radeon_private_t *) dev->dev_private;
int ret = 0;
- if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
+ if (READ_BREADCRUMB(dev_priv) >= swi_nr)
return 0;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
- RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
+ READ_BREADCRUMB(dev_priv) >= swi_nr);
return ret;
}
@@ -349,7 +350,6 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
(drm_radeon_private_t *) dev->dev_private;
int ret;
- atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
ret = drm_vblank_init(dev, 2);
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 1d550a9f..6de4b135 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -305,8 +305,9 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
case RADEON_CP_3D_DRAW_INDX_2:
case RADEON_3D_CLEAR_HIZ:
/* safe but r200 only */
- if (dev_priv->microcode_version != UCODE_R200) {
- DRM_ERROR("Invalid 3d packet for r100-class chip\n");
+ if ((dev_priv->chip_family < CHIP_R200) ||
+ (dev_priv->chip_family > CHIP_RV280)) {
+ DRM_ERROR("Invalid 3d packet for non r200-class chip\n");
return -EINVAL;
}
break;
@@ -359,8 +360,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
break;
case RADEON_3D_RNDR_GEN_INDX_PRIM:
- if (dev_priv->microcode_version != UCODE_R100) {
- DRM_ERROR("Invalid 3d packet for r200-class chip\n");
+ if (dev_priv->chip_family > CHIP_RS200) {
+ DRM_ERROR("Invalid 3d packet for non-r100-class chip\n");
return -EINVAL;
}
if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) {
@@ -370,8 +371,10 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
break;
case RADEON_CP_INDX_BUFFER:
- if (dev_priv->microcode_version != UCODE_R200) {
- DRM_ERROR("Invalid 3d packet for r100-class chip\n");
+ /* safe but r200 only */
+ if ((dev_priv->chip_family < CHIP_R200) ||
+ (dev_priv->chip_family > CHIP_RV280)) {
+ DRM_ERROR("Invalid 3d packet for non-r200-class chip\n");
return -EINVAL;
}
if ((cmd[1] & 0x8000ffff) != 0x80000810) {
@@ -742,13 +745,14 @@ static struct {
*/
static void radeon_clear_box(drm_radeon_private_t * dev_priv,
+ struct drm_radeon_master_private *master_priv,
int x, int y, int w, int h, int r, int g, int b)
{
u32 color;
RING_LOCALS;
- x += dev_priv->sarea_priv->boxes[0].x1;
- y += dev_priv->sarea_priv->boxes[0].y1;
+ x += master_priv->sarea_priv->boxes[0].x1;
+ y += master_priv->sarea_priv->boxes[0].y1;
switch (dev_priv->color_fmt) {
case RADEON_COLOR_FORMAT_RGB565:
@@ -776,7 +780,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
RADEON_GMC_SRC_DATATYPE_COLOR |
RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
- if (dev_priv->sarea_priv->pfCurrentPage == 1) {
+ if (master_priv->sarea_priv->pfCurrentPage == 1) {
OUT_RING(dev_priv->front_pitch_offset);
} else {
OUT_RING(dev_priv->back_pitch_offset);
@@ -790,7 +794,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
ADVANCE_RING();
}
-static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
+static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv, struct drm_radeon_master_private *master_priv)
{
/* Collapse various things into a wait flag -- trying to
* guess if userspase slept -- better just to have them tell us.
@@ -807,12 +811,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
/* Purple box for page flipping
*/
if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
- radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
+ radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255);
/* Red box if we have to wait for idle at any point
*/
if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
- radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
+ radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0);
/* Blue box: lost context?
*/
@@ -820,12 +824,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
/* Yellow box for texture swaps
*/
if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
- radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
+ radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0);
/* Green box if hardware never idles (as far as we can tell)
*/
if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
- radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
+ radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0);
/* Draw bars indicating number of buffers allocated
* (not a great measure, easily confused)
@@ -834,7 +838,7 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
if (dev_priv->stats.requested_bufs > 100)
dev_priv->stats.requested_bufs = 100;
- radeon_clear_box(dev_priv, 4, 16,
+ radeon_clear_box(dev_priv, master_priv, 4, 16,
dev_priv->stats.requested_bufs, 4,
196, 128, 128);
}
@@ -848,11 +852,13 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
*/
static void radeon_cp_dispatch_clear(struct drm_device * dev,
+ struct drm_master *master,
drm_radeon_clear_t * clear,
drm_radeon_clear_rect_t * depth_boxes)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
int nbox = sarea_priv->nbox;
struct drm_clip_rect *pbox = sarea_priv->boxes;
@@ -864,7 +870,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
dev_priv->stats.clears++;
- if (dev_priv->sarea_priv->pfCurrentPage == 1) {
+ if (sarea_priv->pfCurrentPage == 1) {
unsigned int tmp = flags;
flags &= ~(RADEON_FRONT | RADEON_BACK);
@@ -890,7 +896,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
/* Make sure we restore the 3D state next time.
*/
- dev_priv->sarea_priv->ctx_owner = 0;
+ sarea_priv->ctx_owner = 0;
for (i = 0; i < nbox; i++) {
int x = pbox[i].x1;
@@ -967,7 +973,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
/* Make sure we restore the 3D state next time.
* we haven't touched any "normal" state - still need this?
*/
- dev_priv->sarea_priv->ctx_owner = 0;
+ sarea_priv->ctx_owner = 0;
if ((dev_priv->flags & RADEON_HAS_HIERZ)
&& (flags & RADEON_USE_HIERZ)) {
@@ -1015,7 +1021,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
int tileoffset, nrtilesx, nrtilesy, j;
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
if ((dev_priv->flags & RADEON_HAS_HIERZ)
- && !(dev_priv->microcode_version == UCODE_R200)) {
+ && (dev_priv->chip_family < CHIP_R200)) {
/* FIXME : figure this out for r200 (when hierz is enabled). Or
maybe r200 actually doesn't need to put the low-res z value into
the tile cache like r100, but just needs to clear the hi-level z-buffer?
@@ -1044,7 +1050,8 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
ADVANCE_RING();
tileoffset += depthpixperline >> 6;
}
- } else if (dev_priv->microcode_version == UCODE_R200) {
+ } else if ((dev_priv->chip_family >= CHIP_R200) &&
+ (dev_priv->chip_family <= CHIP_RV280)) {
/* works for rv250. */
/* find first macro tile (8x2 4x4 z-pixels on rv250) */
tileoffset =
@@ -1099,7 +1106,8 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
/* TODO don't always clear all hi-level z tiles */
if ((dev_priv->flags & RADEON_HAS_HIERZ)
- && (dev_priv->microcode_version == UCODE_R200)
+ && ((dev_priv->chip_family >= CHIP_R200) &&
+ (dev_priv->chip_family <= CHIP_RV280))
&& (flags & RADEON_USE_HIERZ))
/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
/* FIXME : the mask supposedly contains low-res z values. So can't set
@@ -1119,8 +1127,9 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
* rendering a quad into just those buffers. Thus, we have to
* make sure the 3D engine is configured correctly.
*/
- else if ((dev_priv->microcode_version == UCODE_R200) &&
- (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
+ else if ((dev_priv->chip_family >= CHIP_R200) &&
+ (dev_priv->chip_family <= CHIP_RV280) &&
+ (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
int tempPP_CNTL;
int tempRE_CNTL;
@@ -1214,7 +1223,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
/* Make sure we restore the 3D state next time.
*/
- dev_priv->sarea_priv->ctx_owner = 0;
+ sarea_priv->ctx_owner = 0;
for (i = 0; i < nbox; i++) {
@@ -1285,7 +1294,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
/* Make sure we restore the 3D state next time.
*/
- dev_priv->sarea_priv->ctx_owner = 0;
+ sarea_priv->ctx_owner = 0;
for (i = 0; i < nbox; i++) {
@@ -1328,20 +1337,21 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
* wait on this value before performing the clear ioctl. We
* need this because the card's so damned fast...
*/
- dev_priv->sarea_priv->last_clear++;
+ sarea_priv->last_clear++;
BEGIN_RING(4);
- RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
+ RADEON_CLEAR_AGE(sarea_priv->last_clear);
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
}
-static void radeon_cp_dispatch_swap(struct drm_device * dev)
+static void radeon_cp_dispatch_swap(struct drm_device * dev, struct drm_master *master)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
int nbox = sarea_priv->nbox;
struct drm_clip_rect *pbox = sarea_priv->boxes;
int i;
@@ -1351,7 +1361,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
/* Do some trivial performance monitoring...
*/
if (dev_priv->do_boxes)
- radeon_cp_performance_boxes(dev_priv);
+ radeon_cp_performance_boxes(dev_priv, master_priv);
/* Wait for the 3D stream to idle before dispatching the bitblt.
* This will prevent data corruption between the two streams.
@@ -1385,7 +1395,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
/* Make this work even if front & back are flipped:
*/
OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
- if (dev_priv->sarea_priv->pfCurrentPage == 0) {
+ if (sarea_priv->pfCurrentPage == 0) {
OUT_RING(dev_priv->back_pitch_offset);
OUT_RING(dev_priv->front_pitch_offset);
} else {
@@ -1405,31 +1415,32 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
* throttle the framerate by waiting for this value before
* performing the swapbuffer ioctl.
*/
- dev_priv->sarea_priv->last_frame++;
+ sarea_priv->last_frame++;
BEGIN_RING(4);
- RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+ RADEON_FRAME_AGE(sarea_priv->last_frame);
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
}
-static void radeon_cp_dispatch_flip(struct drm_device * dev)
+void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle;
- int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
+ struct drm_sarea *sarea = (struct drm_sarea *) master_priv->sarea->handle;
+ int offset = (master_priv->sarea_priv->pfCurrentPage == 1)
? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
DRM_DEBUG("pfCurrentPage=%d\n",
- dev_priv->sarea_priv->pfCurrentPage);
+ master_priv->sarea_priv->pfCurrentPage);
/* Do some trivial performance monitoring...
*/
if (dev_priv->do_boxes) {
dev_priv->stats.boxes |= RADEON_BOX_FLIP;
- radeon_cp_performance_boxes(dev_priv);
+ radeon_cp_performance_boxes(dev_priv, master_priv);
}
/* Update the frame offsets for both CRTCs
@@ -1441,7 +1452,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
((sarea->frame.y * dev_priv->front_pitch +
sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
+ offset);
- OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
+ OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base
+ offset);
ADVANCE_RING();
@@ -1450,13 +1461,13 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
* throttle the framerate by waiting for this value before
* performing the swapbuffer ioctl.
*/
- dev_priv->sarea_priv->last_frame++;
- dev_priv->sarea_priv->pfCurrentPage =
- 1 - dev_priv->sarea_priv->pfCurrentPage;
+ master_priv->sarea_priv->last_frame++;
+ master_priv->sarea_priv->pfCurrentPage =
+ 1 - master_priv->sarea_priv->pfCurrentPage;
BEGIN_RING(2);
- RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+ RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame);
ADVANCE_RING();
}
@@ -1494,11 +1505,13 @@ typedef struct {
} drm_radeon_tcl_prim_t;
static void radeon_cp_dispatch_vertex(struct drm_device * dev,
+ struct drm_file *file_priv,
struct drm_buf * buf,
drm_radeon_tcl_prim_t * prim)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
int numverts = (int)prim->numverts;
int nbox = sarea_priv->nbox;
@@ -1539,13 +1552,14 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev,
} while (i < nbox);
}
-static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
+static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_master *master, struct drm_buf * buf)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
RING_LOCALS;
- buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
+ buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
BEGIN_RING(2);
@@ -1590,12 +1604,14 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev,
}
}
-static void radeon_cp_dispatch_indices(struct drm_device * dev,
+static void radeon_cp_dispatch_indices(struct drm_device *dev,
+ struct drm_master *master,
struct drm_buf * elt_buf,
drm_radeon_tcl_prim_t * prim)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
int offset = dev_priv->gart_buffers_offset + prim->offset;
u32 *data;
int dwords;
@@ -1870,7 +1886,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
ADVANCE_RING();
COMMIT_RING();
- radeon_cp_discard_buffer(dev, buf);
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
/* Update the input parameters for next time */
image->y += height;
@@ -2120,7 +2136,8 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi
static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
drm_radeon_clear_t *clear = data;
drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
DRM_DEBUG("\n");
@@ -2136,7 +2153,7 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
sarea_priv->nbox * sizeof(depth_boxes[0])))
return -EFAULT;
- radeon_cp_dispatch_clear(dev, clear, depth_boxes);
+ radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes);
COMMIT_RING();
return 0;
@@ -2144,9 +2161,10 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
/* Not sure why this isn't set all the time:
*/
-static int radeon_do_init_pageflip(struct drm_device * dev)
+static int radeon_do_init_pageflip(struct drm_device * dev, struct drm_master *master)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = master->driver_priv;
RING_LOCALS;
DRM_DEBUG("\n");
@@ -2163,8 +2181,8 @@ static int radeon_do_init_pageflip(struct drm_device * dev)
dev_priv->page_flipping = 1;
- if (dev_priv->sarea_priv->pfCurrentPage != 1)
- dev_priv->sarea_priv->pfCurrentPage = 0;
+ if (master_priv->sarea_priv->pfCurrentPage != 1)
+ master_priv->sarea_priv->pfCurrentPage = 0;
return 0;
}
@@ -2182,9 +2200,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f
RING_SPACE_TEST_WITH_RETURN(dev_priv);
if (!dev_priv->page_flipping)
- radeon_do_init_pageflip(dev);
+ radeon_do_init_pageflip(dev, file_priv->master);
- radeon_cp_dispatch_flip(dev);
+ radeon_cp_dispatch_flip(dev, file_priv->master);
COMMIT_RING();
return 0;
@@ -2193,7 +2211,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f
static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
+
DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -2203,8 +2223,8 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
- radeon_cp_dispatch_swap(dev);
- dev_priv->sarea_priv->ctx_owner = 0;
+ radeon_cp_dispatch_swap(dev, file_priv->master);
+ sarea_priv->ctx_owner = 0;
COMMIT_RING();
return 0;
@@ -2213,6 +2233,7 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
drm_radeon_sarea_t *sarea_priv;
struct drm_device_dma *dma = dev->dma;
struct drm_buf *buf;
@@ -2226,7 +2247,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
return -EINVAL;
}
- sarea_priv = dev_priv->sarea_priv;
+ sarea_priv = master_priv->sarea_priv;
DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
@@ -2280,13 +2301,13 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
prim.finish = vertex->count; /* unused */
prim.prim = vertex->prim;
prim.numverts = vertex->count;
- prim.vc_format = dev_priv->sarea_priv->vc_format;
+ prim.vc_format = sarea_priv->vc_format;
- radeon_cp_dispatch_vertex(dev, buf, &prim);
+ radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim);
}
if (vertex->discard) {
- radeon_cp_discard_buffer(dev, buf);
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
}
COMMIT_RING();
@@ -2296,6 +2317,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
drm_radeon_sarea_t *sarea_priv;
struct drm_device_dma *dma = dev->dma;
struct drm_buf *buf;
@@ -2309,7 +2331,7 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- sarea_priv = dev_priv->sarea_priv;
+ sarea_priv = master_priv->sarea_priv;
DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
DRM_CURRENTPID, elts->idx, elts->start, elts->end,
@@ -2376,11 +2398,11 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
prim.prim = elts->prim;
prim.offset = 0; /* offset from start of dma buffers */
prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
- prim.vc_format = dev_priv->sarea_priv->vc_format;
+ prim.vc_format = sarea_priv->vc_format;
- radeon_cp_dispatch_indices(dev, buf, &prim);
+ radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim);
if (elts->discard) {
- radeon_cp_discard_buffer(dev, buf);
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
}
COMMIT_RING();
@@ -2496,7 +2518,7 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
*/
radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
if (indirect->discard) {
- radeon_cp_discard_buffer(dev, buf);
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
}
COMMIT_RING();
@@ -2506,6 +2528,7 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
drm_radeon_sarea_t *sarea_priv;
struct drm_device_dma *dma = dev->dma;
struct drm_buf *buf;
@@ -2520,7 +2543,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
return -EINVAL;
}
- sarea_priv = dev_priv->sarea_priv;
+ sarea_priv = master_priv->sarea_priv;
DRM_DEBUG("pid=%d index=%d discard=%d\n",
DRM_CURRENTPID, vertex->idx, vertex->discard);
@@ -2582,12 +2605,12 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
tclprim.offset = prim.numverts * 64;
tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
- radeon_cp_dispatch_indices(dev, buf, &tclprim);
+ radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim);
} else {
tclprim.numverts = prim.numverts;
tclprim.offset = 0; /* not used */
- radeon_cp_dispatch_vertex(dev, buf, &tclprim);
+ radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim);
}
if (sarea_priv->nbox == 1)
@@ -2595,7 +2618,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
}
if (vertex->discard) {
- radeon_cp_discard_buffer(dev, buf);
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
}
COMMIT_RING();
@@ -2889,7 +2912,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
orig_nbox = cmdbuf->nbox;
- if (dev_priv->microcode_version == UCODE_R300) {
+ if (dev_priv->chip_family >= CHIP_R300) {
int temp;
temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
@@ -2949,7 +2972,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
goto err;
}
- radeon_cp_discard_buffer(dev, buf);
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
break;
case RADEON_CMD_PACKET3:
@@ -3110,6 +3133,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
drm_radeon_setparam_t *sp = data;
struct drm_radeon_driver_file_fields *radeon_priv;
@@ -3129,14 +3153,14 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
DRM_DEBUG("color tiling disabled\n");
dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->tiling_enabled = 0;
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->tiling_enabled = 0;
} else if (sp->value == 1) {
DRM_DEBUG("color tiling enabled\n");
dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
- if (dev_priv->sarea_priv)
- dev_priv->sarea_priv->tiling_enabled = 1;
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->tiling_enabled = 1;
}
break;
case RADEON_SETPARAM_PCIGART_LOCATION:
@@ -3183,14 +3207,6 @@ void radeon_driver_preclose(struct drm_device *dev,
void radeon_driver_lastclose(struct drm_device *dev)
{
- if (dev->dev_private) {
- drm_radeon_private_t *dev_priv = dev->dev_private;
-
- if (dev_priv->sarea_priv &&
- dev_priv->sarea_priv->pfCurrentPage != 0)
- radeon_cp_dispatch_flip(dev);
- }
-
radeon_do_release(dev);
}
@@ -3251,7 +3267,18 @@ struct drm_ioctl_desc radeon_ioctls[] = {
DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
+ DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_PIN, radeon_gem_pin_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_RADEON_GEM_UNPIN, radeon_gem_unpin_ioctl, DRM_AUTH),
+ 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),
};
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);