radeon_cp.c revision 198695
1139749Simp/*- 295584Sanholt * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 395584Sanholt * Copyright 2000 VA Linux Systems, Inc., Fremont, California. 4182080Srnoland * Copyright 2007 Advanced Micro Devices, Inc. 595584Sanholt * All Rights Reserved. 695584Sanholt * 795584Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 895584Sanholt * copy of this software and associated documentation files (the "Software"), 995584Sanholt * to deal in the Software without restriction, including without limitation 1095584Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1195584Sanholt * and/or sell copies of the Software, and to permit persons to whom the 1295584Sanholt * Software is furnished to do so, subject to the following conditions: 1395584Sanholt * 1495584Sanholt * The above copyright notice and this permission notice (including the next 1595584Sanholt * paragraph) shall be included in all copies or substantial portions of the 1695584Sanholt * Software. 1795584Sanholt * 1895584Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1995584Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2095584Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2195584Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 2295584Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2395584Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2495584Sanholt * DEALINGS IN THE SOFTWARE. 2595584Sanholt * 2695584Sanholt * Authors: 2795584Sanholt * Kevin E. Martin <martin@valinux.com> 2895584Sanholt * Gareth Hughes <gareth@valinux.com> 2995584Sanholt */ 3095584Sanholt 31152909Sanholt#include <sys/cdefs.h> 32152909Sanholt__FBSDID("$FreeBSD: head/sys/dev/drm/radeon_cp.c 198695 2009-10-30 18:07:22Z rnoland $"); 33152909Sanholt 3495584Sanholt#include "dev/drm/drmP.h" 35112015Sanholt#include "dev/drm/drm.h" 36189499Srnoland#include "dev/drm/drm_sarea.h" 3795746Sanholt#include "dev/drm/radeon_drm.h" 3895584Sanholt#include "dev/drm/radeon_drv.h" 39148211Sanholt#include "dev/drm/r300_reg.h" 4095584Sanholt 41182080Srnoland#include "dev/drm/radeon_microcode.h" 42189499Srnoland 4395584Sanholt#define RADEON_FIFO_DEBUG 0 4495584Sanholt 45182080Srnolandstatic int radeon_do_cleanup_cp(struct drm_device * dev); 46182080Srnolandstatic void radeon_do_cp_start(drm_radeon_private_t * dev_priv); 4795584Sanholt 48189499Srnolandu32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) 49189499Srnoland{ 50189499Srnoland u32 val; 51189499Srnoland 52189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 53189499Srnoland val = DRM_READ32(dev_priv->ring_rptr, off); 54189499Srnoland } else { 55189499Srnoland val = *(((volatile u32 *) 56189499Srnoland dev_priv->ring_rptr->handle) + 57189499Srnoland (off / sizeof(u32))); 58189499Srnoland val = le32_to_cpu(val); 59189499Srnoland } 60189499Srnoland return val; 61189499Srnoland} 62189499Srnoland 63189499Srnolandu32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) 64189499Srnoland{ 65189499Srnoland if (dev_priv->writeback_works) 66189499Srnoland return radeon_read_ring_rptr(dev_priv, 0); 67189499Srnoland else { 68189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 69189499Srnoland return RADEON_READ(R600_CP_RB_RPTR); 70189499Srnoland else 71189499Srnoland return RADEON_READ(RADEON_CP_RB_RPTR); 72189499Srnoland } 73189499Srnoland} 74189499Srnoland 75189499Srnolandvoid radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) 76189499Srnoland{ 77189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) 78189499Srnoland DRM_WRITE32(dev_priv->ring_rptr, off, val); 79189499Srnoland else 80189499Srnoland *(((volatile u32 *) dev_priv->ring_rptr->handle) + 81189499Srnoland (off / sizeof(u32))) = cpu_to_le32(val); 82189499Srnoland} 83189499Srnoland 84189499Srnolandvoid radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) 85189499Srnoland{ 86189499Srnoland radeon_write_ring_rptr(dev_priv, 0, val); 87189499Srnoland} 88189499Srnoland 89189499Srnolandu32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) 90189499Srnoland{ 91189499Srnoland if (dev_priv->writeback_works) { 92189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 93189499Srnoland return radeon_read_ring_rptr(dev_priv, 94189499Srnoland R600_SCRATCHOFF(index)); 95189499Srnoland else 96189499Srnoland return radeon_read_ring_rptr(dev_priv, 97189499Srnoland RADEON_SCRATCHOFF(index)); 98189499Srnoland } else { 99189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 100189499Srnoland return RADEON_READ(R600_SCRATCH_REG0 + 4*index); 101189499Srnoland else 102189499Srnoland return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); 103189499Srnoland } 104189499Srnoland} 105189499Srnoland 106189499Srnolandu32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) 107189499Srnoland{ 108189499Srnoland u32 ret; 109189499Srnoland 110189499Srnoland if (addr < 0x10000) 111189499Srnoland ret = DRM_READ32(dev_priv->mmio, addr); 112189499Srnoland else { 113189499Srnoland DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); 114189499Srnoland ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); 115189499Srnoland } 116189499Srnoland 117189499Srnoland return ret; 118189499Srnoland} 119189499Srnoland 120182080Srnolandstatic u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 121182080Srnoland{ 122182080Srnoland u32 ret; 123182080Srnoland RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff)); 124182080Srnoland ret = RADEON_READ(R520_MC_IND_DATA); 125182080Srnoland RADEON_WRITE(R520_MC_IND_INDEX, 0); 126182080Srnoland return ret; 127182080Srnoland} 128112015Sanholt 129182080Srnolandstatic u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 130182080Srnoland{ 131182080Srnoland u32 ret; 132182080Srnoland RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff); 133182080Srnoland ret = RADEON_READ(RS480_NB_MC_DATA); 134182080Srnoland RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); 135182080Srnoland return ret; 136182080Srnoland} 137112015Sanholt 138182080Srnolandstatic u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 139182080Srnoland{ 140182080Srnoland u32 ret; 141182080Srnoland RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); 142182080Srnoland ret = RADEON_READ(RS690_MC_DATA); 143182080Srnoland RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK); 144182080Srnoland return ret; 145182080Srnoland} 14695584Sanholt 147189499Srnolandstatic u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 148189499Srnoland{ 149189499Srnoland u32 ret; 150189499Srnoland RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | 151189499Srnoland RS600_MC_IND_CITF_ARB0)); 152189499Srnoland ret = RADEON_READ(RS600_MC_DATA); 153189499Srnoland return ret; 154189499Srnoland} 155189499Srnoland 156182080Srnolandstatic u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 15795584Sanholt{ 158183828Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 159183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 160189499Srnoland return RS690_READ_MCIND(dev_priv, addr); 161189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 162189499Srnoland return RS600_READ_MCIND(dev_priv, addr); 163182080Srnoland else 164189499Srnoland return RS480_READ_MCIND(dev_priv, addr); 165182080Srnoland} 166182080Srnoland 167182080Srnolandu32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) 168182080Srnoland{ 169182080Srnoland 170189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) 171189499Srnoland return RADEON_READ(R700_MC_VM_FB_LOCATION); 172189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 173189499Srnoland return RADEON_READ(R600_MC_VM_FB_LOCATION); 174189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 175182080Srnoland return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); 176183828Srnoland else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 177183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 178182080Srnoland return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); 179189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 180189499Srnoland return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); 181182080Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) 182182080Srnoland return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); 183182080Srnoland else 184182080Srnoland return RADEON_READ(RADEON_MC_FB_LOCATION); 185182080Srnoland} 186182080Srnoland 187182080Srnolandstatic void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) 188182080Srnoland{ 189189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) 190189499Srnoland RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); 191189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 192189499Srnoland RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); 193189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 194182080Srnoland R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); 195183828Srnoland else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 196183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 197182080Srnoland RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); 198189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 199189499Srnoland RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); 200182080Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) 201182080Srnoland R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); 202182080Srnoland else 203182080Srnoland RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); 204182080Srnoland} 205182080Srnoland 206189499Srnolandvoid radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) 207182080Srnoland{ 208189499Srnoland /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ 209189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { 210189499Srnoland RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ 211189499Srnoland RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); 212189499Srnoland } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 213189499Srnoland RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ 214189499Srnoland RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); 215189499Srnoland } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 216182080Srnoland R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); 217183828Srnoland else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 218183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 219182080Srnoland RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); 220189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 221189499Srnoland RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); 222182080Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) 223182080Srnoland R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); 224182080Srnoland else 225182080Srnoland RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); 226182080Srnoland} 227182080Srnoland 228189499Srnolandvoid radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) 229182080Srnoland{ 230182080Srnoland u32 agp_base_hi = upper_32_bits(agp_base); 231182080Srnoland u32 agp_base_lo = agp_base & 0xffffffff; 232189499Srnoland u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; 233182080Srnoland 234189499Srnoland /* R6xx/R7xx must be aligned to a 4MB boundry */ 235189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) 236189499Srnoland RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); 237189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 238189499Srnoland RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); 239189499Srnoland else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { 240182080Srnoland R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); 241182080Srnoland R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); 242183828Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 243189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { 244182080Srnoland RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); 245182080Srnoland RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); 246189499Srnoland } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { 247189499Srnoland RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); 248189499Srnoland RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); 249182080Srnoland } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { 250182080Srnoland R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); 251182080Srnoland R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); 252182080Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || 253182080Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { 254182080Srnoland RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); 255182080Srnoland RADEON_WRITE(RS480_AGP_BASE_2, agp_base_hi); 256182080Srnoland } else { 257182080Srnoland RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); 258182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200) 259182080Srnoland RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi); 260182080Srnoland } 261182080Srnoland} 262182080Srnoland 263189499Srnolandvoid radeon_enable_bm(struct drm_radeon_private *dev_priv) 264189499Srnoland{ 265189499Srnoland u32 tmp; 266189499Srnoland /* Turn on bus mastering */ 267189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 268189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { 269189499Srnoland /* rs600/rs690/rs740 */ 270189499Srnoland tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; 271189499Srnoland RADEON_WRITE(RADEON_BUS_CNTL, tmp); 272189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || 273189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || 274189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || 275189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { 276189499Srnoland /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ 277189499Srnoland tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; 278189499Srnoland RADEON_WRITE(RADEON_BUS_CNTL, tmp); 279189499Srnoland } /* PCIE cards appears to not need this */ 280189499Srnoland} 281189499Srnoland 282182080Srnolandstatic int RADEON_READ_PLL(struct drm_device * dev, int addr) 283182080Srnoland{ 28495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 28595584Sanholt 28695584Sanholt RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); 28795584Sanholt return RADEON_READ(RADEON_CLOCK_CNTL_DATA); 28895584Sanholt} 28995584Sanholt 290182080Srnolandstatic u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) 291148211Sanholt{ 292148211Sanholt RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); 293148211Sanholt return RADEON_READ(RADEON_PCIE_DATA); 294148211Sanholt} 295148211Sanholt 29695584Sanholt#if RADEON_FIFO_DEBUG 297145132Sanholtstatic void radeon_status(drm_radeon_private_t * dev_priv) 29895584Sanholt{ 299189499Srnoland printk("%s:\n", __func__); 300145132Sanholt printk("RBBM_STATUS = 0x%08x\n", 301145132Sanholt (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); 302145132Sanholt printk("CP_RB_RTPR = 0x%08x\n", 303145132Sanholt (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR)); 304145132Sanholt printk("CP_RB_WTPR = 0x%08x\n", 305145132Sanholt (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR)); 306145132Sanholt printk("AIC_CNTL = 0x%08x\n", 307145132Sanholt (unsigned int)RADEON_READ(RADEON_AIC_CNTL)); 308145132Sanholt printk("AIC_STAT = 0x%08x\n", 309145132Sanholt (unsigned int)RADEON_READ(RADEON_AIC_STAT)); 310145132Sanholt printk("AIC_PT_BASE = 0x%08x\n", 311145132Sanholt (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE)); 312145132Sanholt printk("TLB_ADDR = 0x%08x\n", 313145132Sanholt (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR)); 314145132Sanholt printk("TLB_DATA = 0x%08x\n", 315145132Sanholt (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA)); 31695584Sanholt} 31795584Sanholt#endif 31895584Sanholt 31995584Sanholt/* ================================================================ 32095584Sanholt * Engine, FIFO control 32195584Sanholt */ 32295584Sanholt 323145132Sanholtstatic int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) 32495584Sanholt{ 32595584Sanholt u32 tmp; 32695584Sanholt int i; 32795584Sanholt 328112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 329112015Sanholt 330182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { 331182080Srnoland tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); 332182080Srnoland tmp |= RADEON_RB3D_DC_FLUSH_ALL; 333182080Srnoland RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); 33495584Sanholt 335182080Srnoland for (i = 0; i < dev_priv->usec_timeout; i++) { 336182080Srnoland if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) 337182080Srnoland & RADEON_RB3D_DC_BUSY)) { 338182080Srnoland return 0; 339182080Srnoland } 340182080Srnoland DRM_UDELAY(1); 34195584Sanholt } 342182080Srnoland } else { 343182080Srnoland /* don't flush or purge cache here or lockup */ 344182080Srnoland return 0; 34595584Sanholt } 34695584Sanholt 34795584Sanholt#if RADEON_FIFO_DEBUG 348145132Sanholt DRM_ERROR("failed!\n"); 349145132Sanholt radeon_status(dev_priv); 35095584Sanholt#endif 351182080Srnoland return -EBUSY; 35295584Sanholt} 35395584Sanholt 354145132Sanholtstatic int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) 35595584Sanholt{ 35695584Sanholt int i; 35795584Sanholt 358112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 359112015Sanholt 360145132Sanholt for (i = 0; i < dev_priv->usec_timeout; i++) { 361145132Sanholt int slots = (RADEON_READ(RADEON_RBBM_STATUS) 362145132Sanholt & RADEON_RBBM_FIFOCNT_MASK); 363145132Sanholt if (slots >= entries) 364145132Sanholt return 0; 365145132Sanholt DRM_UDELAY(1); 36695584Sanholt } 367189499Srnoland DRM_DEBUG("wait for fifo failed status : 0x%08X 0x%08X\n", 368182080Srnoland RADEON_READ(RADEON_RBBM_STATUS), 369182080Srnoland RADEON_READ(R300_VAP_CNTL_STATUS)); 37095584Sanholt 37195584Sanholt#if RADEON_FIFO_DEBUG 372145132Sanholt DRM_ERROR("failed!\n"); 373145132Sanholt radeon_status(dev_priv); 37495584Sanholt#endif 375182080Srnoland return -EBUSY; 37695584Sanholt} 37795584Sanholt 378145132Sanholtstatic int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) 37995584Sanholt{ 38095584Sanholt int i, ret; 38195584Sanholt 382112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 383112015Sanholt 384145132Sanholt ret = radeon_do_wait_for_fifo(dev_priv, 64); 385145132Sanholt if (ret) 386145132Sanholt return ret; 387112015Sanholt 388145132Sanholt for (i = 0; i < dev_priv->usec_timeout; i++) { 389145132Sanholt if (!(RADEON_READ(RADEON_RBBM_STATUS) 390145132Sanholt & RADEON_RBBM_ACTIVE)) { 391145132Sanholt radeon_do_pixcache_flush(dev_priv); 39295584Sanholt return 0; 39395584Sanholt } 394145132Sanholt DRM_UDELAY(1); 39595584Sanholt } 396189499Srnoland DRM_DEBUG("wait idle failed status : 0x%08X 0x%08X\n", 397182080Srnoland RADEON_READ(RADEON_RBBM_STATUS), 398182080Srnoland RADEON_READ(R300_VAP_CNTL_STATUS)); 39995584Sanholt 40095584Sanholt#if RADEON_FIFO_DEBUG 401145132Sanholt DRM_ERROR("failed!\n"); 402145132Sanholt radeon_status(dev_priv); 40395584Sanholt#endif 404182080Srnoland return -EBUSY; 40595584Sanholt} 40695584Sanholt 407189499Srnolandstatic void radeon_init_pipes(drm_radeon_private_t *dev_priv) 408182080Srnoland{ 409182080Srnoland uint32_t gb_tile_config, gb_pipe_sel = 0; 410182080Srnoland 411196471Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { 412196471Srnoland uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2); 413196471Srnoland if ((z_pipe_sel & 3) == 3) 414196471Srnoland dev_priv->num_z_pipes = 2; 415196471Srnoland else 416196471Srnoland dev_priv->num_z_pipes = 1; 417196471Srnoland } else 418196471Srnoland dev_priv->num_z_pipes = 1; 419196471Srnoland 420182080Srnoland /* RS4xx/RS6xx/R4xx/R5xx */ 421182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { 422182080Srnoland gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); 423182080Srnoland dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; 424182080Srnoland } else { 425182080Srnoland /* R3xx */ 426182080Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || 427182080Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { 428182080Srnoland dev_priv->num_gb_pipes = 2; 429182080Srnoland } else { 430182080Srnoland /* R3Vxx */ 431182080Srnoland dev_priv->num_gb_pipes = 1; 432182080Srnoland } 433182080Srnoland } 434182080Srnoland DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes); 435182080Srnoland 436182080Srnoland gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/); 437182080Srnoland 438189499Srnoland switch (dev_priv->num_gb_pipes) { 439182080Srnoland case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; 440182080Srnoland case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; 441182080Srnoland case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; 442182080Srnoland default: 443182080Srnoland case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; 444182080Srnoland } 445182080Srnoland 446182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { 447182080Srnoland RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); 448190831Srnoland RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); 449182080Srnoland } 450182080Srnoland RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); 451182080Srnoland radeon_do_wait_for_idle(dev_priv); 452182080Srnoland RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); 453182080Srnoland RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) | 454182080Srnoland R300_DC_AUTOFLUSH_ENABLE | 455182080Srnoland R300_DC_DC_DISABLE_IGNORE_PE)); 456182080Srnoland 457182080Srnoland 458182080Srnoland} 459182080Srnoland 46095584Sanholt/* ================================================================ 46195584Sanholt * CP control, initialization 46295584Sanholt */ 46395584Sanholt 46495584Sanholt/* Load the microcode for the CP */ 465145132Sanholtstatic void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) 46695584Sanholt{ 467190595Srnoland const u32 (*cp)[2]; 46895584Sanholt int i; 469190595Srnoland 470145132Sanholt DRM_DEBUG("\n"); 47195584Sanholt 472190595Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 473190595Srnoland case CHIP_R100: 474190595Srnoland case CHIP_RV100: 475190595Srnoland case CHIP_RV200: 476190595Srnoland case CHIP_RS100: 477190595Srnoland case CHIP_RS200: 478182080Srnoland DRM_INFO("Loading R100 Microcode\n"); 479190595Srnoland cp = R100_cp_microcode; 480190595Srnoland break; 481190595Srnoland case CHIP_R200: 482190595Srnoland case CHIP_RV250: 483190595Srnoland case CHIP_RV280: 484190595Srnoland case CHIP_RS300: 485112015Sanholt DRM_INFO("Loading R200 Microcode\n"); 486190595Srnoland cp = R200_cp_microcode; 487190595Srnoland break; 488190595Srnoland case CHIP_R300: 489190595Srnoland case CHIP_R350: 490190595Srnoland case CHIP_RV350: 491190595Srnoland case CHIP_RV380: 492190595Srnoland case CHIP_RS400: 493190595Srnoland case CHIP_RS480: 494145132Sanholt DRM_INFO("Loading R300 Microcode\n"); 495190595Srnoland cp = R300_cp_microcode; 496190595Srnoland break; 497190595Srnoland case CHIP_R420: 498190595Srnoland case CHIP_R423: 499190595Srnoland case CHIP_RV410: 500182080Srnoland DRM_INFO("Loading R400 Microcode\n"); 501190595Srnoland cp = R420_cp_microcode; 502190595Srnoland break; 503190595Srnoland case CHIP_RS690: 504190595Srnoland case CHIP_RS740: 505183828Srnoland DRM_INFO("Loading RS690/RS740 Microcode\n"); 506190595Srnoland cp = RS690_cp_microcode; 507190595Srnoland break; 508190595Srnoland case CHIP_RS600: 509189499Srnoland DRM_INFO("Loading RS600 Microcode\n"); 510190595Srnoland cp = RS600_cp_microcode; 511190595Srnoland break; 512190595Srnoland case CHIP_RV515: 513190595Srnoland case CHIP_R520: 514190595Srnoland case CHIP_RV530: 515190595Srnoland case CHIP_R580: 516190595Srnoland case CHIP_RV560: 517190595Srnoland case CHIP_RV570: 518182080Srnoland DRM_INFO("Loading R500 Microcode\n"); 519190595Srnoland cp = R520_cp_microcode; 520190595Srnoland break; 521190595Srnoland default: 522190595Srnoland return; 523112015Sanholt } 524190595Srnoland 525190674Srnoland radeon_do_wait_for_idle(dev_priv); 526190674Srnoland 527190674Srnoland RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); 528190674Srnoland 529190595Srnoland for (i = 0; i != 256; i++) { 530190595Srnoland RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, cp[i][1]); 531190595Srnoland RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, cp[i][0]); 532190595Srnoland } 53395584Sanholt} 53495584Sanholt 53595584Sanholt/* Flush any pending commands to the CP. This should only be used just 53695584Sanholt * prior to a wait for idle, as it informs the engine that the command 53795584Sanholt * stream is ending. 53895584Sanholt */ 539145132Sanholtstatic void radeon_do_cp_flush(drm_radeon_private_t * dev_priv) 54095584Sanholt{ 541145132Sanholt DRM_DEBUG("\n"); 54295584Sanholt#if 0 54395584Sanholt u32 tmp; 54495584Sanholt 545145132Sanholt tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); 546145132Sanholt RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); 54795584Sanholt#endif 54895584Sanholt} 54995584Sanholt 55095584Sanholt/* Wait for the CP to go idle. 55195584Sanholt */ 552145132Sanholtint radeon_do_cp_idle(drm_radeon_private_t * dev_priv) 55395584Sanholt{ 55495584Sanholt RING_LOCALS; 555145132Sanholt DRM_DEBUG("\n"); 55695584Sanholt 557145132Sanholt BEGIN_RING(6); 55895584Sanholt 55995584Sanholt RADEON_PURGE_CACHE(); 56095584Sanholt RADEON_PURGE_ZCACHE(); 56195584Sanholt RADEON_WAIT_UNTIL_IDLE(); 56295584Sanholt 56395584Sanholt ADVANCE_RING(); 564112015Sanholt COMMIT_RING(); 56595584Sanholt 566145132Sanholt return radeon_do_wait_for_idle(dev_priv); 56795584Sanholt} 56895584Sanholt 56995584Sanholt/* Start the Command Processor. 57095584Sanholt */ 571145132Sanholtstatic void radeon_do_cp_start(drm_radeon_private_t * dev_priv) 57295584Sanholt{ 57395584Sanholt RING_LOCALS; 574145132Sanholt DRM_DEBUG("\n"); 57595584Sanholt 576145132Sanholt radeon_do_wait_for_idle(dev_priv); 57795584Sanholt 578145132Sanholt RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode); 57995584Sanholt 58095584Sanholt dev_priv->cp_running = 1; 58195584Sanholt 582182080Srnoland BEGIN_RING(8); 583182080Srnoland /* isync can only be written through cp on r5xx write it here */ 584182080Srnoland OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); 585182080Srnoland OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | 586182080Srnoland RADEON_ISYNC_ANY3D_IDLE2D | 587182080Srnoland RADEON_ISYNC_WAIT_IDLEGUI | 588182080Srnoland RADEON_ISYNC_CPSCRATCH_IDLEGUI); 58995584Sanholt RADEON_PURGE_CACHE(); 59095584Sanholt RADEON_PURGE_ZCACHE(); 59195584Sanholt RADEON_WAIT_UNTIL_IDLE(); 59295584Sanholt ADVANCE_RING(); 593112015Sanholt COMMIT_RING(); 594182080Srnoland 595182080Srnoland dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED; 59695584Sanholt} 59795584Sanholt 59895584Sanholt/* Reset the Command Processor. This will not flush any pending 59995584Sanholt * commands, so you must wait for the CP command stream to complete 60095584Sanholt * before calling this routine. 60195584Sanholt */ 602145132Sanholtstatic void radeon_do_cp_reset(drm_radeon_private_t * dev_priv) 60395584Sanholt{ 60495584Sanholt u32 cur_read_ptr; 605145132Sanholt DRM_DEBUG("\n"); 60695584Sanholt 607145132Sanholt cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); 608145132Sanholt RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); 609145132Sanholt SET_RING_HEAD(dev_priv, cur_read_ptr); 61095584Sanholt dev_priv->ring.tail = cur_read_ptr; 61195584Sanholt} 61295584Sanholt 61395584Sanholt/* Stop the Command Processor. This will not flush any pending 61495584Sanholt * commands, so you must flush the command stream and wait for the CP 61595584Sanholt * to go idle before calling this routine. 61695584Sanholt */ 617145132Sanholtstatic void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) 61895584Sanholt{ 619145132Sanholt DRM_DEBUG("\n"); 62095584Sanholt 621145132Sanholt RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); 62295584Sanholt 62395584Sanholt dev_priv->cp_running = 0; 62495584Sanholt} 62595584Sanholt 62695584Sanholt/* Reset the engine. This will stop the CP if it is running. 62795584Sanholt */ 628182080Srnolandstatic int radeon_do_engine_reset(struct drm_device * dev) 62995584Sanholt{ 63095584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 631182080Srnoland u32 clock_cntl_index = 0, mclk_cntl = 0, rbbm_soft_reset; 632145132Sanholt DRM_DEBUG("\n"); 63395584Sanholt 634145132Sanholt radeon_do_pixcache_flush(dev_priv); 63595584Sanholt 636182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { 637189499Srnoland /* may need something similar for newer chips */ 638182080Srnoland clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); 639182080Srnoland mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); 64095584Sanholt 641182080Srnoland RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | 642182080Srnoland RADEON_FORCEON_MCLKA | 643182080Srnoland RADEON_FORCEON_MCLKB | 644182080Srnoland RADEON_FORCEON_YCLKA | 645182080Srnoland RADEON_FORCEON_YCLKB | 646182080Srnoland RADEON_FORCEON_MC | 647182080Srnoland RADEON_FORCEON_AIC)); 648182080Srnoland } 64995584Sanholt 650145132Sanholt rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); 65195584Sanholt 652145132Sanholt RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | 653145132Sanholt RADEON_SOFT_RESET_CP | 654145132Sanholt RADEON_SOFT_RESET_HI | 655145132Sanholt RADEON_SOFT_RESET_SE | 656145132Sanholt RADEON_SOFT_RESET_RE | 657145132Sanholt RADEON_SOFT_RESET_PP | 658145132Sanholt RADEON_SOFT_RESET_E2 | 659145132Sanholt RADEON_SOFT_RESET_RB)); 660145132Sanholt RADEON_READ(RADEON_RBBM_SOFT_RESET); 661145132Sanholt RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & 662145132Sanholt ~(RADEON_SOFT_RESET_CP | 66395584Sanholt RADEON_SOFT_RESET_HI | 66495584Sanholt RADEON_SOFT_RESET_SE | 66595584Sanholt RADEON_SOFT_RESET_RE | 66695584Sanholt RADEON_SOFT_RESET_PP | 66795584Sanholt RADEON_SOFT_RESET_E2 | 668145132Sanholt RADEON_SOFT_RESET_RB))); 669145132Sanholt RADEON_READ(RADEON_RBBM_SOFT_RESET); 67095584Sanholt 671182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { 672182080Srnoland RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); 673182080Srnoland RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); 674182080Srnoland RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); 675182080Srnoland } 67695584Sanholt 677182080Srnoland /* setup the raster pipes */ 678182080Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) 679182080Srnoland radeon_init_pipes(dev_priv); 680182080Srnoland 68195584Sanholt /* Reset the CP ring */ 682145132Sanholt radeon_do_cp_reset(dev_priv); 68395584Sanholt 68495584Sanholt /* The CP is no longer running after an engine reset */ 68595584Sanholt dev_priv->cp_running = 0; 68695584Sanholt 68795584Sanholt /* Reset any pending vertex, indirect buffers */ 688145132Sanholt radeon_freelist_reset(dev); 68995584Sanholt 69095584Sanholt return 0; 69195584Sanholt} 69295584Sanholt 693182080Srnolandstatic void radeon_cp_init_ring_buffer(struct drm_device * dev, 694189499Srnoland drm_radeon_private_t *dev_priv, 695189499Srnoland struct drm_file *file_priv) 69695584Sanholt{ 69795584Sanholt u32 ring_start, cur_read_ptr; 698182080Srnoland 699157617Sanholt /* Initialize the memory controller. With new memory map, the fb location 700157617Sanholt * is not changed, it should have been properly initialized already. Part 701157617Sanholt * of the problem is that the code below is bogus, assuming the GART is 702157617Sanholt * always appended to the fb which is not necessarily the case 703157617Sanholt */ 704157617Sanholt if (!dev_priv->new_memmap) 705182080Srnoland radeon_write_fb_location(dev_priv, 706157617Sanholt ((dev_priv->gart_vm_start - 1) & 0xffff0000) 707157617Sanholt | (dev_priv->fb_location >> 16)); 70895584Sanholt 709145132Sanholt#if __OS_HAS_AGP 710182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 711182080Srnoland radeon_write_agp_base(dev_priv, dev->agp->base); 712182080Srnoland 713182080Srnoland radeon_write_agp_location(dev_priv, 714145132Sanholt (((dev_priv->gart_vm_start - 1 + 715145132Sanholt dev_priv->gart_size) & 0xffff0000) | 716145132Sanholt (dev_priv->gart_vm_start >> 16))); 71795584Sanholt 71895584Sanholt ring_start = (dev_priv->cp_ring->offset 719157617Sanholt - dev->agp->base 720157617Sanholt + dev_priv->gart_vm_start); 721145132Sanholt } else 72295584Sanholt#endif 72395584Sanholt ring_start = (dev_priv->cp_ring->offset 724157617Sanholt - (unsigned long)dev->sg->virtual 725157617Sanholt + dev_priv->gart_vm_start); 72695584Sanholt 727145132Sanholt RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); 72895584Sanholt 72995584Sanholt /* Set the write pointer delay */ 730145132Sanholt RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0); 73195584Sanholt 73295584Sanholt /* Initialize the ring buffer's read and write pointers */ 733145132Sanholt cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); 734145132Sanholt RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); 735145132Sanholt SET_RING_HEAD(dev_priv, cur_read_ptr); 73695584Sanholt dev_priv->ring.tail = cur_read_ptr; 73795584Sanholt 738145132Sanholt#if __OS_HAS_AGP 739182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 740145132Sanholt RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 741145132Sanholt dev_priv->ring_rptr->offset 742145132Sanholt - dev->agp->base + dev_priv->gart_vm_start); 743113995Sanholt } else 744113995Sanholt#endif 745113995Sanholt { 746189499Srnoland RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 747189499Srnoland dev_priv->ring_rptr->offset 748189499Srnoland - ((unsigned long) dev->sg->virtual) 749189499Srnoland + dev_priv->gart_vm_start); 75095584Sanholt } 75195584Sanholt 752157617Sanholt /* Set ring buffer size */ 753157617Sanholt#ifdef __BIG_ENDIAN 754157617Sanholt RADEON_WRITE(RADEON_CP_RB_CNTL, 755182080Srnoland RADEON_BUF_SWAP_32BIT | 756182080Srnoland (dev_priv->ring.fetch_size_l2ow << 18) | 757182080Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 758182080Srnoland dev_priv->ring.size_l2qw); 759157617Sanholt#else 760182080Srnoland RADEON_WRITE(RADEON_CP_RB_CNTL, 761182080Srnoland (dev_priv->ring.fetch_size_l2ow << 18) | 762182080Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 763182080Srnoland dev_priv->ring.size_l2qw); 764157617Sanholt#endif 765157617Sanholt 766189499Srnoland 767112015Sanholt /* Initialize the scratch register pointer. This will cause 768112015Sanholt * the scratch register values to be written out to memory 769112015Sanholt * whenever they are updated. 770112015Sanholt * 771112015Sanholt * We simply put this behind the ring read pointer, this works 772112015Sanholt * with PCI GART as well as (whatever kind of) AGP GART 773112015Sanholt */ 774145132Sanholt RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) 775145132Sanholt + RADEON_SCRATCH_REG_OFFSET); 776112015Sanholt 777145132Sanholt RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); 778112015Sanholt 779189499Srnoland radeon_enable_bm(dev_priv); 780112015Sanholt 781189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); 782189499Srnoland RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); 783112015Sanholt 784189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); 785189499Srnoland RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); 786112015Sanholt 787189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); 788189499Srnoland RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); 789112015Sanholt 790189499Srnoland /* reset sarea copies of these */ 791189499Srnoland if (dev_priv->sarea_priv) { 792189499Srnoland dev_priv->sarea_priv->last_frame = 0; 793189499Srnoland dev_priv->sarea_priv->last_dispatch = 0; 794189499Srnoland dev_priv->sarea_priv->last_clear = 0; 795189499Srnoland } 796189499Srnoland 797145132Sanholt radeon_do_wait_for_idle(dev_priv); 79895584Sanholt 79995584Sanholt /* Sync everything up */ 800145132Sanholt RADEON_WRITE(RADEON_ISYNC_CNTL, 801145132Sanholt (RADEON_ISYNC_ANY2D_IDLE3D | 802145132Sanholt RADEON_ISYNC_ANY3D_IDLE2D | 803145132Sanholt RADEON_ISYNC_WAIT_IDLEGUI | 804145132Sanholt RADEON_ISYNC_CPSCRATCH_IDLEGUI)); 805157617Sanholt 80695584Sanholt} 80795584Sanholt 808157617Sanholtstatic void radeon_test_writeback(drm_radeon_private_t * dev_priv) 809157617Sanholt{ 810157617Sanholt u32 tmp; 811157617Sanholt 812189499Srnoland /* Start with assuming that writeback doesn't work */ 813189499Srnoland dev_priv->writeback_works = 0; 814189499Srnoland 815157617Sanholt /* Writeback doesn't seem to work everywhere, test it here and possibly 816157617Sanholt * enable it if it appears to work 817157617Sanholt */ 818189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); 819189499Srnoland 820157617Sanholt RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); 821157617Sanholt 822157617Sanholt for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { 823189499Srnoland u32 val; 824189499Srnoland 825189499Srnoland val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); 826189499Srnoland if (val == 0xdeadbeef) 827157617Sanholt break; 828157617Sanholt DRM_UDELAY(1); 829157617Sanholt } 830157617Sanholt 831157617Sanholt if (tmp < dev_priv->usec_timeout) { 832157617Sanholt dev_priv->writeback_works = 1; 833157617Sanholt DRM_INFO("writeback test succeeded in %d usecs\n", tmp); 834157617Sanholt } else { 835157617Sanholt dev_priv->writeback_works = 0; 836157617Sanholt DRM_INFO("writeback test failed\n"); 837157617Sanholt } 838157617Sanholt if (radeon_no_wb == 1) { 839157617Sanholt dev_priv->writeback_works = 0; 840157617Sanholt DRM_INFO("writeback forced off\n"); 841157617Sanholt } 842162132Sanholt 843162132Sanholt if (!dev_priv->writeback_works) { 844189499Srnoland /* Disable writeback to avoid unnecessary bus master transfer */ 845189499Srnoland RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | 846189499Srnoland RADEON_RB_NO_UPDATE); 847162132Sanholt RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); 848162132Sanholt } 849157617Sanholt} 850157617Sanholt 851182080Srnoland/* Enable or disable IGP GART on the chip */ 852182080Srnolandstatic void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) 853182080Srnoland{ 854182080Srnoland u32 temp; 855182080Srnoland 856182080Srnoland if (on) { 857182080Srnoland DRM_DEBUG("programming igp gart %08X %08lX %08X\n", 858189499Srnoland dev_priv->gart_vm_start, 859189499Srnoland (long)dev_priv->gart_info.bus_addr, 860189499Srnoland dev_priv->gart_size); 861182080Srnoland 862182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); 863183828Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 864183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 865182080Srnoland IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | 866182080Srnoland RS690_BLOCK_GFX_D3_EN)); 867182080Srnoland else 868182080Srnoland IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); 869182080Srnoland 870182080Srnoland IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | 871182080Srnoland RS480_VA_SIZE_32MB)); 872182080Srnoland 873182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID); 874182080Srnoland IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN | 875182080Srnoland RS480_TLB_ENABLE | 876182080Srnoland RS480_GTW_LAC_EN | 877182080Srnoland RS480_1LEVEL_GART)); 878182080Srnoland 879182080Srnoland temp = dev_priv->gart_info.bus_addr & 0xfffff000; 880182080Srnoland temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4; 881182080Srnoland IGP_WRITE_MCIND(RS480_GART_BASE, temp); 882182080Srnoland 883182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL); 884182080Srnoland IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) | 885182080Srnoland RS480_REQ_TYPE_SNOOP_DIS)); 886182080Srnoland 887182080Srnoland radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start); 888182080Srnoland 889182080Srnoland dev_priv->gart_size = 32*1024*1024; 890189499Srnoland temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 891189499Srnoland 0xffff0000) | (dev_priv->gart_vm_start >> 16)); 892182080Srnoland 893182080Srnoland radeon_write_agp_location(dev_priv, temp); 894182080Srnoland 895182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); 896182080Srnoland IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | 897182080Srnoland RS480_VA_SIZE_32MB)); 898182080Srnoland 899182080Srnoland do { 900182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); 901182080Srnoland if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) 902182080Srnoland break; 903182080Srnoland DRM_UDELAY(1); 904189499Srnoland } while (1); 905182080Srnoland 906182080Srnoland IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 907182080Srnoland RS480_GART_CACHE_INVALIDATE); 908182080Srnoland 909182080Srnoland do { 910182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); 911182080Srnoland if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) 912182080Srnoland break; 913182080Srnoland DRM_UDELAY(1); 914189499Srnoland } while (1); 915182080Srnoland 916182080Srnoland IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); 917182080Srnoland } else { 918182080Srnoland IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0); 919182080Srnoland } 920182080Srnoland} 921182080Srnoland 922189499Srnoland/* Enable or disable IGP GART on the chip */ 923189499Srnolandstatic void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) 924189499Srnoland{ 925189499Srnoland u32 temp; 926189499Srnoland int i; 927189499Srnoland 928189499Srnoland if (on) { 929189499Srnoland DRM_DEBUG("programming igp gart %08X %08lX %08X\n", 930189499Srnoland dev_priv->gart_vm_start, 931189499Srnoland (long)dev_priv->gart_info.bus_addr, 932189499Srnoland dev_priv->gart_size); 933189499Srnoland 934189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | 935189499Srnoland RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); 936189499Srnoland 937189499Srnoland for (i = 0; i < 19; i++) 938189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, 939189499Srnoland (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | 940189499Srnoland RS600_SYSTEM_ACCESS_MODE_IN_SYS | 941189499Srnoland RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | 942189499Srnoland RS600_EFFECTIVE_L1_CACHE_SIZE(3) | 943189499Srnoland RS600_ENABLE_FRAGMENT_PROCESSING | 944189499Srnoland RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); 945189499Srnoland 946189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | 947189499Srnoland RS600_PAGE_TABLE_TYPE_FLAT)); 948189499Srnoland 949189499Srnoland /* disable all other contexts */ 950189499Srnoland for (i = 1; i < 8; i++) 951189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); 952189499Srnoland 953189499Srnoland /* setup the page table aperture */ 954189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, 955189499Srnoland dev_priv->gart_info.bus_addr); 956189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, 957189499Srnoland dev_priv->gart_vm_start); 958189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, 959189499Srnoland (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); 960189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); 961189499Srnoland 962189499Srnoland /* setup the system aperture */ 963189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, 964189499Srnoland dev_priv->gart_vm_start); 965189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, 966189499Srnoland (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); 967189499Srnoland 968189499Srnoland /* enable page tables */ 969189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 970189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); 971189499Srnoland 972189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); 973189499Srnoland IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); 974189499Srnoland 975189499Srnoland /* invalidate the cache */ 976189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 977189499Srnoland 978189499Srnoland temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); 979189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); 980189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 981189499Srnoland 982189499Srnoland temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; 983189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); 984189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 985189499Srnoland 986189499Srnoland temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); 987189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); 988189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 989189499Srnoland 990189499Srnoland } else { 991189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); 992189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); 993189499Srnoland temp &= ~RS600_ENABLE_PAGE_TABLES; 994189499Srnoland IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); 995189499Srnoland } 996189499Srnoland} 997189499Srnoland 998148211Sanholtstatic void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) 999148211Sanholt{ 1000148211Sanholt u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); 1001148211Sanholt if (on) { 1002148211Sanholt 1003152909Sanholt DRM_DEBUG("programming pcie %08X %08lX %08X\n", 1004157617Sanholt dev_priv->gart_vm_start, 1005157617Sanholt (long)dev_priv->gart_info.bus_addr, 1006152909Sanholt dev_priv->gart_size); 1007157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, 1008157617Sanholt dev_priv->gart_vm_start); 1009157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, 1010157617Sanholt dev_priv->gart_info.bus_addr); 1011157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, 1012157617Sanholt dev_priv->gart_vm_start); 1013157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, 1014157617Sanholt dev_priv->gart_vm_start + 1015157617Sanholt dev_priv->gart_size - 1); 1016148211Sanholt 1017182080Srnoland radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ 1018148211Sanholt 1019157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, 1020157617Sanholt RADEON_PCIE_TX_GART_EN); 1021148211Sanholt } else { 1022157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, 1023157617Sanholt tmp & ~RADEON_PCIE_TX_GART_EN); 1024148211Sanholt } 1025148211Sanholt} 1026148211Sanholt 1027119098Sanholt/* Enable or disable PCI GART on the chip */ 1028145132Sanholtstatic void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) 1029119098Sanholt{ 1030152909Sanholt u32 tmp; 1031119098Sanholt 1032182080Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 1033183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740) || 1034182080Srnoland (dev_priv->flags & RADEON_IS_IGPGART)) { 1035182080Srnoland radeon_set_igpgart(dev_priv, on); 1036182080Srnoland return; 1037182080Srnoland } 1038182080Srnoland 1039189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { 1040189499Srnoland rs600_set_igpgart(dev_priv, on); 1041189499Srnoland return; 1042189499Srnoland } 1043189499Srnoland 1044182080Srnoland if (dev_priv->flags & RADEON_IS_PCIE) { 1045148211Sanholt radeon_set_pciegart(dev_priv, on); 1046148211Sanholt return; 1047148211Sanholt } 1048148211Sanholt 1049182080Srnoland tmp = RADEON_READ(RADEON_AIC_CNTL); 1050152909Sanholt 1051145132Sanholt if (on) { 1052145132Sanholt RADEON_WRITE(RADEON_AIC_CNTL, 1053145132Sanholt tmp | RADEON_PCIGART_TRANSLATE_EN); 1054119098Sanholt 1055119098Sanholt /* set PCI GART page-table base address 1056119098Sanholt */ 1057152909Sanholt RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); 1058119098Sanholt 1059119098Sanholt /* set address range for PCI address translate 1060119098Sanholt */ 1061145132Sanholt RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start); 1062145132Sanholt RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start 1063145132Sanholt + dev_priv->gart_size - 1); 1064119098Sanholt 1065119895Sanholt /* Turn off AGP aperture -- is this required for PCI GART? 1066119098Sanholt */ 1067182080Srnoland radeon_write_agp_location(dev_priv, 0xffffffc0); 1068145132Sanholt RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ 1069119098Sanholt } else { 1070145132Sanholt RADEON_WRITE(RADEON_AIC_CNTL, 1071145132Sanholt tmp & ~RADEON_PCIGART_TRANSLATE_EN); 1072119098Sanholt } 1073119098Sanholt} 1074119098Sanholt 1075189499Srnolandstatic int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) 107695584Sanholt{ 1077189499Srnoland struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; 1078189499Srnoland struct radeon_virt_surface *vp; 1079189499Srnoland int i; 1080189499Srnoland 1081189499Srnoland for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { 1082189499Srnoland if (!dev_priv->virt_surfaces[i].file_priv || 1083189499Srnoland dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) 1084189499Srnoland break; 1085189499Srnoland } 1086189499Srnoland if (i >= 2 * RADEON_MAX_SURFACES) 1087189499Srnoland return -ENOMEM; 1088189499Srnoland vp = &dev_priv->virt_surfaces[i]; 1089189499Srnoland 1090189499Srnoland for (i = 0; i < RADEON_MAX_SURFACES; i++) { 1091189499Srnoland struct radeon_surface *sp = &dev_priv->surfaces[i]; 1092189499Srnoland if (sp->refcount) 1093189499Srnoland continue; 1094189499Srnoland 1095189499Srnoland vp->surface_index = i; 1096189499Srnoland vp->lower = gart_info->bus_addr; 1097189499Srnoland vp->upper = vp->lower + gart_info->table_size; 1098189499Srnoland vp->flags = 0; 1099189499Srnoland vp->file_priv = PCIGART_FILE_PRIV; 1100189499Srnoland 1101189499Srnoland sp->refcount = 1; 1102189499Srnoland sp->lower = vp->lower; 1103189499Srnoland sp->upper = vp->upper; 1104189499Srnoland sp->flags = 0; 1105189499Srnoland 1106189499Srnoland RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); 1107189499Srnoland RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); 1108189499Srnoland RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); 1109189499Srnoland return 0; 1110189499Srnoland } 1111189499Srnoland 1112189499Srnoland return -ENOMEM; 1113189499Srnoland} 1114189499Srnoland 1115189499Srnolandstatic int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, 1116189499Srnoland struct drm_file *file_priv) 1117189499Srnoland{ 1118145132Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1119157617Sanholt 1120145132Sanholt DRM_DEBUG("\n"); 112195584Sanholt 1122157617Sanholt /* if we require new memory map but we don't have it fail */ 1123182080Srnoland if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { 1124157617Sanholt DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); 1125157617Sanholt radeon_do_cleanup_cp(dev); 1126182080Srnoland return -EINVAL; 1127157617Sanholt } 1128157617Sanholt 1129189499Srnoland if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { 1130152909Sanholt DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1131182080Srnoland dev_priv->flags &= ~RADEON_IS_AGP; 1132189499Srnoland } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) 1133189499Srnoland && !init->is_pci) { 1134162132Sanholt DRM_DEBUG("Restoring AGP flag\n"); 1135182080Srnoland dev_priv->flags |= RADEON_IS_AGP; 1136162132Sanholt } 1137152909Sanholt 1138182080Srnoland if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { 1139145132Sanholt DRM_ERROR("PCI GART memory not allocated!\n"); 114095584Sanholt radeon_do_cleanup_cp(dev); 1141182080Srnoland return -EINVAL; 114295584Sanholt } 114395584Sanholt 114495584Sanholt dev_priv->usec_timeout = init->usec_timeout; 1145145132Sanholt if (dev_priv->usec_timeout < 1 || 1146145132Sanholt dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { 1147145132Sanholt DRM_DEBUG("TIMEOUT problem!\n"); 114895584Sanholt radeon_do_cleanup_cp(dev); 1149182080Srnoland return -EINVAL; 115095584Sanholt } 115195584Sanholt 1152182080Srnoland /* Enable vblank on CRTC1 for older X servers 1153182080Srnoland */ 1154182080Srnoland dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; 1155145132Sanholt 1156189499Srnoland switch(init->func) { 1157189499Srnoland case RADEON_INIT_R200_CP: 1158189499Srnoland dev_priv->microcode_version = UCODE_R200; 1159189499Srnoland break; 1160189499Srnoland case RADEON_INIT_R300_CP: 1161189499Srnoland dev_priv->microcode_version = UCODE_R300; 1162189499Srnoland break; 1163189499Srnoland default: 1164189499Srnoland dev_priv->microcode_version = UCODE_R100; 1165189499Srnoland } 1166189499Srnoland 1167112015Sanholt dev_priv->do_boxes = 0; 116895584Sanholt dev_priv->cp_mode = init->cp_mode; 116995584Sanholt 117095584Sanholt /* We don't support anything other than bus-mastering ring mode, 117195584Sanholt * but the ring can be in either AGP or PCI space for the ring 117295584Sanholt * read pointer. 117395584Sanholt */ 1174145132Sanholt if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && 1175145132Sanholt (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { 1176145132Sanholt DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); 117795584Sanholt radeon_do_cleanup_cp(dev); 1178182080Srnoland return -EINVAL; 117995584Sanholt } 118095584Sanholt 1181145132Sanholt switch (init->fb_bpp) { 118295584Sanholt case 16: 118395584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 118495584Sanholt break; 118595584Sanholt case 32: 118695584Sanholt default: 118795584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 118895584Sanholt break; 118995584Sanholt } 1190145132Sanholt dev_priv->front_offset = init->front_offset; 1191145132Sanholt dev_priv->front_pitch = init->front_pitch; 1192145132Sanholt dev_priv->back_offset = init->back_offset; 1193145132Sanholt dev_priv->back_pitch = init->back_pitch; 119495584Sanholt 1195145132Sanholt switch (init->depth_bpp) { 119695584Sanholt case 16: 119795584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; 119895584Sanholt break; 119995584Sanholt case 32: 120095584Sanholt default: 120195584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; 120295584Sanholt break; 120395584Sanholt } 1204145132Sanholt dev_priv->depth_offset = init->depth_offset; 1205145132Sanholt dev_priv->depth_pitch = init->depth_pitch; 120695584Sanholt 120795584Sanholt /* Hardware state for depth clears. Remove this if/when we no 120895584Sanholt * longer clear the depth buffer with a 3D rectangle. Hard-code 120995584Sanholt * all values to prevent unwanted 3D state from slipping through 121095584Sanholt * and screwing with the clear operation. 121195584Sanholt */ 121295584Sanholt dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | 121395584Sanholt (dev_priv->color_fmt << 10) | 1214189499Srnoland (dev_priv->microcode_version == 1215189499Srnoland UCODE_R100 ? RADEON_ZBLOCK16 : 0)); 121695584Sanholt 1217145132Sanholt dev_priv->depth_clear.rb3d_zstencilcntl = 1218145132Sanholt (dev_priv->depth_fmt | 1219145132Sanholt RADEON_Z_TEST_ALWAYS | 1220145132Sanholt RADEON_STENCIL_TEST_ALWAYS | 1221145132Sanholt RADEON_STENCIL_S_FAIL_REPLACE | 1222145132Sanholt RADEON_STENCIL_ZPASS_REPLACE | 1223145132Sanholt RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE); 122495584Sanholt 122595584Sanholt dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | 122695584Sanholt RADEON_BFACE_SOLID | 122795584Sanholt RADEON_FFACE_SOLID | 122895584Sanholt RADEON_FLAT_SHADE_VTX_LAST | 122995584Sanholt RADEON_DIFFUSE_SHADE_FLAT | 123095584Sanholt RADEON_ALPHA_SHADE_FLAT | 123195584Sanholt RADEON_SPECULAR_SHADE_FLAT | 123295584Sanholt RADEON_FOG_SHADE_FLAT | 123395584Sanholt RADEON_VTX_PIX_CENTER_OGL | 123495584Sanholt RADEON_ROUND_MODE_TRUNC | 123595584Sanholt RADEON_ROUND_PREC_8TH_PIX); 123695584Sanholt 1237113995Sanholt 1238113995Sanholt dev_priv->ring_offset = init->ring_offset; 1239113995Sanholt dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1240113995Sanholt dev_priv->buffers_offset = init->buffers_offset; 1241119895Sanholt dev_priv->gart_textures_offset = init->gart_textures_offset; 1242145132Sanholt 1243182080Srnoland dev_priv->sarea = drm_getsarea(dev); 1244145132Sanholt if (!dev_priv->sarea) { 124595584Sanholt DRM_ERROR("could not find sarea!\n"); 124695584Sanholt radeon_do_cleanup_cp(dev); 1247182080Srnoland return -EINVAL; 124895584Sanholt } 124995584Sanholt 1250145132Sanholt dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); 1251145132Sanholt if (!dev_priv->cp_ring) { 125295584Sanholt DRM_ERROR("could not find cp ring region!\n"); 125395584Sanholt radeon_do_cleanup_cp(dev); 1254182080Srnoland return -EINVAL; 125595584Sanholt } 1256145132Sanholt dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); 1257145132Sanholt if (!dev_priv->ring_rptr) { 125895584Sanholt DRM_ERROR("could not find ring read pointer!\n"); 125995584Sanholt radeon_do_cleanup_cp(dev); 1260182080Srnoland return -EINVAL; 126195584Sanholt } 1262152909Sanholt dev->agp_buffer_token = init->buffers_offset; 1263145132Sanholt dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1264145132Sanholt if (!dev->agp_buffer_map) { 126595584Sanholt DRM_ERROR("could not find dma buffer region!\n"); 126695584Sanholt radeon_do_cleanup_cp(dev); 1267182080Srnoland return -EINVAL; 126895584Sanholt } 126995584Sanholt 1270145132Sanholt if (init->gart_textures_offset) { 1271145132Sanholt dev_priv->gart_textures = 1272145132Sanholt drm_core_findmap(dev, init->gart_textures_offset); 1273145132Sanholt if (!dev_priv->gart_textures) { 1274119895Sanholt DRM_ERROR("could not find GART texture region!\n"); 127595584Sanholt radeon_do_cleanup_cp(dev); 1276182080Srnoland return -EINVAL; 127795584Sanholt } 127895584Sanholt } 127995584Sanholt 128095584Sanholt dev_priv->sarea_priv = 1281145132Sanholt (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + 1282145132Sanholt init->sarea_priv_offset); 128395584Sanholt 1284145132Sanholt#if __OS_HAS_AGP 1285182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1286189499Srnoland drm_core_ioremap_wc(dev_priv->cp_ring, dev); 1287189499Srnoland drm_core_ioremap_wc(dev_priv->ring_rptr, dev); 1288189499Srnoland drm_core_ioremap_wc(dev->agp_buffer_map, dev); 1289145132Sanholt if (!dev_priv->cp_ring->handle || 1290145132Sanholt !dev_priv->ring_rptr->handle || 1291145132Sanholt !dev->agp_buffer_map->handle) { 129295584Sanholt DRM_ERROR("could not find ioremap agp regions!\n"); 129395584Sanholt radeon_do_cleanup_cp(dev); 1294182080Srnoland return -EINVAL; 129595584Sanholt } 1296119098Sanholt } else 1297119098Sanholt#endif 1298119098Sanholt { 1299189499Srnoland dev_priv->cp_ring->handle = 1300189499Srnoland (void *)(unsigned long)dev_priv->cp_ring->offset; 130195584Sanholt dev_priv->ring_rptr->handle = 1302189499Srnoland (void *)(unsigned long)dev_priv->ring_rptr->offset; 1303145132Sanholt dev->agp_buffer_map->handle = 1304189499Srnoland (void *)(unsigned long)dev->agp_buffer_map->offset; 130595584Sanholt 1306145132Sanholt DRM_DEBUG("dev_priv->cp_ring->handle %p\n", 1307145132Sanholt dev_priv->cp_ring->handle); 1308145132Sanholt DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", 1309145132Sanholt dev_priv->ring_rptr->handle); 1310145132Sanholt DRM_DEBUG("dev->agp_buffer_map->handle %p\n", 1311145132Sanholt dev->agp_buffer_map->handle); 131295584Sanholt } 131395584Sanholt 1314182080Srnoland dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; 1315182080Srnoland dev_priv->fb_size = 1316182080Srnoland ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) 1317157617Sanholt - dev_priv->fb_location; 131895584Sanholt 1319145132Sanholt dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1320145132Sanholt ((dev_priv->front_offset 1321145132Sanholt + dev_priv->fb_location) >> 10)); 1322122580Sanholt 1323145132Sanholt dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | 1324145132Sanholt ((dev_priv->back_offset 1325145132Sanholt + dev_priv->fb_location) >> 10)); 1326122580Sanholt 1327145132Sanholt dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | 1328145132Sanholt ((dev_priv->depth_offset 1329145132Sanholt + dev_priv->fb_location) >> 10)); 1330122580Sanholt 1331119895Sanholt dev_priv->gart_size = init->gart_size; 1332122580Sanholt 1333157617Sanholt /* New let's set the memory map ... */ 1334157617Sanholt if (dev_priv->new_memmap) { 1335157617Sanholt u32 base = 0; 1336157617Sanholt 1337157617Sanholt DRM_INFO("Setting GART location based on new memory map\n"); 1338157617Sanholt 1339157617Sanholt /* If using AGP, try to locate the AGP aperture at the same 1340157617Sanholt * location in the card and on the bus, though we have to 1341157617Sanholt * align it down. 1342157617Sanholt */ 1343145132Sanholt#if __OS_HAS_AGP 1344182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1345157617Sanholt base = dev->agp->base; 1346157617Sanholt /* Check if valid */ 1347182080Srnoland if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && 1348182080Srnoland base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { 1349157617Sanholt DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", 1350157617Sanholt dev->agp->base); 1351157617Sanholt base = 0; 1352157617Sanholt } 1353157617Sanholt } 1354157617Sanholt#endif 1355157617Sanholt /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ 1356157617Sanholt if (base == 0) { 1357157617Sanholt base = dev_priv->fb_location + dev_priv->fb_size; 1358182080Srnoland if (base < dev_priv->fb_location || 1359182080Srnoland ((base + dev_priv->gart_size) & 0xfffffffful) < base) 1360157617Sanholt base = dev_priv->fb_location 1361157617Sanholt - dev_priv->gart_size; 1362182080Srnoland } 1363157617Sanholt dev_priv->gart_vm_start = base & 0xffc00000u; 1364157617Sanholt if (dev_priv->gart_vm_start != base) 1365157617Sanholt DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", 1366157617Sanholt base, dev_priv->gart_vm_start); 1367157617Sanholt } else { 1368157617Sanholt DRM_INFO("Setting GART location based on old memory map\n"); 1369157617Sanholt dev_priv->gart_vm_start = dev_priv->fb_location + 1370157617Sanholt RADEON_READ(RADEON_CONFIG_APER_SIZE); 1371157617Sanholt } 1372157617Sanholt 1373157617Sanholt#if __OS_HAS_AGP 1374182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) 1375145132Sanholt dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 1376145132Sanholt - dev->agp->base 1377145132Sanholt + dev_priv->gart_vm_start); 137895584Sanholt else 137995584Sanholt#endif 1380145132Sanholt dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 1381157617Sanholt - (unsigned long)dev->sg->virtual 1382157617Sanholt + dev_priv->gart_vm_start); 138395584Sanholt 1384145132Sanholt DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); 1385145132Sanholt DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start); 1386145132Sanholt DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n", 1387145132Sanholt dev_priv->gart_buffers_offset); 138895584Sanholt 1389145132Sanholt dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; 1390145132Sanholt dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle 139195584Sanholt + init->ring_size / sizeof(u32)); 139295584Sanholt dev_priv->ring.size = init->ring_size; 1393145132Sanholt dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); 139495584Sanholt 1395182080Srnoland dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; 1396182080Srnoland dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8); 1397182080Srnoland 1398182080Srnoland dev_priv->ring.fetch_size = /* init->fetch_size */ 32; 1399182080Srnoland dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); 1400145132Sanholt dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; 140195584Sanholt 140295584Sanholt dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 140395584Sanholt 1404145132Sanholt#if __OS_HAS_AGP 1405182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1406119098Sanholt /* Turn off PCI GART */ 1407145132Sanholt radeon_set_pcigart(dev_priv, 0); 1408119098Sanholt } else 1409119098Sanholt#endif 1410119098Sanholt { 1411189499Srnoland u32 sctrl; 1412189499Srnoland int ret; 1413189499Srnoland 1414182080Srnoland dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); 1415152909Sanholt /* if we have an offset set from userspace */ 1416182080Srnoland if (dev_priv->pcigart_offset_set) { 1417157617Sanholt dev_priv->gart_info.bus_addr = 1418157617Sanholt dev_priv->pcigart_offset + dev_priv->fb_location; 1419157617Sanholt dev_priv->gart_info.mapping.offset = 1420182080Srnoland dev_priv->pcigart_offset + dev_priv->fb_aper_offset; 1421157617Sanholt dev_priv->gart_info.mapping.size = 1422182080Srnoland dev_priv->gart_info.table_size; 1423157617Sanholt 1424182080Srnoland drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); 1425157617Sanholt dev_priv->gart_info.addr = 1426157617Sanholt dev_priv->gart_info.mapping.handle; 1427152909Sanholt 1428182080Srnoland if (dev_priv->flags & RADEON_IS_PCIE) 1429182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; 1430182080Srnoland else 1431182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; 1432157617Sanholt dev_priv->gart_info.gart_table_location = 1433157617Sanholt DRM_ATI_GART_FB; 1434157617Sanholt 1435157617Sanholt DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", 1436157617Sanholt dev_priv->gart_info.addr, 1437157617Sanholt dev_priv->pcigart_offset); 1438157617Sanholt } else { 1439182080Srnoland if (dev_priv->flags & RADEON_IS_IGPGART) 1440182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; 1441182080Srnoland else 1442182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; 1443157617Sanholt dev_priv->gart_info.gart_table_location = 1444157617Sanholt DRM_ATI_GART_MAIN; 1445152909Sanholt dev_priv->gart_info.addr = NULL; 1446152909Sanholt dev_priv->gart_info.bus_addr = 0; 1447182080Srnoland if (dev_priv->flags & RADEON_IS_PCIE) { 1448157617Sanholt DRM_ERROR 1449157617Sanholt ("Cannot use PCI Express without GART in FB memory\n"); 1450152909Sanholt radeon_do_cleanup_cp(dev); 1451182080Srnoland return -EINVAL; 1452152909Sanholt } 1453152909Sanholt } 1454152909Sanholt 1455189499Srnoland sctrl = RADEON_READ(RADEON_SURFACE_CNTL); 1456189499Srnoland RADEON_WRITE(RADEON_SURFACE_CNTL, 0); 1457189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 1458189499Srnoland ret = r600_page_table_init(dev); 1459189499Srnoland else 1460189499Srnoland ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); 1461189499Srnoland RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); 1462189499Srnoland 1463189499Srnoland if (!ret) { 1464145132Sanholt DRM_ERROR("failed to init PCI GART!\n"); 146595584Sanholt radeon_do_cleanup_cp(dev); 1466182080Srnoland return -ENOMEM; 146795584Sanholt } 146895584Sanholt 1469189499Srnoland ret = radeon_setup_pcigart_surface(dev_priv); 1470189499Srnoland if (ret) { 1471189499Srnoland DRM_ERROR("failed to setup GART surface!\n"); 1472189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 1473189499Srnoland r600_page_table_cleanup(dev, &dev_priv->gart_info); 1474189499Srnoland else 1475189499Srnoland drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); 1476189499Srnoland radeon_do_cleanup_cp(dev); 1477189499Srnoland return ret; 1478189499Srnoland } 1479189499Srnoland 1480119098Sanholt /* Turn on PCI GART */ 1481145132Sanholt radeon_set_pcigart(dev_priv, 1); 148295584Sanholt } 148395584Sanholt 1484145132Sanholt radeon_cp_load_microcode(dev_priv); 1485189499Srnoland radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); 148695584Sanholt 148795584Sanholt dev_priv->last_buf = 0; 148895584Sanholt 1489145132Sanholt radeon_do_engine_reset(dev); 1490157617Sanholt radeon_test_writeback(dev_priv); 149195584Sanholt 149295584Sanholt return 0; 149395584Sanholt} 149495584Sanholt 1495182080Srnolandstatic int radeon_do_cleanup_cp(struct drm_device * dev) 149695584Sanholt{ 1497145132Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1498145132Sanholt DRM_DEBUG("\n"); 149995584Sanholt 1500119098Sanholt /* Make sure interrupts are disabled here because the uninstall ioctl 1501119098Sanholt * may not have been called from userspace and after dev_private 1502119098Sanholt * is freed, it's too late. 1503119098Sanholt */ 1504145132Sanholt if (dev->irq_enabled) 1505145132Sanholt drm_irq_uninstall(dev); 1506119098Sanholt 1507145132Sanholt#if __OS_HAS_AGP 1508182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1509145132Sanholt if (dev_priv->cp_ring != NULL) { 1510145132Sanholt drm_core_ioremapfree(dev_priv->cp_ring, dev); 1511145132Sanholt dev_priv->cp_ring = NULL; 1512145132Sanholt } 1513145132Sanholt if (dev_priv->ring_rptr != NULL) { 1514145132Sanholt drm_core_ioremapfree(dev_priv->ring_rptr, dev); 1515145132Sanholt dev_priv->ring_rptr = NULL; 1516145132Sanholt } 1517145132Sanholt if (dev->agp_buffer_map != NULL) { 1518145132Sanholt drm_core_ioremapfree(dev->agp_buffer_map, dev); 1519145132Sanholt dev->agp_buffer_map = NULL; 1520145132Sanholt } 1521145132Sanholt } else 1522119098Sanholt#endif 1523145132Sanholt { 1524152909Sanholt 1525152909Sanholt if (dev_priv->gart_info.bus_addr) { 1526152909Sanholt /* Turn off PCI GART */ 1527152909Sanholt radeon_set_pcigart(dev_priv, 0); 1528189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 1529189499Srnoland r600_page_table_cleanup(dev, &dev_priv->gart_info); 1530189499Srnoland else { 1531189499Srnoland if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) 1532189499Srnoland DRM_ERROR("failed to cleanup PCI GART!\n"); 1533189499Srnoland } 1534152909Sanholt } 1535152909Sanholt 1536152909Sanholt if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) 1537152909Sanholt { 1538152909Sanholt drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); 1539152909Sanholt dev_priv->gart_info.addr = 0; 1540152909Sanholt } 154195584Sanholt } 1542145132Sanholt /* only clear to the start of flags */ 1543145132Sanholt memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); 154495584Sanholt 154595584Sanholt return 0; 154695584Sanholt} 154795584Sanholt 1548145132Sanholt/* This code will reinit the Radeon CP hardware after a resume from disc. 1549145132Sanholt * AFAIK, it would be very difficult to pickle the state at suspend time, so 1550119098Sanholt * here we make sure that all Radeon hardware initialisation is re-done without 1551119098Sanholt * affecting running applications. 1552119098Sanholt * 1553119098Sanholt * Charl P. Botha <http://cpbotha.net> 1554119098Sanholt */ 1555189499Srnolandstatic int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) 1556119098Sanholt{ 1557119098Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1558119098Sanholt 1559145132Sanholt if (!dev_priv) { 1560145132Sanholt DRM_ERROR("Called with no initialization\n"); 1561182080Srnoland return -EINVAL; 1562119098Sanholt } 1563119098Sanholt 1564119098Sanholt DRM_DEBUG("Starting radeon_do_resume_cp()\n"); 1565119098Sanholt 1566145132Sanholt#if __OS_HAS_AGP 1567182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1568119098Sanholt /* Turn off PCI GART */ 1569145132Sanholt radeon_set_pcigart(dev_priv, 0); 1570119098Sanholt } else 1571119098Sanholt#endif 1572119098Sanholt { 1573119098Sanholt /* Turn on PCI GART */ 1574145132Sanholt radeon_set_pcigart(dev_priv, 1); 1575119098Sanholt } 1576119098Sanholt 1577145132Sanholt radeon_cp_load_microcode(dev_priv); 1578189499Srnoland radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); 1579119098Sanholt 1580145132Sanholt radeon_do_engine_reset(dev); 1581182080Srnoland radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 1582119098Sanholt 1583119098Sanholt DRM_DEBUG("radeon_do_resume_cp() complete\n"); 1584119098Sanholt 1585119098Sanholt return 0; 1586119098Sanholt} 1587119098Sanholt 1588182080Srnolandint radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) 158995584Sanholt{ 1590189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1591182080Srnoland drm_radeon_init_t *init = data; 159295584Sanholt 1593182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 1594119098Sanholt 1595182080Srnoland if (init->func == RADEON_INIT_R300_CP) 1596182080Srnoland r300_init_reg_flags(dev); 159795584Sanholt 1598182080Srnoland switch (init->func) { 159995584Sanholt case RADEON_INIT_CP: 1600112015Sanholt case RADEON_INIT_R200_CP: 1601145132Sanholt case RADEON_INIT_R300_CP: 1602189499Srnoland return radeon_do_init_cp(dev, init, file_priv); 1603189499Srnoland case RADEON_INIT_R600_CP: 1604189499Srnoland return r600_do_init_cp(dev, init, file_priv); 160595584Sanholt case RADEON_CLEANUP_CP: 1606189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1607189499Srnoland return r600_do_cleanup_cp(dev); 1608189499Srnoland else 1609189499Srnoland return radeon_do_cleanup_cp(dev); 161095584Sanholt } 161195584Sanholt 1612182080Srnoland return -EINVAL; 161395584Sanholt} 161495584Sanholt 1615182080Srnolandint radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv) 161695584Sanholt{ 161795584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1618145132Sanholt DRM_DEBUG("\n"); 161995584Sanholt 1620182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 162195584Sanholt 1622145132Sanholt if (dev_priv->cp_running) { 1623182080Srnoland DRM_DEBUG("while CP running\n"); 162495584Sanholt return 0; 162595584Sanholt } 1626145132Sanholt if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) { 1627182080Srnoland DRM_DEBUG("called with bogus CP mode (%d)\n", 1628182080Srnoland dev_priv->cp_mode); 162995584Sanholt return 0; 163095584Sanholt } 163195584Sanholt 1632189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1633189499Srnoland r600_do_cp_start(dev_priv); 1634189499Srnoland else 1635189499Srnoland radeon_do_cp_start(dev_priv); 163695584Sanholt 163795584Sanholt return 0; 163895584Sanholt} 163995584Sanholt 164095584Sanholt/* Stop the CP. The engine must have been idled before calling this 164195584Sanholt * routine. 164295584Sanholt */ 1643182080Srnolandint radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) 164495584Sanholt{ 164595584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1646182080Srnoland drm_radeon_cp_stop_t *stop = data; 164795584Sanholt int ret; 1648145132Sanholt DRM_DEBUG("\n"); 164995584Sanholt 1650182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 165195584Sanholt 1652112015Sanholt if (!dev_priv->cp_running) 1653112015Sanholt return 0; 1654112015Sanholt 165595584Sanholt /* Flush any pending CP commands. This ensures any outstanding 165695584Sanholt * commands are exectuted by the engine before we turn it off. 165795584Sanholt */ 1658182080Srnoland if (stop->flush) { 1659145132Sanholt radeon_do_cp_flush(dev_priv); 166095584Sanholt } 166195584Sanholt 166295584Sanholt /* If we fail to make the engine go idle, we return an error 166395584Sanholt * code so that the DRM ioctl wrapper can try again. 166495584Sanholt */ 1665182080Srnoland if (stop->idle) { 1666189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1667189499Srnoland ret = r600_do_cp_idle(dev_priv); 1668189499Srnoland else 1669189499Srnoland ret = radeon_do_cp_idle(dev_priv); 1670145132Sanholt if (ret) 1671145132Sanholt return ret; 167295584Sanholt } 167395584Sanholt 167495584Sanholt /* Finally, we can turn off the CP. If the engine isn't idle, 167595584Sanholt * we will get some dropped triangles as they won't be fully 167695584Sanholt * rendered before the CP is shut down. 167795584Sanholt */ 1678189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1679189499Srnoland r600_do_cp_stop(dev_priv); 1680189499Srnoland else 1681189499Srnoland radeon_do_cp_stop(dev_priv); 168295584Sanholt 168395584Sanholt /* Reset the engine */ 1684189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1685189499Srnoland r600_do_engine_reset(dev); 1686189499Srnoland else 1687189499Srnoland radeon_do_engine_reset(dev); 168895584Sanholt 168995584Sanholt return 0; 169095584Sanholt} 169195584Sanholt 1692182080Srnolandvoid radeon_do_release(struct drm_device * dev) 1693112015Sanholt{ 1694112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1695145132Sanholt int i, ret; 1696112015Sanholt 1697112015Sanholt if (dev_priv) { 1698112015Sanholt if (dev_priv->cp_running) { 1699112015Sanholt /* Stop the cp */ 1700189557Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 1701189499Srnoland while ((ret = r600_do_cp_idle(dev_priv)) != 0) { 1702189499Srnoland DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1703189499Srnoland mtx_sleep(&ret, &dev->dev_lock, 0, 1704189499Srnoland "rdnrel", 1); 1705189499Srnoland } 1706189499Srnoland } else { 1707189499Srnoland while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { 1708189499Srnoland DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1709189499Srnoland mtx_sleep(&ret, &dev->dev_lock, 0, 1710189499Srnoland "rdnrel", 1); 1711189499Srnoland } 1712112015Sanholt } 1713189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 1714189499Srnoland r600_do_cp_stop(dev_priv); 1715189499Srnoland r600_do_engine_reset(dev); 1716189499Srnoland } else { 1717189499Srnoland radeon_do_cp_stop(dev_priv); 1718189499Srnoland radeon_do_engine_reset(dev); 1719189499Srnoland } 1720112015Sanholt } 1721112015Sanholt 1722189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { 1723189499Srnoland /* Disable *all* interrupts */ 1724189499Srnoland if (dev_priv->mmio) /* remove this after permanent addmaps */ 1725189499Srnoland RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 1726112015Sanholt 1727189499Srnoland if (dev_priv->mmio) { /* remove all surfaces */ 1728189499Srnoland for (i = 0; i < RADEON_MAX_SURFACES; i++) { 1729189499Srnoland RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); 1730189499Srnoland RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 1731189499Srnoland 16 * i, 0); 1732189499Srnoland RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 1733189499Srnoland 16 * i, 0); 1734189499Srnoland } 1735145132Sanholt } 1736145132Sanholt } 1737145132Sanholt 1738112015Sanholt /* Free memory heap structures */ 1739145132Sanholt radeon_mem_takedown(&(dev_priv->gart_heap)); 1740145132Sanholt radeon_mem_takedown(&(dev_priv->fb_heap)); 1741112015Sanholt 1742112015Sanholt /* deallocate kernel resources */ 1743189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1744189499Srnoland r600_do_cleanup_cp(dev); 1745189499Srnoland else 1746189499Srnoland radeon_do_cleanup_cp(dev); 1747112015Sanholt } 1748112015Sanholt} 1749112015Sanholt 175095584Sanholt/* Just reset the CP ring. Called as part of an X Server engine reset. 175195584Sanholt */ 1752182080Srnolandint radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 175395584Sanholt{ 175495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1755145132Sanholt DRM_DEBUG("\n"); 175695584Sanholt 1757182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 175895584Sanholt 1759145132Sanholt if (!dev_priv) { 1760182080Srnoland DRM_DEBUG("called before init done\n"); 1761182080Srnoland return -EINVAL; 176295584Sanholt } 176395584Sanholt 1764189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1765189499Srnoland r600_do_cp_reset(dev_priv); 1766189499Srnoland else 1767189499Srnoland radeon_do_cp_reset(dev_priv); 176895584Sanholt 176995584Sanholt /* The CP is no longer running after an engine reset */ 177095584Sanholt dev_priv->cp_running = 0; 177195584Sanholt 177295584Sanholt return 0; 177395584Sanholt} 177495584Sanholt 1775182080Srnolandint radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) 177695584Sanholt{ 177795584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1778145132Sanholt DRM_DEBUG("\n"); 177995584Sanholt 1780182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 178195584Sanholt 1782189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1783189499Srnoland return r600_do_cp_idle(dev_priv); 1784189499Srnoland else 1785189499Srnoland return radeon_do_cp_idle(dev_priv); 178695584Sanholt} 178795584Sanholt 1788119098Sanholt/* Added by Charl P. Botha to call radeon_do_resume_cp(). 1789119098Sanholt */ 1790182080Srnolandint radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) 1791119098Sanholt{ 1792189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1793189499Srnoland DRM_DEBUG("\n"); 1794119098Sanholt 1795189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1796189499Srnoland return r600_do_resume_cp(dev, file_priv); 1797189499Srnoland else 1798189499Srnoland return radeon_do_resume_cp(dev, file_priv); 1799119098Sanholt} 1800119098Sanholt 1801182080Srnolandint radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 180295584Sanholt{ 1803189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1804145132Sanholt DRM_DEBUG("\n"); 180595584Sanholt 1806182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 180795584Sanholt 1808189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1809189499Srnoland return r600_do_engine_reset(dev); 1810189499Srnoland else 1811189499Srnoland return radeon_do_engine_reset(dev); 181295584Sanholt} 181395584Sanholt 181495584Sanholt/* ================================================================ 181595584Sanholt * Fullscreen mode 181695584Sanholt */ 181795584Sanholt 1818112015Sanholt/* KW: Deprecated to say the least: 1819112015Sanholt */ 1820182080Srnolandint radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) 182195584Sanholt{ 182295584Sanholt return 0; 182395584Sanholt} 182495584Sanholt 182595584Sanholt/* ================================================================ 182695584Sanholt * Freelist management 182795584Sanholt */ 182895584Sanholt 1829112015Sanholt/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through 1830112015Sanholt * bufs until freelist code is used. Note this hides a problem with 1831112015Sanholt * the scratch register * (used to keep track of last buffer 1832112015Sanholt * completed) being written to before * the last buffer has actually 1833145132Sanholt * completed rendering. 1834112015Sanholt * 1835112015Sanholt * KW: It's also a good way to find free buffers quickly. 1836112015Sanholt * 1837112015Sanholt * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't 1838112015Sanholt * sleep. However, bugs in older versions of radeon_accel.c mean that 1839112015Sanholt * we essentially have to do this, else old clients will break. 1840145132Sanholt * 1841112015Sanholt * However, it does leave open a potential deadlock where all the 1842112015Sanholt * buffers are held by other clients, which can't release them because 1843145132Sanholt * they can't get the lock. 1844112015Sanholt */ 1845112015Sanholt 1846182080Srnolandstruct drm_buf *radeon_freelist_get(struct drm_device * dev) 184795584Sanholt{ 1848182080Srnoland struct drm_device_dma *dma = dev->dma; 184995584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1850112015Sanholt drm_radeon_buf_priv_t *buf_priv; 1851182080Srnoland struct drm_buf *buf; 1852112015Sanholt int i, t; 1853112015Sanholt int start; 185495584Sanholt 1855145132Sanholt if (++dev_priv->last_buf >= dma->buf_count) 1856112015Sanholt dev_priv->last_buf = 0; 185795584Sanholt 1858112015Sanholt start = dev_priv->last_buf; 185995584Sanholt 1860145132Sanholt for (t = 0; t < dev_priv->usec_timeout; t++) { 1861189499Srnoland u32 done_age = GET_SCRATCH(dev_priv, 1); 1862145132Sanholt DRM_DEBUG("done_age = %d\n", done_age); 1863198695Srnoland for (i = 0; i < dma->buf_count; i++) { 1864198695Srnoland buf = dma->buflist[start]; 1865112015Sanholt buf_priv = buf->dev_private; 1866182080Srnoland if (buf->file_priv == NULL || (buf->pending && 1867182080Srnoland buf_priv->age <= 1868182080Srnoland done_age)) { 1869112015Sanholt dev_priv->stats.requested_bufs++; 1870112015Sanholt buf->pending = 0; 1871112015Sanholt return buf; 1872112015Sanholt } 1873198695Srnoland if (++start >= dma->buf_count) 1874198695Srnoland start = 0; 1875112015Sanholt } 187695584Sanholt 1877112015Sanholt if (t) { 1878145132Sanholt DRM_UDELAY(1); 1879112015Sanholt dev_priv->stats.freelist_loops++; 1880112015Sanholt } 188195584Sanholt } 188295584Sanholt 1883112015Sanholt return NULL; 188495584Sanholt} 1885145132Sanholt 1886182080Srnolandvoid radeon_freelist_reset(struct drm_device * dev) 188795584Sanholt{ 1888182080Srnoland struct drm_device_dma *dma = dev->dma; 188995584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 189095584Sanholt int i; 189195584Sanholt 189295584Sanholt dev_priv->last_buf = 0; 1893145132Sanholt for (i = 0; i < dma->buf_count; i++) { 1894182080Srnoland struct drm_buf *buf = dma->buflist[i]; 189595584Sanholt drm_radeon_buf_priv_t *buf_priv = buf->dev_private; 189695584Sanholt buf_priv->age = 0; 189795584Sanholt } 189895584Sanholt} 189995584Sanholt 190095584Sanholt/* ================================================================ 190195584Sanholt * CP command submission 190295584Sanholt */ 190395584Sanholt 1904145132Sanholtint radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) 190595584Sanholt{ 190695584Sanholt drm_radeon_ring_buffer_t *ring = &dev_priv->ring; 190795584Sanholt int i; 1908145132Sanholt u32 last_head = GET_RING_HEAD(dev_priv); 190995584Sanholt 1910145132Sanholt for (i = 0; i < dev_priv->usec_timeout; i++) { 1911145132Sanholt u32 head = GET_RING_HEAD(dev_priv); 1912112015Sanholt 1913112015Sanholt ring->space = (head - ring->tail) * sizeof(u32); 1914145132Sanholt if (ring->space <= 0) 1915112015Sanholt ring->space += ring->size; 1916145132Sanholt if (ring->space > n) 191795584Sanholt return 0; 1918145132Sanholt 1919112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 1920112015Sanholt 1921112015Sanholt if (head != last_head) 1922112015Sanholt i = 0; 1923112015Sanholt last_head = head; 1924112015Sanholt 1925145132Sanholt DRM_UDELAY(1); 192695584Sanholt } 192795584Sanholt 192895584Sanholt /* FIXME: This return value is ignored in the BEGIN_RING macro! */ 192995584Sanholt#if RADEON_FIFO_DEBUG 1930145132Sanholt radeon_status(dev_priv); 1931145132Sanholt DRM_ERROR("failed!\n"); 193295584Sanholt#endif 1933182080Srnoland return -EBUSY; 193495584Sanholt} 193595584Sanholt 1936182080Srnolandstatic int radeon_cp_get_buffers(struct drm_device *dev, 1937182080Srnoland struct drm_file *file_priv, 1938182080Srnoland struct drm_dma * d) 193995584Sanholt{ 194095584Sanholt int i; 1941182080Srnoland struct drm_buf *buf; 194295584Sanholt 1943145132Sanholt for (i = d->granted_count; i < d->request_count; i++) { 1944145132Sanholt buf = radeon_freelist_get(dev); 1945145132Sanholt if (!buf) 1946182080Srnoland return -EBUSY; /* NOTE: broken client */ 194795584Sanholt 1948182080Srnoland buf->file_priv = file_priv; 194995584Sanholt 1950145132Sanholt if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, 1951145132Sanholt sizeof(buf->idx))) 1952182080Srnoland return -EFAULT; 1953145132Sanholt if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, 1954145132Sanholt sizeof(buf->total))) 1955182080Srnoland return -EFAULT; 195695584Sanholt 195795584Sanholt d->granted_count++; 195895584Sanholt } 195995584Sanholt return 0; 196095584Sanholt} 196195584Sanholt 1962182080Srnolandint radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) 196395584Sanholt{ 1964182080Srnoland struct drm_device_dma *dma = dev->dma; 196595584Sanholt int ret = 0; 1966182080Srnoland struct drm_dma *d = data; 196795584Sanholt 1968182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 196995584Sanholt 197095584Sanholt /* Please don't send us buffers. 197195584Sanholt */ 1972182080Srnoland if (d->send_count != 0) { 1973145132Sanholt DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", 1974182080Srnoland DRM_CURRENTPID, d->send_count); 1975182080Srnoland return -EINVAL; 197695584Sanholt } 197795584Sanholt 197895584Sanholt /* We'll send you buffers. 197995584Sanholt */ 1980182080Srnoland if (d->request_count < 0 || d->request_count > dma->buf_count) { 1981145132Sanholt DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", 1982182080Srnoland DRM_CURRENTPID, d->request_count, dma->buf_count); 1983182080Srnoland return -EINVAL; 198495584Sanholt } 198595584Sanholt 1986182080Srnoland d->granted_count = 0; 198795584Sanholt 1988182080Srnoland if (d->request_count) { 1989182080Srnoland ret = radeon_cp_get_buffers(dev, file_priv, d); 199095584Sanholt } 199195584Sanholt 199295584Sanholt return ret; 199395584Sanholt} 1994145132Sanholt 1995152909Sanholtint radeon_driver_load(struct drm_device *dev, unsigned long flags) 1996145132Sanholt{ 1997145132Sanholt drm_radeon_private_t *dev_priv; 1998145132Sanholt int ret = 0; 1999145132Sanholt 2000145132Sanholt dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER); 2001145132Sanholt if (dev_priv == NULL) 2002182080Srnoland return -ENOMEM; 2003145132Sanholt 2004145132Sanholt memset(dev_priv, 0, sizeof(drm_radeon_private_t)); 2005145132Sanholt dev->dev_private = (void *)dev_priv; 2006145132Sanholt dev_priv->flags = flags; 2007145132Sanholt 2008182080Srnoland switch (flags & RADEON_FAMILY_MASK) { 2009145132Sanholt case CHIP_R100: 2010145132Sanholt case CHIP_RV200: 2011145132Sanholt case CHIP_R200: 2012145132Sanholt case CHIP_R300: 2013157617Sanholt case CHIP_R350: 2014148211Sanholt case CHIP_R420: 2015183830Srnoland case CHIP_R423: 2016157617Sanholt case CHIP_RV410: 2017182080Srnoland case CHIP_RV515: 2018182080Srnoland case CHIP_R520: 2019182080Srnoland case CHIP_RV570: 2020182080Srnoland case CHIP_R580: 2021182080Srnoland dev_priv->flags |= RADEON_HAS_HIERZ; 2022145132Sanholt break; 2023145132Sanholt default: 2024157617Sanholt /* all other chips have no hierarchical z buffer */ 2025145132Sanholt break; 2026145132Sanholt } 2027145132Sanholt 2028145132Sanholt if (drm_device_is_agp(dev)) 2029182080Srnoland dev_priv->flags |= RADEON_IS_AGP; 2030162132Sanholt else if (drm_device_is_pcie(dev)) 2031182080Srnoland dev_priv->flags |= RADEON_IS_PCIE; 2032162132Sanholt else 2033182080Srnoland dev_priv->flags |= RADEON_IS_PCI; 2034148211Sanholt 2035196470Srnoland mtx_init(&dev_priv->cs.cs_mutex, "cs_mtx", NULL, MTX_DEF); 2036196470Srnoland 2037189499Srnoland ret = drm_addmap(dev, drm_get_resource_start(dev, 2), 2038189499Srnoland drm_get_resource_len(dev, 2), _DRM_REGISTERS, 2039189499Srnoland _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); 2040189499Srnoland if (ret != 0) 2041194969Srnoland goto error; 2042189499Srnoland 2043189130Srnoland ret = drm_vblank_init(dev, 2); 2044194969Srnoland if (ret != 0) 2045194969Srnoland goto error; 2046189130Srnoland 2047194969Srnoland dev->max_vblank_count = 0x001fffff; 2048194969Srnoland 2049145132Sanholt DRM_DEBUG("%s card detected\n", 2050194969Srnoland ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : 2051194969Srnoland (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); 2052194969Srnoland 2053145132Sanholt return ret; 2054194969Srnoland 2055194969Srnolanderror: 2056194969Srnoland radeon_driver_unload(dev); 2057194969Srnoland return ret; 2058145132Sanholt} 2059145132Sanholt 2060152909Sanholt/* Create mappings for registers and framebuffer so userland doesn't necessarily 2061152909Sanholt * have to find them. 2062152909Sanholt */ 2063152909Sanholtint radeon_driver_firstopen(struct drm_device *dev) 2064145132Sanholt{ 2065152909Sanholt int ret; 2066152909Sanholt drm_local_map_t *map; 2067145132Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 2068145132Sanholt 2069182080Srnoland dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; 2070182080Srnoland 2071182080Srnoland dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); 2072182080Srnoland ret = drm_addmap(dev, dev_priv->fb_aper_offset, 2073152909Sanholt drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, 2074152909Sanholt _DRM_WRITE_COMBINING, &map); 2075152909Sanholt if (ret != 0) 2076152909Sanholt return ret; 2077152909Sanholt 2078152909Sanholt return 0; 2079152909Sanholt} 2080152909Sanholt 2081152909Sanholtint radeon_driver_unload(struct drm_device *dev) 2082152909Sanholt{ 2083152909Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 2084152909Sanholt 2085145132Sanholt DRM_DEBUG("\n"); 2086189499Srnoland 2087189499Srnoland drm_rmmap(dev, dev_priv->mmio); 2088189499Srnoland 2089196470Srnoland mtx_destroy(&dev_priv->cs.cs_mutex); 2090196470Srnoland 2091145132Sanholt drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); 2092145132Sanholt 2093145132Sanholt dev->dev_private = NULL; 2094145132Sanholt return 0; 2095145132Sanholt} 2096189499Srnoland 2097189499Srnolandvoid radeon_commit_ring(drm_radeon_private_t *dev_priv) 2098189499Srnoland{ 2099189499Srnoland int i; 2100189499Srnoland u32 *ring; 2101189499Srnoland int tail_aligned; 2102189499Srnoland 2103189499Srnoland /* check if the ring is padded out to 16-dword alignment */ 2104189499Srnoland 2105196470Srnoland tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1); 2106189499Srnoland if (tail_aligned) { 2107196470Srnoland int num_p2 = RADEON_RING_ALIGN - tail_aligned; 2108189499Srnoland 2109189499Srnoland ring = dev_priv->ring.start; 2110189499Srnoland /* pad with some CP_PACKET2 */ 2111189499Srnoland for (i = 0; i < num_p2; i++) 2112189499Srnoland ring[dev_priv->ring.tail + i] = CP_PACKET2(); 2113189499Srnoland 2114189499Srnoland dev_priv->ring.tail += i; 2115189499Srnoland 2116189499Srnoland dev_priv->ring.space -= num_p2 * sizeof(u32); 2117189499Srnoland } 2118189499Srnoland 2119189499Srnoland dev_priv->ring.tail &= dev_priv->ring.tail_mask; 2120189499Srnoland 2121189499Srnoland DRM_MEMORYBARRIER(); 2122189499Srnoland GET_RING_HEAD( dev_priv ); 2123189499Srnoland 2124189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 2125189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); 2126189499Srnoland /* read from PCI bus to ensure correct posting */ 2127189499Srnoland RADEON_READ(R600_CP_RB_RPTR); 2128189499Srnoland } else { 2129189499Srnoland RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); 2130189499Srnoland /* read from PCI bus to ensure correct posting */ 2131189499Srnoland RADEON_READ(RADEON_CP_RB_RPTR); 2132189499Srnoland } 2133189499Srnoland} 2134