xref: /openbmc/linux/drivers/gpu/drm/radeon/r100.c (revision 771fe6b912fca54f03e8a72eb63058b582775362)
1*771fe6b9SJerome Glisse /*
2*771fe6b9SJerome Glisse  * Copyright 2008 Advanced Micro Devices, Inc.
3*771fe6b9SJerome Glisse  * Copyright 2008 Red Hat Inc.
4*771fe6b9SJerome Glisse  * Copyright 2009 Jerome Glisse.
5*771fe6b9SJerome Glisse  *
6*771fe6b9SJerome Glisse  * Permission is hereby granted, free of charge, to any person obtaining a
7*771fe6b9SJerome Glisse  * copy of this software and associated documentation files (the "Software"),
8*771fe6b9SJerome Glisse  * to deal in the Software without restriction, including without limitation
9*771fe6b9SJerome Glisse  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*771fe6b9SJerome Glisse  * and/or sell copies of the Software, and to permit persons to whom the
11*771fe6b9SJerome Glisse  * Software is furnished to do so, subject to the following conditions:
12*771fe6b9SJerome Glisse  *
13*771fe6b9SJerome Glisse  * The above copyright notice and this permission notice shall be included in
14*771fe6b9SJerome Glisse  * all copies or substantial portions of the Software.
15*771fe6b9SJerome Glisse  *
16*771fe6b9SJerome Glisse  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*771fe6b9SJerome Glisse  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*771fe6b9SJerome Glisse  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19*771fe6b9SJerome Glisse  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*771fe6b9SJerome Glisse  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*771fe6b9SJerome Glisse  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*771fe6b9SJerome Glisse  * OTHER DEALINGS IN THE SOFTWARE.
23*771fe6b9SJerome Glisse  *
24*771fe6b9SJerome Glisse  * Authors: Dave Airlie
25*771fe6b9SJerome Glisse  *          Alex Deucher
26*771fe6b9SJerome Glisse  *          Jerome Glisse
27*771fe6b9SJerome Glisse  */
28*771fe6b9SJerome Glisse #include <linux/seq_file.h>
29*771fe6b9SJerome Glisse #include "drmP.h"
30*771fe6b9SJerome Glisse #include "drm.h"
31*771fe6b9SJerome Glisse #include "radeon_drm.h"
32*771fe6b9SJerome Glisse #include "radeon_microcode.h"
33*771fe6b9SJerome Glisse #include "radeon_reg.h"
34*771fe6b9SJerome Glisse #include "radeon.h"
35*771fe6b9SJerome Glisse 
36*771fe6b9SJerome Glisse /* This files gather functions specifics to:
37*771fe6b9SJerome Glisse  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
38*771fe6b9SJerome Glisse  *
39*771fe6b9SJerome Glisse  * Some of these functions might be used by newer ASICs.
40*771fe6b9SJerome Glisse  */
41*771fe6b9SJerome Glisse void r100_hdp_reset(struct radeon_device *rdev);
42*771fe6b9SJerome Glisse void r100_gpu_init(struct radeon_device *rdev);
43*771fe6b9SJerome Glisse int r100_gui_wait_for_idle(struct radeon_device *rdev);
44*771fe6b9SJerome Glisse int r100_mc_wait_for_idle(struct radeon_device *rdev);
45*771fe6b9SJerome Glisse void r100_gpu_wait_for_vsync(struct radeon_device *rdev);
46*771fe6b9SJerome Glisse void r100_gpu_wait_for_vsync2(struct radeon_device *rdev);
47*771fe6b9SJerome Glisse int r100_debugfs_mc_info_init(struct radeon_device *rdev);
48*771fe6b9SJerome Glisse 
49*771fe6b9SJerome Glisse 
50*771fe6b9SJerome Glisse /*
51*771fe6b9SJerome Glisse  * PCI GART
52*771fe6b9SJerome Glisse  */
53*771fe6b9SJerome Glisse void r100_pci_gart_tlb_flush(struct radeon_device *rdev)
54*771fe6b9SJerome Glisse {
55*771fe6b9SJerome Glisse 	/* TODO: can we do somethings here ? */
56*771fe6b9SJerome Glisse 	/* It seems hw only cache one entry so we should discard this
57*771fe6b9SJerome Glisse 	 * entry otherwise if first GPU GART read hit this entry it
58*771fe6b9SJerome Glisse 	 * could end up in wrong address. */
59*771fe6b9SJerome Glisse }
60*771fe6b9SJerome Glisse 
61*771fe6b9SJerome Glisse int r100_pci_gart_enable(struct radeon_device *rdev)
62*771fe6b9SJerome Glisse {
63*771fe6b9SJerome Glisse 	uint32_t tmp;
64*771fe6b9SJerome Glisse 	int r;
65*771fe6b9SJerome Glisse 
66*771fe6b9SJerome Glisse 	/* Initialize common gart structure */
67*771fe6b9SJerome Glisse 	r = radeon_gart_init(rdev);
68*771fe6b9SJerome Glisse 	if (r) {
69*771fe6b9SJerome Glisse 		return r;
70*771fe6b9SJerome Glisse 	}
71*771fe6b9SJerome Glisse 	if (rdev->gart.table.ram.ptr == NULL) {
72*771fe6b9SJerome Glisse 		rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
73*771fe6b9SJerome Glisse 		r = radeon_gart_table_ram_alloc(rdev);
74*771fe6b9SJerome Glisse 		if (r) {
75*771fe6b9SJerome Glisse 			return r;
76*771fe6b9SJerome Glisse 		}
77*771fe6b9SJerome Glisse 	}
78*771fe6b9SJerome Glisse 	/* discard memory request outside of configured range */
79*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
80*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_CNTL, tmp);
81*771fe6b9SJerome Glisse 	/* set address range for PCI address translate */
82*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
83*771fe6b9SJerome Glisse 	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
84*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_HI_ADDR, tmp);
85*771fe6b9SJerome Glisse 	/* Enable bus mastering */
86*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
87*771fe6b9SJerome Glisse 	WREG32(RADEON_BUS_CNTL, tmp);
88*771fe6b9SJerome Glisse 	/* set PCI GART page-table base address */
89*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
90*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
91*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_CNTL, tmp);
92*771fe6b9SJerome Glisse 	r100_pci_gart_tlb_flush(rdev);
93*771fe6b9SJerome Glisse 	rdev->gart.ready = true;
94*771fe6b9SJerome Glisse 	return 0;
95*771fe6b9SJerome Glisse }
96*771fe6b9SJerome Glisse 
97*771fe6b9SJerome Glisse void r100_pci_gart_disable(struct radeon_device *rdev)
98*771fe6b9SJerome Glisse {
99*771fe6b9SJerome Glisse 	uint32_t tmp;
100*771fe6b9SJerome Glisse 
101*771fe6b9SJerome Glisse 	/* discard memory request outside of configured range */
102*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
103*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN);
104*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_LO_ADDR, 0);
105*771fe6b9SJerome Glisse 	WREG32(RADEON_AIC_HI_ADDR, 0);
106*771fe6b9SJerome Glisse }
107*771fe6b9SJerome Glisse 
108*771fe6b9SJerome Glisse int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
109*771fe6b9SJerome Glisse {
110*771fe6b9SJerome Glisse 	if (i < 0 || i > rdev->gart.num_gpu_pages) {
111*771fe6b9SJerome Glisse 		return -EINVAL;
112*771fe6b9SJerome Glisse 	}
113*771fe6b9SJerome Glisse 	rdev->gart.table.ram.ptr[i] = cpu_to_le32((uint32_t)addr);
114*771fe6b9SJerome Glisse 	return 0;
115*771fe6b9SJerome Glisse }
116*771fe6b9SJerome Glisse 
117*771fe6b9SJerome Glisse int r100_gart_enable(struct radeon_device *rdev)
118*771fe6b9SJerome Glisse {
119*771fe6b9SJerome Glisse 	if (rdev->flags & RADEON_IS_AGP) {
120*771fe6b9SJerome Glisse 		r100_pci_gart_disable(rdev);
121*771fe6b9SJerome Glisse 		return 0;
122*771fe6b9SJerome Glisse 	}
123*771fe6b9SJerome Glisse 	return r100_pci_gart_enable(rdev);
124*771fe6b9SJerome Glisse }
125*771fe6b9SJerome Glisse 
126*771fe6b9SJerome Glisse 
127*771fe6b9SJerome Glisse /*
128*771fe6b9SJerome Glisse  * MC
129*771fe6b9SJerome Glisse  */
130*771fe6b9SJerome Glisse void r100_mc_disable_clients(struct radeon_device *rdev)
131*771fe6b9SJerome Glisse {
132*771fe6b9SJerome Glisse 	uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl;
133*771fe6b9SJerome Glisse 
134*771fe6b9SJerome Glisse 	/* FIXME: is this function correct for rs100,rs200,rs300 ? */
135*771fe6b9SJerome Glisse 	if (r100_gui_wait_for_idle(rdev)) {
136*771fe6b9SJerome Glisse 		printk(KERN_WARNING "Failed to wait GUI idle while "
137*771fe6b9SJerome Glisse 		       "programming pipes. Bad things might happen.\n");
138*771fe6b9SJerome Glisse 	}
139*771fe6b9SJerome Glisse 
140*771fe6b9SJerome Glisse 	/* stop display and memory access */
141*771fe6b9SJerome Glisse 	ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL);
142*771fe6b9SJerome Glisse 	WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
143*771fe6b9SJerome Glisse 	crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
144*771fe6b9SJerome Glisse 	WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
145*771fe6b9SJerome Glisse 	crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
146*771fe6b9SJerome Glisse 
147*771fe6b9SJerome Glisse 	r100_gpu_wait_for_vsync(rdev);
148*771fe6b9SJerome Glisse 
149*771fe6b9SJerome Glisse 	WREG32(RADEON_CRTC_GEN_CNTL,
150*771fe6b9SJerome Glisse 	       (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) |
151*771fe6b9SJerome Glisse 	       RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
152*771fe6b9SJerome Glisse 
153*771fe6b9SJerome Glisse 	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
154*771fe6b9SJerome Glisse 		crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
155*771fe6b9SJerome Glisse 
156*771fe6b9SJerome Glisse 		r100_gpu_wait_for_vsync2(rdev);
157*771fe6b9SJerome Glisse 		WREG32(RADEON_CRTC2_GEN_CNTL,
158*771fe6b9SJerome Glisse 		       (crtc2_gen_cntl &
159*771fe6b9SJerome Glisse 		        ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) |
160*771fe6b9SJerome Glisse 		       RADEON_CRTC2_DISP_REQ_EN_B);
161*771fe6b9SJerome Glisse 	}
162*771fe6b9SJerome Glisse 
163*771fe6b9SJerome Glisse 	udelay(500);
164*771fe6b9SJerome Glisse }
165*771fe6b9SJerome Glisse 
166*771fe6b9SJerome Glisse void r100_mc_setup(struct radeon_device *rdev)
167*771fe6b9SJerome Glisse {
168*771fe6b9SJerome Glisse 	uint32_t tmp;
169*771fe6b9SJerome Glisse 	int r;
170*771fe6b9SJerome Glisse 
171*771fe6b9SJerome Glisse 	r = r100_debugfs_mc_info_init(rdev);
172*771fe6b9SJerome Glisse 	if (r) {
173*771fe6b9SJerome Glisse 		DRM_ERROR("Failed to register debugfs file for R100 MC !\n");
174*771fe6b9SJerome Glisse 	}
175*771fe6b9SJerome Glisse 	/* Write VRAM size in case we are limiting it */
176*771fe6b9SJerome Glisse 	WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
177*771fe6b9SJerome Glisse 	tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
178*771fe6b9SJerome Glisse 	tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
179*771fe6b9SJerome Glisse 	tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
180*771fe6b9SJerome Glisse 	WREG32(RADEON_MC_FB_LOCATION, tmp);
181*771fe6b9SJerome Glisse 
182*771fe6b9SJerome Glisse 	/* Enable bus mastering */
183*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
184*771fe6b9SJerome Glisse 	WREG32(RADEON_BUS_CNTL, tmp);
185*771fe6b9SJerome Glisse 
186*771fe6b9SJerome Glisse 	if (rdev->flags & RADEON_IS_AGP) {
187*771fe6b9SJerome Glisse 		tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
188*771fe6b9SJerome Glisse 		tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16);
189*771fe6b9SJerome Glisse 		tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16);
190*771fe6b9SJerome Glisse 		WREG32(RADEON_MC_AGP_LOCATION, tmp);
191*771fe6b9SJerome Glisse 		WREG32(RADEON_AGP_BASE, rdev->mc.agp_base);
192*771fe6b9SJerome Glisse 	} else {
193*771fe6b9SJerome Glisse 		WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF);
194*771fe6b9SJerome Glisse 		WREG32(RADEON_AGP_BASE, 0);
195*771fe6b9SJerome Glisse 	}
196*771fe6b9SJerome Glisse 
197*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
198*771fe6b9SJerome Glisse 	tmp |= (7 << 28);
199*771fe6b9SJerome Glisse 	WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
200*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_HOST_PATH_CNTL);
201*771fe6b9SJerome Glisse 	WREG32(RADEON_HOST_PATH_CNTL, tmp);
202*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_HOST_PATH_CNTL);
203*771fe6b9SJerome Glisse }
204*771fe6b9SJerome Glisse 
205*771fe6b9SJerome Glisse int r100_mc_init(struct radeon_device *rdev)
206*771fe6b9SJerome Glisse {
207*771fe6b9SJerome Glisse 	int r;
208*771fe6b9SJerome Glisse 
209*771fe6b9SJerome Glisse 	if (r100_debugfs_rbbm_init(rdev)) {
210*771fe6b9SJerome Glisse 		DRM_ERROR("Failed to register debugfs file for RBBM !\n");
211*771fe6b9SJerome Glisse 	}
212*771fe6b9SJerome Glisse 
213*771fe6b9SJerome Glisse 	r100_gpu_init(rdev);
214*771fe6b9SJerome Glisse 	/* Disable gart which also disable out of gart access */
215*771fe6b9SJerome Glisse 	r100_pci_gart_disable(rdev);
216*771fe6b9SJerome Glisse 
217*771fe6b9SJerome Glisse 	/* Setup GPU memory space */
218*771fe6b9SJerome Glisse 	rdev->mc.vram_location = 0xFFFFFFFFUL;
219*771fe6b9SJerome Glisse 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
220*771fe6b9SJerome Glisse 	if (rdev->flags & RADEON_IS_AGP) {
221*771fe6b9SJerome Glisse 		r = radeon_agp_init(rdev);
222*771fe6b9SJerome Glisse 		if (r) {
223*771fe6b9SJerome Glisse 			printk(KERN_WARNING "[drm] Disabling AGP\n");
224*771fe6b9SJerome Glisse 			rdev->flags &= ~RADEON_IS_AGP;
225*771fe6b9SJerome Glisse 			rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
226*771fe6b9SJerome Glisse 		} else {
227*771fe6b9SJerome Glisse 			rdev->mc.gtt_location = rdev->mc.agp_base;
228*771fe6b9SJerome Glisse 		}
229*771fe6b9SJerome Glisse 	}
230*771fe6b9SJerome Glisse 	r = radeon_mc_setup(rdev);
231*771fe6b9SJerome Glisse 	if (r) {
232*771fe6b9SJerome Glisse 		return r;
233*771fe6b9SJerome Glisse 	}
234*771fe6b9SJerome Glisse 
235*771fe6b9SJerome Glisse 	r100_mc_disable_clients(rdev);
236*771fe6b9SJerome Glisse 	if (r100_mc_wait_for_idle(rdev)) {
237*771fe6b9SJerome Glisse 		printk(KERN_WARNING "Failed to wait MC idle while "
238*771fe6b9SJerome Glisse 		       "programming pipes. Bad things might happen.\n");
239*771fe6b9SJerome Glisse 	}
240*771fe6b9SJerome Glisse 
241*771fe6b9SJerome Glisse 	r100_mc_setup(rdev);
242*771fe6b9SJerome Glisse 	return 0;
243*771fe6b9SJerome Glisse }
244*771fe6b9SJerome Glisse 
245*771fe6b9SJerome Glisse void r100_mc_fini(struct radeon_device *rdev)
246*771fe6b9SJerome Glisse {
247*771fe6b9SJerome Glisse 	r100_pci_gart_disable(rdev);
248*771fe6b9SJerome Glisse 	radeon_gart_table_ram_free(rdev);
249*771fe6b9SJerome Glisse 	radeon_gart_fini(rdev);
250*771fe6b9SJerome Glisse }
251*771fe6b9SJerome Glisse 
252*771fe6b9SJerome Glisse 
253*771fe6b9SJerome Glisse /*
254*771fe6b9SJerome Glisse  * Fence emission
255*771fe6b9SJerome Glisse  */
256*771fe6b9SJerome Glisse void r100_fence_ring_emit(struct radeon_device *rdev,
257*771fe6b9SJerome Glisse 			  struct radeon_fence *fence)
258*771fe6b9SJerome Glisse {
259*771fe6b9SJerome Glisse 	/* Who ever call radeon_fence_emit should call ring_lock and ask
260*771fe6b9SJerome Glisse 	 * for enough space (today caller are ib schedule and buffer move) */
261*771fe6b9SJerome Glisse 	/* Wait until IDLE & CLEAN */
262*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, PACKET0(0x1720, 0));
263*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, (1 << 16) | (1 << 17));
264*771fe6b9SJerome Glisse 	/* Emit fence sequence & fire IRQ */
265*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0));
266*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, fence->seq);
267*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0));
268*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
269*771fe6b9SJerome Glisse }
270*771fe6b9SJerome Glisse 
271*771fe6b9SJerome Glisse 
272*771fe6b9SJerome Glisse /*
273*771fe6b9SJerome Glisse  * Writeback
274*771fe6b9SJerome Glisse  */
275*771fe6b9SJerome Glisse int r100_wb_init(struct radeon_device *rdev)
276*771fe6b9SJerome Glisse {
277*771fe6b9SJerome Glisse 	int r;
278*771fe6b9SJerome Glisse 
279*771fe6b9SJerome Glisse 	if (rdev->wb.wb_obj == NULL) {
280*771fe6b9SJerome Glisse 		r = radeon_object_create(rdev, NULL, 4096,
281*771fe6b9SJerome Glisse 					 true,
282*771fe6b9SJerome Glisse 					 RADEON_GEM_DOMAIN_GTT,
283*771fe6b9SJerome Glisse 					 false, &rdev->wb.wb_obj);
284*771fe6b9SJerome Glisse 		if (r) {
285*771fe6b9SJerome Glisse 			DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
286*771fe6b9SJerome Glisse 			return r;
287*771fe6b9SJerome Glisse 		}
288*771fe6b9SJerome Glisse 		r = radeon_object_pin(rdev->wb.wb_obj,
289*771fe6b9SJerome Glisse 				      RADEON_GEM_DOMAIN_GTT,
290*771fe6b9SJerome Glisse 				      &rdev->wb.gpu_addr);
291*771fe6b9SJerome Glisse 		if (r) {
292*771fe6b9SJerome Glisse 			DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
293*771fe6b9SJerome Glisse 			return r;
294*771fe6b9SJerome Glisse 		}
295*771fe6b9SJerome Glisse 		r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
296*771fe6b9SJerome Glisse 		if (r) {
297*771fe6b9SJerome Glisse 			DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
298*771fe6b9SJerome Glisse 			return r;
299*771fe6b9SJerome Glisse 		}
300*771fe6b9SJerome Glisse 	}
301*771fe6b9SJerome Glisse 	WREG32(0x774, rdev->wb.gpu_addr);
302*771fe6b9SJerome Glisse 	WREG32(0x70C, rdev->wb.gpu_addr + 1024);
303*771fe6b9SJerome Glisse 	WREG32(0x770, 0xff);
304*771fe6b9SJerome Glisse 	return 0;
305*771fe6b9SJerome Glisse }
306*771fe6b9SJerome Glisse 
307*771fe6b9SJerome Glisse void r100_wb_fini(struct radeon_device *rdev)
308*771fe6b9SJerome Glisse {
309*771fe6b9SJerome Glisse 	if (rdev->wb.wb_obj) {
310*771fe6b9SJerome Glisse 		radeon_object_kunmap(rdev->wb.wb_obj);
311*771fe6b9SJerome Glisse 		radeon_object_unpin(rdev->wb.wb_obj);
312*771fe6b9SJerome Glisse 		radeon_object_unref(&rdev->wb.wb_obj);
313*771fe6b9SJerome Glisse 		rdev->wb.wb = NULL;
314*771fe6b9SJerome Glisse 		rdev->wb.wb_obj = NULL;
315*771fe6b9SJerome Glisse 	}
316*771fe6b9SJerome Glisse }
317*771fe6b9SJerome Glisse 
318*771fe6b9SJerome Glisse int r100_copy_blit(struct radeon_device *rdev,
319*771fe6b9SJerome Glisse 		   uint64_t src_offset,
320*771fe6b9SJerome Glisse 		   uint64_t dst_offset,
321*771fe6b9SJerome Glisse 		   unsigned num_pages,
322*771fe6b9SJerome Glisse 		   struct radeon_fence *fence)
323*771fe6b9SJerome Glisse {
324*771fe6b9SJerome Glisse 	uint32_t cur_pages;
325*771fe6b9SJerome Glisse 	uint32_t stride_bytes = PAGE_SIZE;
326*771fe6b9SJerome Glisse 	uint32_t pitch;
327*771fe6b9SJerome Glisse 	uint32_t stride_pixels;
328*771fe6b9SJerome Glisse 	unsigned ndw;
329*771fe6b9SJerome Glisse 	int num_loops;
330*771fe6b9SJerome Glisse 	int r = 0;
331*771fe6b9SJerome Glisse 
332*771fe6b9SJerome Glisse 	/* radeon limited to 16k stride */
333*771fe6b9SJerome Glisse 	stride_bytes &= 0x3fff;
334*771fe6b9SJerome Glisse 	/* radeon pitch is /64 */
335*771fe6b9SJerome Glisse 	pitch = stride_bytes / 64;
336*771fe6b9SJerome Glisse 	stride_pixels = stride_bytes / 4;
337*771fe6b9SJerome Glisse 	num_loops = DIV_ROUND_UP(num_pages, 8191);
338*771fe6b9SJerome Glisse 
339*771fe6b9SJerome Glisse 	/* Ask for enough room for blit + flush + fence */
340*771fe6b9SJerome Glisse 	ndw = 64 + (10 * num_loops);
341*771fe6b9SJerome Glisse 	r = radeon_ring_lock(rdev, ndw);
342*771fe6b9SJerome Glisse 	if (r) {
343*771fe6b9SJerome Glisse 		DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
344*771fe6b9SJerome Glisse 		return -EINVAL;
345*771fe6b9SJerome Glisse 	}
346*771fe6b9SJerome Glisse 	while (num_pages > 0) {
347*771fe6b9SJerome Glisse 		cur_pages = num_pages;
348*771fe6b9SJerome Glisse 		if (cur_pages > 8191) {
349*771fe6b9SJerome Glisse 			cur_pages = 8191;
350*771fe6b9SJerome Glisse 		}
351*771fe6b9SJerome Glisse 		num_pages -= cur_pages;
352*771fe6b9SJerome Glisse 
353*771fe6b9SJerome Glisse 		/* pages are in Y direction - height
354*771fe6b9SJerome Glisse 		   page width in X direction - width */
355*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, PACKET3(PACKET3_BITBLT_MULTI, 8));
356*771fe6b9SJerome Glisse 		radeon_ring_write(rdev,
357*771fe6b9SJerome Glisse 				  RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
358*771fe6b9SJerome Glisse 				  RADEON_GMC_DST_PITCH_OFFSET_CNTL |
359*771fe6b9SJerome Glisse 				  RADEON_GMC_SRC_CLIPPING |
360*771fe6b9SJerome Glisse 				  RADEON_GMC_DST_CLIPPING |
361*771fe6b9SJerome Glisse 				  RADEON_GMC_BRUSH_NONE |
362*771fe6b9SJerome Glisse 				  (RADEON_COLOR_FORMAT_ARGB8888 << 8) |
363*771fe6b9SJerome Glisse 				  RADEON_GMC_SRC_DATATYPE_COLOR |
364*771fe6b9SJerome Glisse 				  RADEON_ROP3_S |
365*771fe6b9SJerome Glisse 				  RADEON_DP_SRC_SOURCE_MEMORY |
366*771fe6b9SJerome Glisse 				  RADEON_GMC_CLR_CMP_CNTL_DIS |
367*771fe6b9SJerome Glisse 				  RADEON_GMC_WR_MSK_DIS);
368*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, (pitch << 22) | (src_offset >> 10));
369*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, (pitch << 22) | (dst_offset >> 10));
370*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));
371*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, 0);
372*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));
373*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, num_pages);
374*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, num_pages);
375*771fe6b9SJerome Glisse 		radeon_ring_write(rdev, cur_pages | (stride_pixels << 16));
376*771fe6b9SJerome Glisse 	}
377*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0));
378*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, RADEON_RB2D_DC_FLUSH_ALL);
379*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
380*771fe6b9SJerome Glisse 	radeon_ring_write(rdev,
381*771fe6b9SJerome Glisse 			  RADEON_WAIT_2D_IDLECLEAN |
382*771fe6b9SJerome Glisse 			  RADEON_WAIT_HOST_IDLECLEAN |
383*771fe6b9SJerome Glisse 			  RADEON_WAIT_DMA_GUI_IDLE);
384*771fe6b9SJerome Glisse 	if (fence) {
385*771fe6b9SJerome Glisse 		r = radeon_fence_emit(rdev, fence);
386*771fe6b9SJerome Glisse 	}
387*771fe6b9SJerome Glisse 	radeon_ring_unlock_commit(rdev);
388*771fe6b9SJerome Glisse 	return r;
389*771fe6b9SJerome Glisse }
390*771fe6b9SJerome Glisse 
391*771fe6b9SJerome Glisse 
392*771fe6b9SJerome Glisse /*
393*771fe6b9SJerome Glisse  * CP
394*771fe6b9SJerome Glisse  */
395*771fe6b9SJerome Glisse void r100_ring_start(struct radeon_device *rdev)
396*771fe6b9SJerome Glisse {
397*771fe6b9SJerome Glisse 	int r;
398*771fe6b9SJerome Glisse 
399*771fe6b9SJerome Glisse 	r = radeon_ring_lock(rdev, 2);
400*771fe6b9SJerome Glisse 	if (r) {
401*771fe6b9SJerome Glisse 		return;
402*771fe6b9SJerome Glisse 	}
403*771fe6b9SJerome Glisse 	radeon_ring_write(rdev, PACKET0(RADEON_ISYNC_CNTL, 0));
404*771fe6b9SJerome Glisse 	radeon_ring_write(rdev,
405*771fe6b9SJerome Glisse 			  RADEON_ISYNC_ANY2D_IDLE3D |
406*771fe6b9SJerome Glisse 			  RADEON_ISYNC_ANY3D_IDLE2D |
407*771fe6b9SJerome Glisse 			  RADEON_ISYNC_WAIT_IDLEGUI |
408*771fe6b9SJerome Glisse 			  RADEON_ISYNC_CPSCRATCH_IDLEGUI);
409*771fe6b9SJerome Glisse 	radeon_ring_unlock_commit(rdev);
410*771fe6b9SJerome Glisse }
411*771fe6b9SJerome Glisse 
412*771fe6b9SJerome Glisse static void r100_cp_load_microcode(struct radeon_device *rdev)
413*771fe6b9SJerome Glisse {
414*771fe6b9SJerome Glisse 	int i;
415*771fe6b9SJerome Glisse 
416*771fe6b9SJerome Glisse 	if (r100_gui_wait_for_idle(rdev)) {
417*771fe6b9SJerome Glisse 		printk(KERN_WARNING "Failed to wait GUI idle while "
418*771fe6b9SJerome Glisse 		       "programming pipes. Bad things might happen.\n");
419*771fe6b9SJerome Glisse 	}
420*771fe6b9SJerome Glisse 
421*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_ME_RAM_ADDR, 0);
422*771fe6b9SJerome Glisse 	if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
423*771fe6b9SJerome Glisse 	    (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
424*771fe6b9SJerome Glisse 	    (rdev->family == CHIP_RS200)) {
425*771fe6b9SJerome Glisse 		DRM_INFO("Loading R100 Microcode\n");
426*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
427*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, R100_cp_microcode[i][1]);
428*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, R100_cp_microcode[i][0]);
429*771fe6b9SJerome Glisse 		}
430*771fe6b9SJerome Glisse 	} else if ((rdev->family == CHIP_R200) ||
431*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV250) ||
432*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV280) ||
433*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RS300)) {
434*771fe6b9SJerome Glisse 		DRM_INFO("Loading R200 Microcode\n");
435*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
436*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, R200_cp_microcode[i][1]);
437*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, R200_cp_microcode[i][0]);
438*771fe6b9SJerome Glisse 		}
439*771fe6b9SJerome Glisse 	} else if ((rdev->family == CHIP_R300) ||
440*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_R350) ||
441*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV350) ||
442*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV380) ||
443*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RS400) ||
444*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RS480)) {
445*771fe6b9SJerome Glisse 		DRM_INFO("Loading R300 Microcode\n");
446*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
447*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]);
448*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]);
449*771fe6b9SJerome Glisse 		}
450*771fe6b9SJerome Glisse 	} else if ((rdev->family == CHIP_R420) ||
451*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_R423) ||
452*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV410)) {
453*771fe6b9SJerome Glisse 		DRM_INFO("Loading R400 Microcode\n");
454*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
455*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, R420_cp_microcode[i][1]);
456*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]);
457*771fe6b9SJerome Glisse 		}
458*771fe6b9SJerome Glisse 	} else if ((rdev->family == CHIP_RS690) ||
459*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RS740)) {
460*771fe6b9SJerome Glisse 		DRM_INFO("Loading RS690/RS740 Microcode\n");
461*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
462*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]);
463*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]);
464*771fe6b9SJerome Glisse 		}
465*771fe6b9SJerome Glisse 	} else if (rdev->family == CHIP_RS600) {
466*771fe6b9SJerome Glisse 		DRM_INFO("Loading RS600 Microcode\n");
467*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
468*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, RS600_cp_microcode[i][1]);
469*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, RS600_cp_microcode[i][0]);
470*771fe6b9SJerome Glisse 		}
471*771fe6b9SJerome Glisse 	} else if ((rdev->family == CHIP_RV515) ||
472*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_R520) ||
473*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV530) ||
474*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_R580) ||
475*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV560) ||
476*771fe6b9SJerome Glisse 		   (rdev->family == CHIP_RV570)) {
477*771fe6b9SJerome Glisse 		DRM_INFO("Loading R500 Microcode\n");
478*771fe6b9SJerome Glisse 		for (i = 0; i < 256; i++) {
479*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]);
480*771fe6b9SJerome Glisse 			WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]);
481*771fe6b9SJerome Glisse 		}
482*771fe6b9SJerome Glisse 	}
483*771fe6b9SJerome Glisse }
484*771fe6b9SJerome Glisse 
485*771fe6b9SJerome Glisse int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
486*771fe6b9SJerome Glisse {
487*771fe6b9SJerome Glisse 	unsigned rb_bufsz;
488*771fe6b9SJerome Glisse 	unsigned rb_blksz;
489*771fe6b9SJerome Glisse 	unsigned max_fetch;
490*771fe6b9SJerome Glisse 	unsigned pre_write_timer;
491*771fe6b9SJerome Glisse 	unsigned pre_write_limit;
492*771fe6b9SJerome Glisse 	unsigned indirect2_start;
493*771fe6b9SJerome Glisse 	unsigned indirect1_start;
494*771fe6b9SJerome Glisse 	uint32_t tmp;
495*771fe6b9SJerome Glisse 	int r;
496*771fe6b9SJerome Glisse 
497*771fe6b9SJerome Glisse 	if (r100_debugfs_cp_init(rdev)) {
498*771fe6b9SJerome Glisse 		DRM_ERROR("Failed to register debugfs file for CP !\n");
499*771fe6b9SJerome Glisse 	}
500*771fe6b9SJerome Glisse 	/* Reset CP */
501*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_CP_CSQ_STAT);
502*771fe6b9SJerome Glisse 	if ((tmp & (1 << 31))) {
503*771fe6b9SJerome Glisse 		DRM_INFO("radeon: cp busy (0x%08X) resetting\n", tmp);
504*771fe6b9SJerome Glisse 		WREG32(RADEON_CP_CSQ_MODE, 0);
505*771fe6b9SJerome Glisse 		WREG32(RADEON_CP_CSQ_CNTL, 0);
506*771fe6b9SJerome Glisse 		WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
507*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_RBBM_SOFT_RESET);
508*771fe6b9SJerome Glisse 		mdelay(2);
509*771fe6b9SJerome Glisse 		WREG32(RADEON_RBBM_SOFT_RESET, 0);
510*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_RBBM_SOFT_RESET);
511*771fe6b9SJerome Glisse 		mdelay(2);
512*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CP_CSQ_STAT);
513*771fe6b9SJerome Glisse 		if ((tmp & (1 << 31))) {
514*771fe6b9SJerome Glisse 			DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp);
515*771fe6b9SJerome Glisse 		}
516*771fe6b9SJerome Glisse 	} else {
517*771fe6b9SJerome Glisse 		DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
518*771fe6b9SJerome Glisse 	}
519*771fe6b9SJerome Glisse 	/* Align ring size */
520*771fe6b9SJerome Glisse 	rb_bufsz = drm_order(ring_size / 8);
521*771fe6b9SJerome Glisse 	ring_size = (1 << (rb_bufsz + 1)) * 4;
522*771fe6b9SJerome Glisse 	r100_cp_load_microcode(rdev);
523*771fe6b9SJerome Glisse 	r = radeon_ring_init(rdev, ring_size);
524*771fe6b9SJerome Glisse 	if (r) {
525*771fe6b9SJerome Glisse 		return r;
526*771fe6b9SJerome Glisse 	}
527*771fe6b9SJerome Glisse 	/* Each time the cp read 1024 bytes (16 dword/quadword) update
528*771fe6b9SJerome Glisse 	 * the rptr copy in system ram */
529*771fe6b9SJerome Glisse 	rb_blksz = 9;
530*771fe6b9SJerome Glisse 	/* cp will read 128bytes at a time (4 dwords) */
531*771fe6b9SJerome Glisse 	max_fetch = 1;
532*771fe6b9SJerome Glisse 	rdev->cp.align_mask = 16 - 1;
533*771fe6b9SJerome Glisse 	/* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */
534*771fe6b9SJerome Glisse 	pre_write_timer = 64;
535*771fe6b9SJerome Glisse 	/* Force CP_RB_WPTR write if written more than one time before the
536*771fe6b9SJerome Glisse 	 * delay expire
537*771fe6b9SJerome Glisse 	 */
538*771fe6b9SJerome Glisse 	pre_write_limit = 0;
539*771fe6b9SJerome Glisse 	/* Setup the cp cache like this (cache size is 96 dwords) :
540*771fe6b9SJerome Glisse 	 *	RING		0  to 15
541*771fe6b9SJerome Glisse 	 *	INDIRECT1	16 to 79
542*771fe6b9SJerome Glisse 	 *	INDIRECT2	80 to 95
543*771fe6b9SJerome Glisse 	 * So ring cache size is 16dwords (> (2 * max_fetch = 2 * 4dwords))
544*771fe6b9SJerome Glisse 	 *    indirect1 cache size is 64dwords (> (2 * max_fetch = 2 * 4dwords))
545*771fe6b9SJerome Glisse 	 *    indirect2 cache size is 16dwords (> (2 * max_fetch = 2 * 4dwords))
546*771fe6b9SJerome Glisse 	 * Idea being that most of the gpu cmd will be through indirect1 buffer
547*771fe6b9SJerome Glisse 	 * so it gets the bigger cache.
548*771fe6b9SJerome Glisse 	 */
549*771fe6b9SJerome Glisse 	indirect2_start = 80;
550*771fe6b9SJerome Glisse 	indirect1_start = 16;
551*771fe6b9SJerome Glisse 	/* cp setup */
552*771fe6b9SJerome Glisse 	WREG32(0x718, pre_write_timer | (pre_write_limit << 28));
553*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_RB_CNTL,
554*771fe6b9SJerome Glisse 	       REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
555*771fe6b9SJerome Glisse 	       REG_SET(RADEON_RB_BLKSZ, rb_blksz) |
556*771fe6b9SJerome Glisse 	       REG_SET(RADEON_MAX_FETCH, max_fetch) |
557*771fe6b9SJerome Glisse 	       RADEON_RB_NO_UPDATE);
558*771fe6b9SJerome Glisse 	/* Set ring address */
559*771fe6b9SJerome Glisse 	DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr);
560*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr);
561*771fe6b9SJerome Glisse 	/* Force read & write ptr to 0 */
562*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_CP_RB_CNTL);
563*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
564*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_RB_RPTR_WR, 0);
565*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_RB_WPTR, 0);
566*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_RB_CNTL, tmp);
567*771fe6b9SJerome Glisse 	udelay(10);
568*771fe6b9SJerome Glisse 	rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
569*771fe6b9SJerome Glisse 	rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
570*771fe6b9SJerome Glisse 	/* Set cp mode to bus mastering & enable cp*/
571*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_MODE,
572*771fe6b9SJerome Glisse 	       REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
573*771fe6b9SJerome Glisse 	       REG_SET(RADEON_INDIRECT1_START, indirect1_start));
574*771fe6b9SJerome Glisse 	WREG32(0x718, 0);
575*771fe6b9SJerome Glisse 	WREG32(0x744, 0x00004D4D);
576*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
577*771fe6b9SJerome Glisse 	radeon_ring_start(rdev);
578*771fe6b9SJerome Glisse 	r = radeon_ring_test(rdev);
579*771fe6b9SJerome Glisse 	if (r) {
580*771fe6b9SJerome Glisse 		DRM_ERROR("radeon: cp isn't working (%d).\n", r);
581*771fe6b9SJerome Glisse 		return r;
582*771fe6b9SJerome Glisse 	}
583*771fe6b9SJerome Glisse 	rdev->cp.ready = true;
584*771fe6b9SJerome Glisse 	return 0;
585*771fe6b9SJerome Glisse }
586*771fe6b9SJerome Glisse 
587*771fe6b9SJerome Glisse void r100_cp_fini(struct radeon_device *rdev)
588*771fe6b9SJerome Glisse {
589*771fe6b9SJerome Glisse 	/* Disable ring */
590*771fe6b9SJerome Glisse 	rdev->cp.ready = false;
591*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_CNTL, 0);
592*771fe6b9SJerome Glisse 	radeon_ring_fini(rdev);
593*771fe6b9SJerome Glisse 	DRM_INFO("radeon: cp finalized\n");
594*771fe6b9SJerome Glisse }
595*771fe6b9SJerome Glisse 
596*771fe6b9SJerome Glisse void r100_cp_disable(struct radeon_device *rdev)
597*771fe6b9SJerome Glisse {
598*771fe6b9SJerome Glisse 	/* Disable ring */
599*771fe6b9SJerome Glisse 	rdev->cp.ready = false;
600*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_MODE, 0);
601*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_CNTL, 0);
602*771fe6b9SJerome Glisse 	if (r100_gui_wait_for_idle(rdev)) {
603*771fe6b9SJerome Glisse 		printk(KERN_WARNING "Failed to wait GUI idle while "
604*771fe6b9SJerome Glisse 		       "programming pipes. Bad things might happen.\n");
605*771fe6b9SJerome Glisse 	}
606*771fe6b9SJerome Glisse }
607*771fe6b9SJerome Glisse 
608*771fe6b9SJerome Glisse int r100_cp_reset(struct radeon_device *rdev)
609*771fe6b9SJerome Glisse {
610*771fe6b9SJerome Glisse 	uint32_t tmp;
611*771fe6b9SJerome Glisse 	bool reinit_cp;
612*771fe6b9SJerome Glisse 	int i;
613*771fe6b9SJerome Glisse 
614*771fe6b9SJerome Glisse 	reinit_cp = rdev->cp.ready;
615*771fe6b9SJerome Glisse 	rdev->cp.ready = false;
616*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_MODE, 0);
617*771fe6b9SJerome Glisse 	WREG32(RADEON_CP_CSQ_CNTL, 0);
618*771fe6b9SJerome Glisse 	WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
619*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_RBBM_SOFT_RESET);
620*771fe6b9SJerome Glisse 	udelay(200);
621*771fe6b9SJerome Glisse 	WREG32(RADEON_RBBM_SOFT_RESET, 0);
622*771fe6b9SJerome Glisse 	/* Wait to prevent race in RBBM_STATUS */
623*771fe6b9SJerome Glisse 	mdelay(1);
624*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
625*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_RBBM_STATUS);
626*771fe6b9SJerome Glisse 		if (!(tmp & (1 << 16))) {
627*771fe6b9SJerome Glisse 			DRM_INFO("CP reset succeed (RBBM_STATUS=0x%08X)\n",
628*771fe6b9SJerome Glisse 				 tmp);
629*771fe6b9SJerome Glisse 			if (reinit_cp) {
630*771fe6b9SJerome Glisse 				return r100_cp_init(rdev, rdev->cp.ring_size);
631*771fe6b9SJerome Glisse 			}
632*771fe6b9SJerome Glisse 			return 0;
633*771fe6b9SJerome Glisse 		}
634*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
635*771fe6b9SJerome Glisse 	}
636*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_RBBM_STATUS);
637*771fe6b9SJerome Glisse 	DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp);
638*771fe6b9SJerome Glisse 	return -1;
639*771fe6b9SJerome Glisse }
640*771fe6b9SJerome Glisse 
641*771fe6b9SJerome Glisse 
642*771fe6b9SJerome Glisse /*
643*771fe6b9SJerome Glisse  * CS functions
644*771fe6b9SJerome Glisse  */
645*771fe6b9SJerome Glisse int r100_cs_parse_packet0(struct radeon_cs_parser *p,
646*771fe6b9SJerome Glisse 			  struct radeon_cs_packet *pkt,
647*771fe6b9SJerome Glisse 			  unsigned *auth, unsigned n,
648*771fe6b9SJerome Glisse 			  radeon_packet0_check_t check)
649*771fe6b9SJerome Glisse {
650*771fe6b9SJerome Glisse 	unsigned reg;
651*771fe6b9SJerome Glisse 	unsigned i, j, m;
652*771fe6b9SJerome Glisse 	unsigned idx;
653*771fe6b9SJerome Glisse 	int r;
654*771fe6b9SJerome Glisse 
655*771fe6b9SJerome Glisse 	idx = pkt->idx + 1;
656*771fe6b9SJerome Glisse 	reg = pkt->reg;
657*771fe6b9SJerome Glisse 	if (pkt->one_reg_wr) {
658*771fe6b9SJerome Glisse 		if ((reg >> 7) > n) {
659*771fe6b9SJerome Glisse 			return -EINVAL;
660*771fe6b9SJerome Glisse 		}
661*771fe6b9SJerome Glisse 	} else {
662*771fe6b9SJerome Glisse 		if (((reg + (pkt->count << 2)) >> 7) > n) {
663*771fe6b9SJerome Glisse 			return -EINVAL;
664*771fe6b9SJerome Glisse 		}
665*771fe6b9SJerome Glisse 	}
666*771fe6b9SJerome Glisse 	for (i = 0; i <= pkt->count; i++, idx++) {
667*771fe6b9SJerome Glisse 		j = (reg >> 7);
668*771fe6b9SJerome Glisse 		m = 1 << ((reg >> 2) & 31);
669*771fe6b9SJerome Glisse 		if (auth[j] & m) {
670*771fe6b9SJerome Glisse 			r = check(p, pkt, idx, reg);
671*771fe6b9SJerome Glisse 			if (r) {
672*771fe6b9SJerome Glisse 				return r;
673*771fe6b9SJerome Glisse 			}
674*771fe6b9SJerome Glisse 		}
675*771fe6b9SJerome Glisse 		if (pkt->one_reg_wr) {
676*771fe6b9SJerome Glisse 			if (!(auth[j] & m)) {
677*771fe6b9SJerome Glisse 				break;
678*771fe6b9SJerome Glisse 			}
679*771fe6b9SJerome Glisse 		} else {
680*771fe6b9SJerome Glisse 			reg += 4;
681*771fe6b9SJerome Glisse 		}
682*771fe6b9SJerome Glisse 	}
683*771fe6b9SJerome Glisse 	return 0;
684*771fe6b9SJerome Glisse }
685*771fe6b9SJerome Glisse 
686*771fe6b9SJerome Glisse int r100_cs_parse_packet3(struct radeon_cs_parser *p,
687*771fe6b9SJerome Glisse 			  struct radeon_cs_packet *pkt,
688*771fe6b9SJerome Glisse 			  unsigned *auth, unsigned n,
689*771fe6b9SJerome Glisse 			  radeon_packet3_check_t check)
690*771fe6b9SJerome Glisse {
691*771fe6b9SJerome Glisse 	unsigned i, m;
692*771fe6b9SJerome Glisse 
693*771fe6b9SJerome Glisse 	if ((pkt->opcode >> 5) > n) {
694*771fe6b9SJerome Glisse 		return -EINVAL;
695*771fe6b9SJerome Glisse 	}
696*771fe6b9SJerome Glisse 	i = pkt->opcode >> 5;
697*771fe6b9SJerome Glisse 	m = 1 << (pkt->opcode & 31);
698*771fe6b9SJerome Glisse 	if (auth[i] & m) {
699*771fe6b9SJerome Glisse 		return check(p, pkt);
700*771fe6b9SJerome Glisse 	}
701*771fe6b9SJerome Glisse 	return 0;
702*771fe6b9SJerome Glisse }
703*771fe6b9SJerome Glisse 
704*771fe6b9SJerome Glisse void r100_cs_dump_packet(struct radeon_cs_parser *p,
705*771fe6b9SJerome Glisse 			 struct radeon_cs_packet *pkt)
706*771fe6b9SJerome Glisse {
707*771fe6b9SJerome Glisse 	struct radeon_cs_chunk *ib_chunk;
708*771fe6b9SJerome Glisse 	volatile uint32_t *ib;
709*771fe6b9SJerome Glisse 	unsigned i;
710*771fe6b9SJerome Glisse 	unsigned idx;
711*771fe6b9SJerome Glisse 
712*771fe6b9SJerome Glisse 	ib = p->ib->ptr;
713*771fe6b9SJerome Glisse 	ib_chunk = &p->chunks[p->chunk_ib_idx];
714*771fe6b9SJerome Glisse 	idx = pkt->idx;
715*771fe6b9SJerome Glisse 	for (i = 0; i <= (pkt->count + 1); i++, idx++) {
716*771fe6b9SJerome Glisse 		DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]);
717*771fe6b9SJerome Glisse 	}
718*771fe6b9SJerome Glisse }
719*771fe6b9SJerome Glisse 
720*771fe6b9SJerome Glisse /**
721*771fe6b9SJerome Glisse  * r100_cs_packet_parse() - parse cp packet and point ib index to next packet
722*771fe6b9SJerome Glisse  * @parser:	parser structure holding parsing context.
723*771fe6b9SJerome Glisse  * @pkt:	where to store packet informations
724*771fe6b9SJerome Glisse  *
725*771fe6b9SJerome Glisse  * Assume that chunk_ib_index is properly set. Will return -EINVAL
726*771fe6b9SJerome Glisse  * if packet is bigger than remaining ib size. or if packets is unknown.
727*771fe6b9SJerome Glisse  **/
728*771fe6b9SJerome Glisse int r100_cs_packet_parse(struct radeon_cs_parser *p,
729*771fe6b9SJerome Glisse 			 struct radeon_cs_packet *pkt,
730*771fe6b9SJerome Glisse 			 unsigned idx)
731*771fe6b9SJerome Glisse {
732*771fe6b9SJerome Glisse 	struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
733*771fe6b9SJerome Glisse 	uint32_t header = ib_chunk->kdata[idx];
734*771fe6b9SJerome Glisse 
735*771fe6b9SJerome Glisse 	if (idx >= ib_chunk->length_dw) {
736*771fe6b9SJerome Glisse 		DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
737*771fe6b9SJerome Glisse 			  idx, ib_chunk->length_dw);
738*771fe6b9SJerome Glisse 		return -EINVAL;
739*771fe6b9SJerome Glisse 	}
740*771fe6b9SJerome Glisse 	pkt->idx = idx;
741*771fe6b9SJerome Glisse 	pkt->type = CP_PACKET_GET_TYPE(header);
742*771fe6b9SJerome Glisse 	pkt->count = CP_PACKET_GET_COUNT(header);
743*771fe6b9SJerome Glisse 	switch (pkt->type) {
744*771fe6b9SJerome Glisse 	case PACKET_TYPE0:
745*771fe6b9SJerome Glisse 		pkt->reg = CP_PACKET0_GET_REG(header);
746*771fe6b9SJerome Glisse 		pkt->one_reg_wr = CP_PACKET0_GET_ONE_REG_WR(header);
747*771fe6b9SJerome Glisse 		break;
748*771fe6b9SJerome Glisse 	case PACKET_TYPE3:
749*771fe6b9SJerome Glisse 		pkt->opcode = CP_PACKET3_GET_OPCODE(header);
750*771fe6b9SJerome Glisse 		break;
751*771fe6b9SJerome Glisse 	case PACKET_TYPE2:
752*771fe6b9SJerome Glisse 		pkt->count = -1;
753*771fe6b9SJerome Glisse 		break;
754*771fe6b9SJerome Glisse 	default:
755*771fe6b9SJerome Glisse 		DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
756*771fe6b9SJerome Glisse 		return -EINVAL;
757*771fe6b9SJerome Glisse 	}
758*771fe6b9SJerome Glisse 	if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
759*771fe6b9SJerome Glisse 		DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
760*771fe6b9SJerome Glisse 			  pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
761*771fe6b9SJerome Glisse 		return -EINVAL;
762*771fe6b9SJerome Glisse 	}
763*771fe6b9SJerome Glisse 	return 0;
764*771fe6b9SJerome Glisse }
765*771fe6b9SJerome Glisse 
766*771fe6b9SJerome Glisse /**
767*771fe6b9SJerome Glisse  * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3
768*771fe6b9SJerome Glisse  * @parser:		parser structure holding parsing context.
769*771fe6b9SJerome Glisse  * @data:		pointer to relocation data
770*771fe6b9SJerome Glisse  * @offset_start:	starting offset
771*771fe6b9SJerome Glisse  * @offset_mask:	offset mask (to align start offset on)
772*771fe6b9SJerome Glisse  * @reloc:		reloc informations
773*771fe6b9SJerome Glisse  *
774*771fe6b9SJerome Glisse  * Check next packet is relocation packet3, do bo validation and compute
775*771fe6b9SJerome Glisse  * GPU offset using the provided start.
776*771fe6b9SJerome Glisse  **/
777*771fe6b9SJerome Glisse int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
778*771fe6b9SJerome Glisse 			      struct radeon_cs_reloc **cs_reloc)
779*771fe6b9SJerome Glisse {
780*771fe6b9SJerome Glisse 	struct radeon_cs_chunk *ib_chunk;
781*771fe6b9SJerome Glisse 	struct radeon_cs_chunk *relocs_chunk;
782*771fe6b9SJerome Glisse 	struct radeon_cs_packet p3reloc;
783*771fe6b9SJerome Glisse 	unsigned idx;
784*771fe6b9SJerome Glisse 	int r;
785*771fe6b9SJerome Glisse 
786*771fe6b9SJerome Glisse 	if (p->chunk_relocs_idx == -1) {
787*771fe6b9SJerome Glisse 		DRM_ERROR("No relocation chunk !\n");
788*771fe6b9SJerome Glisse 		return -EINVAL;
789*771fe6b9SJerome Glisse 	}
790*771fe6b9SJerome Glisse 	*cs_reloc = NULL;
791*771fe6b9SJerome Glisse 	ib_chunk = &p->chunks[p->chunk_ib_idx];
792*771fe6b9SJerome Glisse 	relocs_chunk = &p->chunks[p->chunk_relocs_idx];
793*771fe6b9SJerome Glisse 	r = r100_cs_packet_parse(p, &p3reloc, p->idx);
794*771fe6b9SJerome Glisse 	if (r) {
795*771fe6b9SJerome Glisse 		return r;
796*771fe6b9SJerome Glisse 	}
797*771fe6b9SJerome Glisse 	p->idx += p3reloc.count + 2;
798*771fe6b9SJerome Glisse 	if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
799*771fe6b9SJerome Glisse 		DRM_ERROR("No packet3 for relocation for packet at %d.\n",
800*771fe6b9SJerome Glisse 			  p3reloc.idx);
801*771fe6b9SJerome Glisse 		r100_cs_dump_packet(p, &p3reloc);
802*771fe6b9SJerome Glisse 		return -EINVAL;
803*771fe6b9SJerome Glisse 	}
804*771fe6b9SJerome Glisse 	idx = ib_chunk->kdata[p3reloc.idx + 1];
805*771fe6b9SJerome Glisse 	if (idx >= relocs_chunk->length_dw) {
806*771fe6b9SJerome Glisse 		DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
807*771fe6b9SJerome Glisse 			  idx, relocs_chunk->length_dw);
808*771fe6b9SJerome Glisse 		r100_cs_dump_packet(p, &p3reloc);
809*771fe6b9SJerome Glisse 		return -EINVAL;
810*771fe6b9SJerome Glisse 	}
811*771fe6b9SJerome Glisse 	/* FIXME: we assume reloc size is 4 dwords */
812*771fe6b9SJerome Glisse 	*cs_reloc = p->relocs_ptr[(idx / 4)];
813*771fe6b9SJerome Glisse 	return 0;
814*771fe6b9SJerome Glisse }
815*771fe6b9SJerome Glisse 
816*771fe6b9SJerome Glisse static int r100_packet0_check(struct radeon_cs_parser *p,
817*771fe6b9SJerome Glisse 			      struct radeon_cs_packet *pkt)
818*771fe6b9SJerome Glisse {
819*771fe6b9SJerome Glisse 	struct radeon_cs_chunk *ib_chunk;
820*771fe6b9SJerome Glisse 	struct radeon_cs_reloc *reloc;
821*771fe6b9SJerome Glisse 	volatile uint32_t *ib;
822*771fe6b9SJerome Glisse 	uint32_t tmp;
823*771fe6b9SJerome Glisse 	unsigned reg;
824*771fe6b9SJerome Glisse 	unsigned i;
825*771fe6b9SJerome Glisse 	unsigned idx;
826*771fe6b9SJerome Glisse 	bool onereg;
827*771fe6b9SJerome Glisse 	int r;
828*771fe6b9SJerome Glisse 
829*771fe6b9SJerome Glisse 	ib = p->ib->ptr;
830*771fe6b9SJerome Glisse 	ib_chunk = &p->chunks[p->chunk_ib_idx];
831*771fe6b9SJerome Glisse 	idx = pkt->idx + 1;
832*771fe6b9SJerome Glisse 	reg = pkt->reg;
833*771fe6b9SJerome Glisse 	onereg = false;
834*771fe6b9SJerome Glisse 	if (CP_PACKET0_GET_ONE_REG_WR(ib_chunk->kdata[pkt->idx])) {
835*771fe6b9SJerome Glisse 		onereg = true;
836*771fe6b9SJerome Glisse 	}
837*771fe6b9SJerome Glisse 	for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
838*771fe6b9SJerome Glisse 		switch (reg) {
839*771fe6b9SJerome Glisse 		/* FIXME: only allow PACKET3 blit? easier to check for out of
840*771fe6b9SJerome Glisse 		 * range access */
841*771fe6b9SJerome Glisse 		case RADEON_DST_PITCH_OFFSET:
842*771fe6b9SJerome Glisse 		case RADEON_SRC_PITCH_OFFSET:
843*771fe6b9SJerome Glisse 			r = r100_cs_packet_next_reloc(p, &reloc);
844*771fe6b9SJerome Glisse 			if (r) {
845*771fe6b9SJerome Glisse 				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
846*771fe6b9SJerome Glisse 					  idx, reg);
847*771fe6b9SJerome Glisse 				r100_cs_dump_packet(p, pkt);
848*771fe6b9SJerome Glisse 				return r;
849*771fe6b9SJerome Glisse 			}
850*771fe6b9SJerome Glisse 			tmp = ib_chunk->kdata[idx] & 0x003fffff;
851*771fe6b9SJerome Glisse 			tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
852*771fe6b9SJerome Glisse 			ib[idx] = (ib_chunk->kdata[idx] & 0xffc00000) | tmp;
853*771fe6b9SJerome Glisse 			break;
854*771fe6b9SJerome Glisse 		case RADEON_RB3D_DEPTHOFFSET:
855*771fe6b9SJerome Glisse 		case RADEON_RB3D_COLOROFFSET:
856*771fe6b9SJerome Glisse 		case R300_RB3D_COLOROFFSET0:
857*771fe6b9SJerome Glisse 		case R300_ZB_DEPTHOFFSET:
858*771fe6b9SJerome Glisse 		case R200_PP_TXOFFSET_0:
859*771fe6b9SJerome Glisse 		case R200_PP_TXOFFSET_1:
860*771fe6b9SJerome Glisse 		case R200_PP_TXOFFSET_2:
861*771fe6b9SJerome Glisse 		case R200_PP_TXOFFSET_3:
862*771fe6b9SJerome Glisse 		case R200_PP_TXOFFSET_4:
863*771fe6b9SJerome Glisse 		case R200_PP_TXOFFSET_5:
864*771fe6b9SJerome Glisse 		case RADEON_PP_TXOFFSET_0:
865*771fe6b9SJerome Glisse 		case RADEON_PP_TXOFFSET_1:
866*771fe6b9SJerome Glisse 		case RADEON_PP_TXOFFSET_2:
867*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0:
868*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+4:
869*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+8:
870*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+12:
871*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+16:
872*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+20:
873*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+24:
874*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+28:
875*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+32:
876*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+36:
877*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+40:
878*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+44:
879*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+48:
880*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+52:
881*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+56:
882*771fe6b9SJerome Glisse 		case R300_TX_OFFSET_0+60:
883*771fe6b9SJerome Glisse 			r = r100_cs_packet_next_reloc(p, &reloc);
884*771fe6b9SJerome Glisse 			if (r) {
885*771fe6b9SJerome Glisse 				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
886*771fe6b9SJerome Glisse 					  idx, reg);
887*771fe6b9SJerome Glisse 				r100_cs_dump_packet(p, pkt);
888*771fe6b9SJerome Glisse 				return r;
889*771fe6b9SJerome Glisse 			}
890*771fe6b9SJerome Glisse 			ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
891*771fe6b9SJerome Glisse 			break;
892*771fe6b9SJerome Glisse 		default:
893*771fe6b9SJerome Glisse 			/* FIXME: we don't want to allow anyothers packet */
894*771fe6b9SJerome Glisse 			break;
895*771fe6b9SJerome Glisse 		}
896*771fe6b9SJerome Glisse 		if (onereg) {
897*771fe6b9SJerome Glisse 			/* FIXME: forbid onereg write to register on relocate */
898*771fe6b9SJerome Glisse 			break;
899*771fe6b9SJerome Glisse 		}
900*771fe6b9SJerome Glisse 	}
901*771fe6b9SJerome Glisse 	return 0;
902*771fe6b9SJerome Glisse }
903*771fe6b9SJerome Glisse 
904*771fe6b9SJerome Glisse static int r100_packet3_check(struct radeon_cs_parser *p,
905*771fe6b9SJerome Glisse 			      struct radeon_cs_packet *pkt)
906*771fe6b9SJerome Glisse {
907*771fe6b9SJerome Glisse 	struct radeon_cs_chunk *ib_chunk;
908*771fe6b9SJerome Glisse 	struct radeon_cs_reloc *reloc;
909*771fe6b9SJerome Glisse 	unsigned idx;
910*771fe6b9SJerome Glisse 	unsigned i, c;
911*771fe6b9SJerome Glisse 	volatile uint32_t *ib;
912*771fe6b9SJerome Glisse 	int r;
913*771fe6b9SJerome Glisse 
914*771fe6b9SJerome Glisse 	ib = p->ib->ptr;
915*771fe6b9SJerome Glisse 	ib_chunk = &p->chunks[p->chunk_ib_idx];
916*771fe6b9SJerome Glisse 	idx = pkt->idx + 1;
917*771fe6b9SJerome Glisse 	switch (pkt->opcode) {
918*771fe6b9SJerome Glisse 	case PACKET3_3D_LOAD_VBPNTR:
919*771fe6b9SJerome Glisse 		c = ib_chunk->kdata[idx++];
920*771fe6b9SJerome Glisse 		for (i = 0; i < (c - 1); i += 2, idx += 3) {
921*771fe6b9SJerome Glisse 			r = r100_cs_packet_next_reloc(p, &reloc);
922*771fe6b9SJerome Glisse 			if (r) {
923*771fe6b9SJerome Glisse 				DRM_ERROR("No reloc for packet3 %d\n",
924*771fe6b9SJerome Glisse 					  pkt->opcode);
925*771fe6b9SJerome Glisse 				r100_cs_dump_packet(p, pkt);
926*771fe6b9SJerome Glisse 				return r;
927*771fe6b9SJerome Glisse 			}
928*771fe6b9SJerome Glisse 			ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
929*771fe6b9SJerome Glisse 			r = r100_cs_packet_next_reloc(p, &reloc);
930*771fe6b9SJerome Glisse 			if (r) {
931*771fe6b9SJerome Glisse 				DRM_ERROR("No reloc for packet3 %d\n",
932*771fe6b9SJerome Glisse 					  pkt->opcode);
933*771fe6b9SJerome Glisse 				r100_cs_dump_packet(p, pkt);
934*771fe6b9SJerome Glisse 				return r;
935*771fe6b9SJerome Glisse 			}
936*771fe6b9SJerome Glisse 			ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset);
937*771fe6b9SJerome Glisse 		}
938*771fe6b9SJerome Glisse 		if (c & 1) {
939*771fe6b9SJerome Glisse 			r = r100_cs_packet_next_reloc(p, &reloc);
940*771fe6b9SJerome Glisse 			if (r) {
941*771fe6b9SJerome Glisse 				DRM_ERROR("No reloc for packet3 %d\n",
942*771fe6b9SJerome Glisse 					  pkt->opcode);
943*771fe6b9SJerome Glisse 				r100_cs_dump_packet(p, pkt);
944*771fe6b9SJerome Glisse 				return r;
945*771fe6b9SJerome Glisse 			}
946*771fe6b9SJerome Glisse 			ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
947*771fe6b9SJerome Glisse 		}
948*771fe6b9SJerome Glisse 		break;
949*771fe6b9SJerome Glisse 	case PACKET3_INDX_BUFFER:
950*771fe6b9SJerome Glisse 		r = r100_cs_packet_next_reloc(p, &reloc);
951*771fe6b9SJerome Glisse 		if (r) {
952*771fe6b9SJerome Glisse 			DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode);
953*771fe6b9SJerome Glisse 			r100_cs_dump_packet(p, pkt);
954*771fe6b9SJerome Glisse 			return r;
955*771fe6b9SJerome Glisse 		}
956*771fe6b9SJerome Glisse 		ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
957*771fe6b9SJerome Glisse 		break;
958*771fe6b9SJerome Glisse 	case 0x23:
959*771fe6b9SJerome Glisse 		/* FIXME: cleanup */
960*771fe6b9SJerome Glisse 		/* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */
961*771fe6b9SJerome Glisse 		r = r100_cs_packet_next_reloc(p, &reloc);
962*771fe6b9SJerome Glisse 		if (r) {
963*771fe6b9SJerome Glisse 			DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode);
964*771fe6b9SJerome Glisse 			r100_cs_dump_packet(p, pkt);
965*771fe6b9SJerome Glisse 			return r;
966*771fe6b9SJerome Glisse 		}
967*771fe6b9SJerome Glisse 		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
968*771fe6b9SJerome Glisse 		break;
969*771fe6b9SJerome Glisse 	case PACKET3_3D_DRAW_IMMD:
970*771fe6b9SJerome Glisse 		/* triggers drawing using in-packet vertex data */
971*771fe6b9SJerome Glisse 	case PACKET3_3D_DRAW_IMMD_2:
972*771fe6b9SJerome Glisse 		/* triggers drawing using in-packet vertex data */
973*771fe6b9SJerome Glisse 	case PACKET3_3D_DRAW_VBUF_2:
974*771fe6b9SJerome Glisse 		/* triggers drawing of vertex buffers setup elsewhere */
975*771fe6b9SJerome Glisse 	case PACKET3_3D_DRAW_INDX_2:
976*771fe6b9SJerome Glisse 		/* triggers drawing using indices to vertex buffer */
977*771fe6b9SJerome Glisse 	case PACKET3_3D_DRAW_VBUF:
978*771fe6b9SJerome Glisse 		/* triggers drawing of vertex buffers setup elsewhere */
979*771fe6b9SJerome Glisse 	case PACKET3_3D_DRAW_INDX:
980*771fe6b9SJerome Glisse 		/* triggers drawing using indices to vertex buffer */
981*771fe6b9SJerome Glisse 	case PACKET3_NOP:
982*771fe6b9SJerome Glisse 		break;
983*771fe6b9SJerome Glisse 	default:
984*771fe6b9SJerome Glisse 		DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
985*771fe6b9SJerome Glisse 		return -EINVAL;
986*771fe6b9SJerome Glisse 	}
987*771fe6b9SJerome Glisse 	return 0;
988*771fe6b9SJerome Glisse }
989*771fe6b9SJerome Glisse 
990*771fe6b9SJerome Glisse int r100_cs_parse(struct radeon_cs_parser *p)
991*771fe6b9SJerome Glisse {
992*771fe6b9SJerome Glisse 	struct radeon_cs_packet pkt;
993*771fe6b9SJerome Glisse 	int r;
994*771fe6b9SJerome Glisse 
995*771fe6b9SJerome Glisse 	do {
996*771fe6b9SJerome Glisse 		r = r100_cs_packet_parse(p, &pkt, p->idx);
997*771fe6b9SJerome Glisse 		if (r) {
998*771fe6b9SJerome Glisse 			return r;
999*771fe6b9SJerome Glisse 		}
1000*771fe6b9SJerome Glisse 		p->idx += pkt.count + 2;
1001*771fe6b9SJerome Glisse 		switch (pkt.type) {
1002*771fe6b9SJerome Glisse 		case PACKET_TYPE0:
1003*771fe6b9SJerome Glisse 			r = r100_packet0_check(p, &pkt);
1004*771fe6b9SJerome Glisse 			break;
1005*771fe6b9SJerome Glisse 		case PACKET_TYPE2:
1006*771fe6b9SJerome Glisse 			break;
1007*771fe6b9SJerome Glisse 		case PACKET_TYPE3:
1008*771fe6b9SJerome Glisse 			r = r100_packet3_check(p, &pkt);
1009*771fe6b9SJerome Glisse 			break;
1010*771fe6b9SJerome Glisse 		default:
1011*771fe6b9SJerome Glisse 			DRM_ERROR("Unknown packet type %d !\n",
1012*771fe6b9SJerome Glisse 					pkt.type);
1013*771fe6b9SJerome Glisse 			return -EINVAL;
1014*771fe6b9SJerome Glisse 		}
1015*771fe6b9SJerome Glisse 		if (r) {
1016*771fe6b9SJerome Glisse 			return r;
1017*771fe6b9SJerome Glisse 		}
1018*771fe6b9SJerome Glisse 	} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
1019*771fe6b9SJerome Glisse 	return 0;
1020*771fe6b9SJerome Glisse }
1021*771fe6b9SJerome Glisse 
1022*771fe6b9SJerome Glisse 
1023*771fe6b9SJerome Glisse /*
1024*771fe6b9SJerome Glisse  * Global GPU functions
1025*771fe6b9SJerome Glisse  */
1026*771fe6b9SJerome Glisse void r100_errata(struct radeon_device *rdev)
1027*771fe6b9SJerome Glisse {
1028*771fe6b9SJerome Glisse 	rdev->pll_errata = 0;
1029*771fe6b9SJerome Glisse 
1030*771fe6b9SJerome Glisse 	if (rdev->family == CHIP_RV200 || rdev->family == CHIP_RS200) {
1031*771fe6b9SJerome Glisse 		rdev->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS;
1032*771fe6b9SJerome Glisse 	}
1033*771fe6b9SJerome Glisse 
1034*771fe6b9SJerome Glisse 	if (rdev->family == CHIP_RV100 ||
1035*771fe6b9SJerome Glisse 	    rdev->family == CHIP_RS100 ||
1036*771fe6b9SJerome Glisse 	    rdev->family == CHIP_RS200) {
1037*771fe6b9SJerome Glisse 		rdev->pll_errata |= CHIP_ERRATA_PLL_DELAY;
1038*771fe6b9SJerome Glisse 	}
1039*771fe6b9SJerome Glisse }
1040*771fe6b9SJerome Glisse 
1041*771fe6b9SJerome Glisse /* Wait for vertical sync on primary CRTC */
1042*771fe6b9SJerome Glisse void r100_gpu_wait_for_vsync(struct radeon_device *rdev)
1043*771fe6b9SJerome Glisse {
1044*771fe6b9SJerome Glisse 	uint32_t crtc_gen_cntl, tmp;
1045*771fe6b9SJerome Glisse 	int i;
1046*771fe6b9SJerome Glisse 
1047*771fe6b9SJerome Glisse 	crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
1048*771fe6b9SJerome Glisse 	if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
1049*771fe6b9SJerome Glisse 	    !(crtc_gen_cntl & RADEON_CRTC_EN)) {
1050*771fe6b9SJerome Glisse 		return;
1051*771fe6b9SJerome Glisse 	}
1052*771fe6b9SJerome Glisse 	/* Clear the CRTC_VBLANK_SAVE bit */
1053*771fe6b9SJerome Glisse 	WREG32(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);
1054*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
1055*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CRTC_STATUS);
1056*771fe6b9SJerome Glisse 		if (tmp & RADEON_CRTC_VBLANK_SAVE) {
1057*771fe6b9SJerome Glisse 			return;
1058*771fe6b9SJerome Glisse 		}
1059*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
1060*771fe6b9SJerome Glisse 	}
1061*771fe6b9SJerome Glisse }
1062*771fe6b9SJerome Glisse 
1063*771fe6b9SJerome Glisse /* Wait for vertical sync on secondary CRTC */
1064*771fe6b9SJerome Glisse void r100_gpu_wait_for_vsync2(struct radeon_device *rdev)
1065*771fe6b9SJerome Glisse {
1066*771fe6b9SJerome Glisse 	uint32_t crtc2_gen_cntl, tmp;
1067*771fe6b9SJerome Glisse 	int i;
1068*771fe6b9SJerome Glisse 
1069*771fe6b9SJerome Glisse 	crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
1070*771fe6b9SJerome Glisse 	if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
1071*771fe6b9SJerome Glisse 	    !(crtc2_gen_cntl & RADEON_CRTC2_EN))
1072*771fe6b9SJerome Glisse 		return;
1073*771fe6b9SJerome Glisse 
1074*771fe6b9SJerome Glisse 	/* Clear the CRTC_VBLANK_SAVE bit */
1075*771fe6b9SJerome Glisse 	WREG32(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);
1076*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
1077*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CRTC2_STATUS);
1078*771fe6b9SJerome Glisse 		if (tmp & RADEON_CRTC2_VBLANK_SAVE) {
1079*771fe6b9SJerome Glisse 			return;
1080*771fe6b9SJerome Glisse 		}
1081*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
1082*771fe6b9SJerome Glisse 	}
1083*771fe6b9SJerome Glisse }
1084*771fe6b9SJerome Glisse 
1085*771fe6b9SJerome Glisse int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n)
1086*771fe6b9SJerome Glisse {
1087*771fe6b9SJerome Glisse 	unsigned i;
1088*771fe6b9SJerome Glisse 	uint32_t tmp;
1089*771fe6b9SJerome Glisse 
1090*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
1091*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
1092*771fe6b9SJerome Glisse 		if (tmp >= n) {
1093*771fe6b9SJerome Glisse 			return 0;
1094*771fe6b9SJerome Glisse 		}
1095*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
1096*771fe6b9SJerome Glisse 	}
1097*771fe6b9SJerome Glisse 	return -1;
1098*771fe6b9SJerome Glisse }
1099*771fe6b9SJerome Glisse 
1100*771fe6b9SJerome Glisse int r100_gui_wait_for_idle(struct radeon_device *rdev)
1101*771fe6b9SJerome Glisse {
1102*771fe6b9SJerome Glisse 	unsigned i;
1103*771fe6b9SJerome Glisse 	uint32_t tmp;
1104*771fe6b9SJerome Glisse 
1105*771fe6b9SJerome Glisse 	if (r100_rbbm_fifo_wait_for_entry(rdev, 64)) {
1106*771fe6b9SJerome Glisse 		printk(KERN_WARNING "radeon: wait for empty RBBM fifo failed !"
1107*771fe6b9SJerome Glisse 		       " Bad things might happen.\n");
1108*771fe6b9SJerome Glisse 	}
1109*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
1110*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_RBBM_STATUS);
1111*771fe6b9SJerome Glisse 		if (!(tmp & (1 << 31))) {
1112*771fe6b9SJerome Glisse 			return 0;
1113*771fe6b9SJerome Glisse 		}
1114*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
1115*771fe6b9SJerome Glisse 	}
1116*771fe6b9SJerome Glisse 	return -1;
1117*771fe6b9SJerome Glisse }
1118*771fe6b9SJerome Glisse 
1119*771fe6b9SJerome Glisse int r100_mc_wait_for_idle(struct radeon_device *rdev)
1120*771fe6b9SJerome Glisse {
1121*771fe6b9SJerome Glisse 	unsigned i;
1122*771fe6b9SJerome Glisse 	uint32_t tmp;
1123*771fe6b9SJerome Glisse 
1124*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
1125*771fe6b9SJerome Glisse 		/* read MC_STATUS */
1126*771fe6b9SJerome Glisse 		tmp = RREG32(0x0150);
1127*771fe6b9SJerome Glisse 		if (tmp & (1 << 2)) {
1128*771fe6b9SJerome Glisse 			return 0;
1129*771fe6b9SJerome Glisse 		}
1130*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
1131*771fe6b9SJerome Glisse 	}
1132*771fe6b9SJerome Glisse 	return -1;
1133*771fe6b9SJerome Glisse }
1134*771fe6b9SJerome Glisse 
1135*771fe6b9SJerome Glisse void r100_gpu_init(struct radeon_device *rdev)
1136*771fe6b9SJerome Glisse {
1137*771fe6b9SJerome Glisse 	/* TODO: anythings to do here ? pipes ? */
1138*771fe6b9SJerome Glisse 	r100_hdp_reset(rdev);
1139*771fe6b9SJerome Glisse }
1140*771fe6b9SJerome Glisse 
1141*771fe6b9SJerome Glisse void r100_hdp_reset(struct radeon_device *rdev)
1142*771fe6b9SJerome Glisse {
1143*771fe6b9SJerome Glisse 	uint32_t tmp;
1144*771fe6b9SJerome Glisse 
1145*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
1146*771fe6b9SJerome Glisse 	tmp |= (7 << 28);
1147*771fe6b9SJerome Glisse 	WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
1148*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_HOST_PATH_CNTL);
1149*771fe6b9SJerome Glisse 	udelay(200);
1150*771fe6b9SJerome Glisse 	WREG32(RADEON_RBBM_SOFT_RESET, 0);
1151*771fe6b9SJerome Glisse 	WREG32(RADEON_HOST_PATH_CNTL, tmp);
1152*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_HOST_PATH_CNTL);
1153*771fe6b9SJerome Glisse }
1154*771fe6b9SJerome Glisse 
1155*771fe6b9SJerome Glisse int r100_rb2d_reset(struct radeon_device *rdev)
1156*771fe6b9SJerome Glisse {
1157*771fe6b9SJerome Glisse 	uint32_t tmp;
1158*771fe6b9SJerome Glisse 	int i;
1159*771fe6b9SJerome Glisse 
1160*771fe6b9SJerome Glisse 	WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2);
1161*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_RBBM_SOFT_RESET);
1162*771fe6b9SJerome Glisse 	udelay(200);
1163*771fe6b9SJerome Glisse 	WREG32(RADEON_RBBM_SOFT_RESET, 0);
1164*771fe6b9SJerome Glisse 	/* Wait to prevent race in RBBM_STATUS */
1165*771fe6b9SJerome Glisse 	mdelay(1);
1166*771fe6b9SJerome Glisse 	for (i = 0; i < rdev->usec_timeout; i++) {
1167*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_RBBM_STATUS);
1168*771fe6b9SJerome Glisse 		if (!(tmp & (1 << 26))) {
1169*771fe6b9SJerome Glisse 			DRM_INFO("RB2D reset succeed (RBBM_STATUS=0x%08X)\n",
1170*771fe6b9SJerome Glisse 				 tmp);
1171*771fe6b9SJerome Glisse 			return 0;
1172*771fe6b9SJerome Glisse 		}
1173*771fe6b9SJerome Glisse 		DRM_UDELAY(1);
1174*771fe6b9SJerome Glisse 	}
1175*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_RBBM_STATUS);
1176*771fe6b9SJerome Glisse 	DRM_ERROR("Failed to reset RB2D (RBBM_STATUS=0x%08X)!\n", tmp);
1177*771fe6b9SJerome Glisse 	return -1;
1178*771fe6b9SJerome Glisse }
1179*771fe6b9SJerome Glisse 
1180*771fe6b9SJerome Glisse int r100_gpu_reset(struct radeon_device *rdev)
1181*771fe6b9SJerome Glisse {
1182*771fe6b9SJerome Glisse 	uint32_t status;
1183*771fe6b9SJerome Glisse 
1184*771fe6b9SJerome Glisse 	/* reset order likely matter */
1185*771fe6b9SJerome Glisse 	status = RREG32(RADEON_RBBM_STATUS);
1186*771fe6b9SJerome Glisse 	/* reset HDP */
1187*771fe6b9SJerome Glisse 	r100_hdp_reset(rdev);
1188*771fe6b9SJerome Glisse 	/* reset rb2d */
1189*771fe6b9SJerome Glisse 	if (status & ((1 << 17) | (1 << 18) | (1 << 27))) {
1190*771fe6b9SJerome Glisse 		r100_rb2d_reset(rdev);
1191*771fe6b9SJerome Glisse 	}
1192*771fe6b9SJerome Glisse 	/* TODO: reset 3D engine */
1193*771fe6b9SJerome Glisse 	/* reset CP */
1194*771fe6b9SJerome Glisse 	status = RREG32(RADEON_RBBM_STATUS);
1195*771fe6b9SJerome Glisse 	if (status & (1 << 16)) {
1196*771fe6b9SJerome Glisse 		r100_cp_reset(rdev);
1197*771fe6b9SJerome Glisse 	}
1198*771fe6b9SJerome Glisse 	/* Check if GPU is idle */
1199*771fe6b9SJerome Glisse 	status = RREG32(RADEON_RBBM_STATUS);
1200*771fe6b9SJerome Glisse 	if (status & (1 << 31)) {
1201*771fe6b9SJerome Glisse 		DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
1202*771fe6b9SJerome Glisse 		return -1;
1203*771fe6b9SJerome Glisse 	}
1204*771fe6b9SJerome Glisse 	DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status);
1205*771fe6b9SJerome Glisse 	return 0;
1206*771fe6b9SJerome Glisse }
1207*771fe6b9SJerome Glisse 
1208*771fe6b9SJerome Glisse 
1209*771fe6b9SJerome Glisse /*
1210*771fe6b9SJerome Glisse  * VRAM info
1211*771fe6b9SJerome Glisse  */
1212*771fe6b9SJerome Glisse static void r100_vram_get_type(struct radeon_device *rdev)
1213*771fe6b9SJerome Glisse {
1214*771fe6b9SJerome Glisse 	uint32_t tmp;
1215*771fe6b9SJerome Glisse 
1216*771fe6b9SJerome Glisse 	rdev->mc.vram_is_ddr = false;
1217*771fe6b9SJerome Glisse 	if (rdev->flags & RADEON_IS_IGP)
1218*771fe6b9SJerome Glisse 		rdev->mc.vram_is_ddr = true;
1219*771fe6b9SJerome Glisse 	else if (RREG32(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR)
1220*771fe6b9SJerome Glisse 		rdev->mc.vram_is_ddr = true;
1221*771fe6b9SJerome Glisse 	if ((rdev->family == CHIP_RV100) ||
1222*771fe6b9SJerome Glisse 	    (rdev->family == CHIP_RS100) ||
1223*771fe6b9SJerome Glisse 	    (rdev->family == CHIP_RS200)) {
1224*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_MEM_CNTL);
1225*771fe6b9SJerome Glisse 		if (tmp & RV100_HALF_MODE) {
1226*771fe6b9SJerome Glisse 			rdev->mc.vram_width = 32;
1227*771fe6b9SJerome Glisse 		} else {
1228*771fe6b9SJerome Glisse 			rdev->mc.vram_width = 64;
1229*771fe6b9SJerome Glisse 		}
1230*771fe6b9SJerome Glisse 		if (rdev->flags & RADEON_SINGLE_CRTC) {
1231*771fe6b9SJerome Glisse 			rdev->mc.vram_width /= 4;
1232*771fe6b9SJerome Glisse 			rdev->mc.vram_is_ddr = true;
1233*771fe6b9SJerome Glisse 		}
1234*771fe6b9SJerome Glisse 	} else if (rdev->family <= CHIP_RV280) {
1235*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_MEM_CNTL);
1236*771fe6b9SJerome Glisse 		if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) {
1237*771fe6b9SJerome Glisse 			rdev->mc.vram_width = 128;
1238*771fe6b9SJerome Glisse 		} else {
1239*771fe6b9SJerome Glisse 			rdev->mc.vram_width = 64;
1240*771fe6b9SJerome Glisse 		}
1241*771fe6b9SJerome Glisse 	} else {
1242*771fe6b9SJerome Glisse 		/* newer IGPs */
1243*771fe6b9SJerome Glisse 		rdev->mc.vram_width = 128;
1244*771fe6b9SJerome Glisse 	}
1245*771fe6b9SJerome Glisse }
1246*771fe6b9SJerome Glisse 
1247*771fe6b9SJerome Glisse void r100_vram_info(struct radeon_device *rdev)
1248*771fe6b9SJerome Glisse {
1249*771fe6b9SJerome Glisse 	r100_vram_get_type(rdev);
1250*771fe6b9SJerome Glisse 
1251*771fe6b9SJerome Glisse 	if (rdev->flags & RADEON_IS_IGP) {
1252*771fe6b9SJerome Glisse 		uint32_t tom;
1253*771fe6b9SJerome Glisse 		/* read NB_TOM to get the amount of ram stolen for the GPU */
1254*771fe6b9SJerome Glisse 		tom = RREG32(RADEON_NB_TOM);
1255*771fe6b9SJerome Glisse 		rdev->mc.vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
1256*771fe6b9SJerome Glisse 		WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
1257*771fe6b9SJerome Glisse 	} else {
1258*771fe6b9SJerome Glisse 		rdev->mc.vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
1259*771fe6b9SJerome Glisse 		/* Some production boards of m6 will report 0
1260*771fe6b9SJerome Glisse 		 * if it's 8 MB
1261*771fe6b9SJerome Glisse 		 */
1262*771fe6b9SJerome Glisse 		if (rdev->mc.vram_size == 0) {
1263*771fe6b9SJerome Glisse 			rdev->mc.vram_size = 8192 * 1024;
1264*771fe6b9SJerome Glisse 			WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
1265*771fe6b9SJerome Glisse 		}
1266*771fe6b9SJerome Glisse 	}
1267*771fe6b9SJerome Glisse 
1268*771fe6b9SJerome Glisse 	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
1269*771fe6b9SJerome Glisse 	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
1270*771fe6b9SJerome Glisse 	if (rdev->mc.aper_size > rdev->mc.vram_size) {
1271*771fe6b9SJerome Glisse 		/* Why does some hw doesn't have CONFIG_MEMSIZE properly
1272*771fe6b9SJerome Glisse 		 * setup ? */
1273*771fe6b9SJerome Glisse 		rdev->mc.vram_size = rdev->mc.aper_size;
1274*771fe6b9SJerome Glisse 		WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size);
1275*771fe6b9SJerome Glisse 	}
1276*771fe6b9SJerome Glisse }
1277*771fe6b9SJerome Glisse 
1278*771fe6b9SJerome Glisse 
1279*771fe6b9SJerome Glisse /*
1280*771fe6b9SJerome Glisse  * Indirect registers accessor
1281*771fe6b9SJerome Glisse  */
1282*771fe6b9SJerome Glisse void r100_pll_errata_after_index(struct radeon_device *rdev)
1283*771fe6b9SJerome Glisse {
1284*771fe6b9SJerome Glisse 	if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) {
1285*771fe6b9SJerome Glisse 		return;
1286*771fe6b9SJerome Glisse 	}
1287*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_CLOCK_CNTL_DATA);
1288*771fe6b9SJerome Glisse 	(void)RREG32(RADEON_CRTC_GEN_CNTL);
1289*771fe6b9SJerome Glisse }
1290*771fe6b9SJerome Glisse 
1291*771fe6b9SJerome Glisse static void r100_pll_errata_after_data(struct radeon_device *rdev)
1292*771fe6b9SJerome Glisse {
1293*771fe6b9SJerome Glisse 	/* This workarounds is necessary on RV100, RS100 and RS200 chips
1294*771fe6b9SJerome Glisse 	 * or the chip could hang on a subsequent access
1295*771fe6b9SJerome Glisse 	 */
1296*771fe6b9SJerome Glisse 	if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) {
1297*771fe6b9SJerome Glisse 		udelay(5000);
1298*771fe6b9SJerome Glisse 	}
1299*771fe6b9SJerome Glisse 
1300*771fe6b9SJerome Glisse 	/* This function is required to workaround a hardware bug in some (all?)
1301*771fe6b9SJerome Glisse 	 * revisions of the R300.  This workaround should be called after every
1302*771fe6b9SJerome Glisse 	 * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
1303*771fe6b9SJerome Glisse 	 * may not be correct.
1304*771fe6b9SJerome Glisse 	 */
1305*771fe6b9SJerome Glisse 	if (rdev->pll_errata & CHIP_ERRATA_R300_CG) {
1306*771fe6b9SJerome Glisse 		uint32_t save, tmp;
1307*771fe6b9SJerome Glisse 
1308*771fe6b9SJerome Glisse 		save = RREG32(RADEON_CLOCK_CNTL_INDEX);
1309*771fe6b9SJerome Glisse 		tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
1310*771fe6b9SJerome Glisse 		WREG32(RADEON_CLOCK_CNTL_INDEX, tmp);
1311*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CLOCK_CNTL_DATA);
1312*771fe6b9SJerome Glisse 		WREG32(RADEON_CLOCK_CNTL_INDEX, save);
1313*771fe6b9SJerome Glisse 	}
1314*771fe6b9SJerome Glisse }
1315*771fe6b9SJerome Glisse 
1316*771fe6b9SJerome Glisse uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg)
1317*771fe6b9SJerome Glisse {
1318*771fe6b9SJerome Glisse 	uint32_t data;
1319*771fe6b9SJerome Glisse 
1320*771fe6b9SJerome Glisse 	WREG8(RADEON_CLOCK_CNTL_INDEX, reg & 0x3f);
1321*771fe6b9SJerome Glisse 	r100_pll_errata_after_index(rdev);
1322*771fe6b9SJerome Glisse 	data = RREG32(RADEON_CLOCK_CNTL_DATA);
1323*771fe6b9SJerome Glisse 	r100_pll_errata_after_data(rdev);
1324*771fe6b9SJerome Glisse 	return data;
1325*771fe6b9SJerome Glisse }
1326*771fe6b9SJerome Glisse 
1327*771fe6b9SJerome Glisse void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
1328*771fe6b9SJerome Glisse {
1329*771fe6b9SJerome Glisse 	WREG8(RADEON_CLOCK_CNTL_INDEX, ((reg & 0x3f) | RADEON_PLL_WR_EN));
1330*771fe6b9SJerome Glisse 	r100_pll_errata_after_index(rdev);
1331*771fe6b9SJerome Glisse 	WREG32(RADEON_CLOCK_CNTL_DATA, v);
1332*771fe6b9SJerome Glisse 	r100_pll_errata_after_data(rdev);
1333*771fe6b9SJerome Glisse }
1334*771fe6b9SJerome Glisse 
1335*771fe6b9SJerome Glisse uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg)
1336*771fe6b9SJerome Glisse {
1337*771fe6b9SJerome Glisse 	if (reg < 0x10000)
1338*771fe6b9SJerome Glisse 		return readl(((void __iomem *)rdev->rmmio) + reg);
1339*771fe6b9SJerome Glisse 	else {
1340*771fe6b9SJerome Glisse 		writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
1341*771fe6b9SJerome Glisse 		return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
1342*771fe6b9SJerome Glisse 	}
1343*771fe6b9SJerome Glisse }
1344*771fe6b9SJerome Glisse 
1345*771fe6b9SJerome Glisse void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
1346*771fe6b9SJerome Glisse {
1347*771fe6b9SJerome Glisse 	if (reg < 0x10000)
1348*771fe6b9SJerome Glisse 		writel(v, ((void __iomem *)rdev->rmmio) + reg);
1349*771fe6b9SJerome Glisse 	else {
1350*771fe6b9SJerome Glisse 		writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
1351*771fe6b9SJerome Glisse 		writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
1352*771fe6b9SJerome Glisse 	}
1353*771fe6b9SJerome Glisse }
1354*771fe6b9SJerome Glisse 
1355*771fe6b9SJerome Glisse /*
1356*771fe6b9SJerome Glisse  * Debugfs info
1357*771fe6b9SJerome Glisse  */
1358*771fe6b9SJerome Glisse #if defined(CONFIG_DEBUG_FS)
1359*771fe6b9SJerome Glisse static int r100_debugfs_rbbm_info(struct seq_file *m, void *data)
1360*771fe6b9SJerome Glisse {
1361*771fe6b9SJerome Glisse 	struct drm_info_node *node = (struct drm_info_node *) m->private;
1362*771fe6b9SJerome Glisse 	struct drm_device *dev = node->minor->dev;
1363*771fe6b9SJerome Glisse 	struct radeon_device *rdev = dev->dev_private;
1364*771fe6b9SJerome Glisse 	uint32_t reg, value;
1365*771fe6b9SJerome Glisse 	unsigned i;
1366*771fe6b9SJerome Glisse 
1367*771fe6b9SJerome Glisse 	seq_printf(m, "RBBM_STATUS 0x%08x\n", RREG32(RADEON_RBBM_STATUS));
1368*771fe6b9SJerome Glisse 	seq_printf(m, "RBBM_CMDFIFO_STAT 0x%08x\n", RREG32(0xE7C));
1369*771fe6b9SJerome Glisse 	seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT));
1370*771fe6b9SJerome Glisse 	for (i = 0; i < 64; i++) {
1371*771fe6b9SJerome Glisse 		WREG32(RADEON_RBBM_CMDFIFO_ADDR, i | 0x100);
1372*771fe6b9SJerome Glisse 		reg = (RREG32(RADEON_RBBM_CMDFIFO_DATA) - 1) >> 2;
1373*771fe6b9SJerome Glisse 		WREG32(RADEON_RBBM_CMDFIFO_ADDR, i);
1374*771fe6b9SJerome Glisse 		value = RREG32(RADEON_RBBM_CMDFIFO_DATA);
1375*771fe6b9SJerome Glisse 		seq_printf(m, "[0x%03X] 0x%04X=0x%08X\n", i, reg, value);
1376*771fe6b9SJerome Glisse 	}
1377*771fe6b9SJerome Glisse 	return 0;
1378*771fe6b9SJerome Glisse }
1379*771fe6b9SJerome Glisse 
1380*771fe6b9SJerome Glisse static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data)
1381*771fe6b9SJerome Glisse {
1382*771fe6b9SJerome Glisse 	struct drm_info_node *node = (struct drm_info_node *) m->private;
1383*771fe6b9SJerome Glisse 	struct drm_device *dev = node->minor->dev;
1384*771fe6b9SJerome Glisse 	struct radeon_device *rdev = dev->dev_private;
1385*771fe6b9SJerome Glisse 	uint32_t rdp, wdp;
1386*771fe6b9SJerome Glisse 	unsigned count, i, j;
1387*771fe6b9SJerome Glisse 
1388*771fe6b9SJerome Glisse 	radeon_ring_free_size(rdev);
1389*771fe6b9SJerome Glisse 	rdp = RREG32(RADEON_CP_RB_RPTR);
1390*771fe6b9SJerome Glisse 	wdp = RREG32(RADEON_CP_RB_WPTR);
1391*771fe6b9SJerome Glisse 	count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
1392*771fe6b9SJerome Glisse 	seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT));
1393*771fe6b9SJerome Glisse 	seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
1394*771fe6b9SJerome Glisse 	seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
1395*771fe6b9SJerome Glisse 	seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
1396*771fe6b9SJerome Glisse 	seq_printf(m, "%u dwords in ring\n", count);
1397*771fe6b9SJerome Glisse 	for (j = 0; j <= count; j++) {
1398*771fe6b9SJerome Glisse 		i = (rdp + j) & rdev->cp.ptr_mask;
1399*771fe6b9SJerome Glisse 		seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
1400*771fe6b9SJerome Glisse 	}
1401*771fe6b9SJerome Glisse 	return 0;
1402*771fe6b9SJerome Glisse }
1403*771fe6b9SJerome Glisse 
1404*771fe6b9SJerome Glisse 
1405*771fe6b9SJerome Glisse static int r100_debugfs_cp_csq_fifo(struct seq_file *m, void *data)
1406*771fe6b9SJerome Glisse {
1407*771fe6b9SJerome Glisse 	struct drm_info_node *node = (struct drm_info_node *) m->private;
1408*771fe6b9SJerome Glisse 	struct drm_device *dev = node->minor->dev;
1409*771fe6b9SJerome Glisse 	struct radeon_device *rdev = dev->dev_private;
1410*771fe6b9SJerome Glisse 	uint32_t csq_stat, csq2_stat, tmp;
1411*771fe6b9SJerome Glisse 	unsigned r_rptr, r_wptr, ib1_rptr, ib1_wptr, ib2_rptr, ib2_wptr;
1412*771fe6b9SJerome Glisse 	unsigned i;
1413*771fe6b9SJerome Glisse 
1414*771fe6b9SJerome Glisse 	seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT));
1415*771fe6b9SJerome Glisse 	seq_printf(m, "CP_CSQ_MODE 0x%08x\n", RREG32(RADEON_CP_CSQ_MODE));
1416*771fe6b9SJerome Glisse 	csq_stat = RREG32(RADEON_CP_CSQ_STAT);
1417*771fe6b9SJerome Glisse 	csq2_stat = RREG32(RADEON_CP_CSQ2_STAT);
1418*771fe6b9SJerome Glisse 	r_rptr = (csq_stat >> 0) & 0x3ff;
1419*771fe6b9SJerome Glisse 	r_wptr = (csq_stat >> 10) & 0x3ff;
1420*771fe6b9SJerome Glisse 	ib1_rptr = (csq_stat >> 20) & 0x3ff;
1421*771fe6b9SJerome Glisse 	ib1_wptr = (csq2_stat >> 0) & 0x3ff;
1422*771fe6b9SJerome Glisse 	ib2_rptr = (csq2_stat >> 10) & 0x3ff;
1423*771fe6b9SJerome Glisse 	ib2_wptr = (csq2_stat >> 20) & 0x3ff;
1424*771fe6b9SJerome Glisse 	seq_printf(m, "CP_CSQ_STAT 0x%08x\n", csq_stat);
1425*771fe6b9SJerome Glisse 	seq_printf(m, "CP_CSQ2_STAT 0x%08x\n", csq2_stat);
1426*771fe6b9SJerome Glisse 	seq_printf(m, "Ring rptr %u\n", r_rptr);
1427*771fe6b9SJerome Glisse 	seq_printf(m, "Ring wptr %u\n", r_wptr);
1428*771fe6b9SJerome Glisse 	seq_printf(m, "Indirect1 rptr %u\n", ib1_rptr);
1429*771fe6b9SJerome Glisse 	seq_printf(m, "Indirect1 wptr %u\n", ib1_wptr);
1430*771fe6b9SJerome Glisse 	seq_printf(m, "Indirect2 rptr %u\n", ib2_rptr);
1431*771fe6b9SJerome Glisse 	seq_printf(m, "Indirect2 wptr %u\n", ib2_wptr);
1432*771fe6b9SJerome Glisse 	/* FIXME: 0, 128, 640 depends on fifo setup see cp_init_kms
1433*771fe6b9SJerome Glisse 	 * 128 = indirect1_start * 8 & 640 = indirect2_start * 8 */
1434*771fe6b9SJerome Glisse 	seq_printf(m, "Ring fifo:\n");
1435*771fe6b9SJerome Glisse 	for (i = 0; i < 256; i++) {
1436*771fe6b9SJerome Glisse 		WREG32(RADEON_CP_CSQ_ADDR, i << 2);
1437*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CP_CSQ_DATA);
1438*771fe6b9SJerome Glisse 		seq_printf(m, "rfifo[%04d]=0x%08X\n", i, tmp);
1439*771fe6b9SJerome Glisse 	}
1440*771fe6b9SJerome Glisse 	seq_printf(m, "Indirect1 fifo:\n");
1441*771fe6b9SJerome Glisse 	for (i = 256; i <= 512; i++) {
1442*771fe6b9SJerome Glisse 		WREG32(RADEON_CP_CSQ_ADDR, i << 2);
1443*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CP_CSQ_DATA);
1444*771fe6b9SJerome Glisse 		seq_printf(m, "ib1fifo[%04d]=0x%08X\n", i, tmp);
1445*771fe6b9SJerome Glisse 	}
1446*771fe6b9SJerome Glisse 	seq_printf(m, "Indirect2 fifo:\n");
1447*771fe6b9SJerome Glisse 	for (i = 640; i < ib1_wptr; i++) {
1448*771fe6b9SJerome Glisse 		WREG32(RADEON_CP_CSQ_ADDR, i << 2);
1449*771fe6b9SJerome Glisse 		tmp = RREG32(RADEON_CP_CSQ_DATA);
1450*771fe6b9SJerome Glisse 		seq_printf(m, "ib2fifo[%04d]=0x%08X\n", i, tmp);
1451*771fe6b9SJerome Glisse 	}
1452*771fe6b9SJerome Glisse 	return 0;
1453*771fe6b9SJerome Glisse }
1454*771fe6b9SJerome Glisse 
1455*771fe6b9SJerome Glisse static int r100_debugfs_mc_info(struct seq_file *m, void *data)
1456*771fe6b9SJerome Glisse {
1457*771fe6b9SJerome Glisse 	struct drm_info_node *node = (struct drm_info_node *) m->private;
1458*771fe6b9SJerome Glisse 	struct drm_device *dev = node->minor->dev;
1459*771fe6b9SJerome Glisse 	struct radeon_device *rdev = dev->dev_private;
1460*771fe6b9SJerome Glisse 	uint32_t tmp;
1461*771fe6b9SJerome Glisse 
1462*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_CONFIG_MEMSIZE);
1463*771fe6b9SJerome Glisse 	seq_printf(m, "CONFIG_MEMSIZE 0x%08x\n", tmp);
1464*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_MC_FB_LOCATION);
1465*771fe6b9SJerome Glisse 	seq_printf(m, "MC_FB_LOCATION 0x%08x\n", tmp);
1466*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_BUS_CNTL);
1467*771fe6b9SJerome Glisse 	seq_printf(m, "BUS_CNTL 0x%08x\n", tmp);
1468*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_MC_AGP_LOCATION);
1469*771fe6b9SJerome Glisse 	seq_printf(m, "MC_AGP_LOCATION 0x%08x\n", tmp);
1470*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_AGP_BASE);
1471*771fe6b9SJerome Glisse 	seq_printf(m, "AGP_BASE 0x%08x\n", tmp);
1472*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_HOST_PATH_CNTL);
1473*771fe6b9SJerome Glisse 	seq_printf(m, "HOST_PATH_CNTL 0x%08x\n", tmp);
1474*771fe6b9SJerome Glisse 	tmp = RREG32(0x01D0);
1475*771fe6b9SJerome Glisse 	seq_printf(m, "AIC_CTRL 0x%08x\n", tmp);
1476*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_AIC_LO_ADDR);
1477*771fe6b9SJerome Glisse 	seq_printf(m, "AIC_LO_ADDR 0x%08x\n", tmp);
1478*771fe6b9SJerome Glisse 	tmp = RREG32(RADEON_AIC_HI_ADDR);
1479*771fe6b9SJerome Glisse 	seq_printf(m, "AIC_HI_ADDR 0x%08x\n", tmp);
1480*771fe6b9SJerome Glisse 	tmp = RREG32(0x01E4);
1481*771fe6b9SJerome Glisse 	seq_printf(m, "AIC_TLB_ADDR 0x%08x\n", tmp);
1482*771fe6b9SJerome Glisse 	return 0;
1483*771fe6b9SJerome Glisse }
1484*771fe6b9SJerome Glisse 
1485*771fe6b9SJerome Glisse static struct drm_info_list r100_debugfs_rbbm_list[] = {
1486*771fe6b9SJerome Glisse 	{"r100_rbbm_info", r100_debugfs_rbbm_info, 0, NULL},
1487*771fe6b9SJerome Glisse };
1488*771fe6b9SJerome Glisse 
1489*771fe6b9SJerome Glisse static struct drm_info_list r100_debugfs_cp_list[] = {
1490*771fe6b9SJerome Glisse 	{"r100_cp_ring_info", r100_debugfs_cp_ring_info, 0, NULL},
1491*771fe6b9SJerome Glisse 	{"r100_cp_csq_fifo", r100_debugfs_cp_csq_fifo, 0, NULL},
1492*771fe6b9SJerome Glisse };
1493*771fe6b9SJerome Glisse 
1494*771fe6b9SJerome Glisse static struct drm_info_list r100_debugfs_mc_info_list[] = {
1495*771fe6b9SJerome Glisse 	{"r100_mc_info", r100_debugfs_mc_info, 0, NULL},
1496*771fe6b9SJerome Glisse };
1497*771fe6b9SJerome Glisse #endif
1498*771fe6b9SJerome Glisse 
1499*771fe6b9SJerome Glisse int r100_debugfs_rbbm_init(struct radeon_device *rdev)
1500*771fe6b9SJerome Glisse {
1501*771fe6b9SJerome Glisse #if defined(CONFIG_DEBUG_FS)
1502*771fe6b9SJerome Glisse 	return radeon_debugfs_add_files(rdev, r100_debugfs_rbbm_list, 1);
1503*771fe6b9SJerome Glisse #else
1504*771fe6b9SJerome Glisse 	return 0;
1505*771fe6b9SJerome Glisse #endif
1506*771fe6b9SJerome Glisse }
1507*771fe6b9SJerome Glisse 
1508*771fe6b9SJerome Glisse int r100_debugfs_cp_init(struct radeon_device *rdev)
1509*771fe6b9SJerome Glisse {
1510*771fe6b9SJerome Glisse #if defined(CONFIG_DEBUG_FS)
1511*771fe6b9SJerome Glisse 	return radeon_debugfs_add_files(rdev, r100_debugfs_cp_list, 2);
1512*771fe6b9SJerome Glisse #else
1513*771fe6b9SJerome Glisse 	return 0;
1514*771fe6b9SJerome Glisse #endif
1515*771fe6b9SJerome Glisse }
1516*771fe6b9SJerome Glisse 
1517*771fe6b9SJerome Glisse int r100_debugfs_mc_info_init(struct radeon_device *rdev)
1518*771fe6b9SJerome Glisse {
1519*771fe6b9SJerome Glisse #if defined(CONFIG_DEBUG_FS)
1520*771fe6b9SJerome Glisse 	return radeon_debugfs_add_files(rdev, r100_debugfs_mc_info_list, 1);
1521*771fe6b9SJerome Glisse #else
1522*771fe6b9SJerome Glisse 	return 0;
1523*771fe6b9SJerome Glisse #endif
1524*771fe6b9SJerome Glisse }
1525