Line data Source code
1 : /*
2 : * Copyright 2008 Advanced Micro Devices, Inc.
3 : * Copyright 2008 Red Hat Inc.
4 : * Copyright 2009 Jerome Glisse.
5 : *
6 : * Permission is hereby granted, free of charge, to any person obtaining a
7 : * copy of this software and associated documentation files (the "Software"),
8 : * to deal in the Software without restriction, including without limitation
9 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 : * and/or sell copies of the Software, and to permit persons to whom the
11 : * Software is furnished to do so, subject to the following conditions:
12 : *
13 : * The above copyright notice and this permission notice shall be included in
14 : * all copies or substantial portions of the Software.
15 : *
16 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 : * OTHER DEALINGS IN THE SOFTWARE.
23 : *
24 : * Authors: Dave Airlie
25 : * Alex Deucher
26 : * Jerome Glisse
27 : */
28 : #include <dev/pci/drm/drmP.h>
29 : #include "radeon.h"
30 : #include "radeon_asic.h"
31 : #include "radeon_audio.h"
32 : #include <dev/pci/drm/radeon_drm.h>
33 : #include "rv770d.h"
34 : #include "atom.h"
35 : #include "avivod.h"
36 :
37 : #define R700_PFP_UCODE_SIZE 848
38 : #define R700_PM4_UCODE_SIZE 1360
39 :
40 : static void rv770_gpu_init(struct radeon_device *rdev);
41 : void rv770_fini(struct radeon_device *rdev);
42 : static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
43 : int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
44 :
45 0 : int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
46 : {
47 0 : unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
48 : int r;
49 :
50 : /* RV740 uses evergreen uvd clk programming */
51 0 : if (rdev->family == CHIP_RV740)
52 0 : return evergreen_set_uvd_clocks(rdev, vclk, dclk);
53 :
54 : /* bypass vclk and dclk with bclk */
55 0 : WREG32_P(CG_UPLL_FUNC_CNTL_2,
56 : VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
57 : ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
58 :
59 0 : if (!vclk || !dclk) {
60 : /* keep the Bypass mode, put PLL to sleep */
61 0 : WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
62 0 : return 0;
63 : }
64 :
65 0 : r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 50000, 160000,
66 : 43663, 0x03FFFFFE, 1, 30, ~0,
67 : &fb_div, &vclk_div, &dclk_div);
68 0 : if (r)
69 0 : return r;
70 :
71 0 : fb_div |= 1;
72 0 : vclk_div -= 1;
73 0 : dclk_div -= 1;
74 :
75 : /* set UPLL_FB_DIV to 0x50000 */
76 0 : WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(0x50000), ~UPLL_FB_DIV_MASK);
77 :
78 : /* deassert UPLL_RESET and UPLL_SLEEP */
79 0 : WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~(UPLL_RESET_MASK | UPLL_SLEEP_MASK));
80 :
81 : /* assert BYPASS EN and FB_DIV[0] <- ??? why? */
82 0 : WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
83 0 : WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(1), ~UPLL_FB_DIV(1));
84 :
85 0 : r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
86 0 : if (r)
87 0 : return r;
88 :
89 : /* assert PLL_RESET */
90 0 : WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
91 :
92 : /* set the required FB_DIV, REF_DIV, Post divder values */
93 0 : WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_REF_DIV(1), ~UPLL_REF_DIV_MASK);
94 0 : WREG32_P(CG_UPLL_FUNC_CNTL_2,
95 : UPLL_SW_HILEN(vclk_div >> 1) |
96 : UPLL_SW_LOLEN((vclk_div >> 1) + (vclk_div & 1)) |
97 : UPLL_SW_HILEN2(dclk_div >> 1) |
98 : UPLL_SW_LOLEN2((dclk_div >> 1) + (dclk_div & 1)),
99 : ~UPLL_SW_MASK);
100 :
101 0 : WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div),
102 : ~UPLL_FB_DIV_MASK);
103 :
104 : /* give the PLL some time to settle */
105 0 : mdelay(15);
106 :
107 : /* deassert PLL_RESET */
108 0 : WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
109 :
110 0 : mdelay(15);
111 :
112 : /* deassert BYPASS EN and FB_DIV[0] <- ??? why? */
113 0 : WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
114 0 : WREG32_P(CG_UPLL_FUNC_CNTL_3, 0, ~UPLL_FB_DIV(1));
115 :
116 0 : r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
117 0 : if (r)
118 0 : return r;
119 :
120 : /* switch VCLK and DCLK selection */
121 0 : WREG32_P(CG_UPLL_FUNC_CNTL_2,
122 : VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
123 : ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
124 :
125 0 : mdelay(100);
126 :
127 0 : return 0;
128 0 : }
129 :
130 : static const u32 r7xx_golden_registers[] =
131 : {
132 : 0x8d00, 0xffffffff, 0x0e0e0074,
133 : 0x8d04, 0xffffffff, 0x013a2b34,
134 : 0x9508, 0xffffffff, 0x00000002,
135 : 0x8b20, 0xffffffff, 0,
136 : 0x88c4, 0xffffffff, 0x000000c2,
137 : 0x28350, 0xffffffff, 0,
138 : 0x9058, 0xffffffff, 0x0fffc40f,
139 : 0x240c, 0xffffffff, 0x00000380,
140 : 0x733c, 0xffffffff, 0x00000002,
141 : 0x2650, 0x00040000, 0,
142 : 0x20bc, 0x00040000, 0,
143 : 0x7300, 0xffffffff, 0x001000f0
144 : };
145 :
146 : static const u32 r7xx_golden_dyn_gpr_registers[] =
147 : {
148 : 0x8db0, 0xffffffff, 0x98989898,
149 : 0x8db4, 0xffffffff, 0x98989898,
150 : 0x8db8, 0xffffffff, 0x98989898,
151 : 0x8dbc, 0xffffffff, 0x98989898,
152 : 0x8dc0, 0xffffffff, 0x98989898,
153 : 0x8dc4, 0xffffffff, 0x98989898,
154 : 0x8dc8, 0xffffffff, 0x98989898,
155 : 0x8dcc, 0xffffffff, 0x98989898,
156 : 0x88c4, 0xffffffff, 0x00000082
157 : };
158 :
159 : static const u32 rv770_golden_registers[] =
160 : {
161 : 0x562c, 0xffffffff, 0,
162 : 0x3f90, 0xffffffff, 0,
163 : 0x9148, 0xffffffff, 0,
164 : 0x3f94, 0xffffffff, 0,
165 : 0x914c, 0xffffffff, 0,
166 : 0x9698, 0x18000000, 0x18000000
167 : };
168 :
169 : static const u32 rv770ce_golden_registers[] =
170 : {
171 : 0x562c, 0xffffffff, 0,
172 : 0x3f90, 0xffffffff, 0x00cc0000,
173 : 0x9148, 0xffffffff, 0x00cc0000,
174 : 0x3f94, 0xffffffff, 0x00cc0000,
175 : 0x914c, 0xffffffff, 0x00cc0000,
176 : 0x9b7c, 0xffffffff, 0x00fa0000,
177 : 0x3f8c, 0xffffffff, 0x00fa0000,
178 : 0x9698, 0x18000000, 0x18000000
179 : };
180 :
181 : static const u32 rv770_mgcg_init[] =
182 : {
183 : 0x8bcc, 0xffffffff, 0x130300f9,
184 : 0x5448, 0xffffffff, 0x100,
185 : 0x55e4, 0xffffffff, 0x100,
186 : 0x160c, 0xffffffff, 0x100,
187 : 0x5644, 0xffffffff, 0x100,
188 : 0xc164, 0xffffffff, 0x100,
189 : 0x8a18, 0xffffffff, 0x100,
190 : 0x897c, 0xffffffff, 0x8000100,
191 : 0x8b28, 0xffffffff, 0x3c000100,
192 : 0x9144, 0xffffffff, 0x100,
193 : 0x9a1c, 0xffffffff, 0x10000,
194 : 0x9a50, 0xffffffff, 0x100,
195 : 0x9a1c, 0xffffffff, 0x10001,
196 : 0x9a50, 0xffffffff, 0x100,
197 : 0x9a1c, 0xffffffff, 0x10002,
198 : 0x9a50, 0xffffffff, 0x100,
199 : 0x9a1c, 0xffffffff, 0x10003,
200 : 0x9a50, 0xffffffff, 0x100,
201 : 0x9a1c, 0xffffffff, 0x0,
202 : 0x9870, 0xffffffff, 0x100,
203 : 0x8d58, 0xffffffff, 0x100,
204 : 0x9500, 0xffffffff, 0x0,
205 : 0x9510, 0xffffffff, 0x100,
206 : 0x9500, 0xffffffff, 0x1,
207 : 0x9510, 0xffffffff, 0x100,
208 : 0x9500, 0xffffffff, 0x2,
209 : 0x9510, 0xffffffff, 0x100,
210 : 0x9500, 0xffffffff, 0x3,
211 : 0x9510, 0xffffffff, 0x100,
212 : 0x9500, 0xffffffff, 0x4,
213 : 0x9510, 0xffffffff, 0x100,
214 : 0x9500, 0xffffffff, 0x5,
215 : 0x9510, 0xffffffff, 0x100,
216 : 0x9500, 0xffffffff, 0x6,
217 : 0x9510, 0xffffffff, 0x100,
218 : 0x9500, 0xffffffff, 0x7,
219 : 0x9510, 0xffffffff, 0x100,
220 : 0x9500, 0xffffffff, 0x8,
221 : 0x9510, 0xffffffff, 0x100,
222 : 0x9500, 0xffffffff, 0x9,
223 : 0x9510, 0xffffffff, 0x100,
224 : 0x9500, 0xffffffff, 0x8000,
225 : 0x9490, 0xffffffff, 0x0,
226 : 0x949c, 0xffffffff, 0x100,
227 : 0x9490, 0xffffffff, 0x1,
228 : 0x949c, 0xffffffff, 0x100,
229 : 0x9490, 0xffffffff, 0x2,
230 : 0x949c, 0xffffffff, 0x100,
231 : 0x9490, 0xffffffff, 0x3,
232 : 0x949c, 0xffffffff, 0x100,
233 : 0x9490, 0xffffffff, 0x4,
234 : 0x949c, 0xffffffff, 0x100,
235 : 0x9490, 0xffffffff, 0x5,
236 : 0x949c, 0xffffffff, 0x100,
237 : 0x9490, 0xffffffff, 0x6,
238 : 0x949c, 0xffffffff, 0x100,
239 : 0x9490, 0xffffffff, 0x7,
240 : 0x949c, 0xffffffff, 0x100,
241 : 0x9490, 0xffffffff, 0x8,
242 : 0x949c, 0xffffffff, 0x100,
243 : 0x9490, 0xffffffff, 0x9,
244 : 0x949c, 0xffffffff, 0x100,
245 : 0x9490, 0xffffffff, 0x8000,
246 : 0x9604, 0xffffffff, 0x0,
247 : 0x9654, 0xffffffff, 0x100,
248 : 0x9604, 0xffffffff, 0x1,
249 : 0x9654, 0xffffffff, 0x100,
250 : 0x9604, 0xffffffff, 0x2,
251 : 0x9654, 0xffffffff, 0x100,
252 : 0x9604, 0xffffffff, 0x3,
253 : 0x9654, 0xffffffff, 0x100,
254 : 0x9604, 0xffffffff, 0x4,
255 : 0x9654, 0xffffffff, 0x100,
256 : 0x9604, 0xffffffff, 0x5,
257 : 0x9654, 0xffffffff, 0x100,
258 : 0x9604, 0xffffffff, 0x6,
259 : 0x9654, 0xffffffff, 0x100,
260 : 0x9604, 0xffffffff, 0x7,
261 : 0x9654, 0xffffffff, 0x100,
262 : 0x9604, 0xffffffff, 0x8,
263 : 0x9654, 0xffffffff, 0x100,
264 : 0x9604, 0xffffffff, 0x9,
265 : 0x9654, 0xffffffff, 0x100,
266 : 0x9604, 0xffffffff, 0x80000000,
267 : 0x9030, 0xffffffff, 0x100,
268 : 0x9034, 0xffffffff, 0x100,
269 : 0x9038, 0xffffffff, 0x100,
270 : 0x903c, 0xffffffff, 0x100,
271 : 0x9040, 0xffffffff, 0x100,
272 : 0xa200, 0xffffffff, 0x100,
273 : 0xa204, 0xffffffff, 0x100,
274 : 0xa208, 0xffffffff, 0x100,
275 : 0xa20c, 0xffffffff, 0x100,
276 : 0x971c, 0xffffffff, 0x100,
277 : 0x915c, 0xffffffff, 0x00020001,
278 : 0x9160, 0xffffffff, 0x00040003,
279 : 0x916c, 0xffffffff, 0x00060005,
280 : 0x9170, 0xffffffff, 0x00080007,
281 : 0x9174, 0xffffffff, 0x000a0009,
282 : 0x9178, 0xffffffff, 0x000c000b,
283 : 0x917c, 0xffffffff, 0x000e000d,
284 : 0x9180, 0xffffffff, 0x0010000f,
285 : 0x918c, 0xffffffff, 0x00120011,
286 : 0x9190, 0xffffffff, 0x00140013,
287 : 0x9194, 0xffffffff, 0x00020001,
288 : 0x9198, 0xffffffff, 0x00040003,
289 : 0x919c, 0xffffffff, 0x00060005,
290 : 0x91a8, 0xffffffff, 0x00080007,
291 : 0x91ac, 0xffffffff, 0x000a0009,
292 : 0x91b0, 0xffffffff, 0x000c000b,
293 : 0x91b4, 0xffffffff, 0x000e000d,
294 : 0x91b8, 0xffffffff, 0x0010000f,
295 : 0x91c4, 0xffffffff, 0x00120011,
296 : 0x91c8, 0xffffffff, 0x00140013,
297 : 0x91cc, 0xffffffff, 0x00020001,
298 : 0x91d0, 0xffffffff, 0x00040003,
299 : 0x91d4, 0xffffffff, 0x00060005,
300 : 0x91e0, 0xffffffff, 0x00080007,
301 : 0x91e4, 0xffffffff, 0x000a0009,
302 : 0x91e8, 0xffffffff, 0x000c000b,
303 : 0x91ec, 0xffffffff, 0x00020001,
304 : 0x91f0, 0xffffffff, 0x00040003,
305 : 0x91f4, 0xffffffff, 0x00060005,
306 : 0x9200, 0xffffffff, 0x00080007,
307 : 0x9204, 0xffffffff, 0x000a0009,
308 : 0x9208, 0xffffffff, 0x000c000b,
309 : 0x920c, 0xffffffff, 0x000e000d,
310 : 0x9210, 0xffffffff, 0x0010000f,
311 : 0x921c, 0xffffffff, 0x00120011,
312 : 0x9220, 0xffffffff, 0x00140013,
313 : 0x9224, 0xffffffff, 0x00020001,
314 : 0x9228, 0xffffffff, 0x00040003,
315 : 0x922c, 0xffffffff, 0x00060005,
316 : 0x9238, 0xffffffff, 0x00080007,
317 : 0x923c, 0xffffffff, 0x000a0009,
318 : 0x9240, 0xffffffff, 0x000c000b,
319 : 0x9244, 0xffffffff, 0x000e000d,
320 : 0x9248, 0xffffffff, 0x0010000f,
321 : 0x9254, 0xffffffff, 0x00120011,
322 : 0x9258, 0xffffffff, 0x00140013,
323 : 0x925c, 0xffffffff, 0x00020001,
324 : 0x9260, 0xffffffff, 0x00040003,
325 : 0x9264, 0xffffffff, 0x00060005,
326 : 0x9270, 0xffffffff, 0x00080007,
327 : 0x9274, 0xffffffff, 0x000a0009,
328 : 0x9278, 0xffffffff, 0x000c000b,
329 : 0x927c, 0xffffffff, 0x000e000d,
330 : 0x9280, 0xffffffff, 0x0010000f,
331 : 0x928c, 0xffffffff, 0x00120011,
332 : 0x9290, 0xffffffff, 0x00140013,
333 : 0x9294, 0xffffffff, 0x00020001,
334 : 0x929c, 0xffffffff, 0x00040003,
335 : 0x92a0, 0xffffffff, 0x00060005,
336 : 0x92a4, 0xffffffff, 0x00080007
337 : };
338 :
339 : static const u32 rv710_golden_registers[] =
340 : {
341 : 0x3f90, 0x00ff0000, 0x00fc0000,
342 : 0x9148, 0x00ff0000, 0x00fc0000,
343 : 0x3f94, 0x00ff0000, 0x00fc0000,
344 : 0x914c, 0x00ff0000, 0x00fc0000,
345 : 0xb4c, 0x00000020, 0x00000020,
346 : 0xa180, 0xffffffff, 0x00003f3f
347 : };
348 :
349 : static const u32 rv710_mgcg_init[] =
350 : {
351 : 0x8bcc, 0xffffffff, 0x13030040,
352 : 0x5448, 0xffffffff, 0x100,
353 : 0x55e4, 0xffffffff, 0x100,
354 : 0x160c, 0xffffffff, 0x100,
355 : 0x5644, 0xffffffff, 0x100,
356 : 0xc164, 0xffffffff, 0x100,
357 : 0x8a18, 0xffffffff, 0x100,
358 : 0x897c, 0xffffffff, 0x8000100,
359 : 0x8b28, 0xffffffff, 0x3c000100,
360 : 0x9144, 0xffffffff, 0x100,
361 : 0x9a1c, 0xffffffff, 0x10000,
362 : 0x9a50, 0xffffffff, 0x100,
363 : 0x9a1c, 0xffffffff, 0x0,
364 : 0x9870, 0xffffffff, 0x100,
365 : 0x8d58, 0xffffffff, 0x100,
366 : 0x9500, 0xffffffff, 0x0,
367 : 0x9510, 0xffffffff, 0x100,
368 : 0x9500, 0xffffffff, 0x1,
369 : 0x9510, 0xffffffff, 0x100,
370 : 0x9500, 0xffffffff, 0x8000,
371 : 0x9490, 0xffffffff, 0x0,
372 : 0x949c, 0xffffffff, 0x100,
373 : 0x9490, 0xffffffff, 0x1,
374 : 0x949c, 0xffffffff, 0x100,
375 : 0x9490, 0xffffffff, 0x8000,
376 : 0x9604, 0xffffffff, 0x0,
377 : 0x9654, 0xffffffff, 0x100,
378 : 0x9604, 0xffffffff, 0x1,
379 : 0x9654, 0xffffffff, 0x100,
380 : 0x9604, 0xffffffff, 0x80000000,
381 : 0x9030, 0xffffffff, 0x100,
382 : 0x9034, 0xffffffff, 0x100,
383 : 0x9038, 0xffffffff, 0x100,
384 : 0x903c, 0xffffffff, 0x100,
385 : 0x9040, 0xffffffff, 0x100,
386 : 0xa200, 0xffffffff, 0x100,
387 : 0xa204, 0xffffffff, 0x100,
388 : 0xa208, 0xffffffff, 0x100,
389 : 0xa20c, 0xffffffff, 0x100,
390 : 0x971c, 0xffffffff, 0x100,
391 : 0x915c, 0xffffffff, 0x00020001,
392 : 0x9174, 0xffffffff, 0x00000003,
393 : 0x9178, 0xffffffff, 0x00050001,
394 : 0x917c, 0xffffffff, 0x00030002,
395 : 0x918c, 0xffffffff, 0x00000004,
396 : 0x9190, 0xffffffff, 0x00070006,
397 : 0x9194, 0xffffffff, 0x00050001,
398 : 0x9198, 0xffffffff, 0x00030002,
399 : 0x91a8, 0xffffffff, 0x00000004,
400 : 0x91ac, 0xffffffff, 0x00070006,
401 : 0x91e8, 0xffffffff, 0x00000001,
402 : 0x9294, 0xffffffff, 0x00000001,
403 : 0x929c, 0xffffffff, 0x00000002,
404 : 0x92a0, 0xffffffff, 0x00040003,
405 : 0x9150, 0xffffffff, 0x4d940000
406 : };
407 :
408 : static const u32 rv730_golden_registers[] =
409 : {
410 : 0x3f90, 0x00ff0000, 0x00f00000,
411 : 0x9148, 0x00ff0000, 0x00f00000,
412 : 0x3f94, 0x00ff0000, 0x00f00000,
413 : 0x914c, 0x00ff0000, 0x00f00000,
414 : 0x900c, 0xffffffff, 0x003b033f,
415 : 0xb4c, 0x00000020, 0x00000020,
416 : 0xa180, 0xffffffff, 0x00003f3f
417 : };
418 :
419 : static const u32 rv730_mgcg_init[] =
420 : {
421 : 0x8bcc, 0xffffffff, 0x130300f9,
422 : 0x5448, 0xffffffff, 0x100,
423 : 0x55e4, 0xffffffff, 0x100,
424 : 0x160c, 0xffffffff, 0x100,
425 : 0x5644, 0xffffffff, 0x100,
426 : 0xc164, 0xffffffff, 0x100,
427 : 0x8a18, 0xffffffff, 0x100,
428 : 0x897c, 0xffffffff, 0x8000100,
429 : 0x8b28, 0xffffffff, 0x3c000100,
430 : 0x9144, 0xffffffff, 0x100,
431 : 0x9a1c, 0xffffffff, 0x10000,
432 : 0x9a50, 0xffffffff, 0x100,
433 : 0x9a1c, 0xffffffff, 0x10001,
434 : 0x9a50, 0xffffffff, 0x100,
435 : 0x9a1c, 0xffffffff, 0x0,
436 : 0x9870, 0xffffffff, 0x100,
437 : 0x8d58, 0xffffffff, 0x100,
438 : 0x9500, 0xffffffff, 0x0,
439 : 0x9510, 0xffffffff, 0x100,
440 : 0x9500, 0xffffffff, 0x1,
441 : 0x9510, 0xffffffff, 0x100,
442 : 0x9500, 0xffffffff, 0x2,
443 : 0x9510, 0xffffffff, 0x100,
444 : 0x9500, 0xffffffff, 0x3,
445 : 0x9510, 0xffffffff, 0x100,
446 : 0x9500, 0xffffffff, 0x4,
447 : 0x9510, 0xffffffff, 0x100,
448 : 0x9500, 0xffffffff, 0x5,
449 : 0x9510, 0xffffffff, 0x100,
450 : 0x9500, 0xffffffff, 0x6,
451 : 0x9510, 0xffffffff, 0x100,
452 : 0x9500, 0xffffffff, 0x7,
453 : 0x9510, 0xffffffff, 0x100,
454 : 0x9500, 0xffffffff, 0x8000,
455 : 0x9490, 0xffffffff, 0x0,
456 : 0x949c, 0xffffffff, 0x100,
457 : 0x9490, 0xffffffff, 0x1,
458 : 0x949c, 0xffffffff, 0x100,
459 : 0x9490, 0xffffffff, 0x2,
460 : 0x949c, 0xffffffff, 0x100,
461 : 0x9490, 0xffffffff, 0x3,
462 : 0x949c, 0xffffffff, 0x100,
463 : 0x9490, 0xffffffff, 0x4,
464 : 0x949c, 0xffffffff, 0x100,
465 : 0x9490, 0xffffffff, 0x5,
466 : 0x949c, 0xffffffff, 0x100,
467 : 0x9490, 0xffffffff, 0x6,
468 : 0x949c, 0xffffffff, 0x100,
469 : 0x9490, 0xffffffff, 0x7,
470 : 0x949c, 0xffffffff, 0x100,
471 : 0x9490, 0xffffffff, 0x8000,
472 : 0x9604, 0xffffffff, 0x0,
473 : 0x9654, 0xffffffff, 0x100,
474 : 0x9604, 0xffffffff, 0x1,
475 : 0x9654, 0xffffffff, 0x100,
476 : 0x9604, 0xffffffff, 0x2,
477 : 0x9654, 0xffffffff, 0x100,
478 : 0x9604, 0xffffffff, 0x3,
479 : 0x9654, 0xffffffff, 0x100,
480 : 0x9604, 0xffffffff, 0x4,
481 : 0x9654, 0xffffffff, 0x100,
482 : 0x9604, 0xffffffff, 0x5,
483 : 0x9654, 0xffffffff, 0x100,
484 : 0x9604, 0xffffffff, 0x6,
485 : 0x9654, 0xffffffff, 0x100,
486 : 0x9604, 0xffffffff, 0x7,
487 : 0x9654, 0xffffffff, 0x100,
488 : 0x9604, 0xffffffff, 0x80000000,
489 : 0x9030, 0xffffffff, 0x100,
490 : 0x9034, 0xffffffff, 0x100,
491 : 0x9038, 0xffffffff, 0x100,
492 : 0x903c, 0xffffffff, 0x100,
493 : 0x9040, 0xffffffff, 0x100,
494 : 0xa200, 0xffffffff, 0x100,
495 : 0xa204, 0xffffffff, 0x100,
496 : 0xa208, 0xffffffff, 0x100,
497 : 0xa20c, 0xffffffff, 0x100,
498 : 0x971c, 0xffffffff, 0x100,
499 : 0x915c, 0xffffffff, 0x00020001,
500 : 0x916c, 0xffffffff, 0x00040003,
501 : 0x9170, 0xffffffff, 0x00000005,
502 : 0x9178, 0xffffffff, 0x00050001,
503 : 0x917c, 0xffffffff, 0x00030002,
504 : 0x918c, 0xffffffff, 0x00000004,
505 : 0x9190, 0xffffffff, 0x00070006,
506 : 0x9194, 0xffffffff, 0x00050001,
507 : 0x9198, 0xffffffff, 0x00030002,
508 : 0x91a8, 0xffffffff, 0x00000004,
509 : 0x91ac, 0xffffffff, 0x00070006,
510 : 0x91b0, 0xffffffff, 0x00050001,
511 : 0x91b4, 0xffffffff, 0x00030002,
512 : 0x91c4, 0xffffffff, 0x00000004,
513 : 0x91c8, 0xffffffff, 0x00070006,
514 : 0x91cc, 0xffffffff, 0x00050001,
515 : 0x91d0, 0xffffffff, 0x00030002,
516 : 0x91e0, 0xffffffff, 0x00000004,
517 : 0x91e4, 0xffffffff, 0x00070006,
518 : 0x91e8, 0xffffffff, 0x00000001,
519 : 0x91ec, 0xffffffff, 0x00050001,
520 : 0x91f0, 0xffffffff, 0x00030002,
521 : 0x9200, 0xffffffff, 0x00000004,
522 : 0x9204, 0xffffffff, 0x00070006,
523 : 0x9208, 0xffffffff, 0x00050001,
524 : 0x920c, 0xffffffff, 0x00030002,
525 : 0x921c, 0xffffffff, 0x00000004,
526 : 0x9220, 0xffffffff, 0x00070006,
527 : 0x9224, 0xffffffff, 0x00050001,
528 : 0x9228, 0xffffffff, 0x00030002,
529 : 0x9238, 0xffffffff, 0x00000004,
530 : 0x923c, 0xffffffff, 0x00070006,
531 : 0x9240, 0xffffffff, 0x00050001,
532 : 0x9244, 0xffffffff, 0x00030002,
533 : 0x9254, 0xffffffff, 0x00000004,
534 : 0x9258, 0xffffffff, 0x00070006,
535 : 0x9294, 0xffffffff, 0x00000001,
536 : 0x929c, 0xffffffff, 0x00000002,
537 : 0x92a0, 0xffffffff, 0x00040003,
538 : 0x92a4, 0xffffffff, 0x00000005
539 : };
540 :
541 : static const u32 rv740_golden_registers[] =
542 : {
543 : 0x88c4, 0xffffffff, 0x00000082,
544 : 0x28a50, 0xfffffffc, 0x00000004,
545 : 0x2650, 0x00040000, 0,
546 : 0x20bc, 0x00040000, 0,
547 : 0x733c, 0xffffffff, 0x00000002,
548 : 0x7300, 0xffffffff, 0x001000f0,
549 : 0x3f90, 0x00ff0000, 0,
550 : 0x9148, 0x00ff0000, 0,
551 : 0x3f94, 0x00ff0000, 0,
552 : 0x914c, 0x00ff0000, 0,
553 : 0x240c, 0xffffffff, 0x00000380,
554 : 0x8a14, 0x00000007, 0x00000007,
555 : 0x8b24, 0xffffffff, 0x00ff0fff,
556 : 0x28a4c, 0xffffffff, 0x00004000,
557 : 0xa180, 0xffffffff, 0x00003f3f,
558 : 0x8d00, 0xffffffff, 0x0e0e003a,
559 : 0x8d04, 0xffffffff, 0x013a0e2a,
560 : 0x8c00, 0xffffffff, 0xe400000f,
561 : 0x8db0, 0xffffffff, 0x98989898,
562 : 0x8db4, 0xffffffff, 0x98989898,
563 : 0x8db8, 0xffffffff, 0x98989898,
564 : 0x8dbc, 0xffffffff, 0x98989898,
565 : 0x8dc0, 0xffffffff, 0x98989898,
566 : 0x8dc4, 0xffffffff, 0x98989898,
567 : 0x8dc8, 0xffffffff, 0x98989898,
568 : 0x8dcc, 0xffffffff, 0x98989898,
569 : 0x9058, 0xffffffff, 0x0fffc40f,
570 : 0x900c, 0xffffffff, 0x003b033f,
571 : 0x28350, 0xffffffff, 0,
572 : 0x8cf0, 0x1fffffff, 0x08e00420,
573 : 0x9508, 0xffffffff, 0x00000002,
574 : 0x88c4, 0xffffffff, 0x000000c2,
575 : 0x9698, 0x18000000, 0x18000000
576 : };
577 :
578 : static const u32 rv740_mgcg_init[] =
579 : {
580 : 0x8bcc, 0xffffffff, 0x13030100,
581 : 0x5448, 0xffffffff, 0x100,
582 : 0x55e4, 0xffffffff, 0x100,
583 : 0x160c, 0xffffffff, 0x100,
584 : 0x5644, 0xffffffff, 0x100,
585 : 0xc164, 0xffffffff, 0x100,
586 : 0x8a18, 0xffffffff, 0x100,
587 : 0x897c, 0xffffffff, 0x100,
588 : 0x8b28, 0xffffffff, 0x100,
589 : 0x9144, 0xffffffff, 0x100,
590 : 0x9a1c, 0xffffffff, 0x10000,
591 : 0x9a50, 0xffffffff, 0x100,
592 : 0x9a1c, 0xffffffff, 0x10001,
593 : 0x9a50, 0xffffffff, 0x100,
594 : 0x9a1c, 0xffffffff, 0x10002,
595 : 0x9a50, 0xffffffff, 0x100,
596 : 0x9a1c, 0xffffffff, 0x10003,
597 : 0x9a50, 0xffffffff, 0x100,
598 : 0x9a1c, 0xffffffff, 0x0,
599 : 0x9870, 0xffffffff, 0x100,
600 : 0x8d58, 0xffffffff, 0x100,
601 : 0x9500, 0xffffffff, 0x0,
602 : 0x9510, 0xffffffff, 0x100,
603 : 0x9500, 0xffffffff, 0x1,
604 : 0x9510, 0xffffffff, 0x100,
605 : 0x9500, 0xffffffff, 0x2,
606 : 0x9510, 0xffffffff, 0x100,
607 : 0x9500, 0xffffffff, 0x3,
608 : 0x9510, 0xffffffff, 0x100,
609 : 0x9500, 0xffffffff, 0x4,
610 : 0x9510, 0xffffffff, 0x100,
611 : 0x9500, 0xffffffff, 0x5,
612 : 0x9510, 0xffffffff, 0x100,
613 : 0x9500, 0xffffffff, 0x6,
614 : 0x9510, 0xffffffff, 0x100,
615 : 0x9500, 0xffffffff, 0x7,
616 : 0x9510, 0xffffffff, 0x100,
617 : 0x9500, 0xffffffff, 0x8000,
618 : 0x9490, 0xffffffff, 0x0,
619 : 0x949c, 0xffffffff, 0x100,
620 : 0x9490, 0xffffffff, 0x1,
621 : 0x949c, 0xffffffff, 0x100,
622 : 0x9490, 0xffffffff, 0x2,
623 : 0x949c, 0xffffffff, 0x100,
624 : 0x9490, 0xffffffff, 0x3,
625 : 0x949c, 0xffffffff, 0x100,
626 : 0x9490, 0xffffffff, 0x4,
627 : 0x949c, 0xffffffff, 0x100,
628 : 0x9490, 0xffffffff, 0x5,
629 : 0x949c, 0xffffffff, 0x100,
630 : 0x9490, 0xffffffff, 0x6,
631 : 0x949c, 0xffffffff, 0x100,
632 : 0x9490, 0xffffffff, 0x7,
633 : 0x949c, 0xffffffff, 0x100,
634 : 0x9490, 0xffffffff, 0x8000,
635 : 0x9604, 0xffffffff, 0x0,
636 : 0x9654, 0xffffffff, 0x100,
637 : 0x9604, 0xffffffff, 0x1,
638 : 0x9654, 0xffffffff, 0x100,
639 : 0x9604, 0xffffffff, 0x2,
640 : 0x9654, 0xffffffff, 0x100,
641 : 0x9604, 0xffffffff, 0x3,
642 : 0x9654, 0xffffffff, 0x100,
643 : 0x9604, 0xffffffff, 0x4,
644 : 0x9654, 0xffffffff, 0x100,
645 : 0x9604, 0xffffffff, 0x5,
646 : 0x9654, 0xffffffff, 0x100,
647 : 0x9604, 0xffffffff, 0x6,
648 : 0x9654, 0xffffffff, 0x100,
649 : 0x9604, 0xffffffff, 0x7,
650 : 0x9654, 0xffffffff, 0x100,
651 : 0x9604, 0xffffffff, 0x80000000,
652 : 0x9030, 0xffffffff, 0x100,
653 : 0x9034, 0xffffffff, 0x100,
654 : 0x9038, 0xffffffff, 0x100,
655 : 0x903c, 0xffffffff, 0x100,
656 : 0x9040, 0xffffffff, 0x100,
657 : 0xa200, 0xffffffff, 0x100,
658 : 0xa204, 0xffffffff, 0x100,
659 : 0xa208, 0xffffffff, 0x100,
660 : 0xa20c, 0xffffffff, 0x100,
661 : 0x971c, 0xffffffff, 0x100,
662 : 0x915c, 0xffffffff, 0x00020001,
663 : 0x9160, 0xffffffff, 0x00040003,
664 : 0x916c, 0xffffffff, 0x00060005,
665 : 0x9170, 0xffffffff, 0x00080007,
666 : 0x9174, 0xffffffff, 0x000a0009,
667 : 0x9178, 0xffffffff, 0x000c000b,
668 : 0x917c, 0xffffffff, 0x000e000d,
669 : 0x9180, 0xffffffff, 0x0010000f,
670 : 0x918c, 0xffffffff, 0x00120011,
671 : 0x9190, 0xffffffff, 0x00140013,
672 : 0x9194, 0xffffffff, 0x00020001,
673 : 0x9198, 0xffffffff, 0x00040003,
674 : 0x919c, 0xffffffff, 0x00060005,
675 : 0x91a8, 0xffffffff, 0x00080007,
676 : 0x91ac, 0xffffffff, 0x000a0009,
677 : 0x91b0, 0xffffffff, 0x000c000b,
678 : 0x91b4, 0xffffffff, 0x000e000d,
679 : 0x91b8, 0xffffffff, 0x0010000f,
680 : 0x91c4, 0xffffffff, 0x00120011,
681 : 0x91c8, 0xffffffff, 0x00140013,
682 : 0x91cc, 0xffffffff, 0x00020001,
683 : 0x91d0, 0xffffffff, 0x00040003,
684 : 0x91d4, 0xffffffff, 0x00060005,
685 : 0x91e0, 0xffffffff, 0x00080007,
686 : 0x91e4, 0xffffffff, 0x000a0009,
687 : 0x91e8, 0xffffffff, 0x000c000b,
688 : 0x91ec, 0xffffffff, 0x00020001,
689 : 0x91f0, 0xffffffff, 0x00040003,
690 : 0x91f4, 0xffffffff, 0x00060005,
691 : 0x9200, 0xffffffff, 0x00080007,
692 : 0x9204, 0xffffffff, 0x000a0009,
693 : 0x9208, 0xffffffff, 0x000c000b,
694 : 0x920c, 0xffffffff, 0x000e000d,
695 : 0x9210, 0xffffffff, 0x0010000f,
696 : 0x921c, 0xffffffff, 0x00120011,
697 : 0x9220, 0xffffffff, 0x00140013,
698 : 0x9224, 0xffffffff, 0x00020001,
699 : 0x9228, 0xffffffff, 0x00040003,
700 : 0x922c, 0xffffffff, 0x00060005,
701 : 0x9238, 0xffffffff, 0x00080007,
702 : 0x923c, 0xffffffff, 0x000a0009,
703 : 0x9240, 0xffffffff, 0x000c000b,
704 : 0x9244, 0xffffffff, 0x000e000d,
705 : 0x9248, 0xffffffff, 0x0010000f,
706 : 0x9254, 0xffffffff, 0x00120011,
707 : 0x9258, 0xffffffff, 0x00140013,
708 : 0x9294, 0xffffffff, 0x00020001,
709 : 0x929c, 0xffffffff, 0x00040003,
710 : 0x92a0, 0xffffffff, 0x00060005,
711 : 0x92a4, 0xffffffff, 0x00080007
712 : };
713 :
714 0 : static void rv770_init_golden_registers(struct radeon_device *rdev)
715 : {
716 0 : switch (rdev->family) {
717 : case CHIP_RV770:
718 0 : radeon_program_register_sequence(rdev,
719 : r7xx_golden_registers,
720 : (const u32)ARRAY_SIZE(r7xx_golden_registers));
721 0 : radeon_program_register_sequence(rdev,
722 : r7xx_golden_dyn_gpr_registers,
723 : (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
724 0 : if (rdev->pdev->device == 0x994e)
725 0 : radeon_program_register_sequence(rdev,
726 : rv770ce_golden_registers,
727 : (const u32)ARRAY_SIZE(rv770ce_golden_registers));
728 : else
729 0 : radeon_program_register_sequence(rdev,
730 : rv770_golden_registers,
731 : (const u32)ARRAY_SIZE(rv770_golden_registers));
732 0 : radeon_program_register_sequence(rdev,
733 : rv770_mgcg_init,
734 : (const u32)ARRAY_SIZE(rv770_mgcg_init));
735 0 : break;
736 : case CHIP_RV730:
737 0 : radeon_program_register_sequence(rdev,
738 : r7xx_golden_registers,
739 : (const u32)ARRAY_SIZE(r7xx_golden_registers));
740 0 : radeon_program_register_sequence(rdev,
741 : r7xx_golden_dyn_gpr_registers,
742 : (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
743 0 : radeon_program_register_sequence(rdev,
744 : rv730_golden_registers,
745 : (const u32)ARRAY_SIZE(rv730_golden_registers));
746 0 : radeon_program_register_sequence(rdev,
747 : rv730_mgcg_init,
748 : (const u32)ARRAY_SIZE(rv730_mgcg_init));
749 0 : break;
750 : case CHIP_RV710:
751 0 : radeon_program_register_sequence(rdev,
752 : r7xx_golden_registers,
753 : (const u32)ARRAY_SIZE(r7xx_golden_registers));
754 0 : radeon_program_register_sequence(rdev,
755 : r7xx_golden_dyn_gpr_registers,
756 : (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
757 0 : radeon_program_register_sequence(rdev,
758 : rv710_golden_registers,
759 : (const u32)ARRAY_SIZE(rv710_golden_registers));
760 0 : radeon_program_register_sequence(rdev,
761 : rv710_mgcg_init,
762 : (const u32)ARRAY_SIZE(rv710_mgcg_init));
763 0 : break;
764 : case CHIP_RV740:
765 0 : radeon_program_register_sequence(rdev,
766 : rv740_golden_registers,
767 : (const u32)ARRAY_SIZE(rv740_golden_registers));
768 0 : radeon_program_register_sequence(rdev,
769 : rv740_mgcg_init,
770 : (const u32)ARRAY_SIZE(rv740_mgcg_init));
771 0 : break;
772 : default:
773 : break;
774 : }
775 0 : }
776 :
777 : #define PCIE_BUS_CLK 10000
778 : #define TCLK (PCIE_BUS_CLK / 10)
779 :
780 : /**
781 : * rv770_get_xclk - get the xclk
782 : *
783 : * @rdev: radeon_device pointer
784 : *
785 : * Returns the reference clock used by the gfx engine
786 : * (r7xx-cayman).
787 : */
788 0 : u32 rv770_get_xclk(struct radeon_device *rdev)
789 : {
790 0 : u32 reference_clock = rdev->clock.spll.reference_freq;
791 0 : u32 tmp = RREG32(CG_CLKPIN_CNTL);
792 :
793 0 : if (tmp & MUX_TCLK_TO_XCLK)
794 0 : return TCLK;
795 :
796 0 : if (tmp & XTALIN_DIVIDE)
797 0 : return reference_clock / 4;
798 :
799 0 : return reference_clock;
800 0 : }
801 :
802 0 : void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
803 : {
804 0 : struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
805 0 : u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
806 : int i;
807 :
808 : /* Lock the graphics update lock */
809 0 : tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
810 0 : WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
811 :
812 : /* update the scanout addresses */
813 0 : if (radeon_crtc->crtc_id) {
814 0 : WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
815 0 : WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
816 0 : } else {
817 0 : WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
818 0 : WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
819 : }
820 0 : WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
821 : (u32)crtc_base);
822 0 : WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
823 : (u32)crtc_base);
824 :
825 : /* Wait for update_pending to go high. */
826 0 : for (i = 0; i < rdev->usec_timeout; i++) {
827 0 : if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
828 : break;
829 0 : udelay(1);
830 : }
831 : DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
832 :
833 : /* Unlock the lock, so double-buffering can take place inside vblank */
834 0 : tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
835 0 : WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
836 0 : }
837 :
838 0 : bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc_id)
839 : {
840 0 : struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
841 :
842 : /* Return current update_pending status: */
843 0 : return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
844 : AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
845 : }
846 :
847 : /* get temperature in millidegrees */
848 0 : int rv770_get_temp(struct radeon_device *rdev)
849 : {
850 0 : u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
851 : ASIC_T_SHIFT;
852 : int actual_temp;
853 :
854 0 : if (temp & 0x400)
855 0 : actual_temp = -256;
856 0 : else if (temp & 0x200)
857 0 : actual_temp = 255;
858 0 : else if (temp & 0x100) {
859 0 : actual_temp = temp & 0x1ff;
860 0 : actual_temp |= ~0x1ff;
861 0 : } else
862 0 : actual_temp = temp & 0xff;
863 :
864 0 : return (actual_temp * 1000) / 2;
865 : }
866 :
867 0 : void rv770_pm_misc(struct radeon_device *rdev)
868 : {
869 0 : int req_ps_idx = rdev->pm.requested_power_state_index;
870 0 : int req_cm_idx = rdev->pm.requested_clock_mode_index;
871 0 : struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
872 0 : struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
873 :
874 0 : if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
875 : /* 0xff01 is a flag rather then an actual voltage */
876 0 : if (voltage->voltage == 0xff01)
877 0 : return;
878 0 : if (voltage->voltage != rdev->pm.current_vddc) {
879 0 : radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
880 0 : rdev->pm.current_vddc = voltage->voltage;
881 : DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
882 0 : }
883 : }
884 0 : }
885 :
886 : /*
887 : * GART
888 : */
889 0 : static int rv770_pcie_gart_enable(struct radeon_device *rdev)
890 : {
891 : u32 tmp;
892 : int r, i;
893 :
894 0 : if (rdev->gart.robj == NULL) {
895 0 : dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
896 0 : return -EINVAL;
897 : }
898 0 : r = radeon_gart_table_vram_pin(rdev);
899 0 : if (r)
900 0 : return r;
901 : /* Setup L2 cache */
902 0 : WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
903 : ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
904 : EFFECTIVE_L2_QUEUE_SIZE(7));
905 0 : WREG32(VM_L2_CNTL2, 0);
906 0 : WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
907 : /* Setup TLB control */
908 : tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
909 : SYSTEM_ACCESS_MODE_NOT_IN_SYS |
910 : SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
911 : EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
912 0 : WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
913 0 : WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
914 0 : WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
915 0 : if (rdev->family == CHIP_RV740)
916 0 : WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp);
917 0 : WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
918 0 : WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
919 0 : WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
920 0 : WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
921 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
922 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
923 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
924 0 : WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
925 : RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
926 0 : WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
927 : (u32)(rdev->dummy_page.addr >> 12));
928 0 : for (i = 1; i < 7; i++)
929 0 : WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
930 :
931 0 : r600_pcie_gart_tlb_flush(rdev);
932 : DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
933 : (unsigned)(rdev->mc.gtt_size >> 20),
934 : (unsigned long long)rdev->gart.table_addr);
935 0 : rdev->gart.ready = true;
936 0 : return 0;
937 0 : }
938 :
939 0 : static void rv770_pcie_gart_disable(struct radeon_device *rdev)
940 : {
941 : u32 tmp;
942 : int i;
943 :
944 : /* Disable all tables */
945 0 : for (i = 0; i < 7; i++)
946 0 : WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
947 :
948 : /* Setup L2 cache */
949 0 : WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
950 : EFFECTIVE_L2_QUEUE_SIZE(7));
951 0 : WREG32(VM_L2_CNTL2, 0);
952 0 : WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
953 : /* Setup TLB control */
954 : tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
955 0 : WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
956 0 : WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
957 0 : WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
958 0 : WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
959 0 : WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
960 0 : WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
961 0 : WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
962 0 : radeon_gart_table_vram_unpin(rdev);
963 0 : }
964 :
965 0 : static void rv770_pcie_gart_fini(struct radeon_device *rdev)
966 : {
967 0 : radeon_gart_fini(rdev);
968 0 : rv770_pcie_gart_disable(rdev);
969 0 : radeon_gart_table_vram_free(rdev);
970 0 : }
971 :
972 :
973 0 : static void rv770_agp_enable(struct radeon_device *rdev)
974 : {
975 : u32 tmp;
976 : int i;
977 :
978 : /* Setup L2 cache */
979 0 : WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
980 : ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
981 : EFFECTIVE_L2_QUEUE_SIZE(7));
982 0 : WREG32(VM_L2_CNTL2, 0);
983 0 : WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
984 : /* Setup TLB control */
985 : tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
986 : SYSTEM_ACCESS_MODE_NOT_IN_SYS |
987 : SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
988 : EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
989 0 : WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
990 0 : WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
991 0 : WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
992 0 : WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
993 0 : WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
994 0 : WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
995 0 : WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
996 0 : for (i = 0; i < 7; i++)
997 0 : WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
998 0 : }
999 :
1000 0 : static void rv770_mc_program(struct radeon_device *rdev)
1001 : {
1002 0 : struct rv515_mc_save save;
1003 : u32 tmp;
1004 : int i, j;
1005 :
1006 : /* Initialize HDP */
1007 0 : for (i = 0, j = 0; i < 32; i++, j += 0x18) {
1008 0 : WREG32((0x2c14 + j), 0x00000000);
1009 0 : WREG32((0x2c18 + j), 0x00000000);
1010 0 : WREG32((0x2c1c + j), 0x00000000);
1011 0 : WREG32((0x2c20 + j), 0x00000000);
1012 0 : WREG32((0x2c24 + j), 0x00000000);
1013 : }
1014 : /* r7xx hw bug. Read from HDP_DEBUG1 rather
1015 : * than writing to HDP_REG_COHERENCY_FLUSH_CNTL
1016 : */
1017 0 : tmp = RREG32(HDP_DEBUG1);
1018 :
1019 0 : rv515_mc_stop(rdev, &save);
1020 0 : if (r600_mc_wait_for_idle(rdev)) {
1021 0 : dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1022 0 : }
1023 : /* Lockout access through VGA aperture*/
1024 0 : WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
1025 : /* Update configuration */
1026 0 : if (rdev->flags & RADEON_IS_AGP) {
1027 0 : if (rdev->mc.vram_start < rdev->mc.gtt_start) {
1028 : /* VRAM before AGP */
1029 0 : WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
1030 : rdev->mc.vram_start >> 12);
1031 0 : WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1032 : rdev->mc.gtt_end >> 12);
1033 0 : } else {
1034 : /* VRAM after AGP */
1035 0 : WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
1036 : rdev->mc.gtt_start >> 12);
1037 0 : WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1038 : rdev->mc.vram_end >> 12);
1039 : }
1040 : } else {
1041 0 : WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
1042 : rdev->mc.vram_start >> 12);
1043 0 : WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1044 : rdev->mc.vram_end >> 12);
1045 : }
1046 0 : WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
1047 0 : tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
1048 0 : tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
1049 0 : WREG32(MC_VM_FB_LOCATION, tmp);
1050 0 : WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
1051 0 : WREG32(HDP_NONSURFACE_INFO, (2 << 7));
1052 0 : WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
1053 0 : if (rdev->flags & RADEON_IS_AGP) {
1054 0 : WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
1055 0 : WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
1056 0 : WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
1057 0 : } else {
1058 0 : WREG32(MC_VM_AGP_BASE, 0);
1059 0 : WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
1060 0 : WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
1061 : }
1062 0 : if (r600_mc_wait_for_idle(rdev)) {
1063 0 : dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1064 0 : }
1065 0 : rv515_mc_resume(rdev, &save);
1066 : /* we need to own VRAM, so turn off the VGA renderer here
1067 : * to stop it overwriting our objects */
1068 0 : rv515_vga_render_disable(rdev);
1069 0 : }
1070 :
1071 :
1072 : /*
1073 : * CP.
1074 : */
1075 0 : void r700_cp_stop(struct radeon_device *rdev)
1076 : {
1077 0 : if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
1078 0 : radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1079 0 : WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1080 0 : WREG32(SCRATCH_UMSK, 0);
1081 0 : rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1082 0 : }
1083 :
1084 0 : static int rv770_cp_load_microcode(struct radeon_device *rdev)
1085 : {
1086 : const __be32 *fw_data;
1087 : int i;
1088 :
1089 0 : if (!rdev->me_fw || !rdev->pfp_fw)
1090 0 : return -EINVAL;
1091 :
1092 0 : r700_cp_stop(rdev);
1093 0 : WREG32(CP_RB_CNTL,
1094 : #ifdef __BIG_ENDIAN
1095 : BUF_SWAP_32BIT |
1096 : #endif
1097 : RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
1098 :
1099 : /* Reset cp */
1100 0 : WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
1101 0 : RREG32(GRBM_SOFT_RESET);
1102 0 : mdelay(15);
1103 0 : WREG32(GRBM_SOFT_RESET, 0);
1104 :
1105 0 : fw_data = (const __be32 *)rdev->pfp_fw->data;
1106 0 : WREG32(CP_PFP_UCODE_ADDR, 0);
1107 0 : for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
1108 0 : WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1109 0 : WREG32(CP_PFP_UCODE_ADDR, 0);
1110 :
1111 0 : fw_data = (const __be32 *)rdev->me_fw->data;
1112 0 : WREG32(CP_ME_RAM_WADDR, 0);
1113 0 : for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
1114 0 : WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1115 :
1116 0 : WREG32(CP_PFP_UCODE_ADDR, 0);
1117 0 : WREG32(CP_ME_RAM_WADDR, 0);
1118 0 : WREG32(CP_ME_RAM_RADDR, 0);
1119 0 : return 0;
1120 0 : }
1121 :
1122 0 : void r700_cp_fini(struct radeon_device *rdev)
1123 : {
1124 0 : struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1125 0 : r700_cp_stop(rdev);
1126 0 : radeon_ring_fini(rdev, ring);
1127 0 : radeon_scratch_free(rdev, ring->rptr_save_reg);
1128 0 : }
1129 :
1130 0 : void rv770_set_clk_bypass_mode(struct radeon_device *rdev)
1131 : {
1132 : u32 tmp, i;
1133 :
1134 0 : if (rdev->flags & RADEON_IS_IGP)
1135 0 : return;
1136 :
1137 0 : tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
1138 0 : tmp &= SCLK_MUX_SEL_MASK;
1139 0 : tmp |= SCLK_MUX_SEL(1) | SCLK_MUX_UPDATE;
1140 0 : WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
1141 :
1142 0 : for (i = 0; i < rdev->usec_timeout; i++) {
1143 0 : if (RREG32(CG_SPLL_STATUS) & SPLL_CHG_STATUS)
1144 : break;
1145 0 : udelay(1);
1146 : }
1147 :
1148 0 : tmp &= ~SCLK_MUX_UPDATE;
1149 0 : WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
1150 :
1151 0 : tmp = RREG32(MPLL_CNTL_MODE);
1152 0 : if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
1153 0 : tmp &= ~RV730_MPLL_MCLK_SEL;
1154 : else
1155 0 : tmp &= ~MPLL_MCLK_SEL;
1156 0 : WREG32(MPLL_CNTL_MODE, tmp);
1157 0 : }
1158 :
1159 : /*
1160 : * Core functions
1161 : */
1162 0 : static void rv770_gpu_init(struct radeon_device *rdev)
1163 : {
1164 : int i, j, num_qd_pipes;
1165 : u32 ta_aux_cntl;
1166 : u32 sx_debug_1;
1167 : u32 smx_dc_ctl0;
1168 : u32 db_debug3;
1169 : u32 num_gs_verts_per_thread;
1170 : u32 vgt_gs_per_es;
1171 : u32 gs_prim_buffer_depth = 0;
1172 : u32 sq_ms_fifo_sizes;
1173 : u32 sq_config;
1174 : u32 sq_thread_resource_mgmt;
1175 : u32 hdp_host_path_cntl;
1176 : u32 sq_dyn_gpr_size_simd_ab_0;
1177 : u32 gb_tiling_config = 0;
1178 : u32 cc_gc_shader_pipe_config = 0;
1179 : u32 mc_arb_ramcfg;
1180 : u32 db_debug4, tmp;
1181 : u32 inactive_pipes, shader_pipe_config;
1182 : u32 disabled_rb_mask;
1183 : unsigned active_number;
1184 :
1185 : /* setup chip specs */
1186 0 : rdev->config.rv770.tiling_group_size = 256;
1187 0 : switch (rdev->family) {
1188 : case CHIP_RV770:
1189 0 : rdev->config.rv770.max_pipes = 4;
1190 0 : rdev->config.rv770.max_tile_pipes = 8;
1191 0 : rdev->config.rv770.max_simds = 10;
1192 0 : rdev->config.rv770.max_backends = 4;
1193 0 : rdev->config.rv770.max_gprs = 256;
1194 0 : rdev->config.rv770.max_threads = 248;
1195 0 : rdev->config.rv770.max_stack_entries = 512;
1196 0 : rdev->config.rv770.max_hw_contexts = 8;
1197 0 : rdev->config.rv770.max_gs_threads = 16 * 2;
1198 0 : rdev->config.rv770.sx_max_export_size = 128;
1199 0 : rdev->config.rv770.sx_max_export_pos_size = 16;
1200 0 : rdev->config.rv770.sx_max_export_smx_size = 112;
1201 0 : rdev->config.rv770.sq_num_cf_insts = 2;
1202 :
1203 0 : rdev->config.rv770.sx_num_of_sets = 7;
1204 0 : rdev->config.rv770.sc_prim_fifo_size = 0xF9;
1205 0 : rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1206 0 : rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1207 0 : break;
1208 : case CHIP_RV730:
1209 0 : rdev->config.rv770.max_pipes = 2;
1210 0 : rdev->config.rv770.max_tile_pipes = 4;
1211 0 : rdev->config.rv770.max_simds = 8;
1212 0 : rdev->config.rv770.max_backends = 2;
1213 0 : rdev->config.rv770.max_gprs = 128;
1214 0 : rdev->config.rv770.max_threads = 248;
1215 0 : rdev->config.rv770.max_stack_entries = 256;
1216 0 : rdev->config.rv770.max_hw_contexts = 8;
1217 0 : rdev->config.rv770.max_gs_threads = 16 * 2;
1218 0 : rdev->config.rv770.sx_max_export_size = 256;
1219 0 : rdev->config.rv770.sx_max_export_pos_size = 32;
1220 0 : rdev->config.rv770.sx_max_export_smx_size = 224;
1221 0 : rdev->config.rv770.sq_num_cf_insts = 2;
1222 :
1223 0 : rdev->config.rv770.sx_num_of_sets = 7;
1224 0 : rdev->config.rv770.sc_prim_fifo_size = 0xf9;
1225 0 : rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1226 0 : rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1227 0 : if (rdev->config.rv770.sx_max_export_pos_size > 16) {
1228 0 : rdev->config.rv770.sx_max_export_pos_size -= 16;
1229 0 : rdev->config.rv770.sx_max_export_smx_size += 16;
1230 0 : }
1231 : break;
1232 : case CHIP_RV710:
1233 0 : rdev->config.rv770.max_pipes = 2;
1234 0 : rdev->config.rv770.max_tile_pipes = 2;
1235 0 : rdev->config.rv770.max_simds = 2;
1236 0 : rdev->config.rv770.max_backends = 1;
1237 0 : rdev->config.rv770.max_gprs = 256;
1238 0 : rdev->config.rv770.max_threads = 192;
1239 0 : rdev->config.rv770.max_stack_entries = 256;
1240 0 : rdev->config.rv770.max_hw_contexts = 4;
1241 0 : rdev->config.rv770.max_gs_threads = 8 * 2;
1242 0 : rdev->config.rv770.sx_max_export_size = 128;
1243 0 : rdev->config.rv770.sx_max_export_pos_size = 16;
1244 0 : rdev->config.rv770.sx_max_export_smx_size = 112;
1245 0 : rdev->config.rv770.sq_num_cf_insts = 1;
1246 :
1247 0 : rdev->config.rv770.sx_num_of_sets = 7;
1248 0 : rdev->config.rv770.sc_prim_fifo_size = 0x40;
1249 0 : rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1250 0 : rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1251 0 : break;
1252 : case CHIP_RV740:
1253 0 : rdev->config.rv770.max_pipes = 4;
1254 0 : rdev->config.rv770.max_tile_pipes = 4;
1255 0 : rdev->config.rv770.max_simds = 8;
1256 0 : rdev->config.rv770.max_backends = 4;
1257 0 : rdev->config.rv770.max_gprs = 256;
1258 0 : rdev->config.rv770.max_threads = 248;
1259 0 : rdev->config.rv770.max_stack_entries = 512;
1260 0 : rdev->config.rv770.max_hw_contexts = 8;
1261 0 : rdev->config.rv770.max_gs_threads = 16 * 2;
1262 0 : rdev->config.rv770.sx_max_export_size = 256;
1263 0 : rdev->config.rv770.sx_max_export_pos_size = 32;
1264 0 : rdev->config.rv770.sx_max_export_smx_size = 224;
1265 0 : rdev->config.rv770.sq_num_cf_insts = 2;
1266 :
1267 0 : rdev->config.rv770.sx_num_of_sets = 7;
1268 0 : rdev->config.rv770.sc_prim_fifo_size = 0x100;
1269 0 : rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1270 0 : rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1271 :
1272 0 : if (rdev->config.rv770.sx_max_export_pos_size > 16) {
1273 0 : rdev->config.rv770.sx_max_export_pos_size -= 16;
1274 0 : rdev->config.rv770.sx_max_export_smx_size += 16;
1275 0 : }
1276 : break;
1277 : default:
1278 : break;
1279 : }
1280 :
1281 : /* Initialize HDP */
1282 : j = 0;
1283 0 : for (i = 0; i < 32; i++) {
1284 0 : WREG32((0x2c14 + j), 0x00000000);
1285 0 : WREG32((0x2c18 + j), 0x00000000);
1286 0 : WREG32((0x2c1c + j), 0x00000000);
1287 0 : WREG32((0x2c20 + j), 0x00000000);
1288 0 : WREG32((0x2c24 + j), 0x00000000);
1289 0 : j += 0x18;
1290 : }
1291 :
1292 0 : WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
1293 :
1294 : /* setup tiling, simd, pipe config */
1295 0 : mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
1296 :
1297 0 : shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG);
1298 0 : inactive_pipes = (shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT;
1299 0 : for (i = 0, tmp = 1, active_number = 0; i < R7XX_MAX_PIPES; i++) {
1300 0 : if (!(inactive_pipes & tmp)) {
1301 0 : active_number++;
1302 0 : }
1303 0 : tmp <<= 1;
1304 : }
1305 0 : if (active_number == 1) {
1306 0 : WREG32(SPI_CONFIG_CNTL, DISABLE_INTERP_1);
1307 0 : } else {
1308 0 : WREG32(SPI_CONFIG_CNTL, 0);
1309 : }
1310 :
1311 0 : cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
1312 0 : tmp = rdev->config.rv770.max_simds -
1313 0 : r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK);
1314 0 : rdev->config.rv770.active_simds = tmp;
1315 :
1316 0 : switch (rdev->config.rv770.max_tile_pipes) {
1317 : case 1:
1318 : default:
1319 : gb_tiling_config = PIPE_TILING(0);
1320 0 : break;
1321 : case 2:
1322 : gb_tiling_config = PIPE_TILING(1);
1323 0 : break;
1324 : case 4:
1325 : gb_tiling_config = PIPE_TILING(2);
1326 0 : break;
1327 : case 8:
1328 : gb_tiling_config = PIPE_TILING(3);
1329 0 : break;
1330 : }
1331 0 : rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes;
1332 :
1333 0 : disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R7XX_MAX_BACKENDS_MASK;
1334 : tmp = 0;
1335 0 : for (i = 0; i < rdev->config.rv770.max_backends; i++)
1336 0 : tmp |= (1 << i);
1337 : /* if all the backends are disabled, fix it up here */
1338 0 : if ((disabled_rb_mask & tmp) == tmp) {
1339 0 : for (i = 0; i < rdev->config.rv770.max_backends; i++)
1340 0 : disabled_rb_mask &= ~(1 << i);
1341 : }
1342 0 : tmp = (gb_tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT;
1343 0 : tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.rv770.max_backends,
1344 : R7XX_MAX_BACKENDS, disabled_rb_mask);
1345 0 : gb_tiling_config |= tmp << 16;
1346 0 : rdev->config.rv770.backend_map = tmp;
1347 :
1348 0 : if (rdev->family == CHIP_RV770)
1349 0 : gb_tiling_config |= BANK_TILING(1);
1350 : else {
1351 0 : if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT)
1352 0 : gb_tiling_config |= BANK_TILING(1);
1353 : else
1354 : gb_tiling_config |= BANK_TILING(0);
1355 : }
1356 0 : rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3);
1357 0 : gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT);
1358 0 : if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
1359 0 : gb_tiling_config |= ROW_TILING(3);
1360 0 : gb_tiling_config |= SAMPLE_SPLIT(3);
1361 0 : } else {
1362 0 : gb_tiling_config |=
1363 0 : ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
1364 0 : gb_tiling_config |=
1365 0 : SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
1366 : }
1367 :
1368 0 : gb_tiling_config |= BANK_SWAPS(1);
1369 0 : rdev->config.rv770.tile_config = gb_tiling_config;
1370 :
1371 0 : WREG32(GB_TILING_CONFIG, gb_tiling_config);
1372 0 : WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
1373 0 : WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
1374 0 : WREG32(DMA_TILING_CONFIG, (gb_tiling_config & 0xffff));
1375 0 : WREG32(DMA_TILING_CONFIG2, (gb_tiling_config & 0xffff));
1376 0 : if (rdev->family == CHIP_RV730) {
1377 0 : WREG32(UVD_UDEC_DB_TILING_CONFIG, (gb_tiling_config & 0xffff));
1378 0 : WREG32(UVD_UDEC_DBW_TILING_CONFIG, (gb_tiling_config & 0xffff));
1379 0 : WREG32(UVD_UDEC_TILING_CONFIG, (gb_tiling_config & 0xffff));
1380 0 : }
1381 :
1382 0 : WREG32(CGTS_SYS_TCC_DISABLE, 0);
1383 0 : WREG32(CGTS_TCC_DISABLE, 0);
1384 0 : WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
1385 0 : WREG32(CGTS_USER_TCC_DISABLE, 0);
1386 :
1387 :
1388 0 : num_qd_pipes = R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
1389 0 : WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK);
1390 0 : WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK);
1391 :
1392 : /* set HW defaults for 3D engine */
1393 0 : WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
1394 : ROQ_IB2_START(0x2b)));
1395 :
1396 0 : WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
1397 :
1398 0 : ta_aux_cntl = RREG32(TA_CNTL_AUX);
1399 0 : WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO);
1400 :
1401 0 : sx_debug_1 = RREG32(SX_DEBUG_1);
1402 0 : sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1403 0 : WREG32(SX_DEBUG_1, sx_debug_1);
1404 :
1405 0 : smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1406 0 : smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff);
1407 0 : smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1);
1408 0 : WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1409 :
1410 0 : if (rdev->family != CHIP_RV740)
1411 0 : WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
1412 : GS_FLUSH_CTL(4) |
1413 : ACK_FLUSH_CTL(3) |
1414 : SYNC_FLUSH_CTL));
1415 :
1416 0 : if (rdev->family != CHIP_RV770)
1417 0 : WREG32(SMX_SAR_CTL0, 0x00003f3f);
1418 :
1419 0 : db_debug3 = RREG32(DB_DEBUG3);
1420 0 : db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f);
1421 0 : switch (rdev->family) {
1422 : case CHIP_RV770:
1423 : case CHIP_RV740:
1424 0 : db_debug3 |= DB_CLK_OFF_DELAY(0x1f);
1425 0 : break;
1426 : case CHIP_RV710:
1427 : case CHIP_RV730:
1428 : default:
1429 0 : db_debug3 |= DB_CLK_OFF_DELAY(2);
1430 0 : break;
1431 : }
1432 0 : WREG32(DB_DEBUG3, db_debug3);
1433 :
1434 0 : if (rdev->family != CHIP_RV770) {
1435 0 : db_debug4 = RREG32(DB_DEBUG4);
1436 0 : db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER;
1437 0 : WREG32(DB_DEBUG4, db_debug4);
1438 0 : }
1439 :
1440 0 : WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) |
1441 : POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
1442 : SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
1443 :
1444 0 : WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
1445 : SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
1446 : SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
1447 :
1448 0 : WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1449 :
1450 0 : WREG32(VGT_NUM_INSTANCES, 1);
1451 :
1452 0 : WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
1453 :
1454 0 : WREG32(CP_PERFMON_CNTL, 0);
1455 :
1456 0 : sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) |
1457 0 : DONE_FIFO_HIWATER(0xe0) |
1458 : ALU_UPDATE_FIFO_HIWATER(0x8));
1459 0 : switch (rdev->family) {
1460 : case CHIP_RV770:
1461 : case CHIP_RV730:
1462 : case CHIP_RV710:
1463 0 : sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
1464 0 : break;
1465 : case CHIP_RV740:
1466 : default:
1467 0 : sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4);
1468 0 : break;
1469 : }
1470 0 : WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
1471 :
1472 : /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
1473 : * should be adjusted as needed by the 2D/3D drivers. This just sets default values
1474 : */
1475 0 : sq_config = RREG32(SQ_CONFIG);
1476 0 : sq_config &= ~(PS_PRIO(3) |
1477 : VS_PRIO(3) |
1478 : GS_PRIO(3) |
1479 : ES_PRIO(3));
1480 0 : sq_config |= (DX9_CONSTS |
1481 : VC_ENABLE |
1482 : EXPORT_SRC_C |
1483 : PS_PRIO(0) |
1484 : VS_PRIO(1) |
1485 : GS_PRIO(2) |
1486 : ES_PRIO(3));
1487 0 : if (rdev->family == CHIP_RV710)
1488 : /* no vertex cache */
1489 0 : sq_config &= ~VC_ENABLE;
1490 :
1491 0 : WREG32(SQ_CONFIG, sq_config);
1492 :
1493 0 : WREG32(SQ_GPR_RESOURCE_MGMT_1, (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
1494 : NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
1495 : NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2)));
1496 :
1497 0 : WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) |
1498 : NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64)));
1499 :
1500 0 : sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) |
1501 0 : NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) |
1502 0 : NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8));
1503 0 : if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads)
1504 0 : sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads);
1505 : else
1506 0 : sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8);
1507 0 : WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
1508 :
1509 0 : WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
1510 : NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
1511 :
1512 0 : WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
1513 : NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
1514 :
1515 0 : sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) |
1516 0 : SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) |
1517 0 : SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) |
1518 0 : SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64));
1519 :
1520 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
1521 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
1522 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
1523 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
1524 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
1525 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
1526 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
1527 0 : WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
1528 :
1529 0 : WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1530 : FORCE_EOV_MAX_REZ_CNT(255)));
1531 :
1532 0 : if (rdev->family == CHIP_RV710)
1533 0 : WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) |
1534 : AUTO_INVLD_EN(ES_AND_GS_AUTO)));
1535 : else
1536 0 : WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) |
1537 : AUTO_INVLD_EN(ES_AND_GS_AUTO)));
1538 :
1539 0 : switch (rdev->family) {
1540 : case CHIP_RV770:
1541 : case CHIP_RV730:
1542 : case CHIP_RV740:
1543 : gs_prim_buffer_depth = 384;
1544 0 : break;
1545 : case CHIP_RV710:
1546 : gs_prim_buffer_depth = 128;
1547 0 : break;
1548 : default:
1549 : break;
1550 : }
1551 :
1552 0 : num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16;
1553 0 : vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
1554 : /* Max value for this is 256 */
1555 0 : if (vgt_gs_per_es > 256)
1556 : vgt_gs_per_es = 256;
1557 :
1558 0 : WREG32(VGT_ES_PER_GS, 128);
1559 0 : WREG32(VGT_GS_PER_ES, vgt_gs_per_es);
1560 0 : WREG32(VGT_GS_PER_VS, 2);
1561 :
1562 : /* more default values. 2D/3D driver should adjust as needed */
1563 0 : WREG32(VGT_GS_VERTEX_REUSE, 16);
1564 0 : WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1565 0 : WREG32(VGT_STRMOUT_EN, 0);
1566 0 : WREG32(SX_MISC, 0);
1567 0 : WREG32(PA_SC_MODE_CNTL, 0);
1568 0 : WREG32(PA_SC_EDGERULE, 0xaaaaaaaa);
1569 0 : WREG32(PA_SC_AA_CONFIG, 0);
1570 0 : WREG32(PA_SC_CLIPRECT_RULE, 0xffff);
1571 0 : WREG32(PA_SC_LINE_STIPPLE, 0);
1572 0 : WREG32(SPI_INPUT_Z, 0);
1573 0 : WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
1574 0 : WREG32(CB_COLOR7_FRAG, 0);
1575 :
1576 : /* clear render buffer base addresses */
1577 0 : WREG32(CB_COLOR0_BASE, 0);
1578 0 : WREG32(CB_COLOR1_BASE, 0);
1579 0 : WREG32(CB_COLOR2_BASE, 0);
1580 0 : WREG32(CB_COLOR3_BASE, 0);
1581 0 : WREG32(CB_COLOR4_BASE, 0);
1582 0 : WREG32(CB_COLOR5_BASE, 0);
1583 0 : WREG32(CB_COLOR6_BASE, 0);
1584 0 : WREG32(CB_COLOR7_BASE, 0);
1585 :
1586 0 : WREG32(TCP_CNTL, 0);
1587 :
1588 0 : hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1589 0 : WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1590 :
1591 0 : WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1592 :
1593 0 : WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
1594 : NUM_CLIP_SEQ(3)));
1595 0 : WREG32(VC_ENHANCE, 0);
1596 0 : }
1597 :
1598 0 : void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
1599 : {
1600 : u64 size_bf, size_af;
1601 :
1602 0 : if (mc->mc_vram_size > 0xE0000000) {
1603 : /* leave room for at least 512M GTT */
1604 0 : dev_warn(rdev->dev, "limiting VRAM\n");
1605 0 : mc->real_vram_size = 0xE0000000;
1606 0 : mc->mc_vram_size = 0xE0000000;
1607 0 : }
1608 0 : if (rdev->flags & RADEON_IS_AGP) {
1609 0 : size_bf = mc->gtt_start;
1610 0 : size_af = mc->mc_mask - mc->gtt_end;
1611 0 : if (size_bf > size_af) {
1612 0 : if (mc->mc_vram_size > size_bf) {
1613 0 : dev_warn(rdev->dev, "limiting VRAM\n");
1614 0 : mc->real_vram_size = size_bf;
1615 0 : mc->mc_vram_size = size_bf;
1616 0 : }
1617 0 : mc->vram_start = mc->gtt_start - mc->mc_vram_size;
1618 0 : } else {
1619 0 : if (mc->mc_vram_size > size_af) {
1620 0 : dev_warn(rdev->dev, "limiting VRAM\n");
1621 0 : mc->real_vram_size = size_af;
1622 0 : mc->mc_vram_size = size_af;
1623 0 : }
1624 0 : mc->vram_start = mc->gtt_end + 1;
1625 : }
1626 0 : mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
1627 : dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
1628 : mc->mc_vram_size >> 20, mc->vram_start,
1629 : mc->vram_end, mc->real_vram_size >> 20);
1630 0 : } else {
1631 0 : radeon_vram_location(rdev, &rdev->mc, 0);
1632 0 : rdev->mc.gtt_base_align = 0;
1633 0 : radeon_gtt_location(rdev, mc);
1634 : }
1635 0 : }
1636 :
1637 0 : static int rv770_mc_init(struct radeon_device *rdev)
1638 : {
1639 : u32 tmp;
1640 : int chansize, numchan;
1641 :
1642 : /* Get VRAM informations */
1643 0 : rdev->mc.vram_is_ddr = true;
1644 0 : tmp = RREG32(MC_ARB_RAMCFG);
1645 0 : if (tmp & CHANSIZE_OVERRIDE) {
1646 : chansize = 16;
1647 0 : } else if (tmp & CHANSIZE_MASK) {
1648 : chansize = 64;
1649 0 : } else {
1650 : chansize = 32;
1651 : }
1652 0 : tmp = RREG32(MC_SHARED_CHMAP);
1653 0 : switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
1654 : case 0:
1655 : default:
1656 : numchan = 1;
1657 0 : break;
1658 : case 1:
1659 : numchan = 2;
1660 0 : break;
1661 : case 2:
1662 : numchan = 4;
1663 0 : break;
1664 : case 3:
1665 : numchan = 8;
1666 0 : break;
1667 : }
1668 0 : rdev->mc.vram_width = numchan * chansize;
1669 : /* Could aper size report 0 ? */
1670 0 : rdev->mc.aper_base = rdev->fb_aper_offset;
1671 0 : rdev->mc.aper_size = rdev->fb_aper_size;
1672 : /* Setup GPU memory space */
1673 0 : rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
1674 0 : rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
1675 0 : rdev->mc.visible_vram_size = rdev->mc.aper_size;
1676 0 : r700_vram_gtt_location(rdev, &rdev->mc);
1677 0 : radeon_update_bandwidth_info(rdev);
1678 :
1679 0 : return 0;
1680 : }
1681 :
1682 0 : static int rv770_startup(struct radeon_device *rdev)
1683 : {
1684 : struct radeon_ring *ring;
1685 : int r;
1686 :
1687 : /* enable pcie gen2 link */
1688 0 : rv770_pcie_gen2_enable(rdev);
1689 :
1690 : /* scratch needs to be initialized before MC */
1691 0 : r = r600_vram_scratch_init(rdev);
1692 0 : if (r)
1693 0 : return r;
1694 :
1695 0 : rv770_mc_program(rdev);
1696 :
1697 0 : if (rdev->flags & RADEON_IS_AGP) {
1698 0 : rv770_agp_enable(rdev);
1699 0 : } else {
1700 0 : r = rv770_pcie_gart_enable(rdev);
1701 0 : if (r)
1702 0 : return r;
1703 : }
1704 :
1705 0 : rv770_gpu_init(rdev);
1706 :
1707 : /* allocate wb buffer */
1708 0 : r = radeon_wb_init(rdev);
1709 0 : if (r)
1710 0 : return r;
1711 :
1712 0 : r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
1713 0 : if (r) {
1714 0 : dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
1715 0 : return r;
1716 : }
1717 :
1718 0 : r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
1719 0 : if (r) {
1720 0 : dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
1721 0 : return r;
1722 : }
1723 :
1724 0 : r = uvd_v2_2_resume(rdev);
1725 0 : if (!r) {
1726 0 : r = radeon_fence_driver_start_ring(rdev,
1727 : R600_RING_TYPE_UVD_INDEX);
1728 0 : if (r)
1729 0 : dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
1730 : }
1731 :
1732 0 : if (r)
1733 0 : rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
1734 :
1735 : /* Enable IRQ */
1736 0 : if (!rdev->irq.installed) {
1737 0 : r = radeon_irq_kms_init(rdev);
1738 0 : if (r)
1739 0 : return r;
1740 : }
1741 :
1742 0 : r = r600_irq_init(rdev);
1743 0 : if (r) {
1744 0 : DRM_ERROR("radeon: IH init failed (%d).\n", r);
1745 0 : radeon_irq_kms_fini(rdev);
1746 0 : return r;
1747 : }
1748 0 : r600_irq_set(rdev);
1749 :
1750 0 : ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1751 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
1752 : RADEON_CP_PACKET2);
1753 0 : if (r)
1754 0 : return r;
1755 :
1756 0 : ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
1757 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
1758 : DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
1759 0 : if (r)
1760 0 : return r;
1761 :
1762 0 : r = rv770_cp_load_microcode(rdev);
1763 0 : if (r)
1764 0 : return r;
1765 0 : r = r600_cp_resume(rdev);
1766 0 : if (r)
1767 0 : return r;
1768 :
1769 0 : r = r600_dma_resume(rdev);
1770 0 : if (r)
1771 0 : return r;
1772 :
1773 0 : ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
1774 0 : if (ring->ring_size) {
1775 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
1776 : RADEON_CP_PACKET2);
1777 0 : if (!r)
1778 0 : r = uvd_v1_0_init(rdev);
1779 :
1780 0 : if (r)
1781 0 : DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
1782 : }
1783 :
1784 0 : r = radeon_ib_pool_init(rdev);
1785 0 : if (r) {
1786 0 : dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
1787 0 : return r;
1788 : }
1789 :
1790 0 : r = radeon_audio_init(rdev);
1791 0 : if (r) {
1792 0 : DRM_ERROR("radeon: audio init failed\n");
1793 0 : return r;
1794 : }
1795 :
1796 0 : return 0;
1797 0 : }
1798 :
1799 0 : int rv770_resume(struct radeon_device *rdev)
1800 : {
1801 : int r;
1802 :
1803 : /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
1804 : * posting will perform necessary task to bring back GPU into good
1805 : * shape.
1806 : */
1807 : /* post card */
1808 0 : atom_asic_init(rdev->mode_info.atom_context);
1809 :
1810 : /* init golden registers */
1811 0 : rv770_init_golden_registers(rdev);
1812 :
1813 0 : if (rdev->pm.pm_method == PM_METHOD_DPM)
1814 0 : radeon_pm_resume(rdev);
1815 :
1816 0 : rdev->accel_working = true;
1817 0 : r = rv770_startup(rdev);
1818 0 : if (r) {
1819 0 : DRM_ERROR("r600 startup failed on resume\n");
1820 0 : rdev->accel_working = false;
1821 0 : return r;
1822 : }
1823 :
1824 0 : return r;
1825 :
1826 0 : }
1827 :
1828 0 : int rv770_suspend(struct radeon_device *rdev)
1829 : {
1830 0 : radeon_pm_suspend(rdev);
1831 0 : radeon_audio_fini(rdev);
1832 0 : uvd_v1_0_fini(rdev);
1833 0 : radeon_uvd_suspend(rdev);
1834 0 : r700_cp_stop(rdev);
1835 0 : r600_dma_stop(rdev);
1836 0 : r600_irq_suspend(rdev);
1837 0 : radeon_wb_disable(rdev);
1838 0 : rv770_pcie_gart_disable(rdev);
1839 :
1840 0 : return 0;
1841 : }
1842 :
1843 : /* Plan is to move initialization in that function and use
1844 : * helper function so that radeon_device_init pretty much
1845 : * do nothing more than calling asic specific function. This
1846 : * should also allow to remove a bunch of callback function
1847 : * like vram_info.
1848 : */
1849 0 : int rv770_init(struct radeon_device *rdev)
1850 : {
1851 : int r;
1852 :
1853 : /* Read BIOS */
1854 0 : if (!radeon_get_bios(rdev)) {
1855 0 : if (ASIC_IS_AVIVO(rdev))
1856 0 : return -EINVAL;
1857 : }
1858 : /* Must be an ATOMBIOS */
1859 0 : if (!rdev->is_atom_bios) {
1860 0 : dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
1861 0 : return -EINVAL;
1862 : }
1863 0 : r = radeon_atombios_init(rdev);
1864 0 : if (r)
1865 0 : return r;
1866 : /* Post card if necessary */
1867 0 : if (!radeon_card_posted(rdev)) {
1868 0 : if (!rdev->bios) {
1869 0 : dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
1870 0 : return -EINVAL;
1871 : }
1872 : DRM_INFO("GPU not posted. posting now...\n");
1873 0 : atom_asic_init(rdev->mode_info.atom_context);
1874 0 : }
1875 : /* init golden registers */
1876 0 : rv770_init_golden_registers(rdev);
1877 : /* Initialize scratch registers */
1878 0 : r600_scratch_init(rdev);
1879 : /* Initialize surface registers */
1880 0 : radeon_surface_init(rdev);
1881 : /* Initialize clocks */
1882 0 : radeon_get_clock_info(rdev->ddev);
1883 : /* Fence driver */
1884 0 : r = radeon_fence_driver_init(rdev);
1885 0 : if (r)
1886 0 : return r;
1887 : /* initialize AGP */
1888 0 : if (rdev->flags & RADEON_IS_AGP) {
1889 0 : r = radeon_agp_init(rdev);
1890 0 : if (r)
1891 0 : radeon_agp_disable(rdev);
1892 : }
1893 0 : r = rv770_mc_init(rdev);
1894 0 : if (r)
1895 0 : return r;
1896 : /* Memory manager */
1897 0 : r = radeon_bo_init(rdev);
1898 0 : if (r)
1899 0 : return r;
1900 :
1901 0 : if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1902 0 : r = r600_init_microcode(rdev);
1903 0 : if (r) {
1904 0 : DRM_ERROR("Failed to load firmware!\n");
1905 0 : return r;
1906 : }
1907 : }
1908 :
1909 : /* Initialize power management */
1910 0 : radeon_pm_init(rdev);
1911 :
1912 0 : rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
1913 0 : r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
1914 :
1915 0 : rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
1916 0 : r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
1917 :
1918 0 : r = radeon_uvd_init(rdev);
1919 0 : if (!r) {
1920 0 : rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
1921 0 : r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
1922 : 4096);
1923 0 : }
1924 :
1925 0 : rdev->ih.ring_obj = NULL;
1926 0 : r600_ih_ring_init(rdev, 64 * 1024);
1927 :
1928 0 : r = r600_pcie_gart_init(rdev);
1929 0 : if (r)
1930 0 : return r;
1931 :
1932 0 : rdev->accel_working = true;
1933 0 : r = rv770_startup(rdev);
1934 0 : if (r) {
1935 0 : dev_err(rdev->dev, "disabling GPU acceleration\n");
1936 0 : r700_cp_fini(rdev);
1937 0 : r600_dma_fini(rdev);
1938 0 : r600_irq_fini(rdev);
1939 0 : radeon_wb_fini(rdev);
1940 0 : radeon_ib_pool_fini(rdev);
1941 0 : radeon_irq_kms_fini(rdev);
1942 0 : rv770_pcie_gart_fini(rdev);
1943 0 : rdev->accel_working = false;
1944 0 : }
1945 :
1946 0 : return 0;
1947 0 : }
1948 :
1949 0 : void rv770_fini(struct radeon_device *rdev)
1950 : {
1951 0 : radeon_pm_fini(rdev);
1952 0 : r700_cp_fini(rdev);
1953 0 : r600_dma_fini(rdev);
1954 0 : r600_irq_fini(rdev);
1955 0 : radeon_wb_fini(rdev);
1956 0 : radeon_ib_pool_fini(rdev);
1957 0 : radeon_irq_kms_fini(rdev);
1958 0 : uvd_v1_0_fini(rdev);
1959 0 : radeon_uvd_fini(rdev);
1960 0 : rv770_pcie_gart_fini(rdev);
1961 0 : r600_vram_scratch_fini(rdev);
1962 0 : radeon_gem_fini(rdev);
1963 0 : radeon_fence_driver_fini(rdev);
1964 0 : radeon_agp_fini(rdev);
1965 0 : radeon_bo_fini(rdev);
1966 0 : radeon_atombios_fini(rdev);
1967 0 : kfree(rdev->bios);
1968 0 : rdev->bios = NULL;
1969 0 : }
1970 :
1971 0 : static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
1972 : {
1973 : u32 link_width_cntl, lanes, speed_cntl, tmp;
1974 : u16 link_cntl2;
1975 0 : u32 mask;
1976 :
1977 0 : if (radeon_pcie_gen2 == 0)
1978 0 : return;
1979 :
1980 0 : if (rdev->flags & RADEON_IS_IGP)
1981 0 : return;
1982 :
1983 0 : if (!(rdev->flags & RADEON_IS_PCIE))
1984 0 : return;
1985 :
1986 : /* x2 cards have a special sequence */
1987 0 : if (ASIC_IS_X2(rdev))
1988 0 : return;
1989 :
1990 0 : if (drm_pcie_get_speed_cap_mask(rdev->ddev, &mask))
1991 0 : return;
1992 :
1993 0 : if (!(mask & (DRM_PCIE_SPEED_50|DRM_PCIE_SPEED_80)))
1994 0 : return;
1995 :
1996 : DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
1997 :
1998 : /* advertise upconfig capability */
1999 0 : link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
2000 0 : link_width_cntl &= ~LC_UPCONFIGURE_DIS;
2001 0 : WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
2002 0 : link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
2003 0 : if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) {
2004 0 : lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT;
2005 0 : link_width_cntl &= ~(LC_LINK_WIDTH_MASK |
2006 : LC_RECONFIG_ARC_MISSING_ESCAPE);
2007 0 : link_width_cntl |= lanes | LC_RECONFIG_NOW |
2008 0 : LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT;
2009 0 : WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
2010 0 : } else {
2011 0 : link_width_cntl |= LC_UPCONFIGURE_DIS;
2012 0 : WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
2013 : }
2014 :
2015 0 : speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
2016 0 : if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
2017 0 : (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
2018 :
2019 0 : tmp = RREG32(0x541c);
2020 0 : WREG32(0x541c, tmp | 0x8);
2021 0 : WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN);
2022 0 : link_cntl2 = RREG16(0x4088);
2023 0 : link_cntl2 &= ~TARGET_LINK_SPEED_MASK;
2024 0 : link_cntl2 |= 0x2;
2025 0 : WREG16(0x4088, link_cntl2);
2026 0 : WREG32(MM_CFGREGS_CNTL, 0);
2027 :
2028 0 : speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
2029 0 : speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
2030 0 : WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
2031 :
2032 0 : speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
2033 0 : speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
2034 0 : WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
2035 :
2036 0 : speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
2037 0 : speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
2038 0 : WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
2039 :
2040 0 : speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
2041 0 : speed_cntl |= LC_GEN2_EN_STRAP;
2042 0 : WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
2043 :
2044 0 : } else {
2045 0 : link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
2046 : /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
2047 : if (1)
2048 0 : link_width_cntl |= LC_UPCONFIGURE_DIS;
2049 : else
2050 : link_width_cntl &= ~LC_UPCONFIGURE_DIS;
2051 0 : WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
2052 : }
2053 0 : }
|