cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

r520.c (8788B)


      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 a
      7 * copy of this software and associated documentation files (the "Software"),
      8 * to deal in the Software without restriction, including without limitation
      9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10 * and/or sell copies of the Software, and to permit persons to whom the
     11 * Software is furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20 * 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 OR
     22 * OTHER DEALINGS IN THE SOFTWARE.
     23 *
     24 * Authors: Dave Airlie
     25 *          Alex Deucher
     26 *          Jerome Glisse
     27 */
     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		0x170C
     59	 * GB_TILE_CONFIG		0x4018
     60	 * GB_FIFO_SIZE			0x4024
     61	 * GB_PIPE_SELECT		0x402C
     62	 * GB_PIPE_SELECT2              0x4124
     63	 *	Z_PIPE_SHIFT			0
     64	 *	Z_PIPE_MASK			0x000000003
     65	 * GB_FIFO_SIZE2                0x4128
     66	 *	SC_SFIFO_SIZE_SHIFT		0
     67	 *	SC_SFIFO_SIZE_MASK		0x000000003
     68	 *	SC_MFIFO_SIZE_SHIFT		2
     69	 *	SC_MFIFO_SIZE_MASK		0x00000000C
     70	 *	FG_SFIFO_SIZE_SHIFT		4
     71	 *	FG_SFIFO_SIZE_MASK		0x000000030
     72	 *	ZB_MFIFO_SIZE_SHIFT		6
     73	 *	ZB_MFIFO_SIZE_MASK		0x0000000C0
     74	 * GA_ENHANCE			0x4274
     75	 * SU_REG_DEST			0x42C8
     76	 */
     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 allocate
    177	 * 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->ddev);
    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}