330 lines · c
1/*2 * Copyright 2008 Advanced Micro Devices, Inc.3 * Copyright 2008 Red Hat Inc.4 * Copyright 2009 Jerome Glisse.5 *6 * Permission is hereby granted, free of charge, to any person obtaining a7 * copy of this software and associated documentation files (the "Software"),8 * to deal in the Software without restriction, including without limitation9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,10 * and/or sell copies of the Software, and to permit persons to whom the11 * Software is furnished to do so, subject to the following conditions:12 *13 * The above copyright notice and this permission notice shall be included in14 * all copies or substantial portions of the Software.15 *16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR22 * OTHER DEALINGS IN THE SOFTWARE.23 *24 * Authors: Dave Airlie25 * Alex Deucher26 * Jerome Glisse27 */28 29#include "radeon.h"30#include "radeon_asic.h"31#include "atom.h"32#include "r520d.h"33 34/* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */35 36int r520_mc_wait_for_idle(struct radeon_device *rdev)37{38 unsigned i;39 uint32_t tmp;40 41 for (i = 0; i < rdev->usec_timeout; i++) {42 /* read MC_STATUS */43 tmp = RREG32_MC(R520_MC_STATUS);44 if (tmp & R520_MC_STATUS_IDLE) {45 return 0;46 }47 udelay(1);48 }49 return -1;50}51 52static void r520_gpu_init(struct radeon_device *rdev)53{54 unsigned pipe_select_current, gb_pipe_select, tmp;55 56 rv515_vga_render_disable(rdev);57 /*58 * DST_PIPE_CONFIG 0x170C59 * GB_TILE_CONFIG 0x401860 * GB_FIFO_SIZE 0x402461 * GB_PIPE_SELECT 0x402C62 * GB_PIPE_SELECT2 0x412463 * Z_PIPE_SHIFT 064 * Z_PIPE_MASK 0x00000000365 * GB_FIFO_SIZE2 0x412866 * SC_SFIFO_SIZE_SHIFT 067 * SC_SFIFO_SIZE_MASK 0x00000000368 * SC_MFIFO_SIZE_SHIFT 269 * SC_MFIFO_SIZE_MASK 0x00000000C70 * FG_SFIFO_SIZE_SHIFT 471 * FG_SFIFO_SIZE_MASK 0x00000003072 * ZB_MFIFO_SIZE_SHIFT 673 * ZB_MFIFO_SIZE_MASK 0x0000000C074 * GA_ENHANCE 0x427475 * SU_REG_DEST 0x42C876 */77 /* workaround for RV530 */78 if (rdev->family == CHIP_RV530) {79 WREG32(0x4128, 0xFF);80 }81 r420_pipes_init(rdev);82 gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);83 tmp = RREG32(R300_DST_PIPE_CONFIG);84 pipe_select_current = (tmp >> 2) & 3;85 tmp = (1 << pipe_select_current) |86 (((gb_pipe_select >> 8) & 0xF) << 4);87 WREG32_PLL(0x000D, tmp);88 if (r520_mc_wait_for_idle(rdev)) {89 pr_warn("Failed to wait MC idle while programming pipes. Bad things might happen.\n");90 }91}92 93static void r520_vram_get_type(struct radeon_device *rdev)94{95 uint32_t tmp;96 97 rdev->mc.vram_width = 128;98 rdev->mc.vram_is_ddr = true;99 tmp = RREG32_MC(R520_MC_CNTL0);100 switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) {101 case 0:102 rdev->mc.vram_width = 32;103 break;104 case 1:105 rdev->mc.vram_width = 64;106 break;107 case 2:108 rdev->mc.vram_width = 128;109 break;110 case 3:111 rdev->mc.vram_width = 256;112 break;113 default:114 rdev->mc.vram_width = 128;115 break;116 }117 if (tmp & R520_MC_CHANNEL_SIZE)118 rdev->mc.vram_width *= 2;119}120 121static void r520_mc_init(struct radeon_device *rdev)122{123 124 r520_vram_get_type(rdev);125 r100_vram_init_sizes(rdev);126 radeon_vram_location(rdev, &rdev->mc, 0);127 rdev->mc.gtt_base_align = 0;128 if (!(rdev->flags & RADEON_IS_AGP))129 radeon_gtt_location(rdev, &rdev->mc);130 radeon_update_bandwidth_info(rdev);131}132 133static void r520_mc_program(struct radeon_device *rdev)134{135 struct rv515_mc_save save;136 137 /* Stops all mc clients */138 rv515_mc_stop(rdev, &save);139 140 /* Wait for mc idle */141 if (r520_mc_wait_for_idle(rdev))142 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");143 /* Write VRAM size in case we are limiting it */144 WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size);145 /* Program MC, should be a 32bits limited address space */146 WREG32_MC(R_000004_MC_FB_LOCATION,147 S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |148 S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));149 WREG32(R_000134_HDP_FB_LOCATION,150 S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));151 if (rdev->flags & RADEON_IS_AGP) {152 WREG32_MC(R_000005_MC_AGP_LOCATION,153 S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) |154 S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16));155 WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base));156 WREG32_MC(R_000007_AGP_BASE_2,157 S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base)));158 } else {159 WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF);160 WREG32_MC(R_000006_AGP_BASE, 0);161 WREG32_MC(R_000007_AGP_BASE_2, 0);162 }163 164 rv515_mc_resume(rdev, &save);165}166 167static int r520_startup(struct radeon_device *rdev)168{169 int r;170 171 r520_mc_program(rdev);172 /* Resume clock */173 rv515_clock_startup(rdev);174 /* Initialize GPU configuration (# pipes, ...) */175 r520_gpu_init(rdev);176 /* Initialize GART (initialize after TTM so we can allocate177 * memory through TTM but finalize after TTM) */178 if (rdev->flags & RADEON_IS_PCIE) {179 r = rv370_pcie_gart_enable(rdev);180 if (r)181 return r;182 }183 184 /* allocate wb buffer */185 r = radeon_wb_init(rdev);186 if (r)187 return r;188 189 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);190 if (r) {191 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);192 return r;193 }194 195 /* Enable IRQ */196 if (!rdev->irq.installed) {197 r = radeon_irq_kms_init(rdev);198 if (r)199 return r;200 }201 202 rs600_irq_set(rdev);203 rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);204 /* 1M ring buffer */205 r = r100_cp_init(rdev, 1024 * 1024);206 if (r) {207 dev_err(rdev->dev, "failed initializing CP (%d).\n", r);208 return r;209 }210 211 r = radeon_ib_pool_init(rdev);212 if (r) {213 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);214 return r;215 }216 217 return 0;218}219 220int r520_resume(struct radeon_device *rdev)221{222 int r;223 224 /* Make sur GART are not working */225 if (rdev->flags & RADEON_IS_PCIE)226 rv370_pcie_gart_disable(rdev);227 /* Resume clock before doing reset */228 rv515_clock_startup(rdev);229 /* Reset gpu before posting otherwise ATOM will enter infinite loop */230 if (radeon_asic_reset(rdev)) {231 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",232 RREG32(R_000E40_RBBM_STATUS),233 RREG32(R_0007C0_CP_STAT));234 }235 /* post */236 atom_asic_init(rdev->mode_info.atom_context);237 /* Resume clock after posting */238 rv515_clock_startup(rdev);239 /* Initialize surface registers */240 radeon_surface_init(rdev);241 242 rdev->accel_working = true;243 r = r520_startup(rdev);244 if (r) {245 rdev->accel_working = false;246 }247 return r;248}249 250int r520_init(struct radeon_device *rdev)251{252 int r;253 254 /* Initialize scratch registers */255 radeon_scratch_init(rdev);256 /* Initialize surface registers */257 radeon_surface_init(rdev);258 /* restore some register to sane defaults */259 r100_restore_sanity(rdev);260 /* TODO: disable VGA need to use VGA request */261 /* BIOS*/262 if (!radeon_get_bios(rdev)) {263 if (ASIC_IS_AVIVO(rdev))264 return -EINVAL;265 }266 if (rdev->is_atom_bios) {267 r = radeon_atombios_init(rdev);268 if (r)269 return r;270 } else {271 dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");272 return -EINVAL;273 }274 /* Reset gpu before posting otherwise ATOM will enter infinite loop */275 if (radeon_asic_reset(rdev)) {276 dev_warn(rdev->dev,277 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",278 RREG32(R_000E40_RBBM_STATUS),279 RREG32(R_0007C0_CP_STAT));280 }281 /* check if cards are posted or not */282 if (radeon_boot_test_post_card(rdev) == false)283 return -EINVAL;284 285 if (!radeon_card_posted(rdev) && rdev->bios) {286 DRM_INFO("GPU not posted. posting now...\n");287 atom_asic_init(rdev->mode_info.atom_context);288 }289 /* Initialize clocks */290 radeon_get_clock_info(rdev_to_drm(rdev));291 /* initialize AGP */292 if (rdev->flags & RADEON_IS_AGP) {293 r = radeon_agp_init(rdev);294 if (r) {295 radeon_agp_disable(rdev);296 }297 }298 /* initialize memory controller */299 r520_mc_init(rdev);300 rv515_debugfs(rdev);301 /* Fence driver */302 radeon_fence_driver_init(rdev);303 /* Memory manager */304 r = radeon_bo_init(rdev);305 if (r)306 return r;307 r = rv370_pcie_gart_init(rdev);308 if (r)309 return r;310 rv515_set_safe_registers(rdev);311 312 /* Initialize power management */313 radeon_pm_init(rdev);314 315 rdev->accel_working = true;316 r = r520_startup(rdev);317 if (r) {318 /* Somethings want wront with the accel init stop accel */319 dev_err(rdev->dev, "Disabling GPU acceleration\n");320 r100_cp_fini(rdev);321 radeon_wb_fini(rdev);322 radeon_ib_pool_fini(rdev);323 radeon_irq_kms_fini(rdev);324 rv370_pcie_gart_fini(rdev);325 radeon_agp_fini(rdev);326 rdev->accel_working = false;327 }328 return 0;329}330