1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2011 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 #include <drm/radeon_drm.h>
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include "atom.h"
34*4882a593Smuzhiyun #include "clearstate_si.h"
35*4882a593Smuzhiyun #include "radeon.h"
36*4882a593Smuzhiyun #include "radeon_asic.h"
37*4882a593Smuzhiyun #include "radeon_audio.h"
38*4882a593Smuzhiyun #include "radeon_ucode.h"
39*4882a593Smuzhiyun #include "si_blit_shaders.h"
40*4882a593Smuzhiyun #include "sid.h"
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_pfp.bin");
44*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_me.bin");
45*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_ce.bin");
46*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
47*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
48*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
49*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/tahiti_pfp.bin");
52*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/tahiti_me.bin");
53*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/tahiti_ce.bin");
54*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/tahiti_mc.bin");
55*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/tahiti_rlc.bin");
56*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/tahiti_smc.bin");
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
59*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
60*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
61*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
62*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
63*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
64*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_pfp.bin");
67*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_me.bin");
68*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_ce.bin");
69*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_mc.bin");
70*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_rlc.bin");
71*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_smc.bin");
72*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/pitcairn_k_smc.bin");
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
75*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_me.bin");
76*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_ce.bin");
77*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_mc.bin");
78*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
79*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
80*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/VERDE_smc.bin");
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_pfp.bin");
83*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_me.bin");
84*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_ce.bin");
85*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_mc.bin");
86*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_rlc.bin");
87*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_smc.bin");
88*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/verde_k_smc.bin");
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
91*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_me.bin");
92*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_ce.bin");
93*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_mc.bin");
94*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
95*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
96*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/OLAND_smc.bin");
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_pfp.bin");
99*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_me.bin");
100*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_ce.bin");
101*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_mc.bin");
102*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_rlc.bin");
103*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_smc.bin");
104*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/oland_k_smc.bin");
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
107*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_me.bin");
108*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
109*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
110*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
111*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
112*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_pfp.bin");
115*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_me.bin");
116*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_ce.bin");
117*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_mc.bin");
118*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_rlc.bin");
119*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_smc.bin");
120*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/hainan_k_smc.bin");
121*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/banks_k_2_smc.bin");
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun MODULE_FIRMWARE("radeon/si58_mc.bin");
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
126*4882a593Smuzhiyun static void si_pcie_gen3_enable(struct radeon_device *rdev);
127*4882a593Smuzhiyun static void si_program_aspm(struct radeon_device *rdev);
128*4882a593Smuzhiyun extern void sumo_rlc_fini(struct radeon_device *rdev);
129*4882a593Smuzhiyun extern int sumo_rlc_init(struct radeon_device *rdev);
130*4882a593Smuzhiyun extern int r600_ih_ring_alloc(struct radeon_device *rdev);
131*4882a593Smuzhiyun extern void r600_ih_ring_fini(struct radeon_device *rdev);
132*4882a593Smuzhiyun extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
133*4882a593Smuzhiyun extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
134*4882a593Smuzhiyun extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
135*4882a593Smuzhiyun extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);
136*4882a593Smuzhiyun extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
137*4882a593Smuzhiyun extern bool evergreen_is_display_hung(struct radeon_device *rdev);
138*4882a593Smuzhiyun static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
139*4882a593Smuzhiyun bool enable);
140*4882a593Smuzhiyun static void si_init_pg(struct radeon_device *rdev);
141*4882a593Smuzhiyun static void si_init_cg(struct radeon_device *rdev);
142*4882a593Smuzhiyun static void si_fini_pg(struct radeon_device *rdev);
143*4882a593Smuzhiyun static void si_fini_cg(struct radeon_device *rdev);
144*4882a593Smuzhiyun static void si_rlc_stop(struct radeon_device *rdev);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun static const u32 crtc_offsets[] =
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun EVERGREEN_CRTC0_REGISTER_OFFSET,
149*4882a593Smuzhiyun EVERGREEN_CRTC1_REGISTER_OFFSET,
150*4882a593Smuzhiyun EVERGREEN_CRTC2_REGISTER_OFFSET,
151*4882a593Smuzhiyun EVERGREEN_CRTC3_REGISTER_OFFSET,
152*4882a593Smuzhiyun EVERGREEN_CRTC4_REGISTER_OFFSET,
153*4882a593Smuzhiyun EVERGREEN_CRTC5_REGISTER_OFFSET
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun static const u32 si_disp_int_status[] =
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun DISP_INTERRUPT_STATUS,
159*4882a593Smuzhiyun DISP_INTERRUPT_STATUS_CONTINUE,
160*4882a593Smuzhiyun DISP_INTERRUPT_STATUS_CONTINUE2,
161*4882a593Smuzhiyun DISP_INTERRUPT_STATUS_CONTINUE3,
162*4882a593Smuzhiyun DISP_INTERRUPT_STATUS_CONTINUE4,
163*4882a593Smuzhiyun DISP_INTERRUPT_STATUS_CONTINUE5
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun #define DC_HPDx_CONTROL(x) (DC_HPD1_CONTROL + (x * 0xc))
167*4882a593Smuzhiyun #define DC_HPDx_INT_CONTROL(x) (DC_HPD1_INT_CONTROL + (x * 0xc))
168*4882a593Smuzhiyun #define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS + (x * 0xc))
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun static const u32 verde_rlc_save_restore_register_list[] =
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun (0x8000 << 16) | (0x98f4 >> 2),
173*4882a593Smuzhiyun 0x00000000,
174*4882a593Smuzhiyun (0x8040 << 16) | (0x98f4 >> 2),
175*4882a593Smuzhiyun 0x00000000,
176*4882a593Smuzhiyun (0x8000 << 16) | (0xe80 >> 2),
177*4882a593Smuzhiyun 0x00000000,
178*4882a593Smuzhiyun (0x8040 << 16) | (0xe80 >> 2),
179*4882a593Smuzhiyun 0x00000000,
180*4882a593Smuzhiyun (0x8000 << 16) | (0x89bc >> 2),
181*4882a593Smuzhiyun 0x00000000,
182*4882a593Smuzhiyun (0x8040 << 16) | (0x89bc >> 2),
183*4882a593Smuzhiyun 0x00000000,
184*4882a593Smuzhiyun (0x8000 << 16) | (0x8c1c >> 2),
185*4882a593Smuzhiyun 0x00000000,
186*4882a593Smuzhiyun (0x8040 << 16) | (0x8c1c >> 2),
187*4882a593Smuzhiyun 0x00000000,
188*4882a593Smuzhiyun (0x9c00 << 16) | (0x98f0 >> 2),
189*4882a593Smuzhiyun 0x00000000,
190*4882a593Smuzhiyun (0x9c00 << 16) | (0xe7c >> 2),
191*4882a593Smuzhiyun 0x00000000,
192*4882a593Smuzhiyun (0x8000 << 16) | (0x9148 >> 2),
193*4882a593Smuzhiyun 0x00000000,
194*4882a593Smuzhiyun (0x8040 << 16) | (0x9148 >> 2),
195*4882a593Smuzhiyun 0x00000000,
196*4882a593Smuzhiyun (0x9c00 << 16) | (0x9150 >> 2),
197*4882a593Smuzhiyun 0x00000000,
198*4882a593Smuzhiyun (0x9c00 << 16) | (0x897c >> 2),
199*4882a593Smuzhiyun 0x00000000,
200*4882a593Smuzhiyun (0x9c00 << 16) | (0x8d8c >> 2),
201*4882a593Smuzhiyun 0x00000000,
202*4882a593Smuzhiyun (0x9c00 << 16) | (0xac54 >> 2),
203*4882a593Smuzhiyun 0X00000000,
204*4882a593Smuzhiyun 0x3,
205*4882a593Smuzhiyun (0x9c00 << 16) | (0x98f8 >> 2),
206*4882a593Smuzhiyun 0x00000000,
207*4882a593Smuzhiyun (0x9c00 << 16) | (0x9910 >> 2),
208*4882a593Smuzhiyun 0x00000000,
209*4882a593Smuzhiyun (0x9c00 << 16) | (0x9914 >> 2),
210*4882a593Smuzhiyun 0x00000000,
211*4882a593Smuzhiyun (0x9c00 << 16) | (0x9918 >> 2),
212*4882a593Smuzhiyun 0x00000000,
213*4882a593Smuzhiyun (0x9c00 << 16) | (0x991c >> 2),
214*4882a593Smuzhiyun 0x00000000,
215*4882a593Smuzhiyun (0x9c00 << 16) | (0x9920 >> 2),
216*4882a593Smuzhiyun 0x00000000,
217*4882a593Smuzhiyun (0x9c00 << 16) | (0x9924 >> 2),
218*4882a593Smuzhiyun 0x00000000,
219*4882a593Smuzhiyun (0x9c00 << 16) | (0x9928 >> 2),
220*4882a593Smuzhiyun 0x00000000,
221*4882a593Smuzhiyun (0x9c00 << 16) | (0x992c >> 2),
222*4882a593Smuzhiyun 0x00000000,
223*4882a593Smuzhiyun (0x9c00 << 16) | (0x9930 >> 2),
224*4882a593Smuzhiyun 0x00000000,
225*4882a593Smuzhiyun (0x9c00 << 16) | (0x9934 >> 2),
226*4882a593Smuzhiyun 0x00000000,
227*4882a593Smuzhiyun (0x9c00 << 16) | (0x9938 >> 2),
228*4882a593Smuzhiyun 0x00000000,
229*4882a593Smuzhiyun (0x9c00 << 16) | (0x993c >> 2),
230*4882a593Smuzhiyun 0x00000000,
231*4882a593Smuzhiyun (0x9c00 << 16) | (0x9940 >> 2),
232*4882a593Smuzhiyun 0x00000000,
233*4882a593Smuzhiyun (0x9c00 << 16) | (0x9944 >> 2),
234*4882a593Smuzhiyun 0x00000000,
235*4882a593Smuzhiyun (0x9c00 << 16) | (0x9948 >> 2),
236*4882a593Smuzhiyun 0x00000000,
237*4882a593Smuzhiyun (0x9c00 << 16) | (0x994c >> 2),
238*4882a593Smuzhiyun 0x00000000,
239*4882a593Smuzhiyun (0x9c00 << 16) | (0x9950 >> 2),
240*4882a593Smuzhiyun 0x00000000,
241*4882a593Smuzhiyun (0x9c00 << 16) | (0x9954 >> 2),
242*4882a593Smuzhiyun 0x00000000,
243*4882a593Smuzhiyun (0x9c00 << 16) | (0x9958 >> 2),
244*4882a593Smuzhiyun 0x00000000,
245*4882a593Smuzhiyun (0x9c00 << 16) | (0x995c >> 2),
246*4882a593Smuzhiyun 0x00000000,
247*4882a593Smuzhiyun (0x9c00 << 16) | (0x9960 >> 2),
248*4882a593Smuzhiyun 0x00000000,
249*4882a593Smuzhiyun (0x9c00 << 16) | (0x9964 >> 2),
250*4882a593Smuzhiyun 0x00000000,
251*4882a593Smuzhiyun (0x9c00 << 16) | (0x9968 >> 2),
252*4882a593Smuzhiyun 0x00000000,
253*4882a593Smuzhiyun (0x9c00 << 16) | (0x996c >> 2),
254*4882a593Smuzhiyun 0x00000000,
255*4882a593Smuzhiyun (0x9c00 << 16) | (0x9970 >> 2),
256*4882a593Smuzhiyun 0x00000000,
257*4882a593Smuzhiyun (0x9c00 << 16) | (0x9974 >> 2),
258*4882a593Smuzhiyun 0x00000000,
259*4882a593Smuzhiyun (0x9c00 << 16) | (0x9978 >> 2),
260*4882a593Smuzhiyun 0x00000000,
261*4882a593Smuzhiyun (0x9c00 << 16) | (0x997c >> 2),
262*4882a593Smuzhiyun 0x00000000,
263*4882a593Smuzhiyun (0x9c00 << 16) | (0x9980 >> 2),
264*4882a593Smuzhiyun 0x00000000,
265*4882a593Smuzhiyun (0x9c00 << 16) | (0x9984 >> 2),
266*4882a593Smuzhiyun 0x00000000,
267*4882a593Smuzhiyun (0x9c00 << 16) | (0x9988 >> 2),
268*4882a593Smuzhiyun 0x00000000,
269*4882a593Smuzhiyun (0x9c00 << 16) | (0x998c >> 2),
270*4882a593Smuzhiyun 0x00000000,
271*4882a593Smuzhiyun (0x9c00 << 16) | (0x8c00 >> 2),
272*4882a593Smuzhiyun 0x00000000,
273*4882a593Smuzhiyun (0x9c00 << 16) | (0x8c14 >> 2),
274*4882a593Smuzhiyun 0x00000000,
275*4882a593Smuzhiyun (0x9c00 << 16) | (0x8c04 >> 2),
276*4882a593Smuzhiyun 0x00000000,
277*4882a593Smuzhiyun (0x9c00 << 16) | (0x8c08 >> 2),
278*4882a593Smuzhiyun 0x00000000,
279*4882a593Smuzhiyun (0x8000 << 16) | (0x9b7c >> 2),
280*4882a593Smuzhiyun 0x00000000,
281*4882a593Smuzhiyun (0x8040 << 16) | (0x9b7c >> 2),
282*4882a593Smuzhiyun 0x00000000,
283*4882a593Smuzhiyun (0x8000 << 16) | (0xe84 >> 2),
284*4882a593Smuzhiyun 0x00000000,
285*4882a593Smuzhiyun (0x8040 << 16) | (0xe84 >> 2),
286*4882a593Smuzhiyun 0x00000000,
287*4882a593Smuzhiyun (0x8000 << 16) | (0x89c0 >> 2),
288*4882a593Smuzhiyun 0x00000000,
289*4882a593Smuzhiyun (0x8040 << 16) | (0x89c0 >> 2),
290*4882a593Smuzhiyun 0x00000000,
291*4882a593Smuzhiyun (0x8000 << 16) | (0x914c >> 2),
292*4882a593Smuzhiyun 0x00000000,
293*4882a593Smuzhiyun (0x8040 << 16) | (0x914c >> 2),
294*4882a593Smuzhiyun 0x00000000,
295*4882a593Smuzhiyun (0x8000 << 16) | (0x8c20 >> 2),
296*4882a593Smuzhiyun 0x00000000,
297*4882a593Smuzhiyun (0x8040 << 16) | (0x8c20 >> 2),
298*4882a593Smuzhiyun 0x00000000,
299*4882a593Smuzhiyun (0x8000 << 16) | (0x9354 >> 2),
300*4882a593Smuzhiyun 0x00000000,
301*4882a593Smuzhiyun (0x8040 << 16) | (0x9354 >> 2),
302*4882a593Smuzhiyun 0x00000000,
303*4882a593Smuzhiyun (0x9c00 << 16) | (0x9060 >> 2),
304*4882a593Smuzhiyun 0x00000000,
305*4882a593Smuzhiyun (0x9c00 << 16) | (0x9364 >> 2),
306*4882a593Smuzhiyun 0x00000000,
307*4882a593Smuzhiyun (0x9c00 << 16) | (0x9100 >> 2),
308*4882a593Smuzhiyun 0x00000000,
309*4882a593Smuzhiyun (0x9c00 << 16) | (0x913c >> 2),
310*4882a593Smuzhiyun 0x00000000,
311*4882a593Smuzhiyun (0x8000 << 16) | (0x90e0 >> 2),
312*4882a593Smuzhiyun 0x00000000,
313*4882a593Smuzhiyun (0x8000 << 16) | (0x90e4 >> 2),
314*4882a593Smuzhiyun 0x00000000,
315*4882a593Smuzhiyun (0x8000 << 16) | (0x90e8 >> 2),
316*4882a593Smuzhiyun 0x00000000,
317*4882a593Smuzhiyun (0x8040 << 16) | (0x90e0 >> 2),
318*4882a593Smuzhiyun 0x00000000,
319*4882a593Smuzhiyun (0x8040 << 16) | (0x90e4 >> 2),
320*4882a593Smuzhiyun 0x00000000,
321*4882a593Smuzhiyun (0x8040 << 16) | (0x90e8 >> 2),
322*4882a593Smuzhiyun 0x00000000,
323*4882a593Smuzhiyun (0x9c00 << 16) | (0x8bcc >> 2),
324*4882a593Smuzhiyun 0x00000000,
325*4882a593Smuzhiyun (0x9c00 << 16) | (0x8b24 >> 2),
326*4882a593Smuzhiyun 0x00000000,
327*4882a593Smuzhiyun (0x9c00 << 16) | (0x88c4 >> 2),
328*4882a593Smuzhiyun 0x00000000,
329*4882a593Smuzhiyun (0x9c00 << 16) | (0x8e50 >> 2),
330*4882a593Smuzhiyun 0x00000000,
331*4882a593Smuzhiyun (0x9c00 << 16) | (0x8c0c >> 2),
332*4882a593Smuzhiyun 0x00000000,
333*4882a593Smuzhiyun (0x9c00 << 16) | (0x8e58 >> 2),
334*4882a593Smuzhiyun 0x00000000,
335*4882a593Smuzhiyun (0x9c00 << 16) | (0x8e5c >> 2),
336*4882a593Smuzhiyun 0x00000000,
337*4882a593Smuzhiyun (0x9c00 << 16) | (0x9508 >> 2),
338*4882a593Smuzhiyun 0x00000000,
339*4882a593Smuzhiyun (0x9c00 << 16) | (0x950c >> 2),
340*4882a593Smuzhiyun 0x00000000,
341*4882a593Smuzhiyun (0x9c00 << 16) | (0x9494 >> 2),
342*4882a593Smuzhiyun 0x00000000,
343*4882a593Smuzhiyun (0x9c00 << 16) | (0xac0c >> 2),
344*4882a593Smuzhiyun 0x00000000,
345*4882a593Smuzhiyun (0x9c00 << 16) | (0xac10 >> 2),
346*4882a593Smuzhiyun 0x00000000,
347*4882a593Smuzhiyun (0x9c00 << 16) | (0xac14 >> 2),
348*4882a593Smuzhiyun 0x00000000,
349*4882a593Smuzhiyun (0x9c00 << 16) | (0xae00 >> 2),
350*4882a593Smuzhiyun 0x00000000,
351*4882a593Smuzhiyun (0x9c00 << 16) | (0xac08 >> 2),
352*4882a593Smuzhiyun 0x00000000,
353*4882a593Smuzhiyun (0x9c00 << 16) | (0x88d4 >> 2),
354*4882a593Smuzhiyun 0x00000000,
355*4882a593Smuzhiyun (0x9c00 << 16) | (0x88c8 >> 2),
356*4882a593Smuzhiyun 0x00000000,
357*4882a593Smuzhiyun (0x9c00 << 16) | (0x88cc >> 2),
358*4882a593Smuzhiyun 0x00000000,
359*4882a593Smuzhiyun (0x9c00 << 16) | (0x89b0 >> 2),
360*4882a593Smuzhiyun 0x00000000,
361*4882a593Smuzhiyun (0x9c00 << 16) | (0x8b10 >> 2),
362*4882a593Smuzhiyun 0x00000000,
363*4882a593Smuzhiyun (0x9c00 << 16) | (0x8a14 >> 2),
364*4882a593Smuzhiyun 0x00000000,
365*4882a593Smuzhiyun (0x9c00 << 16) | (0x9830 >> 2),
366*4882a593Smuzhiyun 0x00000000,
367*4882a593Smuzhiyun (0x9c00 << 16) | (0x9834 >> 2),
368*4882a593Smuzhiyun 0x00000000,
369*4882a593Smuzhiyun (0x9c00 << 16) | (0x9838 >> 2),
370*4882a593Smuzhiyun 0x00000000,
371*4882a593Smuzhiyun (0x9c00 << 16) | (0x9a10 >> 2),
372*4882a593Smuzhiyun 0x00000000,
373*4882a593Smuzhiyun (0x8000 << 16) | (0x9870 >> 2),
374*4882a593Smuzhiyun 0x00000000,
375*4882a593Smuzhiyun (0x8000 << 16) | (0x9874 >> 2),
376*4882a593Smuzhiyun 0x00000000,
377*4882a593Smuzhiyun (0x8001 << 16) | (0x9870 >> 2),
378*4882a593Smuzhiyun 0x00000000,
379*4882a593Smuzhiyun (0x8001 << 16) | (0x9874 >> 2),
380*4882a593Smuzhiyun 0x00000000,
381*4882a593Smuzhiyun (0x8040 << 16) | (0x9870 >> 2),
382*4882a593Smuzhiyun 0x00000000,
383*4882a593Smuzhiyun (0x8040 << 16) | (0x9874 >> 2),
384*4882a593Smuzhiyun 0x00000000,
385*4882a593Smuzhiyun (0x8041 << 16) | (0x9870 >> 2),
386*4882a593Smuzhiyun 0x00000000,
387*4882a593Smuzhiyun (0x8041 << 16) | (0x9874 >> 2),
388*4882a593Smuzhiyun 0x00000000,
389*4882a593Smuzhiyun 0x00000000
390*4882a593Smuzhiyun };
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun static const u32 tahiti_golden_rlc_registers[] =
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun 0xc424, 0xffffffff, 0x00601005,
395*4882a593Smuzhiyun 0xc47c, 0xffffffff, 0x10104040,
396*4882a593Smuzhiyun 0xc488, 0xffffffff, 0x0100000a,
397*4882a593Smuzhiyun 0xc314, 0xffffffff, 0x00000800,
398*4882a593Smuzhiyun 0xc30c, 0xffffffff, 0x800000f4,
399*4882a593Smuzhiyun 0xf4a8, 0xffffffff, 0x00000000
400*4882a593Smuzhiyun };
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun static const u32 tahiti_golden_registers[] =
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun 0x9a10, 0x00010000, 0x00018208,
405*4882a593Smuzhiyun 0x9830, 0xffffffff, 0x00000000,
406*4882a593Smuzhiyun 0x9834, 0xf00fffff, 0x00000400,
407*4882a593Smuzhiyun 0x9838, 0x0002021c, 0x00020200,
408*4882a593Smuzhiyun 0xc78, 0x00000080, 0x00000000,
409*4882a593Smuzhiyun 0xd030, 0x000300c0, 0x00800040,
410*4882a593Smuzhiyun 0xd830, 0x000300c0, 0x00800040,
411*4882a593Smuzhiyun 0x5bb0, 0x000000f0, 0x00000070,
412*4882a593Smuzhiyun 0x5bc0, 0x00200000, 0x50100000,
413*4882a593Smuzhiyun 0x7030, 0x31000311, 0x00000011,
414*4882a593Smuzhiyun 0x277c, 0x00000003, 0x000007ff,
415*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
416*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
417*4882a593Smuzhiyun 0x8b24, 0xffffffff, 0x00ffffff,
418*4882a593Smuzhiyun 0x8b10, 0x0000ff0f, 0x00000000,
419*4882a593Smuzhiyun 0x28a4c, 0x07ffffff, 0x4e000000,
420*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x2a00126a,
421*4882a593Smuzhiyun 0x30, 0x000000ff, 0x0040,
422*4882a593Smuzhiyun 0x34, 0x00000040, 0x00004040,
423*4882a593Smuzhiyun 0x9100, 0x07ffffff, 0x03000000,
424*4882a593Smuzhiyun 0x8e88, 0x01ff1f3f, 0x00000000,
425*4882a593Smuzhiyun 0x8e84, 0x01ff1f3f, 0x00000000,
426*4882a593Smuzhiyun 0x9060, 0x0000007f, 0x00000020,
427*4882a593Smuzhiyun 0x9508, 0x00010000, 0x00010000,
428*4882a593Smuzhiyun 0xac14, 0x00000200, 0x000002fb,
429*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x0000543b,
430*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0xa9210876,
431*4882a593Smuzhiyun 0x88d0, 0xffffffff, 0x000fff40,
432*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
433*4882a593Smuzhiyun 0x1410, 0x20000000, 0x20fffed8,
434*4882a593Smuzhiyun 0x15c0, 0x000c0fc0, 0x000c0400
435*4882a593Smuzhiyun };
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun static const u32 tahiti_golden_registers2[] =
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 0xc64, 0x00000001, 0x00000001
440*4882a593Smuzhiyun };
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun static const u32 pitcairn_golden_rlc_registers[] =
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun 0xc424, 0xffffffff, 0x00601004,
445*4882a593Smuzhiyun 0xc47c, 0xffffffff, 0x10102020,
446*4882a593Smuzhiyun 0xc488, 0xffffffff, 0x01000020,
447*4882a593Smuzhiyun 0xc314, 0xffffffff, 0x00000800,
448*4882a593Smuzhiyun 0xc30c, 0xffffffff, 0x800000a4
449*4882a593Smuzhiyun };
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun static const u32 pitcairn_golden_registers[] =
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 0x9a10, 0x00010000, 0x00018208,
454*4882a593Smuzhiyun 0x9830, 0xffffffff, 0x00000000,
455*4882a593Smuzhiyun 0x9834, 0xf00fffff, 0x00000400,
456*4882a593Smuzhiyun 0x9838, 0x0002021c, 0x00020200,
457*4882a593Smuzhiyun 0xc78, 0x00000080, 0x00000000,
458*4882a593Smuzhiyun 0xd030, 0x000300c0, 0x00800040,
459*4882a593Smuzhiyun 0xd830, 0x000300c0, 0x00800040,
460*4882a593Smuzhiyun 0x5bb0, 0x000000f0, 0x00000070,
461*4882a593Smuzhiyun 0x5bc0, 0x00200000, 0x50100000,
462*4882a593Smuzhiyun 0x7030, 0x31000311, 0x00000011,
463*4882a593Smuzhiyun 0x2ae4, 0x00073ffe, 0x000022a2,
464*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
465*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
466*4882a593Smuzhiyun 0x8b24, 0xffffffff, 0x00ffffff,
467*4882a593Smuzhiyun 0x8b10, 0x0000ff0f, 0x00000000,
468*4882a593Smuzhiyun 0x28a4c, 0x07ffffff, 0x4e000000,
469*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x2a00126a,
470*4882a593Smuzhiyun 0x30, 0x000000ff, 0x0040,
471*4882a593Smuzhiyun 0x34, 0x00000040, 0x00004040,
472*4882a593Smuzhiyun 0x9100, 0x07ffffff, 0x03000000,
473*4882a593Smuzhiyun 0x9060, 0x0000007f, 0x00000020,
474*4882a593Smuzhiyun 0x9508, 0x00010000, 0x00010000,
475*4882a593Smuzhiyun 0xac14, 0x000003ff, 0x000000f7,
476*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x00000000,
477*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0x32761054,
478*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
479*4882a593Smuzhiyun 0x15c0, 0x000c0fc0, 0x000c0400
480*4882a593Smuzhiyun };
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun static const u32 verde_golden_rlc_registers[] =
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun 0xc424, 0xffffffff, 0x033f1005,
485*4882a593Smuzhiyun 0xc47c, 0xffffffff, 0x10808020,
486*4882a593Smuzhiyun 0xc488, 0xffffffff, 0x00800008,
487*4882a593Smuzhiyun 0xc314, 0xffffffff, 0x00001000,
488*4882a593Smuzhiyun 0xc30c, 0xffffffff, 0x80010014
489*4882a593Smuzhiyun };
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun static const u32 verde_golden_registers[] =
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun 0x9a10, 0x00010000, 0x00018208,
494*4882a593Smuzhiyun 0x9830, 0xffffffff, 0x00000000,
495*4882a593Smuzhiyun 0x9834, 0xf00fffff, 0x00000400,
496*4882a593Smuzhiyun 0x9838, 0x0002021c, 0x00020200,
497*4882a593Smuzhiyun 0xc78, 0x00000080, 0x00000000,
498*4882a593Smuzhiyun 0xd030, 0x000300c0, 0x00800040,
499*4882a593Smuzhiyun 0xd030, 0x000300c0, 0x00800040,
500*4882a593Smuzhiyun 0xd830, 0x000300c0, 0x00800040,
501*4882a593Smuzhiyun 0xd830, 0x000300c0, 0x00800040,
502*4882a593Smuzhiyun 0x5bb0, 0x000000f0, 0x00000070,
503*4882a593Smuzhiyun 0x5bc0, 0x00200000, 0x50100000,
504*4882a593Smuzhiyun 0x7030, 0x31000311, 0x00000011,
505*4882a593Smuzhiyun 0x2ae4, 0x00073ffe, 0x000022a2,
506*4882a593Smuzhiyun 0x2ae4, 0x00073ffe, 0x000022a2,
507*4882a593Smuzhiyun 0x2ae4, 0x00073ffe, 0x000022a2,
508*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
509*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
510*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
511*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
512*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
513*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
514*4882a593Smuzhiyun 0x8b24, 0xffffffff, 0x00ffffff,
515*4882a593Smuzhiyun 0x8b10, 0x0000ff0f, 0x00000000,
516*4882a593Smuzhiyun 0x28a4c, 0x07ffffff, 0x4e000000,
517*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x0000124a,
518*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x0000124a,
519*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x0000124a,
520*4882a593Smuzhiyun 0x30, 0x000000ff, 0x0040,
521*4882a593Smuzhiyun 0x34, 0x00000040, 0x00004040,
522*4882a593Smuzhiyun 0x9100, 0x07ffffff, 0x03000000,
523*4882a593Smuzhiyun 0x9100, 0x07ffffff, 0x03000000,
524*4882a593Smuzhiyun 0x8e88, 0x01ff1f3f, 0x00000000,
525*4882a593Smuzhiyun 0x8e88, 0x01ff1f3f, 0x00000000,
526*4882a593Smuzhiyun 0x8e88, 0x01ff1f3f, 0x00000000,
527*4882a593Smuzhiyun 0x8e84, 0x01ff1f3f, 0x00000000,
528*4882a593Smuzhiyun 0x8e84, 0x01ff1f3f, 0x00000000,
529*4882a593Smuzhiyun 0x8e84, 0x01ff1f3f, 0x00000000,
530*4882a593Smuzhiyun 0x9060, 0x0000007f, 0x00000020,
531*4882a593Smuzhiyun 0x9508, 0x00010000, 0x00010000,
532*4882a593Smuzhiyun 0xac14, 0x000003ff, 0x00000003,
533*4882a593Smuzhiyun 0xac14, 0x000003ff, 0x00000003,
534*4882a593Smuzhiyun 0xac14, 0x000003ff, 0x00000003,
535*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x00000000,
536*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x00000000,
537*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x00000000,
538*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0x00001032,
539*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0x00001032,
540*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0x00001032,
541*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
542*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
543*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
544*4882a593Smuzhiyun 0x15c0, 0x000c0fc0, 0x000c0400
545*4882a593Smuzhiyun };
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun static const u32 oland_golden_rlc_registers[] =
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun 0xc424, 0xffffffff, 0x00601005,
550*4882a593Smuzhiyun 0xc47c, 0xffffffff, 0x10104040,
551*4882a593Smuzhiyun 0xc488, 0xffffffff, 0x0100000a,
552*4882a593Smuzhiyun 0xc314, 0xffffffff, 0x00000800,
553*4882a593Smuzhiyun 0xc30c, 0xffffffff, 0x800000f4
554*4882a593Smuzhiyun };
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun static const u32 oland_golden_registers[] =
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun 0x9a10, 0x00010000, 0x00018208,
559*4882a593Smuzhiyun 0x9830, 0xffffffff, 0x00000000,
560*4882a593Smuzhiyun 0x9834, 0xf00fffff, 0x00000400,
561*4882a593Smuzhiyun 0x9838, 0x0002021c, 0x00020200,
562*4882a593Smuzhiyun 0xc78, 0x00000080, 0x00000000,
563*4882a593Smuzhiyun 0xd030, 0x000300c0, 0x00800040,
564*4882a593Smuzhiyun 0xd830, 0x000300c0, 0x00800040,
565*4882a593Smuzhiyun 0x5bb0, 0x000000f0, 0x00000070,
566*4882a593Smuzhiyun 0x5bc0, 0x00200000, 0x50100000,
567*4882a593Smuzhiyun 0x7030, 0x31000311, 0x00000011,
568*4882a593Smuzhiyun 0x2ae4, 0x00073ffe, 0x000022a2,
569*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
570*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
571*4882a593Smuzhiyun 0x8b24, 0xffffffff, 0x00ffffff,
572*4882a593Smuzhiyun 0x8b10, 0x0000ff0f, 0x00000000,
573*4882a593Smuzhiyun 0x28a4c, 0x07ffffff, 0x4e000000,
574*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x00000082,
575*4882a593Smuzhiyun 0x30, 0x000000ff, 0x0040,
576*4882a593Smuzhiyun 0x34, 0x00000040, 0x00004040,
577*4882a593Smuzhiyun 0x9100, 0x07ffffff, 0x03000000,
578*4882a593Smuzhiyun 0x9060, 0x0000007f, 0x00000020,
579*4882a593Smuzhiyun 0x9508, 0x00010000, 0x00010000,
580*4882a593Smuzhiyun 0xac14, 0x000003ff, 0x000000f3,
581*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x00000000,
582*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0x00003210,
583*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
584*4882a593Smuzhiyun 0x15c0, 0x000c0fc0, 0x000c0400
585*4882a593Smuzhiyun };
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun static const u32 hainan_golden_registers[] =
588*4882a593Smuzhiyun {
589*4882a593Smuzhiyun 0x9a10, 0x00010000, 0x00018208,
590*4882a593Smuzhiyun 0x9830, 0xffffffff, 0x00000000,
591*4882a593Smuzhiyun 0x9834, 0xf00fffff, 0x00000400,
592*4882a593Smuzhiyun 0x9838, 0x0002021c, 0x00020200,
593*4882a593Smuzhiyun 0xd0c0, 0xff000fff, 0x00000100,
594*4882a593Smuzhiyun 0xd030, 0x000300c0, 0x00800040,
595*4882a593Smuzhiyun 0xd8c0, 0xff000fff, 0x00000100,
596*4882a593Smuzhiyun 0xd830, 0x000300c0, 0x00800040,
597*4882a593Smuzhiyun 0x2ae4, 0x00073ffe, 0x000022a2,
598*4882a593Smuzhiyun 0x240c, 0x000007ff, 0x00000000,
599*4882a593Smuzhiyun 0x8a14, 0xf000001f, 0x00000007,
600*4882a593Smuzhiyun 0x8b24, 0xffffffff, 0x00ffffff,
601*4882a593Smuzhiyun 0x8b10, 0x0000ff0f, 0x00000000,
602*4882a593Smuzhiyun 0x28a4c, 0x07ffffff, 0x4e000000,
603*4882a593Smuzhiyun 0x28350, 0x3f3f3fff, 0x00000000,
604*4882a593Smuzhiyun 0x30, 0x000000ff, 0x0040,
605*4882a593Smuzhiyun 0x34, 0x00000040, 0x00004040,
606*4882a593Smuzhiyun 0x9100, 0x03e00000, 0x03600000,
607*4882a593Smuzhiyun 0x9060, 0x0000007f, 0x00000020,
608*4882a593Smuzhiyun 0x9508, 0x00010000, 0x00010000,
609*4882a593Smuzhiyun 0xac14, 0x000003ff, 0x000000f1,
610*4882a593Smuzhiyun 0xac10, 0xffffffff, 0x00000000,
611*4882a593Smuzhiyun 0xac0c, 0xffffffff, 0x00003210,
612*4882a593Smuzhiyun 0x88d4, 0x0000001f, 0x00000010,
613*4882a593Smuzhiyun 0x15c0, 0x000c0fc0, 0x000c0400
614*4882a593Smuzhiyun };
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun static const u32 hainan_golden_registers2[] =
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun 0x98f8, 0xffffffff, 0x02010001
619*4882a593Smuzhiyun };
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun static const u32 tahiti_mgcg_cgcg_init[] =
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 0xc400, 0xffffffff, 0xfffffffc,
624*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
625*4882a593Smuzhiyun 0x9a60, 0xffffffff, 0x00000100,
626*4882a593Smuzhiyun 0x92a4, 0xffffffff, 0x00000100,
627*4882a593Smuzhiyun 0xc164, 0xffffffff, 0x00000100,
628*4882a593Smuzhiyun 0x9774, 0xffffffff, 0x00000100,
629*4882a593Smuzhiyun 0x8984, 0xffffffff, 0x06000100,
630*4882a593Smuzhiyun 0x8a18, 0xffffffff, 0x00000100,
631*4882a593Smuzhiyun 0x92a0, 0xffffffff, 0x00000100,
632*4882a593Smuzhiyun 0xc380, 0xffffffff, 0x00000100,
633*4882a593Smuzhiyun 0x8b28, 0xffffffff, 0x00000100,
634*4882a593Smuzhiyun 0x9144, 0xffffffff, 0x00000100,
635*4882a593Smuzhiyun 0x8d88, 0xffffffff, 0x00000100,
636*4882a593Smuzhiyun 0x8d8c, 0xffffffff, 0x00000100,
637*4882a593Smuzhiyun 0x9030, 0xffffffff, 0x00000100,
638*4882a593Smuzhiyun 0x9034, 0xffffffff, 0x00000100,
639*4882a593Smuzhiyun 0x9038, 0xffffffff, 0x00000100,
640*4882a593Smuzhiyun 0x903c, 0xffffffff, 0x00000100,
641*4882a593Smuzhiyun 0xad80, 0xffffffff, 0x00000100,
642*4882a593Smuzhiyun 0xac54, 0xffffffff, 0x00000100,
643*4882a593Smuzhiyun 0x897c, 0xffffffff, 0x06000100,
644*4882a593Smuzhiyun 0x9868, 0xffffffff, 0x00000100,
645*4882a593Smuzhiyun 0x9510, 0xffffffff, 0x00000100,
646*4882a593Smuzhiyun 0xaf04, 0xffffffff, 0x00000100,
647*4882a593Smuzhiyun 0xae04, 0xffffffff, 0x00000100,
648*4882a593Smuzhiyun 0x949c, 0xffffffff, 0x00000100,
649*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
650*4882a593Smuzhiyun 0x9160, 0xffffffff, 0x00010000,
651*4882a593Smuzhiyun 0x9164, 0xffffffff, 0x00030002,
652*4882a593Smuzhiyun 0x9168, 0xffffffff, 0x00040007,
653*4882a593Smuzhiyun 0x916c, 0xffffffff, 0x00060005,
654*4882a593Smuzhiyun 0x9170, 0xffffffff, 0x00090008,
655*4882a593Smuzhiyun 0x9174, 0xffffffff, 0x00020001,
656*4882a593Smuzhiyun 0x9178, 0xffffffff, 0x00040003,
657*4882a593Smuzhiyun 0x917c, 0xffffffff, 0x00000007,
658*4882a593Smuzhiyun 0x9180, 0xffffffff, 0x00060005,
659*4882a593Smuzhiyun 0x9184, 0xffffffff, 0x00090008,
660*4882a593Smuzhiyun 0x9188, 0xffffffff, 0x00030002,
661*4882a593Smuzhiyun 0x918c, 0xffffffff, 0x00050004,
662*4882a593Smuzhiyun 0x9190, 0xffffffff, 0x00000008,
663*4882a593Smuzhiyun 0x9194, 0xffffffff, 0x00070006,
664*4882a593Smuzhiyun 0x9198, 0xffffffff, 0x000a0009,
665*4882a593Smuzhiyun 0x919c, 0xffffffff, 0x00040003,
666*4882a593Smuzhiyun 0x91a0, 0xffffffff, 0x00060005,
667*4882a593Smuzhiyun 0x91a4, 0xffffffff, 0x00000009,
668*4882a593Smuzhiyun 0x91a8, 0xffffffff, 0x00080007,
669*4882a593Smuzhiyun 0x91ac, 0xffffffff, 0x000b000a,
670*4882a593Smuzhiyun 0x91b0, 0xffffffff, 0x00050004,
671*4882a593Smuzhiyun 0x91b4, 0xffffffff, 0x00070006,
672*4882a593Smuzhiyun 0x91b8, 0xffffffff, 0x0008000b,
673*4882a593Smuzhiyun 0x91bc, 0xffffffff, 0x000a0009,
674*4882a593Smuzhiyun 0x91c0, 0xffffffff, 0x000d000c,
675*4882a593Smuzhiyun 0x91c4, 0xffffffff, 0x00060005,
676*4882a593Smuzhiyun 0x91c8, 0xffffffff, 0x00080007,
677*4882a593Smuzhiyun 0x91cc, 0xffffffff, 0x0000000b,
678*4882a593Smuzhiyun 0x91d0, 0xffffffff, 0x000a0009,
679*4882a593Smuzhiyun 0x91d4, 0xffffffff, 0x000d000c,
680*4882a593Smuzhiyun 0x91d8, 0xffffffff, 0x00070006,
681*4882a593Smuzhiyun 0x91dc, 0xffffffff, 0x00090008,
682*4882a593Smuzhiyun 0x91e0, 0xffffffff, 0x0000000c,
683*4882a593Smuzhiyun 0x91e4, 0xffffffff, 0x000b000a,
684*4882a593Smuzhiyun 0x91e8, 0xffffffff, 0x000e000d,
685*4882a593Smuzhiyun 0x91ec, 0xffffffff, 0x00080007,
686*4882a593Smuzhiyun 0x91f0, 0xffffffff, 0x000a0009,
687*4882a593Smuzhiyun 0x91f4, 0xffffffff, 0x0000000d,
688*4882a593Smuzhiyun 0x91f8, 0xffffffff, 0x000c000b,
689*4882a593Smuzhiyun 0x91fc, 0xffffffff, 0x000f000e,
690*4882a593Smuzhiyun 0x9200, 0xffffffff, 0x00090008,
691*4882a593Smuzhiyun 0x9204, 0xffffffff, 0x000b000a,
692*4882a593Smuzhiyun 0x9208, 0xffffffff, 0x000c000f,
693*4882a593Smuzhiyun 0x920c, 0xffffffff, 0x000e000d,
694*4882a593Smuzhiyun 0x9210, 0xffffffff, 0x00110010,
695*4882a593Smuzhiyun 0x9214, 0xffffffff, 0x000a0009,
696*4882a593Smuzhiyun 0x9218, 0xffffffff, 0x000c000b,
697*4882a593Smuzhiyun 0x921c, 0xffffffff, 0x0000000f,
698*4882a593Smuzhiyun 0x9220, 0xffffffff, 0x000e000d,
699*4882a593Smuzhiyun 0x9224, 0xffffffff, 0x00110010,
700*4882a593Smuzhiyun 0x9228, 0xffffffff, 0x000b000a,
701*4882a593Smuzhiyun 0x922c, 0xffffffff, 0x000d000c,
702*4882a593Smuzhiyun 0x9230, 0xffffffff, 0x00000010,
703*4882a593Smuzhiyun 0x9234, 0xffffffff, 0x000f000e,
704*4882a593Smuzhiyun 0x9238, 0xffffffff, 0x00120011,
705*4882a593Smuzhiyun 0x923c, 0xffffffff, 0x000c000b,
706*4882a593Smuzhiyun 0x9240, 0xffffffff, 0x000e000d,
707*4882a593Smuzhiyun 0x9244, 0xffffffff, 0x00000011,
708*4882a593Smuzhiyun 0x9248, 0xffffffff, 0x0010000f,
709*4882a593Smuzhiyun 0x924c, 0xffffffff, 0x00130012,
710*4882a593Smuzhiyun 0x9250, 0xffffffff, 0x000d000c,
711*4882a593Smuzhiyun 0x9254, 0xffffffff, 0x000f000e,
712*4882a593Smuzhiyun 0x9258, 0xffffffff, 0x00100013,
713*4882a593Smuzhiyun 0x925c, 0xffffffff, 0x00120011,
714*4882a593Smuzhiyun 0x9260, 0xffffffff, 0x00150014,
715*4882a593Smuzhiyun 0x9264, 0xffffffff, 0x000e000d,
716*4882a593Smuzhiyun 0x9268, 0xffffffff, 0x0010000f,
717*4882a593Smuzhiyun 0x926c, 0xffffffff, 0x00000013,
718*4882a593Smuzhiyun 0x9270, 0xffffffff, 0x00120011,
719*4882a593Smuzhiyun 0x9274, 0xffffffff, 0x00150014,
720*4882a593Smuzhiyun 0x9278, 0xffffffff, 0x000f000e,
721*4882a593Smuzhiyun 0x927c, 0xffffffff, 0x00110010,
722*4882a593Smuzhiyun 0x9280, 0xffffffff, 0x00000014,
723*4882a593Smuzhiyun 0x9284, 0xffffffff, 0x00130012,
724*4882a593Smuzhiyun 0x9288, 0xffffffff, 0x00160015,
725*4882a593Smuzhiyun 0x928c, 0xffffffff, 0x0010000f,
726*4882a593Smuzhiyun 0x9290, 0xffffffff, 0x00120011,
727*4882a593Smuzhiyun 0x9294, 0xffffffff, 0x00000015,
728*4882a593Smuzhiyun 0x9298, 0xffffffff, 0x00140013,
729*4882a593Smuzhiyun 0x929c, 0xffffffff, 0x00170016,
730*4882a593Smuzhiyun 0x9150, 0xffffffff, 0x96940200,
731*4882a593Smuzhiyun 0x8708, 0xffffffff, 0x00900100,
732*4882a593Smuzhiyun 0xc478, 0xffffffff, 0x00000080,
733*4882a593Smuzhiyun 0xc404, 0xffffffff, 0x0020003f,
734*4882a593Smuzhiyun 0x30, 0xffffffff, 0x0000001c,
735*4882a593Smuzhiyun 0x34, 0x000f0000, 0x000f0000,
736*4882a593Smuzhiyun 0x160c, 0xffffffff, 0x00000100,
737*4882a593Smuzhiyun 0x1024, 0xffffffff, 0x00000100,
738*4882a593Smuzhiyun 0x102c, 0x00000101, 0x00000000,
739*4882a593Smuzhiyun 0x20a8, 0xffffffff, 0x00000104,
740*4882a593Smuzhiyun 0x264c, 0x000c0000, 0x000c0000,
741*4882a593Smuzhiyun 0x2648, 0x000c0000, 0x000c0000,
742*4882a593Smuzhiyun 0x55e4, 0xff000fff, 0x00000100,
743*4882a593Smuzhiyun 0x55e8, 0x00000001, 0x00000001,
744*4882a593Smuzhiyun 0x2f50, 0x00000001, 0x00000001,
745*4882a593Smuzhiyun 0x30cc, 0xc0000fff, 0x00000104,
746*4882a593Smuzhiyun 0xc1e4, 0x00000001, 0x00000001,
747*4882a593Smuzhiyun 0xd0c0, 0xfffffff0, 0x00000100,
748*4882a593Smuzhiyun 0xd8c0, 0xfffffff0, 0x00000100
749*4882a593Smuzhiyun };
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun static const u32 pitcairn_mgcg_cgcg_init[] =
752*4882a593Smuzhiyun {
753*4882a593Smuzhiyun 0xc400, 0xffffffff, 0xfffffffc,
754*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
755*4882a593Smuzhiyun 0x9a60, 0xffffffff, 0x00000100,
756*4882a593Smuzhiyun 0x92a4, 0xffffffff, 0x00000100,
757*4882a593Smuzhiyun 0xc164, 0xffffffff, 0x00000100,
758*4882a593Smuzhiyun 0x9774, 0xffffffff, 0x00000100,
759*4882a593Smuzhiyun 0x8984, 0xffffffff, 0x06000100,
760*4882a593Smuzhiyun 0x8a18, 0xffffffff, 0x00000100,
761*4882a593Smuzhiyun 0x92a0, 0xffffffff, 0x00000100,
762*4882a593Smuzhiyun 0xc380, 0xffffffff, 0x00000100,
763*4882a593Smuzhiyun 0x8b28, 0xffffffff, 0x00000100,
764*4882a593Smuzhiyun 0x9144, 0xffffffff, 0x00000100,
765*4882a593Smuzhiyun 0x8d88, 0xffffffff, 0x00000100,
766*4882a593Smuzhiyun 0x8d8c, 0xffffffff, 0x00000100,
767*4882a593Smuzhiyun 0x9030, 0xffffffff, 0x00000100,
768*4882a593Smuzhiyun 0x9034, 0xffffffff, 0x00000100,
769*4882a593Smuzhiyun 0x9038, 0xffffffff, 0x00000100,
770*4882a593Smuzhiyun 0x903c, 0xffffffff, 0x00000100,
771*4882a593Smuzhiyun 0xad80, 0xffffffff, 0x00000100,
772*4882a593Smuzhiyun 0xac54, 0xffffffff, 0x00000100,
773*4882a593Smuzhiyun 0x897c, 0xffffffff, 0x06000100,
774*4882a593Smuzhiyun 0x9868, 0xffffffff, 0x00000100,
775*4882a593Smuzhiyun 0x9510, 0xffffffff, 0x00000100,
776*4882a593Smuzhiyun 0xaf04, 0xffffffff, 0x00000100,
777*4882a593Smuzhiyun 0xae04, 0xffffffff, 0x00000100,
778*4882a593Smuzhiyun 0x949c, 0xffffffff, 0x00000100,
779*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
780*4882a593Smuzhiyun 0x9160, 0xffffffff, 0x00010000,
781*4882a593Smuzhiyun 0x9164, 0xffffffff, 0x00030002,
782*4882a593Smuzhiyun 0x9168, 0xffffffff, 0x00040007,
783*4882a593Smuzhiyun 0x916c, 0xffffffff, 0x00060005,
784*4882a593Smuzhiyun 0x9170, 0xffffffff, 0x00090008,
785*4882a593Smuzhiyun 0x9174, 0xffffffff, 0x00020001,
786*4882a593Smuzhiyun 0x9178, 0xffffffff, 0x00040003,
787*4882a593Smuzhiyun 0x917c, 0xffffffff, 0x00000007,
788*4882a593Smuzhiyun 0x9180, 0xffffffff, 0x00060005,
789*4882a593Smuzhiyun 0x9184, 0xffffffff, 0x00090008,
790*4882a593Smuzhiyun 0x9188, 0xffffffff, 0x00030002,
791*4882a593Smuzhiyun 0x918c, 0xffffffff, 0x00050004,
792*4882a593Smuzhiyun 0x9190, 0xffffffff, 0x00000008,
793*4882a593Smuzhiyun 0x9194, 0xffffffff, 0x00070006,
794*4882a593Smuzhiyun 0x9198, 0xffffffff, 0x000a0009,
795*4882a593Smuzhiyun 0x919c, 0xffffffff, 0x00040003,
796*4882a593Smuzhiyun 0x91a0, 0xffffffff, 0x00060005,
797*4882a593Smuzhiyun 0x91a4, 0xffffffff, 0x00000009,
798*4882a593Smuzhiyun 0x91a8, 0xffffffff, 0x00080007,
799*4882a593Smuzhiyun 0x91ac, 0xffffffff, 0x000b000a,
800*4882a593Smuzhiyun 0x91b0, 0xffffffff, 0x00050004,
801*4882a593Smuzhiyun 0x91b4, 0xffffffff, 0x00070006,
802*4882a593Smuzhiyun 0x91b8, 0xffffffff, 0x0008000b,
803*4882a593Smuzhiyun 0x91bc, 0xffffffff, 0x000a0009,
804*4882a593Smuzhiyun 0x91c0, 0xffffffff, 0x000d000c,
805*4882a593Smuzhiyun 0x9200, 0xffffffff, 0x00090008,
806*4882a593Smuzhiyun 0x9204, 0xffffffff, 0x000b000a,
807*4882a593Smuzhiyun 0x9208, 0xffffffff, 0x000c000f,
808*4882a593Smuzhiyun 0x920c, 0xffffffff, 0x000e000d,
809*4882a593Smuzhiyun 0x9210, 0xffffffff, 0x00110010,
810*4882a593Smuzhiyun 0x9214, 0xffffffff, 0x000a0009,
811*4882a593Smuzhiyun 0x9218, 0xffffffff, 0x000c000b,
812*4882a593Smuzhiyun 0x921c, 0xffffffff, 0x0000000f,
813*4882a593Smuzhiyun 0x9220, 0xffffffff, 0x000e000d,
814*4882a593Smuzhiyun 0x9224, 0xffffffff, 0x00110010,
815*4882a593Smuzhiyun 0x9228, 0xffffffff, 0x000b000a,
816*4882a593Smuzhiyun 0x922c, 0xffffffff, 0x000d000c,
817*4882a593Smuzhiyun 0x9230, 0xffffffff, 0x00000010,
818*4882a593Smuzhiyun 0x9234, 0xffffffff, 0x000f000e,
819*4882a593Smuzhiyun 0x9238, 0xffffffff, 0x00120011,
820*4882a593Smuzhiyun 0x923c, 0xffffffff, 0x000c000b,
821*4882a593Smuzhiyun 0x9240, 0xffffffff, 0x000e000d,
822*4882a593Smuzhiyun 0x9244, 0xffffffff, 0x00000011,
823*4882a593Smuzhiyun 0x9248, 0xffffffff, 0x0010000f,
824*4882a593Smuzhiyun 0x924c, 0xffffffff, 0x00130012,
825*4882a593Smuzhiyun 0x9250, 0xffffffff, 0x000d000c,
826*4882a593Smuzhiyun 0x9254, 0xffffffff, 0x000f000e,
827*4882a593Smuzhiyun 0x9258, 0xffffffff, 0x00100013,
828*4882a593Smuzhiyun 0x925c, 0xffffffff, 0x00120011,
829*4882a593Smuzhiyun 0x9260, 0xffffffff, 0x00150014,
830*4882a593Smuzhiyun 0x9150, 0xffffffff, 0x96940200,
831*4882a593Smuzhiyun 0x8708, 0xffffffff, 0x00900100,
832*4882a593Smuzhiyun 0xc478, 0xffffffff, 0x00000080,
833*4882a593Smuzhiyun 0xc404, 0xffffffff, 0x0020003f,
834*4882a593Smuzhiyun 0x30, 0xffffffff, 0x0000001c,
835*4882a593Smuzhiyun 0x34, 0x000f0000, 0x000f0000,
836*4882a593Smuzhiyun 0x160c, 0xffffffff, 0x00000100,
837*4882a593Smuzhiyun 0x1024, 0xffffffff, 0x00000100,
838*4882a593Smuzhiyun 0x102c, 0x00000101, 0x00000000,
839*4882a593Smuzhiyun 0x20a8, 0xffffffff, 0x00000104,
840*4882a593Smuzhiyun 0x55e4, 0xff000fff, 0x00000100,
841*4882a593Smuzhiyun 0x55e8, 0x00000001, 0x00000001,
842*4882a593Smuzhiyun 0x2f50, 0x00000001, 0x00000001,
843*4882a593Smuzhiyun 0x30cc, 0xc0000fff, 0x00000104,
844*4882a593Smuzhiyun 0xc1e4, 0x00000001, 0x00000001,
845*4882a593Smuzhiyun 0xd0c0, 0xfffffff0, 0x00000100,
846*4882a593Smuzhiyun 0xd8c0, 0xfffffff0, 0x00000100
847*4882a593Smuzhiyun };
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun static const u32 verde_mgcg_cgcg_init[] =
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun 0xc400, 0xffffffff, 0xfffffffc,
852*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
853*4882a593Smuzhiyun 0x9a60, 0xffffffff, 0x00000100,
854*4882a593Smuzhiyun 0x92a4, 0xffffffff, 0x00000100,
855*4882a593Smuzhiyun 0xc164, 0xffffffff, 0x00000100,
856*4882a593Smuzhiyun 0x9774, 0xffffffff, 0x00000100,
857*4882a593Smuzhiyun 0x8984, 0xffffffff, 0x06000100,
858*4882a593Smuzhiyun 0x8a18, 0xffffffff, 0x00000100,
859*4882a593Smuzhiyun 0x92a0, 0xffffffff, 0x00000100,
860*4882a593Smuzhiyun 0xc380, 0xffffffff, 0x00000100,
861*4882a593Smuzhiyun 0x8b28, 0xffffffff, 0x00000100,
862*4882a593Smuzhiyun 0x9144, 0xffffffff, 0x00000100,
863*4882a593Smuzhiyun 0x8d88, 0xffffffff, 0x00000100,
864*4882a593Smuzhiyun 0x8d8c, 0xffffffff, 0x00000100,
865*4882a593Smuzhiyun 0x9030, 0xffffffff, 0x00000100,
866*4882a593Smuzhiyun 0x9034, 0xffffffff, 0x00000100,
867*4882a593Smuzhiyun 0x9038, 0xffffffff, 0x00000100,
868*4882a593Smuzhiyun 0x903c, 0xffffffff, 0x00000100,
869*4882a593Smuzhiyun 0xad80, 0xffffffff, 0x00000100,
870*4882a593Smuzhiyun 0xac54, 0xffffffff, 0x00000100,
871*4882a593Smuzhiyun 0x897c, 0xffffffff, 0x06000100,
872*4882a593Smuzhiyun 0x9868, 0xffffffff, 0x00000100,
873*4882a593Smuzhiyun 0x9510, 0xffffffff, 0x00000100,
874*4882a593Smuzhiyun 0xaf04, 0xffffffff, 0x00000100,
875*4882a593Smuzhiyun 0xae04, 0xffffffff, 0x00000100,
876*4882a593Smuzhiyun 0x949c, 0xffffffff, 0x00000100,
877*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
878*4882a593Smuzhiyun 0x9160, 0xffffffff, 0x00010000,
879*4882a593Smuzhiyun 0x9164, 0xffffffff, 0x00030002,
880*4882a593Smuzhiyun 0x9168, 0xffffffff, 0x00040007,
881*4882a593Smuzhiyun 0x916c, 0xffffffff, 0x00060005,
882*4882a593Smuzhiyun 0x9170, 0xffffffff, 0x00090008,
883*4882a593Smuzhiyun 0x9174, 0xffffffff, 0x00020001,
884*4882a593Smuzhiyun 0x9178, 0xffffffff, 0x00040003,
885*4882a593Smuzhiyun 0x917c, 0xffffffff, 0x00000007,
886*4882a593Smuzhiyun 0x9180, 0xffffffff, 0x00060005,
887*4882a593Smuzhiyun 0x9184, 0xffffffff, 0x00090008,
888*4882a593Smuzhiyun 0x9188, 0xffffffff, 0x00030002,
889*4882a593Smuzhiyun 0x918c, 0xffffffff, 0x00050004,
890*4882a593Smuzhiyun 0x9190, 0xffffffff, 0x00000008,
891*4882a593Smuzhiyun 0x9194, 0xffffffff, 0x00070006,
892*4882a593Smuzhiyun 0x9198, 0xffffffff, 0x000a0009,
893*4882a593Smuzhiyun 0x919c, 0xffffffff, 0x00040003,
894*4882a593Smuzhiyun 0x91a0, 0xffffffff, 0x00060005,
895*4882a593Smuzhiyun 0x91a4, 0xffffffff, 0x00000009,
896*4882a593Smuzhiyun 0x91a8, 0xffffffff, 0x00080007,
897*4882a593Smuzhiyun 0x91ac, 0xffffffff, 0x000b000a,
898*4882a593Smuzhiyun 0x91b0, 0xffffffff, 0x00050004,
899*4882a593Smuzhiyun 0x91b4, 0xffffffff, 0x00070006,
900*4882a593Smuzhiyun 0x91b8, 0xffffffff, 0x0008000b,
901*4882a593Smuzhiyun 0x91bc, 0xffffffff, 0x000a0009,
902*4882a593Smuzhiyun 0x91c0, 0xffffffff, 0x000d000c,
903*4882a593Smuzhiyun 0x9200, 0xffffffff, 0x00090008,
904*4882a593Smuzhiyun 0x9204, 0xffffffff, 0x000b000a,
905*4882a593Smuzhiyun 0x9208, 0xffffffff, 0x000c000f,
906*4882a593Smuzhiyun 0x920c, 0xffffffff, 0x000e000d,
907*4882a593Smuzhiyun 0x9210, 0xffffffff, 0x00110010,
908*4882a593Smuzhiyun 0x9214, 0xffffffff, 0x000a0009,
909*4882a593Smuzhiyun 0x9218, 0xffffffff, 0x000c000b,
910*4882a593Smuzhiyun 0x921c, 0xffffffff, 0x0000000f,
911*4882a593Smuzhiyun 0x9220, 0xffffffff, 0x000e000d,
912*4882a593Smuzhiyun 0x9224, 0xffffffff, 0x00110010,
913*4882a593Smuzhiyun 0x9228, 0xffffffff, 0x000b000a,
914*4882a593Smuzhiyun 0x922c, 0xffffffff, 0x000d000c,
915*4882a593Smuzhiyun 0x9230, 0xffffffff, 0x00000010,
916*4882a593Smuzhiyun 0x9234, 0xffffffff, 0x000f000e,
917*4882a593Smuzhiyun 0x9238, 0xffffffff, 0x00120011,
918*4882a593Smuzhiyun 0x923c, 0xffffffff, 0x000c000b,
919*4882a593Smuzhiyun 0x9240, 0xffffffff, 0x000e000d,
920*4882a593Smuzhiyun 0x9244, 0xffffffff, 0x00000011,
921*4882a593Smuzhiyun 0x9248, 0xffffffff, 0x0010000f,
922*4882a593Smuzhiyun 0x924c, 0xffffffff, 0x00130012,
923*4882a593Smuzhiyun 0x9250, 0xffffffff, 0x000d000c,
924*4882a593Smuzhiyun 0x9254, 0xffffffff, 0x000f000e,
925*4882a593Smuzhiyun 0x9258, 0xffffffff, 0x00100013,
926*4882a593Smuzhiyun 0x925c, 0xffffffff, 0x00120011,
927*4882a593Smuzhiyun 0x9260, 0xffffffff, 0x00150014,
928*4882a593Smuzhiyun 0x9150, 0xffffffff, 0x96940200,
929*4882a593Smuzhiyun 0x8708, 0xffffffff, 0x00900100,
930*4882a593Smuzhiyun 0xc478, 0xffffffff, 0x00000080,
931*4882a593Smuzhiyun 0xc404, 0xffffffff, 0x0020003f,
932*4882a593Smuzhiyun 0x30, 0xffffffff, 0x0000001c,
933*4882a593Smuzhiyun 0x34, 0x000f0000, 0x000f0000,
934*4882a593Smuzhiyun 0x160c, 0xffffffff, 0x00000100,
935*4882a593Smuzhiyun 0x1024, 0xffffffff, 0x00000100,
936*4882a593Smuzhiyun 0x102c, 0x00000101, 0x00000000,
937*4882a593Smuzhiyun 0x20a8, 0xffffffff, 0x00000104,
938*4882a593Smuzhiyun 0x264c, 0x000c0000, 0x000c0000,
939*4882a593Smuzhiyun 0x2648, 0x000c0000, 0x000c0000,
940*4882a593Smuzhiyun 0x55e4, 0xff000fff, 0x00000100,
941*4882a593Smuzhiyun 0x55e8, 0x00000001, 0x00000001,
942*4882a593Smuzhiyun 0x2f50, 0x00000001, 0x00000001,
943*4882a593Smuzhiyun 0x30cc, 0xc0000fff, 0x00000104,
944*4882a593Smuzhiyun 0xc1e4, 0x00000001, 0x00000001,
945*4882a593Smuzhiyun 0xd0c0, 0xfffffff0, 0x00000100,
946*4882a593Smuzhiyun 0xd8c0, 0xfffffff0, 0x00000100
947*4882a593Smuzhiyun };
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun static const u32 oland_mgcg_cgcg_init[] =
950*4882a593Smuzhiyun {
951*4882a593Smuzhiyun 0xc400, 0xffffffff, 0xfffffffc,
952*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
953*4882a593Smuzhiyun 0x9a60, 0xffffffff, 0x00000100,
954*4882a593Smuzhiyun 0x92a4, 0xffffffff, 0x00000100,
955*4882a593Smuzhiyun 0xc164, 0xffffffff, 0x00000100,
956*4882a593Smuzhiyun 0x9774, 0xffffffff, 0x00000100,
957*4882a593Smuzhiyun 0x8984, 0xffffffff, 0x06000100,
958*4882a593Smuzhiyun 0x8a18, 0xffffffff, 0x00000100,
959*4882a593Smuzhiyun 0x92a0, 0xffffffff, 0x00000100,
960*4882a593Smuzhiyun 0xc380, 0xffffffff, 0x00000100,
961*4882a593Smuzhiyun 0x8b28, 0xffffffff, 0x00000100,
962*4882a593Smuzhiyun 0x9144, 0xffffffff, 0x00000100,
963*4882a593Smuzhiyun 0x8d88, 0xffffffff, 0x00000100,
964*4882a593Smuzhiyun 0x8d8c, 0xffffffff, 0x00000100,
965*4882a593Smuzhiyun 0x9030, 0xffffffff, 0x00000100,
966*4882a593Smuzhiyun 0x9034, 0xffffffff, 0x00000100,
967*4882a593Smuzhiyun 0x9038, 0xffffffff, 0x00000100,
968*4882a593Smuzhiyun 0x903c, 0xffffffff, 0x00000100,
969*4882a593Smuzhiyun 0xad80, 0xffffffff, 0x00000100,
970*4882a593Smuzhiyun 0xac54, 0xffffffff, 0x00000100,
971*4882a593Smuzhiyun 0x897c, 0xffffffff, 0x06000100,
972*4882a593Smuzhiyun 0x9868, 0xffffffff, 0x00000100,
973*4882a593Smuzhiyun 0x9510, 0xffffffff, 0x00000100,
974*4882a593Smuzhiyun 0xaf04, 0xffffffff, 0x00000100,
975*4882a593Smuzhiyun 0xae04, 0xffffffff, 0x00000100,
976*4882a593Smuzhiyun 0x949c, 0xffffffff, 0x00000100,
977*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
978*4882a593Smuzhiyun 0x9160, 0xffffffff, 0x00010000,
979*4882a593Smuzhiyun 0x9164, 0xffffffff, 0x00030002,
980*4882a593Smuzhiyun 0x9168, 0xffffffff, 0x00040007,
981*4882a593Smuzhiyun 0x916c, 0xffffffff, 0x00060005,
982*4882a593Smuzhiyun 0x9170, 0xffffffff, 0x00090008,
983*4882a593Smuzhiyun 0x9174, 0xffffffff, 0x00020001,
984*4882a593Smuzhiyun 0x9178, 0xffffffff, 0x00040003,
985*4882a593Smuzhiyun 0x917c, 0xffffffff, 0x00000007,
986*4882a593Smuzhiyun 0x9180, 0xffffffff, 0x00060005,
987*4882a593Smuzhiyun 0x9184, 0xffffffff, 0x00090008,
988*4882a593Smuzhiyun 0x9188, 0xffffffff, 0x00030002,
989*4882a593Smuzhiyun 0x918c, 0xffffffff, 0x00050004,
990*4882a593Smuzhiyun 0x9190, 0xffffffff, 0x00000008,
991*4882a593Smuzhiyun 0x9194, 0xffffffff, 0x00070006,
992*4882a593Smuzhiyun 0x9198, 0xffffffff, 0x000a0009,
993*4882a593Smuzhiyun 0x919c, 0xffffffff, 0x00040003,
994*4882a593Smuzhiyun 0x91a0, 0xffffffff, 0x00060005,
995*4882a593Smuzhiyun 0x91a4, 0xffffffff, 0x00000009,
996*4882a593Smuzhiyun 0x91a8, 0xffffffff, 0x00080007,
997*4882a593Smuzhiyun 0x91ac, 0xffffffff, 0x000b000a,
998*4882a593Smuzhiyun 0x91b0, 0xffffffff, 0x00050004,
999*4882a593Smuzhiyun 0x91b4, 0xffffffff, 0x00070006,
1000*4882a593Smuzhiyun 0x91b8, 0xffffffff, 0x0008000b,
1001*4882a593Smuzhiyun 0x91bc, 0xffffffff, 0x000a0009,
1002*4882a593Smuzhiyun 0x91c0, 0xffffffff, 0x000d000c,
1003*4882a593Smuzhiyun 0x91c4, 0xffffffff, 0x00060005,
1004*4882a593Smuzhiyun 0x91c8, 0xffffffff, 0x00080007,
1005*4882a593Smuzhiyun 0x91cc, 0xffffffff, 0x0000000b,
1006*4882a593Smuzhiyun 0x91d0, 0xffffffff, 0x000a0009,
1007*4882a593Smuzhiyun 0x91d4, 0xffffffff, 0x000d000c,
1008*4882a593Smuzhiyun 0x9150, 0xffffffff, 0x96940200,
1009*4882a593Smuzhiyun 0x8708, 0xffffffff, 0x00900100,
1010*4882a593Smuzhiyun 0xc478, 0xffffffff, 0x00000080,
1011*4882a593Smuzhiyun 0xc404, 0xffffffff, 0x0020003f,
1012*4882a593Smuzhiyun 0x30, 0xffffffff, 0x0000001c,
1013*4882a593Smuzhiyun 0x34, 0x000f0000, 0x000f0000,
1014*4882a593Smuzhiyun 0x160c, 0xffffffff, 0x00000100,
1015*4882a593Smuzhiyun 0x1024, 0xffffffff, 0x00000100,
1016*4882a593Smuzhiyun 0x102c, 0x00000101, 0x00000000,
1017*4882a593Smuzhiyun 0x20a8, 0xffffffff, 0x00000104,
1018*4882a593Smuzhiyun 0x264c, 0x000c0000, 0x000c0000,
1019*4882a593Smuzhiyun 0x2648, 0x000c0000, 0x000c0000,
1020*4882a593Smuzhiyun 0x55e4, 0xff000fff, 0x00000100,
1021*4882a593Smuzhiyun 0x55e8, 0x00000001, 0x00000001,
1022*4882a593Smuzhiyun 0x2f50, 0x00000001, 0x00000001,
1023*4882a593Smuzhiyun 0x30cc, 0xc0000fff, 0x00000104,
1024*4882a593Smuzhiyun 0xc1e4, 0x00000001, 0x00000001,
1025*4882a593Smuzhiyun 0xd0c0, 0xfffffff0, 0x00000100,
1026*4882a593Smuzhiyun 0xd8c0, 0xfffffff0, 0x00000100
1027*4882a593Smuzhiyun };
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun static const u32 hainan_mgcg_cgcg_init[] =
1030*4882a593Smuzhiyun {
1031*4882a593Smuzhiyun 0xc400, 0xffffffff, 0xfffffffc,
1032*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
1033*4882a593Smuzhiyun 0x9a60, 0xffffffff, 0x00000100,
1034*4882a593Smuzhiyun 0x92a4, 0xffffffff, 0x00000100,
1035*4882a593Smuzhiyun 0xc164, 0xffffffff, 0x00000100,
1036*4882a593Smuzhiyun 0x9774, 0xffffffff, 0x00000100,
1037*4882a593Smuzhiyun 0x8984, 0xffffffff, 0x06000100,
1038*4882a593Smuzhiyun 0x8a18, 0xffffffff, 0x00000100,
1039*4882a593Smuzhiyun 0x92a0, 0xffffffff, 0x00000100,
1040*4882a593Smuzhiyun 0xc380, 0xffffffff, 0x00000100,
1041*4882a593Smuzhiyun 0x8b28, 0xffffffff, 0x00000100,
1042*4882a593Smuzhiyun 0x9144, 0xffffffff, 0x00000100,
1043*4882a593Smuzhiyun 0x8d88, 0xffffffff, 0x00000100,
1044*4882a593Smuzhiyun 0x8d8c, 0xffffffff, 0x00000100,
1045*4882a593Smuzhiyun 0x9030, 0xffffffff, 0x00000100,
1046*4882a593Smuzhiyun 0x9034, 0xffffffff, 0x00000100,
1047*4882a593Smuzhiyun 0x9038, 0xffffffff, 0x00000100,
1048*4882a593Smuzhiyun 0x903c, 0xffffffff, 0x00000100,
1049*4882a593Smuzhiyun 0xad80, 0xffffffff, 0x00000100,
1050*4882a593Smuzhiyun 0xac54, 0xffffffff, 0x00000100,
1051*4882a593Smuzhiyun 0x897c, 0xffffffff, 0x06000100,
1052*4882a593Smuzhiyun 0x9868, 0xffffffff, 0x00000100,
1053*4882a593Smuzhiyun 0x9510, 0xffffffff, 0x00000100,
1054*4882a593Smuzhiyun 0xaf04, 0xffffffff, 0x00000100,
1055*4882a593Smuzhiyun 0xae04, 0xffffffff, 0x00000100,
1056*4882a593Smuzhiyun 0x949c, 0xffffffff, 0x00000100,
1057*4882a593Smuzhiyun 0x802c, 0xffffffff, 0xe0000000,
1058*4882a593Smuzhiyun 0x9160, 0xffffffff, 0x00010000,
1059*4882a593Smuzhiyun 0x9164, 0xffffffff, 0x00030002,
1060*4882a593Smuzhiyun 0x9168, 0xffffffff, 0x00040007,
1061*4882a593Smuzhiyun 0x916c, 0xffffffff, 0x00060005,
1062*4882a593Smuzhiyun 0x9170, 0xffffffff, 0x00090008,
1063*4882a593Smuzhiyun 0x9174, 0xffffffff, 0x00020001,
1064*4882a593Smuzhiyun 0x9178, 0xffffffff, 0x00040003,
1065*4882a593Smuzhiyun 0x917c, 0xffffffff, 0x00000007,
1066*4882a593Smuzhiyun 0x9180, 0xffffffff, 0x00060005,
1067*4882a593Smuzhiyun 0x9184, 0xffffffff, 0x00090008,
1068*4882a593Smuzhiyun 0x9188, 0xffffffff, 0x00030002,
1069*4882a593Smuzhiyun 0x918c, 0xffffffff, 0x00050004,
1070*4882a593Smuzhiyun 0x9190, 0xffffffff, 0x00000008,
1071*4882a593Smuzhiyun 0x9194, 0xffffffff, 0x00070006,
1072*4882a593Smuzhiyun 0x9198, 0xffffffff, 0x000a0009,
1073*4882a593Smuzhiyun 0x919c, 0xffffffff, 0x00040003,
1074*4882a593Smuzhiyun 0x91a0, 0xffffffff, 0x00060005,
1075*4882a593Smuzhiyun 0x91a4, 0xffffffff, 0x00000009,
1076*4882a593Smuzhiyun 0x91a8, 0xffffffff, 0x00080007,
1077*4882a593Smuzhiyun 0x91ac, 0xffffffff, 0x000b000a,
1078*4882a593Smuzhiyun 0x91b0, 0xffffffff, 0x00050004,
1079*4882a593Smuzhiyun 0x91b4, 0xffffffff, 0x00070006,
1080*4882a593Smuzhiyun 0x91b8, 0xffffffff, 0x0008000b,
1081*4882a593Smuzhiyun 0x91bc, 0xffffffff, 0x000a0009,
1082*4882a593Smuzhiyun 0x91c0, 0xffffffff, 0x000d000c,
1083*4882a593Smuzhiyun 0x91c4, 0xffffffff, 0x00060005,
1084*4882a593Smuzhiyun 0x91c8, 0xffffffff, 0x00080007,
1085*4882a593Smuzhiyun 0x91cc, 0xffffffff, 0x0000000b,
1086*4882a593Smuzhiyun 0x91d0, 0xffffffff, 0x000a0009,
1087*4882a593Smuzhiyun 0x91d4, 0xffffffff, 0x000d000c,
1088*4882a593Smuzhiyun 0x9150, 0xffffffff, 0x96940200,
1089*4882a593Smuzhiyun 0x8708, 0xffffffff, 0x00900100,
1090*4882a593Smuzhiyun 0xc478, 0xffffffff, 0x00000080,
1091*4882a593Smuzhiyun 0xc404, 0xffffffff, 0x0020003f,
1092*4882a593Smuzhiyun 0x30, 0xffffffff, 0x0000001c,
1093*4882a593Smuzhiyun 0x34, 0x000f0000, 0x000f0000,
1094*4882a593Smuzhiyun 0x160c, 0xffffffff, 0x00000100,
1095*4882a593Smuzhiyun 0x1024, 0xffffffff, 0x00000100,
1096*4882a593Smuzhiyun 0x20a8, 0xffffffff, 0x00000104,
1097*4882a593Smuzhiyun 0x264c, 0x000c0000, 0x000c0000,
1098*4882a593Smuzhiyun 0x2648, 0x000c0000, 0x000c0000,
1099*4882a593Smuzhiyun 0x2f50, 0x00000001, 0x00000001,
1100*4882a593Smuzhiyun 0x30cc, 0xc0000fff, 0x00000104,
1101*4882a593Smuzhiyun 0xc1e4, 0x00000001, 0x00000001,
1102*4882a593Smuzhiyun 0xd0c0, 0xfffffff0, 0x00000100,
1103*4882a593Smuzhiyun 0xd8c0, 0xfffffff0, 0x00000100
1104*4882a593Smuzhiyun };
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun static u32 verde_pg_init[] =
1107*4882a593Smuzhiyun {
1108*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x40000,
1109*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x200010ff,
1110*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1111*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1112*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1113*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1114*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1115*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x7007,
1116*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x300010ff,
1117*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1118*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1119*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1120*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1121*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1122*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x400000,
1123*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x100010ff,
1124*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1125*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1126*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1127*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1128*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1129*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x120200,
1130*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x500010ff,
1131*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1132*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1133*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1134*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1135*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1136*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x1e1e16,
1137*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x600010ff,
1138*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1139*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1140*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1141*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1142*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1143*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x171f1e,
1144*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x700010ff,
1145*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1146*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1147*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1148*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1149*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1150*4882a593Smuzhiyun 0x353c, 0xffffffff, 0x0,
1151*4882a593Smuzhiyun 0x3538, 0xffffffff, 0x9ff,
1152*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x0,
1153*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x10000800,
1154*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xf,
1155*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xf,
1156*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x4,
1157*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1000051e,
1158*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xffff,
1159*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xffff,
1160*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x8,
1161*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x80500,
1162*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x12,
1163*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x9050c,
1164*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x1d,
1165*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xb052c,
1166*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x2a,
1167*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1053e,
1168*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x2d,
1169*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x10546,
1170*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x30,
1171*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xa054e,
1172*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x3c,
1173*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1055f,
1174*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x3f,
1175*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x10567,
1176*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x42,
1177*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1056f,
1178*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x45,
1179*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x10572,
1180*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x48,
1181*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x20575,
1182*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x4c,
1183*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x190801,
1184*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x67,
1185*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1082a,
1186*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x6a,
1187*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1b082d,
1188*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x87,
1189*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x310851,
1190*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xba,
1191*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x891,
1192*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xbc,
1193*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x893,
1194*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xbe,
1195*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x20895,
1196*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xc2,
1197*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x20899,
1198*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xc6,
1199*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x2089d,
1200*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xca,
1201*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x8a1,
1202*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xcc,
1203*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x8a3,
1204*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xce,
1205*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x308a5,
1206*4882a593Smuzhiyun 0x3500, 0xffffffff, 0xd3,
1207*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x6d08cd,
1208*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x142,
1209*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x2000095a,
1210*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x1,
1211*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x144,
1212*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x301f095b,
1213*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x165,
1214*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xc094d,
1215*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x173,
1216*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xf096d,
1217*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x184,
1218*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x15097f,
1219*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x19b,
1220*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xc0998,
1221*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x1a9,
1222*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x409a7,
1223*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x1af,
1224*4882a593Smuzhiyun 0x3504, 0xffffffff, 0xcdc,
1225*4882a593Smuzhiyun 0x3500, 0xffffffff, 0x1b1,
1226*4882a593Smuzhiyun 0x3504, 0xffffffff, 0x800,
1227*4882a593Smuzhiyun 0x3508, 0xffffffff, 0x6c9b2000,
1228*4882a593Smuzhiyun 0x3510, 0xfc00, 0x2000,
1229*4882a593Smuzhiyun 0x3544, 0xffffffff, 0xfc0,
1230*4882a593Smuzhiyun 0x28d4, 0x00000100, 0x100
1231*4882a593Smuzhiyun };
1232*4882a593Smuzhiyun
si_init_golden_registers(struct radeon_device * rdev)1233*4882a593Smuzhiyun static void si_init_golden_registers(struct radeon_device *rdev)
1234*4882a593Smuzhiyun {
1235*4882a593Smuzhiyun switch (rdev->family) {
1236*4882a593Smuzhiyun case CHIP_TAHITI:
1237*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1238*4882a593Smuzhiyun tahiti_golden_registers,
1239*4882a593Smuzhiyun (const u32)ARRAY_SIZE(tahiti_golden_registers));
1240*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1241*4882a593Smuzhiyun tahiti_golden_rlc_registers,
1242*4882a593Smuzhiyun (const u32)ARRAY_SIZE(tahiti_golden_rlc_registers));
1243*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1244*4882a593Smuzhiyun tahiti_mgcg_cgcg_init,
1245*4882a593Smuzhiyun (const u32)ARRAY_SIZE(tahiti_mgcg_cgcg_init));
1246*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1247*4882a593Smuzhiyun tahiti_golden_registers2,
1248*4882a593Smuzhiyun (const u32)ARRAY_SIZE(tahiti_golden_registers2));
1249*4882a593Smuzhiyun break;
1250*4882a593Smuzhiyun case CHIP_PITCAIRN:
1251*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1252*4882a593Smuzhiyun pitcairn_golden_registers,
1253*4882a593Smuzhiyun (const u32)ARRAY_SIZE(pitcairn_golden_registers));
1254*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1255*4882a593Smuzhiyun pitcairn_golden_rlc_registers,
1256*4882a593Smuzhiyun (const u32)ARRAY_SIZE(pitcairn_golden_rlc_registers));
1257*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1258*4882a593Smuzhiyun pitcairn_mgcg_cgcg_init,
1259*4882a593Smuzhiyun (const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
1260*4882a593Smuzhiyun break;
1261*4882a593Smuzhiyun case CHIP_VERDE:
1262*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1263*4882a593Smuzhiyun verde_golden_registers,
1264*4882a593Smuzhiyun (const u32)ARRAY_SIZE(verde_golden_registers));
1265*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1266*4882a593Smuzhiyun verde_golden_rlc_registers,
1267*4882a593Smuzhiyun (const u32)ARRAY_SIZE(verde_golden_rlc_registers));
1268*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1269*4882a593Smuzhiyun verde_mgcg_cgcg_init,
1270*4882a593Smuzhiyun (const u32)ARRAY_SIZE(verde_mgcg_cgcg_init));
1271*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1272*4882a593Smuzhiyun verde_pg_init,
1273*4882a593Smuzhiyun (const u32)ARRAY_SIZE(verde_pg_init));
1274*4882a593Smuzhiyun break;
1275*4882a593Smuzhiyun case CHIP_OLAND:
1276*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1277*4882a593Smuzhiyun oland_golden_registers,
1278*4882a593Smuzhiyun (const u32)ARRAY_SIZE(oland_golden_registers));
1279*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1280*4882a593Smuzhiyun oland_golden_rlc_registers,
1281*4882a593Smuzhiyun (const u32)ARRAY_SIZE(oland_golden_rlc_registers));
1282*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1283*4882a593Smuzhiyun oland_mgcg_cgcg_init,
1284*4882a593Smuzhiyun (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
1285*4882a593Smuzhiyun break;
1286*4882a593Smuzhiyun case CHIP_HAINAN:
1287*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1288*4882a593Smuzhiyun hainan_golden_registers,
1289*4882a593Smuzhiyun (const u32)ARRAY_SIZE(hainan_golden_registers));
1290*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1291*4882a593Smuzhiyun hainan_golden_registers2,
1292*4882a593Smuzhiyun (const u32)ARRAY_SIZE(hainan_golden_registers2));
1293*4882a593Smuzhiyun radeon_program_register_sequence(rdev,
1294*4882a593Smuzhiyun hainan_mgcg_cgcg_init,
1295*4882a593Smuzhiyun (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init));
1296*4882a593Smuzhiyun break;
1297*4882a593Smuzhiyun default:
1298*4882a593Smuzhiyun break;
1299*4882a593Smuzhiyun }
1300*4882a593Smuzhiyun }
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun /**
1303*4882a593Smuzhiyun * si_get_allowed_info_register - fetch the register for the info ioctl
1304*4882a593Smuzhiyun *
1305*4882a593Smuzhiyun * @rdev: radeon_device pointer
1306*4882a593Smuzhiyun * @reg: register offset in bytes
1307*4882a593Smuzhiyun * @val: register value
1308*4882a593Smuzhiyun *
1309*4882a593Smuzhiyun * Returns 0 for success or -EINVAL for an invalid register
1310*4882a593Smuzhiyun *
1311*4882a593Smuzhiyun */
si_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)1312*4882a593Smuzhiyun int si_get_allowed_info_register(struct radeon_device *rdev,
1313*4882a593Smuzhiyun u32 reg, u32 *val)
1314*4882a593Smuzhiyun {
1315*4882a593Smuzhiyun switch (reg) {
1316*4882a593Smuzhiyun case GRBM_STATUS:
1317*4882a593Smuzhiyun case GRBM_STATUS2:
1318*4882a593Smuzhiyun case GRBM_STATUS_SE0:
1319*4882a593Smuzhiyun case GRBM_STATUS_SE1:
1320*4882a593Smuzhiyun case SRBM_STATUS:
1321*4882a593Smuzhiyun case SRBM_STATUS2:
1322*4882a593Smuzhiyun case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
1323*4882a593Smuzhiyun case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
1324*4882a593Smuzhiyun case UVD_STATUS:
1325*4882a593Smuzhiyun *val = RREG32(reg);
1326*4882a593Smuzhiyun return 0;
1327*4882a593Smuzhiyun default:
1328*4882a593Smuzhiyun return -EINVAL;
1329*4882a593Smuzhiyun }
1330*4882a593Smuzhiyun }
1331*4882a593Smuzhiyun
1332*4882a593Smuzhiyun #define PCIE_BUS_CLK 10000
1333*4882a593Smuzhiyun #define TCLK (PCIE_BUS_CLK / 10)
1334*4882a593Smuzhiyun
1335*4882a593Smuzhiyun /**
1336*4882a593Smuzhiyun * si_get_xclk - get the xclk
1337*4882a593Smuzhiyun *
1338*4882a593Smuzhiyun * @rdev: radeon_device pointer
1339*4882a593Smuzhiyun *
1340*4882a593Smuzhiyun * Returns the reference clock used by the gfx engine
1341*4882a593Smuzhiyun * (SI).
1342*4882a593Smuzhiyun */
si_get_xclk(struct radeon_device * rdev)1343*4882a593Smuzhiyun u32 si_get_xclk(struct radeon_device *rdev)
1344*4882a593Smuzhiyun {
1345*4882a593Smuzhiyun u32 reference_clock = rdev->clock.spll.reference_freq;
1346*4882a593Smuzhiyun u32 tmp;
1347*4882a593Smuzhiyun
1348*4882a593Smuzhiyun tmp = RREG32(CG_CLKPIN_CNTL_2);
1349*4882a593Smuzhiyun if (tmp & MUX_TCLK_TO_XCLK)
1350*4882a593Smuzhiyun return TCLK;
1351*4882a593Smuzhiyun
1352*4882a593Smuzhiyun tmp = RREG32(CG_CLKPIN_CNTL);
1353*4882a593Smuzhiyun if (tmp & XTALIN_DIVIDE)
1354*4882a593Smuzhiyun return reference_clock / 4;
1355*4882a593Smuzhiyun
1356*4882a593Smuzhiyun return reference_clock;
1357*4882a593Smuzhiyun }
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun /* get temperature in millidegrees */
si_get_temp(struct radeon_device * rdev)1360*4882a593Smuzhiyun int si_get_temp(struct radeon_device *rdev)
1361*4882a593Smuzhiyun {
1362*4882a593Smuzhiyun u32 temp;
1363*4882a593Smuzhiyun int actual_temp = 0;
1364*4882a593Smuzhiyun
1365*4882a593Smuzhiyun temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
1366*4882a593Smuzhiyun CTF_TEMP_SHIFT;
1367*4882a593Smuzhiyun
1368*4882a593Smuzhiyun if (temp & 0x200)
1369*4882a593Smuzhiyun actual_temp = 255;
1370*4882a593Smuzhiyun else
1371*4882a593Smuzhiyun actual_temp = temp & 0x1ff;
1372*4882a593Smuzhiyun
1373*4882a593Smuzhiyun actual_temp = (actual_temp * 1000);
1374*4882a593Smuzhiyun
1375*4882a593Smuzhiyun return actual_temp;
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun
1378*4882a593Smuzhiyun #define TAHITI_IO_MC_REGS_SIZE 36
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun static const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1381*4882a593Smuzhiyun {0x0000006f, 0x03044000},
1382*4882a593Smuzhiyun {0x00000070, 0x0480c018},
1383*4882a593Smuzhiyun {0x00000071, 0x00000040},
1384*4882a593Smuzhiyun {0x00000072, 0x01000000},
1385*4882a593Smuzhiyun {0x00000074, 0x000000ff},
1386*4882a593Smuzhiyun {0x00000075, 0x00143400},
1387*4882a593Smuzhiyun {0x00000076, 0x08ec0800},
1388*4882a593Smuzhiyun {0x00000077, 0x040000cc},
1389*4882a593Smuzhiyun {0x00000079, 0x00000000},
1390*4882a593Smuzhiyun {0x0000007a, 0x21000409},
1391*4882a593Smuzhiyun {0x0000007c, 0x00000000},
1392*4882a593Smuzhiyun {0x0000007d, 0xe8000000},
1393*4882a593Smuzhiyun {0x0000007e, 0x044408a8},
1394*4882a593Smuzhiyun {0x0000007f, 0x00000003},
1395*4882a593Smuzhiyun {0x00000080, 0x00000000},
1396*4882a593Smuzhiyun {0x00000081, 0x01000000},
1397*4882a593Smuzhiyun {0x00000082, 0x02000000},
1398*4882a593Smuzhiyun {0x00000083, 0x00000000},
1399*4882a593Smuzhiyun {0x00000084, 0xe3f3e4f4},
1400*4882a593Smuzhiyun {0x00000085, 0x00052024},
1401*4882a593Smuzhiyun {0x00000087, 0x00000000},
1402*4882a593Smuzhiyun {0x00000088, 0x66036603},
1403*4882a593Smuzhiyun {0x00000089, 0x01000000},
1404*4882a593Smuzhiyun {0x0000008b, 0x1c0a0000},
1405*4882a593Smuzhiyun {0x0000008c, 0xff010000},
1406*4882a593Smuzhiyun {0x0000008e, 0xffffefff},
1407*4882a593Smuzhiyun {0x0000008f, 0xfff3efff},
1408*4882a593Smuzhiyun {0x00000090, 0xfff3efbf},
1409*4882a593Smuzhiyun {0x00000094, 0x00101101},
1410*4882a593Smuzhiyun {0x00000095, 0x00000fff},
1411*4882a593Smuzhiyun {0x00000096, 0x00116fff},
1412*4882a593Smuzhiyun {0x00000097, 0x60010000},
1413*4882a593Smuzhiyun {0x00000098, 0x10010000},
1414*4882a593Smuzhiyun {0x00000099, 0x00006000},
1415*4882a593Smuzhiyun {0x0000009a, 0x00001000},
1416*4882a593Smuzhiyun {0x0000009f, 0x00a77400}
1417*4882a593Smuzhiyun };
1418*4882a593Smuzhiyun
1419*4882a593Smuzhiyun static const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1420*4882a593Smuzhiyun {0x0000006f, 0x03044000},
1421*4882a593Smuzhiyun {0x00000070, 0x0480c018},
1422*4882a593Smuzhiyun {0x00000071, 0x00000040},
1423*4882a593Smuzhiyun {0x00000072, 0x01000000},
1424*4882a593Smuzhiyun {0x00000074, 0x000000ff},
1425*4882a593Smuzhiyun {0x00000075, 0x00143400},
1426*4882a593Smuzhiyun {0x00000076, 0x08ec0800},
1427*4882a593Smuzhiyun {0x00000077, 0x040000cc},
1428*4882a593Smuzhiyun {0x00000079, 0x00000000},
1429*4882a593Smuzhiyun {0x0000007a, 0x21000409},
1430*4882a593Smuzhiyun {0x0000007c, 0x00000000},
1431*4882a593Smuzhiyun {0x0000007d, 0xe8000000},
1432*4882a593Smuzhiyun {0x0000007e, 0x044408a8},
1433*4882a593Smuzhiyun {0x0000007f, 0x00000003},
1434*4882a593Smuzhiyun {0x00000080, 0x00000000},
1435*4882a593Smuzhiyun {0x00000081, 0x01000000},
1436*4882a593Smuzhiyun {0x00000082, 0x02000000},
1437*4882a593Smuzhiyun {0x00000083, 0x00000000},
1438*4882a593Smuzhiyun {0x00000084, 0xe3f3e4f4},
1439*4882a593Smuzhiyun {0x00000085, 0x00052024},
1440*4882a593Smuzhiyun {0x00000087, 0x00000000},
1441*4882a593Smuzhiyun {0x00000088, 0x66036603},
1442*4882a593Smuzhiyun {0x00000089, 0x01000000},
1443*4882a593Smuzhiyun {0x0000008b, 0x1c0a0000},
1444*4882a593Smuzhiyun {0x0000008c, 0xff010000},
1445*4882a593Smuzhiyun {0x0000008e, 0xffffefff},
1446*4882a593Smuzhiyun {0x0000008f, 0xfff3efff},
1447*4882a593Smuzhiyun {0x00000090, 0xfff3efbf},
1448*4882a593Smuzhiyun {0x00000094, 0x00101101},
1449*4882a593Smuzhiyun {0x00000095, 0x00000fff},
1450*4882a593Smuzhiyun {0x00000096, 0x00116fff},
1451*4882a593Smuzhiyun {0x00000097, 0x60010000},
1452*4882a593Smuzhiyun {0x00000098, 0x10010000},
1453*4882a593Smuzhiyun {0x00000099, 0x00006000},
1454*4882a593Smuzhiyun {0x0000009a, 0x00001000},
1455*4882a593Smuzhiyun {0x0000009f, 0x00a47400}
1456*4882a593Smuzhiyun };
1457*4882a593Smuzhiyun
1458*4882a593Smuzhiyun static const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1459*4882a593Smuzhiyun {0x0000006f, 0x03044000},
1460*4882a593Smuzhiyun {0x00000070, 0x0480c018},
1461*4882a593Smuzhiyun {0x00000071, 0x00000040},
1462*4882a593Smuzhiyun {0x00000072, 0x01000000},
1463*4882a593Smuzhiyun {0x00000074, 0x000000ff},
1464*4882a593Smuzhiyun {0x00000075, 0x00143400},
1465*4882a593Smuzhiyun {0x00000076, 0x08ec0800},
1466*4882a593Smuzhiyun {0x00000077, 0x040000cc},
1467*4882a593Smuzhiyun {0x00000079, 0x00000000},
1468*4882a593Smuzhiyun {0x0000007a, 0x21000409},
1469*4882a593Smuzhiyun {0x0000007c, 0x00000000},
1470*4882a593Smuzhiyun {0x0000007d, 0xe8000000},
1471*4882a593Smuzhiyun {0x0000007e, 0x044408a8},
1472*4882a593Smuzhiyun {0x0000007f, 0x00000003},
1473*4882a593Smuzhiyun {0x00000080, 0x00000000},
1474*4882a593Smuzhiyun {0x00000081, 0x01000000},
1475*4882a593Smuzhiyun {0x00000082, 0x02000000},
1476*4882a593Smuzhiyun {0x00000083, 0x00000000},
1477*4882a593Smuzhiyun {0x00000084, 0xe3f3e4f4},
1478*4882a593Smuzhiyun {0x00000085, 0x00052024},
1479*4882a593Smuzhiyun {0x00000087, 0x00000000},
1480*4882a593Smuzhiyun {0x00000088, 0x66036603},
1481*4882a593Smuzhiyun {0x00000089, 0x01000000},
1482*4882a593Smuzhiyun {0x0000008b, 0x1c0a0000},
1483*4882a593Smuzhiyun {0x0000008c, 0xff010000},
1484*4882a593Smuzhiyun {0x0000008e, 0xffffefff},
1485*4882a593Smuzhiyun {0x0000008f, 0xfff3efff},
1486*4882a593Smuzhiyun {0x00000090, 0xfff3efbf},
1487*4882a593Smuzhiyun {0x00000094, 0x00101101},
1488*4882a593Smuzhiyun {0x00000095, 0x00000fff},
1489*4882a593Smuzhiyun {0x00000096, 0x00116fff},
1490*4882a593Smuzhiyun {0x00000097, 0x60010000},
1491*4882a593Smuzhiyun {0x00000098, 0x10010000},
1492*4882a593Smuzhiyun {0x00000099, 0x00006000},
1493*4882a593Smuzhiyun {0x0000009a, 0x00001000},
1494*4882a593Smuzhiyun {0x0000009f, 0x00a37400}
1495*4882a593Smuzhiyun };
1496*4882a593Smuzhiyun
1497*4882a593Smuzhiyun static const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1498*4882a593Smuzhiyun {0x0000006f, 0x03044000},
1499*4882a593Smuzhiyun {0x00000070, 0x0480c018},
1500*4882a593Smuzhiyun {0x00000071, 0x00000040},
1501*4882a593Smuzhiyun {0x00000072, 0x01000000},
1502*4882a593Smuzhiyun {0x00000074, 0x000000ff},
1503*4882a593Smuzhiyun {0x00000075, 0x00143400},
1504*4882a593Smuzhiyun {0x00000076, 0x08ec0800},
1505*4882a593Smuzhiyun {0x00000077, 0x040000cc},
1506*4882a593Smuzhiyun {0x00000079, 0x00000000},
1507*4882a593Smuzhiyun {0x0000007a, 0x21000409},
1508*4882a593Smuzhiyun {0x0000007c, 0x00000000},
1509*4882a593Smuzhiyun {0x0000007d, 0xe8000000},
1510*4882a593Smuzhiyun {0x0000007e, 0x044408a8},
1511*4882a593Smuzhiyun {0x0000007f, 0x00000003},
1512*4882a593Smuzhiyun {0x00000080, 0x00000000},
1513*4882a593Smuzhiyun {0x00000081, 0x01000000},
1514*4882a593Smuzhiyun {0x00000082, 0x02000000},
1515*4882a593Smuzhiyun {0x00000083, 0x00000000},
1516*4882a593Smuzhiyun {0x00000084, 0xe3f3e4f4},
1517*4882a593Smuzhiyun {0x00000085, 0x00052024},
1518*4882a593Smuzhiyun {0x00000087, 0x00000000},
1519*4882a593Smuzhiyun {0x00000088, 0x66036603},
1520*4882a593Smuzhiyun {0x00000089, 0x01000000},
1521*4882a593Smuzhiyun {0x0000008b, 0x1c0a0000},
1522*4882a593Smuzhiyun {0x0000008c, 0xff010000},
1523*4882a593Smuzhiyun {0x0000008e, 0xffffefff},
1524*4882a593Smuzhiyun {0x0000008f, 0xfff3efff},
1525*4882a593Smuzhiyun {0x00000090, 0xfff3efbf},
1526*4882a593Smuzhiyun {0x00000094, 0x00101101},
1527*4882a593Smuzhiyun {0x00000095, 0x00000fff},
1528*4882a593Smuzhiyun {0x00000096, 0x00116fff},
1529*4882a593Smuzhiyun {0x00000097, 0x60010000},
1530*4882a593Smuzhiyun {0x00000098, 0x10010000},
1531*4882a593Smuzhiyun {0x00000099, 0x00006000},
1532*4882a593Smuzhiyun {0x0000009a, 0x00001000},
1533*4882a593Smuzhiyun {0x0000009f, 0x00a17730}
1534*4882a593Smuzhiyun };
1535*4882a593Smuzhiyun
1536*4882a593Smuzhiyun static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1537*4882a593Smuzhiyun {0x0000006f, 0x03044000},
1538*4882a593Smuzhiyun {0x00000070, 0x0480c018},
1539*4882a593Smuzhiyun {0x00000071, 0x00000040},
1540*4882a593Smuzhiyun {0x00000072, 0x01000000},
1541*4882a593Smuzhiyun {0x00000074, 0x000000ff},
1542*4882a593Smuzhiyun {0x00000075, 0x00143400},
1543*4882a593Smuzhiyun {0x00000076, 0x08ec0800},
1544*4882a593Smuzhiyun {0x00000077, 0x040000cc},
1545*4882a593Smuzhiyun {0x00000079, 0x00000000},
1546*4882a593Smuzhiyun {0x0000007a, 0x21000409},
1547*4882a593Smuzhiyun {0x0000007c, 0x00000000},
1548*4882a593Smuzhiyun {0x0000007d, 0xe8000000},
1549*4882a593Smuzhiyun {0x0000007e, 0x044408a8},
1550*4882a593Smuzhiyun {0x0000007f, 0x00000003},
1551*4882a593Smuzhiyun {0x00000080, 0x00000000},
1552*4882a593Smuzhiyun {0x00000081, 0x01000000},
1553*4882a593Smuzhiyun {0x00000082, 0x02000000},
1554*4882a593Smuzhiyun {0x00000083, 0x00000000},
1555*4882a593Smuzhiyun {0x00000084, 0xe3f3e4f4},
1556*4882a593Smuzhiyun {0x00000085, 0x00052024},
1557*4882a593Smuzhiyun {0x00000087, 0x00000000},
1558*4882a593Smuzhiyun {0x00000088, 0x66036603},
1559*4882a593Smuzhiyun {0x00000089, 0x01000000},
1560*4882a593Smuzhiyun {0x0000008b, 0x1c0a0000},
1561*4882a593Smuzhiyun {0x0000008c, 0xff010000},
1562*4882a593Smuzhiyun {0x0000008e, 0xffffefff},
1563*4882a593Smuzhiyun {0x0000008f, 0xfff3efff},
1564*4882a593Smuzhiyun {0x00000090, 0xfff3efbf},
1565*4882a593Smuzhiyun {0x00000094, 0x00101101},
1566*4882a593Smuzhiyun {0x00000095, 0x00000fff},
1567*4882a593Smuzhiyun {0x00000096, 0x00116fff},
1568*4882a593Smuzhiyun {0x00000097, 0x60010000},
1569*4882a593Smuzhiyun {0x00000098, 0x10010000},
1570*4882a593Smuzhiyun {0x00000099, 0x00006000},
1571*4882a593Smuzhiyun {0x0000009a, 0x00001000},
1572*4882a593Smuzhiyun {0x0000009f, 0x00a07730}
1573*4882a593Smuzhiyun };
1574*4882a593Smuzhiyun
1575*4882a593Smuzhiyun /* ucode loading */
si_mc_load_microcode(struct radeon_device * rdev)1576*4882a593Smuzhiyun int si_mc_load_microcode(struct radeon_device *rdev)
1577*4882a593Smuzhiyun {
1578*4882a593Smuzhiyun const __be32 *fw_data = NULL;
1579*4882a593Smuzhiyun const __le32 *new_fw_data = NULL;
1580*4882a593Smuzhiyun u32 running;
1581*4882a593Smuzhiyun u32 *io_mc_regs = NULL;
1582*4882a593Smuzhiyun const __le32 *new_io_mc_regs = NULL;
1583*4882a593Smuzhiyun int i, regs_size, ucode_size;
1584*4882a593Smuzhiyun
1585*4882a593Smuzhiyun if (!rdev->mc_fw)
1586*4882a593Smuzhiyun return -EINVAL;
1587*4882a593Smuzhiyun
1588*4882a593Smuzhiyun if (rdev->new_fw) {
1589*4882a593Smuzhiyun const struct mc_firmware_header_v1_0 *hdr =
1590*4882a593Smuzhiyun (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
1591*4882a593Smuzhiyun
1592*4882a593Smuzhiyun radeon_ucode_print_mc_hdr(&hdr->header);
1593*4882a593Smuzhiyun regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
1594*4882a593Smuzhiyun new_io_mc_regs = (const __le32 *)
1595*4882a593Smuzhiyun (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
1596*4882a593Smuzhiyun ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
1597*4882a593Smuzhiyun new_fw_data = (const __le32 *)
1598*4882a593Smuzhiyun (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
1599*4882a593Smuzhiyun } else {
1600*4882a593Smuzhiyun ucode_size = rdev->mc_fw->size / 4;
1601*4882a593Smuzhiyun
1602*4882a593Smuzhiyun switch (rdev->family) {
1603*4882a593Smuzhiyun case CHIP_TAHITI:
1604*4882a593Smuzhiyun io_mc_regs = (u32 *)&tahiti_io_mc_regs;
1605*4882a593Smuzhiyun regs_size = TAHITI_IO_MC_REGS_SIZE;
1606*4882a593Smuzhiyun break;
1607*4882a593Smuzhiyun case CHIP_PITCAIRN:
1608*4882a593Smuzhiyun io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
1609*4882a593Smuzhiyun regs_size = TAHITI_IO_MC_REGS_SIZE;
1610*4882a593Smuzhiyun break;
1611*4882a593Smuzhiyun case CHIP_VERDE:
1612*4882a593Smuzhiyun default:
1613*4882a593Smuzhiyun io_mc_regs = (u32 *)&verde_io_mc_regs;
1614*4882a593Smuzhiyun regs_size = TAHITI_IO_MC_REGS_SIZE;
1615*4882a593Smuzhiyun break;
1616*4882a593Smuzhiyun case CHIP_OLAND:
1617*4882a593Smuzhiyun io_mc_regs = (u32 *)&oland_io_mc_regs;
1618*4882a593Smuzhiyun regs_size = TAHITI_IO_MC_REGS_SIZE;
1619*4882a593Smuzhiyun break;
1620*4882a593Smuzhiyun case CHIP_HAINAN:
1621*4882a593Smuzhiyun io_mc_regs = (u32 *)&hainan_io_mc_regs;
1622*4882a593Smuzhiyun regs_size = TAHITI_IO_MC_REGS_SIZE;
1623*4882a593Smuzhiyun break;
1624*4882a593Smuzhiyun }
1625*4882a593Smuzhiyun fw_data = (const __be32 *)rdev->mc_fw->data;
1626*4882a593Smuzhiyun }
1627*4882a593Smuzhiyun
1628*4882a593Smuzhiyun running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
1629*4882a593Smuzhiyun
1630*4882a593Smuzhiyun if (running == 0) {
1631*4882a593Smuzhiyun /* reset the engine and set to writable */
1632*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1633*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
1634*4882a593Smuzhiyun
1635*4882a593Smuzhiyun /* load mc io regs */
1636*4882a593Smuzhiyun for (i = 0; i < regs_size; i++) {
1637*4882a593Smuzhiyun if (rdev->new_fw) {
1638*4882a593Smuzhiyun WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
1639*4882a593Smuzhiyun WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
1640*4882a593Smuzhiyun } else {
1641*4882a593Smuzhiyun WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
1642*4882a593Smuzhiyun WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
1643*4882a593Smuzhiyun }
1644*4882a593Smuzhiyun }
1645*4882a593Smuzhiyun /* load the MC ucode */
1646*4882a593Smuzhiyun for (i = 0; i < ucode_size; i++) {
1647*4882a593Smuzhiyun if (rdev->new_fw)
1648*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
1649*4882a593Smuzhiyun else
1650*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
1651*4882a593Smuzhiyun }
1652*4882a593Smuzhiyun
1653*4882a593Smuzhiyun /* put the engine back into the active state */
1654*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1655*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
1656*4882a593Smuzhiyun WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
1657*4882a593Smuzhiyun
1658*4882a593Smuzhiyun /* wait for training to complete */
1659*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
1660*4882a593Smuzhiyun if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
1661*4882a593Smuzhiyun break;
1662*4882a593Smuzhiyun udelay(1);
1663*4882a593Smuzhiyun }
1664*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
1665*4882a593Smuzhiyun if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
1666*4882a593Smuzhiyun break;
1667*4882a593Smuzhiyun udelay(1);
1668*4882a593Smuzhiyun }
1669*4882a593Smuzhiyun }
1670*4882a593Smuzhiyun
1671*4882a593Smuzhiyun return 0;
1672*4882a593Smuzhiyun }
1673*4882a593Smuzhiyun
si_init_microcode(struct radeon_device * rdev)1674*4882a593Smuzhiyun static int si_init_microcode(struct radeon_device *rdev)
1675*4882a593Smuzhiyun {
1676*4882a593Smuzhiyun const char *chip_name;
1677*4882a593Smuzhiyun const char *new_chip_name;
1678*4882a593Smuzhiyun size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
1679*4882a593Smuzhiyun size_t smc_req_size, mc2_req_size;
1680*4882a593Smuzhiyun char fw_name[30];
1681*4882a593Smuzhiyun int err;
1682*4882a593Smuzhiyun int new_fw = 0;
1683*4882a593Smuzhiyun bool new_smc = false;
1684*4882a593Smuzhiyun bool si58_fw = false;
1685*4882a593Smuzhiyun bool banks2_fw = false;
1686*4882a593Smuzhiyun
1687*4882a593Smuzhiyun DRM_DEBUG("\n");
1688*4882a593Smuzhiyun
1689*4882a593Smuzhiyun switch (rdev->family) {
1690*4882a593Smuzhiyun case CHIP_TAHITI:
1691*4882a593Smuzhiyun chip_name = "TAHITI";
1692*4882a593Smuzhiyun new_chip_name = "tahiti";
1693*4882a593Smuzhiyun pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1694*4882a593Smuzhiyun me_req_size = SI_PM4_UCODE_SIZE * 4;
1695*4882a593Smuzhiyun ce_req_size = SI_CE_UCODE_SIZE * 4;
1696*4882a593Smuzhiyun rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1697*4882a593Smuzhiyun mc_req_size = SI_MC_UCODE_SIZE * 4;
1698*4882a593Smuzhiyun mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
1699*4882a593Smuzhiyun smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
1700*4882a593Smuzhiyun break;
1701*4882a593Smuzhiyun case CHIP_PITCAIRN:
1702*4882a593Smuzhiyun chip_name = "PITCAIRN";
1703*4882a593Smuzhiyun if ((rdev->pdev->revision == 0x81) &&
1704*4882a593Smuzhiyun ((rdev->pdev->device == 0x6810) ||
1705*4882a593Smuzhiyun (rdev->pdev->device == 0x6811)))
1706*4882a593Smuzhiyun new_smc = true;
1707*4882a593Smuzhiyun new_chip_name = "pitcairn";
1708*4882a593Smuzhiyun pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1709*4882a593Smuzhiyun me_req_size = SI_PM4_UCODE_SIZE * 4;
1710*4882a593Smuzhiyun ce_req_size = SI_CE_UCODE_SIZE * 4;
1711*4882a593Smuzhiyun rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1712*4882a593Smuzhiyun mc_req_size = SI_MC_UCODE_SIZE * 4;
1713*4882a593Smuzhiyun mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
1714*4882a593Smuzhiyun smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
1715*4882a593Smuzhiyun break;
1716*4882a593Smuzhiyun case CHIP_VERDE:
1717*4882a593Smuzhiyun chip_name = "VERDE";
1718*4882a593Smuzhiyun if (((rdev->pdev->device == 0x6820) &&
1719*4882a593Smuzhiyun ((rdev->pdev->revision == 0x81) ||
1720*4882a593Smuzhiyun (rdev->pdev->revision == 0x83))) ||
1721*4882a593Smuzhiyun ((rdev->pdev->device == 0x6821) &&
1722*4882a593Smuzhiyun ((rdev->pdev->revision == 0x83) ||
1723*4882a593Smuzhiyun (rdev->pdev->revision == 0x87))) ||
1724*4882a593Smuzhiyun ((rdev->pdev->revision == 0x87) &&
1725*4882a593Smuzhiyun ((rdev->pdev->device == 0x6823) ||
1726*4882a593Smuzhiyun (rdev->pdev->device == 0x682b))))
1727*4882a593Smuzhiyun new_smc = true;
1728*4882a593Smuzhiyun new_chip_name = "verde";
1729*4882a593Smuzhiyun pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1730*4882a593Smuzhiyun me_req_size = SI_PM4_UCODE_SIZE * 4;
1731*4882a593Smuzhiyun ce_req_size = SI_CE_UCODE_SIZE * 4;
1732*4882a593Smuzhiyun rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1733*4882a593Smuzhiyun mc_req_size = SI_MC_UCODE_SIZE * 4;
1734*4882a593Smuzhiyun mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
1735*4882a593Smuzhiyun smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
1736*4882a593Smuzhiyun break;
1737*4882a593Smuzhiyun case CHIP_OLAND:
1738*4882a593Smuzhiyun chip_name = "OLAND";
1739*4882a593Smuzhiyun if (((rdev->pdev->revision == 0x81) &&
1740*4882a593Smuzhiyun ((rdev->pdev->device == 0x6600) ||
1741*4882a593Smuzhiyun (rdev->pdev->device == 0x6604) ||
1742*4882a593Smuzhiyun (rdev->pdev->device == 0x6605) ||
1743*4882a593Smuzhiyun (rdev->pdev->device == 0x6610))) ||
1744*4882a593Smuzhiyun ((rdev->pdev->revision == 0x83) &&
1745*4882a593Smuzhiyun (rdev->pdev->device == 0x6610)))
1746*4882a593Smuzhiyun new_smc = true;
1747*4882a593Smuzhiyun new_chip_name = "oland";
1748*4882a593Smuzhiyun pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1749*4882a593Smuzhiyun me_req_size = SI_PM4_UCODE_SIZE * 4;
1750*4882a593Smuzhiyun ce_req_size = SI_CE_UCODE_SIZE * 4;
1751*4882a593Smuzhiyun rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1752*4882a593Smuzhiyun mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
1753*4882a593Smuzhiyun smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
1754*4882a593Smuzhiyun break;
1755*4882a593Smuzhiyun case CHIP_HAINAN:
1756*4882a593Smuzhiyun chip_name = "HAINAN";
1757*4882a593Smuzhiyun if (((rdev->pdev->revision == 0x81) &&
1758*4882a593Smuzhiyun (rdev->pdev->device == 0x6660)) ||
1759*4882a593Smuzhiyun ((rdev->pdev->revision == 0x83) &&
1760*4882a593Smuzhiyun ((rdev->pdev->device == 0x6660) ||
1761*4882a593Smuzhiyun (rdev->pdev->device == 0x6663) ||
1762*4882a593Smuzhiyun (rdev->pdev->device == 0x6665) ||
1763*4882a593Smuzhiyun (rdev->pdev->device == 0x6667))))
1764*4882a593Smuzhiyun new_smc = true;
1765*4882a593Smuzhiyun else if ((rdev->pdev->revision == 0xc3) &&
1766*4882a593Smuzhiyun (rdev->pdev->device == 0x6665))
1767*4882a593Smuzhiyun banks2_fw = true;
1768*4882a593Smuzhiyun new_chip_name = "hainan";
1769*4882a593Smuzhiyun pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1770*4882a593Smuzhiyun me_req_size = SI_PM4_UCODE_SIZE * 4;
1771*4882a593Smuzhiyun ce_req_size = SI_CE_UCODE_SIZE * 4;
1772*4882a593Smuzhiyun rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1773*4882a593Smuzhiyun mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
1774*4882a593Smuzhiyun smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
1775*4882a593Smuzhiyun break;
1776*4882a593Smuzhiyun default: BUG();
1777*4882a593Smuzhiyun }
1778*4882a593Smuzhiyun
1779*4882a593Smuzhiyun /* this memory configuration requires special firmware */
1780*4882a593Smuzhiyun if (((RREG32(MC_SEQ_MISC0) & 0xff000000) >> 24) == 0x58)
1781*4882a593Smuzhiyun si58_fw = true;
1782*4882a593Smuzhiyun
1783*4882a593Smuzhiyun DRM_INFO("Loading %s Microcode\n", new_chip_name);
1784*4882a593Smuzhiyun
1785*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name);
1786*4882a593Smuzhiyun err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
1787*4882a593Smuzhiyun if (err) {
1788*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
1789*4882a593Smuzhiyun err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
1790*4882a593Smuzhiyun if (err)
1791*4882a593Smuzhiyun goto out;
1792*4882a593Smuzhiyun if (rdev->pfp_fw->size != pfp_req_size) {
1793*4882a593Smuzhiyun pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1794*4882a593Smuzhiyun rdev->pfp_fw->size, fw_name);
1795*4882a593Smuzhiyun err = -EINVAL;
1796*4882a593Smuzhiyun goto out;
1797*4882a593Smuzhiyun }
1798*4882a593Smuzhiyun } else {
1799*4882a593Smuzhiyun err = radeon_ucode_validate(rdev->pfp_fw);
1800*4882a593Smuzhiyun if (err) {
1801*4882a593Smuzhiyun pr_err("si_cp: validation failed for firmware \"%s\"\n",
1802*4882a593Smuzhiyun fw_name);
1803*4882a593Smuzhiyun goto out;
1804*4882a593Smuzhiyun } else {
1805*4882a593Smuzhiyun new_fw++;
1806*4882a593Smuzhiyun }
1807*4882a593Smuzhiyun }
1808*4882a593Smuzhiyun
1809*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name);
1810*4882a593Smuzhiyun err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
1811*4882a593Smuzhiyun if (err) {
1812*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
1813*4882a593Smuzhiyun err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
1814*4882a593Smuzhiyun if (err)
1815*4882a593Smuzhiyun goto out;
1816*4882a593Smuzhiyun if (rdev->me_fw->size != me_req_size) {
1817*4882a593Smuzhiyun pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1818*4882a593Smuzhiyun rdev->me_fw->size, fw_name);
1819*4882a593Smuzhiyun err = -EINVAL;
1820*4882a593Smuzhiyun }
1821*4882a593Smuzhiyun } else {
1822*4882a593Smuzhiyun err = radeon_ucode_validate(rdev->me_fw);
1823*4882a593Smuzhiyun if (err) {
1824*4882a593Smuzhiyun pr_err("si_cp: validation failed for firmware \"%s\"\n",
1825*4882a593Smuzhiyun fw_name);
1826*4882a593Smuzhiyun goto out;
1827*4882a593Smuzhiyun } else {
1828*4882a593Smuzhiyun new_fw++;
1829*4882a593Smuzhiyun }
1830*4882a593Smuzhiyun }
1831*4882a593Smuzhiyun
1832*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name);
1833*4882a593Smuzhiyun err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
1834*4882a593Smuzhiyun if (err) {
1835*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
1836*4882a593Smuzhiyun err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
1837*4882a593Smuzhiyun if (err)
1838*4882a593Smuzhiyun goto out;
1839*4882a593Smuzhiyun if (rdev->ce_fw->size != ce_req_size) {
1840*4882a593Smuzhiyun pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1841*4882a593Smuzhiyun rdev->ce_fw->size, fw_name);
1842*4882a593Smuzhiyun err = -EINVAL;
1843*4882a593Smuzhiyun }
1844*4882a593Smuzhiyun } else {
1845*4882a593Smuzhiyun err = radeon_ucode_validate(rdev->ce_fw);
1846*4882a593Smuzhiyun if (err) {
1847*4882a593Smuzhiyun pr_err("si_cp: validation failed for firmware \"%s\"\n",
1848*4882a593Smuzhiyun fw_name);
1849*4882a593Smuzhiyun goto out;
1850*4882a593Smuzhiyun } else {
1851*4882a593Smuzhiyun new_fw++;
1852*4882a593Smuzhiyun }
1853*4882a593Smuzhiyun }
1854*4882a593Smuzhiyun
1855*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name);
1856*4882a593Smuzhiyun err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
1857*4882a593Smuzhiyun if (err) {
1858*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
1859*4882a593Smuzhiyun err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
1860*4882a593Smuzhiyun if (err)
1861*4882a593Smuzhiyun goto out;
1862*4882a593Smuzhiyun if (rdev->rlc_fw->size != rlc_req_size) {
1863*4882a593Smuzhiyun pr_err("si_rlc: Bogus length %zu in firmware \"%s\"\n",
1864*4882a593Smuzhiyun rdev->rlc_fw->size, fw_name);
1865*4882a593Smuzhiyun err = -EINVAL;
1866*4882a593Smuzhiyun }
1867*4882a593Smuzhiyun } else {
1868*4882a593Smuzhiyun err = radeon_ucode_validate(rdev->rlc_fw);
1869*4882a593Smuzhiyun if (err) {
1870*4882a593Smuzhiyun pr_err("si_cp: validation failed for firmware \"%s\"\n",
1871*4882a593Smuzhiyun fw_name);
1872*4882a593Smuzhiyun goto out;
1873*4882a593Smuzhiyun } else {
1874*4882a593Smuzhiyun new_fw++;
1875*4882a593Smuzhiyun }
1876*4882a593Smuzhiyun }
1877*4882a593Smuzhiyun
1878*4882a593Smuzhiyun if (si58_fw)
1879*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/si58_mc.bin");
1880*4882a593Smuzhiyun else
1881*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name);
1882*4882a593Smuzhiyun err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1883*4882a593Smuzhiyun if (err) {
1884*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
1885*4882a593Smuzhiyun err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1886*4882a593Smuzhiyun if (err) {
1887*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
1888*4882a593Smuzhiyun err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1889*4882a593Smuzhiyun if (err)
1890*4882a593Smuzhiyun goto out;
1891*4882a593Smuzhiyun }
1892*4882a593Smuzhiyun if ((rdev->mc_fw->size != mc_req_size) &&
1893*4882a593Smuzhiyun (rdev->mc_fw->size != mc2_req_size)) {
1894*4882a593Smuzhiyun pr_err("si_mc: Bogus length %zu in firmware \"%s\"\n",
1895*4882a593Smuzhiyun rdev->mc_fw->size, fw_name);
1896*4882a593Smuzhiyun err = -EINVAL;
1897*4882a593Smuzhiyun }
1898*4882a593Smuzhiyun DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
1899*4882a593Smuzhiyun } else {
1900*4882a593Smuzhiyun err = radeon_ucode_validate(rdev->mc_fw);
1901*4882a593Smuzhiyun if (err) {
1902*4882a593Smuzhiyun pr_err("si_cp: validation failed for firmware \"%s\"\n",
1903*4882a593Smuzhiyun fw_name);
1904*4882a593Smuzhiyun goto out;
1905*4882a593Smuzhiyun } else {
1906*4882a593Smuzhiyun new_fw++;
1907*4882a593Smuzhiyun }
1908*4882a593Smuzhiyun }
1909*4882a593Smuzhiyun
1910*4882a593Smuzhiyun if (banks2_fw)
1911*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/banks_k_2_smc.bin");
1912*4882a593Smuzhiyun else if (new_smc)
1913*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name);
1914*4882a593Smuzhiyun else
1915*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name);
1916*4882a593Smuzhiyun err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
1917*4882a593Smuzhiyun if (err) {
1918*4882a593Smuzhiyun snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
1919*4882a593Smuzhiyun err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
1920*4882a593Smuzhiyun if (err) {
1921*4882a593Smuzhiyun pr_err("smc: error loading firmware \"%s\"\n", fw_name);
1922*4882a593Smuzhiyun release_firmware(rdev->smc_fw);
1923*4882a593Smuzhiyun rdev->smc_fw = NULL;
1924*4882a593Smuzhiyun err = 0;
1925*4882a593Smuzhiyun } else if (rdev->smc_fw->size != smc_req_size) {
1926*4882a593Smuzhiyun pr_err("si_smc: Bogus length %zu in firmware \"%s\"\n",
1927*4882a593Smuzhiyun rdev->smc_fw->size, fw_name);
1928*4882a593Smuzhiyun err = -EINVAL;
1929*4882a593Smuzhiyun }
1930*4882a593Smuzhiyun } else {
1931*4882a593Smuzhiyun err = radeon_ucode_validate(rdev->smc_fw);
1932*4882a593Smuzhiyun if (err) {
1933*4882a593Smuzhiyun pr_err("si_cp: validation failed for firmware \"%s\"\n",
1934*4882a593Smuzhiyun fw_name);
1935*4882a593Smuzhiyun goto out;
1936*4882a593Smuzhiyun } else {
1937*4882a593Smuzhiyun new_fw++;
1938*4882a593Smuzhiyun }
1939*4882a593Smuzhiyun }
1940*4882a593Smuzhiyun
1941*4882a593Smuzhiyun if (new_fw == 0) {
1942*4882a593Smuzhiyun rdev->new_fw = false;
1943*4882a593Smuzhiyun } else if (new_fw < 6) {
1944*4882a593Smuzhiyun pr_err("si_fw: mixing new and old firmware!\n");
1945*4882a593Smuzhiyun err = -EINVAL;
1946*4882a593Smuzhiyun } else {
1947*4882a593Smuzhiyun rdev->new_fw = true;
1948*4882a593Smuzhiyun }
1949*4882a593Smuzhiyun out:
1950*4882a593Smuzhiyun if (err) {
1951*4882a593Smuzhiyun if (err != -EINVAL)
1952*4882a593Smuzhiyun pr_err("si_cp: Failed to load firmware \"%s\"\n",
1953*4882a593Smuzhiyun fw_name);
1954*4882a593Smuzhiyun release_firmware(rdev->pfp_fw);
1955*4882a593Smuzhiyun rdev->pfp_fw = NULL;
1956*4882a593Smuzhiyun release_firmware(rdev->me_fw);
1957*4882a593Smuzhiyun rdev->me_fw = NULL;
1958*4882a593Smuzhiyun release_firmware(rdev->ce_fw);
1959*4882a593Smuzhiyun rdev->ce_fw = NULL;
1960*4882a593Smuzhiyun release_firmware(rdev->rlc_fw);
1961*4882a593Smuzhiyun rdev->rlc_fw = NULL;
1962*4882a593Smuzhiyun release_firmware(rdev->mc_fw);
1963*4882a593Smuzhiyun rdev->mc_fw = NULL;
1964*4882a593Smuzhiyun release_firmware(rdev->smc_fw);
1965*4882a593Smuzhiyun rdev->smc_fw = NULL;
1966*4882a593Smuzhiyun }
1967*4882a593Smuzhiyun return err;
1968*4882a593Smuzhiyun }
1969*4882a593Smuzhiyun
1970*4882a593Smuzhiyun /* watermark setup */
dce6_line_buffer_adjust(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,struct drm_display_mode * mode,struct drm_display_mode * other_mode)1971*4882a593Smuzhiyun static u32 dce6_line_buffer_adjust(struct radeon_device *rdev,
1972*4882a593Smuzhiyun struct radeon_crtc *radeon_crtc,
1973*4882a593Smuzhiyun struct drm_display_mode *mode,
1974*4882a593Smuzhiyun struct drm_display_mode *other_mode)
1975*4882a593Smuzhiyun {
1976*4882a593Smuzhiyun u32 tmp, buffer_alloc, i;
1977*4882a593Smuzhiyun u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
1978*4882a593Smuzhiyun /*
1979*4882a593Smuzhiyun * Line Buffer Setup
1980*4882a593Smuzhiyun * There are 3 line buffers, each one shared by 2 display controllers.
1981*4882a593Smuzhiyun * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
1982*4882a593Smuzhiyun * the display controllers. The paritioning is done via one of four
1983*4882a593Smuzhiyun * preset allocations specified in bits 21:20:
1984*4882a593Smuzhiyun * 0 - half lb
1985*4882a593Smuzhiyun * 2 - whole lb, other crtc must be disabled
1986*4882a593Smuzhiyun */
1987*4882a593Smuzhiyun /* this can get tricky if we have two large displays on a paired group
1988*4882a593Smuzhiyun * of crtcs. Ideally for multiple large displays we'd assign them to
1989*4882a593Smuzhiyun * non-linked crtcs for maximum line buffer allocation.
1990*4882a593Smuzhiyun */
1991*4882a593Smuzhiyun if (radeon_crtc->base.enabled && mode) {
1992*4882a593Smuzhiyun if (other_mode) {
1993*4882a593Smuzhiyun tmp = 0; /* 1/2 */
1994*4882a593Smuzhiyun buffer_alloc = 1;
1995*4882a593Smuzhiyun } else {
1996*4882a593Smuzhiyun tmp = 2; /* whole */
1997*4882a593Smuzhiyun buffer_alloc = 2;
1998*4882a593Smuzhiyun }
1999*4882a593Smuzhiyun } else {
2000*4882a593Smuzhiyun tmp = 0;
2001*4882a593Smuzhiyun buffer_alloc = 0;
2002*4882a593Smuzhiyun }
2003*4882a593Smuzhiyun
2004*4882a593Smuzhiyun WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset,
2005*4882a593Smuzhiyun DC_LB_MEMORY_CONFIG(tmp));
2006*4882a593Smuzhiyun
2007*4882a593Smuzhiyun WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
2008*4882a593Smuzhiyun DMIF_BUFFERS_ALLOCATED(buffer_alloc));
2009*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
2010*4882a593Smuzhiyun if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
2011*4882a593Smuzhiyun DMIF_BUFFERS_ALLOCATED_COMPLETED)
2012*4882a593Smuzhiyun break;
2013*4882a593Smuzhiyun udelay(1);
2014*4882a593Smuzhiyun }
2015*4882a593Smuzhiyun
2016*4882a593Smuzhiyun if (radeon_crtc->base.enabled && mode) {
2017*4882a593Smuzhiyun switch (tmp) {
2018*4882a593Smuzhiyun case 0:
2019*4882a593Smuzhiyun default:
2020*4882a593Smuzhiyun return 4096 * 2;
2021*4882a593Smuzhiyun case 2:
2022*4882a593Smuzhiyun return 8192 * 2;
2023*4882a593Smuzhiyun }
2024*4882a593Smuzhiyun }
2025*4882a593Smuzhiyun
2026*4882a593Smuzhiyun /* controller not enabled, so no lb used */
2027*4882a593Smuzhiyun return 0;
2028*4882a593Smuzhiyun }
2029*4882a593Smuzhiyun
si_get_number_of_dram_channels(struct radeon_device * rdev)2030*4882a593Smuzhiyun static u32 si_get_number_of_dram_channels(struct radeon_device *rdev)
2031*4882a593Smuzhiyun {
2032*4882a593Smuzhiyun u32 tmp = RREG32(MC_SHARED_CHMAP);
2033*4882a593Smuzhiyun
2034*4882a593Smuzhiyun switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
2035*4882a593Smuzhiyun case 0:
2036*4882a593Smuzhiyun default:
2037*4882a593Smuzhiyun return 1;
2038*4882a593Smuzhiyun case 1:
2039*4882a593Smuzhiyun return 2;
2040*4882a593Smuzhiyun case 2:
2041*4882a593Smuzhiyun return 4;
2042*4882a593Smuzhiyun case 3:
2043*4882a593Smuzhiyun return 8;
2044*4882a593Smuzhiyun case 4:
2045*4882a593Smuzhiyun return 3;
2046*4882a593Smuzhiyun case 5:
2047*4882a593Smuzhiyun return 6;
2048*4882a593Smuzhiyun case 6:
2049*4882a593Smuzhiyun return 10;
2050*4882a593Smuzhiyun case 7:
2051*4882a593Smuzhiyun return 12;
2052*4882a593Smuzhiyun case 8:
2053*4882a593Smuzhiyun return 16;
2054*4882a593Smuzhiyun }
2055*4882a593Smuzhiyun }
2056*4882a593Smuzhiyun
2057*4882a593Smuzhiyun struct dce6_wm_params {
2058*4882a593Smuzhiyun u32 dram_channels; /* number of dram channels */
2059*4882a593Smuzhiyun u32 yclk; /* bandwidth per dram data pin in kHz */
2060*4882a593Smuzhiyun u32 sclk; /* engine clock in kHz */
2061*4882a593Smuzhiyun u32 disp_clk; /* display clock in kHz */
2062*4882a593Smuzhiyun u32 src_width; /* viewport width */
2063*4882a593Smuzhiyun u32 active_time; /* active display time in ns */
2064*4882a593Smuzhiyun u32 blank_time; /* blank time in ns */
2065*4882a593Smuzhiyun bool interlaced; /* mode is interlaced */
2066*4882a593Smuzhiyun fixed20_12 vsc; /* vertical scale ratio */
2067*4882a593Smuzhiyun u32 num_heads; /* number of active crtcs */
2068*4882a593Smuzhiyun u32 bytes_per_pixel; /* bytes per pixel display + overlay */
2069*4882a593Smuzhiyun u32 lb_size; /* line buffer allocated to pipe */
2070*4882a593Smuzhiyun u32 vtaps; /* vertical scaler taps */
2071*4882a593Smuzhiyun };
2072*4882a593Smuzhiyun
dce6_dram_bandwidth(struct dce6_wm_params * wm)2073*4882a593Smuzhiyun static u32 dce6_dram_bandwidth(struct dce6_wm_params *wm)
2074*4882a593Smuzhiyun {
2075*4882a593Smuzhiyun /* Calculate raw DRAM Bandwidth */
2076*4882a593Smuzhiyun fixed20_12 dram_efficiency; /* 0.7 */
2077*4882a593Smuzhiyun fixed20_12 yclk, dram_channels, bandwidth;
2078*4882a593Smuzhiyun fixed20_12 a;
2079*4882a593Smuzhiyun
2080*4882a593Smuzhiyun a.full = dfixed_const(1000);
2081*4882a593Smuzhiyun yclk.full = dfixed_const(wm->yclk);
2082*4882a593Smuzhiyun yclk.full = dfixed_div(yclk, a);
2083*4882a593Smuzhiyun dram_channels.full = dfixed_const(wm->dram_channels * 4);
2084*4882a593Smuzhiyun a.full = dfixed_const(10);
2085*4882a593Smuzhiyun dram_efficiency.full = dfixed_const(7);
2086*4882a593Smuzhiyun dram_efficiency.full = dfixed_div(dram_efficiency, a);
2087*4882a593Smuzhiyun bandwidth.full = dfixed_mul(dram_channels, yclk);
2088*4882a593Smuzhiyun bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
2089*4882a593Smuzhiyun
2090*4882a593Smuzhiyun return dfixed_trunc(bandwidth);
2091*4882a593Smuzhiyun }
2092*4882a593Smuzhiyun
dce6_dram_bandwidth_for_display(struct dce6_wm_params * wm)2093*4882a593Smuzhiyun static u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm)
2094*4882a593Smuzhiyun {
2095*4882a593Smuzhiyun /* Calculate DRAM Bandwidth and the part allocated to display. */
2096*4882a593Smuzhiyun fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
2097*4882a593Smuzhiyun fixed20_12 yclk, dram_channels, bandwidth;
2098*4882a593Smuzhiyun fixed20_12 a;
2099*4882a593Smuzhiyun
2100*4882a593Smuzhiyun a.full = dfixed_const(1000);
2101*4882a593Smuzhiyun yclk.full = dfixed_const(wm->yclk);
2102*4882a593Smuzhiyun yclk.full = dfixed_div(yclk, a);
2103*4882a593Smuzhiyun dram_channels.full = dfixed_const(wm->dram_channels * 4);
2104*4882a593Smuzhiyun a.full = dfixed_const(10);
2105*4882a593Smuzhiyun disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
2106*4882a593Smuzhiyun disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
2107*4882a593Smuzhiyun bandwidth.full = dfixed_mul(dram_channels, yclk);
2108*4882a593Smuzhiyun bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
2109*4882a593Smuzhiyun
2110*4882a593Smuzhiyun return dfixed_trunc(bandwidth);
2111*4882a593Smuzhiyun }
2112*4882a593Smuzhiyun
dce6_data_return_bandwidth(struct dce6_wm_params * wm)2113*4882a593Smuzhiyun static u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm)
2114*4882a593Smuzhiyun {
2115*4882a593Smuzhiyun /* Calculate the display Data return Bandwidth */
2116*4882a593Smuzhiyun fixed20_12 return_efficiency; /* 0.8 */
2117*4882a593Smuzhiyun fixed20_12 sclk, bandwidth;
2118*4882a593Smuzhiyun fixed20_12 a;
2119*4882a593Smuzhiyun
2120*4882a593Smuzhiyun a.full = dfixed_const(1000);
2121*4882a593Smuzhiyun sclk.full = dfixed_const(wm->sclk);
2122*4882a593Smuzhiyun sclk.full = dfixed_div(sclk, a);
2123*4882a593Smuzhiyun a.full = dfixed_const(10);
2124*4882a593Smuzhiyun return_efficiency.full = dfixed_const(8);
2125*4882a593Smuzhiyun return_efficiency.full = dfixed_div(return_efficiency, a);
2126*4882a593Smuzhiyun a.full = dfixed_const(32);
2127*4882a593Smuzhiyun bandwidth.full = dfixed_mul(a, sclk);
2128*4882a593Smuzhiyun bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
2129*4882a593Smuzhiyun
2130*4882a593Smuzhiyun return dfixed_trunc(bandwidth);
2131*4882a593Smuzhiyun }
2132*4882a593Smuzhiyun
dce6_get_dmif_bytes_per_request(struct dce6_wm_params * wm)2133*4882a593Smuzhiyun static u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm)
2134*4882a593Smuzhiyun {
2135*4882a593Smuzhiyun return 32;
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun
dce6_dmif_request_bandwidth(struct dce6_wm_params * wm)2138*4882a593Smuzhiyun static u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm)
2139*4882a593Smuzhiyun {
2140*4882a593Smuzhiyun /* Calculate the DMIF Request Bandwidth */
2141*4882a593Smuzhiyun fixed20_12 disp_clk_request_efficiency; /* 0.8 */
2142*4882a593Smuzhiyun fixed20_12 disp_clk, sclk, bandwidth;
2143*4882a593Smuzhiyun fixed20_12 a, b1, b2;
2144*4882a593Smuzhiyun u32 min_bandwidth;
2145*4882a593Smuzhiyun
2146*4882a593Smuzhiyun a.full = dfixed_const(1000);
2147*4882a593Smuzhiyun disp_clk.full = dfixed_const(wm->disp_clk);
2148*4882a593Smuzhiyun disp_clk.full = dfixed_div(disp_clk, a);
2149*4882a593Smuzhiyun a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2);
2150*4882a593Smuzhiyun b1.full = dfixed_mul(a, disp_clk);
2151*4882a593Smuzhiyun
2152*4882a593Smuzhiyun a.full = dfixed_const(1000);
2153*4882a593Smuzhiyun sclk.full = dfixed_const(wm->sclk);
2154*4882a593Smuzhiyun sclk.full = dfixed_div(sclk, a);
2155*4882a593Smuzhiyun a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm));
2156*4882a593Smuzhiyun b2.full = dfixed_mul(a, sclk);
2157*4882a593Smuzhiyun
2158*4882a593Smuzhiyun a.full = dfixed_const(10);
2159*4882a593Smuzhiyun disp_clk_request_efficiency.full = dfixed_const(8);
2160*4882a593Smuzhiyun disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
2161*4882a593Smuzhiyun
2162*4882a593Smuzhiyun min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2));
2163*4882a593Smuzhiyun
2164*4882a593Smuzhiyun a.full = dfixed_const(min_bandwidth);
2165*4882a593Smuzhiyun bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency);
2166*4882a593Smuzhiyun
2167*4882a593Smuzhiyun return dfixed_trunc(bandwidth);
2168*4882a593Smuzhiyun }
2169*4882a593Smuzhiyun
dce6_available_bandwidth(struct dce6_wm_params * wm)2170*4882a593Smuzhiyun static u32 dce6_available_bandwidth(struct dce6_wm_params *wm)
2171*4882a593Smuzhiyun {
2172*4882a593Smuzhiyun /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
2173*4882a593Smuzhiyun u32 dram_bandwidth = dce6_dram_bandwidth(wm);
2174*4882a593Smuzhiyun u32 data_return_bandwidth = dce6_data_return_bandwidth(wm);
2175*4882a593Smuzhiyun u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm);
2176*4882a593Smuzhiyun
2177*4882a593Smuzhiyun return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
2178*4882a593Smuzhiyun }
2179*4882a593Smuzhiyun
dce6_average_bandwidth(struct dce6_wm_params * wm)2180*4882a593Smuzhiyun static u32 dce6_average_bandwidth(struct dce6_wm_params *wm)
2181*4882a593Smuzhiyun {
2182*4882a593Smuzhiyun /* Calculate the display mode Average Bandwidth
2183*4882a593Smuzhiyun * DisplayMode should contain the source and destination dimensions,
2184*4882a593Smuzhiyun * timing, etc.
2185*4882a593Smuzhiyun */
2186*4882a593Smuzhiyun fixed20_12 bpp;
2187*4882a593Smuzhiyun fixed20_12 line_time;
2188*4882a593Smuzhiyun fixed20_12 src_width;
2189*4882a593Smuzhiyun fixed20_12 bandwidth;
2190*4882a593Smuzhiyun fixed20_12 a;
2191*4882a593Smuzhiyun
2192*4882a593Smuzhiyun a.full = dfixed_const(1000);
2193*4882a593Smuzhiyun line_time.full = dfixed_const(wm->active_time + wm->blank_time);
2194*4882a593Smuzhiyun line_time.full = dfixed_div(line_time, a);
2195*4882a593Smuzhiyun bpp.full = dfixed_const(wm->bytes_per_pixel);
2196*4882a593Smuzhiyun src_width.full = dfixed_const(wm->src_width);
2197*4882a593Smuzhiyun bandwidth.full = dfixed_mul(src_width, bpp);
2198*4882a593Smuzhiyun bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
2199*4882a593Smuzhiyun bandwidth.full = dfixed_div(bandwidth, line_time);
2200*4882a593Smuzhiyun
2201*4882a593Smuzhiyun return dfixed_trunc(bandwidth);
2202*4882a593Smuzhiyun }
2203*4882a593Smuzhiyun
dce6_latency_watermark(struct dce6_wm_params * wm)2204*4882a593Smuzhiyun static u32 dce6_latency_watermark(struct dce6_wm_params *wm)
2205*4882a593Smuzhiyun {
2206*4882a593Smuzhiyun /* First calcualte the latency in ns */
2207*4882a593Smuzhiyun u32 mc_latency = 2000; /* 2000 ns. */
2208*4882a593Smuzhiyun u32 available_bandwidth = dce6_available_bandwidth(wm);
2209*4882a593Smuzhiyun u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
2210*4882a593Smuzhiyun u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
2211*4882a593Smuzhiyun u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
2212*4882a593Smuzhiyun u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
2213*4882a593Smuzhiyun (wm->num_heads * cursor_line_pair_return_time);
2214*4882a593Smuzhiyun u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
2215*4882a593Smuzhiyun u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
2216*4882a593Smuzhiyun u32 tmp, dmif_size = 12288;
2217*4882a593Smuzhiyun fixed20_12 a, b, c;
2218*4882a593Smuzhiyun
2219*4882a593Smuzhiyun if (wm->num_heads == 0)
2220*4882a593Smuzhiyun return 0;
2221*4882a593Smuzhiyun
2222*4882a593Smuzhiyun a.full = dfixed_const(2);
2223*4882a593Smuzhiyun b.full = dfixed_const(1);
2224*4882a593Smuzhiyun if ((wm->vsc.full > a.full) ||
2225*4882a593Smuzhiyun ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
2226*4882a593Smuzhiyun (wm->vtaps >= 5) ||
2227*4882a593Smuzhiyun ((wm->vsc.full >= a.full) && wm->interlaced))
2228*4882a593Smuzhiyun max_src_lines_per_dst_line = 4;
2229*4882a593Smuzhiyun else
2230*4882a593Smuzhiyun max_src_lines_per_dst_line = 2;
2231*4882a593Smuzhiyun
2232*4882a593Smuzhiyun a.full = dfixed_const(available_bandwidth);
2233*4882a593Smuzhiyun b.full = dfixed_const(wm->num_heads);
2234*4882a593Smuzhiyun a.full = dfixed_div(a, b);
2235*4882a593Smuzhiyun tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
2236*4882a593Smuzhiyun tmp = min(dfixed_trunc(a), tmp);
2237*4882a593Smuzhiyun
2238*4882a593Smuzhiyun lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
2239*4882a593Smuzhiyun
2240*4882a593Smuzhiyun a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
2241*4882a593Smuzhiyun b.full = dfixed_const(1000);
2242*4882a593Smuzhiyun c.full = dfixed_const(lb_fill_bw);
2243*4882a593Smuzhiyun b.full = dfixed_div(c, b);
2244*4882a593Smuzhiyun a.full = dfixed_div(a, b);
2245*4882a593Smuzhiyun line_fill_time = dfixed_trunc(a);
2246*4882a593Smuzhiyun
2247*4882a593Smuzhiyun if (line_fill_time < wm->active_time)
2248*4882a593Smuzhiyun return latency;
2249*4882a593Smuzhiyun else
2250*4882a593Smuzhiyun return latency + (line_fill_time - wm->active_time);
2251*4882a593Smuzhiyun
2252*4882a593Smuzhiyun }
2253*4882a593Smuzhiyun
dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params * wm)2254*4882a593Smuzhiyun static bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm)
2255*4882a593Smuzhiyun {
2256*4882a593Smuzhiyun if (dce6_average_bandwidth(wm) <=
2257*4882a593Smuzhiyun (dce6_dram_bandwidth_for_display(wm) / wm->num_heads))
2258*4882a593Smuzhiyun return true;
2259*4882a593Smuzhiyun else
2260*4882a593Smuzhiyun return false;
2261*4882a593Smuzhiyun };
2262*4882a593Smuzhiyun
dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params * wm)2263*4882a593Smuzhiyun static bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm)
2264*4882a593Smuzhiyun {
2265*4882a593Smuzhiyun if (dce6_average_bandwidth(wm) <=
2266*4882a593Smuzhiyun (dce6_available_bandwidth(wm) / wm->num_heads))
2267*4882a593Smuzhiyun return true;
2268*4882a593Smuzhiyun else
2269*4882a593Smuzhiyun return false;
2270*4882a593Smuzhiyun };
2271*4882a593Smuzhiyun
dce6_check_latency_hiding(struct dce6_wm_params * wm)2272*4882a593Smuzhiyun static bool dce6_check_latency_hiding(struct dce6_wm_params *wm)
2273*4882a593Smuzhiyun {
2274*4882a593Smuzhiyun u32 lb_partitions = wm->lb_size / wm->src_width;
2275*4882a593Smuzhiyun u32 line_time = wm->active_time + wm->blank_time;
2276*4882a593Smuzhiyun u32 latency_tolerant_lines;
2277*4882a593Smuzhiyun u32 latency_hiding;
2278*4882a593Smuzhiyun fixed20_12 a;
2279*4882a593Smuzhiyun
2280*4882a593Smuzhiyun a.full = dfixed_const(1);
2281*4882a593Smuzhiyun if (wm->vsc.full > a.full)
2282*4882a593Smuzhiyun latency_tolerant_lines = 1;
2283*4882a593Smuzhiyun else {
2284*4882a593Smuzhiyun if (lb_partitions <= (wm->vtaps + 1))
2285*4882a593Smuzhiyun latency_tolerant_lines = 1;
2286*4882a593Smuzhiyun else
2287*4882a593Smuzhiyun latency_tolerant_lines = 2;
2288*4882a593Smuzhiyun }
2289*4882a593Smuzhiyun
2290*4882a593Smuzhiyun latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
2291*4882a593Smuzhiyun
2292*4882a593Smuzhiyun if (dce6_latency_watermark(wm) <= latency_hiding)
2293*4882a593Smuzhiyun return true;
2294*4882a593Smuzhiyun else
2295*4882a593Smuzhiyun return false;
2296*4882a593Smuzhiyun }
2297*4882a593Smuzhiyun
dce6_program_watermarks(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,u32 lb_size,u32 num_heads)2298*4882a593Smuzhiyun static void dce6_program_watermarks(struct radeon_device *rdev,
2299*4882a593Smuzhiyun struct radeon_crtc *radeon_crtc,
2300*4882a593Smuzhiyun u32 lb_size, u32 num_heads)
2301*4882a593Smuzhiyun {
2302*4882a593Smuzhiyun struct drm_display_mode *mode = &radeon_crtc->base.mode;
2303*4882a593Smuzhiyun struct dce6_wm_params wm_low, wm_high;
2304*4882a593Smuzhiyun u32 dram_channels;
2305*4882a593Smuzhiyun u32 active_time;
2306*4882a593Smuzhiyun u32 line_time = 0;
2307*4882a593Smuzhiyun u32 latency_watermark_a = 0, latency_watermark_b = 0;
2308*4882a593Smuzhiyun u32 priority_a_mark = 0, priority_b_mark = 0;
2309*4882a593Smuzhiyun u32 priority_a_cnt = PRIORITY_OFF;
2310*4882a593Smuzhiyun u32 priority_b_cnt = PRIORITY_OFF;
2311*4882a593Smuzhiyun u32 tmp, arb_control3;
2312*4882a593Smuzhiyun fixed20_12 a, b, c;
2313*4882a593Smuzhiyun
2314*4882a593Smuzhiyun if (radeon_crtc->base.enabled && num_heads && mode) {
2315*4882a593Smuzhiyun active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
2316*4882a593Smuzhiyun (u32)mode->clock);
2317*4882a593Smuzhiyun line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
2318*4882a593Smuzhiyun (u32)mode->clock);
2319*4882a593Smuzhiyun line_time = min(line_time, (u32)65535);
2320*4882a593Smuzhiyun priority_a_cnt = 0;
2321*4882a593Smuzhiyun priority_b_cnt = 0;
2322*4882a593Smuzhiyun
2323*4882a593Smuzhiyun if (rdev->family == CHIP_ARUBA)
2324*4882a593Smuzhiyun dram_channels = evergreen_get_number_of_dram_channels(rdev);
2325*4882a593Smuzhiyun else
2326*4882a593Smuzhiyun dram_channels = si_get_number_of_dram_channels(rdev);
2327*4882a593Smuzhiyun
2328*4882a593Smuzhiyun /* watermark for high clocks */
2329*4882a593Smuzhiyun if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
2330*4882a593Smuzhiyun wm_high.yclk =
2331*4882a593Smuzhiyun radeon_dpm_get_mclk(rdev, false) * 10;
2332*4882a593Smuzhiyun wm_high.sclk =
2333*4882a593Smuzhiyun radeon_dpm_get_sclk(rdev, false) * 10;
2334*4882a593Smuzhiyun } else {
2335*4882a593Smuzhiyun wm_high.yclk = rdev->pm.current_mclk * 10;
2336*4882a593Smuzhiyun wm_high.sclk = rdev->pm.current_sclk * 10;
2337*4882a593Smuzhiyun }
2338*4882a593Smuzhiyun
2339*4882a593Smuzhiyun wm_high.disp_clk = mode->clock;
2340*4882a593Smuzhiyun wm_high.src_width = mode->crtc_hdisplay;
2341*4882a593Smuzhiyun wm_high.active_time = active_time;
2342*4882a593Smuzhiyun wm_high.blank_time = line_time - wm_high.active_time;
2343*4882a593Smuzhiyun wm_high.interlaced = false;
2344*4882a593Smuzhiyun if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2345*4882a593Smuzhiyun wm_high.interlaced = true;
2346*4882a593Smuzhiyun wm_high.vsc = radeon_crtc->vsc;
2347*4882a593Smuzhiyun wm_high.vtaps = 1;
2348*4882a593Smuzhiyun if (radeon_crtc->rmx_type != RMX_OFF)
2349*4882a593Smuzhiyun wm_high.vtaps = 2;
2350*4882a593Smuzhiyun wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
2351*4882a593Smuzhiyun wm_high.lb_size = lb_size;
2352*4882a593Smuzhiyun wm_high.dram_channels = dram_channels;
2353*4882a593Smuzhiyun wm_high.num_heads = num_heads;
2354*4882a593Smuzhiyun
2355*4882a593Smuzhiyun /* watermark for low clocks */
2356*4882a593Smuzhiyun if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
2357*4882a593Smuzhiyun wm_low.yclk =
2358*4882a593Smuzhiyun radeon_dpm_get_mclk(rdev, true) * 10;
2359*4882a593Smuzhiyun wm_low.sclk =
2360*4882a593Smuzhiyun radeon_dpm_get_sclk(rdev, true) * 10;
2361*4882a593Smuzhiyun } else {
2362*4882a593Smuzhiyun wm_low.yclk = rdev->pm.current_mclk * 10;
2363*4882a593Smuzhiyun wm_low.sclk = rdev->pm.current_sclk * 10;
2364*4882a593Smuzhiyun }
2365*4882a593Smuzhiyun
2366*4882a593Smuzhiyun wm_low.disp_clk = mode->clock;
2367*4882a593Smuzhiyun wm_low.src_width = mode->crtc_hdisplay;
2368*4882a593Smuzhiyun wm_low.active_time = active_time;
2369*4882a593Smuzhiyun wm_low.blank_time = line_time - wm_low.active_time;
2370*4882a593Smuzhiyun wm_low.interlaced = false;
2371*4882a593Smuzhiyun if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2372*4882a593Smuzhiyun wm_low.interlaced = true;
2373*4882a593Smuzhiyun wm_low.vsc = radeon_crtc->vsc;
2374*4882a593Smuzhiyun wm_low.vtaps = 1;
2375*4882a593Smuzhiyun if (radeon_crtc->rmx_type != RMX_OFF)
2376*4882a593Smuzhiyun wm_low.vtaps = 2;
2377*4882a593Smuzhiyun wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
2378*4882a593Smuzhiyun wm_low.lb_size = lb_size;
2379*4882a593Smuzhiyun wm_low.dram_channels = dram_channels;
2380*4882a593Smuzhiyun wm_low.num_heads = num_heads;
2381*4882a593Smuzhiyun
2382*4882a593Smuzhiyun /* set for high clocks */
2383*4882a593Smuzhiyun latency_watermark_a = min(dce6_latency_watermark(&wm_high), (u32)65535);
2384*4882a593Smuzhiyun /* set for low clocks */
2385*4882a593Smuzhiyun latency_watermark_b = min(dce6_latency_watermark(&wm_low), (u32)65535);
2386*4882a593Smuzhiyun
2387*4882a593Smuzhiyun /* possibly force display priority to high */
2388*4882a593Smuzhiyun /* should really do this at mode validation time... */
2389*4882a593Smuzhiyun if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
2390*4882a593Smuzhiyun !dce6_average_bandwidth_vs_available_bandwidth(&wm_high) ||
2391*4882a593Smuzhiyun !dce6_check_latency_hiding(&wm_high) ||
2392*4882a593Smuzhiyun (rdev->disp_priority == 2)) {
2393*4882a593Smuzhiyun DRM_DEBUG_KMS("force priority to high\n");
2394*4882a593Smuzhiyun priority_a_cnt |= PRIORITY_ALWAYS_ON;
2395*4882a593Smuzhiyun priority_b_cnt |= PRIORITY_ALWAYS_ON;
2396*4882a593Smuzhiyun }
2397*4882a593Smuzhiyun if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
2398*4882a593Smuzhiyun !dce6_average_bandwidth_vs_available_bandwidth(&wm_low) ||
2399*4882a593Smuzhiyun !dce6_check_latency_hiding(&wm_low) ||
2400*4882a593Smuzhiyun (rdev->disp_priority == 2)) {
2401*4882a593Smuzhiyun DRM_DEBUG_KMS("force priority to high\n");
2402*4882a593Smuzhiyun priority_a_cnt |= PRIORITY_ALWAYS_ON;
2403*4882a593Smuzhiyun priority_b_cnt |= PRIORITY_ALWAYS_ON;
2404*4882a593Smuzhiyun }
2405*4882a593Smuzhiyun
2406*4882a593Smuzhiyun a.full = dfixed_const(1000);
2407*4882a593Smuzhiyun b.full = dfixed_const(mode->clock);
2408*4882a593Smuzhiyun b.full = dfixed_div(b, a);
2409*4882a593Smuzhiyun c.full = dfixed_const(latency_watermark_a);
2410*4882a593Smuzhiyun c.full = dfixed_mul(c, b);
2411*4882a593Smuzhiyun c.full = dfixed_mul(c, radeon_crtc->hsc);
2412*4882a593Smuzhiyun c.full = dfixed_div(c, a);
2413*4882a593Smuzhiyun a.full = dfixed_const(16);
2414*4882a593Smuzhiyun c.full = dfixed_div(c, a);
2415*4882a593Smuzhiyun priority_a_mark = dfixed_trunc(c);
2416*4882a593Smuzhiyun priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
2417*4882a593Smuzhiyun
2418*4882a593Smuzhiyun a.full = dfixed_const(1000);
2419*4882a593Smuzhiyun b.full = dfixed_const(mode->clock);
2420*4882a593Smuzhiyun b.full = dfixed_div(b, a);
2421*4882a593Smuzhiyun c.full = dfixed_const(latency_watermark_b);
2422*4882a593Smuzhiyun c.full = dfixed_mul(c, b);
2423*4882a593Smuzhiyun c.full = dfixed_mul(c, radeon_crtc->hsc);
2424*4882a593Smuzhiyun c.full = dfixed_div(c, a);
2425*4882a593Smuzhiyun a.full = dfixed_const(16);
2426*4882a593Smuzhiyun c.full = dfixed_div(c, a);
2427*4882a593Smuzhiyun priority_b_mark = dfixed_trunc(c);
2428*4882a593Smuzhiyun priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
2429*4882a593Smuzhiyun
2430*4882a593Smuzhiyun /* Save number of lines the linebuffer leads before the scanout */
2431*4882a593Smuzhiyun radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
2432*4882a593Smuzhiyun }
2433*4882a593Smuzhiyun
2434*4882a593Smuzhiyun /* select wm A */
2435*4882a593Smuzhiyun arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
2436*4882a593Smuzhiyun tmp = arb_control3;
2437*4882a593Smuzhiyun tmp &= ~LATENCY_WATERMARK_MASK(3);
2438*4882a593Smuzhiyun tmp |= LATENCY_WATERMARK_MASK(1);
2439*4882a593Smuzhiyun WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
2440*4882a593Smuzhiyun WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
2441*4882a593Smuzhiyun (LATENCY_LOW_WATERMARK(latency_watermark_a) |
2442*4882a593Smuzhiyun LATENCY_HIGH_WATERMARK(line_time)));
2443*4882a593Smuzhiyun /* select wm B */
2444*4882a593Smuzhiyun tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
2445*4882a593Smuzhiyun tmp &= ~LATENCY_WATERMARK_MASK(3);
2446*4882a593Smuzhiyun tmp |= LATENCY_WATERMARK_MASK(2);
2447*4882a593Smuzhiyun WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
2448*4882a593Smuzhiyun WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
2449*4882a593Smuzhiyun (LATENCY_LOW_WATERMARK(latency_watermark_b) |
2450*4882a593Smuzhiyun LATENCY_HIGH_WATERMARK(line_time)));
2451*4882a593Smuzhiyun /* restore original selection */
2452*4882a593Smuzhiyun WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3);
2453*4882a593Smuzhiyun
2454*4882a593Smuzhiyun /* write the priority marks */
2455*4882a593Smuzhiyun WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
2456*4882a593Smuzhiyun WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
2457*4882a593Smuzhiyun
2458*4882a593Smuzhiyun /* save values for DPM */
2459*4882a593Smuzhiyun radeon_crtc->line_time = line_time;
2460*4882a593Smuzhiyun radeon_crtc->wm_high = latency_watermark_a;
2461*4882a593Smuzhiyun radeon_crtc->wm_low = latency_watermark_b;
2462*4882a593Smuzhiyun }
2463*4882a593Smuzhiyun
dce6_bandwidth_update(struct radeon_device * rdev)2464*4882a593Smuzhiyun void dce6_bandwidth_update(struct radeon_device *rdev)
2465*4882a593Smuzhiyun {
2466*4882a593Smuzhiyun struct drm_display_mode *mode0 = NULL;
2467*4882a593Smuzhiyun struct drm_display_mode *mode1 = NULL;
2468*4882a593Smuzhiyun u32 num_heads = 0, lb_size;
2469*4882a593Smuzhiyun int i;
2470*4882a593Smuzhiyun
2471*4882a593Smuzhiyun if (!rdev->mode_info.mode_config_initialized)
2472*4882a593Smuzhiyun return;
2473*4882a593Smuzhiyun
2474*4882a593Smuzhiyun radeon_update_display_priority(rdev);
2475*4882a593Smuzhiyun
2476*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i++) {
2477*4882a593Smuzhiyun if (rdev->mode_info.crtcs[i]->base.enabled)
2478*4882a593Smuzhiyun num_heads++;
2479*4882a593Smuzhiyun }
2480*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i += 2) {
2481*4882a593Smuzhiyun mode0 = &rdev->mode_info.crtcs[i]->base.mode;
2482*4882a593Smuzhiyun mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
2483*4882a593Smuzhiyun lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
2484*4882a593Smuzhiyun dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
2485*4882a593Smuzhiyun lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
2486*4882a593Smuzhiyun dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
2487*4882a593Smuzhiyun }
2488*4882a593Smuzhiyun }
2489*4882a593Smuzhiyun
2490*4882a593Smuzhiyun /*
2491*4882a593Smuzhiyun * Core functions
2492*4882a593Smuzhiyun */
si_tiling_mode_table_init(struct radeon_device * rdev)2493*4882a593Smuzhiyun static void si_tiling_mode_table_init(struct radeon_device *rdev)
2494*4882a593Smuzhiyun {
2495*4882a593Smuzhiyun u32 *tile = rdev->config.si.tile_mode_array;
2496*4882a593Smuzhiyun const u32 num_tile_mode_states =
2497*4882a593Smuzhiyun ARRAY_SIZE(rdev->config.si.tile_mode_array);
2498*4882a593Smuzhiyun u32 reg_offset, split_equal_to_row_size;
2499*4882a593Smuzhiyun
2500*4882a593Smuzhiyun switch (rdev->config.si.mem_row_size_in_kb) {
2501*4882a593Smuzhiyun case 1:
2502*4882a593Smuzhiyun split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
2503*4882a593Smuzhiyun break;
2504*4882a593Smuzhiyun case 2:
2505*4882a593Smuzhiyun default:
2506*4882a593Smuzhiyun split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
2507*4882a593Smuzhiyun break;
2508*4882a593Smuzhiyun case 4:
2509*4882a593Smuzhiyun split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
2510*4882a593Smuzhiyun break;
2511*4882a593Smuzhiyun }
2512*4882a593Smuzhiyun
2513*4882a593Smuzhiyun for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2514*4882a593Smuzhiyun tile[reg_offset] = 0;
2515*4882a593Smuzhiyun
2516*4882a593Smuzhiyun switch(rdev->family) {
2517*4882a593Smuzhiyun case CHIP_TAHITI:
2518*4882a593Smuzhiyun case CHIP_PITCAIRN:
2519*4882a593Smuzhiyun /* non-AA compressed depth or any compressed stencil */
2520*4882a593Smuzhiyun tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2521*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2522*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2523*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2524*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2525*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2526*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2527*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2528*4882a593Smuzhiyun /* 2xAA/4xAA compressed depth only */
2529*4882a593Smuzhiyun tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2530*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2531*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2532*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2533*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2534*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2535*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2536*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2537*4882a593Smuzhiyun /* 8xAA compressed depth only */
2538*4882a593Smuzhiyun tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2539*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2540*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2541*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2542*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2543*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2544*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2545*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2546*4882a593Smuzhiyun /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
2547*4882a593Smuzhiyun tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2548*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2549*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2550*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2551*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2552*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2553*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2554*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2555*4882a593Smuzhiyun /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
2556*4882a593Smuzhiyun tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2557*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2558*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2559*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2560*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2561*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2562*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2563*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2564*4882a593Smuzhiyun /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
2565*4882a593Smuzhiyun tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2566*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2567*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2568*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2569*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2570*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2571*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2572*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2573*4882a593Smuzhiyun /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
2574*4882a593Smuzhiyun tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2575*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2576*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2577*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2578*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2579*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2580*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2581*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2582*4882a593Smuzhiyun /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
2583*4882a593Smuzhiyun tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2584*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2585*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2586*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2587*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2588*4882a593Smuzhiyun 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_2));
2591*4882a593Smuzhiyun /* 1D and 1D Array Surfaces */
2592*4882a593Smuzhiyun tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2593*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2594*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2595*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2596*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2597*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2598*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2599*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2600*4882a593Smuzhiyun /* Displayable maps. */
2601*4882a593Smuzhiyun tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2602*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2603*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2604*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2605*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2606*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2607*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2608*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2609*4882a593Smuzhiyun /* Display 8bpp. */
2610*4882a593Smuzhiyun tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2611*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2612*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2613*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2614*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2615*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2616*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2617*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2618*4882a593Smuzhiyun /* Display 16bpp. */
2619*4882a593Smuzhiyun tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2620*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2621*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2622*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2623*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2624*4882a593Smuzhiyun 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 /* Display 32bpp. */
2628*4882a593Smuzhiyun tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2629*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2630*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2631*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2632*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2633*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2634*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2635*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2636*4882a593Smuzhiyun /* Thin. */
2637*4882a593Smuzhiyun tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2638*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2639*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2640*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2641*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2642*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2643*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2644*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2645*4882a593Smuzhiyun /* Thin 8 bpp. */
2646*4882a593Smuzhiyun tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2647*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2648*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2649*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2650*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2651*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2652*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2653*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2654*4882a593Smuzhiyun /* Thin 16 bpp. */
2655*4882a593Smuzhiyun tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2656*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2657*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2658*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2659*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2660*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2661*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2662*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2663*4882a593Smuzhiyun /* Thin 32 bpp. */
2664*4882a593Smuzhiyun tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2665*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2666*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2667*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2668*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2669*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2670*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2671*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2672*4882a593Smuzhiyun /* Thin 64 bpp. */
2673*4882a593Smuzhiyun tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2674*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2675*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2676*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2677*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2678*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2679*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2680*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2681*4882a593Smuzhiyun /* 8 bpp PRT. */
2682*4882a593Smuzhiyun tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2683*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2684*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2685*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2686*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2687*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2688*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2689*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2690*4882a593Smuzhiyun /* 16 bpp PRT */
2691*4882a593Smuzhiyun tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2692*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2693*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2694*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2695*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2696*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2697*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2698*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2699*4882a593Smuzhiyun /* 32 bpp PRT */
2700*4882a593Smuzhiyun tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2701*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2702*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2703*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2704*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2705*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2706*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2707*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2708*4882a593Smuzhiyun /* 64 bpp PRT */
2709*4882a593Smuzhiyun tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2710*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2711*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2712*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2713*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2714*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2715*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2716*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2717*4882a593Smuzhiyun /* 128 bpp PRT */
2718*4882a593Smuzhiyun tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2719*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2720*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2721*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
2722*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_8_BANK) |
2723*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2724*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2725*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2726*4882a593Smuzhiyun
2727*4882a593Smuzhiyun for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2728*4882a593Smuzhiyun WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2729*4882a593Smuzhiyun break;
2730*4882a593Smuzhiyun
2731*4882a593Smuzhiyun case CHIP_VERDE:
2732*4882a593Smuzhiyun case CHIP_OLAND:
2733*4882a593Smuzhiyun case CHIP_HAINAN:
2734*4882a593Smuzhiyun /* non-AA compressed depth or any compressed stencil */
2735*4882a593Smuzhiyun tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2736*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2737*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2738*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2739*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2740*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2741*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2742*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2743*4882a593Smuzhiyun /* 2xAA/4xAA compressed depth only */
2744*4882a593Smuzhiyun tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2745*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2746*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2747*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2748*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2749*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2750*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2751*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2752*4882a593Smuzhiyun /* 8xAA compressed depth only */
2753*4882a593Smuzhiyun tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2754*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2755*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2756*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2757*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2758*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2759*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2760*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2761*4882a593Smuzhiyun /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
2762*4882a593Smuzhiyun tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2763*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2764*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2765*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2766*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2767*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2768*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2769*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2770*4882a593Smuzhiyun /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
2771*4882a593Smuzhiyun tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2772*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2773*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2774*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2775*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2776*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2777*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2778*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2779*4882a593Smuzhiyun /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
2780*4882a593Smuzhiyun tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2781*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2782*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2783*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2784*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2785*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2786*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2787*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2788*4882a593Smuzhiyun /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
2789*4882a593Smuzhiyun tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2790*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2791*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2792*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2793*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2794*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2795*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2796*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2797*4882a593Smuzhiyun /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
2798*4882a593Smuzhiyun tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2799*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2800*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2801*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2802*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2803*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2804*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2805*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2806*4882a593Smuzhiyun /* 1D and 1D Array Surfaces */
2807*4882a593Smuzhiyun tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2808*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2809*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2810*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2811*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2812*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2813*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2814*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2815*4882a593Smuzhiyun /* Displayable maps. */
2816*4882a593Smuzhiyun tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2817*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2818*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2819*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2820*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2821*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2822*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2823*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2824*4882a593Smuzhiyun /* Display 8bpp. */
2825*4882a593Smuzhiyun tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2826*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2827*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2828*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2829*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2830*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2831*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2832*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2833*4882a593Smuzhiyun /* Display 16bpp. */
2834*4882a593Smuzhiyun tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2835*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2836*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2837*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2838*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2839*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2840*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2841*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2842*4882a593Smuzhiyun /* Display 32bpp. */
2843*4882a593Smuzhiyun tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2844*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2845*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2846*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2847*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2848*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2849*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2850*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2851*4882a593Smuzhiyun /* Thin. */
2852*4882a593Smuzhiyun tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2853*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2854*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2855*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2856*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2857*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2858*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2859*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2860*4882a593Smuzhiyun /* Thin 8 bpp. */
2861*4882a593Smuzhiyun tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2862*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2863*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2864*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2865*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2866*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2867*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2868*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2869*4882a593Smuzhiyun /* Thin 16 bpp. */
2870*4882a593Smuzhiyun tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2871*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2872*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2873*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2874*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2875*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2876*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2877*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2878*4882a593Smuzhiyun /* Thin 32 bpp. */
2879*4882a593Smuzhiyun tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2880*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2881*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2882*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2883*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2884*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2885*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2886*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2887*4882a593Smuzhiyun /* Thin 64 bpp. */
2888*4882a593Smuzhiyun tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2889*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2890*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2891*4882a593Smuzhiyun TILE_SPLIT(split_equal_to_row_size) |
2892*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2893*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2894*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2895*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2896*4882a593Smuzhiyun /* 8 bpp PRT. */
2897*4882a593Smuzhiyun tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2898*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2899*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2900*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2901*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2902*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2903*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2904*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2905*4882a593Smuzhiyun /* 16 bpp PRT */
2906*4882a593Smuzhiyun tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2907*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2908*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2909*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2910*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2911*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2912*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2913*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2914*4882a593Smuzhiyun /* 32 bpp PRT */
2915*4882a593Smuzhiyun tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2916*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2917*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2918*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2919*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2920*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2921*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2922*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2923*4882a593Smuzhiyun /* 64 bpp PRT */
2924*4882a593Smuzhiyun tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2925*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2926*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2927*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2928*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_16_BANK) |
2929*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2930*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2931*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2932*4882a593Smuzhiyun /* 128 bpp PRT */
2933*4882a593Smuzhiyun tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2934*4882a593Smuzhiyun MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2935*4882a593Smuzhiyun PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2936*4882a593Smuzhiyun TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
2937*4882a593Smuzhiyun NUM_BANKS(ADDR_SURF_8_BANK) |
2938*4882a593Smuzhiyun BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2939*4882a593Smuzhiyun BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2940*4882a593Smuzhiyun MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2941*4882a593Smuzhiyun
2942*4882a593Smuzhiyun for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2943*4882a593Smuzhiyun WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2944*4882a593Smuzhiyun break;
2945*4882a593Smuzhiyun
2946*4882a593Smuzhiyun default:
2947*4882a593Smuzhiyun DRM_ERROR("unknown asic: 0x%x\n", rdev->family);
2948*4882a593Smuzhiyun }
2949*4882a593Smuzhiyun }
2950*4882a593Smuzhiyun
si_select_se_sh(struct radeon_device * rdev,u32 se_num,u32 sh_num)2951*4882a593Smuzhiyun static void si_select_se_sh(struct radeon_device *rdev,
2952*4882a593Smuzhiyun u32 se_num, u32 sh_num)
2953*4882a593Smuzhiyun {
2954*4882a593Smuzhiyun u32 data = INSTANCE_BROADCAST_WRITES;
2955*4882a593Smuzhiyun
2956*4882a593Smuzhiyun if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
2957*4882a593Smuzhiyun data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
2958*4882a593Smuzhiyun else if (se_num == 0xffffffff)
2959*4882a593Smuzhiyun data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
2960*4882a593Smuzhiyun else if (sh_num == 0xffffffff)
2961*4882a593Smuzhiyun data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
2962*4882a593Smuzhiyun else
2963*4882a593Smuzhiyun data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
2964*4882a593Smuzhiyun WREG32(GRBM_GFX_INDEX, data);
2965*4882a593Smuzhiyun }
2966*4882a593Smuzhiyun
si_create_bitmask(u32 bit_width)2967*4882a593Smuzhiyun static u32 si_create_bitmask(u32 bit_width)
2968*4882a593Smuzhiyun {
2969*4882a593Smuzhiyun u32 i, mask = 0;
2970*4882a593Smuzhiyun
2971*4882a593Smuzhiyun for (i = 0; i < bit_width; i++) {
2972*4882a593Smuzhiyun mask <<= 1;
2973*4882a593Smuzhiyun mask |= 1;
2974*4882a593Smuzhiyun }
2975*4882a593Smuzhiyun return mask;
2976*4882a593Smuzhiyun }
2977*4882a593Smuzhiyun
si_get_cu_enabled(struct radeon_device * rdev,u32 cu_per_sh)2978*4882a593Smuzhiyun static u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh)
2979*4882a593Smuzhiyun {
2980*4882a593Smuzhiyun u32 data, mask;
2981*4882a593Smuzhiyun
2982*4882a593Smuzhiyun data = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
2983*4882a593Smuzhiyun if (data & 1)
2984*4882a593Smuzhiyun data &= INACTIVE_CUS_MASK;
2985*4882a593Smuzhiyun else
2986*4882a593Smuzhiyun data = 0;
2987*4882a593Smuzhiyun data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG);
2988*4882a593Smuzhiyun
2989*4882a593Smuzhiyun data >>= INACTIVE_CUS_SHIFT;
2990*4882a593Smuzhiyun
2991*4882a593Smuzhiyun mask = si_create_bitmask(cu_per_sh);
2992*4882a593Smuzhiyun
2993*4882a593Smuzhiyun return ~data & mask;
2994*4882a593Smuzhiyun }
2995*4882a593Smuzhiyun
si_setup_spi(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 cu_per_sh)2996*4882a593Smuzhiyun static void si_setup_spi(struct radeon_device *rdev,
2997*4882a593Smuzhiyun u32 se_num, u32 sh_per_se,
2998*4882a593Smuzhiyun u32 cu_per_sh)
2999*4882a593Smuzhiyun {
3000*4882a593Smuzhiyun int i, j, k;
3001*4882a593Smuzhiyun u32 data, mask, active_cu;
3002*4882a593Smuzhiyun
3003*4882a593Smuzhiyun for (i = 0; i < se_num; i++) {
3004*4882a593Smuzhiyun for (j = 0; j < sh_per_se; j++) {
3005*4882a593Smuzhiyun si_select_se_sh(rdev, i, j);
3006*4882a593Smuzhiyun data = RREG32(SPI_STATIC_THREAD_MGMT_3);
3007*4882a593Smuzhiyun active_cu = si_get_cu_enabled(rdev, cu_per_sh);
3008*4882a593Smuzhiyun
3009*4882a593Smuzhiyun mask = 1;
3010*4882a593Smuzhiyun for (k = 0; k < 16; k++) {
3011*4882a593Smuzhiyun mask <<= k;
3012*4882a593Smuzhiyun if (active_cu & mask) {
3013*4882a593Smuzhiyun data &= ~mask;
3014*4882a593Smuzhiyun WREG32(SPI_STATIC_THREAD_MGMT_3, data);
3015*4882a593Smuzhiyun break;
3016*4882a593Smuzhiyun }
3017*4882a593Smuzhiyun }
3018*4882a593Smuzhiyun }
3019*4882a593Smuzhiyun }
3020*4882a593Smuzhiyun si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3021*4882a593Smuzhiyun }
3022*4882a593Smuzhiyun
si_get_rb_disabled(struct radeon_device * rdev,u32 max_rb_num_per_se,u32 sh_per_se)3023*4882a593Smuzhiyun static u32 si_get_rb_disabled(struct radeon_device *rdev,
3024*4882a593Smuzhiyun u32 max_rb_num_per_se,
3025*4882a593Smuzhiyun u32 sh_per_se)
3026*4882a593Smuzhiyun {
3027*4882a593Smuzhiyun u32 data, mask;
3028*4882a593Smuzhiyun
3029*4882a593Smuzhiyun data = RREG32(CC_RB_BACKEND_DISABLE);
3030*4882a593Smuzhiyun if (data & 1)
3031*4882a593Smuzhiyun data &= BACKEND_DISABLE_MASK;
3032*4882a593Smuzhiyun else
3033*4882a593Smuzhiyun data = 0;
3034*4882a593Smuzhiyun data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
3035*4882a593Smuzhiyun
3036*4882a593Smuzhiyun data >>= BACKEND_DISABLE_SHIFT;
3037*4882a593Smuzhiyun
3038*4882a593Smuzhiyun mask = si_create_bitmask(max_rb_num_per_se / sh_per_se);
3039*4882a593Smuzhiyun
3040*4882a593Smuzhiyun return data & mask;
3041*4882a593Smuzhiyun }
3042*4882a593Smuzhiyun
si_setup_rb(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 max_rb_num_per_se)3043*4882a593Smuzhiyun static void si_setup_rb(struct radeon_device *rdev,
3044*4882a593Smuzhiyun u32 se_num, u32 sh_per_se,
3045*4882a593Smuzhiyun u32 max_rb_num_per_se)
3046*4882a593Smuzhiyun {
3047*4882a593Smuzhiyun int i, j;
3048*4882a593Smuzhiyun u32 data, mask;
3049*4882a593Smuzhiyun u32 disabled_rbs = 0;
3050*4882a593Smuzhiyun u32 enabled_rbs = 0;
3051*4882a593Smuzhiyun
3052*4882a593Smuzhiyun for (i = 0; i < se_num; i++) {
3053*4882a593Smuzhiyun for (j = 0; j < sh_per_se; j++) {
3054*4882a593Smuzhiyun si_select_se_sh(rdev, i, j);
3055*4882a593Smuzhiyun data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se);
3056*4882a593Smuzhiyun disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH);
3057*4882a593Smuzhiyun }
3058*4882a593Smuzhiyun }
3059*4882a593Smuzhiyun si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3060*4882a593Smuzhiyun
3061*4882a593Smuzhiyun mask = 1;
3062*4882a593Smuzhiyun for (i = 0; i < max_rb_num_per_se * se_num; i++) {
3063*4882a593Smuzhiyun if (!(disabled_rbs & mask))
3064*4882a593Smuzhiyun enabled_rbs |= mask;
3065*4882a593Smuzhiyun mask <<= 1;
3066*4882a593Smuzhiyun }
3067*4882a593Smuzhiyun
3068*4882a593Smuzhiyun rdev->config.si.backend_enable_mask = enabled_rbs;
3069*4882a593Smuzhiyun
3070*4882a593Smuzhiyun for (i = 0; i < se_num; i++) {
3071*4882a593Smuzhiyun si_select_se_sh(rdev, i, 0xffffffff);
3072*4882a593Smuzhiyun data = 0;
3073*4882a593Smuzhiyun for (j = 0; j < sh_per_se; j++) {
3074*4882a593Smuzhiyun switch (enabled_rbs & 3) {
3075*4882a593Smuzhiyun case 1:
3076*4882a593Smuzhiyun data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
3077*4882a593Smuzhiyun break;
3078*4882a593Smuzhiyun case 2:
3079*4882a593Smuzhiyun data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
3080*4882a593Smuzhiyun break;
3081*4882a593Smuzhiyun case 3:
3082*4882a593Smuzhiyun default:
3083*4882a593Smuzhiyun data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
3084*4882a593Smuzhiyun break;
3085*4882a593Smuzhiyun }
3086*4882a593Smuzhiyun enabled_rbs >>= 2;
3087*4882a593Smuzhiyun }
3088*4882a593Smuzhiyun WREG32(PA_SC_RASTER_CONFIG, data);
3089*4882a593Smuzhiyun }
3090*4882a593Smuzhiyun si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3091*4882a593Smuzhiyun }
3092*4882a593Smuzhiyun
si_gpu_init(struct radeon_device * rdev)3093*4882a593Smuzhiyun static void si_gpu_init(struct radeon_device *rdev)
3094*4882a593Smuzhiyun {
3095*4882a593Smuzhiyun u32 gb_addr_config = 0;
3096*4882a593Smuzhiyun u32 mc_shared_chmap, mc_arb_ramcfg;
3097*4882a593Smuzhiyun u32 sx_debug_1;
3098*4882a593Smuzhiyun u32 hdp_host_path_cntl;
3099*4882a593Smuzhiyun u32 tmp;
3100*4882a593Smuzhiyun int i, j;
3101*4882a593Smuzhiyun
3102*4882a593Smuzhiyun switch (rdev->family) {
3103*4882a593Smuzhiyun case CHIP_TAHITI:
3104*4882a593Smuzhiyun rdev->config.si.max_shader_engines = 2;
3105*4882a593Smuzhiyun rdev->config.si.max_tile_pipes = 12;
3106*4882a593Smuzhiyun rdev->config.si.max_cu_per_sh = 8;
3107*4882a593Smuzhiyun rdev->config.si.max_sh_per_se = 2;
3108*4882a593Smuzhiyun rdev->config.si.max_backends_per_se = 4;
3109*4882a593Smuzhiyun rdev->config.si.max_texture_channel_caches = 12;
3110*4882a593Smuzhiyun rdev->config.si.max_gprs = 256;
3111*4882a593Smuzhiyun rdev->config.si.max_gs_threads = 32;
3112*4882a593Smuzhiyun rdev->config.si.max_hw_contexts = 8;
3113*4882a593Smuzhiyun
3114*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3115*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_backend = 0x100;
3116*4882a593Smuzhiyun rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3117*4882a593Smuzhiyun rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3118*4882a593Smuzhiyun gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
3119*4882a593Smuzhiyun break;
3120*4882a593Smuzhiyun case CHIP_PITCAIRN:
3121*4882a593Smuzhiyun rdev->config.si.max_shader_engines = 2;
3122*4882a593Smuzhiyun rdev->config.si.max_tile_pipes = 8;
3123*4882a593Smuzhiyun rdev->config.si.max_cu_per_sh = 5;
3124*4882a593Smuzhiyun rdev->config.si.max_sh_per_se = 2;
3125*4882a593Smuzhiyun rdev->config.si.max_backends_per_se = 4;
3126*4882a593Smuzhiyun rdev->config.si.max_texture_channel_caches = 8;
3127*4882a593Smuzhiyun rdev->config.si.max_gprs = 256;
3128*4882a593Smuzhiyun rdev->config.si.max_gs_threads = 32;
3129*4882a593Smuzhiyun rdev->config.si.max_hw_contexts = 8;
3130*4882a593Smuzhiyun
3131*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3132*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_backend = 0x100;
3133*4882a593Smuzhiyun rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3134*4882a593Smuzhiyun rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3135*4882a593Smuzhiyun gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
3136*4882a593Smuzhiyun break;
3137*4882a593Smuzhiyun case CHIP_VERDE:
3138*4882a593Smuzhiyun default:
3139*4882a593Smuzhiyun rdev->config.si.max_shader_engines = 1;
3140*4882a593Smuzhiyun rdev->config.si.max_tile_pipes = 4;
3141*4882a593Smuzhiyun rdev->config.si.max_cu_per_sh = 5;
3142*4882a593Smuzhiyun rdev->config.si.max_sh_per_se = 2;
3143*4882a593Smuzhiyun rdev->config.si.max_backends_per_se = 4;
3144*4882a593Smuzhiyun rdev->config.si.max_texture_channel_caches = 4;
3145*4882a593Smuzhiyun rdev->config.si.max_gprs = 256;
3146*4882a593Smuzhiyun rdev->config.si.max_gs_threads = 32;
3147*4882a593Smuzhiyun rdev->config.si.max_hw_contexts = 8;
3148*4882a593Smuzhiyun
3149*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3150*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3151*4882a593Smuzhiyun rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3152*4882a593Smuzhiyun rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3153*4882a593Smuzhiyun gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
3154*4882a593Smuzhiyun break;
3155*4882a593Smuzhiyun case CHIP_OLAND:
3156*4882a593Smuzhiyun rdev->config.si.max_shader_engines = 1;
3157*4882a593Smuzhiyun rdev->config.si.max_tile_pipes = 4;
3158*4882a593Smuzhiyun rdev->config.si.max_cu_per_sh = 6;
3159*4882a593Smuzhiyun rdev->config.si.max_sh_per_se = 1;
3160*4882a593Smuzhiyun rdev->config.si.max_backends_per_se = 2;
3161*4882a593Smuzhiyun rdev->config.si.max_texture_channel_caches = 4;
3162*4882a593Smuzhiyun rdev->config.si.max_gprs = 256;
3163*4882a593Smuzhiyun rdev->config.si.max_gs_threads = 16;
3164*4882a593Smuzhiyun rdev->config.si.max_hw_contexts = 8;
3165*4882a593Smuzhiyun
3166*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3167*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3168*4882a593Smuzhiyun rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3169*4882a593Smuzhiyun rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3170*4882a593Smuzhiyun gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
3171*4882a593Smuzhiyun break;
3172*4882a593Smuzhiyun case CHIP_HAINAN:
3173*4882a593Smuzhiyun rdev->config.si.max_shader_engines = 1;
3174*4882a593Smuzhiyun rdev->config.si.max_tile_pipes = 4;
3175*4882a593Smuzhiyun rdev->config.si.max_cu_per_sh = 5;
3176*4882a593Smuzhiyun rdev->config.si.max_sh_per_se = 1;
3177*4882a593Smuzhiyun rdev->config.si.max_backends_per_se = 1;
3178*4882a593Smuzhiyun rdev->config.si.max_texture_channel_caches = 2;
3179*4882a593Smuzhiyun rdev->config.si.max_gprs = 256;
3180*4882a593Smuzhiyun rdev->config.si.max_gs_threads = 16;
3181*4882a593Smuzhiyun rdev->config.si.max_hw_contexts = 8;
3182*4882a593Smuzhiyun
3183*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3184*4882a593Smuzhiyun rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3185*4882a593Smuzhiyun rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3186*4882a593Smuzhiyun rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3187*4882a593Smuzhiyun gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN;
3188*4882a593Smuzhiyun break;
3189*4882a593Smuzhiyun }
3190*4882a593Smuzhiyun
3191*4882a593Smuzhiyun /* Initialize HDP */
3192*4882a593Smuzhiyun for (i = 0, j = 0; i < 32; i++, j += 0x18) {
3193*4882a593Smuzhiyun WREG32((0x2c14 + j), 0x00000000);
3194*4882a593Smuzhiyun WREG32((0x2c18 + j), 0x00000000);
3195*4882a593Smuzhiyun WREG32((0x2c1c + j), 0x00000000);
3196*4882a593Smuzhiyun WREG32((0x2c20 + j), 0x00000000);
3197*4882a593Smuzhiyun WREG32((0x2c24 + j), 0x00000000);
3198*4882a593Smuzhiyun }
3199*4882a593Smuzhiyun
3200*4882a593Smuzhiyun WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
3201*4882a593Smuzhiyun WREG32(SRBM_INT_CNTL, 1);
3202*4882a593Smuzhiyun WREG32(SRBM_INT_ACK, 1);
3203*4882a593Smuzhiyun
3204*4882a593Smuzhiyun evergreen_fix_pci_max_read_req_size(rdev);
3205*4882a593Smuzhiyun
3206*4882a593Smuzhiyun WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
3207*4882a593Smuzhiyun
3208*4882a593Smuzhiyun mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
3209*4882a593Smuzhiyun mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
3210*4882a593Smuzhiyun
3211*4882a593Smuzhiyun rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes;
3212*4882a593Smuzhiyun rdev->config.si.mem_max_burst_length_bytes = 256;
3213*4882a593Smuzhiyun tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
3214*4882a593Smuzhiyun rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
3215*4882a593Smuzhiyun if (rdev->config.si.mem_row_size_in_kb > 4)
3216*4882a593Smuzhiyun rdev->config.si.mem_row_size_in_kb = 4;
3217*4882a593Smuzhiyun /* XXX use MC settings? */
3218*4882a593Smuzhiyun rdev->config.si.shader_engine_tile_size = 32;
3219*4882a593Smuzhiyun rdev->config.si.num_gpus = 1;
3220*4882a593Smuzhiyun rdev->config.si.multi_gpu_tile_size = 64;
3221*4882a593Smuzhiyun
3222*4882a593Smuzhiyun /* fix up row size */
3223*4882a593Smuzhiyun gb_addr_config &= ~ROW_SIZE_MASK;
3224*4882a593Smuzhiyun switch (rdev->config.si.mem_row_size_in_kb) {
3225*4882a593Smuzhiyun case 1:
3226*4882a593Smuzhiyun default:
3227*4882a593Smuzhiyun gb_addr_config |= ROW_SIZE(0);
3228*4882a593Smuzhiyun break;
3229*4882a593Smuzhiyun case 2:
3230*4882a593Smuzhiyun gb_addr_config |= ROW_SIZE(1);
3231*4882a593Smuzhiyun break;
3232*4882a593Smuzhiyun case 4:
3233*4882a593Smuzhiyun gb_addr_config |= ROW_SIZE(2);
3234*4882a593Smuzhiyun break;
3235*4882a593Smuzhiyun }
3236*4882a593Smuzhiyun
3237*4882a593Smuzhiyun /* setup tiling info dword. gb_addr_config is not adequate since it does
3238*4882a593Smuzhiyun * not have bank info, so create a custom tiling dword.
3239*4882a593Smuzhiyun * bits 3:0 num_pipes
3240*4882a593Smuzhiyun * bits 7:4 num_banks
3241*4882a593Smuzhiyun * bits 11:8 group_size
3242*4882a593Smuzhiyun * bits 15:12 row_size
3243*4882a593Smuzhiyun */
3244*4882a593Smuzhiyun rdev->config.si.tile_config = 0;
3245*4882a593Smuzhiyun switch (rdev->config.si.num_tile_pipes) {
3246*4882a593Smuzhiyun case 1:
3247*4882a593Smuzhiyun rdev->config.si.tile_config |= (0 << 0);
3248*4882a593Smuzhiyun break;
3249*4882a593Smuzhiyun case 2:
3250*4882a593Smuzhiyun rdev->config.si.tile_config |= (1 << 0);
3251*4882a593Smuzhiyun break;
3252*4882a593Smuzhiyun case 4:
3253*4882a593Smuzhiyun rdev->config.si.tile_config |= (2 << 0);
3254*4882a593Smuzhiyun break;
3255*4882a593Smuzhiyun case 8:
3256*4882a593Smuzhiyun default:
3257*4882a593Smuzhiyun /* XXX what about 12? */
3258*4882a593Smuzhiyun rdev->config.si.tile_config |= (3 << 0);
3259*4882a593Smuzhiyun break;
3260*4882a593Smuzhiyun }
3261*4882a593Smuzhiyun switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
3262*4882a593Smuzhiyun case 0: /* four banks */
3263*4882a593Smuzhiyun rdev->config.si.tile_config |= 0 << 4;
3264*4882a593Smuzhiyun break;
3265*4882a593Smuzhiyun case 1: /* eight banks */
3266*4882a593Smuzhiyun rdev->config.si.tile_config |= 1 << 4;
3267*4882a593Smuzhiyun break;
3268*4882a593Smuzhiyun case 2: /* sixteen banks */
3269*4882a593Smuzhiyun default:
3270*4882a593Smuzhiyun rdev->config.si.tile_config |= 2 << 4;
3271*4882a593Smuzhiyun break;
3272*4882a593Smuzhiyun }
3273*4882a593Smuzhiyun rdev->config.si.tile_config |=
3274*4882a593Smuzhiyun ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
3275*4882a593Smuzhiyun rdev->config.si.tile_config |=
3276*4882a593Smuzhiyun ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
3277*4882a593Smuzhiyun
3278*4882a593Smuzhiyun WREG32(GB_ADDR_CONFIG, gb_addr_config);
3279*4882a593Smuzhiyun WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
3280*4882a593Smuzhiyun WREG32(DMIF_ADDR_CALC, gb_addr_config);
3281*4882a593Smuzhiyun WREG32(HDP_ADDR_CONFIG, gb_addr_config);
3282*4882a593Smuzhiyun WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
3283*4882a593Smuzhiyun WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
3284*4882a593Smuzhiyun if (rdev->has_uvd) {
3285*4882a593Smuzhiyun WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
3286*4882a593Smuzhiyun WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
3287*4882a593Smuzhiyun WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
3288*4882a593Smuzhiyun }
3289*4882a593Smuzhiyun
3290*4882a593Smuzhiyun si_tiling_mode_table_init(rdev);
3291*4882a593Smuzhiyun
3292*4882a593Smuzhiyun si_setup_rb(rdev, rdev->config.si.max_shader_engines,
3293*4882a593Smuzhiyun rdev->config.si.max_sh_per_se,
3294*4882a593Smuzhiyun rdev->config.si.max_backends_per_se);
3295*4882a593Smuzhiyun
3296*4882a593Smuzhiyun si_setup_spi(rdev, rdev->config.si.max_shader_engines,
3297*4882a593Smuzhiyun rdev->config.si.max_sh_per_se,
3298*4882a593Smuzhiyun rdev->config.si.max_cu_per_sh);
3299*4882a593Smuzhiyun
3300*4882a593Smuzhiyun rdev->config.si.active_cus = 0;
3301*4882a593Smuzhiyun for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
3302*4882a593Smuzhiyun for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
3303*4882a593Smuzhiyun rdev->config.si.active_cus +=
3304*4882a593Smuzhiyun hweight32(si_get_cu_active_bitmap(rdev, i, j));
3305*4882a593Smuzhiyun }
3306*4882a593Smuzhiyun }
3307*4882a593Smuzhiyun
3308*4882a593Smuzhiyun /* set HW defaults for 3D engine */
3309*4882a593Smuzhiyun WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
3310*4882a593Smuzhiyun ROQ_IB2_START(0x2b)));
3311*4882a593Smuzhiyun WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
3312*4882a593Smuzhiyun
3313*4882a593Smuzhiyun sx_debug_1 = RREG32(SX_DEBUG_1);
3314*4882a593Smuzhiyun WREG32(SX_DEBUG_1, sx_debug_1);
3315*4882a593Smuzhiyun
3316*4882a593Smuzhiyun WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
3317*4882a593Smuzhiyun
3318*4882a593Smuzhiyun WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) |
3319*4882a593Smuzhiyun SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) |
3320*4882a593Smuzhiyun SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) |
3321*4882a593Smuzhiyun SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size)));
3322*4882a593Smuzhiyun
3323*4882a593Smuzhiyun WREG32(VGT_NUM_INSTANCES, 1);
3324*4882a593Smuzhiyun
3325*4882a593Smuzhiyun WREG32(CP_PERFMON_CNTL, 0);
3326*4882a593Smuzhiyun
3327*4882a593Smuzhiyun WREG32(SQ_CONFIG, 0);
3328*4882a593Smuzhiyun
3329*4882a593Smuzhiyun WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
3330*4882a593Smuzhiyun FORCE_EOV_MAX_REZ_CNT(255)));
3331*4882a593Smuzhiyun
3332*4882a593Smuzhiyun WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
3333*4882a593Smuzhiyun AUTO_INVLD_EN(ES_AND_GS_AUTO));
3334*4882a593Smuzhiyun
3335*4882a593Smuzhiyun WREG32(VGT_GS_VERTEX_REUSE, 16);
3336*4882a593Smuzhiyun WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
3337*4882a593Smuzhiyun
3338*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER0_SELECT0, 0);
3339*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER0_SELECT1, 0);
3340*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER1_SELECT0, 0);
3341*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER1_SELECT1, 0);
3342*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER2_SELECT0, 0);
3343*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER2_SELECT1, 0);
3344*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER3_SELECT0, 0);
3345*4882a593Smuzhiyun WREG32(CB_PERFCOUNTER3_SELECT1, 0);
3346*4882a593Smuzhiyun
3347*4882a593Smuzhiyun tmp = RREG32(HDP_MISC_CNTL);
3348*4882a593Smuzhiyun tmp |= HDP_FLUSH_INVALIDATE_CACHE;
3349*4882a593Smuzhiyun WREG32(HDP_MISC_CNTL, tmp);
3350*4882a593Smuzhiyun
3351*4882a593Smuzhiyun hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
3352*4882a593Smuzhiyun WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
3353*4882a593Smuzhiyun
3354*4882a593Smuzhiyun WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
3355*4882a593Smuzhiyun
3356*4882a593Smuzhiyun udelay(50);
3357*4882a593Smuzhiyun }
3358*4882a593Smuzhiyun
3359*4882a593Smuzhiyun /*
3360*4882a593Smuzhiyun * GPU scratch registers helpers function.
3361*4882a593Smuzhiyun */
si_scratch_init(struct radeon_device * rdev)3362*4882a593Smuzhiyun static void si_scratch_init(struct radeon_device *rdev)
3363*4882a593Smuzhiyun {
3364*4882a593Smuzhiyun int i;
3365*4882a593Smuzhiyun
3366*4882a593Smuzhiyun rdev->scratch.num_reg = 7;
3367*4882a593Smuzhiyun rdev->scratch.reg_base = SCRATCH_REG0;
3368*4882a593Smuzhiyun for (i = 0; i < rdev->scratch.num_reg; i++) {
3369*4882a593Smuzhiyun rdev->scratch.free[i] = true;
3370*4882a593Smuzhiyun rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
3371*4882a593Smuzhiyun }
3372*4882a593Smuzhiyun }
3373*4882a593Smuzhiyun
si_fence_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)3374*4882a593Smuzhiyun void si_fence_ring_emit(struct radeon_device *rdev,
3375*4882a593Smuzhiyun struct radeon_fence *fence)
3376*4882a593Smuzhiyun {
3377*4882a593Smuzhiyun struct radeon_ring *ring = &rdev->ring[fence->ring];
3378*4882a593Smuzhiyun u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
3379*4882a593Smuzhiyun
3380*4882a593Smuzhiyun /* flush read cache over gart */
3381*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3382*4882a593Smuzhiyun radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
3383*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3384*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
3385*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
3386*4882a593Smuzhiyun PACKET3_TC_ACTION_ENA |
3387*4882a593Smuzhiyun PACKET3_SH_KCACHE_ACTION_ENA |
3388*4882a593Smuzhiyun PACKET3_SH_ICACHE_ACTION_ENA);
3389*4882a593Smuzhiyun radeon_ring_write(ring, 0xFFFFFFFF);
3390*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3391*4882a593Smuzhiyun radeon_ring_write(ring, 10); /* poll interval */
3392*4882a593Smuzhiyun /* EVENT_WRITE_EOP - flush caches, send int */
3393*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
3394*4882a593Smuzhiyun radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5));
3395*4882a593Smuzhiyun radeon_ring_write(ring, lower_32_bits(addr));
3396*4882a593Smuzhiyun radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
3397*4882a593Smuzhiyun radeon_ring_write(ring, fence->seq);
3398*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3399*4882a593Smuzhiyun }
3400*4882a593Smuzhiyun
3401*4882a593Smuzhiyun /*
3402*4882a593Smuzhiyun * IB stuff
3403*4882a593Smuzhiyun */
si_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)3404*4882a593Smuzhiyun void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3405*4882a593Smuzhiyun {
3406*4882a593Smuzhiyun struct radeon_ring *ring = &rdev->ring[ib->ring];
3407*4882a593Smuzhiyun unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
3408*4882a593Smuzhiyun u32 header;
3409*4882a593Smuzhiyun
3410*4882a593Smuzhiyun if (ib->is_const_ib) {
3411*4882a593Smuzhiyun /* set switch buffer packet before const IB */
3412*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
3413*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3414*4882a593Smuzhiyun
3415*4882a593Smuzhiyun header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
3416*4882a593Smuzhiyun } else {
3417*4882a593Smuzhiyun u32 next_rptr;
3418*4882a593Smuzhiyun if (ring->rptr_save_reg) {
3419*4882a593Smuzhiyun next_rptr = ring->wptr + 3 + 4 + 8;
3420*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3421*4882a593Smuzhiyun radeon_ring_write(ring, ((ring->rptr_save_reg -
3422*4882a593Smuzhiyun PACKET3_SET_CONFIG_REG_START) >> 2));
3423*4882a593Smuzhiyun radeon_ring_write(ring, next_rptr);
3424*4882a593Smuzhiyun } else if (rdev->wb.enabled) {
3425*4882a593Smuzhiyun next_rptr = ring->wptr + 5 + 4 + 8;
3426*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
3427*4882a593Smuzhiyun radeon_ring_write(ring, (1 << 8));
3428*4882a593Smuzhiyun radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
3429*4882a593Smuzhiyun radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr));
3430*4882a593Smuzhiyun radeon_ring_write(ring, next_rptr);
3431*4882a593Smuzhiyun }
3432*4882a593Smuzhiyun
3433*4882a593Smuzhiyun header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
3434*4882a593Smuzhiyun }
3435*4882a593Smuzhiyun
3436*4882a593Smuzhiyun radeon_ring_write(ring, header);
3437*4882a593Smuzhiyun radeon_ring_write(ring,
3438*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
3439*4882a593Smuzhiyun (2 << 0) |
3440*4882a593Smuzhiyun #endif
3441*4882a593Smuzhiyun (ib->gpu_addr & 0xFFFFFFFC));
3442*4882a593Smuzhiyun radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
3443*4882a593Smuzhiyun radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
3444*4882a593Smuzhiyun
3445*4882a593Smuzhiyun if (!ib->is_const_ib) {
3446*4882a593Smuzhiyun /* flush read cache over gart for this vmid */
3447*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3448*4882a593Smuzhiyun radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
3449*4882a593Smuzhiyun radeon_ring_write(ring, vm_id);
3450*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
3451*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
3452*4882a593Smuzhiyun PACKET3_TC_ACTION_ENA |
3453*4882a593Smuzhiyun PACKET3_SH_KCACHE_ACTION_ENA |
3454*4882a593Smuzhiyun PACKET3_SH_ICACHE_ACTION_ENA);
3455*4882a593Smuzhiyun radeon_ring_write(ring, 0xFFFFFFFF);
3456*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3457*4882a593Smuzhiyun radeon_ring_write(ring, 10); /* poll interval */
3458*4882a593Smuzhiyun }
3459*4882a593Smuzhiyun }
3460*4882a593Smuzhiyun
3461*4882a593Smuzhiyun /*
3462*4882a593Smuzhiyun * CP.
3463*4882a593Smuzhiyun */
si_cp_enable(struct radeon_device * rdev,bool enable)3464*4882a593Smuzhiyun static void si_cp_enable(struct radeon_device *rdev, bool enable)
3465*4882a593Smuzhiyun {
3466*4882a593Smuzhiyun if (enable)
3467*4882a593Smuzhiyun WREG32(CP_ME_CNTL, 0);
3468*4882a593Smuzhiyun else {
3469*4882a593Smuzhiyun if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3470*4882a593Smuzhiyun radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
3471*4882a593Smuzhiyun WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
3472*4882a593Smuzhiyun WREG32(SCRATCH_UMSK, 0);
3473*4882a593Smuzhiyun rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3474*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3475*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3476*4882a593Smuzhiyun }
3477*4882a593Smuzhiyun udelay(50);
3478*4882a593Smuzhiyun }
3479*4882a593Smuzhiyun
si_cp_load_microcode(struct radeon_device * rdev)3480*4882a593Smuzhiyun static int si_cp_load_microcode(struct radeon_device *rdev)
3481*4882a593Smuzhiyun {
3482*4882a593Smuzhiyun int i;
3483*4882a593Smuzhiyun
3484*4882a593Smuzhiyun if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
3485*4882a593Smuzhiyun return -EINVAL;
3486*4882a593Smuzhiyun
3487*4882a593Smuzhiyun si_cp_enable(rdev, false);
3488*4882a593Smuzhiyun
3489*4882a593Smuzhiyun if (rdev->new_fw) {
3490*4882a593Smuzhiyun const struct gfx_firmware_header_v1_0 *pfp_hdr =
3491*4882a593Smuzhiyun (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
3492*4882a593Smuzhiyun const struct gfx_firmware_header_v1_0 *ce_hdr =
3493*4882a593Smuzhiyun (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
3494*4882a593Smuzhiyun const struct gfx_firmware_header_v1_0 *me_hdr =
3495*4882a593Smuzhiyun (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
3496*4882a593Smuzhiyun const __le32 *fw_data;
3497*4882a593Smuzhiyun u32 fw_size;
3498*4882a593Smuzhiyun
3499*4882a593Smuzhiyun radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
3500*4882a593Smuzhiyun radeon_ucode_print_gfx_hdr(&ce_hdr->header);
3501*4882a593Smuzhiyun radeon_ucode_print_gfx_hdr(&me_hdr->header);
3502*4882a593Smuzhiyun
3503*4882a593Smuzhiyun /* PFP */
3504*4882a593Smuzhiyun fw_data = (const __le32 *)
3505*4882a593Smuzhiyun (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
3506*4882a593Smuzhiyun fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
3507*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_ADDR, 0);
3508*4882a593Smuzhiyun for (i = 0; i < fw_size; i++)
3509*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
3510*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_ADDR, 0);
3511*4882a593Smuzhiyun
3512*4882a593Smuzhiyun /* CE */
3513*4882a593Smuzhiyun fw_data = (const __le32 *)
3514*4882a593Smuzhiyun (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
3515*4882a593Smuzhiyun fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
3516*4882a593Smuzhiyun WREG32(CP_CE_UCODE_ADDR, 0);
3517*4882a593Smuzhiyun for (i = 0; i < fw_size; i++)
3518*4882a593Smuzhiyun WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
3519*4882a593Smuzhiyun WREG32(CP_CE_UCODE_ADDR, 0);
3520*4882a593Smuzhiyun
3521*4882a593Smuzhiyun /* ME */
3522*4882a593Smuzhiyun fw_data = (const __be32 *)
3523*4882a593Smuzhiyun (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
3524*4882a593Smuzhiyun fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
3525*4882a593Smuzhiyun WREG32(CP_ME_RAM_WADDR, 0);
3526*4882a593Smuzhiyun for (i = 0; i < fw_size; i++)
3527*4882a593Smuzhiyun WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
3528*4882a593Smuzhiyun WREG32(CP_ME_RAM_WADDR, 0);
3529*4882a593Smuzhiyun } else {
3530*4882a593Smuzhiyun const __be32 *fw_data;
3531*4882a593Smuzhiyun
3532*4882a593Smuzhiyun /* PFP */
3533*4882a593Smuzhiyun fw_data = (const __be32 *)rdev->pfp_fw->data;
3534*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_ADDR, 0);
3535*4882a593Smuzhiyun for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
3536*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
3537*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_ADDR, 0);
3538*4882a593Smuzhiyun
3539*4882a593Smuzhiyun /* CE */
3540*4882a593Smuzhiyun fw_data = (const __be32 *)rdev->ce_fw->data;
3541*4882a593Smuzhiyun WREG32(CP_CE_UCODE_ADDR, 0);
3542*4882a593Smuzhiyun for (i = 0; i < SI_CE_UCODE_SIZE; i++)
3543*4882a593Smuzhiyun WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
3544*4882a593Smuzhiyun WREG32(CP_CE_UCODE_ADDR, 0);
3545*4882a593Smuzhiyun
3546*4882a593Smuzhiyun /* ME */
3547*4882a593Smuzhiyun fw_data = (const __be32 *)rdev->me_fw->data;
3548*4882a593Smuzhiyun WREG32(CP_ME_RAM_WADDR, 0);
3549*4882a593Smuzhiyun for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
3550*4882a593Smuzhiyun WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
3551*4882a593Smuzhiyun WREG32(CP_ME_RAM_WADDR, 0);
3552*4882a593Smuzhiyun }
3553*4882a593Smuzhiyun
3554*4882a593Smuzhiyun WREG32(CP_PFP_UCODE_ADDR, 0);
3555*4882a593Smuzhiyun WREG32(CP_CE_UCODE_ADDR, 0);
3556*4882a593Smuzhiyun WREG32(CP_ME_RAM_WADDR, 0);
3557*4882a593Smuzhiyun WREG32(CP_ME_RAM_RADDR, 0);
3558*4882a593Smuzhiyun return 0;
3559*4882a593Smuzhiyun }
3560*4882a593Smuzhiyun
si_cp_start(struct radeon_device * rdev)3561*4882a593Smuzhiyun static int si_cp_start(struct radeon_device *rdev)
3562*4882a593Smuzhiyun {
3563*4882a593Smuzhiyun struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3564*4882a593Smuzhiyun int r, i;
3565*4882a593Smuzhiyun
3566*4882a593Smuzhiyun r = radeon_ring_lock(rdev, ring, 7 + 4);
3567*4882a593Smuzhiyun if (r) {
3568*4882a593Smuzhiyun DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3569*4882a593Smuzhiyun return r;
3570*4882a593Smuzhiyun }
3571*4882a593Smuzhiyun /* init the CP */
3572*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
3573*4882a593Smuzhiyun radeon_ring_write(ring, 0x1);
3574*4882a593Smuzhiyun radeon_ring_write(ring, 0x0);
3575*4882a593Smuzhiyun radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1);
3576*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
3577*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3578*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3579*4882a593Smuzhiyun
3580*4882a593Smuzhiyun /* init the CE partitions */
3581*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
3582*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
3583*4882a593Smuzhiyun radeon_ring_write(ring, 0xc000);
3584*4882a593Smuzhiyun radeon_ring_write(ring, 0xe000);
3585*4882a593Smuzhiyun radeon_ring_unlock_commit(rdev, ring, false);
3586*4882a593Smuzhiyun
3587*4882a593Smuzhiyun si_cp_enable(rdev, true);
3588*4882a593Smuzhiyun
3589*4882a593Smuzhiyun r = radeon_ring_lock(rdev, ring, si_default_size + 10);
3590*4882a593Smuzhiyun if (r) {
3591*4882a593Smuzhiyun DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3592*4882a593Smuzhiyun return r;
3593*4882a593Smuzhiyun }
3594*4882a593Smuzhiyun
3595*4882a593Smuzhiyun /* setup clear context state */
3596*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3597*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
3598*4882a593Smuzhiyun
3599*4882a593Smuzhiyun for (i = 0; i < si_default_size; i++)
3600*4882a593Smuzhiyun radeon_ring_write(ring, si_default_state[i]);
3601*4882a593Smuzhiyun
3602*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3603*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
3604*4882a593Smuzhiyun
3605*4882a593Smuzhiyun /* set clear context state */
3606*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
3607*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3608*4882a593Smuzhiyun
3609*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
3610*4882a593Smuzhiyun radeon_ring_write(ring, 0x00000316);
3611*4882a593Smuzhiyun radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
3612*4882a593Smuzhiyun radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
3613*4882a593Smuzhiyun
3614*4882a593Smuzhiyun radeon_ring_unlock_commit(rdev, ring, false);
3615*4882a593Smuzhiyun
3616*4882a593Smuzhiyun for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
3617*4882a593Smuzhiyun ring = &rdev->ring[i];
3618*4882a593Smuzhiyun r = radeon_ring_lock(rdev, ring, 2);
3619*4882a593Smuzhiyun
3620*4882a593Smuzhiyun /* clear the compute context state */
3621*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
3622*4882a593Smuzhiyun radeon_ring_write(ring, 0);
3623*4882a593Smuzhiyun
3624*4882a593Smuzhiyun radeon_ring_unlock_commit(rdev, ring, false);
3625*4882a593Smuzhiyun }
3626*4882a593Smuzhiyun
3627*4882a593Smuzhiyun return 0;
3628*4882a593Smuzhiyun }
3629*4882a593Smuzhiyun
si_cp_fini(struct radeon_device * rdev)3630*4882a593Smuzhiyun static void si_cp_fini(struct radeon_device *rdev)
3631*4882a593Smuzhiyun {
3632*4882a593Smuzhiyun struct radeon_ring *ring;
3633*4882a593Smuzhiyun si_cp_enable(rdev, false);
3634*4882a593Smuzhiyun
3635*4882a593Smuzhiyun ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3636*4882a593Smuzhiyun radeon_ring_fini(rdev, ring);
3637*4882a593Smuzhiyun radeon_scratch_free(rdev, ring->rptr_save_reg);
3638*4882a593Smuzhiyun
3639*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
3640*4882a593Smuzhiyun radeon_ring_fini(rdev, ring);
3641*4882a593Smuzhiyun radeon_scratch_free(rdev, ring->rptr_save_reg);
3642*4882a593Smuzhiyun
3643*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
3644*4882a593Smuzhiyun radeon_ring_fini(rdev, ring);
3645*4882a593Smuzhiyun radeon_scratch_free(rdev, ring->rptr_save_reg);
3646*4882a593Smuzhiyun }
3647*4882a593Smuzhiyun
si_cp_resume(struct radeon_device * rdev)3648*4882a593Smuzhiyun static int si_cp_resume(struct radeon_device *rdev)
3649*4882a593Smuzhiyun {
3650*4882a593Smuzhiyun struct radeon_ring *ring;
3651*4882a593Smuzhiyun u32 tmp;
3652*4882a593Smuzhiyun u32 rb_bufsz;
3653*4882a593Smuzhiyun int r;
3654*4882a593Smuzhiyun
3655*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, false);
3656*4882a593Smuzhiyun
3657*4882a593Smuzhiyun WREG32(CP_SEM_WAIT_TIMER, 0x0);
3658*4882a593Smuzhiyun WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
3659*4882a593Smuzhiyun
3660*4882a593Smuzhiyun /* Set the write pointer delay */
3661*4882a593Smuzhiyun WREG32(CP_RB_WPTR_DELAY, 0);
3662*4882a593Smuzhiyun
3663*4882a593Smuzhiyun WREG32(CP_DEBUG, 0);
3664*4882a593Smuzhiyun WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
3665*4882a593Smuzhiyun
3666*4882a593Smuzhiyun /* ring 0 - compute and gfx */
3667*4882a593Smuzhiyun /* Set ring buffer size */
3668*4882a593Smuzhiyun ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3669*4882a593Smuzhiyun rb_bufsz = order_base_2(ring->ring_size / 8);
3670*4882a593Smuzhiyun tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3671*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
3672*4882a593Smuzhiyun tmp |= BUF_SWAP_32BIT;
3673*4882a593Smuzhiyun #endif
3674*4882a593Smuzhiyun WREG32(CP_RB0_CNTL, tmp);
3675*4882a593Smuzhiyun
3676*4882a593Smuzhiyun /* Initialize the ring buffer's read and write pointers */
3677*4882a593Smuzhiyun WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
3678*4882a593Smuzhiyun ring->wptr = 0;
3679*4882a593Smuzhiyun WREG32(CP_RB0_WPTR, ring->wptr);
3680*4882a593Smuzhiyun
3681*4882a593Smuzhiyun /* set the wb address whether it's enabled or not */
3682*4882a593Smuzhiyun WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
3683*4882a593Smuzhiyun WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
3684*4882a593Smuzhiyun
3685*4882a593Smuzhiyun if (rdev->wb.enabled)
3686*4882a593Smuzhiyun WREG32(SCRATCH_UMSK, 0xff);
3687*4882a593Smuzhiyun else {
3688*4882a593Smuzhiyun tmp |= RB_NO_UPDATE;
3689*4882a593Smuzhiyun WREG32(SCRATCH_UMSK, 0);
3690*4882a593Smuzhiyun }
3691*4882a593Smuzhiyun
3692*4882a593Smuzhiyun mdelay(1);
3693*4882a593Smuzhiyun WREG32(CP_RB0_CNTL, tmp);
3694*4882a593Smuzhiyun
3695*4882a593Smuzhiyun WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
3696*4882a593Smuzhiyun
3697*4882a593Smuzhiyun /* ring1 - compute only */
3698*4882a593Smuzhiyun /* Set ring buffer size */
3699*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
3700*4882a593Smuzhiyun rb_bufsz = order_base_2(ring->ring_size / 8);
3701*4882a593Smuzhiyun tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3702*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
3703*4882a593Smuzhiyun tmp |= BUF_SWAP_32BIT;
3704*4882a593Smuzhiyun #endif
3705*4882a593Smuzhiyun WREG32(CP_RB1_CNTL, tmp);
3706*4882a593Smuzhiyun
3707*4882a593Smuzhiyun /* Initialize the ring buffer's read and write pointers */
3708*4882a593Smuzhiyun WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
3709*4882a593Smuzhiyun ring->wptr = 0;
3710*4882a593Smuzhiyun WREG32(CP_RB1_WPTR, ring->wptr);
3711*4882a593Smuzhiyun
3712*4882a593Smuzhiyun /* set the wb address whether it's enabled or not */
3713*4882a593Smuzhiyun WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
3714*4882a593Smuzhiyun WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
3715*4882a593Smuzhiyun
3716*4882a593Smuzhiyun mdelay(1);
3717*4882a593Smuzhiyun WREG32(CP_RB1_CNTL, tmp);
3718*4882a593Smuzhiyun
3719*4882a593Smuzhiyun WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
3720*4882a593Smuzhiyun
3721*4882a593Smuzhiyun /* ring2 - compute only */
3722*4882a593Smuzhiyun /* Set ring buffer size */
3723*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
3724*4882a593Smuzhiyun rb_bufsz = order_base_2(ring->ring_size / 8);
3725*4882a593Smuzhiyun tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3726*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
3727*4882a593Smuzhiyun tmp |= BUF_SWAP_32BIT;
3728*4882a593Smuzhiyun #endif
3729*4882a593Smuzhiyun WREG32(CP_RB2_CNTL, tmp);
3730*4882a593Smuzhiyun
3731*4882a593Smuzhiyun /* Initialize the ring buffer's read and write pointers */
3732*4882a593Smuzhiyun WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
3733*4882a593Smuzhiyun ring->wptr = 0;
3734*4882a593Smuzhiyun WREG32(CP_RB2_WPTR, ring->wptr);
3735*4882a593Smuzhiyun
3736*4882a593Smuzhiyun /* set the wb address whether it's enabled or not */
3737*4882a593Smuzhiyun WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
3738*4882a593Smuzhiyun WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF);
3739*4882a593Smuzhiyun
3740*4882a593Smuzhiyun mdelay(1);
3741*4882a593Smuzhiyun WREG32(CP_RB2_CNTL, tmp);
3742*4882a593Smuzhiyun
3743*4882a593Smuzhiyun WREG32(CP_RB2_BASE, ring->gpu_addr >> 8);
3744*4882a593Smuzhiyun
3745*4882a593Smuzhiyun /* start the rings */
3746*4882a593Smuzhiyun si_cp_start(rdev);
3747*4882a593Smuzhiyun rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
3748*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true;
3749*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true;
3750*4882a593Smuzhiyun r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
3751*4882a593Smuzhiyun if (r) {
3752*4882a593Smuzhiyun rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3753*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3754*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3755*4882a593Smuzhiyun return r;
3756*4882a593Smuzhiyun }
3757*4882a593Smuzhiyun r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
3758*4882a593Smuzhiyun if (r) {
3759*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3760*4882a593Smuzhiyun }
3761*4882a593Smuzhiyun r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
3762*4882a593Smuzhiyun if (r) {
3763*4882a593Smuzhiyun rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3764*4882a593Smuzhiyun }
3765*4882a593Smuzhiyun
3766*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, true);
3767*4882a593Smuzhiyun
3768*4882a593Smuzhiyun if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3769*4882a593Smuzhiyun radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
3770*4882a593Smuzhiyun
3771*4882a593Smuzhiyun return 0;
3772*4882a593Smuzhiyun }
3773*4882a593Smuzhiyun
si_gpu_check_soft_reset(struct radeon_device * rdev)3774*4882a593Smuzhiyun u32 si_gpu_check_soft_reset(struct radeon_device *rdev)
3775*4882a593Smuzhiyun {
3776*4882a593Smuzhiyun u32 reset_mask = 0;
3777*4882a593Smuzhiyun u32 tmp;
3778*4882a593Smuzhiyun
3779*4882a593Smuzhiyun /* GRBM_STATUS */
3780*4882a593Smuzhiyun tmp = RREG32(GRBM_STATUS);
3781*4882a593Smuzhiyun if (tmp & (PA_BUSY | SC_BUSY |
3782*4882a593Smuzhiyun BCI_BUSY | SX_BUSY |
3783*4882a593Smuzhiyun TA_BUSY | VGT_BUSY |
3784*4882a593Smuzhiyun DB_BUSY | CB_BUSY |
3785*4882a593Smuzhiyun GDS_BUSY | SPI_BUSY |
3786*4882a593Smuzhiyun IA_BUSY | IA_BUSY_NO_DMA))
3787*4882a593Smuzhiyun reset_mask |= RADEON_RESET_GFX;
3788*4882a593Smuzhiyun
3789*4882a593Smuzhiyun if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
3790*4882a593Smuzhiyun CP_BUSY | CP_COHERENCY_BUSY))
3791*4882a593Smuzhiyun reset_mask |= RADEON_RESET_CP;
3792*4882a593Smuzhiyun
3793*4882a593Smuzhiyun if (tmp & GRBM_EE_BUSY)
3794*4882a593Smuzhiyun reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
3795*4882a593Smuzhiyun
3796*4882a593Smuzhiyun /* GRBM_STATUS2 */
3797*4882a593Smuzhiyun tmp = RREG32(GRBM_STATUS2);
3798*4882a593Smuzhiyun if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
3799*4882a593Smuzhiyun reset_mask |= RADEON_RESET_RLC;
3800*4882a593Smuzhiyun
3801*4882a593Smuzhiyun /* DMA_STATUS_REG 0 */
3802*4882a593Smuzhiyun tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
3803*4882a593Smuzhiyun if (!(tmp & DMA_IDLE))
3804*4882a593Smuzhiyun reset_mask |= RADEON_RESET_DMA;
3805*4882a593Smuzhiyun
3806*4882a593Smuzhiyun /* DMA_STATUS_REG 1 */
3807*4882a593Smuzhiyun tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
3808*4882a593Smuzhiyun if (!(tmp & DMA_IDLE))
3809*4882a593Smuzhiyun reset_mask |= RADEON_RESET_DMA1;
3810*4882a593Smuzhiyun
3811*4882a593Smuzhiyun /* SRBM_STATUS2 */
3812*4882a593Smuzhiyun tmp = RREG32(SRBM_STATUS2);
3813*4882a593Smuzhiyun if (tmp & DMA_BUSY)
3814*4882a593Smuzhiyun reset_mask |= RADEON_RESET_DMA;
3815*4882a593Smuzhiyun
3816*4882a593Smuzhiyun if (tmp & DMA1_BUSY)
3817*4882a593Smuzhiyun reset_mask |= RADEON_RESET_DMA1;
3818*4882a593Smuzhiyun
3819*4882a593Smuzhiyun /* SRBM_STATUS */
3820*4882a593Smuzhiyun tmp = RREG32(SRBM_STATUS);
3821*4882a593Smuzhiyun
3822*4882a593Smuzhiyun if (tmp & IH_BUSY)
3823*4882a593Smuzhiyun reset_mask |= RADEON_RESET_IH;
3824*4882a593Smuzhiyun
3825*4882a593Smuzhiyun if (tmp & SEM_BUSY)
3826*4882a593Smuzhiyun reset_mask |= RADEON_RESET_SEM;
3827*4882a593Smuzhiyun
3828*4882a593Smuzhiyun if (tmp & GRBM_RQ_PENDING)
3829*4882a593Smuzhiyun reset_mask |= RADEON_RESET_GRBM;
3830*4882a593Smuzhiyun
3831*4882a593Smuzhiyun if (tmp & VMC_BUSY)
3832*4882a593Smuzhiyun reset_mask |= RADEON_RESET_VMC;
3833*4882a593Smuzhiyun
3834*4882a593Smuzhiyun if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
3835*4882a593Smuzhiyun MCC_BUSY | MCD_BUSY))
3836*4882a593Smuzhiyun reset_mask |= RADEON_RESET_MC;
3837*4882a593Smuzhiyun
3838*4882a593Smuzhiyun if (evergreen_is_display_hung(rdev))
3839*4882a593Smuzhiyun reset_mask |= RADEON_RESET_DISPLAY;
3840*4882a593Smuzhiyun
3841*4882a593Smuzhiyun /* VM_L2_STATUS */
3842*4882a593Smuzhiyun tmp = RREG32(VM_L2_STATUS);
3843*4882a593Smuzhiyun if (tmp & L2_BUSY)
3844*4882a593Smuzhiyun reset_mask |= RADEON_RESET_VMC;
3845*4882a593Smuzhiyun
3846*4882a593Smuzhiyun /* Skip MC reset as it's mostly likely not hung, just busy */
3847*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_MC) {
3848*4882a593Smuzhiyun DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
3849*4882a593Smuzhiyun reset_mask &= ~RADEON_RESET_MC;
3850*4882a593Smuzhiyun }
3851*4882a593Smuzhiyun
3852*4882a593Smuzhiyun return reset_mask;
3853*4882a593Smuzhiyun }
3854*4882a593Smuzhiyun
si_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)3855*4882a593Smuzhiyun static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
3856*4882a593Smuzhiyun {
3857*4882a593Smuzhiyun struct evergreen_mc_save save;
3858*4882a593Smuzhiyun u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
3859*4882a593Smuzhiyun u32 tmp;
3860*4882a593Smuzhiyun
3861*4882a593Smuzhiyun if (reset_mask == 0)
3862*4882a593Smuzhiyun return;
3863*4882a593Smuzhiyun
3864*4882a593Smuzhiyun dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
3865*4882a593Smuzhiyun
3866*4882a593Smuzhiyun evergreen_print_gpu_status_regs(rdev);
3867*4882a593Smuzhiyun dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
3868*4882a593Smuzhiyun RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
3869*4882a593Smuzhiyun dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
3870*4882a593Smuzhiyun RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
3871*4882a593Smuzhiyun
3872*4882a593Smuzhiyun /* disable PG/CG */
3873*4882a593Smuzhiyun si_fini_pg(rdev);
3874*4882a593Smuzhiyun si_fini_cg(rdev);
3875*4882a593Smuzhiyun
3876*4882a593Smuzhiyun /* stop the rlc */
3877*4882a593Smuzhiyun si_rlc_stop(rdev);
3878*4882a593Smuzhiyun
3879*4882a593Smuzhiyun /* Disable CP parsing/prefetching */
3880*4882a593Smuzhiyun WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
3881*4882a593Smuzhiyun
3882*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_DMA) {
3883*4882a593Smuzhiyun /* dma0 */
3884*4882a593Smuzhiyun tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
3885*4882a593Smuzhiyun tmp &= ~DMA_RB_ENABLE;
3886*4882a593Smuzhiyun WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
3887*4882a593Smuzhiyun }
3888*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_DMA1) {
3889*4882a593Smuzhiyun /* dma1 */
3890*4882a593Smuzhiyun tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
3891*4882a593Smuzhiyun tmp &= ~DMA_RB_ENABLE;
3892*4882a593Smuzhiyun WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
3893*4882a593Smuzhiyun }
3894*4882a593Smuzhiyun
3895*4882a593Smuzhiyun udelay(50);
3896*4882a593Smuzhiyun
3897*4882a593Smuzhiyun evergreen_mc_stop(rdev, &save);
3898*4882a593Smuzhiyun if (evergreen_mc_wait_for_idle(rdev)) {
3899*4882a593Smuzhiyun dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
3900*4882a593Smuzhiyun }
3901*4882a593Smuzhiyun
3902*4882a593Smuzhiyun if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
3903*4882a593Smuzhiyun grbm_soft_reset = SOFT_RESET_CB |
3904*4882a593Smuzhiyun SOFT_RESET_DB |
3905*4882a593Smuzhiyun SOFT_RESET_GDS |
3906*4882a593Smuzhiyun SOFT_RESET_PA |
3907*4882a593Smuzhiyun SOFT_RESET_SC |
3908*4882a593Smuzhiyun SOFT_RESET_BCI |
3909*4882a593Smuzhiyun SOFT_RESET_SPI |
3910*4882a593Smuzhiyun SOFT_RESET_SX |
3911*4882a593Smuzhiyun SOFT_RESET_TC |
3912*4882a593Smuzhiyun SOFT_RESET_TA |
3913*4882a593Smuzhiyun SOFT_RESET_VGT |
3914*4882a593Smuzhiyun SOFT_RESET_IA;
3915*4882a593Smuzhiyun }
3916*4882a593Smuzhiyun
3917*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_CP) {
3918*4882a593Smuzhiyun grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
3919*4882a593Smuzhiyun
3920*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_GRBM;
3921*4882a593Smuzhiyun }
3922*4882a593Smuzhiyun
3923*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_DMA)
3924*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_DMA;
3925*4882a593Smuzhiyun
3926*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_DMA1)
3927*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_DMA1;
3928*4882a593Smuzhiyun
3929*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_DISPLAY)
3930*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_DC;
3931*4882a593Smuzhiyun
3932*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_RLC)
3933*4882a593Smuzhiyun grbm_soft_reset |= SOFT_RESET_RLC;
3934*4882a593Smuzhiyun
3935*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_SEM)
3936*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_SEM;
3937*4882a593Smuzhiyun
3938*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_IH)
3939*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_IH;
3940*4882a593Smuzhiyun
3941*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_GRBM)
3942*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_GRBM;
3943*4882a593Smuzhiyun
3944*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_VMC)
3945*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_VMC;
3946*4882a593Smuzhiyun
3947*4882a593Smuzhiyun if (reset_mask & RADEON_RESET_MC)
3948*4882a593Smuzhiyun srbm_soft_reset |= SOFT_RESET_MC;
3949*4882a593Smuzhiyun
3950*4882a593Smuzhiyun if (grbm_soft_reset) {
3951*4882a593Smuzhiyun tmp = RREG32(GRBM_SOFT_RESET);
3952*4882a593Smuzhiyun tmp |= grbm_soft_reset;
3953*4882a593Smuzhiyun dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
3954*4882a593Smuzhiyun WREG32(GRBM_SOFT_RESET, tmp);
3955*4882a593Smuzhiyun tmp = RREG32(GRBM_SOFT_RESET);
3956*4882a593Smuzhiyun
3957*4882a593Smuzhiyun udelay(50);
3958*4882a593Smuzhiyun
3959*4882a593Smuzhiyun tmp &= ~grbm_soft_reset;
3960*4882a593Smuzhiyun WREG32(GRBM_SOFT_RESET, tmp);
3961*4882a593Smuzhiyun tmp = RREG32(GRBM_SOFT_RESET);
3962*4882a593Smuzhiyun }
3963*4882a593Smuzhiyun
3964*4882a593Smuzhiyun if (srbm_soft_reset) {
3965*4882a593Smuzhiyun tmp = RREG32(SRBM_SOFT_RESET);
3966*4882a593Smuzhiyun tmp |= srbm_soft_reset;
3967*4882a593Smuzhiyun dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
3968*4882a593Smuzhiyun WREG32(SRBM_SOFT_RESET, tmp);
3969*4882a593Smuzhiyun tmp = RREG32(SRBM_SOFT_RESET);
3970*4882a593Smuzhiyun
3971*4882a593Smuzhiyun udelay(50);
3972*4882a593Smuzhiyun
3973*4882a593Smuzhiyun tmp &= ~srbm_soft_reset;
3974*4882a593Smuzhiyun WREG32(SRBM_SOFT_RESET, tmp);
3975*4882a593Smuzhiyun tmp = RREG32(SRBM_SOFT_RESET);
3976*4882a593Smuzhiyun }
3977*4882a593Smuzhiyun
3978*4882a593Smuzhiyun /* Wait a little for things to settle down */
3979*4882a593Smuzhiyun udelay(50);
3980*4882a593Smuzhiyun
3981*4882a593Smuzhiyun evergreen_mc_resume(rdev, &save);
3982*4882a593Smuzhiyun udelay(50);
3983*4882a593Smuzhiyun
3984*4882a593Smuzhiyun evergreen_print_gpu_status_regs(rdev);
3985*4882a593Smuzhiyun }
3986*4882a593Smuzhiyun
si_set_clk_bypass_mode(struct radeon_device * rdev)3987*4882a593Smuzhiyun static void si_set_clk_bypass_mode(struct radeon_device *rdev)
3988*4882a593Smuzhiyun {
3989*4882a593Smuzhiyun u32 tmp, i;
3990*4882a593Smuzhiyun
3991*4882a593Smuzhiyun tmp = RREG32(CG_SPLL_FUNC_CNTL);
3992*4882a593Smuzhiyun tmp |= SPLL_BYPASS_EN;
3993*4882a593Smuzhiyun WREG32(CG_SPLL_FUNC_CNTL, tmp);
3994*4882a593Smuzhiyun
3995*4882a593Smuzhiyun tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
3996*4882a593Smuzhiyun tmp |= SPLL_CTLREQ_CHG;
3997*4882a593Smuzhiyun WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
3998*4882a593Smuzhiyun
3999*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
4000*4882a593Smuzhiyun if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
4001*4882a593Smuzhiyun break;
4002*4882a593Smuzhiyun udelay(1);
4003*4882a593Smuzhiyun }
4004*4882a593Smuzhiyun
4005*4882a593Smuzhiyun tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
4006*4882a593Smuzhiyun tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
4007*4882a593Smuzhiyun WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
4008*4882a593Smuzhiyun
4009*4882a593Smuzhiyun tmp = RREG32(MPLL_CNTL_MODE);
4010*4882a593Smuzhiyun tmp &= ~MPLL_MCLK_SEL;
4011*4882a593Smuzhiyun WREG32(MPLL_CNTL_MODE, tmp);
4012*4882a593Smuzhiyun }
4013*4882a593Smuzhiyun
si_spll_powerdown(struct radeon_device * rdev)4014*4882a593Smuzhiyun static void si_spll_powerdown(struct radeon_device *rdev)
4015*4882a593Smuzhiyun {
4016*4882a593Smuzhiyun u32 tmp;
4017*4882a593Smuzhiyun
4018*4882a593Smuzhiyun tmp = RREG32(SPLL_CNTL_MODE);
4019*4882a593Smuzhiyun tmp |= SPLL_SW_DIR_CONTROL;
4020*4882a593Smuzhiyun WREG32(SPLL_CNTL_MODE, tmp);
4021*4882a593Smuzhiyun
4022*4882a593Smuzhiyun tmp = RREG32(CG_SPLL_FUNC_CNTL);
4023*4882a593Smuzhiyun tmp |= SPLL_RESET;
4024*4882a593Smuzhiyun WREG32(CG_SPLL_FUNC_CNTL, tmp);
4025*4882a593Smuzhiyun
4026*4882a593Smuzhiyun tmp = RREG32(CG_SPLL_FUNC_CNTL);
4027*4882a593Smuzhiyun tmp |= SPLL_SLEEP;
4028*4882a593Smuzhiyun WREG32(CG_SPLL_FUNC_CNTL, tmp);
4029*4882a593Smuzhiyun
4030*4882a593Smuzhiyun tmp = RREG32(SPLL_CNTL_MODE);
4031*4882a593Smuzhiyun tmp &= ~SPLL_SW_DIR_CONTROL;
4032*4882a593Smuzhiyun WREG32(SPLL_CNTL_MODE, tmp);
4033*4882a593Smuzhiyun }
4034*4882a593Smuzhiyun
si_gpu_pci_config_reset(struct radeon_device * rdev)4035*4882a593Smuzhiyun static void si_gpu_pci_config_reset(struct radeon_device *rdev)
4036*4882a593Smuzhiyun {
4037*4882a593Smuzhiyun struct evergreen_mc_save save;
4038*4882a593Smuzhiyun u32 tmp, i;
4039*4882a593Smuzhiyun
4040*4882a593Smuzhiyun dev_info(rdev->dev, "GPU pci config reset\n");
4041*4882a593Smuzhiyun
4042*4882a593Smuzhiyun /* disable dpm? */
4043*4882a593Smuzhiyun
4044*4882a593Smuzhiyun /* disable cg/pg */
4045*4882a593Smuzhiyun si_fini_pg(rdev);
4046*4882a593Smuzhiyun si_fini_cg(rdev);
4047*4882a593Smuzhiyun
4048*4882a593Smuzhiyun /* Disable CP parsing/prefetching */
4049*4882a593Smuzhiyun WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
4050*4882a593Smuzhiyun /* dma0 */
4051*4882a593Smuzhiyun tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
4052*4882a593Smuzhiyun tmp &= ~DMA_RB_ENABLE;
4053*4882a593Smuzhiyun WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
4054*4882a593Smuzhiyun /* dma1 */
4055*4882a593Smuzhiyun tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
4056*4882a593Smuzhiyun tmp &= ~DMA_RB_ENABLE;
4057*4882a593Smuzhiyun WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
4058*4882a593Smuzhiyun /* XXX other engines? */
4059*4882a593Smuzhiyun
4060*4882a593Smuzhiyun /* halt the rlc, disable cp internal ints */
4061*4882a593Smuzhiyun si_rlc_stop(rdev);
4062*4882a593Smuzhiyun
4063*4882a593Smuzhiyun udelay(50);
4064*4882a593Smuzhiyun
4065*4882a593Smuzhiyun /* disable mem access */
4066*4882a593Smuzhiyun evergreen_mc_stop(rdev, &save);
4067*4882a593Smuzhiyun if (evergreen_mc_wait_for_idle(rdev)) {
4068*4882a593Smuzhiyun dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
4069*4882a593Smuzhiyun }
4070*4882a593Smuzhiyun
4071*4882a593Smuzhiyun /* set mclk/sclk to bypass */
4072*4882a593Smuzhiyun si_set_clk_bypass_mode(rdev);
4073*4882a593Smuzhiyun /* powerdown spll */
4074*4882a593Smuzhiyun si_spll_powerdown(rdev);
4075*4882a593Smuzhiyun /* disable BM */
4076*4882a593Smuzhiyun pci_clear_master(rdev->pdev);
4077*4882a593Smuzhiyun /* reset */
4078*4882a593Smuzhiyun radeon_pci_config_reset(rdev);
4079*4882a593Smuzhiyun /* wait for asic to come out of reset */
4080*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
4081*4882a593Smuzhiyun if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
4082*4882a593Smuzhiyun break;
4083*4882a593Smuzhiyun udelay(1);
4084*4882a593Smuzhiyun }
4085*4882a593Smuzhiyun }
4086*4882a593Smuzhiyun
si_asic_reset(struct radeon_device * rdev,bool hard)4087*4882a593Smuzhiyun int si_asic_reset(struct radeon_device *rdev, bool hard)
4088*4882a593Smuzhiyun {
4089*4882a593Smuzhiyun u32 reset_mask;
4090*4882a593Smuzhiyun
4091*4882a593Smuzhiyun if (hard) {
4092*4882a593Smuzhiyun si_gpu_pci_config_reset(rdev);
4093*4882a593Smuzhiyun return 0;
4094*4882a593Smuzhiyun }
4095*4882a593Smuzhiyun
4096*4882a593Smuzhiyun reset_mask = si_gpu_check_soft_reset(rdev);
4097*4882a593Smuzhiyun
4098*4882a593Smuzhiyun if (reset_mask)
4099*4882a593Smuzhiyun r600_set_bios_scratch_engine_hung(rdev, true);
4100*4882a593Smuzhiyun
4101*4882a593Smuzhiyun /* try soft reset */
4102*4882a593Smuzhiyun si_gpu_soft_reset(rdev, reset_mask);
4103*4882a593Smuzhiyun
4104*4882a593Smuzhiyun reset_mask = si_gpu_check_soft_reset(rdev);
4105*4882a593Smuzhiyun
4106*4882a593Smuzhiyun /* try pci config reset */
4107*4882a593Smuzhiyun if (reset_mask && radeon_hard_reset)
4108*4882a593Smuzhiyun si_gpu_pci_config_reset(rdev);
4109*4882a593Smuzhiyun
4110*4882a593Smuzhiyun reset_mask = si_gpu_check_soft_reset(rdev);
4111*4882a593Smuzhiyun
4112*4882a593Smuzhiyun if (!reset_mask)
4113*4882a593Smuzhiyun r600_set_bios_scratch_engine_hung(rdev, false);
4114*4882a593Smuzhiyun
4115*4882a593Smuzhiyun return 0;
4116*4882a593Smuzhiyun }
4117*4882a593Smuzhiyun
4118*4882a593Smuzhiyun /**
4119*4882a593Smuzhiyun * si_gfx_is_lockup - Check if the GFX engine is locked up
4120*4882a593Smuzhiyun *
4121*4882a593Smuzhiyun * @rdev: radeon_device pointer
4122*4882a593Smuzhiyun * @ring: radeon_ring structure holding ring information
4123*4882a593Smuzhiyun *
4124*4882a593Smuzhiyun * Check if the GFX engine is locked up.
4125*4882a593Smuzhiyun * Returns true if the engine appears to be locked up, false if not.
4126*4882a593Smuzhiyun */
si_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)4127*4882a593Smuzhiyun bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
4128*4882a593Smuzhiyun {
4129*4882a593Smuzhiyun u32 reset_mask = si_gpu_check_soft_reset(rdev);
4130*4882a593Smuzhiyun
4131*4882a593Smuzhiyun if (!(reset_mask & (RADEON_RESET_GFX |
4132*4882a593Smuzhiyun RADEON_RESET_COMPUTE |
4133*4882a593Smuzhiyun RADEON_RESET_CP))) {
4134*4882a593Smuzhiyun radeon_ring_lockup_update(rdev, ring);
4135*4882a593Smuzhiyun return false;
4136*4882a593Smuzhiyun }
4137*4882a593Smuzhiyun return radeon_ring_test_lockup(rdev, ring);
4138*4882a593Smuzhiyun }
4139*4882a593Smuzhiyun
4140*4882a593Smuzhiyun /* MC */
si_mc_program(struct radeon_device * rdev)4141*4882a593Smuzhiyun static void si_mc_program(struct radeon_device *rdev)
4142*4882a593Smuzhiyun {
4143*4882a593Smuzhiyun struct evergreen_mc_save save;
4144*4882a593Smuzhiyun u32 tmp;
4145*4882a593Smuzhiyun int i, j;
4146*4882a593Smuzhiyun
4147*4882a593Smuzhiyun /* Initialize HDP */
4148*4882a593Smuzhiyun for (i = 0, j = 0; i < 32; i++, j += 0x18) {
4149*4882a593Smuzhiyun WREG32((0x2c14 + j), 0x00000000);
4150*4882a593Smuzhiyun WREG32((0x2c18 + j), 0x00000000);
4151*4882a593Smuzhiyun WREG32((0x2c1c + j), 0x00000000);
4152*4882a593Smuzhiyun WREG32((0x2c20 + j), 0x00000000);
4153*4882a593Smuzhiyun WREG32((0x2c24 + j), 0x00000000);
4154*4882a593Smuzhiyun }
4155*4882a593Smuzhiyun WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
4156*4882a593Smuzhiyun
4157*4882a593Smuzhiyun evergreen_mc_stop(rdev, &save);
4158*4882a593Smuzhiyun if (radeon_mc_wait_for_idle(rdev)) {
4159*4882a593Smuzhiyun dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4160*4882a593Smuzhiyun }
4161*4882a593Smuzhiyun if (!ASIC_IS_NODCE(rdev))
4162*4882a593Smuzhiyun /* Lockout access through VGA aperture*/
4163*4882a593Smuzhiyun WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
4164*4882a593Smuzhiyun /* Update configuration */
4165*4882a593Smuzhiyun WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
4166*4882a593Smuzhiyun rdev->mc.vram_start >> 12);
4167*4882a593Smuzhiyun WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
4168*4882a593Smuzhiyun rdev->mc.vram_end >> 12);
4169*4882a593Smuzhiyun WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
4170*4882a593Smuzhiyun rdev->vram_scratch.gpu_addr >> 12);
4171*4882a593Smuzhiyun tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
4172*4882a593Smuzhiyun tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
4173*4882a593Smuzhiyun WREG32(MC_VM_FB_LOCATION, tmp);
4174*4882a593Smuzhiyun /* XXX double check these! */
4175*4882a593Smuzhiyun WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
4176*4882a593Smuzhiyun WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
4177*4882a593Smuzhiyun WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
4178*4882a593Smuzhiyun WREG32(MC_VM_AGP_BASE, 0);
4179*4882a593Smuzhiyun WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
4180*4882a593Smuzhiyun WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
4181*4882a593Smuzhiyun if (radeon_mc_wait_for_idle(rdev)) {
4182*4882a593Smuzhiyun dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4183*4882a593Smuzhiyun }
4184*4882a593Smuzhiyun evergreen_mc_resume(rdev, &save);
4185*4882a593Smuzhiyun if (!ASIC_IS_NODCE(rdev)) {
4186*4882a593Smuzhiyun /* we need to own VRAM, so turn off the VGA renderer here
4187*4882a593Smuzhiyun * to stop it overwriting our objects */
4188*4882a593Smuzhiyun rv515_vga_render_disable(rdev);
4189*4882a593Smuzhiyun }
4190*4882a593Smuzhiyun }
4191*4882a593Smuzhiyun
si_vram_gtt_location(struct radeon_device * rdev,struct radeon_mc * mc)4192*4882a593Smuzhiyun void si_vram_gtt_location(struct radeon_device *rdev,
4193*4882a593Smuzhiyun struct radeon_mc *mc)
4194*4882a593Smuzhiyun {
4195*4882a593Smuzhiyun if (mc->mc_vram_size > 0xFFC0000000ULL) {
4196*4882a593Smuzhiyun /* leave room for at least 1024M GTT */
4197*4882a593Smuzhiyun dev_warn(rdev->dev, "limiting VRAM\n");
4198*4882a593Smuzhiyun mc->real_vram_size = 0xFFC0000000ULL;
4199*4882a593Smuzhiyun mc->mc_vram_size = 0xFFC0000000ULL;
4200*4882a593Smuzhiyun }
4201*4882a593Smuzhiyun radeon_vram_location(rdev, &rdev->mc, 0);
4202*4882a593Smuzhiyun rdev->mc.gtt_base_align = 0;
4203*4882a593Smuzhiyun radeon_gtt_location(rdev, mc);
4204*4882a593Smuzhiyun }
4205*4882a593Smuzhiyun
si_mc_init(struct radeon_device * rdev)4206*4882a593Smuzhiyun static int si_mc_init(struct radeon_device *rdev)
4207*4882a593Smuzhiyun {
4208*4882a593Smuzhiyun u32 tmp;
4209*4882a593Smuzhiyun int chansize, numchan;
4210*4882a593Smuzhiyun
4211*4882a593Smuzhiyun /* Get VRAM informations */
4212*4882a593Smuzhiyun rdev->mc.vram_is_ddr = true;
4213*4882a593Smuzhiyun tmp = RREG32(MC_ARB_RAMCFG);
4214*4882a593Smuzhiyun if (tmp & CHANSIZE_OVERRIDE) {
4215*4882a593Smuzhiyun chansize = 16;
4216*4882a593Smuzhiyun } else if (tmp & CHANSIZE_MASK) {
4217*4882a593Smuzhiyun chansize = 64;
4218*4882a593Smuzhiyun } else {
4219*4882a593Smuzhiyun chansize = 32;
4220*4882a593Smuzhiyun }
4221*4882a593Smuzhiyun tmp = RREG32(MC_SHARED_CHMAP);
4222*4882a593Smuzhiyun switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
4223*4882a593Smuzhiyun case 0:
4224*4882a593Smuzhiyun default:
4225*4882a593Smuzhiyun numchan = 1;
4226*4882a593Smuzhiyun break;
4227*4882a593Smuzhiyun case 1:
4228*4882a593Smuzhiyun numchan = 2;
4229*4882a593Smuzhiyun break;
4230*4882a593Smuzhiyun case 2:
4231*4882a593Smuzhiyun numchan = 4;
4232*4882a593Smuzhiyun break;
4233*4882a593Smuzhiyun case 3:
4234*4882a593Smuzhiyun numchan = 8;
4235*4882a593Smuzhiyun break;
4236*4882a593Smuzhiyun case 4:
4237*4882a593Smuzhiyun numchan = 3;
4238*4882a593Smuzhiyun break;
4239*4882a593Smuzhiyun case 5:
4240*4882a593Smuzhiyun numchan = 6;
4241*4882a593Smuzhiyun break;
4242*4882a593Smuzhiyun case 6:
4243*4882a593Smuzhiyun numchan = 10;
4244*4882a593Smuzhiyun break;
4245*4882a593Smuzhiyun case 7:
4246*4882a593Smuzhiyun numchan = 12;
4247*4882a593Smuzhiyun break;
4248*4882a593Smuzhiyun case 8:
4249*4882a593Smuzhiyun numchan = 16;
4250*4882a593Smuzhiyun break;
4251*4882a593Smuzhiyun }
4252*4882a593Smuzhiyun rdev->mc.vram_width = numchan * chansize;
4253*4882a593Smuzhiyun /* Could aper size report 0 ? */
4254*4882a593Smuzhiyun rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
4255*4882a593Smuzhiyun rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
4256*4882a593Smuzhiyun /* size in MB on si */
4257*4882a593Smuzhiyun tmp = RREG32(CONFIG_MEMSIZE);
4258*4882a593Smuzhiyun /* some boards may have garbage in the upper 16 bits */
4259*4882a593Smuzhiyun if (tmp & 0xffff0000) {
4260*4882a593Smuzhiyun DRM_INFO("Probable bad vram size: 0x%08x\n", tmp);
4261*4882a593Smuzhiyun if (tmp & 0xffff)
4262*4882a593Smuzhiyun tmp &= 0xffff;
4263*4882a593Smuzhiyun }
4264*4882a593Smuzhiyun rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL;
4265*4882a593Smuzhiyun rdev->mc.real_vram_size = rdev->mc.mc_vram_size;
4266*4882a593Smuzhiyun rdev->mc.visible_vram_size = rdev->mc.aper_size;
4267*4882a593Smuzhiyun si_vram_gtt_location(rdev, &rdev->mc);
4268*4882a593Smuzhiyun radeon_update_bandwidth_info(rdev);
4269*4882a593Smuzhiyun
4270*4882a593Smuzhiyun return 0;
4271*4882a593Smuzhiyun }
4272*4882a593Smuzhiyun
4273*4882a593Smuzhiyun /*
4274*4882a593Smuzhiyun * GART
4275*4882a593Smuzhiyun */
si_pcie_gart_tlb_flush(struct radeon_device * rdev)4276*4882a593Smuzhiyun void si_pcie_gart_tlb_flush(struct radeon_device *rdev)
4277*4882a593Smuzhiyun {
4278*4882a593Smuzhiyun /* flush hdp cache */
4279*4882a593Smuzhiyun WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
4280*4882a593Smuzhiyun
4281*4882a593Smuzhiyun /* bits 0-15 are the VM contexts0-15 */
4282*4882a593Smuzhiyun WREG32(VM_INVALIDATE_REQUEST, 1);
4283*4882a593Smuzhiyun }
4284*4882a593Smuzhiyun
si_pcie_gart_enable(struct radeon_device * rdev)4285*4882a593Smuzhiyun static int si_pcie_gart_enable(struct radeon_device *rdev)
4286*4882a593Smuzhiyun {
4287*4882a593Smuzhiyun int r, i;
4288*4882a593Smuzhiyun
4289*4882a593Smuzhiyun if (rdev->gart.robj == NULL) {
4290*4882a593Smuzhiyun dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
4291*4882a593Smuzhiyun return -EINVAL;
4292*4882a593Smuzhiyun }
4293*4882a593Smuzhiyun r = radeon_gart_table_vram_pin(rdev);
4294*4882a593Smuzhiyun if (r)
4295*4882a593Smuzhiyun return r;
4296*4882a593Smuzhiyun /* Setup TLB control */
4297*4882a593Smuzhiyun WREG32(MC_VM_MX_L1_TLB_CNTL,
4298*4882a593Smuzhiyun (0xA << 7) |
4299*4882a593Smuzhiyun ENABLE_L1_TLB |
4300*4882a593Smuzhiyun ENABLE_L1_FRAGMENT_PROCESSING |
4301*4882a593Smuzhiyun SYSTEM_ACCESS_MODE_NOT_IN_SYS |
4302*4882a593Smuzhiyun ENABLE_ADVANCED_DRIVER_MODEL |
4303*4882a593Smuzhiyun SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
4304*4882a593Smuzhiyun /* Setup L2 cache */
4305*4882a593Smuzhiyun WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
4306*4882a593Smuzhiyun ENABLE_L2_FRAGMENT_PROCESSING |
4307*4882a593Smuzhiyun ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
4308*4882a593Smuzhiyun ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
4309*4882a593Smuzhiyun EFFECTIVE_L2_QUEUE_SIZE(7) |
4310*4882a593Smuzhiyun CONTEXT1_IDENTITY_ACCESS_MODE(1));
4311*4882a593Smuzhiyun WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
4312*4882a593Smuzhiyun WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
4313*4882a593Smuzhiyun BANK_SELECT(4) |
4314*4882a593Smuzhiyun L2_CACHE_BIGK_FRAGMENT_SIZE(4));
4315*4882a593Smuzhiyun /* setup context0 */
4316*4882a593Smuzhiyun WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
4317*4882a593Smuzhiyun WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
4318*4882a593Smuzhiyun WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
4319*4882a593Smuzhiyun WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
4320*4882a593Smuzhiyun (u32)(rdev->dummy_page.addr >> 12));
4321*4882a593Smuzhiyun WREG32(VM_CONTEXT0_CNTL2, 0);
4322*4882a593Smuzhiyun WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
4323*4882a593Smuzhiyun RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
4324*4882a593Smuzhiyun
4325*4882a593Smuzhiyun WREG32(0x15D4, 0);
4326*4882a593Smuzhiyun WREG32(0x15D8, 0);
4327*4882a593Smuzhiyun WREG32(0x15DC, 0);
4328*4882a593Smuzhiyun
4329*4882a593Smuzhiyun /* empty context1-15 */
4330*4882a593Smuzhiyun /* set vm size, must be a multiple of 4 */
4331*4882a593Smuzhiyun WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
4332*4882a593Smuzhiyun WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
4333*4882a593Smuzhiyun /* Assign the pt base to something valid for now; the pts used for
4334*4882a593Smuzhiyun * the VMs are determined by the application and setup and assigned
4335*4882a593Smuzhiyun * on the fly in the vm part of radeon_gart.c
4336*4882a593Smuzhiyun */
4337*4882a593Smuzhiyun for (i = 1; i < 16; i++) {
4338*4882a593Smuzhiyun if (i < 8)
4339*4882a593Smuzhiyun WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
4340*4882a593Smuzhiyun rdev->vm_manager.saved_table_addr[i]);
4341*4882a593Smuzhiyun else
4342*4882a593Smuzhiyun WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
4343*4882a593Smuzhiyun rdev->vm_manager.saved_table_addr[i]);
4344*4882a593Smuzhiyun }
4345*4882a593Smuzhiyun
4346*4882a593Smuzhiyun /* enable context1-15 */
4347*4882a593Smuzhiyun WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
4348*4882a593Smuzhiyun (u32)(rdev->dummy_page.addr >> 12));
4349*4882a593Smuzhiyun WREG32(VM_CONTEXT1_CNTL2, 4);
4350*4882a593Smuzhiyun WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
4351*4882a593Smuzhiyun PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
4352*4882a593Smuzhiyun RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4353*4882a593Smuzhiyun RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
4354*4882a593Smuzhiyun DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4355*4882a593Smuzhiyun DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
4356*4882a593Smuzhiyun PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
4357*4882a593Smuzhiyun PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
4358*4882a593Smuzhiyun VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
4359*4882a593Smuzhiyun VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
4360*4882a593Smuzhiyun READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
4361*4882a593Smuzhiyun READ_PROTECTION_FAULT_ENABLE_DEFAULT |
4362*4882a593Smuzhiyun WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4363*4882a593Smuzhiyun WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
4364*4882a593Smuzhiyun
4365*4882a593Smuzhiyun si_pcie_gart_tlb_flush(rdev);
4366*4882a593Smuzhiyun DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
4367*4882a593Smuzhiyun (unsigned)(rdev->mc.gtt_size >> 20),
4368*4882a593Smuzhiyun (unsigned long long)rdev->gart.table_addr);
4369*4882a593Smuzhiyun rdev->gart.ready = true;
4370*4882a593Smuzhiyun return 0;
4371*4882a593Smuzhiyun }
4372*4882a593Smuzhiyun
si_pcie_gart_disable(struct radeon_device * rdev)4373*4882a593Smuzhiyun static void si_pcie_gart_disable(struct radeon_device *rdev)
4374*4882a593Smuzhiyun {
4375*4882a593Smuzhiyun unsigned i;
4376*4882a593Smuzhiyun
4377*4882a593Smuzhiyun for (i = 1; i < 16; ++i) {
4378*4882a593Smuzhiyun uint32_t reg;
4379*4882a593Smuzhiyun if (i < 8)
4380*4882a593Smuzhiyun reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
4381*4882a593Smuzhiyun else
4382*4882a593Smuzhiyun reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
4383*4882a593Smuzhiyun rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
4384*4882a593Smuzhiyun }
4385*4882a593Smuzhiyun
4386*4882a593Smuzhiyun /* Disable all tables */
4387*4882a593Smuzhiyun WREG32(VM_CONTEXT0_CNTL, 0);
4388*4882a593Smuzhiyun WREG32(VM_CONTEXT1_CNTL, 0);
4389*4882a593Smuzhiyun /* Setup TLB control */
4390*4882a593Smuzhiyun WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
4391*4882a593Smuzhiyun SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
4392*4882a593Smuzhiyun /* Setup L2 cache */
4393*4882a593Smuzhiyun WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
4394*4882a593Smuzhiyun ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
4395*4882a593Smuzhiyun EFFECTIVE_L2_QUEUE_SIZE(7) |
4396*4882a593Smuzhiyun CONTEXT1_IDENTITY_ACCESS_MODE(1));
4397*4882a593Smuzhiyun WREG32(VM_L2_CNTL2, 0);
4398*4882a593Smuzhiyun WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
4399*4882a593Smuzhiyun L2_CACHE_BIGK_FRAGMENT_SIZE(0));
4400*4882a593Smuzhiyun radeon_gart_table_vram_unpin(rdev);
4401*4882a593Smuzhiyun }
4402*4882a593Smuzhiyun
si_pcie_gart_fini(struct radeon_device * rdev)4403*4882a593Smuzhiyun static void si_pcie_gart_fini(struct radeon_device *rdev)
4404*4882a593Smuzhiyun {
4405*4882a593Smuzhiyun si_pcie_gart_disable(rdev);
4406*4882a593Smuzhiyun radeon_gart_table_vram_free(rdev);
4407*4882a593Smuzhiyun radeon_gart_fini(rdev);
4408*4882a593Smuzhiyun }
4409*4882a593Smuzhiyun
4410*4882a593Smuzhiyun /* vm parser */
si_vm_reg_valid(u32 reg)4411*4882a593Smuzhiyun static bool si_vm_reg_valid(u32 reg)
4412*4882a593Smuzhiyun {
4413*4882a593Smuzhiyun /* context regs are fine */
4414*4882a593Smuzhiyun if (reg >= 0x28000)
4415*4882a593Smuzhiyun return true;
4416*4882a593Smuzhiyun
4417*4882a593Smuzhiyun /* shader regs are also fine */
4418*4882a593Smuzhiyun if (reg >= 0xB000 && reg < 0xC000)
4419*4882a593Smuzhiyun return true;
4420*4882a593Smuzhiyun
4421*4882a593Smuzhiyun /* check config regs */
4422*4882a593Smuzhiyun switch (reg) {
4423*4882a593Smuzhiyun case GRBM_GFX_INDEX:
4424*4882a593Smuzhiyun case CP_STRMOUT_CNTL:
4425*4882a593Smuzhiyun case VGT_VTX_VECT_EJECT_REG:
4426*4882a593Smuzhiyun case VGT_CACHE_INVALIDATION:
4427*4882a593Smuzhiyun case VGT_ESGS_RING_SIZE:
4428*4882a593Smuzhiyun case VGT_GSVS_RING_SIZE:
4429*4882a593Smuzhiyun case VGT_GS_VERTEX_REUSE:
4430*4882a593Smuzhiyun case VGT_PRIMITIVE_TYPE:
4431*4882a593Smuzhiyun case VGT_INDEX_TYPE:
4432*4882a593Smuzhiyun case VGT_NUM_INDICES:
4433*4882a593Smuzhiyun case VGT_NUM_INSTANCES:
4434*4882a593Smuzhiyun case VGT_TF_RING_SIZE:
4435*4882a593Smuzhiyun case VGT_HS_OFFCHIP_PARAM:
4436*4882a593Smuzhiyun case VGT_TF_MEMORY_BASE:
4437*4882a593Smuzhiyun case PA_CL_ENHANCE:
4438*4882a593Smuzhiyun case PA_SU_LINE_STIPPLE_VALUE:
4439*4882a593Smuzhiyun case PA_SC_LINE_STIPPLE_STATE:
4440*4882a593Smuzhiyun case PA_SC_ENHANCE:
4441*4882a593Smuzhiyun case SQC_CACHES:
4442*4882a593Smuzhiyun case SPI_STATIC_THREAD_MGMT_1:
4443*4882a593Smuzhiyun case SPI_STATIC_THREAD_MGMT_2:
4444*4882a593Smuzhiyun case SPI_STATIC_THREAD_MGMT_3:
4445*4882a593Smuzhiyun case SPI_PS_MAX_WAVE_ID:
4446*4882a593Smuzhiyun case SPI_CONFIG_CNTL:
4447*4882a593Smuzhiyun case SPI_CONFIG_CNTL_1:
4448*4882a593Smuzhiyun case TA_CNTL_AUX:
4449*4882a593Smuzhiyun case TA_CS_BC_BASE_ADDR:
4450*4882a593Smuzhiyun return true;
4451*4882a593Smuzhiyun default:
4452*4882a593Smuzhiyun DRM_ERROR("Invalid register 0x%x in CS\n", reg);
4453*4882a593Smuzhiyun return false;
4454*4882a593Smuzhiyun }
4455*4882a593Smuzhiyun }
4456*4882a593Smuzhiyun
si_vm_packet3_ce_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4457*4882a593Smuzhiyun static int si_vm_packet3_ce_check(struct radeon_device *rdev,
4458*4882a593Smuzhiyun u32 *ib, struct radeon_cs_packet *pkt)
4459*4882a593Smuzhiyun {
4460*4882a593Smuzhiyun switch (pkt->opcode) {
4461*4882a593Smuzhiyun case PACKET3_NOP:
4462*4882a593Smuzhiyun case PACKET3_SET_BASE:
4463*4882a593Smuzhiyun case PACKET3_SET_CE_DE_COUNTERS:
4464*4882a593Smuzhiyun case PACKET3_LOAD_CONST_RAM:
4465*4882a593Smuzhiyun case PACKET3_WRITE_CONST_RAM:
4466*4882a593Smuzhiyun case PACKET3_WRITE_CONST_RAM_OFFSET:
4467*4882a593Smuzhiyun case PACKET3_DUMP_CONST_RAM:
4468*4882a593Smuzhiyun case PACKET3_INCREMENT_CE_COUNTER:
4469*4882a593Smuzhiyun case PACKET3_WAIT_ON_DE_COUNTER:
4470*4882a593Smuzhiyun case PACKET3_CE_WRITE:
4471*4882a593Smuzhiyun break;
4472*4882a593Smuzhiyun default:
4473*4882a593Smuzhiyun DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode);
4474*4882a593Smuzhiyun return -EINVAL;
4475*4882a593Smuzhiyun }
4476*4882a593Smuzhiyun return 0;
4477*4882a593Smuzhiyun }
4478*4882a593Smuzhiyun
si_vm_packet3_cp_dma_check(u32 * ib,u32 idx)4479*4882a593Smuzhiyun static int si_vm_packet3_cp_dma_check(u32 *ib, u32 idx)
4480*4882a593Smuzhiyun {
4481*4882a593Smuzhiyun u32 start_reg, reg, i;
4482*4882a593Smuzhiyun u32 command = ib[idx + 4];
4483*4882a593Smuzhiyun u32 info = ib[idx + 1];
4484*4882a593Smuzhiyun u32 idx_value = ib[idx];
4485*4882a593Smuzhiyun if (command & PACKET3_CP_DMA_CMD_SAS) {
4486*4882a593Smuzhiyun /* src address space is register */
4487*4882a593Smuzhiyun if (((info & 0x60000000) >> 29) == 0) {
4488*4882a593Smuzhiyun start_reg = idx_value << 2;
4489*4882a593Smuzhiyun if (command & PACKET3_CP_DMA_CMD_SAIC) {
4490*4882a593Smuzhiyun reg = start_reg;
4491*4882a593Smuzhiyun if (!si_vm_reg_valid(reg)) {
4492*4882a593Smuzhiyun DRM_ERROR("CP DMA Bad SRC register\n");
4493*4882a593Smuzhiyun return -EINVAL;
4494*4882a593Smuzhiyun }
4495*4882a593Smuzhiyun } else {
4496*4882a593Smuzhiyun for (i = 0; i < (command & 0x1fffff); i++) {
4497*4882a593Smuzhiyun reg = start_reg + (4 * i);
4498*4882a593Smuzhiyun if (!si_vm_reg_valid(reg)) {
4499*4882a593Smuzhiyun DRM_ERROR("CP DMA Bad SRC register\n");
4500*4882a593Smuzhiyun return -EINVAL;
4501*4882a593Smuzhiyun }
4502*4882a593Smuzhiyun }
4503*4882a593Smuzhiyun }
4504*4882a593Smuzhiyun }
4505*4882a593Smuzhiyun }
4506*4882a593Smuzhiyun if (command & PACKET3_CP_DMA_CMD_DAS) {
4507*4882a593Smuzhiyun /* dst address space is register */
4508*4882a593Smuzhiyun if (((info & 0x00300000) >> 20) == 0) {
4509*4882a593Smuzhiyun start_reg = ib[idx + 2];
4510*4882a593Smuzhiyun if (command & PACKET3_CP_DMA_CMD_DAIC) {
4511*4882a593Smuzhiyun reg = start_reg;
4512*4882a593Smuzhiyun if (!si_vm_reg_valid(reg)) {
4513*4882a593Smuzhiyun DRM_ERROR("CP DMA Bad DST register\n");
4514*4882a593Smuzhiyun return -EINVAL;
4515*4882a593Smuzhiyun }
4516*4882a593Smuzhiyun } else {
4517*4882a593Smuzhiyun for (i = 0; i < (command & 0x1fffff); i++) {
4518*4882a593Smuzhiyun reg = start_reg + (4 * i);
4519*4882a593Smuzhiyun if (!si_vm_reg_valid(reg)) {
4520*4882a593Smuzhiyun DRM_ERROR("CP DMA Bad DST register\n");
4521*4882a593Smuzhiyun return -EINVAL;
4522*4882a593Smuzhiyun }
4523*4882a593Smuzhiyun }
4524*4882a593Smuzhiyun }
4525*4882a593Smuzhiyun }
4526*4882a593Smuzhiyun }
4527*4882a593Smuzhiyun return 0;
4528*4882a593Smuzhiyun }
4529*4882a593Smuzhiyun
si_vm_packet3_gfx_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4530*4882a593Smuzhiyun static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
4531*4882a593Smuzhiyun u32 *ib, struct radeon_cs_packet *pkt)
4532*4882a593Smuzhiyun {
4533*4882a593Smuzhiyun int r;
4534*4882a593Smuzhiyun u32 idx = pkt->idx + 1;
4535*4882a593Smuzhiyun u32 idx_value = ib[idx];
4536*4882a593Smuzhiyun u32 start_reg, end_reg, reg, i;
4537*4882a593Smuzhiyun
4538*4882a593Smuzhiyun switch (pkt->opcode) {
4539*4882a593Smuzhiyun case PACKET3_NOP:
4540*4882a593Smuzhiyun case PACKET3_SET_BASE:
4541*4882a593Smuzhiyun case PACKET3_CLEAR_STATE:
4542*4882a593Smuzhiyun case PACKET3_INDEX_BUFFER_SIZE:
4543*4882a593Smuzhiyun case PACKET3_DISPATCH_DIRECT:
4544*4882a593Smuzhiyun case PACKET3_DISPATCH_INDIRECT:
4545*4882a593Smuzhiyun case PACKET3_ALLOC_GDS:
4546*4882a593Smuzhiyun case PACKET3_WRITE_GDS_RAM:
4547*4882a593Smuzhiyun case PACKET3_ATOMIC_GDS:
4548*4882a593Smuzhiyun case PACKET3_ATOMIC:
4549*4882a593Smuzhiyun case PACKET3_OCCLUSION_QUERY:
4550*4882a593Smuzhiyun case PACKET3_SET_PREDICATION:
4551*4882a593Smuzhiyun case PACKET3_COND_EXEC:
4552*4882a593Smuzhiyun case PACKET3_PRED_EXEC:
4553*4882a593Smuzhiyun case PACKET3_DRAW_INDIRECT:
4554*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_INDIRECT:
4555*4882a593Smuzhiyun case PACKET3_INDEX_BASE:
4556*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_2:
4557*4882a593Smuzhiyun case PACKET3_CONTEXT_CONTROL:
4558*4882a593Smuzhiyun case PACKET3_INDEX_TYPE:
4559*4882a593Smuzhiyun case PACKET3_DRAW_INDIRECT_MULTI:
4560*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_AUTO:
4561*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_IMMD:
4562*4882a593Smuzhiyun case PACKET3_NUM_INSTANCES:
4563*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_MULTI_AUTO:
4564*4882a593Smuzhiyun case PACKET3_STRMOUT_BUFFER_UPDATE:
4565*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_OFFSET_2:
4566*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
4567*4882a593Smuzhiyun case PACKET3_DRAW_INDEX_INDIRECT_MULTI:
4568*4882a593Smuzhiyun case PACKET3_MPEG_INDEX:
4569*4882a593Smuzhiyun case PACKET3_WAIT_REG_MEM:
4570*4882a593Smuzhiyun case PACKET3_MEM_WRITE:
4571*4882a593Smuzhiyun case PACKET3_PFP_SYNC_ME:
4572*4882a593Smuzhiyun case PACKET3_SURFACE_SYNC:
4573*4882a593Smuzhiyun case PACKET3_EVENT_WRITE:
4574*4882a593Smuzhiyun case PACKET3_EVENT_WRITE_EOP:
4575*4882a593Smuzhiyun case PACKET3_EVENT_WRITE_EOS:
4576*4882a593Smuzhiyun case PACKET3_SET_CONTEXT_REG:
4577*4882a593Smuzhiyun case PACKET3_SET_CONTEXT_REG_INDIRECT:
4578*4882a593Smuzhiyun case PACKET3_SET_SH_REG:
4579*4882a593Smuzhiyun case PACKET3_SET_SH_REG_OFFSET:
4580*4882a593Smuzhiyun case PACKET3_INCREMENT_DE_COUNTER:
4581*4882a593Smuzhiyun case PACKET3_WAIT_ON_CE_COUNTER:
4582*4882a593Smuzhiyun case PACKET3_WAIT_ON_AVAIL_BUFFER:
4583*4882a593Smuzhiyun case PACKET3_ME_WRITE:
4584*4882a593Smuzhiyun break;
4585*4882a593Smuzhiyun case PACKET3_COPY_DATA:
4586*4882a593Smuzhiyun if ((idx_value & 0xf00) == 0) {
4587*4882a593Smuzhiyun reg = ib[idx + 3] * 4;
4588*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4589*4882a593Smuzhiyun return -EINVAL;
4590*4882a593Smuzhiyun }
4591*4882a593Smuzhiyun break;
4592*4882a593Smuzhiyun case PACKET3_WRITE_DATA:
4593*4882a593Smuzhiyun if ((idx_value & 0xf00) == 0) {
4594*4882a593Smuzhiyun start_reg = ib[idx + 1] * 4;
4595*4882a593Smuzhiyun if (idx_value & 0x10000) {
4596*4882a593Smuzhiyun if (!si_vm_reg_valid(start_reg))
4597*4882a593Smuzhiyun return -EINVAL;
4598*4882a593Smuzhiyun } else {
4599*4882a593Smuzhiyun for (i = 0; i < (pkt->count - 2); i++) {
4600*4882a593Smuzhiyun reg = start_reg + (4 * i);
4601*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4602*4882a593Smuzhiyun return -EINVAL;
4603*4882a593Smuzhiyun }
4604*4882a593Smuzhiyun }
4605*4882a593Smuzhiyun }
4606*4882a593Smuzhiyun break;
4607*4882a593Smuzhiyun case PACKET3_COND_WRITE:
4608*4882a593Smuzhiyun if (idx_value & 0x100) {
4609*4882a593Smuzhiyun reg = ib[idx + 5] * 4;
4610*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4611*4882a593Smuzhiyun return -EINVAL;
4612*4882a593Smuzhiyun }
4613*4882a593Smuzhiyun break;
4614*4882a593Smuzhiyun case PACKET3_COPY_DW:
4615*4882a593Smuzhiyun if (idx_value & 0x2) {
4616*4882a593Smuzhiyun reg = ib[idx + 3] * 4;
4617*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4618*4882a593Smuzhiyun return -EINVAL;
4619*4882a593Smuzhiyun }
4620*4882a593Smuzhiyun break;
4621*4882a593Smuzhiyun case PACKET3_SET_CONFIG_REG:
4622*4882a593Smuzhiyun start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
4623*4882a593Smuzhiyun end_reg = 4 * pkt->count + start_reg - 4;
4624*4882a593Smuzhiyun if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
4625*4882a593Smuzhiyun (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
4626*4882a593Smuzhiyun (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
4627*4882a593Smuzhiyun DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
4628*4882a593Smuzhiyun return -EINVAL;
4629*4882a593Smuzhiyun }
4630*4882a593Smuzhiyun for (i = 0; i < pkt->count; i++) {
4631*4882a593Smuzhiyun reg = start_reg + (4 * i);
4632*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4633*4882a593Smuzhiyun return -EINVAL;
4634*4882a593Smuzhiyun }
4635*4882a593Smuzhiyun break;
4636*4882a593Smuzhiyun case PACKET3_CP_DMA:
4637*4882a593Smuzhiyun r = si_vm_packet3_cp_dma_check(ib, idx);
4638*4882a593Smuzhiyun if (r)
4639*4882a593Smuzhiyun return r;
4640*4882a593Smuzhiyun break;
4641*4882a593Smuzhiyun default:
4642*4882a593Smuzhiyun DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
4643*4882a593Smuzhiyun return -EINVAL;
4644*4882a593Smuzhiyun }
4645*4882a593Smuzhiyun return 0;
4646*4882a593Smuzhiyun }
4647*4882a593Smuzhiyun
si_vm_packet3_compute_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4648*4882a593Smuzhiyun static int si_vm_packet3_compute_check(struct radeon_device *rdev,
4649*4882a593Smuzhiyun u32 *ib, struct radeon_cs_packet *pkt)
4650*4882a593Smuzhiyun {
4651*4882a593Smuzhiyun int r;
4652*4882a593Smuzhiyun u32 idx = pkt->idx + 1;
4653*4882a593Smuzhiyun u32 idx_value = ib[idx];
4654*4882a593Smuzhiyun u32 start_reg, reg, i;
4655*4882a593Smuzhiyun
4656*4882a593Smuzhiyun switch (pkt->opcode) {
4657*4882a593Smuzhiyun case PACKET3_NOP:
4658*4882a593Smuzhiyun case PACKET3_SET_BASE:
4659*4882a593Smuzhiyun case PACKET3_CLEAR_STATE:
4660*4882a593Smuzhiyun case PACKET3_DISPATCH_DIRECT:
4661*4882a593Smuzhiyun case PACKET3_DISPATCH_INDIRECT:
4662*4882a593Smuzhiyun case PACKET3_ALLOC_GDS:
4663*4882a593Smuzhiyun case PACKET3_WRITE_GDS_RAM:
4664*4882a593Smuzhiyun case PACKET3_ATOMIC_GDS:
4665*4882a593Smuzhiyun case PACKET3_ATOMIC:
4666*4882a593Smuzhiyun case PACKET3_OCCLUSION_QUERY:
4667*4882a593Smuzhiyun case PACKET3_SET_PREDICATION:
4668*4882a593Smuzhiyun case PACKET3_COND_EXEC:
4669*4882a593Smuzhiyun case PACKET3_PRED_EXEC:
4670*4882a593Smuzhiyun case PACKET3_CONTEXT_CONTROL:
4671*4882a593Smuzhiyun case PACKET3_STRMOUT_BUFFER_UPDATE:
4672*4882a593Smuzhiyun case PACKET3_WAIT_REG_MEM:
4673*4882a593Smuzhiyun case PACKET3_MEM_WRITE:
4674*4882a593Smuzhiyun case PACKET3_PFP_SYNC_ME:
4675*4882a593Smuzhiyun case PACKET3_SURFACE_SYNC:
4676*4882a593Smuzhiyun case PACKET3_EVENT_WRITE:
4677*4882a593Smuzhiyun case PACKET3_EVENT_WRITE_EOP:
4678*4882a593Smuzhiyun case PACKET3_EVENT_WRITE_EOS:
4679*4882a593Smuzhiyun case PACKET3_SET_CONTEXT_REG:
4680*4882a593Smuzhiyun case PACKET3_SET_CONTEXT_REG_INDIRECT:
4681*4882a593Smuzhiyun case PACKET3_SET_SH_REG:
4682*4882a593Smuzhiyun case PACKET3_SET_SH_REG_OFFSET:
4683*4882a593Smuzhiyun case PACKET3_INCREMENT_DE_COUNTER:
4684*4882a593Smuzhiyun case PACKET3_WAIT_ON_CE_COUNTER:
4685*4882a593Smuzhiyun case PACKET3_WAIT_ON_AVAIL_BUFFER:
4686*4882a593Smuzhiyun case PACKET3_ME_WRITE:
4687*4882a593Smuzhiyun break;
4688*4882a593Smuzhiyun case PACKET3_COPY_DATA:
4689*4882a593Smuzhiyun if ((idx_value & 0xf00) == 0) {
4690*4882a593Smuzhiyun reg = ib[idx + 3] * 4;
4691*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4692*4882a593Smuzhiyun return -EINVAL;
4693*4882a593Smuzhiyun }
4694*4882a593Smuzhiyun break;
4695*4882a593Smuzhiyun case PACKET3_WRITE_DATA:
4696*4882a593Smuzhiyun if ((idx_value & 0xf00) == 0) {
4697*4882a593Smuzhiyun start_reg = ib[idx + 1] * 4;
4698*4882a593Smuzhiyun if (idx_value & 0x10000) {
4699*4882a593Smuzhiyun if (!si_vm_reg_valid(start_reg))
4700*4882a593Smuzhiyun return -EINVAL;
4701*4882a593Smuzhiyun } else {
4702*4882a593Smuzhiyun for (i = 0; i < (pkt->count - 2); i++) {
4703*4882a593Smuzhiyun reg = start_reg + (4 * i);
4704*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4705*4882a593Smuzhiyun return -EINVAL;
4706*4882a593Smuzhiyun }
4707*4882a593Smuzhiyun }
4708*4882a593Smuzhiyun }
4709*4882a593Smuzhiyun break;
4710*4882a593Smuzhiyun case PACKET3_COND_WRITE:
4711*4882a593Smuzhiyun if (idx_value & 0x100) {
4712*4882a593Smuzhiyun reg = ib[idx + 5] * 4;
4713*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4714*4882a593Smuzhiyun return -EINVAL;
4715*4882a593Smuzhiyun }
4716*4882a593Smuzhiyun break;
4717*4882a593Smuzhiyun case PACKET3_COPY_DW:
4718*4882a593Smuzhiyun if (idx_value & 0x2) {
4719*4882a593Smuzhiyun reg = ib[idx + 3] * 4;
4720*4882a593Smuzhiyun if (!si_vm_reg_valid(reg))
4721*4882a593Smuzhiyun return -EINVAL;
4722*4882a593Smuzhiyun }
4723*4882a593Smuzhiyun break;
4724*4882a593Smuzhiyun case PACKET3_CP_DMA:
4725*4882a593Smuzhiyun r = si_vm_packet3_cp_dma_check(ib, idx);
4726*4882a593Smuzhiyun if (r)
4727*4882a593Smuzhiyun return r;
4728*4882a593Smuzhiyun break;
4729*4882a593Smuzhiyun default:
4730*4882a593Smuzhiyun DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode);
4731*4882a593Smuzhiyun return -EINVAL;
4732*4882a593Smuzhiyun }
4733*4882a593Smuzhiyun return 0;
4734*4882a593Smuzhiyun }
4735*4882a593Smuzhiyun
si_ib_parse(struct radeon_device * rdev,struct radeon_ib * ib)4736*4882a593Smuzhiyun int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
4737*4882a593Smuzhiyun {
4738*4882a593Smuzhiyun int ret = 0;
4739*4882a593Smuzhiyun u32 idx = 0, i;
4740*4882a593Smuzhiyun struct radeon_cs_packet pkt;
4741*4882a593Smuzhiyun
4742*4882a593Smuzhiyun do {
4743*4882a593Smuzhiyun pkt.idx = idx;
4744*4882a593Smuzhiyun pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]);
4745*4882a593Smuzhiyun pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]);
4746*4882a593Smuzhiyun pkt.one_reg_wr = 0;
4747*4882a593Smuzhiyun switch (pkt.type) {
4748*4882a593Smuzhiyun case RADEON_PACKET_TYPE0:
4749*4882a593Smuzhiyun dev_err(rdev->dev, "Packet0 not allowed!\n");
4750*4882a593Smuzhiyun ret = -EINVAL;
4751*4882a593Smuzhiyun break;
4752*4882a593Smuzhiyun case RADEON_PACKET_TYPE2:
4753*4882a593Smuzhiyun idx += 1;
4754*4882a593Smuzhiyun break;
4755*4882a593Smuzhiyun case RADEON_PACKET_TYPE3:
4756*4882a593Smuzhiyun pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
4757*4882a593Smuzhiyun if (ib->is_const_ib)
4758*4882a593Smuzhiyun ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt);
4759*4882a593Smuzhiyun else {
4760*4882a593Smuzhiyun switch (ib->ring) {
4761*4882a593Smuzhiyun case RADEON_RING_TYPE_GFX_INDEX:
4762*4882a593Smuzhiyun ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt);
4763*4882a593Smuzhiyun break;
4764*4882a593Smuzhiyun case CAYMAN_RING_TYPE_CP1_INDEX:
4765*4882a593Smuzhiyun case CAYMAN_RING_TYPE_CP2_INDEX:
4766*4882a593Smuzhiyun ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt);
4767*4882a593Smuzhiyun break;
4768*4882a593Smuzhiyun default:
4769*4882a593Smuzhiyun dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->ring);
4770*4882a593Smuzhiyun ret = -EINVAL;
4771*4882a593Smuzhiyun break;
4772*4882a593Smuzhiyun }
4773*4882a593Smuzhiyun }
4774*4882a593Smuzhiyun idx += pkt.count + 2;
4775*4882a593Smuzhiyun break;
4776*4882a593Smuzhiyun default:
4777*4882a593Smuzhiyun dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
4778*4882a593Smuzhiyun ret = -EINVAL;
4779*4882a593Smuzhiyun break;
4780*4882a593Smuzhiyun }
4781*4882a593Smuzhiyun if (ret) {
4782*4882a593Smuzhiyun for (i = 0; i < ib->length_dw; i++) {
4783*4882a593Smuzhiyun if (i == idx)
4784*4882a593Smuzhiyun printk("\t0x%08x <---\n", ib->ptr[i]);
4785*4882a593Smuzhiyun else
4786*4882a593Smuzhiyun printk("\t0x%08x\n", ib->ptr[i]);
4787*4882a593Smuzhiyun }
4788*4882a593Smuzhiyun break;
4789*4882a593Smuzhiyun }
4790*4882a593Smuzhiyun } while (idx < ib->length_dw);
4791*4882a593Smuzhiyun
4792*4882a593Smuzhiyun return ret;
4793*4882a593Smuzhiyun }
4794*4882a593Smuzhiyun
4795*4882a593Smuzhiyun /*
4796*4882a593Smuzhiyun * vm
4797*4882a593Smuzhiyun */
si_vm_init(struct radeon_device * rdev)4798*4882a593Smuzhiyun int si_vm_init(struct radeon_device *rdev)
4799*4882a593Smuzhiyun {
4800*4882a593Smuzhiyun /* number of VMs */
4801*4882a593Smuzhiyun rdev->vm_manager.nvm = 16;
4802*4882a593Smuzhiyun /* base offset of vram pages */
4803*4882a593Smuzhiyun rdev->vm_manager.vram_base_offset = 0;
4804*4882a593Smuzhiyun
4805*4882a593Smuzhiyun return 0;
4806*4882a593Smuzhiyun }
4807*4882a593Smuzhiyun
si_vm_fini(struct radeon_device * rdev)4808*4882a593Smuzhiyun void si_vm_fini(struct radeon_device *rdev)
4809*4882a593Smuzhiyun {
4810*4882a593Smuzhiyun }
4811*4882a593Smuzhiyun
4812*4882a593Smuzhiyun /**
4813*4882a593Smuzhiyun * si_vm_decode_fault - print human readable fault info
4814*4882a593Smuzhiyun *
4815*4882a593Smuzhiyun * @rdev: radeon_device pointer
4816*4882a593Smuzhiyun * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
4817*4882a593Smuzhiyun * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
4818*4882a593Smuzhiyun *
4819*4882a593Smuzhiyun * Print human readable fault information (SI).
4820*4882a593Smuzhiyun */
si_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr)4821*4882a593Smuzhiyun static void si_vm_decode_fault(struct radeon_device *rdev,
4822*4882a593Smuzhiyun u32 status, u32 addr)
4823*4882a593Smuzhiyun {
4824*4882a593Smuzhiyun u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
4825*4882a593Smuzhiyun u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
4826*4882a593Smuzhiyun u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
4827*4882a593Smuzhiyun char *block;
4828*4882a593Smuzhiyun
4829*4882a593Smuzhiyun if (rdev->family == CHIP_TAHITI) {
4830*4882a593Smuzhiyun switch (mc_id) {
4831*4882a593Smuzhiyun case 160:
4832*4882a593Smuzhiyun case 144:
4833*4882a593Smuzhiyun case 96:
4834*4882a593Smuzhiyun case 80:
4835*4882a593Smuzhiyun case 224:
4836*4882a593Smuzhiyun case 208:
4837*4882a593Smuzhiyun case 32:
4838*4882a593Smuzhiyun case 16:
4839*4882a593Smuzhiyun block = "CB";
4840*4882a593Smuzhiyun break;
4841*4882a593Smuzhiyun case 161:
4842*4882a593Smuzhiyun case 145:
4843*4882a593Smuzhiyun case 97:
4844*4882a593Smuzhiyun case 81:
4845*4882a593Smuzhiyun case 225:
4846*4882a593Smuzhiyun case 209:
4847*4882a593Smuzhiyun case 33:
4848*4882a593Smuzhiyun case 17:
4849*4882a593Smuzhiyun block = "CB_FMASK";
4850*4882a593Smuzhiyun break;
4851*4882a593Smuzhiyun case 162:
4852*4882a593Smuzhiyun case 146:
4853*4882a593Smuzhiyun case 98:
4854*4882a593Smuzhiyun case 82:
4855*4882a593Smuzhiyun case 226:
4856*4882a593Smuzhiyun case 210:
4857*4882a593Smuzhiyun case 34:
4858*4882a593Smuzhiyun case 18:
4859*4882a593Smuzhiyun block = "CB_CMASK";
4860*4882a593Smuzhiyun break;
4861*4882a593Smuzhiyun case 163:
4862*4882a593Smuzhiyun case 147:
4863*4882a593Smuzhiyun case 99:
4864*4882a593Smuzhiyun case 83:
4865*4882a593Smuzhiyun case 227:
4866*4882a593Smuzhiyun case 211:
4867*4882a593Smuzhiyun case 35:
4868*4882a593Smuzhiyun case 19:
4869*4882a593Smuzhiyun block = "CB_IMMED";
4870*4882a593Smuzhiyun break;
4871*4882a593Smuzhiyun case 164:
4872*4882a593Smuzhiyun case 148:
4873*4882a593Smuzhiyun case 100:
4874*4882a593Smuzhiyun case 84:
4875*4882a593Smuzhiyun case 228:
4876*4882a593Smuzhiyun case 212:
4877*4882a593Smuzhiyun case 36:
4878*4882a593Smuzhiyun case 20:
4879*4882a593Smuzhiyun block = "DB";
4880*4882a593Smuzhiyun break;
4881*4882a593Smuzhiyun case 165:
4882*4882a593Smuzhiyun case 149:
4883*4882a593Smuzhiyun case 101:
4884*4882a593Smuzhiyun case 85:
4885*4882a593Smuzhiyun case 229:
4886*4882a593Smuzhiyun case 213:
4887*4882a593Smuzhiyun case 37:
4888*4882a593Smuzhiyun case 21:
4889*4882a593Smuzhiyun block = "DB_HTILE";
4890*4882a593Smuzhiyun break;
4891*4882a593Smuzhiyun case 167:
4892*4882a593Smuzhiyun case 151:
4893*4882a593Smuzhiyun case 103:
4894*4882a593Smuzhiyun case 87:
4895*4882a593Smuzhiyun case 231:
4896*4882a593Smuzhiyun case 215:
4897*4882a593Smuzhiyun case 39:
4898*4882a593Smuzhiyun case 23:
4899*4882a593Smuzhiyun block = "DB_STEN";
4900*4882a593Smuzhiyun break;
4901*4882a593Smuzhiyun case 72:
4902*4882a593Smuzhiyun case 68:
4903*4882a593Smuzhiyun case 64:
4904*4882a593Smuzhiyun case 8:
4905*4882a593Smuzhiyun case 4:
4906*4882a593Smuzhiyun case 0:
4907*4882a593Smuzhiyun case 136:
4908*4882a593Smuzhiyun case 132:
4909*4882a593Smuzhiyun case 128:
4910*4882a593Smuzhiyun case 200:
4911*4882a593Smuzhiyun case 196:
4912*4882a593Smuzhiyun case 192:
4913*4882a593Smuzhiyun block = "TC";
4914*4882a593Smuzhiyun break;
4915*4882a593Smuzhiyun case 112:
4916*4882a593Smuzhiyun case 48:
4917*4882a593Smuzhiyun block = "CP";
4918*4882a593Smuzhiyun break;
4919*4882a593Smuzhiyun case 49:
4920*4882a593Smuzhiyun case 177:
4921*4882a593Smuzhiyun case 50:
4922*4882a593Smuzhiyun case 178:
4923*4882a593Smuzhiyun block = "SH";
4924*4882a593Smuzhiyun break;
4925*4882a593Smuzhiyun case 53:
4926*4882a593Smuzhiyun case 190:
4927*4882a593Smuzhiyun block = "VGT";
4928*4882a593Smuzhiyun break;
4929*4882a593Smuzhiyun case 117:
4930*4882a593Smuzhiyun block = "IH";
4931*4882a593Smuzhiyun break;
4932*4882a593Smuzhiyun case 51:
4933*4882a593Smuzhiyun case 115:
4934*4882a593Smuzhiyun block = "RLC";
4935*4882a593Smuzhiyun break;
4936*4882a593Smuzhiyun case 119:
4937*4882a593Smuzhiyun case 183:
4938*4882a593Smuzhiyun block = "DMA0";
4939*4882a593Smuzhiyun break;
4940*4882a593Smuzhiyun case 61:
4941*4882a593Smuzhiyun block = "DMA1";
4942*4882a593Smuzhiyun break;
4943*4882a593Smuzhiyun case 248:
4944*4882a593Smuzhiyun case 120:
4945*4882a593Smuzhiyun block = "HDP";
4946*4882a593Smuzhiyun break;
4947*4882a593Smuzhiyun default:
4948*4882a593Smuzhiyun block = "unknown";
4949*4882a593Smuzhiyun break;
4950*4882a593Smuzhiyun }
4951*4882a593Smuzhiyun } else {
4952*4882a593Smuzhiyun switch (mc_id) {
4953*4882a593Smuzhiyun case 32:
4954*4882a593Smuzhiyun case 16:
4955*4882a593Smuzhiyun case 96:
4956*4882a593Smuzhiyun case 80:
4957*4882a593Smuzhiyun case 160:
4958*4882a593Smuzhiyun case 144:
4959*4882a593Smuzhiyun case 224:
4960*4882a593Smuzhiyun case 208:
4961*4882a593Smuzhiyun block = "CB";
4962*4882a593Smuzhiyun break;
4963*4882a593Smuzhiyun case 33:
4964*4882a593Smuzhiyun case 17:
4965*4882a593Smuzhiyun case 97:
4966*4882a593Smuzhiyun case 81:
4967*4882a593Smuzhiyun case 161:
4968*4882a593Smuzhiyun case 145:
4969*4882a593Smuzhiyun case 225:
4970*4882a593Smuzhiyun case 209:
4971*4882a593Smuzhiyun block = "CB_FMASK";
4972*4882a593Smuzhiyun break;
4973*4882a593Smuzhiyun case 34:
4974*4882a593Smuzhiyun case 18:
4975*4882a593Smuzhiyun case 98:
4976*4882a593Smuzhiyun case 82:
4977*4882a593Smuzhiyun case 162:
4978*4882a593Smuzhiyun case 146:
4979*4882a593Smuzhiyun case 226:
4980*4882a593Smuzhiyun case 210:
4981*4882a593Smuzhiyun block = "CB_CMASK";
4982*4882a593Smuzhiyun break;
4983*4882a593Smuzhiyun case 35:
4984*4882a593Smuzhiyun case 19:
4985*4882a593Smuzhiyun case 99:
4986*4882a593Smuzhiyun case 83:
4987*4882a593Smuzhiyun case 163:
4988*4882a593Smuzhiyun case 147:
4989*4882a593Smuzhiyun case 227:
4990*4882a593Smuzhiyun case 211:
4991*4882a593Smuzhiyun block = "CB_IMMED";
4992*4882a593Smuzhiyun break;
4993*4882a593Smuzhiyun case 36:
4994*4882a593Smuzhiyun case 20:
4995*4882a593Smuzhiyun case 100:
4996*4882a593Smuzhiyun case 84:
4997*4882a593Smuzhiyun case 164:
4998*4882a593Smuzhiyun case 148:
4999*4882a593Smuzhiyun case 228:
5000*4882a593Smuzhiyun case 212:
5001*4882a593Smuzhiyun block = "DB";
5002*4882a593Smuzhiyun break;
5003*4882a593Smuzhiyun case 37:
5004*4882a593Smuzhiyun case 21:
5005*4882a593Smuzhiyun case 101:
5006*4882a593Smuzhiyun case 85:
5007*4882a593Smuzhiyun case 165:
5008*4882a593Smuzhiyun case 149:
5009*4882a593Smuzhiyun case 229:
5010*4882a593Smuzhiyun case 213:
5011*4882a593Smuzhiyun block = "DB_HTILE";
5012*4882a593Smuzhiyun break;
5013*4882a593Smuzhiyun case 39:
5014*4882a593Smuzhiyun case 23:
5015*4882a593Smuzhiyun case 103:
5016*4882a593Smuzhiyun case 87:
5017*4882a593Smuzhiyun case 167:
5018*4882a593Smuzhiyun case 151:
5019*4882a593Smuzhiyun case 231:
5020*4882a593Smuzhiyun case 215:
5021*4882a593Smuzhiyun block = "DB_STEN";
5022*4882a593Smuzhiyun break;
5023*4882a593Smuzhiyun case 72:
5024*4882a593Smuzhiyun case 68:
5025*4882a593Smuzhiyun case 8:
5026*4882a593Smuzhiyun case 4:
5027*4882a593Smuzhiyun case 136:
5028*4882a593Smuzhiyun case 132:
5029*4882a593Smuzhiyun case 200:
5030*4882a593Smuzhiyun case 196:
5031*4882a593Smuzhiyun block = "TC";
5032*4882a593Smuzhiyun break;
5033*4882a593Smuzhiyun case 112:
5034*4882a593Smuzhiyun case 48:
5035*4882a593Smuzhiyun block = "CP";
5036*4882a593Smuzhiyun break;
5037*4882a593Smuzhiyun case 49:
5038*4882a593Smuzhiyun case 177:
5039*4882a593Smuzhiyun case 50:
5040*4882a593Smuzhiyun case 178:
5041*4882a593Smuzhiyun block = "SH";
5042*4882a593Smuzhiyun break;
5043*4882a593Smuzhiyun case 53:
5044*4882a593Smuzhiyun block = "VGT";
5045*4882a593Smuzhiyun break;
5046*4882a593Smuzhiyun case 117:
5047*4882a593Smuzhiyun block = "IH";
5048*4882a593Smuzhiyun break;
5049*4882a593Smuzhiyun case 51:
5050*4882a593Smuzhiyun case 115:
5051*4882a593Smuzhiyun block = "RLC";
5052*4882a593Smuzhiyun break;
5053*4882a593Smuzhiyun case 119:
5054*4882a593Smuzhiyun case 183:
5055*4882a593Smuzhiyun block = "DMA0";
5056*4882a593Smuzhiyun break;
5057*4882a593Smuzhiyun case 61:
5058*4882a593Smuzhiyun block = "DMA1";
5059*4882a593Smuzhiyun break;
5060*4882a593Smuzhiyun case 248:
5061*4882a593Smuzhiyun case 120:
5062*4882a593Smuzhiyun block = "HDP";
5063*4882a593Smuzhiyun break;
5064*4882a593Smuzhiyun default:
5065*4882a593Smuzhiyun block = "unknown";
5066*4882a593Smuzhiyun break;
5067*4882a593Smuzhiyun }
5068*4882a593Smuzhiyun }
5069*4882a593Smuzhiyun
5070*4882a593Smuzhiyun printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
5071*4882a593Smuzhiyun protections, vmid, addr,
5072*4882a593Smuzhiyun (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
5073*4882a593Smuzhiyun block, mc_id);
5074*4882a593Smuzhiyun }
5075*4882a593Smuzhiyun
si_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)5076*4882a593Smuzhiyun void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
5077*4882a593Smuzhiyun unsigned vm_id, uint64_t pd_addr)
5078*4882a593Smuzhiyun {
5079*4882a593Smuzhiyun /* write new base address */
5080*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5081*4882a593Smuzhiyun radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5082*4882a593Smuzhiyun WRITE_DATA_DST_SEL(0)));
5083*4882a593Smuzhiyun
5084*4882a593Smuzhiyun if (vm_id < 8) {
5085*4882a593Smuzhiyun radeon_ring_write(ring,
5086*4882a593Smuzhiyun (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2);
5087*4882a593Smuzhiyun } else {
5088*4882a593Smuzhiyun radeon_ring_write(ring,
5089*4882a593Smuzhiyun (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2);
5090*4882a593Smuzhiyun }
5091*4882a593Smuzhiyun radeon_ring_write(ring, 0);
5092*4882a593Smuzhiyun radeon_ring_write(ring, pd_addr >> 12);
5093*4882a593Smuzhiyun
5094*4882a593Smuzhiyun /* flush hdp cache */
5095*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5096*4882a593Smuzhiyun radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5097*4882a593Smuzhiyun WRITE_DATA_DST_SEL(0)));
5098*4882a593Smuzhiyun radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
5099*4882a593Smuzhiyun radeon_ring_write(ring, 0);
5100*4882a593Smuzhiyun radeon_ring_write(ring, 0x1);
5101*4882a593Smuzhiyun
5102*4882a593Smuzhiyun /* bits 0-15 are the VM contexts0-15 */
5103*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5104*4882a593Smuzhiyun radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5105*4882a593Smuzhiyun WRITE_DATA_DST_SEL(0)));
5106*4882a593Smuzhiyun radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
5107*4882a593Smuzhiyun radeon_ring_write(ring, 0);
5108*4882a593Smuzhiyun radeon_ring_write(ring, 1 << vm_id);
5109*4882a593Smuzhiyun
5110*4882a593Smuzhiyun /* wait for the invalidate to complete */
5111*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
5112*4882a593Smuzhiyun radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */
5113*4882a593Smuzhiyun WAIT_REG_MEM_ENGINE(0))); /* me */
5114*4882a593Smuzhiyun radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
5115*4882a593Smuzhiyun radeon_ring_write(ring, 0);
5116*4882a593Smuzhiyun radeon_ring_write(ring, 0); /* ref */
5117*4882a593Smuzhiyun radeon_ring_write(ring, 0); /* mask */
5118*4882a593Smuzhiyun radeon_ring_write(ring, 0x20); /* poll interval */
5119*4882a593Smuzhiyun
5120*4882a593Smuzhiyun /* sync PFP to ME, otherwise we might get invalid PFP reads */
5121*4882a593Smuzhiyun radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
5122*4882a593Smuzhiyun radeon_ring_write(ring, 0x0);
5123*4882a593Smuzhiyun }
5124*4882a593Smuzhiyun
5125*4882a593Smuzhiyun /*
5126*4882a593Smuzhiyun * Power and clock gating
5127*4882a593Smuzhiyun */
si_wait_for_rlc_serdes(struct radeon_device * rdev)5128*4882a593Smuzhiyun static void si_wait_for_rlc_serdes(struct radeon_device *rdev)
5129*4882a593Smuzhiyun {
5130*4882a593Smuzhiyun int i;
5131*4882a593Smuzhiyun
5132*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
5133*4882a593Smuzhiyun if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0)
5134*4882a593Smuzhiyun break;
5135*4882a593Smuzhiyun udelay(1);
5136*4882a593Smuzhiyun }
5137*4882a593Smuzhiyun
5138*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
5139*4882a593Smuzhiyun if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0)
5140*4882a593Smuzhiyun break;
5141*4882a593Smuzhiyun udelay(1);
5142*4882a593Smuzhiyun }
5143*4882a593Smuzhiyun }
5144*4882a593Smuzhiyun
si_enable_gui_idle_interrupt(struct radeon_device * rdev,bool enable)5145*4882a593Smuzhiyun static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
5146*4882a593Smuzhiyun bool enable)
5147*4882a593Smuzhiyun {
5148*4882a593Smuzhiyun u32 tmp = RREG32(CP_INT_CNTL_RING0);
5149*4882a593Smuzhiyun u32 mask;
5150*4882a593Smuzhiyun int i;
5151*4882a593Smuzhiyun
5152*4882a593Smuzhiyun if (enable)
5153*4882a593Smuzhiyun tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
5154*4882a593Smuzhiyun else
5155*4882a593Smuzhiyun tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
5156*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING0, tmp);
5157*4882a593Smuzhiyun
5158*4882a593Smuzhiyun if (!enable) {
5159*4882a593Smuzhiyun /* read a gfx register */
5160*4882a593Smuzhiyun tmp = RREG32(DB_DEPTH_INFO);
5161*4882a593Smuzhiyun
5162*4882a593Smuzhiyun mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS;
5163*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
5164*4882a593Smuzhiyun if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS))
5165*4882a593Smuzhiyun break;
5166*4882a593Smuzhiyun udelay(1);
5167*4882a593Smuzhiyun }
5168*4882a593Smuzhiyun }
5169*4882a593Smuzhiyun }
5170*4882a593Smuzhiyun
si_set_uvd_dcm(struct radeon_device * rdev,bool sw_mode)5171*4882a593Smuzhiyun static void si_set_uvd_dcm(struct radeon_device *rdev,
5172*4882a593Smuzhiyun bool sw_mode)
5173*4882a593Smuzhiyun {
5174*4882a593Smuzhiyun u32 tmp, tmp2;
5175*4882a593Smuzhiyun
5176*4882a593Smuzhiyun tmp = RREG32(UVD_CGC_CTRL);
5177*4882a593Smuzhiyun tmp &= ~(CLK_OD_MASK | CG_DT_MASK);
5178*4882a593Smuzhiyun tmp |= DCM | CG_DT(1) | CLK_OD(4);
5179*4882a593Smuzhiyun
5180*4882a593Smuzhiyun if (sw_mode) {
5181*4882a593Smuzhiyun tmp &= ~0x7ffff800;
5182*4882a593Smuzhiyun tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7);
5183*4882a593Smuzhiyun } else {
5184*4882a593Smuzhiyun tmp |= 0x7ffff800;
5185*4882a593Smuzhiyun tmp2 = 0;
5186*4882a593Smuzhiyun }
5187*4882a593Smuzhiyun
5188*4882a593Smuzhiyun WREG32(UVD_CGC_CTRL, tmp);
5189*4882a593Smuzhiyun WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2);
5190*4882a593Smuzhiyun }
5191*4882a593Smuzhiyun
si_init_uvd_internal_cg(struct radeon_device * rdev)5192*4882a593Smuzhiyun void si_init_uvd_internal_cg(struct radeon_device *rdev)
5193*4882a593Smuzhiyun {
5194*4882a593Smuzhiyun bool hw_mode = true;
5195*4882a593Smuzhiyun
5196*4882a593Smuzhiyun if (hw_mode) {
5197*4882a593Smuzhiyun si_set_uvd_dcm(rdev, false);
5198*4882a593Smuzhiyun } else {
5199*4882a593Smuzhiyun u32 tmp = RREG32(UVD_CGC_CTRL);
5200*4882a593Smuzhiyun tmp &= ~DCM;
5201*4882a593Smuzhiyun WREG32(UVD_CGC_CTRL, tmp);
5202*4882a593Smuzhiyun }
5203*4882a593Smuzhiyun }
5204*4882a593Smuzhiyun
si_halt_rlc(struct radeon_device * rdev)5205*4882a593Smuzhiyun static u32 si_halt_rlc(struct radeon_device *rdev)
5206*4882a593Smuzhiyun {
5207*4882a593Smuzhiyun u32 data, orig;
5208*4882a593Smuzhiyun
5209*4882a593Smuzhiyun orig = data = RREG32(RLC_CNTL);
5210*4882a593Smuzhiyun
5211*4882a593Smuzhiyun if (data & RLC_ENABLE) {
5212*4882a593Smuzhiyun data &= ~RLC_ENABLE;
5213*4882a593Smuzhiyun WREG32(RLC_CNTL, data);
5214*4882a593Smuzhiyun
5215*4882a593Smuzhiyun si_wait_for_rlc_serdes(rdev);
5216*4882a593Smuzhiyun }
5217*4882a593Smuzhiyun
5218*4882a593Smuzhiyun return orig;
5219*4882a593Smuzhiyun }
5220*4882a593Smuzhiyun
si_update_rlc(struct radeon_device * rdev,u32 rlc)5221*4882a593Smuzhiyun static void si_update_rlc(struct radeon_device *rdev, u32 rlc)
5222*4882a593Smuzhiyun {
5223*4882a593Smuzhiyun u32 tmp;
5224*4882a593Smuzhiyun
5225*4882a593Smuzhiyun tmp = RREG32(RLC_CNTL);
5226*4882a593Smuzhiyun if (tmp != rlc)
5227*4882a593Smuzhiyun WREG32(RLC_CNTL, rlc);
5228*4882a593Smuzhiyun }
5229*4882a593Smuzhiyun
si_enable_dma_pg(struct radeon_device * rdev,bool enable)5230*4882a593Smuzhiyun static void si_enable_dma_pg(struct radeon_device *rdev, bool enable)
5231*4882a593Smuzhiyun {
5232*4882a593Smuzhiyun u32 data, orig;
5233*4882a593Smuzhiyun
5234*4882a593Smuzhiyun orig = data = RREG32(DMA_PG);
5235*4882a593Smuzhiyun if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA))
5236*4882a593Smuzhiyun data |= PG_CNTL_ENABLE;
5237*4882a593Smuzhiyun else
5238*4882a593Smuzhiyun data &= ~PG_CNTL_ENABLE;
5239*4882a593Smuzhiyun if (orig != data)
5240*4882a593Smuzhiyun WREG32(DMA_PG, data);
5241*4882a593Smuzhiyun }
5242*4882a593Smuzhiyun
si_init_dma_pg(struct radeon_device * rdev)5243*4882a593Smuzhiyun static void si_init_dma_pg(struct radeon_device *rdev)
5244*4882a593Smuzhiyun {
5245*4882a593Smuzhiyun u32 tmp;
5246*4882a593Smuzhiyun
5247*4882a593Smuzhiyun WREG32(DMA_PGFSM_WRITE, 0x00002000);
5248*4882a593Smuzhiyun WREG32(DMA_PGFSM_CONFIG, 0x100010ff);
5249*4882a593Smuzhiyun
5250*4882a593Smuzhiyun for (tmp = 0; tmp < 5; tmp++)
5251*4882a593Smuzhiyun WREG32(DMA_PGFSM_WRITE, 0);
5252*4882a593Smuzhiyun }
5253*4882a593Smuzhiyun
si_enable_gfx_cgpg(struct radeon_device * rdev,bool enable)5254*4882a593Smuzhiyun static void si_enable_gfx_cgpg(struct radeon_device *rdev,
5255*4882a593Smuzhiyun bool enable)
5256*4882a593Smuzhiyun {
5257*4882a593Smuzhiyun u32 tmp;
5258*4882a593Smuzhiyun
5259*4882a593Smuzhiyun if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) {
5260*4882a593Smuzhiyun tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);
5261*4882a593Smuzhiyun WREG32(RLC_TTOP_D, tmp);
5262*4882a593Smuzhiyun
5263*4882a593Smuzhiyun tmp = RREG32(RLC_PG_CNTL);
5264*4882a593Smuzhiyun tmp |= GFX_PG_ENABLE;
5265*4882a593Smuzhiyun WREG32(RLC_PG_CNTL, tmp);
5266*4882a593Smuzhiyun
5267*4882a593Smuzhiyun tmp = RREG32(RLC_AUTO_PG_CTRL);
5268*4882a593Smuzhiyun tmp |= AUTO_PG_EN;
5269*4882a593Smuzhiyun WREG32(RLC_AUTO_PG_CTRL, tmp);
5270*4882a593Smuzhiyun } else {
5271*4882a593Smuzhiyun tmp = RREG32(RLC_AUTO_PG_CTRL);
5272*4882a593Smuzhiyun tmp &= ~AUTO_PG_EN;
5273*4882a593Smuzhiyun WREG32(RLC_AUTO_PG_CTRL, tmp);
5274*4882a593Smuzhiyun
5275*4882a593Smuzhiyun tmp = RREG32(DB_RENDER_CONTROL);
5276*4882a593Smuzhiyun }
5277*4882a593Smuzhiyun }
5278*4882a593Smuzhiyun
si_init_gfx_cgpg(struct radeon_device * rdev)5279*4882a593Smuzhiyun static void si_init_gfx_cgpg(struct radeon_device *rdev)
5280*4882a593Smuzhiyun {
5281*4882a593Smuzhiyun u32 tmp;
5282*4882a593Smuzhiyun
5283*4882a593Smuzhiyun WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
5284*4882a593Smuzhiyun
5285*4882a593Smuzhiyun tmp = RREG32(RLC_PG_CNTL);
5286*4882a593Smuzhiyun tmp |= GFX_PG_SRC;
5287*4882a593Smuzhiyun WREG32(RLC_PG_CNTL, tmp);
5288*4882a593Smuzhiyun
5289*4882a593Smuzhiyun WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
5290*4882a593Smuzhiyun
5291*4882a593Smuzhiyun tmp = RREG32(RLC_AUTO_PG_CTRL);
5292*4882a593Smuzhiyun
5293*4882a593Smuzhiyun tmp &= ~GRBM_REG_SGIT_MASK;
5294*4882a593Smuzhiyun tmp |= GRBM_REG_SGIT(0x700);
5295*4882a593Smuzhiyun tmp &= ~PG_AFTER_GRBM_REG_ST_MASK;
5296*4882a593Smuzhiyun WREG32(RLC_AUTO_PG_CTRL, tmp);
5297*4882a593Smuzhiyun }
5298*4882a593Smuzhiyun
si_get_cu_active_bitmap(struct radeon_device * rdev,u32 se,u32 sh)5299*4882a593Smuzhiyun static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh)
5300*4882a593Smuzhiyun {
5301*4882a593Smuzhiyun u32 mask = 0, tmp, tmp1;
5302*4882a593Smuzhiyun int i;
5303*4882a593Smuzhiyun
5304*4882a593Smuzhiyun si_select_se_sh(rdev, se, sh);
5305*4882a593Smuzhiyun tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
5306*4882a593Smuzhiyun tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
5307*4882a593Smuzhiyun si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
5308*4882a593Smuzhiyun
5309*4882a593Smuzhiyun tmp &= 0xffff0000;
5310*4882a593Smuzhiyun
5311*4882a593Smuzhiyun tmp |= tmp1;
5312*4882a593Smuzhiyun tmp >>= 16;
5313*4882a593Smuzhiyun
5314*4882a593Smuzhiyun for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) {
5315*4882a593Smuzhiyun mask <<= 1;
5316*4882a593Smuzhiyun mask |= 1;
5317*4882a593Smuzhiyun }
5318*4882a593Smuzhiyun
5319*4882a593Smuzhiyun return (~tmp) & mask;
5320*4882a593Smuzhiyun }
5321*4882a593Smuzhiyun
si_init_ao_cu_mask(struct radeon_device * rdev)5322*4882a593Smuzhiyun static void si_init_ao_cu_mask(struct radeon_device *rdev)
5323*4882a593Smuzhiyun {
5324*4882a593Smuzhiyun u32 i, j, k, active_cu_number = 0;
5325*4882a593Smuzhiyun u32 mask, counter, cu_bitmap;
5326*4882a593Smuzhiyun u32 tmp = 0;
5327*4882a593Smuzhiyun
5328*4882a593Smuzhiyun for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
5329*4882a593Smuzhiyun for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
5330*4882a593Smuzhiyun mask = 1;
5331*4882a593Smuzhiyun cu_bitmap = 0;
5332*4882a593Smuzhiyun counter = 0;
5333*4882a593Smuzhiyun for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) {
5334*4882a593Smuzhiyun if (si_get_cu_active_bitmap(rdev, i, j) & mask) {
5335*4882a593Smuzhiyun if (counter < 2)
5336*4882a593Smuzhiyun cu_bitmap |= mask;
5337*4882a593Smuzhiyun counter++;
5338*4882a593Smuzhiyun }
5339*4882a593Smuzhiyun mask <<= 1;
5340*4882a593Smuzhiyun }
5341*4882a593Smuzhiyun
5342*4882a593Smuzhiyun active_cu_number += counter;
5343*4882a593Smuzhiyun tmp |= (cu_bitmap << (i * 16 + j * 8));
5344*4882a593Smuzhiyun }
5345*4882a593Smuzhiyun }
5346*4882a593Smuzhiyun
5347*4882a593Smuzhiyun WREG32(RLC_PG_AO_CU_MASK, tmp);
5348*4882a593Smuzhiyun
5349*4882a593Smuzhiyun tmp = RREG32(RLC_MAX_PG_CU);
5350*4882a593Smuzhiyun tmp &= ~MAX_PU_CU_MASK;
5351*4882a593Smuzhiyun tmp |= MAX_PU_CU(active_cu_number);
5352*4882a593Smuzhiyun WREG32(RLC_MAX_PG_CU, tmp);
5353*4882a593Smuzhiyun }
5354*4882a593Smuzhiyun
si_enable_cgcg(struct radeon_device * rdev,bool enable)5355*4882a593Smuzhiyun static void si_enable_cgcg(struct radeon_device *rdev,
5356*4882a593Smuzhiyun bool enable)
5357*4882a593Smuzhiyun {
5358*4882a593Smuzhiyun u32 data, orig, tmp;
5359*4882a593Smuzhiyun
5360*4882a593Smuzhiyun orig = data = RREG32(RLC_CGCG_CGLS_CTRL);
5361*4882a593Smuzhiyun
5362*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) {
5363*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, true);
5364*4882a593Smuzhiyun
5365*4882a593Smuzhiyun WREG32(RLC_GCPM_GENERAL_3, 0x00000080);
5366*4882a593Smuzhiyun
5367*4882a593Smuzhiyun tmp = si_halt_rlc(rdev);
5368*4882a593Smuzhiyun
5369*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
5370*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
5371*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff);
5372*4882a593Smuzhiyun
5373*4882a593Smuzhiyun si_wait_for_rlc_serdes(rdev);
5374*4882a593Smuzhiyun
5375*4882a593Smuzhiyun si_update_rlc(rdev, tmp);
5376*4882a593Smuzhiyun
5377*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_CTRL, 0x007000ff);
5378*4882a593Smuzhiyun
5379*4882a593Smuzhiyun data |= CGCG_EN | CGLS_EN;
5380*4882a593Smuzhiyun } else {
5381*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, false);
5382*4882a593Smuzhiyun
5383*4882a593Smuzhiyun RREG32(CB_CGTT_SCLK_CTRL);
5384*4882a593Smuzhiyun RREG32(CB_CGTT_SCLK_CTRL);
5385*4882a593Smuzhiyun RREG32(CB_CGTT_SCLK_CTRL);
5386*4882a593Smuzhiyun RREG32(CB_CGTT_SCLK_CTRL);
5387*4882a593Smuzhiyun
5388*4882a593Smuzhiyun data &= ~(CGCG_EN | CGLS_EN);
5389*4882a593Smuzhiyun }
5390*4882a593Smuzhiyun
5391*4882a593Smuzhiyun if (orig != data)
5392*4882a593Smuzhiyun WREG32(RLC_CGCG_CGLS_CTRL, data);
5393*4882a593Smuzhiyun }
5394*4882a593Smuzhiyun
si_enable_mgcg(struct radeon_device * rdev,bool enable)5395*4882a593Smuzhiyun static void si_enable_mgcg(struct radeon_device *rdev,
5396*4882a593Smuzhiyun bool enable)
5397*4882a593Smuzhiyun {
5398*4882a593Smuzhiyun u32 data, orig, tmp = 0;
5399*4882a593Smuzhiyun
5400*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) {
5401*4882a593Smuzhiyun orig = data = RREG32(CGTS_SM_CTRL_REG);
5402*4882a593Smuzhiyun data = 0x96940200;
5403*4882a593Smuzhiyun if (orig != data)
5404*4882a593Smuzhiyun WREG32(CGTS_SM_CTRL_REG, data);
5405*4882a593Smuzhiyun
5406*4882a593Smuzhiyun if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) {
5407*4882a593Smuzhiyun orig = data = RREG32(CP_MEM_SLP_CNTL);
5408*4882a593Smuzhiyun data |= CP_MEM_LS_EN;
5409*4882a593Smuzhiyun if (orig != data)
5410*4882a593Smuzhiyun WREG32(CP_MEM_SLP_CNTL, data);
5411*4882a593Smuzhiyun }
5412*4882a593Smuzhiyun
5413*4882a593Smuzhiyun orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
5414*4882a593Smuzhiyun data &= 0xffffffc0;
5415*4882a593Smuzhiyun if (orig != data)
5416*4882a593Smuzhiyun WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
5417*4882a593Smuzhiyun
5418*4882a593Smuzhiyun tmp = si_halt_rlc(rdev);
5419*4882a593Smuzhiyun
5420*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
5421*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
5422*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff);
5423*4882a593Smuzhiyun
5424*4882a593Smuzhiyun si_update_rlc(rdev, tmp);
5425*4882a593Smuzhiyun } else {
5426*4882a593Smuzhiyun orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
5427*4882a593Smuzhiyun data |= 0x00000003;
5428*4882a593Smuzhiyun if (orig != data)
5429*4882a593Smuzhiyun WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
5430*4882a593Smuzhiyun
5431*4882a593Smuzhiyun data = RREG32(CP_MEM_SLP_CNTL);
5432*4882a593Smuzhiyun if (data & CP_MEM_LS_EN) {
5433*4882a593Smuzhiyun data &= ~CP_MEM_LS_EN;
5434*4882a593Smuzhiyun WREG32(CP_MEM_SLP_CNTL, data);
5435*4882a593Smuzhiyun }
5436*4882a593Smuzhiyun orig = data = RREG32(CGTS_SM_CTRL_REG);
5437*4882a593Smuzhiyun data |= LS_OVERRIDE | OVERRIDE;
5438*4882a593Smuzhiyun if (orig != data)
5439*4882a593Smuzhiyun WREG32(CGTS_SM_CTRL_REG, data);
5440*4882a593Smuzhiyun
5441*4882a593Smuzhiyun tmp = si_halt_rlc(rdev);
5442*4882a593Smuzhiyun
5443*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
5444*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
5445*4882a593Smuzhiyun WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff);
5446*4882a593Smuzhiyun
5447*4882a593Smuzhiyun si_update_rlc(rdev, tmp);
5448*4882a593Smuzhiyun }
5449*4882a593Smuzhiyun }
5450*4882a593Smuzhiyun
si_enable_uvd_mgcg(struct radeon_device * rdev,bool enable)5451*4882a593Smuzhiyun static void si_enable_uvd_mgcg(struct radeon_device *rdev,
5452*4882a593Smuzhiyun bool enable)
5453*4882a593Smuzhiyun {
5454*4882a593Smuzhiyun u32 orig, data, tmp;
5455*4882a593Smuzhiyun
5456*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) {
5457*4882a593Smuzhiyun tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
5458*4882a593Smuzhiyun tmp |= 0x3fff;
5459*4882a593Smuzhiyun WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
5460*4882a593Smuzhiyun
5461*4882a593Smuzhiyun orig = data = RREG32(UVD_CGC_CTRL);
5462*4882a593Smuzhiyun data |= DCM;
5463*4882a593Smuzhiyun if (orig != data)
5464*4882a593Smuzhiyun WREG32(UVD_CGC_CTRL, data);
5465*4882a593Smuzhiyun
5466*4882a593Smuzhiyun WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0);
5467*4882a593Smuzhiyun WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0);
5468*4882a593Smuzhiyun } else {
5469*4882a593Smuzhiyun tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
5470*4882a593Smuzhiyun tmp &= ~0x3fff;
5471*4882a593Smuzhiyun WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
5472*4882a593Smuzhiyun
5473*4882a593Smuzhiyun orig = data = RREG32(UVD_CGC_CTRL);
5474*4882a593Smuzhiyun data &= ~DCM;
5475*4882a593Smuzhiyun if (orig != data)
5476*4882a593Smuzhiyun WREG32(UVD_CGC_CTRL, data);
5477*4882a593Smuzhiyun
5478*4882a593Smuzhiyun WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff);
5479*4882a593Smuzhiyun WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff);
5480*4882a593Smuzhiyun }
5481*4882a593Smuzhiyun }
5482*4882a593Smuzhiyun
5483*4882a593Smuzhiyun static const u32 mc_cg_registers[] =
5484*4882a593Smuzhiyun {
5485*4882a593Smuzhiyun MC_HUB_MISC_HUB_CG,
5486*4882a593Smuzhiyun MC_HUB_MISC_SIP_CG,
5487*4882a593Smuzhiyun MC_HUB_MISC_VM_CG,
5488*4882a593Smuzhiyun MC_XPB_CLK_GAT,
5489*4882a593Smuzhiyun ATC_MISC_CG,
5490*4882a593Smuzhiyun MC_CITF_MISC_WR_CG,
5491*4882a593Smuzhiyun MC_CITF_MISC_RD_CG,
5492*4882a593Smuzhiyun MC_CITF_MISC_VM_CG,
5493*4882a593Smuzhiyun VM_L2_CG,
5494*4882a593Smuzhiyun };
5495*4882a593Smuzhiyun
si_enable_mc_ls(struct radeon_device * rdev,bool enable)5496*4882a593Smuzhiyun static void si_enable_mc_ls(struct radeon_device *rdev,
5497*4882a593Smuzhiyun bool enable)
5498*4882a593Smuzhiyun {
5499*4882a593Smuzhiyun int i;
5500*4882a593Smuzhiyun u32 orig, data;
5501*4882a593Smuzhiyun
5502*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
5503*4882a593Smuzhiyun orig = data = RREG32(mc_cg_registers[i]);
5504*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
5505*4882a593Smuzhiyun data |= MC_LS_ENABLE;
5506*4882a593Smuzhiyun else
5507*4882a593Smuzhiyun data &= ~MC_LS_ENABLE;
5508*4882a593Smuzhiyun if (data != orig)
5509*4882a593Smuzhiyun WREG32(mc_cg_registers[i], data);
5510*4882a593Smuzhiyun }
5511*4882a593Smuzhiyun }
5512*4882a593Smuzhiyun
si_enable_mc_mgcg(struct radeon_device * rdev,bool enable)5513*4882a593Smuzhiyun static void si_enable_mc_mgcg(struct radeon_device *rdev,
5514*4882a593Smuzhiyun bool enable)
5515*4882a593Smuzhiyun {
5516*4882a593Smuzhiyun int i;
5517*4882a593Smuzhiyun u32 orig, data;
5518*4882a593Smuzhiyun
5519*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
5520*4882a593Smuzhiyun orig = data = RREG32(mc_cg_registers[i]);
5521*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG))
5522*4882a593Smuzhiyun data |= MC_CG_ENABLE;
5523*4882a593Smuzhiyun else
5524*4882a593Smuzhiyun data &= ~MC_CG_ENABLE;
5525*4882a593Smuzhiyun if (data != orig)
5526*4882a593Smuzhiyun WREG32(mc_cg_registers[i], data);
5527*4882a593Smuzhiyun }
5528*4882a593Smuzhiyun }
5529*4882a593Smuzhiyun
si_enable_dma_mgcg(struct radeon_device * rdev,bool enable)5530*4882a593Smuzhiyun static void si_enable_dma_mgcg(struct radeon_device *rdev,
5531*4882a593Smuzhiyun bool enable)
5532*4882a593Smuzhiyun {
5533*4882a593Smuzhiyun u32 orig, data, offset;
5534*4882a593Smuzhiyun int i;
5535*4882a593Smuzhiyun
5536*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) {
5537*4882a593Smuzhiyun for (i = 0; i < 2; i++) {
5538*4882a593Smuzhiyun if (i == 0)
5539*4882a593Smuzhiyun offset = DMA0_REGISTER_OFFSET;
5540*4882a593Smuzhiyun else
5541*4882a593Smuzhiyun offset = DMA1_REGISTER_OFFSET;
5542*4882a593Smuzhiyun orig = data = RREG32(DMA_POWER_CNTL + offset);
5543*4882a593Smuzhiyun data &= ~MEM_POWER_OVERRIDE;
5544*4882a593Smuzhiyun if (data != orig)
5545*4882a593Smuzhiyun WREG32(DMA_POWER_CNTL + offset, data);
5546*4882a593Smuzhiyun WREG32(DMA_CLK_CTRL + offset, 0x00000100);
5547*4882a593Smuzhiyun }
5548*4882a593Smuzhiyun } else {
5549*4882a593Smuzhiyun for (i = 0; i < 2; i++) {
5550*4882a593Smuzhiyun if (i == 0)
5551*4882a593Smuzhiyun offset = DMA0_REGISTER_OFFSET;
5552*4882a593Smuzhiyun else
5553*4882a593Smuzhiyun offset = DMA1_REGISTER_OFFSET;
5554*4882a593Smuzhiyun orig = data = RREG32(DMA_POWER_CNTL + offset);
5555*4882a593Smuzhiyun data |= MEM_POWER_OVERRIDE;
5556*4882a593Smuzhiyun if (data != orig)
5557*4882a593Smuzhiyun WREG32(DMA_POWER_CNTL + offset, data);
5558*4882a593Smuzhiyun
5559*4882a593Smuzhiyun orig = data = RREG32(DMA_CLK_CTRL + offset);
5560*4882a593Smuzhiyun data = 0xff000000;
5561*4882a593Smuzhiyun if (data != orig)
5562*4882a593Smuzhiyun WREG32(DMA_CLK_CTRL + offset, data);
5563*4882a593Smuzhiyun }
5564*4882a593Smuzhiyun }
5565*4882a593Smuzhiyun }
5566*4882a593Smuzhiyun
si_enable_bif_mgls(struct radeon_device * rdev,bool enable)5567*4882a593Smuzhiyun static void si_enable_bif_mgls(struct radeon_device *rdev,
5568*4882a593Smuzhiyun bool enable)
5569*4882a593Smuzhiyun {
5570*4882a593Smuzhiyun u32 orig, data;
5571*4882a593Smuzhiyun
5572*4882a593Smuzhiyun orig = data = RREG32_PCIE(PCIE_CNTL2);
5573*4882a593Smuzhiyun
5574*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS))
5575*4882a593Smuzhiyun data |= SLV_MEM_LS_EN | MST_MEM_LS_EN |
5576*4882a593Smuzhiyun REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN;
5577*4882a593Smuzhiyun else
5578*4882a593Smuzhiyun data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN |
5579*4882a593Smuzhiyun REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN);
5580*4882a593Smuzhiyun
5581*4882a593Smuzhiyun if (orig != data)
5582*4882a593Smuzhiyun WREG32_PCIE(PCIE_CNTL2, data);
5583*4882a593Smuzhiyun }
5584*4882a593Smuzhiyun
si_enable_hdp_mgcg(struct radeon_device * rdev,bool enable)5585*4882a593Smuzhiyun static void si_enable_hdp_mgcg(struct radeon_device *rdev,
5586*4882a593Smuzhiyun bool enable)
5587*4882a593Smuzhiyun {
5588*4882a593Smuzhiyun u32 orig, data;
5589*4882a593Smuzhiyun
5590*4882a593Smuzhiyun orig = data = RREG32(HDP_HOST_PATH_CNTL);
5591*4882a593Smuzhiyun
5592*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG))
5593*4882a593Smuzhiyun data &= ~CLOCK_GATING_DIS;
5594*4882a593Smuzhiyun else
5595*4882a593Smuzhiyun data |= CLOCK_GATING_DIS;
5596*4882a593Smuzhiyun
5597*4882a593Smuzhiyun if (orig != data)
5598*4882a593Smuzhiyun WREG32(HDP_HOST_PATH_CNTL, data);
5599*4882a593Smuzhiyun }
5600*4882a593Smuzhiyun
si_enable_hdp_ls(struct radeon_device * rdev,bool enable)5601*4882a593Smuzhiyun static void si_enable_hdp_ls(struct radeon_device *rdev,
5602*4882a593Smuzhiyun bool enable)
5603*4882a593Smuzhiyun {
5604*4882a593Smuzhiyun u32 orig, data;
5605*4882a593Smuzhiyun
5606*4882a593Smuzhiyun orig = data = RREG32(HDP_MEM_POWER_LS);
5607*4882a593Smuzhiyun
5608*4882a593Smuzhiyun if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS))
5609*4882a593Smuzhiyun data |= HDP_LS_ENABLE;
5610*4882a593Smuzhiyun else
5611*4882a593Smuzhiyun data &= ~HDP_LS_ENABLE;
5612*4882a593Smuzhiyun
5613*4882a593Smuzhiyun if (orig != data)
5614*4882a593Smuzhiyun WREG32(HDP_MEM_POWER_LS, data);
5615*4882a593Smuzhiyun }
5616*4882a593Smuzhiyun
si_update_cg(struct radeon_device * rdev,u32 block,bool enable)5617*4882a593Smuzhiyun static void si_update_cg(struct radeon_device *rdev,
5618*4882a593Smuzhiyun u32 block, bool enable)
5619*4882a593Smuzhiyun {
5620*4882a593Smuzhiyun if (block & RADEON_CG_BLOCK_GFX) {
5621*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, false);
5622*4882a593Smuzhiyun /* order matters! */
5623*4882a593Smuzhiyun if (enable) {
5624*4882a593Smuzhiyun si_enable_mgcg(rdev, true);
5625*4882a593Smuzhiyun si_enable_cgcg(rdev, true);
5626*4882a593Smuzhiyun } else {
5627*4882a593Smuzhiyun si_enable_cgcg(rdev, false);
5628*4882a593Smuzhiyun si_enable_mgcg(rdev, false);
5629*4882a593Smuzhiyun }
5630*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, true);
5631*4882a593Smuzhiyun }
5632*4882a593Smuzhiyun
5633*4882a593Smuzhiyun if (block & RADEON_CG_BLOCK_MC) {
5634*4882a593Smuzhiyun si_enable_mc_mgcg(rdev, enable);
5635*4882a593Smuzhiyun si_enable_mc_ls(rdev, enable);
5636*4882a593Smuzhiyun }
5637*4882a593Smuzhiyun
5638*4882a593Smuzhiyun if (block & RADEON_CG_BLOCK_SDMA) {
5639*4882a593Smuzhiyun si_enable_dma_mgcg(rdev, enable);
5640*4882a593Smuzhiyun }
5641*4882a593Smuzhiyun
5642*4882a593Smuzhiyun if (block & RADEON_CG_BLOCK_BIF) {
5643*4882a593Smuzhiyun si_enable_bif_mgls(rdev, enable);
5644*4882a593Smuzhiyun }
5645*4882a593Smuzhiyun
5646*4882a593Smuzhiyun if (block & RADEON_CG_BLOCK_UVD) {
5647*4882a593Smuzhiyun if (rdev->has_uvd) {
5648*4882a593Smuzhiyun si_enable_uvd_mgcg(rdev, enable);
5649*4882a593Smuzhiyun }
5650*4882a593Smuzhiyun }
5651*4882a593Smuzhiyun
5652*4882a593Smuzhiyun if (block & RADEON_CG_BLOCK_HDP) {
5653*4882a593Smuzhiyun si_enable_hdp_mgcg(rdev, enable);
5654*4882a593Smuzhiyun si_enable_hdp_ls(rdev, enable);
5655*4882a593Smuzhiyun }
5656*4882a593Smuzhiyun }
5657*4882a593Smuzhiyun
si_init_cg(struct radeon_device * rdev)5658*4882a593Smuzhiyun static void si_init_cg(struct radeon_device *rdev)
5659*4882a593Smuzhiyun {
5660*4882a593Smuzhiyun si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
5661*4882a593Smuzhiyun RADEON_CG_BLOCK_MC |
5662*4882a593Smuzhiyun RADEON_CG_BLOCK_SDMA |
5663*4882a593Smuzhiyun RADEON_CG_BLOCK_BIF |
5664*4882a593Smuzhiyun RADEON_CG_BLOCK_HDP), true);
5665*4882a593Smuzhiyun if (rdev->has_uvd) {
5666*4882a593Smuzhiyun si_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
5667*4882a593Smuzhiyun si_init_uvd_internal_cg(rdev);
5668*4882a593Smuzhiyun }
5669*4882a593Smuzhiyun }
5670*4882a593Smuzhiyun
si_fini_cg(struct radeon_device * rdev)5671*4882a593Smuzhiyun static void si_fini_cg(struct radeon_device *rdev)
5672*4882a593Smuzhiyun {
5673*4882a593Smuzhiyun if (rdev->has_uvd) {
5674*4882a593Smuzhiyun si_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
5675*4882a593Smuzhiyun }
5676*4882a593Smuzhiyun si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
5677*4882a593Smuzhiyun RADEON_CG_BLOCK_MC |
5678*4882a593Smuzhiyun RADEON_CG_BLOCK_SDMA |
5679*4882a593Smuzhiyun RADEON_CG_BLOCK_BIF |
5680*4882a593Smuzhiyun RADEON_CG_BLOCK_HDP), false);
5681*4882a593Smuzhiyun }
5682*4882a593Smuzhiyun
si_get_csb_size(struct radeon_device * rdev)5683*4882a593Smuzhiyun u32 si_get_csb_size(struct radeon_device *rdev)
5684*4882a593Smuzhiyun {
5685*4882a593Smuzhiyun u32 count = 0;
5686*4882a593Smuzhiyun const struct cs_section_def *sect = NULL;
5687*4882a593Smuzhiyun const struct cs_extent_def *ext = NULL;
5688*4882a593Smuzhiyun
5689*4882a593Smuzhiyun if (rdev->rlc.cs_data == NULL)
5690*4882a593Smuzhiyun return 0;
5691*4882a593Smuzhiyun
5692*4882a593Smuzhiyun /* begin clear state */
5693*4882a593Smuzhiyun count += 2;
5694*4882a593Smuzhiyun /* context control state */
5695*4882a593Smuzhiyun count += 3;
5696*4882a593Smuzhiyun
5697*4882a593Smuzhiyun for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
5698*4882a593Smuzhiyun for (ext = sect->section; ext->extent != NULL; ++ext) {
5699*4882a593Smuzhiyun if (sect->id == SECT_CONTEXT)
5700*4882a593Smuzhiyun count += 2 + ext->reg_count;
5701*4882a593Smuzhiyun else
5702*4882a593Smuzhiyun return 0;
5703*4882a593Smuzhiyun }
5704*4882a593Smuzhiyun }
5705*4882a593Smuzhiyun /* pa_sc_raster_config */
5706*4882a593Smuzhiyun count += 3;
5707*4882a593Smuzhiyun /* end clear state */
5708*4882a593Smuzhiyun count += 2;
5709*4882a593Smuzhiyun /* clear state */
5710*4882a593Smuzhiyun count += 2;
5711*4882a593Smuzhiyun
5712*4882a593Smuzhiyun return count;
5713*4882a593Smuzhiyun }
5714*4882a593Smuzhiyun
si_get_csb_buffer(struct radeon_device * rdev,volatile u32 * buffer)5715*4882a593Smuzhiyun void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
5716*4882a593Smuzhiyun {
5717*4882a593Smuzhiyun u32 count = 0, i;
5718*4882a593Smuzhiyun const struct cs_section_def *sect = NULL;
5719*4882a593Smuzhiyun const struct cs_extent_def *ext = NULL;
5720*4882a593Smuzhiyun
5721*4882a593Smuzhiyun if (rdev->rlc.cs_data == NULL)
5722*4882a593Smuzhiyun return;
5723*4882a593Smuzhiyun if (buffer == NULL)
5724*4882a593Smuzhiyun return;
5725*4882a593Smuzhiyun
5726*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
5727*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
5728*4882a593Smuzhiyun
5729*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
5730*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x80000000);
5731*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x80000000);
5732*4882a593Smuzhiyun
5733*4882a593Smuzhiyun for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
5734*4882a593Smuzhiyun for (ext = sect->section; ext->extent != NULL; ++ext) {
5735*4882a593Smuzhiyun if (sect->id == SECT_CONTEXT) {
5736*4882a593Smuzhiyun buffer[count++] =
5737*4882a593Smuzhiyun cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
5738*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
5739*4882a593Smuzhiyun for (i = 0; i < ext->reg_count; i++)
5740*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(ext->extent[i]);
5741*4882a593Smuzhiyun } else {
5742*4882a593Smuzhiyun return;
5743*4882a593Smuzhiyun }
5744*4882a593Smuzhiyun }
5745*4882a593Smuzhiyun }
5746*4882a593Smuzhiyun
5747*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
5748*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
5749*4882a593Smuzhiyun switch (rdev->family) {
5750*4882a593Smuzhiyun case CHIP_TAHITI:
5751*4882a593Smuzhiyun case CHIP_PITCAIRN:
5752*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x2a00126a);
5753*4882a593Smuzhiyun break;
5754*4882a593Smuzhiyun case CHIP_VERDE:
5755*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x0000124a);
5756*4882a593Smuzhiyun break;
5757*4882a593Smuzhiyun case CHIP_OLAND:
5758*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x00000082);
5759*4882a593Smuzhiyun break;
5760*4882a593Smuzhiyun case CHIP_HAINAN:
5761*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x00000000);
5762*4882a593Smuzhiyun break;
5763*4882a593Smuzhiyun default:
5764*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0x00000000);
5765*4882a593Smuzhiyun break;
5766*4882a593Smuzhiyun }
5767*4882a593Smuzhiyun
5768*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
5769*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
5770*4882a593Smuzhiyun
5771*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
5772*4882a593Smuzhiyun buffer[count++] = cpu_to_le32(0);
5773*4882a593Smuzhiyun }
5774*4882a593Smuzhiyun
si_init_pg(struct radeon_device * rdev)5775*4882a593Smuzhiyun static void si_init_pg(struct radeon_device *rdev)
5776*4882a593Smuzhiyun {
5777*4882a593Smuzhiyun if (rdev->pg_flags) {
5778*4882a593Smuzhiyun if (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA) {
5779*4882a593Smuzhiyun si_init_dma_pg(rdev);
5780*4882a593Smuzhiyun }
5781*4882a593Smuzhiyun si_init_ao_cu_mask(rdev);
5782*4882a593Smuzhiyun if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {
5783*4882a593Smuzhiyun si_init_gfx_cgpg(rdev);
5784*4882a593Smuzhiyun } else {
5785*4882a593Smuzhiyun WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
5786*4882a593Smuzhiyun WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
5787*4882a593Smuzhiyun }
5788*4882a593Smuzhiyun si_enable_dma_pg(rdev, true);
5789*4882a593Smuzhiyun si_enable_gfx_cgpg(rdev, true);
5790*4882a593Smuzhiyun } else {
5791*4882a593Smuzhiyun WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
5792*4882a593Smuzhiyun WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
5793*4882a593Smuzhiyun }
5794*4882a593Smuzhiyun }
5795*4882a593Smuzhiyun
si_fini_pg(struct radeon_device * rdev)5796*4882a593Smuzhiyun static void si_fini_pg(struct radeon_device *rdev)
5797*4882a593Smuzhiyun {
5798*4882a593Smuzhiyun if (rdev->pg_flags) {
5799*4882a593Smuzhiyun si_enable_dma_pg(rdev, false);
5800*4882a593Smuzhiyun si_enable_gfx_cgpg(rdev, false);
5801*4882a593Smuzhiyun }
5802*4882a593Smuzhiyun }
5803*4882a593Smuzhiyun
5804*4882a593Smuzhiyun /*
5805*4882a593Smuzhiyun * RLC
5806*4882a593Smuzhiyun */
si_rlc_reset(struct radeon_device * rdev)5807*4882a593Smuzhiyun void si_rlc_reset(struct radeon_device *rdev)
5808*4882a593Smuzhiyun {
5809*4882a593Smuzhiyun u32 tmp = RREG32(GRBM_SOFT_RESET);
5810*4882a593Smuzhiyun
5811*4882a593Smuzhiyun tmp |= SOFT_RESET_RLC;
5812*4882a593Smuzhiyun WREG32(GRBM_SOFT_RESET, tmp);
5813*4882a593Smuzhiyun udelay(50);
5814*4882a593Smuzhiyun tmp &= ~SOFT_RESET_RLC;
5815*4882a593Smuzhiyun WREG32(GRBM_SOFT_RESET, tmp);
5816*4882a593Smuzhiyun udelay(50);
5817*4882a593Smuzhiyun }
5818*4882a593Smuzhiyun
si_rlc_stop(struct radeon_device * rdev)5819*4882a593Smuzhiyun static void si_rlc_stop(struct radeon_device *rdev)
5820*4882a593Smuzhiyun {
5821*4882a593Smuzhiyun WREG32(RLC_CNTL, 0);
5822*4882a593Smuzhiyun
5823*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, false);
5824*4882a593Smuzhiyun
5825*4882a593Smuzhiyun si_wait_for_rlc_serdes(rdev);
5826*4882a593Smuzhiyun }
5827*4882a593Smuzhiyun
si_rlc_start(struct radeon_device * rdev)5828*4882a593Smuzhiyun static void si_rlc_start(struct radeon_device *rdev)
5829*4882a593Smuzhiyun {
5830*4882a593Smuzhiyun WREG32(RLC_CNTL, RLC_ENABLE);
5831*4882a593Smuzhiyun
5832*4882a593Smuzhiyun si_enable_gui_idle_interrupt(rdev, true);
5833*4882a593Smuzhiyun
5834*4882a593Smuzhiyun udelay(50);
5835*4882a593Smuzhiyun }
5836*4882a593Smuzhiyun
si_lbpw_supported(struct radeon_device * rdev)5837*4882a593Smuzhiyun static bool si_lbpw_supported(struct radeon_device *rdev)
5838*4882a593Smuzhiyun {
5839*4882a593Smuzhiyun u32 tmp;
5840*4882a593Smuzhiyun
5841*4882a593Smuzhiyun /* Enable LBPW only for DDR3 */
5842*4882a593Smuzhiyun tmp = RREG32(MC_SEQ_MISC0);
5843*4882a593Smuzhiyun if ((tmp & 0xF0000000) == 0xB0000000)
5844*4882a593Smuzhiyun return true;
5845*4882a593Smuzhiyun return false;
5846*4882a593Smuzhiyun }
5847*4882a593Smuzhiyun
si_enable_lbpw(struct radeon_device * rdev,bool enable)5848*4882a593Smuzhiyun static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
5849*4882a593Smuzhiyun {
5850*4882a593Smuzhiyun u32 tmp;
5851*4882a593Smuzhiyun
5852*4882a593Smuzhiyun tmp = RREG32(RLC_LB_CNTL);
5853*4882a593Smuzhiyun if (enable)
5854*4882a593Smuzhiyun tmp |= LOAD_BALANCE_ENABLE;
5855*4882a593Smuzhiyun else
5856*4882a593Smuzhiyun tmp &= ~LOAD_BALANCE_ENABLE;
5857*4882a593Smuzhiyun WREG32(RLC_LB_CNTL, tmp);
5858*4882a593Smuzhiyun
5859*4882a593Smuzhiyun if (!enable) {
5860*4882a593Smuzhiyun si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
5861*4882a593Smuzhiyun WREG32(SPI_LB_CU_MASK, 0x00ff);
5862*4882a593Smuzhiyun }
5863*4882a593Smuzhiyun }
5864*4882a593Smuzhiyun
si_rlc_resume(struct radeon_device * rdev)5865*4882a593Smuzhiyun static int si_rlc_resume(struct radeon_device *rdev)
5866*4882a593Smuzhiyun {
5867*4882a593Smuzhiyun u32 i;
5868*4882a593Smuzhiyun
5869*4882a593Smuzhiyun if (!rdev->rlc_fw)
5870*4882a593Smuzhiyun return -EINVAL;
5871*4882a593Smuzhiyun
5872*4882a593Smuzhiyun si_rlc_stop(rdev);
5873*4882a593Smuzhiyun
5874*4882a593Smuzhiyun si_rlc_reset(rdev);
5875*4882a593Smuzhiyun
5876*4882a593Smuzhiyun si_init_pg(rdev);
5877*4882a593Smuzhiyun
5878*4882a593Smuzhiyun si_init_cg(rdev);
5879*4882a593Smuzhiyun
5880*4882a593Smuzhiyun WREG32(RLC_RL_BASE, 0);
5881*4882a593Smuzhiyun WREG32(RLC_RL_SIZE, 0);
5882*4882a593Smuzhiyun WREG32(RLC_LB_CNTL, 0);
5883*4882a593Smuzhiyun WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
5884*4882a593Smuzhiyun WREG32(RLC_LB_CNTR_INIT, 0);
5885*4882a593Smuzhiyun WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
5886*4882a593Smuzhiyun
5887*4882a593Smuzhiyun WREG32(RLC_MC_CNTL, 0);
5888*4882a593Smuzhiyun WREG32(RLC_UCODE_CNTL, 0);
5889*4882a593Smuzhiyun
5890*4882a593Smuzhiyun if (rdev->new_fw) {
5891*4882a593Smuzhiyun const struct rlc_firmware_header_v1_0 *hdr =
5892*4882a593Smuzhiyun (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
5893*4882a593Smuzhiyun u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
5894*4882a593Smuzhiyun const __le32 *fw_data = (const __le32 *)
5895*4882a593Smuzhiyun (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
5896*4882a593Smuzhiyun
5897*4882a593Smuzhiyun radeon_ucode_print_rlc_hdr(&hdr->header);
5898*4882a593Smuzhiyun
5899*4882a593Smuzhiyun for (i = 0; i < fw_size; i++) {
5900*4882a593Smuzhiyun WREG32(RLC_UCODE_ADDR, i);
5901*4882a593Smuzhiyun WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++));
5902*4882a593Smuzhiyun }
5903*4882a593Smuzhiyun } else {
5904*4882a593Smuzhiyun const __be32 *fw_data =
5905*4882a593Smuzhiyun (const __be32 *)rdev->rlc_fw->data;
5906*4882a593Smuzhiyun for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
5907*4882a593Smuzhiyun WREG32(RLC_UCODE_ADDR, i);
5908*4882a593Smuzhiyun WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
5909*4882a593Smuzhiyun }
5910*4882a593Smuzhiyun }
5911*4882a593Smuzhiyun WREG32(RLC_UCODE_ADDR, 0);
5912*4882a593Smuzhiyun
5913*4882a593Smuzhiyun si_enable_lbpw(rdev, si_lbpw_supported(rdev));
5914*4882a593Smuzhiyun
5915*4882a593Smuzhiyun si_rlc_start(rdev);
5916*4882a593Smuzhiyun
5917*4882a593Smuzhiyun return 0;
5918*4882a593Smuzhiyun }
5919*4882a593Smuzhiyun
si_enable_interrupts(struct radeon_device * rdev)5920*4882a593Smuzhiyun static void si_enable_interrupts(struct radeon_device *rdev)
5921*4882a593Smuzhiyun {
5922*4882a593Smuzhiyun u32 ih_cntl = RREG32(IH_CNTL);
5923*4882a593Smuzhiyun u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
5924*4882a593Smuzhiyun
5925*4882a593Smuzhiyun ih_cntl |= ENABLE_INTR;
5926*4882a593Smuzhiyun ih_rb_cntl |= IH_RB_ENABLE;
5927*4882a593Smuzhiyun WREG32(IH_CNTL, ih_cntl);
5928*4882a593Smuzhiyun WREG32(IH_RB_CNTL, ih_rb_cntl);
5929*4882a593Smuzhiyun rdev->ih.enabled = true;
5930*4882a593Smuzhiyun }
5931*4882a593Smuzhiyun
si_disable_interrupts(struct radeon_device * rdev)5932*4882a593Smuzhiyun static void si_disable_interrupts(struct radeon_device *rdev)
5933*4882a593Smuzhiyun {
5934*4882a593Smuzhiyun u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
5935*4882a593Smuzhiyun u32 ih_cntl = RREG32(IH_CNTL);
5936*4882a593Smuzhiyun
5937*4882a593Smuzhiyun ih_rb_cntl &= ~IH_RB_ENABLE;
5938*4882a593Smuzhiyun ih_cntl &= ~ENABLE_INTR;
5939*4882a593Smuzhiyun WREG32(IH_RB_CNTL, ih_rb_cntl);
5940*4882a593Smuzhiyun WREG32(IH_CNTL, ih_cntl);
5941*4882a593Smuzhiyun /* set rptr, wptr to 0 */
5942*4882a593Smuzhiyun WREG32(IH_RB_RPTR, 0);
5943*4882a593Smuzhiyun WREG32(IH_RB_WPTR, 0);
5944*4882a593Smuzhiyun rdev->ih.enabled = false;
5945*4882a593Smuzhiyun rdev->ih.rptr = 0;
5946*4882a593Smuzhiyun }
5947*4882a593Smuzhiyun
si_disable_interrupt_state(struct radeon_device * rdev)5948*4882a593Smuzhiyun static void si_disable_interrupt_state(struct radeon_device *rdev)
5949*4882a593Smuzhiyun {
5950*4882a593Smuzhiyun int i;
5951*4882a593Smuzhiyun u32 tmp;
5952*4882a593Smuzhiyun
5953*4882a593Smuzhiyun tmp = RREG32(CP_INT_CNTL_RING0) &
5954*4882a593Smuzhiyun (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
5955*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING0, tmp);
5956*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING1, 0);
5957*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING2, 0);
5958*4882a593Smuzhiyun tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
5959*4882a593Smuzhiyun WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp);
5960*4882a593Smuzhiyun tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
5961*4882a593Smuzhiyun WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp);
5962*4882a593Smuzhiyun WREG32(GRBM_INT_CNTL, 0);
5963*4882a593Smuzhiyun WREG32(SRBM_INT_CNTL, 0);
5964*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i++)
5965*4882a593Smuzhiyun WREG32(INT_MASK + crtc_offsets[i], 0);
5966*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i++)
5967*4882a593Smuzhiyun WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0);
5968*4882a593Smuzhiyun
5969*4882a593Smuzhiyun if (!ASIC_IS_NODCE(rdev)) {
5970*4882a593Smuzhiyun WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
5971*4882a593Smuzhiyun
5972*4882a593Smuzhiyun for (i = 0; i < 6; i++)
5973*4882a593Smuzhiyun WREG32_AND(DC_HPDx_INT_CONTROL(i),
5974*4882a593Smuzhiyun DC_HPDx_INT_POLARITY);
5975*4882a593Smuzhiyun }
5976*4882a593Smuzhiyun }
5977*4882a593Smuzhiyun
si_irq_init(struct radeon_device * rdev)5978*4882a593Smuzhiyun static int si_irq_init(struct radeon_device *rdev)
5979*4882a593Smuzhiyun {
5980*4882a593Smuzhiyun int ret = 0;
5981*4882a593Smuzhiyun int rb_bufsz;
5982*4882a593Smuzhiyun u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
5983*4882a593Smuzhiyun
5984*4882a593Smuzhiyun /* allocate ring */
5985*4882a593Smuzhiyun ret = r600_ih_ring_alloc(rdev);
5986*4882a593Smuzhiyun if (ret)
5987*4882a593Smuzhiyun return ret;
5988*4882a593Smuzhiyun
5989*4882a593Smuzhiyun /* disable irqs */
5990*4882a593Smuzhiyun si_disable_interrupts(rdev);
5991*4882a593Smuzhiyun
5992*4882a593Smuzhiyun /* init rlc */
5993*4882a593Smuzhiyun ret = si_rlc_resume(rdev);
5994*4882a593Smuzhiyun if (ret) {
5995*4882a593Smuzhiyun r600_ih_ring_fini(rdev);
5996*4882a593Smuzhiyun return ret;
5997*4882a593Smuzhiyun }
5998*4882a593Smuzhiyun
5999*4882a593Smuzhiyun /* setup interrupt control */
6000*4882a593Smuzhiyun /* set dummy read address to dummy page address */
6001*4882a593Smuzhiyun WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8);
6002*4882a593Smuzhiyun interrupt_cntl = RREG32(INTERRUPT_CNTL);
6003*4882a593Smuzhiyun /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
6004*4882a593Smuzhiyun * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
6005*4882a593Smuzhiyun */
6006*4882a593Smuzhiyun interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
6007*4882a593Smuzhiyun /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
6008*4882a593Smuzhiyun interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
6009*4882a593Smuzhiyun WREG32(INTERRUPT_CNTL, interrupt_cntl);
6010*4882a593Smuzhiyun
6011*4882a593Smuzhiyun WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
6012*4882a593Smuzhiyun rb_bufsz = order_base_2(rdev->ih.ring_size / 4);
6013*4882a593Smuzhiyun
6014*4882a593Smuzhiyun ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
6015*4882a593Smuzhiyun IH_WPTR_OVERFLOW_CLEAR |
6016*4882a593Smuzhiyun (rb_bufsz << 1));
6017*4882a593Smuzhiyun
6018*4882a593Smuzhiyun if (rdev->wb.enabled)
6019*4882a593Smuzhiyun ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
6020*4882a593Smuzhiyun
6021*4882a593Smuzhiyun /* set the writeback address whether it's enabled or not */
6022*4882a593Smuzhiyun WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
6023*4882a593Smuzhiyun WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
6024*4882a593Smuzhiyun
6025*4882a593Smuzhiyun WREG32(IH_RB_CNTL, ih_rb_cntl);
6026*4882a593Smuzhiyun
6027*4882a593Smuzhiyun /* set rptr, wptr to 0 */
6028*4882a593Smuzhiyun WREG32(IH_RB_RPTR, 0);
6029*4882a593Smuzhiyun WREG32(IH_RB_WPTR, 0);
6030*4882a593Smuzhiyun
6031*4882a593Smuzhiyun /* Default settings for IH_CNTL (disabled at first) */
6032*4882a593Smuzhiyun ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
6033*4882a593Smuzhiyun /* RPTR_REARM only works if msi's are enabled */
6034*4882a593Smuzhiyun if (rdev->msi_enabled)
6035*4882a593Smuzhiyun ih_cntl |= RPTR_REARM;
6036*4882a593Smuzhiyun WREG32(IH_CNTL, ih_cntl);
6037*4882a593Smuzhiyun
6038*4882a593Smuzhiyun /* force the active interrupt state to all disabled */
6039*4882a593Smuzhiyun si_disable_interrupt_state(rdev);
6040*4882a593Smuzhiyun
6041*4882a593Smuzhiyun pci_set_master(rdev->pdev);
6042*4882a593Smuzhiyun
6043*4882a593Smuzhiyun /* enable irqs */
6044*4882a593Smuzhiyun si_enable_interrupts(rdev);
6045*4882a593Smuzhiyun
6046*4882a593Smuzhiyun return ret;
6047*4882a593Smuzhiyun }
6048*4882a593Smuzhiyun
6049*4882a593Smuzhiyun /* The order we write back each register here is important */
si_irq_set(struct radeon_device * rdev)6050*4882a593Smuzhiyun int si_irq_set(struct radeon_device *rdev)
6051*4882a593Smuzhiyun {
6052*4882a593Smuzhiyun int i;
6053*4882a593Smuzhiyun u32 cp_int_cntl;
6054*4882a593Smuzhiyun u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
6055*4882a593Smuzhiyun u32 grbm_int_cntl = 0;
6056*4882a593Smuzhiyun u32 dma_cntl, dma_cntl1;
6057*4882a593Smuzhiyun u32 thermal_int = 0;
6058*4882a593Smuzhiyun
6059*4882a593Smuzhiyun if (!rdev->irq.installed) {
6060*4882a593Smuzhiyun WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
6061*4882a593Smuzhiyun return -EINVAL;
6062*4882a593Smuzhiyun }
6063*4882a593Smuzhiyun /* don't enable anything if the ih is disabled */
6064*4882a593Smuzhiyun if (!rdev->ih.enabled) {
6065*4882a593Smuzhiyun si_disable_interrupts(rdev);
6066*4882a593Smuzhiyun /* force the active interrupt state to all disabled */
6067*4882a593Smuzhiyun si_disable_interrupt_state(rdev);
6068*4882a593Smuzhiyun return 0;
6069*4882a593Smuzhiyun }
6070*4882a593Smuzhiyun
6071*4882a593Smuzhiyun cp_int_cntl = RREG32(CP_INT_CNTL_RING0) &
6072*4882a593Smuzhiyun (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
6073*4882a593Smuzhiyun
6074*4882a593Smuzhiyun dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
6075*4882a593Smuzhiyun dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
6076*4882a593Smuzhiyun
6077*4882a593Smuzhiyun thermal_int = RREG32(CG_THERMAL_INT) &
6078*4882a593Smuzhiyun ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
6079*4882a593Smuzhiyun
6080*4882a593Smuzhiyun /* enable CP interrupts on all rings */
6081*4882a593Smuzhiyun if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
6082*4882a593Smuzhiyun DRM_DEBUG("si_irq_set: sw int gfx\n");
6083*4882a593Smuzhiyun cp_int_cntl |= TIME_STAMP_INT_ENABLE;
6084*4882a593Smuzhiyun }
6085*4882a593Smuzhiyun if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
6086*4882a593Smuzhiyun DRM_DEBUG("si_irq_set: sw int cp1\n");
6087*4882a593Smuzhiyun cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
6088*4882a593Smuzhiyun }
6089*4882a593Smuzhiyun if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
6090*4882a593Smuzhiyun DRM_DEBUG("si_irq_set: sw int cp2\n");
6091*4882a593Smuzhiyun cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
6092*4882a593Smuzhiyun }
6093*4882a593Smuzhiyun if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
6094*4882a593Smuzhiyun DRM_DEBUG("si_irq_set: sw int dma\n");
6095*4882a593Smuzhiyun dma_cntl |= TRAP_ENABLE;
6096*4882a593Smuzhiyun }
6097*4882a593Smuzhiyun
6098*4882a593Smuzhiyun if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
6099*4882a593Smuzhiyun DRM_DEBUG("si_irq_set: sw int dma1\n");
6100*4882a593Smuzhiyun dma_cntl1 |= TRAP_ENABLE;
6101*4882a593Smuzhiyun }
6102*4882a593Smuzhiyun
6103*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
6104*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING1, cp_int_cntl1);
6105*4882a593Smuzhiyun WREG32(CP_INT_CNTL_RING2, cp_int_cntl2);
6106*4882a593Smuzhiyun
6107*4882a593Smuzhiyun WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl);
6108*4882a593Smuzhiyun WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1);
6109*4882a593Smuzhiyun
6110*4882a593Smuzhiyun WREG32(GRBM_INT_CNTL, grbm_int_cntl);
6111*4882a593Smuzhiyun
6112*4882a593Smuzhiyun if (rdev->irq.dpm_thermal) {
6113*4882a593Smuzhiyun DRM_DEBUG("dpm thermal\n");
6114*4882a593Smuzhiyun thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
6115*4882a593Smuzhiyun }
6116*4882a593Smuzhiyun
6117*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i++) {
6118*4882a593Smuzhiyun radeon_irq_kms_set_irq_n_enabled(
6119*4882a593Smuzhiyun rdev, INT_MASK + crtc_offsets[i], VBLANK_INT_MASK,
6120*4882a593Smuzhiyun rdev->irq.crtc_vblank_int[i] ||
6121*4882a593Smuzhiyun atomic_read(&rdev->irq.pflip[i]), "vblank", i);
6122*4882a593Smuzhiyun }
6123*4882a593Smuzhiyun
6124*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i++)
6125*4882a593Smuzhiyun WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK);
6126*4882a593Smuzhiyun
6127*4882a593Smuzhiyun if (!ASIC_IS_NODCE(rdev)) {
6128*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
6129*4882a593Smuzhiyun radeon_irq_kms_set_irq_n_enabled(
6130*4882a593Smuzhiyun rdev, DC_HPDx_INT_CONTROL(i),
6131*4882a593Smuzhiyun DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN,
6132*4882a593Smuzhiyun rdev->irq.hpd[i], "HPD", i);
6133*4882a593Smuzhiyun }
6134*4882a593Smuzhiyun }
6135*4882a593Smuzhiyun
6136*4882a593Smuzhiyun WREG32(CG_THERMAL_INT, thermal_int);
6137*4882a593Smuzhiyun
6138*4882a593Smuzhiyun /* posting read */
6139*4882a593Smuzhiyun RREG32(SRBM_STATUS);
6140*4882a593Smuzhiyun
6141*4882a593Smuzhiyun return 0;
6142*4882a593Smuzhiyun }
6143*4882a593Smuzhiyun
6144*4882a593Smuzhiyun /* The order we write back each register here is important */
si_irq_ack(struct radeon_device * rdev)6145*4882a593Smuzhiyun static inline void si_irq_ack(struct radeon_device *rdev)
6146*4882a593Smuzhiyun {
6147*4882a593Smuzhiyun int i, j;
6148*4882a593Smuzhiyun u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
6149*4882a593Smuzhiyun u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int;
6150*4882a593Smuzhiyun
6151*4882a593Smuzhiyun if (ASIC_IS_NODCE(rdev))
6152*4882a593Smuzhiyun return;
6153*4882a593Smuzhiyun
6154*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
6155*4882a593Smuzhiyun disp_int[i] = RREG32(si_disp_int_status[i]);
6156*4882a593Smuzhiyun if (i < rdev->num_crtc)
6157*4882a593Smuzhiyun grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]);
6158*4882a593Smuzhiyun }
6159*4882a593Smuzhiyun
6160*4882a593Smuzhiyun /* We write back each interrupt register in pairs of two */
6161*4882a593Smuzhiyun for (i = 0; i < rdev->num_crtc; i += 2) {
6162*4882a593Smuzhiyun for (j = i; j < (i + 2); j++) {
6163*4882a593Smuzhiyun if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED)
6164*4882a593Smuzhiyun WREG32(GRPH_INT_STATUS + crtc_offsets[j],
6165*4882a593Smuzhiyun GRPH_PFLIP_INT_CLEAR);
6166*4882a593Smuzhiyun }
6167*4882a593Smuzhiyun
6168*4882a593Smuzhiyun for (j = i; j < (i + 2); j++) {
6169*4882a593Smuzhiyun if (disp_int[j] & LB_D1_VBLANK_INTERRUPT)
6170*4882a593Smuzhiyun WREG32(VBLANK_STATUS + crtc_offsets[j],
6171*4882a593Smuzhiyun VBLANK_ACK);
6172*4882a593Smuzhiyun if (disp_int[j] & LB_D1_VLINE_INTERRUPT)
6173*4882a593Smuzhiyun WREG32(VLINE_STATUS + crtc_offsets[j],
6174*4882a593Smuzhiyun VLINE_ACK);
6175*4882a593Smuzhiyun }
6176*4882a593Smuzhiyun }
6177*4882a593Smuzhiyun
6178*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
6179*4882a593Smuzhiyun if (disp_int[i] & DC_HPD1_INTERRUPT)
6180*4882a593Smuzhiyun WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK);
6181*4882a593Smuzhiyun }
6182*4882a593Smuzhiyun
6183*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
6184*4882a593Smuzhiyun if (disp_int[i] & DC_HPD1_RX_INTERRUPT)
6185*4882a593Smuzhiyun WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
6186*4882a593Smuzhiyun }
6187*4882a593Smuzhiyun }
6188*4882a593Smuzhiyun
si_irq_disable(struct radeon_device * rdev)6189*4882a593Smuzhiyun static void si_irq_disable(struct radeon_device *rdev)
6190*4882a593Smuzhiyun {
6191*4882a593Smuzhiyun si_disable_interrupts(rdev);
6192*4882a593Smuzhiyun /* Wait and acknowledge irq */
6193*4882a593Smuzhiyun mdelay(1);
6194*4882a593Smuzhiyun si_irq_ack(rdev);
6195*4882a593Smuzhiyun si_disable_interrupt_state(rdev);
6196*4882a593Smuzhiyun }
6197*4882a593Smuzhiyun
si_irq_suspend(struct radeon_device * rdev)6198*4882a593Smuzhiyun static void si_irq_suspend(struct radeon_device *rdev)
6199*4882a593Smuzhiyun {
6200*4882a593Smuzhiyun si_irq_disable(rdev);
6201*4882a593Smuzhiyun si_rlc_stop(rdev);
6202*4882a593Smuzhiyun }
6203*4882a593Smuzhiyun
si_irq_fini(struct radeon_device * rdev)6204*4882a593Smuzhiyun static void si_irq_fini(struct radeon_device *rdev)
6205*4882a593Smuzhiyun {
6206*4882a593Smuzhiyun si_irq_suspend(rdev);
6207*4882a593Smuzhiyun r600_ih_ring_fini(rdev);
6208*4882a593Smuzhiyun }
6209*4882a593Smuzhiyun
si_get_ih_wptr(struct radeon_device * rdev)6210*4882a593Smuzhiyun static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
6211*4882a593Smuzhiyun {
6212*4882a593Smuzhiyun u32 wptr, tmp;
6213*4882a593Smuzhiyun
6214*4882a593Smuzhiyun if (rdev->wb.enabled)
6215*4882a593Smuzhiyun wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
6216*4882a593Smuzhiyun else
6217*4882a593Smuzhiyun wptr = RREG32(IH_RB_WPTR);
6218*4882a593Smuzhiyun
6219*4882a593Smuzhiyun if (wptr & RB_OVERFLOW) {
6220*4882a593Smuzhiyun wptr &= ~RB_OVERFLOW;
6221*4882a593Smuzhiyun /* When a ring buffer overflow happen start parsing interrupt
6222*4882a593Smuzhiyun * from the last not overwritten vector (wptr + 16). Hopefully
6223*4882a593Smuzhiyun * this should allow us to catchup.
6224*4882a593Smuzhiyun */
6225*4882a593Smuzhiyun dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
6226*4882a593Smuzhiyun wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
6227*4882a593Smuzhiyun rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
6228*4882a593Smuzhiyun tmp = RREG32(IH_RB_CNTL);
6229*4882a593Smuzhiyun tmp |= IH_WPTR_OVERFLOW_CLEAR;
6230*4882a593Smuzhiyun WREG32(IH_RB_CNTL, tmp);
6231*4882a593Smuzhiyun }
6232*4882a593Smuzhiyun return (wptr & rdev->ih.ptr_mask);
6233*4882a593Smuzhiyun }
6234*4882a593Smuzhiyun
6235*4882a593Smuzhiyun /* SI IV Ring
6236*4882a593Smuzhiyun * Each IV ring entry is 128 bits:
6237*4882a593Smuzhiyun * [7:0] - interrupt source id
6238*4882a593Smuzhiyun * [31:8] - reserved
6239*4882a593Smuzhiyun * [59:32] - interrupt source data
6240*4882a593Smuzhiyun * [63:60] - reserved
6241*4882a593Smuzhiyun * [71:64] - RINGID
6242*4882a593Smuzhiyun * [79:72] - VMID
6243*4882a593Smuzhiyun * [127:80] - reserved
6244*4882a593Smuzhiyun */
si_irq_process(struct radeon_device * rdev)6245*4882a593Smuzhiyun int si_irq_process(struct radeon_device *rdev)
6246*4882a593Smuzhiyun {
6247*4882a593Smuzhiyun u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
6248*4882a593Smuzhiyun u32 crtc_idx, hpd_idx;
6249*4882a593Smuzhiyun u32 mask;
6250*4882a593Smuzhiyun u32 wptr;
6251*4882a593Smuzhiyun u32 rptr;
6252*4882a593Smuzhiyun u32 src_id, src_data, ring_id;
6253*4882a593Smuzhiyun u32 ring_index;
6254*4882a593Smuzhiyun bool queue_hotplug = false;
6255*4882a593Smuzhiyun bool queue_dp = false;
6256*4882a593Smuzhiyun bool queue_thermal = false;
6257*4882a593Smuzhiyun u32 status, addr;
6258*4882a593Smuzhiyun const char *event_name;
6259*4882a593Smuzhiyun
6260*4882a593Smuzhiyun if (!rdev->ih.enabled || rdev->shutdown)
6261*4882a593Smuzhiyun return IRQ_NONE;
6262*4882a593Smuzhiyun
6263*4882a593Smuzhiyun wptr = si_get_ih_wptr(rdev);
6264*4882a593Smuzhiyun
6265*4882a593Smuzhiyun restart_ih:
6266*4882a593Smuzhiyun /* is somebody else already processing irqs? */
6267*4882a593Smuzhiyun if (atomic_xchg(&rdev->ih.lock, 1))
6268*4882a593Smuzhiyun return IRQ_NONE;
6269*4882a593Smuzhiyun
6270*4882a593Smuzhiyun rptr = rdev->ih.rptr;
6271*4882a593Smuzhiyun DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
6272*4882a593Smuzhiyun
6273*4882a593Smuzhiyun /* Order reading of wptr vs. reading of IH ring data */
6274*4882a593Smuzhiyun rmb();
6275*4882a593Smuzhiyun
6276*4882a593Smuzhiyun /* display interrupts */
6277*4882a593Smuzhiyun si_irq_ack(rdev);
6278*4882a593Smuzhiyun
6279*4882a593Smuzhiyun while (rptr != wptr) {
6280*4882a593Smuzhiyun /* wptr/rptr are in bytes! */
6281*4882a593Smuzhiyun ring_index = rptr / 4;
6282*4882a593Smuzhiyun src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
6283*4882a593Smuzhiyun src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
6284*4882a593Smuzhiyun ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
6285*4882a593Smuzhiyun
6286*4882a593Smuzhiyun switch (src_id) {
6287*4882a593Smuzhiyun case 1: /* D1 vblank/vline */
6288*4882a593Smuzhiyun case 2: /* D2 vblank/vline */
6289*4882a593Smuzhiyun case 3: /* D3 vblank/vline */
6290*4882a593Smuzhiyun case 4: /* D4 vblank/vline */
6291*4882a593Smuzhiyun case 5: /* D5 vblank/vline */
6292*4882a593Smuzhiyun case 6: /* D6 vblank/vline */
6293*4882a593Smuzhiyun crtc_idx = src_id - 1;
6294*4882a593Smuzhiyun
6295*4882a593Smuzhiyun if (src_data == 0) { /* vblank */
6296*4882a593Smuzhiyun mask = LB_D1_VBLANK_INTERRUPT;
6297*4882a593Smuzhiyun event_name = "vblank";
6298*4882a593Smuzhiyun
6299*4882a593Smuzhiyun if (rdev->irq.crtc_vblank_int[crtc_idx]) {
6300*4882a593Smuzhiyun drm_handle_vblank(rdev->ddev, crtc_idx);
6301*4882a593Smuzhiyun rdev->pm.vblank_sync = true;
6302*4882a593Smuzhiyun wake_up(&rdev->irq.vblank_queue);
6303*4882a593Smuzhiyun }
6304*4882a593Smuzhiyun if (atomic_read(&rdev->irq.pflip[crtc_idx])) {
6305*4882a593Smuzhiyun radeon_crtc_handle_vblank(rdev,
6306*4882a593Smuzhiyun crtc_idx);
6307*4882a593Smuzhiyun }
6308*4882a593Smuzhiyun
6309*4882a593Smuzhiyun } else if (src_data == 1) { /* vline */
6310*4882a593Smuzhiyun mask = LB_D1_VLINE_INTERRUPT;
6311*4882a593Smuzhiyun event_name = "vline";
6312*4882a593Smuzhiyun } else {
6313*4882a593Smuzhiyun DRM_DEBUG("Unhandled interrupt: %d %d\n",
6314*4882a593Smuzhiyun src_id, src_data);
6315*4882a593Smuzhiyun break;
6316*4882a593Smuzhiyun }
6317*4882a593Smuzhiyun
6318*4882a593Smuzhiyun if (!(disp_int[crtc_idx] & mask)) {
6319*4882a593Smuzhiyun DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n",
6320*4882a593Smuzhiyun crtc_idx + 1, event_name);
6321*4882a593Smuzhiyun }
6322*4882a593Smuzhiyun
6323*4882a593Smuzhiyun disp_int[crtc_idx] &= ~mask;
6324*4882a593Smuzhiyun DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name);
6325*4882a593Smuzhiyun
6326*4882a593Smuzhiyun break;
6327*4882a593Smuzhiyun case 8: /* D1 page flip */
6328*4882a593Smuzhiyun case 10: /* D2 page flip */
6329*4882a593Smuzhiyun case 12: /* D3 page flip */
6330*4882a593Smuzhiyun case 14: /* D4 page flip */
6331*4882a593Smuzhiyun case 16: /* D5 page flip */
6332*4882a593Smuzhiyun case 18: /* D6 page flip */
6333*4882a593Smuzhiyun DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
6334*4882a593Smuzhiyun if (radeon_use_pflipirq > 0)
6335*4882a593Smuzhiyun radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
6336*4882a593Smuzhiyun break;
6337*4882a593Smuzhiyun case 42: /* HPD hotplug */
6338*4882a593Smuzhiyun if (src_data <= 5) {
6339*4882a593Smuzhiyun hpd_idx = src_data;
6340*4882a593Smuzhiyun mask = DC_HPD1_INTERRUPT;
6341*4882a593Smuzhiyun queue_hotplug = true;
6342*4882a593Smuzhiyun event_name = "HPD";
6343*4882a593Smuzhiyun
6344*4882a593Smuzhiyun } else if (src_data <= 11) {
6345*4882a593Smuzhiyun hpd_idx = src_data - 6;
6346*4882a593Smuzhiyun mask = DC_HPD1_RX_INTERRUPT;
6347*4882a593Smuzhiyun queue_dp = true;
6348*4882a593Smuzhiyun event_name = "HPD_RX";
6349*4882a593Smuzhiyun
6350*4882a593Smuzhiyun } else {
6351*4882a593Smuzhiyun DRM_DEBUG("Unhandled interrupt: %d %d\n",
6352*4882a593Smuzhiyun src_id, src_data);
6353*4882a593Smuzhiyun break;
6354*4882a593Smuzhiyun }
6355*4882a593Smuzhiyun
6356*4882a593Smuzhiyun if (!(disp_int[hpd_idx] & mask))
6357*4882a593Smuzhiyun DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
6358*4882a593Smuzhiyun
6359*4882a593Smuzhiyun disp_int[hpd_idx] &= ~mask;
6360*4882a593Smuzhiyun DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1);
6361*4882a593Smuzhiyun break;
6362*4882a593Smuzhiyun case 96:
6363*4882a593Smuzhiyun DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
6364*4882a593Smuzhiyun WREG32(SRBM_INT_ACK, 0x1);
6365*4882a593Smuzhiyun break;
6366*4882a593Smuzhiyun case 124: /* UVD */
6367*4882a593Smuzhiyun DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
6368*4882a593Smuzhiyun radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
6369*4882a593Smuzhiyun break;
6370*4882a593Smuzhiyun case 146:
6371*4882a593Smuzhiyun case 147:
6372*4882a593Smuzhiyun addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
6373*4882a593Smuzhiyun status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
6374*4882a593Smuzhiyun /* reset addr and status */
6375*4882a593Smuzhiyun WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
6376*4882a593Smuzhiyun if (addr == 0x0 && status == 0x0)
6377*4882a593Smuzhiyun break;
6378*4882a593Smuzhiyun dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
6379*4882a593Smuzhiyun dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
6380*4882a593Smuzhiyun addr);
6381*4882a593Smuzhiyun dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
6382*4882a593Smuzhiyun status);
6383*4882a593Smuzhiyun si_vm_decode_fault(rdev, status, addr);
6384*4882a593Smuzhiyun break;
6385*4882a593Smuzhiyun case 176: /* RINGID0 CP_INT */
6386*4882a593Smuzhiyun radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
6387*4882a593Smuzhiyun break;
6388*4882a593Smuzhiyun case 177: /* RINGID1 CP_INT */
6389*4882a593Smuzhiyun radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6390*4882a593Smuzhiyun break;
6391*4882a593Smuzhiyun case 178: /* RINGID2 CP_INT */
6392*4882a593Smuzhiyun radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6393*4882a593Smuzhiyun break;
6394*4882a593Smuzhiyun case 181: /* CP EOP event */
6395*4882a593Smuzhiyun DRM_DEBUG("IH: CP EOP\n");
6396*4882a593Smuzhiyun switch (ring_id) {
6397*4882a593Smuzhiyun case 0:
6398*4882a593Smuzhiyun radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
6399*4882a593Smuzhiyun break;
6400*4882a593Smuzhiyun case 1:
6401*4882a593Smuzhiyun radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6402*4882a593Smuzhiyun break;
6403*4882a593Smuzhiyun case 2:
6404*4882a593Smuzhiyun radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6405*4882a593Smuzhiyun break;
6406*4882a593Smuzhiyun }
6407*4882a593Smuzhiyun break;
6408*4882a593Smuzhiyun case 224: /* DMA trap event */
6409*4882a593Smuzhiyun DRM_DEBUG("IH: DMA trap\n");
6410*4882a593Smuzhiyun radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
6411*4882a593Smuzhiyun break;
6412*4882a593Smuzhiyun case 230: /* thermal low to high */
6413*4882a593Smuzhiyun DRM_DEBUG("IH: thermal low to high\n");
6414*4882a593Smuzhiyun rdev->pm.dpm.thermal.high_to_low = false;
6415*4882a593Smuzhiyun queue_thermal = true;
6416*4882a593Smuzhiyun break;
6417*4882a593Smuzhiyun case 231: /* thermal high to low */
6418*4882a593Smuzhiyun DRM_DEBUG("IH: thermal high to low\n");
6419*4882a593Smuzhiyun rdev->pm.dpm.thermal.high_to_low = true;
6420*4882a593Smuzhiyun queue_thermal = true;
6421*4882a593Smuzhiyun break;
6422*4882a593Smuzhiyun case 233: /* GUI IDLE */
6423*4882a593Smuzhiyun DRM_DEBUG("IH: GUI idle\n");
6424*4882a593Smuzhiyun break;
6425*4882a593Smuzhiyun case 244: /* DMA trap event */
6426*4882a593Smuzhiyun DRM_DEBUG("IH: DMA1 trap\n");
6427*4882a593Smuzhiyun radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
6428*4882a593Smuzhiyun break;
6429*4882a593Smuzhiyun default:
6430*4882a593Smuzhiyun DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
6431*4882a593Smuzhiyun break;
6432*4882a593Smuzhiyun }
6433*4882a593Smuzhiyun
6434*4882a593Smuzhiyun /* wptr/rptr are in bytes! */
6435*4882a593Smuzhiyun rptr += 16;
6436*4882a593Smuzhiyun rptr &= rdev->ih.ptr_mask;
6437*4882a593Smuzhiyun WREG32(IH_RB_RPTR, rptr);
6438*4882a593Smuzhiyun }
6439*4882a593Smuzhiyun if (queue_dp)
6440*4882a593Smuzhiyun schedule_work(&rdev->dp_work);
6441*4882a593Smuzhiyun if (queue_hotplug)
6442*4882a593Smuzhiyun schedule_delayed_work(&rdev->hotplug_work, 0);
6443*4882a593Smuzhiyun if (queue_thermal && rdev->pm.dpm_enabled)
6444*4882a593Smuzhiyun schedule_work(&rdev->pm.dpm.thermal.work);
6445*4882a593Smuzhiyun rdev->ih.rptr = rptr;
6446*4882a593Smuzhiyun atomic_set(&rdev->ih.lock, 0);
6447*4882a593Smuzhiyun
6448*4882a593Smuzhiyun /* make sure wptr hasn't changed while processing */
6449*4882a593Smuzhiyun wptr = si_get_ih_wptr(rdev);
6450*4882a593Smuzhiyun if (wptr != rptr)
6451*4882a593Smuzhiyun goto restart_ih;
6452*4882a593Smuzhiyun
6453*4882a593Smuzhiyun return IRQ_HANDLED;
6454*4882a593Smuzhiyun }
6455*4882a593Smuzhiyun
6456*4882a593Smuzhiyun /*
6457*4882a593Smuzhiyun * startup/shutdown callbacks
6458*4882a593Smuzhiyun */
si_uvd_init(struct radeon_device * rdev)6459*4882a593Smuzhiyun static void si_uvd_init(struct radeon_device *rdev)
6460*4882a593Smuzhiyun {
6461*4882a593Smuzhiyun int r;
6462*4882a593Smuzhiyun
6463*4882a593Smuzhiyun if (!rdev->has_uvd)
6464*4882a593Smuzhiyun return;
6465*4882a593Smuzhiyun
6466*4882a593Smuzhiyun r = radeon_uvd_init(rdev);
6467*4882a593Smuzhiyun if (r) {
6468*4882a593Smuzhiyun dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
6469*4882a593Smuzhiyun /*
6470*4882a593Smuzhiyun * At this point rdev->uvd.vcpu_bo is NULL which trickles down
6471*4882a593Smuzhiyun * to early fails uvd_v2_2_resume() and thus nothing happens
6472*4882a593Smuzhiyun * there. So it is pointless to try to go through that code
6473*4882a593Smuzhiyun * hence why we disable uvd here.
6474*4882a593Smuzhiyun */
6475*4882a593Smuzhiyun rdev->has_uvd = false;
6476*4882a593Smuzhiyun return;
6477*4882a593Smuzhiyun }
6478*4882a593Smuzhiyun rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
6479*4882a593Smuzhiyun r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
6480*4882a593Smuzhiyun }
6481*4882a593Smuzhiyun
si_uvd_start(struct radeon_device * rdev)6482*4882a593Smuzhiyun static void si_uvd_start(struct radeon_device *rdev)
6483*4882a593Smuzhiyun {
6484*4882a593Smuzhiyun int r;
6485*4882a593Smuzhiyun
6486*4882a593Smuzhiyun if (!rdev->has_uvd)
6487*4882a593Smuzhiyun return;
6488*4882a593Smuzhiyun
6489*4882a593Smuzhiyun r = uvd_v2_2_resume(rdev);
6490*4882a593Smuzhiyun if (r) {
6491*4882a593Smuzhiyun dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
6492*4882a593Smuzhiyun goto error;
6493*4882a593Smuzhiyun }
6494*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
6495*4882a593Smuzhiyun if (r) {
6496*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
6497*4882a593Smuzhiyun goto error;
6498*4882a593Smuzhiyun }
6499*4882a593Smuzhiyun return;
6500*4882a593Smuzhiyun
6501*4882a593Smuzhiyun error:
6502*4882a593Smuzhiyun rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
6503*4882a593Smuzhiyun }
6504*4882a593Smuzhiyun
si_uvd_resume(struct radeon_device * rdev)6505*4882a593Smuzhiyun static void si_uvd_resume(struct radeon_device *rdev)
6506*4882a593Smuzhiyun {
6507*4882a593Smuzhiyun struct radeon_ring *ring;
6508*4882a593Smuzhiyun int r;
6509*4882a593Smuzhiyun
6510*4882a593Smuzhiyun if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
6511*4882a593Smuzhiyun return;
6512*4882a593Smuzhiyun
6513*4882a593Smuzhiyun ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
6514*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
6515*4882a593Smuzhiyun if (r) {
6516*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
6517*4882a593Smuzhiyun return;
6518*4882a593Smuzhiyun }
6519*4882a593Smuzhiyun r = uvd_v1_0_init(rdev);
6520*4882a593Smuzhiyun if (r) {
6521*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
6522*4882a593Smuzhiyun return;
6523*4882a593Smuzhiyun }
6524*4882a593Smuzhiyun }
6525*4882a593Smuzhiyun
si_vce_init(struct radeon_device * rdev)6526*4882a593Smuzhiyun static void si_vce_init(struct radeon_device *rdev)
6527*4882a593Smuzhiyun {
6528*4882a593Smuzhiyun int r;
6529*4882a593Smuzhiyun
6530*4882a593Smuzhiyun if (!rdev->has_vce)
6531*4882a593Smuzhiyun return;
6532*4882a593Smuzhiyun
6533*4882a593Smuzhiyun r = radeon_vce_init(rdev);
6534*4882a593Smuzhiyun if (r) {
6535*4882a593Smuzhiyun dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
6536*4882a593Smuzhiyun /*
6537*4882a593Smuzhiyun * At this point rdev->vce.vcpu_bo is NULL which trickles down
6538*4882a593Smuzhiyun * to early fails si_vce_start() and thus nothing happens
6539*4882a593Smuzhiyun * there. So it is pointless to try to go through that code
6540*4882a593Smuzhiyun * hence why we disable vce here.
6541*4882a593Smuzhiyun */
6542*4882a593Smuzhiyun rdev->has_vce = false;
6543*4882a593Smuzhiyun return;
6544*4882a593Smuzhiyun }
6545*4882a593Smuzhiyun rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
6546*4882a593Smuzhiyun r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
6547*4882a593Smuzhiyun rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
6548*4882a593Smuzhiyun r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
6549*4882a593Smuzhiyun }
6550*4882a593Smuzhiyun
si_vce_start(struct radeon_device * rdev)6551*4882a593Smuzhiyun static void si_vce_start(struct radeon_device *rdev)
6552*4882a593Smuzhiyun {
6553*4882a593Smuzhiyun int r;
6554*4882a593Smuzhiyun
6555*4882a593Smuzhiyun if (!rdev->has_vce)
6556*4882a593Smuzhiyun return;
6557*4882a593Smuzhiyun
6558*4882a593Smuzhiyun r = radeon_vce_resume(rdev);
6559*4882a593Smuzhiyun if (r) {
6560*4882a593Smuzhiyun dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
6561*4882a593Smuzhiyun goto error;
6562*4882a593Smuzhiyun }
6563*4882a593Smuzhiyun r = vce_v1_0_resume(rdev);
6564*4882a593Smuzhiyun if (r) {
6565*4882a593Smuzhiyun dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
6566*4882a593Smuzhiyun goto error;
6567*4882a593Smuzhiyun }
6568*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
6569*4882a593Smuzhiyun if (r) {
6570*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
6571*4882a593Smuzhiyun goto error;
6572*4882a593Smuzhiyun }
6573*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
6574*4882a593Smuzhiyun if (r) {
6575*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
6576*4882a593Smuzhiyun goto error;
6577*4882a593Smuzhiyun }
6578*4882a593Smuzhiyun return;
6579*4882a593Smuzhiyun
6580*4882a593Smuzhiyun error:
6581*4882a593Smuzhiyun rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
6582*4882a593Smuzhiyun rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
6583*4882a593Smuzhiyun }
6584*4882a593Smuzhiyun
si_vce_resume(struct radeon_device * rdev)6585*4882a593Smuzhiyun static void si_vce_resume(struct radeon_device *rdev)
6586*4882a593Smuzhiyun {
6587*4882a593Smuzhiyun struct radeon_ring *ring;
6588*4882a593Smuzhiyun int r;
6589*4882a593Smuzhiyun
6590*4882a593Smuzhiyun if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
6591*4882a593Smuzhiyun return;
6592*4882a593Smuzhiyun
6593*4882a593Smuzhiyun ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
6594*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
6595*4882a593Smuzhiyun if (r) {
6596*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
6597*4882a593Smuzhiyun return;
6598*4882a593Smuzhiyun }
6599*4882a593Smuzhiyun ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
6600*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
6601*4882a593Smuzhiyun if (r) {
6602*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
6603*4882a593Smuzhiyun return;
6604*4882a593Smuzhiyun }
6605*4882a593Smuzhiyun r = vce_v1_0_init(rdev);
6606*4882a593Smuzhiyun if (r) {
6607*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
6608*4882a593Smuzhiyun return;
6609*4882a593Smuzhiyun }
6610*4882a593Smuzhiyun }
6611*4882a593Smuzhiyun
si_startup(struct radeon_device * rdev)6612*4882a593Smuzhiyun static int si_startup(struct radeon_device *rdev)
6613*4882a593Smuzhiyun {
6614*4882a593Smuzhiyun struct radeon_ring *ring;
6615*4882a593Smuzhiyun int r;
6616*4882a593Smuzhiyun
6617*4882a593Smuzhiyun /* enable pcie gen2/3 link */
6618*4882a593Smuzhiyun si_pcie_gen3_enable(rdev);
6619*4882a593Smuzhiyun /* enable aspm */
6620*4882a593Smuzhiyun si_program_aspm(rdev);
6621*4882a593Smuzhiyun
6622*4882a593Smuzhiyun /* scratch needs to be initialized before MC */
6623*4882a593Smuzhiyun r = r600_vram_scratch_init(rdev);
6624*4882a593Smuzhiyun if (r)
6625*4882a593Smuzhiyun return r;
6626*4882a593Smuzhiyun
6627*4882a593Smuzhiyun si_mc_program(rdev);
6628*4882a593Smuzhiyun
6629*4882a593Smuzhiyun if (!rdev->pm.dpm_enabled) {
6630*4882a593Smuzhiyun r = si_mc_load_microcode(rdev);
6631*4882a593Smuzhiyun if (r) {
6632*4882a593Smuzhiyun DRM_ERROR("Failed to load MC firmware!\n");
6633*4882a593Smuzhiyun return r;
6634*4882a593Smuzhiyun }
6635*4882a593Smuzhiyun }
6636*4882a593Smuzhiyun
6637*4882a593Smuzhiyun r = si_pcie_gart_enable(rdev);
6638*4882a593Smuzhiyun if (r)
6639*4882a593Smuzhiyun return r;
6640*4882a593Smuzhiyun si_gpu_init(rdev);
6641*4882a593Smuzhiyun
6642*4882a593Smuzhiyun /* allocate rlc buffers */
6643*4882a593Smuzhiyun if (rdev->family == CHIP_VERDE) {
6644*4882a593Smuzhiyun rdev->rlc.reg_list = verde_rlc_save_restore_register_list;
6645*4882a593Smuzhiyun rdev->rlc.reg_list_size =
6646*4882a593Smuzhiyun (u32)ARRAY_SIZE(verde_rlc_save_restore_register_list);
6647*4882a593Smuzhiyun }
6648*4882a593Smuzhiyun rdev->rlc.cs_data = si_cs_data;
6649*4882a593Smuzhiyun r = sumo_rlc_init(rdev);
6650*4882a593Smuzhiyun if (r) {
6651*4882a593Smuzhiyun DRM_ERROR("Failed to init rlc BOs!\n");
6652*4882a593Smuzhiyun return r;
6653*4882a593Smuzhiyun }
6654*4882a593Smuzhiyun
6655*4882a593Smuzhiyun /* allocate wb buffer */
6656*4882a593Smuzhiyun r = radeon_wb_init(rdev);
6657*4882a593Smuzhiyun if (r)
6658*4882a593Smuzhiyun return r;
6659*4882a593Smuzhiyun
6660*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
6661*4882a593Smuzhiyun if (r) {
6662*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6663*4882a593Smuzhiyun return r;
6664*4882a593Smuzhiyun }
6665*4882a593Smuzhiyun
6666*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6667*4882a593Smuzhiyun if (r) {
6668*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6669*4882a593Smuzhiyun return r;
6670*4882a593Smuzhiyun }
6671*4882a593Smuzhiyun
6672*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6673*4882a593Smuzhiyun if (r) {
6674*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6675*4882a593Smuzhiyun return r;
6676*4882a593Smuzhiyun }
6677*4882a593Smuzhiyun
6678*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
6679*4882a593Smuzhiyun if (r) {
6680*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
6681*4882a593Smuzhiyun return r;
6682*4882a593Smuzhiyun }
6683*4882a593Smuzhiyun
6684*4882a593Smuzhiyun r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
6685*4882a593Smuzhiyun if (r) {
6686*4882a593Smuzhiyun dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
6687*4882a593Smuzhiyun return r;
6688*4882a593Smuzhiyun }
6689*4882a593Smuzhiyun
6690*4882a593Smuzhiyun si_uvd_start(rdev);
6691*4882a593Smuzhiyun si_vce_start(rdev);
6692*4882a593Smuzhiyun
6693*4882a593Smuzhiyun /* Enable IRQ */
6694*4882a593Smuzhiyun if (!rdev->irq.installed) {
6695*4882a593Smuzhiyun r = radeon_irq_kms_init(rdev);
6696*4882a593Smuzhiyun if (r)
6697*4882a593Smuzhiyun return r;
6698*4882a593Smuzhiyun }
6699*4882a593Smuzhiyun
6700*4882a593Smuzhiyun r = si_irq_init(rdev);
6701*4882a593Smuzhiyun if (r) {
6702*4882a593Smuzhiyun DRM_ERROR("radeon: IH init failed (%d).\n", r);
6703*4882a593Smuzhiyun radeon_irq_kms_fini(rdev);
6704*4882a593Smuzhiyun return r;
6705*4882a593Smuzhiyun }
6706*4882a593Smuzhiyun si_irq_set(rdev);
6707*4882a593Smuzhiyun
6708*4882a593Smuzhiyun ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6709*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
6710*4882a593Smuzhiyun RADEON_CP_PACKET2);
6711*4882a593Smuzhiyun if (r)
6712*4882a593Smuzhiyun return r;
6713*4882a593Smuzhiyun
6714*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
6715*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
6716*4882a593Smuzhiyun RADEON_CP_PACKET2);
6717*4882a593Smuzhiyun if (r)
6718*4882a593Smuzhiyun return r;
6719*4882a593Smuzhiyun
6720*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
6721*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
6722*4882a593Smuzhiyun RADEON_CP_PACKET2);
6723*4882a593Smuzhiyun if (r)
6724*4882a593Smuzhiyun return r;
6725*4882a593Smuzhiyun
6726*4882a593Smuzhiyun ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
6727*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
6728*4882a593Smuzhiyun DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
6729*4882a593Smuzhiyun if (r)
6730*4882a593Smuzhiyun return r;
6731*4882a593Smuzhiyun
6732*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
6733*4882a593Smuzhiyun r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
6734*4882a593Smuzhiyun DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
6735*4882a593Smuzhiyun if (r)
6736*4882a593Smuzhiyun return r;
6737*4882a593Smuzhiyun
6738*4882a593Smuzhiyun r = si_cp_load_microcode(rdev);
6739*4882a593Smuzhiyun if (r)
6740*4882a593Smuzhiyun return r;
6741*4882a593Smuzhiyun r = si_cp_resume(rdev);
6742*4882a593Smuzhiyun if (r)
6743*4882a593Smuzhiyun return r;
6744*4882a593Smuzhiyun
6745*4882a593Smuzhiyun r = cayman_dma_resume(rdev);
6746*4882a593Smuzhiyun if (r)
6747*4882a593Smuzhiyun return r;
6748*4882a593Smuzhiyun
6749*4882a593Smuzhiyun si_uvd_resume(rdev);
6750*4882a593Smuzhiyun si_vce_resume(rdev);
6751*4882a593Smuzhiyun
6752*4882a593Smuzhiyun r = radeon_ib_pool_init(rdev);
6753*4882a593Smuzhiyun if (r) {
6754*4882a593Smuzhiyun dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
6755*4882a593Smuzhiyun return r;
6756*4882a593Smuzhiyun }
6757*4882a593Smuzhiyun
6758*4882a593Smuzhiyun r = radeon_vm_manager_init(rdev);
6759*4882a593Smuzhiyun if (r) {
6760*4882a593Smuzhiyun dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
6761*4882a593Smuzhiyun return r;
6762*4882a593Smuzhiyun }
6763*4882a593Smuzhiyun
6764*4882a593Smuzhiyun r = radeon_audio_init(rdev);
6765*4882a593Smuzhiyun if (r)
6766*4882a593Smuzhiyun return r;
6767*4882a593Smuzhiyun
6768*4882a593Smuzhiyun return 0;
6769*4882a593Smuzhiyun }
6770*4882a593Smuzhiyun
si_resume(struct radeon_device * rdev)6771*4882a593Smuzhiyun int si_resume(struct radeon_device *rdev)
6772*4882a593Smuzhiyun {
6773*4882a593Smuzhiyun int r;
6774*4882a593Smuzhiyun
6775*4882a593Smuzhiyun /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
6776*4882a593Smuzhiyun * posting will perform necessary task to bring back GPU into good
6777*4882a593Smuzhiyun * shape.
6778*4882a593Smuzhiyun */
6779*4882a593Smuzhiyun /* post card */
6780*4882a593Smuzhiyun atom_asic_init(rdev->mode_info.atom_context);
6781*4882a593Smuzhiyun
6782*4882a593Smuzhiyun /* init golden registers */
6783*4882a593Smuzhiyun si_init_golden_registers(rdev);
6784*4882a593Smuzhiyun
6785*4882a593Smuzhiyun if (rdev->pm.pm_method == PM_METHOD_DPM)
6786*4882a593Smuzhiyun radeon_pm_resume(rdev);
6787*4882a593Smuzhiyun
6788*4882a593Smuzhiyun rdev->accel_working = true;
6789*4882a593Smuzhiyun r = si_startup(rdev);
6790*4882a593Smuzhiyun if (r) {
6791*4882a593Smuzhiyun DRM_ERROR("si startup failed on resume\n");
6792*4882a593Smuzhiyun rdev->accel_working = false;
6793*4882a593Smuzhiyun return r;
6794*4882a593Smuzhiyun }
6795*4882a593Smuzhiyun
6796*4882a593Smuzhiyun return r;
6797*4882a593Smuzhiyun
6798*4882a593Smuzhiyun }
6799*4882a593Smuzhiyun
si_suspend(struct radeon_device * rdev)6800*4882a593Smuzhiyun int si_suspend(struct radeon_device *rdev)
6801*4882a593Smuzhiyun {
6802*4882a593Smuzhiyun radeon_pm_suspend(rdev);
6803*4882a593Smuzhiyun radeon_audio_fini(rdev);
6804*4882a593Smuzhiyun radeon_vm_manager_fini(rdev);
6805*4882a593Smuzhiyun si_cp_enable(rdev, false);
6806*4882a593Smuzhiyun cayman_dma_stop(rdev);
6807*4882a593Smuzhiyun if (rdev->has_uvd) {
6808*4882a593Smuzhiyun uvd_v1_0_fini(rdev);
6809*4882a593Smuzhiyun radeon_uvd_suspend(rdev);
6810*4882a593Smuzhiyun }
6811*4882a593Smuzhiyun if (rdev->has_vce)
6812*4882a593Smuzhiyun radeon_vce_suspend(rdev);
6813*4882a593Smuzhiyun si_fini_pg(rdev);
6814*4882a593Smuzhiyun si_fini_cg(rdev);
6815*4882a593Smuzhiyun si_irq_suspend(rdev);
6816*4882a593Smuzhiyun radeon_wb_disable(rdev);
6817*4882a593Smuzhiyun si_pcie_gart_disable(rdev);
6818*4882a593Smuzhiyun return 0;
6819*4882a593Smuzhiyun }
6820*4882a593Smuzhiyun
6821*4882a593Smuzhiyun /* Plan is to move initialization in that function and use
6822*4882a593Smuzhiyun * helper function so that radeon_device_init pretty much
6823*4882a593Smuzhiyun * do nothing more than calling asic specific function. This
6824*4882a593Smuzhiyun * should also allow to remove a bunch of callback function
6825*4882a593Smuzhiyun * like vram_info.
6826*4882a593Smuzhiyun */
si_init(struct radeon_device * rdev)6827*4882a593Smuzhiyun int si_init(struct radeon_device *rdev)
6828*4882a593Smuzhiyun {
6829*4882a593Smuzhiyun struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6830*4882a593Smuzhiyun int r;
6831*4882a593Smuzhiyun
6832*4882a593Smuzhiyun /* Read BIOS */
6833*4882a593Smuzhiyun if (!radeon_get_bios(rdev)) {
6834*4882a593Smuzhiyun if (ASIC_IS_AVIVO(rdev))
6835*4882a593Smuzhiyun return -EINVAL;
6836*4882a593Smuzhiyun }
6837*4882a593Smuzhiyun /* Must be an ATOMBIOS */
6838*4882a593Smuzhiyun if (!rdev->is_atom_bios) {
6839*4882a593Smuzhiyun dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
6840*4882a593Smuzhiyun return -EINVAL;
6841*4882a593Smuzhiyun }
6842*4882a593Smuzhiyun r = radeon_atombios_init(rdev);
6843*4882a593Smuzhiyun if (r)
6844*4882a593Smuzhiyun return r;
6845*4882a593Smuzhiyun
6846*4882a593Smuzhiyun /* Post card if necessary */
6847*4882a593Smuzhiyun if (!radeon_card_posted(rdev)) {
6848*4882a593Smuzhiyun if (!rdev->bios) {
6849*4882a593Smuzhiyun dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
6850*4882a593Smuzhiyun return -EINVAL;
6851*4882a593Smuzhiyun }
6852*4882a593Smuzhiyun DRM_INFO("GPU not posted. posting now...\n");
6853*4882a593Smuzhiyun atom_asic_init(rdev->mode_info.atom_context);
6854*4882a593Smuzhiyun }
6855*4882a593Smuzhiyun /* init golden registers */
6856*4882a593Smuzhiyun si_init_golden_registers(rdev);
6857*4882a593Smuzhiyun /* Initialize scratch registers */
6858*4882a593Smuzhiyun si_scratch_init(rdev);
6859*4882a593Smuzhiyun /* Initialize surface registers */
6860*4882a593Smuzhiyun radeon_surface_init(rdev);
6861*4882a593Smuzhiyun /* Initialize clocks */
6862*4882a593Smuzhiyun radeon_get_clock_info(rdev->ddev);
6863*4882a593Smuzhiyun
6864*4882a593Smuzhiyun /* Fence driver */
6865*4882a593Smuzhiyun r = radeon_fence_driver_init(rdev);
6866*4882a593Smuzhiyun if (r)
6867*4882a593Smuzhiyun return r;
6868*4882a593Smuzhiyun
6869*4882a593Smuzhiyun /* initialize memory controller */
6870*4882a593Smuzhiyun r = si_mc_init(rdev);
6871*4882a593Smuzhiyun if (r)
6872*4882a593Smuzhiyun return r;
6873*4882a593Smuzhiyun /* Memory manager */
6874*4882a593Smuzhiyun r = radeon_bo_init(rdev);
6875*4882a593Smuzhiyun if (r)
6876*4882a593Smuzhiyun return r;
6877*4882a593Smuzhiyun
6878*4882a593Smuzhiyun if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
6879*4882a593Smuzhiyun !rdev->rlc_fw || !rdev->mc_fw) {
6880*4882a593Smuzhiyun r = si_init_microcode(rdev);
6881*4882a593Smuzhiyun if (r) {
6882*4882a593Smuzhiyun DRM_ERROR("Failed to load firmware!\n");
6883*4882a593Smuzhiyun return r;
6884*4882a593Smuzhiyun }
6885*4882a593Smuzhiyun }
6886*4882a593Smuzhiyun
6887*4882a593Smuzhiyun /* Initialize power management */
6888*4882a593Smuzhiyun radeon_pm_init(rdev);
6889*4882a593Smuzhiyun
6890*4882a593Smuzhiyun ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6891*4882a593Smuzhiyun ring->ring_obj = NULL;
6892*4882a593Smuzhiyun r600_ring_init(rdev, ring, 1024 * 1024);
6893*4882a593Smuzhiyun
6894*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
6895*4882a593Smuzhiyun ring->ring_obj = NULL;
6896*4882a593Smuzhiyun r600_ring_init(rdev, ring, 1024 * 1024);
6897*4882a593Smuzhiyun
6898*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
6899*4882a593Smuzhiyun ring->ring_obj = NULL;
6900*4882a593Smuzhiyun r600_ring_init(rdev, ring, 1024 * 1024);
6901*4882a593Smuzhiyun
6902*4882a593Smuzhiyun ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
6903*4882a593Smuzhiyun ring->ring_obj = NULL;
6904*4882a593Smuzhiyun r600_ring_init(rdev, ring, 64 * 1024);
6905*4882a593Smuzhiyun
6906*4882a593Smuzhiyun ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
6907*4882a593Smuzhiyun ring->ring_obj = NULL;
6908*4882a593Smuzhiyun r600_ring_init(rdev, ring, 64 * 1024);
6909*4882a593Smuzhiyun
6910*4882a593Smuzhiyun si_uvd_init(rdev);
6911*4882a593Smuzhiyun si_vce_init(rdev);
6912*4882a593Smuzhiyun
6913*4882a593Smuzhiyun rdev->ih.ring_obj = NULL;
6914*4882a593Smuzhiyun r600_ih_ring_init(rdev, 64 * 1024);
6915*4882a593Smuzhiyun
6916*4882a593Smuzhiyun r = r600_pcie_gart_init(rdev);
6917*4882a593Smuzhiyun if (r)
6918*4882a593Smuzhiyun return r;
6919*4882a593Smuzhiyun
6920*4882a593Smuzhiyun rdev->accel_working = true;
6921*4882a593Smuzhiyun r = si_startup(rdev);
6922*4882a593Smuzhiyun if (r) {
6923*4882a593Smuzhiyun dev_err(rdev->dev, "disabling GPU acceleration\n");
6924*4882a593Smuzhiyun si_cp_fini(rdev);
6925*4882a593Smuzhiyun cayman_dma_fini(rdev);
6926*4882a593Smuzhiyun si_irq_fini(rdev);
6927*4882a593Smuzhiyun sumo_rlc_fini(rdev);
6928*4882a593Smuzhiyun radeon_wb_fini(rdev);
6929*4882a593Smuzhiyun radeon_ib_pool_fini(rdev);
6930*4882a593Smuzhiyun radeon_vm_manager_fini(rdev);
6931*4882a593Smuzhiyun radeon_irq_kms_fini(rdev);
6932*4882a593Smuzhiyun si_pcie_gart_fini(rdev);
6933*4882a593Smuzhiyun rdev->accel_working = false;
6934*4882a593Smuzhiyun }
6935*4882a593Smuzhiyun
6936*4882a593Smuzhiyun /* Don't start up if the MC ucode is missing.
6937*4882a593Smuzhiyun * The default clocks and voltages before the MC ucode
6938*4882a593Smuzhiyun * is loaded are not suffient for advanced operations.
6939*4882a593Smuzhiyun */
6940*4882a593Smuzhiyun if (!rdev->mc_fw) {
6941*4882a593Smuzhiyun DRM_ERROR("radeon: MC ucode required for NI+.\n");
6942*4882a593Smuzhiyun return -EINVAL;
6943*4882a593Smuzhiyun }
6944*4882a593Smuzhiyun
6945*4882a593Smuzhiyun return 0;
6946*4882a593Smuzhiyun }
6947*4882a593Smuzhiyun
si_fini(struct radeon_device * rdev)6948*4882a593Smuzhiyun void si_fini(struct radeon_device *rdev)
6949*4882a593Smuzhiyun {
6950*4882a593Smuzhiyun radeon_pm_fini(rdev);
6951*4882a593Smuzhiyun si_cp_fini(rdev);
6952*4882a593Smuzhiyun cayman_dma_fini(rdev);
6953*4882a593Smuzhiyun si_fini_pg(rdev);
6954*4882a593Smuzhiyun si_fini_cg(rdev);
6955*4882a593Smuzhiyun si_irq_fini(rdev);
6956*4882a593Smuzhiyun sumo_rlc_fini(rdev);
6957*4882a593Smuzhiyun radeon_wb_fini(rdev);
6958*4882a593Smuzhiyun radeon_vm_manager_fini(rdev);
6959*4882a593Smuzhiyun radeon_ib_pool_fini(rdev);
6960*4882a593Smuzhiyun radeon_irq_kms_fini(rdev);
6961*4882a593Smuzhiyun if (rdev->has_uvd) {
6962*4882a593Smuzhiyun uvd_v1_0_fini(rdev);
6963*4882a593Smuzhiyun radeon_uvd_fini(rdev);
6964*4882a593Smuzhiyun }
6965*4882a593Smuzhiyun if (rdev->has_vce)
6966*4882a593Smuzhiyun radeon_vce_fini(rdev);
6967*4882a593Smuzhiyun si_pcie_gart_fini(rdev);
6968*4882a593Smuzhiyun r600_vram_scratch_fini(rdev);
6969*4882a593Smuzhiyun radeon_gem_fini(rdev);
6970*4882a593Smuzhiyun radeon_fence_driver_fini(rdev);
6971*4882a593Smuzhiyun radeon_bo_fini(rdev);
6972*4882a593Smuzhiyun radeon_atombios_fini(rdev);
6973*4882a593Smuzhiyun kfree(rdev->bios);
6974*4882a593Smuzhiyun rdev->bios = NULL;
6975*4882a593Smuzhiyun }
6976*4882a593Smuzhiyun
6977*4882a593Smuzhiyun /**
6978*4882a593Smuzhiyun * si_get_gpu_clock_counter - return GPU clock counter snapshot
6979*4882a593Smuzhiyun *
6980*4882a593Smuzhiyun * @rdev: radeon_device pointer
6981*4882a593Smuzhiyun *
6982*4882a593Smuzhiyun * Fetches a GPU clock counter snapshot (SI).
6983*4882a593Smuzhiyun * Returns the 64 bit clock counter snapshot.
6984*4882a593Smuzhiyun */
si_get_gpu_clock_counter(struct radeon_device * rdev)6985*4882a593Smuzhiyun uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev)
6986*4882a593Smuzhiyun {
6987*4882a593Smuzhiyun uint64_t clock;
6988*4882a593Smuzhiyun
6989*4882a593Smuzhiyun mutex_lock(&rdev->gpu_clock_mutex);
6990*4882a593Smuzhiyun WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
6991*4882a593Smuzhiyun clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
6992*4882a593Smuzhiyun ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
6993*4882a593Smuzhiyun mutex_unlock(&rdev->gpu_clock_mutex);
6994*4882a593Smuzhiyun return clock;
6995*4882a593Smuzhiyun }
6996*4882a593Smuzhiyun
si_set_uvd_clocks(struct radeon_device * rdev,u32 vclk,u32 dclk)6997*4882a593Smuzhiyun int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
6998*4882a593Smuzhiyun {
6999*4882a593Smuzhiyun unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
7000*4882a593Smuzhiyun int r;
7001*4882a593Smuzhiyun
7002*4882a593Smuzhiyun /* bypass vclk and dclk with bclk */
7003*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_2,
7004*4882a593Smuzhiyun VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
7005*4882a593Smuzhiyun ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
7006*4882a593Smuzhiyun
7007*4882a593Smuzhiyun /* put PLL in bypass mode */
7008*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
7009*4882a593Smuzhiyun
7010*4882a593Smuzhiyun if (!vclk || !dclk) {
7011*4882a593Smuzhiyun /* keep the Bypass mode */
7012*4882a593Smuzhiyun return 0;
7013*4882a593Smuzhiyun }
7014*4882a593Smuzhiyun
7015*4882a593Smuzhiyun r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000,
7016*4882a593Smuzhiyun 16384, 0x03FFFFFF, 0, 128, 5,
7017*4882a593Smuzhiyun &fb_div, &vclk_div, &dclk_div);
7018*4882a593Smuzhiyun if (r)
7019*4882a593Smuzhiyun return r;
7020*4882a593Smuzhiyun
7021*4882a593Smuzhiyun /* set RESET_ANTI_MUX to 0 */
7022*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
7023*4882a593Smuzhiyun
7024*4882a593Smuzhiyun /* set VCO_MODE to 1 */
7025*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
7026*4882a593Smuzhiyun
7027*4882a593Smuzhiyun /* disable sleep mode */
7028*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
7029*4882a593Smuzhiyun
7030*4882a593Smuzhiyun /* deassert UPLL_RESET */
7031*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
7032*4882a593Smuzhiyun
7033*4882a593Smuzhiyun mdelay(1);
7034*4882a593Smuzhiyun
7035*4882a593Smuzhiyun r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
7036*4882a593Smuzhiyun if (r)
7037*4882a593Smuzhiyun return r;
7038*4882a593Smuzhiyun
7039*4882a593Smuzhiyun /* assert UPLL_RESET again */
7040*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
7041*4882a593Smuzhiyun
7042*4882a593Smuzhiyun /* disable spread spectrum. */
7043*4882a593Smuzhiyun WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
7044*4882a593Smuzhiyun
7045*4882a593Smuzhiyun /* set feedback divider */
7046*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK);
7047*4882a593Smuzhiyun
7048*4882a593Smuzhiyun /* set ref divider to 0 */
7049*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
7050*4882a593Smuzhiyun
7051*4882a593Smuzhiyun if (fb_div < 307200)
7052*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
7053*4882a593Smuzhiyun else
7054*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
7055*4882a593Smuzhiyun
7056*4882a593Smuzhiyun /* set PDIV_A and PDIV_B */
7057*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_2,
7058*4882a593Smuzhiyun UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div),
7059*4882a593Smuzhiyun ~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
7060*4882a593Smuzhiyun
7061*4882a593Smuzhiyun /* give the PLL some time to settle */
7062*4882a593Smuzhiyun mdelay(15);
7063*4882a593Smuzhiyun
7064*4882a593Smuzhiyun /* deassert PLL_RESET */
7065*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
7066*4882a593Smuzhiyun
7067*4882a593Smuzhiyun mdelay(15);
7068*4882a593Smuzhiyun
7069*4882a593Smuzhiyun /* switch from bypass mode to normal mode */
7070*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
7071*4882a593Smuzhiyun
7072*4882a593Smuzhiyun r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
7073*4882a593Smuzhiyun if (r)
7074*4882a593Smuzhiyun return r;
7075*4882a593Smuzhiyun
7076*4882a593Smuzhiyun /* switch VCLK and DCLK selection */
7077*4882a593Smuzhiyun WREG32_P(CG_UPLL_FUNC_CNTL_2,
7078*4882a593Smuzhiyun VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
7079*4882a593Smuzhiyun ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
7080*4882a593Smuzhiyun
7081*4882a593Smuzhiyun mdelay(100);
7082*4882a593Smuzhiyun
7083*4882a593Smuzhiyun return 0;
7084*4882a593Smuzhiyun }
7085*4882a593Smuzhiyun
si_pcie_gen3_enable(struct radeon_device * rdev)7086*4882a593Smuzhiyun static void si_pcie_gen3_enable(struct radeon_device *rdev)
7087*4882a593Smuzhiyun {
7088*4882a593Smuzhiyun struct pci_dev *root = rdev->pdev->bus->self;
7089*4882a593Smuzhiyun enum pci_bus_speed speed_cap;
7090*4882a593Smuzhiyun u32 speed_cntl, current_data_rate;
7091*4882a593Smuzhiyun int i;
7092*4882a593Smuzhiyun u16 tmp16;
7093*4882a593Smuzhiyun
7094*4882a593Smuzhiyun if (pci_is_root_bus(rdev->pdev->bus))
7095*4882a593Smuzhiyun return;
7096*4882a593Smuzhiyun
7097*4882a593Smuzhiyun if (radeon_pcie_gen2 == 0)
7098*4882a593Smuzhiyun return;
7099*4882a593Smuzhiyun
7100*4882a593Smuzhiyun if (rdev->flags & RADEON_IS_IGP)
7101*4882a593Smuzhiyun return;
7102*4882a593Smuzhiyun
7103*4882a593Smuzhiyun if (!(rdev->flags & RADEON_IS_PCIE))
7104*4882a593Smuzhiyun return;
7105*4882a593Smuzhiyun
7106*4882a593Smuzhiyun speed_cap = pcie_get_speed_cap(root);
7107*4882a593Smuzhiyun if (speed_cap == PCI_SPEED_UNKNOWN)
7108*4882a593Smuzhiyun return;
7109*4882a593Smuzhiyun
7110*4882a593Smuzhiyun if ((speed_cap != PCIE_SPEED_8_0GT) &&
7111*4882a593Smuzhiyun (speed_cap != PCIE_SPEED_5_0GT))
7112*4882a593Smuzhiyun return;
7113*4882a593Smuzhiyun
7114*4882a593Smuzhiyun speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
7115*4882a593Smuzhiyun current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
7116*4882a593Smuzhiyun LC_CURRENT_DATA_RATE_SHIFT;
7117*4882a593Smuzhiyun if (speed_cap == PCIE_SPEED_8_0GT) {
7118*4882a593Smuzhiyun if (current_data_rate == 2) {
7119*4882a593Smuzhiyun DRM_INFO("PCIE gen 3 link speeds already enabled\n");
7120*4882a593Smuzhiyun return;
7121*4882a593Smuzhiyun }
7122*4882a593Smuzhiyun DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n");
7123*4882a593Smuzhiyun } else if (speed_cap == PCIE_SPEED_5_0GT) {
7124*4882a593Smuzhiyun if (current_data_rate == 1) {
7125*4882a593Smuzhiyun DRM_INFO("PCIE gen 2 link speeds already enabled\n");
7126*4882a593Smuzhiyun return;
7127*4882a593Smuzhiyun }
7128*4882a593Smuzhiyun DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
7129*4882a593Smuzhiyun }
7130*4882a593Smuzhiyun
7131*4882a593Smuzhiyun if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev))
7132*4882a593Smuzhiyun return;
7133*4882a593Smuzhiyun
7134*4882a593Smuzhiyun if (speed_cap == PCIE_SPEED_8_0GT) {
7135*4882a593Smuzhiyun /* re-try equalization if gen3 is not already enabled */
7136*4882a593Smuzhiyun if (current_data_rate != 2) {
7137*4882a593Smuzhiyun u16 bridge_cfg, gpu_cfg;
7138*4882a593Smuzhiyun u16 bridge_cfg2, gpu_cfg2;
7139*4882a593Smuzhiyun u32 max_lw, current_lw, tmp;
7140*4882a593Smuzhiyun
7141*4882a593Smuzhiyun pcie_capability_read_word(root, PCI_EXP_LNKCTL,
7142*4882a593Smuzhiyun &bridge_cfg);
7143*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
7144*4882a593Smuzhiyun &gpu_cfg);
7145*4882a593Smuzhiyun
7146*4882a593Smuzhiyun tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
7147*4882a593Smuzhiyun pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
7148*4882a593Smuzhiyun
7149*4882a593Smuzhiyun tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
7150*4882a593Smuzhiyun pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
7151*4882a593Smuzhiyun tmp16);
7152*4882a593Smuzhiyun
7153*4882a593Smuzhiyun tmp = RREG32_PCIE(PCIE_LC_STATUS1);
7154*4882a593Smuzhiyun max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
7155*4882a593Smuzhiyun current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT;
7156*4882a593Smuzhiyun
7157*4882a593Smuzhiyun if (current_lw < max_lw) {
7158*4882a593Smuzhiyun tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
7159*4882a593Smuzhiyun if (tmp & LC_RENEGOTIATION_SUPPORT) {
7160*4882a593Smuzhiyun tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS);
7161*4882a593Smuzhiyun tmp |= (max_lw << LC_LINK_WIDTH_SHIFT);
7162*4882a593Smuzhiyun tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW;
7163*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp);
7164*4882a593Smuzhiyun }
7165*4882a593Smuzhiyun }
7166*4882a593Smuzhiyun
7167*4882a593Smuzhiyun for (i = 0; i < 10; i++) {
7168*4882a593Smuzhiyun /* check status */
7169*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev,
7170*4882a593Smuzhiyun PCI_EXP_DEVSTA,
7171*4882a593Smuzhiyun &tmp16);
7172*4882a593Smuzhiyun if (tmp16 & PCI_EXP_DEVSTA_TRPND)
7173*4882a593Smuzhiyun break;
7174*4882a593Smuzhiyun
7175*4882a593Smuzhiyun pcie_capability_read_word(root, PCI_EXP_LNKCTL,
7176*4882a593Smuzhiyun &bridge_cfg);
7177*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev,
7178*4882a593Smuzhiyun PCI_EXP_LNKCTL,
7179*4882a593Smuzhiyun &gpu_cfg);
7180*4882a593Smuzhiyun
7181*4882a593Smuzhiyun pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
7182*4882a593Smuzhiyun &bridge_cfg2);
7183*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev,
7184*4882a593Smuzhiyun PCI_EXP_LNKCTL2,
7185*4882a593Smuzhiyun &gpu_cfg2);
7186*4882a593Smuzhiyun
7187*4882a593Smuzhiyun tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
7188*4882a593Smuzhiyun tmp |= LC_SET_QUIESCE;
7189*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
7190*4882a593Smuzhiyun
7191*4882a593Smuzhiyun tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
7192*4882a593Smuzhiyun tmp |= LC_REDO_EQ;
7193*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
7194*4882a593Smuzhiyun
7195*4882a593Smuzhiyun msleep(100);
7196*4882a593Smuzhiyun
7197*4882a593Smuzhiyun /* linkctl */
7198*4882a593Smuzhiyun pcie_capability_read_word(root, PCI_EXP_LNKCTL,
7199*4882a593Smuzhiyun &tmp16);
7200*4882a593Smuzhiyun tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
7201*4882a593Smuzhiyun tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
7202*4882a593Smuzhiyun pcie_capability_write_word(root,
7203*4882a593Smuzhiyun PCI_EXP_LNKCTL,
7204*4882a593Smuzhiyun tmp16);
7205*4882a593Smuzhiyun
7206*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev,
7207*4882a593Smuzhiyun PCI_EXP_LNKCTL,
7208*4882a593Smuzhiyun &tmp16);
7209*4882a593Smuzhiyun tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
7210*4882a593Smuzhiyun tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
7211*4882a593Smuzhiyun pcie_capability_write_word(rdev->pdev,
7212*4882a593Smuzhiyun PCI_EXP_LNKCTL,
7213*4882a593Smuzhiyun tmp16);
7214*4882a593Smuzhiyun
7215*4882a593Smuzhiyun /* linkctl2 */
7216*4882a593Smuzhiyun pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
7217*4882a593Smuzhiyun &tmp16);
7218*4882a593Smuzhiyun tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
7219*4882a593Smuzhiyun PCI_EXP_LNKCTL2_TX_MARGIN);
7220*4882a593Smuzhiyun tmp16 |= (bridge_cfg2 &
7221*4882a593Smuzhiyun (PCI_EXP_LNKCTL2_ENTER_COMP |
7222*4882a593Smuzhiyun PCI_EXP_LNKCTL2_TX_MARGIN));
7223*4882a593Smuzhiyun pcie_capability_write_word(root,
7224*4882a593Smuzhiyun PCI_EXP_LNKCTL2,
7225*4882a593Smuzhiyun tmp16);
7226*4882a593Smuzhiyun
7227*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev,
7228*4882a593Smuzhiyun PCI_EXP_LNKCTL2,
7229*4882a593Smuzhiyun &tmp16);
7230*4882a593Smuzhiyun tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
7231*4882a593Smuzhiyun PCI_EXP_LNKCTL2_TX_MARGIN);
7232*4882a593Smuzhiyun tmp16 |= (gpu_cfg2 &
7233*4882a593Smuzhiyun (PCI_EXP_LNKCTL2_ENTER_COMP |
7234*4882a593Smuzhiyun PCI_EXP_LNKCTL2_TX_MARGIN));
7235*4882a593Smuzhiyun pcie_capability_write_word(rdev->pdev,
7236*4882a593Smuzhiyun PCI_EXP_LNKCTL2,
7237*4882a593Smuzhiyun tmp16);
7238*4882a593Smuzhiyun
7239*4882a593Smuzhiyun tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
7240*4882a593Smuzhiyun tmp &= ~LC_SET_QUIESCE;
7241*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
7242*4882a593Smuzhiyun }
7243*4882a593Smuzhiyun }
7244*4882a593Smuzhiyun }
7245*4882a593Smuzhiyun
7246*4882a593Smuzhiyun /* set the link speed */
7247*4882a593Smuzhiyun speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE;
7248*4882a593Smuzhiyun speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
7249*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
7250*4882a593Smuzhiyun
7251*4882a593Smuzhiyun pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16);
7252*4882a593Smuzhiyun tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
7253*4882a593Smuzhiyun if (speed_cap == PCIE_SPEED_8_0GT)
7254*4882a593Smuzhiyun tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
7255*4882a593Smuzhiyun else if (speed_cap == PCIE_SPEED_5_0GT)
7256*4882a593Smuzhiyun tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
7257*4882a593Smuzhiyun else
7258*4882a593Smuzhiyun tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
7259*4882a593Smuzhiyun pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16);
7260*4882a593Smuzhiyun
7261*4882a593Smuzhiyun speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
7262*4882a593Smuzhiyun speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
7263*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
7264*4882a593Smuzhiyun
7265*4882a593Smuzhiyun for (i = 0; i < rdev->usec_timeout; i++) {
7266*4882a593Smuzhiyun speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
7267*4882a593Smuzhiyun if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0)
7268*4882a593Smuzhiyun break;
7269*4882a593Smuzhiyun udelay(1);
7270*4882a593Smuzhiyun }
7271*4882a593Smuzhiyun }
7272*4882a593Smuzhiyun
si_program_aspm(struct radeon_device * rdev)7273*4882a593Smuzhiyun static void si_program_aspm(struct radeon_device *rdev)
7274*4882a593Smuzhiyun {
7275*4882a593Smuzhiyun u32 data, orig;
7276*4882a593Smuzhiyun bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
7277*4882a593Smuzhiyun bool disable_clkreq = false;
7278*4882a593Smuzhiyun
7279*4882a593Smuzhiyun if (radeon_aspm == 0)
7280*4882a593Smuzhiyun return;
7281*4882a593Smuzhiyun
7282*4882a593Smuzhiyun if (!(rdev->flags & RADEON_IS_PCIE))
7283*4882a593Smuzhiyun return;
7284*4882a593Smuzhiyun
7285*4882a593Smuzhiyun orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
7286*4882a593Smuzhiyun data &= ~LC_XMIT_N_FTS_MASK;
7287*4882a593Smuzhiyun data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
7288*4882a593Smuzhiyun if (orig != data)
7289*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data);
7290*4882a593Smuzhiyun
7291*4882a593Smuzhiyun orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3);
7292*4882a593Smuzhiyun data |= LC_GO_TO_RECOVERY;
7293*4882a593Smuzhiyun if (orig != data)
7294*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL3, data);
7295*4882a593Smuzhiyun
7296*4882a593Smuzhiyun orig = data = RREG32_PCIE(PCIE_P_CNTL);
7297*4882a593Smuzhiyun data |= P_IGNORE_EDB_ERR;
7298*4882a593Smuzhiyun if (orig != data)
7299*4882a593Smuzhiyun WREG32_PCIE(PCIE_P_CNTL, data);
7300*4882a593Smuzhiyun
7301*4882a593Smuzhiyun orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
7302*4882a593Smuzhiyun data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
7303*4882a593Smuzhiyun data |= LC_PMI_TO_L1_DIS;
7304*4882a593Smuzhiyun if (!disable_l0s)
7305*4882a593Smuzhiyun data |= LC_L0S_INACTIVITY(7);
7306*4882a593Smuzhiyun
7307*4882a593Smuzhiyun if (!disable_l1) {
7308*4882a593Smuzhiyun data |= LC_L1_INACTIVITY(7);
7309*4882a593Smuzhiyun data &= ~LC_PMI_TO_L1_DIS;
7310*4882a593Smuzhiyun if (orig != data)
7311*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
7312*4882a593Smuzhiyun
7313*4882a593Smuzhiyun if (!disable_plloff_in_l1) {
7314*4882a593Smuzhiyun bool clk_req_support;
7315*4882a593Smuzhiyun
7316*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
7317*4882a593Smuzhiyun data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
7318*4882a593Smuzhiyun data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
7319*4882a593Smuzhiyun if (orig != data)
7320*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
7321*4882a593Smuzhiyun
7322*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
7323*4882a593Smuzhiyun data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
7324*4882a593Smuzhiyun data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
7325*4882a593Smuzhiyun if (orig != data)
7326*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
7327*4882a593Smuzhiyun
7328*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
7329*4882a593Smuzhiyun data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
7330*4882a593Smuzhiyun data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
7331*4882a593Smuzhiyun if (orig != data)
7332*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
7333*4882a593Smuzhiyun
7334*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
7335*4882a593Smuzhiyun data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
7336*4882a593Smuzhiyun data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
7337*4882a593Smuzhiyun if (orig != data)
7338*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
7339*4882a593Smuzhiyun
7340*4882a593Smuzhiyun if ((rdev->family != CHIP_OLAND) && (rdev->family != CHIP_HAINAN)) {
7341*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
7342*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_0_MASK;
7343*4882a593Smuzhiyun if (orig != data)
7344*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
7345*4882a593Smuzhiyun
7346*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
7347*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_1_MASK;
7348*4882a593Smuzhiyun if (orig != data)
7349*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
7350*4882a593Smuzhiyun
7351*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2);
7352*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_2_MASK;
7353*4882a593Smuzhiyun if (orig != data)
7354*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2, data);
7355*4882a593Smuzhiyun
7356*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3);
7357*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_3_MASK;
7358*4882a593Smuzhiyun if (orig != data)
7359*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3, data);
7360*4882a593Smuzhiyun
7361*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
7362*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_0_MASK;
7363*4882a593Smuzhiyun if (orig != data)
7364*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
7365*4882a593Smuzhiyun
7366*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
7367*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_1_MASK;
7368*4882a593Smuzhiyun if (orig != data)
7369*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
7370*4882a593Smuzhiyun
7371*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2);
7372*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_2_MASK;
7373*4882a593Smuzhiyun if (orig != data)
7374*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2, data);
7375*4882a593Smuzhiyun
7376*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3);
7377*4882a593Smuzhiyun data &= ~PLL_RAMP_UP_TIME_3_MASK;
7378*4882a593Smuzhiyun if (orig != data)
7379*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3, data);
7380*4882a593Smuzhiyun }
7381*4882a593Smuzhiyun orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
7382*4882a593Smuzhiyun data &= ~LC_DYN_LANES_PWR_STATE_MASK;
7383*4882a593Smuzhiyun data |= LC_DYN_LANES_PWR_STATE(3);
7384*4882a593Smuzhiyun if (orig != data)
7385*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
7386*4882a593Smuzhiyun
7387*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY0(PB0_PIF_CNTL);
7388*4882a593Smuzhiyun data &= ~LS2_EXIT_TIME_MASK;
7389*4882a593Smuzhiyun if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
7390*4882a593Smuzhiyun data |= LS2_EXIT_TIME(5);
7391*4882a593Smuzhiyun if (orig != data)
7392*4882a593Smuzhiyun WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
7393*4882a593Smuzhiyun
7394*4882a593Smuzhiyun orig = data = RREG32_PIF_PHY1(PB1_PIF_CNTL);
7395*4882a593Smuzhiyun data &= ~LS2_EXIT_TIME_MASK;
7396*4882a593Smuzhiyun if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
7397*4882a593Smuzhiyun data |= LS2_EXIT_TIME(5);
7398*4882a593Smuzhiyun if (orig != data)
7399*4882a593Smuzhiyun WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
7400*4882a593Smuzhiyun
7401*4882a593Smuzhiyun if (!disable_clkreq &&
7402*4882a593Smuzhiyun !pci_is_root_bus(rdev->pdev->bus)) {
7403*4882a593Smuzhiyun struct pci_dev *root = rdev->pdev->bus->self;
7404*4882a593Smuzhiyun u32 lnkcap;
7405*4882a593Smuzhiyun
7406*4882a593Smuzhiyun clk_req_support = false;
7407*4882a593Smuzhiyun pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
7408*4882a593Smuzhiyun if (lnkcap & PCI_EXP_LNKCAP_CLKPM)
7409*4882a593Smuzhiyun clk_req_support = true;
7410*4882a593Smuzhiyun } else {
7411*4882a593Smuzhiyun clk_req_support = false;
7412*4882a593Smuzhiyun }
7413*4882a593Smuzhiyun
7414*4882a593Smuzhiyun if (clk_req_support) {
7415*4882a593Smuzhiyun orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2);
7416*4882a593Smuzhiyun data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23;
7417*4882a593Smuzhiyun if (orig != data)
7418*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL2, data);
7419*4882a593Smuzhiyun
7420*4882a593Smuzhiyun orig = data = RREG32(THM_CLK_CNTL);
7421*4882a593Smuzhiyun data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK);
7422*4882a593Smuzhiyun data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1);
7423*4882a593Smuzhiyun if (orig != data)
7424*4882a593Smuzhiyun WREG32(THM_CLK_CNTL, data);
7425*4882a593Smuzhiyun
7426*4882a593Smuzhiyun orig = data = RREG32(MISC_CLK_CNTL);
7427*4882a593Smuzhiyun data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK);
7428*4882a593Smuzhiyun data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1);
7429*4882a593Smuzhiyun if (orig != data)
7430*4882a593Smuzhiyun WREG32(MISC_CLK_CNTL, data);
7431*4882a593Smuzhiyun
7432*4882a593Smuzhiyun orig = data = RREG32(CG_CLKPIN_CNTL);
7433*4882a593Smuzhiyun data &= ~BCLK_AS_XCLK;
7434*4882a593Smuzhiyun if (orig != data)
7435*4882a593Smuzhiyun WREG32(CG_CLKPIN_CNTL, data);
7436*4882a593Smuzhiyun
7437*4882a593Smuzhiyun orig = data = RREG32(CG_CLKPIN_CNTL_2);
7438*4882a593Smuzhiyun data &= ~FORCE_BIF_REFCLK_EN;
7439*4882a593Smuzhiyun if (orig != data)
7440*4882a593Smuzhiyun WREG32(CG_CLKPIN_CNTL_2, data);
7441*4882a593Smuzhiyun
7442*4882a593Smuzhiyun orig = data = RREG32(MPLL_BYPASSCLK_SEL);
7443*4882a593Smuzhiyun data &= ~MPLL_CLKOUT_SEL_MASK;
7444*4882a593Smuzhiyun data |= MPLL_CLKOUT_SEL(4);
7445*4882a593Smuzhiyun if (orig != data)
7446*4882a593Smuzhiyun WREG32(MPLL_BYPASSCLK_SEL, data);
7447*4882a593Smuzhiyun
7448*4882a593Smuzhiyun orig = data = RREG32(SPLL_CNTL_MODE);
7449*4882a593Smuzhiyun data &= ~SPLL_REFCLK_SEL_MASK;
7450*4882a593Smuzhiyun if (orig != data)
7451*4882a593Smuzhiyun WREG32(SPLL_CNTL_MODE, data);
7452*4882a593Smuzhiyun }
7453*4882a593Smuzhiyun }
7454*4882a593Smuzhiyun } else {
7455*4882a593Smuzhiyun if (orig != data)
7456*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
7457*4882a593Smuzhiyun }
7458*4882a593Smuzhiyun
7459*4882a593Smuzhiyun orig = data = RREG32_PCIE(PCIE_CNTL2);
7460*4882a593Smuzhiyun data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN;
7461*4882a593Smuzhiyun if (orig != data)
7462*4882a593Smuzhiyun WREG32_PCIE(PCIE_CNTL2, data);
7463*4882a593Smuzhiyun
7464*4882a593Smuzhiyun if (!disable_l0s) {
7465*4882a593Smuzhiyun data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
7466*4882a593Smuzhiyun if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) {
7467*4882a593Smuzhiyun data = RREG32_PCIE(PCIE_LC_STATUS1);
7468*4882a593Smuzhiyun if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) {
7469*4882a593Smuzhiyun orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
7470*4882a593Smuzhiyun data &= ~LC_L0S_INACTIVITY_MASK;
7471*4882a593Smuzhiyun if (orig != data)
7472*4882a593Smuzhiyun WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
7473*4882a593Smuzhiyun }
7474*4882a593Smuzhiyun }
7475*4882a593Smuzhiyun }
7476*4882a593Smuzhiyun }
7477*4882a593Smuzhiyun
si_vce_send_vcepll_ctlreq(struct radeon_device * rdev)7478*4882a593Smuzhiyun static int si_vce_send_vcepll_ctlreq(struct radeon_device *rdev)
7479*4882a593Smuzhiyun {
7480*4882a593Smuzhiyun unsigned i;
7481*4882a593Smuzhiyun
7482*4882a593Smuzhiyun /* make sure VCEPLL_CTLREQ is deasserted */
7483*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
7484*4882a593Smuzhiyun
7485*4882a593Smuzhiyun mdelay(10);
7486*4882a593Smuzhiyun
7487*4882a593Smuzhiyun /* assert UPLL_CTLREQ */
7488*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
7489*4882a593Smuzhiyun
7490*4882a593Smuzhiyun /* wait for CTLACK and CTLACK2 to get asserted */
7491*4882a593Smuzhiyun for (i = 0; i < 100; ++i) {
7492*4882a593Smuzhiyun uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
7493*4882a593Smuzhiyun if ((RREG32_SMC(CG_VCEPLL_FUNC_CNTL) & mask) == mask)
7494*4882a593Smuzhiyun break;
7495*4882a593Smuzhiyun mdelay(10);
7496*4882a593Smuzhiyun }
7497*4882a593Smuzhiyun
7498*4882a593Smuzhiyun /* deassert UPLL_CTLREQ */
7499*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
7500*4882a593Smuzhiyun
7501*4882a593Smuzhiyun if (i == 100) {
7502*4882a593Smuzhiyun DRM_ERROR("Timeout setting UVD clocks!\n");
7503*4882a593Smuzhiyun return -ETIMEDOUT;
7504*4882a593Smuzhiyun }
7505*4882a593Smuzhiyun
7506*4882a593Smuzhiyun return 0;
7507*4882a593Smuzhiyun }
7508*4882a593Smuzhiyun
si_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)7509*4882a593Smuzhiyun int si_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
7510*4882a593Smuzhiyun {
7511*4882a593Smuzhiyun unsigned fb_div = 0, evclk_div = 0, ecclk_div = 0;
7512*4882a593Smuzhiyun int r;
7513*4882a593Smuzhiyun
7514*4882a593Smuzhiyun /* bypass evclk and ecclk with bclk */
7515*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7516*4882a593Smuzhiyun EVCLK_SRC_SEL(1) | ECCLK_SRC_SEL(1),
7517*4882a593Smuzhiyun ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
7518*4882a593Smuzhiyun
7519*4882a593Smuzhiyun /* put PLL in bypass mode */
7520*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_BYPASS_EN_MASK,
7521*4882a593Smuzhiyun ~VCEPLL_BYPASS_EN_MASK);
7522*4882a593Smuzhiyun
7523*4882a593Smuzhiyun if (!evclk || !ecclk) {
7524*4882a593Smuzhiyun /* keep the Bypass mode, put PLL to sleep */
7525*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
7526*4882a593Smuzhiyun ~VCEPLL_SLEEP_MASK);
7527*4882a593Smuzhiyun return 0;
7528*4882a593Smuzhiyun }
7529*4882a593Smuzhiyun
7530*4882a593Smuzhiyun r = radeon_uvd_calc_upll_dividers(rdev, evclk, ecclk, 125000, 250000,
7531*4882a593Smuzhiyun 16384, 0x03FFFFFF, 0, 128, 5,
7532*4882a593Smuzhiyun &fb_div, &evclk_div, &ecclk_div);
7533*4882a593Smuzhiyun if (r)
7534*4882a593Smuzhiyun return r;
7535*4882a593Smuzhiyun
7536*4882a593Smuzhiyun /* set RESET_ANTI_MUX to 0 */
7537*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
7538*4882a593Smuzhiyun
7539*4882a593Smuzhiyun /* set VCO_MODE to 1 */
7540*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_VCO_MODE_MASK,
7541*4882a593Smuzhiyun ~VCEPLL_VCO_MODE_MASK);
7542*4882a593Smuzhiyun
7543*4882a593Smuzhiyun /* toggle VCEPLL_SLEEP to 1 then back to 0 */
7544*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
7545*4882a593Smuzhiyun ~VCEPLL_SLEEP_MASK);
7546*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_SLEEP_MASK);
7547*4882a593Smuzhiyun
7548*4882a593Smuzhiyun /* deassert VCEPLL_RESET */
7549*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
7550*4882a593Smuzhiyun
7551*4882a593Smuzhiyun mdelay(1);
7552*4882a593Smuzhiyun
7553*4882a593Smuzhiyun r = si_vce_send_vcepll_ctlreq(rdev);
7554*4882a593Smuzhiyun if (r)
7555*4882a593Smuzhiyun return r;
7556*4882a593Smuzhiyun
7557*4882a593Smuzhiyun /* assert VCEPLL_RESET again */
7558*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_RESET_MASK, ~VCEPLL_RESET_MASK);
7559*4882a593Smuzhiyun
7560*4882a593Smuzhiyun /* disable spread spectrum. */
7561*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
7562*4882a593Smuzhiyun
7563*4882a593Smuzhiyun /* set feedback divider */
7564*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_3, VCEPLL_FB_DIV(fb_div), ~VCEPLL_FB_DIV_MASK);
7565*4882a593Smuzhiyun
7566*4882a593Smuzhiyun /* set ref divider to 0 */
7567*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_REF_DIV_MASK);
7568*4882a593Smuzhiyun
7569*4882a593Smuzhiyun /* set PDIV_A and PDIV_B */
7570*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7571*4882a593Smuzhiyun VCEPLL_PDIV_A(evclk_div) | VCEPLL_PDIV_B(ecclk_div),
7572*4882a593Smuzhiyun ~(VCEPLL_PDIV_A_MASK | VCEPLL_PDIV_B_MASK));
7573*4882a593Smuzhiyun
7574*4882a593Smuzhiyun /* give the PLL some time to settle */
7575*4882a593Smuzhiyun mdelay(15);
7576*4882a593Smuzhiyun
7577*4882a593Smuzhiyun /* deassert PLL_RESET */
7578*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
7579*4882a593Smuzhiyun
7580*4882a593Smuzhiyun mdelay(15);
7581*4882a593Smuzhiyun
7582*4882a593Smuzhiyun /* switch from bypass mode to normal mode */
7583*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_BYPASS_EN_MASK);
7584*4882a593Smuzhiyun
7585*4882a593Smuzhiyun r = si_vce_send_vcepll_ctlreq(rdev);
7586*4882a593Smuzhiyun if (r)
7587*4882a593Smuzhiyun return r;
7588*4882a593Smuzhiyun
7589*4882a593Smuzhiyun /* switch VCLK and DCLK selection */
7590*4882a593Smuzhiyun WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7591*4882a593Smuzhiyun EVCLK_SRC_SEL(16) | ECCLK_SRC_SEL(16),
7592*4882a593Smuzhiyun ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
7593*4882a593Smuzhiyun
7594*4882a593Smuzhiyun mdelay(100);
7595*4882a593Smuzhiyun
7596*4882a593Smuzhiyun return 0;
7597*4882a593Smuzhiyun }
7598