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$"); 31254885Sdumbbell 32254885Sdumbbell#include <dev/drm2/drmP.h> 33254885Sdumbbell#include <dev/drm2/drm_crtc_helper.h> 34254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 35254885Sdumbbell#include "radeon_reg.h" 36254885Sdumbbell#include "radeon.h" 37254885Sdumbbell#include "atom.h" 38254885Sdumbbell 39254885Sdumbbellstatic const char radeon_family_name[][16] = { 40254885Sdumbbell "R100", 41254885Sdumbbell "RV100", 42254885Sdumbbell "RS100", 43254885Sdumbbell "RV200", 44254885Sdumbbell "RS200", 45254885Sdumbbell "R200", 46254885Sdumbbell "RV250", 47254885Sdumbbell "RS300", 48254885Sdumbbell "RV280", 49254885Sdumbbell "R300", 50254885Sdumbbell "R350", 51254885Sdumbbell "RV350", 52254885Sdumbbell "RV380", 53254885Sdumbbell "R420", 54254885Sdumbbell "R423", 55254885Sdumbbell "RV410", 56254885Sdumbbell "RS400", 57254885Sdumbbell "RS480", 58254885Sdumbbell "RS600", 59254885Sdumbbell "RS690", 60254885Sdumbbell "RS740", 61254885Sdumbbell "RV515", 62254885Sdumbbell "R520", 63254885Sdumbbell "RV530", 64254885Sdumbbell "RV560", 65254885Sdumbbell "RV570", 66254885Sdumbbell "R580", 67254885Sdumbbell "R600", 68254885Sdumbbell "RV610", 69254885Sdumbbell "RV630", 70254885Sdumbbell "RV670", 71254885Sdumbbell "RV620", 72254885Sdumbbell "RV635", 73254885Sdumbbell "RS780", 74254885Sdumbbell "RS880", 75254885Sdumbbell "RV770", 76254885Sdumbbell "RV730", 77254885Sdumbbell "RV710", 78254885Sdumbbell "RV740", 79254885Sdumbbell "CEDAR", 80254885Sdumbbell "REDWOOD", 81254885Sdumbbell "JUNIPER", 82254885Sdumbbell "CYPRESS", 83254885Sdumbbell "HEMLOCK", 84254885Sdumbbell "PALM", 85254885Sdumbbell "SUMO", 86254885Sdumbbell "SUMO2", 87254885Sdumbbell "BARTS", 88254885Sdumbbell "TURKS", 89254885Sdumbbell "CAICOS", 90254885Sdumbbell "CAYMAN", 91254885Sdumbbell "ARUBA", 92254885Sdumbbell "TAHITI", 93254885Sdumbbell "PITCAIRN", 94254885Sdumbbell "VERDE", 95254885Sdumbbell "LAST", 96254885Sdumbbell}; 97254885Sdumbbell 98254885Sdumbbell/** 99254885Sdumbbell * radeon_surface_init - Clear GPU surface registers. 100254885Sdumbbell * 101254885Sdumbbell * @rdev: radeon_device pointer 102254885Sdumbbell * 103254885Sdumbbell * Clear GPU surface registers (r1xx-r5xx). 104254885Sdumbbell */ 105254885Sdumbbellvoid radeon_surface_init(struct radeon_device *rdev) 106254885Sdumbbell{ 107254885Sdumbbell /* FIXME: check this out */ 108254885Sdumbbell if (rdev->family < CHIP_R600) { 109254885Sdumbbell int i; 110254885Sdumbbell 111254885Sdumbbell for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { 112254885Sdumbbell if (rdev->surface_regs[i].bo) 113254885Sdumbbell radeon_bo_get_surface_reg(rdev->surface_regs[i].bo); 114254885Sdumbbell else 115254885Sdumbbell radeon_clear_surface_reg(rdev, i); 116254885Sdumbbell } 117254885Sdumbbell /* enable surfaces */ 118254885Sdumbbell WREG32(RADEON_SURFACE_CNTL, 0); 119254885Sdumbbell } 120254885Sdumbbell} 121254885Sdumbbell 122254885Sdumbbell/* 123254885Sdumbbell * GPU scratch registers helpers function. 124254885Sdumbbell */ 125254885Sdumbbell/** 126254885Sdumbbell * radeon_scratch_init - Init scratch register driver information. 127254885Sdumbbell * 128254885Sdumbbell * @rdev: radeon_device pointer 129254885Sdumbbell * 130254885Sdumbbell * Init CP scratch register driver information (r1xx-r5xx) 131254885Sdumbbell */ 132254885Sdumbbellvoid radeon_scratch_init(struct radeon_device *rdev) 133254885Sdumbbell{ 134254885Sdumbbell int i; 135254885Sdumbbell 136254885Sdumbbell /* FIXME: check this out */ 137254885Sdumbbell if (rdev->family < CHIP_R300) { 138254885Sdumbbell rdev->scratch.num_reg = 5; 139254885Sdumbbell } else { 140254885Sdumbbell rdev->scratch.num_reg = 7; 141254885Sdumbbell } 142254885Sdumbbell rdev->scratch.reg_base = RADEON_SCRATCH_REG0; 143254885Sdumbbell for (i = 0; i < rdev->scratch.num_reg; i++) { 144254885Sdumbbell rdev->scratch.free[i] = true; 145254885Sdumbbell rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); 146254885Sdumbbell } 147254885Sdumbbell} 148254885Sdumbbell 149254885Sdumbbell/** 150254885Sdumbbell * radeon_scratch_get - Allocate a scratch register 151254885Sdumbbell * 152254885Sdumbbell * @rdev: radeon_device pointer 153254885Sdumbbell * @reg: scratch register mmio offset 154254885Sdumbbell * 155254885Sdumbbell * Allocate a CP scratch register for use by the driver (all asics). 156254885Sdumbbell * Returns 0 on success or -EINVAL on failure. 157254885Sdumbbell */ 158254885Sdumbbellint radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg) 159254885Sdumbbell{ 160254885Sdumbbell int i; 161254885Sdumbbell 162254885Sdumbbell for (i = 0; i < rdev->scratch.num_reg; i++) { 163254885Sdumbbell if (rdev->scratch.free[i]) { 164254885Sdumbbell rdev->scratch.free[i] = false; 165254885Sdumbbell *reg = rdev->scratch.reg[i]; 166254885Sdumbbell return 0; 167254885Sdumbbell } 168254885Sdumbbell } 169254885Sdumbbell return -EINVAL; 170254885Sdumbbell} 171254885Sdumbbell 172254885Sdumbbell/** 173254885Sdumbbell * radeon_scratch_free - Free a scratch register 174254885Sdumbbell * 175254885Sdumbbell * @rdev: radeon_device pointer 176254885Sdumbbell * @reg: scratch register mmio offset 177254885Sdumbbell * 178254885Sdumbbell * Free a CP scratch register allocated for use by the driver (all asics) 179254885Sdumbbell */ 180254885Sdumbbellvoid radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) 181254885Sdumbbell{ 182254885Sdumbbell int i; 183254885Sdumbbell 184254885Sdumbbell for (i = 0; i < rdev->scratch.num_reg; i++) { 185254885Sdumbbell if (rdev->scratch.reg[i] == reg) { 186254885Sdumbbell rdev->scratch.free[i] = true; 187254885Sdumbbell return; 188254885Sdumbbell } 189254885Sdumbbell } 190254885Sdumbbell} 191254885Sdumbbell 192254885Sdumbbell/* 193254885Sdumbbell * radeon_wb_*() 194254885Sdumbbell * Writeback is the the method by which the the GPU updates special pages 195254885Sdumbbell * in memory with the status of certain GPU events (fences, ring pointers, 196254885Sdumbbell * etc.). 197254885Sdumbbell */ 198254885Sdumbbell 199254885Sdumbbell/** 200254885Sdumbbell * radeon_wb_disable - Disable Writeback 201254885Sdumbbell * 202254885Sdumbbell * @rdev: radeon_device pointer 203254885Sdumbbell * 204254885Sdumbbell * Disables Writeback (all asics). Used for suspend. 205254885Sdumbbell */ 206254885Sdumbbellvoid radeon_wb_disable(struct radeon_device *rdev) 207254885Sdumbbell{ 208254885Sdumbbell int r; 209254885Sdumbbell 210254885Sdumbbell if (rdev->wb.wb_obj) { 211254885Sdumbbell r = radeon_bo_reserve(rdev->wb.wb_obj, false); 212254885Sdumbbell if (unlikely(r != 0)) 213254885Sdumbbell return; 214254885Sdumbbell radeon_bo_kunmap(rdev->wb.wb_obj); 215254885Sdumbbell radeon_bo_unpin(rdev->wb.wb_obj); 216254885Sdumbbell radeon_bo_unreserve(rdev->wb.wb_obj); 217254885Sdumbbell } 218254885Sdumbbell rdev->wb.enabled = false; 219254885Sdumbbell} 220254885Sdumbbell 221254885Sdumbbell/** 222254885Sdumbbell * radeon_wb_fini - Disable Writeback and free memory 223254885Sdumbbell * 224254885Sdumbbell * @rdev: radeon_device pointer 225254885Sdumbbell * 226254885Sdumbbell * Disables Writeback and frees the Writeback memory (all asics). 227254885Sdumbbell * Used at driver shutdown. 228254885Sdumbbell */ 229254885Sdumbbellvoid radeon_wb_fini(struct radeon_device *rdev) 230254885Sdumbbell{ 231254885Sdumbbell radeon_wb_disable(rdev); 232254885Sdumbbell if (rdev->wb.wb_obj) { 233254885Sdumbbell radeon_bo_unref(&rdev->wb.wb_obj); 234254885Sdumbbell rdev->wb.wb = NULL; 235254885Sdumbbell rdev->wb.wb_obj = NULL; 236254885Sdumbbell } 237254885Sdumbbell} 238254885Sdumbbell 239254885Sdumbbell/** 240254885Sdumbbell * radeon_wb_init- Init Writeback driver info and allocate memory 241254885Sdumbbell * 242254885Sdumbbell * @rdev: radeon_device pointer 243254885Sdumbbell * 244254885Sdumbbell * Disables Writeback and frees the Writeback memory (all asics). 245254885Sdumbbell * Used at driver startup. 246254885Sdumbbell * Returns 0 on success or an -error on failure. 247254885Sdumbbell */ 248254885Sdumbbellint radeon_wb_init(struct radeon_device *rdev) 249254885Sdumbbell{ 250254885Sdumbbell int r; 251254885Sdumbbell void *wb_ptr; 252254885Sdumbbell 253254885Sdumbbell if (rdev->wb.wb_obj == NULL) { 254254885Sdumbbell r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, 255254885Sdumbbell RADEON_GEM_DOMAIN_GTT, NULL, &rdev->wb.wb_obj); 256254885Sdumbbell if (r) { 257254885Sdumbbell dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); 258254885Sdumbbell return r; 259254885Sdumbbell } 260254885Sdumbbell } 261254885Sdumbbell r = radeon_bo_reserve(rdev->wb.wb_obj, false); 262254885Sdumbbell if (unlikely(r != 0)) { 263254885Sdumbbell radeon_wb_fini(rdev); 264254885Sdumbbell return r; 265254885Sdumbbell } 266254885Sdumbbell r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, 267254885Sdumbbell &rdev->wb.gpu_addr); 268254885Sdumbbell if (r) { 269254885Sdumbbell radeon_bo_unreserve(rdev->wb.wb_obj); 270254885Sdumbbell dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); 271254885Sdumbbell radeon_wb_fini(rdev); 272254885Sdumbbell return r; 273254885Sdumbbell } 274254885Sdumbbell wb_ptr = &rdev->wb.wb; 275254885Sdumbbell r = radeon_bo_kmap(rdev->wb.wb_obj, wb_ptr); 276254885Sdumbbell radeon_bo_unreserve(rdev->wb.wb_obj); 277254885Sdumbbell if (r) { 278254885Sdumbbell dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); 279254885Sdumbbell radeon_wb_fini(rdev); 280254885Sdumbbell return r; 281254885Sdumbbell } 282254885Sdumbbell 283254885Sdumbbell /* clear wb memory */ 284254885Sdumbbell memset(*(void **)wb_ptr, 0, RADEON_GPU_PAGE_SIZE); 285254885Sdumbbell /* disable event_write fences */ 286254885Sdumbbell rdev->wb.use_event = false; 287254885Sdumbbell /* disabled via module param */ 288254885Sdumbbell if (radeon_no_wb == 1) { 289254885Sdumbbell rdev->wb.enabled = false; 290254885Sdumbbell } else { 291254885Sdumbbell if (rdev->flags & RADEON_IS_AGP) { 292254885Sdumbbell /* often unreliable on AGP */ 293254885Sdumbbell rdev->wb.enabled = false; 294254885Sdumbbell } else if (rdev->family < CHIP_R300) { 295254885Sdumbbell /* often unreliable on pre-r300 */ 296254885Sdumbbell rdev->wb.enabled = false; 297254885Sdumbbell } else { 298254885Sdumbbell rdev->wb.enabled = true; 299254885Sdumbbell /* event_write fences are only available on r600+ */ 300254885Sdumbbell if (rdev->family >= CHIP_R600) { 301254885Sdumbbell rdev->wb.use_event = true; 302254885Sdumbbell } 303254885Sdumbbell } 304254885Sdumbbell } 305254885Sdumbbell /* always use writeback/events on NI, APUs */ 306254885Sdumbbell if (rdev->family >= CHIP_PALM) { 307254885Sdumbbell rdev->wb.enabled = true; 308254885Sdumbbell rdev->wb.use_event = true; 309254885Sdumbbell } 310254885Sdumbbell 311254885Sdumbbell dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis"); 312254885Sdumbbell 313254885Sdumbbell return 0; 314254885Sdumbbell} 315254885Sdumbbell 316254885Sdumbbell/** 317254885Sdumbbell * radeon_vram_location - try to find VRAM location 318254885Sdumbbell * @rdev: radeon device structure holding all necessary informations 319254885Sdumbbell * @mc: memory controller structure holding memory informations 320254885Sdumbbell * @base: base address at which to put VRAM 321254885Sdumbbell * 322254885Sdumbbell * Function will place try to place VRAM at base address provided 323254885Sdumbbell * as parameter (which is so far either PCI aperture address or 324254885Sdumbbell * for IGP TOM base address). 325254885Sdumbbell * 326254885Sdumbbell * If there is not enough space to fit the unvisible VRAM in the 32bits 327254885Sdumbbell * address space then we limit the VRAM size to the aperture. 328254885Sdumbbell * 329254885Sdumbbell * If we are using AGP and if the AGP aperture doesn't allow us to have 330254885Sdumbbell * room for all the VRAM than we restrict the VRAM to the PCI aperture 331254885Sdumbbell * size and print a warning. 332254885Sdumbbell * 333254885Sdumbbell * This function will never fails, worst case are limiting VRAM. 334254885Sdumbbell * 335254885Sdumbbell * Note: GTT start, end, size should be initialized before calling this 336254885Sdumbbell * function on AGP platform. 337254885Sdumbbell * 338254885Sdumbbell * Note: We don't explicitly enforce VRAM start to be aligned on VRAM size, 339254885Sdumbbell * this shouldn't be a problem as we are using the PCI aperture as a reference. 340254885Sdumbbell * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but 341254885Sdumbbell * not IGP. 342254885Sdumbbell * 343254885Sdumbbell * Note: we use mc_vram_size as on some board we need to program the mc to 344254885Sdumbbell * cover the whole aperture even if VRAM size is inferior to aperture size 345254885Sdumbbell * Novell bug 204882 + along with lots of ubuntu ones 346254885Sdumbbell * 347254885Sdumbbell * Note: when limiting vram it's safe to overwritte real_vram_size because 348254885Sdumbbell * we are not in case where real_vram_size is inferior to mc_vram_size (ie 349254885Sdumbbell * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu 350254885Sdumbbell * ones) 351254885Sdumbbell * 352254885Sdumbbell * Note: IGP TOM addr should be the same as the aperture addr, we don't 353254885Sdumbbell * explicitly check for that thought. 354254885Sdumbbell * 355254885Sdumbbell * FIXME: when reducing VRAM size align new size on power of 2. 356254885Sdumbbell */ 357254885Sdumbbellvoid radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) 358254885Sdumbbell{ 359254885Sdumbbell uint64_t limit = (uint64_t)radeon_vram_limit << 20; 360254885Sdumbbell 361254885Sdumbbell mc->vram_start = base; 362254885Sdumbbell if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { 363254885Sdumbbell dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); 364254885Sdumbbell mc->real_vram_size = mc->aper_size; 365254885Sdumbbell mc->mc_vram_size = mc->aper_size; 366254885Sdumbbell } 367254885Sdumbbell mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; 368254885Sdumbbell if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { 369254885Sdumbbell dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); 370254885Sdumbbell mc->real_vram_size = mc->aper_size; 371254885Sdumbbell mc->mc_vram_size = mc->aper_size; 372254885Sdumbbell } 373254885Sdumbbell mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; 374254885Sdumbbell if (limit && limit < mc->real_vram_size) 375254885Sdumbbell mc->real_vram_size = limit; 376254885Sdumbbell dev_info(rdev->dev, "VRAM: %juM 0x%016jX - 0x%016jX (%juM used)\n", 377254885Sdumbbell (uintmax_t)mc->mc_vram_size >> 20, (uintmax_t)mc->vram_start, 378254885Sdumbbell (uintmax_t)mc->vram_end, (uintmax_t)mc->real_vram_size >> 20); 379254885Sdumbbell} 380254885Sdumbbell 381254885Sdumbbell/** 382254885Sdumbbell * radeon_gtt_location - try to find GTT location 383254885Sdumbbell * @rdev: radeon device structure holding all necessary informations 384254885Sdumbbell * @mc: memory controller structure holding memory informations 385254885Sdumbbell * 386254885Sdumbbell * Function will place try to place GTT before or after VRAM. 387254885Sdumbbell * 388254885Sdumbbell * If GTT size is bigger than space left then we ajust GTT size. 389254885Sdumbbell * Thus function will never fails. 390254885Sdumbbell * 391254885Sdumbbell * FIXME: when reducing GTT size align new size on power of 2. 392254885Sdumbbell */ 393254885Sdumbbellvoid radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) 394254885Sdumbbell{ 395254885Sdumbbell u64 size_af, size_bf; 396254885Sdumbbell 397254885Sdumbbell size_af = ((0xFFFFFFFF - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align; 398254885Sdumbbell size_bf = mc->vram_start & ~mc->gtt_base_align; 399254885Sdumbbell if (size_bf > size_af) { 400254885Sdumbbell if (mc->gtt_size > size_bf) { 401254885Sdumbbell dev_warn(rdev->dev, "limiting GTT\n"); 402254885Sdumbbell mc->gtt_size = size_bf; 403254885Sdumbbell } 404254885Sdumbbell mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size; 405254885Sdumbbell } else { 406254885Sdumbbell if (mc->gtt_size > size_af) { 407254885Sdumbbell dev_warn(rdev->dev, "limiting GTT\n"); 408254885Sdumbbell mc->gtt_size = size_af; 409254885Sdumbbell } 410254885Sdumbbell mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; 411254885Sdumbbell } 412254885Sdumbbell mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; 413254885Sdumbbell dev_info(rdev->dev, "GTT: %juM 0x%016jX - 0x%016jX\n", 414254885Sdumbbell (uintmax_t)mc->gtt_size >> 20, (uintmax_t)mc->gtt_start, (uintmax_t)mc->gtt_end); 415254885Sdumbbell} 416254885Sdumbbell 417254885Sdumbbell/* 418254885Sdumbbell * GPU helpers function. 419254885Sdumbbell */ 420254885Sdumbbell/** 421254885Sdumbbell * radeon_card_posted - check if the hw has already been initialized 422254885Sdumbbell * 423254885Sdumbbell * @rdev: radeon_device pointer 424254885Sdumbbell * 425254885Sdumbbell * Check if the asic has been initialized (all asics). 426254885Sdumbbell * Used at driver startup. 427254885Sdumbbell * Returns true if initialized or false if not. 428254885Sdumbbell */ 429254885Sdumbbellbool radeon_card_posted(struct radeon_device *rdev) 430254885Sdumbbell{ 431254885Sdumbbell uint32_t reg; 432254885Sdumbbell 433254885Sdumbbell#ifdef DUMBBELL_WIP 434254885Sdumbbell if (efi_enabled(EFI_BOOT) && 435254885Sdumbbell rdev->dev->pci_subvendor == PCI_VENDOR_ID_APPLE) 436254885Sdumbbell return false; 437254885Sdumbbell#endif /* DUMBBELL_WIP */ 438254885Sdumbbell 439254885Sdumbbell /* first check CRTCs */ 440254885Sdumbbell if (ASIC_IS_DCE41(rdev)) { 441254885Sdumbbell reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | 442254885Sdumbbell RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); 443254885Sdumbbell if (reg & EVERGREEN_CRTC_MASTER_EN) 444254885Sdumbbell return true; 445254885Sdumbbell } else if (ASIC_IS_DCE4(rdev)) { 446254885Sdumbbell reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | 447254885Sdumbbell RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | 448254885Sdumbbell RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | 449254885Sdumbbell RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | 450254885Sdumbbell RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | 451254885Sdumbbell RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); 452254885Sdumbbell if (reg & EVERGREEN_CRTC_MASTER_EN) 453254885Sdumbbell return true; 454254885Sdumbbell } else if (ASIC_IS_AVIVO(rdev)) { 455254885Sdumbbell reg = RREG32(AVIVO_D1CRTC_CONTROL) | 456254885Sdumbbell RREG32(AVIVO_D2CRTC_CONTROL); 457254885Sdumbbell if (reg & AVIVO_CRTC_EN) { 458254885Sdumbbell return true; 459254885Sdumbbell } 460254885Sdumbbell } else { 461254885Sdumbbell reg = RREG32(RADEON_CRTC_GEN_CNTL) | 462254885Sdumbbell RREG32(RADEON_CRTC2_GEN_CNTL); 463254885Sdumbbell if (reg & RADEON_CRTC_EN) { 464254885Sdumbbell return true; 465254885Sdumbbell } 466254885Sdumbbell } 467254885Sdumbbell 468254885Sdumbbell /* then check MEM_SIZE, in case the crtcs are off */ 469254885Sdumbbell if (rdev->family >= CHIP_R600) 470254885Sdumbbell reg = RREG32(R600_CONFIG_MEMSIZE); 471254885Sdumbbell else 472254885Sdumbbell reg = RREG32(RADEON_CONFIG_MEMSIZE); 473254885Sdumbbell 474254885Sdumbbell if (reg) 475254885Sdumbbell return true; 476254885Sdumbbell 477254885Sdumbbell return false; 478254885Sdumbbell 479254885Sdumbbell} 480254885Sdumbbell 481254885Sdumbbell/** 482254885Sdumbbell * radeon_update_bandwidth_info - update display bandwidth params 483254885Sdumbbell * 484254885Sdumbbell * @rdev: radeon_device pointer 485254885Sdumbbell * 486254885Sdumbbell * Used when sclk/mclk are switched or display modes are set. 487254885Sdumbbell * params are used to calculate display watermarks (all asics) 488254885Sdumbbell */ 489254885Sdumbbellvoid radeon_update_bandwidth_info(struct radeon_device *rdev) 490254885Sdumbbell{ 491254885Sdumbbell fixed20_12 a; 492254885Sdumbbell u32 sclk = rdev->pm.current_sclk; 493254885Sdumbbell u32 mclk = rdev->pm.current_mclk; 494254885Sdumbbell 495254885Sdumbbell /* sclk/mclk in Mhz */ 496254885Sdumbbell a.full = dfixed_const(100); 497254885Sdumbbell rdev->pm.sclk.full = dfixed_const(sclk); 498254885Sdumbbell rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); 499254885Sdumbbell rdev->pm.mclk.full = dfixed_const(mclk); 500254885Sdumbbell rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); 501254885Sdumbbell 502254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) { 503254885Sdumbbell a.full = dfixed_const(16); 504254885Sdumbbell /* core_bandwidth = sclk(Mhz) * 16 */ 505254885Sdumbbell rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); 506254885Sdumbbell } 507254885Sdumbbell} 508254885Sdumbbell 509254885Sdumbbell/** 510254885Sdumbbell * radeon_boot_test_post_card - check and possibly initialize the hw 511254885Sdumbbell * 512254885Sdumbbell * @rdev: radeon_device pointer 513254885Sdumbbell * 514254885Sdumbbell * Check if the asic is initialized and if not, attempt to initialize 515254885Sdumbbell * it (all asics). 516254885Sdumbbell * Returns true if initialized or false if not. 517254885Sdumbbell */ 518254885Sdumbbellbool radeon_boot_test_post_card(struct radeon_device *rdev) 519254885Sdumbbell{ 520254885Sdumbbell if (radeon_card_posted(rdev)) 521254885Sdumbbell return true; 522254885Sdumbbell 523254885Sdumbbell if (rdev->bios) { 524254885Sdumbbell DRM_INFO("GPU not posted. posting now...\n"); 525254885Sdumbbell if (rdev->is_atom_bios) 526254885Sdumbbell atom_asic_init(rdev->mode_info.atom_context); 527254885Sdumbbell else 528254885Sdumbbell radeon_combios_asic_init(rdev->ddev); 529254885Sdumbbell return true; 530254885Sdumbbell } else { 531254885Sdumbbell dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 532254885Sdumbbell return false; 533254885Sdumbbell } 534254885Sdumbbell} 535254885Sdumbbell 536254885Sdumbbell/** 537254885Sdumbbell * radeon_dummy_page_init - init dummy page used by the driver 538254885Sdumbbell * 539254885Sdumbbell * @rdev: radeon_device pointer 540254885Sdumbbell * 541254885Sdumbbell * Allocate the dummy page used by the driver (all asics). 542254885Sdumbbell * This dummy page is used by the driver as a filler for gart entries 543254885Sdumbbell * when pages are taken out of the GART 544254885Sdumbbell * Returns 0 on sucess, -ENOMEM on failure. 545254885Sdumbbell */ 546254885Sdumbbellint radeon_dummy_page_init(struct radeon_device *rdev) 547254885Sdumbbell{ 548254885Sdumbbell if (rdev->dummy_page.dmah) 549254885Sdumbbell return 0; 550254885Sdumbbell rdev->dummy_page.dmah = drm_pci_alloc(rdev->ddev, 551267042Smarius PAGE_SIZE, PAGE_SIZE, BUS_SPACE_MAXSIZE_32BIT); 552254885Sdumbbell if (rdev->dummy_page.dmah == NULL) 553254885Sdumbbell return -ENOMEM; 554267042Smarius rdev->dummy_page.addr = rdev->dummy_page.dmah->busaddr; 555254885Sdumbbell return 0; 556254885Sdumbbell} 557254885Sdumbbell 558254885Sdumbbell/** 559254885Sdumbbell * radeon_dummy_page_fini - free dummy page used by the driver 560254885Sdumbbell * 561254885Sdumbbell * @rdev: radeon_device pointer 562254885Sdumbbell * 563254885Sdumbbell * Frees the dummy page used by the driver (all asics). 564254885Sdumbbell */ 565254885Sdumbbellvoid radeon_dummy_page_fini(struct radeon_device *rdev) 566254885Sdumbbell{ 567254885Sdumbbell if (rdev->dummy_page.dmah == NULL) 568254885Sdumbbell return; 569254885Sdumbbell drm_pci_free(rdev->ddev, rdev->dummy_page.dmah); 570254885Sdumbbell rdev->dummy_page.dmah = NULL; 571254885Sdumbbell rdev->dummy_page.addr = 0; 572254885Sdumbbell} 573254885Sdumbbell 574254885Sdumbbell 575254885Sdumbbell/* ATOM accessor methods */ 576254885Sdumbbell/* 577254885Sdumbbell * ATOM is an interpreted byte code stored in tables in the vbios. The 578254885Sdumbbell * driver registers callbacks to access registers and the interpreter 579254885Sdumbbell * in the driver parses the tables and executes then to program specific 580254885Sdumbbell * actions (set display modes, asic init, etc.). See radeon_atombios.c, 581254885Sdumbbell * atombios.h, and atom.c 582254885Sdumbbell */ 583254885Sdumbbell 584254885Sdumbbell/** 585254885Sdumbbell * cail_pll_read - read PLL register 586254885Sdumbbell * 587254885Sdumbbell * @info: atom card_info pointer 588254885Sdumbbell * @reg: PLL register offset 589254885Sdumbbell * 590254885Sdumbbell * Provides a PLL register accessor for the atom interpreter (r4xx+). 591254885Sdumbbell * Returns the value of the PLL register. 592254885Sdumbbell */ 593254885Sdumbbellstatic uint32_t cail_pll_read(struct card_info *info, uint32_t reg) 594254885Sdumbbell{ 595254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 596254885Sdumbbell uint32_t r; 597254885Sdumbbell 598254885Sdumbbell r = rdev->pll_rreg(rdev, reg); 599254885Sdumbbell return r; 600254885Sdumbbell} 601254885Sdumbbell 602254885Sdumbbell/** 603254885Sdumbbell * cail_pll_write - write PLL register 604254885Sdumbbell * 605254885Sdumbbell * @info: atom card_info pointer 606254885Sdumbbell * @reg: PLL register offset 607254885Sdumbbell * @val: value to write to the pll register 608254885Sdumbbell * 609254885Sdumbbell * Provides a PLL register accessor for the atom interpreter (r4xx+). 610254885Sdumbbell */ 611254885Sdumbbellstatic void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val) 612254885Sdumbbell{ 613254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 614254885Sdumbbell 615254885Sdumbbell rdev->pll_wreg(rdev, reg, val); 616254885Sdumbbell} 617254885Sdumbbell 618254885Sdumbbell/** 619254885Sdumbbell * cail_mc_read - read MC (Memory Controller) register 620254885Sdumbbell * 621254885Sdumbbell * @info: atom card_info pointer 622254885Sdumbbell * @reg: MC register offset 623254885Sdumbbell * 624254885Sdumbbell * Provides an MC register accessor for the atom interpreter (r4xx+). 625254885Sdumbbell * Returns the value of the MC register. 626254885Sdumbbell */ 627254885Sdumbbellstatic uint32_t cail_mc_read(struct card_info *info, uint32_t reg) 628254885Sdumbbell{ 629254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 630254885Sdumbbell uint32_t r; 631254885Sdumbbell 632254885Sdumbbell r = rdev->mc_rreg(rdev, reg); 633254885Sdumbbell return r; 634254885Sdumbbell} 635254885Sdumbbell 636254885Sdumbbell/** 637254885Sdumbbell * cail_mc_write - write MC (Memory Controller) register 638254885Sdumbbell * 639254885Sdumbbell * @info: atom card_info pointer 640254885Sdumbbell * @reg: MC register offset 641254885Sdumbbell * @val: value to write to the pll register 642254885Sdumbbell * 643254885Sdumbbell * Provides a MC register accessor for the atom interpreter (r4xx+). 644254885Sdumbbell */ 645254885Sdumbbellstatic void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) 646254885Sdumbbell{ 647254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 648254885Sdumbbell 649254885Sdumbbell rdev->mc_wreg(rdev, reg, val); 650254885Sdumbbell} 651254885Sdumbbell 652254885Sdumbbell/** 653254885Sdumbbell * cail_reg_write - write MMIO register 654254885Sdumbbell * 655254885Sdumbbell * @info: atom card_info pointer 656254885Sdumbbell * @reg: MMIO register offset 657254885Sdumbbell * @val: value to write to the pll register 658254885Sdumbbell * 659254885Sdumbbell * Provides a MMIO register accessor for the atom interpreter (r4xx+). 660254885Sdumbbell */ 661254885Sdumbbellstatic void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) 662254885Sdumbbell{ 663254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 664254885Sdumbbell 665254885Sdumbbell WREG32(reg*4, val); 666254885Sdumbbell} 667254885Sdumbbell 668254885Sdumbbell/** 669254885Sdumbbell * cail_reg_read - read MMIO register 670254885Sdumbbell * 671254885Sdumbbell * @info: atom card_info pointer 672254885Sdumbbell * @reg: MMIO register offset 673254885Sdumbbell * 674254885Sdumbbell * Provides an MMIO register accessor for the atom interpreter (r4xx+). 675254885Sdumbbell * Returns the value of the MMIO register. 676254885Sdumbbell */ 677254885Sdumbbellstatic uint32_t cail_reg_read(struct card_info *info, uint32_t reg) 678254885Sdumbbell{ 679254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 680254885Sdumbbell uint32_t r; 681254885Sdumbbell 682254885Sdumbbell r = RREG32(reg*4); 683254885Sdumbbell return r; 684254885Sdumbbell} 685254885Sdumbbell 686254885Sdumbbell/** 687254885Sdumbbell * cail_ioreg_write - write IO register 688254885Sdumbbell * 689254885Sdumbbell * @info: atom card_info pointer 690254885Sdumbbell * @reg: IO register offset 691254885Sdumbbell * @val: value to write to the pll register 692254885Sdumbbell * 693254885Sdumbbell * Provides a IO register accessor for the atom interpreter (r4xx+). 694254885Sdumbbell */ 695254885Sdumbbellstatic void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) 696254885Sdumbbell{ 697254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 698254885Sdumbbell 699254885Sdumbbell WREG32_IO(reg*4, val); 700254885Sdumbbell} 701254885Sdumbbell 702254885Sdumbbell/** 703254885Sdumbbell * cail_ioreg_read - read IO register 704254885Sdumbbell * 705254885Sdumbbell * @info: atom card_info pointer 706254885Sdumbbell * @reg: IO register offset 707254885Sdumbbell * 708254885Sdumbbell * Provides an IO register accessor for the atom interpreter (r4xx+). 709254885Sdumbbell * Returns the value of the IO register. 710254885Sdumbbell */ 711254885Sdumbbellstatic uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) 712254885Sdumbbell{ 713254885Sdumbbell struct radeon_device *rdev = info->dev->dev_private; 714254885Sdumbbell uint32_t r; 715254885Sdumbbell 716254885Sdumbbell r = RREG32_IO(reg*4); 717254885Sdumbbell return r; 718254885Sdumbbell} 719254885Sdumbbell 720254885Sdumbbell/** 721254885Sdumbbell * radeon_atombios_init - init the driver info and callbacks for atombios 722254885Sdumbbell * 723254885Sdumbbell * @rdev: radeon_device pointer 724254885Sdumbbell * 725254885Sdumbbell * Initializes the driver info and register access callbacks for the 726254885Sdumbbell * ATOM interpreter (r4xx+). 727254885Sdumbbell * Returns 0 on sucess, -ENOMEM on failure. 728254885Sdumbbell * Called at driver startup. 729254885Sdumbbell */ 730254885Sdumbbellint radeon_atombios_init(struct radeon_device *rdev) 731254885Sdumbbell{ 732254885Sdumbbell struct card_info *atom_card_info = 733254885Sdumbbell malloc(sizeof(struct card_info), 734254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 735254885Sdumbbell 736254885Sdumbbell if (!atom_card_info) 737254885Sdumbbell return -ENOMEM; 738254885Sdumbbell 739254885Sdumbbell rdev->mode_info.atom_card_info = atom_card_info; 740254885Sdumbbell atom_card_info->dev = rdev->ddev; 741254885Sdumbbell atom_card_info->reg_read = cail_reg_read; 742254885Sdumbbell atom_card_info->reg_write = cail_reg_write; 743254885Sdumbbell /* needed for iio ops */ 744254885Sdumbbell if (rdev->rio_mem) { 745254885Sdumbbell atom_card_info->ioreg_read = cail_ioreg_read; 746254885Sdumbbell atom_card_info->ioreg_write = cail_ioreg_write; 747254885Sdumbbell } else { 748254885Sdumbbell DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n"); 749254885Sdumbbell atom_card_info->ioreg_read = cail_reg_read; 750254885Sdumbbell atom_card_info->ioreg_write = cail_reg_write; 751254885Sdumbbell } 752254885Sdumbbell atom_card_info->mc_read = cail_mc_read; 753254885Sdumbbell atom_card_info->mc_write = cail_mc_write; 754254885Sdumbbell atom_card_info->pll_read = cail_pll_read; 755254885Sdumbbell atom_card_info->pll_write = cail_pll_write; 756254885Sdumbbell 757254885Sdumbbell rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); 758254885Sdumbbell sx_init(&rdev->mode_info.atom_context->mutex, 759254885Sdumbbell "drm__radeon_device__mode_info__atom_context__mutex"); 760254885Sdumbbell radeon_atom_initialize_bios_scratch_regs(rdev->ddev); 761254885Sdumbbell atom_allocate_fb_scratch(rdev->mode_info.atom_context); 762254885Sdumbbell return 0; 763254885Sdumbbell} 764254885Sdumbbell 765254885Sdumbbell/** 766254885Sdumbbell * radeon_atombios_fini - free the driver info and callbacks for atombios 767254885Sdumbbell * 768254885Sdumbbell * @rdev: radeon_device pointer 769254885Sdumbbell * 770254885Sdumbbell * Frees the driver info and register access callbacks for the ATOM 771254885Sdumbbell * interpreter (r4xx+). 772254885Sdumbbell * Called at driver shutdown. 773254885Sdumbbell */ 774254885Sdumbbellvoid radeon_atombios_fini(struct radeon_device *rdev) 775254885Sdumbbell{ 776254885Sdumbbell if (rdev->mode_info.atom_context) { 777254885Sdumbbell free(rdev->mode_info.atom_context->scratch, DRM_MEM_DRIVER); 778254885Sdumbbell atom_destroy(rdev->mode_info.atom_context); 779254885Sdumbbell } 780254885Sdumbbell free(rdev->mode_info.atom_card_info, DRM_MEM_DRIVER); 781254885Sdumbbell} 782254885Sdumbbell 783254885Sdumbbell/* COMBIOS */ 784254885Sdumbbell/* 785254885Sdumbbell * COMBIOS is the bios format prior to ATOM. It provides 786254885Sdumbbell * command tables similar to ATOM, but doesn't have a unified 787254885Sdumbbell * parser. See radeon_combios.c 788254885Sdumbbell */ 789254885Sdumbbell 790254885Sdumbbell/** 791254885Sdumbbell * radeon_combios_init - init the driver info for combios 792254885Sdumbbell * 793254885Sdumbbell * @rdev: radeon_device pointer 794254885Sdumbbell * 795254885Sdumbbell * Initializes the driver info for combios (r1xx-r3xx). 796254885Sdumbbell * Returns 0 on sucess. 797254885Sdumbbell * Called at driver startup. 798254885Sdumbbell */ 799254885Sdumbbellint radeon_combios_init(struct radeon_device *rdev) 800254885Sdumbbell{ 801254885Sdumbbell radeon_combios_initialize_bios_scratch_regs(rdev->ddev); 802254885Sdumbbell return 0; 803254885Sdumbbell} 804254885Sdumbbell 805254885Sdumbbell/** 806254885Sdumbbell * radeon_combios_fini - free the driver info for combios 807254885Sdumbbell * 808254885Sdumbbell * @rdev: radeon_device pointer 809254885Sdumbbell * 810254885Sdumbbell * Frees the driver info for combios (r1xx-r3xx). 811254885Sdumbbell * Called at driver shutdown. 812254885Sdumbbell */ 813254885Sdumbbellvoid radeon_combios_fini(struct radeon_device *rdev) 814254885Sdumbbell{ 815254885Sdumbbell} 816254885Sdumbbell 817254885Sdumbbell#ifdef DUMBBELL_WIP 818254885Sdumbbell/* if we get transitioned to only one device, take VGA back */ 819254885Sdumbbell/** 820254885Sdumbbell * radeon_vga_set_decode - enable/disable vga decode 821254885Sdumbbell * 822254885Sdumbbell * @cookie: radeon_device pointer 823254885Sdumbbell * @state: enable/disable vga decode 824254885Sdumbbell * 825254885Sdumbbell * Enable/disable vga decode (all asics). 826254885Sdumbbell * Returns VGA resource flags. 827254885Sdumbbell */ 828254885Sdumbbellstatic unsigned int radeon_vga_set_decode(void *cookie, bool state) 829254885Sdumbbell{ 830254885Sdumbbell struct radeon_device *rdev = cookie; 831254885Sdumbbell radeon_vga_set_state(rdev, state); 832254885Sdumbbell if (state) 833254885Sdumbbell return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | 834254885Sdumbbell VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 835254885Sdumbbell else 836254885Sdumbbell return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 837254885Sdumbbell} 838254885Sdumbbell#endif /* DUMBBELL_WIP */ 839254885Sdumbbell 840254885Sdumbbell/** 841254885Sdumbbell * radeon_check_pot_argument - check that argument is a power of two 842254885Sdumbbell * 843254885Sdumbbell * @arg: value to check 844254885Sdumbbell * 845254885Sdumbbell * Validates that a certain argument is a power of two (all asics). 846254885Sdumbbell * Returns true if argument is valid. 847254885Sdumbbell */ 848254885Sdumbbellstatic bool radeon_check_pot_argument(int arg) 849254885Sdumbbell{ 850254885Sdumbbell return (arg & (arg - 1)) == 0; 851254885Sdumbbell} 852254885Sdumbbell 853254885Sdumbbell/** 854254885Sdumbbell * radeon_check_arguments - validate module params 855254885Sdumbbell * 856254885Sdumbbell * @rdev: radeon_device pointer 857254885Sdumbbell * 858254885Sdumbbell * Validates certain module parameters and updates 859254885Sdumbbell * the associated values used by the driver (all asics). 860254885Sdumbbell */ 861254885Sdumbbellstatic void radeon_check_arguments(struct radeon_device *rdev) 862254885Sdumbbell{ 863254885Sdumbbell /* vramlimit must be a power of two */ 864254885Sdumbbell if (!radeon_check_pot_argument(radeon_vram_limit)) { 865254885Sdumbbell dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", 866254885Sdumbbell radeon_vram_limit); 867254885Sdumbbell radeon_vram_limit = 0; 868254885Sdumbbell } 869254885Sdumbbell 870254885Sdumbbell /* gtt size must be power of two and greater or equal to 32M */ 871254885Sdumbbell if (radeon_gart_size < 32) { 872254885Sdumbbell dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", 873254885Sdumbbell radeon_gart_size); 874254885Sdumbbell radeon_gart_size = 512; 875254885Sdumbbell 876254885Sdumbbell } else if (!radeon_check_pot_argument(radeon_gart_size)) { 877254885Sdumbbell dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", 878254885Sdumbbell radeon_gart_size); 879254885Sdumbbell radeon_gart_size = 512; 880254885Sdumbbell } 881254885Sdumbbell rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; 882254885Sdumbbell 883254885Sdumbbell /* AGP mode can only be -1, 1, 2, 4, 8 */ 884254885Sdumbbell switch (radeon_agpmode) { 885254885Sdumbbell case -1: 886254885Sdumbbell case 0: 887254885Sdumbbell case 1: 888254885Sdumbbell case 2: 889254885Sdumbbell case 4: 890254885Sdumbbell case 8: 891254885Sdumbbell break; 892254885Sdumbbell default: 893254885Sdumbbell dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: " 894254885Sdumbbell "-1, 0, 1, 2, 4, 8)\n", radeon_agpmode); 895254885Sdumbbell radeon_agpmode = 0; 896254885Sdumbbell break; 897254885Sdumbbell } 898254885Sdumbbell} 899254885Sdumbbell 900254885Sdumbbell/** 901254885Sdumbbell * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is 902254885Sdumbbell * needed for waking up. 903254885Sdumbbell * 904254885Sdumbbell * @pdev: pci dev pointer 905254885Sdumbbell */ 906254885Sdumbbell#ifdef DUMBBELL_WIP 907254885Sdumbbellstatic bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev) 908254885Sdumbbell{ 909254885Sdumbbell 910254885Sdumbbell /* 6600m in a macbook pro */ 911254885Sdumbbell if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE && 912254885Sdumbbell pdev->subsystem_device == 0x00e2) { 913254885Sdumbbell printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n"); 914254885Sdumbbell return true; 915254885Sdumbbell } 916254885Sdumbbell 917254885Sdumbbell return false; 918254885Sdumbbell} 919254885Sdumbbell#endif /* DUMBBELL_WIP */ 920254885Sdumbbell 921254885Sdumbbell/** 922254885Sdumbbell * radeon_switcheroo_set_state - set switcheroo state 923254885Sdumbbell * 924254885Sdumbbell * @pdev: pci dev pointer 925254885Sdumbbell * @state: vga switcheroo state 926254885Sdumbbell * 927254885Sdumbbell * Callback for the switcheroo driver. Suspends or resumes the 928254885Sdumbbell * the asics before or after it is powered up using ACPI methods. 929254885Sdumbbell */ 930254885Sdumbbell#ifdef DUMBBELL_WIP 931254885Sdumbbellstatic void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) 932254885Sdumbbell{ 933254885Sdumbbell struct drm_device *dev = pci_get_drvdata(pdev); 934254885Sdumbbell pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; 935254885Sdumbbell if (state == VGA_SWITCHEROO_ON) { 936254885Sdumbbell unsigned d3_delay = dev->pdev->d3_delay; 937254885Sdumbbell 938254885Sdumbbell printk(KERN_INFO "radeon: switched on\n"); 939254885Sdumbbell /* don't suspend or resume card normally */ 940254885Sdumbbell dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 941254885Sdumbbell 942254885Sdumbbell if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) 943254885Sdumbbell dev->pdev->d3_delay = 20; 944254885Sdumbbell 945254885Sdumbbell radeon_resume_kms(dev); 946254885Sdumbbell 947254885Sdumbbell dev->pdev->d3_delay = d3_delay; 948254885Sdumbbell 949254885Sdumbbell dev->switch_power_state = DRM_SWITCH_POWER_ON; 950254885Sdumbbell drm_kms_helper_poll_enable(dev); 951254885Sdumbbell } else { 952254885Sdumbbell printk(KERN_INFO "radeon: switched off\n"); 953254885Sdumbbell drm_kms_helper_poll_disable(dev); 954254885Sdumbbell dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 955254885Sdumbbell radeon_suspend_kms(dev, pmm); 956254885Sdumbbell dev->switch_power_state = DRM_SWITCH_POWER_OFF; 957254885Sdumbbell } 958254885Sdumbbell} 959254885Sdumbbell#endif /* DUMBBELL_WIP */ 960254885Sdumbbell 961254885Sdumbbell/** 962254885Sdumbbell * radeon_switcheroo_can_switch - see if switcheroo state can change 963254885Sdumbbell * 964254885Sdumbbell * @pdev: pci dev pointer 965254885Sdumbbell * 966254885Sdumbbell * Callback for the switcheroo driver. Check of the switcheroo 967254885Sdumbbell * state can be changed. 968254885Sdumbbell * Returns true if the state can be changed, false if not. 969254885Sdumbbell */ 970254885Sdumbbell#ifdef DUMBBELL_WIP 971254885Sdumbbellstatic bool radeon_switcheroo_can_switch(struct pci_dev *pdev) 972254885Sdumbbell{ 973254885Sdumbbell struct drm_device *dev = pci_get_drvdata(pdev); 974254885Sdumbbell bool can_switch; 975254885Sdumbbell 976254885Sdumbbell spin_lock(&dev->count_lock); 977254885Sdumbbell can_switch = (dev->open_count == 0); 978254885Sdumbbell spin_unlock(&dev->count_lock); 979254885Sdumbbell return can_switch; 980254885Sdumbbell} 981254885Sdumbbell 982254885Sdumbbellstatic const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { 983254885Sdumbbell .set_gpu_state = radeon_switcheroo_set_state, 984254885Sdumbbell .reprobe = NULL, 985254885Sdumbbell .can_switch = radeon_switcheroo_can_switch, 986254885Sdumbbell}; 987254885Sdumbbell#endif /* DUMBBELL_WIP */ 988254885Sdumbbell 989254885Sdumbbell/** 990254885Sdumbbell * radeon_device_init - initialize the driver 991254885Sdumbbell * 992254885Sdumbbell * @rdev: radeon_device pointer 993254885Sdumbbell * @pdev: drm dev pointer 994254885Sdumbbell * @flags: driver flags 995254885Sdumbbell * 996254885Sdumbbell * Initializes the driver info and hw (all asics). 997254885Sdumbbell * Returns 0 for success or an error on failure. 998254885Sdumbbell * Called at driver startup. 999254885Sdumbbell */ 1000254885Sdumbbellint radeon_device_init(struct radeon_device *rdev, 1001254885Sdumbbell struct drm_device *ddev, 1002254885Sdumbbell uint32_t flags) 1003254885Sdumbbell{ 1004254885Sdumbbell int r, i; 1005254885Sdumbbell int dma_bits; 1006254885Sdumbbell 1007254885Sdumbbell rdev->shutdown = false; 1008254885Sdumbbell rdev->dev = ddev->device; 1009254885Sdumbbell rdev->ddev = ddev; 1010254885Sdumbbell rdev->flags = flags; 1011254885Sdumbbell rdev->family = flags & RADEON_FAMILY_MASK; 1012254885Sdumbbell rdev->is_atom_bios = false; 1013254885Sdumbbell rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; 1014254885Sdumbbell rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; 1015254885Sdumbbell rdev->accel_working = false; 1016254885Sdumbbell rdev->fictitious_range_registered = false; 1017254885Sdumbbell /* set up ring ids */ 1018254885Sdumbbell for (i = 0; i < RADEON_NUM_RINGS; i++) { 1019254885Sdumbbell rdev->ring[i].idx = i; 1020254885Sdumbbell } 1021254885Sdumbbell 1022254885Sdumbbell DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", 1023254885Sdumbbell radeon_family_name[rdev->family], ddev->pci_vendor, ddev->pci_device, 1024254885Sdumbbell ddev->pci_subvendor, ddev->pci_subdevice); 1025254885Sdumbbell 1026254885Sdumbbell /* mutex initialization are all done here so we 1027254885Sdumbbell * can recall function without having locking issues */ 1028254885Sdumbbell sx_init(&rdev->ring_lock, "drm__radeon_device__ring_lock"); 1029254885Sdumbbell sx_init(&rdev->dc_hw_i2c_mutex, "drm__radeon_device__dc_hw_i2c_mutex"); 1030254885Sdumbbell atomic_set(&rdev->ih.lock, 0); 1031254885Sdumbbell sx_init(&rdev->gem.mutex, "drm__radeon_device__gem__mutex"); 1032254885Sdumbbell sx_init(&rdev->pm.mutex, "drm__radeon_device__pm__mutex"); 1033254885Sdumbbell sx_init(&rdev->gpu_clock_mutex, "drm__radeon_device__gpu_clock_mutex"); 1034254885Sdumbbell sx_init(&rdev->pm.mclk_lock, "drm__radeon_device__pm__mclk_lock"); 1035254885Sdumbbell sx_init(&rdev->exclusive_lock, "drm__radeon_device__exclusive_lock"); 1036254885Sdumbbell DRM_INIT_WAITQUEUE(&rdev->irq.vblank_queue); 1037254885Sdumbbell r = radeon_gem_init(rdev); 1038254885Sdumbbell if (r) 1039254885Sdumbbell return r; 1040254885Sdumbbell /* initialize vm here */ 1041254885Sdumbbell sx_init(&rdev->vm_manager.lock, "drm__radeon_device__vm_manager__lock"); 1042254885Sdumbbell /* Adjust VM size here. 1043254885Sdumbbell * Currently set to 4GB ((1 << 20) 4k pages). 1044254885Sdumbbell * Max GPUVM size for cayman and SI is 40 bits. 1045254885Sdumbbell */ 1046254885Sdumbbell rdev->vm_manager.max_pfn = 1 << 20; 1047254885Sdumbbell INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); 1048254885Sdumbbell 1049254885Sdumbbell /* Set asic functions */ 1050254885Sdumbbell r = radeon_asic_init(rdev); 1051254885Sdumbbell if (r) 1052254885Sdumbbell return r; 1053254885Sdumbbell radeon_check_arguments(rdev); 1054254885Sdumbbell 1055254885Sdumbbell /* all of the newer IGP chips have an internal gart 1056254885Sdumbbell * However some rs4xx report as AGP, so remove that here. 1057254885Sdumbbell */ 1058254885Sdumbbell if ((rdev->family >= CHIP_RS400) && 1059254885Sdumbbell (rdev->flags & RADEON_IS_IGP)) { 1060254885Sdumbbell rdev->flags &= ~RADEON_IS_AGP; 1061254885Sdumbbell } 1062254885Sdumbbell 1063254885Sdumbbell if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { 1064254885Sdumbbell radeon_agp_disable(rdev); 1065254885Sdumbbell } 1066254885Sdumbbell 1067254885Sdumbbell /* set DMA mask + need_dma32 flags. 1068254885Sdumbbell * PCIE - can handle 40-bits. 1069254885Sdumbbell * IGP - can handle 40-bits 1070254885Sdumbbell * AGP - generally dma32 is safest 1071254885Sdumbbell * PCI - dma32 for legacy pci gart, 40 bits on newer asics 1072254885Sdumbbell */ 1073254885Sdumbbell rdev->need_dma32 = false; 1074254885Sdumbbell if (rdev->flags & RADEON_IS_AGP) 1075254885Sdumbbell rdev->need_dma32 = true; 1076254885Sdumbbell if ((rdev->flags & RADEON_IS_PCI) && 1077254885Sdumbbell (rdev->family <= CHIP_RS740)) 1078254885Sdumbbell rdev->need_dma32 = true; 1079254885Sdumbbell 1080254885Sdumbbell dma_bits = rdev->need_dma32 ? 32 : 40; 1081254885Sdumbbell#ifdef DUMBBELL_WIP 1082254885Sdumbbell r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); 1083254885Sdumbbell if (r) { 1084254885Sdumbbell rdev->need_dma32 = true; 1085254885Sdumbbell dma_bits = 32; 1086254885Sdumbbell printk(KERN_WARNING "radeon: No suitable DMA available.\n"); 1087254885Sdumbbell } 1088254885Sdumbbell r = pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); 1089254885Sdumbbell if (r) { 1090254885Sdumbbell pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(32)); 1091254885Sdumbbell printk(KERN_WARNING "radeon: No coherent DMA available.\n"); 1092254885Sdumbbell } 1093254885Sdumbbell#endif /* DUMBBELL_WIP */ 1094254885Sdumbbell 1095254885Sdumbbell /* Registers mapping */ 1096254885Sdumbbell /* TODO: block userspace mapping of io register */ 1097254885Sdumbbell DRM_SPININIT(&rdev->mmio_idx_lock, "drm__radeon_device__mmio_idx_lock"); 1098254885Sdumbbell rdev->rmmio_rid = PCIR_BAR(2); 1099254885Sdumbbell rdev->rmmio = bus_alloc_resource_any(rdev->dev, SYS_RES_MEMORY, 1100254885Sdumbbell &rdev->rmmio_rid, RF_ACTIVE | RF_SHAREABLE); 1101254885Sdumbbell if (rdev->rmmio == NULL) { 1102254885Sdumbbell return -ENOMEM; 1103254885Sdumbbell } 1104254885Sdumbbell rdev->rmmio_base = rman_get_start(rdev->rmmio); 1105254885Sdumbbell rdev->rmmio_size = rman_get_size(rdev->rmmio); 1106254885Sdumbbell DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); 1107254885Sdumbbell DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); 1108254885Sdumbbell 1109254885Sdumbbell /* io port mapping */ 1110254885Sdumbbell for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { 1111254885Sdumbbell uint32_t data; 1112254885Sdumbbell 1113254885Sdumbbell data = pci_read_config(rdev->dev, PCIR_BAR(i), 4); 1114254885Sdumbbell if (PCI_BAR_IO(data)) { 1115254885Sdumbbell rdev->rio_rid = PCIR_BAR(i); 1116254885Sdumbbell rdev->rio_mem = bus_alloc_resource_any(rdev->dev, 1117254885Sdumbbell SYS_RES_IOPORT, &rdev->rio_rid, 1118254885Sdumbbell RF_ACTIVE | RF_SHAREABLE); 1119254885Sdumbbell break; 1120254885Sdumbbell } 1121254885Sdumbbell } 1122254885Sdumbbell if (rdev->rio_mem == NULL) 1123254885Sdumbbell DRM_ERROR("Unable to find PCI I/O BAR\n"); 1124254885Sdumbbell 1125254885Sdumbbell rdev->tq = taskqueue_create("radeonkms", M_WAITOK, 1126254885Sdumbbell taskqueue_thread_enqueue, &rdev->tq); 1127254885Sdumbbell taskqueue_start_threads(&rdev->tq, 1, PWAIT, "radeon taskq"); 1128254885Sdumbbell 1129254885Sdumbbell#ifdef DUMBBELL_WIP 1130254885Sdumbbell /* if we have > 1 VGA cards, then disable the radeon VGA resources */ 1131254885Sdumbbell /* this will fail for cards that aren't VGA class devices, just 1132254885Sdumbbell * ignore it */ 1133254885Sdumbbell vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); 1134254885Sdumbbell vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops); 1135254885Sdumbbell#endif /* DUMBBELL_WIP */ 1136254885Sdumbbell 1137254885Sdumbbell r = radeon_init(rdev); 1138254885Sdumbbell if (r) 1139254885Sdumbbell return r; 1140254885Sdumbbell 1141254885Sdumbbell r = radeon_ib_ring_tests(rdev); 1142254885Sdumbbell if (r) 1143254885Sdumbbell DRM_ERROR("ib ring test failed (%d).\n", r); 1144254885Sdumbbell 1145254885Sdumbbell if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { 1146254885Sdumbbell /* Acceleration not working on AGP card try again 1147254885Sdumbbell * with fallback to PCI or PCIE GART 1148254885Sdumbbell */ 1149254885Sdumbbell radeon_asic_reset(rdev); 1150254885Sdumbbell radeon_fini(rdev); 1151254885Sdumbbell radeon_agp_disable(rdev); 1152254885Sdumbbell r = radeon_init(rdev); 1153254885Sdumbbell if (r) 1154254885Sdumbbell return r; 1155254885Sdumbbell } 1156254885Sdumbbell 1157254885Sdumbbell DRM_INFO("%s: Taking over the fictitious range 0x%jx-0x%jx\n", 1158254885Sdumbbell __func__, (uintmax_t)rdev->mc.aper_base, 1159254885Sdumbbell (uintmax_t)rdev->mc.aper_base + rdev->mc.visible_vram_size); 1160254885Sdumbbell r = vm_phys_fictitious_reg_range( 1161254885Sdumbbell rdev->mc.aper_base, 1162254885Sdumbbell rdev->mc.aper_base + rdev->mc.visible_vram_size, 1163254885Sdumbbell VM_MEMATTR_WRITE_COMBINING); 1164254885Sdumbbell if (r != 0) { 1165254885Sdumbbell DRM_ERROR("Failed to register fictitious range " 1166254885Sdumbbell "0x%jx-0x%jx (%d).\n", (uintmax_t)rdev->mc.aper_base, 1167254885Sdumbbell (uintmax_t)rdev->mc.aper_base + rdev->mc.visible_vram_size, r); 1168254885Sdumbbell return (-r); 1169254885Sdumbbell } 1170254885Sdumbbell rdev->fictitious_range_registered = true; 1171254885Sdumbbell 1172254885Sdumbbell if ((radeon_testing & 1)) { 1173254885Sdumbbell radeon_test_moves(rdev); 1174254885Sdumbbell } 1175254885Sdumbbell if ((radeon_testing & 2)) { 1176254885Sdumbbell radeon_test_syncing(rdev); 1177254885Sdumbbell } 1178254885Sdumbbell if (radeon_benchmarking) { 1179254885Sdumbbell radeon_benchmark(rdev, radeon_benchmarking); 1180254885Sdumbbell } 1181254885Sdumbbell return 0; 1182254885Sdumbbell} 1183254885Sdumbbell 1184254885Sdumbbell#ifdef DUMBBELL_WIP 1185254885Sdumbbellstatic void radeon_debugfs_remove_files(struct radeon_device *rdev); 1186254885Sdumbbell#endif /* DUMBBELL_WIP */ 1187254885Sdumbbell 1188254885Sdumbbell/** 1189254885Sdumbbell * radeon_device_fini - tear down the driver 1190254885Sdumbbell * 1191254885Sdumbbell * @rdev: radeon_device pointer 1192254885Sdumbbell * 1193254885Sdumbbell * Tear down the driver info (all asics). 1194254885Sdumbbell * Called at driver shutdown. 1195254885Sdumbbell */ 1196254885Sdumbbellvoid radeon_device_fini(struct radeon_device *rdev) 1197254885Sdumbbell{ 1198254885Sdumbbell DRM_INFO("radeon: finishing device.\n"); 1199254885Sdumbbell rdev->shutdown = true; 1200254885Sdumbbell /* evict vram memory */ 1201254885Sdumbbell radeon_bo_evict_vram(rdev); 1202254885Sdumbbell 1203254885Sdumbbell if (rdev->fictitious_range_registered) { 1204254885Sdumbbell vm_phys_fictitious_unreg_range( 1205254885Sdumbbell rdev->mc.aper_base, 1206254885Sdumbbell rdev->mc.aper_base + rdev->mc.visible_vram_size); 1207254885Sdumbbell } 1208254885Sdumbbell 1209254885Sdumbbell radeon_fini(rdev); 1210254885Sdumbbell#ifdef DUMBBELL_WIP 1211254885Sdumbbell vga_switcheroo_unregister_client(rdev->pdev); 1212254885Sdumbbell vga_client_register(rdev->pdev, NULL, NULL, NULL); 1213254885Sdumbbell#endif /* DUMBBELL_WIP */ 1214254885Sdumbbell 1215254885Sdumbbell if (rdev->tq != NULL) { 1216254885Sdumbbell taskqueue_free(rdev->tq); 1217254885Sdumbbell rdev->tq = NULL; 1218254885Sdumbbell } 1219254885Sdumbbell 1220254885Sdumbbell if (rdev->rio_mem) 1221254885Sdumbbell bus_release_resource(rdev->dev, SYS_RES_IOPORT, rdev->rio_rid, 1222254885Sdumbbell rdev->rio_mem); 1223254885Sdumbbell rdev->rio_mem = NULL; 1224254885Sdumbbell bus_release_resource(rdev->dev, SYS_RES_MEMORY, rdev->rmmio_rid, 1225254885Sdumbbell rdev->rmmio); 1226254885Sdumbbell rdev->rmmio = NULL; 1227254885Sdumbbell#ifdef DUMBBELL_WIP 1228254885Sdumbbell radeon_debugfs_remove_files(rdev); 1229254885Sdumbbell#endif /* DUMBBELL_WIP */ 1230254885Sdumbbell} 1231254885Sdumbbell 1232254885Sdumbbell 1233254885Sdumbbell/* 1234254885Sdumbbell * Suspend & resume. 1235254885Sdumbbell */ 1236254885Sdumbbell/** 1237254885Sdumbbell * radeon_suspend_kms - initiate device suspend 1238254885Sdumbbell * 1239254885Sdumbbell * @pdev: drm dev pointer 1240254885Sdumbbell * @state: suspend state 1241254885Sdumbbell * 1242254885Sdumbbell * Puts the hw in the suspend state (all asics). 1243254885Sdumbbell * Returns 0 for success or an error on failure. 1244254885Sdumbbell * Called at driver suspend. 1245254885Sdumbbell */ 1246254885Sdumbbellint radeon_suspend_kms(struct drm_device *dev) 1247254885Sdumbbell{ 1248254885Sdumbbell struct radeon_device *rdev; 1249254885Sdumbbell struct drm_crtc *crtc; 1250254885Sdumbbell struct drm_connector *connector; 1251254885Sdumbbell int i, r; 1252254885Sdumbbell bool force_completion = false; 1253254885Sdumbbell 1254254885Sdumbbell if (dev == NULL || dev->dev_private == NULL) { 1255254885Sdumbbell return -ENODEV; 1256254885Sdumbbell } 1257254885Sdumbbell#ifdef DUMBBELL_WIP 1258254885Sdumbbell if (state.event == PM_EVENT_PRETHAW) { 1259254885Sdumbbell return 0; 1260254885Sdumbbell } 1261254885Sdumbbell#endif /* DUMBBELL_WIP */ 1262254885Sdumbbell rdev = dev->dev_private; 1263254885Sdumbbell 1264254885Sdumbbell if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 1265254885Sdumbbell return 0; 1266254885Sdumbbell 1267254885Sdumbbell drm_kms_helper_poll_disable(dev); 1268254885Sdumbbell 1269254885Sdumbbell /* turn off display hw */ 1270254885Sdumbbell list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1271254885Sdumbbell drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); 1272254885Sdumbbell } 1273254885Sdumbbell 1274254885Sdumbbell /* unpin the front buffers */ 1275254885Sdumbbell list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1276254885Sdumbbell struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); 1277254885Sdumbbell struct radeon_bo *robj; 1278254885Sdumbbell 1279254885Sdumbbell if (rfb == NULL || rfb->obj == NULL) { 1280254885Sdumbbell continue; 1281254885Sdumbbell } 1282254885Sdumbbell robj = gem_to_radeon_bo(rfb->obj); 1283254885Sdumbbell /* don't unpin kernel fb objects */ 1284254885Sdumbbell if (!radeon_fbdev_robj_is_fb(rdev, robj)) { 1285254885Sdumbbell r = radeon_bo_reserve(robj, false); 1286254885Sdumbbell if (r == 0) { 1287254885Sdumbbell radeon_bo_unpin(robj); 1288254885Sdumbbell radeon_bo_unreserve(robj); 1289254885Sdumbbell } 1290254885Sdumbbell } 1291254885Sdumbbell } 1292254885Sdumbbell /* evict vram memory */ 1293254885Sdumbbell radeon_bo_evict_vram(rdev); 1294254885Sdumbbell 1295254885Sdumbbell sx_xlock(&rdev->ring_lock); 1296254885Sdumbbell /* wait for gpu to finish processing current batch */ 1297254885Sdumbbell for (i = 0; i < RADEON_NUM_RINGS; i++) { 1298254885Sdumbbell r = radeon_fence_wait_empty_locked(rdev, i); 1299254885Sdumbbell if (r) { 1300254885Sdumbbell /* delay GPU reset to resume */ 1301254885Sdumbbell force_completion = true; 1302254885Sdumbbell } 1303254885Sdumbbell } 1304254885Sdumbbell if (force_completion) { 1305254885Sdumbbell radeon_fence_driver_force_completion(rdev); 1306254885Sdumbbell } 1307254885Sdumbbell sx_xunlock(&rdev->ring_lock); 1308254885Sdumbbell 1309254885Sdumbbell radeon_save_bios_scratch_regs(rdev); 1310254885Sdumbbell 1311254885Sdumbbell radeon_pm_suspend(rdev); 1312254885Sdumbbell radeon_suspend(rdev); 1313254885Sdumbbell radeon_hpd_fini(rdev); 1314254885Sdumbbell /* evict remaining vram memory */ 1315254885Sdumbbell radeon_bo_evict_vram(rdev); 1316254885Sdumbbell 1317254885Sdumbbell radeon_agp_suspend(rdev); 1318254885Sdumbbell 1319255573Sdumbbell pci_save_state(device_get_parent(rdev->dev)); 1320254885Sdumbbell#ifdef DUMBBELL_WIP 1321254885Sdumbbell if (state.event == PM_EVENT_SUSPEND) { 1322254885Sdumbbell /* Shut down the device */ 1323254885Sdumbbell pci_disable_device(dev->pdev); 1324254885Sdumbbell#endif /* DUMBBELL_WIP */ 1325254885Sdumbbell pci_set_powerstate(dev->device, PCI_POWERSTATE_D3); 1326254885Sdumbbell#ifdef DUMBBELL_WIP 1327254885Sdumbbell } 1328254885Sdumbbell console_lock(); 1329254885Sdumbbell#endif /* DUMBBELL_WIP */ 1330254885Sdumbbell radeon_fbdev_set_suspend(rdev, 1); 1331254885Sdumbbell#ifdef DUMBBELL_WIP 1332254885Sdumbbell console_unlock(); 1333254885Sdumbbell#endif /* DUMBBELL_WIP */ 1334254885Sdumbbell return 0; 1335254885Sdumbbell} 1336254885Sdumbbell 1337254885Sdumbbell/** 1338254885Sdumbbell * radeon_resume_kms - initiate device resume 1339254885Sdumbbell * 1340254885Sdumbbell * @pdev: drm dev pointer 1341254885Sdumbbell * 1342254885Sdumbbell * Bring the hw back to operating state (all asics). 1343254885Sdumbbell * Returns 0 for success or an error on failure. 1344254885Sdumbbell * Called at driver resume. 1345254885Sdumbbell */ 1346254885Sdumbbellint radeon_resume_kms(struct drm_device *dev) 1347254885Sdumbbell{ 1348254885Sdumbbell struct drm_connector *connector; 1349254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1350254885Sdumbbell int r; 1351254885Sdumbbell 1352254885Sdumbbell if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 1353254885Sdumbbell return 0; 1354254885Sdumbbell 1355254885Sdumbbell#ifdef DUMBBELL_WIP 1356254885Sdumbbell console_lock(); 1357254885Sdumbbell#endif /* DUMBBELL_WIP */ 1358254885Sdumbbell pci_set_powerstate(dev->device, PCI_POWERSTATE_D0); 1359255573Sdumbbell pci_restore_state(device_get_parent(rdev->dev)); 1360254885Sdumbbell#ifdef DUMBBELL_WIP 1361254885Sdumbbell if (pci_enable_device(dev->pdev)) { 1362254885Sdumbbell console_unlock(); 1363254885Sdumbbell return -1; 1364254885Sdumbbell } 1365254885Sdumbbell#endif /* DUMBBELL_WIP */ 1366254885Sdumbbell /* resume AGP if in use */ 1367254885Sdumbbell radeon_agp_resume(rdev); 1368254885Sdumbbell radeon_resume(rdev); 1369254885Sdumbbell 1370254885Sdumbbell r = radeon_ib_ring_tests(rdev); 1371254885Sdumbbell if (r) 1372254885Sdumbbell DRM_ERROR("ib ring test failed (%d).\n", r); 1373254885Sdumbbell 1374254885Sdumbbell radeon_pm_resume(rdev); 1375254885Sdumbbell radeon_restore_bios_scratch_regs(rdev); 1376254885Sdumbbell 1377254885Sdumbbell radeon_fbdev_set_suspend(rdev, 0); 1378254885Sdumbbell#ifdef DUMBBELL_WIP 1379254885Sdumbbell console_unlock(); 1380254885Sdumbbell#endif /* DUMBBELL_WIP */ 1381254885Sdumbbell 1382254885Sdumbbell /* init dig PHYs, disp eng pll */ 1383254885Sdumbbell if (rdev->is_atom_bios) { 1384254885Sdumbbell radeon_atom_encoder_init(rdev); 1385254885Sdumbbell radeon_atom_disp_eng_pll_init(rdev); 1386254885Sdumbbell /* turn on the BL */ 1387254885Sdumbbell if (rdev->mode_info.bl_encoder) { 1388254885Sdumbbell u8 bl_level = radeon_get_backlight_level(rdev, 1389254885Sdumbbell rdev->mode_info.bl_encoder); 1390254885Sdumbbell radeon_set_backlight_level(rdev, rdev->mode_info.bl_encoder, 1391254885Sdumbbell bl_level); 1392254885Sdumbbell } 1393254885Sdumbbell } 1394254885Sdumbbell /* reset hpd state */ 1395254885Sdumbbell radeon_hpd_init(rdev); 1396254885Sdumbbell /* blat the mode back in */ 1397254885Sdumbbell drm_helper_resume_force_mode(dev); 1398254885Sdumbbell /* turn on display hw */ 1399254885Sdumbbell list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1400254885Sdumbbell drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); 1401254885Sdumbbell } 1402254885Sdumbbell 1403254885Sdumbbell drm_kms_helper_poll_enable(dev); 1404254885Sdumbbell return 0; 1405254885Sdumbbell} 1406254885Sdumbbell 1407254885Sdumbbell/** 1408254885Sdumbbell * radeon_gpu_reset - reset the asic 1409254885Sdumbbell * 1410254885Sdumbbell * @rdev: radeon device pointer 1411254885Sdumbbell * 1412254885Sdumbbell * Attempt the reset the GPU if it has hung (all asics). 1413254885Sdumbbell * Returns 0 for success or an error on failure. 1414254885Sdumbbell */ 1415254885Sdumbbellint radeon_gpu_reset(struct radeon_device *rdev) 1416254885Sdumbbell{ 1417254885Sdumbbell unsigned ring_sizes[RADEON_NUM_RINGS]; 1418254885Sdumbbell uint32_t *ring_data[RADEON_NUM_RINGS]; 1419254885Sdumbbell 1420254885Sdumbbell bool saved = false; 1421254885Sdumbbell 1422254885Sdumbbell int i, r; 1423254885Sdumbbell int resched; 1424254885Sdumbbell 1425254885Sdumbbell sx_xlock(&rdev->exclusive_lock); 1426254885Sdumbbell radeon_save_bios_scratch_regs(rdev); 1427254885Sdumbbell /* block TTM */ 1428254885Sdumbbell resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); 1429254885Sdumbbell radeon_suspend(rdev); 1430254885Sdumbbell 1431254885Sdumbbell for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1432254885Sdumbbell ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i], 1433254885Sdumbbell &ring_data[i]); 1434254885Sdumbbell if (ring_sizes[i]) { 1435254885Sdumbbell saved = true; 1436254885Sdumbbell dev_info(rdev->dev, "Saved %d dwords of commands " 1437254885Sdumbbell "on ring %d.\n", ring_sizes[i], i); 1438254885Sdumbbell } 1439254885Sdumbbell } 1440254885Sdumbbell 1441254885Sdumbbellretry: 1442254885Sdumbbell r = radeon_asic_reset(rdev); 1443254885Sdumbbell if (!r) { 1444254885Sdumbbell dev_info(rdev->dev, "GPU reset succeeded, trying to resume\n"); 1445254885Sdumbbell radeon_resume(rdev); 1446254885Sdumbbell } 1447254885Sdumbbell 1448254885Sdumbbell radeon_restore_bios_scratch_regs(rdev); 1449254885Sdumbbell 1450254885Sdumbbell if (!r) { 1451254885Sdumbbell for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1452254885Sdumbbell radeon_ring_restore(rdev, &rdev->ring[i], 1453254885Sdumbbell ring_sizes[i], ring_data[i]); 1454254885Sdumbbell ring_sizes[i] = 0; 1455254885Sdumbbell ring_data[i] = NULL; 1456254885Sdumbbell } 1457254885Sdumbbell 1458254885Sdumbbell r = radeon_ib_ring_tests(rdev); 1459254885Sdumbbell if (r) { 1460254885Sdumbbell dev_err(rdev->dev, "ib ring test failed (%d).\n", r); 1461254885Sdumbbell if (saved) { 1462254885Sdumbbell saved = false; 1463254885Sdumbbell radeon_suspend(rdev); 1464254885Sdumbbell goto retry; 1465254885Sdumbbell } 1466254885Sdumbbell } 1467254885Sdumbbell } else { 1468254885Sdumbbell radeon_fence_driver_force_completion(rdev); 1469254885Sdumbbell for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1470254885Sdumbbell free(ring_data[i], DRM_MEM_DRIVER); 1471254885Sdumbbell } 1472254885Sdumbbell } 1473254885Sdumbbell 1474254885Sdumbbell drm_helper_resume_force_mode(rdev->ddev); 1475254885Sdumbbell 1476254885Sdumbbell ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); 1477254885Sdumbbell if (r) { 1478254885Sdumbbell /* bad news, how to tell it to userspace ? */ 1479254885Sdumbbell dev_info(rdev->dev, "GPU reset failed\n"); 1480254885Sdumbbell } 1481254885Sdumbbell 1482254885Sdumbbell sx_xunlock(&rdev->exclusive_lock); 1483254885Sdumbbell return r; 1484254885Sdumbbell} 1485254885Sdumbbell 1486254885Sdumbbell 1487254885Sdumbbell/* 1488254885Sdumbbell * Debugfs 1489254885Sdumbbell */ 1490254885Sdumbbell#ifdef DUMBBELL_WIP 1491254885Sdumbbellint radeon_debugfs_add_files(struct radeon_device *rdev, 1492254885Sdumbbell struct drm_info_list *files, 1493254885Sdumbbell unsigned nfiles) 1494254885Sdumbbell{ 1495254885Sdumbbell unsigned i; 1496254885Sdumbbell 1497254885Sdumbbell for (i = 0; i < rdev->debugfs_count; i++) { 1498254885Sdumbbell if (rdev->debugfs[i].files == files) { 1499254885Sdumbbell /* Already registered */ 1500254885Sdumbbell return 0; 1501254885Sdumbbell } 1502254885Sdumbbell } 1503254885Sdumbbell 1504254885Sdumbbell i = rdev->debugfs_count + 1; 1505254885Sdumbbell if (i > RADEON_DEBUGFS_MAX_COMPONENTS) { 1506254885Sdumbbell DRM_ERROR("Reached maximum number of debugfs components.\n"); 1507254885Sdumbbell DRM_ERROR("Report so we increase " 1508254885Sdumbbell "RADEON_DEBUGFS_MAX_COMPONENTS.\n"); 1509254885Sdumbbell return -EINVAL; 1510254885Sdumbbell } 1511254885Sdumbbell rdev->debugfs[rdev->debugfs_count].files = files; 1512254885Sdumbbell rdev->debugfs[rdev->debugfs_count].num_files = nfiles; 1513254885Sdumbbell rdev->debugfs_count = i; 1514254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 1515254885Sdumbbell drm_debugfs_create_files(files, nfiles, 1516254885Sdumbbell rdev->ddev->control->debugfs_root, 1517254885Sdumbbell rdev->ddev->control); 1518254885Sdumbbell drm_debugfs_create_files(files, nfiles, 1519254885Sdumbbell rdev->ddev->primary->debugfs_root, 1520254885Sdumbbell rdev->ddev->primary); 1521254885Sdumbbell#endif 1522254885Sdumbbell return 0; 1523254885Sdumbbell} 1524254885Sdumbbell 1525254885Sdumbbellstatic void radeon_debugfs_remove_files(struct radeon_device *rdev) 1526254885Sdumbbell{ 1527254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 1528254885Sdumbbell unsigned i; 1529254885Sdumbbell 1530254885Sdumbbell for (i = 0; i < rdev->debugfs_count; i++) { 1531254885Sdumbbell drm_debugfs_remove_files(rdev->debugfs[i].files, 1532254885Sdumbbell rdev->debugfs[i].num_files, 1533254885Sdumbbell rdev->ddev->control); 1534254885Sdumbbell drm_debugfs_remove_files(rdev->debugfs[i].files, 1535254885Sdumbbell rdev->debugfs[i].num_files, 1536254885Sdumbbell rdev->ddev->primary); 1537254885Sdumbbell } 1538254885Sdumbbell#endif 1539254885Sdumbbell} 1540254885Sdumbbell 1541254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 1542254885Sdumbbellint radeon_debugfs_init(struct drm_minor *minor) 1543254885Sdumbbell{ 1544254885Sdumbbell return 0; 1545254885Sdumbbell} 1546254885Sdumbbell 1547254885Sdumbbellvoid radeon_debugfs_cleanup(struct drm_minor *minor) 1548254885Sdumbbell{ 1549254885Sdumbbell} 1550254885Sdumbbell#endif /* DUMBBELL_WIP */ 1551254885Sdumbbell#endif 1552