brintos

brintos / linux-shallow public Read only

0
0
Text · 15.6 KiB · d6c18fd Raw
586 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/seq_file.h>31#include <linux/slab.h>32 33#include <drm/drm_device.h>34#include <drm/drm_file.h>35 36#include "radeon.h"37#include "radeon_asic.h"38#include "rs400d.h"39 40/* This files gather functions specifics to : rs400,rs480 */41static void rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);42 43void rs400_gart_adjust_size(struct radeon_device *rdev)44{45	/* Check gart size */46	switch (rdev->mc.gtt_size/(1024*1024)) {47	case 32:48	case 64:49	case 128:50	case 256:51	case 512:52	case 1024:53	case 2048:54		break;55	default:56		DRM_ERROR("Unable to use IGP GART size %uM\n",57			  (unsigned)(rdev->mc.gtt_size >> 20));58		DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n");59		DRM_ERROR("Forcing to 32M GART size\n");60		rdev->mc.gtt_size = 32 * 1024 * 1024;61		return;62	}63}64 65void rs400_gart_tlb_flush(struct radeon_device *rdev)66{67	uint32_t tmp;68	unsigned int timeout = rdev->usec_timeout;69 70	WREG32_MC(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE);71	do {72		tmp = RREG32_MC(RS480_GART_CACHE_CNTRL);73		if ((tmp & RS480_GART_CACHE_INVALIDATE) == 0)74			break;75		udelay(1);76		timeout--;77	} while (timeout > 0);78	WREG32_MC(RS480_GART_CACHE_CNTRL, 0);79}80 81int rs400_gart_init(struct radeon_device *rdev)82{83	int r;84 85	if (rdev->gart.ptr) {86		WARN(1, "RS400 GART already initialized\n");87		return 0;88	}89	/* Check gart size */90	switch (rdev->mc.gtt_size / (1024 * 1024)) {91	case 32:92	case 64:93	case 128:94	case 256:95	case 512:96	case 1024:97	case 2048:98		break;99	default:100		return -EINVAL;101	}102	/* Initialize common gart structure */103	r = radeon_gart_init(rdev);104	if (r)105		return r;106	rs400_debugfs_pcie_gart_info_init(rdev);107	rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;108	return radeon_gart_table_ram_alloc(rdev);109}110 111int rs400_gart_enable(struct radeon_device *rdev)112{113	uint32_t size_reg;114	uint32_t tmp;115 116	tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);117	tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;118	WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp);119	/* Check gart size */120	switch (rdev->mc.gtt_size / (1024 * 1024)) {121	case 32:122		size_reg = RS480_VA_SIZE_32MB;123		break;124	case 64:125		size_reg = RS480_VA_SIZE_64MB;126		break;127	case 128:128		size_reg = RS480_VA_SIZE_128MB;129		break;130	case 256:131		size_reg = RS480_VA_SIZE_256MB;132		break;133	case 512:134		size_reg = RS480_VA_SIZE_512MB;135		break;136	case 1024:137		size_reg = RS480_VA_SIZE_1GB;138		break;139	case 2048:140		size_reg = RS480_VA_SIZE_2GB;141		break;142	default:143		return -EINVAL;144	}145	/* It should be fine to program it to max value */146	if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {147		WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF);148		WREG32_MC(RS690_MCCFG_AGP_BASE_2, 0);149	} else {150		WREG32(RADEON_AGP_BASE, 0xFFFFFFFF);151		WREG32(RS480_AGP_BASE_2, 0);152	}153	tmp = REG_SET(RS690_MC_AGP_TOP, rdev->mc.gtt_end >> 16);154	tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_start >> 16);155	if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {156		WREG32_MC(RS690_MCCFG_AGP_LOCATION, tmp);157		tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;158		WREG32(RADEON_BUS_CNTL, tmp);159	} else {160		WREG32(RADEON_MC_AGP_LOCATION, tmp);161		tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;162		WREG32(RADEON_BUS_CNTL, tmp);163	}164	/* Table should be in 32bits address space so ignore bits above. */165	tmp = (u32)rdev->gart.table_addr & 0xfffff000;166	tmp |= (upper_32_bits(rdev->gart.table_addr) & 0xff) << 4;167 168	WREG32_MC(RS480_GART_BASE, tmp);169	/* TODO: more tweaking here */170	WREG32_MC(RS480_GART_FEATURE_ID,171		  (RS480_TLB_ENABLE |172		   RS480_GTW_LAC_EN | RS480_1LEVEL_GART));173	/* Disable snooping */174	WREG32_MC(RS480_AGP_MODE_CNTL,175		  (1 << RS480_REQ_TYPE_SNOOP_SHIFT) | RS480_REQ_TYPE_SNOOP_DIS);176	/* Disable AGP mode */177	/* FIXME: according to doc we should set HIDE_MMCFG_BAR=0,178	 * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */179	if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {180		tmp = RREG32_MC(RS480_MC_MISC_CNTL);181		tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN;182		WREG32_MC(RS480_MC_MISC_CNTL, tmp);183	} else {184		tmp = RREG32_MC(RS480_MC_MISC_CNTL);185		tmp |= RS480_GART_INDEX_REG_EN;186		WREG32_MC(RS480_MC_MISC_CNTL, tmp);187	}188	/* Enable gart */189	WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg));190	rs400_gart_tlb_flush(rdev);191	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",192		 (unsigned)(rdev->mc.gtt_size >> 20),193		 (unsigned long long)rdev->gart.table_addr);194	rdev->gart.ready = true;195	return 0;196}197 198void rs400_gart_disable(struct radeon_device *rdev)199{200	uint32_t tmp;201 202	tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);203	tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;204	WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp);205	WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0);206}207 208void rs400_gart_fini(struct radeon_device *rdev)209{210	radeon_gart_fini(rdev);211	rs400_gart_disable(rdev);212	radeon_gart_table_ram_free(rdev);213}214 215#define RS400_PTE_UNSNOOPED (1 << 0)216#define RS400_PTE_WRITEABLE (1 << 2)217#define RS400_PTE_READABLE  (1 << 3)218 219uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags)220{221	uint32_t entry;222 223	entry = (lower_32_bits(addr) & PAGE_MASK) |224		((upper_32_bits(addr) & 0xff) << 4);225	if (flags & RADEON_GART_PAGE_READ)226		entry |= RS400_PTE_READABLE;227	if (flags & RADEON_GART_PAGE_WRITE)228		entry |= RS400_PTE_WRITEABLE;229	if (!(flags & RADEON_GART_PAGE_SNOOP))230		entry |= RS400_PTE_UNSNOOPED;231	return entry;232}233 234void rs400_gart_set_page(struct radeon_device *rdev, unsigned i,235			 uint64_t entry)236{237	u32 *gtt = rdev->gart.ptr;238	gtt[i] = cpu_to_le32(lower_32_bits(entry));239}240 241int rs400_mc_wait_for_idle(struct radeon_device *rdev)242{243	unsigned i;244	uint32_t tmp;245 246	for (i = 0; i < rdev->usec_timeout; i++) {247		/* read MC_STATUS */248		tmp = RREG32(RADEON_MC_STATUS);249		if (tmp & RADEON_MC_IDLE) {250			return 0;251		}252		udelay(1);253	}254	return -1;255}256 257static void rs400_gpu_init(struct radeon_device *rdev)258{259	/* FIXME: is this correct ? */260	r420_pipes_init(rdev);261	if (rs400_mc_wait_for_idle(rdev)) {262		pr_warn("rs400: Failed to wait MC idle while programming pipes. Bad things might happen. %08x\n",263			RREG32(RADEON_MC_STATUS));264	}265}266 267static void rs400_mc_init(struct radeon_device *rdev)268{269	u64 base;270 271	rs400_gart_adjust_size(rdev);272	rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);273	/* DDR for all card after R300 & IGP */274	rdev->mc.vram_is_ddr = true;275	rdev->mc.vram_width = 128;276	r100_vram_init_sizes(rdev);277	base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;278	radeon_vram_location(rdev, &rdev->mc, base);279	rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;280	radeon_gtt_location(rdev, &rdev->mc);281	radeon_update_bandwidth_info(rdev);282}283 284uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)285{286	unsigned long flags;287	uint32_t r;288 289	spin_lock_irqsave(&rdev->mc_idx_lock, flags);290	WREG32(RS480_NB_MC_INDEX, reg & 0xff);291	r = RREG32(RS480_NB_MC_DATA);292	WREG32(RS480_NB_MC_INDEX, 0xff);293	spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);294	return r;295}296 297void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)298{299	unsigned long flags;300 301	spin_lock_irqsave(&rdev->mc_idx_lock, flags);302	WREG32(RS480_NB_MC_INDEX, ((reg) & 0xff) | RS480_NB_MC_IND_WR_EN);303	WREG32(RS480_NB_MC_DATA, (v));304	WREG32(RS480_NB_MC_INDEX, 0xff);305	spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);306}307 308#if defined(CONFIG_DEBUG_FS)309static int rs400_debugfs_gart_info_show(struct seq_file *m, void *unused)310{311	struct radeon_device *rdev = m->private;312	uint32_t tmp;313 314	tmp = RREG32(RADEON_HOST_PATH_CNTL);315	seq_printf(m, "HOST_PATH_CNTL 0x%08x\n", tmp);316	tmp = RREG32(RADEON_BUS_CNTL);317	seq_printf(m, "BUS_CNTL 0x%08x\n", tmp);318	tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);319	seq_printf(m, "AIC_CTRL_SCRATCH 0x%08x\n", tmp);320	if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {321		tmp = RREG32_MC(RS690_MCCFG_AGP_BASE);322		seq_printf(m, "MCCFG_AGP_BASE 0x%08x\n", tmp);323		tmp = RREG32_MC(RS690_MCCFG_AGP_BASE_2);324		seq_printf(m, "MCCFG_AGP_BASE_2 0x%08x\n", tmp);325		tmp = RREG32_MC(RS690_MCCFG_AGP_LOCATION);326		seq_printf(m, "MCCFG_AGP_LOCATION 0x%08x\n", tmp);327		tmp = RREG32_MC(RS690_MCCFG_FB_LOCATION);328		seq_printf(m, "MCCFG_FB_LOCATION 0x%08x\n", tmp);329		tmp = RREG32(RS690_HDP_FB_LOCATION);330		seq_printf(m, "HDP_FB_LOCATION 0x%08x\n", tmp);331	} else {332		tmp = RREG32(RADEON_AGP_BASE);333		seq_printf(m, "AGP_BASE 0x%08x\n", tmp);334		tmp = RREG32(RS480_AGP_BASE_2);335		seq_printf(m, "AGP_BASE_2 0x%08x\n", tmp);336		tmp = RREG32(RADEON_MC_AGP_LOCATION);337		seq_printf(m, "MC_AGP_LOCATION 0x%08x\n", tmp);338	}339	tmp = RREG32_MC(RS480_GART_BASE);340	seq_printf(m, "GART_BASE 0x%08x\n", tmp);341	tmp = RREG32_MC(RS480_GART_FEATURE_ID);342	seq_printf(m, "GART_FEATURE_ID 0x%08x\n", tmp);343	tmp = RREG32_MC(RS480_AGP_MODE_CNTL);344	seq_printf(m, "AGP_MODE_CONTROL 0x%08x\n", tmp);345	tmp = RREG32_MC(RS480_MC_MISC_CNTL);346	seq_printf(m, "MC_MISC_CNTL 0x%08x\n", tmp);347	tmp = RREG32_MC(0x5F);348	seq_printf(m, "MC_MISC_UMA_CNTL 0x%08x\n", tmp);349	tmp = RREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE);350	seq_printf(m, "AGP_ADDRESS_SPACE_SIZE 0x%08x\n", tmp);351	tmp = RREG32_MC(RS480_GART_CACHE_CNTRL);352	seq_printf(m, "GART_CACHE_CNTRL 0x%08x\n", tmp);353	tmp = RREG32_MC(0x3B);354	seq_printf(m, "MC_GART_ERROR_ADDRESS 0x%08x\n", tmp);355	tmp = RREG32_MC(0x3C);356	seq_printf(m, "MC_GART_ERROR_ADDRESS_HI 0x%08x\n", tmp);357	tmp = RREG32_MC(0x30);358	seq_printf(m, "GART_ERROR_0 0x%08x\n", tmp);359	tmp = RREG32_MC(0x31);360	seq_printf(m, "GART_ERROR_1 0x%08x\n", tmp);361	tmp = RREG32_MC(0x32);362	seq_printf(m, "GART_ERROR_2 0x%08x\n", tmp);363	tmp = RREG32_MC(0x33);364	seq_printf(m, "GART_ERROR_3 0x%08x\n", tmp);365	tmp = RREG32_MC(0x34);366	seq_printf(m, "GART_ERROR_4 0x%08x\n", tmp);367	tmp = RREG32_MC(0x35);368	seq_printf(m, "GART_ERROR_5 0x%08x\n", tmp);369	tmp = RREG32_MC(0x36);370	seq_printf(m, "GART_ERROR_6 0x%08x\n", tmp);371	tmp = RREG32_MC(0x37);372	seq_printf(m, "GART_ERROR_7 0x%08x\n", tmp);373	return 0;374}375 376DEFINE_SHOW_ATTRIBUTE(rs400_debugfs_gart_info);377#endif378 379static void rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)380{381#if defined(CONFIG_DEBUG_FS)382	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;383 384	debugfs_create_file("rs400_gart_info", 0444, root, rdev,385			    &rs400_debugfs_gart_info_fops);386#endif387}388 389static void rs400_mc_program(struct radeon_device *rdev)390{391	struct r100_mc_save save;392 393	/* Stops all mc clients */394	r100_mc_stop(rdev, &save);395 396	/* Wait for mc idle */397	if (rs400_mc_wait_for_idle(rdev))398		dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n");399	WREG32(R_000148_MC_FB_LOCATION,400		S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |401		S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));402 403	r100_mc_resume(rdev, &save);404}405 406static int rs400_startup(struct radeon_device *rdev)407{408	int r;409 410	r100_set_common_regs(rdev);411 412	rs400_mc_program(rdev);413	/* Resume clock */414	r300_clock_startup(rdev);415	/* Initialize GPU configuration (# pipes, ...) */416	rs400_gpu_init(rdev);417	r100_enable_bm(rdev);418	/* Initialize GART (initialize after TTM so we can allocate419	 * memory through TTM but finalize after TTM) */420	r = rs400_gart_enable(rdev);421	if (r)422		return r;423 424	/* allocate wb buffer */425	r = radeon_wb_init(rdev);426	if (r)427		return r;428 429	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);430	if (r) {431		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);432		return r;433	}434 435	/* Enable IRQ */436	if (!rdev->irq.installed) {437		r = radeon_irq_kms_init(rdev);438		if (r)439			return r;440	}441 442	r100_irq_set(rdev);443	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);444	/* 1M ring buffer */445	r = r100_cp_init(rdev, 1024 * 1024);446	if (r) {447		dev_err(rdev->dev, "failed initializing CP (%d).\n", r);448		return r;449	}450 451	r = radeon_ib_pool_init(rdev);452	if (r) {453		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);454		return r;455	}456 457	return 0;458}459 460int rs400_resume(struct radeon_device *rdev)461{462	int r;463 464	/* Make sur GART are not working */465	rs400_gart_disable(rdev);466	/* Resume clock before doing reset */467	r300_clock_startup(rdev);468	/* setup MC before calling post tables */469	rs400_mc_program(rdev);470	/* Reset gpu before posting otherwise ATOM will enter infinite loop */471	if (radeon_asic_reset(rdev)) {472		dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",473			RREG32(R_000E40_RBBM_STATUS),474			RREG32(R_0007C0_CP_STAT));475	}476	/* post */477	radeon_combios_asic_init(rdev_to_drm(rdev));478	/* Resume clock after posting */479	r300_clock_startup(rdev);480	/* Initialize surface registers */481	radeon_surface_init(rdev);482 483	rdev->accel_working = true;484	r = rs400_startup(rdev);485	if (r) {486		rdev->accel_working = false;487	}488	return r;489}490 491int rs400_suspend(struct radeon_device *rdev)492{493	radeon_pm_suspend(rdev);494	r100_cp_disable(rdev);495	radeon_wb_disable(rdev);496	r100_irq_disable(rdev);497	rs400_gart_disable(rdev);498	return 0;499}500 501void rs400_fini(struct radeon_device *rdev)502{503	radeon_pm_fini(rdev);504	r100_cp_fini(rdev);505	radeon_wb_fini(rdev);506	radeon_ib_pool_fini(rdev);507	radeon_gem_fini(rdev);508	rs400_gart_fini(rdev);509	radeon_irq_kms_fini(rdev);510	radeon_fence_driver_fini(rdev);511	radeon_bo_fini(rdev);512	radeon_atombios_fini(rdev);513	kfree(rdev->bios);514	rdev->bios = NULL;515}516 517int rs400_init(struct radeon_device *rdev)518{519	int r;520 521	/* Disable VGA */522	r100_vga_render_disable(rdev);523	/* Initialize scratch registers */524	radeon_scratch_init(rdev);525	/* Initialize surface registers */526	radeon_surface_init(rdev);527	/* TODO: disable VGA need to use VGA request */528	/* restore some register to sane defaults */529	r100_restore_sanity(rdev);530	/* BIOS*/531	if (!radeon_get_bios(rdev)) {532		if (ASIC_IS_AVIVO(rdev))533			return -EINVAL;534	}535	if (rdev->is_atom_bios) {536		dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");537		return -EINVAL;538	} else {539		r = radeon_combios_init(rdev);540		if (r)541			return r;542	}543	/* Reset gpu before posting otherwise ATOM will enter infinite loop */544	if (radeon_asic_reset(rdev)) {545		dev_warn(rdev->dev,546			"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",547			RREG32(R_000E40_RBBM_STATUS),548			RREG32(R_0007C0_CP_STAT));549	}550	/* check if cards are posted or not */551	if (radeon_boot_test_post_card(rdev) == false)552		return -EINVAL;553 554	/* Initialize clocks */555	radeon_get_clock_info(rdev_to_drm(rdev));556	/* initialize memory controller */557	rs400_mc_init(rdev);558	/* Fence driver */559	radeon_fence_driver_init(rdev);560	/* Memory manager */561	r = radeon_bo_init(rdev);562	if (r)563		return r;564	r = rs400_gart_init(rdev);565	if (r)566		return r;567	r300_set_reg_safe(rdev);568 569	/* Initialize power management */570	radeon_pm_init(rdev);571 572	rdev->accel_working = true;573	r = rs400_startup(rdev);574	if (r) {575		/* Somethings want wront with the accel init stop accel */576		dev_err(rdev->dev, "Disabling GPU acceleration\n");577		r100_cp_fini(rdev);578		radeon_wb_fini(rdev);579		radeon_ib_pool_fini(rdev);580		rs400_gart_fini(rdev);581		radeon_irq_kms_fini(rdev);582		rdev->accel_working = false;583	}584	return 0;585}586