brintos

brintos / linux-shallow public Read only

0
0
Text · 13.8 KiB · 9a31cde Raw
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