blob: 91530d4c11c4458129290851d157cb5f160796b0 [file] [log] [blame]
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001/*
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 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +100028#include <linux/firmware.h>
29#include <linux/platform_device.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
David Howells760285e2012-10-02 18:01:07 +010031#include <drm/drmP.h>
Jerome Glisse771fe6b2009-06-05 14:42:42 +020032#include "radeon.h"
Daniel Vettere6990372010-03-11 21:19:17 +000033#include "radeon_asic.h"
David Howells760285e2012-10-02 18:01:07 +010034#include <drm/radeon_drm.h>
Jerome Glisse3ce0a232009-09-08 10:10:24 +100035#include "rv770d.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100036#include "atom.h"
Jerome Glissed39c3b82009-09-28 18:34:43 +020037#include "avivod.h"
Jerome Glisse771fe6b2009-06-05 14:42:42 +020038
Jerome Glisse3ce0a232009-09-08 10:10:24 +100039#define R700_PFP_UCODE_SIZE 848
40#define R700_PM4_UCODE_SIZE 1360
Jerome Glisse771fe6b2009-06-05 14:42:42 +020041
Jerome Glisse3ce0a232009-09-08 10:10:24 +100042static void rv770_gpu_init(struct radeon_device *rdev);
43void rv770_fini(struct radeon_device *rdev);
Alex Deucher9e46a482011-01-06 18:49:35 -050044static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
Christian Königef0e6e62013-04-08 12:41:35 +020045int 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
Christian König4ed10832013-04-18 15:25:58 +0200103 /* 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
Christian Königef0e6e62013-04-08 12:41:35 +0200114 /* 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
Christian Königef0e6e62013-04-08 12:41:35 +0200153 /* set UPLL_FB_DIV to 0x50000 */
154 WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(0x50000), ~UPLL_FB_DIV_MASK);
155
Christian König4ed10832013-04-18 15:25:58 +0200156 /* deassert UPLL_RESET and UPLL_SLEEP */
157 WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~(UPLL_RESET_MASK | UPLL_SLEEP_MASK));
Christian Königef0e6e62013-04-08 12:41:35 +0200158
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}
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000207
Alex Deucherfbb55662013-02-26 15:59:47 -0500208static 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
Alex Deucher454d2e22013-02-14 10:04:02 -0500855#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
Christian Königf2ba57b2013-04-08 12:41:29 +0200880int 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
Alex Deucher6f34be52010-11-21 10:59:01 -0500979u32 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);
Alex Deucherf6496472011-11-28 14:49:26 -0500983 int i;
Alex Deucher6f34be52010-11-21 10:59:01 -0500984
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. */
Alex Deucherf6496472011-11-28 14:49:26 -05001003 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 }
Alex Deucher6f34be52010-11-21 10:59:01 -05001008 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
Alex Deucher21a81222010-07-02 12:58:16 -04001018/* get temperature in millidegrees */
Alex Deucher20d391d2011-02-01 16:12:34 -05001019int rv770_get_temp(struct radeon_device *rdev)
Alex Deucher21a81222010-07-02 12:58:16 -04001020{
1021 u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
1022 ASIC_T_SHIFT;
Alex Deucher20d391d2011-02-01 16:12:34 -05001023 int actual_temp;
Alex Deucher21a81222010-07-02 12:58:16 -04001024
Alex Deucher20d391d2011-02-01 16:12:34 -05001025 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;
Alex Deucher21a81222010-07-02 12:58:16 -04001034
Alex Deucher20d391d2011-02-01 16:12:34 -05001035 return (actual_temp * 1000) / 2;
Alex Deucher21a81222010-07-02 12:58:16 -04001036}
1037
Alex Deucher49e02b72010-04-23 17:57:27 -04001038void rv770_pm_misc(struct radeon_device *rdev)
1039{
Rafał Miłeckia081a9d2010-06-07 18:20:25 -04001040 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;
Alex Deucher4d601732010-06-07 18:15:18 -04001044
1045 if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
Alex Deuchera377e182011-06-20 13:00:31 -04001046 /* 0xff01 is a flag rather then an actual voltage */
1047 if (voltage->voltage == 0xff01)
1048 return;
Alex Deucher4d601732010-06-07 18:15:18 -04001049 if (voltage->voltage != rdev->pm.current_vddc) {
Alex Deucher8a83ec52011-04-12 14:49:23 -04001050 radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
Alex Deucher4d601732010-06-07 18:15:18 -04001051 rdev->pm.current_vddc = voltage->voltage;
Rafał Miłecki0fcbe942010-06-07 18:25:21 -04001052 DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
Alex Deucher4d601732010-06-07 18:15:18 -04001053 }
1054 }
Alex Deucher49e02b72010-04-23 17:57:27 -04001055}
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001056
1057/*
1058 * GART
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001059 */
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001060static int rv770_pcie_gart_enable(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001061{
1062 u32 tmp;
1063 int r, i;
1064
Jerome Glissec9a1be92011-11-03 11:16:49 -04001065 if (rdev->gart.robj == NULL) {
Jerome Glisse4aac0472009-09-14 18:29:49 +02001066 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1067 return -EINVAL;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001068 }
Jerome Glisse4aac0472009-09-14 18:29:49 +02001069 r = radeon_gart_table_vram_pin(rdev);
1070 if (r)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001071 return r;
Dave Airlie82568562010-02-05 16:00:07 +10001072 radeon_gart_restore(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001073 /* 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);
Alex Deucher0b8c30b2012-05-31 18:54:43 -04001087 if (rdev->family == CHIP_RV740)
1088 WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001089 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);
Jerome Glisse1a029b72009-10-06 19:04:30 +02001094 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001095 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);
1102
1103 r600_pcie_gart_tlb_flush(rdev);
Tormod Voldenfcf4de52011-08-31 21:54:07 +00001104 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);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001107 rdev->gart.ready = true;
1108 return 0;
1109}
1110
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001111static void rv770_pcie_gart_disable(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001112{
1113 u32 tmp;
Jerome Glissec9a1be92011-11-03 11:16:49 -04001114 int i;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001115
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001116 /* 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);
Jerome Glissec9a1be92011-11-03 11:16:49 -04001134 radeon_gart_table_vram_unpin(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02001135}
1136
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001137static void rv770_pcie_gart_fini(struct radeon_device *rdev)
Jerome Glisse4aac0472009-09-14 18:29:49 +02001138{
Jerome Glissef9274562010-03-17 14:44:29 +00001139 radeon_gart_fini(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02001140 rv770_pcie_gart_disable(rdev);
1141 radeon_gart_table_vram_free(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001142}
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001143
1144
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001145static void rv770_agp_enable(struct radeon_device *rdev)
Jerome Glisse1a029b72009-10-06 19:04:30 +02001146{
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
Jerome Glissea3c19452009-10-01 18:02:13 +02001172static void rv770_mc_program(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001173{
Jerome Glissea3c19452009-10-01 18:02:13 +02001174 struct rv515_mc_save save;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001175 u32 tmp;
1176 int i, j;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001177
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001178 /* 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 }
Alex Deucher812d0462010-07-26 18:51:53 -04001186 /* r7xx hw bug. Read from HDP_DEBUG1 rather
1187 * than writing to HDP_REG_COHERENCY_FLUSH_CNTL
1188 */
1189 tmp = RREG32(HDP_DEBUG1);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001190
Jerome Glissea3c19452009-10-01 18:02:13 +02001191 rv515_mc_stop(rdev, &save);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001192 if (r600_mc_wait_for_idle(rdev)) {
Jerome Glissea3c19452009-10-01 18:02:13 +02001193 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001194 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001195 /* Lockout access through VGA aperture*/
1196 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001197 /* Update configuration */
Jerome Glisse1a029b72009-10-06 19:04:30 +02001198 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 }
Alex Deucher16cdf042011-10-28 10:30:02 -04001218 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
Jerome Glisse1a029b72009-10-06 19:04:30 +02001219 tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001220 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));
Jerome Glisse46fcd2b2010-06-03 19:34:48 +02001224 WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001225 if (rdev->flags & RADEON_IS_AGP) {
Jerome Glisse1a029b72009-10-06 19:04:30 +02001226 WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001227 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 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001234 if (r600_mc_wait_for_idle(rdev)) {
Jerome Glissea3c19452009-10-01 18:02:13 +02001235 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001236 }
Jerome Glissea3c19452009-10-01 18:02:13 +02001237 rv515_mc_resume(rdev, &save);
Dave Airlie698443d2009-09-18 14:16:38 +10001238 /* we need to own VRAM, so turn off the VGA renderer here
1239 * to stop it overwriting our objects */
Jerome Glissed39c3b82009-09-28 18:34:43 +02001240 rv515_vga_render_disable(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001241}
1242
1243
1244/*
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001245 * CP.
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001246 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001247void r700_cp_stop(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001248{
Dave Airlie53595332011-03-14 09:47:24 +10001249 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001250 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
Alex Deucher724c80e2010-08-27 18:25:25 -04001251 WREG32(SCRATCH_UMSK, 0);
Alex Deucher4d756582012-09-27 15:08:35 -04001252 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001253}
1254
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001255static int rv770_cp_load_microcode(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001256{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001257 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);
Cédric Cano4eace7f2011-02-11 19:45:38 -05001264 WREG32(CP_RB_CNTL,
1265#ifdef __BIG_ENDIAN
1266 BUF_SWAP_32BIT |
1267#endif
1268 RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001269
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);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001290 return 0;
1291}
1292
Alex Deucherfe251e22010-03-24 13:36:43 -04001293void r700_cp_fini(struct radeon_device *rdev)
1294{
Christian König45df6802012-07-06 16:22:55 +02001295 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucherfe251e22010-03-24 13:36:43 -04001296 r700_cp_stop(rdev);
Christian König45df6802012-07-06 16:22:55 +02001297 radeon_ring_fini(rdev, ring);
1298 radeon_scratch_free(rdev, ring->rptr_save_reg);
Alex Deucherfe251e22010-03-24 13:36:43 -04001299}
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001300
1301/*
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001302 * Core functions
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001303 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001304static void rv770_gpu_init(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001305{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001306 int i, j, num_qd_pipes;
Alex Deucherd03f5d52010-02-19 16:22:31 -05001307 u32 ta_aux_cntl;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001308 u32 sx_debug_1;
1309 u32 smx_dc_ctl0;
Alex Deucherd03f5d52010-02-19 16:22:31 -05001310 u32 db_debug3;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001311 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;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001319 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;
Alex Deucher416a2bd2012-05-31 19:00:25 -04001323 u32 db_debug4, tmp;
1324 u32 inactive_pipes, shader_pipe_config;
1325 u32 disabled_rb_mask;
1326 unsigned active_number;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001327
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001328 /* setup chip specs */
Alex Deucher416a2bd2012-05-31 19:00:25 -04001329 rdev->config.rv770.tiling_group_size = 256;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001330 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
Alex Deucher416a2bd2012-05-31 19:00:25 -04001440 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
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001470 switch (rdev->config.rv770.max_tile_pipes) {
1471 case 1:
Alex Deucherd03f5d52010-02-19 16:22:31 -05001472 default:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001473 gb_tiling_config = PIPE_TILING(0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001474 break;
1475 case 2:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001476 gb_tiling_config = PIPE_TILING(1);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001477 break;
1478 case 4:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001479 gb_tiling_config = PIPE_TILING(2);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001480 break;
1481 case 8:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001482 gb_tiling_config = PIPE_TILING(3);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001483 break;
1484 }
Alex Deucherd03f5d52010-02-19 16:22:31 -05001485 rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001486
Alex Deucher416a2bd2012-05-31 19:00:25 -04001487 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
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001494 if (rdev->family == CHIP_RV770)
1495 gb_tiling_config |= BANK_TILING(1);
Alex Deucher29d65402012-05-31 18:53:36 -04001496 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 }
Jerome Glisse961fb592010-02-10 22:30:05 +00001502 rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3);
Alex Deucher881fe6c2010-10-18 23:54:56 -04001503 gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT);
Alex Deuchere29649d2009-11-03 10:04:01 -05001504 if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001505 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);
Alex Deuchere7aeeba2010-06-04 13:10:12 -04001515 rdev->config.rv770.tile_config = gb_tiling_config;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001516
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));
Alex Deucher4d756582012-09-27 15:08:35 -04001520 WREG32(DMA_TILING_CONFIG, (gb_tiling_config & 0xffff));
1521 WREG32(DMA_TILING_CONFIG2, (gb_tiling_config & 0xffff));
Christian König9a210592013-04-08 12:41:37 +02001522 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 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001527
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001528 WREG32(CGTS_SYS_TCC_DISABLE, 0);
1529 WREG32(CGTS_TCC_DISABLE, 0);
Alex Deucherf867c60d2010-03-05 14:50:37 -05001530 WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
1531 WREG32(CGTS_USER_TCC_DISABLE, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001532
Alex Deucher416a2bd2012-05-31 19:00:25 -04001533
1534 num_qd_pipes = R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001535 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) |
Alex Deuchere29649d2009-11-03 10:04:01 -05001540 ROQ_IB2_START(0x2b)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001541
1542 WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
1543
Alex Deucherd03f5d52010-02-19 16:22:31 -05001544 ta_aux_cntl = RREG32(TA_CNTL_AUX);
1545 WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001546
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
Alex Deucherd03f5d52010-02-19 16:22:31 -05001556 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));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001561
Alex Deucherb866d132012-06-14 22:06:36 +02001562 if (rdev->family != CHIP_RV770)
1563 WREG32(SMX_SAR_CTL0, 0x00003f3f);
1564
Alex Deucherd03f5d52010-02-19 16:22:31 -05001565 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) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001581 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) |
Alex Deuchere29649d2009-11-03 10:04:01 -05001587 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)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001589
1590 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
Alex Deuchere29649d2009-11-03 10:04:01 -05001591 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)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001593
1594 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1595
1596 WREG32(VGT_NUM_INSTANCES, 1);
1597
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001598 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:
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001607 case CHIP_RV730:
1608 case CHIP_RV710:
Alex Deucherd03f5d52010-02-19 16:22:31 -05001609 sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
1610 break;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001611 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) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001640 NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
1641 NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001642
1643 WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001644 NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001645
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) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001676 FORCE_EOV_MAX_REZ_CNT(255)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001677
1678 if (rdev->family == CHIP_RV710)
1679 WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001680 AUTO_INVLD_EN(ES_AND_GS_AUTO)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001681 else
1682 WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001683 AUTO_INVLD_EN(ES_AND_GS_AUTO)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001684
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)));
Alex Deucherb866d132012-06-14 22:06:36 +02001741 WREG32(VC_ENHANCE, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001742}
1743
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001744void 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;
Alex Deucher9ed8b1f2013-04-08 11:13:01 -04001756 size_af = mc->mc_mask - mc->gtt_end;
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001757 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 }
Jerome Glissedfc6ae52012-04-17 16:51:38 -04001770 mc->vram_start = mc->gtt_end + 1;
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001771 }
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 {
Alex Deucherb4183e32010-12-15 11:04:10 -05001777 radeon_vram_location(rdev, &rdev->mc, 0);
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001778 rdev->mc.gtt_base_align = 0;
1779 radeon_gtt_location(rdev, mc);
1780 }
1781}
1782
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001783static int rv770_mc_init(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001784{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001785 u32 tmp;
Alex Deucher5885b7a2009-10-19 17:23:33 -04001786 int chansize, numchan;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001787
1788 /* Get VRAM informations */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001789 rdev->mc.vram_is_ddr = true;
Alex Deucher5885b7a2009-10-19 17:23:33 -04001790 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;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001815 /* Could aper size report 0 ? */
Jordan Crouse01d73a62010-05-27 13:40:24 -06001816 rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
1817 rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001818 /* Setup GPU memory space */
1819 rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
1820 rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
Jerome Glisse51e5fcd2010-02-19 14:33:54 +00001821 rdev->mc.visible_vram_size = rdev->mc.aper_size;
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001822 r700_vram_gtt_location(rdev, &rdev->mc);
Alex Deucherf47299c2010-03-16 20:54:38 -04001823 radeon_update_bandwidth_info(rdev);
1824
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001825 return 0;
1826}
Jerome Glissed594e462010-02-17 21:54:29 +00001827
Alex Deucher43fb7782013-01-04 09:24:18 -05001828/**
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
Dave Airliefc30b8e2009-09-18 15:19:37 +10001902static int rv770_startup(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001903{
Alex Deucher4d756582012-09-27 15:08:35 -04001904 struct radeon_ring *ring;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001905 int r;
1906
Alex Deucher9e46a482011-01-06 18:49:35 -05001907 /* enable pcie gen2 link */
1908 rv770_pcie_gen2_enable(rdev);
1909
Alex Deucher779720a2009-12-09 19:31:44 -05001910 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
Alex Deucher16cdf042011-10-28 10:30:02 -04001918 r = r600_vram_scratch_init(rdev);
1919 if (r)
1920 return r;
1921
Jerome Glissea3c19452009-10-01 18:02:13 +02001922 rv770_mc_program(rdev);
Jerome Glisse1a029b72009-10-06 19:04:30 +02001923 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 }
Alex Deucher16cdf042011-10-28 10:30:02 -04001930
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001931 rv770_gpu_init(rdev);
Jerome Glissec38c7b62010-02-04 17:27:27 +01001932 r = r600_blit_init(rdev);
1933 if (r) {
1934 r600_blit_fini(rdev);
Alex Deucher27cd7762012-02-23 17:53:42 -05001935 rdev->asic->copy.copy = NULL;
Jerome Glissec38c7b62010-02-04 17:27:27 +01001936 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
1937 }
Alex Deucherb70d6bb2010-08-06 21:36:58 -04001938
Alex Deucher724c80e2010-08-27 18:25:25 -04001939 /* allocate wb buffer */
1940 r = radeon_wb_init(rdev);
1941 if (r)
1942 return r;
1943
Jerome Glisse30eb77f2011-11-20 20:45:34 +00001944 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
Alex Deucher4d756582012-09-27 15:08:35 -04001950 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
Christian Königf2ba57b2013-04-08 12:41:29 +02001956 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
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001967 /* Enable IRQ */
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001968 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
Alex Deucher4d756582012-09-27 15:08:35 -04001976 ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Christian Könige32eb502011-10-23 12:56:27 +02001977 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
Alex Deucher78c55602011-11-17 14:25:56 -05001978 R600_CP_RB_RPTR, R600_CP_RB_WPTR,
1979 0, 0xfffff, RADEON_CP_PACKET2);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001980 if (r)
1981 return r;
Alex Deucher4d756582012-09-27 15:08:35 -04001982
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
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001990 r = rv770_cp_load_microcode(rdev);
1991 if (r)
1992 return r;
1993 r = r600_cp_resume(rdev);
1994 if (r)
1995 return r;
Alex Deucher724c80e2010-08-27 18:25:25 -04001996
Alex Deucher4d756582012-09-27 15:08:35 -04001997 r = r600_dma_resume(rdev);
1998 if (r)
1999 return r;
2000
Christian Königf2ba57b2013-04-08 12:41:29 +02002001 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
Christian König2898c342012-07-05 11:55:34 +02002014 r = radeon_ib_pool_init(rdev);
2015 if (r) {
2016 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisseb15ba512011-11-15 11:48:34 -05002017 return r;
Christian König2898c342012-07-05 11:55:34 +02002018 }
Jerome Glisseb15ba512011-11-15 11:48:34 -05002019
Alex Deucherd4e30ef2012-06-04 17:18:51 -04002020 r = r600_audio_init(rdev);
2021 if (r) {
2022 DRM_ERROR("radeon: audio init failed\n");
2023 return r;
2024 }
2025
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002026 return 0;
2027}
2028
Dave Airliefc30b8e2009-09-18 15:19:37 +10002029int rv770_resume(struct radeon_device *rdev)
2030{
2031 int r;
2032
Jerome Glisse1a029b72009-10-06 19:04:30 +02002033 /* 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 */
Dave Airliefc30b8e2009-09-18 15:19:37 +10002037 /* post card */
Jerome Glissee7d40b92009-10-01 18:02:15 +02002038 atom_asic_init(rdev->mode_info.atom_context);
Dave Airliefc30b8e2009-09-18 15:19:37 +10002039
Alex Deucherfbb55662013-02-26 15:59:47 -05002040 /* init golden registers */
2041 rv770_init_golden_registers(rdev);
2042
Jerome Glisseb15ba512011-11-15 11:48:34 -05002043 rdev->accel_working = true;
Dave Airliefc30b8e2009-09-18 15:19:37 +10002044 r = rv770_startup(rdev);
2045 if (r) {
2046 DRM_ERROR("r600 startup failed on resume\n");
Jerome Glisse6b7746e2012-02-20 17:57:20 -05002047 rdev->accel_working = false;
Dave Airliefc30b8e2009-09-18 15:19:37 +10002048 return r;
2049 }
2050
Dave Airliefc30b8e2009-09-18 15:19:37 +10002051 return r;
2052
2053}
2054
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002055int rv770_suspend(struct radeon_device *rdev)
2056{
Rafał Miłecki8a8c6e72010-03-06 13:03:36 +00002057 r600_audio_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002058 radeon_uvd_suspend(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002059 r700_cp_stop(rdev);
Alex Deucher4d756582012-09-27 15:08:35 -04002060 r600_dma_stop(rdev);
Jerome Glisse0c452492010-01-15 14:44:37 +01002061 r600_irq_suspend(rdev);
Alex Deucher724c80e2010-08-27 18:25:25 -04002062 radeon_wb_disable(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02002063 rv770_pcie_gart_disable(rdev);
Alex Deucher6ddddfe2011-10-14 10:51:22 -04002064
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002065 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
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002078 /* Read BIOS */
2079 if (!radeon_get_bios(rdev)) {
2080 if (ASIC_IS_AVIVO(rdev))
2081 return -EINVAL;
2082 }
2083 /* Must be an ATOMBIOS */
Jerome Glissee7d40b92009-10-01 18:02:15 +02002084 if (!rdev->is_atom_bios) {
2085 dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002086 return -EINVAL;
Jerome Glissee7d40b92009-10-01 18:02:15 +02002087 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002088 r = radeon_atombios_init(rdev);
2089 if (r)
2090 return r;
2091 /* Post card if necessary */
Alex Deucherfd909c32011-01-11 18:08:59 -05002092 if (!radeon_card_posted(rdev)) {
Dave Airlie72542d72009-12-01 14:06:31 +10002093 if (!rdev->bios) {
2094 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2095 return -EINVAL;
2096 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002097 DRM_INFO("GPU not posted. posting now...\n");
2098 atom_asic_init(rdev->mode_info.atom_context);
2099 }
Alex Deucherfbb55662013-02-26 15:59:47 -05002100 /* init golden registers */
2101 rv770_init_golden_registers(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002102 /* Initialize scratch registers */
2103 r600_scratch_init(rdev);
2104 /* Initialize surface registers */
2105 radeon_surface_init(rdev);
Rafał Miłecki74338742009-11-03 00:53:02 +01002106 /* Initialize clocks */
Michel Dänzer5e6dde72009-09-17 09:42:28 +02002107 radeon_get_clock_info(rdev->ddev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002108 /* Fence driver */
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002109 r = radeon_fence_driver_init(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002110 if (r)
2111 return r;
Jerome Glissed594e462010-02-17 21:54:29 +00002112 /* initialize AGP */
Jerome Glisse700a0cc2010-01-13 15:16:38 +01002113 if (rdev->flags & RADEON_IS_AGP) {
2114 r = radeon_agp_init(rdev);
2115 if (r)
2116 radeon_agp_disable(rdev);
2117 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002118 r = rv770_mc_init(rdev);
Jerome Glisseb574f252009-10-06 19:04:29 +02002119 if (r)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002120 return r;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002121 /* Memory manager */
Jerome Glisse4c788672009-11-20 14:29:23 +01002122 r = radeon_bo_init(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002123 if (r)
2124 return r;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002125
2126 r = radeon_irq_kms_init(rdev);
2127 if (r)
2128 return r;
2129
Christian Könige32eb502011-10-23 12:56:27 +02002130 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
2131 r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002132
Alex Deucher4d756582012-09-27 15:08:35 -04002133 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
Christian Königf2ba57b2013-04-08 12:41:29 +02002136 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
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002143 rdev->ih.ring_obj = NULL;
2144 r600_ih_ring_init(rdev, 64 * 1024);
2145
Jerome Glisse4aac0472009-09-14 18:29:49 +02002146 r = r600_pcie_gart_init(rdev);
2147 if (r)
2148 return r;
2149
Alex Deucher779720a2009-12-09 19:31:44 -05002150 rdev->accel_working = true;
Dave Airliefc30b8e2009-09-18 15:19:37 +10002151 r = rv770_startup(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002152 if (r) {
Jerome Glisse655efd32010-02-02 11:51:45 +01002153 dev_err(rdev->dev, "disabling GPU acceleration\n");
Alex Deucherfe251e22010-03-24 13:36:43 -04002154 r700_cp_fini(rdev);
Alex Deucher4d756582012-09-27 15:08:35 -04002155 r600_dma_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01002156 r600_irq_fini(rdev);
Alex Deucher724c80e2010-08-27 18:25:25 -04002157 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002158 radeon_ib_pool_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01002159 radeon_irq_kms_fini(rdev);
Jerome Glisse75c81292009-10-01 18:02:14 +02002160 rv770_pcie_gart_fini(rdev);
Jerome Glisse733289c2009-09-16 15:24:21 +02002161 rdev->accel_working = false;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002162 }
Rafał Miłecki8a8c6e72010-03-06 13:03:36 +00002163
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002164 return 0;
2165}
2166
2167void rv770_fini(struct radeon_device *rdev)
2168{
2169 r600_blit_fini(rdev);
Alex Deucherfe251e22010-03-24 13:36:43 -04002170 r700_cp_fini(rdev);
Alex Deucher4d756582012-09-27 15:08:35 -04002171 r600_dma_fini(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002172 r600_irq_fini(rdev);
Alex Deucher724c80e2010-08-27 18:25:25 -04002173 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002174 radeon_ib_pool_fini(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002175 radeon_irq_kms_fini(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02002176 rv770_pcie_gart_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002177 radeon_uvd_fini(rdev);
Alex Deucher16cdf042011-10-28 10:30:02 -04002178 r600_vram_scratch_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002179 radeon_gem_fini(rdev);
2180 radeon_fence_driver_fini(rdev);
Jerome Glissed0269ed2010-01-07 16:08:32 +01002181 radeon_agp_fini(rdev);
Jerome Glisse4c788672009-11-20 14:29:23 +01002182 radeon_bo_fini(rdev);
Jerome Glissee7d40b92009-10-01 18:02:15 +02002183 radeon_atombios_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002184 kfree(rdev->bios);
2185 rdev->bios = NULL;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002186}
Alex Deucher9e46a482011-01-06 18:49:35 -05002187
2188static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
2189{
2190 u32 link_width_cntl, lanes, speed_cntl, tmp;
2191 u16 link_cntl2;
Dave Airlie197bbb32012-06-27 08:35:54 +01002192 u32 mask;
2193 int ret;
Alex Deucher9e46a482011-01-06 18:49:35 -05002194
Alex Deucherd42dd572011-01-12 20:05:11 -05002195 if (radeon_pcie_gen2 == 0)
2196 return;
2197
Alex Deucher9e46a482011-01-06 18:49:35 -05002198 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
Dave Airlie197bbb32012-06-27 08:35:54 +01002208 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
Alex Deucher9e46a482011-01-06 18:49:35 -05002217 /* advertise upconfig capability */
Alex Deucher492d2b62012-10-25 16:06:59 -04002218 link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002219 link_width_cntl &= ~LC_UPCONFIGURE_DIS;
Alex Deucher492d2b62012-10-25 16:06:59 -04002220 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
2221 link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002222 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;
Alex Deucher492d2b62012-10-25 16:06:59 -04002228 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002229 } else {
2230 link_width_cntl |= LC_UPCONFIGURE_DIS;
Alex Deucher492d2b62012-10-25 16:06:59 -04002231 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002232 }
2233
Alex Deucher492d2b62012-10-25 16:06:59 -04002234 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002235 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
Alex Deucher492d2b62012-10-25 16:06:59 -04002247 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002248 speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
Alex Deucher492d2b62012-10-25 16:06:59 -04002249 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002250
Alex Deucher492d2b62012-10-25 16:06:59 -04002251 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002252 speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
Alex Deucher492d2b62012-10-25 16:06:59 -04002253 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002254
Alex Deucher492d2b62012-10-25 16:06:59 -04002255 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002256 speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
Alex Deucher492d2b62012-10-25 16:06:59 -04002257 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002258
Alex Deucher492d2b62012-10-25 16:06:59 -04002259 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002260 speed_cntl |= LC_GEN2_EN_STRAP;
Alex Deucher492d2b62012-10-25 16:06:59 -04002261 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002262
2263 } else {
Alex Deucher492d2b62012-10-25 16:06:59 -04002264 link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002265 /* 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;
Alex Deucher492d2b62012-10-25 16:06:59 -04002270 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002271 }
2272}