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