brintos

brintos / linux-shallow public Read only

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