From b09cb93e2d188228e26135149786ee231cd9b11d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:23:19 +1000 Subject: radeon: add some more r100 support to test AGP --- shared-core/r300_cmdbuf.c | 3 +++ shared-core/radeon_cs.c | 27 ++------------------------- 2 files changed, 5 insertions(+), 25 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/radeon_cs.c b/shared-core/radeon_cs.c index f9147136..3e47ad12 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -122,7 +122,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct /* 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)); + 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; } @@ -195,30 +195,6 @@ 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) -{ - 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) { @@ -308,6 +284,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 */ -- cgit v1.2.3 From f74721fc2553d81acfe4d4a670833405dd52092b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:24:13 +1000 Subject: radeon: fix unused agp functionality --- shared-core/radeon_cp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 190b1432..d5889e61 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; } } -- cgit v1.2.3 From 48f222751643a349924ba3e6c26890310822f89c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:25:32 +1000 Subject: radeon: export radeon_modeset --- shared-core/radeon_drv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index a6ce129d..3be99eb3 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -460,6 +460,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. -- cgit v1.2.3 From d275f99c9a7d915473034e6abd575f35bea5db9c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:26:00 +1000 Subject: radeon: don't enable dynclks on rs48x --- shared-core/radeon_cp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index d5889e61..ded6f676 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2562,6 +2562,10 @@ int radeon_static_clocks_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + 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)) { -- cgit v1.2.3 From a8f07db596532912e354bb7a2b3acdfc11a8d150 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:26:32 +1000 Subject: radeon: workaround failure to parse some rs48x edid --- linux-core/radeon_connectors.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/linux-core/radeon_connectors.c b/linux-core/radeon_connectors.c index f217fe77..8de21997 100644 --- a/linux-core/radeon_connectors.c +++ b/linux-core/radeon_connectors.c @@ -87,19 +87,23 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) if (radeon_connector->ddc_bus) { radeon_i2c_do_lock(radeon_connector, 1); - edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); + edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); radeon_i2c_do_lock(radeon_connector, 0); if (edid) { drm_mode_connector_update_edid_property(&radeon_connector->base, edid); ret = drm_add_edid_modes(&radeon_connector->base, edid); kfree(edid); + if (ret == 0) + goto native; return ret; } } +native: encoder = radeon_best_single_encoder(connector); if (!encoder) - return connector_status_disconnected; + return 0; + /* we have no EDID modes */ mode = radeon_fp_native_mode(encoder); if (mode) { -- cgit v1.2.3 From 52ef9d87db8d3b7e0e9114f987263292e8e12d6a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:27:00 +1000 Subject: radeon: fix small typo in agp code --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index ded6f676..ae3a69b6 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2439,7 +2439,7 @@ int radeon_modeset_agp_init(struct drm_device *dev) } /* 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; -- cgit v1.2.3 From 0dbe3436ee6e3f2a4d6d252ef5e31b7bb7e36764 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:28:36 +1000 Subject: radeon: fix some warnings --- linux-core/ati_pcigart.c | 10 +++++----- linux-core/drm_bufs.c | 1 - linux-core/radeon_buffer.c | 2 -- shared-core/r300_reg.h | 2 +- shared-core/radeon_cp.c | 7 ++----- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 50e990f1..6b0d8947 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -39,7 +39,7 @@ #define ATI_PCIE_WRITE 0x4 #define ATI_PCIE_READ 0x8 -static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *gart_info, dma_addr_t addr, u32 *pci_gart) +static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *gart_info, dma_addr_t addr, volatile u32 *pci_gart) { u32 page_base; @@ -61,7 +61,7 @@ static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info * *pci_gart = cpu_to_le32(page_base); } -static __inline__ dma_addr_t gart_get_page_from_table(struct drm_ati_pcigart_info *gart_info, u32 *pci_gart) +static __inline__ dma_addr_t gart_get_page_from_table(struct drm_ati_pcigart_info *gart_info, volatile u32 *pci_gart) { dma_addr_t retval; switch(gart_info->gart_reg_if) { @@ -93,7 +93,7 @@ int drm_ati_alloc_pcigart_table(struct drm_device *dev, #ifdef CONFIG_X86 /* IGPs only exist on x86 in any case */ if (gart_info->gart_reg_if == DRM_ATI_GART_IGP) - set_memory_uc(gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT); + set_memory_uc((unsigned long)gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT); #endif memset(gart_info->table_handle->vaddr, 0, gart_info->table_size); @@ -107,7 +107,7 @@ static void drm_ati_free_pcigart_table(struct drm_device *dev, #ifdef CONFIG_X86 /* IGPs only exist on x86 in any case */ if (gart_info->gart_reg_if == DRM_ATI_GART_IGP) - set_memory_wb(gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT); + set_memory_wb((unsigned long)gart_info->table_handle->vaddr, gart_info->table_size >> PAGE_SHIFT); #endif drm_pci_free(dev, gart_info->table_handle); gart_info->table_handle = NULL; @@ -260,7 +260,7 @@ static int ati_pcigart_bind_ttm(struct drm_ttm_backend *backend, j = offset; while (j < (offset + atipci_be->num_pages)) { - if (gart_get_page_from_table(info, pci_gart+j)) + if (gart_get_page_from_table(info, pci_gart + j)) return -EBUSY; j++; } diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index c966badc..15c426cb 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -1544,7 +1544,6 @@ int drm_mapbufs(struct drm_device *dev, void *data, goto done; } down_write(¤t->mm->mmap_sem); - DRM_DEBUG("%x %d\n", token, map->size); virtual = do_mmap(file_priv->filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, diff --git a/linux-core/radeon_buffer.c b/linux-core/radeon_buffer.c index e5a90892..e88378a4 100644 --- a/linux-core/radeon_buffer.c +++ b/linux-core/radeon_buffer.c @@ -350,7 +350,6 @@ static int radeon_move_vram(struct drm_buffer_object * bo, struct drm_bo_mem_reg tmp_mem; struct drm_bo_mem_reg *old_mem = &bo->mem; int ret; - bool was_local = false; /* old - LOCAL memory node bo->mem tmp - TT type memory node @@ -398,7 +397,6 @@ int radeon_move(struct drm_buffer_object * bo, int evict, int no_wait, struct drm_bo_mem_reg *new_mem) { struct drm_device *dev = bo->dev; - struct drm_bo_mem_reg *old_mem = &bo->mem; drm_radeon_private_t *dev_priv = dev->dev_private; if (!dev_priv->cp_running) 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 ae3a69b6..f579e01a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2434,7 +2434,7 @@ 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; } @@ -2457,7 +2457,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; @@ -2713,7 +2713,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; @@ -2735,8 +2734,6 @@ 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; -- cgit v1.2.3 From a066a5f908af0e82b1a0c7099b73d4a63585c69d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:28:56 +1000 Subject: radeon: make writeback work again --- shared-core/radeon_cp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index f579e01a..0200797a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -825,7 +825,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 +833,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 +859,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 +2357,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; } -- cgit v1.2.3 From 3fd0e1483ebe640b69da888e286ea85d11539b46 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:29:22 +1000 Subject: radeon: fixup scratch register interactions properly --- shared-core/radeon_cp.c | 14 +++++++++++++- shared-core/radeon_cs.c | 4 ++-- shared-core/radeon_drv.h | 12 ++++++------ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 0200797a..71d1a61b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -791,7 +791,10 @@ 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, 0x3f); + else + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); /* Turn on bus mastering */ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; @@ -806,6 +809,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 */ diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 3e47ad12..b5982894 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -365,14 +365,14 @@ 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_drv.h b/shared-core/radeon_drv.h index 3be99eb3..2d592e45 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -733,11 +733,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 @@ -1607,7 +1607,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) { -- cgit v1.2.3 From b4803991c8ad8596786f8cf1cffc6417c8ce446a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:30:48 +1000 Subject: radeon: update proper chip family --- shared-core/radeon_cp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 71d1a61b..4f5c538c 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -791,8 +791,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - if (dev_priv->chip_family > CHIP_R300) - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x3f); + if (dev_priv->chip_family >= CHIP_R300) + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7f); else RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x1f); -- cgit v1.2.3 From 653b16f2dd32b5fdbd5f97277edc1c6df66755a9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:31:17 +1000 Subject: radeon: fix accessible VRAM sizing --- linux-core/radeon_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 5e2ad98b..5ecd8c55 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -585,6 +585,9 @@ void radeon_vram_setup(struct drm_device *dev) if (accessible > bar_size) accessible = bar_size; + if (accessible > vram) + accessible = vram; + DRM_INFO("Detected VRAM RAM=%dK, accessible=%uK, BAR=%uK\n", vram, accessible, bar_size); -- cgit v1.2.3 From 1c817cc3fc09abe93539413130de3875e4c7eafe Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:32:39 +1000 Subject: radeon: pull bus master enable into its own function --- linux-core/radeon_pm.c | 6 +----- shared-core/radeon_cp.c | 22 ++++++++++++++++++---- shared-core/radeon_drv.h | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/linux-core/radeon_pm.c b/linux-core/radeon_pm.c index 6b1e6f84..db8f44c4 100644 --- a/linux-core/radeon_pm.c +++ b/linux-core/radeon_pm.c @@ -93,7 +93,6 @@ int radeon_resume(struct drm_device *dev) struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb; int i; - u32 tmp; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return 0; @@ -104,10 +103,7 @@ int radeon_resume(struct drm_device *dev) return -1; /* Turn on bus mastering -todo fix properly */ - if (dev_priv->chip_family < CHIP_RV380) { - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } + radeon_enable_bm(dev_priv); DRM_ERROR("\n"); /* on atom cards re init the whole card diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 4f5c538c..b6207c7d 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -194,6 +194,23 @@ 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_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + /* rs400, rs690/rs740 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || + ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { + /* r1xx, r2xx, r300, r(v)350, r420/r481, 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) { @@ -686,7 +703,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 @@ -796,9 +812,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, 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); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 2d592e45..0d5f762b 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1691,7 +1691,7 @@ extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file * 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); #define MARK_SAFE 1 #define MARK_CHECK_OFFSET 2 -- cgit v1.2.3 From 624da91277ee33936ea3cfaf20e7f6775293deb2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:33:12 +1000 Subject: radeon: add r423 bits to modesetting --- linux-core/radeon_gem.c | 2 ++ linux-core/radeon_legacy_encoders.c | 3 +++ shared-core/radeon_drv.h | 1 + 3 files changed, 6 insertions(+) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 5ecd8c55..4b15fac3 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -525,6 +525,7 @@ static uint32_t radeon_get_accessible_vram(struct drm_device *dev) dev_priv->chip_family == CHIP_RV350 || dev_priv->chip_family == CHIP_RV380 || dev_priv->chip_family == CHIP_R420 || + dev_priv->chip_family == CHIP_R423 || dev_priv->chip_family == CHIP_RV410 || radeon_is_avivo(dev_priv)) { uint32_t temp = RADEON_READ(RADEON_HOST_PATH_CNTL); @@ -963,6 +964,7 @@ void radeon_init_memory_map(struct drm_device *dev) dev_priv->chip_family == CHIP_RV350 || dev_priv->chip_family == CHIP_RV380 || dev_priv->chip_family == CHIP_R420 || + dev_priv->chip_family == CHIP_R423 || dev_priv->chip_family == CHIP_RV410) aper0_base &= ~(mem_size - 1); diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c index 261501d1..3df89d30 100644 --- a/linux-core/radeon_legacy_encoders.c +++ b/linux-core/radeon_legacy_encoders.c @@ -1070,6 +1070,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; //tv_master_cntl |= RADEON_TV_ON; if (dev_priv->chip_family == CHIP_R420 || + dev_priv->chip_family == CHIP_R423 || dev_priv->chip_family == CHIP_RV410) tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | R420_TV_DAC_GDACPD | @@ -1095,6 +1096,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; //tv_master_cntl &= ~RADEON_TV_ON; if (dev_priv->chip_family == CHIP_R420 || + dev_priv->chip_family == CHIP_R423 || dev_priv->chip_family == CHIP_RV410) tv_dac_cntl |= (R420_TV_DAC_RDACPD | R420_TV_DAC_GDACPD | @@ -1158,6 +1160,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, if (dev_priv->chip_family != CHIP_R200) { tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL); if (dev_priv->chip_family == CHIP_R420 || + dev_priv->chip_family == CHIP_R423 || dev_priv->chip_family == CHIP_RV410) { tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | RADEON_TV_DAC_BGADJ_MASK | diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 0d5f762b..17c0c297 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1644,6 +1644,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)) -- cgit v1.2.3 From fd9e05b3f4f464ddf08097817a3af824f54a97ca Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:33:32 +1000 Subject: radeon: release agp on module unload --- shared-core/radeon_cp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b6207c7d..8e97f034 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2476,6 +2476,12 @@ int radeon_modeset_agp_init(struct drm_device *dev) } 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) @@ -2790,6 +2796,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); -- cgit v1.2.3 From 563e7e5930a8d628b33cb1f7a9aaea251f2fc50b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:36:03 +1000 Subject: radeon/drm: fixup ref counting in on fb objs --- linux-core/atombios_crtc.c | 2 +- linux-core/drm_crtc.h | 1 - linux-core/drm_crtc_helper.c | 4 +--- linux-core/drm_crtc_helper.h | 3 +-- linux-core/radeon_display.c | 23 ++++++++++++++--------- linux-core/radeon_fb.c | 2 +- linux-core/radeon_legacy_crtc.c | 4 ++-- linux-core/radeon_mode.h | 3 ++- linux-core/radeon_pm.c | 8 ++++---- 9 files changed, 26 insertions(+), 24 deletions(-) diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c index 3856f8ca..2e144c90 100644 --- a/linux-core/atombios_crtc.c +++ b/linux-core/atombios_crtc.c @@ -276,7 +276,7 @@ void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y) radeon_fb = to_radeon_framebuffer(crtc->fb); - obj = radeon_fb->base.mm_private; + obj = radeon_fb->obj; obj_priv = obj->driver_private; fb_location = obj_priv->bo->offset + dev_priv->fb_location; diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 6a73a71b..13fba4f2 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -240,7 +240,6 @@ struct drm_framebuffer { void *fbdev; u32 pseudo_palette[17]; struct list_head filp_head; - void *mm_private; }; struct drm_property_blob { diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c index b334f5b5..776a98e1 100644 --- a/linux-core/drm_crtc_helper.c +++ b/linux-core/drm_crtc_helper.c @@ -771,15 +771,13 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev) EXPORT_SYMBOL(drm_helper_hotplug_stage_two); int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - struct drm_mode_fb_cmd *mode_cmd, - void *mm_private) + struct drm_mode_fb_cmd *mode_cmd) { fb->width = mode_cmd->width; fb->height = mode_cmd->height; fb->pitch = mode_cmd->pitch; fb->bits_per_pixel = mode_cmd->bpp; fb->depth = mode_cmd->depth; - fb->mm_private = mm_private; return 0; } diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h index 01b14239..c0719157 100644 --- a/linux-core/drm_crtc_helper.h +++ b/linux-core/drm_crtc_helper.h @@ -75,8 +75,7 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_m extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - struct drm_mode_fb_cmd *mode_cmd, - void *mm_private); + struct drm_mode_fb_cmd *mode_cmd); static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs) { diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index ddc933cc..679244a9 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -601,17 +601,18 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) if (fb->fbdev) radeonfb_remove(dev, fb); + drm_gem_object_unreference(radeon_fb->obj); drm_framebuffer_cleanup(fb); kfree(radeon_fb); } static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) + struct drm_file *file_priv, + unsigned int *handle) { - struct drm_gem_object *object = fb->mm_private; + struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); - return drm_gem_handle_create(file_priv, object, handle); + return drm_gem_handle_create(file_priv, radeon_fb->obj, handle); } static const struct drm_framebuffer_funcs radeon_fb_funcs = { @@ -622,7 +623,7 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = { struct drm_framebuffer * radeon_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd *mode_cmd, - void *mm_private) + struct drm_gem_object *obj) { struct radeon_framebuffer *radeon_fb; @@ -631,7 +632,10 @@ radeon_framebuffer_create(struct drm_device *dev, return NULL; drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs); - drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd, mm_private); + drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd); + + radeon_fb->obj = obj; + return &radeon_fb->base; } @@ -641,10 +645,11 @@ radeon_user_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd *mode_cmd) { struct radeon_framebuffer *radeon_fb; - void *mm_private; + struct drm_gem_object *obj; + + obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); - mm_private = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); - return radeon_framebuffer_create(dev, mode_cmd, mm_private); + return radeon_framebuffer_create(dev, mode_cmd, obj); } static const struct drm_mode_config_funcs radeon_mode_funcs = { diff --git a/linux-core/radeon_fb.c b/linux-core/radeon_fb.c index 8d4181e8..405f1da9 100644 --- a/linux-core/radeon_fb.c +++ b/linux-core/radeon_fb.c @@ -1148,7 +1148,7 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) unregister_framebuffer(info); drm_bo_kunmap(&radeon_fb->kmap_obj); mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(fb->mm_private); + drm_gem_object_unreference(radeon_fb->obj); mutex_unlock(&dev->struct_mutex); framebuffer_release(info); } diff --git a/linux-core/radeon_legacy_crtc.c b/linux-core/radeon_legacy_crtc.c index 820bd548..c0a3c0fa 100644 --- a/linux-core/radeon_legacy_crtc.c +++ b/linux-core/radeon_legacy_crtc.c @@ -231,7 +231,7 @@ static bool radeon_set_crtc1_base(struct drm_crtc *crtc, int x, int y) radeon_fb = to_radeon_framebuffer(crtc->fb); - obj = radeon_fb->base.mm_private; + obj = radeon_fb->obj; obj_priv = obj->driver_private; crtc_offset = obj_priv->bo->offset; @@ -654,7 +654,7 @@ static bool radeon_set_crtc2_base(struct drm_crtc *crtc, int x, int y) radeon_fb = to_radeon_framebuffer(crtc->fb); - obj = radeon_fb->base.mm_private; + obj = radeon_fb->obj; obj_priv = obj->driver_private; crtc2_offset = obj_priv->bo->offset; diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index 64608e35..23de1088 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -255,6 +255,7 @@ struct radeon_connector { struct radeon_framebuffer { struct drm_framebuffer base; struct drm_bo_kmap_obj kmap_obj; + struct drm_gem_object *obj; }; extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, @@ -323,7 +324,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd *mode_cmd, - void *mm_private); + struct drm_gem_object *obj); int radeonfb_probe(struct drm_device *dev); diff --git a/linux-core/radeon_pm.c b/linux-core/radeon_pm.c index db8f44c4..259d42da 100644 --- a/linux-core/radeon_pm.c +++ b/linux-core/radeon_pm.c @@ -54,10 +54,10 @@ int radeon_suspend(struct drm_device *dev, pm_message_t state) if (!radeon_fb) continue; - if (!radeon_fb->base.mm_private) + if (!radeon_fb->obj) continue; - radeon_gem_object_unpin(radeon_fb->base.mm_private); + radeon_gem_object_unpin(radeon_fb->obj); } if (!(dev_priv->flags & RADEON_IS_IGP)) @@ -175,10 +175,10 @@ int radeon_resume(struct drm_device *dev) if (!radeon_fb) continue; - if (!radeon_fb->base.mm_private) + if (!radeon_fb->obj) continue; - radeon_gem_object_pin(radeon_fb->base.mm_private, + radeon_gem_object_pin(radeon_fb->obj, PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM); } /* blat the mode back in */ -- cgit v1.2.3 From 8b2925468d326ab6fa31a312e845a3bc71343106 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:39:53 +1000 Subject: radeon: make new CS2 command submission interface port older interface to this --- linux-core/radeon_gem.c | 25 +++-- shared-core/radeon_cs.c | 257 ++++++++++++++++++++++++++++++++++++++------- shared-core/radeon_drm.h | 19 +++- shared-core/radeon_drv.h | 31 ++++-- shared-core/radeon_state.c | 1 + 5 files changed, 273 insertions(+), 60 deletions(-) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 4b15fac3..7899490f 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -1148,11 +1148,11 @@ int radeon_gem_object_unpin(struct drm_gem_object *obj) #define RADEON_NUM_IB (RADEON_IB_MEMORY / RADEON_IB_SIZE) -int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset) +int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser, uint32_t *card_offset) { int i, index = -1; int ret; - drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; for (i = 0; i < RADEON_NUM_IB; i++) { if (!(dev_priv->ib_alloc_bitmap & (1 << i))){ @@ -1178,12 +1178,12 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32 } if (index == -1) { - DRM_ERROR("Major case fail to allocate IB from freelist %x\n", dev_priv->ib_alloc_bitmap); + DRM_ERROR("Major case fail to allocate IB from freelist %llx\n", dev_priv->ib_alloc_bitmap); return -EINVAL; } - if (dwords > RADEON_IB_SIZE / sizeof(uint32_t)) + if (parser->chunks[parser->ib_index].length_dw > RADEON_IB_SIZE / sizeof(uint32_t)) return -EINVAL; ret = drm_bo_do_validate(dev_priv->ib_objs[index]->bo, 0, @@ -1195,25 +1195,24 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32 } *card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset; - *ib = dev_priv->ib_objs[index]->kmap.virtual; + parser->ib = dev_priv->ib_objs[index]->kmap.virtual; dev_priv->ib_alloc_bitmap |= (1 << i); return 0; } -static void radeon_gem_ib_free(struct drm_device *dev, void *ib, uint32_t dwords) +static void radeon_gem_ib_free(struct drm_radeon_cs_parser *parser) { + struct drm_device *dev = parser->dev; drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_fence_object *fence; int ret; int i; for (i = 0; i < RADEON_NUM_IB; i++) { - - if (dev_priv->ib_objs[i]->kmap.virtual == ib) { + if (dev_priv->ib_objs[i]->kmap.virtual == parser->ib) { /* emit a fence object */ ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); if (ret) { - drm_putback_buffer_objects(dev); } /* dereference the fence object */ @@ -1243,19 +1242,19 @@ static int radeon_gem_ib_destroy(struct drm_device *dev) return 0; } -static int radeon_gem_relocate(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *reloc, uint32_t *offset) +static int radeon_gem_relocate(struct drm_radeon_cs_parser *parser, + uint32_t *reloc, uint32_t *offset) { + struct drm_device *dev = parser->dev; drm_radeon_private_t *dev_priv = dev->dev_private; /* relocate the handle */ uint32_t read_domains = reloc[2]; uint32_t write_domain = reloc[3]; struct drm_gem_object *obj; int flags = 0; - int ret; struct drm_radeon_gem_object *obj_priv; - obj = drm_gem_object_lookup(dev, file_priv, reloc[1]); + obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]); if (!obj) return -EINVAL; diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index b5982894..452f04b4 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -29,16 +29,163 @@ #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; + uint32_t card_offset; + long size; + int r, i; + RING_LOCALS; + + /* 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)); + + 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.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; + + switch(parser.chunks[i].chunk_id) { + case RADEON_CHUNK_ID_RELOCS: + case RADEON_CHUNK_ID_IB: + case RADEON_CHUNK_ID_OLD: { + /* copy from user the relocs chunk */ + int size = parser.chunks[i].length_dw * sizeof(uint32_t); + 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; + } + } + 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, &card_offset); + if (r) { + DRM_ERROR("ib_get failed\n"); + goto out; + } + + /* now parse command stream */ + 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(parser.chunks[parser.ib_index].length_dw); + OUT_RING(CP_PACKET2()); + ADVANCE_RING(); + + /* emit cs id sequence */ + dev_priv->cs.id_emit(dev, &cs_id); + COMMIT_RING(); + + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); +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; + struct drm_radeon_kernel_chunk chunk_fake[1]; RING_LOCALS; /* set command stream id to 0 which is fake id */ @@ -69,14 +216,26 @@ 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, &card_offset); 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; } @@ -94,13 +253,13 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); 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; @@ -108,17 +267,24 @@ static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_pr #define RELOC_SIZE 2 #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))) { @@ -130,7 +296,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct 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 +314,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 +325,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 +360,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,17 +368,18 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f return 0; } -int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, - uint32_t *packets, uint32_t offset_dw) +int radeon_cs_packet0(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) + 2; + drm_radeon_private_t *dev_priv = parser->dev->dev_private; + uint32_t hdr, num_dw, reg; int need_reloc = 0; - int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; 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 */ @@ -226,7 +400,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); @@ -245,24 +419,27 @@ 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; + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = parser->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: @@ -275,7 +452,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: @@ -306,10 +483,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; } diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index c924c689..bc2eb45a 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -514,6 +514,7 @@ typedef struct { #define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server #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) @@ -554,6 +555,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect) #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 { @@ -874,11 +876,26 @@ struct drm_radeon_gem_indirect { 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 17c0c297..b741953b 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -294,6 +294,23 @@ 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; + void *ib; +}; + /* command submission struct */ struct drm_radeon_cs_priv { uint32_t id_wcnt; @@ -301,21 +318,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); + int (*parse)(struct drm_radeon_cs_parser *parser); void (*id_emit)(struct drm_device *dev, 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 *card_offset); 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]; @@ -1689,6 +1707,7 @@ 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); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 7262b2aa..f0cd6f89 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3290,6 +3290,7 @@ struct drm_ioctl_desc radeon_ioctls[] = { 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_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); -- cgit v1.2.3 From 35f080559287ebf30f417337fa124d827709503b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:40:24 +1000 Subject: radeon: don't copy to user the cs ids --- shared-core/radeon_cs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 452f04b4..14f3dcd9 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -45,7 +45,7 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) /* 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"); @@ -160,7 +160,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) dev_priv->cs.id_emit(dev, &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(&parser); @@ -190,7 +191,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) /* 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"); @@ -251,7 +252,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) dev_priv->cs.id_emit(dev, &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(&parser); drm_free(packets, size, DRM_MEM_DRIVER); -- cgit v1.2.3 From 6000fa686294019e93f815433a1a9b44db511a69 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:40:52 +1000 Subject: radeon: CS2 make it all work with new relocs style --- linux-core/radeon_gem.c | 47 +++++++++++++++++++++++++++++++++++++++----- shared-core/radeon_cs.c | 52 ++++++++++++++++++++++++++++++------------------- 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 7899490f..851a95d3 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -1242,21 +1242,58 @@ static int radeon_gem_ib_destroy(struct drm_device *dev) return 0; } +static int radeon_gem_find_reloc(struct drm_radeon_cs_parser *parser, + uint32_t offset, uint32_t *handle, + uint32_t *read_domains, uint32_t *write_domain) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index]; + + if (!reloc_chunk->kdata) + return -EINVAL; + + if (offset > reloc_chunk->length_dw){ + DRM_ERROR("Offset larger than chunk %d %d\n", offset, reloc_chunk->length_dw); + return -EINVAL; + } + + *handle = reloc_chunk->kdata[offset]; + *read_domains = reloc_chunk->kdata[offset + 1]; + *write_domain = reloc_chunk->kdata[offset + 2]; + return 0; +} + static int radeon_gem_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint32_t *offset) { struct drm_device *dev = parser->dev; drm_radeon_private_t *dev_priv = dev->dev_private; /* relocate the handle */ - uint32_t read_domains = reloc[2]; - uint32_t write_domain = reloc[3]; + uint32_t read_domains, write_domain; struct drm_gem_object *obj; int flags = 0; + int ret; struct drm_radeon_gem_object *obj_priv; - obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]); - if (!obj) - return -EINVAL; + if (parser->reloc_index == -1) { + obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]); + if (!obj) + return -EINVAL; + read_domains = reloc[2]; + write_domain = reloc[3]; + } else { + uint32_t handle; + + /* have to lookup handle in other chunk */ + ret = radeon_gem_find_reloc(parser, reloc[1], &handle, &read_domains, &write_domain); + if (ret < 0) + return ret; + + obj = drm_gem_object_lookup(dev, parser->file_priv, handle); + if (!obj) + return -EINVAL; + } obj_priv = obj->driver_private; radeon_gem_set_domain(obj, read_domains, write_domain, &flags, false); diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 14f3dcd9..31cd53db 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -68,6 +68,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) goto out; } + parser.dev = dev; + parser.file_priv = fpriv; parser.reloc_index = -1; parser.ib_index = -1; parser.num_chunks = cs->num_chunks; @@ -103,24 +105,29 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) 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_RELOCS: case RADEON_CHUNK_ID_IB: - case RADEON_CHUNK_ID_OLD: { - /* copy from user the relocs chunk */ - int size = parser.chunks[i].length_dw * sizeof(uint32_t); - parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); - if (!parser.chunks[i].kdata) { - r = -ENOMEM; + case RADEON_CHUNK_ID_OLD: + if (size == 0) { + r = -EINVAL; goto out; } - - if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { - r = -EFAULT; - 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; @@ -266,6 +273,7 @@ static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *r 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_radeon_cs_parser *parser, uint32_t offset_dw) @@ -288,9 +296,17 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa /* 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: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg); - 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) { @@ -371,9 +387,7 @@ static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser, int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) { - drm_radeon_private_t *dev_priv = parser->dev->dev_private; uint32_t hdr, num_dw, reg; - int need_reloc = 0; int count_dw = 1; int ret; @@ -422,8 +436,6 @@ int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw) int radeon_cs_parse(struct drm_radeon_cs_parser *parser) { - struct drm_device *dev = parser->dev; - drm_radeon_private_t *dev_priv = parser->dev->dev_private; volatile int rb; struct drm_radeon_kernel_chunk *ib_chunk; /* scan the packet for various things */ -- cgit v1.2.3 From e57072b5ee521ec799d0aa0ef84a7d01d8479202 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:41:12 +1000 Subject: radeon: fix free after refcount --- linux-core/radeon_display.c | 6 +++++- linux-core/radeon_fb.c | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index 679244a9..f16288ef 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -601,7 +601,11 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) if (fb->fbdev) radeonfb_remove(dev, fb); - drm_gem_object_unreference(radeon_fb->obj); + if (radeon_fb->obj) { + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(radeon_fb->obj); + mutex_unlock(&dev->struct_mutex); + } drm_framebuffer_cleanup(fb); kfree(radeon_fb); } diff --git a/linux-core/radeon_fb.c b/linux-core/radeon_fb.c index 405f1da9..d3722c37 100644 --- a/linux-core/radeon_fb.c +++ b/linux-core/radeon_fb.c @@ -1149,6 +1149,7 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) drm_bo_kunmap(&radeon_fb->kmap_obj); mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(radeon_fb->obj); + radeon_fb->obj = NULL; mutex_unlock(&dev->struct_mutex); framebuffer_release(info); } -- cgit v1.2.3 From f5e6dbef797cff18953e4f3271e1c74a0b24b715 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:41:30 +1000 Subject: radeon: fix some warnings --- linux-core/radeon_gem.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 851a95d3..6c62620a 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -126,7 +126,6 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_radeon_gem_object *obj_priv; struct drm_gem_object *obj; int ret = 0; - uint32_t flags; int handle; /* create a gem object to contain this object in */ @@ -157,8 +156,6 @@ fail: int radeon_gem_set_domain(struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain, uint32_t *flags_p, bool unfenced) { - struct drm_device *dev = obj->dev; - drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_radeon_gem_object *obj_priv; uint32_t flags = 0; int ret; @@ -616,7 +613,7 @@ static int radeon_gart_init(struct drm_device *dev) base = dev->agp->base; if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { - DRM_INFO("Can't use agp base @0x%08xlx, won't fit\n", + DRM_INFO("Can't use agp base @0x%08lx, won't fit\n", dev->agp->base); base = 0; } @@ -732,7 +729,7 @@ int radeon_alloc_gart_objects(struct drm_device *dev) return -EINVAL; } - DRM_DEBUG("Ring ptr %p mapped at %d %p, read ptr %p maped at %d %p\n", + DRM_DEBUG("Ring ptr %p mapped at %ld %p, read ptr %p maped at %ld %p\n", dev_priv->mm.ring.bo, dev_priv->mm.ring.bo->offset, dev_priv->mm.ring.kmap.virtual, dev_priv->mm.ring_read.bo, dev_priv->mm.ring_read.bo->offset, dev_priv->mm.ring_read.kmap.virtual); @@ -829,7 +826,6 @@ static void radeon_wait_for_vsync(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; uint32_t crtc_gen_cntl; - int ret; crtc_gen_cntl = RADEON_READ(RADEON_CRTC_GEN_CNTL); if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) || @@ -848,7 +844,6 @@ static void radeon_wait_for_vsync2(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; uint32_t crtc2_gen_cntl; - struct timeval timeout; crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || @@ -917,7 +912,6 @@ void radeon_init_memory_map(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; u32 mem_size, aper_size; - u32 tmp; dev_priv->mc_fb_location = radeon_read_fb_location(dev_priv); radeon_read_agp_location(dev_priv, &dev_priv->mc_agp_loc_lo, &dev_priv->mc_agp_loc_hi); @@ -1581,7 +1575,7 @@ static int radeon_gem_dma_bufs_init(struct drm_device *dev) DRM_DEBUG("\n"); radeon_gem_addbufs(dev); - DRM_DEBUG("%x %d\n", dev_priv->mm.dma_bufs.bo->map_list.hash.key, size); + DRM_DEBUG("%lx %d\n", dev_priv->mm.dma_bufs.bo->map_list.hash.key, size); dev->agp_buffer_token = dev_priv->mm.dma_bufs.bo->map_list.hash.key << PAGE_SHIFT; dev_priv->mm.fake_agp_map.handle = dev_priv->mm.dma_bufs.kmap.virtual; dev_priv->mm.fake_agp_map.size = size; -- cgit v1.2.3 From 4ccec67a239517458bace47bf08f6770393abb37 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:42:01 +1000 Subject: radeon: remove unused gem indirect ioctl --- linux-core/radeon_gem.c | 75 ---------------------------------------------- shared-core/radeon_drm.h | 6 ---- shared-core/radeon_drv.h | 2 -- shared-core/radeon_state.c | 1 - 4 files changed, 84 deletions(-) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 6c62620a..ce33979e 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -424,81 +424,6 @@ int radeon_gem_execbuffer(struct drm_device *dev, void *data, } -int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_radeon_gem_indirect *args = data; - struct drm_radeon_private *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_radeon_gem_object *obj_priv; - uint32_t start, end; - int ret; - RING_LOCALS; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EINVAL; - - obj_priv = obj->driver_private; - - DRM_DEBUG("got here %p %d\n", obj, args->used); - //RING_SPACE_TEST_WITH_RETURN(dev_priv); - //VB_AGE_TEST_WITH_RETURN(dev_priv); - - ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT, - 0 , 0); - if (ret) - return ret; - - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - - start = 0; - end = args->used; - - if (start != end) { - int offset = (dev_priv->gart_vm_start + - + obj_priv->bo->offset + start); - int dwords = (end - start + 3) / sizeof(u32); - - /* Fire off the indirect buffer */ - BEGIN_RING(3); - - OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); - OUT_RING(offset); - OUT_RING(dwords); - - ADVANCE_RING(); - } - - COMMIT_RING(); - - /* we need to fence the buffer */ - ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &obj_priv->fence); - if (ret) { - - drm_putback_buffer_objects(dev); - ret = 0; - goto fail; - } - - /* dereference he fence object */ - drm_fence_usage_deref_unlocked(&obj_priv->fence); - - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - ret = 0; - fail: - return ret; -} - /* * Depending on card genertation, chipset bugs, etc... the amount of vram * accessible to the CPU can vary. This function is our best shot at figuring diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index bc2eb45a..0780eb7f 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -511,7 +511,6 @@ 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_CS 0x25 #define DRM_RADEON_CS2 0x26 @@ -552,7 +551,6 @@ 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_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) @@ -866,10 +864,6 @@ 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. */ diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index b741953b..73e5a261 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1688,8 +1688,6 @@ 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); struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment, diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index f0cd6f89..40ecf1c4 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3288,7 +3288,6 @@ 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_CS, radeon_cs_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH), }; -- cgit v1.2.3 From fc25c81eab2d847c854e0a44cae29f8c2213bba6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:43:29 +1000 Subject: radeon: rs480 fixes for bus mastering --- shared-core/radeon_cp.c | 15 ++++++++------- shared-core/radeon_drv.h | 5 +++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 8e97f034..942ccc51 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -198,15 +198,16 @@ void radeon_enable_bm(struct drm_radeon_private *dev_priv) { u32 tmp; /* Turn on bus mastering */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - /* rs400, rs690/rs740 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; + /* 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_RV380) || - ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { - /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ + } 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 */ diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 73e5a261..85a22e9f 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -591,7 +591,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) @@ -1053,6 +1057,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 -- cgit v1.2.3 From 31f8d4218c0f6455751d8bbc788172912359b0df Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:44:03 +1000 Subject: radeon: add wait rendering API --- linux-core/radeon_gem.c | 25 ++++++++++++++++++++++--- shared-core/radeon_drm.h | 6 ++++-- shared-core/radeon_drv.h | 2 ++ shared-core/radeon_state.c | 1 + 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index ce33979e..f5d6b94a 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -416,14 +416,33 @@ int radeon_gem_busy(struct drm_device *dev, void *data, return 0; } -int radeon_gem_execbuffer(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) { - return -ENOSYS; + struct drm_radeon_gem_wait_rendering *args = data; + struct drm_gem_object *obj; + struct drm_radeon_gem_object *obj_priv; + int ret; + + + obj = drm_gem_object_lookup(dev, file_priv, args->handle); + if (obj == NULL) + return -EINVAL; + obj_priv = obj->driver_private; + mutex_lock(&obj_priv->bo->mutex); + ret = drm_bo_wait(obj_priv->bo, 0, 1, 1, 0); + mutex_unlock(&obj_priv->bo->mutex); + + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + return ret; } + + /* * Depending on card genertation, chipset bugs, etc... the amount of vram * accessible to the CPU can vary. This function is our best shot at figuring diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 0780eb7f..002e4004 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -511,6 +511,7 @@ 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_WAIT_RENDERING 0x24 #define DRM_RADEON_CS 0x25 #define DRM_RADEON_CS2 0x26 @@ -551,7 +552,7 @@ 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_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) @@ -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 { diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 85a22e9f..aa178d4d 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1695,6 +1695,8 @@ int radeon_gem_object_pin(struct drm_gem_object *obj, int radeon_gem_object_unpin(struct drm_gem_object *obj); 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); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 40ecf1c4..ada91362 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3288,6 +3288,7 @@ 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_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), }; -- cgit v1.2.3 From be3dac976e07fbfd727a2d0216ea9ba3247db348 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:44:32 +1000 Subject: radeon: only enable dynclks if asked for --- linux-core/radeon_drv.c | 2 +- shared-core/radeon_cp.c | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index f1fe3012..daa335b9 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -37,7 +37,7 @@ #include "drm_pciids.h" int radeon_no_wb; -int radeon_dynclks = 1; +int radeon_dynclks = -1; int radeon_r4xx_atom = 0; int radeon_agpmode = 0; diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 942ccc51..3f8f0c94 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2601,19 +2601,23 @@ int radeon_static_clocks_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - 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); + 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; } -- cgit v1.2.3 From 4ef8ace9a96bd6bb4040ef5c4c3ea5572d7129e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:45:43 +1000 Subject: radeon: add proc debugging for interrupts/ring --- linux-core/Makefile.kernel | 2 +- linux-core/radeon_drv.c | 2 + linux-core/radeon_gem_proc.c | 143 +++++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_drv.h | 3 + shared-core/radeon_irq.c | 1 + 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 linux-core/radeon_gem_proc.c diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 392abaf9..98616e4b 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -44,7 +44,7 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon_gem.o \ radeon_buffer.o radeon_fence.o atom.o radeon_display.o radeon_atombios.o radeon_i2c.o radeon_connectors.o radeon_cs.o \ atombios_crtc.o radeon_encoders.o radeon_fb.o radeon_combios.o radeon_legacy_crtc.o radeon_legacy_encoders.o \ - radeon_cursor.o radeon_pm.o + radeon_cursor.o radeon_pm.o radeon_gem_proc.o sis-objs := sis_drv.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o savage-objs := savage_drv.o savage_bci.o savage_state.o diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index daa335b9..3bc0c057 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -122,6 +122,8 @@ static struct drm_driver driver = { .dma_ioctl = radeon_cp_buffers, .master_create = radeon_master_create, .master_destroy = radeon_master_destroy, + .proc_init = radeon_gem_proc_init, + .proc_cleanup = radeon_gem_proc_cleanup, .fops = { .owner = THIS_MODULE, .open = drm_open, diff --git a/linux-core/radeon_gem_proc.c b/linux-core/radeon_gem_proc.c new file mode 100644 index 00000000..d3b467b1 --- /dev/null +++ b/linux-core/radeon_gem_proc.c @@ -0,0 +1,143 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * Keith Packard + * + */ + +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" + + +static int radeon_ring_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data) +{ + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + int len = 0; + + if (offset > DRM_PROC_LIMIT) { + *eof = 1; + return 0; + } + + *start = &buf[offset]; + *eof = 0; + DRM_PROC_PRINT("RADEON_CP_RB_WPTR %08x\n", + RADEON_READ(RADEON_CP_RB_WPTR)); + + DRM_PROC_PRINT("RADEON_CP_RB_RPTR %08x\n", + RADEON_READ(RADEON_CP_RB_RPTR)); + + + if (len > request + offset) + return request; + *eof = 1; + return len - offset; +} + +static int radeon_interrupt_info(char *buf, char **start, off_t offset, + int request, int *eof, void *data) +{ + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + int len = 0; + + if (offset > DRM_PROC_LIMIT) { + *eof = 1; + return 0; + } + + *start = &buf[offset]; + *eof = 0; + DRM_PROC_PRINT("Interrupt enable: %08x\n", + RADEON_READ(RADEON_GEN_INT_CNTL)); + + if (dev_priv->chip_family >= CHIP_RS690) { + DRM_PROC_PRINT("DxMODE_INT_MASK: %08x\n", + RADEON_READ(R500_DxMODE_INT_MASK)); + } + DRM_PROC_PRINT("Interrupts received: %d\n", + atomic_read(&dev_priv->irq_received)); + DRM_PROC_PRINT("Current sequence: %d\n", + READ_BREADCRUMB(dev_priv)); + DRM_PROC_PRINT("Counter sequence: %d\n", + dev_priv->counter); + + + if (len > request + offset) + return request; + *eof = 1; + return len - offset; +} + +static struct drm_proc_list { + /** file name */ + const char *name; + /** proc callback*/ + int (*f) (char *, char **, off_t, int, int *, void *); +} radeon_gem_proc_list[] = { + {"radeon_gem_interrupt", radeon_interrupt_info}, + {"radeon_gem_ring", radeon_ring_info}, +}; + + +#define RADEON_GEM_PROC_ENTRIES ARRAY_SIZE(radeon_gem_proc_list) + +int radeon_gem_proc_init(struct drm_minor *minor) +{ + struct proc_dir_entry *ent; + int i, j; + + for (i = 0; i < RADEON_GEM_PROC_ENTRIES; i++) { + ent = create_proc_entry(radeon_gem_proc_list[i].name, + S_IFREG | S_IRUGO, minor->dev_root); + if (!ent) { + DRM_ERROR("Cannot create /proc/dri/.../%s\n", + radeon_gem_proc_list[i].name); + for (j = 0; j < i; j++) + remove_proc_entry(radeon_gem_proc_list[i].name, + minor->dev_root); + return -1; + } + ent->read_proc = radeon_gem_proc_list[i].f; + ent->data = minor; + } + return 0; +} + +void radeon_gem_proc_cleanup(struct drm_minor *minor) +{ + int i; + + if (!minor->dev_root) + return; + + for (i = 0; i < RADEON_GEM_PROC_ENTRIES; i++) + remove_proc_entry(radeon_gem_proc_list[i].name, minor->dev_root); +} diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index aa178d4d..8f77c850 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -459,6 +459,7 @@ typedef struct drm_radeon_private { struct drm_radeon_cs_priv cs; struct radeon_pm_regs pmregs; + atomic_t irq_received; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -1718,6 +1719,8 @@ 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..311901c0 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 */ -- cgit v1.2.3 From ce2cd141c36f330da7e9fb9a281e51abab88e0d1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:46:07 +1000 Subject: radeon: fix race in sysfs --- linux-core/radeon_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index 3bc0c057..f7881720 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -60,8 +60,12 @@ module_param_named(agpmode, radeon_agpmode, int, 0444); static int dri_library_name(struct drm_device * dev, char * buf) { drm_radeon_private_t *dev_priv = dev->dev_private; - int family = dev_priv->flags & RADEON_FAMILY_MASK; + int family; + if (!dev_priv) + return 0; + + family = dev_priv->flags & RADEON_FAMILY_MASK; return snprintf(buf, PAGE_SIZE, "%s\n", (family < CHIP_R200) ? "radeon" : ((family < CHIP_R300) ? "r200" : -- cgit v1.2.3 From 31b8a640db9b55638bf9967f0d78ec665fa8839f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:46:54 +1000 Subject: radeon: overhaul ring interactions emit in 16-dword blocks, emit irqs at same time as everything else --- linux-core/radeon_buffer.c | 10 ++++-- linux-core/radeon_fence.c | 1 - linux-core/radeon_gem.c | 5 +-- shared-core/radeon_cs.c | 84 ++++++++++++++++++++++++++++------------------ shared-core/radeon_drv.h | 6 ++-- shared-core/radeon_irq.c | 16 +++++---- 6 files changed, 77 insertions(+), 45 deletions(-) diff --git a/linux-core/radeon_buffer.c b/linux-core/radeon_buffer.c index e88378a4..571a0b9c 100644 --- a/linux-core/radeon_buffer.c +++ b/linux-core/radeon_buffer.c @@ -170,10 +170,12 @@ void radeon_emit_copy_blit(struct drm_device * dev, ADVANCE_RING(); } - BEGIN_RING(4); + BEGIN_RING(6); OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0)); OUT_RING(RADEON_RB2D_DC_FLUSH_ALL); RADEON_WAIT_UNTIL_2D_IDLE(); + OUT_RING(CP_PACKET2()); + OUT_RING(CP_PACKET2()); ADVANCE_RING(); COMMIT_RING(); @@ -265,10 +267,14 @@ void radeon_emit_solid_fill(struct drm_device * dev, ADVANCE_RING(); } - BEGIN_RING(4); + BEGIN_RING(8); OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0)); OUT_RING(RADEON_RB2D_DC_FLUSH_ALL); RADEON_WAIT_UNTIL_2D_IDLE(); + OUT_RING(CP_PACKET2()); + OUT_RING(CP_PACKET2()); + OUT_RING(CP_PACKET2()); + OUT_RING(CP_PACKET2()); ADVANCE_RING(); COMMIT_RING(); diff --git a/linux-core/radeon_fence.c b/linux-core/radeon_fence.c index 591ad53b..b662da21 100644 --- a/linux-core/radeon_fence.c +++ b/linux-core/radeon_fence.c @@ -39,7 +39,6 @@ int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class, uint32_t *native_type) { struct drm_radeon_private *dev_priv = (struct drm_radeon_private *) dev->dev_private; - RING_LOCALS; if (!dev_priv) return -EINVAL; diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index f5d6b94a..a785041e 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -1086,7 +1086,7 @@ int radeon_gem_object_unpin(struct drm_gem_object *obj) #define RADEON_NUM_IB (RADEON_IB_MEMORY / RADEON_IB_SIZE) -int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser, uint32_t *card_offset) +int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser) { int i, index = -1; int ret; @@ -1132,8 +1132,8 @@ int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser, uint32_t *card_offset return -EINVAL; } - *card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset; parser->ib = dev_priv->ib_objs[index]->kmap.virtual; + parser->card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset; dev_priv->ib_alloc_bitmap |= (1 << i); return 0; } @@ -1150,6 +1150,7 @@ static void radeon_gem_ib_free(struct drm_radeon_cs_parser *parser) if (dev_priv->ib_objs[i]->kmap.virtual == parser->ib) { /* emit a fence object */ ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); + dev_priv->irq_emitted = 0; if (ret) { drm_putback_buffer_objects(dev); } diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 31cd53db..4a231962 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -38,10 +38,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; uint64_t *chunk_array; uint64_t *chunk_array_ptr; - uint32_t card_offset; long size; int r, i; - RING_LOCALS; /* set command stream id to 0 which is fake id */ cs_id = 0; @@ -144,7 +142,7 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) } /* get ib */ - r = dev_priv->cs.ib_get(&parser, &card_offset); + r = dev_priv->cs.ib_get(&parser); if (r) { DRM_ERROR("ib_get failed\n"); goto out; @@ -156,16 +154,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) goto out; } - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); - OUT_RING(card_offset); - OUT_RING(parser.chunks[parser.ib_index].length_dw); - OUT_RING(CP_PACKET2()); - ADVANCE_RING(); - /* emit cs id sequence */ - dev_priv->cs.id_emit(dev, &cs_id); - COMMIT_RING(); + dev_priv->cs.id_emit(&parser, &cs_id); cs->cs_id = cs_id; @@ -194,7 +184,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) long size; int r; struct drm_radeon_kernel_chunk chunk_fake[1]; - RING_LOCALS; /* set command stream id to 0 which is fake id */ cs_id = 0; @@ -237,7 +226,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) parser.reloc_index = -1; /* get ib */ - r = dev_priv->cs.ib_get(&parser, &card_offset); + r = dev_priv->cs.ib_get(&parser); if (r) { goto out; } @@ -248,15 +237,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) 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(); cs->cs_id = cs_id; @@ -518,37 +500,75 @@ 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) diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 8f77c850..83478a27 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -308,6 +308,7 @@ struct drm_radeon_cs_parser { struct drm_radeon_kernel_chunk *chunks; int ib_index; int reloc_index; + uint32_t card_offset; void *ib; }; @@ -319,12 +320,12 @@ struct drm_radeon_cs_priv { uint32_t id_last_scnt; int (*parse)(struct drm_radeon_cs_parser *parser); - void (*id_emit)(struct drm_device *dev, uint32_t *id); + 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_radeon_cs_parser *parser, 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_radeon_cs_parser *parser); /* do a relocation either MM or non-MM */ @@ -459,6 +460,7 @@ typedef struct drm_radeon_private { struct drm_radeon_cs_priv cs; struct radeon_pm_regs pmregs; + int irq_emitted; atomic_t irq_received; } drm_radeon_private_t; diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 311901c0..46a27943 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -223,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; } -- cgit v1.2.3 From 13d9acd3110a32d94434311821362900a9463cf4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:47:14 +1000 Subject: radeon: add more debugging --- linux-core/radeon_gem_proc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/linux-core/radeon_gem_proc.c b/linux-core/radeon_gem_proc.c index d3b467b1..04f5a5fc 100644 --- a/linux-core/radeon_gem_proc.c +++ b/linux-core/radeon_gem_proc.c @@ -84,10 +84,13 @@ static int radeon_interrupt_info(char *buf, char **start, off_t offset, } DRM_PROC_PRINT("Interrupts received: %d\n", atomic_read(&dev_priv->irq_received)); - DRM_PROC_PRINT("Current sequence: %d\n", - READ_BREADCRUMB(dev_priv)); + DRM_PROC_PRINT("Current sequence: %d %d\n", + READ_BREADCRUMB(dev_priv), RADEON_READ(RADEON_SCRATCH_REG3)); DRM_PROC_PRINT("Counter sequence: %d\n", dev_priv->counter); + if (dev_priv->chip_family >= CHIP_R300) + DRM_PROC_PRINT("CS: %d\n", + GET_SCRATCH(6)); if (len > request + offset) -- cgit v1.2.3 From e829d5b6bc9f5887c82653c007641c3c37f7ae67 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:47:49 +1000 Subject: radeon: setup isync cntl properly --- shared-core/radeon_cp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 3f8f0c94..1c187b15 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -591,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(); -- cgit v1.2.3 From cdddff835510eca179ac289f41a1771093939901 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:48:10 +1000 Subject: radeon: enable DVI-D + HDMI connectors. This allows the rs690 to work on DVI --- linux-core/radeon_connectors.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/linux-core/radeon_connectors.c b/linux-core/radeon_connectors.c index 8de21997..18873f0f 100644 --- a/linux-core/radeon_connectors.c +++ b/linux-core/radeon_connectors.c @@ -305,8 +305,11 @@ static struct connector_funcs { { CONNECTOR_LVDS, &radeon_lvds_connector_funcs, &radeon_lvds_connector_helper_funcs, DRM_MODE_CONNECTOR_LVDS, "LVDS" }, { CONNECTOR_DVI_A, &radeon_vga_connector_funcs, &radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_DVIA, "DVI" }, { CONNECTOR_DVI_I, &radeon_dvi_connector_funcs, &radeon_dvi_connector_helper_funcs, DRM_MODE_CONNECTOR_DVII, "DVI" }, - + { CONNECTOR_DVI_D, &radeon_dvi_connector_funcs, &radeon_dvi_connector_helper_funcs, DRM_MODE_CONNECTOR_DVID, "DVI" }, + { CONNECTOR_HDMI_TYPE_A, &radeon_dvi_connector_funcs, &radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_HDMIA, "HDMI" }, + { CONNECTOR_HDMI_TYPE_B, &radeon_dvi_connector_funcs, &radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_HDMIB, "HDMI" }, #if 0 + { CONNECTOR_HDMI_TYPE_A, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, { CONNECTOR_DVI_D, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, { CONNECTOR_STV, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, @@ -314,7 +317,6 @@ static struct connector_funcs { { CONNECTOR_DIGITAL, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, { CONNECTOR_SCART, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, - { CONNECTOR_HDMI_TYPE_A, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, { CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, { CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, { CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA }, -- cgit v1.2.3 From 49551f87fcd21e10a4485b3e00af47f0b9f94a0f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:49:41 +1000 Subject: radeon: set dma bufs bo type to a kernel type --- linux-core/radeon_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index a785041e..f39e8b47 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -1502,7 +1502,7 @@ static int radeon_gem_dma_bufs_init(struct drm_device *dev) if (ret < 0) return ret; - ret = drm_buffer_object_create(dev, size, drm_bo_type_device, + ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MAPPABLE, 0, 0, 0, &dev_priv->mm.dma_bufs.bo); -- cgit v1.2.3 From c153a86af7e4e782e55565f882ef2c8618650150 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:49:59 +1000 Subject: radeon: add more HDMI bits --- linux-core/radeon_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index f16288ef..0b9467fd 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -263,7 +263,9 @@ bool radeon_setup_enc_conn(struct drm_device *dev) /* TMDS on DVI */ if ((mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_I) || - (mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D)) { + (mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D) || + (mode_info->bios_connector[i].connector_type == CONNECTOR_HDMI_TYPE_A) || + (mode_info->bios_connector[i].connector_type == CONNECTOR_HDMI_TYPE_B)) { if (radeon_is_avivo(dev_priv) || radeon_r4xx_atom) encoder = radeon_encoder_atom_tmds_add(dev, i, mode_info->bios_connector[i].tmds_type); else { -- cgit v1.2.3 From 28c9eb7b7493ee2478df66476c742432525f1efa Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:50:46 +1000 Subject: radeon: commit ring after emitting the buffer discards --- shared-core/radeon_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index ada91362..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; -- cgit v1.2.3 From d3aa052f6174ea37136574b68ed55d7cb82c5017 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:51:33 +1000 Subject: radeon: disable debugging message --- shared-core/radeon_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } -- cgit v1.2.3 From 2b9a7d5381534122858dc6e407794e8cd5c04d3e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:51:57 +1000 Subject: radeon: disable AGP for certain chips if not specified until we figure it out --- shared-core/radeon_cp.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 1c187b15..71914782 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2669,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; + } } -- cgit v1.2.3 From 0e1df6216e7ce3a69d4311e4685613e57129285f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:52:25 +1000 Subject: radeon: add mtrr support for VRAM aperture. --- linux-core/radeon_gem.c | 6 ++++++ shared-core/radeon_drv.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index f39e8b47..2e20de3c 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -947,6 +947,10 @@ void radeon_init_memory_map(struct drm_device *dev) - dev_priv->fb_location; } + /* add an MTRR for the VRAM */ + dev_priv->aper_size = aper_size; + dev_priv->vram_mtrr = mtrr_add(dev_priv->fb_aper_offset, dev_priv->aper_size, MTRR_TYPE_WRCOMB, 1); + } /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ @@ -1037,6 +1041,8 @@ void radeon_gem_mm_fini(struct drm_device *dev) DRM_DEBUG("delaying takedown of VRAM memory\n"); } + if (dev_priv->vram_mtrr) + mtrr_del(dev_priv->vram_mtrr, dev_priv->fb_aper_offset, dev_priv->aper_size); mutex_unlock(&dev->struct_mutex); drm_bo_driver_finish(dev); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 83478a27..c6ebf9b6 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -462,6 +462,9 @@ typedef struct drm_radeon_private { 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 { -- cgit v1.2.3 From b7108445c9ebb37d06fcc7821e984124fda928f3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:52:40 +1000 Subject: radeon: fix ROP values for the paint ROP --- linux-core/radeon_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-core/radeon_buffer.c b/linux-core/radeon_buffer.c index 571a0b9c..f047b1ac 100644 --- a/linux-core/radeon_buffer.c +++ b/linux-core/radeon_buffer.c @@ -254,7 +254,8 @@ void radeon_emit_solid_fill(struct drm_device * dev, RADEON_GMC_DST_CLIPPING | RADEON_GMC_BRUSH_SOLID_COLOR | (format << 8) | - RADEON_ROP3_S | + RADEON_ROP3_P | + RADEON_CLR_CMP_SRC_SOURCE | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); OUT_RING((pitch << 22) | (dst_offset >> 10)); // PITCH OUT_RING(0); // SC_TOP_LEFT // DST CLIPPING -- cgit v1.2.3 From 68fcb7770efc20b9e27b1724e2fb5ac112a5330e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 3 Nov 2008 09:58:12 +1000 Subject: radeon: make build again --- linux-core/radeon_drv.c | 2 +- shared-core/radeon_cp.c | 9 --------- shared-core/radeon_cs.c | 2 +- shared-core/radeon_drv.h | 1 + 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index f7881720..f4194688 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -44,7 +44,7 @@ int radeon_agpmode = 0; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); module_param_named(no_wb, radeon_no_wb, int, 0444); -unsigned int radeon_modeset = 0; +int radeon_modeset = 0; module_param_named(modeset, radeon_modeset, int, 0400); MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks"); diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 71914782..9a1e0e02 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2793,15 +2793,6 @@ int radeon_driver_firstopen(struct drm_device *dev) 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; } diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c index 4a231962..3dde321d 100644 --- a/shared-core/radeon_cs.c +++ b/shared-core/radeon_cs.c @@ -313,7 +313,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa case R200_PP_TXOFFSET_1: case RADEON_PP_TXOFFSET_0: case RADEON_PP_TXOFFSET_1: - ret = dev_priv->cs.relocate(parser. ib_chunk->kdata + offset_dw + 2, &offset); + ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset); if (ret) return ret; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index c6ebf9b6..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, -- cgit v1.2.3