1193326Sed/* 2193326Sed * Copyright 2008 Advanced Micro Devices, Inc. 3193326Sed * Copyright 2008 Red Hat Inc. 4193326Sed * Copyright 2009 Jerome Glisse. 5193326Sed * 6193326Sed * Permission is hereby granted, free of charge, to any person obtaining a 7193326Sed * copy of this software and associated documentation files (the "Software"), 8193326Sed * to deal in the Software without restriction, including without limitation 9193326Sed * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10193326Sed * and/or sell copies of the Software, and to permit persons to whom the 11193326Sed * Software is furnished to do so, subject to the following conditions: 12193326Sed * 13193326Sed * The above copyright notice and this permission notice shall be included in 14212904Sdim * all copies or substantial portions of the Software. 15221345Sdim * 16193326Sed * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17193326Sed * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18198092Srdivacky * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19249423Sdim * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20239462Sdim * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21212904Sdim * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22212904Sdim * OTHER DEALINGS IN THE SOFTWARE. 23193326Sed * 24221345Sdim * Authors: Dave Airlie 25193326Sed * Alex Deucher 26193326Sed * Jerome Glisse 27198092Srdivacky */ 28198092Srdivacky 29193326Sed#include "radeon.h" 30249423Sdim#include "radeon_asic.h" 31249423Sdim#include "atom.h" 32249423Sdim#include "r520d.h" 33249423Sdim 34249423Sdim/* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */ 35249423Sdim 36249423Sdimint r520_mc_wait_for_idle(struct radeon_device *rdev) 37249423Sdim{ 38249423Sdim unsigned i; 39249423Sdim uint32_t tmp; 40249423Sdim 41249423Sdim for (i = 0; i < rdev->usec_timeout; i++) { 42234353Sdim /* read MC_STATUS */ 43201361Srdivacky tmp = RREG32_MC(R520_MC_STATUS); 44193326Sed if (tmp & R520_MC_STATUS_IDLE) { 45198092Srdivacky return 0; 46193326Sed } 47193326Sed udelay(1); 48212904Sdim } 49193326Sed return -1; 50224145Sdim} 51224145Sdim 52224145Sdimstatic void r520_gpu_init(struct radeon_device *rdev) 53224145Sdim{ 54224145Sdim unsigned pipe_select_current, gb_pipe_select, tmp; 55224145Sdim 56212904Sdim rv515_vga_render_disable(rdev); 57193326Sed /* 58193326Sed * DST_PIPE_CONFIG 0x170C 59234353Sdim * GB_TILE_CONFIG 0x4018 60234353Sdim * GB_FIFO_SIZE 0x4024 61234353Sdim * GB_PIPE_SELECT 0x402C 62234353Sdim * GB_PIPE_SELECT2 0x4124 63239462Sdim * Z_PIPE_SHIFT 0 64239462Sdim * Z_PIPE_MASK 0x000000003 65234353Sdim * GB_FIFO_SIZE2 0x4128 66234353Sdim * SC_SFIFO_SIZE_SHIFT 0 67234353Sdim * SC_SFIFO_SIZE_MASK 0x000000003 68234353Sdim * SC_MFIFO_SIZE_SHIFT 2 69234353Sdim * SC_MFIFO_SIZE_MASK 0x00000000C 70234353Sdim * FG_SFIFO_SIZE_SHIFT 4 71234353Sdim * FG_SFIFO_SIZE_MASK 0x000000030 72234353Sdim * ZB_MFIFO_SIZE_SHIFT 6 73234353Sdim * ZB_MFIFO_SIZE_MASK 0x0000000C0 74234353Sdim * GA_ENHANCE 0x4274 75239462Sdim * SU_REG_DEST 0x42C8 76234353Sdim */ 77234353Sdim /* workaround for RV530 */ 78234353Sdim if (rdev->family == CHIP_RV530) { 79234353Sdim WREG32(0x4128, 0xFF); 80239462Sdim } 81234353Sdim r420_pipes_init(rdev); 82234353Sdim gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); 83234353Sdim tmp = RREG32(R300_DST_PIPE_CONFIG); 84234353Sdim pipe_select_current = (tmp >> 2) & 3; 85239462Sdim tmp = (1 << pipe_select_current) | 86239462Sdim (((gb_pipe_select >> 8) & 0xF) << 4); 87239462Sdim WREG32_PLL(0x000D, tmp); 88239462Sdim if (r520_mc_wait_for_idle(rdev)) { 89239462Sdim pr_warn("Failed to wait MC idle while programming pipes. Bad things might happen.\n"); 90239462Sdim } 91239462Sdim} 92239462Sdim 93239462Sdimstatic void r520_vram_get_type(struct radeon_device *rdev) 94239462Sdim{ 95239462Sdim uint32_t tmp; 96239462Sdim 97239462Sdim rdev->mc.vram_width = 128; 98239462Sdim rdev->mc.vram_is_ddr = true; 99239462Sdim tmp = RREG32_MC(R520_MC_CNTL0); 100239462Sdim switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) { 101239462Sdim case 0: 102239462Sdim rdev->mc.vram_width = 32; 103239462Sdim break; 104239462Sdim case 1: 105239462Sdim rdev->mc.vram_width = 64; 106239462Sdim break; 107239462Sdim case 2: 108239462Sdim rdev->mc.vram_width = 128; 109239462Sdim break; 110239462Sdim case 3: 111239462Sdim rdev->mc.vram_width = 256; 112239462Sdim break; 113239462Sdim default: 114239462Sdim rdev->mc.vram_width = 128; 115239462Sdim break; 116239462Sdim } 117239462Sdim if (tmp & R520_MC_CHANNEL_SIZE) 118239462Sdim rdev->mc.vram_width *= 2; 119239462Sdim} 120239462Sdim 121193326Sedstatic void r520_mc_init(struct radeon_device *rdev) 122193326Sed{ 123193326Sed 124193326Sed r520_vram_get_type(rdev); 125193326Sed r100_vram_init_sizes(rdev); 126193326Sed radeon_vram_location(rdev, &rdev->mc, 0); 127193326Sed rdev->mc.gtt_base_align = 0; 128193326Sed if (!(rdev->flags & RADEON_IS_AGP)) 129193326Sed radeon_gtt_location(rdev, &rdev->mc); 130193326Sed radeon_update_bandwidth_info(rdev); 131193326Sed} 132251662Sdim 133212904Sdimstatic void r520_mc_program(struct radeon_device *rdev) 134218893Sdim{ 135221345Sdim struct rv515_mc_save save; 136234353Sdim 137226633Sdim /* Stops all mc clients */ 138226633Sdim rv515_mc_stop(rdev, &save); 139199990Srdivacky 140199990Srdivacky /* Wait for mc idle */ 141199990Srdivacky if (r520_mc_wait_for_idle(rdev)) 142212904Sdim dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); 143199990Srdivacky /* Write VRAM size in case we are limiting it */ 144199990Srdivacky WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); 145207619Srdivacky /* Program MC, should be a 32bits limited address space */ 146199990Srdivacky WREG32_MC(R_000004_MC_FB_LOCATION, 147199990Srdivacky S_000004_MC_FB_START(rdev->mc.vram_start >> 16) | 148199990Srdivacky S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16)); 149199990Srdivacky WREG32(R_000134_HDP_FB_LOCATION, 150199990Srdivacky S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); 151199990Srdivacky if (rdev->flags & RADEON_IS_AGP) { 152199990Srdivacky WREG32_MC(R_000005_MC_AGP_LOCATION, 153199990Srdivacky S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) | 154199990Srdivacky S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); 155199990Srdivacky WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); 156199990Srdivacky WREG32_MC(R_000007_AGP_BASE_2, 157199990Srdivacky S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); 158199990Srdivacky } else { 159234353Sdim WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF); 160212904Sdim WREG32_MC(R_000006_AGP_BASE, 0); 161199990Srdivacky WREG32_MC(R_000007_AGP_BASE_2, 0); 162210299Sed } 163210299Sed 164221345Sdim rv515_mc_resume(rdev, &save); 165221345Sdim} 166221345Sdim 167221345Sdimstatic int r520_startup(struct radeon_device *rdev) 168212904Sdim{ 169221345Sdim int r; 170221345Sdim 171221345Sdim r520_mc_program(rdev); 172221345Sdim /* Resume clock */ 173199990Srdivacky rv515_clock_startup(rdev); 174199990Srdivacky /* Initialize GPU configuration (# pipes, ...) */ 175212904Sdim r520_gpu_init(rdev); 176199990Srdivacky /* Initialize GART (initialize after TTM so we can allocate 177199990Srdivacky * memory through TTM but finalize after TTM) */ 178207619Srdivacky if (rdev->flags & RADEON_IS_PCIE) { 179207619Srdivacky r = rv370_pcie_gart_enable(rdev); 180212904Sdim if (r) 181198092Srdivacky return r; 182201361Srdivacky } 183201361Srdivacky 184201361Srdivacky /* allocate wb buffer */ 185201361Srdivacky r = radeon_wb_init(rdev); 186201361Srdivacky if (r) 187201361Srdivacky return r; 188199990Srdivacky 189199990Srdivacky r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 190199990Srdivacky if (r) { 191199990Srdivacky dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 192199990Srdivacky return r; 193199990Srdivacky } 194198092Srdivacky 195199990Srdivacky /* Enable IRQ */ 196199990Srdivacky if (!rdev->irq.installed) { 197199990Srdivacky r = radeon_irq_kms_init(rdev); 198199990Srdivacky if (r) 199199990Srdivacky return r; 200199990Srdivacky } 201199990Srdivacky 202199990Srdivacky rs600_irq_set(rdev); 203199990Srdivacky rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); 204199990Srdivacky /* 1M ring buffer */ 205199990Srdivacky r = r100_cp_init(rdev, 1024 * 1024); 206199990Srdivacky if (r) { 207199990Srdivacky dev_err(rdev->dev, "failed initializing CP (%d).\n", r); 208199990Srdivacky return r; 209193326Sed } 210199482Srdivacky 211193326Sed r = radeon_ib_pool_init(rdev); 212202379Srdivacky if (r) { 213226633Sdim dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 214239462Sdim return r; 215226633Sdim } 216234353Sdim 217226633Sdim return 0; 218226633Sdim} 219226633Sdim 220226633Sdimint r520_resume(struct radeon_device *rdev) 221226633Sdim{ 222226633Sdim int r; 223226633Sdim 224226633Sdim /* Make sur GART are not working */ 225226633Sdim if (rdev->flags & RADEON_IS_PCIE) 226226633Sdim rv370_pcie_gart_disable(rdev); 227226633Sdim /* Resume clock before doing reset */ 228226633Sdim rv515_clock_startup(rdev); 229226633Sdim /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 230226633Sdim if (radeon_asic_reset(rdev)) { 231226633Sdim dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 232234353Sdim RREG32(R_000E40_RBBM_STATUS), 233226633Sdim RREG32(R_0007C0_CP_STAT)); 234226633Sdim } 235226633Sdim /* post */ 236226633Sdim atom_asic_init(rdev->mode_info.atom_context); 237234353Sdim /* Resume clock after posting */ 238226633Sdim rv515_clock_startup(rdev); 239226633Sdim /* Initialize surface registers */ 240234353Sdim radeon_surface_init(rdev); 241226633Sdim 242234353Sdim rdev->accel_working = true; 243239462Sdim r = r520_startup(rdev); 244239462Sdim if (r) { 245226633Sdim rdev->accel_working = false; 246226633Sdim } 247226633Sdim return r; 248226633Sdim} 249226633Sdim 250226633Sdimint r520_init(struct radeon_device *rdev) 251226633Sdim{ 252226633Sdim int r; 253226633Sdim 254226633Sdim /* Initialize scratch registers */ 255226633Sdim radeon_scratch_init(rdev); 256226633Sdim /* Initialize surface registers */ 257226633Sdim radeon_surface_init(rdev); 258226633Sdim /* restore some register to sane defaults */ 259193326Sed r100_restore_sanity(rdev); 260199482Srdivacky /* TODO: disable VGA need to use VGA request */ 261203955Srdivacky /* BIOS*/ 262212904Sdim if (!radeon_get_bios(rdev)) { 263193326Sed if (ASIC_IS_AVIVO(rdev)) 264198893Srdivacky return -EINVAL; 265198092Srdivacky } 266198092Srdivacky if (rdev->is_atom_bios) { 267198092Srdivacky r = radeon_atombios_init(rdev); 268198092Srdivacky if (r) 269198092Srdivacky return r; 270199482Srdivacky } else { 271199482Srdivacky dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); 272212904Sdim return -EINVAL; 273199482Srdivacky } 274198092Srdivacky /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 275193326Sed if (radeon_asic_reset(rdev)) { 276193326Sed dev_warn(rdev->dev, 277193326Sed "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 278193326Sed RREG32(R_000E40_RBBM_STATUS), 279198092Srdivacky RREG32(R_0007C0_CP_STAT)); 280198092Srdivacky } 281193326Sed /* check if cards are posted or not */ 282193326Sed if (radeon_boot_test_post_card(rdev) == false) 283193326Sed return -EINVAL; 284193326Sed 285193326Sed if (!radeon_card_posted(rdev) && rdev->bios) { 286193326Sed DRM_INFO("GPU not posted. posting now...\n"); 287193326Sed atom_asic_init(rdev->mode_info.atom_context); 288193326Sed } 289193326Sed /* Initialize clocks */ 290193326Sed radeon_get_clock_info(rdev->ddev); 291193326Sed /* initialize AGP */ 292193326Sed if (rdev->flags & RADEON_IS_AGP) { 293199482Srdivacky r = radeon_agp_init(rdev); 294212904Sdim if (r) { 295193326Sed radeon_agp_disable(rdev); 296193326Sed } 297193326Sed } 298193326Sed /* initialize memory controller */ 299193326Sed r520_mc_init(rdev); 300193326Sed rv515_debugfs(rdev); 301193326Sed /* Fence driver */ 302193326Sed radeon_fence_driver_init(rdev); 303193326Sed /* Memory manager */ 304198092Srdivacky r = radeon_bo_init(rdev); 305193326Sed if (r) 306193326Sed return r; 307193326Sed r = rv370_pcie_gart_init(rdev); 308198893Srdivacky if (r) 309198092Srdivacky return r; 310198893Srdivacky rv515_set_safe_registers(rdev); 311198893Srdivacky 312198893Srdivacky /* Initialize power management */ 313199482Srdivacky radeon_pm_init(rdev); 314198893Srdivacky 315198893Srdivacky rdev->accel_working = true; 316234353Sdim r = r520_startup(rdev); 317234353Sdim if (r) { 318234353Sdim /* Somethings want wront with the accel init stop accel */ 319234353Sdim dev_err(rdev->dev, "Disabling GPU acceleration\n"); 320234353Sdim r100_cp_fini(rdev); 321221345Sdim radeon_wb_fini(rdev); 322221345Sdim radeon_ib_pool_fini(rdev); 323221345Sdim radeon_irq_kms_fini(rdev); 324221345Sdim rv370_pcie_gart_fini(rdev); 325221345Sdim radeon_agp_fini(rdev); 326221345Sdim rdev->accel_working = false; 327221345Sdim } 328234353Sdim return 0; 329221345Sdim} 330221345Sdim