1254885Sdumbbell/*
2254885Sdumbbell * Copyright 2008 Advanced Micro Devices, Inc.
3254885Sdumbbell * Copyright 2008 Red Hat Inc.
4254885Sdumbbell * Copyright 2009 Jerome Glisse.
5254885Sdumbbell *
6254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a
7254885Sdumbbell * copy of this software and associated documentation files (the "Software"),
8254885Sdumbbell * to deal in the Software without restriction, including without limitation
9254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the
11254885Sdumbbell * Software is furnished to do so, subject to the following conditions:
12254885Sdumbbell *
13254885Sdumbbell * The above copyright notice and this permission notice shall be included in
14254885Sdumbbell * all copies or substantial portions of the Software.
15254885Sdumbbell *
16254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE.
23254885Sdumbbell *
24254885Sdumbbell * Authors: Dave Airlie
25254885Sdumbbell *          Alex Deucher
26254885Sdumbbell *          Jerome Glisse
27254885Sdumbbell */
28254885Sdumbbell
29254885Sdumbbell#include <sys/cdefs.h>
30254885Sdumbbell__FBSDID("$FreeBSD$");
31254885Sdumbbell
32254885Sdumbbell#include <dev/drm2/drmP.h>
33254885Sdumbbell#include <dev/drm2/drm_crtc_helper.h>
34254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h>
35254885Sdumbbell#include "radeon_reg.h"
36254885Sdumbbell#include "radeon.h"
37254885Sdumbbell#include "atom.h"
38254885Sdumbbell
39254885Sdumbbellstatic const char radeon_family_name[][16] = {
40254885Sdumbbell	"R100",
41254885Sdumbbell	"RV100",
42254885Sdumbbell	"RS100",
43254885Sdumbbell	"RV200",
44254885Sdumbbell	"RS200",
45254885Sdumbbell	"R200",
46254885Sdumbbell	"RV250",
47254885Sdumbbell	"RS300",
48254885Sdumbbell	"RV280",
49254885Sdumbbell	"R300",
50254885Sdumbbell	"R350",
51254885Sdumbbell	"RV350",
52254885Sdumbbell	"RV380",
53254885Sdumbbell	"R420",
54254885Sdumbbell	"R423",
55254885Sdumbbell	"RV410",
56254885Sdumbbell	"RS400",
57254885Sdumbbell	"RS480",
58254885Sdumbbell	"RS600",
59254885Sdumbbell	"RS690",
60254885Sdumbbell	"RS740",
61254885Sdumbbell	"RV515",
62254885Sdumbbell	"R520",
63254885Sdumbbell	"RV530",
64254885Sdumbbell	"RV560",
65254885Sdumbbell	"RV570",
66254885Sdumbbell	"R580",
67254885Sdumbbell	"R600",
68254885Sdumbbell	"RV610",
69254885Sdumbbell	"RV630",
70254885Sdumbbell	"RV670",
71254885Sdumbbell	"RV620",
72254885Sdumbbell	"RV635",
73254885Sdumbbell	"RS780",
74254885Sdumbbell	"RS880",
75254885Sdumbbell	"RV770",
76254885Sdumbbell	"RV730",
77254885Sdumbbell	"RV710",
78254885Sdumbbell	"RV740",
79254885Sdumbbell	"CEDAR",
80254885Sdumbbell	"REDWOOD",
81254885Sdumbbell	"JUNIPER",
82254885Sdumbbell	"CYPRESS",
83254885Sdumbbell	"HEMLOCK",
84254885Sdumbbell	"PALM",
85254885Sdumbbell	"SUMO",
86254885Sdumbbell	"SUMO2",
87254885Sdumbbell	"BARTS",
88254885Sdumbbell	"TURKS",
89254885Sdumbbell	"CAICOS",
90254885Sdumbbell	"CAYMAN",
91254885Sdumbbell	"ARUBA",
92254885Sdumbbell	"TAHITI",
93254885Sdumbbell	"PITCAIRN",
94254885Sdumbbell	"VERDE",
95254885Sdumbbell	"LAST",
96254885Sdumbbell};
97254885Sdumbbell
98254885Sdumbbell/**
99254885Sdumbbell * radeon_surface_init - Clear GPU surface registers.
100254885Sdumbbell *
101254885Sdumbbell * @rdev: radeon_device pointer
102254885Sdumbbell *
103254885Sdumbbell * Clear GPU surface registers (r1xx-r5xx).
104254885Sdumbbell */
105254885Sdumbbellvoid radeon_surface_init(struct radeon_device *rdev)
106254885Sdumbbell{
107254885Sdumbbell	/* FIXME: check this out */
108254885Sdumbbell	if (rdev->family < CHIP_R600) {
109254885Sdumbbell		int i;
110254885Sdumbbell
111254885Sdumbbell		for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
112254885Sdumbbell			if (rdev->surface_regs[i].bo)
113254885Sdumbbell				radeon_bo_get_surface_reg(rdev->surface_regs[i].bo);
114254885Sdumbbell			else
115254885Sdumbbell				radeon_clear_surface_reg(rdev, i);
116254885Sdumbbell		}
117254885Sdumbbell		/* enable surfaces */
118254885Sdumbbell		WREG32(RADEON_SURFACE_CNTL, 0);
119254885Sdumbbell	}
120254885Sdumbbell}
121254885Sdumbbell
122254885Sdumbbell/*
123254885Sdumbbell * GPU scratch registers helpers function.
124254885Sdumbbell */
125254885Sdumbbell/**
126254885Sdumbbell * radeon_scratch_init - Init scratch register driver information.
127254885Sdumbbell *
128254885Sdumbbell * @rdev: radeon_device pointer
129254885Sdumbbell *
130254885Sdumbbell * Init CP scratch register driver information (r1xx-r5xx)
131254885Sdumbbell */
132254885Sdumbbellvoid radeon_scratch_init(struct radeon_device *rdev)
133254885Sdumbbell{
134254885Sdumbbell	int i;
135254885Sdumbbell
136254885Sdumbbell	/* FIXME: check this out */
137254885Sdumbbell	if (rdev->family < CHIP_R300) {
138254885Sdumbbell		rdev->scratch.num_reg = 5;
139254885Sdumbbell	} else {
140254885Sdumbbell		rdev->scratch.num_reg = 7;
141254885Sdumbbell	}
142254885Sdumbbell	rdev->scratch.reg_base = RADEON_SCRATCH_REG0;
143254885Sdumbbell	for (i = 0; i < rdev->scratch.num_reg; i++) {
144254885Sdumbbell		rdev->scratch.free[i] = true;
145254885Sdumbbell		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
146254885Sdumbbell	}
147254885Sdumbbell}
148254885Sdumbbell
149254885Sdumbbell/**
150254885Sdumbbell * radeon_scratch_get - Allocate a scratch register
151254885Sdumbbell *
152254885Sdumbbell * @rdev: radeon_device pointer
153254885Sdumbbell * @reg: scratch register mmio offset
154254885Sdumbbell *
155254885Sdumbbell * Allocate a CP scratch register for use by the driver (all asics).
156254885Sdumbbell * Returns 0 on success or -EINVAL on failure.
157254885Sdumbbell */
158254885Sdumbbellint radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
159254885Sdumbbell{
160254885Sdumbbell	int i;
161254885Sdumbbell
162254885Sdumbbell	for (i = 0; i < rdev->scratch.num_reg; i++) {
163254885Sdumbbell		if (rdev->scratch.free[i]) {
164254885Sdumbbell			rdev->scratch.free[i] = false;
165254885Sdumbbell			*reg = rdev->scratch.reg[i];
166254885Sdumbbell			return 0;
167254885Sdumbbell		}
168254885Sdumbbell	}
169254885Sdumbbell	return -EINVAL;
170254885Sdumbbell}
171254885Sdumbbell
172254885Sdumbbell/**
173254885Sdumbbell * radeon_scratch_free - Free a scratch register
174254885Sdumbbell *
175254885Sdumbbell * @rdev: radeon_device pointer
176254885Sdumbbell * @reg: scratch register mmio offset
177254885Sdumbbell *
178254885Sdumbbell * Free a CP scratch register allocated for use by the driver (all asics)
179254885Sdumbbell */
180254885Sdumbbellvoid radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
181254885Sdumbbell{
182254885Sdumbbell	int i;
183254885Sdumbbell
184254885Sdumbbell	for (i = 0; i < rdev->scratch.num_reg; i++) {
185254885Sdumbbell		if (rdev->scratch.reg[i] == reg) {
186254885Sdumbbell			rdev->scratch.free[i] = true;
187254885Sdumbbell			return;
188254885Sdumbbell		}
189254885Sdumbbell	}
190254885Sdumbbell}
191254885Sdumbbell
192254885Sdumbbell/*
193254885Sdumbbell * radeon_wb_*()
194254885Sdumbbell * Writeback is the the method by which the the GPU updates special pages
195254885Sdumbbell * in memory with the status of certain GPU events (fences, ring pointers,
196254885Sdumbbell * etc.).
197254885Sdumbbell */
198254885Sdumbbell
199254885Sdumbbell/**
200254885Sdumbbell * radeon_wb_disable - Disable Writeback
201254885Sdumbbell *
202254885Sdumbbell * @rdev: radeon_device pointer
203254885Sdumbbell *
204254885Sdumbbell * Disables Writeback (all asics).  Used for suspend.
205254885Sdumbbell */
206254885Sdumbbellvoid radeon_wb_disable(struct radeon_device *rdev)
207254885Sdumbbell{
208254885Sdumbbell	int r;
209254885Sdumbbell
210254885Sdumbbell	if (rdev->wb.wb_obj) {
211254885Sdumbbell		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
212254885Sdumbbell		if (unlikely(r != 0))
213254885Sdumbbell			return;
214254885Sdumbbell		radeon_bo_kunmap(rdev->wb.wb_obj);
215254885Sdumbbell		radeon_bo_unpin(rdev->wb.wb_obj);
216254885Sdumbbell		radeon_bo_unreserve(rdev->wb.wb_obj);
217254885Sdumbbell	}
218254885Sdumbbell	rdev->wb.enabled = false;
219254885Sdumbbell}
220254885Sdumbbell
221254885Sdumbbell/**
222254885Sdumbbell * radeon_wb_fini - Disable Writeback and free memory
223254885Sdumbbell *
224254885Sdumbbell * @rdev: radeon_device pointer
225254885Sdumbbell *
226254885Sdumbbell * Disables Writeback and frees the Writeback memory (all asics).
227254885Sdumbbell * Used at driver shutdown.
228254885Sdumbbell */
229254885Sdumbbellvoid radeon_wb_fini(struct radeon_device *rdev)
230254885Sdumbbell{
231254885Sdumbbell	radeon_wb_disable(rdev);
232254885Sdumbbell	if (rdev->wb.wb_obj) {
233254885Sdumbbell		radeon_bo_unref(&rdev->wb.wb_obj);
234254885Sdumbbell		rdev->wb.wb = NULL;
235254885Sdumbbell		rdev->wb.wb_obj = NULL;
236254885Sdumbbell	}
237254885Sdumbbell}
238254885Sdumbbell
239254885Sdumbbell/**
240254885Sdumbbell * radeon_wb_init- Init Writeback driver info and allocate memory
241254885Sdumbbell *
242254885Sdumbbell * @rdev: radeon_device pointer
243254885Sdumbbell *
244254885Sdumbbell * Disables Writeback and frees the Writeback memory (all asics).
245254885Sdumbbell * Used at driver startup.
246254885Sdumbbell * Returns 0 on success or an -error on failure.
247254885Sdumbbell */
248254885Sdumbbellint radeon_wb_init(struct radeon_device *rdev)
249254885Sdumbbell{
250254885Sdumbbell	int r;
251254885Sdumbbell	void *wb_ptr;
252254885Sdumbbell
253254885Sdumbbell	if (rdev->wb.wb_obj == NULL) {
254254885Sdumbbell		r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
255254885Sdumbbell				     RADEON_GEM_DOMAIN_GTT, NULL, &rdev->wb.wb_obj);
256254885Sdumbbell		if (r) {
257254885Sdumbbell			dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
258254885Sdumbbell			return r;
259254885Sdumbbell		}
260254885Sdumbbell	}
261254885Sdumbbell	r = radeon_bo_reserve(rdev->wb.wb_obj, false);
262254885Sdumbbell	if (unlikely(r != 0)) {
263254885Sdumbbell		radeon_wb_fini(rdev);
264254885Sdumbbell		return r;
265254885Sdumbbell	}
266254885Sdumbbell	r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
267254885Sdumbbell			  &rdev->wb.gpu_addr);
268254885Sdumbbell	if (r) {
269254885Sdumbbell		radeon_bo_unreserve(rdev->wb.wb_obj);
270254885Sdumbbell		dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r);
271254885Sdumbbell		radeon_wb_fini(rdev);
272254885Sdumbbell		return r;
273254885Sdumbbell	}
274254885Sdumbbell	wb_ptr = &rdev->wb.wb;
275254885Sdumbbell	r = radeon_bo_kmap(rdev->wb.wb_obj, wb_ptr);
276254885Sdumbbell	radeon_bo_unreserve(rdev->wb.wb_obj);
277254885Sdumbbell	if (r) {
278254885Sdumbbell		dev_warn(rdev->dev, "(%d) map WB bo failed\n", r);
279254885Sdumbbell		radeon_wb_fini(rdev);
280254885Sdumbbell		return r;
281254885Sdumbbell	}
282254885Sdumbbell
283254885Sdumbbell	/* clear wb memory */
284254885Sdumbbell	memset(*(void **)wb_ptr, 0, RADEON_GPU_PAGE_SIZE);
285254885Sdumbbell	/* disable event_write fences */
286254885Sdumbbell	rdev->wb.use_event = false;
287254885Sdumbbell	/* disabled via module param */
288254885Sdumbbell	if (radeon_no_wb == 1) {
289254885Sdumbbell		rdev->wb.enabled = false;
290254885Sdumbbell	} else {
291254885Sdumbbell		if (rdev->flags & RADEON_IS_AGP) {
292254885Sdumbbell			/* often unreliable on AGP */
293254885Sdumbbell			rdev->wb.enabled = false;
294254885Sdumbbell		} else if (rdev->family < CHIP_R300) {
295254885Sdumbbell			/* often unreliable on pre-r300 */
296254885Sdumbbell			rdev->wb.enabled = false;
297254885Sdumbbell		} else {
298254885Sdumbbell			rdev->wb.enabled = true;
299254885Sdumbbell			/* event_write fences are only available on r600+ */
300254885Sdumbbell			if (rdev->family >= CHIP_R600) {
301254885Sdumbbell				rdev->wb.use_event = true;
302254885Sdumbbell			}
303254885Sdumbbell		}
304254885Sdumbbell	}
305254885Sdumbbell	/* always use writeback/events on NI, APUs */
306254885Sdumbbell	if (rdev->family >= CHIP_PALM) {
307254885Sdumbbell		rdev->wb.enabled = true;
308254885Sdumbbell		rdev->wb.use_event = true;
309254885Sdumbbell	}
310254885Sdumbbell
311254885Sdumbbell	dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis");
312254885Sdumbbell
313254885Sdumbbell	return 0;
314254885Sdumbbell}
315254885Sdumbbell
316254885Sdumbbell/**
317254885Sdumbbell * radeon_vram_location - try to find VRAM location
318254885Sdumbbell * @rdev: radeon device structure holding all necessary informations
319254885Sdumbbell * @mc: memory controller structure holding memory informations
320254885Sdumbbell * @base: base address at which to put VRAM
321254885Sdumbbell *
322254885Sdumbbell * Function will place try to place VRAM at base address provided
323254885Sdumbbell * as parameter (which is so far either PCI aperture address or
324254885Sdumbbell * for IGP TOM base address).
325254885Sdumbbell *
326254885Sdumbbell * If there is not enough space to fit the unvisible VRAM in the 32bits
327254885Sdumbbell * address space then we limit the VRAM size to the aperture.
328254885Sdumbbell *
329254885Sdumbbell * If we are using AGP and if the AGP aperture doesn't allow us to have
330254885Sdumbbell * room for all the VRAM than we restrict the VRAM to the PCI aperture
331254885Sdumbbell * size and print a warning.
332254885Sdumbbell *
333254885Sdumbbell * This function will never fails, worst case are limiting VRAM.
334254885Sdumbbell *
335254885Sdumbbell * Note: GTT start, end, size should be initialized before calling this
336254885Sdumbbell * function on AGP platform.
337254885Sdumbbell *
338254885Sdumbbell * Note: We don't explicitly enforce VRAM start to be aligned on VRAM size,
339254885Sdumbbell * this shouldn't be a problem as we are using the PCI aperture as a reference.
340254885Sdumbbell * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but
341254885Sdumbbell * not IGP.
342254885Sdumbbell *
343254885Sdumbbell * Note: we use mc_vram_size as on some board we need to program the mc to
344254885Sdumbbell * cover the whole aperture even if VRAM size is inferior to aperture size
345254885Sdumbbell * Novell bug 204882 + along with lots of ubuntu ones
346254885Sdumbbell *
347254885Sdumbbell * Note: when limiting vram it's safe to overwritte real_vram_size because
348254885Sdumbbell * we are not in case where real_vram_size is inferior to mc_vram_size (ie
349254885Sdumbbell * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu
350254885Sdumbbell * ones)
351254885Sdumbbell *
352254885Sdumbbell * Note: IGP TOM addr should be the same as the aperture addr, we don't
353254885Sdumbbell * explicitly check for that thought.
354254885Sdumbbell *
355254885Sdumbbell * FIXME: when reducing VRAM size align new size on power of 2.
356254885Sdumbbell */
357254885Sdumbbellvoid radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base)
358254885Sdumbbell{
359254885Sdumbbell	uint64_t limit = (uint64_t)radeon_vram_limit << 20;
360254885Sdumbbell
361254885Sdumbbell	mc->vram_start = base;
362254885Sdumbbell	if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) {
363254885Sdumbbell		dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
364254885Sdumbbell		mc->real_vram_size = mc->aper_size;
365254885Sdumbbell		mc->mc_vram_size = mc->aper_size;
366254885Sdumbbell	}
367254885Sdumbbell	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
368254885Sdumbbell	if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) {
369254885Sdumbbell		dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
370254885Sdumbbell		mc->real_vram_size = mc->aper_size;
371254885Sdumbbell		mc->mc_vram_size = mc->aper_size;
372254885Sdumbbell	}
373254885Sdumbbell	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
374254885Sdumbbell	if (limit && limit < mc->real_vram_size)
375254885Sdumbbell		mc->real_vram_size = limit;
376254885Sdumbbell	dev_info(rdev->dev, "VRAM: %juM 0x%016jX - 0x%016jX (%juM used)\n",
377254885Sdumbbell			(uintmax_t)mc->mc_vram_size >> 20, (uintmax_t)mc->vram_start,
378254885Sdumbbell			(uintmax_t)mc->vram_end, (uintmax_t)mc->real_vram_size >> 20);
379254885Sdumbbell}
380254885Sdumbbell
381254885Sdumbbell/**
382254885Sdumbbell * radeon_gtt_location - try to find GTT location
383254885Sdumbbell * @rdev: radeon device structure holding all necessary informations
384254885Sdumbbell * @mc: memory controller structure holding memory informations
385254885Sdumbbell *
386254885Sdumbbell * Function will place try to place GTT before or after VRAM.
387254885Sdumbbell *
388254885Sdumbbell * If GTT size is bigger than space left then we ajust GTT size.
389254885Sdumbbell * Thus function will never fails.
390254885Sdumbbell *
391254885Sdumbbell * FIXME: when reducing GTT size align new size on power of 2.
392254885Sdumbbell */
393254885Sdumbbellvoid radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
394254885Sdumbbell{
395254885Sdumbbell	u64 size_af, size_bf;
396254885Sdumbbell
397254885Sdumbbell	size_af = ((0xFFFFFFFF - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
398254885Sdumbbell	size_bf = mc->vram_start & ~mc->gtt_base_align;
399254885Sdumbbell	if (size_bf > size_af) {
400254885Sdumbbell		if (mc->gtt_size > size_bf) {
401254885Sdumbbell			dev_warn(rdev->dev, "limiting GTT\n");
402254885Sdumbbell			mc->gtt_size = size_bf;
403254885Sdumbbell		}
404254885Sdumbbell		mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size;
405254885Sdumbbell	} else {
406254885Sdumbbell		if (mc->gtt_size > size_af) {
407254885Sdumbbell			dev_warn(rdev->dev, "limiting GTT\n");
408254885Sdumbbell			mc->gtt_size = size_af;
409254885Sdumbbell		}
410254885Sdumbbell		mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
411254885Sdumbbell	}
412254885Sdumbbell	mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
413254885Sdumbbell	dev_info(rdev->dev, "GTT: %juM 0x%016jX - 0x%016jX\n",
414254885Sdumbbell			(uintmax_t)mc->gtt_size >> 20, (uintmax_t)mc->gtt_start, (uintmax_t)mc->gtt_end);
415254885Sdumbbell}
416254885Sdumbbell
417254885Sdumbbell/*
418254885Sdumbbell * GPU helpers function.
419254885Sdumbbell */
420254885Sdumbbell/**
421254885Sdumbbell * radeon_card_posted - check if the hw has already been initialized
422254885Sdumbbell *
423254885Sdumbbell * @rdev: radeon_device pointer
424254885Sdumbbell *
425254885Sdumbbell * Check if the asic has been initialized (all asics).
426254885Sdumbbell * Used at driver startup.
427254885Sdumbbell * Returns true if initialized or false if not.
428254885Sdumbbell */
429254885Sdumbbellbool radeon_card_posted(struct radeon_device *rdev)
430254885Sdumbbell{
431254885Sdumbbell	uint32_t reg;
432254885Sdumbbell
433254885Sdumbbell#ifdef DUMBBELL_WIP
434254885Sdumbbell	if (efi_enabled(EFI_BOOT) &&
435254885Sdumbbell	    rdev->dev->pci_subvendor == PCI_VENDOR_ID_APPLE)
436254885Sdumbbell		return false;
437254885Sdumbbell#endif /* DUMBBELL_WIP */
438254885Sdumbbell
439254885Sdumbbell	/* first check CRTCs */
440254885Sdumbbell	if (ASIC_IS_DCE41(rdev)) {
441254885Sdumbbell		reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
442254885Sdumbbell			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
443254885Sdumbbell		if (reg & EVERGREEN_CRTC_MASTER_EN)
444254885Sdumbbell			return true;
445254885Sdumbbell	} else if (ASIC_IS_DCE4(rdev)) {
446254885Sdumbbell		reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
447254885Sdumbbell			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
448254885Sdumbbell			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
449254885Sdumbbell			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) |
450254885Sdumbbell			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
451254885Sdumbbell			RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
452254885Sdumbbell		if (reg & EVERGREEN_CRTC_MASTER_EN)
453254885Sdumbbell			return true;
454254885Sdumbbell	} else if (ASIC_IS_AVIVO(rdev)) {
455254885Sdumbbell		reg = RREG32(AVIVO_D1CRTC_CONTROL) |
456254885Sdumbbell		      RREG32(AVIVO_D2CRTC_CONTROL);
457254885Sdumbbell		if (reg & AVIVO_CRTC_EN) {
458254885Sdumbbell			return true;
459254885Sdumbbell		}
460254885Sdumbbell	} else {
461254885Sdumbbell		reg = RREG32(RADEON_CRTC_GEN_CNTL) |
462254885Sdumbbell		      RREG32(RADEON_CRTC2_GEN_CNTL);
463254885Sdumbbell		if (reg & RADEON_CRTC_EN) {
464254885Sdumbbell			return true;
465254885Sdumbbell		}
466254885Sdumbbell	}
467254885Sdumbbell
468254885Sdumbbell	/* then check MEM_SIZE, in case the crtcs are off */
469254885Sdumbbell	if (rdev->family >= CHIP_R600)
470254885Sdumbbell		reg = RREG32(R600_CONFIG_MEMSIZE);
471254885Sdumbbell	else
472254885Sdumbbell		reg = RREG32(RADEON_CONFIG_MEMSIZE);
473254885Sdumbbell
474254885Sdumbbell	if (reg)
475254885Sdumbbell		return true;
476254885Sdumbbell
477254885Sdumbbell	return false;
478254885Sdumbbell
479254885Sdumbbell}
480254885Sdumbbell
481254885Sdumbbell/**
482254885Sdumbbell * radeon_update_bandwidth_info - update display bandwidth params
483254885Sdumbbell *
484254885Sdumbbell * @rdev: radeon_device pointer
485254885Sdumbbell *
486254885Sdumbbell * Used when sclk/mclk are switched or display modes are set.
487254885Sdumbbell * params are used to calculate display watermarks (all asics)
488254885Sdumbbell */
489254885Sdumbbellvoid radeon_update_bandwidth_info(struct radeon_device *rdev)
490254885Sdumbbell{
491254885Sdumbbell	fixed20_12 a;
492254885Sdumbbell	u32 sclk = rdev->pm.current_sclk;
493254885Sdumbbell	u32 mclk = rdev->pm.current_mclk;
494254885Sdumbbell
495254885Sdumbbell	/* sclk/mclk in Mhz */
496254885Sdumbbell	a.full = dfixed_const(100);
497254885Sdumbbell	rdev->pm.sclk.full = dfixed_const(sclk);
498254885Sdumbbell	rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
499254885Sdumbbell	rdev->pm.mclk.full = dfixed_const(mclk);
500254885Sdumbbell	rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
501254885Sdumbbell
502254885Sdumbbell	if (rdev->flags & RADEON_IS_IGP) {
503254885Sdumbbell		a.full = dfixed_const(16);
504254885Sdumbbell		/* core_bandwidth = sclk(Mhz) * 16 */
505254885Sdumbbell		rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a);
506254885Sdumbbell	}
507254885Sdumbbell}
508254885Sdumbbell
509254885Sdumbbell/**
510254885Sdumbbell * radeon_boot_test_post_card - check and possibly initialize the hw
511254885Sdumbbell *
512254885Sdumbbell * @rdev: radeon_device pointer
513254885Sdumbbell *
514254885Sdumbbell * Check if the asic is initialized and if not, attempt to initialize
515254885Sdumbbell * it (all asics).
516254885Sdumbbell * Returns true if initialized or false if not.
517254885Sdumbbell */
518254885Sdumbbellbool radeon_boot_test_post_card(struct radeon_device *rdev)
519254885Sdumbbell{
520254885Sdumbbell	if (radeon_card_posted(rdev))
521254885Sdumbbell		return true;
522254885Sdumbbell
523254885Sdumbbell	if (rdev->bios) {
524254885Sdumbbell		DRM_INFO("GPU not posted. posting now...\n");
525254885Sdumbbell		if (rdev->is_atom_bios)
526254885Sdumbbell			atom_asic_init(rdev->mode_info.atom_context);
527254885Sdumbbell		else
528254885Sdumbbell			radeon_combios_asic_init(rdev->ddev);
529254885Sdumbbell		return true;
530254885Sdumbbell	} else {
531254885Sdumbbell		dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
532254885Sdumbbell		return false;
533254885Sdumbbell	}
534254885Sdumbbell}
535254885Sdumbbell
536254885Sdumbbell/**
537254885Sdumbbell * radeon_dummy_page_init - init dummy page used by the driver
538254885Sdumbbell *
539254885Sdumbbell * @rdev: radeon_device pointer
540254885Sdumbbell *
541254885Sdumbbell * Allocate the dummy page used by the driver (all asics).
542254885Sdumbbell * This dummy page is used by the driver as a filler for gart entries
543254885Sdumbbell * when pages are taken out of the GART
544254885Sdumbbell * Returns 0 on sucess, -ENOMEM on failure.
545254885Sdumbbell */
546254885Sdumbbellint radeon_dummy_page_init(struct radeon_device *rdev)
547254885Sdumbbell{
548254885Sdumbbell	if (rdev->dummy_page.dmah)
549254885Sdumbbell		return 0;
550254885Sdumbbell	rdev->dummy_page.dmah = drm_pci_alloc(rdev->ddev,
551267042Smarius	    PAGE_SIZE, PAGE_SIZE, BUS_SPACE_MAXSIZE_32BIT);
552254885Sdumbbell	if (rdev->dummy_page.dmah == NULL)
553254885Sdumbbell		return -ENOMEM;
554267042Smarius	rdev->dummy_page.addr = rdev->dummy_page.dmah->busaddr;
555254885Sdumbbell	return 0;
556254885Sdumbbell}
557254885Sdumbbell
558254885Sdumbbell/**
559254885Sdumbbell * radeon_dummy_page_fini - free dummy page used by the driver
560254885Sdumbbell *
561254885Sdumbbell * @rdev: radeon_device pointer
562254885Sdumbbell *
563254885Sdumbbell * Frees the dummy page used by the driver (all asics).
564254885Sdumbbell */
565254885Sdumbbellvoid radeon_dummy_page_fini(struct radeon_device *rdev)
566254885Sdumbbell{
567254885Sdumbbell	if (rdev->dummy_page.dmah == NULL)
568254885Sdumbbell		return;
569254885Sdumbbell	drm_pci_free(rdev->ddev, rdev->dummy_page.dmah);
570254885Sdumbbell	rdev->dummy_page.dmah = NULL;
571254885Sdumbbell	rdev->dummy_page.addr = 0;
572254885Sdumbbell}
573254885Sdumbbell
574254885Sdumbbell
575254885Sdumbbell/* ATOM accessor methods */
576254885Sdumbbell/*
577254885Sdumbbell * ATOM is an interpreted byte code stored in tables in the vbios.  The
578254885Sdumbbell * driver registers callbacks to access registers and the interpreter
579254885Sdumbbell * in the driver parses the tables and executes then to program specific
580254885Sdumbbell * actions (set display modes, asic init, etc.).  See radeon_atombios.c,
581254885Sdumbbell * atombios.h, and atom.c
582254885Sdumbbell */
583254885Sdumbbell
584254885Sdumbbell/**
585254885Sdumbbell * cail_pll_read - read PLL register
586254885Sdumbbell *
587254885Sdumbbell * @info: atom card_info pointer
588254885Sdumbbell * @reg: PLL register offset
589254885Sdumbbell *
590254885Sdumbbell * Provides a PLL register accessor for the atom interpreter (r4xx+).
591254885Sdumbbell * Returns the value of the PLL register.
592254885Sdumbbell */
593254885Sdumbbellstatic uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
594254885Sdumbbell{
595254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
596254885Sdumbbell	uint32_t r;
597254885Sdumbbell
598254885Sdumbbell	r = rdev->pll_rreg(rdev, reg);
599254885Sdumbbell	return r;
600254885Sdumbbell}
601254885Sdumbbell
602254885Sdumbbell/**
603254885Sdumbbell * cail_pll_write - write PLL register
604254885Sdumbbell *
605254885Sdumbbell * @info: atom card_info pointer
606254885Sdumbbell * @reg: PLL register offset
607254885Sdumbbell * @val: value to write to the pll register
608254885Sdumbbell *
609254885Sdumbbell * Provides a PLL register accessor for the atom interpreter (r4xx+).
610254885Sdumbbell */
611254885Sdumbbellstatic void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val)
612254885Sdumbbell{
613254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
614254885Sdumbbell
615254885Sdumbbell	rdev->pll_wreg(rdev, reg, val);
616254885Sdumbbell}
617254885Sdumbbell
618254885Sdumbbell/**
619254885Sdumbbell * cail_mc_read - read MC (Memory Controller) register
620254885Sdumbbell *
621254885Sdumbbell * @info: atom card_info pointer
622254885Sdumbbell * @reg: MC register offset
623254885Sdumbbell *
624254885Sdumbbell * Provides an MC register accessor for the atom interpreter (r4xx+).
625254885Sdumbbell * Returns the value of the MC register.
626254885Sdumbbell */
627254885Sdumbbellstatic uint32_t cail_mc_read(struct card_info *info, uint32_t reg)
628254885Sdumbbell{
629254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
630254885Sdumbbell	uint32_t r;
631254885Sdumbbell
632254885Sdumbbell	r = rdev->mc_rreg(rdev, reg);
633254885Sdumbbell	return r;
634254885Sdumbbell}
635254885Sdumbbell
636254885Sdumbbell/**
637254885Sdumbbell * cail_mc_write - write MC (Memory Controller) register
638254885Sdumbbell *
639254885Sdumbbell * @info: atom card_info pointer
640254885Sdumbbell * @reg: MC register offset
641254885Sdumbbell * @val: value to write to the pll register
642254885Sdumbbell *
643254885Sdumbbell * Provides a MC register accessor for the atom interpreter (r4xx+).
644254885Sdumbbell */
645254885Sdumbbellstatic void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val)
646254885Sdumbbell{
647254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
648254885Sdumbbell
649254885Sdumbbell	rdev->mc_wreg(rdev, reg, val);
650254885Sdumbbell}
651254885Sdumbbell
652254885Sdumbbell/**
653254885Sdumbbell * cail_reg_write - write MMIO register
654254885Sdumbbell *
655254885Sdumbbell * @info: atom card_info pointer
656254885Sdumbbell * @reg: MMIO register offset
657254885Sdumbbell * @val: value to write to the pll register
658254885Sdumbbell *
659254885Sdumbbell * Provides a MMIO register accessor for the atom interpreter (r4xx+).
660254885Sdumbbell */
661254885Sdumbbellstatic void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val)
662254885Sdumbbell{
663254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
664254885Sdumbbell
665254885Sdumbbell	WREG32(reg*4, val);
666254885Sdumbbell}
667254885Sdumbbell
668254885Sdumbbell/**
669254885Sdumbbell * cail_reg_read - read MMIO register
670254885Sdumbbell *
671254885Sdumbbell * @info: atom card_info pointer
672254885Sdumbbell * @reg: MMIO register offset
673254885Sdumbbell *
674254885Sdumbbell * Provides an MMIO register accessor for the atom interpreter (r4xx+).
675254885Sdumbbell * Returns the value of the MMIO register.
676254885Sdumbbell */
677254885Sdumbbellstatic uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
678254885Sdumbbell{
679254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
680254885Sdumbbell	uint32_t r;
681254885Sdumbbell
682254885Sdumbbell	r = RREG32(reg*4);
683254885Sdumbbell	return r;
684254885Sdumbbell}
685254885Sdumbbell
686254885Sdumbbell/**
687254885Sdumbbell * cail_ioreg_write - write IO register
688254885Sdumbbell *
689254885Sdumbbell * @info: atom card_info pointer
690254885Sdumbbell * @reg: IO register offset
691254885Sdumbbell * @val: value to write to the pll register
692254885Sdumbbell *
693254885Sdumbbell * Provides a IO register accessor for the atom interpreter (r4xx+).
694254885Sdumbbell */
695254885Sdumbbellstatic void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val)
696254885Sdumbbell{
697254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
698254885Sdumbbell
699254885Sdumbbell	WREG32_IO(reg*4, val);
700254885Sdumbbell}
701254885Sdumbbell
702254885Sdumbbell/**
703254885Sdumbbell * cail_ioreg_read - read IO register
704254885Sdumbbell *
705254885Sdumbbell * @info: atom card_info pointer
706254885Sdumbbell * @reg: IO register offset
707254885Sdumbbell *
708254885Sdumbbell * Provides an IO register accessor for the atom interpreter (r4xx+).
709254885Sdumbbell * Returns the value of the IO register.
710254885Sdumbbell */
711254885Sdumbbellstatic uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
712254885Sdumbbell{
713254885Sdumbbell	struct radeon_device *rdev = info->dev->dev_private;
714254885Sdumbbell	uint32_t r;
715254885Sdumbbell
716254885Sdumbbell	r = RREG32_IO(reg*4);
717254885Sdumbbell	return r;
718254885Sdumbbell}
719254885Sdumbbell
720254885Sdumbbell/**
721254885Sdumbbell * radeon_atombios_init - init the driver info and callbacks for atombios
722254885Sdumbbell *
723254885Sdumbbell * @rdev: radeon_device pointer
724254885Sdumbbell *
725254885Sdumbbell * Initializes the driver info and register access callbacks for the
726254885Sdumbbell * ATOM interpreter (r4xx+).
727254885Sdumbbell * Returns 0 on sucess, -ENOMEM on failure.
728254885Sdumbbell * Called at driver startup.
729254885Sdumbbell */
730254885Sdumbbellint radeon_atombios_init(struct radeon_device *rdev)
731254885Sdumbbell{
732254885Sdumbbell	struct card_info *atom_card_info =
733254885Sdumbbell	    malloc(sizeof(struct card_info),
734254885Sdumbbell		DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
735254885Sdumbbell
736254885Sdumbbell	if (!atom_card_info)
737254885Sdumbbell		return -ENOMEM;
738254885Sdumbbell
739254885Sdumbbell	rdev->mode_info.atom_card_info = atom_card_info;
740254885Sdumbbell	atom_card_info->dev = rdev->ddev;
741254885Sdumbbell	atom_card_info->reg_read = cail_reg_read;
742254885Sdumbbell	atom_card_info->reg_write = cail_reg_write;
743254885Sdumbbell	/* needed for iio ops */
744254885Sdumbbell	if (rdev->rio_mem) {
745254885Sdumbbell		atom_card_info->ioreg_read = cail_ioreg_read;
746254885Sdumbbell		atom_card_info->ioreg_write = cail_ioreg_write;
747254885Sdumbbell	} else {
748254885Sdumbbell		DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n");
749254885Sdumbbell		atom_card_info->ioreg_read = cail_reg_read;
750254885Sdumbbell		atom_card_info->ioreg_write = cail_reg_write;
751254885Sdumbbell	}
752254885Sdumbbell	atom_card_info->mc_read = cail_mc_read;
753254885Sdumbbell	atom_card_info->mc_write = cail_mc_write;
754254885Sdumbbell	atom_card_info->pll_read = cail_pll_read;
755254885Sdumbbell	atom_card_info->pll_write = cail_pll_write;
756254885Sdumbbell
757254885Sdumbbell	rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
758254885Sdumbbell	sx_init(&rdev->mode_info.atom_context->mutex,
759254885Sdumbbell	    "drm__radeon_device__mode_info__atom_context__mutex");
760254885Sdumbbell	radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
761254885Sdumbbell	atom_allocate_fb_scratch(rdev->mode_info.atom_context);
762254885Sdumbbell	return 0;
763254885Sdumbbell}
764254885Sdumbbell
765254885Sdumbbell/**
766254885Sdumbbell * radeon_atombios_fini - free the driver info and callbacks for atombios
767254885Sdumbbell *
768254885Sdumbbell * @rdev: radeon_device pointer
769254885Sdumbbell *
770254885Sdumbbell * Frees the driver info and register access callbacks for the ATOM
771254885Sdumbbell * interpreter (r4xx+).
772254885Sdumbbell * Called at driver shutdown.
773254885Sdumbbell */
774254885Sdumbbellvoid radeon_atombios_fini(struct radeon_device *rdev)
775254885Sdumbbell{
776254885Sdumbbell	if (rdev->mode_info.atom_context) {
777254885Sdumbbell		free(rdev->mode_info.atom_context->scratch, DRM_MEM_DRIVER);
778254885Sdumbbell		atom_destroy(rdev->mode_info.atom_context);
779254885Sdumbbell	}
780254885Sdumbbell	free(rdev->mode_info.atom_card_info, DRM_MEM_DRIVER);
781254885Sdumbbell}
782254885Sdumbbell
783254885Sdumbbell/* COMBIOS */
784254885Sdumbbell/*
785254885Sdumbbell * COMBIOS is the bios format prior to ATOM. It provides
786254885Sdumbbell * command tables similar to ATOM, but doesn't have a unified
787254885Sdumbbell * parser.  See radeon_combios.c
788254885Sdumbbell */
789254885Sdumbbell
790254885Sdumbbell/**
791254885Sdumbbell * radeon_combios_init - init the driver info for combios
792254885Sdumbbell *
793254885Sdumbbell * @rdev: radeon_device pointer
794254885Sdumbbell *
795254885Sdumbbell * Initializes the driver info for combios (r1xx-r3xx).
796254885Sdumbbell * Returns 0 on sucess.
797254885Sdumbbell * Called at driver startup.
798254885Sdumbbell */
799254885Sdumbbellint radeon_combios_init(struct radeon_device *rdev)
800254885Sdumbbell{
801254885Sdumbbell	radeon_combios_initialize_bios_scratch_regs(rdev->ddev);
802254885Sdumbbell	return 0;
803254885Sdumbbell}
804254885Sdumbbell
805254885Sdumbbell/**
806254885Sdumbbell * radeon_combios_fini - free the driver info for combios
807254885Sdumbbell *
808254885Sdumbbell * @rdev: radeon_device pointer
809254885Sdumbbell *
810254885Sdumbbell * Frees the driver info for combios (r1xx-r3xx).
811254885Sdumbbell * Called at driver shutdown.
812254885Sdumbbell */
813254885Sdumbbellvoid radeon_combios_fini(struct radeon_device *rdev)
814254885Sdumbbell{
815254885Sdumbbell}
816254885Sdumbbell
817254885Sdumbbell#ifdef DUMBBELL_WIP
818254885Sdumbbell/* if we get transitioned to only one device, take VGA back */
819254885Sdumbbell/**
820254885Sdumbbell * radeon_vga_set_decode - enable/disable vga decode
821254885Sdumbbell *
822254885Sdumbbell * @cookie: radeon_device pointer
823254885Sdumbbell * @state: enable/disable vga decode
824254885Sdumbbell *
825254885Sdumbbell * Enable/disable vga decode (all asics).
826254885Sdumbbell * Returns VGA resource flags.
827254885Sdumbbell */
828254885Sdumbbellstatic unsigned int radeon_vga_set_decode(void *cookie, bool state)
829254885Sdumbbell{
830254885Sdumbbell	struct radeon_device *rdev = cookie;
831254885Sdumbbell	radeon_vga_set_state(rdev, state);
832254885Sdumbbell	if (state)
833254885Sdumbbell		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
834254885Sdumbbell		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
835254885Sdumbbell	else
836254885Sdumbbell		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
837254885Sdumbbell}
838254885Sdumbbell#endif /* DUMBBELL_WIP */
839254885Sdumbbell
840254885Sdumbbell/**
841254885Sdumbbell * radeon_check_pot_argument - check that argument is a power of two
842254885Sdumbbell *
843254885Sdumbbell * @arg: value to check
844254885Sdumbbell *
845254885Sdumbbell * Validates that a certain argument is a power of two (all asics).
846254885Sdumbbell * Returns true if argument is valid.
847254885Sdumbbell */
848254885Sdumbbellstatic bool radeon_check_pot_argument(int arg)
849254885Sdumbbell{
850254885Sdumbbell	return (arg & (arg - 1)) == 0;
851254885Sdumbbell}
852254885Sdumbbell
853254885Sdumbbell/**
854254885Sdumbbell * radeon_check_arguments - validate module params
855254885Sdumbbell *
856254885Sdumbbell * @rdev: radeon_device pointer
857254885Sdumbbell *
858254885Sdumbbell * Validates certain module parameters and updates
859254885Sdumbbell * the associated values used by the driver (all asics).
860254885Sdumbbell */
861254885Sdumbbellstatic void radeon_check_arguments(struct radeon_device *rdev)
862254885Sdumbbell{
863254885Sdumbbell	/* vramlimit must be a power of two */
864254885Sdumbbell	if (!radeon_check_pot_argument(radeon_vram_limit)) {
865254885Sdumbbell		dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n",
866254885Sdumbbell				radeon_vram_limit);
867254885Sdumbbell		radeon_vram_limit = 0;
868254885Sdumbbell	}
869254885Sdumbbell
870254885Sdumbbell	/* gtt size must be power of two and greater or equal to 32M */
871254885Sdumbbell	if (radeon_gart_size < 32) {
872254885Sdumbbell		dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n",
873254885Sdumbbell				radeon_gart_size);
874254885Sdumbbell		radeon_gart_size = 512;
875254885Sdumbbell
876254885Sdumbbell	} else if (!radeon_check_pot_argument(radeon_gart_size)) {
877254885Sdumbbell		dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
878254885Sdumbbell				radeon_gart_size);
879254885Sdumbbell		radeon_gart_size = 512;
880254885Sdumbbell	}
881254885Sdumbbell	rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20;
882254885Sdumbbell
883254885Sdumbbell	/* AGP mode can only be -1, 1, 2, 4, 8 */
884254885Sdumbbell	switch (radeon_agpmode) {
885254885Sdumbbell	case -1:
886254885Sdumbbell	case 0:
887254885Sdumbbell	case 1:
888254885Sdumbbell	case 2:
889254885Sdumbbell	case 4:
890254885Sdumbbell	case 8:
891254885Sdumbbell		break;
892254885Sdumbbell	default:
893254885Sdumbbell		dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: "
894254885Sdumbbell				"-1, 0, 1, 2, 4, 8)\n", radeon_agpmode);
895254885Sdumbbell		radeon_agpmode = 0;
896254885Sdumbbell		break;
897254885Sdumbbell	}
898254885Sdumbbell}
899254885Sdumbbell
900254885Sdumbbell/**
901254885Sdumbbell * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is
902254885Sdumbbell * needed for waking up.
903254885Sdumbbell *
904254885Sdumbbell * @pdev: pci dev pointer
905254885Sdumbbell */
906254885Sdumbbell#ifdef DUMBBELL_WIP
907254885Sdumbbellstatic bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
908254885Sdumbbell{
909254885Sdumbbell
910254885Sdumbbell	/* 6600m in a macbook pro */
911254885Sdumbbell	if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
912254885Sdumbbell	    pdev->subsystem_device == 0x00e2) {
913254885Sdumbbell		printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n");
914254885Sdumbbell		return true;
915254885Sdumbbell	}
916254885Sdumbbell
917254885Sdumbbell	return false;
918254885Sdumbbell}
919254885Sdumbbell#endif /* DUMBBELL_WIP */
920254885Sdumbbell
921254885Sdumbbell/**
922254885Sdumbbell * radeon_switcheroo_set_state - set switcheroo state
923254885Sdumbbell *
924254885Sdumbbell * @pdev: pci dev pointer
925254885Sdumbbell * @state: vga switcheroo state
926254885Sdumbbell *
927254885Sdumbbell * Callback for the switcheroo driver.  Suspends or resumes the
928254885Sdumbbell * the asics before or after it is powered up using ACPI methods.
929254885Sdumbbell */
930254885Sdumbbell#ifdef DUMBBELL_WIP
931254885Sdumbbellstatic void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
932254885Sdumbbell{
933254885Sdumbbell	struct drm_device *dev = pci_get_drvdata(pdev);
934254885Sdumbbell	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
935254885Sdumbbell	if (state == VGA_SWITCHEROO_ON) {
936254885Sdumbbell		unsigned d3_delay = dev->pdev->d3_delay;
937254885Sdumbbell
938254885Sdumbbell		printk(KERN_INFO "radeon: switched on\n");
939254885Sdumbbell		/* don't suspend or resume card normally */
940254885Sdumbbell		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
941254885Sdumbbell
942254885Sdumbbell		if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev))
943254885Sdumbbell			dev->pdev->d3_delay = 20;
944254885Sdumbbell
945254885Sdumbbell		radeon_resume_kms(dev);
946254885Sdumbbell
947254885Sdumbbell		dev->pdev->d3_delay = d3_delay;
948254885Sdumbbell
949254885Sdumbbell		dev->switch_power_state = DRM_SWITCH_POWER_ON;
950254885Sdumbbell		drm_kms_helper_poll_enable(dev);
951254885Sdumbbell	} else {
952254885Sdumbbell		printk(KERN_INFO "radeon: switched off\n");
953254885Sdumbbell		drm_kms_helper_poll_disable(dev);
954254885Sdumbbell		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
955254885Sdumbbell		radeon_suspend_kms(dev, pmm);
956254885Sdumbbell		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
957254885Sdumbbell	}
958254885Sdumbbell}
959254885Sdumbbell#endif /* DUMBBELL_WIP */
960254885Sdumbbell
961254885Sdumbbell/**
962254885Sdumbbell * radeon_switcheroo_can_switch - see if switcheroo state can change
963254885Sdumbbell *
964254885Sdumbbell * @pdev: pci dev pointer
965254885Sdumbbell *
966254885Sdumbbell * Callback for the switcheroo driver.  Check of the switcheroo
967254885Sdumbbell * state can be changed.
968254885Sdumbbell * Returns true if the state can be changed, false if not.
969254885Sdumbbell */
970254885Sdumbbell#ifdef DUMBBELL_WIP
971254885Sdumbbellstatic bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
972254885Sdumbbell{
973254885Sdumbbell	struct drm_device *dev = pci_get_drvdata(pdev);
974254885Sdumbbell	bool can_switch;
975254885Sdumbbell
976254885Sdumbbell	spin_lock(&dev->count_lock);
977254885Sdumbbell	can_switch = (dev->open_count == 0);
978254885Sdumbbell	spin_unlock(&dev->count_lock);
979254885Sdumbbell	return can_switch;
980254885Sdumbbell}
981254885Sdumbbell
982254885Sdumbbellstatic const struct vga_switcheroo_client_ops radeon_switcheroo_ops = {
983254885Sdumbbell	.set_gpu_state = radeon_switcheroo_set_state,
984254885Sdumbbell	.reprobe = NULL,
985254885Sdumbbell	.can_switch = radeon_switcheroo_can_switch,
986254885Sdumbbell};
987254885Sdumbbell#endif /* DUMBBELL_WIP */
988254885Sdumbbell
989254885Sdumbbell/**
990254885Sdumbbell * radeon_device_init - initialize the driver
991254885Sdumbbell *
992254885Sdumbbell * @rdev: radeon_device pointer
993254885Sdumbbell * @pdev: drm dev pointer
994254885Sdumbbell * @flags: driver flags
995254885Sdumbbell *
996254885Sdumbbell * Initializes the driver info and hw (all asics).
997254885Sdumbbell * Returns 0 for success or an error on failure.
998254885Sdumbbell * Called at driver startup.
999254885Sdumbbell */
1000254885Sdumbbellint radeon_device_init(struct radeon_device *rdev,
1001254885Sdumbbell		       struct drm_device *ddev,
1002254885Sdumbbell		       uint32_t flags)
1003254885Sdumbbell{
1004254885Sdumbbell	int r, i;
1005254885Sdumbbell	int dma_bits;
1006254885Sdumbbell
1007254885Sdumbbell	rdev->shutdown = false;
1008254885Sdumbbell	rdev->dev = ddev->device;
1009254885Sdumbbell	rdev->ddev = ddev;
1010254885Sdumbbell	rdev->flags = flags;
1011254885Sdumbbell	rdev->family = flags & RADEON_FAMILY_MASK;
1012254885Sdumbbell	rdev->is_atom_bios = false;
1013254885Sdumbbell	rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
1014254885Sdumbbell	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
1015254885Sdumbbell	rdev->accel_working = false;
1016254885Sdumbbell	rdev->fictitious_range_registered = false;
1017254885Sdumbbell	/* set up ring ids */
1018254885Sdumbbell	for (i = 0; i < RADEON_NUM_RINGS; i++) {
1019254885Sdumbbell		rdev->ring[i].idx = i;
1020254885Sdumbbell	}
1021254885Sdumbbell
1022254885Sdumbbell	DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n",
1023254885Sdumbbell		radeon_family_name[rdev->family], ddev->pci_vendor, ddev->pci_device,
1024254885Sdumbbell		ddev->pci_subvendor, ddev->pci_subdevice);
1025254885Sdumbbell
1026254885Sdumbbell	/* mutex initialization are all done here so we
1027254885Sdumbbell	 * can recall function without having locking issues */
1028254885Sdumbbell	sx_init(&rdev->ring_lock, "drm__radeon_device__ring_lock");
1029254885Sdumbbell	sx_init(&rdev->dc_hw_i2c_mutex, "drm__radeon_device__dc_hw_i2c_mutex");
1030254885Sdumbbell	atomic_set(&rdev->ih.lock, 0);
1031254885Sdumbbell	sx_init(&rdev->gem.mutex, "drm__radeon_device__gem__mutex");
1032254885Sdumbbell	sx_init(&rdev->pm.mutex, "drm__radeon_device__pm__mutex");
1033254885Sdumbbell	sx_init(&rdev->gpu_clock_mutex, "drm__radeon_device__gpu_clock_mutex");
1034254885Sdumbbell	sx_init(&rdev->pm.mclk_lock, "drm__radeon_device__pm__mclk_lock");
1035254885Sdumbbell	sx_init(&rdev->exclusive_lock, "drm__radeon_device__exclusive_lock");
1036254885Sdumbbell	DRM_INIT_WAITQUEUE(&rdev->irq.vblank_queue);
1037254885Sdumbbell	r = radeon_gem_init(rdev);
1038254885Sdumbbell	if (r)
1039254885Sdumbbell		return r;
1040254885Sdumbbell	/* initialize vm here */
1041254885Sdumbbell	sx_init(&rdev->vm_manager.lock, "drm__radeon_device__vm_manager__lock");
1042254885Sdumbbell	/* Adjust VM size here.
1043254885Sdumbbell	 * Currently set to 4GB ((1 << 20) 4k pages).
1044254885Sdumbbell	 * Max GPUVM size for cayman and SI is 40 bits.
1045254885Sdumbbell	 */
1046254885Sdumbbell	rdev->vm_manager.max_pfn = 1 << 20;
1047254885Sdumbbell	INIT_LIST_HEAD(&rdev->vm_manager.lru_vm);
1048254885Sdumbbell
1049254885Sdumbbell	/* Set asic functions */
1050254885Sdumbbell	r = radeon_asic_init(rdev);
1051254885Sdumbbell	if (r)
1052254885Sdumbbell		return r;
1053254885Sdumbbell	radeon_check_arguments(rdev);
1054254885Sdumbbell
1055254885Sdumbbell	/* all of the newer IGP chips have an internal gart
1056254885Sdumbbell	 * However some rs4xx report as AGP, so remove that here.
1057254885Sdumbbell	 */
1058254885Sdumbbell	if ((rdev->family >= CHIP_RS400) &&
1059254885Sdumbbell	    (rdev->flags & RADEON_IS_IGP)) {
1060254885Sdumbbell		rdev->flags &= ~RADEON_IS_AGP;
1061254885Sdumbbell	}
1062254885Sdumbbell
1063254885Sdumbbell	if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
1064254885Sdumbbell		radeon_agp_disable(rdev);
1065254885Sdumbbell	}
1066254885Sdumbbell
1067254885Sdumbbell	/* set DMA mask + need_dma32 flags.
1068254885Sdumbbell	 * PCIE - can handle 40-bits.
1069254885Sdumbbell	 * IGP - can handle 40-bits
1070254885Sdumbbell	 * AGP - generally dma32 is safest
1071254885Sdumbbell	 * PCI - dma32 for legacy pci gart, 40 bits on newer asics
1072254885Sdumbbell	 */
1073254885Sdumbbell	rdev->need_dma32 = false;
1074254885Sdumbbell	if (rdev->flags & RADEON_IS_AGP)
1075254885Sdumbbell		rdev->need_dma32 = true;
1076254885Sdumbbell	if ((rdev->flags & RADEON_IS_PCI) &&
1077254885Sdumbbell	    (rdev->family <= CHIP_RS740))
1078254885Sdumbbell		rdev->need_dma32 = true;
1079254885Sdumbbell
1080254885Sdumbbell	dma_bits = rdev->need_dma32 ? 32 : 40;
1081254885Sdumbbell#ifdef DUMBBELL_WIP
1082254885Sdumbbell	r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
1083254885Sdumbbell	if (r) {
1084254885Sdumbbell		rdev->need_dma32 = true;
1085254885Sdumbbell		dma_bits = 32;
1086254885Sdumbbell		printk(KERN_WARNING "radeon: No suitable DMA available.\n");
1087254885Sdumbbell	}
1088254885Sdumbbell	r = pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
1089254885Sdumbbell	if (r) {
1090254885Sdumbbell		pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(32));
1091254885Sdumbbell		printk(KERN_WARNING "radeon: No coherent DMA available.\n");
1092254885Sdumbbell	}
1093254885Sdumbbell#endif /* DUMBBELL_WIP */
1094254885Sdumbbell
1095254885Sdumbbell	/* Registers mapping */
1096254885Sdumbbell	/* TODO: block userspace mapping of io register */
1097254885Sdumbbell	DRM_SPININIT(&rdev->mmio_idx_lock, "drm__radeon_device__mmio_idx_lock");
1098254885Sdumbbell	rdev->rmmio_rid = PCIR_BAR(2);
1099254885Sdumbbell	rdev->rmmio = bus_alloc_resource_any(rdev->dev, SYS_RES_MEMORY,
1100254885Sdumbbell	    &rdev->rmmio_rid, RF_ACTIVE | RF_SHAREABLE);
1101254885Sdumbbell	if (rdev->rmmio == NULL) {
1102254885Sdumbbell		return -ENOMEM;
1103254885Sdumbbell	}
1104254885Sdumbbell	rdev->rmmio_base = rman_get_start(rdev->rmmio);
1105254885Sdumbbell	rdev->rmmio_size = rman_get_size(rdev->rmmio);
1106254885Sdumbbell	DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
1107254885Sdumbbell	DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
1108254885Sdumbbell
1109254885Sdumbbell	/* io port mapping */
1110254885Sdumbbell	for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) {
1111254885Sdumbbell		uint32_t data;
1112254885Sdumbbell
1113254885Sdumbbell		data = pci_read_config(rdev->dev, PCIR_BAR(i), 4);
1114254885Sdumbbell		if (PCI_BAR_IO(data)) {
1115254885Sdumbbell			rdev->rio_rid = PCIR_BAR(i);
1116254885Sdumbbell			rdev->rio_mem = bus_alloc_resource_any(rdev->dev,
1117254885Sdumbbell			    SYS_RES_IOPORT, &rdev->rio_rid,
1118254885Sdumbbell			    RF_ACTIVE | RF_SHAREABLE);
1119254885Sdumbbell			break;
1120254885Sdumbbell		}
1121254885Sdumbbell	}
1122254885Sdumbbell	if (rdev->rio_mem == NULL)
1123254885Sdumbbell		DRM_ERROR("Unable to find PCI I/O BAR\n");
1124254885Sdumbbell
1125254885Sdumbbell	rdev->tq = taskqueue_create("radeonkms", M_WAITOK,
1126254885Sdumbbell	    taskqueue_thread_enqueue, &rdev->tq);
1127254885Sdumbbell	taskqueue_start_threads(&rdev->tq, 1, PWAIT, "radeon taskq");
1128254885Sdumbbell
1129254885Sdumbbell#ifdef DUMBBELL_WIP
1130254885Sdumbbell	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
1131254885Sdumbbell	/* this will fail for cards that aren't VGA class devices, just
1132254885Sdumbbell	 * ignore it */
1133254885Sdumbbell	vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
1134254885Sdumbbell	vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops);
1135254885Sdumbbell#endif /* DUMBBELL_WIP */
1136254885Sdumbbell
1137254885Sdumbbell	r = radeon_init(rdev);
1138254885Sdumbbell	if (r)
1139254885Sdumbbell		return r;
1140254885Sdumbbell
1141254885Sdumbbell	r = radeon_ib_ring_tests(rdev);
1142254885Sdumbbell	if (r)
1143254885Sdumbbell		DRM_ERROR("ib ring test failed (%d).\n", r);
1144254885Sdumbbell
1145254885Sdumbbell	if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
1146254885Sdumbbell		/* Acceleration not working on AGP card try again
1147254885Sdumbbell		 * with fallback to PCI or PCIE GART
1148254885Sdumbbell		 */
1149254885Sdumbbell		radeon_asic_reset(rdev);
1150254885Sdumbbell		radeon_fini(rdev);
1151254885Sdumbbell		radeon_agp_disable(rdev);
1152254885Sdumbbell		r = radeon_init(rdev);
1153254885Sdumbbell		if (r)
1154254885Sdumbbell			return r;
1155254885Sdumbbell	}
1156254885Sdumbbell
1157254885Sdumbbell	DRM_INFO("%s: Taking over the fictitious range 0x%jx-0x%jx\n",
1158254885Sdumbbell	    __func__, (uintmax_t)rdev->mc.aper_base,
1159254885Sdumbbell	    (uintmax_t)rdev->mc.aper_base + rdev->mc.visible_vram_size);
1160254885Sdumbbell	r = vm_phys_fictitious_reg_range(
1161254885Sdumbbell	    rdev->mc.aper_base,
1162254885Sdumbbell	    rdev->mc.aper_base + rdev->mc.visible_vram_size,
1163254885Sdumbbell	    VM_MEMATTR_WRITE_COMBINING);
1164254885Sdumbbell	if (r != 0) {
1165254885Sdumbbell		DRM_ERROR("Failed to register fictitious range "
1166254885Sdumbbell		    "0x%jx-0x%jx (%d).\n", (uintmax_t)rdev->mc.aper_base,
1167254885Sdumbbell		    (uintmax_t)rdev->mc.aper_base + rdev->mc.visible_vram_size, r);
1168254885Sdumbbell		return (-r);
1169254885Sdumbbell	}
1170254885Sdumbbell	rdev->fictitious_range_registered = true;
1171254885Sdumbbell
1172254885Sdumbbell	if ((radeon_testing & 1)) {
1173254885Sdumbbell		radeon_test_moves(rdev);
1174254885Sdumbbell	}
1175254885Sdumbbell	if ((radeon_testing & 2)) {
1176254885Sdumbbell		radeon_test_syncing(rdev);
1177254885Sdumbbell	}
1178254885Sdumbbell	if (radeon_benchmarking) {
1179254885Sdumbbell		radeon_benchmark(rdev, radeon_benchmarking);
1180254885Sdumbbell	}
1181254885Sdumbbell	return 0;
1182254885Sdumbbell}
1183254885Sdumbbell
1184254885Sdumbbell#ifdef DUMBBELL_WIP
1185254885Sdumbbellstatic void radeon_debugfs_remove_files(struct radeon_device *rdev);
1186254885Sdumbbell#endif /* DUMBBELL_WIP */
1187254885Sdumbbell
1188254885Sdumbbell/**
1189254885Sdumbbell * radeon_device_fini - tear down the driver
1190254885Sdumbbell *
1191254885Sdumbbell * @rdev: radeon_device pointer
1192254885Sdumbbell *
1193254885Sdumbbell * Tear down the driver info (all asics).
1194254885Sdumbbell * Called at driver shutdown.
1195254885Sdumbbell */
1196254885Sdumbbellvoid radeon_device_fini(struct radeon_device *rdev)
1197254885Sdumbbell{
1198254885Sdumbbell	DRM_INFO("radeon: finishing device.\n");
1199254885Sdumbbell	rdev->shutdown = true;
1200254885Sdumbbell	/* evict vram memory */
1201254885Sdumbbell	radeon_bo_evict_vram(rdev);
1202254885Sdumbbell
1203254885Sdumbbell	if (rdev->fictitious_range_registered) {
1204254885Sdumbbell		vm_phys_fictitious_unreg_range(
1205254885Sdumbbell		    rdev->mc.aper_base,
1206254885Sdumbbell		    rdev->mc.aper_base + rdev->mc.visible_vram_size);
1207254885Sdumbbell	}
1208254885Sdumbbell
1209254885Sdumbbell	radeon_fini(rdev);
1210254885Sdumbbell#ifdef DUMBBELL_WIP
1211254885Sdumbbell	vga_switcheroo_unregister_client(rdev->pdev);
1212254885Sdumbbell	vga_client_register(rdev->pdev, NULL, NULL, NULL);
1213254885Sdumbbell#endif /* DUMBBELL_WIP */
1214254885Sdumbbell
1215254885Sdumbbell	if (rdev->tq != NULL) {
1216254885Sdumbbell		taskqueue_free(rdev->tq);
1217254885Sdumbbell		rdev->tq = NULL;
1218254885Sdumbbell	}
1219254885Sdumbbell
1220254885Sdumbbell	if (rdev->rio_mem)
1221254885Sdumbbell		bus_release_resource(rdev->dev, SYS_RES_IOPORT, rdev->rio_rid,
1222254885Sdumbbell		    rdev->rio_mem);
1223254885Sdumbbell	rdev->rio_mem = NULL;
1224254885Sdumbbell	bus_release_resource(rdev->dev, SYS_RES_MEMORY, rdev->rmmio_rid,
1225254885Sdumbbell	    rdev->rmmio);
1226254885Sdumbbell	rdev->rmmio = NULL;
1227254885Sdumbbell#ifdef DUMBBELL_WIP
1228254885Sdumbbell	radeon_debugfs_remove_files(rdev);
1229254885Sdumbbell#endif /* DUMBBELL_WIP */
1230254885Sdumbbell}
1231254885Sdumbbell
1232254885Sdumbbell
1233254885Sdumbbell/*
1234254885Sdumbbell * Suspend & resume.
1235254885Sdumbbell */
1236254885Sdumbbell/**
1237254885Sdumbbell * radeon_suspend_kms - initiate device suspend
1238254885Sdumbbell *
1239254885Sdumbbell * @pdev: drm dev pointer
1240254885Sdumbbell * @state: suspend state
1241254885Sdumbbell *
1242254885Sdumbbell * Puts the hw in the suspend state (all asics).
1243254885Sdumbbell * Returns 0 for success or an error on failure.
1244254885Sdumbbell * Called at driver suspend.
1245254885Sdumbbell */
1246254885Sdumbbellint radeon_suspend_kms(struct drm_device *dev)
1247254885Sdumbbell{
1248254885Sdumbbell	struct radeon_device *rdev;
1249254885Sdumbbell	struct drm_crtc *crtc;
1250254885Sdumbbell	struct drm_connector *connector;
1251254885Sdumbbell	int i, r;
1252254885Sdumbbell	bool force_completion = false;
1253254885Sdumbbell
1254254885Sdumbbell	if (dev == NULL || dev->dev_private == NULL) {
1255254885Sdumbbell		return -ENODEV;
1256254885Sdumbbell	}
1257254885Sdumbbell#ifdef DUMBBELL_WIP
1258254885Sdumbbell	if (state.event == PM_EVENT_PRETHAW) {
1259254885Sdumbbell		return 0;
1260254885Sdumbbell	}
1261254885Sdumbbell#endif /* DUMBBELL_WIP */
1262254885Sdumbbell	rdev = dev->dev_private;
1263254885Sdumbbell
1264254885Sdumbbell	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
1265254885Sdumbbell		return 0;
1266254885Sdumbbell
1267254885Sdumbbell	drm_kms_helper_poll_disable(dev);
1268254885Sdumbbell
1269254885Sdumbbell	/* turn off display hw */
1270254885Sdumbbell	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1271254885Sdumbbell		drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
1272254885Sdumbbell	}
1273254885Sdumbbell
1274254885Sdumbbell	/* unpin the front buffers */
1275254885Sdumbbell	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1276254885Sdumbbell		struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
1277254885Sdumbbell		struct radeon_bo *robj;
1278254885Sdumbbell
1279254885Sdumbbell		if (rfb == NULL || rfb->obj == NULL) {
1280254885Sdumbbell			continue;
1281254885Sdumbbell		}
1282254885Sdumbbell		robj = gem_to_radeon_bo(rfb->obj);
1283254885Sdumbbell		/* don't unpin kernel fb objects */
1284254885Sdumbbell		if (!radeon_fbdev_robj_is_fb(rdev, robj)) {
1285254885Sdumbbell			r = radeon_bo_reserve(robj, false);
1286254885Sdumbbell			if (r == 0) {
1287254885Sdumbbell				radeon_bo_unpin(robj);
1288254885Sdumbbell				radeon_bo_unreserve(robj);
1289254885Sdumbbell			}
1290254885Sdumbbell		}
1291254885Sdumbbell	}
1292254885Sdumbbell	/* evict vram memory */
1293254885Sdumbbell	radeon_bo_evict_vram(rdev);
1294254885Sdumbbell
1295254885Sdumbbell	sx_xlock(&rdev->ring_lock);
1296254885Sdumbbell	/* wait for gpu to finish processing current batch */
1297254885Sdumbbell	for (i = 0; i < RADEON_NUM_RINGS; i++) {
1298254885Sdumbbell		r = radeon_fence_wait_empty_locked(rdev, i);
1299254885Sdumbbell		if (r) {
1300254885Sdumbbell			/* delay GPU reset to resume */
1301254885Sdumbbell			force_completion = true;
1302254885Sdumbbell		}
1303254885Sdumbbell	}
1304254885Sdumbbell	if (force_completion) {
1305254885Sdumbbell		radeon_fence_driver_force_completion(rdev);
1306254885Sdumbbell	}
1307254885Sdumbbell	sx_xunlock(&rdev->ring_lock);
1308254885Sdumbbell
1309254885Sdumbbell	radeon_save_bios_scratch_regs(rdev);
1310254885Sdumbbell
1311254885Sdumbbell	radeon_pm_suspend(rdev);
1312254885Sdumbbell	radeon_suspend(rdev);
1313254885Sdumbbell	radeon_hpd_fini(rdev);
1314254885Sdumbbell	/* evict remaining vram memory */
1315254885Sdumbbell	radeon_bo_evict_vram(rdev);
1316254885Sdumbbell
1317254885Sdumbbell	radeon_agp_suspend(rdev);
1318254885Sdumbbell
1319255573Sdumbbell	pci_save_state(device_get_parent(rdev->dev));
1320254885Sdumbbell#ifdef DUMBBELL_WIP
1321254885Sdumbbell	if (state.event == PM_EVENT_SUSPEND) {
1322254885Sdumbbell		/* Shut down the device */
1323254885Sdumbbell		pci_disable_device(dev->pdev);
1324254885Sdumbbell#endif /* DUMBBELL_WIP */
1325254885Sdumbbell		pci_set_powerstate(dev->device, PCI_POWERSTATE_D3);
1326254885Sdumbbell#ifdef DUMBBELL_WIP
1327254885Sdumbbell	}
1328254885Sdumbbell	console_lock();
1329254885Sdumbbell#endif /* DUMBBELL_WIP */
1330254885Sdumbbell	radeon_fbdev_set_suspend(rdev, 1);
1331254885Sdumbbell#ifdef DUMBBELL_WIP
1332254885Sdumbbell	console_unlock();
1333254885Sdumbbell#endif /* DUMBBELL_WIP */
1334254885Sdumbbell	return 0;
1335254885Sdumbbell}
1336254885Sdumbbell
1337254885Sdumbbell/**
1338254885Sdumbbell * radeon_resume_kms - initiate device resume
1339254885Sdumbbell *
1340254885Sdumbbell * @pdev: drm dev pointer
1341254885Sdumbbell *
1342254885Sdumbbell * Bring the hw back to operating state (all asics).
1343254885Sdumbbell * Returns 0 for success or an error on failure.
1344254885Sdumbbell * Called at driver resume.
1345254885Sdumbbell */
1346254885Sdumbbellint radeon_resume_kms(struct drm_device *dev)
1347254885Sdumbbell{
1348254885Sdumbbell	struct drm_connector *connector;
1349254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
1350254885Sdumbbell	int r;
1351254885Sdumbbell
1352254885Sdumbbell	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
1353254885Sdumbbell		return 0;
1354254885Sdumbbell
1355254885Sdumbbell#ifdef DUMBBELL_WIP
1356254885Sdumbbell	console_lock();
1357254885Sdumbbell#endif /* DUMBBELL_WIP */
1358254885Sdumbbell	pci_set_powerstate(dev->device, PCI_POWERSTATE_D0);
1359255573Sdumbbell	pci_restore_state(device_get_parent(rdev->dev));
1360254885Sdumbbell#ifdef DUMBBELL_WIP
1361254885Sdumbbell	if (pci_enable_device(dev->pdev)) {
1362254885Sdumbbell		console_unlock();
1363254885Sdumbbell		return -1;
1364254885Sdumbbell	}
1365254885Sdumbbell#endif /* DUMBBELL_WIP */
1366254885Sdumbbell	/* resume AGP if in use */
1367254885Sdumbbell	radeon_agp_resume(rdev);
1368254885Sdumbbell	radeon_resume(rdev);
1369254885Sdumbbell
1370254885Sdumbbell	r = radeon_ib_ring_tests(rdev);
1371254885Sdumbbell	if (r)
1372254885Sdumbbell		DRM_ERROR("ib ring test failed (%d).\n", r);
1373254885Sdumbbell
1374254885Sdumbbell	radeon_pm_resume(rdev);
1375254885Sdumbbell	radeon_restore_bios_scratch_regs(rdev);
1376254885Sdumbbell
1377254885Sdumbbell	radeon_fbdev_set_suspend(rdev, 0);
1378254885Sdumbbell#ifdef DUMBBELL_WIP
1379254885Sdumbbell	console_unlock();
1380254885Sdumbbell#endif /* DUMBBELL_WIP */
1381254885Sdumbbell
1382254885Sdumbbell	/* init dig PHYs, disp eng pll */
1383254885Sdumbbell	if (rdev->is_atom_bios) {
1384254885Sdumbbell		radeon_atom_encoder_init(rdev);
1385254885Sdumbbell		radeon_atom_disp_eng_pll_init(rdev);
1386254885Sdumbbell		/* turn on the BL */
1387254885Sdumbbell		if (rdev->mode_info.bl_encoder) {
1388254885Sdumbbell			u8 bl_level = radeon_get_backlight_level(rdev,
1389254885Sdumbbell								 rdev->mode_info.bl_encoder);
1390254885Sdumbbell			radeon_set_backlight_level(rdev, rdev->mode_info.bl_encoder,
1391254885Sdumbbell						   bl_level);
1392254885Sdumbbell		}
1393254885Sdumbbell	}
1394254885Sdumbbell	/* reset hpd state */
1395254885Sdumbbell	radeon_hpd_init(rdev);
1396254885Sdumbbell	/* blat the mode back in */
1397254885Sdumbbell	drm_helper_resume_force_mode(dev);
1398254885Sdumbbell	/* turn on display hw */
1399254885Sdumbbell	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1400254885Sdumbbell		drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
1401254885Sdumbbell	}
1402254885Sdumbbell
1403254885Sdumbbell	drm_kms_helper_poll_enable(dev);
1404254885Sdumbbell	return 0;
1405254885Sdumbbell}
1406254885Sdumbbell
1407254885Sdumbbell/**
1408254885Sdumbbell * radeon_gpu_reset - reset the asic
1409254885Sdumbbell *
1410254885Sdumbbell * @rdev: radeon device pointer
1411254885Sdumbbell *
1412254885Sdumbbell * Attempt the reset the GPU if it has hung (all asics).
1413254885Sdumbbell * Returns 0 for success or an error on failure.
1414254885Sdumbbell */
1415254885Sdumbbellint radeon_gpu_reset(struct radeon_device *rdev)
1416254885Sdumbbell{
1417254885Sdumbbell	unsigned ring_sizes[RADEON_NUM_RINGS];
1418254885Sdumbbell	uint32_t *ring_data[RADEON_NUM_RINGS];
1419254885Sdumbbell
1420254885Sdumbbell	bool saved = false;
1421254885Sdumbbell
1422254885Sdumbbell	int i, r;
1423254885Sdumbbell	int resched;
1424254885Sdumbbell
1425254885Sdumbbell	sx_xlock(&rdev->exclusive_lock);
1426254885Sdumbbell	radeon_save_bios_scratch_regs(rdev);
1427254885Sdumbbell	/* block TTM */
1428254885Sdumbbell	resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
1429254885Sdumbbell	radeon_suspend(rdev);
1430254885Sdumbbell
1431254885Sdumbbell	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1432254885Sdumbbell		ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
1433254885Sdumbbell						   &ring_data[i]);
1434254885Sdumbbell		if (ring_sizes[i]) {
1435254885Sdumbbell			saved = true;
1436254885Sdumbbell			dev_info(rdev->dev, "Saved %d dwords of commands "
1437254885Sdumbbell				 "on ring %d.\n", ring_sizes[i], i);
1438254885Sdumbbell		}
1439254885Sdumbbell	}
1440254885Sdumbbell
1441254885Sdumbbellretry:
1442254885Sdumbbell	r = radeon_asic_reset(rdev);
1443254885Sdumbbell	if (!r) {
1444254885Sdumbbell		dev_info(rdev->dev, "GPU reset succeeded, trying to resume\n");
1445254885Sdumbbell		radeon_resume(rdev);
1446254885Sdumbbell	}
1447254885Sdumbbell
1448254885Sdumbbell	radeon_restore_bios_scratch_regs(rdev);
1449254885Sdumbbell
1450254885Sdumbbell	if (!r) {
1451254885Sdumbbell		for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1452254885Sdumbbell			radeon_ring_restore(rdev, &rdev->ring[i],
1453254885Sdumbbell					    ring_sizes[i], ring_data[i]);
1454254885Sdumbbell			ring_sizes[i] = 0;
1455254885Sdumbbell			ring_data[i] = NULL;
1456254885Sdumbbell		}
1457254885Sdumbbell
1458254885Sdumbbell		r = radeon_ib_ring_tests(rdev);
1459254885Sdumbbell		if (r) {
1460254885Sdumbbell			dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
1461254885Sdumbbell			if (saved) {
1462254885Sdumbbell				saved = false;
1463254885Sdumbbell				radeon_suspend(rdev);
1464254885Sdumbbell				goto retry;
1465254885Sdumbbell			}
1466254885Sdumbbell		}
1467254885Sdumbbell	} else {
1468254885Sdumbbell		radeon_fence_driver_force_completion(rdev);
1469254885Sdumbbell		for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1470254885Sdumbbell			free(ring_data[i], DRM_MEM_DRIVER);
1471254885Sdumbbell		}
1472254885Sdumbbell	}
1473254885Sdumbbell
1474254885Sdumbbell	drm_helper_resume_force_mode(rdev->ddev);
1475254885Sdumbbell
1476254885Sdumbbell	ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
1477254885Sdumbbell	if (r) {
1478254885Sdumbbell		/* bad news, how to tell it to userspace ? */
1479254885Sdumbbell		dev_info(rdev->dev, "GPU reset failed\n");
1480254885Sdumbbell	}
1481254885Sdumbbell
1482254885Sdumbbell	sx_xunlock(&rdev->exclusive_lock);
1483254885Sdumbbell	return r;
1484254885Sdumbbell}
1485254885Sdumbbell
1486254885Sdumbbell
1487254885Sdumbbell/*
1488254885Sdumbbell * Debugfs
1489254885Sdumbbell */
1490254885Sdumbbell#ifdef DUMBBELL_WIP
1491254885Sdumbbellint radeon_debugfs_add_files(struct radeon_device *rdev,
1492254885Sdumbbell			     struct drm_info_list *files,
1493254885Sdumbbell			     unsigned nfiles)
1494254885Sdumbbell{
1495254885Sdumbbell	unsigned i;
1496254885Sdumbbell
1497254885Sdumbbell	for (i = 0; i < rdev->debugfs_count; i++) {
1498254885Sdumbbell		if (rdev->debugfs[i].files == files) {
1499254885Sdumbbell			/* Already registered */
1500254885Sdumbbell			return 0;
1501254885Sdumbbell		}
1502254885Sdumbbell	}
1503254885Sdumbbell
1504254885Sdumbbell	i = rdev->debugfs_count + 1;
1505254885Sdumbbell	if (i > RADEON_DEBUGFS_MAX_COMPONENTS) {
1506254885Sdumbbell		DRM_ERROR("Reached maximum number of debugfs components.\n");
1507254885Sdumbbell		DRM_ERROR("Report so we increase "
1508254885Sdumbbell		          "RADEON_DEBUGFS_MAX_COMPONENTS.\n");
1509254885Sdumbbell		return -EINVAL;
1510254885Sdumbbell	}
1511254885Sdumbbell	rdev->debugfs[rdev->debugfs_count].files = files;
1512254885Sdumbbell	rdev->debugfs[rdev->debugfs_count].num_files = nfiles;
1513254885Sdumbbell	rdev->debugfs_count = i;
1514254885Sdumbbell#if defined(CONFIG_DEBUG_FS)
1515254885Sdumbbell	drm_debugfs_create_files(files, nfiles,
1516254885Sdumbbell				 rdev->ddev->control->debugfs_root,
1517254885Sdumbbell				 rdev->ddev->control);
1518254885Sdumbbell	drm_debugfs_create_files(files, nfiles,
1519254885Sdumbbell				 rdev->ddev->primary->debugfs_root,
1520254885Sdumbbell				 rdev->ddev->primary);
1521254885Sdumbbell#endif
1522254885Sdumbbell	return 0;
1523254885Sdumbbell}
1524254885Sdumbbell
1525254885Sdumbbellstatic void radeon_debugfs_remove_files(struct radeon_device *rdev)
1526254885Sdumbbell{
1527254885Sdumbbell#if defined(CONFIG_DEBUG_FS)
1528254885Sdumbbell	unsigned i;
1529254885Sdumbbell
1530254885Sdumbbell	for (i = 0; i < rdev->debugfs_count; i++) {
1531254885Sdumbbell		drm_debugfs_remove_files(rdev->debugfs[i].files,
1532254885Sdumbbell					 rdev->debugfs[i].num_files,
1533254885Sdumbbell					 rdev->ddev->control);
1534254885Sdumbbell		drm_debugfs_remove_files(rdev->debugfs[i].files,
1535254885Sdumbbell					 rdev->debugfs[i].num_files,
1536254885Sdumbbell					 rdev->ddev->primary);
1537254885Sdumbbell	}
1538254885Sdumbbell#endif
1539254885Sdumbbell}
1540254885Sdumbbell
1541254885Sdumbbell#if defined(CONFIG_DEBUG_FS)
1542254885Sdumbbellint radeon_debugfs_init(struct drm_minor *minor)
1543254885Sdumbbell{
1544254885Sdumbbell	return 0;
1545254885Sdumbbell}
1546254885Sdumbbell
1547254885Sdumbbellvoid radeon_debugfs_cleanup(struct drm_minor *minor)
1548254885Sdumbbell{
1549254885Sdumbbell}
1550254885Sdumbbell#endif /* DUMBBELL_WIP */
1551254885Sdumbbell#endif
1552