xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/radeon/cik.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2012 Advanced Micro Devices, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun  * all copies or substantial portions of the Software.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*4882a593Smuzhiyun  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun  * OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * Authors: Alex Deucher
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include <linux/firmware.h>
26*4882a593Smuzhiyun #include <linux/module.h>
27*4882a593Smuzhiyun #include <linux/pci.h>
28*4882a593Smuzhiyun #include <linux/slab.h>
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include <drm/drm_vblank.h>
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #include "atom.h"
33*4882a593Smuzhiyun #include "cik_blit_shaders.h"
34*4882a593Smuzhiyun #include "cikd.h"
35*4882a593Smuzhiyun #include "clearstate_ci.h"
36*4882a593Smuzhiyun #include "radeon.h"
37*4882a593Smuzhiyun #include "radeon_asic.h"
38*4882a593Smuzhiyun #include "radeon_audio.h"
39*4882a593Smuzhiyun #include "radeon_ucode.h"
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #define SH_MEM_CONFIG_GFX_DEFAULT \
42*4882a593Smuzhiyun 	ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED)
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_pfp.bin");
45*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_me.bin");
46*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_ce.bin");
47*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_mec.bin");
48*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_mc.bin");
49*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_mc2.bin");
50*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
51*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
52*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/BONAIRE_smc.bin");
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_pfp.bin");
55*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_me.bin");
56*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_ce.bin");
57*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_mec.bin");
58*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_mc.bin");
59*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_rlc.bin");
60*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_sdma.bin");
61*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_smc.bin");
62*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/bonaire_k_smc.bin");
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_pfp.bin");
65*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_me.bin");
66*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_ce.bin");
67*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_mec.bin");
68*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_mc.bin");
69*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_mc2.bin");
70*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_rlc.bin");
71*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_sdma.bin");
72*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAWAII_smc.bin");
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_pfp.bin");
75*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_me.bin");
76*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_ce.bin");
77*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_mec.bin");
78*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_mc.bin");
79*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_rlc.bin");
80*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_sdma.bin");
81*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_smc.bin");
82*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hawaii_k_smc.bin");
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KAVERI_pfp.bin");
85*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KAVERI_me.bin");
86*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KAVERI_ce.bin");
87*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KAVERI_mec.bin");
88*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KAVERI_rlc.bin");
89*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KAVERI_sdma.bin");
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_pfp.bin");
92*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_me.bin");
93*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_ce.bin");
94*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_mec.bin");
95*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_mec2.bin");
96*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_rlc.bin");
97*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kaveri_sdma.bin");
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KABINI_pfp.bin");
100*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KABINI_me.bin");
101*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KABINI_ce.bin");
102*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KABINI_mec.bin");
103*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KABINI_rlc.bin");
104*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/KABINI_sdma.bin");
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kabini_pfp.bin");
107*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kabini_me.bin");
108*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kabini_ce.bin");
109*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kabini_mec.bin");
110*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kabini_rlc.bin");
111*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/kabini_sdma.bin");
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/MULLINS_pfp.bin");
114*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/MULLINS_me.bin");
115*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/MULLINS_ce.bin");
116*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/MULLINS_mec.bin");
117*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/MULLINS_rlc.bin");
118*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/MULLINS_sdma.bin");
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/mullins_pfp.bin");
121*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/mullins_me.bin");
122*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/mullins_ce.bin");
123*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/mullins_mec.bin");
124*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/mullins_rlc.bin");
125*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/mullins_sdma.bin");
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun extern int r600_ih_ring_alloc(struct radeon_device *rdev);
128*4882a593Smuzhiyun extern void r600_ih_ring_fini(struct radeon_device *rdev);
129*4882a593Smuzhiyun extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
130*4882a593Smuzhiyun extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
131*4882a593Smuzhiyun extern bool evergreen_is_display_hung(struct radeon_device *rdev);
132*4882a593Smuzhiyun extern void sumo_rlc_fini(struct radeon_device *rdev);
133*4882a593Smuzhiyun extern int sumo_rlc_init(struct radeon_device *rdev);
134*4882a593Smuzhiyun extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
135*4882a593Smuzhiyun extern void si_rlc_reset(struct radeon_device *rdev);
136*4882a593Smuzhiyun extern void si_init_uvd_internal_cg(struct radeon_device *rdev);
137*4882a593Smuzhiyun static u32 cik_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
138*4882a593Smuzhiyun extern int cik_sdma_resume(struct radeon_device *rdev);
139*4882a593Smuzhiyun extern void cik_sdma_enable(struct radeon_device *rdev, bool enable);
140*4882a593Smuzhiyun extern void cik_sdma_fini(struct radeon_device *rdev);
141*4882a593Smuzhiyun extern void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable);
142*4882a593Smuzhiyun static void cik_rlc_stop(struct radeon_device *rdev);
143*4882a593Smuzhiyun static void cik_pcie_gen3_enable(struct radeon_device *rdev);
144*4882a593Smuzhiyun static void cik_program_aspm(struct radeon_device *rdev);
145*4882a593Smuzhiyun static void cik_init_pg(struct radeon_device *rdev);
146*4882a593Smuzhiyun static void cik_init_cg(struct radeon_device *rdev);
147*4882a593Smuzhiyun static void cik_fini_pg(struct radeon_device *rdev);
148*4882a593Smuzhiyun static void cik_fini_cg(struct radeon_device *rdev);
149*4882a593Smuzhiyun static void cik_enable_gui_idle_interrupt(struct radeon_device *rdev,
150*4882a593Smuzhiyun 					  bool enable);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /**
153*4882a593Smuzhiyun  * cik_get_allowed_info_register - fetch the register for the info ioctl
154*4882a593Smuzhiyun  *
155*4882a593Smuzhiyun  * @rdev: radeon_device pointer
156*4882a593Smuzhiyun  * @reg: register offset in bytes
157*4882a593Smuzhiyun  * @val: register value
158*4882a593Smuzhiyun  *
159*4882a593Smuzhiyun  * Returns 0 for success or -EINVAL for an invalid register
160*4882a593Smuzhiyun  *
161*4882a593Smuzhiyun  */
cik_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)162*4882a593Smuzhiyun int cik_get_allowed_info_register(struct radeon_device *rdev,
163*4882a593Smuzhiyun 				  u32 reg, u32 *val)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	switch (reg) {
166*4882a593Smuzhiyun 	case GRBM_STATUS:
167*4882a593Smuzhiyun 	case GRBM_STATUS2:
168*4882a593Smuzhiyun 	case GRBM_STATUS_SE0:
169*4882a593Smuzhiyun 	case GRBM_STATUS_SE1:
170*4882a593Smuzhiyun 	case GRBM_STATUS_SE2:
171*4882a593Smuzhiyun 	case GRBM_STATUS_SE3:
172*4882a593Smuzhiyun 	case SRBM_STATUS:
173*4882a593Smuzhiyun 	case SRBM_STATUS2:
174*4882a593Smuzhiyun 	case (SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET):
175*4882a593Smuzhiyun 	case (SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET):
176*4882a593Smuzhiyun 	case UVD_STATUS:
177*4882a593Smuzhiyun 	/* TODO VCE */
178*4882a593Smuzhiyun 		*val = RREG32(reg);
179*4882a593Smuzhiyun 		return 0;
180*4882a593Smuzhiyun 	default:
181*4882a593Smuzhiyun 		return -EINVAL;
182*4882a593Smuzhiyun 	}
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun /*
186*4882a593Smuzhiyun  * Indirect registers accessor
187*4882a593Smuzhiyun  */
cik_didt_rreg(struct radeon_device * rdev,u32 reg)188*4882a593Smuzhiyun u32 cik_didt_rreg(struct radeon_device *rdev, u32 reg)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	unsigned long flags;
191*4882a593Smuzhiyun 	u32 r;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	spin_lock_irqsave(&rdev->didt_idx_lock, flags);
194*4882a593Smuzhiyun 	WREG32(CIK_DIDT_IND_INDEX, (reg));
195*4882a593Smuzhiyun 	r = RREG32(CIK_DIDT_IND_DATA);
196*4882a593Smuzhiyun 	spin_unlock_irqrestore(&rdev->didt_idx_lock, flags);
197*4882a593Smuzhiyun 	return r;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
cik_didt_wreg(struct radeon_device * rdev,u32 reg,u32 v)200*4882a593Smuzhiyun void cik_didt_wreg(struct radeon_device *rdev, u32 reg, u32 v)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	unsigned long flags;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	spin_lock_irqsave(&rdev->didt_idx_lock, flags);
205*4882a593Smuzhiyun 	WREG32(CIK_DIDT_IND_INDEX, (reg));
206*4882a593Smuzhiyun 	WREG32(CIK_DIDT_IND_DATA, (v));
207*4882a593Smuzhiyun 	spin_unlock_irqrestore(&rdev->didt_idx_lock, flags);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun /* get temperature in millidegrees */
ci_get_temp(struct radeon_device * rdev)211*4882a593Smuzhiyun int ci_get_temp(struct radeon_device *rdev)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	u32 temp;
214*4882a593Smuzhiyun 	int actual_temp = 0;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	temp = (RREG32_SMC(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
217*4882a593Smuzhiyun 		CTF_TEMP_SHIFT;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (temp & 0x200)
220*4882a593Smuzhiyun 		actual_temp = 255;
221*4882a593Smuzhiyun 	else
222*4882a593Smuzhiyun 		actual_temp = temp & 0x1ff;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	return actual_temp * 1000;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun /* get temperature in millidegrees */
kv_get_temp(struct radeon_device * rdev)228*4882a593Smuzhiyun int kv_get_temp(struct radeon_device *rdev)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	u32 temp;
231*4882a593Smuzhiyun 	int actual_temp = 0;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	temp = RREG32_SMC(0xC0300E0C);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	if (temp)
236*4882a593Smuzhiyun 		actual_temp = (temp / 8) - 49;
237*4882a593Smuzhiyun 	else
238*4882a593Smuzhiyun 		actual_temp = 0;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	return actual_temp * 1000;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /*
244*4882a593Smuzhiyun  * Indirect registers accessor
245*4882a593Smuzhiyun  */
cik_pciep_rreg(struct radeon_device * rdev,u32 reg)246*4882a593Smuzhiyun u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun 	unsigned long flags;
249*4882a593Smuzhiyun 	u32 r;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	spin_lock_irqsave(&rdev->pciep_idx_lock, flags);
252*4882a593Smuzhiyun 	WREG32(PCIE_INDEX, reg);
253*4882a593Smuzhiyun 	(void)RREG32(PCIE_INDEX);
254*4882a593Smuzhiyun 	r = RREG32(PCIE_DATA);
255*4882a593Smuzhiyun 	spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags);
256*4882a593Smuzhiyun 	return r;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
cik_pciep_wreg(struct radeon_device * rdev,u32 reg,u32 v)259*4882a593Smuzhiyun void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	unsigned long flags;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	spin_lock_irqsave(&rdev->pciep_idx_lock, flags);
264*4882a593Smuzhiyun 	WREG32(PCIE_INDEX, reg);
265*4882a593Smuzhiyun 	(void)RREG32(PCIE_INDEX);
266*4882a593Smuzhiyun 	WREG32(PCIE_DATA, v);
267*4882a593Smuzhiyun 	(void)RREG32(PCIE_DATA);
268*4882a593Smuzhiyun 	spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun static const u32 spectre_rlc_save_restore_register_list[] =
272*4882a593Smuzhiyun {
273*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc12c >> 2),
274*4882a593Smuzhiyun 	0x00000000,
275*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc140 >> 2),
276*4882a593Smuzhiyun 	0x00000000,
277*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc150 >> 2),
278*4882a593Smuzhiyun 	0x00000000,
279*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc15c >> 2),
280*4882a593Smuzhiyun 	0x00000000,
281*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc168 >> 2),
282*4882a593Smuzhiyun 	0x00000000,
283*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc170 >> 2),
284*4882a593Smuzhiyun 	0x00000000,
285*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc178 >> 2),
286*4882a593Smuzhiyun 	0x00000000,
287*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc204 >> 2),
288*4882a593Smuzhiyun 	0x00000000,
289*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2b4 >> 2),
290*4882a593Smuzhiyun 	0x00000000,
291*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2b8 >> 2),
292*4882a593Smuzhiyun 	0x00000000,
293*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2bc >> 2),
294*4882a593Smuzhiyun 	0x00000000,
295*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2c0 >> 2),
296*4882a593Smuzhiyun 	0x00000000,
297*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8228 >> 2),
298*4882a593Smuzhiyun 	0x00000000,
299*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x829c >> 2),
300*4882a593Smuzhiyun 	0x00000000,
301*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x869c >> 2),
302*4882a593Smuzhiyun 	0x00000000,
303*4882a593Smuzhiyun 	(0x0600 << 16) | (0x98f4 >> 2),
304*4882a593Smuzhiyun 	0x00000000,
305*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x98f8 >> 2),
306*4882a593Smuzhiyun 	0x00000000,
307*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9900 >> 2),
308*4882a593Smuzhiyun 	0x00000000,
309*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc260 >> 2),
310*4882a593Smuzhiyun 	0x00000000,
311*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x90e8 >> 2),
312*4882a593Smuzhiyun 	0x00000000,
313*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c000 >> 2),
314*4882a593Smuzhiyun 	0x00000000,
315*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c00c >> 2),
316*4882a593Smuzhiyun 	0x00000000,
317*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c1c >> 2),
318*4882a593Smuzhiyun 	0x00000000,
319*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9700 >> 2),
320*4882a593Smuzhiyun 	0x00000000,
321*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xcd20 >> 2),
322*4882a593Smuzhiyun 	0x00000000,
323*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xcd20 >> 2),
324*4882a593Smuzhiyun 	0x00000000,
325*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xcd20 >> 2),
326*4882a593Smuzhiyun 	0x00000000,
327*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xcd20 >> 2),
328*4882a593Smuzhiyun 	0x00000000,
329*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xcd20 >> 2),
330*4882a593Smuzhiyun 	0x00000000,
331*4882a593Smuzhiyun 	(0x8e00 << 16) | (0xcd20 >> 2),
332*4882a593Smuzhiyun 	0x00000000,
333*4882a593Smuzhiyun 	(0x9e00 << 16) | (0xcd20 >> 2),
334*4882a593Smuzhiyun 	0x00000000,
335*4882a593Smuzhiyun 	(0xae00 << 16) | (0xcd20 >> 2),
336*4882a593Smuzhiyun 	0x00000000,
337*4882a593Smuzhiyun 	(0xbe00 << 16) | (0xcd20 >> 2),
338*4882a593Smuzhiyun 	0x00000000,
339*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x89bc >> 2),
340*4882a593Smuzhiyun 	0x00000000,
341*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8900 >> 2),
342*4882a593Smuzhiyun 	0x00000000,
343*4882a593Smuzhiyun 	0x3,
344*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc130 >> 2),
345*4882a593Smuzhiyun 	0x00000000,
346*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc134 >> 2),
347*4882a593Smuzhiyun 	0x00000000,
348*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc1fc >> 2),
349*4882a593Smuzhiyun 	0x00000000,
350*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc208 >> 2),
351*4882a593Smuzhiyun 	0x00000000,
352*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc264 >> 2),
353*4882a593Smuzhiyun 	0x00000000,
354*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc268 >> 2),
355*4882a593Smuzhiyun 	0x00000000,
356*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc26c >> 2),
357*4882a593Smuzhiyun 	0x00000000,
358*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc270 >> 2),
359*4882a593Smuzhiyun 	0x00000000,
360*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc274 >> 2),
361*4882a593Smuzhiyun 	0x00000000,
362*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc278 >> 2),
363*4882a593Smuzhiyun 	0x00000000,
364*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc27c >> 2),
365*4882a593Smuzhiyun 	0x00000000,
366*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc280 >> 2),
367*4882a593Smuzhiyun 	0x00000000,
368*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc284 >> 2),
369*4882a593Smuzhiyun 	0x00000000,
370*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc288 >> 2),
371*4882a593Smuzhiyun 	0x00000000,
372*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc28c >> 2),
373*4882a593Smuzhiyun 	0x00000000,
374*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc290 >> 2),
375*4882a593Smuzhiyun 	0x00000000,
376*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc294 >> 2),
377*4882a593Smuzhiyun 	0x00000000,
378*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc298 >> 2),
379*4882a593Smuzhiyun 	0x00000000,
380*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc29c >> 2),
381*4882a593Smuzhiyun 	0x00000000,
382*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2a0 >> 2),
383*4882a593Smuzhiyun 	0x00000000,
384*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2a4 >> 2),
385*4882a593Smuzhiyun 	0x00000000,
386*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2a8 >> 2),
387*4882a593Smuzhiyun 	0x00000000,
388*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2ac  >> 2),
389*4882a593Smuzhiyun 	0x00000000,
390*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2b0 >> 2),
391*4882a593Smuzhiyun 	0x00000000,
392*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x301d0 >> 2),
393*4882a593Smuzhiyun 	0x00000000,
394*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30238 >> 2),
395*4882a593Smuzhiyun 	0x00000000,
396*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30250 >> 2),
397*4882a593Smuzhiyun 	0x00000000,
398*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30254 >> 2),
399*4882a593Smuzhiyun 	0x00000000,
400*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30258 >> 2),
401*4882a593Smuzhiyun 	0x00000000,
402*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3025c >> 2),
403*4882a593Smuzhiyun 	0x00000000,
404*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc900 >> 2),
405*4882a593Smuzhiyun 	0x00000000,
406*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc900 >> 2),
407*4882a593Smuzhiyun 	0x00000000,
408*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc900 >> 2),
409*4882a593Smuzhiyun 	0x00000000,
410*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc900 >> 2),
411*4882a593Smuzhiyun 	0x00000000,
412*4882a593Smuzhiyun 	(0x8e00 << 16) | (0xc900 >> 2),
413*4882a593Smuzhiyun 	0x00000000,
414*4882a593Smuzhiyun 	(0x9e00 << 16) | (0xc900 >> 2),
415*4882a593Smuzhiyun 	0x00000000,
416*4882a593Smuzhiyun 	(0xae00 << 16) | (0xc900 >> 2),
417*4882a593Smuzhiyun 	0x00000000,
418*4882a593Smuzhiyun 	(0xbe00 << 16) | (0xc900 >> 2),
419*4882a593Smuzhiyun 	0x00000000,
420*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc904 >> 2),
421*4882a593Smuzhiyun 	0x00000000,
422*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc904 >> 2),
423*4882a593Smuzhiyun 	0x00000000,
424*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc904 >> 2),
425*4882a593Smuzhiyun 	0x00000000,
426*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc904 >> 2),
427*4882a593Smuzhiyun 	0x00000000,
428*4882a593Smuzhiyun 	(0x8e00 << 16) | (0xc904 >> 2),
429*4882a593Smuzhiyun 	0x00000000,
430*4882a593Smuzhiyun 	(0x9e00 << 16) | (0xc904 >> 2),
431*4882a593Smuzhiyun 	0x00000000,
432*4882a593Smuzhiyun 	(0xae00 << 16) | (0xc904 >> 2),
433*4882a593Smuzhiyun 	0x00000000,
434*4882a593Smuzhiyun 	(0xbe00 << 16) | (0xc904 >> 2),
435*4882a593Smuzhiyun 	0x00000000,
436*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc908 >> 2),
437*4882a593Smuzhiyun 	0x00000000,
438*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc908 >> 2),
439*4882a593Smuzhiyun 	0x00000000,
440*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc908 >> 2),
441*4882a593Smuzhiyun 	0x00000000,
442*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc908 >> 2),
443*4882a593Smuzhiyun 	0x00000000,
444*4882a593Smuzhiyun 	(0x8e00 << 16) | (0xc908 >> 2),
445*4882a593Smuzhiyun 	0x00000000,
446*4882a593Smuzhiyun 	(0x9e00 << 16) | (0xc908 >> 2),
447*4882a593Smuzhiyun 	0x00000000,
448*4882a593Smuzhiyun 	(0xae00 << 16) | (0xc908 >> 2),
449*4882a593Smuzhiyun 	0x00000000,
450*4882a593Smuzhiyun 	(0xbe00 << 16) | (0xc908 >> 2),
451*4882a593Smuzhiyun 	0x00000000,
452*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc90c >> 2),
453*4882a593Smuzhiyun 	0x00000000,
454*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc90c >> 2),
455*4882a593Smuzhiyun 	0x00000000,
456*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc90c >> 2),
457*4882a593Smuzhiyun 	0x00000000,
458*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc90c >> 2),
459*4882a593Smuzhiyun 	0x00000000,
460*4882a593Smuzhiyun 	(0x8e00 << 16) | (0xc90c >> 2),
461*4882a593Smuzhiyun 	0x00000000,
462*4882a593Smuzhiyun 	(0x9e00 << 16) | (0xc90c >> 2),
463*4882a593Smuzhiyun 	0x00000000,
464*4882a593Smuzhiyun 	(0xae00 << 16) | (0xc90c >> 2),
465*4882a593Smuzhiyun 	0x00000000,
466*4882a593Smuzhiyun 	(0xbe00 << 16) | (0xc90c >> 2),
467*4882a593Smuzhiyun 	0x00000000,
468*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc910 >> 2),
469*4882a593Smuzhiyun 	0x00000000,
470*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc910 >> 2),
471*4882a593Smuzhiyun 	0x00000000,
472*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc910 >> 2),
473*4882a593Smuzhiyun 	0x00000000,
474*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc910 >> 2),
475*4882a593Smuzhiyun 	0x00000000,
476*4882a593Smuzhiyun 	(0x8e00 << 16) | (0xc910 >> 2),
477*4882a593Smuzhiyun 	0x00000000,
478*4882a593Smuzhiyun 	(0x9e00 << 16) | (0xc910 >> 2),
479*4882a593Smuzhiyun 	0x00000000,
480*4882a593Smuzhiyun 	(0xae00 << 16) | (0xc910 >> 2),
481*4882a593Smuzhiyun 	0x00000000,
482*4882a593Smuzhiyun 	(0xbe00 << 16) | (0xc910 >> 2),
483*4882a593Smuzhiyun 	0x00000000,
484*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc99c >> 2),
485*4882a593Smuzhiyun 	0x00000000,
486*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9834 >> 2),
487*4882a593Smuzhiyun 	0x00000000,
488*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f00 >> 2),
489*4882a593Smuzhiyun 	0x00000000,
490*4882a593Smuzhiyun 	(0x0001 << 16) | (0x30f00 >> 2),
491*4882a593Smuzhiyun 	0x00000000,
492*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f04 >> 2),
493*4882a593Smuzhiyun 	0x00000000,
494*4882a593Smuzhiyun 	(0x0001 << 16) | (0x30f04 >> 2),
495*4882a593Smuzhiyun 	0x00000000,
496*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f08 >> 2),
497*4882a593Smuzhiyun 	0x00000000,
498*4882a593Smuzhiyun 	(0x0001 << 16) | (0x30f08 >> 2),
499*4882a593Smuzhiyun 	0x00000000,
500*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f0c >> 2),
501*4882a593Smuzhiyun 	0x00000000,
502*4882a593Smuzhiyun 	(0x0001 << 16) | (0x30f0c >> 2),
503*4882a593Smuzhiyun 	0x00000000,
504*4882a593Smuzhiyun 	(0x0600 << 16) | (0x9b7c >> 2),
505*4882a593Smuzhiyun 	0x00000000,
506*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8a14 >> 2),
507*4882a593Smuzhiyun 	0x00000000,
508*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8a18 >> 2),
509*4882a593Smuzhiyun 	0x00000000,
510*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a00 >> 2),
511*4882a593Smuzhiyun 	0x00000000,
512*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8bf0 >> 2),
513*4882a593Smuzhiyun 	0x00000000,
514*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8bcc >> 2),
515*4882a593Smuzhiyun 	0x00000000,
516*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8b24 >> 2),
517*4882a593Smuzhiyun 	0x00000000,
518*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30a04 >> 2),
519*4882a593Smuzhiyun 	0x00000000,
520*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a10 >> 2),
521*4882a593Smuzhiyun 	0x00000000,
522*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a14 >> 2),
523*4882a593Smuzhiyun 	0x00000000,
524*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a18 >> 2),
525*4882a593Smuzhiyun 	0x00000000,
526*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a2c >> 2),
527*4882a593Smuzhiyun 	0x00000000,
528*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc700 >> 2),
529*4882a593Smuzhiyun 	0x00000000,
530*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc704 >> 2),
531*4882a593Smuzhiyun 	0x00000000,
532*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc708 >> 2),
533*4882a593Smuzhiyun 	0x00000000,
534*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc768 >> 2),
535*4882a593Smuzhiyun 	0x00000000,
536*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc770 >> 2),
537*4882a593Smuzhiyun 	0x00000000,
538*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc774 >> 2),
539*4882a593Smuzhiyun 	0x00000000,
540*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc778 >> 2),
541*4882a593Smuzhiyun 	0x00000000,
542*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc77c >> 2),
543*4882a593Smuzhiyun 	0x00000000,
544*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc780 >> 2),
545*4882a593Smuzhiyun 	0x00000000,
546*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc784 >> 2),
547*4882a593Smuzhiyun 	0x00000000,
548*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc788 >> 2),
549*4882a593Smuzhiyun 	0x00000000,
550*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc78c >> 2),
551*4882a593Smuzhiyun 	0x00000000,
552*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc798 >> 2),
553*4882a593Smuzhiyun 	0x00000000,
554*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc79c >> 2),
555*4882a593Smuzhiyun 	0x00000000,
556*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc7a0 >> 2),
557*4882a593Smuzhiyun 	0x00000000,
558*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc7a4 >> 2),
559*4882a593Smuzhiyun 	0x00000000,
560*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc7a8 >> 2),
561*4882a593Smuzhiyun 	0x00000000,
562*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc7ac >> 2),
563*4882a593Smuzhiyun 	0x00000000,
564*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc7b0 >> 2),
565*4882a593Smuzhiyun 	0x00000000,
566*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc7b4 >> 2),
567*4882a593Smuzhiyun 	0x00000000,
568*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9100 >> 2),
569*4882a593Smuzhiyun 	0x00000000,
570*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c010 >> 2),
571*4882a593Smuzhiyun 	0x00000000,
572*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92a8 >> 2),
573*4882a593Smuzhiyun 	0x00000000,
574*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92ac >> 2),
575*4882a593Smuzhiyun 	0x00000000,
576*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92b4 >> 2),
577*4882a593Smuzhiyun 	0x00000000,
578*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92b8 >> 2),
579*4882a593Smuzhiyun 	0x00000000,
580*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92bc >> 2),
581*4882a593Smuzhiyun 	0x00000000,
582*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92c0 >> 2),
583*4882a593Smuzhiyun 	0x00000000,
584*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92c4 >> 2),
585*4882a593Smuzhiyun 	0x00000000,
586*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92c8 >> 2),
587*4882a593Smuzhiyun 	0x00000000,
588*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92cc >> 2),
589*4882a593Smuzhiyun 	0x00000000,
590*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x92d0 >> 2),
591*4882a593Smuzhiyun 	0x00000000,
592*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c00 >> 2),
593*4882a593Smuzhiyun 	0x00000000,
594*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c04 >> 2),
595*4882a593Smuzhiyun 	0x00000000,
596*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c20 >> 2),
597*4882a593Smuzhiyun 	0x00000000,
598*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c38 >> 2),
599*4882a593Smuzhiyun 	0x00000000,
600*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c3c >> 2),
601*4882a593Smuzhiyun 	0x00000000,
602*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xae00 >> 2),
603*4882a593Smuzhiyun 	0x00000000,
604*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9604 >> 2),
605*4882a593Smuzhiyun 	0x00000000,
606*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac08 >> 2),
607*4882a593Smuzhiyun 	0x00000000,
608*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac0c >> 2),
609*4882a593Smuzhiyun 	0x00000000,
610*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac10 >> 2),
611*4882a593Smuzhiyun 	0x00000000,
612*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac14 >> 2),
613*4882a593Smuzhiyun 	0x00000000,
614*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac58 >> 2),
615*4882a593Smuzhiyun 	0x00000000,
616*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac68 >> 2),
617*4882a593Smuzhiyun 	0x00000000,
618*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac6c >> 2),
619*4882a593Smuzhiyun 	0x00000000,
620*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac70 >> 2),
621*4882a593Smuzhiyun 	0x00000000,
622*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac74 >> 2),
623*4882a593Smuzhiyun 	0x00000000,
624*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac78 >> 2),
625*4882a593Smuzhiyun 	0x00000000,
626*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac7c >> 2),
627*4882a593Smuzhiyun 	0x00000000,
628*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac80 >> 2),
629*4882a593Smuzhiyun 	0x00000000,
630*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac84 >> 2),
631*4882a593Smuzhiyun 	0x00000000,
632*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac88 >> 2),
633*4882a593Smuzhiyun 	0x00000000,
634*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac8c >> 2),
635*4882a593Smuzhiyun 	0x00000000,
636*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x970c >> 2),
637*4882a593Smuzhiyun 	0x00000000,
638*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9714 >> 2),
639*4882a593Smuzhiyun 	0x00000000,
640*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9718 >> 2),
641*4882a593Smuzhiyun 	0x00000000,
642*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x971c >> 2),
643*4882a593Smuzhiyun 	0x00000000,
644*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x31068 >> 2),
645*4882a593Smuzhiyun 	0x00000000,
646*4882a593Smuzhiyun 	(0x4e00 << 16) | (0x31068 >> 2),
647*4882a593Smuzhiyun 	0x00000000,
648*4882a593Smuzhiyun 	(0x5e00 << 16) | (0x31068 >> 2),
649*4882a593Smuzhiyun 	0x00000000,
650*4882a593Smuzhiyun 	(0x6e00 << 16) | (0x31068 >> 2),
651*4882a593Smuzhiyun 	0x00000000,
652*4882a593Smuzhiyun 	(0x7e00 << 16) | (0x31068 >> 2),
653*4882a593Smuzhiyun 	0x00000000,
654*4882a593Smuzhiyun 	(0x8e00 << 16) | (0x31068 >> 2),
655*4882a593Smuzhiyun 	0x00000000,
656*4882a593Smuzhiyun 	(0x9e00 << 16) | (0x31068 >> 2),
657*4882a593Smuzhiyun 	0x00000000,
658*4882a593Smuzhiyun 	(0xae00 << 16) | (0x31068 >> 2),
659*4882a593Smuzhiyun 	0x00000000,
660*4882a593Smuzhiyun 	(0xbe00 << 16) | (0x31068 >> 2),
661*4882a593Smuzhiyun 	0x00000000,
662*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xcd10 >> 2),
663*4882a593Smuzhiyun 	0x00000000,
664*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xcd14 >> 2),
665*4882a593Smuzhiyun 	0x00000000,
666*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88b0 >> 2),
667*4882a593Smuzhiyun 	0x00000000,
668*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88b4 >> 2),
669*4882a593Smuzhiyun 	0x00000000,
670*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88b8 >> 2),
671*4882a593Smuzhiyun 	0x00000000,
672*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88bc >> 2),
673*4882a593Smuzhiyun 	0x00000000,
674*4882a593Smuzhiyun 	(0x0400 << 16) | (0x89c0 >> 2),
675*4882a593Smuzhiyun 	0x00000000,
676*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88c4 >> 2),
677*4882a593Smuzhiyun 	0x00000000,
678*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88c8 >> 2),
679*4882a593Smuzhiyun 	0x00000000,
680*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88d0 >> 2),
681*4882a593Smuzhiyun 	0x00000000,
682*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88d4 >> 2),
683*4882a593Smuzhiyun 	0x00000000,
684*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88d8 >> 2),
685*4882a593Smuzhiyun 	0x00000000,
686*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8980 >> 2),
687*4882a593Smuzhiyun 	0x00000000,
688*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30938 >> 2),
689*4882a593Smuzhiyun 	0x00000000,
690*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3093c >> 2),
691*4882a593Smuzhiyun 	0x00000000,
692*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30940 >> 2),
693*4882a593Smuzhiyun 	0x00000000,
694*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x89a0 >> 2),
695*4882a593Smuzhiyun 	0x00000000,
696*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30900 >> 2),
697*4882a593Smuzhiyun 	0x00000000,
698*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30904 >> 2),
699*4882a593Smuzhiyun 	0x00000000,
700*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x89b4 >> 2),
701*4882a593Smuzhiyun 	0x00000000,
702*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c210 >> 2),
703*4882a593Smuzhiyun 	0x00000000,
704*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c214 >> 2),
705*4882a593Smuzhiyun 	0x00000000,
706*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c218 >> 2),
707*4882a593Smuzhiyun 	0x00000000,
708*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8904 >> 2),
709*4882a593Smuzhiyun 	0x00000000,
710*4882a593Smuzhiyun 	0x5,
711*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c28 >> 2),
712*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c2c >> 2),
713*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c30 >> 2),
714*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c34 >> 2),
715*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9600 >> 2),
716*4882a593Smuzhiyun };
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun static const u32 kalindi_rlc_save_restore_register_list[] =
719*4882a593Smuzhiyun {
720*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc12c >> 2),
721*4882a593Smuzhiyun 	0x00000000,
722*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc140 >> 2),
723*4882a593Smuzhiyun 	0x00000000,
724*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc150 >> 2),
725*4882a593Smuzhiyun 	0x00000000,
726*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc15c >> 2),
727*4882a593Smuzhiyun 	0x00000000,
728*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc168 >> 2),
729*4882a593Smuzhiyun 	0x00000000,
730*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc170 >> 2),
731*4882a593Smuzhiyun 	0x00000000,
732*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc204 >> 2),
733*4882a593Smuzhiyun 	0x00000000,
734*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2b4 >> 2),
735*4882a593Smuzhiyun 	0x00000000,
736*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2b8 >> 2),
737*4882a593Smuzhiyun 	0x00000000,
738*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2bc >> 2),
739*4882a593Smuzhiyun 	0x00000000,
740*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2c0 >> 2),
741*4882a593Smuzhiyun 	0x00000000,
742*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8228 >> 2),
743*4882a593Smuzhiyun 	0x00000000,
744*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x829c >> 2),
745*4882a593Smuzhiyun 	0x00000000,
746*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x869c >> 2),
747*4882a593Smuzhiyun 	0x00000000,
748*4882a593Smuzhiyun 	(0x0600 << 16) | (0x98f4 >> 2),
749*4882a593Smuzhiyun 	0x00000000,
750*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x98f8 >> 2),
751*4882a593Smuzhiyun 	0x00000000,
752*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9900 >> 2),
753*4882a593Smuzhiyun 	0x00000000,
754*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc260 >> 2),
755*4882a593Smuzhiyun 	0x00000000,
756*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x90e8 >> 2),
757*4882a593Smuzhiyun 	0x00000000,
758*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c000 >> 2),
759*4882a593Smuzhiyun 	0x00000000,
760*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c00c >> 2),
761*4882a593Smuzhiyun 	0x00000000,
762*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c1c >> 2),
763*4882a593Smuzhiyun 	0x00000000,
764*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9700 >> 2),
765*4882a593Smuzhiyun 	0x00000000,
766*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xcd20 >> 2),
767*4882a593Smuzhiyun 	0x00000000,
768*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xcd20 >> 2),
769*4882a593Smuzhiyun 	0x00000000,
770*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xcd20 >> 2),
771*4882a593Smuzhiyun 	0x00000000,
772*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xcd20 >> 2),
773*4882a593Smuzhiyun 	0x00000000,
774*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xcd20 >> 2),
775*4882a593Smuzhiyun 	0x00000000,
776*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x89bc >> 2),
777*4882a593Smuzhiyun 	0x00000000,
778*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8900 >> 2),
779*4882a593Smuzhiyun 	0x00000000,
780*4882a593Smuzhiyun 	0x3,
781*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc130 >> 2),
782*4882a593Smuzhiyun 	0x00000000,
783*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc134 >> 2),
784*4882a593Smuzhiyun 	0x00000000,
785*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc1fc >> 2),
786*4882a593Smuzhiyun 	0x00000000,
787*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc208 >> 2),
788*4882a593Smuzhiyun 	0x00000000,
789*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc264 >> 2),
790*4882a593Smuzhiyun 	0x00000000,
791*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc268 >> 2),
792*4882a593Smuzhiyun 	0x00000000,
793*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc26c >> 2),
794*4882a593Smuzhiyun 	0x00000000,
795*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc270 >> 2),
796*4882a593Smuzhiyun 	0x00000000,
797*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc274 >> 2),
798*4882a593Smuzhiyun 	0x00000000,
799*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc28c >> 2),
800*4882a593Smuzhiyun 	0x00000000,
801*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc290 >> 2),
802*4882a593Smuzhiyun 	0x00000000,
803*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc294 >> 2),
804*4882a593Smuzhiyun 	0x00000000,
805*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc298 >> 2),
806*4882a593Smuzhiyun 	0x00000000,
807*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2a0 >> 2),
808*4882a593Smuzhiyun 	0x00000000,
809*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2a4 >> 2),
810*4882a593Smuzhiyun 	0x00000000,
811*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2a8 >> 2),
812*4882a593Smuzhiyun 	0x00000000,
813*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc2ac >> 2),
814*4882a593Smuzhiyun 	0x00000000,
815*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x301d0 >> 2),
816*4882a593Smuzhiyun 	0x00000000,
817*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30238 >> 2),
818*4882a593Smuzhiyun 	0x00000000,
819*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30250 >> 2),
820*4882a593Smuzhiyun 	0x00000000,
821*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30254 >> 2),
822*4882a593Smuzhiyun 	0x00000000,
823*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30258 >> 2),
824*4882a593Smuzhiyun 	0x00000000,
825*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3025c >> 2),
826*4882a593Smuzhiyun 	0x00000000,
827*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc900 >> 2),
828*4882a593Smuzhiyun 	0x00000000,
829*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc900 >> 2),
830*4882a593Smuzhiyun 	0x00000000,
831*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc900 >> 2),
832*4882a593Smuzhiyun 	0x00000000,
833*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc900 >> 2),
834*4882a593Smuzhiyun 	0x00000000,
835*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc904 >> 2),
836*4882a593Smuzhiyun 	0x00000000,
837*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc904 >> 2),
838*4882a593Smuzhiyun 	0x00000000,
839*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc904 >> 2),
840*4882a593Smuzhiyun 	0x00000000,
841*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc904 >> 2),
842*4882a593Smuzhiyun 	0x00000000,
843*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc908 >> 2),
844*4882a593Smuzhiyun 	0x00000000,
845*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc908 >> 2),
846*4882a593Smuzhiyun 	0x00000000,
847*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc908 >> 2),
848*4882a593Smuzhiyun 	0x00000000,
849*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc908 >> 2),
850*4882a593Smuzhiyun 	0x00000000,
851*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc90c >> 2),
852*4882a593Smuzhiyun 	0x00000000,
853*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc90c >> 2),
854*4882a593Smuzhiyun 	0x00000000,
855*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc90c >> 2),
856*4882a593Smuzhiyun 	0x00000000,
857*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc90c >> 2),
858*4882a593Smuzhiyun 	0x00000000,
859*4882a593Smuzhiyun 	(0x4e00 << 16) | (0xc910 >> 2),
860*4882a593Smuzhiyun 	0x00000000,
861*4882a593Smuzhiyun 	(0x5e00 << 16) | (0xc910 >> 2),
862*4882a593Smuzhiyun 	0x00000000,
863*4882a593Smuzhiyun 	(0x6e00 << 16) | (0xc910 >> 2),
864*4882a593Smuzhiyun 	0x00000000,
865*4882a593Smuzhiyun 	(0x7e00 << 16) | (0xc910 >> 2),
866*4882a593Smuzhiyun 	0x00000000,
867*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc99c >> 2),
868*4882a593Smuzhiyun 	0x00000000,
869*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9834 >> 2),
870*4882a593Smuzhiyun 	0x00000000,
871*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f00 >> 2),
872*4882a593Smuzhiyun 	0x00000000,
873*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f04 >> 2),
874*4882a593Smuzhiyun 	0x00000000,
875*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f08 >> 2),
876*4882a593Smuzhiyun 	0x00000000,
877*4882a593Smuzhiyun 	(0x0000 << 16) | (0x30f0c >> 2),
878*4882a593Smuzhiyun 	0x00000000,
879*4882a593Smuzhiyun 	(0x0600 << 16) | (0x9b7c >> 2),
880*4882a593Smuzhiyun 	0x00000000,
881*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8a14 >> 2),
882*4882a593Smuzhiyun 	0x00000000,
883*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8a18 >> 2),
884*4882a593Smuzhiyun 	0x00000000,
885*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a00 >> 2),
886*4882a593Smuzhiyun 	0x00000000,
887*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8bf0 >> 2),
888*4882a593Smuzhiyun 	0x00000000,
889*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8bcc >> 2),
890*4882a593Smuzhiyun 	0x00000000,
891*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8b24 >> 2),
892*4882a593Smuzhiyun 	0x00000000,
893*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30a04 >> 2),
894*4882a593Smuzhiyun 	0x00000000,
895*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a10 >> 2),
896*4882a593Smuzhiyun 	0x00000000,
897*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a14 >> 2),
898*4882a593Smuzhiyun 	0x00000000,
899*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a18 >> 2),
900*4882a593Smuzhiyun 	0x00000000,
901*4882a593Smuzhiyun 	(0x0600 << 16) | (0x30a2c >> 2),
902*4882a593Smuzhiyun 	0x00000000,
903*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc700 >> 2),
904*4882a593Smuzhiyun 	0x00000000,
905*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc704 >> 2),
906*4882a593Smuzhiyun 	0x00000000,
907*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc708 >> 2),
908*4882a593Smuzhiyun 	0x00000000,
909*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xc768 >> 2),
910*4882a593Smuzhiyun 	0x00000000,
911*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc770 >> 2),
912*4882a593Smuzhiyun 	0x00000000,
913*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc774 >> 2),
914*4882a593Smuzhiyun 	0x00000000,
915*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc798 >> 2),
916*4882a593Smuzhiyun 	0x00000000,
917*4882a593Smuzhiyun 	(0x0400 << 16) | (0xc79c >> 2),
918*4882a593Smuzhiyun 	0x00000000,
919*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9100 >> 2),
920*4882a593Smuzhiyun 	0x00000000,
921*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c010 >> 2),
922*4882a593Smuzhiyun 	0x00000000,
923*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c00 >> 2),
924*4882a593Smuzhiyun 	0x00000000,
925*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c04 >> 2),
926*4882a593Smuzhiyun 	0x00000000,
927*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c20 >> 2),
928*4882a593Smuzhiyun 	0x00000000,
929*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c38 >> 2),
930*4882a593Smuzhiyun 	0x00000000,
931*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c3c >> 2),
932*4882a593Smuzhiyun 	0x00000000,
933*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xae00 >> 2),
934*4882a593Smuzhiyun 	0x00000000,
935*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9604 >> 2),
936*4882a593Smuzhiyun 	0x00000000,
937*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac08 >> 2),
938*4882a593Smuzhiyun 	0x00000000,
939*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac0c >> 2),
940*4882a593Smuzhiyun 	0x00000000,
941*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac10 >> 2),
942*4882a593Smuzhiyun 	0x00000000,
943*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac14 >> 2),
944*4882a593Smuzhiyun 	0x00000000,
945*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac58 >> 2),
946*4882a593Smuzhiyun 	0x00000000,
947*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac68 >> 2),
948*4882a593Smuzhiyun 	0x00000000,
949*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac6c >> 2),
950*4882a593Smuzhiyun 	0x00000000,
951*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac70 >> 2),
952*4882a593Smuzhiyun 	0x00000000,
953*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac74 >> 2),
954*4882a593Smuzhiyun 	0x00000000,
955*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac78 >> 2),
956*4882a593Smuzhiyun 	0x00000000,
957*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac7c >> 2),
958*4882a593Smuzhiyun 	0x00000000,
959*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac80 >> 2),
960*4882a593Smuzhiyun 	0x00000000,
961*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac84 >> 2),
962*4882a593Smuzhiyun 	0x00000000,
963*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac88 >> 2),
964*4882a593Smuzhiyun 	0x00000000,
965*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xac8c >> 2),
966*4882a593Smuzhiyun 	0x00000000,
967*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x970c >> 2),
968*4882a593Smuzhiyun 	0x00000000,
969*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9714 >> 2),
970*4882a593Smuzhiyun 	0x00000000,
971*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9718 >> 2),
972*4882a593Smuzhiyun 	0x00000000,
973*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x971c >> 2),
974*4882a593Smuzhiyun 	0x00000000,
975*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x31068 >> 2),
976*4882a593Smuzhiyun 	0x00000000,
977*4882a593Smuzhiyun 	(0x4e00 << 16) | (0x31068 >> 2),
978*4882a593Smuzhiyun 	0x00000000,
979*4882a593Smuzhiyun 	(0x5e00 << 16) | (0x31068 >> 2),
980*4882a593Smuzhiyun 	0x00000000,
981*4882a593Smuzhiyun 	(0x6e00 << 16) | (0x31068 >> 2),
982*4882a593Smuzhiyun 	0x00000000,
983*4882a593Smuzhiyun 	(0x7e00 << 16) | (0x31068 >> 2),
984*4882a593Smuzhiyun 	0x00000000,
985*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xcd10 >> 2),
986*4882a593Smuzhiyun 	0x00000000,
987*4882a593Smuzhiyun 	(0x0e00 << 16) | (0xcd14 >> 2),
988*4882a593Smuzhiyun 	0x00000000,
989*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88b0 >> 2),
990*4882a593Smuzhiyun 	0x00000000,
991*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88b4 >> 2),
992*4882a593Smuzhiyun 	0x00000000,
993*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88b8 >> 2),
994*4882a593Smuzhiyun 	0x00000000,
995*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88bc >> 2),
996*4882a593Smuzhiyun 	0x00000000,
997*4882a593Smuzhiyun 	(0x0400 << 16) | (0x89c0 >> 2),
998*4882a593Smuzhiyun 	0x00000000,
999*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88c4 >> 2),
1000*4882a593Smuzhiyun 	0x00000000,
1001*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88c8 >> 2),
1002*4882a593Smuzhiyun 	0x00000000,
1003*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88d0 >> 2),
1004*4882a593Smuzhiyun 	0x00000000,
1005*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88d4 >> 2),
1006*4882a593Smuzhiyun 	0x00000000,
1007*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x88d8 >> 2),
1008*4882a593Smuzhiyun 	0x00000000,
1009*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8980 >> 2),
1010*4882a593Smuzhiyun 	0x00000000,
1011*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30938 >> 2),
1012*4882a593Smuzhiyun 	0x00000000,
1013*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3093c >> 2),
1014*4882a593Smuzhiyun 	0x00000000,
1015*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30940 >> 2),
1016*4882a593Smuzhiyun 	0x00000000,
1017*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x89a0 >> 2),
1018*4882a593Smuzhiyun 	0x00000000,
1019*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30900 >> 2),
1020*4882a593Smuzhiyun 	0x00000000,
1021*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x30904 >> 2),
1022*4882a593Smuzhiyun 	0x00000000,
1023*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x89b4 >> 2),
1024*4882a593Smuzhiyun 	0x00000000,
1025*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3e1fc >> 2),
1026*4882a593Smuzhiyun 	0x00000000,
1027*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c210 >> 2),
1028*4882a593Smuzhiyun 	0x00000000,
1029*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c214 >> 2),
1030*4882a593Smuzhiyun 	0x00000000,
1031*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x3c218 >> 2),
1032*4882a593Smuzhiyun 	0x00000000,
1033*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8904 >> 2),
1034*4882a593Smuzhiyun 	0x00000000,
1035*4882a593Smuzhiyun 	0x5,
1036*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c28 >> 2),
1037*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c2c >> 2),
1038*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c30 >> 2),
1039*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x8c34 >> 2),
1040*4882a593Smuzhiyun 	(0x0e00 << 16) | (0x9600 >> 2),
1041*4882a593Smuzhiyun };
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun static const u32 bonaire_golden_spm_registers[] =
1044*4882a593Smuzhiyun {
1045*4882a593Smuzhiyun 	0x30800, 0xe0ffffff, 0xe0000000
1046*4882a593Smuzhiyun };
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun static const u32 bonaire_golden_common_registers[] =
1049*4882a593Smuzhiyun {
1050*4882a593Smuzhiyun 	0xc770, 0xffffffff, 0x00000800,
1051*4882a593Smuzhiyun 	0xc774, 0xffffffff, 0x00000800,
1052*4882a593Smuzhiyun 	0xc798, 0xffffffff, 0x00007fbf,
1053*4882a593Smuzhiyun 	0xc79c, 0xffffffff, 0x00007faf
1054*4882a593Smuzhiyun };
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun static const u32 bonaire_golden_registers[] =
1057*4882a593Smuzhiyun {
1058*4882a593Smuzhiyun 	0x3354, 0x00000333, 0x00000333,
1059*4882a593Smuzhiyun 	0x3350, 0x000c0fc0, 0x00040200,
1060*4882a593Smuzhiyun 	0x9a10, 0x00010000, 0x00058208,
1061*4882a593Smuzhiyun 	0x3c000, 0xffff1fff, 0x00140000,
1062*4882a593Smuzhiyun 	0x3c200, 0xfdfc0fff, 0x00000100,
1063*4882a593Smuzhiyun 	0x3c234, 0x40000000, 0x40000200,
1064*4882a593Smuzhiyun 	0x9830, 0xffffffff, 0x00000000,
1065*4882a593Smuzhiyun 	0x9834, 0xf00fffff, 0x00000400,
1066*4882a593Smuzhiyun 	0x9838, 0x0002021c, 0x00020200,
1067*4882a593Smuzhiyun 	0xc78, 0x00000080, 0x00000000,
1068*4882a593Smuzhiyun 	0x5bb0, 0x000000f0, 0x00000070,
1069*4882a593Smuzhiyun 	0x5bc0, 0xf0311fff, 0x80300000,
1070*4882a593Smuzhiyun 	0x98f8, 0x73773777, 0x12010001,
1071*4882a593Smuzhiyun 	0x350c, 0x00810000, 0x408af000,
1072*4882a593Smuzhiyun 	0x7030, 0x31000111, 0x00000011,
1073*4882a593Smuzhiyun 	0x2f48, 0x73773777, 0x12010001,
1074*4882a593Smuzhiyun 	0x220c, 0x00007fb6, 0x0021a1b1,
1075*4882a593Smuzhiyun 	0x2210, 0x00007fb6, 0x002021b1,
1076*4882a593Smuzhiyun 	0x2180, 0x00007fb6, 0x00002191,
1077*4882a593Smuzhiyun 	0x2218, 0x00007fb6, 0x002121b1,
1078*4882a593Smuzhiyun 	0x221c, 0x00007fb6, 0x002021b1,
1079*4882a593Smuzhiyun 	0x21dc, 0x00007fb6, 0x00002191,
1080*4882a593Smuzhiyun 	0x21e0, 0x00007fb6, 0x00002191,
1081*4882a593Smuzhiyun 	0x3628, 0x0000003f, 0x0000000a,
1082*4882a593Smuzhiyun 	0x362c, 0x0000003f, 0x0000000a,
1083*4882a593Smuzhiyun 	0x2ae4, 0x00073ffe, 0x000022a2,
1084*4882a593Smuzhiyun 	0x240c, 0x000007ff, 0x00000000,
1085*4882a593Smuzhiyun 	0x8a14, 0xf000003f, 0x00000007,
1086*4882a593Smuzhiyun 	0x8bf0, 0x00002001, 0x00000001,
1087*4882a593Smuzhiyun 	0x8b24, 0xffffffff, 0x00ffffff,
1088*4882a593Smuzhiyun 	0x30a04, 0x0000ff0f, 0x00000000,
1089*4882a593Smuzhiyun 	0x28a4c, 0x07ffffff, 0x06000000,
1090*4882a593Smuzhiyun 	0x4d8, 0x00000fff, 0x00000100,
1091*4882a593Smuzhiyun 	0x3e78, 0x00000001, 0x00000002,
1092*4882a593Smuzhiyun 	0x9100, 0x03000000, 0x0362c688,
1093*4882a593Smuzhiyun 	0x8c00, 0x000000ff, 0x00000001,
1094*4882a593Smuzhiyun 	0xe40, 0x00001fff, 0x00001fff,
1095*4882a593Smuzhiyun 	0x9060, 0x0000007f, 0x00000020,
1096*4882a593Smuzhiyun 	0x9508, 0x00010000, 0x00010000,
1097*4882a593Smuzhiyun 	0xac14, 0x000003ff, 0x000000f3,
1098*4882a593Smuzhiyun 	0xac0c, 0xffffffff, 0x00001032
1099*4882a593Smuzhiyun };
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun static const u32 bonaire_mgcg_cgcg_init[] =
1102*4882a593Smuzhiyun {
1103*4882a593Smuzhiyun 	0xc420, 0xffffffff, 0xfffffffc,
1104*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1105*4882a593Smuzhiyun 	0x3c2a0, 0xffffffff, 0x00000100,
1106*4882a593Smuzhiyun 	0x3c208, 0xffffffff, 0x00000100,
1107*4882a593Smuzhiyun 	0x3c2c0, 0xffffffff, 0xc0000100,
1108*4882a593Smuzhiyun 	0x3c2c8, 0xffffffff, 0xc0000100,
1109*4882a593Smuzhiyun 	0x3c2c4, 0xffffffff, 0xc0000100,
1110*4882a593Smuzhiyun 	0x55e4, 0xffffffff, 0x00600100,
1111*4882a593Smuzhiyun 	0x3c280, 0xffffffff, 0x00000100,
1112*4882a593Smuzhiyun 	0x3c214, 0xffffffff, 0x06000100,
1113*4882a593Smuzhiyun 	0x3c220, 0xffffffff, 0x00000100,
1114*4882a593Smuzhiyun 	0x3c218, 0xffffffff, 0x06000100,
1115*4882a593Smuzhiyun 	0x3c204, 0xffffffff, 0x00000100,
1116*4882a593Smuzhiyun 	0x3c2e0, 0xffffffff, 0x00000100,
1117*4882a593Smuzhiyun 	0x3c224, 0xffffffff, 0x00000100,
1118*4882a593Smuzhiyun 	0x3c200, 0xffffffff, 0x00000100,
1119*4882a593Smuzhiyun 	0x3c230, 0xffffffff, 0x00000100,
1120*4882a593Smuzhiyun 	0x3c234, 0xffffffff, 0x00000100,
1121*4882a593Smuzhiyun 	0x3c250, 0xffffffff, 0x00000100,
1122*4882a593Smuzhiyun 	0x3c254, 0xffffffff, 0x00000100,
1123*4882a593Smuzhiyun 	0x3c258, 0xffffffff, 0x00000100,
1124*4882a593Smuzhiyun 	0x3c25c, 0xffffffff, 0x00000100,
1125*4882a593Smuzhiyun 	0x3c260, 0xffffffff, 0x00000100,
1126*4882a593Smuzhiyun 	0x3c27c, 0xffffffff, 0x00000100,
1127*4882a593Smuzhiyun 	0x3c278, 0xffffffff, 0x00000100,
1128*4882a593Smuzhiyun 	0x3c210, 0xffffffff, 0x06000100,
1129*4882a593Smuzhiyun 	0x3c290, 0xffffffff, 0x00000100,
1130*4882a593Smuzhiyun 	0x3c274, 0xffffffff, 0x00000100,
1131*4882a593Smuzhiyun 	0x3c2b4, 0xffffffff, 0x00000100,
1132*4882a593Smuzhiyun 	0x3c2b0, 0xffffffff, 0x00000100,
1133*4882a593Smuzhiyun 	0x3c270, 0xffffffff, 0x00000100,
1134*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1135*4882a593Smuzhiyun 	0x3c020, 0xffffffff, 0x00010000,
1136*4882a593Smuzhiyun 	0x3c024, 0xffffffff, 0x00030002,
1137*4882a593Smuzhiyun 	0x3c028, 0xffffffff, 0x00040007,
1138*4882a593Smuzhiyun 	0x3c02c, 0xffffffff, 0x00060005,
1139*4882a593Smuzhiyun 	0x3c030, 0xffffffff, 0x00090008,
1140*4882a593Smuzhiyun 	0x3c034, 0xffffffff, 0x00010000,
1141*4882a593Smuzhiyun 	0x3c038, 0xffffffff, 0x00030002,
1142*4882a593Smuzhiyun 	0x3c03c, 0xffffffff, 0x00040007,
1143*4882a593Smuzhiyun 	0x3c040, 0xffffffff, 0x00060005,
1144*4882a593Smuzhiyun 	0x3c044, 0xffffffff, 0x00090008,
1145*4882a593Smuzhiyun 	0x3c048, 0xffffffff, 0x00010000,
1146*4882a593Smuzhiyun 	0x3c04c, 0xffffffff, 0x00030002,
1147*4882a593Smuzhiyun 	0x3c050, 0xffffffff, 0x00040007,
1148*4882a593Smuzhiyun 	0x3c054, 0xffffffff, 0x00060005,
1149*4882a593Smuzhiyun 	0x3c058, 0xffffffff, 0x00090008,
1150*4882a593Smuzhiyun 	0x3c05c, 0xffffffff, 0x00010000,
1151*4882a593Smuzhiyun 	0x3c060, 0xffffffff, 0x00030002,
1152*4882a593Smuzhiyun 	0x3c064, 0xffffffff, 0x00040007,
1153*4882a593Smuzhiyun 	0x3c068, 0xffffffff, 0x00060005,
1154*4882a593Smuzhiyun 	0x3c06c, 0xffffffff, 0x00090008,
1155*4882a593Smuzhiyun 	0x3c070, 0xffffffff, 0x00010000,
1156*4882a593Smuzhiyun 	0x3c074, 0xffffffff, 0x00030002,
1157*4882a593Smuzhiyun 	0x3c078, 0xffffffff, 0x00040007,
1158*4882a593Smuzhiyun 	0x3c07c, 0xffffffff, 0x00060005,
1159*4882a593Smuzhiyun 	0x3c080, 0xffffffff, 0x00090008,
1160*4882a593Smuzhiyun 	0x3c084, 0xffffffff, 0x00010000,
1161*4882a593Smuzhiyun 	0x3c088, 0xffffffff, 0x00030002,
1162*4882a593Smuzhiyun 	0x3c08c, 0xffffffff, 0x00040007,
1163*4882a593Smuzhiyun 	0x3c090, 0xffffffff, 0x00060005,
1164*4882a593Smuzhiyun 	0x3c094, 0xffffffff, 0x00090008,
1165*4882a593Smuzhiyun 	0x3c098, 0xffffffff, 0x00010000,
1166*4882a593Smuzhiyun 	0x3c09c, 0xffffffff, 0x00030002,
1167*4882a593Smuzhiyun 	0x3c0a0, 0xffffffff, 0x00040007,
1168*4882a593Smuzhiyun 	0x3c0a4, 0xffffffff, 0x00060005,
1169*4882a593Smuzhiyun 	0x3c0a8, 0xffffffff, 0x00090008,
1170*4882a593Smuzhiyun 	0x3c000, 0xffffffff, 0x96e00200,
1171*4882a593Smuzhiyun 	0x8708, 0xffffffff, 0x00900100,
1172*4882a593Smuzhiyun 	0xc424, 0xffffffff, 0x0020003f,
1173*4882a593Smuzhiyun 	0x38, 0xffffffff, 0x0140001c,
1174*4882a593Smuzhiyun 	0x3c, 0x000f0000, 0x000f0000,
1175*4882a593Smuzhiyun 	0x220, 0xffffffff, 0xC060000C,
1176*4882a593Smuzhiyun 	0x224, 0xc0000fff, 0x00000100,
1177*4882a593Smuzhiyun 	0xf90, 0xffffffff, 0x00000100,
1178*4882a593Smuzhiyun 	0xf98, 0x00000101, 0x00000000,
1179*4882a593Smuzhiyun 	0x20a8, 0xffffffff, 0x00000104,
1180*4882a593Smuzhiyun 	0x55e4, 0xff000fff, 0x00000100,
1181*4882a593Smuzhiyun 	0x30cc, 0xc0000fff, 0x00000104,
1182*4882a593Smuzhiyun 	0xc1e4, 0x00000001, 0x00000001,
1183*4882a593Smuzhiyun 	0xd00c, 0xff000ff0, 0x00000100,
1184*4882a593Smuzhiyun 	0xd80c, 0xff000ff0, 0x00000100
1185*4882a593Smuzhiyun };
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun static const u32 spectre_golden_spm_registers[] =
1188*4882a593Smuzhiyun {
1189*4882a593Smuzhiyun 	0x30800, 0xe0ffffff, 0xe0000000
1190*4882a593Smuzhiyun };
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun static const u32 spectre_golden_common_registers[] =
1193*4882a593Smuzhiyun {
1194*4882a593Smuzhiyun 	0xc770, 0xffffffff, 0x00000800,
1195*4882a593Smuzhiyun 	0xc774, 0xffffffff, 0x00000800,
1196*4882a593Smuzhiyun 	0xc798, 0xffffffff, 0x00007fbf,
1197*4882a593Smuzhiyun 	0xc79c, 0xffffffff, 0x00007faf
1198*4882a593Smuzhiyun };
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun static const u32 spectre_golden_registers[] =
1201*4882a593Smuzhiyun {
1202*4882a593Smuzhiyun 	0x3c000, 0xffff1fff, 0x96940200,
1203*4882a593Smuzhiyun 	0x3c00c, 0xffff0001, 0xff000000,
1204*4882a593Smuzhiyun 	0x3c200, 0xfffc0fff, 0x00000100,
1205*4882a593Smuzhiyun 	0x6ed8, 0x00010101, 0x00010000,
1206*4882a593Smuzhiyun 	0x9834, 0xf00fffff, 0x00000400,
1207*4882a593Smuzhiyun 	0x9838, 0xfffffffc, 0x00020200,
1208*4882a593Smuzhiyun 	0x5bb0, 0x000000f0, 0x00000070,
1209*4882a593Smuzhiyun 	0x5bc0, 0xf0311fff, 0x80300000,
1210*4882a593Smuzhiyun 	0x98f8, 0x73773777, 0x12010001,
1211*4882a593Smuzhiyun 	0x9b7c, 0x00ff0000, 0x00fc0000,
1212*4882a593Smuzhiyun 	0x2f48, 0x73773777, 0x12010001,
1213*4882a593Smuzhiyun 	0x8a14, 0xf000003f, 0x00000007,
1214*4882a593Smuzhiyun 	0x8b24, 0xffffffff, 0x00ffffff,
1215*4882a593Smuzhiyun 	0x28350, 0x3f3f3fff, 0x00000082,
1216*4882a593Smuzhiyun 	0x28354, 0x0000003f, 0x00000000,
1217*4882a593Smuzhiyun 	0x3e78, 0x00000001, 0x00000002,
1218*4882a593Smuzhiyun 	0x913c, 0xffff03df, 0x00000004,
1219*4882a593Smuzhiyun 	0xc768, 0x00000008, 0x00000008,
1220*4882a593Smuzhiyun 	0x8c00, 0x000008ff, 0x00000800,
1221*4882a593Smuzhiyun 	0x9508, 0x00010000, 0x00010000,
1222*4882a593Smuzhiyun 	0xac0c, 0xffffffff, 0x54763210,
1223*4882a593Smuzhiyun 	0x214f8, 0x01ff01ff, 0x00000002,
1224*4882a593Smuzhiyun 	0x21498, 0x007ff800, 0x00200000,
1225*4882a593Smuzhiyun 	0x2015c, 0xffffffff, 0x00000f40,
1226*4882a593Smuzhiyun 	0x30934, 0xffffffff, 0x00000001
1227*4882a593Smuzhiyun };
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun static const u32 spectre_mgcg_cgcg_init[] =
1230*4882a593Smuzhiyun {
1231*4882a593Smuzhiyun 	0xc420, 0xffffffff, 0xfffffffc,
1232*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1233*4882a593Smuzhiyun 	0x3c2a0, 0xffffffff, 0x00000100,
1234*4882a593Smuzhiyun 	0x3c208, 0xffffffff, 0x00000100,
1235*4882a593Smuzhiyun 	0x3c2c0, 0xffffffff, 0x00000100,
1236*4882a593Smuzhiyun 	0x3c2c8, 0xffffffff, 0x00000100,
1237*4882a593Smuzhiyun 	0x3c2c4, 0xffffffff, 0x00000100,
1238*4882a593Smuzhiyun 	0x55e4, 0xffffffff, 0x00600100,
1239*4882a593Smuzhiyun 	0x3c280, 0xffffffff, 0x00000100,
1240*4882a593Smuzhiyun 	0x3c214, 0xffffffff, 0x06000100,
1241*4882a593Smuzhiyun 	0x3c220, 0xffffffff, 0x00000100,
1242*4882a593Smuzhiyun 	0x3c218, 0xffffffff, 0x06000100,
1243*4882a593Smuzhiyun 	0x3c204, 0xffffffff, 0x00000100,
1244*4882a593Smuzhiyun 	0x3c2e0, 0xffffffff, 0x00000100,
1245*4882a593Smuzhiyun 	0x3c224, 0xffffffff, 0x00000100,
1246*4882a593Smuzhiyun 	0x3c200, 0xffffffff, 0x00000100,
1247*4882a593Smuzhiyun 	0x3c230, 0xffffffff, 0x00000100,
1248*4882a593Smuzhiyun 	0x3c234, 0xffffffff, 0x00000100,
1249*4882a593Smuzhiyun 	0x3c250, 0xffffffff, 0x00000100,
1250*4882a593Smuzhiyun 	0x3c254, 0xffffffff, 0x00000100,
1251*4882a593Smuzhiyun 	0x3c258, 0xffffffff, 0x00000100,
1252*4882a593Smuzhiyun 	0x3c25c, 0xffffffff, 0x00000100,
1253*4882a593Smuzhiyun 	0x3c260, 0xffffffff, 0x00000100,
1254*4882a593Smuzhiyun 	0x3c27c, 0xffffffff, 0x00000100,
1255*4882a593Smuzhiyun 	0x3c278, 0xffffffff, 0x00000100,
1256*4882a593Smuzhiyun 	0x3c210, 0xffffffff, 0x06000100,
1257*4882a593Smuzhiyun 	0x3c290, 0xffffffff, 0x00000100,
1258*4882a593Smuzhiyun 	0x3c274, 0xffffffff, 0x00000100,
1259*4882a593Smuzhiyun 	0x3c2b4, 0xffffffff, 0x00000100,
1260*4882a593Smuzhiyun 	0x3c2b0, 0xffffffff, 0x00000100,
1261*4882a593Smuzhiyun 	0x3c270, 0xffffffff, 0x00000100,
1262*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1263*4882a593Smuzhiyun 	0x3c020, 0xffffffff, 0x00010000,
1264*4882a593Smuzhiyun 	0x3c024, 0xffffffff, 0x00030002,
1265*4882a593Smuzhiyun 	0x3c028, 0xffffffff, 0x00040007,
1266*4882a593Smuzhiyun 	0x3c02c, 0xffffffff, 0x00060005,
1267*4882a593Smuzhiyun 	0x3c030, 0xffffffff, 0x00090008,
1268*4882a593Smuzhiyun 	0x3c034, 0xffffffff, 0x00010000,
1269*4882a593Smuzhiyun 	0x3c038, 0xffffffff, 0x00030002,
1270*4882a593Smuzhiyun 	0x3c03c, 0xffffffff, 0x00040007,
1271*4882a593Smuzhiyun 	0x3c040, 0xffffffff, 0x00060005,
1272*4882a593Smuzhiyun 	0x3c044, 0xffffffff, 0x00090008,
1273*4882a593Smuzhiyun 	0x3c048, 0xffffffff, 0x00010000,
1274*4882a593Smuzhiyun 	0x3c04c, 0xffffffff, 0x00030002,
1275*4882a593Smuzhiyun 	0x3c050, 0xffffffff, 0x00040007,
1276*4882a593Smuzhiyun 	0x3c054, 0xffffffff, 0x00060005,
1277*4882a593Smuzhiyun 	0x3c058, 0xffffffff, 0x00090008,
1278*4882a593Smuzhiyun 	0x3c05c, 0xffffffff, 0x00010000,
1279*4882a593Smuzhiyun 	0x3c060, 0xffffffff, 0x00030002,
1280*4882a593Smuzhiyun 	0x3c064, 0xffffffff, 0x00040007,
1281*4882a593Smuzhiyun 	0x3c068, 0xffffffff, 0x00060005,
1282*4882a593Smuzhiyun 	0x3c06c, 0xffffffff, 0x00090008,
1283*4882a593Smuzhiyun 	0x3c070, 0xffffffff, 0x00010000,
1284*4882a593Smuzhiyun 	0x3c074, 0xffffffff, 0x00030002,
1285*4882a593Smuzhiyun 	0x3c078, 0xffffffff, 0x00040007,
1286*4882a593Smuzhiyun 	0x3c07c, 0xffffffff, 0x00060005,
1287*4882a593Smuzhiyun 	0x3c080, 0xffffffff, 0x00090008,
1288*4882a593Smuzhiyun 	0x3c084, 0xffffffff, 0x00010000,
1289*4882a593Smuzhiyun 	0x3c088, 0xffffffff, 0x00030002,
1290*4882a593Smuzhiyun 	0x3c08c, 0xffffffff, 0x00040007,
1291*4882a593Smuzhiyun 	0x3c090, 0xffffffff, 0x00060005,
1292*4882a593Smuzhiyun 	0x3c094, 0xffffffff, 0x00090008,
1293*4882a593Smuzhiyun 	0x3c098, 0xffffffff, 0x00010000,
1294*4882a593Smuzhiyun 	0x3c09c, 0xffffffff, 0x00030002,
1295*4882a593Smuzhiyun 	0x3c0a0, 0xffffffff, 0x00040007,
1296*4882a593Smuzhiyun 	0x3c0a4, 0xffffffff, 0x00060005,
1297*4882a593Smuzhiyun 	0x3c0a8, 0xffffffff, 0x00090008,
1298*4882a593Smuzhiyun 	0x3c0ac, 0xffffffff, 0x00010000,
1299*4882a593Smuzhiyun 	0x3c0b0, 0xffffffff, 0x00030002,
1300*4882a593Smuzhiyun 	0x3c0b4, 0xffffffff, 0x00040007,
1301*4882a593Smuzhiyun 	0x3c0b8, 0xffffffff, 0x00060005,
1302*4882a593Smuzhiyun 	0x3c0bc, 0xffffffff, 0x00090008,
1303*4882a593Smuzhiyun 	0x3c000, 0xffffffff, 0x96e00200,
1304*4882a593Smuzhiyun 	0x8708, 0xffffffff, 0x00900100,
1305*4882a593Smuzhiyun 	0xc424, 0xffffffff, 0x0020003f,
1306*4882a593Smuzhiyun 	0x38, 0xffffffff, 0x0140001c,
1307*4882a593Smuzhiyun 	0x3c, 0x000f0000, 0x000f0000,
1308*4882a593Smuzhiyun 	0x220, 0xffffffff, 0xC060000C,
1309*4882a593Smuzhiyun 	0x224, 0xc0000fff, 0x00000100,
1310*4882a593Smuzhiyun 	0xf90, 0xffffffff, 0x00000100,
1311*4882a593Smuzhiyun 	0xf98, 0x00000101, 0x00000000,
1312*4882a593Smuzhiyun 	0x20a8, 0xffffffff, 0x00000104,
1313*4882a593Smuzhiyun 	0x55e4, 0xff000fff, 0x00000100,
1314*4882a593Smuzhiyun 	0x30cc, 0xc0000fff, 0x00000104,
1315*4882a593Smuzhiyun 	0xc1e4, 0x00000001, 0x00000001,
1316*4882a593Smuzhiyun 	0xd00c, 0xff000ff0, 0x00000100,
1317*4882a593Smuzhiyun 	0xd80c, 0xff000ff0, 0x00000100
1318*4882a593Smuzhiyun };
1319*4882a593Smuzhiyun 
1320*4882a593Smuzhiyun static const u32 kalindi_golden_spm_registers[] =
1321*4882a593Smuzhiyun {
1322*4882a593Smuzhiyun 	0x30800, 0xe0ffffff, 0xe0000000
1323*4882a593Smuzhiyun };
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun static const u32 kalindi_golden_common_registers[] =
1326*4882a593Smuzhiyun {
1327*4882a593Smuzhiyun 	0xc770, 0xffffffff, 0x00000800,
1328*4882a593Smuzhiyun 	0xc774, 0xffffffff, 0x00000800,
1329*4882a593Smuzhiyun 	0xc798, 0xffffffff, 0x00007fbf,
1330*4882a593Smuzhiyun 	0xc79c, 0xffffffff, 0x00007faf
1331*4882a593Smuzhiyun };
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun static const u32 kalindi_golden_registers[] =
1334*4882a593Smuzhiyun {
1335*4882a593Smuzhiyun 	0x3c000, 0xffffdfff, 0x6e944040,
1336*4882a593Smuzhiyun 	0x55e4, 0xff607fff, 0xfc000100,
1337*4882a593Smuzhiyun 	0x3c220, 0xff000fff, 0x00000100,
1338*4882a593Smuzhiyun 	0x3c224, 0xff000fff, 0x00000100,
1339*4882a593Smuzhiyun 	0x3c200, 0xfffc0fff, 0x00000100,
1340*4882a593Smuzhiyun 	0x6ed8, 0x00010101, 0x00010000,
1341*4882a593Smuzhiyun 	0x9830, 0xffffffff, 0x00000000,
1342*4882a593Smuzhiyun 	0x9834, 0xf00fffff, 0x00000400,
1343*4882a593Smuzhiyun 	0x5bb0, 0x000000f0, 0x00000070,
1344*4882a593Smuzhiyun 	0x5bc0, 0xf0311fff, 0x80300000,
1345*4882a593Smuzhiyun 	0x98f8, 0x73773777, 0x12010001,
1346*4882a593Smuzhiyun 	0x98fc, 0xffffffff, 0x00000010,
1347*4882a593Smuzhiyun 	0x9b7c, 0x00ff0000, 0x00fc0000,
1348*4882a593Smuzhiyun 	0x8030, 0x00001f0f, 0x0000100a,
1349*4882a593Smuzhiyun 	0x2f48, 0x73773777, 0x12010001,
1350*4882a593Smuzhiyun 	0x2408, 0x000fffff, 0x000c007f,
1351*4882a593Smuzhiyun 	0x8a14, 0xf000003f, 0x00000007,
1352*4882a593Smuzhiyun 	0x8b24, 0x3fff3fff, 0x00ffcfff,
1353*4882a593Smuzhiyun 	0x30a04, 0x0000ff0f, 0x00000000,
1354*4882a593Smuzhiyun 	0x28a4c, 0x07ffffff, 0x06000000,
1355*4882a593Smuzhiyun 	0x4d8, 0x00000fff, 0x00000100,
1356*4882a593Smuzhiyun 	0x3e78, 0x00000001, 0x00000002,
1357*4882a593Smuzhiyun 	0xc768, 0x00000008, 0x00000008,
1358*4882a593Smuzhiyun 	0x8c00, 0x000000ff, 0x00000003,
1359*4882a593Smuzhiyun 	0x214f8, 0x01ff01ff, 0x00000002,
1360*4882a593Smuzhiyun 	0x21498, 0x007ff800, 0x00200000,
1361*4882a593Smuzhiyun 	0x2015c, 0xffffffff, 0x00000f40,
1362*4882a593Smuzhiyun 	0x88c4, 0x001f3ae3, 0x00000082,
1363*4882a593Smuzhiyun 	0x88d4, 0x0000001f, 0x00000010,
1364*4882a593Smuzhiyun 	0x30934, 0xffffffff, 0x00000000
1365*4882a593Smuzhiyun };
1366*4882a593Smuzhiyun 
1367*4882a593Smuzhiyun static const u32 kalindi_mgcg_cgcg_init[] =
1368*4882a593Smuzhiyun {
1369*4882a593Smuzhiyun 	0xc420, 0xffffffff, 0xfffffffc,
1370*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1371*4882a593Smuzhiyun 	0x3c2a0, 0xffffffff, 0x00000100,
1372*4882a593Smuzhiyun 	0x3c208, 0xffffffff, 0x00000100,
1373*4882a593Smuzhiyun 	0x3c2c0, 0xffffffff, 0x00000100,
1374*4882a593Smuzhiyun 	0x3c2c8, 0xffffffff, 0x00000100,
1375*4882a593Smuzhiyun 	0x3c2c4, 0xffffffff, 0x00000100,
1376*4882a593Smuzhiyun 	0x55e4, 0xffffffff, 0x00600100,
1377*4882a593Smuzhiyun 	0x3c280, 0xffffffff, 0x00000100,
1378*4882a593Smuzhiyun 	0x3c214, 0xffffffff, 0x06000100,
1379*4882a593Smuzhiyun 	0x3c220, 0xffffffff, 0x00000100,
1380*4882a593Smuzhiyun 	0x3c218, 0xffffffff, 0x06000100,
1381*4882a593Smuzhiyun 	0x3c204, 0xffffffff, 0x00000100,
1382*4882a593Smuzhiyun 	0x3c2e0, 0xffffffff, 0x00000100,
1383*4882a593Smuzhiyun 	0x3c224, 0xffffffff, 0x00000100,
1384*4882a593Smuzhiyun 	0x3c200, 0xffffffff, 0x00000100,
1385*4882a593Smuzhiyun 	0x3c230, 0xffffffff, 0x00000100,
1386*4882a593Smuzhiyun 	0x3c234, 0xffffffff, 0x00000100,
1387*4882a593Smuzhiyun 	0x3c250, 0xffffffff, 0x00000100,
1388*4882a593Smuzhiyun 	0x3c254, 0xffffffff, 0x00000100,
1389*4882a593Smuzhiyun 	0x3c258, 0xffffffff, 0x00000100,
1390*4882a593Smuzhiyun 	0x3c25c, 0xffffffff, 0x00000100,
1391*4882a593Smuzhiyun 	0x3c260, 0xffffffff, 0x00000100,
1392*4882a593Smuzhiyun 	0x3c27c, 0xffffffff, 0x00000100,
1393*4882a593Smuzhiyun 	0x3c278, 0xffffffff, 0x00000100,
1394*4882a593Smuzhiyun 	0x3c210, 0xffffffff, 0x06000100,
1395*4882a593Smuzhiyun 	0x3c290, 0xffffffff, 0x00000100,
1396*4882a593Smuzhiyun 	0x3c274, 0xffffffff, 0x00000100,
1397*4882a593Smuzhiyun 	0x3c2b4, 0xffffffff, 0x00000100,
1398*4882a593Smuzhiyun 	0x3c2b0, 0xffffffff, 0x00000100,
1399*4882a593Smuzhiyun 	0x3c270, 0xffffffff, 0x00000100,
1400*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1401*4882a593Smuzhiyun 	0x3c020, 0xffffffff, 0x00010000,
1402*4882a593Smuzhiyun 	0x3c024, 0xffffffff, 0x00030002,
1403*4882a593Smuzhiyun 	0x3c028, 0xffffffff, 0x00040007,
1404*4882a593Smuzhiyun 	0x3c02c, 0xffffffff, 0x00060005,
1405*4882a593Smuzhiyun 	0x3c030, 0xffffffff, 0x00090008,
1406*4882a593Smuzhiyun 	0x3c034, 0xffffffff, 0x00010000,
1407*4882a593Smuzhiyun 	0x3c038, 0xffffffff, 0x00030002,
1408*4882a593Smuzhiyun 	0x3c03c, 0xffffffff, 0x00040007,
1409*4882a593Smuzhiyun 	0x3c040, 0xffffffff, 0x00060005,
1410*4882a593Smuzhiyun 	0x3c044, 0xffffffff, 0x00090008,
1411*4882a593Smuzhiyun 	0x3c000, 0xffffffff, 0x96e00200,
1412*4882a593Smuzhiyun 	0x8708, 0xffffffff, 0x00900100,
1413*4882a593Smuzhiyun 	0xc424, 0xffffffff, 0x0020003f,
1414*4882a593Smuzhiyun 	0x38, 0xffffffff, 0x0140001c,
1415*4882a593Smuzhiyun 	0x3c, 0x000f0000, 0x000f0000,
1416*4882a593Smuzhiyun 	0x220, 0xffffffff, 0xC060000C,
1417*4882a593Smuzhiyun 	0x224, 0xc0000fff, 0x00000100,
1418*4882a593Smuzhiyun 	0x20a8, 0xffffffff, 0x00000104,
1419*4882a593Smuzhiyun 	0x55e4, 0xff000fff, 0x00000100,
1420*4882a593Smuzhiyun 	0x30cc, 0xc0000fff, 0x00000104,
1421*4882a593Smuzhiyun 	0xc1e4, 0x00000001, 0x00000001,
1422*4882a593Smuzhiyun 	0xd00c, 0xff000ff0, 0x00000100,
1423*4882a593Smuzhiyun 	0xd80c, 0xff000ff0, 0x00000100
1424*4882a593Smuzhiyun };
1425*4882a593Smuzhiyun 
1426*4882a593Smuzhiyun static const u32 hawaii_golden_spm_registers[] =
1427*4882a593Smuzhiyun {
1428*4882a593Smuzhiyun 	0x30800, 0xe0ffffff, 0xe0000000
1429*4882a593Smuzhiyun };
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun static const u32 hawaii_golden_common_registers[] =
1432*4882a593Smuzhiyun {
1433*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1434*4882a593Smuzhiyun 	0x28350, 0xffffffff, 0x3a00161a,
1435*4882a593Smuzhiyun 	0x28354, 0xffffffff, 0x0000002e,
1436*4882a593Smuzhiyun 	0x9a10, 0xffffffff, 0x00018208,
1437*4882a593Smuzhiyun 	0x98f8, 0xffffffff, 0x12011003
1438*4882a593Smuzhiyun };
1439*4882a593Smuzhiyun 
1440*4882a593Smuzhiyun static const u32 hawaii_golden_registers[] =
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun 	0x3354, 0x00000333, 0x00000333,
1443*4882a593Smuzhiyun 	0x9a10, 0x00010000, 0x00058208,
1444*4882a593Smuzhiyun 	0x9830, 0xffffffff, 0x00000000,
1445*4882a593Smuzhiyun 	0x9834, 0xf00fffff, 0x00000400,
1446*4882a593Smuzhiyun 	0x9838, 0x0002021c, 0x00020200,
1447*4882a593Smuzhiyun 	0xc78, 0x00000080, 0x00000000,
1448*4882a593Smuzhiyun 	0x5bb0, 0x000000f0, 0x00000070,
1449*4882a593Smuzhiyun 	0x5bc0, 0xf0311fff, 0x80300000,
1450*4882a593Smuzhiyun 	0x350c, 0x00810000, 0x408af000,
1451*4882a593Smuzhiyun 	0x7030, 0x31000111, 0x00000011,
1452*4882a593Smuzhiyun 	0x2f48, 0x73773777, 0x12010001,
1453*4882a593Smuzhiyun 	0x2120, 0x0000007f, 0x0000001b,
1454*4882a593Smuzhiyun 	0x21dc, 0x00007fb6, 0x00002191,
1455*4882a593Smuzhiyun 	0x3628, 0x0000003f, 0x0000000a,
1456*4882a593Smuzhiyun 	0x362c, 0x0000003f, 0x0000000a,
1457*4882a593Smuzhiyun 	0x2ae4, 0x00073ffe, 0x000022a2,
1458*4882a593Smuzhiyun 	0x240c, 0x000007ff, 0x00000000,
1459*4882a593Smuzhiyun 	0x8bf0, 0x00002001, 0x00000001,
1460*4882a593Smuzhiyun 	0x8b24, 0xffffffff, 0x00ffffff,
1461*4882a593Smuzhiyun 	0x30a04, 0x0000ff0f, 0x00000000,
1462*4882a593Smuzhiyun 	0x28a4c, 0x07ffffff, 0x06000000,
1463*4882a593Smuzhiyun 	0x3e78, 0x00000001, 0x00000002,
1464*4882a593Smuzhiyun 	0xc768, 0x00000008, 0x00000008,
1465*4882a593Smuzhiyun 	0xc770, 0x00000f00, 0x00000800,
1466*4882a593Smuzhiyun 	0xc774, 0x00000f00, 0x00000800,
1467*4882a593Smuzhiyun 	0xc798, 0x00ffffff, 0x00ff7fbf,
1468*4882a593Smuzhiyun 	0xc79c, 0x00ffffff, 0x00ff7faf,
1469*4882a593Smuzhiyun 	0x8c00, 0x000000ff, 0x00000800,
1470*4882a593Smuzhiyun 	0xe40, 0x00001fff, 0x00001fff,
1471*4882a593Smuzhiyun 	0x9060, 0x0000007f, 0x00000020,
1472*4882a593Smuzhiyun 	0x9508, 0x00010000, 0x00010000,
1473*4882a593Smuzhiyun 	0xae00, 0x00100000, 0x000ff07c,
1474*4882a593Smuzhiyun 	0xac14, 0x000003ff, 0x0000000f,
1475*4882a593Smuzhiyun 	0xac10, 0xffffffff, 0x7564fdec,
1476*4882a593Smuzhiyun 	0xac0c, 0xffffffff, 0x3120b9a8,
1477*4882a593Smuzhiyun 	0xac08, 0x20000000, 0x0f9c0000
1478*4882a593Smuzhiyun };
1479*4882a593Smuzhiyun 
1480*4882a593Smuzhiyun static const u32 hawaii_mgcg_cgcg_init[] =
1481*4882a593Smuzhiyun {
1482*4882a593Smuzhiyun 	0xc420, 0xffffffff, 0xfffffffd,
1483*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1484*4882a593Smuzhiyun 	0x3c2a0, 0xffffffff, 0x00000100,
1485*4882a593Smuzhiyun 	0x3c208, 0xffffffff, 0x00000100,
1486*4882a593Smuzhiyun 	0x3c2c0, 0xffffffff, 0x00000100,
1487*4882a593Smuzhiyun 	0x3c2c8, 0xffffffff, 0x00000100,
1488*4882a593Smuzhiyun 	0x3c2c4, 0xffffffff, 0x00000100,
1489*4882a593Smuzhiyun 	0x55e4, 0xffffffff, 0x00200100,
1490*4882a593Smuzhiyun 	0x3c280, 0xffffffff, 0x00000100,
1491*4882a593Smuzhiyun 	0x3c214, 0xffffffff, 0x06000100,
1492*4882a593Smuzhiyun 	0x3c220, 0xffffffff, 0x00000100,
1493*4882a593Smuzhiyun 	0x3c218, 0xffffffff, 0x06000100,
1494*4882a593Smuzhiyun 	0x3c204, 0xffffffff, 0x00000100,
1495*4882a593Smuzhiyun 	0x3c2e0, 0xffffffff, 0x00000100,
1496*4882a593Smuzhiyun 	0x3c224, 0xffffffff, 0x00000100,
1497*4882a593Smuzhiyun 	0x3c200, 0xffffffff, 0x00000100,
1498*4882a593Smuzhiyun 	0x3c230, 0xffffffff, 0x00000100,
1499*4882a593Smuzhiyun 	0x3c234, 0xffffffff, 0x00000100,
1500*4882a593Smuzhiyun 	0x3c250, 0xffffffff, 0x00000100,
1501*4882a593Smuzhiyun 	0x3c254, 0xffffffff, 0x00000100,
1502*4882a593Smuzhiyun 	0x3c258, 0xffffffff, 0x00000100,
1503*4882a593Smuzhiyun 	0x3c25c, 0xffffffff, 0x00000100,
1504*4882a593Smuzhiyun 	0x3c260, 0xffffffff, 0x00000100,
1505*4882a593Smuzhiyun 	0x3c27c, 0xffffffff, 0x00000100,
1506*4882a593Smuzhiyun 	0x3c278, 0xffffffff, 0x00000100,
1507*4882a593Smuzhiyun 	0x3c210, 0xffffffff, 0x06000100,
1508*4882a593Smuzhiyun 	0x3c290, 0xffffffff, 0x00000100,
1509*4882a593Smuzhiyun 	0x3c274, 0xffffffff, 0x00000100,
1510*4882a593Smuzhiyun 	0x3c2b4, 0xffffffff, 0x00000100,
1511*4882a593Smuzhiyun 	0x3c2b0, 0xffffffff, 0x00000100,
1512*4882a593Smuzhiyun 	0x3c270, 0xffffffff, 0x00000100,
1513*4882a593Smuzhiyun 	0x30800, 0xffffffff, 0xe0000000,
1514*4882a593Smuzhiyun 	0x3c020, 0xffffffff, 0x00010000,
1515*4882a593Smuzhiyun 	0x3c024, 0xffffffff, 0x00030002,
1516*4882a593Smuzhiyun 	0x3c028, 0xffffffff, 0x00040007,
1517*4882a593Smuzhiyun 	0x3c02c, 0xffffffff, 0x00060005,
1518*4882a593Smuzhiyun 	0x3c030, 0xffffffff, 0x00090008,
1519*4882a593Smuzhiyun 	0x3c034, 0xffffffff, 0x00010000,
1520*4882a593Smuzhiyun 	0x3c038, 0xffffffff, 0x00030002,
1521*4882a593Smuzhiyun 	0x3c03c, 0xffffffff, 0x00040007,
1522*4882a593Smuzhiyun 	0x3c040, 0xffffffff, 0x00060005,
1523*4882a593Smuzhiyun 	0x3c044, 0xffffffff, 0x00090008,
1524*4882a593Smuzhiyun 	0x3c048, 0xffffffff, 0x00010000,
1525*4882a593Smuzhiyun 	0x3c04c, 0xffffffff, 0x00030002,
1526*4882a593Smuzhiyun 	0x3c050, 0xffffffff, 0x00040007,
1527*4882a593Smuzhiyun 	0x3c054, 0xffffffff, 0x00060005,
1528*4882a593Smuzhiyun 	0x3c058, 0xffffffff, 0x00090008,
1529*4882a593Smuzhiyun 	0x3c05c, 0xffffffff, 0x00010000,
1530*4882a593Smuzhiyun 	0x3c060, 0xffffffff, 0x00030002,
1531*4882a593Smuzhiyun 	0x3c064, 0xffffffff, 0x00040007,
1532*4882a593Smuzhiyun 	0x3c068, 0xffffffff, 0x00060005,
1533*4882a593Smuzhiyun 	0x3c06c, 0xffffffff, 0x00090008,
1534*4882a593Smuzhiyun 	0x3c070, 0xffffffff, 0x00010000,
1535*4882a593Smuzhiyun 	0x3c074, 0xffffffff, 0x00030002,
1536*4882a593Smuzhiyun 	0x3c078, 0xffffffff, 0x00040007,
1537*4882a593Smuzhiyun 	0x3c07c, 0xffffffff, 0x00060005,
1538*4882a593Smuzhiyun 	0x3c080, 0xffffffff, 0x00090008,
1539*4882a593Smuzhiyun 	0x3c084, 0xffffffff, 0x00010000,
1540*4882a593Smuzhiyun 	0x3c088, 0xffffffff, 0x00030002,
1541*4882a593Smuzhiyun 	0x3c08c, 0xffffffff, 0x00040007,
1542*4882a593Smuzhiyun 	0x3c090, 0xffffffff, 0x00060005,
1543*4882a593Smuzhiyun 	0x3c094, 0xffffffff, 0x00090008,
1544*4882a593Smuzhiyun 	0x3c098, 0xffffffff, 0x00010000,
1545*4882a593Smuzhiyun 	0x3c09c, 0xffffffff, 0x00030002,
1546*4882a593Smuzhiyun 	0x3c0a0, 0xffffffff, 0x00040007,
1547*4882a593Smuzhiyun 	0x3c0a4, 0xffffffff, 0x00060005,
1548*4882a593Smuzhiyun 	0x3c0a8, 0xffffffff, 0x00090008,
1549*4882a593Smuzhiyun 	0x3c0ac, 0xffffffff, 0x00010000,
1550*4882a593Smuzhiyun 	0x3c0b0, 0xffffffff, 0x00030002,
1551*4882a593Smuzhiyun 	0x3c0b4, 0xffffffff, 0x00040007,
1552*4882a593Smuzhiyun 	0x3c0b8, 0xffffffff, 0x00060005,
1553*4882a593Smuzhiyun 	0x3c0bc, 0xffffffff, 0x00090008,
1554*4882a593Smuzhiyun 	0x3c0c0, 0xffffffff, 0x00010000,
1555*4882a593Smuzhiyun 	0x3c0c4, 0xffffffff, 0x00030002,
1556*4882a593Smuzhiyun 	0x3c0c8, 0xffffffff, 0x00040007,
1557*4882a593Smuzhiyun 	0x3c0cc, 0xffffffff, 0x00060005,
1558*4882a593Smuzhiyun 	0x3c0d0, 0xffffffff, 0x00090008,
1559*4882a593Smuzhiyun 	0x3c0d4, 0xffffffff, 0x00010000,
1560*4882a593Smuzhiyun 	0x3c0d8, 0xffffffff, 0x00030002,
1561*4882a593Smuzhiyun 	0x3c0dc, 0xffffffff, 0x00040007,
1562*4882a593Smuzhiyun 	0x3c0e0, 0xffffffff, 0x00060005,
1563*4882a593Smuzhiyun 	0x3c0e4, 0xffffffff, 0x00090008,
1564*4882a593Smuzhiyun 	0x3c0e8, 0xffffffff, 0x00010000,
1565*4882a593Smuzhiyun 	0x3c0ec, 0xffffffff, 0x00030002,
1566*4882a593Smuzhiyun 	0x3c0f0, 0xffffffff, 0x00040007,
1567*4882a593Smuzhiyun 	0x3c0f4, 0xffffffff, 0x00060005,
1568*4882a593Smuzhiyun 	0x3c0f8, 0xffffffff, 0x00090008,
1569*4882a593Smuzhiyun 	0xc318, 0xffffffff, 0x00020200,
1570*4882a593Smuzhiyun 	0x3350, 0xffffffff, 0x00000200,
1571*4882a593Smuzhiyun 	0x15c0, 0xffffffff, 0x00000400,
1572*4882a593Smuzhiyun 	0x55e8, 0xffffffff, 0x00000000,
1573*4882a593Smuzhiyun 	0x2f50, 0xffffffff, 0x00000902,
1574*4882a593Smuzhiyun 	0x3c000, 0xffffffff, 0x96940200,
1575*4882a593Smuzhiyun 	0x8708, 0xffffffff, 0x00900100,
1576*4882a593Smuzhiyun 	0xc424, 0xffffffff, 0x0020003f,
1577*4882a593Smuzhiyun 	0x38, 0xffffffff, 0x0140001c,
1578*4882a593Smuzhiyun 	0x3c, 0x000f0000, 0x000f0000,
1579*4882a593Smuzhiyun 	0x220, 0xffffffff, 0xc060000c,
1580*4882a593Smuzhiyun 	0x224, 0xc0000fff, 0x00000100,
1581*4882a593Smuzhiyun 	0xf90, 0xffffffff, 0x00000100,
1582*4882a593Smuzhiyun 	0xf98, 0x00000101, 0x00000000,
1583*4882a593Smuzhiyun 	0x20a8, 0xffffffff, 0x00000104,
1584*4882a593Smuzhiyun 	0x55e4, 0xff000fff, 0x00000100,
1585*4882a593Smuzhiyun 	0x30cc, 0xc0000fff, 0x00000104,
1586*4882a593Smuzhiyun 	0xc1e4, 0x00000001, 0x00000001,
1587*4882a593Smuzhiyun 	0xd00c, 0xff000ff0, 0x00000100,
1588*4882a593Smuzhiyun 	0xd80c, 0xff000ff0, 0x00000100
1589*4882a593Smuzhiyun };
1590*4882a593Smuzhiyun 
1591*4882a593Smuzhiyun static const u32 godavari_golden_registers[] =
1592*4882a593Smuzhiyun {
1593*4882a593Smuzhiyun 	0x55e4, 0xff607fff, 0xfc000100,
1594*4882a593Smuzhiyun 	0x6ed8, 0x00010101, 0x00010000,
1595*4882a593Smuzhiyun 	0x9830, 0xffffffff, 0x00000000,
1596*4882a593Smuzhiyun 	0x98302, 0xf00fffff, 0x00000400,
1597*4882a593Smuzhiyun 	0x6130, 0xffffffff, 0x00010000,
1598*4882a593Smuzhiyun 	0x5bb0, 0x000000f0, 0x00000070,
1599*4882a593Smuzhiyun 	0x5bc0, 0xf0311fff, 0x80300000,
1600*4882a593Smuzhiyun 	0x98f8, 0x73773777, 0x12010001,
1601*4882a593Smuzhiyun 	0x98fc, 0xffffffff, 0x00000010,
1602*4882a593Smuzhiyun 	0x8030, 0x00001f0f, 0x0000100a,
1603*4882a593Smuzhiyun 	0x2f48, 0x73773777, 0x12010001,
1604*4882a593Smuzhiyun 	0x2408, 0x000fffff, 0x000c007f,
1605*4882a593Smuzhiyun 	0x8a14, 0xf000003f, 0x00000007,
1606*4882a593Smuzhiyun 	0x8b24, 0xffffffff, 0x00ff0fff,
1607*4882a593Smuzhiyun 	0x30a04, 0x0000ff0f, 0x00000000,
1608*4882a593Smuzhiyun 	0x28a4c, 0x07ffffff, 0x06000000,
1609*4882a593Smuzhiyun 	0x4d8, 0x00000fff, 0x00000100,
1610*4882a593Smuzhiyun 	0xd014, 0x00010000, 0x00810001,
1611*4882a593Smuzhiyun 	0xd814, 0x00010000, 0x00810001,
1612*4882a593Smuzhiyun 	0x3e78, 0x00000001, 0x00000002,
1613*4882a593Smuzhiyun 	0xc768, 0x00000008, 0x00000008,
1614*4882a593Smuzhiyun 	0xc770, 0x00000f00, 0x00000800,
1615*4882a593Smuzhiyun 	0xc774, 0x00000f00, 0x00000800,
1616*4882a593Smuzhiyun 	0xc798, 0x00ffffff, 0x00ff7fbf,
1617*4882a593Smuzhiyun 	0xc79c, 0x00ffffff, 0x00ff7faf,
1618*4882a593Smuzhiyun 	0x8c00, 0x000000ff, 0x00000001,
1619*4882a593Smuzhiyun 	0x214f8, 0x01ff01ff, 0x00000002,
1620*4882a593Smuzhiyun 	0x21498, 0x007ff800, 0x00200000,
1621*4882a593Smuzhiyun 	0x2015c, 0xffffffff, 0x00000f40,
1622*4882a593Smuzhiyun 	0x88c4, 0x001f3ae3, 0x00000082,
1623*4882a593Smuzhiyun 	0x88d4, 0x0000001f, 0x00000010,
1624*4882a593Smuzhiyun 	0x30934, 0xffffffff, 0x00000000
1625*4882a593Smuzhiyun };
1626*4882a593Smuzhiyun 
1627*4882a593Smuzhiyun 
cik_init_golden_registers(struct radeon_device * rdev)1628*4882a593Smuzhiyun static void cik_init_golden_registers(struct radeon_device *rdev)
1629*4882a593Smuzhiyun {
1630*4882a593Smuzhiyun 	switch (rdev->family) {
1631*4882a593Smuzhiyun 	case CHIP_BONAIRE:
1632*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1633*4882a593Smuzhiyun 						 bonaire_mgcg_cgcg_init,
1634*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(bonaire_mgcg_cgcg_init));
1635*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1636*4882a593Smuzhiyun 						 bonaire_golden_registers,
1637*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(bonaire_golden_registers));
1638*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1639*4882a593Smuzhiyun 						 bonaire_golden_common_registers,
1640*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(bonaire_golden_common_registers));
1641*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1642*4882a593Smuzhiyun 						 bonaire_golden_spm_registers,
1643*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(bonaire_golden_spm_registers));
1644*4882a593Smuzhiyun 		break;
1645*4882a593Smuzhiyun 	case CHIP_KABINI:
1646*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1647*4882a593Smuzhiyun 						 kalindi_mgcg_cgcg_init,
1648*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
1649*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1650*4882a593Smuzhiyun 						 kalindi_golden_registers,
1651*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_golden_registers));
1652*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1653*4882a593Smuzhiyun 						 kalindi_golden_common_registers,
1654*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_golden_common_registers));
1655*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1656*4882a593Smuzhiyun 						 kalindi_golden_spm_registers,
1657*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
1658*4882a593Smuzhiyun 		break;
1659*4882a593Smuzhiyun 	case CHIP_MULLINS:
1660*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1661*4882a593Smuzhiyun 						 kalindi_mgcg_cgcg_init,
1662*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
1663*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1664*4882a593Smuzhiyun 						 godavari_golden_registers,
1665*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(godavari_golden_registers));
1666*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1667*4882a593Smuzhiyun 						 kalindi_golden_common_registers,
1668*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_golden_common_registers));
1669*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1670*4882a593Smuzhiyun 						 kalindi_golden_spm_registers,
1671*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
1672*4882a593Smuzhiyun 		break;
1673*4882a593Smuzhiyun 	case CHIP_KAVERI:
1674*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1675*4882a593Smuzhiyun 						 spectre_mgcg_cgcg_init,
1676*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(spectre_mgcg_cgcg_init));
1677*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1678*4882a593Smuzhiyun 						 spectre_golden_registers,
1679*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(spectre_golden_registers));
1680*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1681*4882a593Smuzhiyun 						 spectre_golden_common_registers,
1682*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(spectre_golden_common_registers));
1683*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1684*4882a593Smuzhiyun 						 spectre_golden_spm_registers,
1685*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(spectre_golden_spm_registers));
1686*4882a593Smuzhiyun 		break;
1687*4882a593Smuzhiyun 	case CHIP_HAWAII:
1688*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1689*4882a593Smuzhiyun 						 hawaii_mgcg_cgcg_init,
1690*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(hawaii_mgcg_cgcg_init));
1691*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1692*4882a593Smuzhiyun 						 hawaii_golden_registers,
1693*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(hawaii_golden_registers));
1694*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1695*4882a593Smuzhiyun 						 hawaii_golden_common_registers,
1696*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(hawaii_golden_common_registers));
1697*4882a593Smuzhiyun 		radeon_program_register_sequence(rdev,
1698*4882a593Smuzhiyun 						 hawaii_golden_spm_registers,
1699*4882a593Smuzhiyun 						 (const u32)ARRAY_SIZE(hawaii_golden_spm_registers));
1700*4882a593Smuzhiyun 		break;
1701*4882a593Smuzhiyun 	default:
1702*4882a593Smuzhiyun 		break;
1703*4882a593Smuzhiyun 	}
1704*4882a593Smuzhiyun }
1705*4882a593Smuzhiyun 
1706*4882a593Smuzhiyun /**
1707*4882a593Smuzhiyun  * cik_get_xclk - get the xclk
1708*4882a593Smuzhiyun  *
1709*4882a593Smuzhiyun  * @rdev: radeon_device pointer
1710*4882a593Smuzhiyun  *
1711*4882a593Smuzhiyun  * Returns the reference clock used by the gfx engine
1712*4882a593Smuzhiyun  * (CIK).
1713*4882a593Smuzhiyun  */
cik_get_xclk(struct radeon_device * rdev)1714*4882a593Smuzhiyun u32 cik_get_xclk(struct radeon_device *rdev)
1715*4882a593Smuzhiyun {
1716*4882a593Smuzhiyun 	u32 reference_clock = rdev->clock.spll.reference_freq;
1717*4882a593Smuzhiyun 
1718*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP) {
1719*4882a593Smuzhiyun 		if (RREG32_SMC(GENERAL_PWRMGT) & GPU_COUNTER_CLK)
1720*4882a593Smuzhiyun 			return reference_clock / 2;
1721*4882a593Smuzhiyun 	} else {
1722*4882a593Smuzhiyun 		if (RREG32_SMC(CG_CLKPIN_CNTL) & XTALIN_DIVIDE)
1723*4882a593Smuzhiyun 			return reference_clock / 4;
1724*4882a593Smuzhiyun 	}
1725*4882a593Smuzhiyun 	return reference_clock;
1726*4882a593Smuzhiyun }
1727*4882a593Smuzhiyun 
1728*4882a593Smuzhiyun /**
1729*4882a593Smuzhiyun  * cik_mm_rdoorbell - read a doorbell dword
1730*4882a593Smuzhiyun  *
1731*4882a593Smuzhiyun  * @rdev: radeon_device pointer
1732*4882a593Smuzhiyun  * @index: doorbell index
1733*4882a593Smuzhiyun  *
1734*4882a593Smuzhiyun  * Returns the value in the doorbell aperture at the
1735*4882a593Smuzhiyun  * requested doorbell index (CIK).
1736*4882a593Smuzhiyun  */
cik_mm_rdoorbell(struct radeon_device * rdev,u32 index)1737*4882a593Smuzhiyun u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index)
1738*4882a593Smuzhiyun {
1739*4882a593Smuzhiyun 	if (index < rdev->doorbell.num_doorbells) {
1740*4882a593Smuzhiyun 		return readl(rdev->doorbell.ptr + index);
1741*4882a593Smuzhiyun 	} else {
1742*4882a593Smuzhiyun 		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
1743*4882a593Smuzhiyun 		return 0;
1744*4882a593Smuzhiyun 	}
1745*4882a593Smuzhiyun }
1746*4882a593Smuzhiyun 
1747*4882a593Smuzhiyun /**
1748*4882a593Smuzhiyun  * cik_mm_wdoorbell - write a doorbell dword
1749*4882a593Smuzhiyun  *
1750*4882a593Smuzhiyun  * @rdev: radeon_device pointer
1751*4882a593Smuzhiyun  * @index: doorbell index
1752*4882a593Smuzhiyun  * @v: value to write
1753*4882a593Smuzhiyun  *
1754*4882a593Smuzhiyun  * Writes @v to the doorbell aperture at the
1755*4882a593Smuzhiyun  * requested doorbell index (CIK).
1756*4882a593Smuzhiyun  */
cik_mm_wdoorbell(struct radeon_device * rdev,u32 index,u32 v)1757*4882a593Smuzhiyun void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v)
1758*4882a593Smuzhiyun {
1759*4882a593Smuzhiyun 	if (index < rdev->doorbell.num_doorbells) {
1760*4882a593Smuzhiyun 		writel(v, rdev->doorbell.ptr + index);
1761*4882a593Smuzhiyun 	} else {
1762*4882a593Smuzhiyun 		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
1763*4882a593Smuzhiyun 	}
1764*4882a593Smuzhiyun }
1765*4882a593Smuzhiyun 
1766*4882a593Smuzhiyun #define BONAIRE_IO_MC_REGS_SIZE 36
1767*4882a593Smuzhiyun 
1768*4882a593Smuzhiyun static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
1769*4882a593Smuzhiyun {
1770*4882a593Smuzhiyun 	{0x00000070, 0x04400000},
1771*4882a593Smuzhiyun 	{0x00000071, 0x80c01803},
1772*4882a593Smuzhiyun 	{0x00000072, 0x00004004},
1773*4882a593Smuzhiyun 	{0x00000073, 0x00000100},
1774*4882a593Smuzhiyun 	{0x00000074, 0x00ff0000},
1775*4882a593Smuzhiyun 	{0x00000075, 0x34000000},
1776*4882a593Smuzhiyun 	{0x00000076, 0x08000014},
1777*4882a593Smuzhiyun 	{0x00000077, 0x00cc08ec},
1778*4882a593Smuzhiyun 	{0x00000078, 0x00000400},
1779*4882a593Smuzhiyun 	{0x00000079, 0x00000000},
1780*4882a593Smuzhiyun 	{0x0000007a, 0x04090000},
1781*4882a593Smuzhiyun 	{0x0000007c, 0x00000000},
1782*4882a593Smuzhiyun 	{0x0000007e, 0x4408a8e8},
1783*4882a593Smuzhiyun 	{0x0000007f, 0x00000304},
1784*4882a593Smuzhiyun 	{0x00000080, 0x00000000},
1785*4882a593Smuzhiyun 	{0x00000082, 0x00000001},
1786*4882a593Smuzhiyun 	{0x00000083, 0x00000002},
1787*4882a593Smuzhiyun 	{0x00000084, 0xf3e4f400},
1788*4882a593Smuzhiyun 	{0x00000085, 0x052024e3},
1789*4882a593Smuzhiyun 	{0x00000087, 0x00000000},
1790*4882a593Smuzhiyun 	{0x00000088, 0x01000000},
1791*4882a593Smuzhiyun 	{0x0000008a, 0x1c0a0000},
1792*4882a593Smuzhiyun 	{0x0000008b, 0xff010000},
1793*4882a593Smuzhiyun 	{0x0000008d, 0xffffefff},
1794*4882a593Smuzhiyun 	{0x0000008e, 0xfff3efff},
1795*4882a593Smuzhiyun 	{0x0000008f, 0xfff3efbf},
1796*4882a593Smuzhiyun 	{0x00000092, 0xf7ffffff},
1797*4882a593Smuzhiyun 	{0x00000093, 0xffffff7f},
1798*4882a593Smuzhiyun 	{0x00000095, 0x00101101},
1799*4882a593Smuzhiyun 	{0x00000096, 0x00000fff},
1800*4882a593Smuzhiyun 	{0x00000097, 0x00116fff},
1801*4882a593Smuzhiyun 	{0x00000098, 0x60010000},
1802*4882a593Smuzhiyun 	{0x00000099, 0x10010000},
1803*4882a593Smuzhiyun 	{0x0000009a, 0x00006000},
1804*4882a593Smuzhiyun 	{0x0000009b, 0x00001000},
1805*4882a593Smuzhiyun 	{0x0000009f, 0x00b48000}
1806*4882a593Smuzhiyun };
1807*4882a593Smuzhiyun 
1808*4882a593Smuzhiyun #define HAWAII_IO_MC_REGS_SIZE 22
1809*4882a593Smuzhiyun 
1810*4882a593Smuzhiyun static const u32 hawaii_io_mc_regs[HAWAII_IO_MC_REGS_SIZE][2] =
1811*4882a593Smuzhiyun {
1812*4882a593Smuzhiyun 	{0x0000007d, 0x40000000},
1813*4882a593Smuzhiyun 	{0x0000007e, 0x40180304},
1814*4882a593Smuzhiyun 	{0x0000007f, 0x0000ff00},
1815*4882a593Smuzhiyun 	{0x00000081, 0x00000000},
1816*4882a593Smuzhiyun 	{0x00000083, 0x00000800},
1817*4882a593Smuzhiyun 	{0x00000086, 0x00000000},
1818*4882a593Smuzhiyun 	{0x00000087, 0x00000100},
1819*4882a593Smuzhiyun 	{0x00000088, 0x00020100},
1820*4882a593Smuzhiyun 	{0x00000089, 0x00000000},
1821*4882a593Smuzhiyun 	{0x0000008b, 0x00040000},
1822*4882a593Smuzhiyun 	{0x0000008c, 0x00000100},
1823*4882a593Smuzhiyun 	{0x0000008e, 0xff010000},
1824*4882a593Smuzhiyun 	{0x00000090, 0xffffefff},
1825*4882a593Smuzhiyun 	{0x00000091, 0xfff3efff},
1826*4882a593Smuzhiyun 	{0x00000092, 0xfff3efbf},
1827*4882a593Smuzhiyun 	{0x00000093, 0xf7ffffff},
1828*4882a593Smuzhiyun 	{0x00000094, 0xffffff7f},
1829*4882a593Smuzhiyun 	{0x00000095, 0x00000fff},
1830*4882a593Smuzhiyun 	{0x00000096, 0x00116fff},
1831*4882a593Smuzhiyun 	{0x00000097, 0x60010000},
1832*4882a593Smuzhiyun 	{0x00000098, 0x10010000},
1833*4882a593Smuzhiyun 	{0x0000009f, 0x00c79000}
1834*4882a593Smuzhiyun };
1835*4882a593Smuzhiyun 
1836*4882a593Smuzhiyun 
1837*4882a593Smuzhiyun /**
1838*4882a593Smuzhiyun  * cik_srbm_select - select specific register instances
1839*4882a593Smuzhiyun  *
1840*4882a593Smuzhiyun  * @rdev: radeon_device pointer
1841*4882a593Smuzhiyun  * @me: selected ME (micro engine)
1842*4882a593Smuzhiyun  * @pipe: pipe
1843*4882a593Smuzhiyun  * @queue: queue
1844*4882a593Smuzhiyun  * @vmid: VMID
1845*4882a593Smuzhiyun  *
1846*4882a593Smuzhiyun  * Switches the currently active registers instances.  Some
1847*4882a593Smuzhiyun  * registers are instanced per VMID, others are instanced per
1848*4882a593Smuzhiyun  * me/pipe/queue combination.
1849*4882a593Smuzhiyun  */
cik_srbm_select(struct radeon_device * rdev,u32 me,u32 pipe,u32 queue,u32 vmid)1850*4882a593Smuzhiyun static void cik_srbm_select(struct radeon_device *rdev,
1851*4882a593Smuzhiyun 			    u32 me, u32 pipe, u32 queue, u32 vmid)
1852*4882a593Smuzhiyun {
1853*4882a593Smuzhiyun 	u32 srbm_gfx_cntl = (PIPEID(pipe & 0x3) |
1854*4882a593Smuzhiyun 			     MEID(me & 0x3) |
1855*4882a593Smuzhiyun 			     VMID(vmid & 0xf) |
1856*4882a593Smuzhiyun 			     QUEUEID(queue & 0x7));
1857*4882a593Smuzhiyun 	WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl);
1858*4882a593Smuzhiyun }
1859*4882a593Smuzhiyun 
1860*4882a593Smuzhiyun /* ucode loading */
1861*4882a593Smuzhiyun /**
1862*4882a593Smuzhiyun  * ci_mc_load_microcode - load MC ucode into the hw
1863*4882a593Smuzhiyun  *
1864*4882a593Smuzhiyun  * @rdev: radeon_device pointer
1865*4882a593Smuzhiyun  *
1866*4882a593Smuzhiyun  * Load the GDDR MC ucode into the hw (CIK).
1867*4882a593Smuzhiyun  * Returns 0 on success, error on failure.
1868*4882a593Smuzhiyun  */
ci_mc_load_microcode(struct radeon_device * rdev)1869*4882a593Smuzhiyun int ci_mc_load_microcode(struct radeon_device *rdev)
1870*4882a593Smuzhiyun {
1871*4882a593Smuzhiyun 	const __be32 *fw_data = NULL;
1872*4882a593Smuzhiyun 	const __le32 *new_fw_data = NULL;
1873*4882a593Smuzhiyun 	u32 running, tmp;
1874*4882a593Smuzhiyun 	u32 *io_mc_regs = NULL;
1875*4882a593Smuzhiyun 	const __le32 *new_io_mc_regs = NULL;
1876*4882a593Smuzhiyun 	int i, regs_size, ucode_size;
1877*4882a593Smuzhiyun 
1878*4882a593Smuzhiyun 	if (!rdev->mc_fw)
1879*4882a593Smuzhiyun 		return -EINVAL;
1880*4882a593Smuzhiyun 
1881*4882a593Smuzhiyun 	if (rdev->new_fw) {
1882*4882a593Smuzhiyun 		const struct mc_firmware_header_v1_0 *hdr =
1883*4882a593Smuzhiyun 			(const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
1884*4882a593Smuzhiyun 
1885*4882a593Smuzhiyun 		radeon_ucode_print_mc_hdr(&hdr->header);
1886*4882a593Smuzhiyun 
1887*4882a593Smuzhiyun 		regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
1888*4882a593Smuzhiyun 		new_io_mc_regs = (const __le32 *)
1889*4882a593Smuzhiyun 			(rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
1890*4882a593Smuzhiyun 		ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
1891*4882a593Smuzhiyun 		new_fw_data = (const __le32 *)
1892*4882a593Smuzhiyun 			(rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
1893*4882a593Smuzhiyun 	} else {
1894*4882a593Smuzhiyun 		ucode_size = rdev->mc_fw->size / 4;
1895*4882a593Smuzhiyun 
1896*4882a593Smuzhiyun 		switch (rdev->family) {
1897*4882a593Smuzhiyun 		case CHIP_BONAIRE:
1898*4882a593Smuzhiyun 			io_mc_regs = (u32 *)&bonaire_io_mc_regs;
1899*4882a593Smuzhiyun 			regs_size = BONAIRE_IO_MC_REGS_SIZE;
1900*4882a593Smuzhiyun 			break;
1901*4882a593Smuzhiyun 		case CHIP_HAWAII:
1902*4882a593Smuzhiyun 			io_mc_regs = (u32 *)&hawaii_io_mc_regs;
1903*4882a593Smuzhiyun 			regs_size = HAWAII_IO_MC_REGS_SIZE;
1904*4882a593Smuzhiyun 			break;
1905*4882a593Smuzhiyun 		default:
1906*4882a593Smuzhiyun 			return -EINVAL;
1907*4882a593Smuzhiyun 		}
1908*4882a593Smuzhiyun 		fw_data = (const __be32 *)rdev->mc_fw->data;
1909*4882a593Smuzhiyun 	}
1910*4882a593Smuzhiyun 
1911*4882a593Smuzhiyun 	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
1912*4882a593Smuzhiyun 
1913*4882a593Smuzhiyun 	if (running == 0) {
1914*4882a593Smuzhiyun 		/* reset the engine and set to writable */
1915*4882a593Smuzhiyun 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1916*4882a593Smuzhiyun 		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
1917*4882a593Smuzhiyun 
1918*4882a593Smuzhiyun 		/* load mc io regs */
1919*4882a593Smuzhiyun 		for (i = 0; i < regs_size; i++) {
1920*4882a593Smuzhiyun 			if (rdev->new_fw) {
1921*4882a593Smuzhiyun 				WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
1922*4882a593Smuzhiyun 				WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
1923*4882a593Smuzhiyun 			} else {
1924*4882a593Smuzhiyun 				WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
1925*4882a593Smuzhiyun 				WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
1926*4882a593Smuzhiyun 			}
1927*4882a593Smuzhiyun 		}
1928*4882a593Smuzhiyun 
1929*4882a593Smuzhiyun 		tmp = RREG32(MC_SEQ_MISC0);
1930*4882a593Smuzhiyun 		if ((rdev->pdev->device == 0x6649) && ((tmp & 0xff00) == 0x5600)) {
1931*4882a593Smuzhiyun 			WREG32(MC_SEQ_IO_DEBUG_INDEX, 5);
1932*4882a593Smuzhiyun 			WREG32(MC_SEQ_IO_DEBUG_DATA, 0x00000023);
1933*4882a593Smuzhiyun 			WREG32(MC_SEQ_IO_DEBUG_INDEX, 9);
1934*4882a593Smuzhiyun 			WREG32(MC_SEQ_IO_DEBUG_DATA, 0x000001f0);
1935*4882a593Smuzhiyun 		}
1936*4882a593Smuzhiyun 
1937*4882a593Smuzhiyun 		/* load the MC ucode */
1938*4882a593Smuzhiyun 		for (i = 0; i < ucode_size; i++) {
1939*4882a593Smuzhiyun 			if (rdev->new_fw)
1940*4882a593Smuzhiyun 				WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
1941*4882a593Smuzhiyun 			else
1942*4882a593Smuzhiyun 				WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
1943*4882a593Smuzhiyun 		}
1944*4882a593Smuzhiyun 
1945*4882a593Smuzhiyun 		/* put the engine back into the active state */
1946*4882a593Smuzhiyun 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1947*4882a593Smuzhiyun 		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
1948*4882a593Smuzhiyun 		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
1949*4882a593Smuzhiyun 
1950*4882a593Smuzhiyun 		/* wait for training to complete */
1951*4882a593Smuzhiyun 		for (i = 0; i < rdev->usec_timeout; i++) {
1952*4882a593Smuzhiyun 			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
1953*4882a593Smuzhiyun 				break;
1954*4882a593Smuzhiyun 			udelay(1);
1955*4882a593Smuzhiyun 		}
1956*4882a593Smuzhiyun 		for (i = 0; i < rdev->usec_timeout; i++) {
1957*4882a593Smuzhiyun 			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
1958*4882a593Smuzhiyun 				break;
1959*4882a593Smuzhiyun 			udelay(1);
1960*4882a593Smuzhiyun 		}
1961*4882a593Smuzhiyun 	}
1962*4882a593Smuzhiyun 
1963*4882a593Smuzhiyun 	return 0;
1964*4882a593Smuzhiyun }
1965*4882a593Smuzhiyun 
1966*4882a593Smuzhiyun /**
1967*4882a593Smuzhiyun  * cik_init_microcode - load ucode images from disk
1968*4882a593Smuzhiyun  *
1969*4882a593Smuzhiyun  * @rdev: radeon_device pointer
1970*4882a593Smuzhiyun  *
1971*4882a593Smuzhiyun  * Use the firmware interface to load the ucode images into
1972*4882a593Smuzhiyun  * the driver (not loaded into hw).
1973*4882a593Smuzhiyun  * Returns 0 on success, error on failure.
1974*4882a593Smuzhiyun  */
cik_init_microcode(struct radeon_device * rdev)1975*4882a593Smuzhiyun static int cik_init_microcode(struct radeon_device *rdev)
1976*4882a593Smuzhiyun {
1977*4882a593Smuzhiyun 	const char *chip_name;
1978*4882a593Smuzhiyun 	const char *new_chip_name;
1979*4882a593Smuzhiyun 	size_t pfp_req_size, me_req_size, ce_req_size,
1980*4882a593Smuzhiyun 		mec_req_size, rlc_req_size, mc_req_size = 0,
1981*4882a593Smuzhiyun 		sdma_req_size, smc_req_size = 0, mc2_req_size = 0;
1982*4882a593Smuzhiyun 	char fw_name[30];
1983*4882a593Smuzhiyun 	int new_fw = 0;
1984*4882a593Smuzhiyun 	int err;
1985*4882a593Smuzhiyun 	int num_fw;
1986*4882a593Smuzhiyun 	bool new_smc = false;
1987*4882a593Smuzhiyun 
1988*4882a593Smuzhiyun 	DRM_DEBUG("\n");
1989*4882a593Smuzhiyun 
1990*4882a593Smuzhiyun 	switch (rdev->family) {
1991*4882a593Smuzhiyun 	case CHIP_BONAIRE:
1992*4882a593Smuzhiyun 		chip_name = "BONAIRE";
1993*4882a593Smuzhiyun 		if ((rdev->pdev->revision == 0x80) ||
1994*4882a593Smuzhiyun 		    (rdev->pdev->revision == 0x81) ||
1995*4882a593Smuzhiyun 		    (rdev->pdev->device == 0x665f))
1996*4882a593Smuzhiyun 			new_smc = true;
1997*4882a593Smuzhiyun 		new_chip_name = "bonaire";
1998*4882a593Smuzhiyun 		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
1999*4882a593Smuzhiyun 		me_req_size = CIK_ME_UCODE_SIZE * 4;
2000*4882a593Smuzhiyun 		ce_req_size = CIK_CE_UCODE_SIZE * 4;
2001*4882a593Smuzhiyun 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
2002*4882a593Smuzhiyun 		rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
2003*4882a593Smuzhiyun 		mc_req_size = BONAIRE_MC_UCODE_SIZE * 4;
2004*4882a593Smuzhiyun 		mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4;
2005*4882a593Smuzhiyun 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
2006*4882a593Smuzhiyun 		smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4);
2007*4882a593Smuzhiyun 		num_fw = 8;
2008*4882a593Smuzhiyun 		break;
2009*4882a593Smuzhiyun 	case CHIP_HAWAII:
2010*4882a593Smuzhiyun 		chip_name = "HAWAII";
2011*4882a593Smuzhiyun 		if (rdev->pdev->revision == 0x80)
2012*4882a593Smuzhiyun 			new_smc = true;
2013*4882a593Smuzhiyun 		new_chip_name = "hawaii";
2014*4882a593Smuzhiyun 		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
2015*4882a593Smuzhiyun 		me_req_size = CIK_ME_UCODE_SIZE * 4;
2016*4882a593Smuzhiyun 		ce_req_size = CIK_CE_UCODE_SIZE * 4;
2017*4882a593Smuzhiyun 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
2018*4882a593Smuzhiyun 		rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
2019*4882a593Smuzhiyun 		mc_req_size = HAWAII_MC_UCODE_SIZE * 4;
2020*4882a593Smuzhiyun 		mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4;
2021*4882a593Smuzhiyun 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
2022*4882a593Smuzhiyun 		smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4);
2023*4882a593Smuzhiyun 		num_fw = 8;
2024*4882a593Smuzhiyun 		break;
2025*4882a593Smuzhiyun 	case CHIP_KAVERI:
2026*4882a593Smuzhiyun 		chip_name = "KAVERI";
2027*4882a593Smuzhiyun 		new_chip_name = "kaveri";
2028*4882a593Smuzhiyun 		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
2029*4882a593Smuzhiyun 		me_req_size = CIK_ME_UCODE_SIZE * 4;
2030*4882a593Smuzhiyun 		ce_req_size = CIK_CE_UCODE_SIZE * 4;
2031*4882a593Smuzhiyun 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
2032*4882a593Smuzhiyun 		rlc_req_size = KV_RLC_UCODE_SIZE * 4;
2033*4882a593Smuzhiyun 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
2034*4882a593Smuzhiyun 		num_fw = 7;
2035*4882a593Smuzhiyun 		break;
2036*4882a593Smuzhiyun 	case CHIP_KABINI:
2037*4882a593Smuzhiyun 		chip_name = "KABINI";
2038*4882a593Smuzhiyun 		new_chip_name = "kabini";
2039*4882a593Smuzhiyun 		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
2040*4882a593Smuzhiyun 		me_req_size = CIK_ME_UCODE_SIZE * 4;
2041*4882a593Smuzhiyun 		ce_req_size = CIK_CE_UCODE_SIZE * 4;
2042*4882a593Smuzhiyun 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
2043*4882a593Smuzhiyun 		rlc_req_size = KB_RLC_UCODE_SIZE * 4;
2044*4882a593Smuzhiyun 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
2045*4882a593Smuzhiyun 		num_fw = 6;
2046*4882a593Smuzhiyun 		break;
2047*4882a593Smuzhiyun 	case CHIP_MULLINS:
2048*4882a593Smuzhiyun 		chip_name = "MULLINS";
2049*4882a593Smuzhiyun 		new_chip_name = "mullins";
2050*4882a593Smuzhiyun 		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
2051*4882a593Smuzhiyun 		me_req_size = CIK_ME_UCODE_SIZE * 4;
2052*4882a593Smuzhiyun 		ce_req_size = CIK_CE_UCODE_SIZE * 4;
2053*4882a593Smuzhiyun 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
2054*4882a593Smuzhiyun 		rlc_req_size = ML_RLC_UCODE_SIZE * 4;
2055*4882a593Smuzhiyun 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
2056*4882a593Smuzhiyun 		num_fw = 6;
2057*4882a593Smuzhiyun 		break;
2058*4882a593Smuzhiyun 	default: BUG();
2059*4882a593Smuzhiyun 	}
2060*4882a593Smuzhiyun 
2061*4882a593Smuzhiyun 	DRM_INFO("Loading %s Microcode\n", new_chip_name);
2062*4882a593Smuzhiyun 
2063*4882a593Smuzhiyun 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name);
2064*4882a593Smuzhiyun 	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
2065*4882a593Smuzhiyun 	if (err) {
2066*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
2067*4882a593Smuzhiyun 		err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
2068*4882a593Smuzhiyun 		if (err)
2069*4882a593Smuzhiyun 			goto out;
2070*4882a593Smuzhiyun 		if (rdev->pfp_fw->size != pfp_req_size) {
2071*4882a593Smuzhiyun 			pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n",
2072*4882a593Smuzhiyun 			       rdev->pfp_fw->size, fw_name);
2073*4882a593Smuzhiyun 			err = -EINVAL;
2074*4882a593Smuzhiyun 			goto out;
2075*4882a593Smuzhiyun 		}
2076*4882a593Smuzhiyun 	} else {
2077*4882a593Smuzhiyun 		err = radeon_ucode_validate(rdev->pfp_fw);
2078*4882a593Smuzhiyun 		if (err) {
2079*4882a593Smuzhiyun 			pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2080*4882a593Smuzhiyun 			       fw_name);
2081*4882a593Smuzhiyun 			goto out;
2082*4882a593Smuzhiyun 		} else {
2083*4882a593Smuzhiyun 			new_fw++;
2084*4882a593Smuzhiyun 		}
2085*4882a593Smuzhiyun 	}
2086*4882a593Smuzhiyun 
2087*4882a593Smuzhiyun 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name);
2088*4882a593Smuzhiyun 	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
2089*4882a593Smuzhiyun 	if (err) {
2090*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
2091*4882a593Smuzhiyun 		err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
2092*4882a593Smuzhiyun 		if (err)
2093*4882a593Smuzhiyun 			goto out;
2094*4882a593Smuzhiyun 		if (rdev->me_fw->size != me_req_size) {
2095*4882a593Smuzhiyun 			pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n",
2096*4882a593Smuzhiyun 			       rdev->me_fw->size, fw_name);
2097*4882a593Smuzhiyun 			err = -EINVAL;
2098*4882a593Smuzhiyun 		}
2099*4882a593Smuzhiyun 	} else {
2100*4882a593Smuzhiyun 		err = radeon_ucode_validate(rdev->me_fw);
2101*4882a593Smuzhiyun 		if (err) {
2102*4882a593Smuzhiyun 			pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2103*4882a593Smuzhiyun 			       fw_name);
2104*4882a593Smuzhiyun 			goto out;
2105*4882a593Smuzhiyun 		} else {
2106*4882a593Smuzhiyun 			new_fw++;
2107*4882a593Smuzhiyun 		}
2108*4882a593Smuzhiyun 	}
2109*4882a593Smuzhiyun 
2110*4882a593Smuzhiyun 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name);
2111*4882a593Smuzhiyun 	err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
2112*4882a593Smuzhiyun 	if (err) {
2113*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
2114*4882a593Smuzhiyun 		err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
2115*4882a593Smuzhiyun 		if (err)
2116*4882a593Smuzhiyun 			goto out;
2117*4882a593Smuzhiyun 		if (rdev->ce_fw->size != ce_req_size) {
2118*4882a593Smuzhiyun 			pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n",
2119*4882a593Smuzhiyun 			       rdev->ce_fw->size, fw_name);
2120*4882a593Smuzhiyun 			err = -EINVAL;
2121*4882a593Smuzhiyun 		}
2122*4882a593Smuzhiyun 	} else {
2123*4882a593Smuzhiyun 		err = radeon_ucode_validate(rdev->ce_fw);
2124*4882a593Smuzhiyun 		if (err) {
2125*4882a593Smuzhiyun 			pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2126*4882a593Smuzhiyun 			       fw_name);
2127*4882a593Smuzhiyun 			goto out;
2128*4882a593Smuzhiyun 		} else {
2129*4882a593Smuzhiyun 			new_fw++;
2130*4882a593Smuzhiyun 		}
2131*4882a593Smuzhiyun 	}
2132*4882a593Smuzhiyun 
2133*4882a593Smuzhiyun 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", new_chip_name);
2134*4882a593Smuzhiyun 	err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev);
2135*4882a593Smuzhiyun 	if (err) {
2136*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name);
2137*4882a593Smuzhiyun 		err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev);
2138*4882a593Smuzhiyun 		if (err)
2139*4882a593Smuzhiyun 			goto out;
2140*4882a593Smuzhiyun 		if (rdev->mec_fw->size != mec_req_size) {
2141*4882a593Smuzhiyun 			pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n",
2142*4882a593Smuzhiyun 			       rdev->mec_fw->size, fw_name);
2143*4882a593Smuzhiyun 			err = -EINVAL;
2144*4882a593Smuzhiyun 		}
2145*4882a593Smuzhiyun 	} else {
2146*4882a593Smuzhiyun 		err = radeon_ucode_validate(rdev->mec_fw);
2147*4882a593Smuzhiyun 		if (err) {
2148*4882a593Smuzhiyun 			pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2149*4882a593Smuzhiyun 			       fw_name);
2150*4882a593Smuzhiyun 			goto out;
2151*4882a593Smuzhiyun 		} else {
2152*4882a593Smuzhiyun 			new_fw++;
2153*4882a593Smuzhiyun 		}
2154*4882a593Smuzhiyun 	}
2155*4882a593Smuzhiyun 
2156*4882a593Smuzhiyun 	if (rdev->family == CHIP_KAVERI) {
2157*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec2.bin", new_chip_name);
2158*4882a593Smuzhiyun 		err = request_firmware(&rdev->mec2_fw, fw_name, rdev->dev);
2159*4882a593Smuzhiyun 		if (err) {
2160*4882a593Smuzhiyun 			goto out;
2161*4882a593Smuzhiyun 		} else {
2162*4882a593Smuzhiyun 			err = radeon_ucode_validate(rdev->mec2_fw);
2163*4882a593Smuzhiyun 			if (err) {
2164*4882a593Smuzhiyun 				goto out;
2165*4882a593Smuzhiyun 			} else {
2166*4882a593Smuzhiyun 				new_fw++;
2167*4882a593Smuzhiyun 			}
2168*4882a593Smuzhiyun 		}
2169*4882a593Smuzhiyun 	}
2170*4882a593Smuzhiyun 
2171*4882a593Smuzhiyun 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name);
2172*4882a593Smuzhiyun 	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
2173*4882a593Smuzhiyun 	if (err) {
2174*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
2175*4882a593Smuzhiyun 		err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
2176*4882a593Smuzhiyun 		if (err)
2177*4882a593Smuzhiyun 			goto out;
2178*4882a593Smuzhiyun 		if (rdev->rlc_fw->size != rlc_req_size) {
2179*4882a593Smuzhiyun 			pr_err("cik_rlc: Bogus length %zu in firmware \"%s\"\n",
2180*4882a593Smuzhiyun 			       rdev->rlc_fw->size, fw_name);
2181*4882a593Smuzhiyun 			err = -EINVAL;
2182*4882a593Smuzhiyun 		}
2183*4882a593Smuzhiyun 	} else {
2184*4882a593Smuzhiyun 		err = radeon_ucode_validate(rdev->rlc_fw);
2185*4882a593Smuzhiyun 		if (err) {
2186*4882a593Smuzhiyun 			pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2187*4882a593Smuzhiyun 			       fw_name);
2188*4882a593Smuzhiyun 			goto out;
2189*4882a593Smuzhiyun 		} else {
2190*4882a593Smuzhiyun 			new_fw++;
2191*4882a593Smuzhiyun 		}
2192*4882a593Smuzhiyun 	}
2193*4882a593Smuzhiyun 
2194*4882a593Smuzhiyun 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", new_chip_name);
2195*4882a593Smuzhiyun 	err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev);
2196*4882a593Smuzhiyun 	if (err) {
2197*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name);
2198*4882a593Smuzhiyun 		err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev);
2199*4882a593Smuzhiyun 		if (err)
2200*4882a593Smuzhiyun 			goto out;
2201*4882a593Smuzhiyun 		if (rdev->sdma_fw->size != sdma_req_size) {
2202*4882a593Smuzhiyun 			pr_err("cik_sdma: Bogus length %zu in firmware \"%s\"\n",
2203*4882a593Smuzhiyun 			       rdev->sdma_fw->size, fw_name);
2204*4882a593Smuzhiyun 			err = -EINVAL;
2205*4882a593Smuzhiyun 		}
2206*4882a593Smuzhiyun 	} else {
2207*4882a593Smuzhiyun 		err = radeon_ucode_validate(rdev->sdma_fw);
2208*4882a593Smuzhiyun 		if (err) {
2209*4882a593Smuzhiyun 			pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2210*4882a593Smuzhiyun 			       fw_name);
2211*4882a593Smuzhiyun 			goto out;
2212*4882a593Smuzhiyun 		} else {
2213*4882a593Smuzhiyun 			new_fw++;
2214*4882a593Smuzhiyun 		}
2215*4882a593Smuzhiyun 	}
2216*4882a593Smuzhiyun 
2217*4882a593Smuzhiyun 	/* No SMC, MC ucode on APUs */
2218*4882a593Smuzhiyun 	if (!(rdev->flags & RADEON_IS_IGP)) {
2219*4882a593Smuzhiyun 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name);
2220*4882a593Smuzhiyun 		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
2221*4882a593Smuzhiyun 		if (err) {
2222*4882a593Smuzhiyun 			snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
2223*4882a593Smuzhiyun 			err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
2224*4882a593Smuzhiyun 			if (err) {
2225*4882a593Smuzhiyun 				snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
2226*4882a593Smuzhiyun 				err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
2227*4882a593Smuzhiyun 				if (err)
2228*4882a593Smuzhiyun 					goto out;
2229*4882a593Smuzhiyun 			}
2230*4882a593Smuzhiyun 			if ((rdev->mc_fw->size != mc_req_size) &&
2231*4882a593Smuzhiyun 			    (rdev->mc_fw->size != mc2_req_size)){
2232*4882a593Smuzhiyun 				pr_err("cik_mc: Bogus length %zu in firmware \"%s\"\n",
2233*4882a593Smuzhiyun 				       rdev->mc_fw->size, fw_name);
2234*4882a593Smuzhiyun 				err = -EINVAL;
2235*4882a593Smuzhiyun 			}
2236*4882a593Smuzhiyun 			DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
2237*4882a593Smuzhiyun 		} else {
2238*4882a593Smuzhiyun 			err = radeon_ucode_validate(rdev->mc_fw);
2239*4882a593Smuzhiyun 			if (err) {
2240*4882a593Smuzhiyun 				pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2241*4882a593Smuzhiyun 				       fw_name);
2242*4882a593Smuzhiyun 				goto out;
2243*4882a593Smuzhiyun 			} else {
2244*4882a593Smuzhiyun 				new_fw++;
2245*4882a593Smuzhiyun 			}
2246*4882a593Smuzhiyun 		}
2247*4882a593Smuzhiyun 
2248*4882a593Smuzhiyun 		if (new_smc)
2249*4882a593Smuzhiyun 			snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name);
2250*4882a593Smuzhiyun 		else
2251*4882a593Smuzhiyun 			snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name);
2252*4882a593Smuzhiyun 		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
2253*4882a593Smuzhiyun 		if (err) {
2254*4882a593Smuzhiyun 			snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
2255*4882a593Smuzhiyun 			err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
2256*4882a593Smuzhiyun 			if (err) {
2257*4882a593Smuzhiyun 				pr_err("smc: error loading firmware \"%s\"\n",
2258*4882a593Smuzhiyun 				       fw_name);
2259*4882a593Smuzhiyun 				release_firmware(rdev->smc_fw);
2260*4882a593Smuzhiyun 				rdev->smc_fw = NULL;
2261*4882a593Smuzhiyun 				err = 0;
2262*4882a593Smuzhiyun 			} else if (rdev->smc_fw->size != smc_req_size) {
2263*4882a593Smuzhiyun 				pr_err("cik_smc: Bogus length %zu in firmware \"%s\"\n",
2264*4882a593Smuzhiyun 				       rdev->smc_fw->size, fw_name);
2265*4882a593Smuzhiyun 				err = -EINVAL;
2266*4882a593Smuzhiyun 			}
2267*4882a593Smuzhiyun 		} else {
2268*4882a593Smuzhiyun 			err = radeon_ucode_validate(rdev->smc_fw);
2269*4882a593Smuzhiyun 			if (err) {
2270*4882a593Smuzhiyun 				pr_err("cik_fw: validation failed for firmware \"%s\"\n",
2271*4882a593Smuzhiyun 				       fw_name);
2272*4882a593Smuzhiyun 				goto out;
2273*4882a593Smuzhiyun 			} else {
2274*4882a593Smuzhiyun 				new_fw++;
2275*4882a593Smuzhiyun 			}
2276*4882a593Smuzhiyun 		}
2277*4882a593Smuzhiyun 	}
2278*4882a593Smuzhiyun 
2279*4882a593Smuzhiyun 	if (new_fw == 0) {
2280*4882a593Smuzhiyun 		rdev->new_fw = false;
2281*4882a593Smuzhiyun 	} else if (new_fw < num_fw) {
2282*4882a593Smuzhiyun 		pr_err("ci_fw: mixing new and old firmware!\n");
2283*4882a593Smuzhiyun 		err = -EINVAL;
2284*4882a593Smuzhiyun 	} else {
2285*4882a593Smuzhiyun 		rdev->new_fw = true;
2286*4882a593Smuzhiyun 	}
2287*4882a593Smuzhiyun 
2288*4882a593Smuzhiyun out:
2289*4882a593Smuzhiyun 	if (err) {
2290*4882a593Smuzhiyun 		if (err != -EINVAL)
2291*4882a593Smuzhiyun 			pr_err("cik_cp: Failed to load firmware \"%s\"\n",
2292*4882a593Smuzhiyun 			       fw_name);
2293*4882a593Smuzhiyun 		release_firmware(rdev->pfp_fw);
2294*4882a593Smuzhiyun 		rdev->pfp_fw = NULL;
2295*4882a593Smuzhiyun 		release_firmware(rdev->me_fw);
2296*4882a593Smuzhiyun 		rdev->me_fw = NULL;
2297*4882a593Smuzhiyun 		release_firmware(rdev->ce_fw);
2298*4882a593Smuzhiyun 		rdev->ce_fw = NULL;
2299*4882a593Smuzhiyun 		release_firmware(rdev->mec_fw);
2300*4882a593Smuzhiyun 		rdev->mec_fw = NULL;
2301*4882a593Smuzhiyun 		release_firmware(rdev->mec2_fw);
2302*4882a593Smuzhiyun 		rdev->mec2_fw = NULL;
2303*4882a593Smuzhiyun 		release_firmware(rdev->rlc_fw);
2304*4882a593Smuzhiyun 		rdev->rlc_fw = NULL;
2305*4882a593Smuzhiyun 		release_firmware(rdev->sdma_fw);
2306*4882a593Smuzhiyun 		rdev->sdma_fw = NULL;
2307*4882a593Smuzhiyun 		release_firmware(rdev->mc_fw);
2308*4882a593Smuzhiyun 		rdev->mc_fw = NULL;
2309*4882a593Smuzhiyun 		release_firmware(rdev->smc_fw);
2310*4882a593Smuzhiyun 		rdev->smc_fw = NULL;
2311*4882a593Smuzhiyun 	}
2312*4882a593Smuzhiyun 	return err;
2313*4882a593Smuzhiyun }
2314*4882a593Smuzhiyun 
2315*4882a593Smuzhiyun /*
2316*4882a593Smuzhiyun  * Core functions
2317*4882a593Smuzhiyun  */
2318*4882a593Smuzhiyun /**
2319*4882a593Smuzhiyun  * cik_tiling_mode_table_init - init the hw tiling table
2320*4882a593Smuzhiyun  *
2321*4882a593Smuzhiyun  * @rdev: radeon_device pointer
2322*4882a593Smuzhiyun  *
2323*4882a593Smuzhiyun  * Starting with SI, the tiling setup is done globally in a
2324*4882a593Smuzhiyun  * set of 32 tiling modes.  Rather than selecting each set of
2325*4882a593Smuzhiyun  * parameters per surface as on older asics, we just select
2326*4882a593Smuzhiyun  * which index in the tiling table we want to use, and the
2327*4882a593Smuzhiyun  * surface uses those parameters (CIK).
2328*4882a593Smuzhiyun  */
cik_tiling_mode_table_init(struct radeon_device * rdev)2329*4882a593Smuzhiyun static void cik_tiling_mode_table_init(struct radeon_device *rdev)
2330*4882a593Smuzhiyun {
2331*4882a593Smuzhiyun 	u32 *tile = rdev->config.cik.tile_mode_array;
2332*4882a593Smuzhiyun 	u32 *macrotile = rdev->config.cik.macrotile_mode_array;
2333*4882a593Smuzhiyun 	const u32 num_tile_mode_states =
2334*4882a593Smuzhiyun 			ARRAY_SIZE(rdev->config.cik.tile_mode_array);
2335*4882a593Smuzhiyun 	const u32 num_secondary_tile_mode_states =
2336*4882a593Smuzhiyun 			ARRAY_SIZE(rdev->config.cik.macrotile_mode_array);
2337*4882a593Smuzhiyun 	u32 reg_offset, split_equal_to_row_size;
2338*4882a593Smuzhiyun 	u32 num_pipe_configs;
2339*4882a593Smuzhiyun 	u32 num_rbs = rdev->config.cik.max_backends_per_se *
2340*4882a593Smuzhiyun 		rdev->config.cik.max_shader_engines;
2341*4882a593Smuzhiyun 
2342*4882a593Smuzhiyun 	switch (rdev->config.cik.mem_row_size_in_kb) {
2343*4882a593Smuzhiyun 	case 1:
2344*4882a593Smuzhiyun 		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
2345*4882a593Smuzhiyun 		break;
2346*4882a593Smuzhiyun 	case 2:
2347*4882a593Smuzhiyun 	default:
2348*4882a593Smuzhiyun 		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
2349*4882a593Smuzhiyun 		break;
2350*4882a593Smuzhiyun 	case 4:
2351*4882a593Smuzhiyun 		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
2352*4882a593Smuzhiyun 		break;
2353*4882a593Smuzhiyun 	}
2354*4882a593Smuzhiyun 
2355*4882a593Smuzhiyun 	num_pipe_configs = rdev->config.cik.max_tile_pipes;
2356*4882a593Smuzhiyun 	if (num_pipe_configs > 8)
2357*4882a593Smuzhiyun 		num_pipe_configs = 16;
2358*4882a593Smuzhiyun 
2359*4882a593Smuzhiyun 	for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2360*4882a593Smuzhiyun 		tile[reg_offset] = 0;
2361*4882a593Smuzhiyun 	for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
2362*4882a593Smuzhiyun 		macrotile[reg_offset] = 0;
2363*4882a593Smuzhiyun 
2364*4882a593Smuzhiyun 	switch(num_pipe_configs) {
2365*4882a593Smuzhiyun 	case 16:
2366*4882a593Smuzhiyun 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2367*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2368*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2369*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
2370*4882a593Smuzhiyun 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2371*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2372*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2373*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
2374*4882a593Smuzhiyun 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2375*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2376*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2377*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2378*4882a593Smuzhiyun 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2379*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2380*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2381*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
2382*4882a593Smuzhiyun 		tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2383*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2384*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2385*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2386*4882a593Smuzhiyun 		tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2387*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2388*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
2389*4882a593Smuzhiyun 		tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2390*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2391*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2392*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2393*4882a593Smuzhiyun 		tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2394*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2395*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2396*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2397*4882a593Smuzhiyun 		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2398*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16));
2399*4882a593Smuzhiyun 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2400*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2401*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
2402*4882a593Smuzhiyun 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2403*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2404*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2405*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2406*4882a593Smuzhiyun 		tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2407*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2408*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
2409*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2410*4882a593Smuzhiyun 		tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2411*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2412*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2413*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2414*4882a593Smuzhiyun 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2415*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2416*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
2417*4882a593Smuzhiyun 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2418*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2419*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2420*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2421*4882a593Smuzhiyun 		tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2422*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2423*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
2424*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2425*4882a593Smuzhiyun 		tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2426*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2427*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2428*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2429*4882a593Smuzhiyun 		tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2430*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2431*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
2432*4882a593Smuzhiyun 		tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2433*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2434*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2435*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2436*4882a593Smuzhiyun 		tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2437*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2438*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) |
2439*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2440*4882a593Smuzhiyun 		tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2441*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2442*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) |
2443*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2444*4882a593Smuzhiyun 
2445*4882a593Smuzhiyun 		macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2446*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2447*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2448*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_16_BANK));
2449*4882a593Smuzhiyun 		macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2450*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2451*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2452*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_16_BANK));
2453*4882a593Smuzhiyun 		macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2454*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2455*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2456*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_16_BANK));
2457*4882a593Smuzhiyun 		macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2458*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2459*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2460*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_16_BANK));
2461*4882a593Smuzhiyun 		macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2462*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2463*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2464*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_8_BANK));
2465*4882a593Smuzhiyun 		macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2466*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2467*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2468*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_4_BANK));
2469*4882a593Smuzhiyun 		macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2470*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2471*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2472*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_2_BANK));
2473*4882a593Smuzhiyun 		macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2474*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2475*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2476*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_16_BANK));
2477*4882a593Smuzhiyun 		macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2478*4882a593Smuzhiyun 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2479*4882a593Smuzhiyun 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2480*4882a593Smuzhiyun 			   NUM_BANKS(ADDR_SURF_16_BANK));
2481*4882a593Smuzhiyun 		macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2482*4882a593Smuzhiyun 			    BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2483*4882a593Smuzhiyun 			    MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2484*4882a593Smuzhiyun 			    NUM_BANKS(ADDR_SURF_16_BANK));
2485*4882a593Smuzhiyun 		macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2486*4882a593Smuzhiyun 			    BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2487*4882a593Smuzhiyun 			    MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2488*4882a593Smuzhiyun 			    NUM_BANKS(ADDR_SURF_8_BANK));
2489*4882a593Smuzhiyun 		macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2490*4882a593Smuzhiyun 			    BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2491*4882a593Smuzhiyun 			    MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2492*4882a593Smuzhiyun 			    NUM_BANKS(ADDR_SURF_4_BANK));
2493*4882a593Smuzhiyun 		macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2494*4882a593Smuzhiyun 			    BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2495*4882a593Smuzhiyun 			    MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2496*4882a593Smuzhiyun 			    NUM_BANKS(ADDR_SURF_2_BANK));
2497*4882a593Smuzhiyun 		macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2498*4882a593Smuzhiyun 			    BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2499*4882a593Smuzhiyun 			    MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2500*4882a593Smuzhiyun 			    NUM_BANKS(ADDR_SURF_2_BANK));
2501*4882a593Smuzhiyun 
2502*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2503*4882a593Smuzhiyun 			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2504*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
2505*4882a593Smuzhiyun 			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]);
2506*4882a593Smuzhiyun 		break;
2507*4882a593Smuzhiyun 
2508*4882a593Smuzhiyun 	case 8:
2509*4882a593Smuzhiyun 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2510*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2511*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2512*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
2513*4882a593Smuzhiyun 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2514*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2515*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2516*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
2517*4882a593Smuzhiyun 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2518*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2519*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2520*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2521*4882a593Smuzhiyun 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2522*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2523*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2524*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
2525*4882a593Smuzhiyun 		tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2526*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2527*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2528*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2529*4882a593Smuzhiyun 		tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2530*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2531*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
2532*4882a593Smuzhiyun 		tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2533*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2534*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2535*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2536*4882a593Smuzhiyun 		tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2537*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2538*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2539*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2540*4882a593Smuzhiyun 		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2541*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16));
2542*4882a593Smuzhiyun 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2543*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2544*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
2545*4882a593Smuzhiyun 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2546*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2547*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2548*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2549*4882a593Smuzhiyun 		tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2550*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2551*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2552*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2553*4882a593Smuzhiyun 		tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2554*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2555*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2556*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2557*4882a593Smuzhiyun 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2558*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2559*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
2560*4882a593Smuzhiyun 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2561*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2562*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2563*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2564*4882a593Smuzhiyun 		tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2565*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2566*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2567*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2568*4882a593Smuzhiyun 		tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2569*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2570*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2571*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2572*4882a593Smuzhiyun 		tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2573*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2574*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
2575*4882a593Smuzhiyun 		tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2576*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2577*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2578*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2579*4882a593Smuzhiyun 		tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2580*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2581*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2582*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2583*4882a593Smuzhiyun 		tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2584*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2585*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
2586*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2587*4882a593Smuzhiyun 
2588*4882a593Smuzhiyun 		macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2589*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2590*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2591*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2592*4882a593Smuzhiyun 		macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2593*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2594*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2595*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2596*4882a593Smuzhiyun 		macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2597*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2598*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2599*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2600*4882a593Smuzhiyun 		macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2601*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2602*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2603*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2604*4882a593Smuzhiyun 		macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2605*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2606*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2607*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_8_BANK));
2608*4882a593Smuzhiyun 		macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2609*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2610*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2611*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_4_BANK));
2612*4882a593Smuzhiyun 		macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2613*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2614*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2615*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_2_BANK));
2616*4882a593Smuzhiyun 		macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2617*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
2618*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2619*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2620*4882a593Smuzhiyun 		macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2621*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2622*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2623*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2624*4882a593Smuzhiyun 		macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2625*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2626*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2627*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2628*4882a593Smuzhiyun 		macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2629*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2630*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2631*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2632*4882a593Smuzhiyun 		macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2633*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2634*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2635*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_8_BANK));
2636*4882a593Smuzhiyun 		macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2637*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2638*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2639*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_4_BANK));
2640*4882a593Smuzhiyun 		macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2641*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2642*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2643*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_2_BANK));
2644*4882a593Smuzhiyun 
2645*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2646*4882a593Smuzhiyun 			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2647*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
2648*4882a593Smuzhiyun 			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]);
2649*4882a593Smuzhiyun 		break;
2650*4882a593Smuzhiyun 
2651*4882a593Smuzhiyun 	case 4:
2652*4882a593Smuzhiyun 		if (num_rbs == 4) {
2653*4882a593Smuzhiyun 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2654*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2655*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2656*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
2657*4882a593Smuzhiyun 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2658*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2659*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2660*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
2661*4882a593Smuzhiyun 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2662*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2663*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2664*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2665*4882a593Smuzhiyun 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2666*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2667*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2668*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
2669*4882a593Smuzhiyun 		tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2670*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2671*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2672*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2673*4882a593Smuzhiyun 		tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2674*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2675*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
2676*4882a593Smuzhiyun 		tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2677*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2678*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2679*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2680*4882a593Smuzhiyun 		tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2681*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2682*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2683*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2684*4882a593Smuzhiyun 		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2685*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16));
2686*4882a593Smuzhiyun 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2687*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2688*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
2689*4882a593Smuzhiyun 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2690*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2691*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2692*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2693*4882a593Smuzhiyun 		tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2694*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2695*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2696*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2697*4882a593Smuzhiyun 		tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2698*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2699*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2700*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2701*4882a593Smuzhiyun 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2702*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2703*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
2704*4882a593Smuzhiyun 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2705*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2706*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2707*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2708*4882a593Smuzhiyun 		tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2709*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2710*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2711*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2712*4882a593Smuzhiyun 		tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2713*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2714*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2715*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2716*4882a593Smuzhiyun 		tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2717*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2718*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
2719*4882a593Smuzhiyun 		tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2720*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2721*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2722*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2723*4882a593Smuzhiyun 		tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2724*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2725*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2726*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2727*4882a593Smuzhiyun 		tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2728*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2729*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_16x16) |
2730*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2731*4882a593Smuzhiyun 
2732*4882a593Smuzhiyun 		} else if (num_rbs < 4) {
2733*4882a593Smuzhiyun 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2734*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2735*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2736*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
2737*4882a593Smuzhiyun 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2738*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2739*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2740*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
2741*4882a593Smuzhiyun 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2742*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2743*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2744*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2745*4882a593Smuzhiyun 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2746*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2747*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2748*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
2749*4882a593Smuzhiyun 		tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2750*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2751*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2752*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2753*4882a593Smuzhiyun 		tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2754*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2755*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
2756*4882a593Smuzhiyun 		tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2757*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2758*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2759*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2760*4882a593Smuzhiyun 		tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2761*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2762*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2763*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2764*4882a593Smuzhiyun 		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2765*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16));
2766*4882a593Smuzhiyun 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2767*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2768*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
2769*4882a593Smuzhiyun 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2770*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2771*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2772*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2773*4882a593Smuzhiyun 		tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2774*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2775*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2776*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2777*4882a593Smuzhiyun 		tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2778*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2779*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2780*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2781*4882a593Smuzhiyun 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2782*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2783*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
2784*4882a593Smuzhiyun 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2785*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2786*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2787*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2788*4882a593Smuzhiyun 		tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2789*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2790*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2791*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2792*4882a593Smuzhiyun 		tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2793*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2794*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2795*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2796*4882a593Smuzhiyun 		tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2797*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2798*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
2799*4882a593Smuzhiyun 		tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2800*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2801*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2802*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2803*4882a593Smuzhiyun 		tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2804*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2805*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2806*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2807*4882a593Smuzhiyun 		tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2808*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2809*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2810*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2811*4882a593Smuzhiyun 		}
2812*4882a593Smuzhiyun 
2813*4882a593Smuzhiyun 		macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2814*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2815*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2816*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2817*4882a593Smuzhiyun 		macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2818*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2819*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2820*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2821*4882a593Smuzhiyun 		macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2822*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2823*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2824*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2825*4882a593Smuzhiyun 		macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2826*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2827*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2828*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2829*4882a593Smuzhiyun 		macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2830*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2831*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2832*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2833*4882a593Smuzhiyun 		macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2834*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2835*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2836*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_8_BANK));
2837*4882a593Smuzhiyun 		macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2838*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2839*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2840*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_4_BANK));
2841*4882a593Smuzhiyun 		macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2842*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
2843*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2844*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2845*4882a593Smuzhiyun 		macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2846*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2847*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2848*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2849*4882a593Smuzhiyun 		macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2850*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2851*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2852*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2853*4882a593Smuzhiyun 		macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2854*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2855*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2856*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2857*4882a593Smuzhiyun 		macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2858*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2859*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2860*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2861*4882a593Smuzhiyun 		macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2862*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2863*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2864*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_8_BANK));
2865*4882a593Smuzhiyun 		macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2866*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2867*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
2868*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_4_BANK));
2869*4882a593Smuzhiyun 
2870*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2871*4882a593Smuzhiyun 			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2872*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
2873*4882a593Smuzhiyun 			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]);
2874*4882a593Smuzhiyun 		break;
2875*4882a593Smuzhiyun 
2876*4882a593Smuzhiyun 	case 2:
2877*4882a593Smuzhiyun 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2878*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2879*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2880*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
2881*4882a593Smuzhiyun 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2882*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2883*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2884*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
2885*4882a593Smuzhiyun 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2886*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2887*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2888*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2889*4882a593Smuzhiyun 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2890*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2891*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2892*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
2893*4882a593Smuzhiyun 		tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2894*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2895*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2896*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2897*4882a593Smuzhiyun 		tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2898*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2899*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
2900*4882a593Smuzhiyun 		tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2901*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2902*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2903*4882a593Smuzhiyun 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
2904*4882a593Smuzhiyun 		tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2905*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
2906*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2) |
2907*4882a593Smuzhiyun 			   TILE_SPLIT(split_equal_to_row_size));
2908*4882a593Smuzhiyun 		tile[8] = ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2909*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2);
2910*4882a593Smuzhiyun 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2911*4882a593Smuzhiyun 			   MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2912*4882a593Smuzhiyun 			   PIPE_CONFIG(ADDR_SURF_P2));
2913*4882a593Smuzhiyun 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2914*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2915*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2916*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2917*4882a593Smuzhiyun 		tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2918*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2919*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2920*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2921*4882a593Smuzhiyun 		tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2922*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
2923*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2924*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2925*4882a593Smuzhiyun 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2926*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2927*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
2928*4882a593Smuzhiyun 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2929*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2930*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2931*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2932*4882a593Smuzhiyun 		tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2933*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2934*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2935*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2936*4882a593Smuzhiyun 		tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2937*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
2938*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2939*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2940*4882a593Smuzhiyun 		tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2941*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2942*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2));
2943*4882a593Smuzhiyun 		tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2944*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2945*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2946*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2947*4882a593Smuzhiyun 		tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
2948*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2949*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2950*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2951*4882a593Smuzhiyun 		tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
2952*4882a593Smuzhiyun 			    MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
2953*4882a593Smuzhiyun 			    PIPE_CONFIG(ADDR_SURF_P2) |
2954*4882a593Smuzhiyun 			    SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
2955*4882a593Smuzhiyun 
2956*4882a593Smuzhiyun 		macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2957*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2958*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2959*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2960*4882a593Smuzhiyun 		macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2961*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2962*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2963*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2964*4882a593Smuzhiyun 		macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2965*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2966*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2967*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2968*4882a593Smuzhiyun 		macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2969*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2970*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2971*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2972*4882a593Smuzhiyun 		macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2973*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2974*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2975*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2976*4882a593Smuzhiyun 		macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2977*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2978*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2979*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2980*4882a593Smuzhiyun 		macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2981*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2982*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
2983*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_8_BANK));
2984*4882a593Smuzhiyun 		macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) |
2985*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
2986*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2987*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2988*4882a593Smuzhiyun 		macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) |
2989*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2990*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2991*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2992*4882a593Smuzhiyun 		macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2993*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2994*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2995*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
2996*4882a593Smuzhiyun 		macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2997*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2998*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
2999*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
3000*4882a593Smuzhiyun 		macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
3001*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
3002*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
3003*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
3004*4882a593Smuzhiyun 		macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
3005*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
3006*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
3007*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_16_BANK));
3008*4882a593Smuzhiyun 		macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
3009*4882a593Smuzhiyun 				BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
3010*4882a593Smuzhiyun 				MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
3011*4882a593Smuzhiyun 				NUM_BANKS(ADDR_SURF_8_BANK));
3012*4882a593Smuzhiyun 
3013*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
3014*4882a593Smuzhiyun 			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
3015*4882a593Smuzhiyun 		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++)
3016*4882a593Smuzhiyun 			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]);
3017*4882a593Smuzhiyun 		break;
3018*4882a593Smuzhiyun 
3019*4882a593Smuzhiyun 	default:
3020*4882a593Smuzhiyun 		DRM_ERROR("unknown num pipe config: 0x%x\n", num_pipe_configs);
3021*4882a593Smuzhiyun 	}
3022*4882a593Smuzhiyun }
3023*4882a593Smuzhiyun 
3024*4882a593Smuzhiyun /**
3025*4882a593Smuzhiyun  * cik_select_se_sh - select which SE, SH to address
3026*4882a593Smuzhiyun  *
3027*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3028*4882a593Smuzhiyun  * @se_num: shader engine to address
3029*4882a593Smuzhiyun  * @sh_num: sh block to address
3030*4882a593Smuzhiyun  *
3031*4882a593Smuzhiyun  * Select which SE, SH combinations to address. Certain
3032*4882a593Smuzhiyun  * registers are instanced per SE or SH.  0xffffffff means
3033*4882a593Smuzhiyun  * broadcast to all SEs or SHs (CIK).
3034*4882a593Smuzhiyun  */
cik_select_se_sh(struct radeon_device * rdev,u32 se_num,u32 sh_num)3035*4882a593Smuzhiyun static void cik_select_se_sh(struct radeon_device *rdev,
3036*4882a593Smuzhiyun 			     u32 se_num, u32 sh_num)
3037*4882a593Smuzhiyun {
3038*4882a593Smuzhiyun 	u32 data = INSTANCE_BROADCAST_WRITES;
3039*4882a593Smuzhiyun 
3040*4882a593Smuzhiyun 	if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
3041*4882a593Smuzhiyun 		data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
3042*4882a593Smuzhiyun 	else if (se_num == 0xffffffff)
3043*4882a593Smuzhiyun 		data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
3044*4882a593Smuzhiyun 	else if (sh_num == 0xffffffff)
3045*4882a593Smuzhiyun 		data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
3046*4882a593Smuzhiyun 	else
3047*4882a593Smuzhiyun 		data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
3048*4882a593Smuzhiyun 	WREG32(GRBM_GFX_INDEX, data);
3049*4882a593Smuzhiyun }
3050*4882a593Smuzhiyun 
3051*4882a593Smuzhiyun /**
3052*4882a593Smuzhiyun  * cik_create_bitmask - create a bitmask
3053*4882a593Smuzhiyun  *
3054*4882a593Smuzhiyun  * @bit_width: length of the mask
3055*4882a593Smuzhiyun  *
3056*4882a593Smuzhiyun  * create a variable length bit mask (CIK).
3057*4882a593Smuzhiyun  * Returns the bitmask.
3058*4882a593Smuzhiyun  */
cik_create_bitmask(u32 bit_width)3059*4882a593Smuzhiyun static u32 cik_create_bitmask(u32 bit_width)
3060*4882a593Smuzhiyun {
3061*4882a593Smuzhiyun 	u32 i, mask = 0;
3062*4882a593Smuzhiyun 
3063*4882a593Smuzhiyun 	for (i = 0; i < bit_width; i++) {
3064*4882a593Smuzhiyun 		mask <<= 1;
3065*4882a593Smuzhiyun 		mask |= 1;
3066*4882a593Smuzhiyun 	}
3067*4882a593Smuzhiyun 	return mask;
3068*4882a593Smuzhiyun }
3069*4882a593Smuzhiyun 
3070*4882a593Smuzhiyun /**
3071*4882a593Smuzhiyun  * cik_get_rb_disabled - computes the mask of disabled RBs
3072*4882a593Smuzhiyun  *
3073*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3074*4882a593Smuzhiyun  * @max_rb_num: max RBs (render backends) for the asic
3075*4882a593Smuzhiyun  * @se_num: number of SEs (shader engines) for the asic
3076*4882a593Smuzhiyun  * @sh_per_se: number of SH blocks per SE for the asic
3077*4882a593Smuzhiyun  *
3078*4882a593Smuzhiyun  * Calculates the bitmask of disabled RBs (CIK).
3079*4882a593Smuzhiyun  * Returns the disabled RB bitmask.
3080*4882a593Smuzhiyun  */
cik_get_rb_disabled(struct radeon_device * rdev,u32 max_rb_num_per_se,u32 sh_per_se)3081*4882a593Smuzhiyun static u32 cik_get_rb_disabled(struct radeon_device *rdev,
3082*4882a593Smuzhiyun 			      u32 max_rb_num_per_se,
3083*4882a593Smuzhiyun 			      u32 sh_per_se)
3084*4882a593Smuzhiyun {
3085*4882a593Smuzhiyun 	u32 data, mask;
3086*4882a593Smuzhiyun 
3087*4882a593Smuzhiyun 	data = RREG32(CC_RB_BACKEND_DISABLE);
3088*4882a593Smuzhiyun 	if (data & 1)
3089*4882a593Smuzhiyun 		data &= BACKEND_DISABLE_MASK;
3090*4882a593Smuzhiyun 	else
3091*4882a593Smuzhiyun 		data = 0;
3092*4882a593Smuzhiyun 	data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
3093*4882a593Smuzhiyun 
3094*4882a593Smuzhiyun 	data >>= BACKEND_DISABLE_SHIFT;
3095*4882a593Smuzhiyun 
3096*4882a593Smuzhiyun 	mask = cik_create_bitmask(max_rb_num_per_se / sh_per_se);
3097*4882a593Smuzhiyun 
3098*4882a593Smuzhiyun 	return data & mask;
3099*4882a593Smuzhiyun }
3100*4882a593Smuzhiyun 
3101*4882a593Smuzhiyun /**
3102*4882a593Smuzhiyun  * cik_setup_rb - setup the RBs on the asic
3103*4882a593Smuzhiyun  *
3104*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3105*4882a593Smuzhiyun  * @se_num: number of SEs (shader engines) for the asic
3106*4882a593Smuzhiyun  * @sh_per_se: number of SH blocks per SE for the asic
3107*4882a593Smuzhiyun  * @max_rb_num: max RBs (render backends) for the asic
3108*4882a593Smuzhiyun  *
3109*4882a593Smuzhiyun  * Configures per-SE/SH RB registers (CIK).
3110*4882a593Smuzhiyun  */
cik_setup_rb(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 max_rb_num_per_se)3111*4882a593Smuzhiyun static void cik_setup_rb(struct radeon_device *rdev,
3112*4882a593Smuzhiyun 			 u32 se_num, u32 sh_per_se,
3113*4882a593Smuzhiyun 			 u32 max_rb_num_per_se)
3114*4882a593Smuzhiyun {
3115*4882a593Smuzhiyun 	int i, j;
3116*4882a593Smuzhiyun 	u32 data, mask;
3117*4882a593Smuzhiyun 	u32 disabled_rbs = 0;
3118*4882a593Smuzhiyun 	u32 enabled_rbs = 0;
3119*4882a593Smuzhiyun 
3120*4882a593Smuzhiyun 	for (i = 0; i < se_num; i++) {
3121*4882a593Smuzhiyun 		for (j = 0; j < sh_per_se; j++) {
3122*4882a593Smuzhiyun 			cik_select_se_sh(rdev, i, j);
3123*4882a593Smuzhiyun 			data = cik_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se);
3124*4882a593Smuzhiyun 			if (rdev->family == CHIP_HAWAII)
3125*4882a593Smuzhiyun 				disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH);
3126*4882a593Smuzhiyun 			else
3127*4882a593Smuzhiyun 				disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH);
3128*4882a593Smuzhiyun 		}
3129*4882a593Smuzhiyun 	}
3130*4882a593Smuzhiyun 	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3131*4882a593Smuzhiyun 
3132*4882a593Smuzhiyun 	mask = 1;
3133*4882a593Smuzhiyun 	for (i = 0; i < max_rb_num_per_se * se_num; i++) {
3134*4882a593Smuzhiyun 		if (!(disabled_rbs & mask))
3135*4882a593Smuzhiyun 			enabled_rbs |= mask;
3136*4882a593Smuzhiyun 		mask <<= 1;
3137*4882a593Smuzhiyun 	}
3138*4882a593Smuzhiyun 
3139*4882a593Smuzhiyun 	rdev->config.cik.backend_enable_mask = enabled_rbs;
3140*4882a593Smuzhiyun 
3141*4882a593Smuzhiyun 	for (i = 0; i < se_num; i++) {
3142*4882a593Smuzhiyun 		cik_select_se_sh(rdev, i, 0xffffffff);
3143*4882a593Smuzhiyun 		data = 0;
3144*4882a593Smuzhiyun 		for (j = 0; j < sh_per_se; j++) {
3145*4882a593Smuzhiyun 			switch (enabled_rbs & 3) {
3146*4882a593Smuzhiyun 			case 0:
3147*4882a593Smuzhiyun 				if (j == 0)
3148*4882a593Smuzhiyun 					data |= PKR_MAP(RASTER_CONFIG_RB_MAP_3);
3149*4882a593Smuzhiyun 				else
3150*4882a593Smuzhiyun 					data |= PKR_MAP(RASTER_CONFIG_RB_MAP_0);
3151*4882a593Smuzhiyun 				break;
3152*4882a593Smuzhiyun 			case 1:
3153*4882a593Smuzhiyun 				data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
3154*4882a593Smuzhiyun 				break;
3155*4882a593Smuzhiyun 			case 2:
3156*4882a593Smuzhiyun 				data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
3157*4882a593Smuzhiyun 				break;
3158*4882a593Smuzhiyun 			case 3:
3159*4882a593Smuzhiyun 			default:
3160*4882a593Smuzhiyun 				data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
3161*4882a593Smuzhiyun 				break;
3162*4882a593Smuzhiyun 			}
3163*4882a593Smuzhiyun 			enabled_rbs >>= 2;
3164*4882a593Smuzhiyun 		}
3165*4882a593Smuzhiyun 		WREG32(PA_SC_RASTER_CONFIG, data);
3166*4882a593Smuzhiyun 	}
3167*4882a593Smuzhiyun 	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3168*4882a593Smuzhiyun }
3169*4882a593Smuzhiyun 
3170*4882a593Smuzhiyun /**
3171*4882a593Smuzhiyun  * cik_gpu_init - setup the 3D engine
3172*4882a593Smuzhiyun  *
3173*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3174*4882a593Smuzhiyun  *
3175*4882a593Smuzhiyun  * Configures the 3D engine and tiling configuration
3176*4882a593Smuzhiyun  * registers so that the 3D engine is usable.
3177*4882a593Smuzhiyun  */
cik_gpu_init(struct radeon_device * rdev)3178*4882a593Smuzhiyun static void cik_gpu_init(struct radeon_device *rdev)
3179*4882a593Smuzhiyun {
3180*4882a593Smuzhiyun 	u32 gb_addr_config = RREG32(GB_ADDR_CONFIG);
3181*4882a593Smuzhiyun 	u32 mc_shared_chmap, mc_arb_ramcfg;
3182*4882a593Smuzhiyun 	u32 hdp_host_path_cntl;
3183*4882a593Smuzhiyun 	u32 tmp;
3184*4882a593Smuzhiyun 	int i, j;
3185*4882a593Smuzhiyun 
3186*4882a593Smuzhiyun 	switch (rdev->family) {
3187*4882a593Smuzhiyun 	case CHIP_BONAIRE:
3188*4882a593Smuzhiyun 		rdev->config.cik.max_shader_engines = 2;
3189*4882a593Smuzhiyun 		rdev->config.cik.max_tile_pipes = 4;
3190*4882a593Smuzhiyun 		rdev->config.cik.max_cu_per_sh = 7;
3191*4882a593Smuzhiyun 		rdev->config.cik.max_sh_per_se = 1;
3192*4882a593Smuzhiyun 		rdev->config.cik.max_backends_per_se = 2;
3193*4882a593Smuzhiyun 		rdev->config.cik.max_texture_channel_caches = 4;
3194*4882a593Smuzhiyun 		rdev->config.cik.max_gprs = 256;
3195*4882a593Smuzhiyun 		rdev->config.cik.max_gs_threads = 32;
3196*4882a593Smuzhiyun 		rdev->config.cik.max_hw_contexts = 8;
3197*4882a593Smuzhiyun 
3198*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
3199*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
3200*4882a593Smuzhiyun 		rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
3201*4882a593Smuzhiyun 		rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
3202*4882a593Smuzhiyun 		gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
3203*4882a593Smuzhiyun 		break;
3204*4882a593Smuzhiyun 	case CHIP_HAWAII:
3205*4882a593Smuzhiyun 		rdev->config.cik.max_shader_engines = 4;
3206*4882a593Smuzhiyun 		rdev->config.cik.max_tile_pipes = 16;
3207*4882a593Smuzhiyun 		rdev->config.cik.max_cu_per_sh = 11;
3208*4882a593Smuzhiyun 		rdev->config.cik.max_sh_per_se = 1;
3209*4882a593Smuzhiyun 		rdev->config.cik.max_backends_per_se = 4;
3210*4882a593Smuzhiyun 		rdev->config.cik.max_texture_channel_caches = 16;
3211*4882a593Smuzhiyun 		rdev->config.cik.max_gprs = 256;
3212*4882a593Smuzhiyun 		rdev->config.cik.max_gs_threads = 32;
3213*4882a593Smuzhiyun 		rdev->config.cik.max_hw_contexts = 8;
3214*4882a593Smuzhiyun 
3215*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
3216*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
3217*4882a593Smuzhiyun 		rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
3218*4882a593Smuzhiyun 		rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
3219*4882a593Smuzhiyun 		gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN;
3220*4882a593Smuzhiyun 		break;
3221*4882a593Smuzhiyun 	case CHIP_KAVERI:
3222*4882a593Smuzhiyun 		rdev->config.cik.max_shader_engines = 1;
3223*4882a593Smuzhiyun 		rdev->config.cik.max_tile_pipes = 4;
3224*4882a593Smuzhiyun 		rdev->config.cik.max_cu_per_sh = 8;
3225*4882a593Smuzhiyun 		rdev->config.cik.max_backends_per_se = 2;
3226*4882a593Smuzhiyun 		rdev->config.cik.max_sh_per_se = 1;
3227*4882a593Smuzhiyun 		rdev->config.cik.max_texture_channel_caches = 4;
3228*4882a593Smuzhiyun 		rdev->config.cik.max_gprs = 256;
3229*4882a593Smuzhiyun 		rdev->config.cik.max_gs_threads = 16;
3230*4882a593Smuzhiyun 		rdev->config.cik.max_hw_contexts = 8;
3231*4882a593Smuzhiyun 
3232*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
3233*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
3234*4882a593Smuzhiyun 		rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
3235*4882a593Smuzhiyun 		rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
3236*4882a593Smuzhiyun 		gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
3237*4882a593Smuzhiyun 		break;
3238*4882a593Smuzhiyun 	case CHIP_KABINI:
3239*4882a593Smuzhiyun 	case CHIP_MULLINS:
3240*4882a593Smuzhiyun 	default:
3241*4882a593Smuzhiyun 		rdev->config.cik.max_shader_engines = 1;
3242*4882a593Smuzhiyun 		rdev->config.cik.max_tile_pipes = 2;
3243*4882a593Smuzhiyun 		rdev->config.cik.max_cu_per_sh = 2;
3244*4882a593Smuzhiyun 		rdev->config.cik.max_sh_per_se = 1;
3245*4882a593Smuzhiyun 		rdev->config.cik.max_backends_per_se = 1;
3246*4882a593Smuzhiyun 		rdev->config.cik.max_texture_channel_caches = 2;
3247*4882a593Smuzhiyun 		rdev->config.cik.max_gprs = 256;
3248*4882a593Smuzhiyun 		rdev->config.cik.max_gs_threads = 16;
3249*4882a593Smuzhiyun 		rdev->config.cik.max_hw_contexts = 8;
3250*4882a593Smuzhiyun 
3251*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
3252*4882a593Smuzhiyun 		rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
3253*4882a593Smuzhiyun 		rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
3254*4882a593Smuzhiyun 		rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
3255*4882a593Smuzhiyun 		gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
3256*4882a593Smuzhiyun 		break;
3257*4882a593Smuzhiyun 	}
3258*4882a593Smuzhiyun 
3259*4882a593Smuzhiyun 	/* Initialize HDP */
3260*4882a593Smuzhiyun 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
3261*4882a593Smuzhiyun 		WREG32((0x2c14 + j), 0x00000000);
3262*4882a593Smuzhiyun 		WREG32((0x2c18 + j), 0x00000000);
3263*4882a593Smuzhiyun 		WREG32((0x2c1c + j), 0x00000000);
3264*4882a593Smuzhiyun 		WREG32((0x2c20 + j), 0x00000000);
3265*4882a593Smuzhiyun 		WREG32((0x2c24 + j), 0x00000000);
3266*4882a593Smuzhiyun 	}
3267*4882a593Smuzhiyun 
3268*4882a593Smuzhiyun 	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
3269*4882a593Smuzhiyun 	WREG32(SRBM_INT_CNTL, 0x1);
3270*4882a593Smuzhiyun 	WREG32(SRBM_INT_ACK, 0x1);
3271*4882a593Smuzhiyun 
3272*4882a593Smuzhiyun 	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
3273*4882a593Smuzhiyun 
3274*4882a593Smuzhiyun 	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
3275*4882a593Smuzhiyun 	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
3276*4882a593Smuzhiyun 
3277*4882a593Smuzhiyun 	rdev->config.cik.num_tile_pipes = rdev->config.cik.max_tile_pipes;
3278*4882a593Smuzhiyun 	rdev->config.cik.mem_max_burst_length_bytes = 256;
3279*4882a593Smuzhiyun 	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
3280*4882a593Smuzhiyun 	rdev->config.cik.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
3281*4882a593Smuzhiyun 	if (rdev->config.cik.mem_row_size_in_kb > 4)
3282*4882a593Smuzhiyun 		rdev->config.cik.mem_row_size_in_kb = 4;
3283*4882a593Smuzhiyun 	/* XXX use MC settings? */
3284*4882a593Smuzhiyun 	rdev->config.cik.shader_engine_tile_size = 32;
3285*4882a593Smuzhiyun 	rdev->config.cik.num_gpus = 1;
3286*4882a593Smuzhiyun 	rdev->config.cik.multi_gpu_tile_size = 64;
3287*4882a593Smuzhiyun 
3288*4882a593Smuzhiyun 	/* fix up row size */
3289*4882a593Smuzhiyun 	gb_addr_config &= ~ROW_SIZE_MASK;
3290*4882a593Smuzhiyun 	switch (rdev->config.cik.mem_row_size_in_kb) {
3291*4882a593Smuzhiyun 	case 1:
3292*4882a593Smuzhiyun 	default:
3293*4882a593Smuzhiyun 		gb_addr_config |= ROW_SIZE(0);
3294*4882a593Smuzhiyun 		break;
3295*4882a593Smuzhiyun 	case 2:
3296*4882a593Smuzhiyun 		gb_addr_config |= ROW_SIZE(1);
3297*4882a593Smuzhiyun 		break;
3298*4882a593Smuzhiyun 	case 4:
3299*4882a593Smuzhiyun 		gb_addr_config |= ROW_SIZE(2);
3300*4882a593Smuzhiyun 		break;
3301*4882a593Smuzhiyun 	}
3302*4882a593Smuzhiyun 
3303*4882a593Smuzhiyun 	/* setup tiling info dword.  gb_addr_config is not adequate since it does
3304*4882a593Smuzhiyun 	 * not have bank info, so create a custom tiling dword.
3305*4882a593Smuzhiyun 	 * bits 3:0   num_pipes
3306*4882a593Smuzhiyun 	 * bits 7:4   num_banks
3307*4882a593Smuzhiyun 	 * bits 11:8  group_size
3308*4882a593Smuzhiyun 	 * bits 15:12 row_size
3309*4882a593Smuzhiyun 	 */
3310*4882a593Smuzhiyun 	rdev->config.cik.tile_config = 0;
3311*4882a593Smuzhiyun 	switch (rdev->config.cik.num_tile_pipes) {
3312*4882a593Smuzhiyun 	case 1:
3313*4882a593Smuzhiyun 		rdev->config.cik.tile_config |= (0 << 0);
3314*4882a593Smuzhiyun 		break;
3315*4882a593Smuzhiyun 	case 2:
3316*4882a593Smuzhiyun 		rdev->config.cik.tile_config |= (1 << 0);
3317*4882a593Smuzhiyun 		break;
3318*4882a593Smuzhiyun 	case 4:
3319*4882a593Smuzhiyun 		rdev->config.cik.tile_config |= (2 << 0);
3320*4882a593Smuzhiyun 		break;
3321*4882a593Smuzhiyun 	case 8:
3322*4882a593Smuzhiyun 	default:
3323*4882a593Smuzhiyun 		/* XXX what about 12? */
3324*4882a593Smuzhiyun 		rdev->config.cik.tile_config |= (3 << 0);
3325*4882a593Smuzhiyun 		break;
3326*4882a593Smuzhiyun 	}
3327*4882a593Smuzhiyun 	rdev->config.cik.tile_config |=
3328*4882a593Smuzhiyun 		((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
3329*4882a593Smuzhiyun 	rdev->config.cik.tile_config |=
3330*4882a593Smuzhiyun 		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
3331*4882a593Smuzhiyun 	rdev->config.cik.tile_config |=
3332*4882a593Smuzhiyun 		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
3333*4882a593Smuzhiyun 
3334*4882a593Smuzhiyun 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
3335*4882a593Smuzhiyun 	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
3336*4882a593Smuzhiyun 	WREG32(DMIF_ADDR_CALC, gb_addr_config);
3337*4882a593Smuzhiyun 	WREG32(SDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET, gb_addr_config & 0x70);
3338*4882a593Smuzhiyun 	WREG32(SDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET, gb_addr_config & 0x70);
3339*4882a593Smuzhiyun 	WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
3340*4882a593Smuzhiyun 	WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
3341*4882a593Smuzhiyun 	WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
3342*4882a593Smuzhiyun 
3343*4882a593Smuzhiyun 	cik_tiling_mode_table_init(rdev);
3344*4882a593Smuzhiyun 
3345*4882a593Smuzhiyun 	cik_setup_rb(rdev, rdev->config.cik.max_shader_engines,
3346*4882a593Smuzhiyun 		     rdev->config.cik.max_sh_per_se,
3347*4882a593Smuzhiyun 		     rdev->config.cik.max_backends_per_se);
3348*4882a593Smuzhiyun 
3349*4882a593Smuzhiyun 	rdev->config.cik.active_cus = 0;
3350*4882a593Smuzhiyun 	for (i = 0; i < rdev->config.cik.max_shader_engines; i++) {
3351*4882a593Smuzhiyun 		for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) {
3352*4882a593Smuzhiyun 			rdev->config.cik.active_cus +=
3353*4882a593Smuzhiyun 				hweight32(cik_get_cu_active_bitmap(rdev, i, j));
3354*4882a593Smuzhiyun 		}
3355*4882a593Smuzhiyun 	}
3356*4882a593Smuzhiyun 
3357*4882a593Smuzhiyun 	/* set HW defaults for 3D engine */
3358*4882a593Smuzhiyun 	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
3359*4882a593Smuzhiyun 
3360*4882a593Smuzhiyun 	WREG32(SX_DEBUG_1, 0x20);
3361*4882a593Smuzhiyun 
3362*4882a593Smuzhiyun 	WREG32(TA_CNTL_AUX, 0x00010000);
3363*4882a593Smuzhiyun 
3364*4882a593Smuzhiyun 	tmp = RREG32(SPI_CONFIG_CNTL);
3365*4882a593Smuzhiyun 	tmp |= 0x03000000;
3366*4882a593Smuzhiyun 	WREG32(SPI_CONFIG_CNTL, tmp);
3367*4882a593Smuzhiyun 
3368*4882a593Smuzhiyun 	WREG32(SQ_CONFIG, 1);
3369*4882a593Smuzhiyun 
3370*4882a593Smuzhiyun 	WREG32(DB_DEBUG, 0);
3371*4882a593Smuzhiyun 
3372*4882a593Smuzhiyun 	tmp = RREG32(DB_DEBUG2) & ~0xf00fffff;
3373*4882a593Smuzhiyun 	tmp |= 0x00000400;
3374*4882a593Smuzhiyun 	WREG32(DB_DEBUG2, tmp);
3375*4882a593Smuzhiyun 
3376*4882a593Smuzhiyun 	tmp = RREG32(DB_DEBUG3) & ~0x0002021c;
3377*4882a593Smuzhiyun 	tmp |= 0x00020200;
3378*4882a593Smuzhiyun 	WREG32(DB_DEBUG3, tmp);
3379*4882a593Smuzhiyun 
3380*4882a593Smuzhiyun 	tmp = RREG32(CB_HW_CONTROL) & ~0x00010000;
3381*4882a593Smuzhiyun 	tmp |= 0x00018208;
3382*4882a593Smuzhiyun 	WREG32(CB_HW_CONTROL, tmp);
3383*4882a593Smuzhiyun 
3384*4882a593Smuzhiyun 	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
3385*4882a593Smuzhiyun 
3386*4882a593Smuzhiyun 	WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.cik.sc_prim_fifo_size_frontend) |
3387*4882a593Smuzhiyun 				 SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.cik.sc_prim_fifo_size_backend) |
3388*4882a593Smuzhiyun 				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cik.sc_hiz_tile_fifo_size) |
3389*4882a593Smuzhiyun 				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cik.sc_earlyz_tile_fifo_size)));
3390*4882a593Smuzhiyun 
3391*4882a593Smuzhiyun 	WREG32(VGT_NUM_INSTANCES, 1);
3392*4882a593Smuzhiyun 
3393*4882a593Smuzhiyun 	WREG32(CP_PERFMON_CNTL, 0);
3394*4882a593Smuzhiyun 
3395*4882a593Smuzhiyun 	WREG32(SQ_CONFIG, 0);
3396*4882a593Smuzhiyun 
3397*4882a593Smuzhiyun 	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
3398*4882a593Smuzhiyun 					  FORCE_EOV_MAX_REZ_CNT(255)));
3399*4882a593Smuzhiyun 
3400*4882a593Smuzhiyun 	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
3401*4882a593Smuzhiyun 	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
3402*4882a593Smuzhiyun 
3403*4882a593Smuzhiyun 	WREG32(VGT_GS_VERTEX_REUSE, 16);
3404*4882a593Smuzhiyun 	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
3405*4882a593Smuzhiyun 
3406*4882a593Smuzhiyun 	tmp = RREG32(HDP_MISC_CNTL);
3407*4882a593Smuzhiyun 	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
3408*4882a593Smuzhiyun 	WREG32(HDP_MISC_CNTL, tmp);
3409*4882a593Smuzhiyun 
3410*4882a593Smuzhiyun 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
3411*4882a593Smuzhiyun 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
3412*4882a593Smuzhiyun 
3413*4882a593Smuzhiyun 	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
3414*4882a593Smuzhiyun 	WREG32(PA_SC_ENHANCE, ENABLE_PA_SC_OUT_OF_ORDER);
3415*4882a593Smuzhiyun 
3416*4882a593Smuzhiyun 	udelay(50);
3417*4882a593Smuzhiyun }
3418*4882a593Smuzhiyun 
3419*4882a593Smuzhiyun /*
3420*4882a593Smuzhiyun  * GPU scratch registers helpers function.
3421*4882a593Smuzhiyun  */
3422*4882a593Smuzhiyun /**
3423*4882a593Smuzhiyun  * cik_scratch_init - setup driver info for CP scratch regs
3424*4882a593Smuzhiyun  *
3425*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3426*4882a593Smuzhiyun  *
3427*4882a593Smuzhiyun  * Set up the number and offset of the CP scratch registers.
3428*4882a593Smuzhiyun  * NOTE: use of CP scratch registers is a legacy inferface and
3429*4882a593Smuzhiyun  * is not used by default on newer asics (r6xx+).  On newer asics,
3430*4882a593Smuzhiyun  * memory buffers are used for fences rather than scratch regs.
3431*4882a593Smuzhiyun  */
cik_scratch_init(struct radeon_device * rdev)3432*4882a593Smuzhiyun static void cik_scratch_init(struct radeon_device *rdev)
3433*4882a593Smuzhiyun {
3434*4882a593Smuzhiyun 	int i;
3435*4882a593Smuzhiyun 
3436*4882a593Smuzhiyun 	rdev->scratch.num_reg = 7;
3437*4882a593Smuzhiyun 	rdev->scratch.reg_base = SCRATCH_REG0;
3438*4882a593Smuzhiyun 	for (i = 0; i < rdev->scratch.num_reg; i++) {
3439*4882a593Smuzhiyun 		rdev->scratch.free[i] = true;
3440*4882a593Smuzhiyun 		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
3441*4882a593Smuzhiyun 	}
3442*4882a593Smuzhiyun }
3443*4882a593Smuzhiyun 
3444*4882a593Smuzhiyun /**
3445*4882a593Smuzhiyun  * cik_ring_test - basic gfx ring test
3446*4882a593Smuzhiyun  *
3447*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3448*4882a593Smuzhiyun  * @ring: radeon_ring structure holding ring information
3449*4882a593Smuzhiyun  *
3450*4882a593Smuzhiyun  * Allocate a scratch register and write to it using the gfx ring (CIK).
3451*4882a593Smuzhiyun  * Provides a basic gfx ring test to verify that the ring is working.
3452*4882a593Smuzhiyun  * Used by cik_cp_gfx_resume();
3453*4882a593Smuzhiyun  * Returns 0 on success, error on failure.
3454*4882a593Smuzhiyun  */
cik_ring_test(struct radeon_device * rdev,struct radeon_ring * ring)3455*4882a593Smuzhiyun int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
3456*4882a593Smuzhiyun {
3457*4882a593Smuzhiyun 	uint32_t scratch;
3458*4882a593Smuzhiyun 	uint32_t tmp = 0;
3459*4882a593Smuzhiyun 	unsigned i;
3460*4882a593Smuzhiyun 	int r;
3461*4882a593Smuzhiyun 
3462*4882a593Smuzhiyun 	r = radeon_scratch_get(rdev, &scratch);
3463*4882a593Smuzhiyun 	if (r) {
3464*4882a593Smuzhiyun 		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
3465*4882a593Smuzhiyun 		return r;
3466*4882a593Smuzhiyun 	}
3467*4882a593Smuzhiyun 	WREG32(scratch, 0xCAFEDEAD);
3468*4882a593Smuzhiyun 	r = radeon_ring_lock(rdev, ring, 3);
3469*4882a593Smuzhiyun 	if (r) {
3470*4882a593Smuzhiyun 		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ring->idx, r);
3471*4882a593Smuzhiyun 		radeon_scratch_free(rdev, scratch);
3472*4882a593Smuzhiyun 		return r;
3473*4882a593Smuzhiyun 	}
3474*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
3475*4882a593Smuzhiyun 	radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2));
3476*4882a593Smuzhiyun 	radeon_ring_write(ring, 0xDEADBEEF);
3477*4882a593Smuzhiyun 	radeon_ring_unlock_commit(rdev, ring, false);
3478*4882a593Smuzhiyun 
3479*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
3480*4882a593Smuzhiyun 		tmp = RREG32(scratch);
3481*4882a593Smuzhiyun 		if (tmp == 0xDEADBEEF)
3482*4882a593Smuzhiyun 			break;
3483*4882a593Smuzhiyun 		udelay(1);
3484*4882a593Smuzhiyun 	}
3485*4882a593Smuzhiyun 	if (i < rdev->usec_timeout) {
3486*4882a593Smuzhiyun 		DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
3487*4882a593Smuzhiyun 	} else {
3488*4882a593Smuzhiyun 		DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
3489*4882a593Smuzhiyun 			  ring->idx, scratch, tmp);
3490*4882a593Smuzhiyun 		r = -EINVAL;
3491*4882a593Smuzhiyun 	}
3492*4882a593Smuzhiyun 	radeon_scratch_free(rdev, scratch);
3493*4882a593Smuzhiyun 	return r;
3494*4882a593Smuzhiyun }
3495*4882a593Smuzhiyun 
3496*4882a593Smuzhiyun /**
3497*4882a593Smuzhiyun  * cik_hdp_flush_cp_ring_emit - emit an hdp flush on the cp
3498*4882a593Smuzhiyun  *
3499*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3500*4882a593Smuzhiyun  * @ridx: radeon ring index
3501*4882a593Smuzhiyun  *
3502*4882a593Smuzhiyun  * Emits an hdp flush on the cp.
3503*4882a593Smuzhiyun  */
cik_hdp_flush_cp_ring_emit(struct radeon_device * rdev,int ridx)3504*4882a593Smuzhiyun static void cik_hdp_flush_cp_ring_emit(struct radeon_device *rdev,
3505*4882a593Smuzhiyun 				       int ridx)
3506*4882a593Smuzhiyun {
3507*4882a593Smuzhiyun 	struct radeon_ring *ring = &rdev->ring[ridx];
3508*4882a593Smuzhiyun 	u32 ref_and_mask;
3509*4882a593Smuzhiyun 
3510*4882a593Smuzhiyun 	switch (ring->idx) {
3511*4882a593Smuzhiyun 	case CAYMAN_RING_TYPE_CP1_INDEX:
3512*4882a593Smuzhiyun 	case CAYMAN_RING_TYPE_CP2_INDEX:
3513*4882a593Smuzhiyun 	default:
3514*4882a593Smuzhiyun 		switch (ring->me) {
3515*4882a593Smuzhiyun 		case 0:
3516*4882a593Smuzhiyun 			ref_and_mask = CP2 << ring->pipe;
3517*4882a593Smuzhiyun 			break;
3518*4882a593Smuzhiyun 		case 1:
3519*4882a593Smuzhiyun 			ref_and_mask = CP6 << ring->pipe;
3520*4882a593Smuzhiyun 			break;
3521*4882a593Smuzhiyun 		default:
3522*4882a593Smuzhiyun 			return;
3523*4882a593Smuzhiyun 		}
3524*4882a593Smuzhiyun 		break;
3525*4882a593Smuzhiyun 	case RADEON_RING_TYPE_GFX_INDEX:
3526*4882a593Smuzhiyun 		ref_and_mask = CP0;
3527*4882a593Smuzhiyun 		break;
3528*4882a593Smuzhiyun 	}
3529*4882a593Smuzhiyun 
3530*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
3531*4882a593Smuzhiyun 	radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(1) | /* write, wait, write */
3532*4882a593Smuzhiyun 				 WAIT_REG_MEM_FUNCTION(3) |  /* == */
3533*4882a593Smuzhiyun 				 WAIT_REG_MEM_ENGINE(1)));   /* pfp */
3534*4882a593Smuzhiyun 	radeon_ring_write(ring, GPU_HDP_FLUSH_REQ >> 2);
3535*4882a593Smuzhiyun 	radeon_ring_write(ring, GPU_HDP_FLUSH_DONE >> 2);
3536*4882a593Smuzhiyun 	radeon_ring_write(ring, ref_and_mask);
3537*4882a593Smuzhiyun 	radeon_ring_write(ring, ref_and_mask);
3538*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x20); /* poll interval */
3539*4882a593Smuzhiyun }
3540*4882a593Smuzhiyun 
3541*4882a593Smuzhiyun /**
3542*4882a593Smuzhiyun  * cik_fence_gfx_ring_emit - emit a fence on the gfx ring
3543*4882a593Smuzhiyun  *
3544*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3545*4882a593Smuzhiyun  * @fence: radeon fence object
3546*4882a593Smuzhiyun  *
3547*4882a593Smuzhiyun  * Emits a fence sequnce number on the gfx ring and flushes
3548*4882a593Smuzhiyun  * GPU caches.
3549*4882a593Smuzhiyun  */
cik_fence_gfx_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)3550*4882a593Smuzhiyun void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
3551*4882a593Smuzhiyun 			     struct radeon_fence *fence)
3552*4882a593Smuzhiyun {
3553*4882a593Smuzhiyun 	struct radeon_ring *ring = &rdev->ring[fence->ring];
3554*4882a593Smuzhiyun 	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
3555*4882a593Smuzhiyun 
3556*4882a593Smuzhiyun 	/* Workaround for cache flush problems. First send a dummy EOP
3557*4882a593Smuzhiyun 	 * event down the pipe with seq one below.
3558*4882a593Smuzhiyun 	 */
3559*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
3560*4882a593Smuzhiyun 	radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
3561*4882a593Smuzhiyun 				 EOP_TC_ACTION_EN |
3562*4882a593Smuzhiyun 				 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
3563*4882a593Smuzhiyun 				 EVENT_INDEX(5)));
3564*4882a593Smuzhiyun 	radeon_ring_write(ring, addr & 0xfffffffc);
3565*4882a593Smuzhiyun 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) |
3566*4882a593Smuzhiyun 				DATA_SEL(1) | INT_SEL(0));
3567*4882a593Smuzhiyun 	radeon_ring_write(ring, fence->seq - 1);
3568*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
3569*4882a593Smuzhiyun 
3570*4882a593Smuzhiyun 	/* Then send the real EOP event down the pipe. */
3571*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
3572*4882a593Smuzhiyun 	radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
3573*4882a593Smuzhiyun 				 EOP_TC_ACTION_EN |
3574*4882a593Smuzhiyun 				 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
3575*4882a593Smuzhiyun 				 EVENT_INDEX(5)));
3576*4882a593Smuzhiyun 	radeon_ring_write(ring, addr & 0xfffffffc);
3577*4882a593Smuzhiyun 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(1) | INT_SEL(2));
3578*4882a593Smuzhiyun 	radeon_ring_write(ring, fence->seq);
3579*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
3580*4882a593Smuzhiyun }
3581*4882a593Smuzhiyun 
3582*4882a593Smuzhiyun /**
3583*4882a593Smuzhiyun  * cik_fence_compute_ring_emit - emit a fence on the compute ring
3584*4882a593Smuzhiyun  *
3585*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3586*4882a593Smuzhiyun  * @fence: radeon fence object
3587*4882a593Smuzhiyun  *
3588*4882a593Smuzhiyun  * Emits a fence sequnce number on the compute ring and flushes
3589*4882a593Smuzhiyun  * GPU caches.
3590*4882a593Smuzhiyun  */
cik_fence_compute_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)3591*4882a593Smuzhiyun void cik_fence_compute_ring_emit(struct radeon_device *rdev,
3592*4882a593Smuzhiyun 				 struct radeon_fence *fence)
3593*4882a593Smuzhiyun {
3594*4882a593Smuzhiyun 	struct radeon_ring *ring = &rdev->ring[fence->ring];
3595*4882a593Smuzhiyun 	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
3596*4882a593Smuzhiyun 
3597*4882a593Smuzhiyun 	/* RELEASE_MEM - flush caches, send int */
3598*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 5));
3599*4882a593Smuzhiyun 	radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
3600*4882a593Smuzhiyun 				 EOP_TC_ACTION_EN |
3601*4882a593Smuzhiyun 				 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
3602*4882a593Smuzhiyun 				 EVENT_INDEX(5)));
3603*4882a593Smuzhiyun 	radeon_ring_write(ring, DATA_SEL(1) | INT_SEL(2));
3604*4882a593Smuzhiyun 	radeon_ring_write(ring, addr & 0xfffffffc);
3605*4882a593Smuzhiyun 	radeon_ring_write(ring, upper_32_bits(addr));
3606*4882a593Smuzhiyun 	radeon_ring_write(ring, fence->seq);
3607*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
3608*4882a593Smuzhiyun }
3609*4882a593Smuzhiyun 
3610*4882a593Smuzhiyun /**
3611*4882a593Smuzhiyun  * cik_semaphore_ring_emit - emit a semaphore on the CP ring
3612*4882a593Smuzhiyun  *
3613*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3614*4882a593Smuzhiyun  * @ring: radeon ring buffer object
3615*4882a593Smuzhiyun  * @semaphore: radeon semaphore object
3616*4882a593Smuzhiyun  * @emit_wait: Is this a sempahore wait?
3617*4882a593Smuzhiyun  *
3618*4882a593Smuzhiyun  * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP
3619*4882a593Smuzhiyun  * from running ahead of semaphore waits.
3620*4882a593Smuzhiyun  */
cik_semaphore_ring_emit(struct radeon_device * rdev,struct radeon_ring * ring,struct radeon_semaphore * semaphore,bool emit_wait)3621*4882a593Smuzhiyun bool cik_semaphore_ring_emit(struct radeon_device *rdev,
3622*4882a593Smuzhiyun 			     struct radeon_ring *ring,
3623*4882a593Smuzhiyun 			     struct radeon_semaphore *semaphore,
3624*4882a593Smuzhiyun 			     bool emit_wait)
3625*4882a593Smuzhiyun {
3626*4882a593Smuzhiyun 	uint64_t addr = semaphore->gpu_addr;
3627*4882a593Smuzhiyun 	unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
3628*4882a593Smuzhiyun 
3629*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
3630*4882a593Smuzhiyun 	radeon_ring_write(ring, lower_32_bits(addr));
3631*4882a593Smuzhiyun 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel);
3632*4882a593Smuzhiyun 
3633*4882a593Smuzhiyun 	if (emit_wait && ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
3634*4882a593Smuzhiyun 		/* Prevent the PFP from running ahead of the semaphore wait */
3635*4882a593Smuzhiyun 		radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
3636*4882a593Smuzhiyun 		radeon_ring_write(ring, 0x0);
3637*4882a593Smuzhiyun 	}
3638*4882a593Smuzhiyun 
3639*4882a593Smuzhiyun 	return true;
3640*4882a593Smuzhiyun }
3641*4882a593Smuzhiyun 
3642*4882a593Smuzhiyun /**
3643*4882a593Smuzhiyun  * cik_copy_cpdma - copy pages using the CP DMA engine
3644*4882a593Smuzhiyun  *
3645*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3646*4882a593Smuzhiyun  * @src_offset: src GPU address
3647*4882a593Smuzhiyun  * @dst_offset: dst GPU address
3648*4882a593Smuzhiyun  * @num_gpu_pages: number of GPU pages to xfer
3649*4882a593Smuzhiyun  * @resv: reservation object to sync to
3650*4882a593Smuzhiyun  *
3651*4882a593Smuzhiyun  * Copy GPU paging using the CP DMA engine (CIK+).
3652*4882a593Smuzhiyun  * Used by the radeon ttm implementation to move pages if
3653*4882a593Smuzhiyun  * registered as the asic copy callback.
3654*4882a593Smuzhiyun  */
cik_copy_cpdma(struct radeon_device * rdev,uint64_t src_offset,uint64_t dst_offset,unsigned num_gpu_pages,struct dma_resv * resv)3655*4882a593Smuzhiyun struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
3656*4882a593Smuzhiyun 				    uint64_t src_offset, uint64_t dst_offset,
3657*4882a593Smuzhiyun 				    unsigned num_gpu_pages,
3658*4882a593Smuzhiyun 				    struct dma_resv *resv)
3659*4882a593Smuzhiyun {
3660*4882a593Smuzhiyun 	struct radeon_fence *fence;
3661*4882a593Smuzhiyun 	struct radeon_sync sync;
3662*4882a593Smuzhiyun 	int ring_index = rdev->asic->copy.blit_ring_index;
3663*4882a593Smuzhiyun 	struct radeon_ring *ring = &rdev->ring[ring_index];
3664*4882a593Smuzhiyun 	u32 size_in_bytes, cur_size_in_bytes, control;
3665*4882a593Smuzhiyun 	int i, num_loops;
3666*4882a593Smuzhiyun 	int r = 0;
3667*4882a593Smuzhiyun 
3668*4882a593Smuzhiyun 	radeon_sync_create(&sync);
3669*4882a593Smuzhiyun 
3670*4882a593Smuzhiyun 	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
3671*4882a593Smuzhiyun 	num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
3672*4882a593Smuzhiyun 	r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18);
3673*4882a593Smuzhiyun 	if (r) {
3674*4882a593Smuzhiyun 		DRM_ERROR("radeon: moving bo (%d).\n", r);
3675*4882a593Smuzhiyun 		radeon_sync_free(rdev, &sync, NULL);
3676*4882a593Smuzhiyun 		return ERR_PTR(r);
3677*4882a593Smuzhiyun 	}
3678*4882a593Smuzhiyun 
3679*4882a593Smuzhiyun 	radeon_sync_resv(rdev, &sync, resv, false);
3680*4882a593Smuzhiyun 	radeon_sync_rings(rdev, &sync, ring->idx);
3681*4882a593Smuzhiyun 
3682*4882a593Smuzhiyun 	for (i = 0; i < num_loops; i++) {
3683*4882a593Smuzhiyun 		cur_size_in_bytes = size_in_bytes;
3684*4882a593Smuzhiyun 		if (cur_size_in_bytes > 0x1fffff)
3685*4882a593Smuzhiyun 			cur_size_in_bytes = 0x1fffff;
3686*4882a593Smuzhiyun 		size_in_bytes -= cur_size_in_bytes;
3687*4882a593Smuzhiyun 		control = 0;
3688*4882a593Smuzhiyun 		if (size_in_bytes == 0)
3689*4882a593Smuzhiyun 			control |= PACKET3_DMA_DATA_CP_SYNC;
3690*4882a593Smuzhiyun 		radeon_ring_write(ring, PACKET3(PACKET3_DMA_DATA, 5));
3691*4882a593Smuzhiyun 		radeon_ring_write(ring, control);
3692*4882a593Smuzhiyun 		radeon_ring_write(ring, lower_32_bits(src_offset));
3693*4882a593Smuzhiyun 		radeon_ring_write(ring, upper_32_bits(src_offset));
3694*4882a593Smuzhiyun 		radeon_ring_write(ring, lower_32_bits(dst_offset));
3695*4882a593Smuzhiyun 		radeon_ring_write(ring, upper_32_bits(dst_offset));
3696*4882a593Smuzhiyun 		radeon_ring_write(ring, cur_size_in_bytes);
3697*4882a593Smuzhiyun 		src_offset += cur_size_in_bytes;
3698*4882a593Smuzhiyun 		dst_offset += cur_size_in_bytes;
3699*4882a593Smuzhiyun 	}
3700*4882a593Smuzhiyun 
3701*4882a593Smuzhiyun 	r = radeon_fence_emit(rdev, &fence, ring->idx);
3702*4882a593Smuzhiyun 	if (r) {
3703*4882a593Smuzhiyun 		radeon_ring_unlock_undo(rdev, ring);
3704*4882a593Smuzhiyun 		radeon_sync_free(rdev, &sync, NULL);
3705*4882a593Smuzhiyun 		return ERR_PTR(r);
3706*4882a593Smuzhiyun 	}
3707*4882a593Smuzhiyun 
3708*4882a593Smuzhiyun 	radeon_ring_unlock_commit(rdev, ring, false);
3709*4882a593Smuzhiyun 	radeon_sync_free(rdev, &sync, fence);
3710*4882a593Smuzhiyun 
3711*4882a593Smuzhiyun 	return fence;
3712*4882a593Smuzhiyun }
3713*4882a593Smuzhiyun 
3714*4882a593Smuzhiyun /*
3715*4882a593Smuzhiyun  * IB stuff
3716*4882a593Smuzhiyun  */
3717*4882a593Smuzhiyun /**
3718*4882a593Smuzhiyun  * cik_ring_ib_execute - emit an IB (Indirect Buffer) on the gfx ring
3719*4882a593Smuzhiyun  *
3720*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3721*4882a593Smuzhiyun  * @ib: radeon indirect buffer object
3722*4882a593Smuzhiyun  *
3723*4882a593Smuzhiyun  * Emits a DE (drawing engine) or CE (constant engine) IB
3724*4882a593Smuzhiyun  * on the gfx ring.  IBs are usually generated by userspace
3725*4882a593Smuzhiyun  * acceleration drivers and submitted to the kernel for
3726*4882a593Smuzhiyun  * scheduling on the ring.  This function schedules the IB
3727*4882a593Smuzhiyun  * on the gfx ring for execution by the GPU.
3728*4882a593Smuzhiyun  */
cik_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)3729*4882a593Smuzhiyun void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3730*4882a593Smuzhiyun {
3731*4882a593Smuzhiyun 	struct radeon_ring *ring = &rdev->ring[ib->ring];
3732*4882a593Smuzhiyun 	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
3733*4882a593Smuzhiyun 	u32 header, control = INDIRECT_BUFFER_VALID;
3734*4882a593Smuzhiyun 
3735*4882a593Smuzhiyun 	if (ib->is_const_ib) {
3736*4882a593Smuzhiyun 		/* set switch buffer packet before const IB */
3737*4882a593Smuzhiyun 		radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
3738*4882a593Smuzhiyun 		radeon_ring_write(ring, 0);
3739*4882a593Smuzhiyun 
3740*4882a593Smuzhiyun 		header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
3741*4882a593Smuzhiyun 	} else {
3742*4882a593Smuzhiyun 		u32 next_rptr;
3743*4882a593Smuzhiyun 		if (ring->rptr_save_reg) {
3744*4882a593Smuzhiyun 			next_rptr = ring->wptr + 3 + 4;
3745*4882a593Smuzhiyun 			radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
3746*4882a593Smuzhiyun 			radeon_ring_write(ring, ((ring->rptr_save_reg -
3747*4882a593Smuzhiyun 						  PACKET3_SET_UCONFIG_REG_START) >> 2));
3748*4882a593Smuzhiyun 			radeon_ring_write(ring, next_rptr);
3749*4882a593Smuzhiyun 		} else if (rdev->wb.enabled) {
3750*4882a593Smuzhiyun 			next_rptr = ring->wptr + 5 + 4;
3751*4882a593Smuzhiyun 			radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
3752*4882a593Smuzhiyun 			radeon_ring_write(ring, WRITE_DATA_DST_SEL(1));
3753*4882a593Smuzhiyun 			radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
3754*4882a593Smuzhiyun 			radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr));
3755*4882a593Smuzhiyun 			radeon_ring_write(ring, next_rptr);
3756*4882a593Smuzhiyun 		}
3757*4882a593Smuzhiyun 
3758*4882a593Smuzhiyun 		header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
3759*4882a593Smuzhiyun 	}
3760*4882a593Smuzhiyun 
3761*4882a593Smuzhiyun 	control |= ib->length_dw | (vm_id << 24);
3762*4882a593Smuzhiyun 
3763*4882a593Smuzhiyun 	radeon_ring_write(ring, header);
3764*4882a593Smuzhiyun 	radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFFC));
3765*4882a593Smuzhiyun 	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
3766*4882a593Smuzhiyun 	radeon_ring_write(ring, control);
3767*4882a593Smuzhiyun }
3768*4882a593Smuzhiyun 
3769*4882a593Smuzhiyun /**
3770*4882a593Smuzhiyun  * cik_ib_test - basic gfx ring IB test
3771*4882a593Smuzhiyun  *
3772*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3773*4882a593Smuzhiyun  * @ring: radeon_ring structure holding ring information
3774*4882a593Smuzhiyun  *
3775*4882a593Smuzhiyun  * Allocate an IB and execute it on the gfx ring (CIK).
3776*4882a593Smuzhiyun  * Provides a basic gfx ring test to verify that IBs are working.
3777*4882a593Smuzhiyun  * Returns 0 on success, error on failure.
3778*4882a593Smuzhiyun  */
cik_ib_test(struct radeon_device * rdev,struct radeon_ring * ring)3779*4882a593Smuzhiyun int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
3780*4882a593Smuzhiyun {
3781*4882a593Smuzhiyun 	struct radeon_ib ib;
3782*4882a593Smuzhiyun 	uint32_t scratch;
3783*4882a593Smuzhiyun 	uint32_t tmp = 0;
3784*4882a593Smuzhiyun 	unsigned i;
3785*4882a593Smuzhiyun 	int r;
3786*4882a593Smuzhiyun 
3787*4882a593Smuzhiyun 	r = radeon_scratch_get(rdev, &scratch);
3788*4882a593Smuzhiyun 	if (r) {
3789*4882a593Smuzhiyun 		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
3790*4882a593Smuzhiyun 		return r;
3791*4882a593Smuzhiyun 	}
3792*4882a593Smuzhiyun 	WREG32(scratch, 0xCAFEDEAD);
3793*4882a593Smuzhiyun 	r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
3794*4882a593Smuzhiyun 	if (r) {
3795*4882a593Smuzhiyun 		DRM_ERROR("radeon: failed to get ib (%d).\n", r);
3796*4882a593Smuzhiyun 		radeon_scratch_free(rdev, scratch);
3797*4882a593Smuzhiyun 		return r;
3798*4882a593Smuzhiyun 	}
3799*4882a593Smuzhiyun 	ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
3800*4882a593Smuzhiyun 	ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2);
3801*4882a593Smuzhiyun 	ib.ptr[2] = 0xDEADBEEF;
3802*4882a593Smuzhiyun 	ib.length_dw = 3;
3803*4882a593Smuzhiyun 	r = radeon_ib_schedule(rdev, &ib, NULL, false);
3804*4882a593Smuzhiyun 	if (r) {
3805*4882a593Smuzhiyun 		radeon_scratch_free(rdev, scratch);
3806*4882a593Smuzhiyun 		radeon_ib_free(rdev, &ib);
3807*4882a593Smuzhiyun 		DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
3808*4882a593Smuzhiyun 		return r;
3809*4882a593Smuzhiyun 	}
3810*4882a593Smuzhiyun 	r = radeon_fence_wait_timeout(ib.fence, false, usecs_to_jiffies(
3811*4882a593Smuzhiyun 		RADEON_USEC_IB_TEST_TIMEOUT));
3812*4882a593Smuzhiyun 	if (r < 0) {
3813*4882a593Smuzhiyun 		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
3814*4882a593Smuzhiyun 		radeon_scratch_free(rdev, scratch);
3815*4882a593Smuzhiyun 		radeon_ib_free(rdev, &ib);
3816*4882a593Smuzhiyun 		return r;
3817*4882a593Smuzhiyun 	} else if (r == 0) {
3818*4882a593Smuzhiyun 		DRM_ERROR("radeon: fence wait timed out.\n");
3819*4882a593Smuzhiyun 		radeon_scratch_free(rdev, scratch);
3820*4882a593Smuzhiyun 		radeon_ib_free(rdev, &ib);
3821*4882a593Smuzhiyun 		return -ETIMEDOUT;
3822*4882a593Smuzhiyun 	}
3823*4882a593Smuzhiyun 	r = 0;
3824*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
3825*4882a593Smuzhiyun 		tmp = RREG32(scratch);
3826*4882a593Smuzhiyun 		if (tmp == 0xDEADBEEF)
3827*4882a593Smuzhiyun 			break;
3828*4882a593Smuzhiyun 		udelay(1);
3829*4882a593Smuzhiyun 	}
3830*4882a593Smuzhiyun 	if (i < rdev->usec_timeout) {
3831*4882a593Smuzhiyun 		DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i);
3832*4882a593Smuzhiyun 	} else {
3833*4882a593Smuzhiyun 		DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n",
3834*4882a593Smuzhiyun 			  scratch, tmp);
3835*4882a593Smuzhiyun 		r = -EINVAL;
3836*4882a593Smuzhiyun 	}
3837*4882a593Smuzhiyun 	radeon_scratch_free(rdev, scratch);
3838*4882a593Smuzhiyun 	radeon_ib_free(rdev, &ib);
3839*4882a593Smuzhiyun 	return r;
3840*4882a593Smuzhiyun }
3841*4882a593Smuzhiyun 
3842*4882a593Smuzhiyun /*
3843*4882a593Smuzhiyun  * CP.
3844*4882a593Smuzhiyun  * On CIK, gfx and compute now have independant command processors.
3845*4882a593Smuzhiyun  *
3846*4882a593Smuzhiyun  * GFX
3847*4882a593Smuzhiyun  * Gfx consists of a single ring and can process both gfx jobs and
3848*4882a593Smuzhiyun  * compute jobs.  The gfx CP consists of three microengines (ME):
3849*4882a593Smuzhiyun  * PFP - Pre-Fetch Parser
3850*4882a593Smuzhiyun  * ME - Micro Engine
3851*4882a593Smuzhiyun  * CE - Constant Engine
3852*4882a593Smuzhiyun  * The PFP and ME make up what is considered the Drawing Engine (DE).
3853*4882a593Smuzhiyun  * The CE is an asynchronous engine used for updating buffer desciptors
3854*4882a593Smuzhiyun  * used by the DE so that they can be loaded into cache in parallel
3855*4882a593Smuzhiyun  * while the DE is processing state update packets.
3856*4882a593Smuzhiyun  *
3857*4882a593Smuzhiyun  * Compute
3858*4882a593Smuzhiyun  * The compute CP consists of two microengines (ME):
3859*4882a593Smuzhiyun  * MEC1 - Compute MicroEngine 1
3860*4882a593Smuzhiyun  * MEC2 - Compute MicroEngine 2
3861*4882a593Smuzhiyun  * Each MEC supports 4 compute pipes and each pipe supports 8 queues.
3862*4882a593Smuzhiyun  * The queues are exposed to userspace and are programmed directly
3863*4882a593Smuzhiyun  * by the compute runtime.
3864*4882a593Smuzhiyun  */
3865*4882a593Smuzhiyun /**
3866*4882a593Smuzhiyun  * cik_cp_gfx_enable - enable/disable the gfx CP MEs
3867*4882a593Smuzhiyun  *
3868*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3869*4882a593Smuzhiyun  * @enable: enable or disable the MEs
3870*4882a593Smuzhiyun  *
3871*4882a593Smuzhiyun  * Halts or unhalts the gfx MEs.
3872*4882a593Smuzhiyun  */
cik_cp_gfx_enable(struct radeon_device * rdev,bool enable)3873*4882a593Smuzhiyun static void cik_cp_gfx_enable(struct radeon_device *rdev, bool enable)
3874*4882a593Smuzhiyun {
3875*4882a593Smuzhiyun 	if (enable)
3876*4882a593Smuzhiyun 		WREG32(CP_ME_CNTL, 0);
3877*4882a593Smuzhiyun 	else {
3878*4882a593Smuzhiyun 		if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3879*4882a593Smuzhiyun 			radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
3880*4882a593Smuzhiyun 		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
3881*4882a593Smuzhiyun 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3882*4882a593Smuzhiyun 	}
3883*4882a593Smuzhiyun 	udelay(50);
3884*4882a593Smuzhiyun }
3885*4882a593Smuzhiyun 
3886*4882a593Smuzhiyun /**
3887*4882a593Smuzhiyun  * cik_cp_gfx_load_microcode - load the gfx CP ME ucode
3888*4882a593Smuzhiyun  *
3889*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3890*4882a593Smuzhiyun  *
3891*4882a593Smuzhiyun  * Loads the gfx PFP, ME, and CE ucode.
3892*4882a593Smuzhiyun  * Returns 0 for success, -EINVAL if the ucode is not available.
3893*4882a593Smuzhiyun  */
cik_cp_gfx_load_microcode(struct radeon_device * rdev)3894*4882a593Smuzhiyun static int cik_cp_gfx_load_microcode(struct radeon_device *rdev)
3895*4882a593Smuzhiyun {
3896*4882a593Smuzhiyun 	int i;
3897*4882a593Smuzhiyun 
3898*4882a593Smuzhiyun 	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
3899*4882a593Smuzhiyun 		return -EINVAL;
3900*4882a593Smuzhiyun 
3901*4882a593Smuzhiyun 	cik_cp_gfx_enable(rdev, false);
3902*4882a593Smuzhiyun 
3903*4882a593Smuzhiyun 	if (rdev->new_fw) {
3904*4882a593Smuzhiyun 		const struct gfx_firmware_header_v1_0 *pfp_hdr =
3905*4882a593Smuzhiyun 			(const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
3906*4882a593Smuzhiyun 		const struct gfx_firmware_header_v1_0 *ce_hdr =
3907*4882a593Smuzhiyun 			(const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
3908*4882a593Smuzhiyun 		const struct gfx_firmware_header_v1_0 *me_hdr =
3909*4882a593Smuzhiyun 			(const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
3910*4882a593Smuzhiyun 		const __le32 *fw_data;
3911*4882a593Smuzhiyun 		u32 fw_size;
3912*4882a593Smuzhiyun 
3913*4882a593Smuzhiyun 		radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
3914*4882a593Smuzhiyun 		radeon_ucode_print_gfx_hdr(&ce_hdr->header);
3915*4882a593Smuzhiyun 		radeon_ucode_print_gfx_hdr(&me_hdr->header);
3916*4882a593Smuzhiyun 
3917*4882a593Smuzhiyun 		/* PFP */
3918*4882a593Smuzhiyun 		fw_data = (const __le32 *)
3919*4882a593Smuzhiyun 			(rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
3920*4882a593Smuzhiyun 		fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
3921*4882a593Smuzhiyun 		WREG32(CP_PFP_UCODE_ADDR, 0);
3922*4882a593Smuzhiyun 		for (i = 0; i < fw_size; i++)
3923*4882a593Smuzhiyun 			WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
3924*4882a593Smuzhiyun 		WREG32(CP_PFP_UCODE_ADDR, le32_to_cpu(pfp_hdr->header.ucode_version));
3925*4882a593Smuzhiyun 
3926*4882a593Smuzhiyun 		/* CE */
3927*4882a593Smuzhiyun 		fw_data = (const __le32 *)
3928*4882a593Smuzhiyun 			(rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
3929*4882a593Smuzhiyun 		fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
3930*4882a593Smuzhiyun 		WREG32(CP_CE_UCODE_ADDR, 0);
3931*4882a593Smuzhiyun 		for (i = 0; i < fw_size; i++)
3932*4882a593Smuzhiyun 			WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
3933*4882a593Smuzhiyun 		WREG32(CP_CE_UCODE_ADDR, le32_to_cpu(ce_hdr->header.ucode_version));
3934*4882a593Smuzhiyun 
3935*4882a593Smuzhiyun 		/* ME */
3936*4882a593Smuzhiyun 		fw_data = (const __be32 *)
3937*4882a593Smuzhiyun 			(rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
3938*4882a593Smuzhiyun 		fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
3939*4882a593Smuzhiyun 		WREG32(CP_ME_RAM_WADDR, 0);
3940*4882a593Smuzhiyun 		for (i = 0; i < fw_size; i++)
3941*4882a593Smuzhiyun 			WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
3942*4882a593Smuzhiyun 		WREG32(CP_ME_RAM_WADDR, le32_to_cpu(me_hdr->header.ucode_version));
3943*4882a593Smuzhiyun 		WREG32(CP_ME_RAM_RADDR, le32_to_cpu(me_hdr->header.ucode_version));
3944*4882a593Smuzhiyun 	} else {
3945*4882a593Smuzhiyun 		const __be32 *fw_data;
3946*4882a593Smuzhiyun 
3947*4882a593Smuzhiyun 		/* PFP */
3948*4882a593Smuzhiyun 		fw_data = (const __be32 *)rdev->pfp_fw->data;
3949*4882a593Smuzhiyun 		WREG32(CP_PFP_UCODE_ADDR, 0);
3950*4882a593Smuzhiyun 		for (i = 0; i < CIK_PFP_UCODE_SIZE; i++)
3951*4882a593Smuzhiyun 			WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
3952*4882a593Smuzhiyun 		WREG32(CP_PFP_UCODE_ADDR, 0);
3953*4882a593Smuzhiyun 
3954*4882a593Smuzhiyun 		/* CE */
3955*4882a593Smuzhiyun 		fw_data = (const __be32 *)rdev->ce_fw->data;
3956*4882a593Smuzhiyun 		WREG32(CP_CE_UCODE_ADDR, 0);
3957*4882a593Smuzhiyun 		for (i = 0; i < CIK_CE_UCODE_SIZE; i++)
3958*4882a593Smuzhiyun 			WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
3959*4882a593Smuzhiyun 		WREG32(CP_CE_UCODE_ADDR, 0);
3960*4882a593Smuzhiyun 
3961*4882a593Smuzhiyun 		/* ME */
3962*4882a593Smuzhiyun 		fw_data = (const __be32 *)rdev->me_fw->data;
3963*4882a593Smuzhiyun 		WREG32(CP_ME_RAM_WADDR, 0);
3964*4882a593Smuzhiyun 		for (i = 0; i < CIK_ME_UCODE_SIZE; i++)
3965*4882a593Smuzhiyun 			WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
3966*4882a593Smuzhiyun 		WREG32(CP_ME_RAM_WADDR, 0);
3967*4882a593Smuzhiyun 	}
3968*4882a593Smuzhiyun 
3969*4882a593Smuzhiyun 	return 0;
3970*4882a593Smuzhiyun }
3971*4882a593Smuzhiyun 
3972*4882a593Smuzhiyun /**
3973*4882a593Smuzhiyun  * cik_cp_gfx_start - start the gfx ring
3974*4882a593Smuzhiyun  *
3975*4882a593Smuzhiyun  * @rdev: radeon_device pointer
3976*4882a593Smuzhiyun  *
3977*4882a593Smuzhiyun  * Enables the ring and loads the clear state context and other
3978*4882a593Smuzhiyun  * packets required to init the ring.
3979*4882a593Smuzhiyun  * Returns 0 for success, error for failure.
3980*4882a593Smuzhiyun  */
cik_cp_gfx_start(struct radeon_device * rdev)3981*4882a593Smuzhiyun static int cik_cp_gfx_start(struct radeon_device *rdev)
3982*4882a593Smuzhiyun {
3983*4882a593Smuzhiyun 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3984*4882a593Smuzhiyun 	int r, i;
3985*4882a593Smuzhiyun 
3986*4882a593Smuzhiyun 	/* init the CP */
3987*4882a593Smuzhiyun 	WREG32(CP_MAX_CONTEXT, rdev->config.cik.max_hw_contexts - 1);
3988*4882a593Smuzhiyun 	WREG32(CP_ENDIAN_SWAP, 0);
3989*4882a593Smuzhiyun 	WREG32(CP_DEVICE_ID, 1);
3990*4882a593Smuzhiyun 
3991*4882a593Smuzhiyun 	cik_cp_gfx_enable(rdev, true);
3992*4882a593Smuzhiyun 
3993*4882a593Smuzhiyun 	r = radeon_ring_lock(rdev, ring, cik_default_size + 17);
3994*4882a593Smuzhiyun 	if (r) {
3995*4882a593Smuzhiyun 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3996*4882a593Smuzhiyun 		return r;
3997*4882a593Smuzhiyun 	}
3998*4882a593Smuzhiyun 
3999*4882a593Smuzhiyun 	/* init the CE partitions.  CE only used for gfx on CIK */
4000*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
4001*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
4002*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x8000);
4003*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x8000);
4004*4882a593Smuzhiyun 
4005*4882a593Smuzhiyun 	/* setup clear context state */
4006*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
4007*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
4008*4882a593Smuzhiyun 
4009*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_CONTEXT_CONTROL, 1));
4010*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x80000000);
4011*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x80000000);
4012*4882a593Smuzhiyun 
4013*4882a593Smuzhiyun 	for (i = 0; i < cik_default_size; i++)
4014*4882a593Smuzhiyun 		radeon_ring_write(ring, cik_default_state[i]);
4015*4882a593Smuzhiyun 
4016*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
4017*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
4018*4882a593Smuzhiyun 
4019*4882a593Smuzhiyun 	/* set clear context state */
4020*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
4021*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
4022*4882a593Smuzhiyun 
4023*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
4024*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x00000316);
4025*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
4026*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
4027*4882a593Smuzhiyun 
4028*4882a593Smuzhiyun 	radeon_ring_unlock_commit(rdev, ring, false);
4029*4882a593Smuzhiyun 
4030*4882a593Smuzhiyun 	return 0;
4031*4882a593Smuzhiyun }
4032*4882a593Smuzhiyun 
4033*4882a593Smuzhiyun /**
4034*4882a593Smuzhiyun  * cik_cp_gfx_fini - stop the gfx ring
4035*4882a593Smuzhiyun  *
4036*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4037*4882a593Smuzhiyun  *
4038*4882a593Smuzhiyun  * Stop the gfx ring and tear down the driver ring
4039*4882a593Smuzhiyun  * info.
4040*4882a593Smuzhiyun  */
cik_cp_gfx_fini(struct radeon_device * rdev)4041*4882a593Smuzhiyun static void cik_cp_gfx_fini(struct radeon_device *rdev)
4042*4882a593Smuzhiyun {
4043*4882a593Smuzhiyun 	cik_cp_gfx_enable(rdev, false);
4044*4882a593Smuzhiyun 	radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
4045*4882a593Smuzhiyun }
4046*4882a593Smuzhiyun 
4047*4882a593Smuzhiyun /**
4048*4882a593Smuzhiyun  * cik_cp_gfx_resume - setup the gfx ring buffer registers
4049*4882a593Smuzhiyun  *
4050*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4051*4882a593Smuzhiyun  *
4052*4882a593Smuzhiyun  * Program the location and size of the gfx ring buffer
4053*4882a593Smuzhiyun  * and test it to make sure it's working.
4054*4882a593Smuzhiyun  * Returns 0 for success, error for failure.
4055*4882a593Smuzhiyun  */
cik_cp_gfx_resume(struct radeon_device * rdev)4056*4882a593Smuzhiyun static int cik_cp_gfx_resume(struct radeon_device *rdev)
4057*4882a593Smuzhiyun {
4058*4882a593Smuzhiyun 	struct radeon_ring *ring;
4059*4882a593Smuzhiyun 	u32 tmp;
4060*4882a593Smuzhiyun 	u32 rb_bufsz;
4061*4882a593Smuzhiyun 	u64 rb_addr;
4062*4882a593Smuzhiyun 	int r;
4063*4882a593Smuzhiyun 
4064*4882a593Smuzhiyun 	WREG32(CP_SEM_WAIT_TIMER, 0x0);
4065*4882a593Smuzhiyun 	if (rdev->family != CHIP_HAWAII)
4066*4882a593Smuzhiyun 		WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
4067*4882a593Smuzhiyun 
4068*4882a593Smuzhiyun 	/* Set the write pointer delay */
4069*4882a593Smuzhiyun 	WREG32(CP_RB_WPTR_DELAY, 0);
4070*4882a593Smuzhiyun 
4071*4882a593Smuzhiyun 	/* set the RB to use vmid 0 */
4072*4882a593Smuzhiyun 	WREG32(CP_RB_VMID, 0);
4073*4882a593Smuzhiyun 
4074*4882a593Smuzhiyun 	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
4075*4882a593Smuzhiyun 
4076*4882a593Smuzhiyun 	/* ring 0 - compute and gfx */
4077*4882a593Smuzhiyun 	/* Set ring buffer size */
4078*4882a593Smuzhiyun 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
4079*4882a593Smuzhiyun 	rb_bufsz = order_base_2(ring->ring_size / 8);
4080*4882a593Smuzhiyun 	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
4081*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
4082*4882a593Smuzhiyun 	tmp |= BUF_SWAP_32BIT;
4083*4882a593Smuzhiyun #endif
4084*4882a593Smuzhiyun 	WREG32(CP_RB0_CNTL, tmp);
4085*4882a593Smuzhiyun 
4086*4882a593Smuzhiyun 	/* Initialize the ring buffer's read and write pointers */
4087*4882a593Smuzhiyun 	WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
4088*4882a593Smuzhiyun 	ring->wptr = 0;
4089*4882a593Smuzhiyun 	WREG32(CP_RB0_WPTR, ring->wptr);
4090*4882a593Smuzhiyun 
4091*4882a593Smuzhiyun 	/* set the wb address wether it's enabled or not */
4092*4882a593Smuzhiyun 	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
4093*4882a593Smuzhiyun 	WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
4094*4882a593Smuzhiyun 
4095*4882a593Smuzhiyun 	/* scratch register shadowing is no longer supported */
4096*4882a593Smuzhiyun 	WREG32(SCRATCH_UMSK, 0);
4097*4882a593Smuzhiyun 
4098*4882a593Smuzhiyun 	if (!rdev->wb.enabled)
4099*4882a593Smuzhiyun 		tmp |= RB_NO_UPDATE;
4100*4882a593Smuzhiyun 
4101*4882a593Smuzhiyun 	mdelay(1);
4102*4882a593Smuzhiyun 	WREG32(CP_RB0_CNTL, tmp);
4103*4882a593Smuzhiyun 
4104*4882a593Smuzhiyun 	rb_addr = ring->gpu_addr >> 8;
4105*4882a593Smuzhiyun 	WREG32(CP_RB0_BASE, rb_addr);
4106*4882a593Smuzhiyun 	WREG32(CP_RB0_BASE_HI, upper_32_bits(rb_addr));
4107*4882a593Smuzhiyun 
4108*4882a593Smuzhiyun 	/* start the ring */
4109*4882a593Smuzhiyun 	cik_cp_gfx_start(rdev);
4110*4882a593Smuzhiyun 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
4111*4882a593Smuzhiyun 	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
4112*4882a593Smuzhiyun 	if (r) {
4113*4882a593Smuzhiyun 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
4114*4882a593Smuzhiyun 		return r;
4115*4882a593Smuzhiyun 	}
4116*4882a593Smuzhiyun 
4117*4882a593Smuzhiyun 	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
4118*4882a593Smuzhiyun 		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
4119*4882a593Smuzhiyun 
4120*4882a593Smuzhiyun 	return 0;
4121*4882a593Smuzhiyun }
4122*4882a593Smuzhiyun 
cik_gfx_get_rptr(struct radeon_device * rdev,struct radeon_ring * ring)4123*4882a593Smuzhiyun u32 cik_gfx_get_rptr(struct radeon_device *rdev,
4124*4882a593Smuzhiyun 		     struct radeon_ring *ring)
4125*4882a593Smuzhiyun {
4126*4882a593Smuzhiyun 	u32 rptr;
4127*4882a593Smuzhiyun 
4128*4882a593Smuzhiyun 	if (rdev->wb.enabled)
4129*4882a593Smuzhiyun 		rptr = rdev->wb.wb[ring->rptr_offs/4];
4130*4882a593Smuzhiyun 	else
4131*4882a593Smuzhiyun 		rptr = RREG32(CP_RB0_RPTR);
4132*4882a593Smuzhiyun 
4133*4882a593Smuzhiyun 	return rptr;
4134*4882a593Smuzhiyun }
4135*4882a593Smuzhiyun 
cik_gfx_get_wptr(struct radeon_device * rdev,struct radeon_ring * ring)4136*4882a593Smuzhiyun u32 cik_gfx_get_wptr(struct radeon_device *rdev,
4137*4882a593Smuzhiyun 		     struct radeon_ring *ring)
4138*4882a593Smuzhiyun {
4139*4882a593Smuzhiyun 	return RREG32(CP_RB0_WPTR);
4140*4882a593Smuzhiyun }
4141*4882a593Smuzhiyun 
cik_gfx_set_wptr(struct radeon_device * rdev,struct radeon_ring * ring)4142*4882a593Smuzhiyun void cik_gfx_set_wptr(struct radeon_device *rdev,
4143*4882a593Smuzhiyun 		      struct radeon_ring *ring)
4144*4882a593Smuzhiyun {
4145*4882a593Smuzhiyun 	WREG32(CP_RB0_WPTR, ring->wptr);
4146*4882a593Smuzhiyun 	(void)RREG32(CP_RB0_WPTR);
4147*4882a593Smuzhiyun }
4148*4882a593Smuzhiyun 
cik_compute_get_rptr(struct radeon_device * rdev,struct radeon_ring * ring)4149*4882a593Smuzhiyun u32 cik_compute_get_rptr(struct radeon_device *rdev,
4150*4882a593Smuzhiyun 			 struct radeon_ring *ring)
4151*4882a593Smuzhiyun {
4152*4882a593Smuzhiyun 	u32 rptr;
4153*4882a593Smuzhiyun 
4154*4882a593Smuzhiyun 	if (rdev->wb.enabled) {
4155*4882a593Smuzhiyun 		rptr = rdev->wb.wb[ring->rptr_offs/4];
4156*4882a593Smuzhiyun 	} else {
4157*4882a593Smuzhiyun 		mutex_lock(&rdev->srbm_mutex);
4158*4882a593Smuzhiyun 		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
4159*4882a593Smuzhiyun 		rptr = RREG32(CP_HQD_PQ_RPTR);
4160*4882a593Smuzhiyun 		cik_srbm_select(rdev, 0, 0, 0, 0);
4161*4882a593Smuzhiyun 		mutex_unlock(&rdev->srbm_mutex);
4162*4882a593Smuzhiyun 	}
4163*4882a593Smuzhiyun 
4164*4882a593Smuzhiyun 	return rptr;
4165*4882a593Smuzhiyun }
4166*4882a593Smuzhiyun 
cik_compute_get_wptr(struct radeon_device * rdev,struct radeon_ring * ring)4167*4882a593Smuzhiyun u32 cik_compute_get_wptr(struct radeon_device *rdev,
4168*4882a593Smuzhiyun 			 struct radeon_ring *ring)
4169*4882a593Smuzhiyun {
4170*4882a593Smuzhiyun 	u32 wptr;
4171*4882a593Smuzhiyun 
4172*4882a593Smuzhiyun 	if (rdev->wb.enabled) {
4173*4882a593Smuzhiyun 		/* XXX check if swapping is necessary on BE */
4174*4882a593Smuzhiyun 		wptr = rdev->wb.wb[ring->wptr_offs/4];
4175*4882a593Smuzhiyun 	} else {
4176*4882a593Smuzhiyun 		mutex_lock(&rdev->srbm_mutex);
4177*4882a593Smuzhiyun 		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
4178*4882a593Smuzhiyun 		wptr = RREG32(CP_HQD_PQ_WPTR);
4179*4882a593Smuzhiyun 		cik_srbm_select(rdev, 0, 0, 0, 0);
4180*4882a593Smuzhiyun 		mutex_unlock(&rdev->srbm_mutex);
4181*4882a593Smuzhiyun 	}
4182*4882a593Smuzhiyun 
4183*4882a593Smuzhiyun 	return wptr;
4184*4882a593Smuzhiyun }
4185*4882a593Smuzhiyun 
cik_compute_set_wptr(struct radeon_device * rdev,struct radeon_ring * ring)4186*4882a593Smuzhiyun void cik_compute_set_wptr(struct radeon_device *rdev,
4187*4882a593Smuzhiyun 			  struct radeon_ring *ring)
4188*4882a593Smuzhiyun {
4189*4882a593Smuzhiyun 	/* XXX check if swapping is necessary on BE */
4190*4882a593Smuzhiyun 	rdev->wb.wb[ring->wptr_offs/4] = ring->wptr;
4191*4882a593Smuzhiyun 	WDOORBELL32(ring->doorbell_index, ring->wptr);
4192*4882a593Smuzhiyun }
4193*4882a593Smuzhiyun 
cik_compute_stop(struct radeon_device * rdev,struct radeon_ring * ring)4194*4882a593Smuzhiyun static void cik_compute_stop(struct radeon_device *rdev,
4195*4882a593Smuzhiyun 			     struct radeon_ring *ring)
4196*4882a593Smuzhiyun {
4197*4882a593Smuzhiyun 	u32 j, tmp;
4198*4882a593Smuzhiyun 
4199*4882a593Smuzhiyun 	cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
4200*4882a593Smuzhiyun 	/* Disable wptr polling. */
4201*4882a593Smuzhiyun 	tmp = RREG32(CP_PQ_WPTR_POLL_CNTL);
4202*4882a593Smuzhiyun 	tmp &= ~WPTR_POLL_EN;
4203*4882a593Smuzhiyun 	WREG32(CP_PQ_WPTR_POLL_CNTL, tmp);
4204*4882a593Smuzhiyun 	/* Disable HQD. */
4205*4882a593Smuzhiyun 	if (RREG32(CP_HQD_ACTIVE) & 1) {
4206*4882a593Smuzhiyun 		WREG32(CP_HQD_DEQUEUE_REQUEST, 1);
4207*4882a593Smuzhiyun 		for (j = 0; j < rdev->usec_timeout; j++) {
4208*4882a593Smuzhiyun 			if (!(RREG32(CP_HQD_ACTIVE) & 1))
4209*4882a593Smuzhiyun 				break;
4210*4882a593Smuzhiyun 			udelay(1);
4211*4882a593Smuzhiyun 		}
4212*4882a593Smuzhiyun 		WREG32(CP_HQD_DEQUEUE_REQUEST, 0);
4213*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_RPTR, 0);
4214*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_WPTR, 0);
4215*4882a593Smuzhiyun 	}
4216*4882a593Smuzhiyun 	cik_srbm_select(rdev, 0, 0, 0, 0);
4217*4882a593Smuzhiyun }
4218*4882a593Smuzhiyun 
4219*4882a593Smuzhiyun /**
4220*4882a593Smuzhiyun  * cik_cp_compute_enable - enable/disable the compute CP MEs
4221*4882a593Smuzhiyun  *
4222*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4223*4882a593Smuzhiyun  * @enable: enable or disable the MEs
4224*4882a593Smuzhiyun  *
4225*4882a593Smuzhiyun  * Halts or unhalts the compute MEs.
4226*4882a593Smuzhiyun  */
cik_cp_compute_enable(struct radeon_device * rdev,bool enable)4227*4882a593Smuzhiyun static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable)
4228*4882a593Smuzhiyun {
4229*4882a593Smuzhiyun 	if (enable)
4230*4882a593Smuzhiyun 		WREG32(CP_MEC_CNTL, 0);
4231*4882a593Smuzhiyun 	else {
4232*4882a593Smuzhiyun 		/*
4233*4882a593Smuzhiyun 		 * To make hibernation reliable we need to clear compute ring
4234*4882a593Smuzhiyun 		 * configuration before halting the compute ring.
4235*4882a593Smuzhiyun 		 */
4236*4882a593Smuzhiyun 		mutex_lock(&rdev->srbm_mutex);
4237*4882a593Smuzhiyun 		cik_compute_stop(rdev,&rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
4238*4882a593Smuzhiyun 		cik_compute_stop(rdev,&rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
4239*4882a593Smuzhiyun 		mutex_unlock(&rdev->srbm_mutex);
4240*4882a593Smuzhiyun 
4241*4882a593Smuzhiyun 		WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT));
4242*4882a593Smuzhiyun 		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
4243*4882a593Smuzhiyun 		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
4244*4882a593Smuzhiyun 	}
4245*4882a593Smuzhiyun 	udelay(50);
4246*4882a593Smuzhiyun }
4247*4882a593Smuzhiyun 
4248*4882a593Smuzhiyun /**
4249*4882a593Smuzhiyun  * cik_cp_compute_load_microcode - load the compute CP ME ucode
4250*4882a593Smuzhiyun  *
4251*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4252*4882a593Smuzhiyun  *
4253*4882a593Smuzhiyun  * Loads the compute MEC1&2 ucode.
4254*4882a593Smuzhiyun  * Returns 0 for success, -EINVAL if the ucode is not available.
4255*4882a593Smuzhiyun  */
cik_cp_compute_load_microcode(struct radeon_device * rdev)4256*4882a593Smuzhiyun static int cik_cp_compute_load_microcode(struct radeon_device *rdev)
4257*4882a593Smuzhiyun {
4258*4882a593Smuzhiyun 	int i;
4259*4882a593Smuzhiyun 
4260*4882a593Smuzhiyun 	if (!rdev->mec_fw)
4261*4882a593Smuzhiyun 		return -EINVAL;
4262*4882a593Smuzhiyun 
4263*4882a593Smuzhiyun 	cik_cp_compute_enable(rdev, false);
4264*4882a593Smuzhiyun 
4265*4882a593Smuzhiyun 	if (rdev->new_fw) {
4266*4882a593Smuzhiyun 		const struct gfx_firmware_header_v1_0 *mec_hdr =
4267*4882a593Smuzhiyun 			(const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data;
4268*4882a593Smuzhiyun 		const __le32 *fw_data;
4269*4882a593Smuzhiyun 		u32 fw_size;
4270*4882a593Smuzhiyun 
4271*4882a593Smuzhiyun 		radeon_ucode_print_gfx_hdr(&mec_hdr->header);
4272*4882a593Smuzhiyun 
4273*4882a593Smuzhiyun 		/* MEC1 */
4274*4882a593Smuzhiyun 		fw_data = (const __le32 *)
4275*4882a593Smuzhiyun 			(rdev->mec_fw->data + le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes));
4276*4882a593Smuzhiyun 		fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4;
4277*4882a593Smuzhiyun 		WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
4278*4882a593Smuzhiyun 		for (i = 0; i < fw_size; i++)
4279*4882a593Smuzhiyun 			WREG32(CP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data++));
4280*4882a593Smuzhiyun 		WREG32(CP_MEC_ME1_UCODE_ADDR, le32_to_cpu(mec_hdr->header.ucode_version));
4281*4882a593Smuzhiyun 
4282*4882a593Smuzhiyun 		/* MEC2 */
4283*4882a593Smuzhiyun 		if (rdev->family == CHIP_KAVERI) {
4284*4882a593Smuzhiyun 			const struct gfx_firmware_header_v1_0 *mec2_hdr =
4285*4882a593Smuzhiyun 				(const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data;
4286*4882a593Smuzhiyun 
4287*4882a593Smuzhiyun 			fw_data = (const __le32 *)
4288*4882a593Smuzhiyun 				(rdev->mec2_fw->data +
4289*4882a593Smuzhiyun 				 le32_to_cpu(mec2_hdr->header.ucode_array_offset_bytes));
4290*4882a593Smuzhiyun 			fw_size = le32_to_cpu(mec2_hdr->header.ucode_size_bytes) / 4;
4291*4882a593Smuzhiyun 			WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
4292*4882a593Smuzhiyun 			for (i = 0; i < fw_size; i++)
4293*4882a593Smuzhiyun 				WREG32(CP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data++));
4294*4882a593Smuzhiyun 			WREG32(CP_MEC_ME2_UCODE_ADDR, le32_to_cpu(mec2_hdr->header.ucode_version));
4295*4882a593Smuzhiyun 		}
4296*4882a593Smuzhiyun 	} else {
4297*4882a593Smuzhiyun 		const __be32 *fw_data;
4298*4882a593Smuzhiyun 
4299*4882a593Smuzhiyun 		/* MEC1 */
4300*4882a593Smuzhiyun 		fw_data = (const __be32 *)rdev->mec_fw->data;
4301*4882a593Smuzhiyun 		WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
4302*4882a593Smuzhiyun 		for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
4303*4882a593Smuzhiyun 			WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++));
4304*4882a593Smuzhiyun 		WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
4305*4882a593Smuzhiyun 
4306*4882a593Smuzhiyun 		if (rdev->family == CHIP_KAVERI) {
4307*4882a593Smuzhiyun 			/* MEC2 */
4308*4882a593Smuzhiyun 			fw_data = (const __be32 *)rdev->mec_fw->data;
4309*4882a593Smuzhiyun 			WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
4310*4882a593Smuzhiyun 			for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
4311*4882a593Smuzhiyun 				WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++));
4312*4882a593Smuzhiyun 			WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
4313*4882a593Smuzhiyun 		}
4314*4882a593Smuzhiyun 	}
4315*4882a593Smuzhiyun 
4316*4882a593Smuzhiyun 	return 0;
4317*4882a593Smuzhiyun }
4318*4882a593Smuzhiyun 
4319*4882a593Smuzhiyun /**
4320*4882a593Smuzhiyun  * cik_cp_compute_start - start the compute queues
4321*4882a593Smuzhiyun  *
4322*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4323*4882a593Smuzhiyun  *
4324*4882a593Smuzhiyun  * Enable the compute queues.
4325*4882a593Smuzhiyun  * Returns 0 for success, error for failure.
4326*4882a593Smuzhiyun  */
cik_cp_compute_start(struct radeon_device * rdev)4327*4882a593Smuzhiyun static int cik_cp_compute_start(struct radeon_device *rdev)
4328*4882a593Smuzhiyun {
4329*4882a593Smuzhiyun 	cik_cp_compute_enable(rdev, true);
4330*4882a593Smuzhiyun 
4331*4882a593Smuzhiyun 	return 0;
4332*4882a593Smuzhiyun }
4333*4882a593Smuzhiyun 
4334*4882a593Smuzhiyun /**
4335*4882a593Smuzhiyun  * cik_cp_compute_fini - stop the compute queues
4336*4882a593Smuzhiyun  *
4337*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4338*4882a593Smuzhiyun  *
4339*4882a593Smuzhiyun  * Stop the compute queues and tear down the driver queue
4340*4882a593Smuzhiyun  * info.
4341*4882a593Smuzhiyun  */
cik_cp_compute_fini(struct radeon_device * rdev)4342*4882a593Smuzhiyun static void cik_cp_compute_fini(struct radeon_device *rdev)
4343*4882a593Smuzhiyun {
4344*4882a593Smuzhiyun 	int i, idx, r;
4345*4882a593Smuzhiyun 
4346*4882a593Smuzhiyun 	cik_cp_compute_enable(rdev, false);
4347*4882a593Smuzhiyun 
4348*4882a593Smuzhiyun 	for (i = 0; i < 2; i++) {
4349*4882a593Smuzhiyun 		if (i == 0)
4350*4882a593Smuzhiyun 			idx = CAYMAN_RING_TYPE_CP1_INDEX;
4351*4882a593Smuzhiyun 		else
4352*4882a593Smuzhiyun 			idx = CAYMAN_RING_TYPE_CP2_INDEX;
4353*4882a593Smuzhiyun 
4354*4882a593Smuzhiyun 		if (rdev->ring[idx].mqd_obj) {
4355*4882a593Smuzhiyun 			r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false);
4356*4882a593Smuzhiyun 			if (unlikely(r != 0))
4357*4882a593Smuzhiyun 				dev_warn(rdev->dev, "(%d) reserve MQD bo failed\n", r);
4358*4882a593Smuzhiyun 
4359*4882a593Smuzhiyun 			radeon_bo_unpin(rdev->ring[idx].mqd_obj);
4360*4882a593Smuzhiyun 			radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
4361*4882a593Smuzhiyun 
4362*4882a593Smuzhiyun 			radeon_bo_unref(&rdev->ring[idx].mqd_obj);
4363*4882a593Smuzhiyun 			rdev->ring[idx].mqd_obj = NULL;
4364*4882a593Smuzhiyun 		}
4365*4882a593Smuzhiyun 	}
4366*4882a593Smuzhiyun }
4367*4882a593Smuzhiyun 
cik_mec_fini(struct radeon_device * rdev)4368*4882a593Smuzhiyun static void cik_mec_fini(struct radeon_device *rdev)
4369*4882a593Smuzhiyun {
4370*4882a593Smuzhiyun 	int r;
4371*4882a593Smuzhiyun 
4372*4882a593Smuzhiyun 	if (rdev->mec.hpd_eop_obj) {
4373*4882a593Smuzhiyun 		r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false);
4374*4882a593Smuzhiyun 		if (unlikely(r != 0))
4375*4882a593Smuzhiyun 			dev_warn(rdev->dev, "(%d) reserve HPD EOP bo failed\n", r);
4376*4882a593Smuzhiyun 		radeon_bo_unpin(rdev->mec.hpd_eop_obj);
4377*4882a593Smuzhiyun 		radeon_bo_unreserve(rdev->mec.hpd_eop_obj);
4378*4882a593Smuzhiyun 
4379*4882a593Smuzhiyun 		radeon_bo_unref(&rdev->mec.hpd_eop_obj);
4380*4882a593Smuzhiyun 		rdev->mec.hpd_eop_obj = NULL;
4381*4882a593Smuzhiyun 	}
4382*4882a593Smuzhiyun }
4383*4882a593Smuzhiyun 
4384*4882a593Smuzhiyun #define MEC_HPD_SIZE 2048
4385*4882a593Smuzhiyun 
cik_mec_init(struct radeon_device * rdev)4386*4882a593Smuzhiyun static int cik_mec_init(struct radeon_device *rdev)
4387*4882a593Smuzhiyun {
4388*4882a593Smuzhiyun 	int r;
4389*4882a593Smuzhiyun 	u32 *hpd;
4390*4882a593Smuzhiyun 
4391*4882a593Smuzhiyun 	/*
4392*4882a593Smuzhiyun 	 * KV:    2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total
4393*4882a593Smuzhiyun 	 * CI/KB: 1 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 32 Queues total
4394*4882a593Smuzhiyun 	 */
4395*4882a593Smuzhiyun 	if (rdev->family == CHIP_KAVERI)
4396*4882a593Smuzhiyun 		rdev->mec.num_mec = 2;
4397*4882a593Smuzhiyun 	else
4398*4882a593Smuzhiyun 		rdev->mec.num_mec = 1;
4399*4882a593Smuzhiyun 	rdev->mec.num_pipe = 4;
4400*4882a593Smuzhiyun 	rdev->mec.num_queue = rdev->mec.num_mec * rdev->mec.num_pipe * 8;
4401*4882a593Smuzhiyun 
4402*4882a593Smuzhiyun 	if (rdev->mec.hpd_eop_obj == NULL) {
4403*4882a593Smuzhiyun 		r = radeon_bo_create(rdev,
4404*4882a593Smuzhiyun 				     rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2,
4405*4882a593Smuzhiyun 				     PAGE_SIZE, true,
4406*4882a593Smuzhiyun 				     RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL,
4407*4882a593Smuzhiyun 				     &rdev->mec.hpd_eop_obj);
4408*4882a593Smuzhiyun 		if (r) {
4409*4882a593Smuzhiyun 			dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r);
4410*4882a593Smuzhiyun 			return r;
4411*4882a593Smuzhiyun 		}
4412*4882a593Smuzhiyun 	}
4413*4882a593Smuzhiyun 
4414*4882a593Smuzhiyun 	r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false);
4415*4882a593Smuzhiyun 	if (unlikely(r != 0)) {
4416*4882a593Smuzhiyun 		cik_mec_fini(rdev);
4417*4882a593Smuzhiyun 		return r;
4418*4882a593Smuzhiyun 	}
4419*4882a593Smuzhiyun 	r = radeon_bo_pin(rdev->mec.hpd_eop_obj, RADEON_GEM_DOMAIN_GTT,
4420*4882a593Smuzhiyun 			  &rdev->mec.hpd_eop_gpu_addr);
4421*4882a593Smuzhiyun 	if (r) {
4422*4882a593Smuzhiyun 		dev_warn(rdev->dev, "(%d) pin HDP EOP bo failed\n", r);
4423*4882a593Smuzhiyun 		cik_mec_fini(rdev);
4424*4882a593Smuzhiyun 		return r;
4425*4882a593Smuzhiyun 	}
4426*4882a593Smuzhiyun 	r = radeon_bo_kmap(rdev->mec.hpd_eop_obj, (void **)&hpd);
4427*4882a593Smuzhiyun 	if (r) {
4428*4882a593Smuzhiyun 		dev_warn(rdev->dev, "(%d) map HDP EOP bo failed\n", r);
4429*4882a593Smuzhiyun 		cik_mec_fini(rdev);
4430*4882a593Smuzhiyun 		return r;
4431*4882a593Smuzhiyun 	}
4432*4882a593Smuzhiyun 
4433*4882a593Smuzhiyun 	/* clear memory.  Not sure if this is required or not */
4434*4882a593Smuzhiyun 	memset(hpd, 0, rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2);
4435*4882a593Smuzhiyun 
4436*4882a593Smuzhiyun 	radeon_bo_kunmap(rdev->mec.hpd_eop_obj);
4437*4882a593Smuzhiyun 	radeon_bo_unreserve(rdev->mec.hpd_eop_obj);
4438*4882a593Smuzhiyun 
4439*4882a593Smuzhiyun 	return 0;
4440*4882a593Smuzhiyun }
4441*4882a593Smuzhiyun 
4442*4882a593Smuzhiyun struct hqd_registers
4443*4882a593Smuzhiyun {
4444*4882a593Smuzhiyun 	u32 cp_mqd_base_addr;
4445*4882a593Smuzhiyun 	u32 cp_mqd_base_addr_hi;
4446*4882a593Smuzhiyun 	u32 cp_hqd_active;
4447*4882a593Smuzhiyun 	u32 cp_hqd_vmid;
4448*4882a593Smuzhiyun 	u32 cp_hqd_persistent_state;
4449*4882a593Smuzhiyun 	u32 cp_hqd_pipe_priority;
4450*4882a593Smuzhiyun 	u32 cp_hqd_queue_priority;
4451*4882a593Smuzhiyun 	u32 cp_hqd_quantum;
4452*4882a593Smuzhiyun 	u32 cp_hqd_pq_base;
4453*4882a593Smuzhiyun 	u32 cp_hqd_pq_base_hi;
4454*4882a593Smuzhiyun 	u32 cp_hqd_pq_rptr;
4455*4882a593Smuzhiyun 	u32 cp_hqd_pq_rptr_report_addr;
4456*4882a593Smuzhiyun 	u32 cp_hqd_pq_rptr_report_addr_hi;
4457*4882a593Smuzhiyun 	u32 cp_hqd_pq_wptr_poll_addr;
4458*4882a593Smuzhiyun 	u32 cp_hqd_pq_wptr_poll_addr_hi;
4459*4882a593Smuzhiyun 	u32 cp_hqd_pq_doorbell_control;
4460*4882a593Smuzhiyun 	u32 cp_hqd_pq_wptr;
4461*4882a593Smuzhiyun 	u32 cp_hqd_pq_control;
4462*4882a593Smuzhiyun 	u32 cp_hqd_ib_base_addr;
4463*4882a593Smuzhiyun 	u32 cp_hqd_ib_base_addr_hi;
4464*4882a593Smuzhiyun 	u32 cp_hqd_ib_rptr;
4465*4882a593Smuzhiyun 	u32 cp_hqd_ib_control;
4466*4882a593Smuzhiyun 	u32 cp_hqd_iq_timer;
4467*4882a593Smuzhiyun 	u32 cp_hqd_iq_rptr;
4468*4882a593Smuzhiyun 	u32 cp_hqd_dequeue_request;
4469*4882a593Smuzhiyun 	u32 cp_hqd_dma_offload;
4470*4882a593Smuzhiyun 	u32 cp_hqd_sema_cmd;
4471*4882a593Smuzhiyun 	u32 cp_hqd_msg_type;
4472*4882a593Smuzhiyun 	u32 cp_hqd_atomic0_preop_lo;
4473*4882a593Smuzhiyun 	u32 cp_hqd_atomic0_preop_hi;
4474*4882a593Smuzhiyun 	u32 cp_hqd_atomic1_preop_lo;
4475*4882a593Smuzhiyun 	u32 cp_hqd_atomic1_preop_hi;
4476*4882a593Smuzhiyun 	u32 cp_hqd_hq_scheduler0;
4477*4882a593Smuzhiyun 	u32 cp_hqd_hq_scheduler1;
4478*4882a593Smuzhiyun 	u32 cp_mqd_control;
4479*4882a593Smuzhiyun };
4480*4882a593Smuzhiyun 
4481*4882a593Smuzhiyun struct bonaire_mqd
4482*4882a593Smuzhiyun {
4483*4882a593Smuzhiyun 	u32 header;
4484*4882a593Smuzhiyun 	u32 dispatch_initiator;
4485*4882a593Smuzhiyun 	u32 dimensions[3];
4486*4882a593Smuzhiyun 	u32 start_idx[3];
4487*4882a593Smuzhiyun 	u32 num_threads[3];
4488*4882a593Smuzhiyun 	u32 pipeline_stat_enable;
4489*4882a593Smuzhiyun 	u32 perf_counter_enable;
4490*4882a593Smuzhiyun 	u32 pgm[2];
4491*4882a593Smuzhiyun 	u32 tba[2];
4492*4882a593Smuzhiyun 	u32 tma[2];
4493*4882a593Smuzhiyun 	u32 pgm_rsrc[2];
4494*4882a593Smuzhiyun 	u32 vmid;
4495*4882a593Smuzhiyun 	u32 resource_limits;
4496*4882a593Smuzhiyun 	u32 static_thread_mgmt01[2];
4497*4882a593Smuzhiyun 	u32 tmp_ring_size;
4498*4882a593Smuzhiyun 	u32 static_thread_mgmt23[2];
4499*4882a593Smuzhiyun 	u32 restart[3];
4500*4882a593Smuzhiyun 	u32 thread_trace_enable;
4501*4882a593Smuzhiyun 	u32 reserved1;
4502*4882a593Smuzhiyun 	u32 user_data[16];
4503*4882a593Smuzhiyun 	u32 vgtcs_invoke_count[2];
4504*4882a593Smuzhiyun 	struct hqd_registers queue_state;
4505*4882a593Smuzhiyun 	u32 dequeue_cntr;
4506*4882a593Smuzhiyun 	u32 interrupt_queue[64];
4507*4882a593Smuzhiyun };
4508*4882a593Smuzhiyun 
4509*4882a593Smuzhiyun /**
4510*4882a593Smuzhiyun  * cik_cp_compute_resume - setup the compute queue registers
4511*4882a593Smuzhiyun  *
4512*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4513*4882a593Smuzhiyun  *
4514*4882a593Smuzhiyun  * Program the compute queues and test them to make sure they
4515*4882a593Smuzhiyun  * are working.
4516*4882a593Smuzhiyun  * Returns 0 for success, error for failure.
4517*4882a593Smuzhiyun  */
cik_cp_compute_resume(struct radeon_device * rdev)4518*4882a593Smuzhiyun static int cik_cp_compute_resume(struct radeon_device *rdev)
4519*4882a593Smuzhiyun {
4520*4882a593Smuzhiyun 	int r, i, j, idx;
4521*4882a593Smuzhiyun 	u32 tmp;
4522*4882a593Smuzhiyun 	bool use_doorbell = true;
4523*4882a593Smuzhiyun 	u64 hqd_gpu_addr;
4524*4882a593Smuzhiyun 	u64 mqd_gpu_addr;
4525*4882a593Smuzhiyun 	u64 eop_gpu_addr;
4526*4882a593Smuzhiyun 	u64 wb_gpu_addr;
4527*4882a593Smuzhiyun 	u32 *buf;
4528*4882a593Smuzhiyun 	struct bonaire_mqd *mqd;
4529*4882a593Smuzhiyun 
4530*4882a593Smuzhiyun 	r = cik_cp_compute_start(rdev);
4531*4882a593Smuzhiyun 	if (r)
4532*4882a593Smuzhiyun 		return r;
4533*4882a593Smuzhiyun 
4534*4882a593Smuzhiyun 	/* fix up chicken bits */
4535*4882a593Smuzhiyun 	tmp = RREG32(CP_CPF_DEBUG);
4536*4882a593Smuzhiyun 	tmp |= (1 << 23);
4537*4882a593Smuzhiyun 	WREG32(CP_CPF_DEBUG, tmp);
4538*4882a593Smuzhiyun 
4539*4882a593Smuzhiyun 	/* init the pipes */
4540*4882a593Smuzhiyun 	mutex_lock(&rdev->srbm_mutex);
4541*4882a593Smuzhiyun 
4542*4882a593Smuzhiyun 	for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); ++i) {
4543*4882a593Smuzhiyun 		int me = (i < 4) ? 1 : 2;
4544*4882a593Smuzhiyun 		int pipe = (i < 4) ? i : (i - 4);
4545*4882a593Smuzhiyun 
4546*4882a593Smuzhiyun 		cik_srbm_select(rdev, me, pipe, 0, 0);
4547*4882a593Smuzhiyun 
4548*4882a593Smuzhiyun 		eop_gpu_addr = rdev->mec.hpd_eop_gpu_addr + (i * MEC_HPD_SIZE * 2) ;
4549*4882a593Smuzhiyun 		/* write the EOP addr */
4550*4882a593Smuzhiyun 		WREG32(CP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8);
4551*4882a593Smuzhiyun 		WREG32(CP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8);
4552*4882a593Smuzhiyun 
4553*4882a593Smuzhiyun 		/* set the VMID assigned */
4554*4882a593Smuzhiyun 		WREG32(CP_HPD_EOP_VMID, 0);
4555*4882a593Smuzhiyun 
4556*4882a593Smuzhiyun 		/* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */
4557*4882a593Smuzhiyun 		tmp = RREG32(CP_HPD_EOP_CONTROL);
4558*4882a593Smuzhiyun 		tmp &= ~EOP_SIZE_MASK;
4559*4882a593Smuzhiyun 		tmp |= order_base_2(MEC_HPD_SIZE / 8);
4560*4882a593Smuzhiyun 		WREG32(CP_HPD_EOP_CONTROL, tmp);
4561*4882a593Smuzhiyun 
4562*4882a593Smuzhiyun 	}
4563*4882a593Smuzhiyun 	cik_srbm_select(rdev, 0, 0, 0, 0);
4564*4882a593Smuzhiyun 	mutex_unlock(&rdev->srbm_mutex);
4565*4882a593Smuzhiyun 
4566*4882a593Smuzhiyun 	/* init the queues.  Just two for now. */
4567*4882a593Smuzhiyun 	for (i = 0; i < 2; i++) {
4568*4882a593Smuzhiyun 		if (i == 0)
4569*4882a593Smuzhiyun 			idx = CAYMAN_RING_TYPE_CP1_INDEX;
4570*4882a593Smuzhiyun 		else
4571*4882a593Smuzhiyun 			idx = CAYMAN_RING_TYPE_CP2_INDEX;
4572*4882a593Smuzhiyun 
4573*4882a593Smuzhiyun 		if (rdev->ring[idx].mqd_obj == NULL) {
4574*4882a593Smuzhiyun 			r = radeon_bo_create(rdev,
4575*4882a593Smuzhiyun 					     sizeof(struct bonaire_mqd),
4576*4882a593Smuzhiyun 					     PAGE_SIZE, true,
4577*4882a593Smuzhiyun 					     RADEON_GEM_DOMAIN_GTT, 0, NULL,
4578*4882a593Smuzhiyun 					     NULL, &rdev->ring[idx].mqd_obj);
4579*4882a593Smuzhiyun 			if (r) {
4580*4882a593Smuzhiyun 				dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r);
4581*4882a593Smuzhiyun 				return r;
4582*4882a593Smuzhiyun 			}
4583*4882a593Smuzhiyun 		}
4584*4882a593Smuzhiyun 
4585*4882a593Smuzhiyun 		r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false);
4586*4882a593Smuzhiyun 		if (unlikely(r != 0)) {
4587*4882a593Smuzhiyun 			cik_cp_compute_fini(rdev);
4588*4882a593Smuzhiyun 			return r;
4589*4882a593Smuzhiyun 		}
4590*4882a593Smuzhiyun 		r = radeon_bo_pin(rdev->ring[idx].mqd_obj, RADEON_GEM_DOMAIN_GTT,
4591*4882a593Smuzhiyun 				  &mqd_gpu_addr);
4592*4882a593Smuzhiyun 		if (r) {
4593*4882a593Smuzhiyun 			dev_warn(rdev->dev, "(%d) pin MQD bo failed\n", r);
4594*4882a593Smuzhiyun 			cik_cp_compute_fini(rdev);
4595*4882a593Smuzhiyun 			return r;
4596*4882a593Smuzhiyun 		}
4597*4882a593Smuzhiyun 		r = radeon_bo_kmap(rdev->ring[idx].mqd_obj, (void **)&buf);
4598*4882a593Smuzhiyun 		if (r) {
4599*4882a593Smuzhiyun 			dev_warn(rdev->dev, "(%d) map MQD bo failed\n", r);
4600*4882a593Smuzhiyun 			cik_cp_compute_fini(rdev);
4601*4882a593Smuzhiyun 			return r;
4602*4882a593Smuzhiyun 		}
4603*4882a593Smuzhiyun 
4604*4882a593Smuzhiyun 		/* init the mqd struct */
4605*4882a593Smuzhiyun 		memset(buf, 0, sizeof(struct bonaire_mqd));
4606*4882a593Smuzhiyun 
4607*4882a593Smuzhiyun 		mqd = (struct bonaire_mqd *)buf;
4608*4882a593Smuzhiyun 		mqd->header = 0xC0310800;
4609*4882a593Smuzhiyun 		mqd->static_thread_mgmt01[0] = 0xffffffff;
4610*4882a593Smuzhiyun 		mqd->static_thread_mgmt01[1] = 0xffffffff;
4611*4882a593Smuzhiyun 		mqd->static_thread_mgmt23[0] = 0xffffffff;
4612*4882a593Smuzhiyun 		mqd->static_thread_mgmt23[1] = 0xffffffff;
4613*4882a593Smuzhiyun 
4614*4882a593Smuzhiyun 		mutex_lock(&rdev->srbm_mutex);
4615*4882a593Smuzhiyun 		cik_srbm_select(rdev, rdev->ring[idx].me,
4616*4882a593Smuzhiyun 				rdev->ring[idx].pipe,
4617*4882a593Smuzhiyun 				rdev->ring[idx].queue, 0);
4618*4882a593Smuzhiyun 
4619*4882a593Smuzhiyun 		/* disable wptr polling */
4620*4882a593Smuzhiyun 		tmp = RREG32(CP_PQ_WPTR_POLL_CNTL);
4621*4882a593Smuzhiyun 		tmp &= ~WPTR_POLL_EN;
4622*4882a593Smuzhiyun 		WREG32(CP_PQ_WPTR_POLL_CNTL, tmp);
4623*4882a593Smuzhiyun 
4624*4882a593Smuzhiyun 		/* enable doorbell? */
4625*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_doorbell_control =
4626*4882a593Smuzhiyun 			RREG32(CP_HQD_PQ_DOORBELL_CONTROL);
4627*4882a593Smuzhiyun 		if (use_doorbell)
4628*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN;
4629*4882a593Smuzhiyun 		else
4630*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_EN;
4631*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_DOORBELL_CONTROL,
4632*4882a593Smuzhiyun 		       mqd->queue_state.cp_hqd_pq_doorbell_control);
4633*4882a593Smuzhiyun 
4634*4882a593Smuzhiyun 		/* disable the queue if it's active */
4635*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_dequeue_request = 0;
4636*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_rptr = 0;
4637*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_wptr= 0;
4638*4882a593Smuzhiyun 		if (RREG32(CP_HQD_ACTIVE) & 1) {
4639*4882a593Smuzhiyun 			WREG32(CP_HQD_DEQUEUE_REQUEST, 1);
4640*4882a593Smuzhiyun 			for (j = 0; j < rdev->usec_timeout; j++) {
4641*4882a593Smuzhiyun 				if (!(RREG32(CP_HQD_ACTIVE) & 1))
4642*4882a593Smuzhiyun 					break;
4643*4882a593Smuzhiyun 				udelay(1);
4644*4882a593Smuzhiyun 			}
4645*4882a593Smuzhiyun 			WREG32(CP_HQD_DEQUEUE_REQUEST, mqd->queue_state.cp_hqd_dequeue_request);
4646*4882a593Smuzhiyun 			WREG32(CP_HQD_PQ_RPTR, mqd->queue_state.cp_hqd_pq_rptr);
4647*4882a593Smuzhiyun 			WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
4648*4882a593Smuzhiyun 		}
4649*4882a593Smuzhiyun 
4650*4882a593Smuzhiyun 		/* set the pointer to the MQD */
4651*4882a593Smuzhiyun 		mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc;
4652*4882a593Smuzhiyun 		mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr);
4653*4882a593Smuzhiyun 		WREG32(CP_MQD_BASE_ADDR, mqd->queue_state.cp_mqd_base_addr);
4654*4882a593Smuzhiyun 		WREG32(CP_MQD_BASE_ADDR_HI, mqd->queue_state.cp_mqd_base_addr_hi);
4655*4882a593Smuzhiyun 		/* set MQD vmid to 0 */
4656*4882a593Smuzhiyun 		mqd->queue_state.cp_mqd_control = RREG32(CP_MQD_CONTROL);
4657*4882a593Smuzhiyun 		mqd->queue_state.cp_mqd_control &= ~MQD_VMID_MASK;
4658*4882a593Smuzhiyun 		WREG32(CP_MQD_CONTROL, mqd->queue_state.cp_mqd_control);
4659*4882a593Smuzhiyun 
4660*4882a593Smuzhiyun 		/* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */
4661*4882a593Smuzhiyun 		hqd_gpu_addr = rdev->ring[idx].gpu_addr >> 8;
4662*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr;
4663*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr);
4664*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_BASE, mqd->queue_state.cp_hqd_pq_base);
4665*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_BASE_HI, mqd->queue_state.cp_hqd_pq_base_hi);
4666*4882a593Smuzhiyun 
4667*4882a593Smuzhiyun 		/* set up the HQD, this is similar to CP_RB0_CNTL */
4668*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control = RREG32(CP_HQD_PQ_CONTROL);
4669*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control &=
4670*4882a593Smuzhiyun 			~(QUEUE_SIZE_MASK | RPTR_BLOCK_SIZE_MASK);
4671*4882a593Smuzhiyun 
4672*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control |=
4673*4882a593Smuzhiyun 			order_base_2(rdev->ring[idx].ring_size / 8);
4674*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control |=
4675*4882a593Smuzhiyun 			(order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8);
4676*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
4677*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control |= BUF_SWAP_32BIT;
4678*4882a593Smuzhiyun #endif
4679*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control &=
4680*4882a593Smuzhiyun 			~(UNORD_DISPATCH | ROQ_PQ_IB_FLIP | PQ_VOLATILE);
4681*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_control |=
4682*4882a593Smuzhiyun 			PRIV_STATE | KMD_QUEUE; /* assuming kernel queue control */
4683*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_CONTROL, mqd->queue_state.cp_hqd_pq_control);
4684*4882a593Smuzhiyun 
4685*4882a593Smuzhiyun 		/* only used if CP_PQ_WPTR_POLL_CNTL.WPTR_POLL_EN=1 */
4686*4882a593Smuzhiyun 		if (i == 0)
4687*4882a593Smuzhiyun 			wb_gpu_addr = rdev->wb.gpu_addr + CIK_WB_CP1_WPTR_OFFSET;
4688*4882a593Smuzhiyun 		else
4689*4882a593Smuzhiyun 			wb_gpu_addr = rdev->wb.gpu_addr + CIK_WB_CP2_WPTR_OFFSET;
4690*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_wptr_poll_addr = wb_gpu_addr & 0xfffffffc;
4691*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff;
4692*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_WPTR_POLL_ADDR, mqd->queue_state.cp_hqd_pq_wptr_poll_addr);
4693*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_WPTR_POLL_ADDR_HI,
4694*4882a593Smuzhiyun 		       mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi);
4695*4882a593Smuzhiyun 
4696*4882a593Smuzhiyun 		/* set the wb address wether it's enabled or not */
4697*4882a593Smuzhiyun 		if (i == 0)
4698*4882a593Smuzhiyun 			wb_gpu_addr = rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET;
4699*4882a593Smuzhiyun 		else
4700*4882a593Smuzhiyun 			wb_gpu_addr = rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET;
4701*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_rptr_report_addr = wb_gpu_addr & 0xfffffffc;
4702*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi =
4703*4882a593Smuzhiyun 			upper_32_bits(wb_gpu_addr) & 0xffff;
4704*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_RPTR_REPORT_ADDR,
4705*4882a593Smuzhiyun 		       mqd->queue_state.cp_hqd_pq_rptr_report_addr);
4706*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_RPTR_REPORT_ADDR_HI,
4707*4882a593Smuzhiyun 		       mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi);
4708*4882a593Smuzhiyun 
4709*4882a593Smuzhiyun 		/* enable the doorbell if requested */
4710*4882a593Smuzhiyun 		if (use_doorbell) {
4711*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control =
4712*4882a593Smuzhiyun 				RREG32(CP_HQD_PQ_DOORBELL_CONTROL);
4713*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_OFFSET_MASK;
4714*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control |=
4715*4882a593Smuzhiyun 				DOORBELL_OFFSET(rdev->ring[idx].doorbell_index);
4716*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN;
4717*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control &=
4718*4882a593Smuzhiyun 				~(DOORBELL_SOURCE | DOORBELL_HIT);
4719*4882a593Smuzhiyun 
4720*4882a593Smuzhiyun 		} else {
4721*4882a593Smuzhiyun 			mqd->queue_state.cp_hqd_pq_doorbell_control = 0;
4722*4882a593Smuzhiyun 		}
4723*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_DOORBELL_CONTROL,
4724*4882a593Smuzhiyun 		       mqd->queue_state.cp_hqd_pq_doorbell_control);
4725*4882a593Smuzhiyun 
4726*4882a593Smuzhiyun 		/* read and write pointers, similar to CP_RB0_WPTR/_RPTR */
4727*4882a593Smuzhiyun 		rdev->ring[idx].wptr = 0;
4728*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_wptr = rdev->ring[idx].wptr;
4729*4882a593Smuzhiyun 		WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
4730*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_pq_rptr = RREG32(CP_HQD_PQ_RPTR);
4731*4882a593Smuzhiyun 
4732*4882a593Smuzhiyun 		/* set the vmid for the queue */
4733*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_vmid = 0;
4734*4882a593Smuzhiyun 		WREG32(CP_HQD_VMID, mqd->queue_state.cp_hqd_vmid);
4735*4882a593Smuzhiyun 
4736*4882a593Smuzhiyun 		/* activate the queue */
4737*4882a593Smuzhiyun 		mqd->queue_state.cp_hqd_active = 1;
4738*4882a593Smuzhiyun 		WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
4739*4882a593Smuzhiyun 
4740*4882a593Smuzhiyun 		cik_srbm_select(rdev, 0, 0, 0, 0);
4741*4882a593Smuzhiyun 		mutex_unlock(&rdev->srbm_mutex);
4742*4882a593Smuzhiyun 
4743*4882a593Smuzhiyun 		radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
4744*4882a593Smuzhiyun 		radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
4745*4882a593Smuzhiyun 
4746*4882a593Smuzhiyun 		rdev->ring[idx].ready = true;
4747*4882a593Smuzhiyun 		r = radeon_ring_test(rdev, idx, &rdev->ring[idx]);
4748*4882a593Smuzhiyun 		if (r)
4749*4882a593Smuzhiyun 			rdev->ring[idx].ready = false;
4750*4882a593Smuzhiyun 	}
4751*4882a593Smuzhiyun 
4752*4882a593Smuzhiyun 	return 0;
4753*4882a593Smuzhiyun }
4754*4882a593Smuzhiyun 
cik_cp_enable(struct radeon_device * rdev,bool enable)4755*4882a593Smuzhiyun static void cik_cp_enable(struct radeon_device *rdev, bool enable)
4756*4882a593Smuzhiyun {
4757*4882a593Smuzhiyun 	cik_cp_gfx_enable(rdev, enable);
4758*4882a593Smuzhiyun 	cik_cp_compute_enable(rdev, enable);
4759*4882a593Smuzhiyun }
4760*4882a593Smuzhiyun 
cik_cp_load_microcode(struct radeon_device * rdev)4761*4882a593Smuzhiyun static int cik_cp_load_microcode(struct radeon_device *rdev)
4762*4882a593Smuzhiyun {
4763*4882a593Smuzhiyun 	int r;
4764*4882a593Smuzhiyun 
4765*4882a593Smuzhiyun 	r = cik_cp_gfx_load_microcode(rdev);
4766*4882a593Smuzhiyun 	if (r)
4767*4882a593Smuzhiyun 		return r;
4768*4882a593Smuzhiyun 	r = cik_cp_compute_load_microcode(rdev);
4769*4882a593Smuzhiyun 	if (r)
4770*4882a593Smuzhiyun 		return r;
4771*4882a593Smuzhiyun 
4772*4882a593Smuzhiyun 	return 0;
4773*4882a593Smuzhiyun }
4774*4882a593Smuzhiyun 
cik_cp_fini(struct radeon_device * rdev)4775*4882a593Smuzhiyun static void cik_cp_fini(struct radeon_device *rdev)
4776*4882a593Smuzhiyun {
4777*4882a593Smuzhiyun 	cik_cp_gfx_fini(rdev);
4778*4882a593Smuzhiyun 	cik_cp_compute_fini(rdev);
4779*4882a593Smuzhiyun }
4780*4882a593Smuzhiyun 
cik_cp_resume(struct radeon_device * rdev)4781*4882a593Smuzhiyun static int cik_cp_resume(struct radeon_device *rdev)
4782*4882a593Smuzhiyun {
4783*4882a593Smuzhiyun 	int r;
4784*4882a593Smuzhiyun 
4785*4882a593Smuzhiyun 	cik_enable_gui_idle_interrupt(rdev, false);
4786*4882a593Smuzhiyun 
4787*4882a593Smuzhiyun 	r = cik_cp_load_microcode(rdev);
4788*4882a593Smuzhiyun 	if (r)
4789*4882a593Smuzhiyun 		return r;
4790*4882a593Smuzhiyun 
4791*4882a593Smuzhiyun 	r = cik_cp_gfx_resume(rdev);
4792*4882a593Smuzhiyun 	if (r)
4793*4882a593Smuzhiyun 		return r;
4794*4882a593Smuzhiyun 	r = cik_cp_compute_resume(rdev);
4795*4882a593Smuzhiyun 	if (r)
4796*4882a593Smuzhiyun 		return r;
4797*4882a593Smuzhiyun 
4798*4882a593Smuzhiyun 	cik_enable_gui_idle_interrupt(rdev, true);
4799*4882a593Smuzhiyun 
4800*4882a593Smuzhiyun 	return 0;
4801*4882a593Smuzhiyun }
4802*4882a593Smuzhiyun 
cik_print_gpu_status_regs(struct radeon_device * rdev)4803*4882a593Smuzhiyun static void cik_print_gpu_status_regs(struct radeon_device *rdev)
4804*4882a593Smuzhiyun {
4805*4882a593Smuzhiyun 	dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
4806*4882a593Smuzhiyun 		RREG32(GRBM_STATUS));
4807*4882a593Smuzhiyun 	dev_info(rdev->dev, "  GRBM_STATUS2=0x%08X\n",
4808*4882a593Smuzhiyun 		RREG32(GRBM_STATUS2));
4809*4882a593Smuzhiyun 	dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
4810*4882a593Smuzhiyun 		RREG32(GRBM_STATUS_SE0));
4811*4882a593Smuzhiyun 	dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
4812*4882a593Smuzhiyun 		RREG32(GRBM_STATUS_SE1));
4813*4882a593Smuzhiyun 	dev_info(rdev->dev, "  GRBM_STATUS_SE2=0x%08X\n",
4814*4882a593Smuzhiyun 		RREG32(GRBM_STATUS_SE2));
4815*4882a593Smuzhiyun 	dev_info(rdev->dev, "  GRBM_STATUS_SE3=0x%08X\n",
4816*4882a593Smuzhiyun 		RREG32(GRBM_STATUS_SE3));
4817*4882a593Smuzhiyun 	dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
4818*4882a593Smuzhiyun 		RREG32(SRBM_STATUS));
4819*4882a593Smuzhiyun 	dev_info(rdev->dev, "  SRBM_STATUS2=0x%08X\n",
4820*4882a593Smuzhiyun 		RREG32(SRBM_STATUS2));
4821*4882a593Smuzhiyun 	dev_info(rdev->dev, "  SDMA0_STATUS_REG   = 0x%08X\n",
4822*4882a593Smuzhiyun 		RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET));
4823*4882a593Smuzhiyun 	dev_info(rdev->dev, "  SDMA1_STATUS_REG   = 0x%08X\n",
4824*4882a593Smuzhiyun 		 RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET));
4825*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_STAT = 0x%08x\n", RREG32(CP_STAT));
4826*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_STALLED_STAT1 = 0x%08x\n",
4827*4882a593Smuzhiyun 		 RREG32(CP_STALLED_STAT1));
4828*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_STALLED_STAT2 = 0x%08x\n",
4829*4882a593Smuzhiyun 		 RREG32(CP_STALLED_STAT2));
4830*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_STALLED_STAT3 = 0x%08x\n",
4831*4882a593Smuzhiyun 		 RREG32(CP_STALLED_STAT3));
4832*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_CPF_BUSY_STAT = 0x%08x\n",
4833*4882a593Smuzhiyun 		 RREG32(CP_CPF_BUSY_STAT));
4834*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_CPF_STALLED_STAT1 = 0x%08x\n",
4835*4882a593Smuzhiyun 		 RREG32(CP_CPF_STALLED_STAT1));
4836*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_CPF_STATUS = 0x%08x\n", RREG32(CP_CPF_STATUS));
4837*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_CPC_BUSY_STAT = 0x%08x\n", RREG32(CP_CPC_BUSY_STAT));
4838*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_CPC_STALLED_STAT1 = 0x%08x\n",
4839*4882a593Smuzhiyun 		 RREG32(CP_CPC_STALLED_STAT1));
4840*4882a593Smuzhiyun 	dev_info(rdev->dev, "  CP_CPC_STATUS = 0x%08x\n", RREG32(CP_CPC_STATUS));
4841*4882a593Smuzhiyun }
4842*4882a593Smuzhiyun 
4843*4882a593Smuzhiyun /**
4844*4882a593Smuzhiyun  * cik_gpu_check_soft_reset - check which blocks are busy
4845*4882a593Smuzhiyun  *
4846*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4847*4882a593Smuzhiyun  *
4848*4882a593Smuzhiyun  * Check which blocks are busy and return the relevant reset
4849*4882a593Smuzhiyun  * mask to be used by cik_gpu_soft_reset().
4850*4882a593Smuzhiyun  * Returns a mask of the blocks to be reset.
4851*4882a593Smuzhiyun  */
cik_gpu_check_soft_reset(struct radeon_device * rdev)4852*4882a593Smuzhiyun u32 cik_gpu_check_soft_reset(struct radeon_device *rdev)
4853*4882a593Smuzhiyun {
4854*4882a593Smuzhiyun 	u32 reset_mask = 0;
4855*4882a593Smuzhiyun 	u32 tmp;
4856*4882a593Smuzhiyun 
4857*4882a593Smuzhiyun 	/* GRBM_STATUS */
4858*4882a593Smuzhiyun 	tmp = RREG32(GRBM_STATUS);
4859*4882a593Smuzhiyun 	if (tmp & (PA_BUSY | SC_BUSY |
4860*4882a593Smuzhiyun 		   BCI_BUSY | SX_BUSY |
4861*4882a593Smuzhiyun 		   TA_BUSY | VGT_BUSY |
4862*4882a593Smuzhiyun 		   DB_BUSY | CB_BUSY |
4863*4882a593Smuzhiyun 		   GDS_BUSY | SPI_BUSY |
4864*4882a593Smuzhiyun 		   IA_BUSY | IA_BUSY_NO_DMA))
4865*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_GFX;
4866*4882a593Smuzhiyun 
4867*4882a593Smuzhiyun 	if (tmp & (CP_BUSY | CP_COHERENCY_BUSY))
4868*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_CP;
4869*4882a593Smuzhiyun 
4870*4882a593Smuzhiyun 	/* GRBM_STATUS2 */
4871*4882a593Smuzhiyun 	tmp = RREG32(GRBM_STATUS2);
4872*4882a593Smuzhiyun 	if (tmp & RLC_BUSY)
4873*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_RLC;
4874*4882a593Smuzhiyun 
4875*4882a593Smuzhiyun 	/* SDMA0_STATUS_REG */
4876*4882a593Smuzhiyun 	tmp = RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET);
4877*4882a593Smuzhiyun 	if (!(tmp & SDMA_IDLE))
4878*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_DMA;
4879*4882a593Smuzhiyun 
4880*4882a593Smuzhiyun 	/* SDMA1_STATUS_REG */
4881*4882a593Smuzhiyun 	tmp = RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET);
4882*4882a593Smuzhiyun 	if (!(tmp & SDMA_IDLE))
4883*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_DMA1;
4884*4882a593Smuzhiyun 
4885*4882a593Smuzhiyun 	/* SRBM_STATUS2 */
4886*4882a593Smuzhiyun 	tmp = RREG32(SRBM_STATUS2);
4887*4882a593Smuzhiyun 	if (tmp & SDMA_BUSY)
4888*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_DMA;
4889*4882a593Smuzhiyun 
4890*4882a593Smuzhiyun 	if (tmp & SDMA1_BUSY)
4891*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_DMA1;
4892*4882a593Smuzhiyun 
4893*4882a593Smuzhiyun 	/* SRBM_STATUS */
4894*4882a593Smuzhiyun 	tmp = RREG32(SRBM_STATUS);
4895*4882a593Smuzhiyun 
4896*4882a593Smuzhiyun 	if (tmp & IH_BUSY)
4897*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_IH;
4898*4882a593Smuzhiyun 
4899*4882a593Smuzhiyun 	if (tmp & SEM_BUSY)
4900*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_SEM;
4901*4882a593Smuzhiyun 
4902*4882a593Smuzhiyun 	if (tmp & GRBM_RQ_PENDING)
4903*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_GRBM;
4904*4882a593Smuzhiyun 
4905*4882a593Smuzhiyun 	if (tmp & VMC_BUSY)
4906*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_VMC;
4907*4882a593Smuzhiyun 
4908*4882a593Smuzhiyun 	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
4909*4882a593Smuzhiyun 		   MCC_BUSY | MCD_BUSY))
4910*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_MC;
4911*4882a593Smuzhiyun 
4912*4882a593Smuzhiyun 	if (evergreen_is_display_hung(rdev))
4913*4882a593Smuzhiyun 		reset_mask |= RADEON_RESET_DISPLAY;
4914*4882a593Smuzhiyun 
4915*4882a593Smuzhiyun 	/* Skip MC reset as it's mostly likely not hung, just busy */
4916*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_MC) {
4917*4882a593Smuzhiyun 		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
4918*4882a593Smuzhiyun 		reset_mask &= ~RADEON_RESET_MC;
4919*4882a593Smuzhiyun 	}
4920*4882a593Smuzhiyun 
4921*4882a593Smuzhiyun 	return reset_mask;
4922*4882a593Smuzhiyun }
4923*4882a593Smuzhiyun 
4924*4882a593Smuzhiyun /**
4925*4882a593Smuzhiyun  * cik_gpu_soft_reset - soft reset GPU
4926*4882a593Smuzhiyun  *
4927*4882a593Smuzhiyun  * @rdev: radeon_device pointer
4928*4882a593Smuzhiyun  * @reset_mask: mask of which blocks to reset
4929*4882a593Smuzhiyun  *
4930*4882a593Smuzhiyun  * Soft reset the blocks specified in @reset_mask.
4931*4882a593Smuzhiyun  */
cik_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)4932*4882a593Smuzhiyun static void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
4933*4882a593Smuzhiyun {
4934*4882a593Smuzhiyun 	struct evergreen_mc_save save;
4935*4882a593Smuzhiyun 	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
4936*4882a593Smuzhiyun 	u32 tmp;
4937*4882a593Smuzhiyun 
4938*4882a593Smuzhiyun 	if (reset_mask == 0)
4939*4882a593Smuzhiyun 		return;
4940*4882a593Smuzhiyun 
4941*4882a593Smuzhiyun 	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
4942*4882a593Smuzhiyun 
4943*4882a593Smuzhiyun 	cik_print_gpu_status_regs(rdev);
4944*4882a593Smuzhiyun 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
4945*4882a593Smuzhiyun 		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
4946*4882a593Smuzhiyun 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
4947*4882a593Smuzhiyun 		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
4948*4882a593Smuzhiyun 
4949*4882a593Smuzhiyun 	/* disable CG/PG */
4950*4882a593Smuzhiyun 	cik_fini_pg(rdev);
4951*4882a593Smuzhiyun 	cik_fini_cg(rdev);
4952*4882a593Smuzhiyun 
4953*4882a593Smuzhiyun 	/* stop the rlc */
4954*4882a593Smuzhiyun 	cik_rlc_stop(rdev);
4955*4882a593Smuzhiyun 
4956*4882a593Smuzhiyun 	/* Disable GFX parsing/prefetching */
4957*4882a593Smuzhiyun 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
4958*4882a593Smuzhiyun 
4959*4882a593Smuzhiyun 	/* Disable MEC parsing/prefetching */
4960*4882a593Smuzhiyun 	WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT);
4961*4882a593Smuzhiyun 
4962*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_DMA) {
4963*4882a593Smuzhiyun 		/* sdma0 */
4964*4882a593Smuzhiyun 		tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET);
4965*4882a593Smuzhiyun 		tmp |= SDMA_HALT;
4966*4882a593Smuzhiyun 		WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp);
4967*4882a593Smuzhiyun 	}
4968*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_DMA1) {
4969*4882a593Smuzhiyun 		/* sdma1 */
4970*4882a593Smuzhiyun 		tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET);
4971*4882a593Smuzhiyun 		tmp |= SDMA_HALT;
4972*4882a593Smuzhiyun 		WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp);
4973*4882a593Smuzhiyun 	}
4974*4882a593Smuzhiyun 
4975*4882a593Smuzhiyun 	evergreen_mc_stop(rdev, &save);
4976*4882a593Smuzhiyun 	if (evergreen_mc_wait_for_idle(rdev)) {
4977*4882a593Smuzhiyun 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4978*4882a593Smuzhiyun 	}
4979*4882a593Smuzhiyun 
4980*4882a593Smuzhiyun 	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP))
4981*4882a593Smuzhiyun 		grbm_soft_reset = SOFT_RESET_CP | SOFT_RESET_GFX;
4982*4882a593Smuzhiyun 
4983*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_CP) {
4984*4882a593Smuzhiyun 		grbm_soft_reset |= SOFT_RESET_CP;
4985*4882a593Smuzhiyun 
4986*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_GRBM;
4987*4882a593Smuzhiyun 	}
4988*4882a593Smuzhiyun 
4989*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_DMA)
4990*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_SDMA;
4991*4882a593Smuzhiyun 
4992*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_DMA1)
4993*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_SDMA1;
4994*4882a593Smuzhiyun 
4995*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_DISPLAY)
4996*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_DC;
4997*4882a593Smuzhiyun 
4998*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_RLC)
4999*4882a593Smuzhiyun 		grbm_soft_reset |= SOFT_RESET_RLC;
5000*4882a593Smuzhiyun 
5001*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_SEM)
5002*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_SEM;
5003*4882a593Smuzhiyun 
5004*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_IH)
5005*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_IH;
5006*4882a593Smuzhiyun 
5007*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_GRBM)
5008*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_GRBM;
5009*4882a593Smuzhiyun 
5010*4882a593Smuzhiyun 	if (reset_mask & RADEON_RESET_VMC)
5011*4882a593Smuzhiyun 		srbm_soft_reset |= SOFT_RESET_VMC;
5012*4882a593Smuzhiyun 
5013*4882a593Smuzhiyun 	if (!(rdev->flags & RADEON_IS_IGP)) {
5014*4882a593Smuzhiyun 		if (reset_mask & RADEON_RESET_MC)
5015*4882a593Smuzhiyun 			srbm_soft_reset |= SOFT_RESET_MC;
5016*4882a593Smuzhiyun 	}
5017*4882a593Smuzhiyun 
5018*4882a593Smuzhiyun 	if (grbm_soft_reset) {
5019*4882a593Smuzhiyun 		tmp = RREG32(GRBM_SOFT_RESET);
5020*4882a593Smuzhiyun 		tmp |= grbm_soft_reset;
5021*4882a593Smuzhiyun 		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
5022*4882a593Smuzhiyun 		WREG32(GRBM_SOFT_RESET, tmp);
5023*4882a593Smuzhiyun 		tmp = RREG32(GRBM_SOFT_RESET);
5024*4882a593Smuzhiyun 
5025*4882a593Smuzhiyun 		udelay(50);
5026*4882a593Smuzhiyun 
5027*4882a593Smuzhiyun 		tmp &= ~grbm_soft_reset;
5028*4882a593Smuzhiyun 		WREG32(GRBM_SOFT_RESET, tmp);
5029*4882a593Smuzhiyun 		tmp = RREG32(GRBM_SOFT_RESET);
5030*4882a593Smuzhiyun 	}
5031*4882a593Smuzhiyun 
5032*4882a593Smuzhiyun 	if (srbm_soft_reset) {
5033*4882a593Smuzhiyun 		tmp = RREG32(SRBM_SOFT_RESET);
5034*4882a593Smuzhiyun 		tmp |= srbm_soft_reset;
5035*4882a593Smuzhiyun 		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
5036*4882a593Smuzhiyun 		WREG32(SRBM_SOFT_RESET, tmp);
5037*4882a593Smuzhiyun 		tmp = RREG32(SRBM_SOFT_RESET);
5038*4882a593Smuzhiyun 
5039*4882a593Smuzhiyun 		udelay(50);
5040*4882a593Smuzhiyun 
5041*4882a593Smuzhiyun 		tmp &= ~srbm_soft_reset;
5042*4882a593Smuzhiyun 		WREG32(SRBM_SOFT_RESET, tmp);
5043*4882a593Smuzhiyun 		tmp = RREG32(SRBM_SOFT_RESET);
5044*4882a593Smuzhiyun 	}
5045*4882a593Smuzhiyun 
5046*4882a593Smuzhiyun 	/* Wait a little for things to settle down */
5047*4882a593Smuzhiyun 	udelay(50);
5048*4882a593Smuzhiyun 
5049*4882a593Smuzhiyun 	evergreen_mc_resume(rdev, &save);
5050*4882a593Smuzhiyun 	udelay(50);
5051*4882a593Smuzhiyun 
5052*4882a593Smuzhiyun 	cik_print_gpu_status_regs(rdev);
5053*4882a593Smuzhiyun }
5054*4882a593Smuzhiyun 
5055*4882a593Smuzhiyun struct kv_reset_save_regs {
5056*4882a593Smuzhiyun 	u32 gmcon_reng_execute;
5057*4882a593Smuzhiyun 	u32 gmcon_misc;
5058*4882a593Smuzhiyun 	u32 gmcon_misc3;
5059*4882a593Smuzhiyun };
5060*4882a593Smuzhiyun 
kv_save_regs_for_reset(struct radeon_device * rdev,struct kv_reset_save_regs * save)5061*4882a593Smuzhiyun static void kv_save_regs_for_reset(struct radeon_device *rdev,
5062*4882a593Smuzhiyun 				   struct kv_reset_save_regs *save)
5063*4882a593Smuzhiyun {
5064*4882a593Smuzhiyun 	save->gmcon_reng_execute = RREG32(GMCON_RENG_EXECUTE);
5065*4882a593Smuzhiyun 	save->gmcon_misc = RREG32(GMCON_MISC);
5066*4882a593Smuzhiyun 	save->gmcon_misc3 = RREG32(GMCON_MISC3);
5067*4882a593Smuzhiyun 
5068*4882a593Smuzhiyun 	WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute & ~RENG_EXECUTE_ON_PWR_UP);
5069*4882a593Smuzhiyun 	WREG32(GMCON_MISC, save->gmcon_misc & ~(RENG_EXECUTE_ON_REG_UPDATE |
5070*4882a593Smuzhiyun 						STCTRL_STUTTER_EN));
5071*4882a593Smuzhiyun }
5072*4882a593Smuzhiyun 
kv_restore_regs_for_reset(struct radeon_device * rdev,struct kv_reset_save_regs * save)5073*4882a593Smuzhiyun static void kv_restore_regs_for_reset(struct radeon_device *rdev,
5074*4882a593Smuzhiyun 				      struct kv_reset_save_regs *save)
5075*4882a593Smuzhiyun {
5076*4882a593Smuzhiyun 	int i;
5077*4882a593Smuzhiyun 
5078*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0);
5079*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0x200010ff);
5080*4882a593Smuzhiyun 
5081*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5082*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5083*4882a593Smuzhiyun 
5084*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0);
5085*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0x300010ff);
5086*4882a593Smuzhiyun 
5087*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5088*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5089*4882a593Smuzhiyun 
5090*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x210000);
5091*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0xa00010ff);
5092*4882a593Smuzhiyun 
5093*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5094*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5095*4882a593Smuzhiyun 
5096*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x21003);
5097*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0xb00010ff);
5098*4882a593Smuzhiyun 
5099*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5100*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5101*4882a593Smuzhiyun 
5102*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x2b00);
5103*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0xc00010ff);
5104*4882a593Smuzhiyun 
5105*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5106*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5107*4882a593Smuzhiyun 
5108*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0);
5109*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0xd00010ff);
5110*4882a593Smuzhiyun 
5111*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5112*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5113*4882a593Smuzhiyun 
5114*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x420000);
5115*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0x100010ff);
5116*4882a593Smuzhiyun 
5117*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5118*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5119*4882a593Smuzhiyun 
5120*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x120202);
5121*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0x500010ff);
5122*4882a593Smuzhiyun 
5123*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5124*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5125*4882a593Smuzhiyun 
5126*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x3e3e36);
5127*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0x600010ff);
5128*4882a593Smuzhiyun 
5129*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5130*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5131*4882a593Smuzhiyun 
5132*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x373f3e);
5133*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0x700010ff);
5134*4882a593Smuzhiyun 
5135*4882a593Smuzhiyun 	for (i = 0; i < 5; i++)
5136*4882a593Smuzhiyun 		WREG32(GMCON_PGFSM_WRITE, 0);
5137*4882a593Smuzhiyun 
5138*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_WRITE, 0x3e1332);
5139*4882a593Smuzhiyun 	WREG32(GMCON_PGFSM_CONFIG, 0xe00010ff);
5140*4882a593Smuzhiyun 
5141*4882a593Smuzhiyun 	WREG32(GMCON_MISC3, save->gmcon_misc3);
5142*4882a593Smuzhiyun 	WREG32(GMCON_MISC, save->gmcon_misc);
5143*4882a593Smuzhiyun 	WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute);
5144*4882a593Smuzhiyun }
5145*4882a593Smuzhiyun 
cik_gpu_pci_config_reset(struct radeon_device * rdev)5146*4882a593Smuzhiyun static void cik_gpu_pci_config_reset(struct radeon_device *rdev)
5147*4882a593Smuzhiyun {
5148*4882a593Smuzhiyun 	struct evergreen_mc_save save;
5149*4882a593Smuzhiyun 	struct kv_reset_save_regs kv_save = { 0 };
5150*4882a593Smuzhiyun 	u32 tmp, i;
5151*4882a593Smuzhiyun 
5152*4882a593Smuzhiyun 	dev_info(rdev->dev, "GPU pci config reset\n");
5153*4882a593Smuzhiyun 
5154*4882a593Smuzhiyun 	/* disable dpm? */
5155*4882a593Smuzhiyun 
5156*4882a593Smuzhiyun 	/* disable cg/pg */
5157*4882a593Smuzhiyun 	cik_fini_pg(rdev);
5158*4882a593Smuzhiyun 	cik_fini_cg(rdev);
5159*4882a593Smuzhiyun 
5160*4882a593Smuzhiyun 	/* Disable GFX parsing/prefetching */
5161*4882a593Smuzhiyun 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
5162*4882a593Smuzhiyun 
5163*4882a593Smuzhiyun 	/* Disable MEC parsing/prefetching */
5164*4882a593Smuzhiyun 	WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT);
5165*4882a593Smuzhiyun 
5166*4882a593Smuzhiyun 	/* sdma0 */
5167*4882a593Smuzhiyun 	tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET);
5168*4882a593Smuzhiyun 	tmp |= SDMA_HALT;
5169*4882a593Smuzhiyun 	WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp);
5170*4882a593Smuzhiyun 	/* sdma1 */
5171*4882a593Smuzhiyun 	tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET);
5172*4882a593Smuzhiyun 	tmp |= SDMA_HALT;
5173*4882a593Smuzhiyun 	WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp);
5174*4882a593Smuzhiyun 	/* XXX other engines? */
5175*4882a593Smuzhiyun 
5176*4882a593Smuzhiyun 	/* halt the rlc, disable cp internal ints */
5177*4882a593Smuzhiyun 	cik_rlc_stop(rdev);
5178*4882a593Smuzhiyun 
5179*4882a593Smuzhiyun 	udelay(50);
5180*4882a593Smuzhiyun 
5181*4882a593Smuzhiyun 	/* disable mem access */
5182*4882a593Smuzhiyun 	evergreen_mc_stop(rdev, &save);
5183*4882a593Smuzhiyun 	if (evergreen_mc_wait_for_idle(rdev)) {
5184*4882a593Smuzhiyun 		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
5185*4882a593Smuzhiyun 	}
5186*4882a593Smuzhiyun 
5187*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP)
5188*4882a593Smuzhiyun 		kv_save_regs_for_reset(rdev, &kv_save);
5189*4882a593Smuzhiyun 
5190*4882a593Smuzhiyun 	/* disable BM */
5191*4882a593Smuzhiyun 	pci_clear_master(rdev->pdev);
5192*4882a593Smuzhiyun 	/* reset */
5193*4882a593Smuzhiyun 	radeon_pci_config_reset(rdev);
5194*4882a593Smuzhiyun 
5195*4882a593Smuzhiyun 	udelay(100);
5196*4882a593Smuzhiyun 
5197*4882a593Smuzhiyun 	/* wait for asic to come out of reset */
5198*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
5199*4882a593Smuzhiyun 		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
5200*4882a593Smuzhiyun 			break;
5201*4882a593Smuzhiyun 		udelay(1);
5202*4882a593Smuzhiyun 	}
5203*4882a593Smuzhiyun 
5204*4882a593Smuzhiyun 	/* does asic init need to be run first??? */
5205*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP)
5206*4882a593Smuzhiyun 		kv_restore_regs_for_reset(rdev, &kv_save);
5207*4882a593Smuzhiyun }
5208*4882a593Smuzhiyun 
5209*4882a593Smuzhiyun /**
5210*4882a593Smuzhiyun  * cik_asic_reset - soft reset GPU
5211*4882a593Smuzhiyun  *
5212*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5213*4882a593Smuzhiyun  * @hard: force hard reset
5214*4882a593Smuzhiyun  *
5215*4882a593Smuzhiyun  * Look up which blocks are hung and attempt
5216*4882a593Smuzhiyun  * to reset them.
5217*4882a593Smuzhiyun  * Returns 0 for success.
5218*4882a593Smuzhiyun  */
cik_asic_reset(struct radeon_device * rdev,bool hard)5219*4882a593Smuzhiyun int cik_asic_reset(struct radeon_device *rdev, bool hard)
5220*4882a593Smuzhiyun {
5221*4882a593Smuzhiyun 	u32 reset_mask;
5222*4882a593Smuzhiyun 
5223*4882a593Smuzhiyun 	if (hard) {
5224*4882a593Smuzhiyun 		cik_gpu_pci_config_reset(rdev);
5225*4882a593Smuzhiyun 		return 0;
5226*4882a593Smuzhiyun 	}
5227*4882a593Smuzhiyun 
5228*4882a593Smuzhiyun 	reset_mask = cik_gpu_check_soft_reset(rdev);
5229*4882a593Smuzhiyun 
5230*4882a593Smuzhiyun 	if (reset_mask)
5231*4882a593Smuzhiyun 		r600_set_bios_scratch_engine_hung(rdev, true);
5232*4882a593Smuzhiyun 
5233*4882a593Smuzhiyun 	/* try soft reset */
5234*4882a593Smuzhiyun 	cik_gpu_soft_reset(rdev, reset_mask);
5235*4882a593Smuzhiyun 
5236*4882a593Smuzhiyun 	reset_mask = cik_gpu_check_soft_reset(rdev);
5237*4882a593Smuzhiyun 
5238*4882a593Smuzhiyun 	/* try pci config reset */
5239*4882a593Smuzhiyun 	if (reset_mask && radeon_hard_reset)
5240*4882a593Smuzhiyun 		cik_gpu_pci_config_reset(rdev);
5241*4882a593Smuzhiyun 
5242*4882a593Smuzhiyun 	reset_mask = cik_gpu_check_soft_reset(rdev);
5243*4882a593Smuzhiyun 
5244*4882a593Smuzhiyun 	if (!reset_mask)
5245*4882a593Smuzhiyun 		r600_set_bios_scratch_engine_hung(rdev, false);
5246*4882a593Smuzhiyun 
5247*4882a593Smuzhiyun 	return 0;
5248*4882a593Smuzhiyun }
5249*4882a593Smuzhiyun 
5250*4882a593Smuzhiyun /**
5251*4882a593Smuzhiyun  * cik_gfx_is_lockup - check if the 3D engine is locked up
5252*4882a593Smuzhiyun  *
5253*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5254*4882a593Smuzhiyun  * @ring: radeon_ring structure holding ring information
5255*4882a593Smuzhiyun  *
5256*4882a593Smuzhiyun  * Check if the 3D engine is locked up (CIK).
5257*4882a593Smuzhiyun  * Returns true if the engine is locked, false if not.
5258*4882a593Smuzhiyun  */
cik_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)5259*4882a593Smuzhiyun bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
5260*4882a593Smuzhiyun {
5261*4882a593Smuzhiyun 	u32 reset_mask = cik_gpu_check_soft_reset(rdev);
5262*4882a593Smuzhiyun 
5263*4882a593Smuzhiyun 	if (!(reset_mask & (RADEON_RESET_GFX |
5264*4882a593Smuzhiyun 			    RADEON_RESET_COMPUTE |
5265*4882a593Smuzhiyun 			    RADEON_RESET_CP))) {
5266*4882a593Smuzhiyun 		radeon_ring_lockup_update(rdev, ring);
5267*4882a593Smuzhiyun 		return false;
5268*4882a593Smuzhiyun 	}
5269*4882a593Smuzhiyun 	return radeon_ring_test_lockup(rdev, ring);
5270*4882a593Smuzhiyun }
5271*4882a593Smuzhiyun 
5272*4882a593Smuzhiyun /* MC */
5273*4882a593Smuzhiyun /**
5274*4882a593Smuzhiyun  * cik_mc_program - program the GPU memory controller
5275*4882a593Smuzhiyun  *
5276*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5277*4882a593Smuzhiyun  *
5278*4882a593Smuzhiyun  * Set the location of vram, gart, and AGP in the GPU's
5279*4882a593Smuzhiyun  * physical address space (CIK).
5280*4882a593Smuzhiyun  */
cik_mc_program(struct radeon_device * rdev)5281*4882a593Smuzhiyun static void cik_mc_program(struct radeon_device *rdev)
5282*4882a593Smuzhiyun {
5283*4882a593Smuzhiyun 	struct evergreen_mc_save save;
5284*4882a593Smuzhiyun 	u32 tmp;
5285*4882a593Smuzhiyun 	int i, j;
5286*4882a593Smuzhiyun 
5287*4882a593Smuzhiyun 	/* Initialize HDP */
5288*4882a593Smuzhiyun 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
5289*4882a593Smuzhiyun 		WREG32((0x2c14 + j), 0x00000000);
5290*4882a593Smuzhiyun 		WREG32((0x2c18 + j), 0x00000000);
5291*4882a593Smuzhiyun 		WREG32((0x2c1c + j), 0x00000000);
5292*4882a593Smuzhiyun 		WREG32((0x2c20 + j), 0x00000000);
5293*4882a593Smuzhiyun 		WREG32((0x2c24 + j), 0x00000000);
5294*4882a593Smuzhiyun 	}
5295*4882a593Smuzhiyun 	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
5296*4882a593Smuzhiyun 
5297*4882a593Smuzhiyun 	evergreen_mc_stop(rdev, &save);
5298*4882a593Smuzhiyun 	if (radeon_mc_wait_for_idle(rdev)) {
5299*4882a593Smuzhiyun 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
5300*4882a593Smuzhiyun 	}
5301*4882a593Smuzhiyun 	/* Lockout access through VGA aperture*/
5302*4882a593Smuzhiyun 	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
5303*4882a593Smuzhiyun 	/* Update configuration */
5304*4882a593Smuzhiyun 	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
5305*4882a593Smuzhiyun 	       rdev->mc.vram_start >> 12);
5306*4882a593Smuzhiyun 	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
5307*4882a593Smuzhiyun 	       rdev->mc.vram_end >> 12);
5308*4882a593Smuzhiyun 	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
5309*4882a593Smuzhiyun 	       rdev->vram_scratch.gpu_addr >> 12);
5310*4882a593Smuzhiyun 	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
5311*4882a593Smuzhiyun 	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
5312*4882a593Smuzhiyun 	WREG32(MC_VM_FB_LOCATION, tmp);
5313*4882a593Smuzhiyun 	/* XXX double check these! */
5314*4882a593Smuzhiyun 	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
5315*4882a593Smuzhiyun 	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
5316*4882a593Smuzhiyun 	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
5317*4882a593Smuzhiyun 	WREG32(MC_VM_AGP_BASE, 0);
5318*4882a593Smuzhiyun 	WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
5319*4882a593Smuzhiyun 	WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
5320*4882a593Smuzhiyun 	if (radeon_mc_wait_for_idle(rdev)) {
5321*4882a593Smuzhiyun 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
5322*4882a593Smuzhiyun 	}
5323*4882a593Smuzhiyun 	evergreen_mc_resume(rdev, &save);
5324*4882a593Smuzhiyun 	/* we need to own VRAM, so turn off the VGA renderer here
5325*4882a593Smuzhiyun 	 * to stop it overwriting our objects */
5326*4882a593Smuzhiyun 	rv515_vga_render_disable(rdev);
5327*4882a593Smuzhiyun }
5328*4882a593Smuzhiyun 
5329*4882a593Smuzhiyun /**
5330*4882a593Smuzhiyun  * cik_mc_init - initialize the memory controller driver params
5331*4882a593Smuzhiyun  *
5332*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5333*4882a593Smuzhiyun  *
5334*4882a593Smuzhiyun  * Look up the amount of vram, vram width, and decide how to place
5335*4882a593Smuzhiyun  * vram and gart within the GPU's physical address space (CIK).
5336*4882a593Smuzhiyun  * Returns 0 for success.
5337*4882a593Smuzhiyun  */
cik_mc_init(struct radeon_device * rdev)5338*4882a593Smuzhiyun static int cik_mc_init(struct radeon_device *rdev)
5339*4882a593Smuzhiyun {
5340*4882a593Smuzhiyun 	u32 tmp;
5341*4882a593Smuzhiyun 	int chansize, numchan;
5342*4882a593Smuzhiyun 
5343*4882a593Smuzhiyun 	/* Get VRAM informations */
5344*4882a593Smuzhiyun 	rdev->mc.vram_is_ddr = true;
5345*4882a593Smuzhiyun 	tmp = RREG32(MC_ARB_RAMCFG);
5346*4882a593Smuzhiyun 	if (tmp & CHANSIZE_MASK) {
5347*4882a593Smuzhiyun 		chansize = 64;
5348*4882a593Smuzhiyun 	} else {
5349*4882a593Smuzhiyun 		chansize = 32;
5350*4882a593Smuzhiyun 	}
5351*4882a593Smuzhiyun 	tmp = RREG32(MC_SHARED_CHMAP);
5352*4882a593Smuzhiyun 	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
5353*4882a593Smuzhiyun 	case 0:
5354*4882a593Smuzhiyun 	default:
5355*4882a593Smuzhiyun 		numchan = 1;
5356*4882a593Smuzhiyun 		break;
5357*4882a593Smuzhiyun 	case 1:
5358*4882a593Smuzhiyun 		numchan = 2;
5359*4882a593Smuzhiyun 		break;
5360*4882a593Smuzhiyun 	case 2:
5361*4882a593Smuzhiyun 		numchan = 4;
5362*4882a593Smuzhiyun 		break;
5363*4882a593Smuzhiyun 	case 3:
5364*4882a593Smuzhiyun 		numchan = 8;
5365*4882a593Smuzhiyun 		break;
5366*4882a593Smuzhiyun 	case 4:
5367*4882a593Smuzhiyun 		numchan = 3;
5368*4882a593Smuzhiyun 		break;
5369*4882a593Smuzhiyun 	case 5:
5370*4882a593Smuzhiyun 		numchan = 6;
5371*4882a593Smuzhiyun 		break;
5372*4882a593Smuzhiyun 	case 6:
5373*4882a593Smuzhiyun 		numchan = 10;
5374*4882a593Smuzhiyun 		break;
5375*4882a593Smuzhiyun 	case 7:
5376*4882a593Smuzhiyun 		numchan = 12;
5377*4882a593Smuzhiyun 		break;
5378*4882a593Smuzhiyun 	case 8:
5379*4882a593Smuzhiyun 		numchan = 16;
5380*4882a593Smuzhiyun 		break;
5381*4882a593Smuzhiyun 	}
5382*4882a593Smuzhiyun 	rdev->mc.vram_width = numchan * chansize;
5383*4882a593Smuzhiyun 	/* Could aper size report 0 ? */
5384*4882a593Smuzhiyun 	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
5385*4882a593Smuzhiyun 	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
5386*4882a593Smuzhiyun 	/* size in MB on si */
5387*4882a593Smuzhiyun 	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
5388*4882a593Smuzhiyun 	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
5389*4882a593Smuzhiyun 	rdev->mc.visible_vram_size = rdev->mc.aper_size;
5390*4882a593Smuzhiyun 	si_vram_gtt_location(rdev, &rdev->mc);
5391*4882a593Smuzhiyun 	radeon_update_bandwidth_info(rdev);
5392*4882a593Smuzhiyun 
5393*4882a593Smuzhiyun 	return 0;
5394*4882a593Smuzhiyun }
5395*4882a593Smuzhiyun 
5396*4882a593Smuzhiyun /*
5397*4882a593Smuzhiyun  * GART
5398*4882a593Smuzhiyun  * VMID 0 is the physical GPU addresses as used by the kernel.
5399*4882a593Smuzhiyun  * VMIDs 1-15 are used for userspace clients and are handled
5400*4882a593Smuzhiyun  * by the radeon vm/hsa code.
5401*4882a593Smuzhiyun  */
5402*4882a593Smuzhiyun /**
5403*4882a593Smuzhiyun  * cik_pcie_gart_tlb_flush - gart tlb flush callback
5404*4882a593Smuzhiyun  *
5405*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5406*4882a593Smuzhiyun  *
5407*4882a593Smuzhiyun  * Flush the TLB for the VMID 0 page table (CIK).
5408*4882a593Smuzhiyun  */
cik_pcie_gart_tlb_flush(struct radeon_device * rdev)5409*4882a593Smuzhiyun void cik_pcie_gart_tlb_flush(struct radeon_device *rdev)
5410*4882a593Smuzhiyun {
5411*4882a593Smuzhiyun 	/* flush hdp cache */
5412*4882a593Smuzhiyun 	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0);
5413*4882a593Smuzhiyun 
5414*4882a593Smuzhiyun 	/* bits 0-15 are the VM contexts0-15 */
5415*4882a593Smuzhiyun 	WREG32(VM_INVALIDATE_REQUEST, 0x1);
5416*4882a593Smuzhiyun }
5417*4882a593Smuzhiyun 
5418*4882a593Smuzhiyun /**
5419*4882a593Smuzhiyun  * cik_pcie_gart_enable - gart enable
5420*4882a593Smuzhiyun  *
5421*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5422*4882a593Smuzhiyun  *
5423*4882a593Smuzhiyun  * This sets up the TLBs, programs the page tables for VMID0,
5424*4882a593Smuzhiyun  * sets up the hw for VMIDs 1-15 which are allocated on
5425*4882a593Smuzhiyun  * demand, and sets up the global locations for the LDS, GDS,
5426*4882a593Smuzhiyun  * and GPUVM for FSA64 clients (CIK).
5427*4882a593Smuzhiyun  * Returns 0 for success, errors for failure.
5428*4882a593Smuzhiyun  */
cik_pcie_gart_enable(struct radeon_device * rdev)5429*4882a593Smuzhiyun static int cik_pcie_gart_enable(struct radeon_device *rdev)
5430*4882a593Smuzhiyun {
5431*4882a593Smuzhiyun 	int r, i;
5432*4882a593Smuzhiyun 
5433*4882a593Smuzhiyun 	if (rdev->gart.robj == NULL) {
5434*4882a593Smuzhiyun 		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
5435*4882a593Smuzhiyun 		return -EINVAL;
5436*4882a593Smuzhiyun 	}
5437*4882a593Smuzhiyun 	r = radeon_gart_table_vram_pin(rdev);
5438*4882a593Smuzhiyun 	if (r)
5439*4882a593Smuzhiyun 		return r;
5440*4882a593Smuzhiyun 	/* Setup TLB control */
5441*4882a593Smuzhiyun 	WREG32(MC_VM_MX_L1_TLB_CNTL,
5442*4882a593Smuzhiyun 	       (0xA << 7) |
5443*4882a593Smuzhiyun 	       ENABLE_L1_TLB |
5444*4882a593Smuzhiyun 	       ENABLE_L1_FRAGMENT_PROCESSING |
5445*4882a593Smuzhiyun 	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
5446*4882a593Smuzhiyun 	       ENABLE_ADVANCED_DRIVER_MODEL |
5447*4882a593Smuzhiyun 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
5448*4882a593Smuzhiyun 	/* Setup L2 cache */
5449*4882a593Smuzhiyun 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
5450*4882a593Smuzhiyun 	       ENABLE_L2_FRAGMENT_PROCESSING |
5451*4882a593Smuzhiyun 	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
5452*4882a593Smuzhiyun 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
5453*4882a593Smuzhiyun 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
5454*4882a593Smuzhiyun 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
5455*4882a593Smuzhiyun 	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
5456*4882a593Smuzhiyun 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
5457*4882a593Smuzhiyun 	       BANK_SELECT(4) |
5458*4882a593Smuzhiyun 	       L2_CACHE_BIGK_FRAGMENT_SIZE(4));
5459*4882a593Smuzhiyun 	/* setup context0 */
5460*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
5461*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
5462*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
5463*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
5464*4882a593Smuzhiyun 			(u32)(rdev->dummy_page.addr >> 12));
5465*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_CNTL2, 0);
5466*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
5467*4882a593Smuzhiyun 				  RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
5468*4882a593Smuzhiyun 
5469*4882a593Smuzhiyun 	WREG32(0x15D4, 0);
5470*4882a593Smuzhiyun 	WREG32(0x15D8, 0);
5471*4882a593Smuzhiyun 	WREG32(0x15DC, 0);
5472*4882a593Smuzhiyun 
5473*4882a593Smuzhiyun 	/* restore context1-15 */
5474*4882a593Smuzhiyun 	/* set vm size, must be a multiple of 4 */
5475*4882a593Smuzhiyun 	WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
5476*4882a593Smuzhiyun 	WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
5477*4882a593Smuzhiyun 	for (i = 1; i < 16; i++) {
5478*4882a593Smuzhiyun 		if (i < 8)
5479*4882a593Smuzhiyun 			WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
5480*4882a593Smuzhiyun 			       rdev->vm_manager.saved_table_addr[i]);
5481*4882a593Smuzhiyun 		else
5482*4882a593Smuzhiyun 			WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
5483*4882a593Smuzhiyun 			       rdev->vm_manager.saved_table_addr[i]);
5484*4882a593Smuzhiyun 	}
5485*4882a593Smuzhiyun 
5486*4882a593Smuzhiyun 	/* enable context1-15 */
5487*4882a593Smuzhiyun 	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
5488*4882a593Smuzhiyun 	       (u32)(rdev->dummy_page.addr >> 12));
5489*4882a593Smuzhiyun 	WREG32(VM_CONTEXT1_CNTL2, 4);
5490*4882a593Smuzhiyun 	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
5491*4882a593Smuzhiyun 				PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
5492*4882a593Smuzhiyun 				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
5493*4882a593Smuzhiyun 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
5494*4882a593Smuzhiyun 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
5495*4882a593Smuzhiyun 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
5496*4882a593Smuzhiyun 				PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
5497*4882a593Smuzhiyun 				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
5498*4882a593Smuzhiyun 				VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
5499*4882a593Smuzhiyun 				VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
5500*4882a593Smuzhiyun 				READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
5501*4882a593Smuzhiyun 				READ_PROTECTION_FAULT_ENABLE_DEFAULT |
5502*4882a593Smuzhiyun 				WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
5503*4882a593Smuzhiyun 				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
5504*4882a593Smuzhiyun 
5505*4882a593Smuzhiyun 	if (rdev->family == CHIP_KAVERI) {
5506*4882a593Smuzhiyun 		u32 tmp = RREG32(CHUB_CONTROL);
5507*4882a593Smuzhiyun 		tmp &= ~BYPASS_VM;
5508*4882a593Smuzhiyun 		WREG32(CHUB_CONTROL, tmp);
5509*4882a593Smuzhiyun 	}
5510*4882a593Smuzhiyun 
5511*4882a593Smuzhiyun 	/* XXX SH_MEM regs */
5512*4882a593Smuzhiyun 	/* where to put LDS, scratch, GPUVM in FSA64 space */
5513*4882a593Smuzhiyun 	mutex_lock(&rdev->srbm_mutex);
5514*4882a593Smuzhiyun 	for (i = 0; i < 16; i++) {
5515*4882a593Smuzhiyun 		cik_srbm_select(rdev, 0, 0, 0, i);
5516*4882a593Smuzhiyun 		/* CP and shaders */
5517*4882a593Smuzhiyun 		WREG32(SH_MEM_CONFIG, SH_MEM_CONFIG_GFX_DEFAULT);
5518*4882a593Smuzhiyun 		WREG32(SH_MEM_APE1_BASE, 1);
5519*4882a593Smuzhiyun 		WREG32(SH_MEM_APE1_LIMIT, 0);
5520*4882a593Smuzhiyun 		WREG32(SH_MEM_BASES, 0);
5521*4882a593Smuzhiyun 		/* SDMA GFX */
5522*4882a593Smuzhiyun 		WREG32(SDMA0_GFX_VIRTUAL_ADDR + SDMA0_REGISTER_OFFSET, 0);
5523*4882a593Smuzhiyun 		WREG32(SDMA0_GFX_APE1_CNTL + SDMA0_REGISTER_OFFSET, 0);
5524*4882a593Smuzhiyun 		WREG32(SDMA0_GFX_VIRTUAL_ADDR + SDMA1_REGISTER_OFFSET, 0);
5525*4882a593Smuzhiyun 		WREG32(SDMA0_GFX_APE1_CNTL + SDMA1_REGISTER_OFFSET, 0);
5526*4882a593Smuzhiyun 		/* XXX SDMA RLC - todo */
5527*4882a593Smuzhiyun 	}
5528*4882a593Smuzhiyun 	cik_srbm_select(rdev, 0, 0, 0, 0);
5529*4882a593Smuzhiyun 	mutex_unlock(&rdev->srbm_mutex);
5530*4882a593Smuzhiyun 
5531*4882a593Smuzhiyun 	cik_pcie_gart_tlb_flush(rdev);
5532*4882a593Smuzhiyun 	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
5533*4882a593Smuzhiyun 		 (unsigned)(rdev->mc.gtt_size >> 20),
5534*4882a593Smuzhiyun 		 (unsigned long long)rdev->gart.table_addr);
5535*4882a593Smuzhiyun 	rdev->gart.ready = true;
5536*4882a593Smuzhiyun 	return 0;
5537*4882a593Smuzhiyun }
5538*4882a593Smuzhiyun 
5539*4882a593Smuzhiyun /**
5540*4882a593Smuzhiyun  * cik_pcie_gart_disable - gart disable
5541*4882a593Smuzhiyun  *
5542*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5543*4882a593Smuzhiyun  *
5544*4882a593Smuzhiyun  * This disables all VM page table (CIK).
5545*4882a593Smuzhiyun  */
cik_pcie_gart_disable(struct radeon_device * rdev)5546*4882a593Smuzhiyun static void cik_pcie_gart_disable(struct radeon_device *rdev)
5547*4882a593Smuzhiyun {
5548*4882a593Smuzhiyun 	unsigned i;
5549*4882a593Smuzhiyun 
5550*4882a593Smuzhiyun 	for (i = 1; i < 16; ++i) {
5551*4882a593Smuzhiyun 		uint32_t reg;
5552*4882a593Smuzhiyun 		if (i < 8)
5553*4882a593Smuzhiyun 			reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
5554*4882a593Smuzhiyun 		else
5555*4882a593Smuzhiyun 			reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
5556*4882a593Smuzhiyun 		rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
5557*4882a593Smuzhiyun 	}
5558*4882a593Smuzhiyun 
5559*4882a593Smuzhiyun 	/* Disable all tables */
5560*4882a593Smuzhiyun 	WREG32(VM_CONTEXT0_CNTL, 0);
5561*4882a593Smuzhiyun 	WREG32(VM_CONTEXT1_CNTL, 0);
5562*4882a593Smuzhiyun 	/* Setup TLB control */
5563*4882a593Smuzhiyun 	WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
5564*4882a593Smuzhiyun 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
5565*4882a593Smuzhiyun 	/* Setup L2 cache */
5566*4882a593Smuzhiyun 	WREG32(VM_L2_CNTL,
5567*4882a593Smuzhiyun 	       ENABLE_L2_FRAGMENT_PROCESSING |
5568*4882a593Smuzhiyun 	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
5569*4882a593Smuzhiyun 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
5570*4882a593Smuzhiyun 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
5571*4882a593Smuzhiyun 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
5572*4882a593Smuzhiyun 	WREG32(VM_L2_CNTL2, 0);
5573*4882a593Smuzhiyun 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
5574*4882a593Smuzhiyun 	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
5575*4882a593Smuzhiyun 	radeon_gart_table_vram_unpin(rdev);
5576*4882a593Smuzhiyun }
5577*4882a593Smuzhiyun 
5578*4882a593Smuzhiyun /**
5579*4882a593Smuzhiyun  * cik_pcie_gart_fini - vm fini callback
5580*4882a593Smuzhiyun  *
5581*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5582*4882a593Smuzhiyun  *
5583*4882a593Smuzhiyun  * Tears down the driver GART/VM setup (CIK).
5584*4882a593Smuzhiyun  */
cik_pcie_gart_fini(struct radeon_device * rdev)5585*4882a593Smuzhiyun static void cik_pcie_gart_fini(struct radeon_device *rdev)
5586*4882a593Smuzhiyun {
5587*4882a593Smuzhiyun 	cik_pcie_gart_disable(rdev);
5588*4882a593Smuzhiyun 	radeon_gart_table_vram_free(rdev);
5589*4882a593Smuzhiyun 	radeon_gart_fini(rdev);
5590*4882a593Smuzhiyun }
5591*4882a593Smuzhiyun 
5592*4882a593Smuzhiyun /* vm parser */
5593*4882a593Smuzhiyun /**
5594*4882a593Smuzhiyun  * cik_ib_parse - vm ib_parse callback
5595*4882a593Smuzhiyun  *
5596*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5597*4882a593Smuzhiyun  * @ib: indirect buffer pointer
5598*4882a593Smuzhiyun  *
5599*4882a593Smuzhiyun  * CIK uses hw IB checking so this is a nop (CIK).
5600*4882a593Smuzhiyun  */
cik_ib_parse(struct radeon_device * rdev,struct radeon_ib * ib)5601*4882a593Smuzhiyun int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
5602*4882a593Smuzhiyun {
5603*4882a593Smuzhiyun 	return 0;
5604*4882a593Smuzhiyun }
5605*4882a593Smuzhiyun 
5606*4882a593Smuzhiyun /*
5607*4882a593Smuzhiyun  * vm
5608*4882a593Smuzhiyun  * VMID 0 is the physical GPU addresses as used by the kernel.
5609*4882a593Smuzhiyun  * VMIDs 1-15 are used for userspace clients and are handled
5610*4882a593Smuzhiyun  * by the radeon vm/hsa code.
5611*4882a593Smuzhiyun  */
5612*4882a593Smuzhiyun /**
5613*4882a593Smuzhiyun  * cik_vm_init - cik vm init callback
5614*4882a593Smuzhiyun  *
5615*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5616*4882a593Smuzhiyun  *
5617*4882a593Smuzhiyun  * Inits cik specific vm parameters (number of VMs, base of vram for
5618*4882a593Smuzhiyun  * VMIDs 1-15) (CIK).
5619*4882a593Smuzhiyun  * Returns 0 for success.
5620*4882a593Smuzhiyun  */
cik_vm_init(struct radeon_device * rdev)5621*4882a593Smuzhiyun int cik_vm_init(struct radeon_device *rdev)
5622*4882a593Smuzhiyun {
5623*4882a593Smuzhiyun 	/*
5624*4882a593Smuzhiyun 	 * number of VMs
5625*4882a593Smuzhiyun 	 * VMID 0 is reserved for System
5626*4882a593Smuzhiyun 	 * radeon graphics/compute will use VMIDs 1-15
5627*4882a593Smuzhiyun 	 */
5628*4882a593Smuzhiyun 	rdev->vm_manager.nvm = 16;
5629*4882a593Smuzhiyun 	/* base offset of vram pages */
5630*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP) {
5631*4882a593Smuzhiyun 		u64 tmp = RREG32(MC_VM_FB_OFFSET);
5632*4882a593Smuzhiyun 		tmp <<= 22;
5633*4882a593Smuzhiyun 		rdev->vm_manager.vram_base_offset = tmp;
5634*4882a593Smuzhiyun 	} else
5635*4882a593Smuzhiyun 		rdev->vm_manager.vram_base_offset = 0;
5636*4882a593Smuzhiyun 
5637*4882a593Smuzhiyun 	return 0;
5638*4882a593Smuzhiyun }
5639*4882a593Smuzhiyun 
5640*4882a593Smuzhiyun /**
5641*4882a593Smuzhiyun  * cik_vm_fini - cik vm fini callback
5642*4882a593Smuzhiyun  *
5643*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5644*4882a593Smuzhiyun  *
5645*4882a593Smuzhiyun  * Tear down any asic specific VM setup (CIK).
5646*4882a593Smuzhiyun  */
cik_vm_fini(struct radeon_device * rdev)5647*4882a593Smuzhiyun void cik_vm_fini(struct radeon_device *rdev)
5648*4882a593Smuzhiyun {
5649*4882a593Smuzhiyun }
5650*4882a593Smuzhiyun 
5651*4882a593Smuzhiyun /**
5652*4882a593Smuzhiyun  * cik_vm_decode_fault - print human readable fault info
5653*4882a593Smuzhiyun  *
5654*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5655*4882a593Smuzhiyun  * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
5656*4882a593Smuzhiyun  * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
5657*4882a593Smuzhiyun  *
5658*4882a593Smuzhiyun  * Print human readable fault information (CIK).
5659*4882a593Smuzhiyun  */
cik_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr,u32 mc_client)5660*4882a593Smuzhiyun static void cik_vm_decode_fault(struct radeon_device *rdev,
5661*4882a593Smuzhiyun 				u32 status, u32 addr, u32 mc_client)
5662*4882a593Smuzhiyun {
5663*4882a593Smuzhiyun 	u32 mc_id;
5664*4882a593Smuzhiyun 	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
5665*4882a593Smuzhiyun 	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
5666*4882a593Smuzhiyun 	char block[5] = { mc_client >> 24, (mc_client >> 16) & 0xff,
5667*4882a593Smuzhiyun 		(mc_client >> 8) & 0xff, mc_client & 0xff, 0 };
5668*4882a593Smuzhiyun 
5669*4882a593Smuzhiyun 	if (rdev->family == CHIP_HAWAII)
5670*4882a593Smuzhiyun 		mc_id = (status & HAWAII_MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
5671*4882a593Smuzhiyun 	else
5672*4882a593Smuzhiyun 		mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
5673*4882a593Smuzhiyun 
5674*4882a593Smuzhiyun 	printk("VM fault (0x%02x, vmid %d) at page %u, %s from '%s' (0x%08x) (%d)\n",
5675*4882a593Smuzhiyun 	       protections, vmid, addr,
5676*4882a593Smuzhiyun 	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
5677*4882a593Smuzhiyun 	       block, mc_client, mc_id);
5678*4882a593Smuzhiyun }
5679*4882a593Smuzhiyun 
5680*4882a593Smuzhiyun /**
5681*4882a593Smuzhiyun  * cik_vm_flush - cik vm flush using the CP
5682*4882a593Smuzhiyun  *
5683*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5684*4882a593Smuzhiyun  *
5685*4882a593Smuzhiyun  * Update the page table base and flush the VM TLB
5686*4882a593Smuzhiyun  * using the CP (CIK).
5687*4882a593Smuzhiyun  */
cik_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)5688*4882a593Smuzhiyun void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
5689*4882a593Smuzhiyun 		  unsigned vm_id, uint64_t pd_addr)
5690*4882a593Smuzhiyun {
5691*4882a593Smuzhiyun 	int usepfp = (ring->idx == RADEON_RING_TYPE_GFX_INDEX);
5692*4882a593Smuzhiyun 
5693*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5694*4882a593Smuzhiyun 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
5695*4882a593Smuzhiyun 				 WRITE_DATA_DST_SEL(0)));
5696*4882a593Smuzhiyun 	if (vm_id < 8) {
5697*4882a593Smuzhiyun 		radeon_ring_write(ring,
5698*4882a593Smuzhiyun 				  (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2);
5699*4882a593Smuzhiyun 	} else {
5700*4882a593Smuzhiyun 		radeon_ring_write(ring,
5701*4882a593Smuzhiyun 				  (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2);
5702*4882a593Smuzhiyun 	}
5703*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
5704*4882a593Smuzhiyun 	radeon_ring_write(ring, pd_addr >> 12);
5705*4882a593Smuzhiyun 
5706*4882a593Smuzhiyun 	/* update SH_MEM_* regs */
5707*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5708*4882a593Smuzhiyun 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
5709*4882a593Smuzhiyun 				 WRITE_DATA_DST_SEL(0)));
5710*4882a593Smuzhiyun 	radeon_ring_write(ring, SRBM_GFX_CNTL >> 2);
5711*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
5712*4882a593Smuzhiyun 	radeon_ring_write(ring, VMID(vm_id));
5713*4882a593Smuzhiyun 
5714*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6));
5715*4882a593Smuzhiyun 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
5716*4882a593Smuzhiyun 				 WRITE_DATA_DST_SEL(0)));
5717*4882a593Smuzhiyun 	radeon_ring_write(ring, SH_MEM_BASES >> 2);
5718*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
5719*4882a593Smuzhiyun 
5720*4882a593Smuzhiyun 	radeon_ring_write(ring, 0); /* SH_MEM_BASES */
5721*4882a593Smuzhiyun 	radeon_ring_write(ring, SH_MEM_CONFIG_GFX_DEFAULT); /* SH_MEM_CONFIG */
5722*4882a593Smuzhiyun 	radeon_ring_write(ring, 1); /* SH_MEM_APE1_BASE */
5723*4882a593Smuzhiyun 	radeon_ring_write(ring, 0); /* SH_MEM_APE1_LIMIT */
5724*4882a593Smuzhiyun 
5725*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5726*4882a593Smuzhiyun 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
5727*4882a593Smuzhiyun 				 WRITE_DATA_DST_SEL(0)));
5728*4882a593Smuzhiyun 	radeon_ring_write(ring, SRBM_GFX_CNTL >> 2);
5729*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
5730*4882a593Smuzhiyun 	radeon_ring_write(ring, VMID(0));
5731*4882a593Smuzhiyun 
5732*4882a593Smuzhiyun 	/* HDP flush */
5733*4882a593Smuzhiyun 	cik_hdp_flush_cp_ring_emit(rdev, ring->idx);
5734*4882a593Smuzhiyun 
5735*4882a593Smuzhiyun 	/* bits 0-15 are the VM contexts0-15 */
5736*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5737*4882a593Smuzhiyun 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
5738*4882a593Smuzhiyun 				 WRITE_DATA_DST_SEL(0)));
5739*4882a593Smuzhiyun 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
5740*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
5741*4882a593Smuzhiyun 	radeon_ring_write(ring, 1 << vm_id);
5742*4882a593Smuzhiyun 
5743*4882a593Smuzhiyun 	/* wait for the invalidate to complete */
5744*4882a593Smuzhiyun 	radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
5745*4882a593Smuzhiyun 	radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */
5746*4882a593Smuzhiyun 				 WAIT_REG_MEM_FUNCTION(0) |  /* always */
5747*4882a593Smuzhiyun 				 WAIT_REG_MEM_ENGINE(0))); /* me */
5748*4882a593Smuzhiyun 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
5749*4882a593Smuzhiyun 	radeon_ring_write(ring, 0);
5750*4882a593Smuzhiyun 	radeon_ring_write(ring, 0); /* ref */
5751*4882a593Smuzhiyun 	radeon_ring_write(ring, 0); /* mask */
5752*4882a593Smuzhiyun 	radeon_ring_write(ring, 0x20); /* poll interval */
5753*4882a593Smuzhiyun 
5754*4882a593Smuzhiyun 	/* compute doesn't have PFP */
5755*4882a593Smuzhiyun 	if (usepfp) {
5756*4882a593Smuzhiyun 		/* sync PFP to ME, otherwise we might get invalid PFP reads */
5757*4882a593Smuzhiyun 		radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
5758*4882a593Smuzhiyun 		radeon_ring_write(ring, 0x0);
5759*4882a593Smuzhiyun 	}
5760*4882a593Smuzhiyun }
5761*4882a593Smuzhiyun 
5762*4882a593Smuzhiyun /*
5763*4882a593Smuzhiyun  * RLC
5764*4882a593Smuzhiyun  * The RLC is a multi-purpose microengine that handles a
5765*4882a593Smuzhiyun  * variety of functions, the most important of which is
5766*4882a593Smuzhiyun  * the interrupt controller.
5767*4882a593Smuzhiyun  */
cik_enable_gui_idle_interrupt(struct radeon_device * rdev,bool enable)5768*4882a593Smuzhiyun static void cik_enable_gui_idle_interrupt(struct radeon_device *rdev,
5769*4882a593Smuzhiyun 					  bool enable)
5770*4882a593Smuzhiyun {
5771*4882a593Smuzhiyun 	u32 tmp = RREG32(CP_INT_CNTL_RING0);
5772*4882a593Smuzhiyun 
5773*4882a593Smuzhiyun 	if (enable)
5774*4882a593Smuzhiyun 		tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
5775*4882a593Smuzhiyun 	else
5776*4882a593Smuzhiyun 		tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
5777*4882a593Smuzhiyun 	WREG32(CP_INT_CNTL_RING0, tmp);
5778*4882a593Smuzhiyun }
5779*4882a593Smuzhiyun 
cik_enable_lbpw(struct radeon_device * rdev,bool enable)5780*4882a593Smuzhiyun static void cik_enable_lbpw(struct radeon_device *rdev, bool enable)
5781*4882a593Smuzhiyun {
5782*4882a593Smuzhiyun 	u32 tmp;
5783*4882a593Smuzhiyun 
5784*4882a593Smuzhiyun 	tmp = RREG32(RLC_LB_CNTL);
5785*4882a593Smuzhiyun 	if (enable)
5786*4882a593Smuzhiyun 		tmp |= LOAD_BALANCE_ENABLE;
5787*4882a593Smuzhiyun 	else
5788*4882a593Smuzhiyun 		tmp &= ~LOAD_BALANCE_ENABLE;
5789*4882a593Smuzhiyun 	WREG32(RLC_LB_CNTL, tmp);
5790*4882a593Smuzhiyun }
5791*4882a593Smuzhiyun 
cik_wait_for_rlc_serdes(struct radeon_device * rdev)5792*4882a593Smuzhiyun static void cik_wait_for_rlc_serdes(struct radeon_device *rdev)
5793*4882a593Smuzhiyun {
5794*4882a593Smuzhiyun 	u32 i, j, k;
5795*4882a593Smuzhiyun 	u32 mask;
5796*4882a593Smuzhiyun 
5797*4882a593Smuzhiyun 	for (i = 0; i < rdev->config.cik.max_shader_engines; i++) {
5798*4882a593Smuzhiyun 		for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) {
5799*4882a593Smuzhiyun 			cik_select_se_sh(rdev, i, j);
5800*4882a593Smuzhiyun 			for (k = 0; k < rdev->usec_timeout; k++) {
5801*4882a593Smuzhiyun 				if (RREG32(RLC_SERDES_CU_MASTER_BUSY) == 0)
5802*4882a593Smuzhiyun 					break;
5803*4882a593Smuzhiyun 				udelay(1);
5804*4882a593Smuzhiyun 			}
5805*4882a593Smuzhiyun 		}
5806*4882a593Smuzhiyun 	}
5807*4882a593Smuzhiyun 	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
5808*4882a593Smuzhiyun 
5809*4882a593Smuzhiyun 	mask = SE_MASTER_BUSY_MASK | GC_MASTER_BUSY | TC0_MASTER_BUSY | TC1_MASTER_BUSY;
5810*4882a593Smuzhiyun 	for (k = 0; k < rdev->usec_timeout; k++) {
5811*4882a593Smuzhiyun 		if ((RREG32(RLC_SERDES_NONCU_MASTER_BUSY) & mask) == 0)
5812*4882a593Smuzhiyun 			break;
5813*4882a593Smuzhiyun 		udelay(1);
5814*4882a593Smuzhiyun 	}
5815*4882a593Smuzhiyun }
5816*4882a593Smuzhiyun 
cik_update_rlc(struct radeon_device * rdev,u32 rlc)5817*4882a593Smuzhiyun static void cik_update_rlc(struct radeon_device *rdev, u32 rlc)
5818*4882a593Smuzhiyun {
5819*4882a593Smuzhiyun 	u32 tmp;
5820*4882a593Smuzhiyun 
5821*4882a593Smuzhiyun 	tmp = RREG32(RLC_CNTL);
5822*4882a593Smuzhiyun 	if (tmp != rlc)
5823*4882a593Smuzhiyun 		WREG32(RLC_CNTL, rlc);
5824*4882a593Smuzhiyun }
5825*4882a593Smuzhiyun 
cik_halt_rlc(struct radeon_device * rdev)5826*4882a593Smuzhiyun static u32 cik_halt_rlc(struct radeon_device *rdev)
5827*4882a593Smuzhiyun {
5828*4882a593Smuzhiyun 	u32 data, orig;
5829*4882a593Smuzhiyun 
5830*4882a593Smuzhiyun 	orig = data = RREG32(RLC_CNTL);
5831*4882a593Smuzhiyun 
5832*4882a593Smuzhiyun 	if (data & RLC_ENABLE) {
5833*4882a593Smuzhiyun 		u32 i;
5834*4882a593Smuzhiyun 
5835*4882a593Smuzhiyun 		data &= ~RLC_ENABLE;
5836*4882a593Smuzhiyun 		WREG32(RLC_CNTL, data);
5837*4882a593Smuzhiyun 
5838*4882a593Smuzhiyun 		for (i = 0; i < rdev->usec_timeout; i++) {
5839*4882a593Smuzhiyun 			if ((RREG32(RLC_GPM_STAT) & RLC_GPM_BUSY) == 0)
5840*4882a593Smuzhiyun 				break;
5841*4882a593Smuzhiyun 			udelay(1);
5842*4882a593Smuzhiyun 		}
5843*4882a593Smuzhiyun 
5844*4882a593Smuzhiyun 		cik_wait_for_rlc_serdes(rdev);
5845*4882a593Smuzhiyun 	}
5846*4882a593Smuzhiyun 
5847*4882a593Smuzhiyun 	return orig;
5848*4882a593Smuzhiyun }
5849*4882a593Smuzhiyun 
cik_enter_rlc_safe_mode(struct radeon_device * rdev)5850*4882a593Smuzhiyun void cik_enter_rlc_safe_mode(struct radeon_device *rdev)
5851*4882a593Smuzhiyun {
5852*4882a593Smuzhiyun 	u32 tmp, i, mask;
5853*4882a593Smuzhiyun 
5854*4882a593Smuzhiyun 	tmp = REQ | MESSAGE(MSG_ENTER_RLC_SAFE_MODE);
5855*4882a593Smuzhiyun 	WREG32(RLC_GPR_REG2, tmp);
5856*4882a593Smuzhiyun 
5857*4882a593Smuzhiyun 	mask = GFX_POWER_STATUS | GFX_CLOCK_STATUS;
5858*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
5859*4882a593Smuzhiyun 		if ((RREG32(RLC_GPM_STAT) & mask) == mask)
5860*4882a593Smuzhiyun 			break;
5861*4882a593Smuzhiyun 		udelay(1);
5862*4882a593Smuzhiyun 	}
5863*4882a593Smuzhiyun 
5864*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
5865*4882a593Smuzhiyun 		if ((RREG32(RLC_GPR_REG2) & REQ) == 0)
5866*4882a593Smuzhiyun 			break;
5867*4882a593Smuzhiyun 		udelay(1);
5868*4882a593Smuzhiyun 	}
5869*4882a593Smuzhiyun }
5870*4882a593Smuzhiyun 
cik_exit_rlc_safe_mode(struct radeon_device * rdev)5871*4882a593Smuzhiyun void cik_exit_rlc_safe_mode(struct radeon_device *rdev)
5872*4882a593Smuzhiyun {
5873*4882a593Smuzhiyun 	u32 tmp;
5874*4882a593Smuzhiyun 
5875*4882a593Smuzhiyun 	tmp = REQ | MESSAGE(MSG_EXIT_RLC_SAFE_MODE);
5876*4882a593Smuzhiyun 	WREG32(RLC_GPR_REG2, tmp);
5877*4882a593Smuzhiyun }
5878*4882a593Smuzhiyun 
5879*4882a593Smuzhiyun /**
5880*4882a593Smuzhiyun  * cik_rlc_stop - stop the RLC ME
5881*4882a593Smuzhiyun  *
5882*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5883*4882a593Smuzhiyun  *
5884*4882a593Smuzhiyun  * Halt the RLC ME (MicroEngine) (CIK).
5885*4882a593Smuzhiyun  */
cik_rlc_stop(struct radeon_device * rdev)5886*4882a593Smuzhiyun static void cik_rlc_stop(struct radeon_device *rdev)
5887*4882a593Smuzhiyun {
5888*4882a593Smuzhiyun 	WREG32(RLC_CNTL, 0);
5889*4882a593Smuzhiyun 
5890*4882a593Smuzhiyun 	cik_enable_gui_idle_interrupt(rdev, false);
5891*4882a593Smuzhiyun 
5892*4882a593Smuzhiyun 	cik_wait_for_rlc_serdes(rdev);
5893*4882a593Smuzhiyun }
5894*4882a593Smuzhiyun 
5895*4882a593Smuzhiyun /**
5896*4882a593Smuzhiyun  * cik_rlc_start - start the RLC ME
5897*4882a593Smuzhiyun  *
5898*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5899*4882a593Smuzhiyun  *
5900*4882a593Smuzhiyun  * Unhalt the RLC ME (MicroEngine) (CIK).
5901*4882a593Smuzhiyun  */
cik_rlc_start(struct radeon_device * rdev)5902*4882a593Smuzhiyun static void cik_rlc_start(struct radeon_device *rdev)
5903*4882a593Smuzhiyun {
5904*4882a593Smuzhiyun 	WREG32(RLC_CNTL, RLC_ENABLE);
5905*4882a593Smuzhiyun 
5906*4882a593Smuzhiyun 	cik_enable_gui_idle_interrupt(rdev, true);
5907*4882a593Smuzhiyun 
5908*4882a593Smuzhiyun 	udelay(50);
5909*4882a593Smuzhiyun }
5910*4882a593Smuzhiyun 
5911*4882a593Smuzhiyun /**
5912*4882a593Smuzhiyun  * cik_rlc_resume - setup the RLC hw
5913*4882a593Smuzhiyun  *
5914*4882a593Smuzhiyun  * @rdev: radeon_device pointer
5915*4882a593Smuzhiyun  *
5916*4882a593Smuzhiyun  * Initialize the RLC registers, load the ucode,
5917*4882a593Smuzhiyun  * and start the RLC (CIK).
5918*4882a593Smuzhiyun  * Returns 0 for success, -EINVAL if the ucode is not available.
5919*4882a593Smuzhiyun  */
cik_rlc_resume(struct radeon_device * rdev)5920*4882a593Smuzhiyun static int cik_rlc_resume(struct radeon_device *rdev)
5921*4882a593Smuzhiyun {
5922*4882a593Smuzhiyun 	u32 i, size, tmp;
5923*4882a593Smuzhiyun 
5924*4882a593Smuzhiyun 	if (!rdev->rlc_fw)
5925*4882a593Smuzhiyun 		return -EINVAL;
5926*4882a593Smuzhiyun 
5927*4882a593Smuzhiyun 	cik_rlc_stop(rdev);
5928*4882a593Smuzhiyun 
5929*4882a593Smuzhiyun 	/* disable CG */
5930*4882a593Smuzhiyun 	tmp = RREG32(RLC_CGCG_CGLS_CTRL) & 0xfffffffc;
5931*4882a593Smuzhiyun 	WREG32(RLC_CGCG_CGLS_CTRL, tmp);
5932*4882a593Smuzhiyun 
5933*4882a593Smuzhiyun 	si_rlc_reset(rdev);
5934*4882a593Smuzhiyun 
5935*4882a593Smuzhiyun 	cik_init_pg(rdev);
5936*4882a593Smuzhiyun 
5937*4882a593Smuzhiyun 	cik_init_cg(rdev);
5938*4882a593Smuzhiyun 
5939*4882a593Smuzhiyun 	WREG32(RLC_LB_CNTR_INIT, 0);
5940*4882a593Smuzhiyun 	WREG32(RLC_LB_CNTR_MAX, 0x00008000);
5941*4882a593Smuzhiyun 
5942*4882a593Smuzhiyun 	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
5943*4882a593Smuzhiyun 	WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
5944*4882a593Smuzhiyun 	WREG32(RLC_LB_PARAMS, 0x00600408);
5945*4882a593Smuzhiyun 	WREG32(RLC_LB_CNTL, 0x80000004);
5946*4882a593Smuzhiyun 
5947*4882a593Smuzhiyun 	WREG32(RLC_MC_CNTL, 0);
5948*4882a593Smuzhiyun 	WREG32(RLC_UCODE_CNTL, 0);
5949*4882a593Smuzhiyun 
5950*4882a593Smuzhiyun 	if (rdev->new_fw) {
5951*4882a593Smuzhiyun 		const struct rlc_firmware_header_v1_0 *hdr =
5952*4882a593Smuzhiyun 			(const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
5953*4882a593Smuzhiyun 		const __le32 *fw_data = (const __le32 *)
5954*4882a593Smuzhiyun 			(rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
5955*4882a593Smuzhiyun 
5956*4882a593Smuzhiyun 		radeon_ucode_print_rlc_hdr(&hdr->header);
5957*4882a593Smuzhiyun 
5958*4882a593Smuzhiyun 		size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
5959*4882a593Smuzhiyun 		WREG32(RLC_GPM_UCODE_ADDR, 0);
5960*4882a593Smuzhiyun 		for (i = 0; i < size; i++)
5961*4882a593Smuzhiyun 			WREG32(RLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++));
5962*4882a593Smuzhiyun 		WREG32(RLC_GPM_UCODE_ADDR, le32_to_cpu(hdr->header.ucode_version));
5963*4882a593Smuzhiyun 	} else {
5964*4882a593Smuzhiyun 		const __be32 *fw_data;
5965*4882a593Smuzhiyun 
5966*4882a593Smuzhiyun 		switch (rdev->family) {
5967*4882a593Smuzhiyun 		case CHIP_BONAIRE:
5968*4882a593Smuzhiyun 		case CHIP_HAWAII:
5969*4882a593Smuzhiyun 		default:
5970*4882a593Smuzhiyun 			size = BONAIRE_RLC_UCODE_SIZE;
5971*4882a593Smuzhiyun 			break;
5972*4882a593Smuzhiyun 		case CHIP_KAVERI:
5973*4882a593Smuzhiyun 			size = KV_RLC_UCODE_SIZE;
5974*4882a593Smuzhiyun 			break;
5975*4882a593Smuzhiyun 		case CHIP_KABINI:
5976*4882a593Smuzhiyun 			size = KB_RLC_UCODE_SIZE;
5977*4882a593Smuzhiyun 			break;
5978*4882a593Smuzhiyun 		case CHIP_MULLINS:
5979*4882a593Smuzhiyun 			size = ML_RLC_UCODE_SIZE;
5980*4882a593Smuzhiyun 			break;
5981*4882a593Smuzhiyun 		}
5982*4882a593Smuzhiyun 
5983*4882a593Smuzhiyun 		fw_data = (const __be32 *)rdev->rlc_fw->data;
5984*4882a593Smuzhiyun 		WREG32(RLC_GPM_UCODE_ADDR, 0);
5985*4882a593Smuzhiyun 		for (i = 0; i < size; i++)
5986*4882a593Smuzhiyun 			WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++));
5987*4882a593Smuzhiyun 		WREG32(RLC_GPM_UCODE_ADDR, 0);
5988*4882a593Smuzhiyun 	}
5989*4882a593Smuzhiyun 
5990*4882a593Smuzhiyun 	/* XXX - find out what chips support lbpw */
5991*4882a593Smuzhiyun 	cik_enable_lbpw(rdev, false);
5992*4882a593Smuzhiyun 
5993*4882a593Smuzhiyun 	if (rdev->family == CHIP_BONAIRE)
5994*4882a593Smuzhiyun 		WREG32(RLC_DRIVER_DMA_STATUS, 0);
5995*4882a593Smuzhiyun 
5996*4882a593Smuzhiyun 	cik_rlc_start(rdev);
5997*4882a593Smuzhiyun 
5998*4882a593Smuzhiyun 	return 0;
5999*4882a593Smuzhiyun }
6000*4882a593Smuzhiyun 
cik_enable_cgcg(struct radeon_device * rdev,bool enable)6001*4882a593Smuzhiyun static void cik_enable_cgcg(struct radeon_device *rdev, bool enable)
6002*4882a593Smuzhiyun {
6003*4882a593Smuzhiyun 	u32 data, orig, tmp, tmp2;
6004*4882a593Smuzhiyun 
6005*4882a593Smuzhiyun 	orig = data = RREG32(RLC_CGCG_CGLS_CTRL);
6006*4882a593Smuzhiyun 
6007*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) {
6008*4882a593Smuzhiyun 		cik_enable_gui_idle_interrupt(rdev, true);
6009*4882a593Smuzhiyun 
6010*4882a593Smuzhiyun 		tmp = cik_halt_rlc(rdev);
6011*4882a593Smuzhiyun 
6012*4882a593Smuzhiyun 		cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
6013*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff);
6014*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff);
6015*4882a593Smuzhiyun 		tmp2 = BPM_ADDR_MASK | CGCG_OVERRIDE_0 | CGLS_ENABLE;
6016*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_CTRL, tmp2);
6017*4882a593Smuzhiyun 
6018*4882a593Smuzhiyun 		cik_update_rlc(rdev, tmp);
6019*4882a593Smuzhiyun 
6020*4882a593Smuzhiyun 		data |= CGCG_EN | CGLS_EN;
6021*4882a593Smuzhiyun 	} else {
6022*4882a593Smuzhiyun 		cik_enable_gui_idle_interrupt(rdev, false);
6023*4882a593Smuzhiyun 
6024*4882a593Smuzhiyun 		RREG32(CB_CGTT_SCLK_CTRL);
6025*4882a593Smuzhiyun 		RREG32(CB_CGTT_SCLK_CTRL);
6026*4882a593Smuzhiyun 		RREG32(CB_CGTT_SCLK_CTRL);
6027*4882a593Smuzhiyun 		RREG32(CB_CGTT_SCLK_CTRL);
6028*4882a593Smuzhiyun 
6029*4882a593Smuzhiyun 		data &= ~(CGCG_EN | CGLS_EN);
6030*4882a593Smuzhiyun 	}
6031*4882a593Smuzhiyun 
6032*4882a593Smuzhiyun 	if (orig != data)
6033*4882a593Smuzhiyun 		WREG32(RLC_CGCG_CGLS_CTRL, data);
6034*4882a593Smuzhiyun 
6035*4882a593Smuzhiyun }
6036*4882a593Smuzhiyun 
cik_enable_mgcg(struct radeon_device * rdev,bool enable)6037*4882a593Smuzhiyun static void cik_enable_mgcg(struct radeon_device *rdev, bool enable)
6038*4882a593Smuzhiyun {
6039*4882a593Smuzhiyun 	u32 data, orig, tmp = 0;
6040*4882a593Smuzhiyun 
6041*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) {
6042*4882a593Smuzhiyun 		if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGLS) {
6043*4882a593Smuzhiyun 			if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) {
6044*4882a593Smuzhiyun 				orig = data = RREG32(CP_MEM_SLP_CNTL);
6045*4882a593Smuzhiyun 				data |= CP_MEM_LS_EN;
6046*4882a593Smuzhiyun 				if (orig != data)
6047*4882a593Smuzhiyun 					WREG32(CP_MEM_SLP_CNTL, data);
6048*4882a593Smuzhiyun 			}
6049*4882a593Smuzhiyun 		}
6050*4882a593Smuzhiyun 
6051*4882a593Smuzhiyun 		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
6052*4882a593Smuzhiyun 		data |= 0x00000001;
6053*4882a593Smuzhiyun 		data &= 0xfffffffd;
6054*4882a593Smuzhiyun 		if (orig != data)
6055*4882a593Smuzhiyun 			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
6056*4882a593Smuzhiyun 
6057*4882a593Smuzhiyun 		tmp = cik_halt_rlc(rdev);
6058*4882a593Smuzhiyun 
6059*4882a593Smuzhiyun 		cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
6060*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff);
6061*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff);
6062*4882a593Smuzhiyun 		data = BPM_ADDR_MASK | MGCG_OVERRIDE_0;
6063*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_CTRL, data);
6064*4882a593Smuzhiyun 
6065*4882a593Smuzhiyun 		cik_update_rlc(rdev, tmp);
6066*4882a593Smuzhiyun 
6067*4882a593Smuzhiyun 		if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGTS) {
6068*4882a593Smuzhiyun 			orig = data = RREG32(CGTS_SM_CTRL_REG);
6069*4882a593Smuzhiyun 			data &= ~SM_MODE_MASK;
6070*4882a593Smuzhiyun 			data |= SM_MODE(0x2);
6071*4882a593Smuzhiyun 			data |= SM_MODE_ENABLE;
6072*4882a593Smuzhiyun 			data &= ~CGTS_OVERRIDE;
6073*4882a593Smuzhiyun 			if ((rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGLS) &&
6074*4882a593Smuzhiyun 			    (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGTS_LS))
6075*4882a593Smuzhiyun 				data &= ~CGTS_LS_OVERRIDE;
6076*4882a593Smuzhiyun 			data &= ~ON_MONITOR_ADD_MASK;
6077*4882a593Smuzhiyun 			data |= ON_MONITOR_ADD_EN;
6078*4882a593Smuzhiyun 			data |= ON_MONITOR_ADD(0x96);
6079*4882a593Smuzhiyun 			if (orig != data)
6080*4882a593Smuzhiyun 				WREG32(CGTS_SM_CTRL_REG, data);
6081*4882a593Smuzhiyun 		}
6082*4882a593Smuzhiyun 	} else {
6083*4882a593Smuzhiyun 		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
6084*4882a593Smuzhiyun 		data |= 0x00000003;
6085*4882a593Smuzhiyun 		if (orig != data)
6086*4882a593Smuzhiyun 			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
6087*4882a593Smuzhiyun 
6088*4882a593Smuzhiyun 		data = RREG32(RLC_MEM_SLP_CNTL);
6089*4882a593Smuzhiyun 		if (data & RLC_MEM_LS_EN) {
6090*4882a593Smuzhiyun 			data &= ~RLC_MEM_LS_EN;
6091*4882a593Smuzhiyun 			WREG32(RLC_MEM_SLP_CNTL, data);
6092*4882a593Smuzhiyun 		}
6093*4882a593Smuzhiyun 
6094*4882a593Smuzhiyun 		data = RREG32(CP_MEM_SLP_CNTL);
6095*4882a593Smuzhiyun 		if (data & CP_MEM_LS_EN) {
6096*4882a593Smuzhiyun 			data &= ~CP_MEM_LS_EN;
6097*4882a593Smuzhiyun 			WREG32(CP_MEM_SLP_CNTL, data);
6098*4882a593Smuzhiyun 		}
6099*4882a593Smuzhiyun 
6100*4882a593Smuzhiyun 		orig = data = RREG32(CGTS_SM_CTRL_REG);
6101*4882a593Smuzhiyun 		data |= CGTS_OVERRIDE | CGTS_LS_OVERRIDE;
6102*4882a593Smuzhiyun 		if (orig != data)
6103*4882a593Smuzhiyun 			WREG32(CGTS_SM_CTRL_REG, data);
6104*4882a593Smuzhiyun 
6105*4882a593Smuzhiyun 		tmp = cik_halt_rlc(rdev);
6106*4882a593Smuzhiyun 
6107*4882a593Smuzhiyun 		cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
6108*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff);
6109*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff);
6110*4882a593Smuzhiyun 		data = BPM_ADDR_MASK | MGCG_OVERRIDE_1;
6111*4882a593Smuzhiyun 		WREG32(RLC_SERDES_WR_CTRL, data);
6112*4882a593Smuzhiyun 
6113*4882a593Smuzhiyun 		cik_update_rlc(rdev, tmp);
6114*4882a593Smuzhiyun 	}
6115*4882a593Smuzhiyun }
6116*4882a593Smuzhiyun 
6117*4882a593Smuzhiyun static const u32 mc_cg_registers[] =
6118*4882a593Smuzhiyun {
6119*4882a593Smuzhiyun 	MC_HUB_MISC_HUB_CG,
6120*4882a593Smuzhiyun 	MC_HUB_MISC_SIP_CG,
6121*4882a593Smuzhiyun 	MC_HUB_MISC_VM_CG,
6122*4882a593Smuzhiyun 	MC_XPB_CLK_GAT,
6123*4882a593Smuzhiyun 	ATC_MISC_CG,
6124*4882a593Smuzhiyun 	MC_CITF_MISC_WR_CG,
6125*4882a593Smuzhiyun 	MC_CITF_MISC_RD_CG,
6126*4882a593Smuzhiyun 	MC_CITF_MISC_VM_CG,
6127*4882a593Smuzhiyun 	VM_L2_CG,
6128*4882a593Smuzhiyun };
6129*4882a593Smuzhiyun 
cik_enable_mc_ls(struct radeon_device * rdev,bool enable)6130*4882a593Smuzhiyun static void cik_enable_mc_ls(struct radeon_device *rdev,
6131*4882a593Smuzhiyun 			     bool enable)
6132*4882a593Smuzhiyun {
6133*4882a593Smuzhiyun 	int i;
6134*4882a593Smuzhiyun 	u32 orig, data;
6135*4882a593Smuzhiyun 
6136*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
6137*4882a593Smuzhiyun 		orig = data = RREG32(mc_cg_registers[i]);
6138*4882a593Smuzhiyun 		if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
6139*4882a593Smuzhiyun 			data |= MC_LS_ENABLE;
6140*4882a593Smuzhiyun 		else
6141*4882a593Smuzhiyun 			data &= ~MC_LS_ENABLE;
6142*4882a593Smuzhiyun 		if (data != orig)
6143*4882a593Smuzhiyun 			WREG32(mc_cg_registers[i], data);
6144*4882a593Smuzhiyun 	}
6145*4882a593Smuzhiyun }
6146*4882a593Smuzhiyun 
cik_enable_mc_mgcg(struct radeon_device * rdev,bool enable)6147*4882a593Smuzhiyun static void cik_enable_mc_mgcg(struct radeon_device *rdev,
6148*4882a593Smuzhiyun 			       bool enable)
6149*4882a593Smuzhiyun {
6150*4882a593Smuzhiyun 	int i;
6151*4882a593Smuzhiyun 	u32 orig, data;
6152*4882a593Smuzhiyun 
6153*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
6154*4882a593Smuzhiyun 		orig = data = RREG32(mc_cg_registers[i]);
6155*4882a593Smuzhiyun 		if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG))
6156*4882a593Smuzhiyun 			data |= MC_CG_ENABLE;
6157*4882a593Smuzhiyun 		else
6158*4882a593Smuzhiyun 			data &= ~MC_CG_ENABLE;
6159*4882a593Smuzhiyun 		if (data != orig)
6160*4882a593Smuzhiyun 			WREG32(mc_cg_registers[i], data);
6161*4882a593Smuzhiyun 	}
6162*4882a593Smuzhiyun }
6163*4882a593Smuzhiyun 
cik_enable_sdma_mgcg(struct radeon_device * rdev,bool enable)6164*4882a593Smuzhiyun static void cik_enable_sdma_mgcg(struct radeon_device *rdev,
6165*4882a593Smuzhiyun 				 bool enable)
6166*4882a593Smuzhiyun {
6167*4882a593Smuzhiyun 	u32 orig, data;
6168*4882a593Smuzhiyun 
6169*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) {
6170*4882a593Smuzhiyun 		WREG32(SDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET, 0x00000100);
6171*4882a593Smuzhiyun 		WREG32(SDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET, 0x00000100);
6172*4882a593Smuzhiyun 	} else {
6173*4882a593Smuzhiyun 		orig = data = RREG32(SDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET);
6174*4882a593Smuzhiyun 		data |= 0xff000000;
6175*4882a593Smuzhiyun 		if (data != orig)
6176*4882a593Smuzhiyun 			WREG32(SDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET, data);
6177*4882a593Smuzhiyun 
6178*4882a593Smuzhiyun 		orig = data = RREG32(SDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET);
6179*4882a593Smuzhiyun 		data |= 0xff000000;
6180*4882a593Smuzhiyun 		if (data != orig)
6181*4882a593Smuzhiyun 			WREG32(SDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET, data);
6182*4882a593Smuzhiyun 	}
6183*4882a593Smuzhiyun }
6184*4882a593Smuzhiyun 
cik_enable_sdma_mgls(struct radeon_device * rdev,bool enable)6185*4882a593Smuzhiyun static void cik_enable_sdma_mgls(struct radeon_device *rdev,
6186*4882a593Smuzhiyun 				 bool enable)
6187*4882a593Smuzhiyun {
6188*4882a593Smuzhiyun 	u32 orig, data;
6189*4882a593Smuzhiyun 
6190*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_LS)) {
6191*4882a593Smuzhiyun 		orig = data = RREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET);
6192*4882a593Smuzhiyun 		data |= 0x100;
6193*4882a593Smuzhiyun 		if (orig != data)
6194*4882a593Smuzhiyun 			WREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET, data);
6195*4882a593Smuzhiyun 
6196*4882a593Smuzhiyun 		orig = data = RREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET);
6197*4882a593Smuzhiyun 		data |= 0x100;
6198*4882a593Smuzhiyun 		if (orig != data)
6199*4882a593Smuzhiyun 			WREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET, data);
6200*4882a593Smuzhiyun 	} else {
6201*4882a593Smuzhiyun 		orig = data = RREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET);
6202*4882a593Smuzhiyun 		data &= ~0x100;
6203*4882a593Smuzhiyun 		if (orig != data)
6204*4882a593Smuzhiyun 			WREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET, data);
6205*4882a593Smuzhiyun 
6206*4882a593Smuzhiyun 		orig = data = RREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET);
6207*4882a593Smuzhiyun 		data &= ~0x100;
6208*4882a593Smuzhiyun 		if (orig != data)
6209*4882a593Smuzhiyun 			WREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET, data);
6210*4882a593Smuzhiyun 	}
6211*4882a593Smuzhiyun }
6212*4882a593Smuzhiyun 
cik_enable_uvd_mgcg(struct radeon_device * rdev,bool enable)6213*4882a593Smuzhiyun static void cik_enable_uvd_mgcg(struct radeon_device *rdev,
6214*4882a593Smuzhiyun 				bool enable)
6215*4882a593Smuzhiyun {
6216*4882a593Smuzhiyun 	u32 orig, data;
6217*4882a593Smuzhiyun 
6218*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) {
6219*4882a593Smuzhiyun 		data = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
6220*4882a593Smuzhiyun 		data = 0xfff;
6221*4882a593Smuzhiyun 		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, data);
6222*4882a593Smuzhiyun 
6223*4882a593Smuzhiyun 		orig = data = RREG32(UVD_CGC_CTRL);
6224*4882a593Smuzhiyun 		data |= DCM;
6225*4882a593Smuzhiyun 		if (orig != data)
6226*4882a593Smuzhiyun 			WREG32(UVD_CGC_CTRL, data);
6227*4882a593Smuzhiyun 	} else {
6228*4882a593Smuzhiyun 		data = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
6229*4882a593Smuzhiyun 		data &= ~0xfff;
6230*4882a593Smuzhiyun 		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, data);
6231*4882a593Smuzhiyun 
6232*4882a593Smuzhiyun 		orig = data = RREG32(UVD_CGC_CTRL);
6233*4882a593Smuzhiyun 		data &= ~DCM;
6234*4882a593Smuzhiyun 		if (orig != data)
6235*4882a593Smuzhiyun 			WREG32(UVD_CGC_CTRL, data);
6236*4882a593Smuzhiyun 	}
6237*4882a593Smuzhiyun }
6238*4882a593Smuzhiyun 
cik_enable_bif_mgls(struct radeon_device * rdev,bool enable)6239*4882a593Smuzhiyun static void cik_enable_bif_mgls(struct radeon_device *rdev,
6240*4882a593Smuzhiyun 			       bool enable)
6241*4882a593Smuzhiyun {
6242*4882a593Smuzhiyun 	u32 orig, data;
6243*4882a593Smuzhiyun 
6244*4882a593Smuzhiyun 	orig = data = RREG32_PCIE_PORT(PCIE_CNTL2);
6245*4882a593Smuzhiyun 
6246*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS))
6247*4882a593Smuzhiyun 		data |= SLV_MEM_LS_EN | MST_MEM_LS_EN |
6248*4882a593Smuzhiyun 			REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN;
6249*4882a593Smuzhiyun 	else
6250*4882a593Smuzhiyun 		data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN |
6251*4882a593Smuzhiyun 			  REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN);
6252*4882a593Smuzhiyun 
6253*4882a593Smuzhiyun 	if (orig != data)
6254*4882a593Smuzhiyun 		WREG32_PCIE_PORT(PCIE_CNTL2, data);
6255*4882a593Smuzhiyun }
6256*4882a593Smuzhiyun 
cik_enable_hdp_mgcg(struct radeon_device * rdev,bool enable)6257*4882a593Smuzhiyun static void cik_enable_hdp_mgcg(struct radeon_device *rdev,
6258*4882a593Smuzhiyun 				bool enable)
6259*4882a593Smuzhiyun {
6260*4882a593Smuzhiyun 	u32 orig, data;
6261*4882a593Smuzhiyun 
6262*4882a593Smuzhiyun 	orig = data = RREG32(HDP_HOST_PATH_CNTL);
6263*4882a593Smuzhiyun 
6264*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG))
6265*4882a593Smuzhiyun 		data &= ~CLOCK_GATING_DIS;
6266*4882a593Smuzhiyun 	else
6267*4882a593Smuzhiyun 		data |= CLOCK_GATING_DIS;
6268*4882a593Smuzhiyun 
6269*4882a593Smuzhiyun 	if (orig != data)
6270*4882a593Smuzhiyun 		WREG32(HDP_HOST_PATH_CNTL, data);
6271*4882a593Smuzhiyun }
6272*4882a593Smuzhiyun 
cik_enable_hdp_ls(struct radeon_device * rdev,bool enable)6273*4882a593Smuzhiyun static void cik_enable_hdp_ls(struct radeon_device *rdev,
6274*4882a593Smuzhiyun 			      bool enable)
6275*4882a593Smuzhiyun {
6276*4882a593Smuzhiyun 	u32 orig, data;
6277*4882a593Smuzhiyun 
6278*4882a593Smuzhiyun 	orig = data = RREG32(HDP_MEM_POWER_LS);
6279*4882a593Smuzhiyun 
6280*4882a593Smuzhiyun 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS))
6281*4882a593Smuzhiyun 		data |= HDP_LS_ENABLE;
6282*4882a593Smuzhiyun 	else
6283*4882a593Smuzhiyun 		data &= ~HDP_LS_ENABLE;
6284*4882a593Smuzhiyun 
6285*4882a593Smuzhiyun 	if (orig != data)
6286*4882a593Smuzhiyun 		WREG32(HDP_MEM_POWER_LS, data);
6287*4882a593Smuzhiyun }
6288*4882a593Smuzhiyun 
cik_update_cg(struct radeon_device * rdev,u32 block,bool enable)6289*4882a593Smuzhiyun void cik_update_cg(struct radeon_device *rdev,
6290*4882a593Smuzhiyun 		   u32 block, bool enable)
6291*4882a593Smuzhiyun {
6292*4882a593Smuzhiyun 
6293*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_GFX) {
6294*4882a593Smuzhiyun 		cik_enable_gui_idle_interrupt(rdev, false);
6295*4882a593Smuzhiyun 		/* order matters! */
6296*4882a593Smuzhiyun 		if (enable) {
6297*4882a593Smuzhiyun 			cik_enable_mgcg(rdev, true);
6298*4882a593Smuzhiyun 			cik_enable_cgcg(rdev, true);
6299*4882a593Smuzhiyun 		} else {
6300*4882a593Smuzhiyun 			cik_enable_cgcg(rdev, false);
6301*4882a593Smuzhiyun 			cik_enable_mgcg(rdev, false);
6302*4882a593Smuzhiyun 		}
6303*4882a593Smuzhiyun 		cik_enable_gui_idle_interrupt(rdev, true);
6304*4882a593Smuzhiyun 	}
6305*4882a593Smuzhiyun 
6306*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_MC) {
6307*4882a593Smuzhiyun 		if (!(rdev->flags & RADEON_IS_IGP)) {
6308*4882a593Smuzhiyun 			cik_enable_mc_mgcg(rdev, enable);
6309*4882a593Smuzhiyun 			cik_enable_mc_ls(rdev, enable);
6310*4882a593Smuzhiyun 		}
6311*4882a593Smuzhiyun 	}
6312*4882a593Smuzhiyun 
6313*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_SDMA) {
6314*4882a593Smuzhiyun 		cik_enable_sdma_mgcg(rdev, enable);
6315*4882a593Smuzhiyun 		cik_enable_sdma_mgls(rdev, enable);
6316*4882a593Smuzhiyun 	}
6317*4882a593Smuzhiyun 
6318*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_BIF) {
6319*4882a593Smuzhiyun 		cik_enable_bif_mgls(rdev, enable);
6320*4882a593Smuzhiyun 	}
6321*4882a593Smuzhiyun 
6322*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_UVD) {
6323*4882a593Smuzhiyun 		if (rdev->has_uvd)
6324*4882a593Smuzhiyun 			cik_enable_uvd_mgcg(rdev, enable);
6325*4882a593Smuzhiyun 	}
6326*4882a593Smuzhiyun 
6327*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_HDP) {
6328*4882a593Smuzhiyun 		cik_enable_hdp_mgcg(rdev, enable);
6329*4882a593Smuzhiyun 		cik_enable_hdp_ls(rdev, enable);
6330*4882a593Smuzhiyun 	}
6331*4882a593Smuzhiyun 
6332*4882a593Smuzhiyun 	if (block & RADEON_CG_BLOCK_VCE) {
6333*4882a593Smuzhiyun 		vce_v2_0_enable_mgcg(rdev, enable);
6334*4882a593Smuzhiyun 	}
6335*4882a593Smuzhiyun }
6336*4882a593Smuzhiyun 
cik_init_cg(struct radeon_device * rdev)6337*4882a593Smuzhiyun static void cik_init_cg(struct radeon_device *rdev)
6338*4882a593Smuzhiyun {
6339*4882a593Smuzhiyun 
6340*4882a593Smuzhiyun 	cik_update_cg(rdev, RADEON_CG_BLOCK_GFX, true);
6341*4882a593Smuzhiyun 
6342*4882a593Smuzhiyun 	if (rdev->has_uvd)
6343*4882a593Smuzhiyun 		si_init_uvd_internal_cg(rdev);
6344*4882a593Smuzhiyun 
6345*4882a593Smuzhiyun 	cik_update_cg(rdev, (RADEON_CG_BLOCK_MC |
6346*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_SDMA |
6347*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_BIF |
6348*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_UVD |
6349*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_HDP), true);
6350*4882a593Smuzhiyun }
6351*4882a593Smuzhiyun 
cik_fini_cg(struct radeon_device * rdev)6352*4882a593Smuzhiyun static void cik_fini_cg(struct radeon_device *rdev)
6353*4882a593Smuzhiyun {
6354*4882a593Smuzhiyun 	cik_update_cg(rdev, (RADEON_CG_BLOCK_MC |
6355*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_SDMA |
6356*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_BIF |
6357*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_UVD |
6358*4882a593Smuzhiyun 			     RADEON_CG_BLOCK_HDP), false);
6359*4882a593Smuzhiyun 
6360*4882a593Smuzhiyun 	cik_update_cg(rdev, RADEON_CG_BLOCK_GFX, false);
6361*4882a593Smuzhiyun }
6362*4882a593Smuzhiyun 
cik_enable_sck_slowdown_on_pu(struct radeon_device * rdev,bool enable)6363*4882a593Smuzhiyun static void cik_enable_sck_slowdown_on_pu(struct radeon_device *rdev,
6364*4882a593Smuzhiyun 					  bool enable)
6365*4882a593Smuzhiyun {
6366*4882a593Smuzhiyun 	u32 data, orig;
6367*4882a593Smuzhiyun 
6368*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6369*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_RLC_SMU_HS))
6370*4882a593Smuzhiyun 		data |= SMU_CLK_SLOWDOWN_ON_PU_ENABLE;
6371*4882a593Smuzhiyun 	else
6372*4882a593Smuzhiyun 		data &= ~SMU_CLK_SLOWDOWN_ON_PU_ENABLE;
6373*4882a593Smuzhiyun 	if (orig != data)
6374*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6375*4882a593Smuzhiyun }
6376*4882a593Smuzhiyun 
cik_enable_sck_slowdown_on_pd(struct radeon_device * rdev,bool enable)6377*4882a593Smuzhiyun static void cik_enable_sck_slowdown_on_pd(struct radeon_device *rdev,
6378*4882a593Smuzhiyun 					  bool enable)
6379*4882a593Smuzhiyun {
6380*4882a593Smuzhiyun 	u32 data, orig;
6381*4882a593Smuzhiyun 
6382*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6383*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_RLC_SMU_HS))
6384*4882a593Smuzhiyun 		data |= SMU_CLK_SLOWDOWN_ON_PD_ENABLE;
6385*4882a593Smuzhiyun 	else
6386*4882a593Smuzhiyun 		data &= ~SMU_CLK_SLOWDOWN_ON_PD_ENABLE;
6387*4882a593Smuzhiyun 	if (orig != data)
6388*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6389*4882a593Smuzhiyun }
6390*4882a593Smuzhiyun 
cik_enable_cp_pg(struct radeon_device * rdev,bool enable)6391*4882a593Smuzhiyun static void cik_enable_cp_pg(struct radeon_device *rdev, bool enable)
6392*4882a593Smuzhiyun {
6393*4882a593Smuzhiyun 	u32 data, orig;
6394*4882a593Smuzhiyun 
6395*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6396*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_CP))
6397*4882a593Smuzhiyun 		data &= ~DISABLE_CP_PG;
6398*4882a593Smuzhiyun 	else
6399*4882a593Smuzhiyun 		data |= DISABLE_CP_PG;
6400*4882a593Smuzhiyun 	if (orig != data)
6401*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6402*4882a593Smuzhiyun }
6403*4882a593Smuzhiyun 
cik_enable_gds_pg(struct radeon_device * rdev,bool enable)6404*4882a593Smuzhiyun static void cik_enable_gds_pg(struct radeon_device *rdev, bool enable)
6405*4882a593Smuzhiyun {
6406*4882a593Smuzhiyun 	u32 data, orig;
6407*4882a593Smuzhiyun 
6408*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6409*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GDS))
6410*4882a593Smuzhiyun 		data &= ~DISABLE_GDS_PG;
6411*4882a593Smuzhiyun 	else
6412*4882a593Smuzhiyun 		data |= DISABLE_GDS_PG;
6413*4882a593Smuzhiyun 	if (orig != data)
6414*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6415*4882a593Smuzhiyun }
6416*4882a593Smuzhiyun 
6417*4882a593Smuzhiyun #define CP_ME_TABLE_SIZE    96
6418*4882a593Smuzhiyun #define CP_ME_TABLE_OFFSET  2048
6419*4882a593Smuzhiyun #define CP_MEC_TABLE_OFFSET 4096
6420*4882a593Smuzhiyun 
cik_init_cp_pg_table(struct radeon_device * rdev)6421*4882a593Smuzhiyun void cik_init_cp_pg_table(struct radeon_device *rdev)
6422*4882a593Smuzhiyun {
6423*4882a593Smuzhiyun 	volatile u32 *dst_ptr;
6424*4882a593Smuzhiyun 	int me, i, max_me = 4;
6425*4882a593Smuzhiyun 	u32 bo_offset = 0;
6426*4882a593Smuzhiyun 	u32 table_offset, table_size;
6427*4882a593Smuzhiyun 
6428*4882a593Smuzhiyun 	if (rdev->family == CHIP_KAVERI)
6429*4882a593Smuzhiyun 		max_me = 5;
6430*4882a593Smuzhiyun 
6431*4882a593Smuzhiyun 	if (rdev->rlc.cp_table_ptr == NULL)
6432*4882a593Smuzhiyun 		return;
6433*4882a593Smuzhiyun 
6434*4882a593Smuzhiyun 	/* write the cp table buffer */
6435*4882a593Smuzhiyun 	dst_ptr = rdev->rlc.cp_table_ptr;
6436*4882a593Smuzhiyun 	for (me = 0; me < max_me; me++) {
6437*4882a593Smuzhiyun 		if (rdev->new_fw) {
6438*4882a593Smuzhiyun 			const __le32 *fw_data;
6439*4882a593Smuzhiyun 			const struct gfx_firmware_header_v1_0 *hdr;
6440*4882a593Smuzhiyun 
6441*4882a593Smuzhiyun 			if (me == 0) {
6442*4882a593Smuzhiyun 				hdr = (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
6443*4882a593Smuzhiyun 				fw_data = (const __le32 *)
6444*4882a593Smuzhiyun 					(rdev->ce_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
6445*4882a593Smuzhiyun 				table_offset = le32_to_cpu(hdr->jt_offset);
6446*4882a593Smuzhiyun 				table_size = le32_to_cpu(hdr->jt_size);
6447*4882a593Smuzhiyun 			} else if (me == 1) {
6448*4882a593Smuzhiyun 				hdr = (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
6449*4882a593Smuzhiyun 				fw_data = (const __le32 *)
6450*4882a593Smuzhiyun 					(rdev->pfp_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
6451*4882a593Smuzhiyun 				table_offset = le32_to_cpu(hdr->jt_offset);
6452*4882a593Smuzhiyun 				table_size = le32_to_cpu(hdr->jt_size);
6453*4882a593Smuzhiyun 			} else if (me == 2) {
6454*4882a593Smuzhiyun 				hdr = (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
6455*4882a593Smuzhiyun 				fw_data = (const __le32 *)
6456*4882a593Smuzhiyun 					(rdev->me_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
6457*4882a593Smuzhiyun 				table_offset = le32_to_cpu(hdr->jt_offset);
6458*4882a593Smuzhiyun 				table_size = le32_to_cpu(hdr->jt_size);
6459*4882a593Smuzhiyun 			} else if (me == 3) {
6460*4882a593Smuzhiyun 				hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data;
6461*4882a593Smuzhiyun 				fw_data = (const __le32 *)
6462*4882a593Smuzhiyun 					(rdev->mec_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
6463*4882a593Smuzhiyun 				table_offset = le32_to_cpu(hdr->jt_offset);
6464*4882a593Smuzhiyun 				table_size = le32_to_cpu(hdr->jt_size);
6465*4882a593Smuzhiyun 			} else {
6466*4882a593Smuzhiyun 				hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data;
6467*4882a593Smuzhiyun 				fw_data = (const __le32 *)
6468*4882a593Smuzhiyun 					(rdev->mec2_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
6469*4882a593Smuzhiyun 				table_offset = le32_to_cpu(hdr->jt_offset);
6470*4882a593Smuzhiyun 				table_size = le32_to_cpu(hdr->jt_size);
6471*4882a593Smuzhiyun 			}
6472*4882a593Smuzhiyun 
6473*4882a593Smuzhiyun 			for (i = 0; i < table_size; i ++) {
6474*4882a593Smuzhiyun 				dst_ptr[bo_offset + i] =
6475*4882a593Smuzhiyun 					cpu_to_le32(le32_to_cpu(fw_data[table_offset + i]));
6476*4882a593Smuzhiyun 			}
6477*4882a593Smuzhiyun 			bo_offset += table_size;
6478*4882a593Smuzhiyun 		} else {
6479*4882a593Smuzhiyun 			const __be32 *fw_data;
6480*4882a593Smuzhiyun 			table_size = CP_ME_TABLE_SIZE;
6481*4882a593Smuzhiyun 
6482*4882a593Smuzhiyun 			if (me == 0) {
6483*4882a593Smuzhiyun 				fw_data = (const __be32 *)rdev->ce_fw->data;
6484*4882a593Smuzhiyun 				table_offset = CP_ME_TABLE_OFFSET;
6485*4882a593Smuzhiyun 			} else if (me == 1) {
6486*4882a593Smuzhiyun 				fw_data = (const __be32 *)rdev->pfp_fw->data;
6487*4882a593Smuzhiyun 				table_offset = CP_ME_TABLE_OFFSET;
6488*4882a593Smuzhiyun 			} else if (me == 2) {
6489*4882a593Smuzhiyun 				fw_data = (const __be32 *)rdev->me_fw->data;
6490*4882a593Smuzhiyun 				table_offset = CP_ME_TABLE_OFFSET;
6491*4882a593Smuzhiyun 			} else {
6492*4882a593Smuzhiyun 				fw_data = (const __be32 *)rdev->mec_fw->data;
6493*4882a593Smuzhiyun 				table_offset = CP_MEC_TABLE_OFFSET;
6494*4882a593Smuzhiyun 			}
6495*4882a593Smuzhiyun 
6496*4882a593Smuzhiyun 			for (i = 0; i < table_size; i ++) {
6497*4882a593Smuzhiyun 				dst_ptr[bo_offset + i] =
6498*4882a593Smuzhiyun 					cpu_to_le32(be32_to_cpu(fw_data[table_offset + i]));
6499*4882a593Smuzhiyun 			}
6500*4882a593Smuzhiyun 			bo_offset += table_size;
6501*4882a593Smuzhiyun 		}
6502*4882a593Smuzhiyun 	}
6503*4882a593Smuzhiyun }
6504*4882a593Smuzhiyun 
cik_enable_gfx_cgpg(struct radeon_device * rdev,bool enable)6505*4882a593Smuzhiyun static void cik_enable_gfx_cgpg(struct radeon_device *rdev,
6506*4882a593Smuzhiyun 				bool enable)
6507*4882a593Smuzhiyun {
6508*4882a593Smuzhiyun 	u32 data, orig;
6509*4882a593Smuzhiyun 
6510*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) {
6511*4882a593Smuzhiyun 		orig = data = RREG32(RLC_PG_CNTL);
6512*4882a593Smuzhiyun 		data |= GFX_PG_ENABLE;
6513*4882a593Smuzhiyun 		if (orig != data)
6514*4882a593Smuzhiyun 			WREG32(RLC_PG_CNTL, data);
6515*4882a593Smuzhiyun 
6516*4882a593Smuzhiyun 		orig = data = RREG32(RLC_AUTO_PG_CTRL);
6517*4882a593Smuzhiyun 		data |= AUTO_PG_EN;
6518*4882a593Smuzhiyun 		if (orig != data)
6519*4882a593Smuzhiyun 			WREG32(RLC_AUTO_PG_CTRL, data);
6520*4882a593Smuzhiyun 	} else {
6521*4882a593Smuzhiyun 		orig = data = RREG32(RLC_PG_CNTL);
6522*4882a593Smuzhiyun 		data &= ~GFX_PG_ENABLE;
6523*4882a593Smuzhiyun 		if (orig != data)
6524*4882a593Smuzhiyun 			WREG32(RLC_PG_CNTL, data);
6525*4882a593Smuzhiyun 
6526*4882a593Smuzhiyun 		orig = data = RREG32(RLC_AUTO_PG_CTRL);
6527*4882a593Smuzhiyun 		data &= ~AUTO_PG_EN;
6528*4882a593Smuzhiyun 		if (orig != data)
6529*4882a593Smuzhiyun 			WREG32(RLC_AUTO_PG_CTRL, data);
6530*4882a593Smuzhiyun 
6531*4882a593Smuzhiyun 		data = RREG32(DB_RENDER_CONTROL);
6532*4882a593Smuzhiyun 	}
6533*4882a593Smuzhiyun }
6534*4882a593Smuzhiyun 
cik_get_cu_active_bitmap(struct radeon_device * rdev,u32 se,u32 sh)6535*4882a593Smuzhiyun static u32 cik_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh)
6536*4882a593Smuzhiyun {
6537*4882a593Smuzhiyun 	u32 mask = 0, tmp, tmp1;
6538*4882a593Smuzhiyun 	int i;
6539*4882a593Smuzhiyun 
6540*4882a593Smuzhiyun 	cik_select_se_sh(rdev, se, sh);
6541*4882a593Smuzhiyun 	tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
6542*4882a593Smuzhiyun 	tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
6543*4882a593Smuzhiyun 	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
6544*4882a593Smuzhiyun 
6545*4882a593Smuzhiyun 	tmp &= 0xffff0000;
6546*4882a593Smuzhiyun 
6547*4882a593Smuzhiyun 	tmp |= tmp1;
6548*4882a593Smuzhiyun 	tmp >>= 16;
6549*4882a593Smuzhiyun 
6550*4882a593Smuzhiyun 	for (i = 0; i < rdev->config.cik.max_cu_per_sh; i ++) {
6551*4882a593Smuzhiyun 		mask <<= 1;
6552*4882a593Smuzhiyun 		mask |= 1;
6553*4882a593Smuzhiyun 	}
6554*4882a593Smuzhiyun 
6555*4882a593Smuzhiyun 	return (~tmp) & mask;
6556*4882a593Smuzhiyun }
6557*4882a593Smuzhiyun 
cik_init_ao_cu_mask(struct radeon_device * rdev)6558*4882a593Smuzhiyun static void cik_init_ao_cu_mask(struct radeon_device *rdev)
6559*4882a593Smuzhiyun {
6560*4882a593Smuzhiyun 	u32 i, j, k, active_cu_number = 0;
6561*4882a593Smuzhiyun 	u32 mask, counter, cu_bitmap;
6562*4882a593Smuzhiyun 	u32 tmp = 0;
6563*4882a593Smuzhiyun 
6564*4882a593Smuzhiyun 	for (i = 0; i < rdev->config.cik.max_shader_engines; i++) {
6565*4882a593Smuzhiyun 		for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) {
6566*4882a593Smuzhiyun 			mask = 1;
6567*4882a593Smuzhiyun 			cu_bitmap = 0;
6568*4882a593Smuzhiyun 			counter = 0;
6569*4882a593Smuzhiyun 			for (k = 0; k < rdev->config.cik.max_cu_per_sh; k ++) {
6570*4882a593Smuzhiyun 				if (cik_get_cu_active_bitmap(rdev, i, j) & mask) {
6571*4882a593Smuzhiyun 					if (counter < 2)
6572*4882a593Smuzhiyun 						cu_bitmap |= mask;
6573*4882a593Smuzhiyun 					counter ++;
6574*4882a593Smuzhiyun 				}
6575*4882a593Smuzhiyun 				mask <<= 1;
6576*4882a593Smuzhiyun 			}
6577*4882a593Smuzhiyun 
6578*4882a593Smuzhiyun 			active_cu_number += counter;
6579*4882a593Smuzhiyun 			tmp |= (cu_bitmap << (i * 16 + j * 8));
6580*4882a593Smuzhiyun 		}
6581*4882a593Smuzhiyun 	}
6582*4882a593Smuzhiyun 
6583*4882a593Smuzhiyun 	WREG32(RLC_PG_AO_CU_MASK, tmp);
6584*4882a593Smuzhiyun 
6585*4882a593Smuzhiyun 	tmp = RREG32(RLC_MAX_PG_CU);
6586*4882a593Smuzhiyun 	tmp &= ~MAX_PU_CU_MASK;
6587*4882a593Smuzhiyun 	tmp |= MAX_PU_CU(active_cu_number);
6588*4882a593Smuzhiyun 	WREG32(RLC_MAX_PG_CU, tmp);
6589*4882a593Smuzhiyun }
6590*4882a593Smuzhiyun 
cik_enable_gfx_static_mgpg(struct radeon_device * rdev,bool enable)6591*4882a593Smuzhiyun static void cik_enable_gfx_static_mgpg(struct radeon_device *rdev,
6592*4882a593Smuzhiyun 				       bool enable)
6593*4882a593Smuzhiyun {
6594*4882a593Smuzhiyun 	u32 data, orig;
6595*4882a593Smuzhiyun 
6596*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6597*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_SMG))
6598*4882a593Smuzhiyun 		data |= STATIC_PER_CU_PG_ENABLE;
6599*4882a593Smuzhiyun 	else
6600*4882a593Smuzhiyun 		data &= ~STATIC_PER_CU_PG_ENABLE;
6601*4882a593Smuzhiyun 	if (orig != data)
6602*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6603*4882a593Smuzhiyun }
6604*4882a593Smuzhiyun 
cik_enable_gfx_dynamic_mgpg(struct radeon_device * rdev,bool enable)6605*4882a593Smuzhiyun static void cik_enable_gfx_dynamic_mgpg(struct radeon_device *rdev,
6606*4882a593Smuzhiyun 					bool enable)
6607*4882a593Smuzhiyun {
6608*4882a593Smuzhiyun 	u32 data, orig;
6609*4882a593Smuzhiyun 
6610*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6611*4882a593Smuzhiyun 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_DMG))
6612*4882a593Smuzhiyun 		data |= DYN_PER_CU_PG_ENABLE;
6613*4882a593Smuzhiyun 	else
6614*4882a593Smuzhiyun 		data &= ~DYN_PER_CU_PG_ENABLE;
6615*4882a593Smuzhiyun 	if (orig != data)
6616*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6617*4882a593Smuzhiyun }
6618*4882a593Smuzhiyun 
6619*4882a593Smuzhiyun #define RLC_SAVE_AND_RESTORE_STARTING_OFFSET 0x90
6620*4882a593Smuzhiyun #define RLC_CLEAR_STATE_DESCRIPTOR_OFFSET    0x3D
6621*4882a593Smuzhiyun 
cik_init_gfx_cgpg(struct radeon_device * rdev)6622*4882a593Smuzhiyun static void cik_init_gfx_cgpg(struct radeon_device *rdev)
6623*4882a593Smuzhiyun {
6624*4882a593Smuzhiyun 	u32 data, orig;
6625*4882a593Smuzhiyun 	u32 i;
6626*4882a593Smuzhiyun 
6627*4882a593Smuzhiyun 	if (rdev->rlc.cs_data) {
6628*4882a593Smuzhiyun 		WREG32(RLC_GPM_SCRATCH_ADDR, RLC_CLEAR_STATE_DESCRIPTOR_OFFSET);
6629*4882a593Smuzhiyun 		WREG32(RLC_GPM_SCRATCH_DATA, upper_32_bits(rdev->rlc.clear_state_gpu_addr));
6630*4882a593Smuzhiyun 		WREG32(RLC_GPM_SCRATCH_DATA, lower_32_bits(rdev->rlc.clear_state_gpu_addr));
6631*4882a593Smuzhiyun 		WREG32(RLC_GPM_SCRATCH_DATA, rdev->rlc.clear_state_size);
6632*4882a593Smuzhiyun 	} else {
6633*4882a593Smuzhiyun 		WREG32(RLC_GPM_SCRATCH_ADDR, RLC_CLEAR_STATE_DESCRIPTOR_OFFSET);
6634*4882a593Smuzhiyun 		for (i = 0; i < 3; i++)
6635*4882a593Smuzhiyun 			WREG32(RLC_GPM_SCRATCH_DATA, 0);
6636*4882a593Smuzhiyun 	}
6637*4882a593Smuzhiyun 	if (rdev->rlc.reg_list) {
6638*4882a593Smuzhiyun 		WREG32(RLC_GPM_SCRATCH_ADDR, RLC_SAVE_AND_RESTORE_STARTING_OFFSET);
6639*4882a593Smuzhiyun 		for (i = 0; i < rdev->rlc.reg_list_size; i++)
6640*4882a593Smuzhiyun 			WREG32(RLC_GPM_SCRATCH_DATA, rdev->rlc.reg_list[i]);
6641*4882a593Smuzhiyun 	}
6642*4882a593Smuzhiyun 
6643*4882a593Smuzhiyun 	orig = data = RREG32(RLC_PG_CNTL);
6644*4882a593Smuzhiyun 	data |= GFX_PG_SRC;
6645*4882a593Smuzhiyun 	if (orig != data)
6646*4882a593Smuzhiyun 		WREG32(RLC_PG_CNTL, data);
6647*4882a593Smuzhiyun 
6648*4882a593Smuzhiyun 	WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
6649*4882a593Smuzhiyun 	WREG32(RLC_CP_TABLE_RESTORE, rdev->rlc.cp_table_gpu_addr >> 8);
6650*4882a593Smuzhiyun 
6651*4882a593Smuzhiyun 	data = RREG32(CP_RB_WPTR_POLL_CNTL);
6652*4882a593Smuzhiyun 	data &= ~IDLE_POLL_COUNT_MASK;
6653*4882a593Smuzhiyun 	data |= IDLE_POLL_COUNT(0x60);
6654*4882a593Smuzhiyun 	WREG32(CP_RB_WPTR_POLL_CNTL, data);
6655*4882a593Smuzhiyun 
6656*4882a593Smuzhiyun 	data = 0x10101010;
6657*4882a593Smuzhiyun 	WREG32(RLC_PG_DELAY, data);
6658*4882a593Smuzhiyun 
6659*4882a593Smuzhiyun 	data = RREG32(RLC_PG_DELAY_2);
6660*4882a593Smuzhiyun 	data &= ~0xff;
6661*4882a593Smuzhiyun 	data |= 0x3;
6662*4882a593Smuzhiyun 	WREG32(RLC_PG_DELAY_2, data);
6663*4882a593Smuzhiyun 
6664*4882a593Smuzhiyun 	data = RREG32(RLC_AUTO_PG_CTRL);
6665*4882a593Smuzhiyun 	data &= ~GRBM_REG_SGIT_MASK;
6666*4882a593Smuzhiyun 	data |= GRBM_REG_SGIT(0x700);
6667*4882a593Smuzhiyun 	WREG32(RLC_AUTO_PG_CTRL, data);
6668*4882a593Smuzhiyun 
6669*4882a593Smuzhiyun }
6670*4882a593Smuzhiyun 
cik_update_gfx_pg(struct radeon_device * rdev,bool enable)6671*4882a593Smuzhiyun static void cik_update_gfx_pg(struct radeon_device *rdev, bool enable)
6672*4882a593Smuzhiyun {
6673*4882a593Smuzhiyun 	cik_enable_gfx_cgpg(rdev, enable);
6674*4882a593Smuzhiyun 	cik_enable_gfx_static_mgpg(rdev, enable);
6675*4882a593Smuzhiyun 	cik_enable_gfx_dynamic_mgpg(rdev, enable);
6676*4882a593Smuzhiyun }
6677*4882a593Smuzhiyun 
cik_get_csb_size(struct radeon_device * rdev)6678*4882a593Smuzhiyun u32 cik_get_csb_size(struct radeon_device *rdev)
6679*4882a593Smuzhiyun {
6680*4882a593Smuzhiyun 	u32 count = 0;
6681*4882a593Smuzhiyun 	const struct cs_section_def *sect = NULL;
6682*4882a593Smuzhiyun 	const struct cs_extent_def *ext = NULL;
6683*4882a593Smuzhiyun 
6684*4882a593Smuzhiyun 	if (rdev->rlc.cs_data == NULL)
6685*4882a593Smuzhiyun 		return 0;
6686*4882a593Smuzhiyun 
6687*4882a593Smuzhiyun 	/* begin clear state */
6688*4882a593Smuzhiyun 	count += 2;
6689*4882a593Smuzhiyun 	/* context control state */
6690*4882a593Smuzhiyun 	count += 3;
6691*4882a593Smuzhiyun 
6692*4882a593Smuzhiyun 	for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
6693*4882a593Smuzhiyun 		for (ext = sect->section; ext->extent != NULL; ++ext) {
6694*4882a593Smuzhiyun 			if (sect->id == SECT_CONTEXT)
6695*4882a593Smuzhiyun 				count += 2 + ext->reg_count;
6696*4882a593Smuzhiyun 			else
6697*4882a593Smuzhiyun 				return 0;
6698*4882a593Smuzhiyun 		}
6699*4882a593Smuzhiyun 	}
6700*4882a593Smuzhiyun 	/* pa_sc_raster_config/pa_sc_raster_config1 */
6701*4882a593Smuzhiyun 	count += 4;
6702*4882a593Smuzhiyun 	/* end clear state */
6703*4882a593Smuzhiyun 	count += 2;
6704*4882a593Smuzhiyun 	/* clear state */
6705*4882a593Smuzhiyun 	count += 2;
6706*4882a593Smuzhiyun 
6707*4882a593Smuzhiyun 	return count;
6708*4882a593Smuzhiyun }
6709*4882a593Smuzhiyun 
cik_get_csb_buffer(struct radeon_device * rdev,volatile u32 * buffer)6710*4882a593Smuzhiyun void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
6711*4882a593Smuzhiyun {
6712*4882a593Smuzhiyun 	u32 count = 0, i;
6713*4882a593Smuzhiyun 	const struct cs_section_def *sect = NULL;
6714*4882a593Smuzhiyun 	const struct cs_extent_def *ext = NULL;
6715*4882a593Smuzhiyun 
6716*4882a593Smuzhiyun 	if (rdev->rlc.cs_data == NULL)
6717*4882a593Smuzhiyun 		return;
6718*4882a593Smuzhiyun 	if (buffer == NULL)
6719*4882a593Smuzhiyun 		return;
6720*4882a593Smuzhiyun 
6721*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
6722*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
6723*4882a593Smuzhiyun 
6724*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
6725*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(0x80000000);
6726*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(0x80000000);
6727*4882a593Smuzhiyun 
6728*4882a593Smuzhiyun 	for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
6729*4882a593Smuzhiyun 		for (ext = sect->section; ext->extent != NULL; ++ext) {
6730*4882a593Smuzhiyun 			if (sect->id == SECT_CONTEXT) {
6731*4882a593Smuzhiyun 				buffer[count++] =
6732*4882a593Smuzhiyun 					cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
6733*4882a593Smuzhiyun 				buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
6734*4882a593Smuzhiyun 				for (i = 0; i < ext->reg_count; i++)
6735*4882a593Smuzhiyun 					buffer[count++] = cpu_to_le32(ext->extent[i]);
6736*4882a593Smuzhiyun 			} else {
6737*4882a593Smuzhiyun 				return;
6738*4882a593Smuzhiyun 			}
6739*4882a593Smuzhiyun 		}
6740*4882a593Smuzhiyun 	}
6741*4882a593Smuzhiyun 
6742*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 2));
6743*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
6744*4882a593Smuzhiyun 	switch (rdev->family) {
6745*4882a593Smuzhiyun 	case CHIP_BONAIRE:
6746*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x16000012);
6747*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000);
6748*4882a593Smuzhiyun 		break;
6749*4882a593Smuzhiyun 	case CHIP_KAVERI:
6750*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000); /* XXX */
6751*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000);
6752*4882a593Smuzhiyun 		break;
6753*4882a593Smuzhiyun 	case CHIP_KABINI:
6754*4882a593Smuzhiyun 	case CHIP_MULLINS:
6755*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000); /* XXX */
6756*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000);
6757*4882a593Smuzhiyun 		break;
6758*4882a593Smuzhiyun 	case CHIP_HAWAII:
6759*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x3a00161a);
6760*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x0000002e);
6761*4882a593Smuzhiyun 		break;
6762*4882a593Smuzhiyun 	default:
6763*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000);
6764*4882a593Smuzhiyun 		buffer[count++] = cpu_to_le32(0x00000000);
6765*4882a593Smuzhiyun 		break;
6766*4882a593Smuzhiyun 	}
6767*4882a593Smuzhiyun 
6768*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
6769*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
6770*4882a593Smuzhiyun 
6771*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
6772*4882a593Smuzhiyun 	buffer[count++] = cpu_to_le32(0);
6773*4882a593Smuzhiyun }
6774*4882a593Smuzhiyun 
cik_init_pg(struct radeon_device * rdev)6775*4882a593Smuzhiyun static void cik_init_pg(struct radeon_device *rdev)
6776*4882a593Smuzhiyun {
6777*4882a593Smuzhiyun 	if (rdev->pg_flags) {
6778*4882a593Smuzhiyun 		cik_enable_sck_slowdown_on_pu(rdev, true);
6779*4882a593Smuzhiyun 		cik_enable_sck_slowdown_on_pd(rdev, true);
6780*4882a593Smuzhiyun 		if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {
6781*4882a593Smuzhiyun 			cik_init_gfx_cgpg(rdev);
6782*4882a593Smuzhiyun 			cik_enable_cp_pg(rdev, true);
6783*4882a593Smuzhiyun 			cik_enable_gds_pg(rdev, true);
6784*4882a593Smuzhiyun 		}
6785*4882a593Smuzhiyun 		cik_init_ao_cu_mask(rdev);
6786*4882a593Smuzhiyun 		cik_update_gfx_pg(rdev, true);
6787*4882a593Smuzhiyun 	}
6788*4882a593Smuzhiyun }
6789*4882a593Smuzhiyun 
cik_fini_pg(struct radeon_device * rdev)6790*4882a593Smuzhiyun static void cik_fini_pg(struct radeon_device *rdev)
6791*4882a593Smuzhiyun {
6792*4882a593Smuzhiyun 	if (rdev->pg_flags) {
6793*4882a593Smuzhiyun 		cik_update_gfx_pg(rdev, false);
6794*4882a593Smuzhiyun 		if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {
6795*4882a593Smuzhiyun 			cik_enable_cp_pg(rdev, false);
6796*4882a593Smuzhiyun 			cik_enable_gds_pg(rdev, false);
6797*4882a593Smuzhiyun 		}
6798*4882a593Smuzhiyun 	}
6799*4882a593Smuzhiyun }
6800*4882a593Smuzhiyun 
6801*4882a593Smuzhiyun /*
6802*4882a593Smuzhiyun  * Interrupts
6803*4882a593Smuzhiyun  * Starting with r6xx, interrupts are handled via a ring buffer.
6804*4882a593Smuzhiyun  * Ring buffers are areas of GPU accessible memory that the GPU
6805*4882a593Smuzhiyun  * writes interrupt vectors into and the host reads vectors out of.
6806*4882a593Smuzhiyun  * There is a rptr (read pointer) that determines where the
6807*4882a593Smuzhiyun  * host is currently reading, and a wptr (write pointer)
6808*4882a593Smuzhiyun  * which determines where the GPU has written.  When the
6809*4882a593Smuzhiyun  * pointers are equal, the ring is idle.  When the GPU
6810*4882a593Smuzhiyun  * writes vectors to the ring buffer, it increments the
6811*4882a593Smuzhiyun  * wptr.  When there is an interrupt, the host then starts
6812*4882a593Smuzhiyun  * fetching commands and processing them until the pointers are
6813*4882a593Smuzhiyun  * equal again at which point it updates the rptr.
6814*4882a593Smuzhiyun  */
6815*4882a593Smuzhiyun 
6816*4882a593Smuzhiyun /**
6817*4882a593Smuzhiyun  * cik_enable_interrupts - Enable the interrupt ring buffer
6818*4882a593Smuzhiyun  *
6819*4882a593Smuzhiyun  * @rdev: radeon_device pointer
6820*4882a593Smuzhiyun  *
6821*4882a593Smuzhiyun  * Enable the interrupt ring buffer (CIK).
6822*4882a593Smuzhiyun  */
cik_enable_interrupts(struct radeon_device * rdev)6823*4882a593Smuzhiyun static void cik_enable_interrupts(struct radeon_device *rdev)
6824*4882a593Smuzhiyun {
6825*4882a593Smuzhiyun 	u32 ih_cntl = RREG32(IH_CNTL);
6826*4882a593Smuzhiyun 	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
6827*4882a593Smuzhiyun 
6828*4882a593Smuzhiyun 	ih_cntl |= ENABLE_INTR;
6829*4882a593Smuzhiyun 	ih_rb_cntl |= IH_RB_ENABLE;
6830*4882a593Smuzhiyun 	WREG32(IH_CNTL, ih_cntl);
6831*4882a593Smuzhiyun 	WREG32(IH_RB_CNTL, ih_rb_cntl);
6832*4882a593Smuzhiyun 	rdev->ih.enabled = true;
6833*4882a593Smuzhiyun }
6834*4882a593Smuzhiyun 
6835*4882a593Smuzhiyun /**
6836*4882a593Smuzhiyun  * cik_disable_interrupts - Disable the interrupt ring buffer
6837*4882a593Smuzhiyun  *
6838*4882a593Smuzhiyun  * @rdev: radeon_device pointer
6839*4882a593Smuzhiyun  *
6840*4882a593Smuzhiyun  * Disable the interrupt ring buffer (CIK).
6841*4882a593Smuzhiyun  */
cik_disable_interrupts(struct radeon_device * rdev)6842*4882a593Smuzhiyun static void cik_disable_interrupts(struct radeon_device *rdev)
6843*4882a593Smuzhiyun {
6844*4882a593Smuzhiyun 	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
6845*4882a593Smuzhiyun 	u32 ih_cntl = RREG32(IH_CNTL);
6846*4882a593Smuzhiyun 
6847*4882a593Smuzhiyun 	ih_rb_cntl &= ~IH_RB_ENABLE;
6848*4882a593Smuzhiyun 	ih_cntl &= ~ENABLE_INTR;
6849*4882a593Smuzhiyun 	WREG32(IH_RB_CNTL, ih_rb_cntl);
6850*4882a593Smuzhiyun 	WREG32(IH_CNTL, ih_cntl);
6851*4882a593Smuzhiyun 	/* set rptr, wptr to 0 */
6852*4882a593Smuzhiyun 	WREG32(IH_RB_RPTR, 0);
6853*4882a593Smuzhiyun 	WREG32(IH_RB_WPTR, 0);
6854*4882a593Smuzhiyun 	rdev->ih.enabled = false;
6855*4882a593Smuzhiyun 	rdev->ih.rptr = 0;
6856*4882a593Smuzhiyun }
6857*4882a593Smuzhiyun 
6858*4882a593Smuzhiyun /**
6859*4882a593Smuzhiyun  * cik_disable_interrupt_state - Disable all interrupt sources
6860*4882a593Smuzhiyun  *
6861*4882a593Smuzhiyun  * @rdev: radeon_device pointer
6862*4882a593Smuzhiyun  *
6863*4882a593Smuzhiyun  * Clear all interrupt enable bits used by the driver (CIK).
6864*4882a593Smuzhiyun  */
cik_disable_interrupt_state(struct radeon_device * rdev)6865*4882a593Smuzhiyun static void cik_disable_interrupt_state(struct radeon_device *rdev)
6866*4882a593Smuzhiyun {
6867*4882a593Smuzhiyun 	u32 tmp;
6868*4882a593Smuzhiyun 
6869*4882a593Smuzhiyun 	/* gfx ring */
6870*4882a593Smuzhiyun 	tmp = RREG32(CP_INT_CNTL_RING0) &
6871*4882a593Smuzhiyun 		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
6872*4882a593Smuzhiyun 	WREG32(CP_INT_CNTL_RING0, tmp);
6873*4882a593Smuzhiyun 	/* sdma */
6874*4882a593Smuzhiyun 	tmp = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
6875*4882a593Smuzhiyun 	WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, tmp);
6876*4882a593Smuzhiyun 	tmp = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
6877*4882a593Smuzhiyun 	WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, tmp);
6878*4882a593Smuzhiyun 	/* compute queues */
6879*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE0_INT_CNTL, 0);
6880*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE1_INT_CNTL, 0);
6881*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE2_INT_CNTL, 0);
6882*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE3_INT_CNTL, 0);
6883*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE0_INT_CNTL, 0);
6884*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE1_INT_CNTL, 0);
6885*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE2_INT_CNTL, 0);
6886*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE3_INT_CNTL, 0);
6887*4882a593Smuzhiyun 	/* grbm */
6888*4882a593Smuzhiyun 	WREG32(GRBM_INT_CNTL, 0);
6889*4882a593Smuzhiyun 	/* SRBM */
6890*4882a593Smuzhiyun 	WREG32(SRBM_INT_CNTL, 0);
6891*4882a593Smuzhiyun 	/* vline/vblank, etc. */
6892*4882a593Smuzhiyun 	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
6893*4882a593Smuzhiyun 	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
6894*4882a593Smuzhiyun 	if (rdev->num_crtc >= 4) {
6895*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
6896*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
6897*4882a593Smuzhiyun 	}
6898*4882a593Smuzhiyun 	if (rdev->num_crtc >= 6) {
6899*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
6900*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
6901*4882a593Smuzhiyun 	}
6902*4882a593Smuzhiyun 	/* pflip */
6903*4882a593Smuzhiyun 	if (rdev->num_crtc >= 2) {
6904*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
6905*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
6906*4882a593Smuzhiyun 	}
6907*4882a593Smuzhiyun 	if (rdev->num_crtc >= 4) {
6908*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
6909*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
6910*4882a593Smuzhiyun 	}
6911*4882a593Smuzhiyun 	if (rdev->num_crtc >= 6) {
6912*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
6913*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
6914*4882a593Smuzhiyun 	}
6915*4882a593Smuzhiyun 
6916*4882a593Smuzhiyun 	/* dac hotplug */
6917*4882a593Smuzhiyun 	WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
6918*4882a593Smuzhiyun 
6919*4882a593Smuzhiyun 	/* digital hotplug */
6920*4882a593Smuzhiyun 	tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
6921*4882a593Smuzhiyun 	WREG32(DC_HPD1_INT_CONTROL, tmp);
6922*4882a593Smuzhiyun 	tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
6923*4882a593Smuzhiyun 	WREG32(DC_HPD2_INT_CONTROL, tmp);
6924*4882a593Smuzhiyun 	tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
6925*4882a593Smuzhiyun 	WREG32(DC_HPD3_INT_CONTROL, tmp);
6926*4882a593Smuzhiyun 	tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
6927*4882a593Smuzhiyun 	WREG32(DC_HPD4_INT_CONTROL, tmp);
6928*4882a593Smuzhiyun 	tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
6929*4882a593Smuzhiyun 	WREG32(DC_HPD5_INT_CONTROL, tmp);
6930*4882a593Smuzhiyun 	tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
6931*4882a593Smuzhiyun 	WREG32(DC_HPD6_INT_CONTROL, tmp);
6932*4882a593Smuzhiyun 
6933*4882a593Smuzhiyun }
6934*4882a593Smuzhiyun 
6935*4882a593Smuzhiyun /**
6936*4882a593Smuzhiyun  * cik_irq_init - init and enable the interrupt ring
6937*4882a593Smuzhiyun  *
6938*4882a593Smuzhiyun  * @rdev: radeon_device pointer
6939*4882a593Smuzhiyun  *
6940*4882a593Smuzhiyun  * Allocate a ring buffer for the interrupt controller,
6941*4882a593Smuzhiyun  * enable the RLC, disable interrupts, enable the IH
6942*4882a593Smuzhiyun  * ring buffer and enable it (CIK).
6943*4882a593Smuzhiyun  * Called at device load and reume.
6944*4882a593Smuzhiyun  * Returns 0 for success, errors for failure.
6945*4882a593Smuzhiyun  */
cik_irq_init(struct radeon_device * rdev)6946*4882a593Smuzhiyun static int cik_irq_init(struct radeon_device *rdev)
6947*4882a593Smuzhiyun {
6948*4882a593Smuzhiyun 	int ret = 0;
6949*4882a593Smuzhiyun 	int rb_bufsz;
6950*4882a593Smuzhiyun 	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
6951*4882a593Smuzhiyun 
6952*4882a593Smuzhiyun 	/* allocate ring */
6953*4882a593Smuzhiyun 	ret = r600_ih_ring_alloc(rdev);
6954*4882a593Smuzhiyun 	if (ret)
6955*4882a593Smuzhiyun 		return ret;
6956*4882a593Smuzhiyun 
6957*4882a593Smuzhiyun 	/* disable irqs */
6958*4882a593Smuzhiyun 	cik_disable_interrupts(rdev);
6959*4882a593Smuzhiyun 
6960*4882a593Smuzhiyun 	/* init rlc */
6961*4882a593Smuzhiyun 	ret = cik_rlc_resume(rdev);
6962*4882a593Smuzhiyun 	if (ret) {
6963*4882a593Smuzhiyun 		r600_ih_ring_fini(rdev);
6964*4882a593Smuzhiyun 		return ret;
6965*4882a593Smuzhiyun 	}
6966*4882a593Smuzhiyun 
6967*4882a593Smuzhiyun 	/* setup interrupt control */
6968*4882a593Smuzhiyun 	/* set dummy read address to dummy page address */
6969*4882a593Smuzhiyun 	WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8);
6970*4882a593Smuzhiyun 	interrupt_cntl = RREG32(INTERRUPT_CNTL);
6971*4882a593Smuzhiyun 	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
6972*4882a593Smuzhiyun 	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
6973*4882a593Smuzhiyun 	 */
6974*4882a593Smuzhiyun 	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
6975*4882a593Smuzhiyun 	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
6976*4882a593Smuzhiyun 	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
6977*4882a593Smuzhiyun 	WREG32(INTERRUPT_CNTL, interrupt_cntl);
6978*4882a593Smuzhiyun 
6979*4882a593Smuzhiyun 	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
6980*4882a593Smuzhiyun 	rb_bufsz = order_base_2(rdev->ih.ring_size / 4);
6981*4882a593Smuzhiyun 
6982*4882a593Smuzhiyun 	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
6983*4882a593Smuzhiyun 		      IH_WPTR_OVERFLOW_CLEAR |
6984*4882a593Smuzhiyun 		      (rb_bufsz << 1));
6985*4882a593Smuzhiyun 
6986*4882a593Smuzhiyun 	if (rdev->wb.enabled)
6987*4882a593Smuzhiyun 		ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
6988*4882a593Smuzhiyun 
6989*4882a593Smuzhiyun 	/* set the writeback address whether it's enabled or not */
6990*4882a593Smuzhiyun 	WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
6991*4882a593Smuzhiyun 	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
6992*4882a593Smuzhiyun 
6993*4882a593Smuzhiyun 	WREG32(IH_RB_CNTL, ih_rb_cntl);
6994*4882a593Smuzhiyun 
6995*4882a593Smuzhiyun 	/* set rptr, wptr to 0 */
6996*4882a593Smuzhiyun 	WREG32(IH_RB_RPTR, 0);
6997*4882a593Smuzhiyun 	WREG32(IH_RB_WPTR, 0);
6998*4882a593Smuzhiyun 
6999*4882a593Smuzhiyun 	/* Default settings for IH_CNTL (disabled at first) */
7000*4882a593Smuzhiyun 	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
7001*4882a593Smuzhiyun 	/* RPTR_REARM only works if msi's are enabled */
7002*4882a593Smuzhiyun 	if (rdev->msi_enabled)
7003*4882a593Smuzhiyun 		ih_cntl |= RPTR_REARM;
7004*4882a593Smuzhiyun 	WREG32(IH_CNTL, ih_cntl);
7005*4882a593Smuzhiyun 
7006*4882a593Smuzhiyun 	/* force the active interrupt state to all disabled */
7007*4882a593Smuzhiyun 	cik_disable_interrupt_state(rdev);
7008*4882a593Smuzhiyun 
7009*4882a593Smuzhiyun 	pci_set_master(rdev->pdev);
7010*4882a593Smuzhiyun 
7011*4882a593Smuzhiyun 	/* enable irqs */
7012*4882a593Smuzhiyun 	cik_enable_interrupts(rdev);
7013*4882a593Smuzhiyun 
7014*4882a593Smuzhiyun 	return ret;
7015*4882a593Smuzhiyun }
7016*4882a593Smuzhiyun 
7017*4882a593Smuzhiyun /**
7018*4882a593Smuzhiyun  * cik_irq_set - enable/disable interrupt sources
7019*4882a593Smuzhiyun  *
7020*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7021*4882a593Smuzhiyun  *
7022*4882a593Smuzhiyun  * Enable interrupt sources on the GPU (vblanks, hpd,
7023*4882a593Smuzhiyun  * etc.) (CIK).
7024*4882a593Smuzhiyun  * Returns 0 for success, errors for failure.
7025*4882a593Smuzhiyun  */
cik_irq_set(struct radeon_device * rdev)7026*4882a593Smuzhiyun int cik_irq_set(struct radeon_device *rdev)
7027*4882a593Smuzhiyun {
7028*4882a593Smuzhiyun 	u32 cp_int_cntl;
7029*4882a593Smuzhiyun 	u32 cp_m1p0, cp_m1p1, cp_m1p2, cp_m1p3;
7030*4882a593Smuzhiyun 	u32 cp_m2p0, cp_m2p1, cp_m2p2, cp_m2p3;
7031*4882a593Smuzhiyun 	u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
7032*4882a593Smuzhiyun 	u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
7033*4882a593Smuzhiyun 	u32 grbm_int_cntl = 0;
7034*4882a593Smuzhiyun 	u32 dma_cntl, dma_cntl1;
7035*4882a593Smuzhiyun 
7036*4882a593Smuzhiyun 	if (!rdev->irq.installed) {
7037*4882a593Smuzhiyun 		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
7038*4882a593Smuzhiyun 		return -EINVAL;
7039*4882a593Smuzhiyun 	}
7040*4882a593Smuzhiyun 	/* don't enable anything if the ih is disabled */
7041*4882a593Smuzhiyun 	if (!rdev->ih.enabled) {
7042*4882a593Smuzhiyun 		cik_disable_interrupts(rdev);
7043*4882a593Smuzhiyun 		/* force the active interrupt state to all disabled */
7044*4882a593Smuzhiyun 		cik_disable_interrupt_state(rdev);
7045*4882a593Smuzhiyun 		return 0;
7046*4882a593Smuzhiyun 	}
7047*4882a593Smuzhiyun 
7048*4882a593Smuzhiyun 	cp_int_cntl = RREG32(CP_INT_CNTL_RING0) &
7049*4882a593Smuzhiyun 		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
7050*4882a593Smuzhiyun 	cp_int_cntl |= PRIV_INSTR_INT_ENABLE | PRIV_REG_INT_ENABLE;
7051*4882a593Smuzhiyun 
7052*4882a593Smuzhiyun 	hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
7053*4882a593Smuzhiyun 	hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
7054*4882a593Smuzhiyun 	hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
7055*4882a593Smuzhiyun 	hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
7056*4882a593Smuzhiyun 	hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
7057*4882a593Smuzhiyun 	hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN);
7058*4882a593Smuzhiyun 
7059*4882a593Smuzhiyun 	dma_cntl = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
7060*4882a593Smuzhiyun 	dma_cntl1 = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
7061*4882a593Smuzhiyun 
7062*4882a593Smuzhiyun 	cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7063*4882a593Smuzhiyun 	cp_m1p1 = RREG32(CP_ME1_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7064*4882a593Smuzhiyun 	cp_m1p2 = RREG32(CP_ME1_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7065*4882a593Smuzhiyun 	cp_m1p3 = RREG32(CP_ME1_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7066*4882a593Smuzhiyun 	cp_m2p0 = RREG32(CP_ME2_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7067*4882a593Smuzhiyun 	cp_m2p1 = RREG32(CP_ME2_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7068*4882a593Smuzhiyun 	cp_m2p2 = RREG32(CP_ME2_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7069*4882a593Smuzhiyun 	cp_m2p3 = RREG32(CP_ME2_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
7070*4882a593Smuzhiyun 
7071*4882a593Smuzhiyun 	/* enable CP interrupts on all rings */
7072*4882a593Smuzhiyun 	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
7073*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: sw int gfx\n");
7074*4882a593Smuzhiyun 		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
7075*4882a593Smuzhiyun 	}
7076*4882a593Smuzhiyun 	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
7077*4882a593Smuzhiyun 		struct radeon_ring *ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
7078*4882a593Smuzhiyun 		DRM_DEBUG("si_irq_set: sw int cp1\n");
7079*4882a593Smuzhiyun 		if (ring->me == 1) {
7080*4882a593Smuzhiyun 			switch (ring->pipe) {
7081*4882a593Smuzhiyun 			case 0:
7082*4882a593Smuzhiyun 				cp_m1p0 |= TIME_STAMP_INT_ENABLE;
7083*4882a593Smuzhiyun 				break;
7084*4882a593Smuzhiyun 			case 1:
7085*4882a593Smuzhiyun 				cp_m1p1 |= TIME_STAMP_INT_ENABLE;
7086*4882a593Smuzhiyun 				break;
7087*4882a593Smuzhiyun 			case 2:
7088*4882a593Smuzhiyun 				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
7089*4882a593Smuzhiyun 				break;
7090*4882a593Smuzhiyun 			case 3:
7091*4882a593Smuzhiyun 				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
7092*4882a593Smuzhiyun 				break;
7093*4882a593Smuzhiyun 			default:
7094*4882a593Smuzhiyun 				DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe);
7095*4882a593Smuzhiyun 				break;
7096*4882a593Smuzhiyun 			}
7097*4882a593Smuzhiyun 		} else if (ring->me == 2) {
7098*4882a593Smuzhiyun 			switch (ring->pipe) {
7099*4882a593Smuzhiyun 			case 0:
7100*4882a593Smuzhiyun 				cp_m2p0 |= TIME_STAMP_INT_ENABLE;
7101*4882a593Smuzhiyun 				break;
7102*4882a593Smuzhiyun 			case 1:
7103*4882a593Smuzhiyun 				cp_m2p1 |= TIME_STAMP_INT_ENABLE;
7104*4882a593Smuzhiyun 				break;
7105*4882a593Smuzhiyun 			case 2:
7106*4882a593Smuzhiyun 				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
7107*4882a593Smuzhiyun 				break;
7108*4882a593Smuzhiyun 			case 3:
7109*4882a593Smuzhiyun 				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
7110*4882a593Smuzhiyun 				break;
7111*4882a593Smuzhiyun 			default:
7112*4882a593Smuzhiyun 				DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe);
7113*4882a593Smuzhiyun 				break;
7114*4882a593Smuzhiyun 			}
7115*4882a593Smuzhiyun 		} else {
7116*4882a593Smuzhiyun 			DRM_DEBUG("si_irq_set: sw int cp1 invalid me %d\n", ring->me);
7117*4882a593Smuzhiyun 		}
7118*4882a593Smuzhiyun 	}
7119*4882a593Smuzhiyun 	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
7120*4882a593Smuzhiyun 		struct radeon_ring *ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
7121*4882a593Smuzhiyun 		DRM_DEBUG("si_irq_set: sw int cp2\n");
7122*4882a593Smuzhiyun 		if (ring->me == 1) {
7123*4882a593Smuzhiyun 			switch (ring->pipe) {
7124*4882a593Smuzhiyun 			case 0:
7125*4882a593Smuzhiyun 				cp_m1p0 |= TIME_STAMP_INT_ENABLE;
7126*4882a593Smuzhiyun 				break;
7127*4882a593Smuzhiyun 			case 1:
7128*4882a593Smuzhiyun 				cp_m1p1 |= TIME_STAMP_INT_ENABLE;
7129*4882a593Smuzhiyun 				break;
7130*4882a593Smuzhiyun 			case 2:
7131*4882a593Smuzhiyun 				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
7132*4882a593Smuzhiyun 				break;
7133*4882a593Smuzhiyun 			case 3:
7134*4882a593Smuzhiyun 				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
7135*4882a593Smuzhiyun 				break;
7136*4882a593Smuzhiyun 			default:
7137*4882a593Smuzhiyun 				DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe);
7138*4882a593Smuzhiyun 				break;
7139*4882a593Smuzhiyun 			}
7140*4882a593Smuzhiyun 		} else if (ring->me == 2) {
7141*4882a593Smuzhiyun 			switch (ring->pipe) {
7142*4882a593Smuzhiyun 			case 0:
7143*4882a593Smuzhiyun 				cp_m2p0 |= TIME_STAMP_INT_ENABLE;
7144*4882a593Smuzhiyun 				break;
7145*4882a593Smuzhiyun 			case 1:
7146*4882a593Smuzhiyun 				cp_m2p1 |= TIME_STAMP_INT_ENABLE;
7147*4882a593Smuzhiyun 				break;
7148*4882a593Smuzhiyun 			case 2:
7149*4882a593Smuzhiyun 				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
7150*4882a593Smuzhiyun 				break;
7151*4882a593Smuzhiyun 			case 3:
7152*4882a593Smuzhiyun 				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
7153*4882a593Smuzhiyun 				break;
7154*4882a593Smuzhiyun 			default:
7155*4882a593Smuzhiyun 				DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe);
7156*4882a593Smuzhiyun 				break;
7157*4882a593Smuzhiyun 			}
7158*4882a593Smuzhiyun 		} else {
7159*4882a593Smuzhiyun 			DRM_DEBUG("si_irq_set: sw int cp2 invalid me %d\n", ring->me);
7160*4882a593Smuzhiyun 		}
7161*4882a593Smuzhiyun 	}
7162*4882a593Smuzhiyun 
7163*4882a593Smuzhiyun 	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
7164*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: sw int dma\n");
7165*4882a593Smuzhiyun 		dma_cntl |= TRAP_ENABLE;
7166*4882a593Smuzhiyun 	}
7167*4882a593Smuzhiyun 
7168*4882a593Smuzhiyun 	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
7169*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: sw int dma1\n");
7170*4882a593Smuzhiyun 		dma_cntl1 |= TRAP_ENABLE;
7171*4882a593Smuzhiyun 	}
7172*4882a593Smuzhiyun 
7173*4882a593Smuzhiyun 	if (rdev->irq.crtc_vblank_int[0] ||
7174*4882a593Smuzhiyun 	    atomic_read(&rdev->irq.pflip[0])) {
7175*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: vblank 0\n");
7176*4882a593Smuzhiyun 		crtc1 |= VBLANK_INTERRUPT_MASK;
7177*4882a593Smuzhiyun 	}
7178*4882a593Smuzhiyun 	if (rdev->irq.crtc_vblank_int[1] ||
7179*4882a593Smuzhiyun 	    atomic_read(&rdev->irq.pflip[1])) {
7180*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: vblank 1\n");
7181*4882a593Smuzhiyun 		crtc2 |= VBLANK_INTERRUPT_MASK;
7182*4882a593Smuzhiyun 	}
7183*4882a593Smuzhiyun 	if (rdev->irq.crtc_vblank_int[2] ||
7184*4882a593Smuzhiyun 	    atomic_read(&rdev->irq.pflip[2])) {
7185*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: vblank 2\n");
7186*4882a593Smuzhiyun 		crtc3 |= VBLANK_INTERRUPT_MASK;
7187*4882a593Smuzhiyun 	}
7188*4882a593Smuzhiyun 	if (rdev->irq.crtc_vblank_int[3] ||
7189*4882a593Smuzhiyun 	    atomic_read(&rdev->irq.pflip[3])) {
7190*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: vblank 3\n");
7191*4882a593Smuzhiyun 		crtc4 |= VBLANK_INTERRUPT_MASK;
7192*4882a593Smuzhiyun 	}
7193*4882a593Smuzhiyun 	if (rdev->irq.crtc_vblank_int[4] ||
7194*4882a593Smuzhiyun 	    atomic_read(&rdev->irq.pflip[4])) {
7195*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: vblank 4\n");
7196*4882a593Smuzhiyun 		crtc5 |= VBLANK_INTERRUPT_MASK;
7197*4882a593Smuzhiyun 	}
7198*4882a593Smuzhiyun 	if (rdev->irq.crtc_vblank_int[5] ||
7199*4882a593Smuzhiyun 	    atomic_read(&rdev->irq.pflip[5])) {
7200*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: vblank 5\n");
7201*4882a593Smuzhiyun 		crtc6 |= VBLANK_INTERRUPT_MASK;
7202*4882a593Smuzhiyun 	}
7203*4882a593Smuzhiyun 	if (rdev->irq.hpd[0]) {
7204*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: hpd 1\n");
7205*4882a593Smuzhiyun 		hpd1 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
7206*4882a593Smuzhiyun 	}
7207*4882a593Smuzhiyun 	if (rdev->irq.hpd[1]) {
7208*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: hpd 2\n");
7209*4882a593Smuzhiyun 		hpd2 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
7210*4882a593Smuzhiyun 	}
7211*4882a593Smuzhiyun 	if (rdev->irq.hpd[2]) {
7212*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: hpd 3\n");
7213*4882a593Smuzhiyun 		hpd3 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
7214*4882a593Smuzhiyun 	}
7215*4882a593Smuzhiyun 	if (rdev->irq.hpd[3]) {
7216*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: hpd 4\n");
7217*4882a593Smuzhiyun 		hpd4 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
7218*4882a593Smuzhiyun 	}
7219*4882a593Smuzhiyun 	if (rdev->irq.hpd[4]) {
7220*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: hpd 5\n");
7221*4882a593Smuzhiyun 		hpd5 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
7222*4882a593Smuzhiyun 	}
7223*4882a593Smuzhiyun 	if (rdev->irq.hpd[5]) {
7224*4882a593Smuzhiyun 		DRM_DEBUG("cik_irq_set: hpd 6\n");
7225*4882a593Smuzhiyun 		hpd6 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN;
7226*4882a593Smuzhiyun 	}
7227*4882a593Smuzhiyun 
7228*4882a593Smuzhiyun 	WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
7229*4882a593Smuzhiyun 
7230*4882a593Smuzhiyun 	WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, dma_cntl);
7231*4882a593Smuzhiyun 	WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, dma_cntl1);
7232*4882a593Smuzhiyun 
7233*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE0_INT_CNTL, cp_m1p0);
7234*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE1_INT_CNTL, cp_m1p1);
7235*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE2_INT_CNTL, cp_m1p2);
7236*4882a593Smuzhiyun 	WREG32(CP_ME1_PIPE3_INT_CNTL, cp_m1p3);
7237*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE0_INT_CNTL, cp_m2p0);
7238*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE1_INT_CNTL, cp_m2p1);
7239*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE2_INT_CNTL, cp_m2p2);
7240*4882a593Smuzhiyun 	WREG32(CP_ME2_PIPE3_INT_CNTL, cp_m2p3);
7241*4882a593Smuzhiyun 
7242*4882a593Smuzhiyun 	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
7243*4882a593Smuzhiyun 
7244*4882a593Smuzhiyun 	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
7245*4882a593Smuzhiyun 	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
7246*4882a593Smuzhiyun 	if (rdev->num_crtc >= 4) {
7247*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
7248*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
7249*4882a593Smuzhiyun 	}
7250*4882a593Smuzhiyun 	if (rdev->num_crtc >= 6) {
7251*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
7252*4882a593Smuzhiyun 		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
7253*4882a593Smuzhiyun 	}
7254*4882a593Smuzhiyun 
7255*4882a593Smuzhiyun 	if (rdev->num_crtc >= 2) {
7256*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
7257*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_MASK);
7258*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
7259*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_MASK);
7260*4882a593Smuzhiyun 	}
7261*4882a593Smuzhiyun 	if (rdev->num_crtc >= 4) {
7262*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
7263*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_MASK);
7264*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
7265*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_MASK);
7266*4882a593Smuzhiyun 	}
7267*4882a593Smuzhiyun 	if (rdev->num_crtc >= 6) {
7268*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
7269*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_MASK);
7270*4882a593Smuzhiyun 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
7271*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_MASK);
7272*4882a593Smuzhiyun 	}
7273*4882a593Smuzhiyun 
7274*4882a593Smuzhiyun 	WREG32(DC_HPD1_INT_CONTROL, hpd1);
7275*4882a593Smuzhiyun 	WREG32(DC_HPD2_INT_CONTROL, hpd2);
7276*4882a593Smuzhiyun 	WREG32(DC_HPD3_INT_CONTROL, hpd3);
7277*4882a593Smuzhiyun 	WREG32(DC_HPD4_INT_CONTROL, hpd4);
7278*4882a593Smuzhiyun 	WREG32(DC_HPD5_INT_CONTROL, hpd5);
7279*4882a593Smuzhiyun 	WREG32(DC_HPD6_INT_CONTROL, hpd6);
7280*4882a593Smuzhiyun 
7281*4882a593Smuzhiyun 	/* posting read */
7282*4882a593Smuzhiyun 	RREG32(SRBM_STATUS);
7283*4882a593Smuzhiyun 
7284*4882a593Smuzhiyun 	return 0;
7285*4882a593Smuzhiyun }
7286*4882a593Smuzhiyun 
7287*4882a593Smuzhiyun /**
7288*4882a593Smuzhiyun  * cik_irq_ack - ack interrupt sources
7289*4882a593Smuzhiyun  *
7290*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7291*4882a593Smuzhiyun  *
7292*4882a593Smuzhiyun  * Ack interrupt sources on the GPU (vblanks, hpd,
7293*4882a593Smuzhiyun  * etc.) (CIK).  Certain interrupts sources are sw
7294*4882a593Smuzhiyun  * generated and do not require an explicit ack.
7295*4882a593Smuzhiyun  */
cik_irq_ack(struct radeon_device * rdev)7296*4882a593Smuzhiyun static inline void cik_irq_ack(struct radeon_device *rdev)
7297*4882a593Smuzhiyun {
7298*4882a593Smuzhiyun 	u32 tmp;
7299*4882a593Smuzhiyun 
7300*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int = RREG32(DISP_INTERRUPT_STATUS);
7301*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
7302*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2);
7303*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3);
7304*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4);
7305*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
7306*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6);
7307*4882a593Smuzhiyun 
7308*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.d1grph_int = RREG32(GRPH_INT_STATUS +
7309*4882a593Smuzhiyun 		EVERGREEN_CRTC0_REGISTER_OFFSET);
7310*4882a593Smuzhiyun 	rdev->irq.stat_regs.cik.d2grph_int = RREG32(GRPH_INT_STATUS +
7311*4882a593Smuzhiyun 		EVERGREEN_CRTC1_REGISTER_OFFSET);
7312*4882a593Smuzhiyun 	if (rdev->num_crtc >= 4) {
7313*4882a593Smuzhiyun 		rdev->irq.stat_regs.cik.d3grph_int = RREG32(GRPH_INT_STATUS +
7314*4882a593Smuzhiyun 			EVERGREEN_CRTC2_REGISTER_OFFSET);
7315*4882a593Smuzhiyun 		rdev->irq.stat_regs.cik.d4grph_int = RREG32(GRPH_INT_STATUS +
7316*4882a593Smuzhiyun 			EVERGREEN_CRTC3_REGISTER_OFFSET);
7317*4882a593Smuzhiyun 	}
7318*4882a593Smuzhiyun 	if (rdev->num_crtc >= 6) {
7319*4882a593Smuzhiyun 		rdev->irq.stat_regs.cik.d5grph_int = RREG32(GRPH_INT_STATUS +
7320*4882a593Smuzhiyun 			EVERGREEN_CRTC4_REGISTER_OFFSET);
7321*4882a593Smuzhiyun 		rdev->irq.stat_regs.cik.d6grph_int = RREG32(GRPH_INT_STATUS +
7322*4882a593Smuzhiyun 			EVERGREEN_CRTC5_REGISTER_OFFSET);
7323*4882a593Smuzhiyun 	}
7324*4882a593Smuzhiyun 
7325*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
7326*4882a593Smuzhiyun 		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET,
7327*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_CLEAR);
7328*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
7329*4882a593Smuzhiyun 		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET,
7330*4882a593Smuzhiyun 		       GRPH_PFLIP_INT_CLEAR);
7331*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)
7332*4882a593Smuzhiyun 		WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
7333*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)
7334*4882a593Smuzhiyun 		WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
7335*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
7336*4882a593Smuzhiyun 		WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
7337*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT)
7338*4882a593Smuzhiyun 		WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
7339*4882a593Smuzhiyun 
7340*4882a593Smuzhiyun 	if (rdev->num_crtc >= 4) {
7341*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
7342*4882a593Smuzhiyun 			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET,
7343*4882a593Smuzhiyun 			       GRPH_PFLIP_INT_CLEAR);
7344*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
7345*4882a593Smuzhiyun 			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET,
7346*4882a593Smuzhiyun 			       GRPH_PFLIP_INT_CLEAR);
7347*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
7348*4882a593Smuzhiyun 			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
7349*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
7350*4882a593Smuzhiyun 			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
7351*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
7352*4882a593Smuzhiyun 			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
7353*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
7354*4882a593Smuzhiyun 			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
7355*4882a593Smuzhiyun 	}
7356*4882a593Smuzhiyun 
7357*4882a593Smuzhiyun 	if (rdev->num_crtc >= 6) {
7358*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
7359*4882a593Smuzhiyun 			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET,
7360*4882a593Smuzhiyun 			       GRPH_PFLIP_INT_CLEAR);
7361*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
7362*4882a593Smuzhiyun 			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET,
7363*4882a593Smuzhiyun 			       GRPH_PFLIP_INT_CLEAR);
7364*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
7365*4882a593Smuzhiyun 			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
7366*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
7367*4882a593Smuzhiyun 			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
7368*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
7369*4882a593Smuzhiyun 			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
7370*4882a593Smuzhiyun 		if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
7371*4882a593Smuzhiyun 			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
7372*4882a593Smuzhiyun 	}
7373*4882a593Smuzhiyun 
7374*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) {
7375*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD1_INT_CONTROL);
7376*4882a593Smuzhiyun 		tmp |= DC_HPDx_INT_ACK;
7377*4882a593Smuzhiyun 		WREG32(DC_HPD1_INT_CONTROL, tmp);
7378*4882a593Smuzhiyun 	}
7379*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) {
7380*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD2_INT_CONTROL);
7381*4882a593Smuzhiyun 		tmp |= DC_HPDx_INT_ACK;
7382*4882a593Smuzhiyun 		WREG32(DC_HPD2_INT_CONTROL, tmp);
7383*4882a593Smuzhiyun 	}
7384*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) {
7385*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD3_INT_CONTROL);
7386*4882a593Smuzhiyun 		tmp |= DC_HPDx_INT_ACK;
7387*4882a593Smuzhiyun 		WREG32(DC_HPD3_INT_CONTROL, tmp);
7388*4882a593Smuzhiyun 	}
7389*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) {
7390*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD4_INT_CONTROL);
7391*4882a593Smuzhiyun 		tmp |= DC_HPDx_INT_ACK;
7392*4882a593Smuzhiyun 		WREG32(DC_HPD4_INT_CONTROL, tmp);
7393*4882a593Smuzhiyun 	}
7394*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) {
7395*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD5_INT_CONTROL);
7396*4882a593Smuzhiyun 		tmp |= DC_HPDx_INT_ACK;
7397*4882a593Smuzhiyun 		WREG32(DC_HPD5_INT_CONTROL, tmp);
7398*4882a593Smuzhiyun 	}
7399*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) {
7400*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD6_INT_CONTROL);
7401*4882a593Smuzhiyun 		tmp |= DC_HPDx_INT_ACK;
7402*4882a593Smuzhiyun 		WREG32(DC_HPD6_INT_CONTROL, tmp);
7403*4882a593Smuzhiyun 	}
7404*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT) {
7405*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD1_INT_CONTROL);
7406*4882a593Smuzhiyun 		tmp |= DC_HPDx_RX_INT_ACK;
7407*4882a593Smuzhiyun 		WREG32(DC_HPD1_INT_CONTROL, tmp);
7408*4882a593Smuzhiyun 	}
7409*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
7410*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD2_INT_CONTROL);
7411*4882a593Smuzhiyun 		tmp |= DC_HPDx_RX_INT_ACK;
7412*4882a593Smuzhiyun 		WREG32(DC_HPD2_INT_CONTROL, tmp);
7413*4882a593Smuzhiyun 	}
7414*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
7415*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD3_INT_CONTROL);
7416*4882a593Smuzhiyun 		tmp |= DC_HPDx_RX_INT_ACK;
7417*4882a593Smuzhiyun 		WREG32(DC_HPD3_INT_CONTROL, tmp);
7418*4882a593Smuzhiyun 	}
7419*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
7420*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD4_INT_CONTROL);
7421*4882a593Smuzhiyun 		tmp |= DC_HPDx_RX_INT_ACK;
7422*4882a593Smuzhiyun 		WREG32(DC_HPD4_INT_CONTROL, tmp);
7423*4882a593Smuzhiyun 	}
7424*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
7425*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD5_INT_CONTROL);
7426*4882a593Smuzhiyun 		tmp |= DC_HPDx_RX_INT_ACK;
7427*4882a593Smuzhiyun 		WREG32(DC_HPD5_INT_CONTROL, tmp);
7428*4882a593Smuzhiyun 	}
7429*4882a593Smuzhiyun 	if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
7430*4882a593Smuzhiyun 		tmp = RREG32(DC_HPD6_INT_CONTROL);
7431*4882a593Smuzhiyun 		tmp |= DC_HPDx_RX_INT_ACK;
7432*4882a593Smuzhiyun 		WREG32(DC_HPD6_INT_CONTROL, tmp);
7433*4882a593Smuzhiyun 	}
7434*4882a593Smuzhiyun }
7435*4882a593Smuzhiyun 
7436*4882a593Smuzhiyun /**
7437*4882a593Smuzhiyun  * cik_irq_disable - disable interrupts
7438*4882a593Smuzhiyun  *
7439*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7440*4882a593Smuzhiyun  *
7441*4882a593Smuzhiyun  * Disable interrupts on the hw (CIK).
7442*4882a593Smuzhiyun  */
cik_irq_disable(struct radeon_device * rdev)7443*4882a593Smuzhiyun static void cik_irq_disable(struct radeon_device *rdev)
7444*4882a593Smuzhiyun {
7445*4882a593Smuzhiyun 	cik_disable_interrupts(rdev);
7446*4882a593Smuzhiyun 	/* Wait and acknowledge irq */
7447*4882a593Smuzhiyun 	mdelay(1);
7448*4882a593Smuzhiyun 	cik_irq_ack(rdev);
7449*4882a593Smuzhiyun 	cik_disable_interrupt_state(rdev);
7450*4882a593Smuzhiyun }
7451*4882a593Smuzhiyun 
7452*4882a593Smuzhiyun /**
7453*4882a593Smuzhiyun  * cik_irq_disable - disable interrupts for suspend
7454*4882a593Smuzhiyun  *
7455*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7456*4882a593Smuzhiyun  *
7457*4882a593Smuzhiyun  * Disable interrupts and stop the RLC (CIK).
7458*4882a593Smuzhiyun  * Used for suspend.
7459*4882a593Smuzhiyun  */
cik_irq_suspend(struct radeon_device * rdev)7460*4882a593Smuzhiyun static void cik_irq_suspend(struct radeon_device *rdev)
7461*4882a593Smuzhiyun {
7462*4882a593Smuzhiyun 	cik_irq_disable(rdev);
7463*4882a593Smuzhiyun 	cik_rlc_stop(rdev);
7464*4882a593Smuzhiyun }
7465*4882a593Smuzhiyun 
7466*4882a593Smuzhiyun /**
7467*4882a593Smuzhiyun  * cik_irq_fini - tear down interrupt support
7468*4882a593Smuzhiyun  *
7469*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7470*4882a593Smuzhiyun  *
7471*4882a593Smuzhiyun  * Disable interrupts on the hw and free the IH ring
7472*4882a593Smuzhiyun  * buffer (CIK).
7473*4882a593Smuzhiyun  * Used for driver unload.
7474*4882a593Smuzhiyun  */
cik_irq_fini(struct radeon_device * rdev)7475*4882a593Smuzhiyun static void cik_irq_fini(struct radeon_device *rdev)
7476*4882a593Smuzhiyun {
7477*4882a593Smuzhiyun 	cik_irq_suspend(rdev);
7478*4882a593Smuzhiyun 	r600_ih_ring_fini(rdev);
7479*4882a593Smuzhiyun }
7480*4882a593Smuzhiyun 
7481*4882a593Smuzhiyun /**
7482*4882a593Smuzhiyun  * cik_get_ih_wptr - get the IH ring buffer wptr
7483*4882a593Smuzhiyun  *
7484*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7485*4882a593Smuzhiyun  *
7486*4882a593Smuzhiyun  * Get the IH ring buffer wptr from either the register
7487*4882a593Smuzhiyun  * or the writeback memory buffer (CIK).  Also check for
7488*4882a593Smuzhiyun  * ring buffer overflow and deal with it.
7489*4882a593Smuzhiyun  * Used by cik_irq_process().
7490*4882a593Smuzhiyun  * Returns the value of the wptr.
7491*4882a593Smuzhiyun  */
cik_get_ih_wptr(struct radeon_device * rdev)7492*4882a593Smuzhiyun static inline u32 cik_get_ih_wptr(struct radeon_device *rdev)
7493*4882a593Smuzhiyun {
7494*4882a593Smuzhiyun 	u32 wptr, tmp;
7495*4882a593Smuzhiyun 
7496*4882a593Smuzhiyun 	if (rdev->wb.enabled)
7497*4882a593Smuzhiyun 		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
7498*4882a593Smuzhiyun 	else
7499*4882a593Smuzhiyun 		wptr = RREG32(IH_RB_WPTR);
7500*4882a593Smuzhiyun 
7501*4882a593Smuzhiyun 	if (wptr & RB_OVERFLOW) {
7502*4882a593Smuzhiyun 		wptr &= ~RB_OVERFLOW;
7503*4882a593Smuzhiyun 		/* When a ring buffer overflow happen start parsing interrupt
7504*4882a593Smuzhiyun 		 * from the last not overwritten vector (wptr + 16). Hopefully
7505*4882a593Smuzhiyun 		 * this should allow us to catchup.
7506*4882a593Smuzhiyun 		 */
7507*4882a593Smuzhiyun 		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
7508*4882a593Smuzhiyun 			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
7509*4882a593Smuzhiyun 		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
7510*4882a593Smuzhiyun 		tmp = RREG32(IH_RB_CNTL);
7511*4882a593Smuzhiyun 		tmp |= IH_WPTR_OVERFLOW_CLEAR;
7512*4882a593Smuzhiyun 		WREG32(IH_RB_CNTL, tmp);
7513*4882a593Smuzhiyun 	}
7514*4882a593Smuzhiyun 	return (wptr & rdev->ih.ptr_mask);
7515*4882a593Smuzhiyun }
7516*4882a593Smuzhiyun 
7517*4882a593Smuzhiyun /*        CIK IV Ring
7518*4882a593Smuzhiyun  * Each IV ring entry is 128 bits:
7519*4882a593Smuzhiyun  * [7:0]    - interrupt source id
7520*4882a593Smuzhiyun  * [31:8]   - reserved
7521*4882a593Smuzhiyun  * [59:32]  - interrupt source data
7522*4882a593Smuzhiyun  * [63:60]  - reserved
7523*4882a593Smuzhiyun  * [71:64]  - RINGID
7524*4882a593Smuzhiyun  *            CP:
7525*4882a593Smuzhiyun  *            ME_ID [1:0], PIPE_ID[1:0], QUEUE_ID[2:0]
7526*4882a593Smuzhiyun  *            QUEUE_ID - for compute, which of the 8 queues owned by the dispatcher
7527*4882a593Smuzhiyun  *                     - for gfx, hw shader state (0=PS...5=LS, 6=CS)
7528*4882a593Smuzhiyun  *            ME_ID - 0 = gfx, 1 = first 4 CS pipes, 2 = second 4 CS pipes
7529*4882a593Smuzhiyun  *            PIPE_ID - ME0 0=3D
7530*4882a593Smuzhiyun  *                    - ME1&2 compute dispatcher (4 pipes each)
7531*4882a593Smuzhiyun  *            SDMA:
7532*4882a593Smuzhiyun  *            INSTANCE_ID [1:0], QUEUE_ID[1:0]
7533*4882a593Smuzhiyun  *            INSTANCE_ID - 0 = sdma0, 1 = sdma1
7534*4882a593Smuzhiyun  *            QUEUE_ID - 0 = gfx, 1 = rlc0, 2 = rlc1
7535*4882a593Smuzhiyun  * [79:72]  - VMID
7536*4882a593Smuzhiyun  * [95:80]  - PASID
7537*4882a593Smuzhiyun  * [127:96] - reserved
7538*4882a593Smuzhiyun  */
7539*4882a593Smuzhiyun /**
7540*4882a593Smuzhiyun  * cik_irq_process - interrupt handler
7541*4882a593Smuzhiyun  *
7542*4882a593Smuzhiyun  * @rdev: radeon_device pointer
7543*4882a593Smuzhiyun  *
7544*4882a593Smuzhiyun  * Interrupt hander (CIK).  Walk the IH ring,
7545*4882a593Smuzhiyun  * ack interrupts and schedule work to handle
7546*4882a593Smuzhiyun  * interrupt events.
7547*4882a593Smuzhiyun  * Returns irq process return code.
7548*4882a593Smuzhiyun  */
cik_irq_process(struct radeon_device * rdev)7549*4882a593Smuzhiyun int cik_irq_process(struct radeon_device *rdev)
7550*4882a593Smuzhiyun {
7551*4882a593Smuzhiyun 	struct radeon_ring *cp1_ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
7552*4882a593Smuzhiyun 	struct radeon_ring *cp2_ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
7553*4882a593Smuzhiyun 	u32 wptr;
7554*4882a593Smuzhiyun 	u32 rptr;
7555*4882a593Smuzhiyun 	u32 src_id, src_data, ring_id;
7556*4882a593Smuzhiyun 	u8 me_id, pipe_id, queue_id;
7557*4882a593Smuzhiyun 	u32 ring_index;
7558*4882a593Smuzhiyun 	bool queue_hotplug = false;
7559*4882a593Smuzhiyun 	bool queue_dp = false;
7560*4882a593Smuzhiyun 	bool queue_reset = false;
7561*4882a593Smuzhiyun 	u32 addr, status, mc_client;
7562*4882a593Smuzhiyun 	bool queue_thermal = false;
7563*4882a593Smuzhiyun 
7564*4882a593Smuzhiyun 	if (!rdev->ih.enabled || rdev->shutdown)
7565*4882a593Smuzhiyun 		return IRQ_NONE;
7566*4882a593Smuzhiyun 
7567*4882a593Smuzhiyun 	wptr = cik_get_ih_wptr(rdev);
7568*4882a593Smuzhiyun 
7569*4882a593Smuzhiyun restart_ih:
7570*4882a593Smuzhiyun 	/* is somebody else already processing irqs? */
7571*4882a593Smuzhiyun 	if (atomic_xchg(&rdev->ih.lock, 1))
7572*4882a593Smuzhiyun 		return IRQ_NONE;
7573*4882a593Smuzhiyun 
7574*4882a593Smuzhiyun 	rptr = rdev->ih.rptr;
7575*4882a593Smuzhiyun 	DRM_DEBUG("cik_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
7576*4882a593Smuzhiyun 
7577*4882a593Smuzhiyun 	/* Order reading of wptr vs. reading of IH ring data */
7578*4882a593Smuzhiyun 	rmb();
7579*4882a593Smuzhiyun 
7580*4882a593Smuzhiyun 	/* display interrupts */
7581*4882a593Smuzhiyun 	cik_irq_ack(rdev);
7582*4882a593Smuzhiyun 
7583*4882a593Smuzhiyun 	while (rptr != wptr) {
7584*4882a593Smuzhiyun 		/* wptr/rptr are in bytes! */
7585*4882a593Smuzhiyun 		ring_index = rptr / 4;
7586*4882a593Smuzhiyun 
7587*4882a593Smuzhiyun 		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
7588*4882a593Smuzhiyun 		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
7589*4882a593Smuzhiyun 		ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
7590*4882a593Smuzhiyun 
7591*4882a593Smuzhiyun 		switch (src_id) {
7592*4882a593Smuzhiyun 		case 1: /* D1 vblank/vline */
7593*4882a593Smuzhiyun 			switch (src_data) {
7594*4882a593Smuzhiyun 			case 0: /* D1 vblank */
7595*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT))
7596*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7597*4882a593Smuzhiyun 
7598*4882a593Smuzhiyun 				if (rdev->irq.crtc_vblank_int[0]) {
7599*4882a593Smuzhiyun 					drm_handle_vblank(rdev->ddev, 0);
7600*4882a593Smuzhiyun 					rdev->pm.vblank_sync = true;
7601*4882a593Smuzhiyun 					wake_up(&rdev->irq.vblank_queue);
7602*4882a593Smuzhiyun 				}
7603*4882a593Smuzhiyun 				if (atomic_read(&rdev->irq.pflip[0]))
7604*4882a593Smuzhiyun 					radeon_crtc_handle_vblank(rdev, 0);
7605*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
7606*4882a593Smuzhiyun 				DRM_DEBUG("IH: D1 vblank\n");
7607*4882a593Smuzhiyun 
7608*4882a593Smuzhiyun 				break;
7609*4882a593Smuzhiyun 			case 1: /* D1 vline */
7610*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT))
7611*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7612*4882a593Smuzhiyun 
7613*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT;
7614*4882a593Smuzhiyun 				DRM_DEBUG("IH: D1 vline\n");
7615*4882a593Smuzhiyun 
7616*4882a593Smuzhiyun 				break;
7617*4882a593Smuzhiyun 			default:
7618*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7619*4882a593Smuzhiyun 				break;
7620*4882a593Smuzhiyun 			}
7621*4882a593Smuzhiyun 			break;
7622*4882a593Smuzhiyun 		case 2: /* D2 vblank/vline */
7623*4882a593Smuzhiyun 			switch (src_data) {
7624*4882a593Smuzhiyun 			case 0: /* D2 vblank */
7625*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
7626*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7627*4882a593Smuzhiyun 
7628*4882a593Smuzhiyun 				if (rdev->irq.crtc_vblank_int[1]) {
7629*4882a593Smuzhiyun 					drm_handle_vblank(rdev->ddev, 1);
7630*4882a593Smuzhiyun 					rdev->pm.vblank_sync = true;
7631*4882a593Smuzhiyun 					wake_up(&rdev->irq.vblank_queue);
7632*4882a593Smuzhiyun 				}
7633*4882a593Smuzhiyun 				if (atomic_read(&rdev->irq.pflip[1]))
7634*4882a593Smuzhiyun 					radeon_crtc_handle_vblank(rdev, 1);
7635*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
7636*4882a593Smuzhiyun 				DRM_DEBUG("IH: D2 vblank\n");
7637*4882a593Smuzhiyun 
7638*4882a593Smuzhiyun 				break;
7639*4882a593Smuzhiyun 			case 1: /* D2 vline */
7640*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT))
7641*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7642*4882a593Smuzhiyun 
7643*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
7644*4882a593Smuzhiyun 				DRM_DEBUG("IH: D2 vline\n");
7645*4882a593Smuzhiyun 
7646*4882a593Smuzhiyun 				break;
7647*4882a593Smuzhiyun 			default:
7648*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7649*4882a593Smuzhiyun 				break;
7650*4882a593Smuzhiyun 			}
7651*4882a593Smuzhiyun 			break;
7652*4882a593Smuzhiyun 		case 3: /* D3 vblank/vline */
7653*4882a593Smuzhiyun 			switch (src_data) {
7654*4882a593Smuzhiyun 			case 0: /* D3 vblank */
7655*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
7656*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7657*4882a593Smuzhiyun 
7658*4882a593Smuzhiyun 				if (rdev->irq.crtc_vblank_int[2]) {
7659*4882a593Smuzhiyun 					drm_handle_vblank(rdev->ddev, 2);
7660*4882a593Smuzhiyun 					rdev->pm.vblank_sync = true;
7661*4882a593Smuzhiyun 					wake_up(&rdev->irq.vblank_queue);
7662*4882a593Smuzhiyun 				}
7663*4882a593Smuzhiyun 				if (atomic_read(&rdev->irq.pflip[2]))
7664*4882a593Smuzhiyun 					radeon_crtc_handle_vblank(rdev, 2);
7665*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
7666*4882a593Smuzhiyun 				DRM_DEBUG("IH: D3 vblank\n");
7667*4882a593Smuzhiyun 
7668*4882a593Smuzhiyun 				break;
7669*4882a593Smuzhiyun 			case 1: /* D3 vline */
7670*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
7671*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7672*4882a593Smuzhiyun 
7673*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
7674*4882a593Smuzhiyun 				DRM_DEBUG("IH: D3 vline\n");
7675*4882a593Smuzhiyun 
7676*4882a593Smuzhiyun 				break;
7677*4882a593Smuzhiyun 			default:
7678*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7679*4882a593Smuzhiyun 				break;
7680*4882a593Smuzhiyun 			}
7681*4882a593Smuzhiyun 			break;
7682*4882a593Smuzhiyun 		case 4: /* D4 vblank/vline */
7683*4882a593Smuzhiyun 			switch (src_data) {
7684*4882a593Smuzhiyun 			case 0: /* D4 vblank */
7685*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
7686*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7687*4882a593Smuzhiyun 
7688*4882a593Smuzhiyun 				if (rdev->irq.crtc_vblank_int[3]) {
7689*4882a593Smuzhiyun 					drm_handle_vblank(rdev->ddev, 3);
7690*4882a593Smuzhiyun 					rdev->pm.vblank_sync = true;
7691*4882a593Smuzhiyun 					wake_up(&rdev->irq.vblank_queue);
7692*4882a593Smuzhiyun 				}
7693*4882a593Smuzhiyun 				if (atomic_read(&rdev->irq.pflip[3]))
7694*4882a593Smuzhiyun 					radeon_crtc_handle_vblank(rdev, 3);
7695*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
7696*4882a593Smuzhiyun 				DRM_DEBUG("IH: D4 vblank\n");
7697*4882a593Smuzhiyun 
7698*4882a593Smuzhiyun 				break;
7699*4882a593Smuzhiyun 			case 1: /* D4 vline */
7700*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
7701*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7702*4882a593Smuzhiyun 
7703*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
7704*4882a593Smuzhiyun 				DRM_DEBUG("IH: D4 vline\n");
7705*4882a593Smuzhiyun 
7706*4882a593Smuzhiyun 				break;
7707*4882a593Smuzhiyun 			default:
7708*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7709*4882a593Smuzhiyun 				break;
7710*4882a593Smuzhiyun 			}
7711*4882a593Smuzhiyun 			break;
7712*4882a593Smuzhiyun 		case 5: /* D5 vblank/vline */
7713*4882a593Smuzhiyun 			switch (src_data) {
7714*4882a593Smuzhiyun 			case 0: /* D5 vblank */
7715*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
7716*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7717*4882a593Smuzhiyun 
7718*4882a593Smuzhiyun 				if (rdev->irq.crtc_vblank_int[4]) {
7719*4882a593Smuzhiyun 					drm_handle_vblank(rdev->ddev, 4);
7720*4882a593Smuzhiyun 					rdev->pm.vblank_sync = true;
7721*4882a593Smuzhiyun 					wake_up(&rdev->irq.vblank_queue);
7722*4882a593Smuzhiyun 				}
7723*4882a593Smuzhiyun 				if (atomic_read(&rdev->irq.pflip[4]))
7724*4882a593Smuzhiyun 					radeon_crtc_handle_vblank(rdev, 4);
7725*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
7726*4882a593Smuzhiyun 				DRM_DEBUG("IH: D5 vblank\n");
7727*4882a593Smuzhiyun 
7728*4882a593Smuzhiyun 				break;
7729*4882a593Smuzhiyun 			case 1: /* D5 vline */
7730*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
7731*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7732*4882a593Smuzhiyun 
7733*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
7734*4882a593Smuzhiyun 				DRM_DEBUG("IH: D5 vline\n");
7735*4882a593Smuzhiyun 
7736*4882a593Smuzhiyun 				break;
7737*4882a593Smuzhiyun 			default:
7738*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7739*4882a593Smuzhiyun 				break;
7740*4882a593Smuzhiyun 			}
7741*4882a593Smuzhiyun 			break;
7742*4882a593Smuzhiyun 		case 6: /* D6 vblank/vline */
7743*4882a593Smuzhiyun 			switch (src_data) {
7744*4882a593Smuzhiyun 			case 0: /* D6 vblank */
7745*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
7746*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7747*4882a593Smuzhiyun 
7748*4882a593Smuzhiyun 				if (rdev->irq.crtc_vblank_int[5]) {
7749*4882a593Smuzhiyun 					drm_handle_vblank(rdev->ddev, 5);
7750*4882a593Smuzhiyun 					rdev->pm.vblank_sync = true;
7751*4882a593Smuzhiyun 					wake_up(&rdev->irq.vblank_queue);
7752*4882a593Smuzhiyun 				}
7753*4882a593Smuzhiyun 				if (atomic_read(&rdev->irq.pflip[5]))
7754*4882a593Smuzhiyun 					radeon_crtc_handle_vblank(rdev, 5);
7755*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
7756*4882a593Smuzhiyun 				DRM_DEBUG("IH: D6 vblank\n");
7757*4882a593Smuzhiyun 
7758*4882a593Smuzhiyun 				break;
7759*4882a593Smuzhiyun 			case 1: /* D6 vline */
7760*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
7761*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7762*4882a593Smuzhiyun 
7763*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
7764*4882a593Smuzhiyun 				DRM_DEBUG("IH: D6 vline\n");
7765*4882a593Smuzhiyun 
7766*4882a593Smuzhiyun 				break;
7767*4882a593Smuzhiyun 			default:
7768*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7769*4882a593Smuzhiyun 				break;
7770*4882a593Smuzhiyun 			}
7771*4882a593Smuzhiyun 			break;
7772*4882a593Smuzhiyun 		case 8: /* D1 page flip */
7773*4882a593Smuzhiyun 		case 10: /* D2 page flip */
7774*4882a593Smuzhiyun 		case 12: /* D3 page flip */
7775*4882a593Smuzhiyun 		case 14: /* D4 page flip */
7776*4882a593Smuzhiyun 		case 16: /* D5 page flip */
7777*4882a593Smuzhiyun 		case 18: /* D6 page flip */
7778*4882a593Smuzhiyun 			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
7779*4882a593Smuzhiyun 			if (radeon_use_pflipirq > 0)
7780*4882a593Smuzhiyun 				radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
7781*4882a593Smuzhiyun 			break;
7782*4882a593Smuzhiyun 		case 42: /* HPD hotplug */
7783*4882a593Smuzhiyun 			switch (src_data) {
7784*4882a593Smuzhiyun 			case 0:
7785*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT))
7786*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7787*4882a593Smuzhiyun 
7788*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT;
7789*4882a593Smuzhiyun 				queue_hotplug = true;
7790*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD1\n");
7791*4882a593Smuzhiyun 
7792*4882a593Smuzhiyun 				break;
7793*4882a593Smuzhiyun 			case 1:
7794*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT))
7795*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7796*4882a593Smuzhiyun 
7797*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
7798*4882a593Smuzhiyun 				queue_hotplug = true;
7799*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD2\n");
7800*4882a593Smuzhiyun 
7801*4882a593Smuzhiyun 				break;
7802*4882a593Smuzhiyun 			case 2:
7803*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT))
7804*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7805*4882a593Smuzhiyun 
7806*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
7807*4882a593Smuzhiyun 				queue_hotplug = true;
7808*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD3\n");
7809*4882a593Smuzhiyun 
7810*4882a593Smuzhiyun 				break;
7811*4882a593Smuzhiyun 			case 3:
7812*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT))
7813*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7814*4882a593Smuzhiyun 
7815*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
7816*4882a593Smuzhiyun 				queue_hotplug = true;
7817*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD4\n");
7818*4882a593Smuzhiyun 
7819*4882a593Smuzhiyun 				break;
7820*4882a593Smuzhiyun 			case 4:
7821*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT))
7822*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7823*4882a593Smuzhiyun 
7824*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
7825*4882a593Smuzhiyun 				queue_hotplug = true;
7826*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD5\n");
7827*4882a593Smuzhiyun 
7828*4882a593Smuzhiyun 				break;
7829*4882a593Smuzhiyun 			case 5:
7830*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT))
7831*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7832*4882a593Smuzhiyun 
7833*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
7834*4882a593Smuzhiyun 				queue_hotplug = true;
7835*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD6\n");
7836*4882a593Smuzhiyun 
7837*4882a593Smuzhiyun 				break;
7838*4882a593Smuzhiyun 			case 6:
7839*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT))
7840*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7841*4882a593Smuzhiyun 
7842*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT;
7843*4882a593Smuzhiyun 				queue_dp = true;
7844*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD_RX 1\n");
7845*4882a593Smuzhiyun 
7846*4882a593Smuzhiyun 				break;
7847*4882a593Smuzhiyun 			case 7:
7848*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT))
7849*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7850*4882a593Smuzhiyun 
7851*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
7852*4882a593Smuzhiyun 				queue_dp = true;
7853*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD_RX 2\n");
7854*4882a593Smuzhiyun 
7855*4882a593Smuzhiyun 				break;
7856*4882a593Smuzhiyun 			case 8:
7857*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
7858*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7859*4882a593Smuzhiyun 
7860*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
7861*4882a593Smuzhiyun 				queue_dp = true;
7862*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD_RX 3\n");
7863*4882a593Smuzhiyun 
7864*4882a593Smuzhiyun 				break;
7865*4882a593Smuzhiyun 			case 9:
7866*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
7867*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7868*4882a593Smuzhiyun 
7869*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
7870*4882a593Smuzhiyun 				queue_dp = true;
7871*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD_RX 4\n");
7872*4882a593Smuzhiyun 
7873*4882a593Smuzhiyun 				break;
7874*4882a593Smuzhiyun 			case 10:
7875*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
7876*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7877*4882a593Smuzhiyun 
7878*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
7879*4882a593Smuzhiyun 				queue_dp = true;
7880*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD_RX 5\n");
7881*4882a593Smuzhiyun 
7882*4882a593Smuzhiyun 				break;
7883*4882a593Smuzhiyun 			case 11:
7884*4882a593Smuzhiyun 				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
7885*4882a593Smuzhiyun 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
7886*4882a593Smuzhiyun 
7887*4882a593Smuzhiyun 				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
7888*4882a593Smuzhiyun 				queue_dp = true;
7889*4882a593Smuzhiyun 				DRM_DEBUG("IH: HPD_RX 6\n");
7890*4882a593Smuzhiyun 
7891*4882a593Smuzhiyun 				break;
7892*4882a593Smuzhiyun 			default:
7893*4882a593Smuzhiyun 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
7894*4882a593Smuzhiyun 				break;
7895*4882a593Smuzhiyun 			}
7896*4882a593Smuzhiyun 			break;
7897*4882a593Smuzhiyun 		case 96:
7898*4882a593Smuzhiyun 			DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
7899*4882a593Smuzhiyun 			WREG32(SRBM_INT_ACK, 0x1);
7900*4882a593Smuzhiyun 			break;
7901*4882a593Smuzhiyun 		case 124: /* UVD */
7902*4882a593Smuzhiyun 			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
7903*4882a593Smuzhiyun 			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
7904*4882a593Smuzhiyun 			break;
7905*4882a593Smuzhiyun 		case 146:
7906*4882a593Smuzhiyun 		case 147:
7907*4882a593Smuzhiyun 			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
7908*4882a593Smuzhiyun 			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
7909*4882a593Smuzhiyun 			mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
7910*4882a593Smuzhiyun 			/* reset addr and status */
7911*4882a593Smuzhiyun 			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
7912*4882a593Smuzhiyun 			if (addr == 0x0 && status == 0x0)
7913*4882a593Smuzhiyun 				break;
7914*4882a593Smuzhiyun 			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
7915*4882a593Smuzhiyun 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
7916*4882a593Smuzhiyun 				addr);
7917*4882a593Smuzhiyun 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
7918*4882a593Smuzhiyun 				status);
7919*4882a593Smuzhiyun 			cik_vm_decode_fault(rdev, status, addr, mc_client);
7920*4882a593Smuzhiyun 			break;
7921*4882a593Smuzhiyun 		case 167: /* VCE */
7922*4882a593Smuzhiyun 			DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data);
7923*4882a593Smuzhiyun 			switch (src_data) {
7924*4882a593Smuzhiyun 			case 0:
7925*4882a593Smuzhiyun 				radeon_fence_process(rdev, TN_RING_TYPE_VCE1_INDEX);
7926*4882a593Smuzhiyun 				break;
7927*4882a593Smuzhiyun 			case 1:
7928*4882a593Smuzhiyun 				radeon_fence_process(rdev, TN_RING_TYPE_VCE2_INDEX);
7929*4882a593Smuzhiyun 				break;
7930*4882a593Smuzhiyun 			default:
7931*4882a593Smuzhiyun 				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
7932*4882a593Smuzhiyun 				break;
7933*4882a593Smuzhiyun 			}
7934*4882a593Smuzhiyun 			break;
7935*4882a593Smuzhiyun 		case 176: /* GFX RB CP_INT */
7936*4882a593Smuzhiyun 		case 177: /* GFX IB CP_INT */
7937*4882a593Smuzhiyun 			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
7938*4882a593Smuzhiyun 			break;
7939*4882a593Smuzhiyun 		case 181: /* CP EOP event */
7940*4882a593Smuzhiyun 			DRM_DEBUG("IH: CP EOP\n");
7941*4882a593Smuzhiyun 			/* XXX check the bitfield order! */
7942*4882a593Smuzhiyun 			me_id = (ring_id & 0x60) >> 5;
7943*4882a593Smuzhiyun 			pipe_id = (ring_id & 0x18) >> 3;
7944*4882a593Smuzhiyun 			queue_id = (ring_id & 0x7) >> 0;
7945*4882a593Smuzhiyun 			switch (me_id) {
7946*4882a593Smuzhiyun 			case 0:
7947*4882a593Smuzhiyun 				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
7948*4882a593Smuzhiyun 				break;
7949*4882a593Smuzhiyun 			case 1:
7950*4882a593Smuzhiyun 			case 2:
7951*4882a593Smuzhiyun 				if ((cp1_ring->me == me_id) & (cp1_ring->pipe == pipe_id))
7952*4882a593Smuzhiyun 					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
7953*4882a593Smuzhiyun 				if ((cp2_ring->me == me_id) & (cp2_ring->pipe == pipe_id))
7954*4882a593Smuzhiyun 					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
7955*4882a593Smuzhiyun 				break;
7956*4882a593Smuzhiyun 			}
7957*4882a593Smuzhiyun 			break;
7958*4882a593Smuzhiyun 		case 184: /* CP Privileged reg access */
7959*4882a593Smuzhiyun 			DRM_ERROR("Illegal register access in command stream\n");
7960*4882a593Smuzhiyun 			/* XXX check the bitfield order! */
7961*4882a593Smuzhiyun 			me_id = (ring_id & 0x60) >> 5;
7962*4882a593Smuzhiyun 			pipe_id = (ring_id & 0x18) >> 3;
7963*4882a593Smuzhiyun 			queue_id = (ring_id & 0x7) >> 0;
7964*4882a593Smuzhiyun 			switch (me_id) {
7965*4882a593Smuzhiyun 			case 0:
7966*4882a593Smuzhiyun 				/* This results in a full GPU reset, but all we need to do is soft
7967*4882a593Smuzhiyun 				 * reset the CP for gfx
7968*4882a593Smuzhiyun 				 */
7969*4882a593Smuzhiyun 				queue_reset = true;
7970*4882a593Smuzhiyun 				break;
7971*4882a593Smuzhiyun 			case 1:
7972*4882a593Smuzhiyun 				/* XXX compute */
7973*4882a593Smuzhiyun 				queue_reset = true;
7974*4882a593Smuzhiyun 				break;
7975*4882a593Smuzhiyun 			case 2:
7976*4882a593Smuzhiyun 				/* XXX compute */
7977*4882a593Smuzhiyun 				queue_reset = true;
7978*4882a593Smuzhiyun 				break;
7979*4882a593Smuzhiyun 			}
7980*4882a593Smuzhiyun 			break;
7981*4882a593Smuzhiyun 		case 185: /* CP Privileged inst */
7982*4882a593Smuzhiyun 			DRM_ERROR("Illegal instruction in command stream\n");
7983*4882a593Smuzhiyun 			/* XXX check the bitfield order! */
7984*4882a593Smuzhiyun 			me_id = (ring_id & 0x60) >> 5;
7985*4882a593Smuzhiyun 			pipe_id = (ring_id & 0x18) >> 3;
7986*4882a593Smuzhiyun 			queue_id = (ring_id & 0x7) >> 0;
7987*4882a593Smuzhiyun 			switch (me_id) {
7988*4882a593Smuzhiyun 			case 0:
7989*4882a593Smuzhiyun 				/* This results in a full GPU reset, but all we need to do is soft
7990*4882a593Smuzhiyun 				 * reset the CP for gfx
7991*4882a593Smuzhiyun 				 */
7992*4882a593Smuzhiyun 				queue_reset = true;
7993*4882a593Smuzhiyun 				break;
7994*4882a593Smuzhiyun 			case 1:
7995*4882a593Smuzhiyun 				/* XXX compute */
7996*4882a593Smuzhiyun 				queue_reset = true;
7997*4882a593Smuzhiyun 				break;
7998*4882a593Smuzhiyun 			case 2:
7999*4882a593Smuzhiyun 				/* XXX compute */
8000*4882a593Smuzhiyun 				queue_reset = true;
8001*4882a593Smuzhiyun 				break;
8002*4882a593Smuzhiyun 			}
8003*4882a593Smuzhiyun 			break;
8004*4882a593Smuzhiyun 		case 224: /* SDMA trap event */
8005*4882a593Smuzhiyun 			/* XXX check the bitfield order! */
8006*4882a593Smuzhiyun 			me_id = (ring_id & 0x3) >> 0;
8007*4882a593Smuzhiyun 			queue_id = (ring_id & 0xc) >> 2;
8008*4882a593Smuzhiyun 			DRM_DEBUG("IH: SDMA trap\n");
8009*4882a593Smuzhiyun 			switch (me_id) {
8010*4882a593Smuzhiyun 			case 0:
8011*4882a593Smuzhiyun 				switch (queue_id) {
8012*4882a593Smuzhiyun 				case 0:
8013*4882a593Smuzhiyun 					radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
8014*4882a593Smuzhiyun 					break;
8015*4882a593Smuzhiyun 				case 1:
8016*4882a593Smuzhiyun 					/* XXX compute */
8017*4882a593Smuzhiyun 					break;
8018*4882a593Smuzhiyun 				case 2:
8019*4882a593Smuzhiyun 					/* XXX compute */
8020*4882a593Smuzhiyun 					break;
8021*4882a593Smuzhiyun 				}
8022*4882a593Smuzhiyun 				break;
8023*4882a593Smuzhiyun 			case 1:
8024*4882a593Smuzhiyun 				switch (queue_id) {
8025*4882a593Smuzhiyun 				case 0:
8026*4882a593Smuzhiyun 					radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
8027*4882a593Smuzhiyun 					break;
8028*4882a593Smuzhiyun 				case 1:
8029*4882a593Smuzhiyun 					/* XXX compute */
8030*4882a593Smuzhiyun 					break;
8031*4882a593Smuzhiyun 				case 2:
8032*4882a593Smuzhiyun 					/* XXX compute */
8033*4882a593Smuzhiyun 					break;
8034*4882a593Smuzhiyun 				}
8035*4882a593Smuzhiyun 				break;
8036*4882a593Smuzhiyun 			}
8037*4882a593Smuzhiyun 			break;
8038*4882a593Smuzhiyun 		case 230: /* thermal low to high */
8039*4882a593Smuzhiyun 			DRM_DEBUG("IH: thermal low to high\n");
8040*4882a593Smuzhiyun 			rdev->pm.dpm.thermal.high_to_low = false;
8041*4882a593Smuzhiyun 			queue_thermal = true;
8042*4882a593Smuzhiyun 			break;
8043*4882a593Smuzhiyun 		case 231: /* thermal high to low */
8044*4882a593Smuzhiyun 			DRM_DEBUG("IH: thermal high to low\n");
8045*4882a593Smuzhiyun 			rdev->pm.dpm.thermal.high_to_low = true;
8046*4882a593Smuzhiyun 			queue_thermal = true;
8047*4882a593Smuzhiyun 			break;
8048*4882a593Smuzhiyun 		case 233: /* GUI IDLE */
8049*4882a593Smuzhiyun 			DRM_DEBUG("IH: GUI idle\n");
8050*4882a593Smuzhiyun 			break;
8051*4882a593Smuzhiyun 		case 241: /* SDMA Privileged inst */
8052*4882a593Smuzhiyun 		case 247: /* SDMA Privileged inst */
8053*4882a593Smuzhiyun 			DRM_ERROR("Illegal instruction in SDMA command stream\n");
8054*4882a593Smuzhiyun 			/* XXX check the bitfield order! */
8055*4882a593Smuzhiyun 			me_id = (ring_id & 0x3) >> 0;
8056*4882a593Smuzhiyun 			queue_id = (ring_id & 0xc) >> 2;
8057*4882a593Smuzhiyun 			switch (me_id) {
8058*4882a593Smuzhiyun 			case 0:
8059*4882a593Smuzhiyun 				switch (queue_id) {
8060*4882a593Smuzhiyun 				case 0:
8061*4882a593Smuzhiyun 					queue_reset = true;
8062*4882a593Smuzhiyun 					break;
8063*4882a593Smuzhiyun 				case 1:
8064*4882a593Smuzhiyun 					/* XXX compute */
8065*4882a593Smuzhiyun 					queue_reset = true;
8066*4882a593Smuzhiyun 					break;
8067*4882a593Smuzhiyun 				case 2:
8068*4882a593Smuzhiyun 					/* XXX compute */
8069*4882a593Smuzhiyun 					queue_reset = true;
8070*4882a593Smuzhiyun 					break;
8071*4882a593Smuzhiyun 				}
8072*4882a593Smuzhiyun 				break;
8073*4882a593Smuzhiyun 			case 1:
8074*4882a593Smuzhiyun 				switch (queue_id) {
8075*4882a593Smuzhiyun 				case 0:
8076*4882a593Smuzhiyun 					queue_reset = true;
8077*4882a593Smuzhiyun 					break;
8078*4882a593Smuzhiyun 				case 1:
8079*4882a593Smuzhiyun 					/* XXX compute */
8080*4882a593Smuzhiyun 					queue_reset = true;
8081*4882a593Smuzhiyun 					break;
8082*4882a593Smuzhiyun 				case 2:
8083*4882a593Smuzhiyun 					/* XXX compute */
8084*4882a593Smuzhiyun 					queue_reset = true;
8085*4882a593Smuzhiyun 					break;
8086*4882a593Smuzhiyun 				}
8087*4882a593Smuzhiyun 				break;
8088*4882a593Smuzhiyun 			}
8089*4882a593Smuzhiyun 			break;
8090*4882a593Smuzhiyun 		default:
8091*4882a593Smuzhiyun 			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
8092*4882a593Smuzhiyun 			break;
8093*4882a593Smuzhiyun 		}
8094*4882a593Smuzhiyun 
8095*4882a593Smuzhiyun 		/* wptr/rptr are in bytes! */
8096*4882a593Smuzhiyun 		rptr += 16;
8097*4882a593Smuzhiyun 		rptr &= rdev->ih.ptr_mask;
8098*4882a593Smuzhiyun 		WREG32(IH_RB_RPTR, rptr);
8099*4882a593Smuzhiyun 	}
8100*4882a593Smuzhiyun 	if (queue_dp)
8101*4882a593Smuzhiyun 		schedule_work(&rdev->dp_work);
8102*4882a593Smuzhiyun 	if (queue_hotplug)
8103*4882a593Smuzhiyun 		schedule_delayed_work(&rdev->hotplug_work, 0);
8104*4882a593Smuzhiyun 	if (queue_reset) {
8105*4882a593Smuzhiyun 		rdev->needs_reset = true;
8106*4882a593Smuzhiyun 		wake_up_all(&rdev->fence_queue);
8107*4882a593Smuzhiyun 	}
8108*4882a593Smuzhiyun 	if (queue_thermal)
8109*4882a593Smuzhiyun 		schedule_work(&rdev->pm.dpm.thermal.work);
8110*4882a593Smuzhiyun 	rdev->ih.rptr = rptr;
8111*4882a593Smuzhiyun 	atomic_set(&rdev->ih.lock, 0);
8112*4882a593Smuzhiyun 
8113*4882a593Smuzhiyun 	/* make sure wptr hasn't changed while processing */
8114*4882a593Smuzhiyun 	wptr = cik_get_ih_wptr(rdev);
8115*4882a593Smuzhiyun 	if (wptr != rptr)
8116*4882a593Smuzhiyun 		goto restart_ih;
8117*4882a593Smuzhiyun 
8118*4882a593Smuzhiyun 	return IRQ_HANDLED;
8119*4882a593Smuzhiyun }
8120*4882a593Smuzhiyun 
8121*4882a593Smuzhiyun /*
8122*4882a593Smuzhiyun  * startup/shutdown callbacks
8123*4882a593Smuzhiyun  */
cik_uvd_init(struct radeon_device * rdev)8124*4882a593Smuzhiyun static void cik_uvd_init(struct radeon_device *rdev)
8125*4882a593Smuzhiyun {
8126*4882a593Smuzhiyun 	int r;
8127*4882a593Smuzhiyun 
8128*4882a593Smuzhiyun 	if (!rdev->has_uvd)
8129*4882a593Smuzhiyun 		return;
8130*4882a593Smuzhiyun 
8131*4882a593Smuzhiyun 	r = radeon_uvd_init(rdev);
8132*4882a593Smuzhiyun 	if (r) {
8133*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
8134*4882a593Smuzhiyun 		/*
8135*4882a593Smuzhiyun 		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
8136*4882a593Smuzhiyun 		 * to early fails cik_uvd_start() and thus nothing happens
8137*4882a593Smuzhiyun 		 * there. So it is pointless to try to go through that code
8138*4882a593Smuzhiyun 		 * hence why we disable uvd here.
8139*4882a593Smuzhiyun 		 */
8140*4882a593Smuzhiyun 		rdev->has_uvd = false;
8141*4882a593Smuzhiyun 		return;
8142*4882a593Smuzhiyun 	}
8143*4882a593Smuzhiyun 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
8144*4882a593Smuzhiyun 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
8145*4882a593Smuzhiyun }
8146*4882a593Smuzhiyun 
cik_uvd_start(struct radeon_device * rdev)8147*4882a593Smuzhiyun static void cik_uvd_start(struct radeon_device *rdev)
8148*4882a593Smuzhiyun {
8149*4882a593Smuzhiyun 	int r;
8150*4882a593Smuzhiyun 
8151*4882a593Smuzhiyun 	if (!rdev->has_uvd)
8152*4882a593Smuzhiyun 		return;
8153*4882a593Smuzhiyun 
8154*4882a593Smuzhiyun 	r = radeon_uvd_resume(rdev);
8155*4882a593Smuzhiyun 	if (r) {
8156*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
8157*4882a593Smuzhiyun 		goto error;
8158*4882a593Smuzhiyun 	}
8159*4882a593Smuzhiyun 	r = uvd_v4_2_resume(rdev);
8160*4882a593Smuzhiyun 	if (r) {
8161*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed UVD 4.2 resume (%d).\n", r);
8162*4882a593Smuzhiyun 		goto error;
8163*4882a593Smuzhiyun 	}
8164*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
8165*4882a593Smuzhiyun 	if (r) {
8166*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
8167*4882a593Smuzhiyun 		goto error;
8168*4882a593Smuzhiyun 	}
8169*4882a593Smuzhiyun 	return;
8170*4882a593Smuzhiyun 
8171*4882a593Smuzhiyun error:
8172*4882a593Smuzhiyun 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
8173*4882a593Smuzhiyun }
8174*4882a593Smuzhiyun 
cik_uvd_resume(struct radeon_device * rdev)8175*4882a593Smuzhiyun static void cik_uvd_resume(struct radeon_device *rdev)
8176*4882a593Smuzhiyun {
8177*4882a593Smuzhiyun 	struct radeon_ring *ring;
8178*4882a593Smuzhiyun 	int r;
8179*4882a593Smuzhiyun 
8180*4882a593Smuzhiyun 	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
8181*4882a593Smuzhiyun 		return;
8182*4882a593Smuzhiyun 
8183*4882a593Smuzhiyun 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
8184*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
8185*4882a593Smuzhiyun 	if (r) {
8186*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
8187*4882a593Smuzhiyun 		return;
8188*4882a593Smuzhiyun 	}
8189*4882a593Smuzhiyun 	r = uvd_v1_0_init(rdev);
8190*4882a593Smuzhiyun 	if (r) {
8191*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
8192*4882a593Smuzhiyun 		return;
8193*4882a593Smuzhiyun 	}
8194*4882a593Smuzhiyun }
8195*4882a593Smuzhiyun 
cik_vce_init(struct radeon_device * rdev)8196*4882a593Smuzhiyun static void cik_vce_init(struct radeon_device *rdev)
8197*4882a593Smuzhiyun {
8198*4882a593Smuzhiyun 	int r;
8199*4882a593Smuzhiyun 
8200*4882a593Smuzhiyun 	if (!rdev->has_vce)
8201*4882a593Smuzhiyun 		return;
8202*4882a593Smuzhiyun 
8203*4882a593Smuzhiyun 	r = radeon_vce_init(rdev);
8204*4882a593Smuzhiyun 	if (r) {
8205*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
8206*4882a593Smuzhiyun 		/*
8207*4882a593Smuzhiyun 		 * At this point rdev->vce.vcpu_bo is NULL which trickles down
8208*4882a593Smuzhiyun 		 * to early fails cik_vce_start() and thus nothing happens
8209*4882a593Smuzhiyun 		 * there. So it is pointless to try to go through that code
8210*4882a593Smuzhiyun 		 * hence why we disable vce here.
8211*4882a593Smuzhiyun 		 */
8212*4882a593Smuzhiyun 		rdev->has_vce = false;
8213*4882a593Smuzhiyun 		return;
8214*4882a593Smuzhiyun 	}
8215*4882a593Smuzhiyun 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
8216*4882a593Smuzhiyun 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
8217*4882a593Smuzhiyun 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
8218*4882a593Smuzhiyun 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
8219*4882a593Smuzhiyun }
8220*4882a593Smuzhiyun 
cik_vce_start(struct radeon_device * rdev)8221*4882a593Smuzhiyun static void cik_vce_start(struct radeon_device *rdev)
8222*4882a593Smuzhiyun {
8223*4882a593Smuzhiyun 	int r;
8224*4882a593Smuzhiyun 
8225*4882a593Smuzhiyun 	if (!rdev->has_vce)
8226*4882a593Smuzhiyun 		return;
8227*4882a593Smuzhiyun 
8228*4882a593Smuzhiyun 	r = radeon_vce_resume(rdev);
8229*4882a593Smuzhiyun 	if (r) {
8230*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
8231*4882a593Smuzhiyun 		goto error;
8232*4882a593Smuzhiyun 	}
8233*4882a593Smuzhiyun 	r = vce_v2_0_resume(rdev);
8234*4882a593Smuzhiyun 	if (r) {
8235*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
8236*4882a593Smuzhiyun 		goto error;
8237*4882a593Smuzhiyun 	}
8238*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
8239*4882a593Smuzhiyun 	if (r) {
8240*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
8241*4882a593Smuzhiyun 		goto error;
8242*4882a593Smuzhiyun 	}
8243*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
8244*4882a593Smuzhiyun 	if (r) {
8245*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
8246*4882a593Smuzhiyun 		goto error;
8247*4882a593Smuzhiyun 	}
8248*4882a593Smuzhiyun 	return;
8249*4882a593Smuzhiyun 
8250*4882a593Smuzhiyun error:
8251*4882a593Smuzhiyun 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
8252*4882a593Smuzhiyun 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
8253*4882a593Smuzhiyun }
8254*4882a593Smuzhiyun 
cik_vce_resume(struct radeon_device * rdev)8255*4882a593Smuzhiyun static void cik_vce_resume(struct radeon_device *rdev)
8256*4882a593Smuzhiyun {
8257*4882a593Smuzhiyun 	struct radeon_ring *ring;
8258*4882a593Smuzhiyun 	int r;
8259*4882a593Smuzhiyun 
8260*4882a593Smuzhiyun 	if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
8261*4882a593Smuzhiyun 		return;
8262*4882a593Smuzhiyun 
8263*4882a593Smuzhiyun 	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
8264*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
8265*4882a593Smuzhiyun 	if (r) {
8266*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
8267*4882a593Smuzhiyun 		return;
8268*4882a593Smuzhiyun 	}
8269*4882a593Smuzhiyun 	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
8270*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
8271*4882a593Smuzhiyun 	if (r) {
8272*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
8273*4882a593Smuzhiyun 		return;
8274*4882a593Smuzhiyun 	}
8275*4882a593Smuzhiyun 	r = vce_v1_0_init(rdev);
8276*4882a593Smuzhiyun 	if (r) {
8277*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
8278*4882a593Smuzhiyun 		return;
8279*4882a593Smuzhiyun 	}
8280*4882a593Smuzhiyun }
8281*4882a593Smuzhiyun 
8282*4882a593Smuzhiyun /**
8283*4882a593Smuzhiyun  * cik_startup - program the asic to a functional state
8284*4882a593Smuzhiyun  *
8285*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8286*4882a593Smuzhiyun  *
8287*4882a593Smuzhiyun  * Programs the asic to a functional state (CIK).
8288*4882a593Smuzhiyun  * Called by cik_init() and cik_resume().
8289*4882a593Smuzhiyun  * Returns 0 for success, error for failure.
8290*4882a593Smuzhiyun  */
cik_startup(struct radeon_device * rdev)8291*4882a593Smuzhiyun static int cik_startup(struct radeon_device *rdev)
8292*4882a593Smuzhiyun {
8293*4882a593Smuzhiyun 	struct radeon_ring *ring;
8294*4882a593Smuzhiyun 	u32 nop;
8295*4882a593Smuzhiyun 	int r;
8296*4882a593Smuzhiyun 
8297*4882a593Smuzhiyun 	/* enable pcie gen2/3 link */
8298*4882a593Smuzhiyun 	cik_pcie_gen3_enable(rdev);
8299*4882a593Smuzhiyun 	/* enable aspm */
8300*4882a593Smuzhiyun 	cik_program_aspm(rdev);
8301*4882a593Smuzhiyun 
8302*4882a593Smuzhiyun 	/* scratch needs to be initialized before MC */
8303*4882a593Smuzhiyun 	r = r600_vram_scratch_init(rdev);
8304*4882a593Smuzhiyun 	if (r)
8305*4882a593Smuzhiyun 		return r;
8306*4882a593Smuzhiyun 
8307*4882a593Smuzhiyun 	cik_mc_program(rdev);
8308*4882a593Smuzhiyun 
8309*4882a593Smuzhiyun 	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
8310*4882a593Smuzhiyun 		r = ci_mc_load_microcode(rdev);
8311*4882a593Smuzhiyun 		if (r) {
8312*4882a593Smuzhiyun 			DRM_ERROR("Failed to load MC firmware!\n");
8313*4882a593Smuzhiyun 			return r;
8314*4882a593Smuzhiyun 		}
8315*4882a593Smuzhiyun 	}
8316*4882a593Smuzhiyun 
8317*4882a593Smuzhiyun 	r = cik_pcie_gart_enable(rdev);
8318*4882a593Smuzhiyun 	if (r)
8319*4882a593Smuzhiyun 		return r;
8320*4882a593Smuzhiyun 	cik_gpu_init(rdev);
8321*4882a593Smuzhiyun 
8322*4882a593Smuzhiyun 	/* allocate rlc buffers */
8323*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP) {
8324*4882a593Smuzhiyun 		if (rdev->family == CHIP_KAVERI) {
8325*4882a593Smuzhiyun 			rdev->rlc.reg_list = spectre_rlc_save_restore_register_list;
8326*4882a593Smuzhiyun 			rdev->rlc.reg_list_size =
8327*4882a593Smuzhiyun 				(u32)ARRAY_SIZE(spectre_rlc_save_restore_register_list);
8328*4882a593Smuzhiyun 		} else {
8329*4882a593Smuzhiyun 			rdev->rlc.reg_list = kalindi_rlc_save_restore_register_list;
8330*4882a593Smuzhiyun 			rdev->rlc.reg_list_size =
8331*4882a593Smuzhiyun 				(u32)ARRAY_SIZE(kalindi_rlc_save_restore_register_list);
8332*4882a593Smuzhiyun 		}
8333*4882a593Smuzhiyun 	}
8334*4882a593Smuzhiyun 	rdev->rlc.cs_data = ci_cs_data;
8335*4882a593Smuzhiyun 	rdev->rlc.cp_table_size = ALIGN(CP_ME_TABLE_SIZE * 5 * 4, 2048); /* CP JT */
8336*4882a593Smuzhiyun 	rdev->rlc.cp_table_size += 64 * 1024; /* GDS */
8337*4882a593Smuzhiyun 	r = sumo_rlc_init(rdev);
8338*4882a593Smuzhiyun 	if (r) {
8339*4882a593Smuzhiyun 		DRM_ERROR("Failed to init rlc BOs!\n");
8340*4882a593Smuzhiyun 		return r;
8341*4882a593Smuzhiyun 	}
8342*4882a593Smuzhiyun 
8343*4882a593Smuzhiyun 	/* allocate wb buffer */
8344*4882a593Smuzhiyun 	r = radeon_wb_init(rdev);
8345*4882a593Smuzhiyun 	if (r)
8346*4882a593Smuzhiyun 		return r;
8347*4882a593Smuzhiyun 
8348*4882a593Smuzhiyun 	/* allocate mec buffers */
8349*4882a593Smuzhiyun 	r = cik_mec_init(rdev);
8350*4882a593Smuzhiyun 	if (r) {
8351*4882a593Smuzhiyun 		DRM_ERROR("Failed to init MEC BOs!\n");
8352*4882a593Smuzhiyun 		return r;
8353*4882a593Smuzhiyun 	}
8354*4882a593Smuzhiyun 
8355*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
8356*4882a593Smuzhiyun 	if (r) {
8357*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
8358*4882a593Smuzhiyun 		return r;
8359*4882a593Smuzhiyun 	}
8360*4882a593Smuzhiyun 
8361*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
8362*4882a593Smuzhiyun 	if (r) {
8363*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
8364*4882a593Smuzhiyun 		return r;
8365*4882a593Smuzhiyun 	}
8366*4882a593Smuzhiyun 
8367*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
8368*4882a593Smuzhiyun 	if (r) {
8369*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
8370*4882a593Smuzhiyun 		return r;
8371*4882a593Smuzhiyun 	}
8372*4882a593Smuzhiyun 
8373*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
8374*4882a593Smuzhiyun 	if (r) {
8375*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
8376*4882a593Smuzhiyun 		return r;
8377*4882a593Smuzhiyun 	}
8378*4882a593Smuzhiyun 
8379*4882a593Smuzhiyun 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
8380*4882a593Smuzhiyun 	if (r) {
8381*4882a593Smuzhiyun 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
8382*4882a593Smuzhiyun 		return r;
8383*4882a593Smuzhiyun 	}
8384*4882a593Smuzhiyun 
8385*4882a593Smuzhiyun 	cik_uvd_start(rdev);
8386*4882a593Smuzhiyun 	cik_vce_start(rdev);
8387*4882a593Smuzhiyun 
8388*4882a593Smuzhiyun 	/* Enable IRQ */
8389*4882a593Smuzhiyun 	if (!rdev->irq.installed) {
8390*4882a593Smuzhiyun 		r = radeon_irq_kms_init(rdev);
8391*4882a593Smuzhiyun 		if (r)
8392*4882a593Smuzhiyun 			return r;
8393*4882a593Smuzhiyun 	}
8394*4882a593Smuzhiyun 
8395*4882a593Smuzhiyun 	r = cik_irq_init(rdev);
8396*4882a593Smuzhiyun 	if (r) {
8397*4882a593Smuzhiyun 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
8398*4882a593Smuzhiyun 		radeon_irq_kms_fini(rdev);
8399*4882a593Smuzhiyun 		return r;
8400*4882a593Smuzhiyun 	}
8401*4882a593Smuzhiyun 	cik_irq_set(rdev);
8402*4882a593Smuzhiyun 
8403*4882a593Smuzhiyun 	if (rdev->family == CHIP_HAWAII) {
8404*4882a593Smuzhiyun 		if (rdev->new_fw)
8405*4882a593Smuzhiyun 			nop = PACKET3(PACKET3_NOP, 0x3FFF);
8406*4882a593Smuzhiyun 		else
8407*4882a593Smuzhiyun 			nop = RADEON_CP_PACKET2;
8408*4882a593Smuzhiyun 	} else {
8409*4882a593Smuzhiyun 		nop = PACKET3(PACKET3_NOP, 0x3FFF);
8410*4882a593Smuzhiyun 	}
8411*4882a593Smuzhiyun 
8412*4882a593Smuzhiyun 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
8413*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
8414*4882a593Smuzhiyun 			     nop);
8415*4882a593Smuzhiyun 	if (r)
8416*4882a593Smuzhiyun 		return r;
8417*4882a593Smuzhiyun 
8418*4882a593Smuzhiyun 	/* set up the compute queues */
8419*4882a593Smuzhiyun 	/* type-2 packets are deprecated on MEC, use type-3 instead */
8420*4882a593Smuzhiyun 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
8421*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
8422*4882a593Smuzhiyun 			     nop);
8423*4882a593Smuzhiyun 	if (r)
8424*4882a593Smuzhiyun 		return r;
8425*4882a593Smuzhiyun 	ring->me = 1; /* first MEC */
8426*4882a593Smuzhiyun 	ring->pipe = 0; /* first pipe */
8427*4882a593Smuzhiyun 	ring->queue = 0; /* first queue */
8428*4882a593Smuzhiyun 	ring->wptr_offs = CIK_WB_CP1_WPTR_OFFSET;
8429*4882a593Smuzhiyun 
8430*4882a593Smuzhiyun 	/* type-2 packets are deprecated on MEC, use type-3 instead */
8431*4882a593Smuzhiyun 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
8432*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
8433*4882a593Smuzhiyun 			     nop);
8434*4882a593Smuzhiyun 	if (r)
8435*4882a593Smuzhiyun 		return r;
8436*4882a593Smuzhiyun 	/* dGPU only have 1 MEC */
8437*4882a593Smuzhiyun 	ring->me = 1; /* first MEC */
8438*4882a593Smuzhiyun 	ring->pipe = 0; /* first pipe */
8439*4882a593Smuzhiyun 	ring->queue = 1; /* second queue */
8440*4882a593Smuzhiyun 	ring->wptr_offs = CIK_WB_CP2_WPTR_OFFSET;
8441*4882a593Smuzhiyun 
8442*4882a593Smuzhiyun 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
8443*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
8444*4882a593Smuzhiyun 			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
8445*4882a593Smuzhiyun 	if (r)
8446*4882a593Smuzhiyun 		return r;
8447*4882a593Smuzhiyun 
8448*4882a593Smuzhiyun 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
8449*4882a593Smuzhiyun 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
8450*4882a593Smuzhiyun 			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
8451*4882a593Smuzhiyun 	if (r)
8452*4882a593Smuzhiyun 		return r;
8453*4882a593Smuzhiyun 
8454*4882a593Smuzhiyun 	r = cik_cp_resume(rdev);
8455*4882a593Smuzhiyun 	if (r)
8456*4882a593Smuzhiyun 		return r;
8457*4882a593Smuzhiyun 
8458*4882a593Smuzhiyun 	r = cik_sdma_resume(rdev);
8459*4882a593Smuzhiyun 	if (r)
8460*4882a593Smuzhiyun 		return r;
8461*4882a593Smuzhiyun 
8462*4882a593Smuzhiyun 	cik_uvd_resume(rdev);
8463*4882a593Smuzhiyun 	cik_vce_resume(rdev);
8464*4882a593Smuzhiyun 
8465*4882a593Smuzhiyun 	r = radeon_ib_pool_init(rdev);
8466*4882a593Smuzhiyun 	if (r) {
8467*4882a593Smuzhiyun 		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
8468*4882a593Smuzhiyun 		return r;
8469*4882a593Smuzhiyun 	}
8470*4882a593Smuzhiyun 
8471*4882a593Smuzhiyun 	r = radeon_vm_manager_init(rdev);
8472*4882a593Smuzhiyun 	if (r) {
8473*4882a593Smuzhiyun 		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
8474*4882a593Smuzhiyun 		return r;
8475*4882a593Smuzhiyun 	}
8476*4882a593Smuzhiyun 
8477*4882a593Smuzhiyun 	r = radeon_audio_init(rdev);
8478*4882a593Smuzhiyun 	if (r)
8479*4882a593Smuzhiyun 		return r;
8480*4882a593Smuzhiyun 
8481*4882a593Smuzhiyun 	return 0;
8482*4882a593Smuzhiyun }
8483*4882a593Smuzhiyun 
8484*4882a593Smuzhiyun /**
8485*4882a593Smuzhiyun  * cik_resume - resume the asic to a functional state
8486*4882a593Smuzhiyun  *
8487*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8488*4882a593Smuzhiyun  *
8489*4882a593Smuzhiyun  * Programs the asic to a functional state (CIK).
8490*4882a593Smuzhiyun  * Called at resume.
8491*4882a593Smuzhiyun  * Returns 0 for success, error for failure.
8492*4882a593Smuzhiyun  */
cik_resume(struct radeon_device * rdev)8493*4882a593Smuzhiyun int cik_resume(struct radeon_device *rdev)
8494*4882a593Smuzhiyun {
8495*4882a593Smuzhiyun 	int r;
8496*4882a593Smuzhiyun 
8497*4882a593Smuzhiyun 	/* post card */
8498*4882a593Smuzhiyun 	atom_asic_init(rdev->mode_info.atom_context);
8499*4882a593Smuzhiyun 
8500*4882a593Smuzhiyun 	/* init golden registers */
8501*4882a593Smuzhiyun 	cik_init_golden_registers(rdev);
8502*4882a593Smuzhiyun 
8503*4882a593Smuzhiyun 	if (rdev->pm.pm_method == PM_METHOD_DPM)
8504*4882a593Smuzhiyun 		radeon_pm_resume(rdev);
8505*4882a593Smuzhiyun 
8506*4882a593Smuzhiyun 	rdev->accel_working = true;
8507*4882a593Smuzhiyun 	r = cik_startup(rdev);
8508*4882a593Smuzhiyun 	if (r) {
8509*4882a593Smuzhiyun 		DRM_ERROR("cik startup failed on resume\n");
8510*4882a593Smuzhiyun 		rdev->accel_working = false;
8511*4882a593Smuzhiyun 		return r;
8512*4882a593Smuzhiyun 	}
8513*4882a593Smuzhiyun 
8514*4882a593Smuzhiyun 	return r;
8515*4882a593Smuzhiyun 
8516*4882a593Smuzhiyun }
8517*4882a593Smuzhiyun 
8518*4882a593Smuzhiyun /**
8519*4882a593Smuzhiyun  * cik_suspend - suspend the asic
8520*4882a593Smuzhiyun  *
8521*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8522*4882a593Smuzhiyun  *
8523*4882a593Smuzhiyun  * Bring the chip into a state suitable for suspend (CIK).
8524*4882a593Smuzhiyun  * Called at suspend.
8525*4882a593Smuzhiyun  * Returns 0 for success.
8526*4882a593Smuzhiyun  */
cik_suspend(struct radeon_device * rdev)8527*4882a593Smuzhiyun int cik_suspend(struct radeon_device *rdev)
8528*4882a593Smuzhiyun {
8529*4882a593Smuzhiyun 	radeon_pm_suspend(rdev);
8530*4882a593Smuzhiyun 	radeon_audio_fini(rdev);
8531*4882a593Smuzhiyun 	radeon_vm_manager_fini(rdev);
8532*4882a593Smuzhiyun 	cik_cp_enable(rdev, false);
8533*4882a593Smuzhiyun 	cik_sdma_enable(rdev, false);
8534*4882a593Smuzhiyun 	if (rdev->has_uvd) {
8535*4882a593Smuzhiyun 		uvd_v1_0_fini(rdev);
8536*4882a593Smuzhiyun 		radeon_uvd_suspend(rdev);
8537*4882a593Smuzhiyun 	}
8538*4882a593Smuzhiyun 	if (rdev->has_vce)
8539*4882a593Smuzhiyun 		radeon_vce_suspend(rdev);
8540*4882a593Smuzhiyun 	cik_fini_pg(rdev);
8541*4882a593Smuzhiyun 	cik_fini_cg(rdev);
8542*4882a593Smuzhiyun 	cik_irq_suspend(rdev);
8543*4882a593Smuzhiyun 	radeon_wb_disable(rdev);
8544*4882a593Smuzhiyun 	cik_pcie_gart_disable(rdev);
8545*4882a593Smuzhiyun 	return 0;
8546*4882a593Smuzhiyun }
8547*4882a593Smuzhiyun 
8548*4882a593Smuzhiyun /* Plan is to move initialization in that function and use
8549*4882a593Smuzhiyun  * helper function so that radeon_device_init pretty much
8550*4882a593Smuzhiyun  * do nothing more than calling asic specific function. This
8551*4882a593Smuzhiyun  * should also allow to remove a bunch of callback function
8552*4882a593Smuzhiyun  * like vram_info.
8553*4882a593Smuzhiyun  */
8554*4882a593Smuzhiyun /**
8555*4882a593Smuzhiyun  * cik_init - asic specific driver and hw init
8556*4882a593Smuzhiyun  *
8557*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8558*4882a593Smuzhiyun  *
8559*4882a593Smuzhiyun  * Setup asic specific driver variables and program the hw
8560*4882a593Smuzhiyun  * to a functional state (CIK).
8561*4882a593Smuzhiyun  * Called at driver startup.
8562*4882a593Smuzhiyun  * Returns 0 for success, errors for failure.
8563*4882a593Smuzhiyun  */
cik_init(struct radeon_device * rdev)8564*4882a593Smuzhiyun int cik_init(struct radeon_device *rdev)
8565*4882a593Smuzhiyun {
8566*4882a593Smuzhiyun 	struct radeon_ring *ring;
8567*4882a593Smuzhiyun 	int r;
8568*4882a593Smuzhiyun 
8569*4882a593Smuzhiyun 	/* Read BIOS */
8570*4882a593Smuzhiyun 	if (!radeon_get_bios(rdev)) {
8571*4882a593Smuzhiyun 		if (ASIC_IS_AVIVO(rdev))
8572*4882a593Smuzhiyun 			return -EINVAL;
8573*4882a593Smuzhiyun 	}
8574*4882a593Smuzhiyun 	/* Must be an ATOMBIOS */
8575*4882a593Smuzhiyun 	if (!rdev->is_atom_bios) {
8576*4882a593Smuzhiyun 		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
8577*4882a593Smuzhiyun 		return -EINVAL;
8578*4882a593Smuzhiyun 	}
8579*4882a593Smuzhiyun 	r = radeon_atombios_init(rdev);
8580*4882a593Smuzhiyun 	if (r)
8581*4882a593Smuzhiyun 		return r;
8582*4882a593Smuzhiyun 
8583*4882a593Smuzhiyun 	/* Post card if necessary */
8584*4882a593Smuzhiyun 	if (!radeon_card_posted(rdev)) {
8585*4882a593Smuzhiyun 		if (!rdev->bios) {
8586*4882a593Smuzhiyun 			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
8587*4882a593Smuzhiyun 			return -EINVAL;
8588*4882a593Smuzhiyun 		}
8589*4882a593Smuzhiyun 		DRM_INFO("GPU not posted. posting now...\n");
8590*4882a593Smuzhiyun 		atom_asic_init(rdev->mode_info.atom_context);
8591*4882a593Smuzhiyun 	}
8592*4882a593Smuzhiyun 	/* init golden registers */
8593*4882a593Smuzhiyun 	cik_init_golden_registers(rdev);
8594*4882a593Smuzhiyun 	/* Initialize scratch registers */
8595*4882a593Smuzhiyun 	cik_scratch_init(rdev);
8596*4882a593Smuzhiyun 	/* Initialize surface registers */
8597*4882a593Smuzhiyun 	radeon_surface_init(rdev);
8598*4882a593Smuzhiyun 	/* Initialize clocks */
8599*4882a593Smuzhiyun 	radeon_get_clock_info(rdev->ddev);
8600*4882a593Smuzhiyun 
8601*4882a593Smuzhiyun 	/* Fence driver */
8602*4882a593Smuzhiyun 	r = radeon_fence_driver_init(rdev);
8603*4882a593Smuzhiyun 	if (r)
8604*4882a593Smuzhiyun 		return r;
8605*4882a593Smuzhiyun 
8606*4882a593Smuzhiyun 	/* initialize memory controller */
8607*4882a593Smuzhiyun 	r = cik_mc_init(rdev);
8608*4882a593Smuzhiyun 	if (r)
8609*4882a593Smuzhiyun 		return r;
8610*4882a593Smuzhiyun 	/* Memory manager */
8611*4882a593Smuzhiyun 	r = radeon_bo_init(rdev);
8612*4882a593Smuzhiyun 	if (r)
8613*4882a593Smuzhiyun 		return r;
8614*4882a593Smuzhiyun 
8615*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP) {
8616*4882a593Smuzhiyun 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
8617*4882a593Smuzhiyun 		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
8618*4882a593Smuzhiyun 			r = cik_init_microcode(rdev);
8619*4882a593Smuzhiyun 			if (r) {
8620*4882a593Smuzhiyun 				DRM_ERROR("Failed to load firmware!\n");
8621*4882a593Smuzhiyun 				return r;
8622*4882a593Smuzhiyun 			}
8623*4882a593Smuzhiyun 		}
8624*4882a593Smuzhiyun 	} else {
8625*4882a593Smuzhiyun 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
8626*4882a593Smuzhiyun 		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw ||
8627*4882a593Smuzhiyun 		    !rdev->mc_fw) {
8628*4882a593Smuzhiyun 			r = cik_init_microcode(rdev);
8629*4882a593Smuzhiyun 			if (r) {
8630*4882a593Smuzhiyun 				DRM_ERROR("Failed to load firmware!\n");
8631*4882a593Smuzhiyun 				return r;
8632*4882a593Smuzhiyun 			}
8633*4882a593Smuzhiyun 		}
8634*4882a593Smuzhiyun 	}
8635*4882a593Smuzhiyun 
8636*4882a593Smuzhiyun 	/* Initialize power management */
8637*4882a593Smuzhiyun 	radeon_pm_init(rdev);
8638*4882a593Smuzhiyun 
8639*4882a593Smuzhiyun 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
8640*4882a593Smuzhiyun 	ring->ring_obj = NULL;
8641*4882a593Smuzhiyun 	r600_ring_init(rdev, ring, 1024 * 1024);
8642*4882a593Smuzhiyun 
8643*4882a593Smuzhiyun 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
8644*4882a593Smuzhiyun 	ring->ring_obj = NULL;
8645*4882a593Smuzhiyun 	r600_ring_init(rdev, ring, 1024 * 1024);
8646*4882a593Smuzhiyun 	r = radeon_doorbell_get(rdev, &ring->doorbell_index);
8647*4882a593Smuzhiyun 	if (r)
8648*4882a593Smuzhiyun 		return r;
8649*4882a593Smuzhiyun 
8650*4882a593Smuzhiyun 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
8651*4882a593Smuzhiyun 	ring->ring_obj = NULL;
8652*4882a593Smuzhiyun 	r600_ring_init(rdev, ring, 1024 * 1024);
8653*4882a593Smuzhiyun 	r = radeon_doorbell_get(rdev, &ring->doorbell_index);
8654*4882a593Smuzhiyun 	if (r)
8655*4882a593Smuzhiyun 		return r;
8656*4882a593Smuzhiyun 
8657*4882a593Smuzhiyun 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
8658*4882a593Smuzhiyun 	ring->ring_obj = NULL;
8659*4882a593Smuzhiyun 	r600_ring_init(rdev, ring, 256 * 1024);
8660*4882a593Smuzhiyun 
8661*4882a593Smuzhiyun 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
8662*4882a593Smuzhiyun 	ring->ring_obj = NULL;
8663*4882a593Smuzhiyun 	r600_ring_init(rdev, ring, 256 * 1024);
8664*4882a593Smuzhiyun 
8665*4882a593Smuzhiyun 	cik_uvd_init(rdev);
8666*4882a593Smuzhiyun 	cik_vce_init(rdev);
8667*4882a593Smuzhiyun 
8668*4882a593Smuzhiyun 	rdev->ih.ring_obj = NULL;
8669*4882a593Smuzhiyun 	r600_ih_ring_init(rdev, 64 * 1024);
8670*4882a593Smuzhiyun 
8671*4882a593Smuzhiyun 	r = r600_pcie_gart_init(rdev);
8672*4882a593Smuzhiyun 	if (r)
8673*4882a593Smuzhiyun 		return r;
8674*4882a593Smuzhiyun 
8675*4882a593Smuzhiyun 	rdev->accel_working = true;
8676*4882a593Smuzhiyun 	r = cik_startup(rdev);
8677*4882a593Smuzhiyun 	if (r) {
8678*4882a593Smuzhiyun 		dev_err(rdev->dev, "disabling GPU acceleration\n");
8679*4882a593Smuzhiyun 		cik_cp_fini(rdev);
8680*4882a593Smuzhiyun 		cik_sdma_fini(rdev);
8681*4882a593Smuzhiyun 		cik_irq_fini(rdev);
8682*4882a593Smuzhiyun 		sumo_rlc_fini(rdev);
8683*4882a593Smuzhiyun 		cik_mec_fini(rdev);
8684*4882a593Smuzhiyun 		radeon_wb_fini(rdev);
8685*4882a593Smuzhiyun 		radeon_ib_pool_fini(rdev);
8686*4882a593Smuzhiyun 		radeon_vm_manager_fini(rdev);
8687*4882a593Smuzhiyun 		radeon_irq_kms_fini(rdev);
8688*4882a593Smuzhiyun 		cik_pcie_gart_fini(rdev);
8689*4882a593Smuzhiyun 		rdev->accel_working = false;
8690*4882a593Smuzhiyun 	}
8691*4882a593Smuzhiyun 
8692*4882a593Smuzhiyun 	/* Don't start up if the MC ucode is missing.
8693*4882a593Smuzhiyun 	 * The default clocks and voltages before the MC ucode
8694*4882a593Smuzhiyun 	 * is loaded are not suffient for advanced operations.
8695*4882a593Smuzhiyun 	 */
8696*4882a593Smuzhiyun 	if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
8697*4882a593Smuzhiyun 		DRM_ERROR("radeon: MC ucode required for NI+.\n");
8698*4882a593Smuzhiyun 		return -EINVAL;
8699*4882a593Smuzhiyun 	}
8700*4882a593Smuzhiyun 
8701*4882a593Smuzhiyun 	return 0;
8702*4882a593Smuzhiyun }
8703*4882a593Smuzhiyun 
8704*4882a593Smuzhiyun /**
8705*4882a593Smuzhiyun  * cik_fini - asic specific driver and hw fini
8706*4882a593Smuzhiyun  *
8707*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8708*4882a593Smuzhiyun  *
8709*4882a593Smuzhiyun  * Tear down the asic specific driver variables and program the hw
8710*4882a593Smuzhiyun  * to an idle state (CIK).
8711*4882a593Smuzhiyun  * Called at driver unload.
8712*4882a593Smuzhiyun  */
cik_fini(struct radeon_device * rdev)8713*4882a593Smuzhiyun void cik_fini(struct radeon_device *rdev)
8714*4882a593Smuzhiyun {
8715*4882a593Smuzhiyun 	radeon_pm_fini(rdev);
8716*4882a593Smuzhiyun 	cik_cp_fini(rdev);
8717*4882a593Smuzhiyun 	cik_sdma_fini(rdev);
8718*4882a593Smuzhiyun 	cik_fini_pg(rdev);
8719*4882a593Smuzhiyun 	cik_fini_cg(rdev);
8720*4882a593Smuzhiyun 	cik_irq_fini(rdev);
8721*4882a593Smuzhiyun 	sumo_rlc_fini(rdev);
8722*4882a593Smuzhiyun 	cik_mec_fini(rdev);
8723*4882a593Smuzhiyun 	radeon_wb_fini(rdev);
8724*4882a593Smuzhiyun 	radeon_vm_manager_fini(rdev);
8725*4882a593Smuzhiyun 	radeon_ib_pool_fini(rdev);
8726*4882a593Smuzhiyun 	radeon_irq_kms_fini(rdev);
8727*4882a593Smuzhiyun 	uvd_v1_0_fini(rdev);
8728*4882a593Smuzhiyun 	radeon_uvd_fini(rdev);
8729*4882a593Smuzhiyun 	radeon_vce_fini(rdev);
8730*4882a593Smuzhiyun 	cik_pcie_gart_fini(rdev);
8731*4882a593Smuzhiyun 	r600_vram_scratch_fini(rdev);
8732*4882a593Smuzhiyun 	radeon_gem_fini(rdev);
8733*4882a593Smuzhiyun 	radeon_fence_driver_fini(rdev);
8734*4882a593Smuzhiyun 	radeon_bo_fini(rdev);
8735*4882a593Smuzhiyun 	radeon_atombios_fini(rdev);
8736*4882a593Smuzhiyun 	kfree(rdev->bios);
8737*4882a593Smuzhiyun 	rdev->bios = NULL;
8738*4882a593Smuzhiyun }
8739*4882a593Smuzhiyun 
dce8_program_fmt(struct drm_encoder * encoder)8740*4882a593Smuzhiyun void dce8_program_fmt(struct drm_encoder *encoder)
8741*4882a593Smuzhiyun {
8742*4882a593Smuzhiyun 	struct drm_device *dev = encoder->dev;
8743*4882a593Smuzhiyun 	struct radeon_device *rdev = dev->dev_private;
8744*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
8745*4882a593Smuzhiyun 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
8746*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
8747*4882a593Smuzhiyun 	int bpc = 0;
8748*4882a593Smuzhiyun 	u32 tmp = 0;
8749*4882a593Smuzhiyun 	enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
8750*4882a593Smuzhiyun 
8751*4882a593Smuzhiyun 	if (connector) {
8752*4882a593Smuzhiyun 		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
8753*4882a593Smuzhiyun 		bpc = radeon_get_monitor_bpc(connector);
8754*4882a593Smuzhiyun 		dither = radeon_connector->dither;
8755*4882a593Smuzhiyun 	}
8756*4882a593Smuzhiyun 
8757*4882a593Smuzhiyun 	/* LVDS/eDP FMT is set up by atom */
8758*4882a593Smuzhiyun 	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
8759*4882a593Smuzhiyun 		return;
8760*4882a593Smuzhiyun 
8761*4882a593Smuzhiyun 	/* not needed for analog */
8762*4882a593Smuzhiyun 	if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
8763*4882a593Smuzhiyun 	    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
8764*4882a593Smuzhiyun 		return;
8765*4882a593Smuzhiyun 
8766*4882a593Smuzhiyun 	if (bpc == 0)
8767*4882a593Smuzhiyun 		return;
8768*4882a593Smuzhiyun 
8769*4882a593Smuzhiyun 	switch (bpc) {
8770*4882a593Smuzhiyun 	case 6:
8771*4882a593Smuzhiyun 		if (dither == RADEON_FMT_DITHER_ENABLE)
8772*4882a593Smuzhiyun 			/* XXX sort out optimal dither settings */
8773*4882a593Smuzhiyun 			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
8774*4882a593Smuzhiyun 				FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(0));
8775*4882a593Smuzhiyun 		else
8776*4882a593Smuzhiyun 			tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(0));
8777*4882a593Smuzhiyun 		break;
8778*4882a593Smuzhiyun 	case 8:
8779*4882a593Smuzhiyun 		if (dither == RADEON_FMT_DITHER_ENABLE)
8780*4882a593Smuzhiyun 			/* XXX sort out optimal dither settings */
8781*4882a593Smuzhiyun 			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
8782*4882a593Smuzhiyun 				FMT_RGB_RANDOM_ENABLE |
8783*4882a593Smuzhiyun 				FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(1));
8784*4882a593Smuzhiyun 		else
8785*4882a593Smuzhiyun 			tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(1));
8786*4882a593Smuzhiyun 		break;
8787*4882a593Smuzhiyun 	case 10:
8788*4882a593Smuzhiyun 		if (dither == RADEON_FMT_DITHER_ENABLE)
8789*4882a593Smuzhiyun 			/* XXX sort out optimal dither settings */
8790*4882a593Smuzhiyun 			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
8791*4882a593Smuzhiyun 				FMT_RGB_RANDOM_ENABLE |
8792*4882a593Smuzhiyun 				FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(2));
8793*4882a593Smuzhiyun 		else
8794*4882a593Smuzhiyun 			tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(2));
8795*4882a593Smuzhiyun 		break;
8796*4882a593Smuzhiyun 	default:
8797*4882a593Smuzhiyun 		/* not needed */
8798*4882a593Smuzhiyun 		break;
8799*4882a593Smuzhiyun 	}
8800*4882a593Smuzhiyun 
8801*4882a593Smuzhiyun 	WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
8802*4882a593Smuzhiyun }
8803*4882a593Smuzhiyun 
8804*4882a593Smuzhiyun /* display watermark setup */
8805*4882a593Smuzhiyun /**
8806*4882a593Smuzhiyun  * dce8_line_buffer_adjust - Set up the line buffer
8807*4882a593Smuzhiyun  *
8808*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8809*4882a593Smuzhiyun  * @radeon_crtc: the selected display controller
8810*4882a593Smuzhiyun  * @mode: the current display mode on the selected display
8811*4882a593Smuzhiyun  * controller
8812*4882a593Smuzhiyun  *
8813*4882a593Smuzhiyun  * Setup up the line buffer allocation for
8814*4882a593Smuzhiyun  * the selected display controller (CIK).
8815*4882a593Smuzhiyun  * Returns the line buffer size in pixels.
8816*4882a593Smuzhiyun  */
dce8_line_buffer_adjust(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,struct drm_display_mode * mode)8817*4882a593Smuzhiyun static u32 dce8_line_buffer_adjust(struct radeon_device *rdev,
8818*4882a593Smuzhiyun 				   struct radeon_crtc *radeon_crtc,
8819*4882a593Smuzhiyun 				   struct drm_display_mode *mode)
8820*4882a593Smuzhiyun {
8821*4882a593Smuzhiyun 	u32 tmp, buffer_alloc, i;
8822*4882a593Smuzhiyun 	u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
8823*4882a593Smuzhiyun 	/*
8824*4882a593Smuzhiyun 	 * Line Buffer Setup
8825*4882a593Smuzhiyun 	 * There are 6 line buffers, one for each display controllers.
8826*4882a593Smuzhiyun 	 * There are 3 partitions per LB. Select the number of partitions
8827*4882a593Smuzhiyun 	 * to enable based on the display width.  For display widths larger
8828*4882a593Smuzhiyun 	 * than 4096, you need use to use 2 display controllers and combine
8829*4882a593Smuzhiyun 	 * them using the stereo blender.
8830*4882a593Smuzhiyun 	 */
8831*4882a593Smuzhiyun 	if (radeon_crtc->base.enabled && mode) {
8832*4882a593Smuzhiyun 		if (mode->crtc_hdisplay < 1920) {
8833*4882a593Smuzhiyun 			tmp = 1;
8834*4882a593Smuzhiyun 			buffer_alloc = 2;
8835*4882a593Smuzhiyun 		} else if (mode->crtc_hdisplay < 2560) {
8836*4882a593Smuzhiyun 			tmp = 2;
8837*4882a593Smuzhiyun 			buffer_alloc = 2;
8838*4882a593Smuzhiyun 		} else if (mode->crtc_hdisplay < 4096) {
8839*4882a593Smuzhiyun 			tmp = 0;
8840*4882a593Smuzhiyun 			buffer_alloc = (rdev->flags & RADEON_IS_IGP) ? 2 : 4;
8841*4882a593Smuzhiyun 		} else {
8842*4882a593Smuzhiyun 			DRM_DEBUG_KMS("Mode too big for LB!\n");
8843*4882a593Smuzhiyun 			tmp = 0;
8844*4882a593Smuzhiyun 			buffer_alloc = (rdev->flags & RADEON_IS_IGP) ? 2 : 4;
8845*4882a593Smuzhiyun 		}
8846*4882a593Smuzhiyun 	} else {
8847*4882a593Smuzhiyun 		tmp = 1;
8848*4882a593Smuzhiyun 		buffer_alloc = 0;
8849*4882a593Smuzhiyun 	}
8850*4882a593Smuzhiyun 
8851*4882a593Smuzhiyun 	WREG32(LB_MEMORY_CTRL + radeon_crtc->crtc_offset,
8852*4882a593Smuzhiyun 	       LB_MEMORY_CONFIG(tmp) | LB_MEMORY_SIZE(0x6B0));
8853*4882a593Smuzhiyun 
8854*4882a593Smuzhiyun 	WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
8855*4882a593Smuzhiyun 	       DMIF_BUFFERS_ALLOCATED(buffer_alloc));
8856*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
8857*4882a593Smuzhiyun 		if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
8858*4882a593Smuzhiyun 		    DMIF_BUFFERS_ALLOCATED_COMPLETED)
8859*4882a593Smuzhiyun 			break;
8860*4882a593Smuzhiyun 		udelay(1);
8861*4882a593Smuzhiyun 	}
8862*4882a593Smuzhiyun 
8863*4882a593Smuzhiyun 	if (radeon_crtc->base.enabled && mode) {
8864*4882a593Smuzhiyun 		switch (tmp) {
8865*4882a593Smuzhiyun 		case 0:
8866*4882a593Smuzhiyun 		default:
8867*4882a593Smuzhiyun 			return 4096 * 2;
8868*4882a593Smuzhiyun 		case 1:
8869*4882a593Smuzhiyun 			return 1920 * 2;
8870*4882a593Smuzhiyun 		case 2:
8871*4882a593Smuzhiyun 			return 2560 * 2;
8872*4882a593Smuzhiyun 		}
8873*4882a593Smuzhiyun 	}
8874*4882a593Smuzhiyun 
8875*4882a593Smuzhiyun 	/* controller not enabled, so no lb used */
8876*4882a593Smuzhiyun 	return 0;
8877*4882a593Smuzhiyun }
8878*4882a593Smuzhiyun 
8879*4882a593Smuzhiyun /**
8880*4882a593Smuzhiyun  * cik_get_number_of_dram_channels - get the number of dram channels
8881*4882a593Smuzhiyun  *
8882*4882a593Smuzhiyun  * @rdev: radeon_device pointer
8883*4882a593Smuzhiyun  *
8884*4882a593Smuzhiyun  * Look up the number of video ram channels (CIK).
8885*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
8886*4882a593Smuzhiyun  * Returns the number of dram channels
8887*4882a593Smuzhiyun  */
cik_get_number_of_dram_channels(struct radeon_device * rdev)8888*4882a593Smuzhiyun static u32 cik_get_number_of_dram_channels(struct radeon_device *rdev)
8889*4882a593Smuzhiyun {
8890*4882a593Smuzhiyun 	u32 tmp = RREG32(MC_SHARED_CHMAP);
8891*4882a593Smuzhiyun 
8892*4882a593Smuzhiyun 	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
8893*4882a593Smuzhiyun 	case 0:
8894*4882a593Smuzhiyun 	default:
8895*4882a593Smuzhiyun 		return 1;
8896*4882a593Smuzhiyun 	case 1:
8897*4882a593Smuzhiyun 		return 2;
8898*4882a593Smuzhiyun 	case 2:
8899*4882a593Smuzhiyun 		return 4;
8900*4882a593Smuzhiyun 	case 3:
8901*4882a593Smuzhiyun 		return 8;
8902*4882a593Smuzhiyun 	case 4:
8903*4882a593Smuzhiyun 		return 3;
8904*4882a593Smuzhiyun 	case 5:
8905*4882a593Smuzhiyun 		return 6;
8906*4882a593Smuzhiyun 	case 6:
8907*4882a593Smuzhiyun 		return 10;
8908*4882a593Smuzhiyun 	case 7:
8909*4882a593Smuzhiyun 		return 12;
8910*4882a593Smuzhiyun 	case 8:
8911*4882a593Smuzhiyun 		return 16;
8912*4882a593Smuzhiyun 	}
8913*4882a593Smuzhiyun }
8914*4882a593Smuzhiyun 
8915*4882a593Smuzhiyun struct dce8_wm_params {
8916*4882a593Smuzhiyun 	u32 dram_channels; /* number of dram channels */
8917*4882a593Smuzhiyun 	u32 yclk;          /* bandwidth per dram data pin in kHz */
8918*4882a593Smuzhiyun 	u32 sclk;          /* engine clock in kHz */
8919*4882a593Smuzhiyun 	u32 disp_clk;      /* display clock in kHz */
8920*4882a593Smuzhiyun 	u32 src_width;     /* viewport width */
8921*4882a593Smuzhiyun 	u32 active_time;   /* active display time in ns */
8922*4882a593Smuzhiyun 	u32 blank_time;    /* blank time in ns */
8923*4882a593Smuzhiyun 	bool interlaced;    /* mode is interlaced */
8924*4882a593Smuzhiyun 	fixed20_12 vsc;    /* vertical scale ratio */
8925*4882a593Smuzhiyun 	u32 num_heads;     /* number of active crtcs */
8926*4882a593Smuzhiyun 	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
8927*4882a593Smuzhiyun 	u32 lb_size;       /* line buffer allocated to pipe */
8928*4882a593Smuzhiyun 	u32 vtaps;         /* vertical scaler taps */
8929*4882a593Smuzhiyun };
8930*4882a593Smuzhiyun 
8931*4882a593Smuzhiyun /**
8932*4882a593Smuzhiyun  * dce8_dram_bandwidth - get the dram bandwidth
8933*4882a593Smuzhiyun  *
8934*4882a593Smuzhiyun  * @wm: watermark calculation data
8935*4882a593Smuzhiyun  *
8936*4882a593Smuzhiyun  * Calculate the raw dram bandwidth (CIK).
8937*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
8938*4882a593Smuzhiyun  * Returns the dram bandwidth in MBytes/s
8939*4882a593Smuzhiyun  */
dce8_dram_bandwidth(struct dce8_wm_params * wm)8940*4882a593Smuzhiyun static u32 dce8_dram_bandwidth(struct dce8_wm_params *wm)
8941*4882a593Smuzhiyun {
8942*4882a593Smuzhiyun 	/* Calculate raw DRAM Bandwidth */
8943*4882a593Smuzhiyun 	fixed20_12 dram_efficiency; /* 0.7 */
8944*4882a593Smuzhiyun 	fixed20_12 yclk, dram_channels, bandwidth;
8945*4882a593Smuzhiyun 	fixed20_12 a;
8946*4882a593Smuzhiyun 
8947*4882a593Smuzhiyun 	a.full = dfixed_const(1000);
8948*4882a593Smuzhiyun 	yclk.full = dfixed_const(wm->yclk);
8949*4882a593Smuzhiyun 	yclk.full = dfixed_div(yclk, a);
8950*4882a593Smuzhiyun 	dram_channels.full = dfixed_const(wm->dram_channels * 4);
8951*4882a593Smuzhiyun 	a.full = dfixed_const(10);
8952*4882a593Smuzhiyun 	dram_efficiency.full = dfixed_const(7);
8953*4882a593Smuzhiyun 	dram_efficiency.full = dfixed_div(dram_efficiency, a);
8954*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(dram_channels, yclk);
8955*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
8956*4882a593Smuzhiyun 
8957*4882a593Smuzhiyun 	return dfixed_trunc(bandwidth);
8958*4882a593Smuzhiyun }
8959*4882a593Smuzhiyun 
8960*4882a593Smuzhiyun /**
8961*4882a593Smuzhiyun  * dce8_dram_bandwidth_for_display - get the dram bandwidth for display
8962*4882a593Smuzhiyun  *
8963*4882a593Smuzhiyun  * @wm: watermark calculation data
8964*4882a593Smuzhiyun  *
8965*4882a593Smuzhiyun  * Calculate the dram bandwidth used for display (CIK).
8966*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
8967*4882a593Smuzhiyun  * Returns the dram bandwidth for display in MBytes/s
8968*4882a593Smuzhiyun  */
dce8_dram_bandwidth_for_display(struct dce8_wm_params * wm)8969*4882a593Smuzhiyun static u32 dce8_dram_bandwidth_for_display(struct dce8_wm_params *wm)
8970*4882a593Smuzhiyun {
8971*4882a593Smuzhiyun 	/* Calculate DRAM Bandwidth and the part allocated to display. */
8972*4882a593Smuzhiyun 	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
8973*4882a593Smuzhiyun 	fixed20_12 yclk, dram_channels, bandwidth;
8974*4882a593Smuzhiyun 	fixed20_12 a;
8975*4882a593Smuzhiyun 
8976*4882a593Smuzhiyun 	a.full = dfixed_const(1000);
8977*4882a593Smuzhiyun 	yclk.full = dfixed_const(wm->yclk);
8978*4882a593Smuzhiyun 	yclk.full = dfixed_div(yclk, a);
8979*4882a593Smuzhiyun 	dram_channels.full = dfixed_const(wm->dram_channels * 4);
8980*4882a593Smuzhiyun 	a.full = dfixed_const(10);
8981*4882a593Smuzhiyun 	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
8982*4882a593Smuzhiyun 	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
8983*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(dram_channels, yclk);
8984*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
8985*4882a593Smuzhiyun 
8986*4882a593Smuzhiyun 	return dfixed_trunc(bandwidth);
8987*4882a593Smuzhiyun }
8988*4882a593Smuzhiyun 
8989*4882a593Smuzhiyun /**
8990*4882a593Smuzhiyun  * dce8_data_return_bandwidth - get the data return bandwidth
8991*4882a593Smuzhiyun  *
8992*4882a593Smuzhiyun  * @wm: watermark calculation data
8993*4882a593Smuzhiyun  *
8994*4882a593Smuzhiyun  * Calculate the data return bandwidth used for display (CIK).
8995*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
8996*4882a593Smuzhiyun  * Returns the data return bandwidth in MBytes/s
8997*4882a593Smuzhiyun  */
dce8_data_return_bandwidth(struct dce8_wm_params * wm)8998*4882a593Smuzhiyun static u32 dce8_data_return_bandwidth(struct dce8_wm_params *wm)
8999*4882a593Smuzhiyun {
9000*4882a593Smuzhiyun 	/* Calculate the display Data return Bandwidth */
9001*4882a593Smuzhiyun 	fixed20_12 return_efficiency; /* 0.8 */
9002*4882a593Smuzhiyun 	fixed20_12 sclk, bandwidth;
9003*4882a593Smuzhiyun 	fixed20_12 a;
9004*4882a593Smuzhiyun 
9005*4882a593Smuzhiyun 	a.full = dfixed_const(1000);
9006*4882a593Smuzhiyun 	sclk.full = dfixed_const(wm->sclk);
9007*4882a593Smuzhiyun 	sclk.full = dfixed_div(sclk, a);
9008*4882a593Smuzhiyun 	a.full = dfixed_const(10);
9009*4882a593Smuzhiyun 	return_efficiency.full = dfixed_const(8);
9010*4882a593Smuzhiyun 	return_efficiency.full = dfixed_div(return_efficiency, a);
9011*4882a593Smuzhiyun 	a.full = dfixed_const(32);
9012*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(a, sclk);
9013*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
9014*4882a593Smuzhiyun 
9015*4882a593Smuzhiyun 	return dfixed_trunc(bandwidth);
9016*4882a593Smuzhiyun }
9017*4882a593Smuzhiyun 
9018*4882a593Smuzhiyun /**
9019*4882a593Smuzhiyun  * dce8_dmif_request_bandwidth - get the dmif bandwidth
9020*4882a593Smuzhiyun  *
9021*4882a593Smuzhiyun  * @wm: watermark calculation data
9022*4882a593Smuzhiyun  *
9023*4882a593Smuzhiyun  * Calculate the dmif bandwidth used for display (CIK).
9024*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9025*4882a593Smuzhiyun  * Returns the dmif bandwidth in MBytes/s
9026*4882a593Smuzhiyun  */
dce8_dmif_request_bandwidth(struct dce8_wm_params * wm)9027*4882a593Smuzhiyun static u32 dce8_dmif_request_bandwidth(struct dce8_wm_params *wm)
9028*4882a593Smuzhiyun {
9029*4882a593Smuzhiyun 	/* Calculate the DMIF Request Bandwidth */
9030*4882a593Smuzhiyun 	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
9031*4882a593Smuzhiyun 	fixed20_12 disp_clk, bandwidth;
9032*4882a593Smuzhiyun 	fixed20_12 a, b;
9033*4882a593Smuzhiyun 
9034*4882a593Smuzhiyun 	a.full = dfixed_const(1000);
9035*4882a593Smuzhiyun 	disp_clk.full = dfixed_const(wm->disp_clk);
9036*4882a593Smuzhiyun 	disp_clk.full = dfixed_div(disp_clk, a);
9037*4882a593Smuzhiyun 	a.full = dfixed_const(32);
9038*4882a593Smuzhiyun 	b.full = dfixed_mul(a, disp_clk);
9039*4882a593Smuzhiyun 
9040*4882a593Smuzhiyun 	a.full = dfixed_const(10);
9041*4882a593Smuzhiyun 	disp_clk_request_efficiency.full = dfixed_const(8);
9042*4882a593Smuzhiyun 	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
9043*4882a593Smuzhiyun 
9044*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(b, disp_clk_request_efficiency);
9045*4882a593Smuzhiyun 
9046*4882a593Smuzhiyun 	return dfixed_trunc(bandwidth);
9047*4882a593Smuzhiyun }
9048*4882a593Smuzhiyun 
9049*4882a593Smuzhiyun /**
9050*4882a593Smuzhiyun  * dce8_available_bandwidth - get the min available bandwidth
9051*4882a593Smuzhiyun  *
9052*4882a593Smuzhiyun  * @wm: watermark calculation data
9053*4882a593Smuzhiyun  *
9054*4882a593Smuzhiyun  * Calculate the min available bandwidth used for display (CIK).
9055*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9056*4882a593Smuzhiyun  * Returns the min available bandwidth in MBytes/s
9057*4882a593Smuzhiyun  */
dce8_available_bandwidth(struct dce8_wm_params * wm)9058*4882a593Smuzhiyun static u32 dce8_available_bandwidth(struct dce8_wm_params *wm)
9059*4882a593Smuzhiyun {
9060*4882a593Smuzhiyun 	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
9061*4882a593Smuzhiyun 	u32 dram_bandwidth = dce8_dram_bandwidth(wm);
9062*4882a593Smuzhiyun 	u32 data_return_bandwidth = dce8_data_return_bandwidth(wm);
9063*4882a593Smuzhiyun 	u32 dmif_req_bandwidth = dce8_dmif_request_bandwidth(wm);
9064*4882a593Smuzhiyun 
9065*4882a593Smuzhiyun 	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
9066*4882a593Smuzhiyun }
9067*4882a593Smuzhiyun 
9068*4882a593Smuzhiyun /**
9069*4882a593Smuzhiyun  * dce8_average_bandwidth - get the average available bandwidth
9070*4882a593Smuzhiyun  *
9071*4882a593Smuzhiyun  * @wm: watermark calculation data
9072*4882a593Smuzhiyun  *
9073*4882a593Smuzhiyun  * Calculate the average available bandwidth used for display (CIK).
9074*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9075*4882a593Smuzhiyun  * Returns the average available bandwidth in MBytes/s
9076*4882a593Smuzhiyun  */
dce8_average_bandwidth(struct dce8_wm_params * wm)9077*4882a593Smuzhiyun static u32 dce8_average_bandwidth(struct dce8_wm_params *wm)
9078*4882a593Smuzhiyun {
9079*4882a593Smuzhiyun 	/* Calculate the display mode Average Bandwidth
9080*4882a593Smuzhiyun 	 * DisplayMode should contain the source and destination dimensions,
9081*4882a593Smuzhiyun 	 * timing, etc.
9082*4882a593Smuzhiyun 	 */
9083*4882a593Smuzhiyun 	fixed20_12 bpp;
9084*4882a593Smuzhiyun 	fixed20_12 line_time;
9085*4882a593Smuzhiyun 	fixed20_12 src_width;
9086*4882a593Smuzhiyun 	fixed20_12 bandwidth;
9087*4882a593Smuzhiyun 	fixed20_12 a;
9088*4882a593Smuzhiyun 
9089*4882a593Smuzhiyun 	a.full = dfixed_const(1000);
9090*4882a593Smuzhiyun 	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
9091*4882a593Smuzhiyun 	line_time.full = dfixed_div(line_time, a);
9092*4882a593Smuzhiyun 	bpp.full = dfixed_const(wm->bytes_per_pixel);
9093*4882a593Smuzhiyun 	src_width.full = dfixed_const(wm->src_width);
9094*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(src_width, bpp);
9095*4882a593Smuzhiyun 	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
9096*4882a593Smuzhiyun 	bandwidth.full = dfixed_div(bandwidth, line_time);
9097*4882a593Smuzhiyun 
9098*4882a593Smuzhiyun 	return dfixed_trunc(bandwidth);
9099*4882a593Smuzhiyun }
9100*4882a593Smuzhiyun 
9101*4882a593Smuzhiyun /**
9102*4882a593Smuzhiyun  * dce8_latency_watermark - get the latency watermark
9103*4882a593Smuzhiyun  *
9104*4882a593Smuzhiyun  * @wm: watermark calculation data
9105*4882a593Smuzhiyun  *
9106*4882a593Smuzhiyun  * Calculate the latency watermark (CIK).
9107*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9108*4882a593Smuzhiyun  * Returns the latency watermark in ns
9109*4882a593Smuzhiyun  */
dce8_latency_watermark(struct dce8_wm_params * wm)9110*4882a593Smuzhiyun static u32 dce8_latency_watermark(struct dce8_wm_params *wm)
9111*4882a593Smuzhiyun {
9112*4882a593Smuzhiyun 	/* First calculate the latency in ns */
9113*4882a593Smuzhiyun 	u32 mc_latency = 2000; /* 2000 ns. */
9114*4882a593Smuzhiyun 	u32 available_bandwidth = dce8_available_bandwidth(wm);
9115*4882a593Smuzhiyun 	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
9116*4882a593Smuzhiyun 	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
9117*4882a593Smuzhiyun 	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
9118*4882a593Smuzhiyun 	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
9119*4882a593Smuzhiyun 		(wm->num_heads * cursor_line_pair_return_time);
9120*4882a593Smuzhiyun 	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
9121*4882a593Smuzhiyun 	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
9122*4882a593Smuzhiyun 	u32 tmp, dmif_size = 12288;
9123*4882a593Smuzhiyun 	fixed20_12 a, b, c;
9124*4882a593Smuzhiyun 
9125*4882a593Smuzhiyun 	if (wm->num_heads == 0)
9126*4882a593Smuzhiyun 		return 0;
9127*4882a593Smuzhiyun 
9128*4882a593Smuzhiyun 	a.full = dfixed_const(2);
9129*4882a593Smuzhiyun 	b.full = dfixed_const(1);
9130*4882a593Smuzhiyun 	if ((wm->vsc.full > a.full) ||
9131*4882a593Smuzhiyun 	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
9132*4882a593Smuzhiyun 	    (wm->vtaps >= 5) ||
9133*4882a593Smuzhiyun 	    ((wm->vsc.full >= a.full) && wm->interlaced))
9134*4882a593Smuzhiyun 		max_src_lines_per_dst_line = 4;
9135*4882a593Smuzhiyun 	else
9136*4882a593Smuzhiyun 		max_src_lines_per_dst_line = 2;
9137*4882a593Smuzhiyun 
9138*4882a593Smuzhiyun 	a.full = dfixed_const(available_bandwidth);
9139*4882a593Smuzhiyun 	b.full = dfixed_const(wm->num_heads);
9140*4882a593Smuzhiyun 	a.full = dfixed_div(a, b);
9141*4882a593Smuzhiyun 	tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
9142*4882a593Smuzhiyun 	tmp = min(dfixed_trunc(a), tmp);
9143*4882a593Smuzhiyun 
9144*4882a593Smuzhiyun 	lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
9145*4882a593Smuzhiyun 
9146*4882a593Smuzhiyun 	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
9147*4882a593Smuzhiyun 	b.full = dfixed_const(1000);
9148*4882a593Smuzhiyun 	c.full = dfixed_const(lb_fill_bw);
9149*4882a593Smuzhiyun 	b.full = dfixed_div(c, b);
9150*4882a593Smuzhiyun 	a.full = dfixed_div(a, b);
9151*4882a593Smuzhiyun 	line_fill_time = dfixed_trunc(a);
9152*4882a593Smuzhiyun 
9153*4882a593Smuzhiyun 	if (line_fill_time < wm->active_time)
9154*4882a593Smuzhiyun 		return latency;
9155*4882a593Smuzhiyun 	else
9156*4882a593Smuzhiyun 		return latency + (line_fill_time - wm->active_time);
9157*4882a593Smuzhiyun 
9158*4882a593Smuzhiyun }
9159*4882a593Smuzhiyun 
9160*4882a593Smuzhiyun /**
9161*4882a593Smuzhiyun  * dce8_average_bandwidth_vs_dram_bandwidth_for_display - check
9162*4882a593Smuzhiyun  * average and available dram bandwidth
9163*4882a593Smuzhiyun  *
9164*4882a593Smuzhiyun  * @wm: watermark calculation data
9165*4882a593Smuzhiyun  *
9166*4882a593Smuzhiyun  * Check if the display average bandwidth fits in the display
9167*4882a593Smuzhiyun  * dram bandwidth (CIK).
9168*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9169*4882a593Smuzhiyun  * Returns true if the display fits, false if not.
9170*4882a593Smuzhiyun  */
dce8_average_bandwidth_vs_dram_bandwidth_for_display(struct dce8_wm_params * wm)9171*4882a593Smuzhiyun static bool dce8_average_bandwidth_vs_dram_bandwidth_for_display(struct dce8_wm_params *wm)
9172*4882a593Smuzhiyun {
9173*4882a593Smuzhiyun 	if (dce8_average_bandwidth(wm) <=
9174*4882a593Smuzhiyun 	    (dce8_dram_bandwidth_for_display(wm) / wm->num_heads))
9175*4882a593Smuzhiyun 		return true;
9176*4882a593Smuzhiyun 	else
9177*4882a593Smuzhiyun 		return false;
9178*4882a593Smuzhiyun }
9179*4882a593Smuzhiyun 
9180*4882a593Smuzhiyun /**
9181*4882a593Smuzhiyun  * dce8_average_bandwidth_vs_available_bandwidth - check
9182*4882a593Smuzhiyun  * average and available bandwidth
9183*4882a593Smuzhiyun  *
9184*4882a593Smuzhiyun  * @wm: watermark calculation data
9185*4882a593Smuzhiyun  *
9186*4882a593Smuzhiyun  * Check if the display average bandwidth fits in the display
9187*4882a593Smuzhiyun  * available bandwidth (CIK).
9188*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9189*4882a593Smuzhiyun  * Returns true if the display fits, false if not.
9190*4882a593Smuzhiyun  */
dce8_average_bandwidth_vs_available_bandwidth(struct dce8_wm_params * wm)9191*4882a593Smuzhiyun static bool dce8_average_bandwidth_vs_available_bandwidth(struct dce8_wm_params *wm)
9192*4882a593Smuzhiyun {
9193*4882a593Smuzhiyun 	if (dce8_average_bandwidth(wm) <=
9194*4882a593Smuzhiyun 	    (dce8_available_bandwidth(wm) / wm->num_heads))
9195*4882a593Smuzhiyun 		return true;
9196*4882a593Smuzhiyun 	else
9197*4882a593Smuzhiyun 		return false;
9198*4882a593Smuzhiyun }
9199*4882a593Smuzhiyun 
9200*4882a593Smuzhiyun /**
9201*4882a593Smuzhiyun  * dce8_check_latency_hiding - check latency hiding
9202*4882a593Smuzhiyun  *
9203*4882a593Smuzhiyun  * @wm: watermark calculation data
9204*4882a593Smuzhiyun  *
9205*4882a593Smuzhiyun  * Check latency hiding (CIK).
9206*4882a593Smuzhiyun  * Used for display watermark bandwidth calculations
9207*4882a593Smuzhiyun  * Returns true if the display fits, false if not.
9208*4882a593Smuzhiyun  */
dce8_check_latency_hiding(struct dce8_wm_params * wm)9209*4882a593Smuzhiyun static bool dce8_check_latency_hiding(struct dce8_wm_params *wm)
9210*4882a593Smuzhiyun {
9211*4882a593Smuzhiyun 	u32 lb_partitions = wm->lb_size / wm->src_width;
9212*4882a593Smuzhiyun 	u32 line_time = wm->active_time + wm->blank_time;
9213*4882a593Smuzhiyun 	u32 latency_tolerant_lines;
9214*4882a593Smuzhiyun 	u32 latency_hiding;
9215*4882a593Smuzhiyun 	fixed20_12 a;
9216*4882a593Smuzhiyun 
9217*4882a593Smuzhiyun 	a.full = dfixed_const(1);
9218*4882a593Smuzhiyun 	if (wm->vsc.full > a.full)
9219*4882a593Smuzhiyun 		latency_tolerant_lines = 1;
9220*4882a593Smuzhiyun 	else {
9221*4882a593Smuzhiyun 		if (lb_partitions <= (wm->vtaps + 1))
9222*4882a593Smuzhiyun 			latency_tolerant_lines = 1;
9223*4882a593Smuzhiyun 		else
9224*4882a593Smuzhiyun 			latency_tolerant_lines = 2;
9225*4882a593Smuzhiyun 	}
9226*4882a593Smuzhiyun 
9227*4882a593Smuzhiyun 	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
9228*4882a593Smuzhiyun 
9229*4882a593Smuzhiyun 	if (dce8_latency_watermark(wm) <= latency_hiding)
9230*4882a593Smuzhiyun 		return true;
9231*4882a593Smuzhiyun 	else
9232*4882a593Smuzhiyun 		return false;
9233*4882a593Smuzhiyun }
9234*4882a593Smuzhiyun 
9235*4882a593Smuzhiyun /**
9236*4882a593Smuzhiyun  * dce8_program_watermarks - program display watermarks
9237*4882a593Smuzhiyun  *
9238*4882a593Smuzhiyun  * @rdev: radeon_device pointer
9239*4882a593Smuzhiyun  * @radeon_crtc: the selected display controller
9240*4882a593Smuzhiyun  * @lb_size: line buffer size
9241*4882a593Smuzhiyun  * @num_heads: number of display controllers in use
9242*4882a593Smuzhiyun  *
9243*4882a593Smuzhiyun  * Calculate and program the display watermarks for the
9244*4882a593Smuzhiyun  * selected display controller (CIK).
9245*4882a593Smuzhiyun  */
dce8_program_watermarks(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,u32 lb_size,u32 num_heads)9246*4882a593Smuzhiyun static void dce8_program_watermarks(struct radeon_device *rdev,
9247*4882a593Smuzhiyun 				    struct radeon_crtc *radeon_crtc,
9248*4882a593Smuzhiyun 				    u32 lb_size, u32 num_heads)
9249*4882a593Smuzhiyun {
9250*4882a593Smuzhiyun 	struct drm_display_mode *mode = &radeon_crtc->base.mode;
9251*4882a593Smuzhiyun 	struct dce8_wm_params wm_low, wm_high;
9252*4882a593Smuzhiyun 	u32 active_time;
9253*4882a593Smuzhiyun 	u32 line_time = 0;
9254*4882a593Smuzhiyun 	u32 latency_watermark_a = 0, latency_watermark_b = 0;
9255*4882a593Smuzhiyun 	u32 tmp, wm_mask;
9256*4882a593Smuzhiyun 
9257*4882a593Smuzhiyun 	if (radeon_crtc->base.enabled && num_heads && mode) {
9258*4882a593Smuzhiyun 		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
9259*4882a593Smuzhiyun 					    (u32)mode->clock);
9260*4882a593Smuzhiyun 		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
9261*4882a593Smuzhiyun 					  (u32)mode->clock);
9262*4882a593Smuzhiyun 		line_time = min(line_time, (u32)65535);
9263*4882a593Smuzhiyun 
9264*4882a593Smuzhiyun 		/* watermark for high clocks */
9265*4882a593Smuzhiyun 		if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
9266*4882a593Smuzhiyun 		    rdev->pm.dpm_enabled) {
9267*4882a593Smuzhiyun 			wm_high.yclk =
9268*4882a593Smuzhiyun 				radeon_dpm_get_mclk(rdev, false) * 10;
9269*4882a593Smuzhiyun 			wm_high.sclk =
9270*4882a593Smuzhiyun 				radeon_dpm_get_sclk(rdev, false) * 10;
9271*4882a593Smuzhiyun 		} else {
9272*4882a593Smuzhiyun 			wm_high.yclk = rdev->pm.current_mclk * 10;
9273*4882a593Smuzhiyun 			wm_high.sclk = rdev->pm.current_sclk * 10;
9274*4882a593Smuzhiyun 		}
9275*4882a593Smuzhiyun 
9276*4882a593Smuzhiyun 		wm_high.disp_clk = mode->clock;
9277*4882a593Smuzhiyun 		wm_high.src_width = mode->crtc_hdisplay;
9278*4882a593Smuzhiyun 		wm_high.active_time = active_time;
9279*4882a593Smuzhiyun 		wm_high.blank_time = line_time - wm_high.active_time;
9280*4882a593Smuzhiyun 		wm_high.interlaced = false;
9281*4882a593Smuzhiyun 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
9282*4882a593Smuzhiyun 			wm_high.interlaced = true;
9283*4882a593Smuzhiyun 		wm_high.vsc = radeon_crtc->vsc;
9284*4882a593Smuzhiyun 		wm_high.vtaps = 1;
9285*4882a593Smuzhiyun 		if (radeon_crtc->rmx_type != RMX_OFF)
9286*4882a593Smuzhiyun 			wm_high.vtaps = 2;
9287*4882a593Smuzhiyun 		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
9288*4882a593Smuzhiyun 		wm_high.lb_size = lb_size;
9289*4882a593Smuzhiyun 		wm_high.dram_channels = cik_get_number_of_dram_channels(rdev);
9290*4882a593Smuzhiyun 		wm_high.num_heads = num_heads;
9291*4882a593Smuzhiyun 
9292*4882a593Smuzhiyun 		/* set for high clocks */
9293*4882a593Smuzhiyun 		latency_watermark_a = min(dce8_latency_watermark(&wm_high), (u32)65535);
9294*4882a593Smuzhiyun 
9295*4882a593Smuzhiyun 		/* possibly force display priority to high */
9296*4882a593Smuzhiyun 		/* should really do this at mode validation time... */
9297*4882a593Smuzhiyun 		if (!dce8_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
9298*4882a593Smuzhiyun 		    !dce8_average_bandwidth_vs_available_bandwidth(&wm_high) ||
9299*4882a593Smuzhiyun 		    !dce8_check_latency_hiding(&wm_high) ||
9300*4882a593Smuzhiyun 		    (rdev->disp_priority == 2)) {
9301*4882a593Smuzhiyun 			DRM_DEBUG_KMS("force priority to high\n");
9302*4882a593Smuzhiyun 		}
9303*4882a593Smuzhiyun 
9304*4882a593Smuzhiyun 		/* watermark for low clocks */
9305*4882a593Smuzhiyun 		if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
9306*4882a593Smuzhiyun 		    rdev->pm.dpm_enabled) {
9307*4882a593Smuzhiyun 			wm_low.yclk =
9308*4882a593Smuzhiyun 				radeon_dpm_get_mclk(rdev, true) * 10;
9309*4882a593Smuzhiyun 			wm_low.sclk =
9310*4882a593Smuzhiyun 				radeon_dpm_get_sclk(rdev, true) * 10;
9311*4882a593Smuzhiyun 		} else {
9312*4882a593Smuzhiyun 			wm_low.yclk = rdev->pm.current_mclk * 10;
9313*4882a593Smuzhiyun 			wm_low.sclk = rdev->pm.current_sclk * 10;
9314*4882a593Smuzhiyun 		}
9315*4882a593Smuzhiyun 
9316*4882a593Smuzhiyun 		wm_low.disp_clk = mode->clock;
9317*4882a593Smuzhiyun 		wm_low.src_width = mode->crtc_hdisplay;
9318*4882a593Smuzhiyun 		wm_low.active_time = active_time;
9319*4882a593Smuzhiyun 		wm_low.blank_time = line_time - wm_low.active_time;
9320*4882a593Smuzhiyun 		wm_low.interlaced = false;
9321*4882a593Smuzhiyun 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
9322*4882a593Smuzhiyun 			wm_low.interlaced = true;
9323*4882a593Smuzhiyun 		wm_low.vsc = radeon_crtc->vsc;
9324*4882a593Smuzhiyun 		wm_low.vtaps = 1;
9325*4882a593Smuzhiyun 		if (radeon_crtc->rmx_type != RMX_OFF)
9326*4882a593Smuzhiyun 			wm_low.vtaps = 2;
9327*4882a593Smuzhiyun 		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
9328*4882a593Smuzhiyun 		wm_low.lb_size = lb_size;
9329*4882a593Smuzhiyun 		wm_low.dram_channels = cik_get_number_of_dram_channels(rdev);
9330*4882a593Smuzhiyun 		wm_low.num_heads = num_heads;
9331*4882a593Smuzhiyun 
9332*4882a593Smuzhiyun 		/* set for low clocks */
9333*4882a593Smuzhiyun 		latency_watermark_b = min(dce8_latency_watermark(&wm_low), (u32)65535);
9334*4882a593Smuzhiyun 
9335*4882a593Smuzhiyun 		/* possibly force display priority to high */
9336*4882a593Smuzhiyun 		/* should really do this at mode validation time... */
9337*4882a593Smuzhiyun 		if (!dce8_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
9338*4882a593Smuzhiyun 		    !dce8_average_bandwidth_vs_available_bandwidth(&wm_low) ||
9339*4882a593Smuzhiyun 		    !dce8_check_latency_hiding(&wm_low) ||
9340*4882a593Smuzhiyun 		    (rdev->disp_priority == 2)) {
9341*4882a593Smuzhiyun 			DRM_DEBUG_KMS("force priority to high\n");
9342*4882a593Smuzhiyun 		}
9343*4882a593Smuzhiyun 
9344*4882a593Smuzhiyun 		/* Save number of lines the linebuffer leads before the scanout */
9345*4882a593Smuzhiyun 		radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
9346*4882a593Smuzhiyun 	}
9347*4882a593Smuzhiyun 
9348*4882a593Smuzhiyun 	/* select wm A */
9349*4882a593Smuzhiyun 	wm_mask = RREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset);
9350*4882a593Smuzhiyun 	tmp = wm_mask;
9351*4882a593Smuzhiyun 	tmp &= ~LATENCY_WATERMARK_MASK(3);
9352*4882a593Smuzhiyun 	tmp |= LATENCY_WATERMARK_MASK(1);
9353*4882a593Smuzhiyun 	WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, tmp);
9354*4882a593Smuzhiyun 	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
9355*4882a593Smuzhiyun 	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
9356*4882a593Smuzhiyun 		LATENCY_HIGH_WATERMARK(line_time)));
9357*4882a593Smuzhiyun 	/* select wm B */
9358*4882a593Smuzhiyun 	tmp = RREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset);
9359*4882a593Smuzhiyun 	tmp &= ~LATENCY_WATERMARK_MASK(3);
9360*4882a593Smuzhiyun 	tmp |= LATENCY_WATERMARK_MASK(2);
9361*4882a593Smuzhiyun 	WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, tmp);
9362*4882a593Smuzhiyun 	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
9363*4882a593Smuzhiyun 	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
9364*4882a593Smuzhiyun 		LATENCY_HIGH_WATERMARK(line_time)));
9365*4882a593Smuzhiyun 	/* restore original selection */
9366*4882a593Smuzhiyun 	WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, wm_mask);
9367*4882a593Smuzhiyun 
9368*4882a593Smuzhiyun 	/* save values for DPM */
9369*4882a593Smuzhiyun 	radeon_crtc->line_time = line_time;
9370*4882a593Smuzhiyun 	radeon_crtc->wm_high = latency_watermark_a;
9371*4882a593Smuzhiyun 	radeon_crtc->wm_low = latency_watermark_b;
9372*4882a593Smuzhiyun }
9373*4882a593Smuzhiyun 
9374*4882a593Smuzhiyun /**
9375*4882a593Smuzhiyun  * dce8_bandwidth_update - program display watermarks
9376*4882a593Smuzhiyun  *
9377*4882a593Smuzhiyun  * @rdev: radeon_device pointer
9378*4882a593Smuzhiyun  *
9379*4882a593Smuzhiyun  * Calculate and program the display watermarks and line
9380*4882a593Smuzhiyun  * buffer allocation (CIK).
9381*4882a593Smuzhiyun  */
dce8_bandwidth_update(struct radeon_device * rdev)9382*4882a593Smuzhiyun void dce8_bandwidth_update(struct radeon_device *rdev)
9383*4882a593Smuzhiyun {
9384*4882a593Smuzhiyun 	struct drm_display_mode *mode = NULL;
9385*4882a593Smuzhiyun 	u32 num_heads = 0, lb_size;
9386*4882a593Smuzhiyun 	int i;
9387*4882a593Smuzhiyun 
9388*4882a593Smuzhiyun 	if (!rdev->mode_info.mode_config_initialized)
9389*4882a593Smuzhiyun 		return;
9390*4882a593Smuzhiyun 
9391*4882a593Smuzhiyun 	radeon_update_display_priority(rdev);
9392*4882a593Smuzhiyun 
9393*4882a593Smuzhiyun 	for (i = 0; i < rdev->num_crtc; i++) {
9394*4882a593Smuzhiyun 		if (rdev->mode_info.crtcs[i]->base.enabled)
9395*4882a593Smuzhiyun 			num_heads++;
9396*4882a593Smuzhiyun 	}
9397*4882a593Smuzhiyun 	for (i = 0; i < rdev->num_crtc; i++) {
9398*4882a593Smuzhiyun 		mode = &rdev->mode_info.crtcs[i]->base.mode;
9399*4882a593Smuzhiyun 		lb_size = dce8_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode);
9400*4882a593Smuzhiyun 		dce8_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
9401*4882a593Smuzhiyun 	}
9402*4882a593Smuzhiyun }
9403*4882a593Smuzhiyun 
9404*4882a593Smuzhiyun /**
9405*4882a593Smuzhiyun  * cik_get_gpu_clock_counter - return GPU clock counter snapshot
9406*4882a593Smuzhiyun  *
9407*4882a593Smuzhiyun  * @rdev: radeon_device pointer
9408*4882a593Smuzhiyun  *
9409*4882a593Smuzhiyun  * Fetches a GPU clock counter snapshot (SI).
9410*4882a593Smuzhiyun  * Returns the 64 bit clock counter snapshot.
9411*4882a593Smuzhiyun  */
cik_get_gpu_clock_counter(struct radeon_device * rdev)9412*4882a593Smuzhiyun uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev)
9413*4882a593Smuzhiyun {
9414*4882a593Smuzhiyun 	uint64_t clock;
9415*4882a593Smuzhiyun 
9416*4882a593Smuzhiyun 	mutex_lock(&rdev->gpu_clock_mutex);
9417*4882a593Smuzhiyun 	WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
9418*4882a593Smuzhiyun 	clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
9419*4882a593Smuzhiyun 		((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
9420*4882a593Smuzhiyun 	mutex_unlock(&rdev->gpu_clock_mutex);
9421*4882a593Smuzhiyun 	return clock;
9422*4882a593Smuzhiyun }
9423*4882a593Smuzhiyun 
cik_set_uvd_clock(struct radeon_device * rdev,u32 clock,u32 cntl_reg,u32 status_reg)9424*4882a593Smuzhiyun static int cik_set_uvd_clock(struct radeon_device *rdev, u32 clock,
9425*4882a593Smuzhiyun 			     u32 cntl_reg, u32 status_reg)
9426*4882a593Smuzhiyun {
9427*4882a593Smuzhiyun 	int r, i;
9428*4882a593Smuzhiyun 	struct atom_clock_dividers dividers;
9429*4882a593Smuzhiyun 	uint32_t tmp;
9430*4882a593Smuzhiyun 
9431*4882a593Smuzhiyun 	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
9432*4882a593Smuzhiyun 					   clock, false, &dividers);
9433*4882a593Smuzhiyun 	if (r)
9434*4882a593Smuzhiyun 		return r;
9435*4882a593Smuzhiyun 
9436*4882a593Smuzhiyun 	tmp = RREG32_SMC(cntl_reg);
9437*4882a593Smuzhiyun 	tmp &= ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK);
9438*4882a593Smuzhiyun 	tmp |= dividers.post_divider;
9439*4882a593Smuzhiyun 	WREG32_SMC(cntl_reg, tmp);
9440*4882a593Smuzhiyun 
9441*4882a593Smuzhiyun 	for (i = 0; i < 100; i++) {
9442*4882a593Smuzhiyun 		if (RREG32_SMC(status_reg) & DCLK_STATUS)
9443*4882a593Smuzhiyun 			break;
9444*4882a593Smuzhiyun 		mdelay(10);
9445*4882a593Smuzhiyun 	}
9446*4882a593Smuzhiyun 	if (i == 100)
9447*4882a593Smuzhiyun 		return -ETIMEDOUT;
9448*4882a593Smuzhiyun 
9449*4882a593Smuzhiyun 	return 0;
9450*4882a593Smuzhiyun }
9451*4882a593Smuzhiyun 
cik_set_uvd_clocks(struct radeon_device * rdev,u32 vclk,u32 dclk)9452*4882a593Smuzhiyun int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
9453*4882a593Smuzhiyun {
9454*4882a593Smuzhiyun 	int r = 0;
9455*4882a593Smuzhiyun 
9456*4882a593Smuzhiyun 	r = cik_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS);
9457*4882a593Smuzhiyun 	if (r)
9458*4882a593Smuzhiyun 		return r;
9459*4882a593Smuzhiyun 
9460*4882a593Smuzhiyun 	r = cik_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS);
9461*4882a593Smuzhiyun 	return r;
9462*4882a593Smuzhiyun }
9463*4882a593Smuzhiyun 
cik_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)9464*4882a593Smuzhiyun int cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
9465*4882a593Smuzhiyun {
9466*4882a593Smuzhiyun 	int r, i;
9467*4882a593Smuzhiyun 	struct atom_clock_dividers dividers;
9468*4882a593Smuzhiyun 	u32 tmp;
9469*4882a593Smuzhiyun 
9470*4882a593Smuzhiyun 	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
9471*4882a593Smuzhiyun 					   ecclk, false, &dividers);
9472*4882a593Smuzhiyun 	if (r)
9473*4882a593Smuzhiyun 		return r;
9474*4882a593Smuzhiyun 
9475*4882a593Smuzhiyun 	for (i = 0; i < 100; i++) {
9476*4882a593Smuzhiyun 		if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS)
9477*4882a593Smuzhiyun 			break;
9478*4882a593Smuzhiyun 		mdelay(10);
9479*4882a593Smuzhiyun 	}
9480*4882a593Smuzhiyun 	if (i == 100)
9481*4882a593Smuzhiyun 		return -ETIMEDOUT;
9482*4882a593Smuzhiyun 
9483*4882a593Smuzhiyun 	tmp = RREG32_SMC(CG_ECLK_CNTL);
9484*4882a593Smuzhiyun 	tmp &= ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK);
9485*4882a593Smuzhiyun 	tmp |= dividers.post_divider;
9486*4882a593Smuzhiyun 	WREG32_SMC(CG_ECLK_CNTL, tmp);
9487*4882a593Smuzhiyun 
9488*4882a593Smuzhiyun 	for (i = 0; i < 100; i++) {
9489*4882a593Smuzhiyun 		if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS)
9490*4882a593Smuzhiyun 			break;
9491*4882a593Smuzhiyun 		mdelay(10);
9492*4882a593Smuzhiyun 	}
9493*4882a593Smuzhiyun 	if (i == 100)
9494*4882a593Smuzhiyun 		return -ETIMEDOUT;
9495*4882a593Smuzhiyun 
9496*4882a593Smuzhiyun 	return 0;
9497*4882a593Smuzhiyun }
9498*4882a593Smuzhiyun 
cik_pcie_gen3_enable(struct radeon_device * rdev)9499*4882a593Smuzhiyun static void cik_pcie_gen3_enable(struct radeon_device *rdev)
9500*4882a593Smuzhiyun {
9501*4882a593Smuzhiyun 	struct pci_dev *root = rdev->pdev->bus->self;
9502*4882a593Smuzhiyun 	enum pci_bus_speed speed_cap;
9503*4882a593Smuzhiyun 	u32 speed_cntl, current_data_rate;
9504*4882a593Smuzhiyun 	int i;
9505*4882a593Smuzhiyun 	u16 tmp16;
9506*4882a593Smuzhiyun 
9507*4882a593Smuzhiyun 	if (pci_is_root_bus(rdev->pdev->bus))
9508*4882a593Smuzhiyun 		return;
9509*4882a593Smuzhiyun 
9510*4882a593Smuzhiyun 	if (radeon_pcie_gen2 == 0)
9511*4882a593Smuzhiyun 		return;
9512*4882a593Smuzhiyun 
9513*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP)
9514*4882a593Smuzhiyun 		return;
9515*4882a593Smuzhiyun 
9516*4882a593Smuzhiyun 	if (!(rdev->flags & RADEON_IS_PCIE))
9517*4882a593Smuzhiyun 		return;
9518*4882a593Smuzhiyun 
9519*4882a593Smuzhiyun 	speed_cap = pcie_get_speed_cap(root);
9520*4882a593Smuzhiyun 	if (speed_cap == PCI_SPEED_UNKNOWN)
9521*4882a593Smuzhiyun 		return;
9522*4882a593Smuzhiyun 
9523*4882a593Smuzhiyun 	if ((speed_cap != PCIE_SPEED_8_0GT) &&
9524*4882a593Smuzhiyun 	    (speed_cap != PCIE_SPEED_5_0GT))
9525*4882a593Smuzhiyun 		return;
9526*4882a593Smuzhiyun 
9527*4882a593Smuzhiyun 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
9528*4882a593Smuzhiyun 	current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
9529*4882a593Smuzhiyun 		LC_CURRENT_DATA_RATE_SHIFT;
9530*4882a593Smuzhiyun 	if (speed_cap == PCIE_SPEED_8_0GT) {
9531*4882a593Smuzhiyun 		if (current_data_rate == 2) {
9532*4882a593Smuzhiyun 			DRM_INFO("PCIE gen 3 link speeds already enabled\n");
9533*4882a593Smuzhiyun 			return;
9534*4882a593Smuzhiyun 		}
9535*4882a593Smuzhiyun 		DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n");
9536*4882a593Smuzhiyun 	} else if (speed_cap == PCIE_SPEED_5_0GT) {
9537*4882a593Smuzhiyun 		if (current_data_rate == 1) {
9538*4882a593Smuzhiyun 			DRM_INFO("PCIE gen 2 link speeds already enabled\n");
9539*4882a593Smuzhiyun 			return;
9540*4882a593Smuzhiyun 		}
9541*4882a593Smuzhiyun 		DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
9542*4882a593Smuzhiyun 	}
9543*4882a593Smuzhiyun 
9544*4882a593Smuzhiyun 	if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev))
9545*4882a593Smuzhiyun 		return;
9546*4882a593Smuzhiyun 
9547*4882a593Smuzhiyun 	if (speed_cap == PCIE_SPEED_8_0GT) {
9548*4882a593Smuzhiyun 		/* re-try equalization if gen3 is not already enabled */
9549*4882a593Smuzhiyun 		if (current_data_rate != 2) {
9550*4882a593Smuzhiyun 			u16 bridge_cfg, gpu_cfg;
9551*4882a593Smuzhiyun 			u16 bridge_cfg2, gpu_cfg2;
9552*4882a593Smuzhiyun 			u32 max_lw, current_lw, tmp;
9553*4882a593Smuzhiyun 
9554*4882a593Smuzhiyun 			pcie_capability_read_word(root, PCI_EXP_LNKCTL,
9555*4882a593Smuzhiyun 						  &bridge_cfg);
9556*4882a593Smuzhiyun 			pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
9557*4882a593Smuzhiyun 						  &gpu_cfg);
9558*4882a593Smuzhiyun 
9559*4882a593Smuzhiyun 			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
9560*4882a593Smuzhiyun 			pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
9561*4882a593Smuzhiyun 
9562*4882a593Smuzhiyun 			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
9563*4882a593Smuzhiyun 			pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
9564*4882a593Smuzhiyun 						   tmp16);
9565*4882a593Smuzhiyun 
9566*4882a593Smuzhiyun 			tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
9567*4882a593Smuzhiyun 			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
9568*4882a593Smuzhiyun 			current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT;
9569*4882a593Smuzhiyun 
9570*4882a593Smuzhiyun 			if (current_lw < max_lw) {
9571*4882a593Smuzhiyun 				tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
9572*4882a593Smuzhiyun 				if (tmp & LC_RENEGOTIATION_SUPPORT) {
9573*4882a593Smuzhiyun 					tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS);
9574*4882a593Smuzhiyun 					tmp |= (max_lw << LC_LINK_WIDTH_SHIFT);
9575*4882a593Smuzhiyun 					tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW;
9576*4882a593Smuzhiyun 					WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp);
9577*4882a593Smuzhiyun 				}
9578*4882a593Smuzhiyun 			}
9579*4882a593Smuzhiyun 
9580*4882a593Smuzhiyun 			for (i = 0; i < 10; i++) {
9581*4882a593Smuzhiyun 				/* check status */
9582*4882a593Smuzhiyun 				pcie_capability_read_word(rdev->pdev,
9583*4882a593Smuzhiyun 							  PCI_EXP_DEVSTA,
9584*4882a593Smuzhiyun 							  &tmp16);
9585*4882a593Smuzhiyun 				if (tmp16 & PCI_EXP_DEVSTA_TRPND)
9586*4882a593Smuzhiyun 					break;
9587*4882a593Smuzhiyun 
9588*4882a593Smuzhiyun 				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
9589*4882a593Smuzhiyun 							  &bridge_cfg);
9590*4882a593Smuzhiyun 				pcie_capability_read_word(rdev->pdev,
9591*4882a593Smuzhiyun 							  PCI_EXP_LNKCTL,
9592*4882a593Smuzhiyun 							  &gpu_cfg);
9593*4882a593Smuzhiyun 
9594*4882a593Smuzhiyun 				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
9595*4882a593Smuzhiyun 							  &bridge_cfg2);
9596*4882a593Smuzhiyun 				pcie_capability_read_word(rdev->pdev,
9597*4882a593Smuzhiyun 							  PCI_EXP_LNKCTL2,
9598*4882a593Smuzhiyun 							  &gpu_cfg2);
9599*4882a593Smuzhiyun 
9600*4882a593Smuzhiyun 				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
9601*4882a593Smuzhiyun 				tmp |= LC_SET_QUIESCE;
9602*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
9603*4882a593Smuzhiyun 
9604*4882a593Smuzhiyun 				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
9605*4882a593Smuzhiyun 				tmp |= LC_REDO_EQ;
9606*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
9607*4882a593Smuzhiyun 
9608*4882a593Smuzhiyun 				msleep(100);
9609*4882a593Smuzhiyun 
9610*4882a593Smuzhiyun 				/* linkctl */
9611*4882a593Smuzhiyun 				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
9612*4882a593Smuzhiyun 							  &tmp16);
9613*4882a593Smuzhiyun 				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
9614*4882a593Smuzhiyun 				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
9615*4882a593Smuzhiyun 				pcie_capability_write_word(root, PCI_EXP_LNKCTL,
9616*4882a593Smuzhiyun 							   tmp16);
9617*4882a593Smuzhiyun 
9618*4882a593Smuzhiyun 				pcie_capability_read_word(rdev->pdev,
9619*4882a593Smuzhiyun 							  PCI_EXP_LNKCTL,
9620*4882a593Smuzhiyun 							  &tmp16);
9621*4882a593Smuzhiyun 				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
9622*4882a593Smuzhiyun 				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
9623*4882a593Smuzhiyun 				pcie_capability_write_word(rdev->pdev,
9624*4882a593Smuzhiyun 							   PCI_EXP_LNKCTL,
9625*4882a593Smuzhiyun 							   tmp16);
9626*4882a593Smuzhiyun 
9627*4882a593Smuzhiyun 				/* linkctl2 */
9628*4882a593Smuzhiyun 				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
9629*4882a593Smuzhiyun 							  &tmp16);
9630*4882a593Smuzhiyun 				tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
9631*4882a593Smuzhiyun 					   PCI_EXP_LNKCTL2_TX_MARGIN);
9632*4882a593Smuzhiyun 				tmp16 |= (bridge_cfg2 &
9633*4882a593Smuzhiyun 					  (PCI_EXP_LNKCTL2_ENTER_COMP |
9634*4882a593Smuzhiyun 					   PCI_EXP_LNKCTL2_TX_MARGIN));
9635*4882a593Smuzhiyun 				pcie_capability_write_word(root,
9636*4882a593Smuzhiyun 							   PCI_EXP_LNKCTL2,
9637*4882a593Smuzhiyun 							   tmp16);
9638*4882a593Smuzhiyun 
9639*4882a593Smuzhiyun 				pcie_capability_read_word(rdev->pdev,
9640*4882a593Smuzhiyun 							  PCI_EXP_LNKCTL2,
9641*4882a593Smuzhiyun 							  &tmp16);
9642*4882a593Smuzhiyun 				tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
9643*4882a593Smuzhiyun 					   PCI_EXP_LNKCTL2_TX_MARGIN);
9644*4882a593Smuzhiyun 				tmp16 |= (gpu_cfg2 &
9645*4882a593Smuzhiyun 					  (PCI_EXP_LNKCTL2_ENTER_COMP |
9646*4882a593Smuzhiyun 					   PCI_EXP_LNKCTL2_TX_MARGIN));
9647*4882a593Smuzhiyun 				pcie_capability_write_word(rdev->pdev,
9648*4882a593Smuzhiyun 							   PCI_EXP_LNKCTL2,
9649*4882a593Smuzhiyun 							   tmp16);
9650*4882a593Smuzhiyun 
9651*4882a593Smuzhiyun 				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
9652*4882a593Smuzhiyun 				tmp &= ~LC_SET_QUIESCE;
9653*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
9654*4882a593Smuzhiyun 			}
9655*4882a593Smuzhiyun 		}
9656*4882a593Smuzhiyun 	}
9657*4882a593Smuzhiyun 
9658*4882a593Smuzhiyun 	/* set the link speed */
9659*4882a593Smuzhiyun 	speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE;
9660*4882a593Smuzhiyun 	speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
9661*4882a593Smuzhiyun 	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
9662*4882a593Smuzhiyun 
9663*4882a593Smuzhiyun 	pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16);
9664*4882a593Smuzhiyun 	tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
9665*4882a593Smuzhiyun 	if (speed_cap == PCIE_SPEED_8_0GT)
9666*4882a593Smuzhiyun 		tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
9667*4882a593Smuzhiyun 	else if (speed_cap == PCIE_SPEED_5_0GT)
9668*4882a593Smuzhiyun 		tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
9669*4882a593Smuzhiyun 	else
9670*4882a593Smuzhiyun 		tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
9671*4882a593Smuzhiyun 	pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16);
9672*4882a593Smuzhiyun 
9673*4882a593Smuzhiyun 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
9674*4882a593Smuzhiyun 	speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
9675*4882a593Smuzhiyun 	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
9676*4882a593Smuzhiyun 
9677*4882a593Smuzhiyun 	for (i = 0; i < rdev->usec_timeout; i++) {
9678*4882a593Smuzhiyun 		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
9679*4882a593Smuzhiyun 		if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0)
9680*4882a593Smuzhiyun 			break;
9681*4882a593Smuzhiyun 		udelay(1);
9682*4882a593Smuzhiyun 	}
9683*4882a593Smuzhiyun }
9684*4882a593Smuzhiyun 
cik_program_aspm(struct radeon_device * rdev)9685*4882a593Smuzhiyun static void cik_program_aspm(struct radeon_device *rdev)
9686*4882a593Smuzhiyun {
9687*4882a593Smuzhiyun 	u32 data, orig;
9688*4882a593Smuzhiyun 	bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
9689*4882a593Smuzhiyun 	bool disable_clkreq = false;
9690*4882a593Smuzhiyun 
9691*4882a593Smuzhiyun 	if (radeon_aspm == 0)
9692*4882a593Smuzhiyun 		return;
9693*4882a593Smuzhiyun 
9694*4882a593Smuzhiyun 	/* XXX double check IGPs */
9695*4882a593Smuzhiyun 	if (rdev->flags & RADEON_IS_IGP)
9696*4882a593Smuzhiyun 		return;
9697*4882a593Smuzhiyun 
9698*4882a593Smuzhiyun 	if (!(rdev->flags & RADEON_IS_PCIE))
9699*4882a593Smuzhiyun 		return;
9700*4882a593Smuzhiyun 
9701*4882a593Smuzhiyun 	orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
9702*4882a593Smuzhiyun 	data &= ~LC_XMIT_N_FTS_MASK;
9703*4882a593Smuzhiyun 	data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
9704*4882a593Smuzhiyun 	if (orig != data)
9705*4882a593Smuzhiyun 		WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data);
9706*4882a593Smuzhiyun 
9707*4882a593Smuzhiyun 	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3);
9708*4882a593Smuzhiyun 	data |= LC_GO_TO_RECOVERY;
9709*4882a593Smuzhiyun 	if (orig != data)
9710*4882a593Smuzhiyun 		WREG32_PCIE_PORT(PCIE_LC_CNTL3, data);
9711*4882a593Smuzhiyun 
9712*4882a593Smuzhiyun 	orig = data = RREG32_PCIE_PORT(PCIE_P_CNTL);
9713*4882a593Smuzhiyun 	data |= P_IGNORE_EDB_ERR;
9714*4882a593Smuzhiyun 	if (orig != data)
9715*4882a593Smuzhiyun 		WREG32_PCIE_PORT(PCIE_P_CNTL, data);
9716*4882a593Smuzhiyun 
9717*4882a593Smuzhiyun 	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
9718*4882a593Smuzhiyun 	data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
9719*4882a593Smuzhiyun 	data |= LC_PMI_TO_L1_DIS;
9720*4882a593Smuzhiyun 	if (!disable_l0s)
9721*4882a593Smuzhiyun 		data |= LC_L0S_INACTIVITY(7);
9722*4882a593Smuzhiyun 
9723*4882a593Smuzhiyun 	if (!disable_l1) {
9724*4882a593Smuzhiyun 		data |= LC_L1_INACTIVITY(7);
9725*4882a593Smuzhiyun 		data &= ~LC_PMI_TO_L1_DIS;
9726*4882a593Smuzhiyun 		if (orig != data)
9727*4882a593Smuzhiyun 			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
9728*4882a593Smuzhiyun 
9729*4882a593Smuzhiyun 		if (!disable_plloff_in_l1) {
9730*4882a593Smuzhiyun 			bool clk_req_support;
9731*4882a593Smuzhiyun 
9732*4882a593Smuzhiyun 			orig = data = RREG32_PCIE_PORT(PB0_PIF_PWRDOWN_0);
9733*4882a593Smuzhiyun 			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
9734*4882a593Smuzhiyun 			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
9735*4882a593Smuzhiyun 			if (orig != data)
9736*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PB0_PIF_PWRDOWN_0, data);
9737*4882a593Smuzhiyun 
9738*4882a593Smuzhiyun 			orig = data = RREG32_PCIE_PORT(PB0_PIF_PWRDOWN_1);
9739*4882a593Smuzhiyun 			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
9740*4882a593Smuzhiyun 			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
9741*4882a593Smuzhiyun 			if (orig != data)
9742*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PB0_PIF_PWRDOWN_1, data);
9743*4882a593Smuzhiyun 
9744*4882a593Smuzhiyun 			orig = data = RREG32_PCIE_PORT(PB1_PIF_PWRDOWN_0);
9745*4882a593Smuzhiyun 			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
9746*4882a593Smuzhiyun 			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
9747*4882a593Smuzhiyun 			if (orig != data)
9748*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PB1_PIF_PWRDOWN_0, data);
9749*4882a593Smuzhiyun 
9750*4882a593Smuzhiyun 			orig = data = RREG32_PCIE_PORT(PB1_PIF_PWRDOWN_1);
9751*4882a593Smuzhiyun 			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
9752*4882a593Smuzhiyun 			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
9753*4882a593Smuzhiyun 			if (orig != data)
9754*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PB1_PIF_PWRDOWN_1, data);
9755*4882a593Smuzhiyun 
9756*4882a593Smuzhiyun 			orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
9757*4882a593Smuzhiyun 			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
9758*4882a593Smuzhiyun 			data |= LC_DYN_LANES_PWR_STATE(3);
9759*4882a593Smuzhiyun 			if (orig != data)
9760*4882a593Smuzhiyun 				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
9761*4882a593Smuzhiyun 
9762*4882a593Smuzhiyun 			if (!disable_clkreq &&
9763*4882a593Smuzhiyun 			    !pci_is_root_bus(rdev->pdev->bus)) {
9764*4882a593Smuzhiyun 				struct pci_dev *root = rdev->pdev->bus->self;
9765*4882a593Smuzhiyun 				u32 lnkcap;
9766*4882a593Smuzhiyun 
9767*4882a593Smuzhiyun 				clk_req_support = false;
9768*4882a593Smuzhiyun 				pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
9769*4882a593Smuzhiyun 				if (lnkcap & PCI_EXP_LNKCAP_CLKPM)
9770*4882a593Smuzhiyun 					clk_req_support = true;
9771*4882a593Smuzhiyun 			} else {
9772*4882a593Smuzhiyun 				clk_req_support = false;
9773*4882a593Smuzhiyun 			}
9774*4882a593Smuzhiyun 
9775*4882a593Smuzhiyun 			if (clk_req_support) {
9776*4882a593Smuzhiyun 				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2);
9777*4882a593Smuzhiyun 				data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23;
9778*4882a593Smuzhiyun 				if (orig != data)
9779*4882a593Smuzhiyun 					WREG32_PCIE_PORT(PCIE_LC_CNTL2, data);
9780*4882a593Smuzhiyun 
9781*4882a593Smuzhiyun 				orig = data = RREG32_SMC(THM_CLK_CNTL);
9782*4882a593Smuzhiyun 				data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK);
9783*4882a593Smuzhiyun 				data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1);
9784*4882a593Smuzhiyun 				if (orig != data)
9785*4882a593Smuzhiyun 					WREG32_SMC(THM_CLK_CNTL, data);
9786*4882a593Smuzhiyun 
9787*4882a593Smuzhiyun 				orig = data = RREG32_SMC(MISC_CLK_CTRL);
9788*4882a593Smuzhiyun 				data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK);
9789*4882a593Smuzhiyun 				data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1);
9790*4882a593Smuzhiyun 				if (orig != data)
9791*4882a593Smuzhiyun 					WREG32_SMC(MISC_CLK_CTRL, data);
9792*4882a593Smuzhiyun 
9793*4882a593Smuzhiyun 				orig = data = RREG32_SMC(CG_CLKPIN_CNTL);
9794*4882a593Smuzhiyun 				data &= ~BCLK_AS_XCLK;
9795*4882a593Smuzhiyun 				if (orig != data)
9796*4882a593Smuzhiyun 					WREG32_SMC(CG_CLKPIN_CNTL, data);
9797*4882a593Smuzhiyun 
9798*4882a593Smuzhiyun 				orig = data = RREG32_SMC(CG_CLKPIN_CNTL_2);
9799*4882a593Smuzhiyun 				data &= ~FORCE_BIF_REFCLK_EN;
9800*4882a593Smuzhiyun 				if (orig != data)
9801*4882a593Smuzhiyun 					WREG32_SMC(CG_CLKPIN_CNTL_2, data);
9802*4882a593Smuzhiyun 
9803*4882a593Smuzhiyun 				orig = data = RREG32_SMC(MPLL_BYPASSCLK_SEL);
9804*4882a593Smuzhiyun 				data &= ~MPLL_CLKOUT_SEL_MASK;
9805*4882a593Smuzhiyun 				data |= MPLL_CLKOUT_SEL(4);
9806*4882a593Smuzhiyun 				if (orig != data)
9807*4882a593Smuzhiyun 					WREG32_SMC(MPLL_BYPASSCLK_SEL, data);
9808*4882a593Smuzhiyun 			}
9809*4882a593Smuzhiyun 		}
9810*4882a593Smuzhiyun 	} else {
9811*4882a593Smuzhiyun 		if (orig != data)
9812*4882a593Smuzhiyun 			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
9813*4882a593Smuzhiyun 	}
9814*4882a593Smuzhiyun 
9815*4882a593Smuzhiyun 	orig = data = RREG32_PCIE_PORT(PCIE_CNTL2);
9816*4882a593Smuzhiyun 	data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN;
9817*4882a593Smuzhiyun 	if (orig != data)
9818*4882a593Smuzhiyun 		WREG32_PCIE_PORT(PCIE_CNTL2, data);
9819*4882a593Smuzhiyun 
9820*4882a593Smuzhiyun 	if (!disable_l0s) {
9821*4882a593Smuzhiyun 		data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
9822*4882a593Smuzhiyun 		if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) {
9823*4882a593Smuzhiyun 			data = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
9824*4882a593Smuzhiyun 			if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) {
9825*4882a593Smuzhiyun 				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
9826*4882a593Smuzhiyun 				data &= ~LC_L0S_INACTIVITY_MASK;
9827*4882a593Smuzhiyun 				if (orig != data)
9828*4882a593Smuzhiyun 					WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
9829*4882a593Smuzhiyun 			}
9830*4882a593Smuzhiyun 		}
9831*4882a593Smuzhiyun 	}
9832*4882a593Smuzhiyun }
9833