diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 325 |
1 files changed, 172 insertions, 153 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index eab31c1d6df..609719490ec 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -33,8 +33,8 @@ #include "radeon.h" #include "radeon_mode.h" #include "r600d.h" -#include "avivod.h" #include "atom.h" +#include "avivod.h" #define PFP_UCODE_SIZE 576 #define PM4_UCODE_SIZE 1792 @@ -65,16 +65,11 @@ MODULE_FIRMWARE("radeon/RV710_me.bin"); int r600_debugfs_mc_info_init(struct radeon_device *rdev); -/* This files gather functions specifics to: - * r600,rv610,rv630,rv620,rv635,rv670 - * - * Some of these functions might be used by newer ASICs. - */ +/* r600,rv610,rv630,rv620,rv635,rv670 */ int r600_mc_wait_for_idle(struct radeon_device *rdev); void r600_gpu_init(struct radeon_device *rdev); void r600_fini(struct radeon_device *rdev); - /* * R600 PCIE GART */ @@ -168,7 +163,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); @@ -225,6 +220,40 @@ void r600_pcie_gart_fini(struct radeon_device *rdev) radeon_gart_fini(rdev); } +void r600_agp_enable(struct radeon_device *rdev) +{ + u32 tmp; + int i; + + /* Setup L2 cache */ + WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | + ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | + EFFECTIVE_L2_QUEUE_SIZE(7)); + WREG32(VM_L2_CNTL2, 0); + WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); + /* Setup TLB control */ + tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | + SYSTEM_ACCESS_MODE_NOT_IN_SYS | + EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | + ENABLE_WAIT_L2_QUERY; + WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING); + WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); + WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); + WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); + for (i = 0; i < 7; i++) + WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); +} + int r600_mc_wait_for_idle(struct radeon_device *rdev) { unsigned i; @@ -240,14 +269,9 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev) return -1; } -static void r600_mc_resume(struct radeon_device *rdev) +static void r600_mc_program(struct radeon_device *rdev) { - u32 d1vga_control, d2vga_control; - u32 vga_render_control, vga_hdp_control; - u32 d1crtc_control, d2crtc_control; - u32 new_d1grph_primary, new_d1grph_secondary; - u32 new_d2grph_primary, new_d2grph_secondary; - u64 old_vram_start; + struct rv515_mc_save save; u32 tmp; int i, j; @@ -261,88 +285,54 @@ static void r600_mc_resume(struct radeon_device *rdev) } WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); - d1vga_control = RREG32(D1VGA_CONTROL); - d2vga_control = RREG32(D2VGA_CONTROL); - vga_render_control = RREG32(VGA_RENDER_CONTROL); - vga_hdp_control = RREG32(VGA_HDP_CONTROL); - d1crtc_control = RREG32(D1CRTC_CONTROL); - d2crtc_control = RREG32(D2CRTC_CONTROL); - old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; - new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS); - new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS); - new_d1grph_primary += rdev->mc.vram_start - old_vram_start; - new_d1grph_secondary += rdev->mc.vram_start - old_vram_start; - new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS); - new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS); - new_d2grph_primary += rdev->mc.vram_start - old_vram_start; - new_d2grph_secondary += rdev->mc.vram_start - old_vram_start; - - /* Stop all video */ - WREG32(D1VGA_CONTROL, 0); - WREG32(D2VGA_CONTROL, 0); - WREG32(VGA_RENDER_CONTROL, 0); - WREG32(D1CRTC_UPDATE_LOCK, 1); - WREG32(D2CRTC_UPDATE_LOCK, 1); - WREG32(D1CRTC_CONTROL, 0); - WREG32(D2CRTC_CONTROL, 0); - WREG32(D1CRTC_UPDATE_LOCK, 0); - WREG32(D2CRTC_UPDATE_LOCK, 0); - - mdelay(1); + rv515_mc_stop(rdev, &save); if (r600_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "[drm] MC not idle !\n"); + dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } - - /* Lockout access through VGA aperture*/ + /* Lockout access through VGA aperture (doesn't exist before R600) */ WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); - /* Update configuration */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); + if (rdev->flags & RADEON_IS_AGP) { + if (rdev->mc.vram_start < rdev->mc.gtt_start) { + /* VRAM before AGP */ + WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, + rdev->mc.vram_start >> 12); + WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, + rdev->mc.gtt_end >> 12); + } else { + /* VRAM after AGP */ + WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, + rdev->mc.gtt_start >> 12); + WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, + rdev->mc.vram_end >> 12); + } + } else { + WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); + WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); + } WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); - tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; + tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); WREG32(MC_VM_FB_LOCATION, tmp); WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); WREG32(HDP_NONSURFACE_INFO, (2 << 7)); - WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); + WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF); if (rdev->flags & RADEON_IS_AGP) { - WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); - WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); + WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22); + WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22); WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); } else { WREG32(MC_VM_AGP_BASE, 0); WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); } - WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary); - WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary); - WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary); - WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary); - WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); - - /* Unlock host access */ - WREG32(VGA_HDP_CONTROL, vga_hdp_control); - - mdelay(1); if (r600_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "[drm] MC not idle !\n"); + dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } - - /* Restore video state */ - WREG32(D1CRTC_UPDATE_LOCK, 1); - WREG32(D2CRTC_UPDATE_LOCK, 1); - WREG32(D1CRTC_CONTROL, d1crtc_control); - WREG32(D2CRTC_CONTROL, d2crtc_control); - WREG32(D1CRTC_UPDATE_LOCK, 0); - WREG32(D2CRTC_UPDATE_LOCK, 0); - WREG32(D1VGA_CONTROL, d1vga_control); - WREG32(D2VGA_CONTROL, d2vga_control); - WREG32(VGA_RENDER_CONTROL, vga_render_control); - + rv515_mc_resume(rdev, &save); /* we need to own VRAM, so turn off the VGA renderer here * to stop it overwriting our objects */ - radeon_avivo_vga_render_disable(rdev); + rv515_vga_render_disable(rdev); } int r600_mc_init(struct radeon_device *rdev) @@ -380,6 +370,13 @@ int r600_mc_init(struct radeon_device *rdev) /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); + + if (rdev->mc.mc_vram_size > rdev->mc.aper_size) + rdev->mc.mc_vram_size = rdev->mc.aper_size; + + if (rdev->mc.real_vram_size > rdev->mc.aper_size) + rdev->mc.real_vram_size = rdev->mc.aper_size; + if (rdev->flags & RADEON_IS_AGP) { r = radeon_agp_init(rdev); if (r) @@ -438,9 +435,9 @@ int r600_mc_init(struct radeon_device *rdev) } } rdev->mc.vram_start = rdev->mc.vram_location; - rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; + rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; rdev->mc.gtt_start = rdev->mc.gtt_location; - rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; + rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; /* FIXME: we should enforce default clock in case GPU is not in * default setup */ @@ -456,6 +453,7 @@ int r600_mc_init(struct radeon_device *rdev) */ int r600_gpu_soft_reset(struct radeon_device *rdev) { + struct rv515_mc_save save; u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | @@ -473,13 +471,25 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); u32 srbm_reset = 0; + u32 tmp; + dev_info(rdev->dev, "GPU softreset \n"); + dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", + RREG32(R_008010_GRBM_STATUS)); + dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", + RREG32(R_008014_GRBM_STATUS2)); + dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", + RREG32(R_000E50_SRBM_STATUS)); + rv515_mc_stop(rdev, &save); + if (r600_mc_wait_for_idle(rdev)) { + dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); + } /* Disable CP parsing/prefetching */ WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); /* Check if any of the rendering block is busy and reset it */ if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { - WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) | + tmp = S_008020_SOFT_RESET_CR(1) | S_008020_SOFT_RESET_DB(1) | S_008020_SOFT_RESET_CB(1) | S_008020_SOFT_RESET_PA(1) | @@ -491,14 +501,18 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) S_008020_SOFT_RESET_TC(1) | S_008020_SOFT_RESET_TA(1) | S_008020_SOFT_RESET_VC(1) | - S_008020_SOFT_RESET_VGT(1)); + S_008020_SOFT_RESET_VGT(1); + dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); + WREG32(R_008020_GRBM_SOFT_RESET, tmp); (void)RREG32(R_008020_GRBM_SOFT_RESET); udelay(50); WREG32(R_008020_GRBM_SOFT_RESET, 0); (void)RREG32(R_008020_GRBM_SOFT_RESET); } /* Reset CP (we always reset CP) */ - WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1)); + tmp = S_008020_SOFT_RESET_CP(1); + dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); + WREG32(R_008020_GRBM_SOFT_RESET, tmp); (void)RREG32(R_008020_GRBM_SOFT_RESET); udelay(50); WREG32(R_008020_GRBM_SOFT_RESET, 0); @@ -526,6 +540,14 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) srbm_reset |= S_000E60_SOFT_RESET_RLC(1); if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) srbm_reset |= S_000E60_SOFT_RESET_SEM(1); + if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS))) + srbm_reset |= S_000E60_SOFT_RESET_BIF(1); + dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset); + WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); + (void)RREG32(R_000E60_SRBM_SOFT_RESET); + udelay(50); + WREG32(R_000E60_SRBM_SOFT_RESET, 0); + (void)RREG32(R_000E60_SRBM_SOFT_RESET); WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); (void)RREG32(R_000E60_SRBM_SOFT_RESET); udelay(50); @@ -533,6 +555,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) (void)RREG32(R_000E60_SRBM_SOFT_RESET); /* Wait a little for things to settle down */ udelay(50); + dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", + RREG32(R_008010_GRBM_STATUS)); + dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", + RREG32(R_008014_GRBM_STATUS2)); + dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", + RREG32(R_000E50_SRBM_STATUS)); + /* After reset we need to reinit the asic as GPU often endup in an + * incoherent state. + */ + atom_asic_init(rdev->mode_info.atom_context); + rv515_mc_resume(rdev, &save); return 0; } @@ -1343,32 +1376,47 @@ int r600_ring_test(struct radeon_device *rdev) return r; } -/* - * Writeback - */ -int r600_wb_init(struct radeon_device *rdev) +void r600_wb_disable(struct radeon_device *rdev) +{ + WREG32(SCRATCH_UMSK, 0); + if (rdev->wb.wb_obj) { + radeon_object_kunmap(rdev->wb.wb_obj); + radeon_object_unpin(rdev->wb.wb_obj); + } +} + +void r600_wb_fini(struct radeon_device *rdev) +{ + r600_wb_disable(rdev); + if (rdev->wb.wb_obj) { + radeon_object_unref(&rdev->wb.wb_obj); + rdev->wb.wb = NULL; + rdev->wb.wb_obj = NULL; + } +} + +int r600_wb_enable(struct radeon_device *rdev) { int r; if (rdev->wb.wb_obj == NULL) { - r = radeon_object_create(rdev, NULL, 4096, - true, - RADEON_GEM_DOMAIN_GTT, - false, &rdev->wb.wb_obj); + r = radeon_object_create(rdev, NULL, 4096, true, + RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj); if (r) { - DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r); + dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r); return r; } - r = radeon_object_pin(rdev->wb.wb_obj, - RADEON_GEM_DOMAIN_GTT, - &rdev->wb.gpu_addr); + r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, + &rdev->wb.gpu_addr); if (r) { - DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r); + dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r); + r600_wb_fini(rdev); return r; } r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); if (r) { - DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); + dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r); + r600_wb_fini(rdev); return r; } } @@ -1379,21 +1427,6 @@ int r600_wb_init(struct radeon_device *rdev) return 0; } -void r600_wb_fini(struct radeon_device *rdev) -{ - if (rdev->wb.wb_obj) { - radeon_object_kunmap(rdev->wb.wb_obj); - radeon_object_unpin(rdev->wb.wb_obj); - radeon_object_unref(&rdev->wb.wb_obj); - rdev->wb.wb = NULL; - rdev->wb.wb_obj = NULL; - } -} - - -/* - * CS - */ void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { @@ -1470,11 +1503,14 @@ int r600_startup(struct radeon_device *rdev) { int r; - r600_gpu_reset(rdev); - r600_mc_resume(rdev); - r = r600_pcie_gart_enable(rdev); - if (r) - return r; + r600_mc_program(rdev); + if (rdev->flags & RADEON_IS_AGP) { + r600_agp_enable(rdev); + } else { + r = r600_pcie_gart_enable(rdev); + if (r) + return r; + } r600_gpu_init(rdev); r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, @@ -1493,9 +1529,8 @@ int r600_startup(struct radeon_device *rdev) r = r600_cp_resume(rdev); if (r) return r; - r = r600_wb_init(rdev); - if (r) - return r; + /* write back buffer are not vital so don't worry about failure */ + r600_wb_enable(rdev); return 0; } @@ -1517,15 +1552,12 @@ int r600_resume(struct radeon_device *rdev) { int r; - if (radeon_gpu_reset(rdev)) { - /* FIXME: what do we want to do here ? */ - } + /* Do not reset GPU before posting, on r600 hw unlike on r500 hw, + * posting will perform necessary task to bring back GPU into good + * shape. + */ /* post card */ - if (rdev->is_atom_bios) { - atom_asic_init(rdev->mode_info.atom_context); - } else { - radeon_combios_asic_init(rdev->ddev); - } + atom_asic_init(rdev->mode_info.atom_context); /* Initialize clocks */ r = radeon_clocks_init(rdev); if (r) { @@ -1538,7 +1570,7 @@ int r600_resume(struct radeon_device *rdev) return r; } - r = radeon_ib_test(rdev); + r = r600_ib_test(rdev); if (r) { DRM_ERROR("radeon: failled testing IB (%d).\n", r); return r; @@ -1546,13 +1578,12 @@ int r600_resume(struct radeon_device *rdev) return r; } - int r600_suspend(struct radeon_device *rdev) { /* FIXME: we should wait for ring to be empty */ r600_cp_stop(rdev); rdev->cp.ready = false; - + r600_wb_disable(rdev); r600_pcie_gart_disable(rdev); /* unpin shaders bo */ radeon_object_unpin(rdev->r600_blit.shader_obj); @@ -1569,7 +1600,6 @@ int r600_init(struct radeon_device *rdev) { int r; - rdev->new_init_path = true; r = radeon_dummy_page_init(rdev); if (r) return r; @@ -1586,8 +1616,10 @@ int r600_init(struct radeon_device *rdev) return -EINVAL; } /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) + if (!rdev->is_atom_bios) { + dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); return -EINVAL; + } r = radeon_atombios_init(rdev); if (r) return r; @@ -1609,15 +1641,8 @@ int r600_init(struct radeon_device *rdev) if (r) return r; r = r600_mc_init(rdev); - if (r) { - if (rdev->flags & RADEON_IS_AGP) { - /* Retry with disabling AGP */ - r600_fini(rdev); - rdev->flags &= ~RADEON_IS_AGP; - return r600_init(rdev); - } + if (r) return r; - } /* Memory manager */ r = radeon_object_init(rdev); if (r) @@ -1646,12 +1671,10 @@ int r600_init(struct radeon_device *rdev) r = r600_startup(rdev); if (r) { - if (rdev->flags & RADEON_IS_AGP) { - /* Retry with disabling AGP */ - r600_fini(rdev); - rdev->flags &= ~RADEON_IS_AGP; - return r600_init(rdev); - } + r600_suspend(rdev); + r600_wb_fini(rdev); + radeon_ring_fini(rdev); + r600_pcie_gart_fini(rdev); rdev->accel_working = false; } if (rdev->accel_working) { @@ -1660,7 +1683,7 @@ int r600_init(struct radeon_device *rdev) DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); rdev->accel_working = false; } - r = radeon_ib_test(rdev); + r = r600_ib_test(rdev); if (r) { DRM_ERROR("radeon: failled testing IB (%d).\n", r); rdev->accel_working = false; @@ -1676,19 +1699,15 @@ void r600_fini(struct radeon_device *rdev) r600_blit_fini(rdev); radeon_ring_fini(rdev); + r600_wb_fini(rdev); r600_pcie_gart_fini(rdev); radeon_gem_fini(rdev); radeon_fence_driver_fini(rdev); radeon_clocks_fini(rdev); -#if __OS_HAS_AGP if (rdev->flags & RADEON_IS_AGP) radeon_agp_fini(rdev); -#endif radeon_object_fini(rdev); - if (rdev->is_atom_bios) - radeon_atombios_fini(rdev); - else - radeon_combios_fini(rdev); + radeon_atombios_fini(rdev); kfree(rdev->bios); rdev->bios = NULL; radeon_dummy_page_fini(rdev); |