xref: /NextBSD/sys/dev/drm2/radeon/r420.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
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 <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <dev/drm2/drmP.h>
33 #include "radeon_reg.h"
34 #include "radeon.h"
35 #include "radeon_asic.h"
36 #include "atom.h"
37 #include "r100d.h"
38 #include "r420d.h"
39 #include "r420_reg_safe.h"
40 
r420_pm_init_profile(struct radeon_device * rdev)41 void r420_pm_init_profile(struct radeon_device *rdev)
42 {
43 	/* default */
44 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
45 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
46 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
47 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
48 	/* low sh */
49 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0;
50 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0;
51 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
52 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
53 	/* mid sh */
54 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0;
55 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1;
56 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
57 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
58 	/* high sh */
59 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0;
60 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
61 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
62 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
63 	/* low mh */
64 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0;
65 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
66 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
67 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
68 	/* mid mh */
69 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0;
70 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
71 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
72 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
73 	/* high mh */
74 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0;
75 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
76 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
77 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
78 }
79 
r420_set_reg_safe(struct radeon_device * rdev)80 static void r420_set_reg_safe(struct radeon_device *rdev)
81 {
82 	rdev->config.r300.reg_safe_bm = r420_reg_safe_bm;
83 	rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm);
84 }
85 
r420_pipes_init(struct radeon_device * rdev)86 void r420_pipes_init(struct radeon_device *rdev)
87 {
88 	unsigned tmp;
89 	unsigned gb_pipe_select;
90 	unsigned num_pipes;
91 
92 	/* GA_ENHANCE workaround TCL deadlock issue */
93 	WREG32(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL |
94 	       (1 << 2) | (1 << 3));
95 	/* add idle wait as per freedesktop.org bug 24041 */
96 	if (r100_gui_wait_for_idle(rdev)) {
97 		DRM_ERROR("Failed to wait GUI idle while "
98 		       "programming pipes. Bad things might happen.\n");
99 	}
100 	/* get max number of pipes */
101 	gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);
102 	num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
103 
104 	/* SE chips have 1 pipe */
105 	if ((rdev->ddev->pci_device == 0x5e4c) ||
106 	    (rdev->ddev->pci_device == 0x5e4f))
107 		num_pipes = 1;
108 
109 	rdev->num_gb_pipes = num_pipes;
110 	tmp = 0;
111 	switch (num_pipes) {
112 	default:
113 		/* force to 1 pipe */
114 		num_pipes = 1;
115 	case 1:
116 		tmp = (0 << 1);
117 		break;
118 	case 2:
119 		tmp = (3 << 1);
120 		break;
121 	case 3:
122 		tmp = (6 << 1);
123 		break;
124 	case 4:
125 		tmp = (7 << 1);
126 		break;
127 	}
128 	WREG32(R500_SU_REG_DEST, (1 << num_pipes) - 1);
129 	/* Sub pixel 1/12 so we can have 4K rendering according to doc */
130 	tmp |= R300_TILE_SIZE_16 | R300_ENABLE_TILING;
131 	WREG32(R300_GB_TILE_CONFIG, tmp);
132 	if (r100_gui_wait_for_idle(rdev)) {
133 		DRM_ERROR("Failed to wait GUI idle while "
134 		       "programming pipes. Bad things might happen.\n");
135 	}
136 
137 	tmp = RREG32(R300_DST_PIPE_CONFIG);
138 	WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG);
139 
140 	WREG32(R300_RB2D_DSTCACHE_MODE,
141 	       RREG32(R300_RB2D_DSTCACHE_MODE) |
142 	       R300_DC_AUTOFLUSH_ENABLE |
143 	       R300_DC_DC_DISABLE_IGNORE_PE);
144 
145 	if (r100_gui_wait_for_idle(rdev)) {
146 		DRM_ERROR("Failed to wait GUI idle while "
147 		       "programming pipes. Bad things might happen.\n");
148 	}
149 
150 	if (rdev->family == CHIP_RV530) {
151 		tmp = RREG32(RV530_GB_PIPE_SELECT2);
152 		if ((tmp & 3) == 3)
153 			rdev->num_z_pipes = 2;
154 		else
155 			rdev->num_z_pipes = 1;
156 	} else
157 		rdev->num_z_pipes = 1;
158 
159 	DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n",
160 		 rdev->num_gb_pipes, rdev->num_z_pipes);
161 }
162 
r420_mc_rreg(struct radeon_device * rdev,u32 reg)163 u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg)
164 {
165 	u32 r;
166 
167 	WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg));
168 	r = RREG32(R_0001FC_MC_IND_DATA);
169 	return r;
170 }
171 
r420_mc_wreg(struct radeon_device * rdev,u32 reg,u32 v)172 void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
173 {
174 	WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) |
175 		S_0001F8_MC_IND_WR_EN(1));
176 	WREG32(R_0001FC_MC_IND_DATA, v);
177 }
178 
r420_debugfs(struct radeon_device * rdev)179 static void r420_debugfs(struct radeon_device *rdev)
180 {
181 	if (r100_debugfs_rbbm_init(rdev)) {
182 		DRM_ERROR("Failed to register debugfs file for RBBM !\n");
183 	}
184 	if (r420_debugfs_pipes_info_init(rdev)) {
185 		DRM_ERROR("Failed to register debugfs file for pipes !\n");
186 	}
187 }
188 
r420_clock_resume(struct radeon_device * rdev)189 static void r420_clock_resume(struct radeon_device *rdev)
190 {
191 	u32 sclk_cntl;
192 
193 	if (radeon_dynclks != -1 && radeon_dynclks)
194 		radeon_atom_set_clock_gating(rdev, 1);
195 	sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);
196 	sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
197 	if (rdev->family == CHIP_R420)
198 		sclk_cntl |= S_00000D_FORCE_PX(1) | S_00000D_FORCE_TX(1);
199 	WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl);
200 }
201 
r420_cp_errata_init(struct radeon_device * rdev)202 static void r420_cp_errata_init(struct radeon_device *rdev)
203 {
204 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
205 
206 	/* RV410 and R420 can lock up if CP DMA to host memory happens
207 	 * while the 2D engine is busy.
208 	 *
209 	 * The proper workaround is to queue a RESYNC at the beginning
210 	 * of the CP init, apparently.
211 	 */
212 	radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch);
213 	radeon_ring_lock(rdev, ring, 8);
214 	radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1));
215 	radeon_ring_write(ring, rdev->config.r300.resync_scratch);
216 	radeon_ring_write(ring, 0xDEADBEEF);
217 	radeon_ring_unlock_commit(rdev, ring);
218 }
219 
r420_cp_errata_fini(struct radeon_device * rdev)220 static void r420_cp_errata_fini(struct radeon_device *rdev)
221 {
222 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
223 
224 	/* Catch the RESYNC we dispatched all the way back,
225 	 * at the very beginning of the CP init.
226 	 */
227 	radeon_ring_lock(rdev, ring, 8);
228 	radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
229 	radeon_ring_write(ring, R300_RB3D_DC_FINISH);
230 	radeon_ring_unlock_commit(rdev, ring);
231 	radeon_scratch_free(rdev, rdev->config.r300.resync_scratch);
232 }
233 
r420_startup(struct radeon_device * rdev)234 static int r420_startup(struct radeon_device *rdev)
235 {
236 	int r;
237 
238 	/* set common regs */
239 	r100_set_common_regs(rdev);
240 	/* program mc */
241 	r300_mc_program(rdev);
242 	/* Resume clock */
243 	r420_clock_resume(rdev);
244 	/* Initialize GART (initialize after TTM so we can allocate
245 	 * memory through TTM but finalize after TTM) */
246 	if (rdev->flags & RADEON_IS_PCIE) {
247 		r = rv370_pcie_gart_enable(rdev);
248 		if (r)
249 			return r;
250 	}
251 	if (rdev->flags & RADEON_IS_PCI) {
252 		r = r100_pci_gart_enable(rdev);
253 		if (r)
254 			return r;
255 	}
256 	r420_pipes_init(rdev);
257 
258 	/* allocate wb buffer */
259 	r = radeon_wb_init(rdev);
260 	if (r)
261 		return r;
262 
263 	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
264 	if (r) {
265 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
266 		return r;
267 	}
268 
269 	/* Enable IRQ */
270 	r100_irq_set(rdev);
271 	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
272 	/* 1M ring buffer */
273 	r = r100_cp_init(rdev, 1024 * 1024);
274 	if (r) {
275 		dev_err(rdev->dev, "failed initializing CP (%d).\n", r);
276 		return r;
277 	}
278 	r420_cp_errata_init(rdev);
279 
280 	r = radeon_ib_pool_init(rdev);
281 	if (r) {
282 		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
283 		return r;
284 	}
285 
286 	return 0;
287 }
288 
r420_resume(struct radeon_device * rdev)289 int r420_resume(struct radeon_device *rdev)
290 {
291 	int r;
292 
293 	/* Make sur GART are not working */
294 	if (rdev->flags & RADEON_IS_PCIE)
295 		rv370_pcie_gart_disable(rdev);
296 	if (rdev->flags & RADEON_IS_PCI)
297 		r100_pci_gart_disable(rdev);
298 	/* Resume clock before doing reset */
299 	r420_clock_resume(rdev);
300 	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
301 	if (radeon_asic_reset(rdev)) {
302 		dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
303 			RREG32(R_000E40_RBBM_STATUS),
304 			RREG32(R_0007C0_CP_STAT));
305 	}
306 	/* check if cards are posted or not */
307 	if (rdev->is_atom_bios) {
308 		atom_asic_init(rdev->mode_info.atom_context);
309 	} else {
310 		radeon_combios_asic_init(rdev->ddev);
311 	}
312 	/* Resume clock after posting */
313 	r420_clock_resume(rdev);
314 	/* Initialize surface registers */
315 	radeon_surface_init(rdev);
316 
317 	rdev->accel_working = true;
318 	r = r420_startup(rdev);
319 	if (r) {
320 		rdev->accel_working = false;
321 	}
322 	return r;
323 }
324 
r420_suspend(struct radeon_device * rdev)325 int r420_suspend(struct radeon_device *rdev)
326 {
327 	r420_cp_errata_fini(rdev);
328 	r100_cp_disable(rdev);
329 	radeon_wb_disable(rdev);
330 	r100_irq_disable(rdev);
331 	if (rdev->flags & RADEON_IS_PCIE)
332 		rv370_pcie_gart_disable(rdev);
333 	if (rdev->flags & RADEON_IS_PCI)
334 		r100_pci_gart_disable(rdev);
335 	return 0;
336 }
337 
r420_fini(struct radeon_device * rdev)338 void r420_fini(struct radeon_device *rdev)
339 {
340 	r100_cp_fini(rdev);
341 	radeon_wb_fini(rdev);
342 	radeon_ib_pool_fini(rdev);
343 	radeon_gem_fini(rdev);
344 	if (rdev->flags & RADEON_IS_PCIE)
345 		rv370_pcie_gart_fini(rdev);
346 	if (rdev->flags & RADEON_IS_PCI)
347 		r100_pci_gart_fini(rdev);
348 	radeon_agp_fini(rdev);
349 	radeon_irq_kms_fini(rdev);
350 	radeon_fence_driver_fini(rdev);
351 	radeon_bo_fini(rdev);
352 	if (rdev->is_atom_bios) {
353 		radeon_atombios_fini(rdev);
354 	} else {
355 		radeon_combios_fini(rdev);
356 	}
357 	free(rdev->bios, DRM_MEM_DRIVER);
358 	rdev->bios = NULL;
359 }
360 
r420_init(struct radeon_device * rdev)361 int r420_init(struct radeon_device *rdev)
362 {
363 	int r;
364 
365 	/* Initialize scratch registers */
366 	radeon_scratch_init(rdev);
367 	/* Initialize surface registers */
368 	radeon_surface_init(rdev);
369 	/* TODO: disable VGA need to use VGA request */
370 	/* restore some register to sane defaults */
371 	r100_restore_sanity(rdev);
372 	/* BIOS*/
373 	if (!radeon_get_bios(rdev)) {
374 		if (ASIC_IS_AVIVO(rdev))
375 			return -EINVAL;
376 	}
377 	if (rdev->is_atom_bios) {
378 		r = radeon_atombios_init(rdev);
379 		if (r) {
380 			return r;
381 		}
382 	} else {
383 		r = radeon_combios_init(rdev);
384 		if (r) {
385 			return r;
386 		}
387 	}
388 	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
389 	if (radeon_asic_reset(rdev)) {
390 		dev_warn(rdev->dev,
391 			"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
392 			RREG32(R_000E40_RBBM_STATUS),
393 			RREG32(R_0007C0_CP_STAT));
394 	}
395 	/* check if cards are posted or not */
396 	if (radeon_boot_test_post_card(rdev) == false)
397 		return -EINVAL;
398 
399 	/* Initialize clocks */
400 	radeon_get_clock_info(rdev->ddev);
401 	/* initialize AGP */
402 	if (rdev->flags & RADEON_IS_AGP) {
403 		r = radeon_agp_init(rdev);
404 		if (r) {
405 			radeon_agp_disable(rdev);
406 		}
407 	}
408 	/* initialize memory controller */
409 	r300_mc_init(rdev);
410 	r420_debugfs(rdev);
411 	/* Fence driver */
412 	r = radeon_fence_driver_init(rdev);
413 	if (r) {
414 		return r;
415 	}
416 	r = radeon_irq_kms_init(rdev);
417 	if (r) {
418 		return r;
419 	}
420 	/* Memory manager */
421 	r = radeon_bo_init(rdev);
422 	if (r) {
423 		return r;
424 	}
425 	if (rdev->family == CHIP_R420)
426 		r100_enable_bm(rdev);
427 
428 	if (rdev->flags & RADEON_IS_PCIE) {
429 		r = rv370_pcie_gart_init(rdev);
430 		if (r)
431 			return r;
432 	}
433 	if (rdev->flags & RADEON_IS_PCI) {
434 		r = r100_pci_gart_init(rdev);
435 		if (r)
436 			return r;
437 	}
438 	r420_set_reg_safe(rdev);
439 
440 	rdev->accel_working = true;
441 	r = r420_startup(rdev);
442 	if (r) {
443 		/* Somethings want wront with the accel init stop accel */
444 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
445 		r100_cp_fini(rdev);
446 		radeon_wb_fini(rdev);
447 		radeon_ib_pool_fini(rdev);
448 		radeon_irq_kms_fini(rdev);
449 		if (rdev->flags & RADEON_IS_PCIE)
450 			rv370_pcie_gart_fini(rdev);
451 		if (rdev->flags & RADEON_IS_PCI)
452 			r100_pci_gart_fini(rdev);
453 		radeon_agp_fini(rdev);
454 		rdev->accel_working = false;
455 	}
456 	return 0;
457 }
458 
459 /*
460  * Debugfs info
461  */
462 #if defined(CONFIG_DEBUG_FS)
r420_debugfs_pipes_info(struct seq_file * m,void * data)463 static int r420_debugfs_pipes_info(struct seq_file *m, void *data)
464 {
465 	struct drm_info_node *node = (struct drm_info_node *) m->private;
466 	struct drm_device *dev = node->minor->dev;
467 	struct radeon_device *rdev = dev->dev_private;
468 	uint32_t tmp;
469 
470 	tmp = RREG32(R400_GB_PIPE_SELECT);
471 	seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp);
472 	tmp = RREG32(R300_GB_TILE_CONFIG);
473 	seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp);
474 	tmp = RREG32(R300_DST_PIPE_CONFIG);
475 	seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp);
476 	return 0;
477 }
478 
479 static struct drm_info_list r420_pipes_info_list[] = {
480 	{"r420_pipes_info", r420_debugfs_pipes_info, 0, NULL},
481 };
482 #endif
483 
r420_debugfs_pipes_info_init(struct radeon_device * rdev)484 int r420_debugfs_pipes_info_init(struct radeon_device *rdev)
485 {
486 #if defined(CONFIG_DEBUG_FS)
487 	return radeon_debugfs_add_files(rdev, r420_pipes_info_list, 1);
488 #else
489 	return 0;
490 #endif
491 }
492