radeon_cp.c revision 298955
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 298955 2016-05-03 03:41:25Z pfg $"); 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 *) 56207066Srnoland dev_priv->ring_rptr->virtual) + 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 80207066Srnoland *(((volatile u32 *) dev_priv->ring_rptr->virtual) + 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 234298955Spfg /* R6xx/R7xx must be aligned to a 4MB boundary */ 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 545258780Seadler tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1U << 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 723207067Srnoland ring_start = (dev_priv->cp_ring->offset - dev->sg->vaddr + 724207067Srnoland dev_priv->gart_vm_start); 72595584Sanholt 726145132Sanholt RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); 72795584Sanholt 72895584Sanholt /* Set the write pointer delay */ 729145132Sanholt RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0); 73095584Sanholt 73195584Sanholt /* Initialize the ring buffer's read and write pointers */ 732145132Sanholt cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); 733145132Sanholt RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); 734145132Sanholt SET_RING_HEAD(dev_priv, cur_read_ptr); 73595584Sanholt dev_priv->ring.tail = cur_read_ptr; 73695584Sanholt 737145132Sanholt#if __OS_HAS_AGP 738182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 739145132Sanholt RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 740145132Sanholt dev_priv->ring_rptr->offset 741145132Sanholt - dev->agp->base + dev_priv->gart_vm_start); 742113995Sanholt } else 743113995Sanholt#endif 744113995Sanholt { 745189499Srnoland RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 746207067Srnoland dev_priv->ring_rptr->offset - dev->sg->vaddr + 747207067Srnoland dev_priv->gart_vm_start); 74895584Sanholt } 74995584Sanholt 750157617Sanholt /* Set ring buffer size */ 751157617Sanholt#ifdef __BIG_ENDIAN 752157617Sanholt RADEON_WRITE(RADEON_CP_RB_CNTL, 753182080Srnoland RADEON_BUF_SWAP_32BIT | 754182080Srnoland (dev_priv->ring.fetch_size_l2ow << 18) | 755182080Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 756182080Srnoland dev_priv->ring.size_l2qw); 757157617Sanholt#else 758182080Srnoland RADEON_WRITE(RADEON_CP_RB_CNTL, 759182080Srnoland (dev_priv->ring.fetch_size_l2ow << 18) | 760182080Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 761182080Srnoland dev_priv->ring.size_l2qw); 762157617Sanholt#endif 763157617Sanholt 764189499Srnoland 765112015Sanholt /* Initialize the scratch register pointer. This will cause 766112015Sanholt * the scratch register values to be written out to memory 767112015Sanholt * whenever they are updated. 768112015Sanholt * 769112015Sanholt * We simply put this behind the ring read pointer, this works 770112015Sanholt * with PCI GART as well as (whatever kind of) AGP GART 771112015Sanholt */ 772145132Sanholt RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) 773145132Sanholt + RADEON_SCRATCH_REG_OFFSET); 774112015Sanholt 775145132Sanholt RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); 776112015Sanholt 777189499Srnoland radeon_enable_bm(dev_priv); 778112015Sanholt 779189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); 780189499Srnoland RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); 781112015Sanholt 782189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); 783189499Srnoland RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); 784112015Sanholt 785189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); 786189499Srnoland RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); 787112015Sanholt 788189499Srnoland /* reset sarea copies of these */ 789189499Srnoland if (dev_priv->sarea_priv) { 790189499Srnoland dev_priv->sarea_priv->last_frame = 0; 791189499Srnoland dev_priv->sarea_priv->last_dispatch = 0; 792189499Srnoland dev_priv->sarea_priv->last_clear = 0; 793189499Srnoland } 794189499Srnoland 795145132Sanholt radeon_do_wait_for_idle(dev_priv); 79695584Sanholt 79795584Sanholt /* Sync everything up */ 798145132Sanholt RADEON_WRITE(RADEON_ISYNC_CNTL, 799145132Sanholt (RADEON_ISYNC_ANY2D_IDLE3D | 800145132Sanholt RADEON_ISYNC_ANY3D_IDLE2D | 801145132Sanholt RADEON_ISYNC_WAIT_IDLEGUI | 802145132Sanholt RADEON_ISYNC_CPSCRATCH_IDLEGUI)); 803157617Sanholt 80495584Sanholt} 80595584Sanholt 806157617Sanholtstatic void radeon_test_writeback(drm_radeon_private_t * dev_priv) 807157617Sanholt{ 808157617Sanholt u32 tmp; 809157617Sanholt 810189499Srnoland /* Start with assuming that writeback doesn't work */ 811189499Srnoland dev_priv->writeback_works = 0; 812189499Srnoland 813157617Sanholt /* Writeback doesn't seem to work everywhere, test it here and possibly 814157617Sanholt * enable it if it appears to work 815157617Sanholt */ 816189499Srnoland radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); 817189499Srnoland 818157617Sanholt RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); 819157617Sanholt 820157617Sanholt for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { 821189499Srnoland u32 val; 822189499Srnoland 823189499Srnoland val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); 824189499Srnoland if (val == 0xdeadbeef) 825157617Sanholt break; 826157617Sanholt DRM_UDELAY(1); 827157617Sanholt } 828157617Sanholt 829157617Sanholt if (tmp < dev_priv->usec_timeout) { 830157617Sanholt dev_priv->writeback_works = 1; 831157617Sanholt DRM_INFO("writeback test succeeded in %d usecs\n", tmp); 832157617Sanholt } else { 833157617Sanholt dev_priv->writeback_works = 0; 834157617Sanholt DRM_INFO("writeback test failed\n"); 835157617Sanholt } 836157617Sanholt if (radeon_no_wb == 1) { 837157617Sanholt dev_priv->writeback_works = 0; 838157617Sanholt DRM_INFO("writeback forced off\n"); 839157617Sanholt } 840162132Sanholt 841162132Sanholt if (!dev_priv->writeback_works) { 842189499Srnoland /* Disable writeback to avoid unnecessary bus master transfer */ 843189499Srnoland RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | 844189499Srnoland RADEON_RB_NO_UPDATE); 845162132Sanholt RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); 846162132Sanholt } 847157617Sanholt} 848157617Sanholt 849182080Srnoland/* Enable or disable IGP GART on the chip */ 850182080Srnolandstatic void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) 851182080Srnoland{ 852182080Srnoland u32 temp; 853182080Srnoland 854182080Srnoland if (on) { 855182080Srnoland DRM_DEBUG("programming igp gart %08X %08lX %08X\n", 856189499Srnoland dev_priv->gart_vm_start, 857189499Srnoland (long)dev_priv->gart_info.bus_addr, 858189499Srnoland dev_priv->gart_size); 859182080Srnoland 860182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); 861183828Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 862183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) 863182080Srnoland IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | 864182080Srnoland RS690_BLOCK_GFX_D3_EN)); 865182080Srnoland else 866182080Srnoland IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); 867182080Srnoland 868182080Srnoland IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | 869182080Srnoland RS480_VA_SIZE_32MB)); 870182080Srnoland 871182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID); 872182080Srnoland IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN | 873182080Srnoland RS480_TLB_ENABLE | 874182080Srnoland RS480_GTW_LAC_EN | 875182080Srnoland RS480_1LEVEL_GART)); 876182080Srnoland 877182080Srnoland temp = dev_priv->gart_info.bus_addr & 0xfffff000; 878182080Srnoland temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4; 879182080Srnoland IGP_WRITE_MCIND(RS480_GART_BASE, temp); 880182080Srnoland 881182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL); 882182080Srnoland IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) | 883182080Srnoland RS480_REQ_TYPE_SNOOP_DIS)); 884182080Srnoland 885182080Srnoland radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start); 886182080Srnoland 887182080Srnoland dev_priv->gart_size = 32*1024*1024; 888189499Srnoland temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 889189499Srnoland 0xffff0000) | (dev_priv->gart_vm_start >> 16)); 890182080Srnoland 891182080Srnoland radeon_write_agp_location(dev_priv, temp); 892182080Srnoland 893182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); 894182080Srnoland IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | 895182080Srnoland RS480_VA_SIZE_32MB)); 896182080Srnoland 897182080Srnoland do { 898182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); 899182080Srnoland if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) 900182080Srnoland break; 901182080Srnoland DRM_UDELAY(1); 902189499Srnoland } while (1); 903182080Srnoland 904182080Srnoland IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 905182080Srnoland RS480_GART_CACHE_INVALIDATE); 906182080Srnoland 907182080Srnoland do { 908182080Srnoland temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); 909182080Srnoland if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) 910182080Srnoland break; 911182080Srnoland DRM_UDELAY(1); 912189499Srnoland } while (1); 913182080Srnoland 914182080Srnoland IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); 915182080Srnoland } else { 916182080Srnoland IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0); 917182080Srnoland } 918182080Srnoland} 919182080Srnoland 920189499Srnoland/* Enable or disable IGP GART on the chip */ 921189499Srnolandstatic void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) 922189499Srnoland{ 923189499Srnoland u32 temp; 924189499Srnoland int i; 925189499Srnoland 926189499Srnoland if (on) { 927189499Srnoland DRM_DEBUG("programming igp gart %08X %08lX %08X\n", 928189499Srnoland dev_priv->gart_vm_start, 929189499Srnoland (long)dev_priv->gart_info.bus_addr, 930189499Srnoland dev_priv->gart_size); 931189499Srnoland 932189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | 933189499Srnoland RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); 934189499Srnoland 935189499Srnoland for (i = 0; i < 19; i++) 936189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, 937189499Srnoland (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | 938189499Srnoland RS600_SYSTEM_ACCESS_MODE_IN_SYS | 939189499Srnoland RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | 940189499Srnoland RS600_EFFECTIVE_L1_CACHE_SIZE(3) | 941189499Srnoland RS600_ENABLE_FRAGMENT_PROCESSING | 942189499Srnoland RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); 943189499Srnoland 944189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | 945189499Srnoland RS600_PAGE_TABLE_TYPE_FLAT)); 946189499Srnoland 947189499Srnoland /* disable all other contexts */ 948189499Srnoland for (i = 1; i < 8; i++) 949189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); 950189499Srnoland 951189499Srnoland /* setup the page table aperture */ 952189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, 953189499Srnoland dev_priv->gart_info.bus_addr); 954189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, 955189499Srnoland dev_priv->gart_vm_start); 956189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, 957189499Srnoland (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); 958189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); 959189499Srnoland 960189499Srnoland /* setup the system aperture */ 961189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, 962189499Srnoland dev_priv->gart_vm_start); 963189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, 964189499Srnoland (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); 965189499Srnoland 966189499Srnoland /* enable page tables */ 967189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 968189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); 969189499Srnoland 970189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); 971189499Srnoland IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); 972189499Srnoland 973189499Srnoland /* invalidate the cache */ 974189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 975189499Srnoland 976189499Srnoland temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); 977189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); 978189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 979189499Srnoland 980189499Srnoland temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; 981189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); 982189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 983189499Srnoland 984189499Srnoland temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); 985189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); 986189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); 987189499Srnoland 988189499Srnoland } else { 989189499Srnoland IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); 990189499Srnoland temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); 991189499Srnoland temp &= ~RS600_ENABLE_PAGE_TABLES; 992189499Srnoland IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); 993189499Srnoland } 994189499Srnoland} 995189499Srnoland 996148211Sanholtstatic void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) 997148211Sanholt{ 998148211Sanholt u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); 999148211Sanholt if (on) { 1000148211Sanholt 1001152909Sanholt DRM_DEBUG("programming pcie %08X %08lX %08X\n", 1002157617Sanholt dev_priv->gart_vm_start, 1003157617Sanholt (long)dev_priv->gart_info.bus_addr, 1004152909Sanholt dev_priv->gart_size); 1005157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, 1006157617Sanholt dev_priv->gart_vm_start); 1007157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, 1008157617Sanholt dev_priv->gart_info.bus_addr); 1009157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, 1010157617Sanholt dev_priv->gart_vm_start); 1011157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, 1012157617Sanholt dev_priv->gart_vm_start + 1013157617Sanholt dev_priv->gart_size - 1); 1014148211Sanholt 1015182080Srnoland radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ 1016148211Sanholt 1017157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, 1018157617Sanholt RADEON_PCIE_TX_GART_EN); 1019148211Sanholt } else { 1020157617Sanholt RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, 1021157617Sanholt tmp & ~RADEON_PCIE_TX_GART_EN); 1022148211Sanholt } 1023148211Sanholt} 1024148211Sanholt 1025119098Sanholt/* Enable or disable PCI GART on the chip */ 1026145132Sanholtstatic void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) 1027119098Sanholt{ 1028152909Sanholt u32 tmp; 1029119098Sanholt 1030182080Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 1031183828Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740) || 1032182080Srnoland (dev_priv->flags & RADEON_IS_IGPGART)) { 1033182080Srnoland radeon_set_igpgart(dev_priv, on); 1034182080Srnoland return; 1035182080Srnoland } 1036182080Srnoland 1037189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { 1038189499Srnoland rs600_set_igpgart(dev_priv, on); 1039189499Srnoland return; 1040189499Srnoland } 1041189499Srnoland 1042182080Srnoland if (dev_priv->flags & RADEON_IS_PCIE) { 1043148211Sanholt radeon_set_pciegart(dev_priv, on); 1044148211Sanholt return; 1045148211Sanholt } 1046148211Sanholt 1047182080Srnoland tmp = RADEON_READ(RADEON_AIC_CNTL); 1048152909Sanholt 1049145132Sanholt if (on) { 1050145132Sanholt RADEON_WRITE(RADEON_AIC_CNTL, 1051145132Sanholt tmp | RADEON_PCIGART_TRANSLATE_EN); 1052119098Sanholt 1053119098Sanholt /* set PCI GART page-table base address 1054119098Sanholt */ 1055152909Sanholt RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); 1056119098Sanholt 1057119098Sanholt /* set address range for PCI address translate 1058119098Sanholt */ 1059145132Sanholt RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start); 1060145132Sanholt RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start 1061145132Sanholt + dev_priv->gart_size - 1); 1062119098Sanholt 1063119895Sanholt /* Turn off AGP aperture -- is this required for PCI GART? 1064119098Sanholt */ 1065182080Srnoland radeon_write_agp_location(dev_priv, 0xffffffc0); 1066145132Sanholt RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ 1067119098Sanholt } else { 1068145132Sanholt RADEON_WRITE(RADEON_AIC_CNTL, 1069145132Sanholt tmp & ~RADEON_PCIGART_TRANSLATE_EN); 1070119098Sanholt } 1071119098Sanholt} 1072119098Sanholt 1073189499Srnolandstatic int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) 107495584Sanholt{ 1075189499Srnoland struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; 1076189499Srnoland struct radeon_virt_surface *vp; 1077189499Srnoland int i; 1078189499Srnoland 1079189499Srnoland for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { 1080189499Srnoland if (!dev_priv->virt_surfaces[i].file_priv || 1081189499Srnoland dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) 1082189499Srnoland break; 1083189499Srnoland } 1084189499Srnoland if (i >= 2 * RADEON_MAX_SURFACES) 1085189499Srnoland return -ENOMEM; 1086189499Srnoland vp = &dev_priv->virt_surfaces[i]; 1087189499Srnoland 1088189499Srnoland for (i = 0; i < RADEON_MAX_SURFACES; i++) { 1089189499Srnoland struct radeon_surface *sp = &dev_priv->surfaces[i]; 1090189499Srnoland if (sp->refcount) 1091189499Srnoland continue; 1092189499Srnoland 1093189499Srnoland vp->surface_index = i; 1094189499Srnoland vp->lower = gart_info->bus_addr; 1095189499Srnoland vp->upper = vp->lower + gart_info->table_size; 1096189499Srnoland vp->flags = 0; 1097189499Srnoland vp->file_priv = PCIGART_FILE_PRIV; 1098189499Srnoland 1099189499Srnoland sp->refcount = 1; 1100189499Srnoland sp->lower = vp->lower; 1101189499Srnoland sp->upper = vp->upper; 1102189499Srnoland sp->flags = 0; 1103189499Srnoland 1104189499Srnoland RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); 1105189499Srnoland RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); 1106189499Srnoland RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); 1107189499Srnoland return 0; 1108189499Srnoland } 1109189499Srnoland 1110189499Srnoland return -ENOMEM; 1111189499Srnoland} 1112189499Srnoland 1113189499Srnolandstatic int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, 1114189499Srnoland struct drm_file *file_priv) 1115189499Srnoland{ 1116145132Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1117157617Sanholt 1118145132Sanholt DRM_DEBUG("\n"); 111995584Sanholt 1120157617Sanholt /* if we require new memory map but we don't have it fail */ 1121182080Srnoland if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { 1122157617Sanholt DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); 1123157617Sanholt radeon_do_cleanup_cp(dev); 1124182080Srnoland return -EINVAL; 1125157617Sanholt } 1126157617Sanholt 1127189499Srnoland if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { 1128152909Sanholt DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1129182080Srnoland dev_priv->flags &= ~RADEON_IS_AGP; 1130189499Srnoland } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) 1131189499Srnoland && !init->is_pci) { 1132162132Sanholt DRM_DEBUG("Restoring AGP flag\n"); 1133182080Srnoland dev_priv->flags |= RADEON_IS_AGP; 1134162132Sanholt } 1135152909Sanholt 1136182080Srnoland if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { 1137145132Sanholt DRM_ERROR("PCI GART memory not allocated!\n"); 113895584Sanholt radeon_do_cleanup_cp(dev); 1139182080Srnoland return -EINVAL; 114095584Sanholt } 114195584Sanholt 114295584Sanholt dev_priv->usec_timeout = init->usec_timeout; 1143145132Sanholt if (dev_priv->usec_timeout < 1 || 1144145132Sanholt dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { 1145145132Sanholt DRM_DEBUG("TIMEOUT problem!\n"); 114695584Sanholt radeon_do_cleanup_cp(dev); 1147182080Srnoland return -EINVAL; 114895584Sanholt } 114995584Sanholt 1150182080Srnoland /* Enable vblank on CRTC1 for older X servers 1151182080Srnoland */ 1152182080Srnoland dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; 1153145132Sanholt 1154189499Srnoland switch(init->func) { 1155189499Srnoland case RADEON_INIT_R200_CP: 1156189499Srnoland dev_priv->microcode_version = UCODE_R200; 1157189499Srnoland break; 1158189499Srnoland case RADEON_INIT_R300_CP: 1159189499Srnoland dev_priv->microcode_version = UCODE_R300; 1160189499Srnoland break; 1161189499Srnoland default: 1162189499Srnoland dev_priv->microcode_version = UCODE_R100; 1163189499Srnoland } 1164189499Srnoland 1165112015Sanholt dev_priv->do_boxes = 0; 116695584Sanholt dev_priv->cp_mode = init->cp_mode; 116795584Sanholt 116895584Sanholt /* We don't support anything other than bus-mastering ring mode, 116995584Sanholt * but the ring can be in either AGP or PCI space for the ring 117095584Sanholt * read pointer. 117195584Sanholt */ 1172145132Sanholt if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && 1173145132Sanholt (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { 1174145132Sanholt DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); 117595584Sanholt radeon_do_cleanup_cp(dev); 1176182080Srnoland return -EINVAL; 117795584Sanholt } 117895584Sanholt 1179145132Sanholt switch (init->fb_bpp) { 118095584Sanholt case 16: 118195584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 118295584Sanholt break; 118395584Sanholt case 32: 118495584Sanholt default: 118595584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 118695584Sanholt break; 118795584Sanholt } 1188145132Sanholt dev_priv->front_offset = init->front_offset; 1189145132Sanholt dev_priv->front_pitch = init->front_pitch; 1190145132Sanholt dev_priv->back_offset = init->back_offset; 1191145132Sanholt dev_priv->back_pitch = init->back_pitch; 119295584Sanholt 1193145132Sanholt switch (init->depth_bpp) { 119495584Sanholt case 16: 119595584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; 119695584Sanholt break; 119795584Sanholt case 32: 119895584Sanholt default: 119995584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; 120095584Sanholt break; 120195584Sanholt } 1202145132Sanholt dev_priv->depth_offset = init->depth_offset; 1203145132Sanholt dev_priv->depth_pitch = init->depth_pitch; 120495584Sanholt 120595584Sanholt /* Hardware state for depth clears. Remove this if/when we no 120695584Sanholt * longer clear the depth buffer with a 3D rectangle. Hard-code 120795584Sanholt * all values to prevent unwanted 3D state from slipping through 120895584Sanholt * and screwing with the clear operation. 120995584Sanholt */ 121095584Sanholt dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | 121195584Sanholt (dev_priv->color_fmt << 10) | 1212189499Srnoland (dev_priv->microcode_version == 1213189499Srnoland UCODE_R100 ? RADEON_ZBLOCK16 : 0)); 121495584Sanholt 1215145132Sanholt dev_priv->depth_clear.rb3d_zstencilcntl = 1216145132Sanholt (dev_priv->depth_fmt | 1217145132Sanholt RADEON_Z_TEST_ALWAYS | 1218145132Sanholt RADEON_STENCIL_TEST_ALWAYS | 1219145132Sanholt RADEON_STENCIL_S_FAIL_REPLACE | 1220145132Sanholt RADEON_STENCIL_ZPASS_REPLACE | 1221145132Sanholt RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE); 122295584Sanholt 122395584Sanholt dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | 122495584Sanholt RADEON_BFACE_SOLID | 122595584Sanholt RADEON_FFACE_SOLID | 122695584Sanholt RADEON_FLAT_SHADE_VTX_LAST | 122795584Sanholt RADEON_DIFFUSE_SHADE_FLAT | 122895584Sanholt RADEON_ALPHA_SHADE_FLAT | 122995584Sanholt RADEON_SPECULAR_SHADE_FLAT | 123095584Sanholt RADEON_FOG_SHADE_FLAT | 123195584Sanholt RADEON_VTX_PIX_CENTER_OGL | 123295584Sanholt RADEON_ROUND_MODE_TRUNC | 123395584Sanholt RADEON_ROUND_PREC_8TH_PIX); 123495584Sanholt 1235113995Sanholt 1236113995Sanholt dev_priv->ring_offset = init->ring_offset; 1237113995Sanholt dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1238113995Sanholt dev_priv->buffers_offset = init->buffers_offset; 1239119895Sanholt dev_priv->gart_textures_offset = init->gart_textures_offset; 1240145132Sanholt 1241182080Srnoland dev_priv->sarea = drm_getsarea(dev); 1242145132Sanholt if (!dev_priv->sarea) { 124395584Sanholt DRM_ERROR("could not find sarea!\n"); 124495584Sanholt radeon_do_cleanup_cp(dev); 1245182080Srnoland return -EINVAL; 124695584Sanholt } 124795584Sanholt 1248145132Sanholt dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); 1249145132Sanholt if (!dev_priv->cp_ring) { 125095584Sanholt DRM_ERROR("could not find cp ring region!\n"); 125195584Sanholt radeon_do_cleanup_cp(dev); 1252182080Srnoland return -EINVAL; 125395584Sanholt } 1254145132Sanholt dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); 1255145132Sanholt if (!dev_priv->ring_rptr) { 125695584Sanholt DRM_ERROR("could not find ring read pointer!\n"); 125795584Sanholt radeon_do_cleanup_cp(dev); 1258182080Srnoland return -EINVAL; 125995584Sanholt } 1260152909Sanholt dev->agp_buffer_token = init->buffers_offset; 1261145132Sanholt dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1262145132Sanholt if (!dev->agp_buffer_map) { 126395584Sanholt DRM_ERROR("could not find dma buffer region!\n"); 126495584Sanholt radeon_do_cleanup_cp(dev); 1265182080Srnoland return -EINVAL; 126695584Sanholt } 126795584Sanholt 1268145132Sanholt if (init->gart_textures_offset) { 1269145132Sanholt dev_priv->gart_textures = 1270145132Sanholt drm_core_findmap(dev, init->gart_textures_offset); 1271145132Sanholt if (!dev_priv->gart_textures) { 1272119895Sanholt DRM_ERROR("could not find GART texture region!\n"); 127395584Sanholt radeon_do_cleanup_cp(dev); 1274182080Srnoland return -EINVAL; 127595584Sanholt } 127695584Sanholt } 127795584Sanholt 127895584Sanholt dev_priv->sarea_priv = 1279207066Srnoland (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->virtual + 1280145132Sanholt init->sarea_priv_offset); 128195584Sanholt 1282145132Sanholt#if __OS_HAS_AGP 1283182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1284189499Srnoland drm_core_ioremap_wc(dev_priv->cp_ring, dev); 1285189499Srnoland drm_core_ioremap_wc(dev_priv->ring_rptr, dev); 1286189499Srnoland drm_core_ioremap_wc(dev->agp_buffer_map, dev); 1287207066Srnoland if (!dev_priv->cp_ring->virtual || 1288207066Srnoland !dev_priv->ring_rptr->virtual || 1289207066Srnoland !dev->agp_buffer_map->virtual) { 129095584Sanholt DRM_ERROR("could not find ioremap agp regions!\n"); 129195584Sanholt radeon_do_cleanup_cp(dev); 1292182080Srnoland return -EINVAL; 129395584Sanholt } 1294119098Sanholt } else 1295119098Sanholt#endif 1296119098Sanholt { 1297207066Srnoland dev_priv->cp_ring->virtual = 1298189499Srnoland (void *)(unsigned long)dev_priv->cp_ring->offset; 1299207066Srnoland dev_priv->ring_rptr->virtual = 1300189499Srnoland (void *)(unsigned long)dev_priv->ring_rptr->offset; 1301207066Srnoland dev->agp_buffer_map->virtual = 1302189499Srnoland (void *)(unsigned long)dev->agp_buffer_map->offset; 130395584Sanholt 1304207066Srnoland DRM_DEBUG("dev_priv->cp_ring->virtual %p\n", 1305207066Srnoland dev_priv->cp_ring->virtual); 1306207066Srnoland DRM_DEBUG("dev_priv->ring_rptr->virtual %p\n", 1307207066Srnoland dev_priv->ring_rptr->virtual); 1308207066Srnoland DRM_DEBUG("dev->agp_buffer_map->virtual %p\n", 1309207066Srnoland dev->agp_buffer_map->virtual); 131095584Sanholt } 131195584Sanholt 1312182080Srnoland dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; 1313182080Srnoland dev_priv->fb_size = 1314182080Srnoland ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) 1315157617Sanholt - dev_priv->fb_location; 131695584Sanholt 1317145132Sanholt dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1318145132Sanholt ((dev_priv->front_offset 1319145132Sanholt + dev_priv->fb_location) >> 10)); 1320122580Sanholt 1321145132Sanholt dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | 1322145132Sanholt ((dev_priv->back_offset 1323145132Sanholt + dev_priv->fb_location) >> 10)); 1324122580Sanholt 1325145132Sanholt dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | 1326145132Sanholt ((dev_priv->depth_offset 1327145132Sanholt + dev_priv->fb_location) >> 10)); 1328122580Sanholt 1329119895Sanholt dev_priv->gart_size = init->gart_size; 1330122580Sanholt 1331157617Sanholt /* New let's set the memory map ... */ 1332157617Sanholt if (dev_priv->new_memmap) { 1333157617Sanholt u32 base = 0; 1334157617Sanholt 1335157617Sanholt DRM_INFO("Setting GART location based on new memory map\n"); 1336157617Sanholt 1337157617Sanholt /* If using AGP, try to locate the AGP aperture at the same 1338157617Sanholt * location in the card and on the bus, though we have to 1339157617Sanholt * align it down. 1340157617Sanholt */ 1341145132Sanholt#if __OS_HAS_AGP 1342182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1343157617Sanholt base = dev->agp->base; 1344157617Sanholt /* Check if valid */ 1345182080Srnoland if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && 1346182080Srnoland base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { 1347157617Sanholt DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", 1348157617Sanholt dev->agp->base); 1349157617Sanholt base = 0; 1350157617Sanholt } 1351157617Sanholt } 1352157617Sanholt#endif 1353157617Sanholt /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ 1354157617Sanholt if (base == 0) { 1355157617Sanholt base = dev_priv->fb_location + dev_priv->fb_size; 1356182080Srnoland if (base < dev_priv->fb_location || 1357182080Srnoland ((base + dev_priv->gart_size) & 0xfffffffful) < base) 1358157617Sanholt base = dev_priv->fb_location 1359157617Sanholt - dev_priv->gart_size; 1360182080Srnoland } 1361157617Sanholt dev_priv->gart_vm_start = base & 0xffc00000u; 1362157617Sanholt if (dev_priv->gart_vm_start != base) 1363157617Sanholt DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", 1364157617Sanholt base, dev_priv->gart_vm_start); 1365157617Sanholt } else { 1366157617Sanholt DRM_INFO("Setting GART location based on old memory map\n"); 1367157617Sanholt dev_priv->gart_vm_start = dev_priv->fb_location + 1368157617Sanholt RADEON_READ(RADEON_CONFIG_APER_SIZE); 1369157617Sanholt } 1370157617Sanholt 1371157617Sanholt#if __OS_HAS_AGP 1372182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) 1373145132Sanholt dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 1374145132Sanholt - dev->agp->base 1375145132Sanholt + dev_priv->gart_vm_start); 137695584Sanholt else 137795584Sanholt#endif 1378207067Srnoland dev_priv->gart_buffers_offset = dev->agp_buffer_map->offset - 1379207067Srnoland dev->sg->vaddr + dev_priv->gart_vm_start; 138095584Sanholt 1381145132Sanholt DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); 1382145132Sanholt DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start); 1383145132Sanholt DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n", 1384145132Sanholt dev_priv->gart_buffers_offset); 138595584Sanholt 1386207066Srnoland dev_priv->ring.start = (u32 *) dev_priv->cp_ring->virtual; 1387207066Srnoland dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->virtual 138895584Sanholt + init->ring_size / sizeof(u32)); 138995584Sanholt dev_priv->ring.size = init->ring_size; 1390145132Sanholt dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); 139195584Sanholt 1392182080Srnoland dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; 1393182080Srnoland dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8); 1394182080Srnoland 1395182080Srnoland dev_priv->ring.fetch_size = /* init->fetch_size */ 32; 1396182080Srnoland dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); 1397145132Sanholt dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; 139895584Sanholt 139995584Sanholt dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 140095584Sanholt 1401145132Sanholt#if __OS_HAS_AGP 1402182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1403119098Sanholt /* Turn off PCI GART */ 1404145132Sanholt radeon_set_pcigart(dev_priv, 0); 1405119098Sanholt } else 1406119098Sanholt#endif 1407119098Sanholt { 1408189499Srnoland u32 sctrl; 1409189499Srnoland int ret; 1410189499Srnoland 1411182080Srnoland dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); 1412152909Sanholt /* if we have an offset set from userspace */ 1413182080Srnoland if (dev_priv->pcigart_offset_set) { 1414157617Sanholt dev_priv->gart_info.bus_addr = 1415157617Sanholt dev_priv->pcigart_offset + dev_priv->fb_location; 1416157617Sanholt dev_priv->gart_info.mapping.offset = 1417182080Srnoland dev_priv->pcigart_offset + dev_priv->fb_aper_offset; 1418157617Sanholt dev_priv->gart_info.mapping.size = 1419182080Srnoland dev_priv->gart_info.table_size; 1420157617Sanholt 1421182080Srnoland drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); 1422157617Sanholt dev_priv->gart_info.addr = 1423207066Srnoland dev_priv->gart_info.mapping.virtual; 1424152909Sanholt 1425182080Srnoland if (dev_priv->flags & RADEON_IS_PCIE) 1426182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; 1427182080Srnoland else 1428182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; 1429157617Sanholt dev_priv->gart_info.gart_table_location = 1430157617Sanholt DRM_ATI_GART_FB; 1431157617Sanholt 1432157617Sanholt DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", 1433157617Sanholt dev_priv->gart_info.addr, 1434157617Sanholt dev_priv->pcigart_offset); 1435157617Sanholt } else { 1436182080Srnoland if (dev_priv->flags & RADEON_IS_IGPGART) 1437182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; 1438182080Srnoland else 1439182080Srnoland dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; 1440157617Sanholt dev_priv->gart_info.gart_table_location = 1441157617Sanholt DRM_ATI_GART_MAIN; 1442152909Sanholt dev_priv->gart_info.addr = NULL; 1443152909Sanholt dev_priv->gart_info.bus_addr = 0; 1444182080Srnoland if (dev_priv->flags & RADEON_IS_PCIE) { 1445157617Sanholt DRM_ERROR 1446157617Sanholt ("Cannot use PCI Express without GART in FB memory\n"); 1447152909Sanholt radeon_do_cleanup_cp(dev); 1448182080Srnoland return -EINVAL; 1449152909Sanholt } 1450152909Sanholt } 1451152909Sanholt 1452189499Srnoland sctrl = RADEON_READ(RADEON_SURFACE_CNTL); 1453189499Srnoland RADEON_WRITE(RADEON_SURFACE_CNTL, 0); 1454189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 1455189499Srnoland ret = r600_page_table_init(dev); 1456189499Srnoland else 1457189499Srnoland ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); 1458189499Srnoland RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); 1459189499Srnoland 1460189499Srnoland if (!ret) { 1461145132Sanholt DRM_ERROR("failed to init PCI GART!\n"); 146295584Sanholt radeon_do_cleanup_cp(dev); 1463182080Srnoland return -ENOMEM; 146495584Sanholt } 146595584Sanholt 1466189499Srnoland ret = radeon_setup_pcigart_surface(dev_priv); 1467189499Srnoland if (ret) { 1468189499Srnoland DRM_ERROR("failed to setup GART surface!\n"); 1469189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 1470189499Srnoland r600_page_table_cleanup(dev, &dev_priv->gart_info); 1471189499Srnoland else 1472189499Srnoland drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); 1473189499Srnoland radeon_do_cleanup_cp(dev); 1474189499Srnoland return ret; 1475189499Srnoland } 1476189499Srnoland 1477119098Sanholt /* Turn on PCI GART */ 1478145132Sanholt radeon_set_pcigart(dev_priv, 1); 147995584Sanholt } 148095584Sanholt 1481145132Sanholt radeon_cp_load_microcode(dev_priv); 1482189499Srnoland radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); 148395584Sanholt 148495584Sanholt dev_priv->last_buf = 0; 148595584Sanholt 1486145132Sanholt radeon_do_engine_reset(dev); 1487157617Sanholt radeon_test_writeback(dev_priv); 148895584Sanholt 148995584Sanholt return 0; 149095584Sanholt} 149195584Sanholt 1492182080Srnolandstatic int radeon_do_cleanup_cp(struct drm_device * dev) 149395584Sanholt{ 1494145132Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1495145132Sanholt DRM_DEBUG("\n"); 149695584Sanholt 1497119098Sanholt /* Make sure interrupts are disabled here because the uninstall ioctl 1498119098Sanholt * may not have been called from userspace and after dev_private 1499119098Sanholt * is freed, it's too late. 1500119098Sanholt */ 1501145132Sanholt if (dev->irq_enabled) 1502145132Sanholt drm_irq_uninstall(dev); 1503119098Sanholt 1504145132Sanholt#if __OS_HAS_AGP 1505182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1506145132Sanholt if (dev_priv->cp_ring != NULL) { 1507145132Sanholt drm_core_ioremapfree(dev_priv->cp_ring, dev); 1508145132Sanholt dev_priv->cp_ring = NULL; 1509145132Sanholt } 1510145132Sanholt if (dev_priv->ring_rptr != NULL) { 1511145132Sanholt drm_core_ioremapfree(dev_priv->ring_rptr, dev); 1512145132Sanholt dev_priv->ring_rptr = NULL; 1513145132Sanholt } 1514145132Sanholt if (dev->agp_buffer_map != NULL) { 1515145132Sanholt drm_core_ioremapfree(dev->agp_buffer_map, dev); 1516145132Sanholt dev->agp_buffer_map = NULL; 1517145132Sanholt } 1518145132Sanholt } else 1519119098Sanholt#endif 1520145132Sanholt { 1521152909Sanholt 1522152909Sanholt if (dev_priv->gart_info.bus_addr) { 1523152909Sanholt /* Turn off PCI GART */ 1524152909Sanholt radeon_set_pcigart(dev_priv, 0); 1525189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) 1526189499Srnoland r600_page_table_cleanup(dev, &dev_priv->gart_info); 1527189499Srnoland else { 1528189499Srnoland if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) 1529189499Srnoland DRM_ERROR("failed to cleanup PCI GART!\n"); 1530189499Srnoland } 1531152909Sanholt } 1532152909Sanholt 1533152909Sanholt if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) 1534152909Sanholt { 1535152909Sanholt drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); 1536152909Sanholt dev_priv->gart_info.addr = 0; 1537152909Sanholt } 153895584Sanholt } 1539145132Sanholt /* only clear to the start of flags */ 1540145132Sanholt memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); 154195584Sanholt 154295584Sanholt return 0; 154395584Sanholt} 154495584Sanholt 1545145132Sanholt/* This code will reinit the Radeon CP hardware after a resume from disc. 1546145132Sanholt * AFAIK, it would be very difficult to pickle the state at suspend time, so 1547119098Sanholt * here we make sure that all Radeon hardware initialisation is re-done without 1548119098Sanholt * affecting running applications. 1549119098Sanholt * 1550119098Sanholt * Charl P. Botha <http://cpbotha.net> 1551119098Sanholt */ 1552189499Srnolandstatic int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) 1553119098Sanholt{ 1554119098Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1555119098Sanholt 1556145132Sanholt if (!dev_priv) { 1557145132Sanholt DRM_ERROR("Called with no initialization\n"); 1558182080Srnoland return -EINVAL; 1559119098Sanholt } 1560119098Sanholt 1561119098Sanholt DRM_DEBUG("Starting radeon_do_resume_cp()\n"); 1562119098Sanholt 1563145132Sanholt#if __OS_HAS_AGP 1564182080Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1565119098Sanholt /* Turn off PCI GART */ 1566145132Sanholt radeon_set_pcigart(dev_priv, 0); 1567119098Sanholt } else 1568119098Sanholt#endif 1569119098Sanholt { 1570119098Sanholt /* Turn on PCI GART */ 1571145132Sanholt radeon_set_pcigart(dev_priv, 1); 1572119098Sanholt } 1573119098Sanholt 1574145132Sanholt radeon_cp_load_microcode(dev_priv); 1575189499Srnoland radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); 1576119098Sanholt 1577145132Sanholt radeon_do_engine_reset(dev); 1578182080Srnoland radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 1579119098Sanholt 1580119098Sanholt DRM_DEBUG("radeon_do_resume_cp() complete\n"); 1581119098Sanholt 1582119098Sanholt return 0; 1583119098Sanholt} 1584119098Sanholt 1585182080Srnolandint radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) 158695584Sanholt{ 1587189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1588182080Srnoland drm_radeon_init_t *init = data; 158995584Sanholt 1590182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 1591119098Sanholt 1592182080Srnoland if (init->func == RADEON_INIT_R300_CP) 1593182080Srnoland r300_init_reg_flags(dev); 159495584Sanholt 1595182080Srnoland switch (init->func) { 159695584Sanholt case RADEON_INIT_CP: 1597112015Sanholt case RADEON_INIT_R200_CP: 1598145132Sanholt case RADEON_INIT_R300_CP: 1599189499Srnoland return radeon_do_init_cp(dev, init, file_priv); 1600189499Srnoland case RADEON_INIT_R600_CP: 1601189499Srnoland return r600_do_init_cp(dev, init, file_priv); 160295584Sanholt case RADEON_CLEANUP_CP: 1603189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1604189499Srnoland return r600_do_cleanup_cp(dev); 1605189499Srnoland else 1606189499Srnoland return radeon_do_cleanup_cp(dev); 160795584Sanholt } 160895584Sanholt 1609182080Srnoland return -EINVAL; 161095584Sanholt} 161195584Sanholt 1612182080Srnolandint radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv) 161395584Sanholt{ 161495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1615145132Sanholt DRM_DEBUG("\n"); 161695584Sanholt 1617182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 161895584Sanholt 1619145132Sanholt if (dev_priv->cp_running) { 1620182080Srnoland DRM_DEBUG("while CP running\n"); 162195584Sanholt return 0; 162295584Sanholt } 1623145132Sanholt if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) { 1624182080Srnoland DRM_DEBUG("called with bogus CP mode (%d)\n", 1625182080Srnoland dev_priv->cp_mode); 162695584Sanholt return 0; 162795584Sanholt } 162895584Sanholt 1629189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1630189499Srnoland r600_do_cp_start(dev_priv); 1631189499Srnoland else 1632189499Srnoland radeon_do_cp_start(dev_priv); 163395584Sanholt 163495584Sanholt return 0; 163595584Sanholt} 163695584Sanholt 163795584Sanholt/* Stop the CP. The engine must have been idled before calling this 163895584Sanholt * routine. 163995584Sanholt */ 1640182080Srnolandint radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) 164195584Sanholt{ 164295584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1643182080Srnoland drm_radeon_cp_stop_t *stop = data; 164495584Sanholt int ret; 1645145132Sanholt DRM_DEBUG("\n"); 164695584Sanholt 1647182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 164895584Sanholt 1649112015Sanholt if (!dev_priv->cp_running) 1650112015Sanholt return 0; 1651112015Sanholt 165295584Sanholt /* Flush any pending CP commands. This ensures any outstanding 165395584Sanholt * commands are exectuted by the engine before we turn it off. 165495584Sanholt */ 1655182080Srnoland if (stop->flush) { 1656145132Sanholt radeon_do_cp_flush(dev_priv); 165795584Sanholt } 165895584Sanholt 165995584Sanholt /* If we fail to make the engine go idle, we return an error 166095584Sanholt * code so that the DRM ioctl wrapper can try again. 166195584Sanholt */ 1662182080Srnoland if (stop->idle) { 1663189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1664189499Srnoland ret = r600_do_cp_idle(dev_priv); 1665189499Srnoland else 1666189499Srnoland ret = radeon_do_cp_idle(dev_priv); 1667145132Sanholt if (ret) 1668145132Sanholt return ret; 166995584Sanholt } 167095584Sanholt 167195584Sanholt /* Finally, we can turn off the CP. If the engine isn't idle, 167295584Sanholt * we will get some dropped triangles as they won't be fully 167395584Sanholt * rendered before the CP is shut down. 167495584Sanholt */ 1675189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1676189499Srnoland r600_do_cp_stop(dev_priv); 1677189499Srnoland else 1678189499Srnoland radeon_do_cp_stop(dev_priv); 167995584Sanholt 168095584Sanholt /* Reset the engine */ 1681189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1682189499Srnoland r600_do_engine_reset(dev); 1683189499Srnoland else 1684189499Srnoland radeon_do_engine_reset(dev); 168595584Sanholt 168695584Sanholt return 0; 168795584Sanholt} 168895584Sanholt 1689182080Srnolandvoid radeon_do_release(struct drm_device * dev) 1690112015Sanholt{ 1691112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1692145132Sanholt int i, ret; 1693112015Sanholt 1694112015Sanholt if (dev_priv) { 1695112015Sanholt if (dev_priv->cp_running) { 1696112015Sanholt /* Stop the cp */ 1697189557Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 1698189499Srnoland while ((ret = r600_do_cp_idle(dev_priv)) != 0) { 1699189499Srnoland DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1700189499Srnoland mtx_sleep(&ret, &dev->dev_lock, 0, 1701189499Srnoland "rdnrel", 1); 1702189499Srnoland } 1703189499Srnoland } else { 1704189499Srnoland while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { 1705189499Srnoland DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1706189499Srnoland mtx_sleep(&ret, &dev->dev_lock, 0, 1707189499Srnoland "rdnrel", 1); 1708189499Srnoland } 1709112015Sanholt } 1710189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 1711189499Srnoland r600_do_cp_stop(dev_priv); 1712189499Srnoland r600_do_engine_reset(dev); 1713189499Srnoland } else { 1714189499Srnoland radeon_do_cp_stop(dev_priv); 1715189499Srnoland radeon_do_engine_reset(dev); 1716189499Srnoland } 1717112015Sanholt } 1718112015Sanholt 1719189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { 1720189499Srnoland /* Disable *all* interrupts */ 1721189499Srnoland if (dev_priv->mmio) /* remove this after permanent addmaps */ 1722189499Srnoland RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 1723112015Sanholt 1724189499Srnoland if (dev_priv->mmio) { /* remove all surfaces */ 1725189499Srnoland for (i = 0; i < RADEON_MAX_SURFACES; i++) { 1726189499Srnoland RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); 1727189499Srnoland RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 1728189499Srnoland 16 * i, 0); 1729189499Srnoland RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 1730189499Srnoland 16 * i, 0); 1731189499Srnoland } 1732145132Sanholt } 1733145132Sanholt } 1734145132Sanholt 1735112015Sanholt /* Free memory heap structures */ 1736145132Sanholt radeon_mem_takedown(&(dev_priv->gart_heap)); 1737145132Sanholt radeon_mem_takedown(&(dev_priv->fb_heap)); 1738112015Sanholt 1739112015Sanholt /* deallocate kernel resources */ 1740189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1741189499Srnoland r600_do_cleanup_cp(dev); 1742189499Srnoland else 1743189499Srnoland radeon_do_cleanup_cp(dev); 1744112015Sanholt } 1745112015Sanholt} 1746112015Sanholt 174795584Sanholt/* Just reset the CP ring. Called as part of an X Server engine reset. 174895584Sanholt */ 1749182080Srnolandint radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 175095584Sanholt{ 175195584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1752145132Sanholt DRM_DEBUG("\n"); 175395584Sanholt 1754182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 175595584Sanholt 1756145132Sanholt if (!dev_priv) { 1757182080Srnoland DRM_DEBUG("called before init done\n"); 1758182080Srnoland return -EINVAL; 175995584Sanholt } 176095584Sanholt 1761189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1762189499Srnoland r600_do_cp_reset(dev_priv); 1763189499Srnoland else 1764189499Srnoland radeon_do_cp_reset(dev_priv); 176595584Sanholt 176695584Sanholt /* The CP is no longer running after an engine reset */ 176795584Sanholt dev_priv->cp_running = 0; 176895584Sanholt 176995584Sanholt return 0; 177095584Sanholt} 177195584Sanholt 1772182080Srnolandint radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) 177395584Sanholt{ 177495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1775145132Sanholt DRM_DEBUG("\n"); 177695584Sanholt 1777182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 177895584Sanholt 1779189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1780189499Srnoland return r600_do_cp_idle(dev_priv); 1781189499Srnoland else 1782189499Srnoland return radeon_do_cp_idle(dev_priv); 178395584Sanholt} 178495584Sanholt 1785119098Sanholt/* Added by Charl P. Botha to call radeon_do_resume_cp(). 1786119098Sanholt */ 1787182080Srnolandint radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) 1788119098Sanholt{ 1789189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1790189499Srnoland DRM_DEBUG("\n"); 1791119098Sanholt 1792189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1793189499Srnoland return r600_do_resume_cp(dev, file_priv); 1794189499Srnoland else 1795189499Srnoland return radeon_do_resume_cp(dev, file_priv); 1796119098Sanholt} 1797119098Sanholt 1798182080Srnolandint radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) 179995584Sanholt{ 1800189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1801145132Sanholt DRM_DEBUG("\n"); 180295584Sanholt 1803182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 180495584Sanholt 1805189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 1806189499Srnoland return r600_do_engine_reset(dev); 1807189499Srnoland else 1808189499Srnoland return radeon_do_engine_reset(dev); 180995584Sanholt} 181095584Sanholt 181195584Sanholt/* ================================================================ 181295584Sanholt * Fullscreen mode 181395584Sanholt */ 181495584Sanholt 1815112015Sanholt/* KW: Deprecated to say the least: 1816112015Sanholt */ 1817182080Srnolandint radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) 181895584Sanholt{ 181995584Sanholt return 0; 182095584Sanholt} 182195584Sanholt 182295584Sanholt/* ================================================================ 182395584Sanholt * Freelist management 182495584Sanholt */ 182595584Sanholt 1826112015Sanholt/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through 1827112015Sanholt * bufs until freelist code is used. Note this hides a problem with 1828112015Sanholt * the scratch register * (used to keep track of last buffer 1829112015Sanholt * completed) being written to before * the last buffer has actually 1830145132Sanholt * completed rendering. 1831112015Sanholt * 1832112015Sanholt * KW: It's also a good way to find free buffers quickly. 1833112015Sanholt * 1834112015Sanholt * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't 1835112015Sanholt * sleep. However, bugs in older versions of radeon_accel.c mean that 1836112015Sanholt * we essentially have to do this, else old clients will break. 1837145132Sanholt * 1838112015Sanholt * However, it does leave open a potential deadlock where all the 1839112015Sanholt * buffers are held by other clients, which can't release them because 1840145132Sanholt * they can't get the lock. 1841112015Sanholt */ 1842112015Sanholt 1843182080Srnolandstruct drm_buf *radeon_freelist_get(struct drm_device * dev) 184495584Sanholt{ 1845182080Srnoland struct drm_device_dma *dma = dev->dma; 184695584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1847112015Sanholt drm_radeon_buf_priv_t *buf_priv; 1848182080Srnoland struct drm_buf *buf; 1849112015Sanholt int i, t; 1850112015Sanholt int start; 185195584Sanholt 1852145132Sanholt if (++dev_priv->last_buf >= dma->buf_count) 1853112015Sanholt dev_priv->last_buf = 0; 185495584Sanholt 1855112015Sanholt start = dev_priv->last_buf; 185695584Sanholt 1857145132Sanholt for (t = 0; t < dev_priv->usec_timeout; t++) { 1858189499Srnoland u32 done_age = GET_SCRATCH(dev_priv, 1); 1859145132Sanholt DRM_DEBUG("done_age = %d\n", done_age); 1860198695Srnoland for (i = 0; i < dma->buf_count; i++) { 1861198695Srnoland buf = dma->buflist[start]; 1862112015Sanholt buf_priv = buf->dev_private; 1863182080Srnoland if (buf->file_priv == NULL || (buf->pending && 1864182080Srnoland buf_priv->age <= 1865182080Srnoland done_age)) { 1866112015Sanholt dev_priv->stats.requested_bufs++; 1867112015Sanholt buf->pending = 0; 1868112015Sanholt return buf; 1869112015Sanholt } 1870198695Srnoland if (++start >= dma->buf_count) 1871198695Srnoland start = 0; 1872112015Sanholt } 187395584Sanholt 1874112015Sanholt if (t) { 1875145132Sanholt DRM_UDELAY(1); 1876112015Sanholt dev_priv->stats.freelist_loops++; 1877112015Sanholt } 187895584Sanholt } 187995584Sanholt 1880112015Sanholt return NULL; 188195584Sanholt} 1882145132Sanholt 1883182080Srnolandvoid radeon_freelist_reset(struct drm_device * dev) 188495584Sanholt{ 1885182080Srnoland struct drm_device_dma *dma = dev->dma; 188695584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 188795584Sanholt int i; 188895584Sanholt 188995584Sanholt dev_priv->last_buf = 0; 1890145132Sanholt for (i = 0; i < dma->buf_count; i++) { 1891182080Srnoland struct drm_buf *buf = dma->buflist[i]; 189295584Sanholt drm_radeon_buf_priv_t *buf_priv = buf->dev_private; 189395584Sanholt buf_priv->age = 0; 189495584Sanholt } 189595584Sanholt} 189695584Sanholt 189795584Sanholt/* ================================================================ 189895584Sanholt * CP command submission 189995584Sanholt */ 190095584Sanholt 1901145132Sanholtint radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) 190295584Sanholt{ 190395584Sanholt drm_radeon_ring_buffer_t *ring = &dev_priv->ring; 190495584Sanholt int i; 1905145132Sanholt u32 last_head = GET_RING_HEAD(dev_priv); 190695584Sanholt 1907145132Sanholt for (i = 0; i < dev_priv->usec_timeout; i++) { 1908145132Sanholt u32 head = GET_RING_HEAD(dev_priv); 1909112015Sanholt 1910112015Sanholt ring->space = (head - ring->tail) * sizeof(u32); 1911145132Sanholt if (ring->space <= 0) 1912112015Sanholt ring->space += ring->size; 1913145132Sanholt if (ring->space > n) 191495584Sanholt return 0; 1915145132Sanholt 1916112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 1917112015Sanholt 1918112015Sanholt if (head != last_head) 1919112015Sanholt i = 0; 1920112015Sanholt last_head = head; 1921112015Sanholt 1922145132Sanholt DRM_UDELAY(1); 192395584Sanholt } 192495584Sanholt 192595584Sanholt /* FIXME: This return value is ignored in the BEGIN_RING macro! */ 192695584Sanholt#if RADEON_FIFO_DEBUG 1927145132Sanholt radeon_status(dev_priv); 1928145132Sanholt DRM_ERROR("failed!\n"); 192995584Sanholt#endif 1930182080Srnoland return -EBUSY; 193195584Sanholt} 193295584Sanholt 1933182080Srnolandstatic int radeon_cp_get_buffers(struct drm_device *dev, 1934182080Srnoland struct drm_file *file_priv, 1935182080Srnoland struct drm_dma * d) 193695584Sanholt{ 193795584Sanholt int i; 1938182080Srnoland struct drm_buf *buf; 193995584Sanholt 1940145132Sanholt for (i = d->granted_count; i < d->request_count; i++) { 1941145132Sanholt buf = radeon_freelist_get(dev); 1942145132Sanholt if (!buf) 1943182080Srnoland return -EBUSY; /* NOTE: broken client */ 194495584Sanholt 1945182080Srnoland buf->file_priv = file_priv; 194695584Sanholt 1947145132Sanholt if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, 1948145132Sanholt sizeof(buf->idx))) 1949182080Srnoland return -EFAULT; 1950145132Sanholt if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, 1951145132Sanholt sizeof(buf->total))) 1952182080Srnoland return -EFAULT; 195395584Sanholt 195495584Sanholt d->granted_count++; 195595584Sanholt } 195695584Sanholt return 0; 195795584Sanholt} 195895584Sanholt 1959182080Srnolandint radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) 196095584Sanholt{ 1961182080Srnoland struct drm_device_dma *dma = dev->dma; 196295584Sanholt int ret = 0; 1963182080Srnoland struct drm_dma *d = data; 196495584Sanholt 1965182080Srnoland LOCK_TEST_WITH_RETURN(dev, file_priv); 196695584Sanholt 196795584Sanholt /* Please don't send us buffers. 196895584Sanholt */ 1969182080Srnoland if (d->send_count != 0) { 1970145132Sanholt DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", 1971182080Srnoland DRM_CURRENTPID, d->send_count); 1972182080Srnoland return -EINVAL; 197395584Sanholt } 197495584Sanholt 197595584Sanholt /* We'll send you buffers. 197695584Sanholt */ 1977182080Srnoland if (d->request_count < 0 || d->request_count > dma->buf_count) { 1978145132Sanholt DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", 1979182080Srnoland DRM_CURRENTPID, d->request_count, dma->buf_count); 1980182080Srnoland return -EINVAL; 198195584Sanholt } 198295584Sanholt 1983182080Srnoland d->granted_count = 0; 198495584Sanholt 1985182080Srnoland if (d->request_count) { 1986182080Srnoland ret = radeon_cp_get_buffers(dev, file_priv, d); 198795584Sanholt } 198895584Sanholt 198995584Sanholt return ret; 199095584Sanholt} 1991145132Sanholt 1992152909Sanholtint radeon_driver_load(struct drm_device *dev, unsigned long flags) 1993145132Sanholt{ 1994145132Sanholt drm_radeon_private_t *dev_priv; 1995145132Sanholt int ret = 0; 1996145132Sanholt 1997145132Sanholt dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER); 1998145132Sanholt if (dev_priv == NULL) 1999182080Srnoland return -ENOMEM; 2000145132Sanholt 2001145132Sanholt memset(dev_priv, 0, sizeof(drm_radeon_private_t)); 2002145132Sanholt dev->dev_private = (void *)dev_priv; 2003145132Sanholt dev_priv->flags = flags; 2004145132Sanholt 2005182080Srnoland switch (flags & RADEON_FAMILY_MASK) { 2006145132Sanholt case CHIP_R100: 2007145132Sanholt case CHIP_RV200: 2008145132Sanholt case CHIP_R200: 2009145132Sanholt case CHIP_R300: 2010157617Sanholt case CHIP_R350: 2011148211Sanholt case CHIP_R420: 2012183830Srnoland case CHIP_R423: 2013157617Sanholt case CHIP_RV410: 2014182080Srnoland case CHIP_RV515: 2015182080Srnoland case CHIP_R520: 2016182080Srnoland case CHIP_RV570: 2017182080Srnoland case CHIP_R580: 2018182080Srnoland dev_priv->flags |= RADEON_HAS_HIERZ; 2019145132Sanholt break; 2020145132Sanholt default: 2021157617Sanholt /* all other chips have no hierarchical z buffer */ 2022145132Sanholt break; 2023145132Sanholt } 2024145132Sanholt 2025145132Sanholt if (drm_device_is_agp(dev)) 2026182080Srnoland dev_priv->flags |= RADEON_IS_AGP; 2027162132Sanholt else if (drm_device_is_pcie(dev)) 2028182080Srnoland dev_priv->flags |= RADEON_IS_PCIE; 2029162132Sanholt else 2030182080Srnoland dev_priv->flags |= RADEON_IS_PCI; 2031148211Sanholt 2032196470Srnoland mtx_init(&dev_priv->cs.cs_mutex, "cs_mtx", NULL, MTX_DEF); 2033196470Srnoland 2034189499Srnoland ret = drm_addmap(dev, drm_get_resource_start(dev, 2), 2035189499Srnoland drm_get_resource_len(dev, 2), _DRM_REGISTERS, 2036189499Srnoland _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); 2037189499Srnoland if (ret != 0) 2038194969Srnoland goto error; 2039189499Srnoland 2040189130Srnoland ret = drm_vblank_init(dev, 2); 2041194969Srnoland if (ret != 0) 2042194969Srnoland goto error; 2043189130Srnoland 2044194969Srnoland dev->max_vblank_count = 0x001fffff; 2045194969Srnoland 2046145132Sanholt DRM_DEBUG("%s card detected\n", 2047194969Srnoland ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : 2048194969Srnoland (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); 2049194969Srnoland 2050145132Sanholt return ret; 2051194969Srnoland 2052194969Srnolanderror: 2053194969Srnoland radeon_driver_unload(dev); 2054194969Srnoland return ret; 2055145132Sanholt} 2056145132Sanholt 2057152909Sanholt/* Create mappings for registers and framebuffer so userland doesn't necessarily 2058152909Sanholt * have to find them. 2059152909Sanholt */ 2060152909Sanholtint radeon_driver_firstopen(struct drm_device *dev) 2061145132Sanholt{ 2062152909Sanholt int ret; 2063152909Sanholt drm_local_map_t *map; 2064145132Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 2065145132Sanholt 2066182080Srnoland dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; 2067182080Srnoland 2068182080Srnoland dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); 2069182080Srnoland ret = drm_addmap(dev, dev_priv->fb_aper_offset, 2070152909Sanholt drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, 2071152909Sanholt _DRM_WRITE_COMBINING, &map); 2072152909Sanholt if (ret != 0) 2073152909Sanholt return ret; 2074152909Sanholt 2075152909Sanholt return 0; 2076152909Sanholt} 2077152909Sanholt 2078152909Sanholtint radeon_driver_unload(struct drm_device *dev) 2079152909Sanholt{ 2080152909Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 2081152909Sanholt 2082145132Sanholt DRM_DEBUG("\n"); 2083189499Srnoland 2084189499Srnoland drm_rmmap(dev, dev_priv->mmio); 2085189499Srnoland 2086196470Srnoland mtx_destroy(&dev_priv->cs.cs_mutex); 2087196470Srnoland 2088145132Sanholt drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); 2089145132Sanholt 2090145132Sanholt dev->dev_private = NULL; 2091145132Sanholt return 0; 2092145132Sanholt} 2093189499Srnoland 2094189499Srnolandvoid radeon_commit_ring(drm_radeon_private_t *dev_priv) 2095189499Srnoland{ 2096189499Srnoland int i; 2097189499Srnoland u32 *ring; 2098189499Srnoland int tail_aligned; 2099189499Srnoland 2100189499Srnoland /* check if the ring is padded out to 16-dword alignment */ 2101189499Srnoland 2102196470Srnoland tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1); 2103189499Srnoland if (tail_aligned) { 2104196470Srnoland int num_p2 = RADEON_RING_ALIGN - tail_aligned; 2105189499Srnoland 2106189499Srnoland ring = dev_priv->ring.start; 2107189499Srnoland /* pad with some CP_PACKET2 */ 2108189499Srnoland for (i = 0; i < num_p2; i++) 2109189499Srnoland ring[dev_priv->ring.tail + i] = CP_PACKET2(); 2110189499Srnoland 2111189499Srnoland dev_priv->ring.tail += i; 2112189499Srnoland 2113189499Srnoland dev_priv->ring.space -= num_p2 * sizeof(u32); 2114189499Srnoland } 2115189499Srnoland 2116189499Srnoland dev_priv->ring.tail &= dev_priv->ring.tail_mask; 2117189499Srnoland 2118189499Srnoland DRM_MEMORYBARRIER(); 2119189499Srnoland GET_RING_HEAD( dev_priv ); 2120189499Srnoland 2121189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { 2122189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); 2123189499Srnoland /* read from PCI bus to ensure correct posting */ 2124189499Srnoland RADEON_READ(R600_CP_RB_RPTR); 2125189499Srnoland } else { 2126189499Srnoland RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); 2127189499Srnoland /* read from PCI bus to ensure correct posting */ 2128189499Srnoland RADEON_READ(RADEON_CP_RB_RPTR); 2129189499Srnoland } 2130189499Srnoland} 2131