1193326Sed/*
2193326Sed * Copyright 2008 Advanced Micro Devices, Inc.
3193326Sed * Copyright 2008 Red Hat Inc.
4193326Sed * Copyright 2009 Jerome Glisse.
5193326Sed *
6193326Sed * Permission is hereby granted, free of charge, to any person obtaining a
7193326Sed * copy of this software and associated documentation files (the "Software"),
8193326Sed * to deal in the Software without restriction, including without limitation
9193326Sed * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10193326Sed * and/or sell copies of the Software, and to permit persons to whom the
11193326Sed * Software is furnished to do so, subject to the following conditions:
12193326Sed *
13193326Sed * The above copyright notice and this permission notice shall be included in
14212904Sdim * all copies or substantial portions of the Software.
15221345Sdim *
16193326Sed * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17193326Sed * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18198092Srdivacky * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19249423Sdim * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20239462Sdim * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21212904Sdim * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22212904Sdim * OTHER DEALINGS IN THE SOFTWARE.
23193326Sed *
24221345Sdim * Authors: Dave Airlie
25193326Sed *          Alex Deucher
26193326Sed *          Jerome Glisse
27198092Srdivacky */
28198092Srdivacky
29193326Sed#include "radeon.h"
30249423Sdim#include "radeon_asic.h"
31249423Sdim#include "atom.h"
32249423Sdim#include "r520d.h"
33249423Sdim
34249423Sdim/* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */
35249423Sdim
36249423Sdimint r520_mc_wait_for_idle(struct radeon_device *rdev)
37249423Sdim{
38249423Sdim	unsigned i;
39249423Sdim	uint32_t tmp;
40249423Sdim
41249423Sdim	for (i = 0; i < rdev->usec_timeout; i++) {
42234353Sdim		/* read MC_STATUS */
43201361Srdivacky		tmp = RREG32_MC(R520_MC_STATUS);
44193326Sed		if (tmp & R520_MC_STATUS_IDLE) {
45198092Srdivacky			return 0;
46193326Sed		}
47193326Sed		udelay(1);
48212904Sdim	}
49193326Sed	return -1;
50224145Sdim}
51224145Sdim
52224145Sdimstatic void r520_gpu_init(struct radeon_device *rdev)
53224145Sdim{
54224145Sdim	unsigned pipe_select_current, gb_pipe_select, tmp;
55224145Sdim
56212904Sdim	rv515_vga_render_disable(rdev);
57193326Sed	/*
58193326Sed	 * DST_PIPE_CONFIG		0x170C
59234353Sdim	 * GB_TILE_CONFIG		0x4018
60234353Sdim	 * GB_FIFO_SIZE			0x4024
61234353Sdim	 * GB_PIPE_SELECT		0x402C
62234353Sdim	 * GB_PIPE_SELECT2              0x4124
63239462Sdim	 *	Z_PIPE_SHIFT			0
64239462Sdim	 *	Z_PIPE_MASK			0x000000003
65234353Sdim	 * GB_FIFO_SIZE2                0x4128
66234353Sdim	 *	SC_SFIFO_SIZE_SHIFT		0
67234353Sdim	 *	SC_SFIFO_SIZE_MASK		0x000000003
68234353Sdim	 *	SC_MFIFO_SIZE_SHIFT		2
69234353Sdim	 *	SC_MFIFO_SIZE_MASK		0x00000000C
70234353Sdim	 *	FG_SFIFO_SIZE_SHIFT		4
71234353Sdim	 *	FG_SFIFO_SIZE_MASK		0x000000030
72234353Sdim	 *	ZB_MFIFO_SIZE_SHIFT		6
73234353Sdim	 *	ZB_MFIFO_SIZE_MASK		0x0000000C0
74234353Sdim	 * GA_ENHANCE			0x4274
75239462Sdim	 * SU_REG_DEST			0x42C8
76234353Sdim	 */
77234353Sdim	/* workaround for RV530 */
78234353Sdim	if (rdev->family == CHIP_RV530) {
79234353Sdim		WREG32(0x4128, 0xFF);
80239462Sdim	}
81234353Sdim	r420_pipes_init(rdev);
82234353Sdim	gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);
83234353Sdim	tmp = RREG32(R300_DST_PIPE_CONFIG);
84234353Sdim	pipe_select_current = (tmp >> 2) & 3;
85239462Sdim	tmp = (1 << pipe_select_current) |
86239462Sdim	      (((gb_pipe_select >> 8) & 0xF) << 4);
87239462Sdim	WREG32_PLL(0x000D, tmp);
88239462Sdim	if (r520_mc_wait_for_idle(rdev)) {
89239462Sdim		pr_warn("Failed to wait MC idle while programming pipes. Bad things might happen.\n");
90239462Sdim	}
91239462Sdim}
92239462Sdim
93239462Sdimstatic void r520_vram_get_type(struct radeon_device *rdev)
94239462Sdim{
95239462Sdim	uint32_t tmp;
96239462Sdim
97239462Sdim	rdev->mc.vram_width = 128;
98239462Sdim	rdev->mc.vram_is_ddr = true;
99239462Sdim	tmp = RREG32_MC(R520_MC_CNTL0);
100239462Sdim	switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) {
101239462Sdim	case 0:
102239462Sdim		rdev->mc.vram_width = 32;
103239462Sdim		break;
104239462Sdim	case 1:
105239462Sdim		rdev->mc.vram_width = 64;
106239462Sdim		break;
107239462Sdim	case 2:
108239462Sdim		rdev->mc.vram_width = 128;
109239462Sdim		break;
110239462Sdim	case 3:
111239462Sdim		rdev->mc.vram_width = 256;
112239462Sdim		break;
113239462Sdim	default:
114239462Sdim		rdev->mc.vram_width = 128;
115239462Sdim		break;
116239462Sdim	}
117239462Sdim	if (tmp & R520_MC_CHANNEL_SIZE)
118239462Sdim		rdev->mc.vram_width *= 2;
119239462Sdim}
120239462Sdim
121193326Sedstatic void r520_mc_init(struct radeon_device *rdev)
122193326Sed{
123193326Sed
124193326Sed	r520_vram_get_type(rdev);
125193326Sed	r100_vram_init_sizes(rdev);
126193326Sed	radeon_vram_location(rdev, &rdev->mc, 0);
127193326Sed	rdev->mc.gtt_base_align = 0;
128193326Sed	if (!(rdev->flags & RADEON_IS_AGP))
129193326Sed		radeon_gtt_location(rdev, &rdev->mc);
130193326Sed	radeon_update_bandwidth_info(rdev);
131193326Sed}
132251662Sdim
133212904Sdimstatic void r520_mc_program(struct radeon_device *rdev)
134218893Sdim{
135221345Sdim	struct rv515_mc_save save;
136234353Sdim
137226633Sdim	/* Stops all mc clients */
138226633Sdim	rv515_mc_stop(rdev, &save);
139199990Srdivacky
140199990Srdivacky	/* Wait for mc idle */
141199990Srdivacky	if (r520_mc_wait_for_idle(rdev))
142212904Sdim		dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
143199990Srdivacky	/* Write VRAM size in case we are limiting it */
144199990Srdivacky	WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
145207619Srdivacky	/* Program MC, should be a 32bits limited address space */
146199990Srdivacky	WREG32_MC(R_000004_MC_FB_LOCATION,
147199990Srdivacky			S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
148199990Srdivacky			S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
149199990Srdivacky	WREG32(R_000134_HDP_FB_LOCATION,
150199990Srdivacky		S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
151199990Srdivacky	if (rdev->flags & RADEON_IS_AGP) {
152199990Srdivacky		WREG32_MC(R_000005_MC_AGP_LOCATION,
153199990Srdivacky			S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) |
154199990Srdivacky			S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
155199990Srdivacky		WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
156199990Srdivacky		WREG32_MC(R_000007_AGP_BASE_2,
157199990Srdivacky			S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base)));
158199990Srdivacky	} else {
159234353Sdim		WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF);
160212904Sdim		WREG32_MC(R_000006_AGP_BASE, 0);
161199990Srdivacky		WREG32_MC(R_000007_AGP_BASE_2, 0);
162210299Sed	}
163210299Sed
164221345Sdim	rv515_mc_resume(rdev, &save);
165221345Sdim}
166221345Sdim
167221345Sdimstatic int r520_startup(struct radeon_device *rdev)
168212904Sdim{
169221345Sdim	int r;
170221345Sdim
171221345Sdim	r520_mc_program(rdev);
172221345Sdim	/* Resume clock */
173199990Srdivacky	rv515_clock_startup(rdev);
174199990Srdivacky	/* Initialize GPU configuration (# pipes, ...) */
175212904Sdim	r520_gpu_init(rdev);
176199990Srdivacky	/* Initialize GART (initialize after TTM so we can allocate
177199990Srdivacky	 * memory through TTM but finalize after TTM) */
178207619Srdivacky	if (rdev->flags & RADEON_IS_PCIE) {
179207619Srdivacky		r = rv370_pcie_gart_enable(rdev);
180212904Sdim		if (r)
181198092Srdivacky			return r;
182201361Srdivacky	}
183201361Srdivacky
184201361Srdivacky	/* allocate wb buffer */
185201361Srdivacky	r = radeon_wb_init(rdev);
186201361Srdivacky	if (r)
187201361Srdivacky		return r;
188199990Srdivacky
189199990Srdivacky	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
190199990Srdivacky	if (r) {
191199990Srdivacky		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
192199990Srdivacky		return r;
193199990Srdivacky	}
194198092Srdivacky
195199990Srdivacky	/* Enable IRQ */
196199990Srdivacky	if (!rdev->irq.installed) {
197199990Srdivacky		r = radeon_irq_kms_init(rdev);
198199990Srdivacky		if (r)
199199990Srdivacky			return r;
200199990Srdivacky	}
201199990Srdivacky
202199990Srdivacky	rs600_irq_set(rdev);
203199990Srdivacky	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
204199990Srdivacky	/* 1M ring buffer */
205199990Srdivacky	r = r100_cp_init(rdev, 1024 * 1024);
206199990Srdivacky	if (r) {
207199990Srdivacky		dev_err(rdev->dev, "failed initializing CP (%d).\n", r);
208199990Srdivacky		return r;
209193326Sed	}
210199482Srdivacky
211193326Sed	r = radeon_ib_pool_init(rdev);
212202379Srdivacky	if (r) {
213226633Sdim		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
214239462Sdim		return r;
215226633Sdim	}
216234353Sdim
217226633Sdim	return 0;
218226633Sdim}
219226633Sdim
220226633Sdimint r520_resume(struct radeon_device *rdev)
221226633Sdim{
222226633Sdim	int r;
223226633Sdim
224226633Sdim	/* Make sur GART are not working */
225226633Sdim	if (rdev->flags & RADEON_IS_PCIE)
226226633Sdim		rv370_pcie_gart_disable(rdev);
227226633Sdim	/* Resume clock before doing reset */
228226633Sdim	rv515_clock_startup(rdev);
229226633Sdim	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
230226633Sdim	if (radeon_asic_reset(rdev)) {
231226633Sdim		dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
232234353Sdim			RREG32(R_000E40_RBBM_STATUS),
233226633Sdim			RREG32(R_0007C0_CP_STAT));
234226633Sdim	}
235226633Sdim	/* post */
236226633Sdim	atom_asic_init(rdev->mode_info.atom_context);
237234353Sdim	/* Resume clock after posting */
238226633Sdim	rv515_clock_startup(rdev);
239226633Sdim	/* Initialize surface registers */
240234353Sdim	radeon_surface_init(rdev);
241226633Sdim
242234353Sdim	rdev->accel_working = true;
243239462Sdim	r = r520_startup(rdev);
244239462Sdim	if (r) {
245226633Sdim		rdev->accel_working = false;
246226633Sdim	}
247226633Sdim	return r;
248226633Sdim}
249226633Sdim
250226633Sdimint r520_init(struct radeon_device *rdev)
251226633Sdim{
252226633Sdim	int r;
253226633Sdim
254226633Sdim	/* Initialize scratch registers */
255226633Sdim	radeon_scratch_init(rdev);
256226633Sdim	/* Initialize surface registers */
257226633Sdim	radeon_surface_init(rdev);
258226633Sdim	/* restore some register to sane defaults */
259193326Sed	r100_restore_sanity(rdev);
260199482Srdivacky	/* TODO: disable VGA need to use VGA request */
261203955Srdivacky	/* BIOS*/
262212904Sdim	if (!radeon_get_bios(rdev)) {
263193326Sed		if (ASIC_IS_AVIVO(rdev))
264198893Srdivacky			return -EINVAL;
265198092Srdivacky	}
266198092Srdivacky	if (rdev->is_atom_bios) {
267198092Srdivacky		r = radeon_atombios_init(rdev);
268198092Srdivacky		if (r)
269198092Srdivacky			return r;
270199482Srdivacky	} else {
271199482Srdivacky		dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
272212904Sdim		return -EINVAL;
273199482Srdivacky	}
274198092Srdivacky	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
275193326Sed	if (radeon_asic_reset(rdev)) {
276193326Sed		dev_warn(rdev->dev,
277193326Sed			"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
278193326Sed			RREG32(R_000E40_RBBM_STATUS),
279198092Srdivacky			RREG32(R_0007C0_CP_STAT));
280198092Srdivacky	}
281193326Sed	/* check if cards are posted or not */
282193326Sed	if (radeon_boot_test_post_card(rdev) == false)
283193326Sed		return -EINVAL;
284193326Sed
285193326Sed	if (!radeon_card_posted(rdev) && rdev->bios) {
286193326Sed		DRM_INFO("GPU not posted. posting now...\n");
287193326Sed		atom_asic_init(rdev->mode_info.atom_context);
288193326Sed	}
289193326Sed	/* Initialize clocks */
290193326Sed	radeon_get_clock_info(rdev->ddev);
291193326Sed	/* initialize AGP */
292193326Sed	if (rdev->flags & RADEON_IS_AGP) {
293199482Srdivacky		r = radeon_agp_init(rdev);
294212904Sdim		if (r) {
295193326Sed			radeon_agp_disable(rdev);
296193326Sed		}
297193326Sed	}
298193326Sed	/* initialize memory controller */
299193326Sed	r520_mc_init(rdev);
300193326Sed	rv515_debugfs(rdev);
301193326Sed	/* Fence driver */
302193326Sed	radeon_fence_driver_init(rdev);
303193326Sed	/* Memory manager */
304198092Srdivacky	r = radeon_bo_init(rdev);
305193326Sed	if (r)
306193326Sed		return r;
307193326Sed	r = rv370_pcie_gart_init(rdev);
308198893Srdivacky	if (r)
309198092Srdivacky		return r;
310198893Srdivacky	rv515_set_safe_registers(rdev);
311198893Srdivacky
312198893Srdivacky	/* Initialize power management */
313199482Srdivacky	radeon_pm_init(rdev);
314198893Srdivacky
315198893Srdivacky	rdev->accel_working = true;
316234353Sdim	r = r520_startup(rdev);
317234353Sdim	if (r) {
318234353Sdim		/* Somethings want wront with the accel init stop accel */
319234353Sdim		dev_err(rdev->dev, "Disabling GPU acceleration\n");
320234353Sdim		r100_cp_fini(rdev);
321221345Sdim		radeon_wb_fini(rdev);
322221345Sdim		radeon_ib_pool_fini(rdev);
323221345Sdim		radeon_irq_kms_fini(rdev);
324221345Sdim		rv370_pcie_gart_fini(rdev);
325221345Sdim		radeon_agp_fini(rdev);
326221345Sdim		rdev->accel_working = false;
327221345Sdim	}
328234353Sdim	return 0;
329221345Sdim}
330221345Sdim