r300.c revision 261455
1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2008 Advanced Micro Devices, Inc. 3254885Sdumbbell * Copyright 2008 Red Hat Inc. 4254885Sdumbbell * Copyright 2009 Jerome Glisse. 5254885Sdumbbell * 6254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 7254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 8254885Sdumbbell * to deal in the Software without restriction, including without limitation 9254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 11254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 12254885Sdumbbell * 13254885Sdumbbell * The above copyright notice and this permission notice shall be included in 14254885Sdumbbell * all copies or substantial portions of the Software. 15254885Sdumbbell * 16254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 23254885Sdumbbell * 24254885Sdumbbell * Authors: Dave Airlie 25254885Sdumbbell * Alex Deucher 26254885Sdumbbell * Jerome Glisse 27254885Sdumbbell */ 28254885Sdumbbell 29254885Sdumbbell#include <sys/cdefs.h> 30254885Sdumbbell__FBSDID("$FreeBSD: stable/10/sys/dev/drm2/radeon/r300.c 261455 2014-02-04 03:36:42Z eadler $"); 31254885Sdumbbell 32254885Sdumbbell#include <dev/drm2/drmP.h> 33254885Sdumbbell#include <dev/drm2/drm.h> 34254885Sdumbbell#include <dev/drm2/drm_crtc_helper.h> 35254885Sdumbbell#include "radeon_reg.h" 36254885Sdumbbell#include "radeon.h" 37254885Sdumbbell#include "radeon_asic.h" 38254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 39254885Sdumbbell#include "r100_track.h" 40254885Sdumbbell#include "r300d.h" 41254885Sdumbbell#include "rv350d.h" 42254885Sdumbbell#include "r300_reg_safe.h" 43254885Sdumbbell 44254885Sdumbbell/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 45254885Sdumbbell * 46254885Sdumbbell * GPU Errata: 47254885Sdumbbell * - HOST_PATH_CNTL: r300 family seems to dislike write to HOST_PATH_CNTL 48254885Sdumbbell * using MMIO to flush host path read cache, this lead to HARDLOCKUP. 49254885Sdumbbell * However, scheduling such write to the ring seems harmless, i suspect 50254885Sdumbbell * the CP read collide with the flush somehow, or maybe the MC, hard to 51254885Sdumbbell * tell. (Jerome Glisse) 52254885Sdumbbell */ 53254885Sdumbbell 54254885Sdumbbell/* 55254885Sdumbbell * rv370,rv380 PCIE GART 56254885Sdumbbell */ 57254885Sdumbbellstatic int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev); 58254885Sdumbbell 59254885Sdumbbellvoid rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) 60254885Sdumbbell{ 61254885Sdumbbell uint32_t tmp; 62254885Sdumbbell int i; 63254885Sdumbbell 64254885Sdumbbell /* Workaround HW bug do flush 2 times */ 65254885Sdumbbell for (i = 0; i < 2; i++) { 66254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 67254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); 68254885Sdumbbell (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 69254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); 70254885Sdumbbell } 71254885Sdumbbell mb(); 72254885Sdumbbell} 73254885Sdumbbell 74254885Sdumbbell#define R300_PTE_WRITEABLE (1 << 2) 75254885Sdumbbell#define R300_PTE_READABLE (1 << 3) 76254885Sdumbbell 77254885Sdumbbellint rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 78254885Sdumbbell{ 79254885Sdumbbell volatile uint32_t *ptr = rdev->gart.ptr; 80254885Sdumbbell 81254885Sdumbbell if (i < 0 || i > rdev->gart.num_gpu_pages) { 82254885Sdumbbell return -EINVAL; 83254885Sdumbbell } 84254885Sdumbbell addr = (lower_32_bits(addr) >> 8) | 85254885Sdumbbell ((upper_32_bits(addr) & 0xff) << 24) | 86254885Sdumbbell R300_PTE_WRITEABLE | R300_PTE_READABLE; 87254885Sdumbbell /* on x86 we want this to be CPU endian, on powerpc 88254885Sdumbbell * on powerpc without HW swappers, it'll get swapped on way 89254885Sdumbbell * into VRAM - so no need for cpu_to_le32 on VRAM tables */ 90254885Sdumbbell ptr += i; 91254885Sdumbbell *ptr = (uint32_t)addr; 92254885Sdumbbell return 0; 93254885Sdumbbell} 94254885Sdumbbell 95254885Sdumbbellint rv370_pcie_gart_init(struct radeon_device *rdev) 96254885Sdumbbell{ 97254885Sdumbbell int r; 98254885Sdumbbell 99254885Sdumbbell if (rdev->gart.robj) { 100254885Sdumbbell DRM_ERROR("RV370 PCIE GART already initialized\n"); 101254885Sdumbbell return 0; 102254885Sdumbbell } 103254885Sdumbbell /* Initialize common gart structure */ 104254885Sdumbbell r = radeon_gart_init(rdev); 105254885Sdumbbell if (r) 106254885Sdumbbell return r; 107254885Sdumbbell r = rv370_debugfs_pcie_gart_info_init(rdev); 108254885Sdumbbell if (r) 109254885Sdumbbell DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); 110254885Sdumbbell rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; 111254885Sdumbbell rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; 112254885Sdumbbell rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; 113254885Sdumbbell return radeon_gart_table_vram_alloc(rdev); 114254885Sdumbbell} 115254885Sdumbbell 116254885Sdumbbellint rv370_pcie_gart_enable(struct radeon_device *rdev) 117254885Sdumbbell{ 118254885Sdumbbell uint32_t table_addr; 119254885Sdumbbell uint32_t tmp; 120254885Sdumbbell int r; 121254885Sdumbbell 122254885Sdumbbell if (rdev->gart.robj == NULL) { 123254885Sdumbbell dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 124254885Sdumbbell return -EINVAL; 125254885Sdumbbell } 126254885Sdumbbell r = radeon_gart_table_vram_pin(rdev); 127254885Sdumbbell if (r) 128254885Sdumbbell return r; 129254885Sdumbbell radeon_gart_restore(rdev); 130254885Sdumbbell /* discard memory request outside of configured range */ 131254885Sdumbbell tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; 132254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); 133254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_start); 134254885Sdumbbell tmp = rdev->mc.gtt_end & ~RADEON_GPU_PAGE_MASK; 135254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); 136254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); 137254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); 138254885Sdumbbell table_addr = rdev->gart.table_addr; 139254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_BASE, table_addr); 140254885Sdumbbell /* FIXME: setup default page */ 141254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_start); 142254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0); 143254885Sdumbbell /* Clear error */ 144254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_ERROR, 0); 145254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 146254885Sdumbbell tmp |= RADEON_PCIE_TX_GART_EN; 147254885Sdumbbell tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; 148254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); 149254885Sdumbbell rv370_pcie_gart_tlb_flush(rdev); 150254885Sdumbbell DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 151254885Sdumbbell (unsigned)(rdev->mc.gtt_size >> 20), 152254885Sdumbbell (unsigned long long)table_addr); 153254885Sdumbbell rdev->gart.ready = true; 154254885Sdumbbell return 0; 155254885Sdumbbell} 156254885Sdumbbell 157254885Sdumbbellvoid rv370_pcie_gart_disable(struct radeon_device *rdev) 158254885Sdumbbell{ 159254885Sdumbbell u32 tmp; 160254885Sdumbbell 161254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); 162254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); 163254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); 164254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); 165254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 166254885Sdumbbell tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; 167254885Sdumbbell WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); 168254885Sdumbbell radeon_gart_table_vram_unpin(rdev); 169254885Sdumbbell} 170254885Sdumbbell 171254885Sdumbbellvoid rv370_pcie_gart_fini(struct radeon_device *rdev) 172254885Sdumbbell{ 173254885Sdumbbell radeon_gart_fini(rdev); 174254885Sdumbbell rv370_pcie_gart_disable(rdev); 175254885Sdumbbell radeon_gart_table_vram_free(rdev); 176254885Sdumbbell} 177254885Sdumbbell 178254885Sdumbbellvoid r300_fence_ring_emit(struct radeon_device *rdev, 179254885Sdumbbell struct radeon_fence *fence) 180254885Sdumbbell{ 181254885Sdumbbell struct radeon_ring *ring = &rdev->ring[fence->ring]; 182254885Sdumbbell 183254885Sdumbbell /* Who ever call radeon_fence_emit should call ring_lock and ask 184254885Sdumbbell * for enough space (today caller are ib schedule and buffer move) */ 185254885Sdumbbell /* Write SC register so SC & US assert idle */ 186254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RE_SCISSORS_TL, 0)); 187254885Sdumbbell radeon_ring_write(ring, 0); 188254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RE_SCISSORS_BR, 0)); 189254885Sdumbbell radeon_ring_write(ring, 0); 190254885Sdumbbell /* Flush 3D cache */ 191254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); 192254885Sdumbbell radeon_ring_write(ring, R300_RB3D_DC_FLUSH); 193254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); 194254885Sdumbbell radeon_ring_write(ring, R300_ZC_FLUSH); 195254885Sdumbbell /* Wait until IDLE & CLEAN */ 196254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 197254885Sdumbbell radeon_ring_write(ring, (RADEON_WAIT_3D_IDLECLEAN | 198254885Sdumbbell RADEON_WAIT_2D_IDLECLEAN | 199254885Sdumbbell RADEON_WAIT_DMA_GUI_IDLE)); 200254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); 201254885Sdumbbell radeon_ring_write(ring, rdev->config.r300.hdp_cntl | 202254885Sdumbbell RADEON_HDP_READ_BUFFER_INVALIDATE); 203254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); 204254885Sdumbbell radeon_ring_write(ring, rdev->config.r300.hdp_cntl); 205254885Sdumbbell /* Emit fence sequence & fire IRQ */ 206254885Sdumbbell radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); 207254885Sdumbbell radeon_ring_write(ring, fence->seq); 208254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0)); 209254885Sdumbbell radeon_ring_write(ring, RADEON_SW_INT_FIRE); 210254885Sdumbbell} 211254885Sdumbbell 212254885Sdumbbellvoid r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) 213254885Sdumbbell{ 214254885Sdumbbell unsigned gb_tile_config; 215254885Sdumbbell int r; 216254885Sdumbbell 217254885Sdumbbell /* Sub pixel 1/12 so we can have 4K rendering according to doc */ 218254885Sdumbbell gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); 219254885Sdumbbell switch(rdev->num_gb_pipes) { 220254885Sdumbbell case 2: 221254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_R300; 222254885Sdumbbell break; 223254885Sdumbbell case 3: 224254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_R420_3P; 225254885Sdumbbell break; 226254885Sdumbbell case 4: 227254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_R420; 228254885Sdumbbell break; 229254885Sdumbbell case 1: 230254885Sdumbbell default: 231254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_RV350; 232254885Sdumbbell break; 233254885Sdumbbell } 234254885Sdumbbell 235254885Sdumbbell r = radeon_ring_lock(rdev, ring, 64); 236254885Sdumbbell if (r) { 237254885Sdumbbell return; 238254885Sdumbbell } 239254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_ISYNC_CNTL, 0)); 240254885Sdumbbell radeon_ring_write(ring, 241254885Sdumbbell RADEON_ISYNC_ANY2D_IDLE3D | 242254885Sdumbbell RADEON_ISYNC_ANY3D_IDLE2D | 243254885Sdumbbell RADEON_ISYNC_WAIT_IDLEGUI | 244254885Sdumbbell RADEON_ISYNC_CPSCRATCH_IDLEGUI); 245254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GB_TILE_CONFIG, 0)); 246254885Sdumbbell radeon_ring_write(ring, gb_tile_config); 247254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 248254885Sdumbbell radeon_ring_write(ring, 249254885Sdumbbell RADEON_WAIT_2D_IDLECLEAN | 250254885Sdumbbell RADEON_WAIT_3D_IDLECLEAN); 251254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); 252254885Sdumbbell radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); 253254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GB_SELECT, 0)); 254254885Sdumbbell radeon_ring_write(ring, 0); 255254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GB_ENABLE, 0)); 256254885Sdumbbell radeon_ring_write(ring, 0); 257254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); 258254885Sdumbbell radeon_ring_write(ring, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); 259254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); 260254885Sdumbbell radeon_ring_write(ring, R300_ZC_FLUSH | R300_ZC_FREE); 261254885Sdumbbell radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); 262254885Sdumbbell radeon_ring_write(ring, 263254885Sdumbbell RADEON_WAIT_2D_IDLECLEAN | 264254885Sdumbbell RADEON_WAIT_3D_IDLECLEAN); 265254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GB_AA_CONFIG, 0)); 266254885Sdumbbell radeon_ring_write(ring, 0); 267254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); 268254885Sdumbbell radeon_ring_write(ring, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); 269254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); 270254885Sdumbbell radeon_ring_write(ring, R300_ZC_FLUSH | R300_ZC_FREE); 271254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GB_MSPOS0, 0)); 272254885Sdumbbell radeon_ring_write(ring, 273254885Sdumbbell ((6 << R300_MS_X0_SHIFT) | 274254885Sdumbbell (6 << R300_MS_Y0_SHIFT) | 275254885Sdumbbell (6 << R300_MS_X1_SHIFT) | 276254885Sdumbbell (6 << R300_MS_Y1_SHIFT) | 277254885Sdumbbell (6 << R300_MS_X2_SHIFT) | 278254885Sdumbbell (6 << R300_MS_Y2_SHIFT) | 279254885Sdumbbell (6 << R300_MSBD0_Y_SHIFT) | 280254885Sdumbbell (6 << R300_MSBD0_X_SHIFT))); 281254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GB_MSPOS1, 0)); 282254885Sdumbbell radeon_ring_write(ring, 283254885Sdumbbell ((6 << R300_MS_X3_SHIFT) | 284254885Sdumbbell (6 << R300_MS_Y3_SHIFT) | 285254885Sdumbbell (6 << R300_MS_X4_SHIFT) | 286254885Sdumbbell (6 << R300_MS_Y4_SHIFT) | 287254885Sdumbbell (6 << R300_MS_X5_SHIFT) | 288254885Sdumbbell (6 << R300_MS_Y5_SHIFT) | 289254885Sdumbbell (6 << R300_MSBD1_SHIFT))); 290254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GA_ENHANCE, 0)); 291254885Sdumbbell radeon_ring_write(ring, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); 292254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GA_POLY_MODE, 0)); 293254885Sdumbbell radeon_ring_write(ring, 294254885Sdumbbell R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE); 295254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_GA_ROUND_MODE, 0)); 296254885Sdumbbell radeon_ring_write(ring, 297254885Sdumbbell R300_GEOMETRY_ROUND_NEAREST | 298254885Sdumbbell R300_COLOR_ROUND_NEAREST); 299254885Sdumbbell radeon_ring_unlock_commit(rdev, ring); 300254885Sdumbbell} 301254885Sdumbbell 302254885Sdumbbellstatic void r300_errata(struct radeon_device *rdev) 303254885Sdumbbell{ 304254885Sdumbbell rdev->pll_errata = 0; 305254885Sdumbbell 306254885Sdumbbell if (rdev->family == CHIP_R300 && 307254885Sdumbbell (RREG32(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) { 308254885Sdumbbell rdev->pll_errata |= CHIP_ERRATA_R300_CG; 309254885Sdumbbell } 310254885Sdumbbell} 311254885Sdumbbell 312254885Sdumbbellint r300_mc_wait_for_idle(struct radeon_device *rdev) 313254885Sdumbbell{ 314254885Sdumbbell unsigned i; 315254885Sdumbbell uint32_t tmp; 316254885Sdumbbell 317254885Sdumbbell for (i = 0; i < rdev->usec_timeout; i++) { 318254885Sdumbbell /* read MC_STATUS */ 319254885Sdumbbell tmp = RREG32(RADEON_MC_STATUS); 320254885Sdumbbell if (tmp & R300_MC_IDLE) { 321254885Sdumbbell return 0; 322254885Sdumbbell } 323254885Sdumbbell DRM_UDELAY(1); 324254885Sdumbbell } 325254885Sdumbbell return -1; 326254885Sdumbbell} 327254885Sdumbbell 328254885Sdumbbellstatic void r300_gpu_init(struct radeon_device *rdev) 329254885Sdumbbell{ 330254885Sdumbbell uint32_t gb_tile_config, tmp; 331254885Sdumbbell 332254885Sdumbbell if ((rdev->family == CHIP_R300 && rdev->ddev->pci_device != 0x4144) || 333254885Sdumbbell (rdev->family == CHIP_R350 && rdev->ddev->pci_device != 0x4148)) { 334254885Sdumbbell /* r300,r350 */ 335254885Sdumbbell rdev->num_gb_pipes = 2; 336254885Sdumbbell } else { 337254885Sdumbbell /* rv350,rv370,rv380,r300 AD, r350 AH */ 338254885Sdumbbell rdev->num_gb_pipes = 1; 339254885Sdumbbell } 340254885Sdumbbell rdev->num_z_pipes = 1; 341254885Sdumbbell gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); 342254885Sdumbbell switch (rdev->num_gb_pipes) { 343254885Sdumbbell case 2: 344254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_R300; 345254885Sdumbbell break; 346254885Sdumbbell case 3: 347254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_R420_3P; 348254885Sdumbbell break; 349254885Sdumbbell case 4: 350254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_R420; 351254885Sdumbbell break; 352254885Sdumbbell default: 353254885Sdumbbell case 1: 354254885Sdumbbell gb_tile_config |= R300_PIPE_COUNT_RV350; 355254885Sdumbbell break; 356254885Sdumbbell } 357254885Sdumbbell WREG32(R300_GB_TILE_CONFIG, gb_tile_config); 358254885Sdumbbell 359254885Sdumbbell if (r100_gui_wait_for_idle(rdev)) { 360254885Sdumbbell DRM_ERROR("Failed to wait GUI idle while " 361254885Sdumbbell "programming pipes. Bad things might happen.\n"); 362254885Sdumbbell } 363254885Sdumbbell 364254885Sdumbbell tmp = RREG32(R300_DST_PIPE_CONFIG); 365254885Sdumbbell WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG); 366254885Sdumbbell 367254885Sdumbbell WREG32(R300_RB2D_DSTCACHE_MODE, 368254885Sdumbbell R300_DC_AUTOFLUSH_ENABLE | 369254885Sdumbbell R300_DC_DC_DISABLE_IGNORE_PE); 370254885Sdumbbell 371254885Sdumbbell if (r100_gui_wait_for_idle(rdev)) { 372254885Sdumbbell DRM_ERROR("Failed to wait GUI idle while " 373254885Sdumbbell "programming pipes. Bad things might happen.\n"); 374254885Sdumbbell } 375254885Sdumbbell if (r300_mc_wait_for_idle(rdev)) { 376254885Sdumbbell DRM_ERROR("Failed to wait MC idle while " 377254885Sdumbbell "programming pipes. Bad things might happen.\n"); 378254885Sdumbbell } 379254885Sdumbbell DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n", 380254885Sdumbbell rdev->num_gb_pipes, rdev->num_z_pipes); 381254885Sdumbbell} 382254885Sdumbbell 383254885Sdumbbellint r300_asic_reset(struct radeon_device *rdev) 384254885Sdumbbell{ 385254885Sdumbbell struct r100_mc_save save; 386254885Sdumbbell u32 status, tmp; 387254885Sdumbbell int ret = 0; 388254885Sdumbbell 389254885Sdumbbell status = RREG32(R_000E40_RBBM_STATUS); 390254885Sdumbbell if (!G_000E40_GUI_ACTIVE(status)) { 391254885Sdumbbell return 0; 392254885Sdumbbell } 393254885Sdumbbell r100_mc_stop(rdev, &save); 394254885Sdumbbell status = RREG32(R_000E40_RBBM_STATUS); 395254885Sdumbbell dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 396254885Sdumbbell /* stop CP */ 397254885Sdumbbell WREG32(RADEON_CP_CSQ_CNTL, 0); 398254885Sdumbbell tmp = RREG32(RADEON_CP_RB_CNTL); 399254885Sdumbbell WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); 400254885Sdumbbell WREG32(RADEON_CP_RB_RPTR_WR, 0); 401254885Sdumbbell WREG32(RADEON_CP_RB_WPTR, 0); 402254885Sdumbbell WREG32(RADEON_CP_RB_CNTL, tmp); 403254885Sdumbbell /* save PCI state */ 404255573Sdumbbell pci_save_state(device_get_parent(rdev->dev)); 405254885Sdumbbell /* disable bus mastering */ 406254885Sdumbbell r100_bm_disable(rdev); 407254885Sdumbbell WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | 408254885Sdumbbell S_0000F0_SOFT_RESET_GA(1)); 409254885Sdumbbell RREG32(R_0000F0_RBBM_SOFT_RESET); 410254885Sdumbbell DRM_MDELAY(500); 411254885Sdumbbell WREG32(R_0000F0_RBBM_SOFT_RESET, 0); 412254885Sdumbbell DRM_MDELAY(1); 413254885Sdumbbell status = RREG32(R_000E40_RBBM_STATUS); 414254885Sdumbbell dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 415254885Sdumbbell /* resetting the CP seems to be problematic sometimes it end up 416254885Sdumbbell * hard locking the computer, but it's necessary for successful 417254885Sdumbbell * reset more test & playing is needed on R3XX/R4XX to find a 418254885Sdumbbell * reliable (if any solution) 419254885Sdumbbell */ 420254885Sdumbbell WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); 421254885Sdumbbell RREG32(R_0000F0_RBBM_SOFT_RESET); 422254885Sdumbbell DRM_MDELAY(500); 423254885Sdumbbell WREG32(R_0000F0_RBBM_SOFT_RESET, 0); 424254885Sdumbbell DRM_MDELAY(1); 425254885Sdumbbell status = RREG32(R_000E40_RBBM_STATUS); 426254885Sdumbbell dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 427254885Sdumbbell /* restore PCI & busmastering */ 428255573Sdumbbell pci_restore_state(device_get_parent(rdev->dev)); 429254885Sdumbbell r100_enable_bm(rdev); 430254885Sdumbbell /* Check if GPU is idle */ 431254885Sdumbbell if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { 432254885Sdumbbell dev_err(rdev->dev, "failed to reset GPU\n"); 433254885Sdumbbell ret = -1; 434254885Sdumbbell } else 435254885Sdumbbell dev_info(rdev->dev, "GPU reset succeed\n"); 436254885Sdumbbell r100_mc_resume(rdev, &save); 437254885Sdumbbell return ret; 438254885Sdumbbell} 439254885Sdumbbell 440254885Sdumbbell/* 441254885Sdumbbell * r300,r350,rv350,rv380 VRAM info 442254885Sdumbbell */ 443254885Sdumbbellvoid r300_mc_init(struct radeon_device *rdev) 444254885Sdumbbell{ 445254885Sdumbbell u64 base; 446254885Sdumbbell u32 tmp; 447254885Sdumbbell 448254885Sdumbbell /* DDR for all card after R300 & IGP */ 449254885Sdumbbell rdev->mc.vram_is_ddr = true; 450254885Sdumbbell tmp = RREG32(RADEON_MEM_CNTL); 451254885Sdumbbell tmp &= R300_MEM_NUM_CHANNELS_MASK; 452254885Sdumbbell switch (tmp) { 453254885Sdumbbell case 0: rdev->mc.vram_width = 64; break; 454254885Sdumbbell case 1: rdev->mc.vram_width = 128; break; 455254885Sdumbbell case 2: rdev->mc.vram_width = 256; break; 456254885Sdumbbell default: rdev->mc.vram_width = 128; break; 457254885Sdumbbell } 458254885Sdumbbell r100_vram_init_sizes(rdev); 459254885Sdumbbell base = rdev->mc.aper_base; 460254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) 461254885Sdumbbell base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; 462254885Sdumbbell radeon_vram_location(rdev, &rdev->mc, base); 463254885Sdumbbell rdev->mc.gtt_base_align = 0; 464254885Sdumbbell if (!(rdev->flags & RADEON_IS_AGP)) 465254885Sdumbbell radeon_gtt_location(rdev, &rdev->mc); 466254885Sdumbbell radeon_update_bandwidth_info(rdev); 467254885Sdumbbell} 468254885Sdumbbell 469254885Sdumbbellvoid rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) 470254885Sdumbbell{ 471254885Sdumbbell uint32_t link_width_cntl, mask; 472254885Sdumbbell 473254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) 474254885Sdumbbell return; 475254885Sdumbbell 476254885Sdumbbell if (!(rdev->flags & RADEON_IS_PCIE)) 477254885Sdumbbell return; 478254885Sdumbbell 479254885Sdumbbell /* FIXME wait for idle */ 480254885Sdumbbell 481254885Sdumbbell switch (lanes) { 482254885Sdumbbell case 0: 483254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X0; 484254885Sdumbbell break; 485254885Sdumbbell case 1: 486254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X1; 487254885Sdumbbell break; 488254885Sdumbbell case 2: 489254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X2; 490254885Sdumbbell break; 491254885Sdumbbell case 4: 492254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X4; 493254885Sdumbbell break; 494254885Sdumbbell case 8: 495254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X8; 496254885Sdumbbell break; 497254885Sdumbbell case 12: 498254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X12; 499254885Sdumbbell break; 500254885Sdumbbell case 16: 501254885Sdumbbell default: 502254885Sdumbbell mask = RADEON_PCIE_LC_LINK_WIDTH_X16; 503254885Sdumbbell break; 504254885Sdumbbell } 505254885Sdumbbell 506254885Sdumbbell link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); 507254885Sdumbbell 508254885Sdumbbell if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == 509254885Sdumbbell (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) 510254885Sdumbbell return; 511254885Sdumbbell 512254885Sdumbbell link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | 513254885Sdumbbell RADEON_PCIE_LC_RECONFIG_NOW | 514254885Sdumbbell RADEON_PCIE_LC_RECONFIG_LATER | 515254885Sdumbbell RADEON_PCIE_LC_SHORT_RECONFIG_EN); 516254885Sdumbbell link_width_cntl |= mask; 517254885Sdumbbell WREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); 518254885Sdumbbell WREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | 519254885Sdumbbell RADEON_PCIE_LC_RECONFIG_NOW)); 520254885Sdumbbell 521254885Sdumbbell /* wait for lane set to complete */ 522254885Sdumbbell link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); 523254885Sdumbbell while (link_width_cntl == 0xffffffff) 524254885Sdumbbell link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); 525254885Sdumbbell 526254885Sdumbbell} 527254885Sdumbbell 528254885Sdumbbellint rv370_get_pcie_lanes(struct radeon_device *rdev) 529254885Sdumbbell{ 530254885Sdumbbell u32 link_width_cntl; 531254885Sdumbbell 532254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) 533254885Sdumbbell return 0; 534254885Sdumbbell 535254885Sdumbbell if (!(rdev->flags & RADEON_IS_PCIE)) 536254885Sdumbbell return 0; 537254885Sdumbbell 538254885Sdumbbell /* FIXME wait for idle */ 539254885Sdumbbell 540254885Sdumbbell link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); 541254885Sdumbbell 542254885Sdumbbell switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { 543254885Sdumbbell case RADEON_PCIE_LC_LINK_WIDTH_X0: 544254885Sdumbbell return 0; 545254885Sdumbbell case RADEON_PCIE_LC_LINK_WIDTH_X1: 546254885Sdumbbell return 1; 547254885Sdumbbell case RADEON_PCIE_LC_LINK_WIDTH_X2: 548254885Sdumbbell return 2; 549254885Sdumbbell case RADEON_PCIE_LC_LINK_WIDTH_X4: 550254885Sdumbbell return 4; 551254885Sdumbbell case RADEON_PCIE_LC_LINK_WIDTH_X8: 552254885Sdumbbell return 8; 553254885Sdumbbell case RADEON_PCIE_LC_LINK_WIDTH_X16: 554254885Sdumbbell default: 555254885Sdumbbell return 16; 556254885Sdumbbell } 557254885Sdumbbell} 558254885Sdumbbell 559254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 560254885Sdumbbellstatic int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data) 561254885Sdumbbell{ 562254885Sdumbbell struct drm_info_node *node = (struct drm_info_node *) m->private; 563254885Sdumbbell struct drm_device *dev = node->minor->dev; 564254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 565254885Sdumbbell uint32_t tmp; 566254885Sdumbbell 567254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 568254885Sdumbbell seq_printf(m, "PCIE_TX_GART_CNTL 0x%08x\n", tmp); 569254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_BASE); 570254885Sdumbbell seq_printf(m, "PCIE_TX_GART_BASE 0x%08x\n", tmp); 571254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_START_LO); 572254885Sdumbbell seq_printf(m, "PCIE_TX_GART_START_LO 0x%08x\n", tmp); 573254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_START_HI); 574254885Sdumbbell seq_printf(m, "PCIE_TX_GART_START_HI 0x%08x\n", tmp); 575254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_END_LO); 576254885Sdumbbell seq_printf(m, "PCIE_TX_GART_END_LO 0x%08x\n", tmp); 577254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_END_HI); 578254885Sdumbbell seq_printf(m, "PCIE_TX_GART_END_HI 0x%08x\n", tmp); 579254885Sdumbbell tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_ERROR); 580254885Sdumbbell seq_printf(m, "PCIE_TX_GART_ERROR 0x%08x\n", tmp); 581254885Sdumbbell return 0; 582254885Sdumbbell} 583254885Sdumbbell 584254885Sdumbbellstatic struct drm_info_list rv370_pcie_gart_info_list[] = { 585254885Sdumbbell {"rv370_pcie_gart_info", rv370_debugfs_pcie_gart_info, 0, NULL}, 586254885Sdumbbell}; 587254885Sdumbbell#endif 588254885Sdumbbell 589254885Sdumbbellstatic int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev) 590254885Sdumbbell{ 591254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 592254885Sdumbbell return radeon_debugfs_add_files(rdev, rv370_pcie_gart_info_list, 1); 593254885Sdumbbell#else 594254885Sdumbbell return 0; 595254885Sdumbbell#endif 596254885Sdumbbell} 597254885Sdumbbell 598254885Sdumbbellstatic int r300_packet0_check(struct radeon_cs_parser *p, 599254885Sdumbbell struct radeon_cs_packet *pkt, 600254885Sdumbbell unsigned idx, unsigned reg) 601254885Sdumbbell{ 602254885Sdumbbell struct radeon_cs_reloc *reloc; 603254885Sdumbbell struct r100_cs_track *track; 604254885Sdumbbell volatile uint32_t *ib; 605254885Sdumbbell uint32_t tmp, tile_flags = 0; 606254885Sdumbbell unsigned i; 607254885Sdumbbell int r; 608254885Sdumbbell u32 idx_value; 609254885Sdumbbell 610254885Sdumbbell ib = p->ib.ptr; 611254885Sdumbbell track = (struct r100_cs_track *)p->track; 612254885Sdumbbell idx_value = radeon_get_ib_value(p, idx); 613254885Sdumbbell 614254885Sdumbbell switch(reg) { 615254885Sdumbbell case AVIVO_D1MODE_VLINE_START_END: 616254885Sdumbbell case RADEON_CRTC_GUI_TRIG_VLINE: 617254885Sdumbbell r = r100_cs_packet_parse_vline(p); 618254885Sdumbbell if (r) { 619254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 620254885Sdumbbell idx, reg); 621254885Sdumbbell r100_cs_dump_packet(p, pkt); 622254885Sdumbbell return r; 623254885Sdumbbell } 624254885Sdumbbell break; 625254885Sdumbbell case RADEON_DST_PITCH_OFFSET: 626254885Sdumbbell case RADEON_SRC_PITCH_OFFSET: 627254885Sdumbbell r = r100_reloc_pitch_offset(p, pkt, idx, reg); 628254885Sdumbbell if (r) 629254885Sdumbbell return r; 630254885Sdumbbell break; 631254885Sdumbbell case R300_RB3D_COLOROFFSET0: 632254885Sdumbbell case R300_RB3D_COLOROFFSET1: 633254885Sdumbbell case R300_RB3D_COLOROFFSET2: 634254885Sdumbbell case R300_RB3D_COLOROFFSET3: 635254885Sdumbbell i = (reg - R300_RB3D_COLOROFFSET0) >> 2; 636254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 637254885Sdumbbell if (r) { 638254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 639254885Sdumbbell idx, reg); 640254885Sdumbbell r100_cs_dump_packet(p, pkt); 641254885Sdumbbell return r; 642254885Sdumbbell } 643254885Sdumbbell track->cb[i].robj = reloc->robj; 644254885Sdumbbell track->cb[i].offset = idx_value; 645254885Sdumbbell track->cb_dirty = true; 646254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 647254885Sdumbbell break; 648254885Sdumbbell case R300_ZB_DEPTHOFFSET: 649254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 650254885Sdumbbell if (r) { 651254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 652254885Sdumbbell idx, reg); 653254885Sdumbbell r100_cs_dump_packet(p, pkt); 654254885Sdumbbell return r; 655254885Sdumbbell } 656254885Sdumbbell track->zb.robj = reloc->robj; 657254885Sdumbbell track->zb.offset = idx_value; 658254885Sdumbbell track->zb_dirty = true; 659254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 660254885Sdumbbell break; 661254885Sdumbbell case R300_TX_OFFSET_0: 662254885Sdumbbell case R300_TX_OFFSET_0+4: 663254885Sdumbbell case R300_TX_OFFSET_0+8: 664254885Sdumbbell case R300_TX_OFFSET_0+12: 665254885Sdumbbell case R300_TX_OFFSET_0+16: 666254885Sdumbbell case R300_TX_OFFSET_0+20: 667254885Sdumbbell case R300_TX_OFFSET_0+24: 668254885Sdumbbell case R300_TX_OFFSET_0+28: 669254885Sdumbbell case R300_TX_OFFSET_0+32: 670254885Sdumbbell case R300_TX_OFFSET_0+36: 671254885Sdumbbell case R300_TX_OFFSET_0+40: 672254885Sdumbbell case R300_TX_OFFSET_0+44: 673254885Sdumbbell case R300_TX_OFFSET_0+48: 674254885Sdumbbell case R300_TX_OFFSET_0+52: 675254885Sdumbbell case R300_TX_OFFSET_0+56: 676254885Sdumbbell case R300_TX_OFFSET_0+60: 677254885Sdumbbell i = (reg - R300_TX_OFFSET_0) >> 2; 678254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 679254885Sdumbbell if (r) { 680254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 681254885Sdumbbell idx, reg); 682254885Sdumbbell r100_cs_dump_packet(p, pkt); 683254885Sdumbbell return r; 684254885Sdumbbell } 685254885Sdumbbell 686254885Sdumbbell if (p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) { 687254885Sdumbbell ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ 688254885Sdumbbell ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); 689254885Sdumbbell } else { 690254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 691254885Sdumbbell tile_flags |= R300_TXO_MACRO_TILE; 692254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 693254885Sdumbbell tile_flags |= R300_TXO_MICRO_TILE; 694254885Sdumbbell else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) 695254885Sdumbbell tile_flags |= R300_TXO_MICRO_TILE_SQUARE; 696254885Sdumbbell 697254885Sdumbbell tmp = idx_value + ((u32)reloc->lobj.gpu_offset); 698254885Sdumbbell tmp |= tile_flags; 699254885Sdumbbell ib[idx] = tmp; 700254885Sdumbbell } 701254885Sdumbbell track->textures[i].robj = reloc->robj; 702254885Sdumbbell track->tex_dirty = true; 703254885Sdumbbell break; 704254885Sdumbbell /* Tracked registers */ 705254885Sdumbbell case 0x2084: 706254885Sdumbbell /* VAP_VF_CNTL */ 707254885Sdumbbell track->vap_vf_cntl = idx_value; 708254885Sdumbbell break; 709254885Sdumbbell case 0x20B4: 710254885Sdumbbell /* VAP_VTX_SIZE */ 711254885Sdumbbell track->vtx_size = idx_value & 0x7F; 712254885Sdumbbell break; 713254885Sdumbbell case 0x2134: 714254885Sdumbbell /* VAP_VF_MAX_VTX_INDX */ 715254885Sdumbbell track->max_indx = idx_value & 0x00FFFFFFUL; 716254885Sdumbbell break; 717254885Sdumbbell case 0x2088: 718254885Sdumbbell /* VAP_ALT_NUM_VERTICES - only valid on r500 */ 719254885Sdumbbell if (p->rdev->family < CHIP_RV515) 720254885Sdumbbell goto fail; 721254885Sdumbbell track->vap_alt_nverts = idx_value & 0xFFFFFF; 722254885Sdumbbell break; 723254885Sdumbbell case 0x43E4: 724254885Sdumbbell /* SC_SCISSOR1 */ 725254885Sdumbbell track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; 726254885Sdumbbell if (p->rdev->family < CHIP_RV515) { 727254885Sdumbbell track->maxy -= 1440; 728254885Sdumbbell } 729254885Sdumbbell track->cb_dirty = true; 730254885Sdumbbell track->zb_dirty = true; 731254885Sdumbbell break; 732254885Sdumbbell case 0x4E00: 733254885Sdumbbell /* RB3D_CCTL */ 734254885Sdumbbell if ((idx_value & (1 << 10)) && /* CMASK_ENABLE */ 735254885Sdumbbell p->rdev->cmask_filp != p->filp) { 736254885Sdumbbell DRM_ERROR("Invalid RB3D_CCTL: Cannot enable CMASK.\n"); 737254885Sdumbbell return -EINVAL; 738254885Sdumbbell } 739254885Sdumbbell track->num_cb = ((idx_value >> 5) & 0x3) + 1; 740254885Sdumbbell track->cb_dirty = true; 741254885Sdumbbell break; 742254885Sdumbbell case 0x4E38: 743254885Sdumbbell case 0x4E3C: 744254885Sdumbbell case 0x4E40: 745254885Sdumbbell case 0x4E44: 746254885Sdumbbell /* RB3D_COLORPITCH0 */ 747254885Sdumbbell /* RB3D_COLORPITCH1 */ 748254885Sdumbbell /* RB3D_COLORPITCH2 */ 749254885Sdumbbell /* RB3D_COLORPITCH3 */ 750254885Sdumbbell if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 751254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 752254885Sdumbbell if (r) { 753254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 754254885Sdumbbell idx, reg); 755254885Sdumbbell r100_cs_dump_packet(p, pkt); 756254885Sdumbbell return r; 757254885Sdumbbell } 758254885Sdumbbell 759254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 760254885Sdumbbell tile_flags |= R300_COLOR_TILE_ENABLE; 761254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 762254885Sdumbbell tile_flags |= R300_COLOR_MICROTILE_ENABLE; 763254885Sdumbbell else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) 764254885Sdumbbell tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; 765254885Sdumbbell 766254885Sdumbbell tmp = idx_value & ~(0x7 << 16); 767254885Sdumbbell tmp |= tile_flags; 768254885Sdumbbell ib[idx] = tmp; 769254885Sdumbbell } 770254885Sdumbbell i = (reg - 0x4E38) >> 2; 771254885Sdumbbell track->cb[i].pitch = idx_value & 0x3FFE; 772254885Sdumbbell switch (((idx_value >> 21) & 0xF)) { 773254885Sdumbbell case 9: 774254885Sdumbbell case 11: 775254885Sdumbbell case 12: 776254885Sdumbbell track->cb[i].cpp = 1; 777254885Sdumbbell break; 778254885Sdumbbell case 3: 779254885Sdumbbell case 4: 780254885Sdumbbell case 13: 781254885Sdumbbell case 15: 782254885Sdumbbell track->cb[i].cpp = 2; 783254885Sdumbbell break; 784254885Sdumbbell case 5: 785254885Sdumbbell if (p->rdev->family < CHIP_RV515) { 786254885Sdumbbell DRM_ERROR("Invalid color buffer format (%d)!\n", 787254885Sdumbbell ((idx_value >> 21) & 0xF)); 788254885Sdumbbell return -EINVAL; 789254885Sdumbbell } 790254885Sdumbbell /* Pass through. */ 791254885Sdumbbell case 6: 792254885Sdumbbell track->cb[i].cpp = 4; 793254885Sdumbbell break; 794254885Sdumbbell case 10: 795254885Sdumbbell track->cb[i].cpp = 8; 796254885Sdumbbell break; 797254885Sdumbbell case 7: 798254885Sdumbbell track->cb[i].cpp = 16; 799254885Sdumbbell break; 800254885Sdumbbell default: 801254885Sdumbbell DRM_ERROR("Invalid color buffer format (%d) !\n", 802254885Sdumbbell ((idx_value >> 21) & 0xF)); 803254885Sdumbbell return -EINVAL; 804254885Sdumbbell } 805254885Sdumbbell track->cb_dirty = true; 806254885Sdumbbell break; 807254885Sdumbbell case 0x4F00: 808254885Sdumbbell /* ZB_CNTL */ 809254885Sdumbbell if (idx_value & 2) { 810254885Sdumbbell track->z_enabled = true; 811254885Sdumbbell } else { 812254885Sdumbbell track->z_enabled = false; 813254885Sdumbbell } 814254885Sdumbbell track->zb_dirty = true; 815254885Sdumbbell break; 816254885Sdumbbell case 0x4F10: 817254885Sdumbbell /* ZB_FORMAT */ 818254885Sdumbbell switch ((idx_value & 0xF)) { 819254885Sdumbbell case 0: 820254885Sdumbbell case 1: 821254885Sdumbbell track->zb.cpp = 2; 822254885Sdumbbell break; 823254885Sdumbbell case 2: 824254885Sdumbbell track->zb.cpp = 4; 825254885Sdumbbell break; 826254885Sdumbbell default: 827254885Sdumbbell DRM_ERROR("Invalid z buffer format (%d) !\n", 828254885Sdumbbell (idx_value & 0xF)); 829254885Sdumbbell return -EINVAL; 830254885Sdumbbell } 831254885Sdumbbell track->zb_dirty = true; 832254885Sdumbbell break; 833254885Sdumbbell case 0x4F24: 834254885Sdumbbell /* ZB_DEPTHPITCH */ 835254885Sdumbbell if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 836254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 837254885Sdumbbell if (r) { 838254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 839254885Sdumbbell idx, reg); 840254885Sdumbbell r100_cs_dump_packet(p, pkt); 841254885Sdumbbell return r; 842254885Sdumbbell } 843254885Sdumbbell 844254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 845254885Sdumbbell tile_flags |= R300_DEPTHMACROTILE_ENABLE; 846254885Sdumbbell if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 847254885Sdumbbell tile_flags |= R300_DEPTHMICROTILE_TILED; 848254885Sdumbbell else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) 849254885Sdumbbell tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; 850254885Sdumbbell 851254885Sdumbbell tmp = idx_value & ~(0x7 << 16); 852254885Sdumbbell tmp |= tile_flags; 853254885Sdumbbell ib[idx] = tmp; 854254885Sdumbbell } 855254885Sdumbbell track->zb.pitch = idx_value & 0x3FFC; 856254885Sdumbbell track->zb_dirty = true; 857254885Sdumbbell break; 858254885Sdumbbell case 0x4104: 859254885Sdumbbell /* TX_ENABLE */ 860254885Sdumbbell for (i = 0; i < 16; i++) { 861254885Sdumbbell bool enabled; 862254885Sdumbbell 863254885Sdumbbell enabled = !!(idx_value & (1 << i)); 864254885Sdumbbell track->textures[i].enabled = enabled; 865254885Sdumbbell } 866254885Sdumbbell track->tex_dirty = true; 867254885Sdumbbell break; 868254885Sdumbbell case 0x44C0: 869254885Sdumbbell case 0x44C4: 870254885Sdumbbell case 0x44C8: 871254885Sdumbbell case 0x44CC: 872254885Sdumbbell case 0x44D0: 873254885Sdumbbell case 0x44D4: 874254885Sdumbbell case 0x44D8: 875254885Sdumbbell case 0x44DC: 876254885Sdumbbell case 0x44E0: 877254885Sdumbbell case 0x44E4: 878254885Sdumbbell case 0x44E8: 879254885Sdumbbell case 0x44EC: 880254885Sdumbbell case 0x44F0: 881254885Sdumbbell case 0x44F4: 882254885Sdumbbell case 0x44F8: 883254885Sdumbbell case 0x44FC: 884254885Sdumbbell /* TX_FORMAT1_[0-15] */ 885254885Sdumbbell i = (reg - 0x44C0) >> 2; 886254885Sdumbbell tmp = (idx_value >> 25) & 0x3; 887254885Sdumbbell track->textures[i].tex_coord_type = tmp; 888254885Sdumbbell switch ((idx_value & 0x1F)) { 889254885Sdumbbell case R300_TX_FORMAT_X8: 890254885Sdumbbell case R300_TX_FORMAT_Y4X4: 891254885Sdumbbell case R300_TX_FORMAT_Z3Y3X2: 892254885Sdumbbell track->textures[i].cpp = 1; 893254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 894254885Sdumbbell break; 895254885Sdumbbell case R300_TX_FORMAT_X16: 896254885Sdumbbell case R300_TX_FORMAT_FL_I16: 897254885Sdumbbell case R300_TX_FORMAT_Y8X8: 898254885Sdumbbell case R300_TX_FORMAT_Z5Y6X5: 899254885Sdumbbell case R300_TX_FORMAT_Z6Y5X5: 900254885Sdumbbell case R300_TX_FORMAT_W4Z4Y4X4: 901254885Sdumbbell case R300_TX_FORMAT_W1Z5Y5X5: 902254885Sdumbbell case R300_TX_FORMAT_D3DMFT_CxV8U8: 903254885Sdumbbell case R300_TX_FORMAT_B8G8_B8G8: 904254885Sdumbbell case R300_TX_FORMAT_G8R8_G8B8: 905254885Sdumbbell track->textures[i].cpp = 2; 906254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 907254885Sdumbbell break; 908254885Sdumbbell case R300_TX_FORMAT_Y16X16: 909254885Sdumbbell case R300_TX_FORMAT_FL_I16A16: 910254885Sdumbbell case R300_TX_FORMAT_Z11Y11X10: 911254885Sdumbbell case R300_TX_FORMAT_Z10Y11X11: 912254885Sdumbbell case R300_TX_FORMAT_W8Z8Y8X8: 913254885Sdumbbell case R300_TX_FORMAT_W2Z10Y10X10: 914254885Sdumbbell case 0x17: 915254885Sdumbbell case R300_TX_FORMAT_FL_I32: 916254885Sdumbbell case 0x1e: 917254885Sdumbbell track->textures[i].cpp = 4; 918254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 919254885Sdumbbell break; 920254885Sdumbbell case R300_TX_FORMAT_W16Z16Y16X16: 921254885Sdumbbell case R300_TX_FORMAT_FL_R16G16B16A16: 922254885Sdumbbell case R300_TX_FORMAT_FL_I32A32: 923254885Sdumbbell track->textures[i].cpp = 8; 924254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 925254885Sdumbbell break; 926254885Sdumbbell case R300_TX_FORMAT_FL_R32G32B32A32: 927254885Sdumbbell track->textures[i].cpp = 16; 928254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_NONE; 929254885Sdumbbell break; 930254885Sdumbbell case R300_TX_FORMAT_DXT1: 931254885Sdumbbell track->textures[i].cpp = 1; 932254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_DXT1; 933254885Sdumbbell break; 934254885Sdumbbell case R300_TX_FORMAT_ATI2N: 935254885Sdumbbell if (p->rdev->family < CHIP_R420) { 936254885Sdumbbell DRM_ERROR("Invalid texture format %u\n", 937254885Sdumbbell (idx_value & 0x1F)); 938254885Sdumbbell return -EINVAL; 939254885Sdumbbell } 940254885Sdumbbell /* The same rules apply as for DXT3/5. */ 941254885Sdumbbell /* Pass through. */ 942254885Sdumbbell case R300_TX_FORMAT_DXT3: 943254885Sdumbbell case R300_TX_FORMAT_DXT5: 944254885Sdumbbell track->textures[i].cpp = 1; 945254885Sdumbbell track->textures[i].compress_format = R100_TRACK_COMP_DXT35; 946254885Sdumbbell break; 947254885Sdumbbell default: 948254885Sdumbbell DRM_ERROR("Invalid texture format %u\n", 949254885Sdumbbell (idx_value & 0x1F)); 950254885Sdumbbell return -EINVAL; 951254885Sdumbbell } 952254885Sdumbbell track->tex_dirty = true; 953254885Sdumbbell break; 954254885Sdumbbell case 0x4400: 955254885Sdumbbell case 0x4404: 956254885Sdumbbell case 0x4408: 957254885Sdumbbell case 0x440C: 958254885Sdumbbell case 0x4410: 959254885Sdumbbell case 0x4414: 960254885Sdumbbell case 0x4418: 961254885Sdumbbell case 0x441C: 962254885Sdumbbell case 0x4420: 963254885Sdumbbell case 0x4424: 964254885Sdumbbell case 0x4428: 965254885Sdumbbell case 0x442C: 966254885Sdumbbell case 0x4430: 967254885Sdumbbell case 0x4434: 968254885Sdumbbell case 0x4438: 969254885Sdumbbell case 0x443C: 970254885Sdumbbell /* TX_FILTER0_[0-15] */ 971254885Sdumbbell i = (reg - 0x4400) >> 2; 972254885Sdumbbell tmp = idx_value & 0x7; 973254885Sdumbbell if (tmp == 2 || tmp == 4 || tmp == 6) { 974254885Sdumbbell track->textures[i].roundup_w = false; 975254885Sdumbbell } 976254885Sdumbbell tmp = (idx_value >> 3) & 0x7; 977254885Sdumbbell if (tmp == 2 || tmp == 4 || tmp == 6) { 978254885Sdumbbell track->textures[i].roundup_h = false; 979254885Sdumbbell } 980254885Sdumbbell track->tex_dirty = true; 981254885Sdumbbell break; 982254885Sdumbbell case 0x4500: 983254885Sdumbbell case 0x4504: 984254885Sdumbbell case 0x4508: 985254885Sdumbbell case 0x450C: 986254885Sdumbbell case 0x4510: 987254885Sdumbbell case 0x4514: 988254885Sdumbbell case 0x4518: 989254885Sdumbbell case 0x451C: 990254885Sdumbbell case 0x4520: 991254885Sdumbbell case 0x4524: 992254885Sdumbbell case 0x4528: 993254885Sdumbbell case 0x452C: 994254885Sdumbbell case 0x4530: 995254885Sdumbbell case 0x4534: 996254885Sdumbbell case 0x4538: 997254885Sdumbbell case 0x453C: 998254885Sdumbbell /* TX_FORMAT2_[0-15] */ 999254885Sdumbbell i = (reg - 0x4500) >> 2; 1000254885Sdumbbell tmp = idx_value & 0x3FFF; 1001254885Sdumbbell track->textures[i].pitch = tmp + 1; 1002254885Sdumbbell if (p->rdev->family >= CHIP_RV515) { 1003254885Sdumbbell tmp = ((idx_value >> 15) & 1) << 11; 1004254885Sdumbbell track->textures[i].width_11 = tmp; 1005254885Sdumbbell tmp = ((idx_value >> 16) & 1) << 11; 1006254885Sdumbbell track->textures[i].height_11 = tmp; 1007254885Sdumbbell 1008254885Sdumbbell /* ATI1N */ 1009254885Sdumbbell if (idx_value & (1 << 14)) { 1010254885Sdumbbell /* The same rules apply as for DXT1. */ 1011254885Sdumbbell track->textures[i].compress_format = 1012254885Sdumbbell R100_TRACK_COMP_DXT1; 1013254885Sdumbbell } 1014254885Sdumbbell } else if (idx_value & (1 << 14)) { 1015254885Sdumbbell DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); 1016254885Sdumbbell return -EINVAL; 1017254885Sdumbbell } 1018254885Sdumbbell track->tex_dirty = true; 1019254885Sdumbbell break; 1020254885Sdumbbell case 0x4480: 1021254885Sdumbbell case 0x4484: 1022254885Sdumbbell case 0x4488: 1023254885Sdumbbell case 0x448C: 1024254885Sdumbbell case 0x4490: 1025254885Sdumbbell case 0x4494: 1026254885Sdumbbell case 0x4498: 1027254885Sdumbbell case 0x449C: 1028254885Sdumbbell case 0x44A0: 1029254885Sdumbbell case 0x44A4: 1030254885Sdumbbell case 0x44A8: 1031254885Sdumbbell case 0x44AC: 1032254885Sdumbbell case 0x44B0: 1033254885Sdumbbell case 0x44B4: 1034254885Sdumbbell case 0x44B8: 1035254885Sdumbbell case 0x44BC: 1036254885Sdumbbell /* TX_FORMAT0_[0-15] */ 1037254885Sdumbbell i = (reg - 0x4480) >> 2; 1038254885Sdumbbell tmp = idx_value & 0x7FF; 1039254885Sdumbbell track->textures[i].width = tmp + 1; 1040254885Sdumbbell tmp = (idx_value >> 11) & 0x7FF; 1041254885Sdumbbell track->textures[i].height = tmp + 1; 1042254885Sdumbbell tmp = (idx_value >> 26) & 0xF; 1043254885Sdumbbell track->textures[i].num_levels = tmp; 1044261455Seadler tmp = idx_value & (1U << 31); 1045254885Sdumbbell track->textures[i].use_pitch = !!tmp; 1046254885Sdumbbell tmp = (idx_value >> 22) & 0xF; 1047254885Sdumbbell track->textures[i].txdepth = tmp; 1048254885Sdumbbell track->tex_dirty = true; 1049254885Sdumbbell break; 1050254885Sdumbbell case R300_ZB_ZPASS_ADDR: 1051254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 1052254885Sdumbbell if (r) { 1053254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1054254885Sdumbbell idx, reg); 1055254885Sdumbbell r100_cs_dump_packet(p, pkt); 1056254885Sdumbbell return r; 1057254885Sdumbbell } 1058254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 1059254885Sdumbbell break; 1060254885Sdumbbell case 0x4e0c: 1061254885Sdumbbell /* RB3D_COLOR_CHANNEL_MASK */ 1062254885Sdumbbell track->color_channel_mask = idx_value; 1063254885Sdumbbell track->cb_dirty = true; 1064254885Sdumbbell break; 1065254885Sdumbbell case 0x43a4: 1066254885Sdumbbell /* SC_HYPERZ_EN */ 1067254885Sdumbbell /* r300c emits this register - we need to disable hyperz for it 1068254885Sdumbbell * without complaining */ 1069254885Sdumbbell if (p->rdev->hyperz_filp != p->filp) { 1070254885Sdumbbell if (idx_value & 0x1) 1071254885Sdumbbell ib[idx] = idx_value & ~1; 1072254885Sdumbbell } 1073254885Sdumbbell break; 1074254885Sdumbbell case 0x4f1c: 1075254885Sdumbbell /* ZB_BW_CNTL */ 1076254885Sdumbbell track->zb_cb_clear = !!(idx_value & (1 << 5)); 1077254885Sdumbbell track->cb_dirty = true; 1078254885Sdumbbell track->zb_dirty = true; 1079254885Sdumbbell if (p->rdev->hyperz_filp != p->filp) { 1080254885Sdumbbell if (idx_value & (R300_HIZ_ENABLE | 1081254885Sdumbbell R300_RD_COMP_ENABLE | 1082254885Sdumbbell R300_WR_COMP_ENABLE | 1083254885Sdumbbell R300_FAST_FILL_ENABLE)) 1084254885Sdumbbell goto fail; 1085254885Sdumbbell } 1086254885Sdumbbell break; 1087254885Sdumbbell case 0x4e04: 1088254885Sdumbbell /* RB3D_BLENDCNTL */ 1089254885Sdumbbell track->blend_read_enable = !!(idx_value & (1 << 2)); 1090254885Sdumbbell track->cb_dirty = true; 1091254885Sdumbbell break; 1092254885Sdumbbell case R300_RB3D_AARESOLVE_OFFSET: 1093254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 1094254885Sdumbbell if (r) { 1095254885Sdumbbell DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1096254885Sdumbbell idx, reg); 1097254885Sdumbbell r100_cs_dump_packet(p, pkt); 1098254885Sdumbbell return r; 1099254885Sdumbbell } 1100254885Sdumbbell track->aa.robj = reloc->robj; 1101254885Sdumbbell track->aa.offset = idx_value; 1102254885Sdumbbell track->aa_dirty = true; 1103254885Sdumbbell ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); 1104254885Sdumbbell break; 1105254885Sdumbbell case R300_RB3D_AARESOLVE_PITCH: 1106254885Sdumbbell track->aa.pitch = idx_value & 0x3FFE; 1107254885Sdumbbell track->aa_dirty = true; 1108254885Sdumbbell break; 1109254885Sdumbbell case R300_RB3D_AARESOLVE_CTL: 1110254885Sdumbbell track->aaresolve = idx_value & 0x1; 1111254885Sdumbbell track->aa_dirty = true; 1112254885Sdumbbell break; 1113254885Sdumbbell case 0x4f30: /* ZB_MASK_OFFSET */ 1114254885Sdumbbell case 0x4f34: /* ZB_ZMASK_PITCH */ 1115254885Sdumbbell case 0x4f44: /* ZB_HIZ_OFFSET */ 1116254885Sdumbbell case 0x4f54: /* ZB_HIZ_PITCH */ 1117254885Sdumbbell if (idx_value && (p->rdev->hyperz_filp != p->filp)) 1118254885Sdumbbell goto fail; 1119254885Sdumbbell break; 1120254885Sdumbbell case 0x4028: 1121254885Sdumbbell if (idx_value && (p->rdev->hyperz_filp != p->filp)) 1122254885Sdumbbell goto fail; 1123254885Sdumbbell /* GB_Z_PEQ_CONFIG */ 1124254885Sdumbbell if (p->rdev->family >= CHIP_RV350) 1125254885Sdumbbell break; 1126254885Sdumbbell goto fail; 1127254885Sdumbbell break; 1128254885Sdumbbell case 0x4be8: 1129254885Sdumbbell /* valid register only on RV530 */ 1130254885Sdumbbell if (p->rdev->family == CHIP_RV530) 1131254885Sdumbbell break; 1132254885Sdumbbell /* fallthrough do not move */ 1133254885Sdumbbell default: 1134254885Sdumbbell goto fail; 1135254885Sdumbbell } 1136254885Sdumbbell return 0; 1137254885Sdumbbellfail: 1138254885Sdumbbell DRM_ERROR("Forbidden register 0x%04X in cs at %d (val=%08x)\n", 1139254885Sdumbbell reg, idx, idx_value); 1140254885Sdumbbell return -EINVAL; 1141254885Sdumbbell} 1142254885Sdumbbell 1143254885Sdumbbellstatic int r300_packet3_check(struct radeon_cs_parser *p, 1144254885Sdumbbell struct radeon_cs_packet *pkt) 1145254885Sdumbbell{ 1146254885Sdumbbell struct radeon_cs_reloc *reloc; 1147254885Sdumbbell struct r100_cs_track *track; 1148254885Sdumbbell volatile uint32_t *ib; 1149254885Sdumbbell unsigned idx; 1150254885Sdumbbell int r; 1151254885Sdumbbell 1152254885Sdumbbell ib = p->ib.ptr; 1153254885Sdumbbell idx = pkt->idx + 1; 1154254885Sdumbbell track = (struct r100_cs_track *)p->track; 1155254885Sdumbbell switch(pkt->opcode) { 1156254885Sdumbbell case PACKET3_3D_LOAD_VBPNTR: 1157254885Sdumbbell r = r100_packet3_load_vbpntr(p, pkt, idx); 1158254885Sdumbbell if (r) 1159254885Sdumbbell return r; 1160254885Sdumbbell break; 1161254885Sdumbbell case PACKET3_INDX_BUFFER: 1162254885Sdumbbell r = r100_cs_packet_next_reloc(p, &reloc); 1163254885Sdumbbell if (r) { 1164254885Sdumbbell DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); 1165254885Sdumbbell r100_cs_dump_packet(p, pkt); 1166254885Sdumbbell return r; 1167254885Sdumbbell } 1168254885Sdumbbell ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); 1169254885Sdumbbell r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); 1170254885Sdumbbell if (r) { 1171254885Sdumbbell return r; 1172254885Sdumbbell } 1173254885Sdumbbell break; 1174254885Sdumbbell /* Draw packet */ 1175254885Sdumbbell case PACKET3_3D_DRAW_IMMD: 1176254885Sdumbbell /* Number of dwords is vtx_size * (num_vertices - 1) 1177254885Sdumbbell * PRIM_WALK must be equal to 3 vertex data in embedded 1178254885Sdumbbell * in cmd stream */ 1179254885Sdumbbell if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) { 1180254885Sdumbbell DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); 1181254885Sdumbbell return -EINVAL; 1182254885Sdumbbell } 1183254885Sdumbbell track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); 1184254885Sdumbbell track->immd_dwords = pkt->count - 1; 1185254885Sdumbbell r = r100_cs_track_check(p->rdev, track); 1186254885Sdumbbell if (r) { 1187254885Sdumbbell return r; 1188254885Sdumbbell } 1189254885Sdumbbell break; 1190254885Sdumbbell case PACKET3_3D_DRAW_IMMD_2: 1191254885Sdumbbell /* Number of dwords is vtx_size * (num_vertices - 1) 1192254885Sdumbbell * PRIM_WALK must be equal to 3 vertex data in embedded 1193254885Sdumbbell * in cmd stream */ 1194254885Sdumbbell if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) { 1195254885Sdumbbell DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); 1196254885Sdumbbell return -EINVAL; 1197254885Sdumbbell } 1198254885Sdumbbell track->vap_vf_cntl = radeon_get_ib_value(p, idx); 1199254885Sdumbbell track->immd_dwords = pkt->count; 1200254885Sdumbbell r = r100_cs_track_check(p->rdev, track); 1201254885Sdumbbell if (r) { 1202254885Sdumbbell return r; 1203254885Sdumbbell } 1204254885Sdumbbell break; 1205254885Sdumbbell case PACKET3_3D_DRAW_VBUF: 1206254885Sdumbbell track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); 1207254885Sdumbbell r = r100_cs_track_check(p->rdev, track); 1208254885Sdumbbell if (r) { 1209254885Sdumbbell return r; 1210254885Sdumbbell } 1211254885Sdumbbell break; 1212254885Sdumbbell case PACKET3_3D_DRAW_VBUF_2: 1213254885Sdumbbell track->vap_vf_cntl = radeon_get_ib_value(p, idx); 1214254885Sdumbbell r = r100_cs_track_check(p->rdev, track); 1215254885Sdumbbell if (r) { 1216254885Sdumbbell return r; 1217254885Sdumbbell } 1218254885Sdumbbell break; 1219254885Sdumbbell case PACKET3_3D_DRAW_INDX: 1220254885Sdumbbell track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); 1221254885Sdumbbell r = r100_cs_track_check(p->rdev, track); 1222254885Sdumbbell if (r) { 1223254885Sdumbbell return r; 1224254885Sdumbbell } 1225254885Sdumbbell break; 1226254885Sdumbbell case PACKET3_3D_DRAW_INDX_2: 1227254885Sdumbbell track->vap_vf_cntl = radeon_get_ib_value(p, idx); 1228254885Sdumbbell r = r100_cs_track_check(p->rdev, track); 1229254885Sdumbbell if (r) { 1230254885Sdumbbell return r; 1231254885Sdumbbell } 1232254885Sdumbbell break; 1233254885Sdumbbell case PACKET3_3D_CLEAR_HIZ: 1234254885Sdumbbell case PACKET3_3D_CLEAR_ZMASK: 1235254885Sdumbbell if (p->rdev->hyperz_filp != p->filp) 1236254885Sdumbbell return -EINVAL; 1237254885Sdumbbell break; 1238254885Sdumbbell case PACKET3_3D_CLEAR_CMASK: 1239254885Sdumbbell if (p->rdev->cmask_filp != p->filp) 1240254885Sdumbbell return -EINVAL; 1241254885Sdumbbell break; 1242254885Sdumbbell case PACKET3_NOP: 1243254885Sdumbbell break; 1244254885Sdumbbell default: 1245254885Sdumbbell DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); 1246254885Sdumbbell return -EINVAL; 1247254885Sdumbbell } 1248254885Sdumbbell return 0; 1249254885Sdumbbell} 1250254885Sdumbbell 1251254885Sdumbbellint r300_cs_parse(struct radeon_cs_parser *p) 1252254885Sdumbbell{ 1253254885Sdumbbell struct radeon_cs_packet pkt; 1254254885Sdumbbell struct r100_cs_track *track; 1255254885Sdumbbell int r; 1256254885Sdumbbell 1257254885Sdumbbell track = malloc(sizeof(*track), DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1258254885Sdumbbell if (track == NULL) 1259254885Sdumbbell return -ENOMEM; 1260254885Sdumbbell r100_cs_track_clear(p->rdev, track); 1261254885Sdumbbell p->track = track; 1262254885Sdumbbell do { 1263254885Sdumbbell r = r100_cs_packet_parse(p, &pkt, p->idx); 1264254885Sdumbbell if (r) { 1265254885Sdumbbell free(p->track, DRM_MEM_DRIVER); 1266254885Sdumbbell p->track = NULL; 1267254885Sdumbbell return r; 1268254885Sdumbbell } 1269254885Sdumbbell p->idx += pkt.count + 2; 1270254885Sdumbbell switch (pkt.type) { 1271254885Sdumbbell case PACKET_TYPE0: 1272254885Sdumbbell r = r100_cs_parse_packet0(p, &pkt, 1273254885Sdumbbell p->rdev->config.r300.reg_safe_bm, 1274254885Sdumbbell p->rdev->config.r300.reg_safe_bm_size, 1275254885Sdumbbell &r300_packet0_check); 1276254885Sdumbbell break; 1277254885Sdumbbell case PACKET_TYPE2: 1278254885Sdumbbell break; 1279254885Sdumbbell case PACKET_TYPE3: 1280254885Sdumbbell r = r300_packet3_check(p, &pkt); 1281254885Sdumbbell break; 1282254885Sdumbbell default: 1283254885Sdumbbell DRM_ERROR("Unknown packet type %d !\n", pkt.type); 1284254885Sdumbbell free(p->track, DRM_MEM_DRIVER); 1285254885Sdumbbell p->track = NULL; 1286254885Sdumbbell return -EINVAL; 1287254885Sdumbbell } 1288254885Sdumbbell if (r) { 1289254885Sdumbbell free(p->track, DRM_MEM_DRIVER); 1290254885Sdumbbell p->track = NULL; 1291254885Sdumbbell return r; 1292254885Sdumbbell } 1293254885Sdumbbell } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); 1294254885Sdumbbell free(p->track, DRM_MEM_DRIVER); 1295254885Sdumbbell p->track = NULL; 1296254885Sdumbbell return 0; 1297254885Sdumbbell} 1298254885Sdumbbell 1299254885Sdumbbellvoid r300_set_reg_safe(struct radeon_device *rdev) 1300254885Sdumbbell{ 1301254885Sdumbbell rdev->config.r300.reg_safe_bm = r300_reg_safe_bm; 1302254885Sdumbbell rdev->config.r300.reg_safe_bm_size = DRM_ARRAY_SIZE(r300_reg_safe_bm); 1303254885Sdumbbell} 1304254885Sdumbbell 1305254885Sdumbbellvoid r300_mc_program(struct radeon_device *rdev) 1306254885Sdumbbell{ 1307254885Sdumbbell struct r100_mc_save save; 1308254885Sdumbbell int r; 1309254885Sdumbbell 1310254885Sdumbbell r = r100_debugfs_mc_info_init(rdev); 1311254885Sdumbbell if (r) { 1312254885Sdumbbell dev_err(rdev->dev, "Failed to create r100_mc debugfs file.\n"); 1313254885Sdumbbell } 1314254885Sdumbbell 1315254885Sdumbbell /* Stops all mc clients */ 1316254885Sdumbbell r100_mc_stop(rdev, &save); 1317254885Sdumbbell if (rdev->flags & RADEON_IS_AGP) { 1318254885Sdumbbell WREG32(R_00014C_MC_AGP_LOCATION, 1319254885Sdumbbell S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | 1320254885Sdumbbell S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); 1321254885Sdumbbell WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); 1322254885Sdumbbell WREG32(R_00015C_AGP_BASE_2, 1323254885Sdumbbell upper_32_bits(rdev->mc.agp_base) & 0xff); 1324254885Sdumbbell } else { 1325254885Sdumbbell WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF); 1326254885Sdumbbell WREG32(R_000170_AGP_BASE, 0); 1327254885Sdumbbell WREG32(R_00015C_AGP_BASE_2, 0); 1328254885Sdumbbell } 1329254885Sdumbbell /* Wait for mc idle */ 1330254885Sdumbbell if (r300_mc_wait_for_idle(rdev)) 1331254885Sdumbbell DRM_INFO("Failed to wait MC idle before programming MC.\n"); 1332254885Sdumbbell /* Program MC, should be a 32bits limited address space */ 1333254885Sdumbbell WREG32(R_000148_MC_FB_LOCATION, 1334254885Sdumbbell S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | 1335254885Sdumbbell S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); 1336254885Sdumbbell r100_mc_resume(rdev, &save); 1337254885Sdumbbell} 1338254885Sdumbbell 1339254885Sdumbbellvoid r300_clock_startup(struct radeon_device *rdev) 1340254885Sdumbbell{ 1341254885Sdumbbell u32 tmp; 1342254885Sdumbbell 1343254885Sdumbbell if (radeon_dynclks != -1 && radeon_dynclks) 1344254885Sdumbbell radeon_legacy_set_clock_gating(rdev, 1); 1345254885Sdumbbell /* We need to force on some of the block */ 1346254885Sdumbbell tmp = RREG32_PLL(R_00000D_SCLK_CNTL); 1347254885Sdumbbell tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); 1348254885Sdumbbell if ((rdev->family == CHIP_RV350) || (rdev->family == CHIP_RV380)) 1349254885Sdumbbell tmp |= S_00000D_FORCE_VAP(1); 1350254885Sdumbbell WREG32_PLL(R_00000D_SCLK_CNTL, tmp); 1351254885Sdumbbell} 1352254885Sdumbbell 1353254885Sdumbbellstatic int r300_startup(struct radeon_device *rdev) 1354254885Sdumbbell{ 1355254885Sdumbbell int r; 1356254885Sdumbbell 1357254885Sdumbbell /* set common regs */ 1358254885Sdumbbell r100_set_common_regs(rdev); 1359254885Sdumbbell /* program mc */ 1360254885Sdumbbell r300_mc_program(rdev); 1361254885Sdumbbell /* Resume clock */ 1362254885Sdumbbell r300_clock_startup(rdev); 1363254885Sdumbbell /* Initialize GPU configuration (# pipes, ...) */ 1364254885Sdumbbell r300_gpu_init(rdev); 1365254885Sdumbbell /* Initialize GART (initialize after TTM so we can allocate 1366254885Sdumbbell * memory through TTM but finalize after TTM) */ 1367254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) { 1368254885Sdumbbell r = rv370_pcie_gart_enable(rdev); 1369254885Sdumbbell if (r) 1370254885Sdumbbell return r; 1371254885Sdumbbell } 1372254885Sdumbbell 1373254885Sdumbbell if (rdev->family == CHIP_R300 || 1374254885Sdumbbell rdev->family == CHIP_R350 || 1375254885Sdumbbell rdev->family == CHIP_RV350) 1376254885Sdumbbell r100_enable_bm(rdev); 1377254885Sdumbbell 1378254885Sdumbbell if (rdev->flags & RADEON_IS_PCI) { 1379254885Sdumbbell r = r100_pci_gart_enable(rdev); 1380254885Sdumbbell if (r) 1381254885Sdumbbell return r; 1382254885Sdumbbell } 1383254885Sdumbbell 1384254885Sdumbbell /* allocate wb buffer */ 1385254885Sdumbbell r = radeon_wb_init(rdev); 1386254885Sdumbbell if (r) 1387254885Sdumbbell return r; 1388254885Sdumbbell 1389254885Sdumbbell r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 1390254885Sdumbbell if (r) { 1391254885Sdumbbell dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 1392254885Sdumbbell return r; 1393254885Sdumbbell } 1394254885Sdumbbell 1395254885Sdumbbell /* Enable IRQ */ 1396254885Sdumbbell r100_irq_set(rdev); 1397254885Sdumbbell rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); 1398254885Sdumbbell /* 1M ring buffer */ 1399254885Sdumbbell r = r100_cp_init(rdev, 1024 * 1024); 1400254885Sdumbbell if (r) { 1401254885Sdumbbell dev_err(rdev->dev, "failed initializing CP (%d).\n", r); 1402254885Sdumbbell return r; 1403254885Sdumbbell } 1404254885Sdumbbell 1405254885Sdumbbell r = radeon_ib_pool_init(rdev); 1406254885Sdumbbell if (r) { 1407254885Sdumbbell dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 1408254885Sdumbbell return r; 1409254885Sdumbbell } 1410254885Sdumbbell 1411254885Sdumbbell return 0; 1412254885Sdumbbell} 1413254885Sdumbbell 1414254885Sdumbbellint r300_resume(struct radeon_device *rdev) 1415254885Sdumbbell{ 1416254885Sdumbbell int r; 1417254885Sdumbbell 1418254885Sdumbbell /* Make sur GART are not working */ 1419254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) 1420254885Sdumbbell rv370_pcie_gart_disable(rdev); 1421254885Sdumbbell if (rdev->flags & RADEON_IS_PCI) 1422254885Sdumbbell r100_pci_gart_disable(rdev); 1423254885Sdumbbell /* Resume clock before doing reset */ 1424254885Sdumbbell r300_clock_startup(rdev); 1425254885Sdumbbell /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 1426254885Sdumbbell if (radeon_asic_reset(rdev)) { 1427254885Sdumbbell dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 1428254885Sdumbbell RREG32(R_000E40_RBBM_STATUS), 1429254885Sdumbbell RREG32(R_0007C0_CP_STAT)); 1430254885Sdumbbell } 1431254885Sdumbbell /* post */ 1432254885Sdumbbell radeon_combios_asic_init(rdev->ddev); 1433254885Sdumbbell /* Resume clock after posting */ 1434254885Sdumbbell r300_clock_startup(rdev); 1435254885Sdumbbell /* Initialize surface registers */ 1436254885Sdumbbell radeon_surface_init(rdev); 1437254885Sdumbbell 1438254885Sdumbbell rdev->accel_working = true; 1439254885Sdumbbell r = r300_startup(rdev); 1440254885Sdumbbell if (r) { 1441254885Sdumbbell rdev->accel_working = false; 1442254885Sdumbbell } 1443254885Sdumbbell return r; 1444254885Sdumbbell} 1445254885Sdumbbell 1446254885Sdumbbellint r300_suspend(struct radeon_device *rdev) 1447254885Sdumbbell{ 1448254885Sdumbbell r100_cp_disable(rdev); 1449254885Sdumbbell radeon_wb_disable(rdev); 1450254885Sdumbbell r100_irq_disable(rdev); 1451254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) 1452254885Sdumbbell rv370_pcie_gart_disable(rdev); 1453254885Sdumbbell if (rdev->flags & RADEON_IS_PCI) 1454254885Sdumbbell r100_pci_gart_disable(rdev); 1455254885Sdumbbell return 0; 1456254885Sdumbbell} 1457254885Sdumbbell 1458254885Sdumbbellvoid r300_fini(struct radeon_device *rdev) 1459254885Sdumbbell{ 1460254885Sdumbbell r100_cp_fini(rdev); 1461254885Sdumbbell radeon_wb_fini(rdev); 1462254885Sdumbbell radeon_ib_pool_fini(rdev); 1463254885Sdumbbell radeon_gem_fini(rdev); 1464254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) 1465254885Sdumbbell rv370_pcie_gart_fini(rdev); 1466254885Sdumbbell if (rdev->flags & RADEON_IS_PCI) 1467254885Sdumbbell r100_pci_gart_fini(rdev); 1468254885Sdumbbell radeon_agp_fini(rdev); 1469254885Sdumbbell radeon_irq_kms_fini(rdev); 1470254885Sdumbbell radeon_fence_driver_fini(rdev); 1471254885Sdumbbell radeon_bo_fini(rdev); 1472254885Sdumbbell radeon_atombios_fini(rdev); 1473254885Sdumbbell free(rdev->bios, DRM_MEM_DRIVER); 1474254885Sdumbbell rdev->bios = NULL; 1475254885Sdumbbell} 1476254885Sdumbbell 1477254885Sdumbbellint r300_init(struct radeon_device *rdev) 1478254885Sdumbbell{ 1479254885Sdumbbell int r; 1480254885Sdumbbell 1481254885Sdumbbell /* Disable VGA */ 1482254885Sdumbbell r100_vga_render_disable(rdev); 1483254885Sdumbbell /* Initialize scratch registers */ 1484254885Sdumbbell radeon_scratch_init(rdev); 1485254885Sdumbbell /* Initialize surface registers */ 1486254885Sdumbbell radeon_surface_init(rdev); 1487254885Sdumbbell /* TODO: disable VGA need to use VGA request */ 1488254885Sdumbbell /* restore some register to sane defaults */ 1489254885Sdumbbell r100_restore_sanity(rdev); 1490254885Sdumbbell /* BIOS*/ 1491254885Sdumbbell if (!radeon_get_bios(rdev)) { 1492254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) 1493254885Sdumbbell return -EINVAL; 1494254885Sdumbbell } 1495254885Sdumbbell if (rdev->is_atom_bios) { 1496254885Sdumbbell dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); 1497254885Sdumbbell return -EINVAL; 1498254885Sdumbbell } else { 1499254885Sdumbbell r = radeon_combios_init(rdev); 1500254885Sdumbbell if (r) 1501254885Sdumbbell return r; 1502254885Sdumbbell } 1503254885Sdumbbell /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 1504254885Sdumbbell if (radeon_asic_reset(rdev)) { 1505254885Sdumbbell dev_warn(rdev->dev, 1506254885Sdumbbell "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 1507254885Sdumbbell RREG32(R_000E40_RBBM_STATUS), 1508254885Sdumbbell RREG32(R_0007C0_CP_STAT)); 1509254885Sdumbbell } 1510254885Sdumbbell /* check if cards are posted or not */ 1511254885Sdumbbell if (radeon_boot_test_post_card(rdev) == false) 1512254885Sdumbbell return -EINVAL; 1513254885Sdumbbell /* Set asic errata */ 1514254885Sdumbbell r300_errata(rdev); 1515254885Sdumbbell /* Initialize clocks */ 1516254885Sdumbbell radeon_get_clock_info(rdev->ddev); 1517254885Sdumbbell /* initialize AGP */ 1518254885Sdumbbell if (rdev->flags & RADEON_IS_AGP) { 1519254885Sdumbbell r = radeon_agp_init(rdev); 1520254885Sdumbbell if (r) { 1521254885Sdumbbell radeon_agp_disable(rdev); 1522254885Sdumbbell } 1523254885Sdumbbell } 1524254885Sdumbbell /* initialize memory controller */ 1525254885Sdumbbell r300_mc_init(rdev); 1526254885Sdumbbell /* Fence driver */ 1527254885Sdumbbell r = radeon_fence_driver_init(rdev); 1528254885Sdumbbell if (r) 1529254885Sdumbbell return r; 1530254885Sdumbbell r = radeon_irq_kms_init(rdev); 1531254885Sdumbbell if (r) 1532254885Sdumbbell return r; 1533254885Sdumbbell /* Memory manager */ 1534254885Sdumbbell r = radeon_bo_init(rdev); 1535254885Sdumbbell if (r) 1536254885Sdumbbell return r; 1537254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) { 1538254885Sdumbbell r = rv370_pcie_gart_init(rdev); 1539254885Sdumbbell if (r) 1540254885Sdumbbell return r; 1541254885Sdumbbell } 1542254885Sdumbbell if (rdev->flags & RADEON_IS_PCI) { 1543254885Sdumbbell r = r100_pci_gart_init(rdev); 1544254885Sdumbbell if (r) 1545254885Sdumbbell return r; 1546254885Sdumbbell } 1547254885Sdumbbell r300_set_reg_safe(rdev); 1548254885Sdumbbell 1549254885Sdumbbell rdev->accel_working = true; 1550254885Sdumbbell r = r300_startup(rdev); 1551254885Sdumbbell if (r) { 1552254885Sdumbbell /* Somethings want wront with the accel init stop accel */ 1553254885Sdumbbell dev_err(rdev->dev, "Disabling GPU acceleration\n"); 1554254885Sdumbbell r100_cp_fini(rdev); 1555254885Sdumbbell radeon_wb_fini(rdev); 1556254885Sdumbbell radeon_ib_pool_fini(rdev); 1557254885Sdumbbell radeon_irq_kms_fini(rdev); 1558254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) 1559254885Sdumbbell rv370_pcie_gart_fini(rdev); 1560254885Sdumbbell if (rdev->flags & RADEON_IS_PCI) 1561254885Sdumbbell r100_pci_gart_fini(rdev); 1562254885Sdumbbell radeon_agp_fini(rdev); 1563254885Sdumbbell rdev->accel_working = false; 1564254885Sdumbbell } 1565254885Sdumbbell return 0; 1566254885Sdumbbell} 1567