From bdc5a8b62ef2f59e05f69da2150212c0243f6efb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 1 Apr 2007 19:09:00 +1000 Subject: radeon: enable buffer manager --- shared-core/radeon_cp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index e02796e7..93c75d10 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2244,6 +2244,9 @@ int radeon_driver_firstopen(struct drm_device *dev) if (ret != 0) return ret; +#ifdef RADEON_HAVE_BUFFER + drm_bo_driver_init(dev); +#endif return 0; } -- cgit v1.2.3 From 4294dcc050c5d2685f633e8a52deb925d806be85 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 12:26:06 +1000 Subject: complete PCIE backend for ttm ttm test runs with it at least, needs to do more testing on it --- shared-core/radeon_cp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 56d17b9a..9dc871ca 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1384,6 +1384,26 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } + +void radeon_gart_flush(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (dev_priv->flags & RADEON_IS_IGPGART) { + RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); + RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1); + RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); + RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); + } else if (dev_priv->flags & RADEON_IS_PCIE) { + + + } else { + + + } + +} + static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; -- cgit v1.2.3 From c9dbe0f2c2248ef8c3ba5718f77922d1c7429e6f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 12:38:43 +1000 Subject: invalidate gart tlb on PCIE after table change --- shared-core/radeon_cp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9dc871ca..2c0549e5 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1395,8 +1395,11 @@ void radeon_gart_flush(struct drm_device *dev) RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); } else if (dev_priv->flags & RADEON_IS_PCIE) { - - + u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); + tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB; + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); + tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB; + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); } else { -- cgit v1.2.3 From 75c9e0d3462f04766d490fac5cc93569957a8365 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 26 Feb 2008 23:30:45 +0100 Subject: radeon: remove TTM from an earlier merge --- shared-core/radeon_cp.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index f0eda664..ac46da38 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1518,28 +1518,6 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } -void radeon_gart_flush(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (dev_priv->flags & RADEON_IS_IGPGART) { - RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); - RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1); - RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); - RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); - } else if (dev_priv->flags & RADEON_IS_PCIE) { - u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); - tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB; - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB; - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - } else { - - - } - -} - static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2455,9 +2433,6 @@ int radeon_driver_firstopen(struct drm_device *dev) if (ret != 0) return ret; -#ifdef RADEON_HAVE_BUFFER - drm_bo_driver_init(dev); -#endif return 0; } -- cgit v1.2.3 From df9871064e8b564d9ae2e56d561b64434fd004af Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Jul 2008 08:56:23 +1000 Subject: radeon: add initial atombios modesetting and GEM -> TTM translation layer. This is an initial import of the atom bios parser with modesetting support for r500 hw using atombios. It also includes a simple memory manager layer that translates a radeon GEM style interface onto TTM internally. So far this memory manager has only been used for pinned object allocation for the DDX to test modesetting. --- shared-core/radeon_cp.c | 992 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 903 insertions(+), 89 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 819a61ae..80951e91 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -31,6 +31,7 @@ #include "drmP.h" #include "drm.h" +#include "drm_sarea.h" #include "radeon_drm.h" #include "radeon_drv.h" #include "r300_reg.h" @@ -75,6 +76,23 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) return RS480_READ_MCIND(dev_priv, addr); } +u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr) +{ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + return IGP_READ_MCIND(dev_priv, addr); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) + return R500_READ_MCIND(dev_priv, addr); + return 0; +} + +void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val) +{ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + IGP_WRITE_MCIND(addr, val); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) + R500_WRITE_MCIND(addr, val); +} + u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { @@ -133,12 +151,57 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) } } -static int RADEON_READ_PLL(struct drm_device * dev, int addr) + +void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv) { - drm_radeon_private_t *dev_priv = dev->dev_private; + if (!(dev_priv->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) + return; + + (void)RADEON_READ(RADEON_CLOCK_CNTL_DATA); + (void)RADEON_READ(RADEON_CRTC_GEN_CNTL); +} + +void radeon_pll_errata_after_data(struct drm_radeon_private *dev_priv) +{ + /* This workarounds is necessary on RV100, RS100 and RS200 chips + * or the chip could hang on a subsequent access + */ + if (dev_priv->pll_errata & CHIP_ERRATA_PLL_DELAY) + udelay(5000); + + /* This function is required to workaround a hardware bug in some (all?) + * revisions of the R300. This workaround should be called after every + * CLOCK_CNTL_INDEX register access. If not, register reads afterward + * may not be correct. + */ + if (dev_priv->pll_errata & CHIP_ERRATA_R300_CG) { + uint32_t save, tmp; + + save = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); + tmp = save & ~(0x3f | RADEON_PLL_WR_EN); + RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, tmp); + tmp = RADEON_READ(RADEON_CLOCK_CNTL_DATA); + RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, save); + } +} + +int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) +{ + uint32_t data; - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); - return RADEON_READ(RADEON_CLOCK_CNTL_DATA); + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f); + radeon_pll_errata_after_index(dev_priv); + data = RADEON_READ(RADEON_CLOCK_CNTL_DATA); + radeon_pll_errata_after_data(dev_priv); + return data; +} + +void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data) +{ + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, ((addr & 0x3f) | RADEON_PLL_WR_EN)); + radeon_pll_errata_after_index(dev_priv); + RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, data); + radeon_pll_errata_after_data(dev_priv); } static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) @@ -147,6 +210,39 @@ static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) return RADEON_READ(RADEON_PCIE_DATA); } +/* ATOM accessor methods */ +static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) +{ + uint32_t ret = radeon_read_mc_reg(info->dev->dev_private, reg); + + // DRM_DEBUG("(%x) = %x\n", reg, ret); + return ret; +} + +static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) +{ + // DRM_DEBUG("(%x, %x)\n", reg, val); + radeon_write_mc_reg(info->dev->dev_private, reg, val); +} + +static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) +{ + drm_radeon_private_t *dev_priv = info->dev->dev_private; + + // DRM_DEBUG("(%x, %x)\n", reg*4, val); + RADEON_WRITE(reg*4, val); +} + +static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) +{ + uint32_t ret; + drm_radeon_private_t *dev_priv = info->dev->dev_private; + + ret = RADEON_READ(reg*4); + // DRM_DEBUG("(%x) = %x\n", reg*4, ret); + return ret; +} + #if RADEON_FIFO_DEBUG static void radeon_status(drm_radeon_private_t * dev_priv) { @@ -298,7 +394,7 @@ static void radeon_init_pipes(drm_radeon_private_t * dev_priv) } if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); + RADEON_WRITE_PLL(dev_priv, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); } RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); @@ -491,15 +587,15 @@ static int radeon_do_engine_reset(struct drm_device * dev) if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { /* may need something similar for newer chips */ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); - mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); - - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | - RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC | - RADEON_FORCEON_AIC)); + mclk_cntl = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, (mclk_cntl | + RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB | + RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC | + RADEON_FORCEON_AIC)); } rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); @@ -524,7 +620,7 @@ static int radeon_do_engine_reset(struct drm_device * dev) RADEON_READ(RADEON_RBBM_SOFT_RESET); if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, mclk_cntl); RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); } @@ -540,7 +636,8 @@ static int radeon_do_engine_reset(struct drm_device * dev) dev_priv->cp_running = 0; /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset(dev); + if (dev->dma) + radeon_freelist_reset(dev); return 0; } @@ -558,9 +655,13 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, */ if (!dev_priv->new_memmap) radeon_write_fb_location(dev_priv, - ((dev_priv->gart_vm_start - 1) & 0xffff0000) - | (dev_priv->fb_location >> 16)); - + ((dev_priv->gart_vm_start - 1) & 0xffff0000) + | (dev_priv->fb_location >> 16)); + + if (dev_priv->mm.ring) { + ring_start = dev_priv->mm.ring->offset + + dev_priv->gart_vm_start; + } else #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { radeon_write_agp_base(dev_priv, dev->agp->base); @@ -590,6 +691,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, SET_RING_HEAD(dev_priv, cur_read_ptr); dev_priv->ring.tail = cur_read_ptr; + + if (dev_priv->mm.ring_read_ptr) { + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, + dev_priv->mm.ring_read_ptr->offset + + dev_priv->gart_vm_start); + } else #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, @@ -638,9 +745,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); - dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle + - (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + if (dev_priv->mm.ring_read_ptr) + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->mm.ring_read_ptr_map.virtual + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + else + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); @@ -648,15 +760,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; RADEON_WRITE(RADEON_BUS_CNTL, tmp); - dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; - RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); + dev_priv->scratch[0] = 0; + RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); - dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; - RADEON_WRITE(RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch); + dev_priv->scratch[1] = 0; + RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); - dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; - RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); + dev_priv->scratch[2] = 0; + RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); radeon_do_wait_for_idle(dev_priv); @@ -672,15 +783,21 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, static void radeon_test_writeback(drm_radeon_private_t * dev_priv) { u32 tmp; + void *ring_read_ptr; + + if (dev_priv->mm.ring_read_ptr) + ring_read_ptr = dev_priv->mm.ring_read_ptr_map.virtual; + else + ring_read_ptr = dev_priv->ring_rptr->handle; /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ - DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); + writel(0, ring_read_ptr + RADEON_SCRATCHOFF(1)); RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == + if (readl(ring_read_ptr + RADEON_SCRATCHOFF(1)) == 0xdeadbeef) break; DRM_UDELAY(1); @@ -813,7 +930,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) } /* Enable or disable PCI GART on the chip */ -static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) +void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; @@ -854,9 +971,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } -static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) +static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; DRM_DEBUG("\n"); @@ -897,17 +1016,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) */ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; - switch(init->func) { - case RADEON_INIT_R200_CP: - dev_priv->microcode_version = UCODE_R200; - break; - case RADEON_INIT_R300_CP: - dev_priv->microcode_version = UCODE_R300; - break; - default: - dev_priv->microcode_version = UCODE_R100; - } - dev_priv->do_boxes = 0; dev_priv->cp_mode = init->cp_mode; @@ -955,9 +1063,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) */ dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | (dev_priv->color_fmt << 10) | - (dev_priv->microcode_version == - UCODE_R100 ? RADEON_ZBLOCK16 : 0)); - + (dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0)); + dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | RADEON_Z_TEST_ALWAYS | @@ -984,8 +1091,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) dev_priv->buffers_offset = init->buffers_offset; dev_priv->gart_textures_offset = init->gart_textures_offset; - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { + master_priv->sarea = drm_getsarea(dev); + if (!master_priv->sarea) { DRM_ERROR("could not find sarea!\n"); radeon_do_cleanup_cp(dev); return -EINVAL; @@ -1021,10 +1128,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) } } - dev_priv->sarea_priv = - (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { drm_core_ioremap(dev_priv->cp_ring, dev); @@ -1155,28 +1258,41 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); /* if we have an offset set from userspace */ if (dev_priv->pcigart_offset_set) { - dev_priv->gart_info.bus_addr = - dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->pcigart_offset + dev_priv->fb_aper_offset; - dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; - - drm_core_ioremap(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; - - if (dev_priv->flags & RADEON_IS_PCIE) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - dev_priv->gart_info.gart_table_location = - DRM_ATI_GART_FB; - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", - dev_priv->gart_info.addr, - dev_priv->pcigart_offset); + /* if it came from userspace - remap it */ + if (dev_priv->pcigart_offset_set == 1) { + dev_priv->gart_info.bus_addr = + dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.mapping.offset = + dev_priv->pcigart_offset + dev_priv->fb_aper_offset; + dev_priv->gart_info.mapping.size = + dev_priv->gart_info.table_size; + + /* this is done by the mm now */ + drm_core_ioremap(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = + dev_priv->gart_info.mapping.handle; + + memset(dev_priv->gart_info.addr, 0, dev_priv->gart_info.table_size); + if (dev_priv->flags & RADEON_IS_PCIE) + dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; + else + dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; + dev_priv->gart_info.gart_table_location = + DRM_ATI_GART_FB; + + DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", + dev_priv->gart_info.addr, + dev_priv->pcigart_offset); + } } else { + + if (dev_priv->flags & RADEON_IS_PCIE) { + DRM_ERROR + ("Cannot use PCI Express without GART in FB memory\n"); + radeon_do_cleanup_cp(dev); + return -EINVAL; + } if (dev_priv->flags & RADEON_IS_IGPGART) dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; else @@ -1185,12 +1301,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) DRM_ATI_GART_MAIN; dev_priv->gart_info.addr = NULL; dev_priv->gart_info.bus_addr = 0; - if (dev_priv->flags & RADEON_IS_PCIE) { - DRM_ERROR - ("Cannot use PCI Express without GART in FB memory\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } + } if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { @@ -1253,8 +1364,10 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = 0; + if (dev_priv->pcigart_offset_set == 1) { + drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = NULL; + } } } /* only clear to the start of flags */ @@ -1305,6 +1418,10 @@ static int radeon_do_resume_cp(struct drm_device * dev) int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_init_t *init = data; + + /* on a modesetting driver ignore this stuff */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -1315,7 +1432,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri case RADEON_INIT_CP: case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: - return radeon_do_init_cp(dev, init); + return radeon_do_init_cp(dev, init, file_priv); case RADEON_CLEANUP_CP: return radeon_do_cleanup_cp(dev); } @@ -1328,6 +1445,9 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); if (dev_priv->cp_running) { @@ -1355,6 +1475,9 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri int ret; DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv->cp_running) @@ -1393,6 +1516,9 @@ void radeon_do_release(struct drm_device * dev) drm_radeon_private_t *dev_priv = dev->dev_private; int i, ret; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + if (dev_priv) { if (dev_priv->cp_running) { /* Stop the cp */ @@ -1431,6 +1557,9 @@ void radeon_do_release(struct drm_device * dev) radeon_mem_takedown(&(dev_priv->gart_heap)); radeon_mem_takedown(&(dev_priv->fb_heap)); + + radeon_gem_mm_fini(dev); + /* deallocate kernel resources */ radeon_do_cleanup_cp(dev); } @@ -1443,6 +1572,9 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { @@ -1463,7 +1595,9 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, file_priv); + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + LOCK_TEST_WITH_RETURN(dev, file_priv); return radeon_do_cp_idle(dev_priv); } @@ -1473,6 +1607,9 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + return radeon_do_resume_cp(dev); } @@ -1480,6 +1617,9 @@ int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *fil { DRM_DEBUG("\n"); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + LOCK_TEST_WITH_RETURN(dev, file_priv); return radeon_do_engine_reset(dev); @@ -1702,6 +1842,541 @@ int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_ return ret; } +static void radeon_get_vram_type(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t tmp; + + if (dev_priv->flags & RADEON_IS_IGP || (dev_priv->chip_family >= CHIP_R300)) + dev_priv->is_ddr = true; + else if (RADEON_READ(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR) + dev_priv->is_ddr = true; + else + dev_priv->is_ddr = false; + + if ((dev_priv->chip_family >= CHIP_R600) && + (dev_priv->chip_family <= CHIP_RV635)) { + int chansize; + + tmp = RADEON_READ(R600_RAMCFG); + if (tmp & R600_CHANSIZE_OVERRIDE) + chansize = 16; + else if (tmp & R600_CHANSIZE) + chansize = 64; + else + chansize = 32; + + if (dev_priv->chip_family == CHIP_R600) + dev_priv->ram_width = 8 * chansize; + else if (dev_priv->chip_family == CHIP_RV670) + dev_priv->ram_width = 4 * chansize; + else if ((dev_priv->chip_family == CHIP_RV610) || + (dev_priv->chip_family == CHIP_RV620)) + dev_priv->ram_width = chansize; + else if ((dev_priv->chip_family == CHIP_RV630) || + (dev_priv->chip_family == CHIP_RV635)) + dev_priv->ram_width = 2 * chansize; + } else if (dev_priv->chip_family == CHIP_RV515) { + tmp = radeon_read_mc_reg(dev_priv, RV515_MC_CNTL); + tmp &= RV515_MEM_NUM_CHANNELS_MASK; + switch (tmp) { + case 0: dev_priv->ram_width = 64; break; + case 1: dev_priv->ram_width = 128; break; + default: dev_priv->ram_width = 128; break; + } + } else if ((dev_priv->chip_family >= CHIP_R520) && + (dev_priv->chip_family <= CHIP_RV570)) { + tmp = radeon_read_mc_reg(dev_priv, R520_MC_CNTL0); + switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) { + case 0: dev_priv->ram_width = 32; break; + case 1: dev_priv->ram_width = 64; break; + case 2: dev_priv->ram_width = 128; break; + case 3: dev_priv->ram_width = 256; break; + default: dev_priv->ram_width = 128; break; + } + } else if ((dev_priv->chip_family == CHIP_RV100) || + (dev_priv->chip_family == CHIP_RS100) || + (dev_priv->chip_family == CHIP_RS200)) { + tmp = RADEON_READ(RADEON_MEM_CNTL); + if (tmp & RV100_HALF_MODE) + dev_priv->ram_width = 32; + else + dev_priv->ram_width = 64; + + if (dev_priv->flags & RADEON_SINGLE_CRTC) { + dev_priv->ram_width /= 4; + dev_priv->is_ddr = true; + } + } else if (dev_priv->chip_family <= CHIP_RV280) { + tmp = RADEON_READ(RADEON_MEM_CNTL); + if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) + dev_priv->ram_width = 128; + else + dev_priv->ram_width = 64; + } else { + /* newer IGPs */ + dev_priv->ram_width = 128; + } + DRM_DEBUG("RAM width %d bits %cDR\n", dev_priv->ram_width, dev_priv->is_ddr ? 'D' : 'S'); +} + +static void radeon_force_some_clocks(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t tmp; + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); +} + +static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t tmp; + + switch(mode) { + case 0: + if (dev_priv->flags & RADEON_SINGLE_CRTC) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | + RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | + RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | + RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | + RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | + RADEON_SCLK_FORCE_RB); + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + } else if (dev_priv->chip_family == CHIP_RV350) { + /* for RV350/M10, no delays are required. */ + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp |= (R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | + RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | + R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | + R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | + R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | + R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); + tmp |= RADEON_DYN_STOP_LAT_MASK; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | + R300_DVOCLK_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + R300_PIXCLK_DVO_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb | + R300_PIXCLK_TRANS_ALWAYS_ONb | + R300_PIXCLK_TVO_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + } else { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); + tmp |= RADEON_SCLK_FORCE_SE; + + if ( dev_priv->flags & RADEON_SINGLE_CRTC ) { + tmp |= ( RADEON_SCLK_FORCE_RB | + RADEON_SCLK_FORCE_TDM | + RADEON_SCLK_FORCE_TAM | + RADEON_SCLK_FORCE_PB | + RADEON_SCLK_FORCE_RE | + RADEON_SCLK_FORCE_VIP | + RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_DISP2 | + RADEON_SCLK_FORCE_HDP ); + } else if ((dev_priv->chip_family == CHIP_R300) || + (dev_priv->chip_family == CHIP_R350)) { + tmp |= ( RADEON_SCLK_FORCE_HDP | + RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_DISP2 | + RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP); + } + + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + udelay(16000); + + if ((dev_priv->chip_family == CHIP_R300) || + (dev_priv->chip_family == CHIP_R350)) { + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp |= ( R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + udelay(16000); + } + + if (dev_priv->flags & RADEON_IS_IGP) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + tmp &= ~(RADEON_FORCEON_MCLKA | + RADEON_FORCEON_YCLKA); + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp); + udelay(16000); + } + + if ((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250) || + (dev_priv->chip_family == CHIP_RV280)) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp |= RADEON_SCLK_MORE_FORCEON; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + udelay(16000); + } + + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb); + + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + udelay(16000); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + } + DRM_DEBUG("Dynamic Clock Scaling Disabled\n"); + break; + case 1: + if (dev_priv->flags & RADEON_SINGLE_CRTC) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + if ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) > + RADEON_CFG_ATI_REV_A13) { + tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB); + } + tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | + RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | + RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | + RADEON_SCLK_FORCE_TDM); + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + } else if ((dev_priv->chip_family == CHIP_R300) || + (dev_priv->chip_family == CHIP_R350) || + (dev_priv->chip_family == CHIP_RV350)) { + if (dev_priv->chip_family == CHIP_RV350) { + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp &= ~(R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | + R300_SCLK_GA_MAX_DYN_STOP_LAT | + R300_SCLK_CBA_MAX_DYN_STOP_LAT); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | + RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | + R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | + R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | + R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | + R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); + tmp |= RADEON_DYN_STOP_LAT_MASK; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | + R300_DVOCLK_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + R300_PIXCLK_DVO_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb | + R300_PIXCLK_TRANS_ALWAYS_ONb | + R300_PIXCLK_TVO_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_MISC); + tmp |= (RADEON_MC_MCLK_DYN_ENABLE | + RADEON_IO_MCLK_DYN_ENABLE); + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_MISC, tmp); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + tmp |= (RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB); + + tmp &= ~(RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC); + + /* Some releases of vbios have set DISABLE_MC_MCLKA + and DISABLE_MC_MCLKB bits in the vbios table. Setting these + bits will cause H/W hang when reading video memory with dynamic clocking + enabled. */ + if ((tmp & R300_DISABLE_MC_MCLKA) && + (tmp & R300_DISABLE_MC_MCLKB)) { + /* If both bits are set, then check the active channels */ + tmp = RADEON_READ_PLL(dev_priv, RADEON_MCLK_CNTL); + if (dev_priv->ram_width == 64) { + if (RADEON_READ(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY) + tmp &= ~R300_DISABLE_MC_MCLKB; + else + tmp &= ~R300_DISABLE_MC_MCLKA; + } else { + tmp &= ~(R300_DISABLE_MC_MCLKA | + R300_DISABLE_MC_MCLKB); + } + } + + RADEON_WRITE_PLL(dev_priv, RADEON_MCLK_CNTL, tmp); + } else { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + tmp &= ~(R300_SCLK_FORCE_VAP); + tmp |= RADEON_SCLK_FORCE_CP; + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + udelay(15000); + + tmp = RADEON_READ_PLL(dev_priv, R300_SCLK_CNTL2); + tmp &= ~(R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + RADEON_WRITE_PLL(dev_priv, R300_SCLK_CNTL2, tmp); + } + } else { + tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL); + tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | + RADEON_DISP_DYN_STOP_LAT_MASK | + RADEON_DYN_STOP_MODE_MASK); + + tmp |= (RADEON_ENGIN_DYNCLK_MODE | + (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); + RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PWRMGT_CNTL, tmp); + udelay(15000); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_CLK_PIN_CNTL); + tmp |= RADEON_SCLK_DYN_START_CNTL; + RADEON_WRITE_PLL(dev_priv, RADEON_CLK_PIN_CNTL, tmp); + udelay(15000); + + /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 + to lockup randomly, leave them as set by BIOS. + */ + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_CNTL); + /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/ + tmp &= ~RADEON_SCLK_FORCEON_MASK; + + /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ + if (((dev_priv->chip_family == CHIP_RV250) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) || + ((dev_priv->chip_family == CHIP_RV100) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <= + RADEON_CFG_ATI_REV_A13))){ + tmp |= RADEON_SCLK_FORCE_CP; + tmp |= RADEON_SCLK_FORCE_VIP; + } + + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_CNTL, tmp); + + if ((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250) || + (dev_priv->chip_family == CHIP_RV280)) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + + /* RV200::A11 A12 RV250::A11 A12 */ + if (((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250)) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) { + tmp |= RADEON_SCLK_MORE_FORCEON; + } + RADEON_WRITE_PLL(dev_priv, RADEON_SCLK_MORE_CNTL, tmp); + udelay(15000); + } + + /* RV200::A11 A12, RV250::A11 A12 */ + if (((dev_priv->chip_family == CHIP_RV200) || + (dev_priv->chip_family == CHIP_RV250)) && + ((RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) { + tmp = RADEON_READ_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL); + tmp |= RADEON_TCL_BYPASS_DISABLE; + RADEON_WRITE_PLL(dev_priv, RADEON_PLL_PWRMGT_CNTL, tmp); + } + udelay(15000); + + /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/ + tmp = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb); + + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + udelay(15000); + + tmp = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + udelay(15000); + } + DRM_DEBUG("Dynamic Clock Scaling Enabled\n"); + break; + default: + break; + } + +} + +int radeon_modeset_cp_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + /* allocate a ring and ring rptr bits from GART space */ + /* these are allocated in GEM files */ + + dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; + dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; + dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; + + dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual; + dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual + + dev_priv->ring.size / sizeof(u32); + dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); + dev_priv->ring.rptr_update = 4096; + dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8); + dev_priv->ring.fetch_size = 32; + dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16); + dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; + dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + + dev_priv->new_memmap = 1; + + radeon_cp_load_microcode(dev_priv); + + DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring->offset, dev_priv->mm.ring_read_ptr->offset); + + radeon_cp_init_ring_buffer(dev, dev_priv); + + radeon_do_engine_reset(dev); + radeon_test_writeback(dev_priv); + + radeon_do_cp_start(dev_priv); + return 0; +} + +static bool radeon_get_bios(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u8 __iomem *bios; + size_t size; + uint16_t tmp; + + bios = pci_map_rom(dev->pdev, &size); + if (!bios) + return -1; + + dev_priv->bios = kmalloc(size, GFP_KERNEL); + if (!dev_priv->bios) { + pci_unmap_rom(dev->pdev, bios); + return -1; + } + + memcpy(dev_priv->bios, bios, size); + + pci_unmap_rom(dev->pdev, bios); + + if (dev_priv->bios[0] != 0x55 || dev_priv->bios[1] != 0xaa) + goto free_bios; + + dev_priv->bios_header_start = radeon_bios16(dev_priv, 0x48); + + if (!dev_priv->bios_header_start) + goto free_bios; + + tmp = dev_priv->bios_header_start + 4; + + if (!memcmp(dev_priv->bios + tmp, "ATOM", 4) || + !memcmp(dev_priv->bios + tmp, "MOTA", 4)) + dev_priv->is_atom_bios = true; + else + dev_priv->is_atom_bios = false; + + DRM_DEBUG("%sBIOS detected\n", dev_priv->is_atom_bios ? "ATOM" : "COM"); + return true; +free_bios: + kfree(dev_priv->bios); + dev_priv->bios = NULL; + return false; +} + +int radeon_modeset_preinit(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + static struct card_info card; + int ret; + + card.dev = dev; + card.reg_read = cail_reg_read; + card.reg_write = cail_reg_write; + card.mc_read = cail_mc_read; + card.mc_write = cail_mc_write; + + ret = radeon_get_bios(dev); + if (!ret) + return -1; + + if (dev_priv->is_atom_bios) { + dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); + radeon_get_clock_info(dev); + } + return 0; +} + + int radeon_driver_load(struct drm_device *dev, unsigned long flags) { drm_radeon_private_t *dev_priv; @@ -1734,6 +2409,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) break; } + dev_priv->chip_family = flags & RADEON_FAMILY_MASK; if (drm_device_is_agp(dev)) dev_priv->flags |= RADEON_IS_AGP; else if (drm_device_is_pcie(dev)) @@ -1741,11 +2417,122 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; + + DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); + + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), + drm_get_resource_len(dev, 2), _DRM_REGISTERS, + _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio); + if (ret != 0) + return ret; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + radeon_modeset_preinit(dev); + + + radeon_get_vram_type(dev); + + dev_priv->pll_errata = 0; + + if (dev_priv->chip_family == CHIP_R300 && + (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) + dev_priv->pll_errata |= CHIP_ERRATA_R300_CG; + + if (dev_priv->chip_family == CHIP_RV200 || + dev_priv->chip_family == CHIP_RS200) + dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; + + + if (dev_priv->chip_family == CHIP_RV100 || + dev_priv->chip_family == CHIP_RS100 || + dev_priv->chip_family == CHIP_RS200) + dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY; + + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { + radeon_set_dynamic_clock(dev, radeon_dynclks); + } else if (radeon_is_avivo(dev_priv)) { + if (radeon_dynclks) { + radeon_atom_static_pwrmgt_setup(dev, 1); + radeon_atom_dyn_clk_setup(dev, 1); + } + } + radeon_force_some_clocks(dev); + } + + /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ + dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); + + drm_bo_driver_init(dev); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + + dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; + dev_priv->fb_size = + ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) + - dev_priv->fb_location; + radeon_gem_mm_init(dev); + radeon_modeset_init(dev); + + radeon_modeset_cp_init(dev); + dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); + + drm_irq_install(dev); + } + + return ret; } + +int radeon_master_create(struct drm_device *dev, struct drm_master *master) +{ + struct drm_radeon_master_private *master_priv; + unsigned long sareapage; + int ret; + + master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER); + if (!master_priv) + return -ENOMEM; + + /* prebuild the SAREA */ + sareapage = max(SAREA_MAX, PAGE_SIZE); + ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER, + &master_priv->sarea); + if (ret) { + DRM_ERROR("SAREA setup failed\n"); + return ret; + } + master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); + master_priv->sarea_priv->pfCurrentPage = 0; + + master->driver_priv = master_priv; + return 0; +} + +void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) +{ + struct drm_radeon_master_private *master_priv = master->driver_priv; + struct drm_radeon_private *dev_priv = dev->dev_private; + + if (!master_priv) + return; + + if (master_priv->sarea_priv && + master_priv->sarea_priv->pfCurrentPage != 0) + radeon_cp_dispatch_flip(dev, master); + + master_priv->sarea_priv = NULL; + if (master_priv->sarea) + drm_rmmap(dev, master_priv->sarea); + + drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); + + master->driver_priv = NULL; +} /* Create mappings for registers and framebuffer so userland doesn't necessarily * have to find them. */ @@ -1757,13 +2544,9 @@ int radeon_driver_firstopen(struct drm_device *dev) dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - ret = drm_addmap(dev, drm_get_resource_start(dev, 2), - drm_get_resource_len(dev, 2), _DRM_REGISTERS, - _DRM_READ_ONLY, &dev_priv->mmio); - if (ret != 0) - return ret; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + radeon_gem_mm_init(dev); - dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); ret = drm_addmap(dev, dev_priv->fb_aper_offset, drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING, &map); @@ -1777,9 +2560,40 @@ int radeon_driver_unload(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_irq_uninstall(dev); + radeon_modeset_cleanup(dev); + radeon_gem_mm_fini(dev); + } + + drm_bo_driver_finish(dev); + drm_rmmap(dev, dev_priv->mmio); + DRM_DEBUG("\n"); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; } + +void radeon_gart_flush(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (dev_priv->flags & RADEON_IS_IGPGART) { + IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); + IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE); + IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); + IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); + } else if (dev_priv->flags & RADEON_IS_PCIE) { + u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); + tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB; + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); + tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB; + RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); + } else { + + + } + +} -- cgit v1.2.3 From 38835f9cd2b44cfb6587a52ba1bfe292b958d0e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Jul 2008 15:21:13 +1000 Subject: radeon command submission start take code from Jerome munge into a TTM IB re-use --- shared-core/radeon_cp.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 80951e91..46f4290a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -658,8 +658,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, ((dev_priv->gart_vm_start - 1) & 0xffff0000) | (dev_priv->fb_location >> 16)); - if (dev_priv->mm.ring) { - ring_start = dev_priv->mm.ring->offset + + if (dev_priv->mm.ring.bo) { + ring_start = dev_priv->mm.ring.bo->offset + dev_priv->gart_vm_start; } else #if __OS_HAS_AGP @@ -692,9 +692,9 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring.tail = cur_read_ptr; - if (dev_priv->mm.ring_read_ptr) { + if (dev_priv->mm.ring_read.bo) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->mm.ring_read_ptr->offset + + dev_priv->mm.ring_read.bo->offset + dev_priv->gart_vm_start); } else #if __OS_HAS_AGP @@ -745,9 +745,9 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); - if (dev_priv->mm.ring_read_ptr) + if (dev_priv->mm.ring_read.bo) dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->mm.ring_read_ptr_map.virtual + + dev_priv->mm.ring_read.kmap.virtual + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); else dev_priv->scratch = ((__volatile__ u32 *) @@ -772,12 +772,18 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ + if (dev_priv->chip_family > CHIP_RV280) { RADEON_WRITE(RADEON_ISYNC_CNTL, (RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); - + } else { + RADEON_WRITE(RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI)); + } } static void radeon_test_writeback(drm_radeon_private_t * dev_priv) @@ -785,8 +791,8 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) u32 tmp; void *ring_read_ptr; - if (dev_priv->mm.ring_read_ptr) - ring_read_ptr = dev_priv->mm.ring_read_ptr_map.virtual; + if (dev_priv->mm.ring_read.bo) + ring_read_ptr = dev_priv->mm.ring_read.kmap.virtual; else ring_read_ptr = dev_priv->ring_rptr->handle; @@ -2282,8 +2288,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; - dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual; - dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual + + dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual; + dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual + dev_priv->ring.size / sizeof(u32); dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); dev_priv->ring.rptr_update = 4096; @@ -2297,7 +2303,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) radeon_cp_load_microcode(dev_priv); - DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring->offset, dev_priv->mm.ring_read_ptr->offset); + DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); radeon_cp_init_ring_buffer(dev, dev_priv); -- cgit v1.2.3 From dc3a7c023dd089150ee2dc40755fde348252bedb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Jul 2008 17:27:24 +1000 Subject: r300: initial command stream parser for packet 0. this at least parses the DDX stream and lets me run gnome-terminal/metacity --- shared-core/radeon_cp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 46f4290a..48f72ab0 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2301,6 +2301,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->new_memmap = 1; + r300_init_reg_flags(dev); + radeon_cp_load_microcode(dev_priv); DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); -- cgit v1.2.3 From af6efc3d778b96164849f822331938c4cdf8f4b2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Aug 2008 14:53:45 +1000 Subject: i915/radeon: use rmmap locked --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 48f72ab0..b69fadbb 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2535,7 +2535,7 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) master_priv->sarea_priv = NULL; if (master_priv->sarea) - drm_rmmap(dev, master_priv->sarea); + drm_rmmap_locked(dev, master_priv->sarea); drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); -- cgit v1.2.3 From aa8e15f8b51e555e78cb93e279bad5843eea5391 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Aug 2008 14:59:17 +1000 Subject: radeon: add userspace mm enable switch --- shared-core/radeon_cp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b69fadbb..430f5493 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1364,8 +1364,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->gart_info.bus_addr) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); } if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) @@ -1373,6 +1372,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->pcigart_offset_set == 1) { drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); dev_priv->gart_info.addr = NULL; + dev_priv->pcigart_offset_set = 0; } } } @@ -1563,8 +1563,10 @@ void radeon_do_release(struct drm_device * dev) radeon_mem_takedown(&(dev_priv->gart_heap)); radeon_mem_takedown(&(dev_priv->fb_heap)); - - radeon_gem_mm_fini(dev); + if (dev_priv->user_mm_enable) { + radeon_gem_mm_fini(dev); + dev_priv->user_mm_enable = false; + } /* deallocate kernel resources */ radeon_do_cleanup_cp(dev); -- cgit v1.2.3 From 513d4c3ff1937159e0d32047376415df09031ce6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 6 Aug 2008 10:21:20 +1000 Subject: radeon: fix setting new memmap in right place --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 430f5493..4c03f739 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2301,7 +2301,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - dev_priv->new_memmap = 1; + dev_priv->new_memmap = true; r300_init_reg_flags(dev); -- cgit v1.2.3 From c2184e450e4c5613c1f1a004d183ad478358013e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 8 Aug 2008 16:04:45 +1000 Subject: radeon: add initial support for legacy crtc/encoders. not all there yet --- shared-core/radeon_cp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 4c03f739..b751740c 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2282,6 +2282,7 @@ static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) int radeon_modeset_cp_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t tmp; /* allocate a ring and ring rptr bits from GART space */ /* these are allocated in GEM files */ @@ -2311,6 +2312,11 @@ int radeon_modeset_cp_init(struct drm_device *dev) radeon_cp_init_ring_buffer(dev, dev_priv); + /* need to enable BUS mastering in Buscntl */ + tmp = RADEON_READ(RADEON_BUS_CNTL); + tmp &= ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + radeon_do_engine_reset(dev); radeon_test_writeback(dev_priv); @@ -2381,8 +2387,8 @@ int radeon_modeset_preinit(struct drm_device *dev) if (dev_priv->is_atom_bios) { dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); - radeon_get_clock_info(dev); } + radeon_get_clock_info(dev); return 0; } -- cgit v1.2.3 From 5f427e9aaed76ec827b9523b4022205f5bd09a4a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 11 Aug 2008 12:29:42 -0400 Subject: Brute force port of legacy crtc/encoder code - removed save/init/restore chain with set functions --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b751740c..53177bb0 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -185,7 +185,7 @@ void radeon_pll_errata_after_data(struct drm_radeon_private *dev_priv) } } -int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) +u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) { uint32_t data; -- cgit v1.2.3 From 30ff279e42b3b0608e8ff6620d2958c174449798 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Aug 2008 14:43:51 +1000 Subject: radeon: add support for memory map init --- shared-core/radeon_cp.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 04f4b1f8..e30696fc 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -107,7 +107,33 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) return RADEON_READ(RADEON_MC_FB_LOCATION); } -static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) +void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi) +{ + if (dev_priv->chip_family == CHIP_RV770) { + + } else if (dev_priv->chip_family == CHIP_R600) { + *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_hi = 0; + } else if (dev_priv->chip_family == CHIP_RS600) { + *agp_lo = 0; + *agp_hi = 0; + } else if (dev_priv->chip_family == CHIP_RS690 || + dev_priv->chip_family == CHIP_RS740) { + *agp_lo = radeon_read_mc_reg(dev_priv, RS690_MC_AGP_LOCATION); + *agp_hi = 0; + } else if (dev_priv->chip_family >= CHIP_R520) { + *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_hi = 0; + } +} + +void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); @@ -119,7 +145,7 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); } -static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) +static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc, u32 agp_loc_hi) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); @@ -672,7 +698,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, radeon_write_agp_location(dev_priv, (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); + (dev_priv->gart_vm_start >> 16)), 0); ring_start = (dev_priv->cp_ring->offset - dev->agp->base @@ -873,7 +899,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 0xffff0000) | (dev_priv->gart_vm_start >> 16)); - radeon_write_agp_location(dev_priv, temp); + radeon_write_agp_location(dev_priv, temp, 0); temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | @@ -921,7 +947,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) dev_priv->gart_vm_start + dev_priv->gart_size - 1); - radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ + radeon_write_agp_location(dev_priv, 0xffffffc0, 0); /* ?? */ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); @@ -965,7 +991,7 @@ void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) /* Turn off AGP aperture -- is this required for PCI GART? */ - radeon_write_agp_location(dev_priv, 0xffffffc0); + radeon_write_agp_location(dev_priv, 0xffffffc0, 0); RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ } else { RADEON_WRITE(RADEON_AIC_CNTL, @@ -2482,10 +2508,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (drm_core_check_feature(dev, DRIVER_MODESET)) { - dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; - dev_priv->fb_size = - ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) - - dev_priv->fb_location; radeon_gem_mm_init(dev); radeon_modeset_init(dev); -- cgit v1.2.3 From aed70622ab33500721a30b06ec3783c581615cbb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 17 Aug 2008 18:09:07 -0400 Subject: radeon: first pass at bios scratch regs - todo: updated connected status --- shared-core/radeon_cp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index e30696fc..6b71360f 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2409,8 +2409,12 @@ int radeon_modeset_preinit(struct drm_device *dev) if (dev_priv->is_atom_bios) { dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); - } + radeon_atom_initialize_bios_scratch_regs(dev); + } else + radeon_combios_initialize_bios_scratch_regs(dev); + radeon_get_clock_info(dev); + return 0; } -- cgit v1.2.3 From 2a6dad31d84252d505f392f91dffd90689bb947c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:05:59 +1000 Subject: radeon: add initial suspend/resume support plus a bunch of fixes --- shared-core/radeon_cp.c | 103 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 32 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6b71360f..a34c6530 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -521,7 +521,6 @@ static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv) DRM_DEBUG("\n"); #if 0 u32 tmp; - tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); #endif @@ -761,8 +760,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring.size_l2qw); #endif - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; /* Initialize the scratch register pointer. This will cause * the scratch register values to be written out to memory @@ -1341,6 +1338,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, radeon_set_pcigart(dev_priv, 1); } + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + radeon_cp_load_microcode(dev_priv); radeon_cp_init_ring_buffer(dev, dev_priv); @@ -2301,14 +2301,64 @@ static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) } -int radeon_modeset_cp_init(struct drm_device *dev) +int radeon_modeset_cp_suspend(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int ret; + + ret = radeon_do_cp_idle(dev_priv); + if (ret) + DRM_ERROR("failed to idle CP on suspend\n"); + + radeon_do_cp_stop(dev_priv); + radeon_do_engine_reset(dev); + if (dev_priv->flags & RADEON_IS_AGP) { + } else { + radeon_set_pcigart(dev_priv, 0); + } + + return 0; +} + +int radeon_modeset_cp_resume(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; uint32_t tmp; + radeon_do_wait_for_idle(dev_priv); +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + /* Turn off PCI GART */ + radeon_set_pcigart(dev_priv, 0); + } else +#endif + { + /* Turn on PCI GART */ + radeon_set_pcigart(dev_priv, 1); + } + radeon_gart_flush(dev); + + DRM_ERROR("microcode loading\n"); + radeon_cp_load_microcode(dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); + + DRM_ERROR("engine init\n"); + radeon_do_engine_reset(dev); + + radeon_do_cp_start(dev_priv); + return 0; +} + +int radeon_modeset_cp_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + /* allocate a ring and ring rptr bits from GART space */ /* these are allocated in GEM files */ + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; @@ -2327,23 +2377,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->new_memmap = true; r300_init_reg_flags(dev); - - radeon_cp_load_microcode(dev_priv); - DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); - - radeon_cp_init_ring_buffer(dev, dev_priv); - - /* need to enable BUS mastering in Buscntl */ - tmp = RADEON_READ(RADEON_BUS_CNTL); - tmp &= ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - - radeon_do_engine_reset(dev); - radeon_test_writeback(dev_priv); - - radeon_do_cp_start(dev_priv); - return 0; + return radeon_modeset_cp_resume(dev); } static bool radeon_get_bios(struct drm_device *dev) @@ -2418,6 +2453,20 @@ int radeon_modeset_preinit(struct drm_device *dev) return 0; } +int radeon_static_clocks_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { + radeon_set_dynamic_clock(dev, radeon_dynclks); + } else if (radeon_is_avivo(dev_priv)) { + if (radeon_dynclks) { + radeon_atom_static_pwrmgt_setup(dev, 1); + radeon_atom_dyn_clk_setup(dev, 1); + } + } + radeon_force_some_clocks(dev); +} int radeon_driver_load(struct drm_device *dev, unsigned long flags) { @@ -2473,7 +2522,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (drm_core_check_feature(dev, DRIVER_MODESET)) radeon_modeset_preinit(dev); - radeon_get_vram_type(dev); dev_priv->pll_errata = 0; @@ -2493,17 +2541,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY; - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) { - radeon_set_dynamic_clock(dev, radeon_dynclks); - } else if (radeon_is_avivo(dev_priv)) { - if (radeon_dynclks) { - radeon_atom_static_pwrmgt_setup(dev, 1); - radeon_atom_dyn_clk_setup(dev, 1); - } - } - radeon_force_some_clocks(dev); - } + if (drm_core_check_feature(dev, DRIVER_MODESET)) + radeon_static_clocks_init(dev); /* init memory manager - start with all of VRAM and a 32MB GART aperture for now */ dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); -- cgit v1.2.3 From ed961cb428a73a35d473c27f62809ef80bde8706 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:14:32 +1000 Subject: radeon: remove unneeded debugging --- shared-core/radeon_cp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index a34c6530..8fc43756 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2338,11 +2338,9 @@ int radeon_modeset_cp_resume(struct drm_device *dev) } radeon_gart_flush(dev); - DRM_ERROR("microcode loading\n"); radeon_cp_load_microcode(dev_priv); radeon_cp_init_ring_buffer(dev, dev_priv); - DRM_ERROR("engine init\n"); radeon_do_engine_reset(dev); radeon_do_cp_start(dev_priv); -- cgit v1.2.3 From 515aa0800cf2d91bdf4706463e0531c5081a2679 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:17:27 +1000 Subject: radeon: do proper memory controller init and setup --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 8fc43756..63957cd7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -356,7 +356,7 @@ static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) return -EBUSY; } -static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) +int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) { int i, ret; -- cgit v1.2.3 From 8f38c28a3924dbda5babcf035911e103f27f9a05 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:19:08 +1000 Subject: radeon: fail properly if we can't create the ring. Normally this will be due to an AGP driver needing updating --- shared-core/radeon_cp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 63957cd7..6c5bf03b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2549,7 +2549,9 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (drm_core_check_feature(dev, DRIVER_MODESET)) { - radeon_gem_mm_init(dev); + ret = radeon_gem_mm_init(dev); + if (ret) + goto modeset_fail; radeon_modeset_init(dev); radeon_modeset_cp_init(dev); @@ -2559,6 +2561,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) } + return ret; +modeset_fail: + dev->driver->driver_features &= ~DRIVER_MODESET; + drm_put_minor(&dev->control); return ret; } -- cgit v1.2.3 From e1e782af5ddafdd24a4cf741139bb0b8e682e543 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Sep 2008 15:11:48 -0400 Subject: Radeon: restructure PLL data - store pixel clocks, core clock, and memory clocks separately - grab all pll limits from bios tables --- shared-core/radeon_cp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6c5bf03b..1ad005b7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2506,8 +2506,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; - - DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); @@ -2527,7 +2525,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (dev_priv->chip_family == CHIP_R300 && (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) dev_priv->pll_errata |= CHIP_ERRATA_R300_CG; - + if (dev_priv->chip_family == CHIP_RV200 || dev_priv->chip_family == CHIP_RS200) dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; -- cgit v1.2.3 From 34af71c42a66e5ef6a9a08250ca541030ca3cc4f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Sep 2008 16:07:41 -0400 Subject: radeon: add function to configure PCIE lanes --- shared-core/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 1ad005b7..b934d3bc 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -235,7 +235,7 @@ void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t da radeon_pll_errata_after_data(dev_priv); } -static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) +u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) { RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); return RADEON_READ(RADEON_PCIE_DATA); -- cgit v1.2.3 From 35e379ce5a0d23f4c812739f89e02703900cd91b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 24 Sep 2008 15:25:35 +1000 Subject: radeon: add r600 modesetting registers writes --- shared-core/radeon_cp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index b934d3bc..ffe066fc 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -101,6 +101,10 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + return RADEON_READ(R700_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_MC_VM_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else @@ -110,7 +114,8 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) void radeon_read_agp_location(drm_radeon_private_t *dev_priv, u32 *agp_lo, u32 *agp_hi) { if (dev_priv->chip_family == CHIP_RV770) { - + *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_R600) { *agp_lo = RADEON_READ(R600_MC_VM_AGP_BOT); *agp_hi = RADEON_READ(R600_MC_VM_AGP_TOP); @@ -139,6 +144,10 @@ void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else @@ -151,7 +160,10 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc); + RADEON_WRITE(R600_MC_VM_AGP_TOP, agp_loc_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); @@ -2357,6 +2369,9 @@ int radeon_modeset_cp_init(struct drm_device *dev) /* Start with assuming that writeback doesn't work */ dev_priv->writeback_works = 0; + if (dev_priv->chip_family > CHIP_R600) + return; + dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT; dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; -- cgit v1.2.3 From 26076bf24a4e720e389d0a3ea616a8350397fdfc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 16 Oct 2008 10:59:31 +1000 Subject: radeon: add initial agp support. This add agpmode command line option. --- shared-core/radeon_cp.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9825d709..190b1432 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2334,7 +2334,6 @@ int radeon_modeset_cp_suspend(struct drm_device *dev) int radeon_modeset_cp_resume(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - uint32_t tmp; radeon_do_wait_for_idle(dev_priv); #if __OS_HAS_AGP @@ -2358,6 +2357,95 @@ int radeon_modeset_cp_resume(struct drm_device *dev) return 0; } +#if __OS_HAS_AGP +int radeon_modeset_agp_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_agp_mode mode; + struct drm_agp_info info; + int ret; + int default_mode; + uint32_t agp_status; + bool is_v3; + + /* Acquire AGP. */ + ret = drm_agp_acquire(dev); + if (ret) { + DRM_ERROR("Unable to acquire AGP: %d\n", ret); + return ret; + } + + ret = drm_agp_info(dev, &info); + if (ret) { + DRM_ERROR("Unable to get AGP info: %d\n", ret); + return ret; + } + + mode.mode = info.mode; + + agp_status = (RADEON_READ(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; + is_v3 = !!(agp_status & RADEON_AGPv3_MODE); + + if (is_v3) { + default_mode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; + } else { + if (agp_status & RADEON_AGP_4X_MODE) default_mode = 4; + else if (agp_status & RADEON_AGP_2X_MODE) default_mode = 2; + else default_mode = 1; + } + + if (radeon_agpmode > 0) { + if ((radeon_agpmode < (is_v3 ? 4 : 1)) || + (radeon_agpmode > (is_v3 ? 8 : 4)) || + (radeon_agpmode & (radeon_agpmode - 1))) { + DRM_ERROR("Illegal AGP Mode: %d (valid %s), leaving at %d\n", + radeon_agpmode, is_v3 ? "4, 8" : "1, 2, 4", + default_mode); + radeon_agpmode = default_mode; + } + else + DRM_INFO("AGP mode requested: %d\n", radeon_agpmode); + } else + radeon_agpmode = default_mode; + + mode.mode &= ~RADEON_AGP_MODE_MASK; + if (is_v3) { + switch(radeon_agpmode) { + case 8: + mode.mode |= RADEON_AGPv3_8X_MODE; + break; + case 4: + default: + mode.mode |= RADEON_AGPv3_4X_MODE; + break; + } + } else { + switch(radeon_agpmode) { + case 4: mode.mode |= RADEON_AGP_4X_MODE; + case 2: mode.mode |= RADEON_AGP_2X_MODE; + case 1: + default: + mode.mode |= RADEON_AGP_1X_MODE; + break; + } + } + + mode.mode &= ~RADEON_AGP_FW_MODE; /* disable fw */ + + ret = drm_agp_enable(dev, mode); + if (ret) { + DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode); + return ret; + } + + /* workaround some hw issues */ + if (dev_priv->chip_family <= CHIP_R200) { + RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000); + } + return 0; +} +#endif + int radeon_modeset_cp_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2389,6 +2477,11 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->new_memmap = true; r300_init_reg_flags(dev); + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) + radeon_modeset_agp_init(dev); +#endif return radeon_modeset_cp_resume(dev); } @@ -2478,6 +2571,7 @@ int radeon_static_clocks_init(struct drm_device *dev) } } radeon_force_some_clocks(dev); + return 0; } int radeon_driver_load(struct drm_device *dev, unsigned long flags) @@ -2523,6 +2617,12 @@ 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; + } + + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), drm_get_resource_len(dev, 2), _DRM_REGISTERS, _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio); -- 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(-) (limited to 'shared-core/radeon_cp.c') 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 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(+) (limited to 'shared-core/radeon_cp.c') 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 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(-) (limited to 'shared-core/radeon_cp.c') 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 --- shared-core/radeon_cp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'shared-core/radeon_cp.c') 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(-) (limited to 'shared-core/radeon_cp.c') 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 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'shared-core/radeon_cp.c') 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 */ -- 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(-) (limited to 'shared-core/radeon_cp.c') 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 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 --- shared-core/radeon_cp.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'shared-core/radeon_cp.c') 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); -- 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(+) (limited to 'shared-core/radeon_cp.c') 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 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 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'shared-core/radeon_cp.c') 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 */ -- 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 --- shared-core/radeon_cp.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'shared-core/radeon_cp.c') 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 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(-) (limited to 'shared-core/radeon_cp.c') 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 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(-) (limited to 'shared-core/radeon_cp.c') 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 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 --- shared-core/radeon_cp.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'shared-core/radeon_cp.c') 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; } -- cgit v1.2.3 From 08ef5b5e677579892a454d44a96a12dc771b56ac Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:24:42 +1000 Subject: radeon: force all ring writes to 16-dword alignment. --- shared-core/radeon_cp.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9a1e0e02..73192d03 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1313,9 +1313,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8); - dev_priv->ring.fetch_size = /* init->fetch_size */ 32; - dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); - + dev_priv->ring.fetch_size_l2ow = 2; dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; @@ -2513,8 +2511,7 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); dev_priv->ring.rptr_update = 4096; dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8); - dev_priv->ring.fetch_size = 32; - dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16); + dev_priv->ring.fetch_size_l2ow = 2; /* do what tcore does */ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; @@ -2841,3 +2838,33 @@ void radeon_gart_flush(struct drm_device *dev) } } + +void radeon_commit_ring(drm_radeon_private_t *dev_priv) +{ + int i; + u32 *ring; + int tail_aligned; + + /* check if the ring is padded out to 16-dword alignment */ + + tail_aligned = dev_priv->ring.tail & 0xf; + if (tail_aligned) { + int num_p2 = 16 - tail_aligned; + + ring = dev_priv->ring.start; + /* pad with some CP_PACKET2 */ + for (i = 0; i < num_p2; i++) + ring[dev_priv->ring.tail + i] = CP_PACKET2(); + + dev_priv->ring.tail += i; + + dev_priv->ring.space -= num_p2 * sizeof(u32); + } + + DRM_MEMORYBARRIER(); + GET_RING_HEAD( dev_priv ); + + RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); + /* read from PCI bus to ensure correct posting */ + RADEON_READ( RADEON_CP_RB_RPTR ); +} -- cgit v1.2.3 From 758376e6eb2155605ad502d0dc5147c74f3c47a6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:25:12 +1000 Subject: radeon: disable HDP read cache for now --- shared-core/radeon_cp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 73192d03..a087829e 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2519,6 +2519,9 @@ int radeon_modeset_cp_init(struct drm_device *dev) r300_init_reg_flags(dev); + /* turn off HDP read cache for now */ + RADEON_WRITE(RADEON_HOST_PATH_CNTL, RADEON_READ(RADEON_HOST_PATH_CNTL) | RADEON_HP_LIN_RD_CACHE_DIS); + #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) radeon_modeset_agp_init(dev); -- cgit v1.2.3 From 994f2405030f7f595c4ec6bee524f7c06f27cd7b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2008 15:25:27 +1000 Subject: radeon: fix ring tail overflow issue since alignment --- shared-core/radeon_cp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/radeon_cp.c') diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index a087829e..285bd4d7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2863,6 +2863,8 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv) dev_priv->ring.space -= num_p2 * sizeof(u32); } + + dev_priv->ring.tail &= dev_priv->ring.tail_mask; DRM_MEMORYBARRIER(); GET_RING_HEAD( dev_priv ); -- cgit v1.2.3