502 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 <linux/debugfs.h>30#include <linux/pci.h>31#include <linux/seq_file.h>32#include <linux/slab.h>33 34#include <drm/drm_device.h>35#include <drm/drm_file.h>36 37#include "atom.h"38#include "r100d.h"39#include "r420_reg_safe.h"40#include "r420d.h"41#include "radeon.h"42#include "radeon_asic.h"43#include "radeon_reg.h"44 45void r420_pm_init_profile(struct radeon_device *rdev)46{47 /* default */48 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;49 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;50 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;51 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;52 /* low sh */53 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0;54 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0;55 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;56 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;57 /* mid sh */58 rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0;59 rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1;60 rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;61 rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;62 /* high sh */63 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0;64 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;65 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;66 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;67 /* low mh */68 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0;69 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;70 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;71 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;72 /* mid mh */73 rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0;74 rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;75 rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;76 rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;77 /* high mh */78 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0;79 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;80 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;81 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;82}83 84static void r420_set_reg_safe(struct radeon_device *rdev)85{86 rdev->config.r300.reg_safe_bm = r420_reg_safe_bm;87 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm);88}89 90void r420_pipes_init(struct radeon_device *rdev)91{92 unsigned tmp;93 unsigned gb_pipe_select;94 unsigned num_pipes;95 96 /* GA_ENHANCE workaround TCL deadlock issue */97 WREG32(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL |98 (1 << 2) | (1 << 3));99 /* add idle wait as per freedesktop.org bug 24041 */100 if (r100_gui_wait_for_idle(rdev)) {101 pr_warn("Failed to wait GUI idle while programming pipes. Bad things might happen.\n");102 }103 /* get max number of pipes */104 gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);105 num_pipes = ((gb_pipe_select >> 12) & 3) + 1;106 107 /* SE chips have 1 pipe */108 if ((rdev->pdev->device == 0x5e4c) ||109 (rdev->pdev->device == 0x5e4f))110 num_pipes = 1;111 112 rdev->num_gb_pipes = num_pipes;113 tmp = 0;114 switch (num_pipes) {115 default:116 /* force to 1 pipe */117 num_pipes = 1;118 fallthrough;119 case 1:120 tmp = (0 << 1);121 break;122 case 2:123 tmp = (3 << 1);124 break;125 case 3:126 tmp = (6 << 1);127 break;128 case 4:129 tmp = (7 << 1);130 break;131 }132 WREG32(R500_SU_REG_DEST, (1 << num_pipes) - 1);133 /* Sub pixel 1/12 so we can have 4K rendering according to doc */134 tmp |= R300_TILE_SIZE_16 | R300_ENABLE_TILING;135 WREG32(R300_GB_TILE_CONFIG, tmp);136 if (r100_gui_wait_for_idle(rdev)) {137 pr_warn("Failed to wait GUI idle while programming pipes. Bad things might happen.\n");138 }139 140 tmp = RREG32(R300_DST_PIPE_CONFIG);141 WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG);142 143 WREG32(R300_RB2D_DSTCACHE_MODE,144 RREG32(R300_RB2D_DSTCACHE_MODE) |145 R300_DC_AUTOFLUSH_ENABLE |146 R300_DC_DC_DISABLE_IGNORE_PE);147 148 if (r100_gui_wait_for_idle(rdev)) {149 pr_warn("Failed to wait GUI idle while programming pipes. Bad things might happen.\n");150 }151 152 if (rdev->family == CHIP_RV530) {153 tmp = RREG32(RV530_GB_PIPE_SELECT2);154 if ((tmp & 3) == 3)155 rdev->num_z_pipes = 2;156 else157 rdev->num_z_pipes = 1;158 } else159 rdev->num_z_pipes = 1;160 161 DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n",162 rdev->num_gb_pipes, rdev->num_z_pipes);163}164 165u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg)166{167 unsigned long flags;168 u32 r;169 170 spin_lock_irqsave(&rdev->mc_idx_lock, flags);171 WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg));172 r = RREG32(R_0001FC_MC_IND_DATA);173 spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);174 return r;175}176 177void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v)178{179 unsigned long flags;180 181 spin_lock_irqsave(&rdev->mc_idx_lock, flags);182 WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) |183 S_0001F8_MC_IND_WR_EN(1));184 WREG32(R_0001FC_MC_IND_DATA, v);185 spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);186}187 188static void r420_debugfs(struct radeon_device *rdev)189{190 r100_debugfs_rbbm_init(rdev);191 r420_debugfs_pipes_info_init(rdev);192}193 194static void r420_clock_resume(struct radeon_device *rdev)195{196 u32 sclk_cntl;197 198 if (radeon_dynclks != -1 && radeon_dynclks)199 radeon_atom_set_clock_gating(rdev, 1);200 sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);201 sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);202 if (rdev->family == CHIP_R420)203 sclk_cntl |= S_00000D_FORCE_PX(1) | S_00000D_FORCE_TX(1);204 WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl);205}206 207static void r420_cp_errata_init(struct radeon_device *rdev)208{209 int r;210 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];211 212 /* RV410 and R420 can lock up if CP DMA to host memory happens213 * while the 2D engine is busy.214 *215 * The proper workaround is to queue a RESYNC at the beginning216 * of the CP init, apparently.217 */218 radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch);219 r = radeon_ring_lock(rdev, ring, 8);220 WARN_ON(r);221 radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1));222 radeon_ring_write(ring, rdev->config.r300.resync_scratch);223 radeon_ring_write(ring, 0xDEADBEEF);224 radeon_ring_unlock_commit(rdev, ring, false);225}226 227static void r420_cp_errata_fini(struct radeon_device *rdev)228{229 int r;230 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];231 232 /* Catch the RESYNC we dispatched all the way back,233 * at the very beginning of the CP init.234 */235 r = radeon_ring_lock(rdev, ring, 8);236 WARN_ON(r);237 radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));238 radeon_ring_write(ring, R300_RB3D_DC_FINISH);239 radeon_ring_unlock_commit(rdev, ring, false);240 radeon_scratch_free(rdev, rdev->config.r300.resync_scratch);241}242 243static int r420_startup(struct radeon_device *rdev)244{245 int r;246 247 /* set common regs */248 r100_set_common_regs(rdev);249 /* program mc */250 r300_mc_program(rdev);251 /* Resume clock */252 r420_clock_resume(rdev);253 /* Initialize GART (initialize after TTM so we can allocate254 * memory through TTM but finalize after TTM) */255 if (rdev->flags & RADEON_IS_PCIE) {256 r = rv370_pcie_gart_enable(rdev);257 if (r)258 return r;259 }260 if (rdev->flags & RADEON_IS_PCI) {261 r = r100_pci_gart_enable(rdev);262 if (r)263 return r;264 }265 r420_pipes_init(rdev);266 267 /* allocate wb buffer */268 r = radeon_wb_init(rdev);269 if (r)270 return r;271 272 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);273 if (r) {274 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);275 return r;276 }277 278 /* Enable IRQ */279 if (!rdev->irq.installed) {280 r = radeon_irq_kms_init(rdev);281 if (r)282 return r;283 }284 285 r100_irq_set(rdev);286 rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);287 /* 1M ring buffer */288 r = r100_cp_init(rdev, 1024 * 1024);289 if (r) {290 dev_err(rdev->dev, "failed initializing CP (%d).\n", r);291 return r;292 }293 r420_cp_errata_init(rdev);294 295 r = radeon_ib_pool_init(rdev);296 if (r) {297 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);298 return r;299 }300 301 return 0;302}303 304int r420_resume(struct radeon_device *rdev)305{306 int r;307 308 /* Make sur GART are not working */309 if (rdev->flags & RADEON_IS_PCIE)310 rv370_pcie_gart_disable(rdev);311 if (rdev->flags & RADEON_IS_PCI)312 r100_pci_gart_disable(rdev);313 /* Resume clock before doing reset */314 r420_clock_resume(rdev);315 /* Reset gpu before posting otherwise ATOM will enter infinite loop */316 if (radeon_asic_reset(rdev)) {317 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",318 RREG32(R_000E40_RBBM_STATUS),319 RREG32(R_0007C0_CP_STAT));320 }321 /* check if cards are posted or not */322 if (rdev->is_atom_bios) {323 atom_asic_init(rdev->mode_info.atom_context);324 } else {325 radeon_combios_asic_init(rdev_to_drm(rdev));326 }327 /* Resume clock after posting */328 r420_clock_resume(rdev);329 /* Initialize surface registers */330 radeon_surface_init(rdev);331 332 rdev->accel_working = true;333 r = r420_startup(rdev);334 if (r) {335 rdev->accel_working = false;336 }337 return r;338}339 340int r420_suspend(struct radeon_device *rdev)341{342 radeon_pm_suspend(rdev);343 r420_cp_errata_fini(rdev);344 r100_cp_disable(rdev);345 radeon_wb_disable(rdev);346 r100_irq_disable(rdev);347 if (rdev->flags & RADEON_IS_PCIE)348 rv370_pcie_gart_disable(rdev);349 if (rdev->flags & RADEON_IS_PCI)350 r100_pci_gart_disable(rdev);351 return 0;352}353 354void r420_fini(struct radeon_device *rdev)355{356 radeon_pm_fini(rdev);357 r100_cp_fini(rdev);358 radeon_wb_fini(rdev);359 radeon_ib_pool_fini(rdev);360 radeon_gem_fini(rdev);361 if (rdev->flags & RADEON_IS_PCIE)362 rv370_pcie_gart_fini(rdev);363 if (rdev->flags & RADEON_IS_PCI)364 r100_pci_gart_fini(rdev);365 radeon_agp_fini(rdev);366 radeon_irq_kms_fini(rdev);367 radeon_fence_driver_fini(rdev);368 radeon_bo_fini(rdev);369 if (rdev->is_atom_bios) {370 radeon_atombios_fini(rdev);371 } else {372 radeon_combios_fini(rdev);373 }374 kfree(rdev->bios);375 rdev->bios = NULL;376}377 378int r420_init(struct radeon_device *rdev)379{380 int r;381 382 /* Initialize scratch registers */383 radeon_scratch_init(rdev);384 /* Initialize surface registers */385 radeon_surface_init(rdev);386 /* TODO: disable VGA need to use VGA request */387 /* restore some register to sane defaults */388 r100_restore_sanity(rdev);389 /* BIOS*/390 if (!radeon_get_bios(rdev)) {391 if (ASIC_IS_AVIVO(rdev))392 return -EINVAL;393 }394 if (rdev->is_atom_bios) {395 r = radeon_atombios_init(rdev);396 if (r) {397 return r;398 }399 } else {400 r = radeon_combios_init(rdev);401 if (r) {402 return r;403 }404 }405 /* Reset gpu before posting otherwise ATOM will enter infinite loop */406 if (radeon_asic_reset(rdev)) {407 dev_warn(rdev->dev,408 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",409 RREG32(R_000E40_RBBM_STATUS),410 RREG32(R_0007C0_CP_STAT));411 }412 /* check if cards are posted or not */413 if (radeon_boot_test_post_card(rdev) == false)414 return -EINVAL;415 416 /* Initialize clocks */417 radeon_get_clock_info(rdev_to_drm(rdev));418 /* initialize AGP */419 if (rdev->flags & RADEON_IS_AGP) {420 r = radeon_agp_init(rdev);421 if (r) {422 radeon_agp_disable(rdev);423 }424 }425 /* initialize memory controller */426 r300_mc_init(rdev);427 r420_debugfs(rdev);428 /* Fence driver */429 radeon_fence_driver_init(rdev);430 /* Memory manager */431 r = radeon_bo_init(rdev);432 if (r) {433 return r;434 }435 if (rdev->family == CHIP_R420)436 r100_enable_bm(rdev);437 438 if (rdev->flags & RADEON_IS_PCIE) {439 r = rv370_pcie_gart_init(rdev);440 if (r)441 return r;442 }443 if (rdev->flags & RADEON_IS_PCI) {444 r = r100_pci_gart_init(rdev);445 if (r)446 return r;447 }448 r420_set_reg_safe(rdev);449 450 /* Initialize power management */451 radeon_pm_init(rdev);452 453 rdev->accel_working = true;454 r = r420_startup(rdev);455 if (r) {456 /* Somethings want wront with the accel init stop accel */457 dev_err(rdev->dev, "Disabling GPU acceleration\n");458 r100_cp_fini(rdev);459 radeon_wb_fini(rdev);460 radeon_ib_pool_fini(rdev);461 radeon_irq_kms_fini(rdev);462 if (rdev->flags & RADEON_IS_PCIE)463 rv370_pcie_gart_fini(rdev);464 if (rdev->flags & RADEON_IS_PCI)465 r100_pci_gart_fini(rdev);466 radeon_agp_fini(rdev);467 rdev->accel_working = false;468 }469 return 0;470}471 472/*473 * Debugfs info474 */475#if defined(CONFIG_DEBUG_FS)476static int r420_debugfs_pipes_info_show(struct seq_file *m, void *unused)477{478 struct radeon_device *rdev = m->private;479 uint32_t tmp;480 481 tmp = RREG32(R400_GB_PIPE_SELECT);482 seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp);483 tmp = RREG32(R300_GB_TILE_CONFIG);484 seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp);485 tmp = RREG32(R300_DST_PIPE_CONFIG);486 seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp);487 return 0;488}489 490DEFINE_SHOW_ATTRIBUTE(r420_debugfs_pipes_info);491#endif492 493void r420_debugfs_pipes_info_init(struct radeon_device *rdev)494{495#if defined(CONFIG_DEBUG_FS)496 struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;497 498 debugfs_create_file("r420_pipes_info", 0444, root, rdev,499 &r420_debugfs_pipes_info_fops);500#endif501}502