blob: 372016e266d0add52a44b3a9a012d21415d77eea [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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
David Howells760285e2012-10-02 18:01:07 +010030#include <drm/drmP.h>
Jerome Glisse771fe6b2009-06-05 14:42:42 +020031#include "radeon.h"
Daniel Vettere6990372010-03-11 21:19:17 +000032#include "radeon_asic.h"
David Howells760285e2012-10-02 18:01:07 +010033#include <drm/radeon_drm.h>
Jerome Glisse3ce0a232009-09-08 10:10:24 +100034#include "rv770d.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100035#include "atom.h"
Jerome Glissed39c3b82009-09-28 18:34:43 +020036#include "avivod.h"
Jerome Glisse771fe6b2009-06-05 14:42:42 +020037
Jerome Glisse3ce0a232009-09-08 10:10:24 +100038#define R700_PFP_UCODE_SIZE 848
39#define R700_PM4_UCODE_SIZE 1360
Jerome Glisse771fe6b2009-06-05 14:42:42 +020040
Jerome Glisse3ce0a232009-09-08 10:10:24 +100041static void rv770_gpu_init(struct radeon_device *rdev);
42void rv770_fini(struct radeon_device *rdev);
Alex Deucher9e46a482011-01-06 18:49:35 -050043static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
Christian Königef0e6e62013-04-08 12:41:35 +020044int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
45
Christian Königef0e6e62013-04-08 12:41:35 +020046int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
47{
Christian Königfacd1122013-04-29 11:55:02 +020048 unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
Christian Königef0e6e62013-04-08 12:41:35 +020049 int r;
50
51 /* RV740 uses evergreen uvd clk programming */
52 if (rdev->family == CHIP_RV740)
53 return evergreen_set_uvd_clocks(rdev, vclk, dclk);
54
Christian König4ed10832013-04-18 15:25:58 +020055 /* bypass vclk and dclk with bclk */
56 WREG32_P(CG_UPLL_FUNC_CNTL_2,
57 VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
58 ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
59
60 if (!vclk || !dclk) {
61 /* keep the Bypass mode, put PLL to sleep */
62 WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
63 return 0;
64 }
65
Christian Königfacd1122013-04-29 11:55:02 +020066 r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 50000, 160000,
67 43663, 0x03FFFFFE, 1, 30, ~0,
68 &fb_div, &vclk_div, &dclk_div);
69 if (r)
70 return r;
Christian Königef0e6e62013-04-08 12:41:35 +020071
Christian Königfacd1122013-04-29 11:55:02 +020072 fb_div |= 1;
73 vclk_div -= 1;
74 dclk_div -= 1;
Christian Königef0e6e62013-04-08 12:41:35 +020075
Christian Königef0e6e62013-04-08 12:41:35 +020076 /* set UPLL_FB_DIV to 0x50000 */
77 WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(0x50000), ~UPLL_FB_DIV_MASK);
78
Christian König4ed10832013-04-18 15:25:58 +020079 /* deassert UPLL_RESET and UPLL_SLEEP */
80 WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~(UPLL_RESET_MASK | UPLL_SLEEP_MASK));
Christian Königef0e6e62013-04-08 12:41:35 +020081
82 /* assert BYPASS EN and FB_DIV[0] <- ??? why? */
83 WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
84 WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(1), ~UPLL_FB_DIV(1));
85
Christian Königfacd1122013-04-29 11:55:02 +020086 r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
Christian Königef0e6e62013-04-08 12:41:35 +020087 if (r)
88 return r;
89
90 /* assert PLL_RESET */
91 WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
92
93 /* set the required FB_DIV, REF_DIV, Post divder values */
94 WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_REF_DIV(1), ~UPLL_REF_DIV_MASK);
95 WREG32_P(CG_UPLL_FUNC_CNTL_2,
Christian Königfacd1122013-04-29 11:55:02 +020096 UPLL_SW_HILEN(vclk_div >> 1) |
97 UPLL_SW_LOLEN((vclk_div >> 1) + (vclk_div & 1)) |
98 UPLL_SW_HILEN2(dclk_div >> 1) |
99 UPLL_SW_LOLEN2((dclk_div >> 1) + (dclk_div & 1)),
Christian Königef0e6e62013-04-08 12:41:35 +0200100 ~UPLL_SW_MASK);
101
Christian Königfacd1122013-04-29 11:55:02 +0200102 WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div),
Christian Königef0e6e62013-04-08 12:41:35 +0200103 ~UPLL_FB_DIV_MASK);
104
105 /* give the PLL some time to settle */
106 mdelay(15);
107
108 /* deassert PLL_RESET */
109 WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
110
111 mdelay(15);
112
113 /* deassert BYPASS EN and FB_DIV[0] <- ??? why? */
114 WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
115 WREG32_P(CG_UPLL_FUNC_CNTL_3, 0, ~UPLL_FB_DIV(1));
116
Christian Königfacd1122013-04-29 11:55:02 +0200117 r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
Christian Königef0e6e62013-04-08 12:41:35 +0200118 if (r)
119 return r;
120
121 /* switch VCLK and DCLK selection */
122 WREG32_P(CG_UPLL_FUNC_CNTL_2,
123 VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
124 ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
125
126 mdelay(100);
127
128 return 0;
129}
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000130
Alex Deucherfbb55662013-02-26 15:59:47 -0500131static const u32 r7xx_golden_registers[] =
132{
133 0x8d00, 0xffffffff, 0x0e0e0074,
134 0x8d04, 0xffffffff, 0x013a2b34,
135 0x9508, 0xffffffff, 0x00000002,
136 0x8b20, 0xffffffff, 0,
137 0x88c4, 0xffffffff, 0x000000c2,
138 0x28350, 0xffffffff, 0,
139 0x9058, 0xffffffff, 0x0fffc40f,
140 0x240c, 0xffffffff, 0x00000380,
141 0x733c, 0xffffffff, 0x00000002,
142 0x2650, 0x00040000, 0,
143 0x20bc, 0x00040000, 0,
144 0x7300, 0xffffffff, 0x001000f0
145};
146
147static const u32 r7xx_golden_dyn_gpr_registers[] =
148{
149 0x8db0, 0xffffffff, 0x98989898,
150 0x8db4, 0xffffffff, 0x98989898,
151 0x8db8, 0xffffffff, 0x98989898,
152 0x8dbc, 0xffffffff, 0x98989898,
153 0x8dc0, 0xffffffff, 0x98989898,
154 0x8dc4, 0xffffffff, 0x98989898,
155 0x8dc8, 0xffffffff, 0x98989898,
156 0x8dcc, 0xffffffff, 0x98989898,
157 0x88c4, 0xffffffff, 0x00000082
158};
159
160static const u32 rv770_golden_registers[] =
161{
162 0x562c, 0xffffffff, 0,
163 0x3f90, 0xffffffff, 0,
164 0x9148, 0xffffffff, 0,
165 0x3f94, 0xffffffff, 0,
166 0x914c, 0xffffffff, 0,
167 0x9698, 0x18000000, 0x18000000
168};
169
170static const u32 rv770ce_golden_registers[] =
171{
172 0x562c, 0xffffffff, 0,
173 0x3f90, 0xffffffff, 0x00cc0000,
174 0x9148, 0xffffffff, 0x00cc0000,
175 0x3f94, 0xffffffff, 0x00cc0000,
176 0x914c, 0xffffffff, 0x00cc0000,
177 0x9b7c, 0xffffffff, 0x00fa0000,
178 0x3f8c, 0xffffffff, 0x00fa0000,
179 0x9698, 0x18000000, 0x18000000
180};
181
182static const u32 rv770_mgcg_init[] =
183{
184 0x8bcc, 0xffffffff, 0x130300f9,
185 0x5448, 0xffffffff, 0x100,
186 0x55e4, 0xffffffff, 0x100,
187 0x160c, 0xffffffff, 0x100,
188 0x5644, 0xffffffff, 0x100,
189 0xc164, 0xffffffff, 0x100,
190 0x8a18, 0xffffffff, 0x100,
191 0x897c, 0xffffffff, 0x8000100,
192 0x8b28, 0xffffffff, 0x3c000100,
193 0x9144, 0xffffffff, 0x100,
194 0x9a1c, 0xffffffff, 0x10000,
195 0x9a50, 0xffffffff, 0x100,
196 0x9a1c, 0xffffffff, 0x10001,
197 0x9a50, 0xffffffff, 0x100,
198 0x9a1c, 0xffffffff, 0x10002,
199 0x9a50, 0xffffffff, 0x100,
200 0x9a1c, 0xffffffff, 0x10003,
201 0x9a50, 0xffffffff, 0x100,
202 0x9a1c, 0xffffffff, 0x0,
203 0x9870, 0xffffffff, 0x100,
204 0x8d58, 0xffffffff, 0x100,
205 0x9500, 0xffffffff, 0x0,
206 0x9510, 0xffffffff, 0x100,
207 0x9500, 0xffffffff, 0x1,
208 0x9510, 0xffffffff, 0x100,
209 0x9500, 0xffffffff, 0x2,
210 0x9510, 0xffffffff, 0x100,
211 0x9500, 0xffffffff, 0x3,
212 0x9510, 0xffffffff, 0x100,
213 0x9500, 0xffffffff, 0x4,
214 0x9510, 0xffffffff, 0x100,
215 0x9500, 0xffffffff, 0x5,
216 0x9510, 0xffffffff, 0x100,
217 0x9500, 0xffffffff, 0x6,
218 0x9510, 0xffffffff, 0x100,
219 0x9500, 0xffffffff, 0x7,
220 0x9510, 0xffffffff, 0x100,
221 0x9500, 0xffffffff, 0x8,
222 0x9510, 0xffffffff, 0x100,
223 0x9500, 0xffffffff, 0x9,
224 0x9510, 0xffffffff, 0x100,
225 0x9500, 0xffffffff, 0x8000,
226 0x9490, 0xffffffff, 0x0,
227 0x949c, 0xffffffff, 0x100,
228 0x9490, 0xffffffff, 0x1,
229 0x949c, 0xffffffff, 0x100,
230 0x9490, 0xffffffff, 0x2,
231 0x949c, 0xffffffff, 0x100,
232 0x9490, 0xffffffff, 0x3,
233 0x949c, 0xffffffff, 0x100,
234 0x9490, 0xffffffff, 0x4,
235 0x949c, 0xffffffff, 0x100,
236 0x9490, 0xffffffff, 0x5,
237 0x949c, 0xffffffff, 0x100,
238 0x9490, 0xffffffff, 0x6,
239 0x949c, 0xffffffff, 0x100,
240 0x9490, 0xffffffff, 0x7,
241 0x949c, 0xffffffff, 0x100,
242 0x9490, 0xffffffff, 0x8,
243 0x949c, 0xffffffff, 0x100,
244 0x9490, 0xffffffff, 0x9,
245 0x949c, 0xffffffff, 0x100,
246 0x9490, 0xffffffff, 0x8000,
247 0x9604, 0xffffffff, 0x0,
248 0x9654, 0xffffffff, 0x100,
249 0x9604, 0xffffffff, 0x1,
250 0x9654, 0xffffffff, 0x100,
251 0x9604, 0xffffffff, 0x2,
252 0x9654, 0xffffffff, 0x100,
253 0x9604, 0xffffffff, 0x3,
254 0x9654, 0xffffffff, 0x100,
255 0x9604, 0xffffffff, 0x4,
256 0x9654, 0xffffffff, 0x100,
257 0x9604, 0xffffffff, 0x5,
258 0x9654, 0xffffffff, 0x100,
259 0x9604, 0xffffffff, 0x6,
260 0x9654, 0xffffffff, 0x100,
261 0x9604, 0xffffffff, 0x7,
262 0x9654, 0xffffffff, 0x100,
263 0x9604, 0xffffffff, 0x8,
264 0x9654, 0xffffffff, 0x100,
265 0x9604, 0xffffffff, 0x9,
266 0x9654, 0xffffffff, 0x100,
267 0x9604, 0xffffffff, 0x80000000,
268 0x9030, 0xffffffff, 0x100,
269 0x9034, 0xffffffff, 0x100,
270 0x9038, 0xffffffff, 0x100,
271 0x903c, 0xffffffff, 0x100,
272 0x9040, 0xffffffff, 0x100,
273 0xa200, 0xffffffff, 0x100,
274 0xa204, 0xffffffff, 0x100,
275 0xa208, 0xffffffff, 0x100,
276 0xa20c, 0xffffffff, 0x100,
277 0x971c, 0xffffffff, 0x100,
278 0x915c, 0xffffffff, 0x00020001,
279 0x9160, 0xffffffff, 0x00040003,
280 0x916c, 0xffffffff, 0x00060005,
281 0x9170, 0xffffffff, 0x00080007,
282 0x9174, 0xffffffff, 0x000a0009,
283 0x9178, 0xffffffff, 0x000c000b,
284 0x917c, 0xffffffff, 0x000e000d,
285 0x9180, 0xffffffff, 0x0010000f,
286 0x918c, 0xffffffff, 0x00120011,
287 0x9190, 0xffffffff, 0x00140013,
288 0x9194, 0xffffffff, 0x00020001,
289 0x9198, 0xffffffff, 0x00040003,
290 0x919c, 0xffffffff, 0x00060005,
291 0x91a8, 0xffffffff, 0x00080007,
292 0x91ac, 0xffffffff, 0x000a0009,
293 0x91b0, 0xffffffff, 0x000c000b,
294 0x91b4, 0xffffffff, 0x000e000d,
295 0x91b8, 0xffffffff, 0x0010000f,
296 0x91c4, 0xffffffff, 0x00120011,
297 0x91c8, 0xffffffff, 0x00140013,
298 0x91cc, 0xffffffff, 0x00020001,
299 0x91d0, 0xffffffff, 0x00040003,
300 0x91d4, 0xffffffff, 0x00060005,
301 0x91e0, 0xffffffff, 0x00080007,
302 0x91e4, 0xffffffff, 0x000a0009,
303 0x91e8, 0xffffffff, 0x000c000b,
304 0x91ec, 0xffffffff, 0x00020001,
305 0x91f0, 0xffffffff, 0x00040003,
306 0x91f4, 0xffffffff, 0x00060005,
307 0x9200, 0xffffffff, 0x00080007,
308 0x9204, 0xffffffff, 0x000a0009,
309 0x9208, 0xffffffff, 0x000c000b,
310 0x920c, 0xffffffff, 0x000e000d,
311 0x9210, 0xffffffff, 0x0010000f,
312 0x921c, 0xffffffff, 0x00120011,
313 0x9220, 0xffffffff, 0x00140013,
314 0x9224, 0xffffffff, 0x00020001,
315 0x9228, 0xffffffff, 0x00040003,
316 0x922c, 0xffffffff, 0x00060005,
317 0x9238, 0xffffffff, 0x00080007,
318 0x923c, 0xffffffff, 0x000a0009,
319 0x9240, 0xffffffff, 0x000c000b,
320 0x9244, 0xffffffff, 0x000e000d,
321 0x9248, 0xffffffff, 0x0010000f,
322 0x9254, 0xffffffff, 0x00120011,
323 0x9258, 0xffffffff, 0x00140013,
324 0x925c, 0xffffffff, 0x00020001,
325 0x9260, 0xffffffff, 0x00040003,
326 0x9264, 0xffffffff, 0x00060005,
327 0x9270, 0xffffffff, 0x00080007,
328 0x9274, 0xffffffff, 0x000a0009,
329 0x9278, 0xffffffff, 0x000c000b,
330 0x927c, 0xffffffff, 0x000e000d,
331 0x9280, 0xffffffff, 0x0010000f,
332 0x928c, 0xffffffff, 0x00120011,
333 0x9290, 0xffffffff, 0x00140013,
334 0x9294, 0xffffffff, 0x00020001,
335 0x929c, 0xffffffff, 0x00040003,
336 0x92a0, 0xffffffff, 0x00060005,
337 0x92a4, 0xffffffff, 0x00080007
338};
339
340static const u32 rv710_golden_registers[] =
341{
342 0x3f90, 0x00ff0000, 0x00fc0000,
343 0x9148, 0x00ff0000, 0x00fc0000,
344 0x3f94, 0x00ff0000, 0x00fc0000,
345 0x914c, 0x00ff0000, 0x00fc0000,
346 0xb4c, 0x00000020, 0x00000020,
347 0xa180, 0xffffffff, 0x00003f3f
348};
349
350static const u32 rv710_mgcg_init[] =
351{
352 0x8bcc, 0xffffffff, 0x13030040,
353 0x5448, 0xffffffff, 0x100,
354 0x55e4, 0xffffffff, 0x100,
355 0x160c, 0xffffffff, 0x100,
356 0x5644, 0xffffffff, 0x100,
357 0xc164, 0xffffffff, 0x100,
358 0x8a18, 0xffffffff, 0x100,
359 0x897c, 0xffffffff, 0x8000100,
360 0x8b28, 0xffffffff, 0x3c000100,
361 0x9144, 0xffffffff, 0x100,
362 0x9a1c, 0xffffffff, 0x10000,
363 0x9a50, 0xffffffff, 0x100,
364 0x9a1c, 0xffffffff, 0x0,
365 0x9870, 0xffffffff, 0x100,
366 0x8d58, 0xffffffff, 0x100,
367 0x9500, 0xffffffff, 0x0,
368 0x9510, 0xffffffff, 0x100,
369 0x9500, 0xffffffff, 0x1,
370 0x9510, 0xffffffff, 0x100,
371 0x9500, 0xffffffff, 0x8000,
372 0x9490, 0xffffffff, 0x0,
373 0x949c, 0xffffffff, 0x100,
374 0x9490, 0xffffffff, 0x1,
375 0x949c, 0xffffffff, 0x100,
376 0x9490, 0xffffffff, 0x8000,
377 0x9604, 0xffffffff, 0x0,
378 0x9654, 0xffffffff, 0x100,
379 0x9604, 0xffffffff, 0x1,
380 0x9654, 0xffffffff, 0x100,
381 0x9604, 0xffffffff, 0x80000000,
382 0x9030, 0xffffffff, 0x100,
383 0x9034, 0xffffffff, 0x100,
384 0x9038, 0xffffffff, 0x100,
385 0x903c, 0xffffffff, 0x100,
386 0x9040, 0xffffffff, 0x100,
387 0xa200, 0xffffffff, 0x100,
388 0xa204, 0xffffffff, 0x100,
389 0xa208, 0xffffffff, 0x100,
390 0xa20c, 0xffffffff, 0x100,
391 0x971c, 0xffffffff, 0x100,
392 0x915c, 0xffffffff, 0x00020001,
393 0x9174, 0xffffffff, 0x00000003,
394 0x9178, 0xffffffff, 0x00050001,
395 0x917c, 0xffffffff, 0x00030002,
396 0x918c, 0xffffffff, 0x00000004,
397 0x9190, 0xffffffff, 0x00070006,
398 0x9194, 0xffffffff, 0x00050001,
399 0x9198, 0xffffffff, 0x00030002,
400 0x91a8, 0xffffffff, 0x00000004,
401 0x91ac, 0xffffffff, 0x00070006,
402 0x91e8, 0xffffffff, 0x00000001,
403 0x9294, 0xffffffff, 0x00000001,
404 0x929c, 0xffffffff, 0x00000002,
405 0x92a0, 0xffffffff, 0x00040003,
406 0x9150, 0xffffffff, 0x4d940000
407};
408
409static const u32 rv730_golden_registers[] =
410{
411 0x3f90, 0x00ff0000, 0x00f00000,
412 0x9148, 0x00ff0000, 0x00f00000,
413 0x3f94, 0x00ff0000, 0x00f00000,
414 0x914c, 0x00ff0000, 0x00f00000,
415 0x900c, 0xffffffff, 0x003b033f,
416 0xb4c, 0x00000020, 0x00000020,
417 0xa180, 0xffffffff, 0x00003f3f
418};
419
420static const u32 rv730_mgcg_init[] =
421{
422 0x8bcc, 0xffffffff, 0x130300f9,
423 0x5448, 0xffffffff, 0x100,
424 0x55e4, 0xffffffff, 0x100,
425 0x160c, 0xffffffff, 0x100,
426 0x5644, 0xffffffff, 0x100,
427 0xc164, 0xffffffff, 0x100,
428 0x8a18, 0xffffffff, 0x100,
429 0x897c, 0xffffffff, 0x8000100,
430 0x8b28, 0xffffffff, 0x3c000100,
431 0x9144, 0xffffffff, 0x100,
432 0x9a1c, 0xffffffff, 0x10000,
433 0x9a50, 0xffffffff, 0x100,
434 0x9a1c, 0xffffffff, 0x10001,
435 0x9a50, 0xffffffff, 0x100,
436 0x9a1c, 0xffffffff, 0x0,
437 0x9870, 0xffffffff, 0x100,
438 0x8d58, 0xffffffff, 0x100,
439 0x9500, 0xffffffff, 0x0,
440 0x9510, 0xffffffff, 0x100,
441 0x9500, 0xffffffff, 0x1,
442 0x9510, 0xffffffff, 0x100,
443 0x9500, 0xffffffff, 0x2,
444 0x9510, 0xffffffff, 0x100,
445 0x9500, 0xffffffff, 0x3,
446 0x9510, 0xffffffff, 0x100,
447 0x9500, 0xffffffff, 0x4,
448 0x9510, 0xffffffff, 0x100,
449 0x9500, 0xffffffff, 0x5,
450 0x9510, 0xffffffff, 0x100,
451 0x9500, 0xffffffff, 0x6,
452 0x9510, 0xffffffff, 0x100,
453 0x9500, 0xffffffff, 0x7,
454 0x9510, 0xffffffff, 0x100,
455 0x9500, 0xffffffff, 0x8000,
456 0x9490, 0xffffffff, 0x0,
457 0x949c, 0xffffffff, 0x100,
458 0x9490, 0xffffffff, 0x1,
459 0x949c, 0xffffffff, 0x100,
460 0x9490, 0xffffffff, 0x2,
461 0x949c, 0xffffffff, 0x100,
462 0x9490, 0xffffffff, 0x3,
463 0x949c, 0xffffffff, 0x100,
464 0x9490, 0xffffffff, 0x4,
465 0x949c, 0xffffffff, 0x100,
466 0x9490, 0xffffffff, 0x5,
467 0x949c, 0xffffffff, 0x100,
468 0x9490, 0xffffffff, 0x6,
469 0x949c, 0xffffffff, 0x100,
470 0x9490, 0xffffffff, 0x7,
471 0x949c, 0xffffffff, 0x100,
472 0x9490, 0xffffffff, 0x8000,
473 0x9604, 0xffffffff, 0x0,
474 0x9654, 0xffffffff, 0x100,
475 0x9604, 0xffffffff, 0x1,
476 0x9654, 0xffffffff, 0x100,
477 0x9604, 0xffffffff, 0x2,
478 0x9654, 0xffffffff, 0x100,
479 0x9604, 0xffffffff, 0x3,
480 0x9654, 0xffffffff, 0x100,
481 0x9604, 0xffffffff, 0x4,
482 0x9654, 0xffffffff, 0x100,
483 0x9604, 0xffffffff, 0x5,
484 0x9654, 0xffffffff, 0x100,
485 0x9604, 0xffffffff, 0x6,
486 0x9654, 0xffffffff, 0x100,
487 0x9604, 0xffffffff, 0x7,
488 0x9654, 0xffffffff, 0x100,
489 0x9604, 0xffffffff, 0x80000000,
490 0x9030, 0xffffffff, 0x100,
491 0x9034, 0xffffffff, 0x100,
492 0x9038, 0xffffffff, 0x100,
493 0x903c, 0xffffffff, 0x100,
494 0x9040, 0xffffffff, 0x100,
495 0xa200, 0xffffffff, 0x100,
496 0xa204, 0xffffffff, 0x100,
497 0xa208, 0xffffffff, 0x100,
498 0xa20c, 0xffffffff, 0x100,
499 0x971c, 0xffffffff, 0x100,
500 0x915c, 0xffffffff, 0x00020001,
501 0x916c, 0xffffffff, 0x00040003,
502 0x9170, 0xffffffff, 0x00000005,
503 0x9178, 0xffffffff, 0x00050001,
504 0x917c, 0xffffffff, 0x00030002,
505 0x918c, 0xffffffff, 0x00000004,
506 0x9190, 0xffffffff, 0x00070006,
507 0x9194, 0xffffffff, 0x00050001,
508 0x9198, 0xffffffff, 0x00030002,
509 0x91a8, 0xffffffff, 0x00000004,
510 0x91ac, 0xffffffff, 0x00070006,
511 0x91b0, 0xffffffff, 0x00050001,
512 0x91b4, 0xffffffff, 0x00030002,
513 0x91c4, 0xffffffff, 0x00000004,
514 0x91c8, 0xffffffff, 0x00070006,
515 0x91cc, 0xffffffff, 0x00050001,
516 0x91d0, 0xffffffff, 0x00030002,
517 0x91e0, 0xffffffff, 0x00000004,
518 0x91e4, 0xffffffff, 0x00070006,
519 0x91e8, 0xffffffff, 0x00000001,
520 0x91ec, 0xffffffff, 0x00050001,
521 0x91f0, 0xffffffff, 0x00030002,
522 0x9200, 0xffffffff, 0x00000004,
523 0x9204, 0xffffffff, 0x00070006,
524 0x9208, 0xffffffff, 0x00050001,
525 0x920c, 0xffffffff, 0x00030002,
526 0x921c, 0xffffffff, 0x00000004,
527 0x9220, 0xffffffff, 0x00070006,
528 0x9224, 0xffffffff, 0x00050001,
529 0x9228, 0xffffffff, 0x00030002,
530 0x9238, 0xffffffff, 0x00000004,
531 0x923c, 0xffffffff, 0x00070006,
532 0x9240, 0xffffffff, 0x00050001,
533 0x9244, 0xffffffff, 0x00030002,
534 0x9254, 0xffffffff, 0x00000004,
535 0x9258, 0xffffffff, 0x00070006,
536 0x9294, 0xffffffff, 0x00000001,
537 0x929c, 0xffffffff, 0x00000002,
538 0x92a0, 0xffffffff, 0x00040003,
539 0x92a4, 0xffffffff, 0x00000005
540};
541
542static const u32 rv740_golden_registers[] =
543{
544 0x88c4, 0xffffffff, 0x00000082,
545 0x28a50, 0xfffffffc, 0x00000004,
546 0x2650, 0x00040000, 0,
547 0x20bc, 0x00040000, 0,
548 0x733c, 0xffffffff, 0x00000002,
549 0x7300, 0xffffffff, 0x001000f0,
550 0x3f90, 0x00ff0000, 0,
551 0x9148, 0x00ff0000, 0,
552 0x3f94, 0x00ff0000, 0,
553 0x914c, 0x00ff0000, 0,
554 0x240c, 0xffffffff, 0x00000380,
555 0x8a14, 0x00000007, 0x00000007,
556 0x8b24, 0xffffffff, 0x00ff0fff,
557 0x28a4c, 0xffffffff, 0x00004000,
558 0xa180, 0xffffffff, 0x00003f3f,
559 0x8d00, 0xffffffff, 0x0e0e003a,
560 0x8d04, 0xffffffff, 0x013a0e2a,
561 0x8c00, 0xffffffff, 0xe400000f,
562 0x8db0, 0xffffffff, 0x98989898,
563 0x8db4, 0xffffffff, 0x98989898,
564 0x8db8, 0xffffffff, 0x98989898,
565 0x8dbc, 0xffffffff, 0x98989898,
566 0x8dc0, 0xffffffff, 0x98989898,
567 0x8dc4, 0xffffffff, 0x98989898,
568 0x8dc8, 0xffffffff, 0x98989898,
569 0x8dcc, 0xffffffff, 0x98989898,
570 0x9058, 0xffffffff, 0x0fffc40f,
571 0x900c, 0xffffffff, 0x003b033f,
572 0x28350, 0xffffffff, 0,
573 0x8cf0, 0x1fffffff, 0x08e00420,
574 0x9508, 0xffffffff, 0x00000002,
575 0x88c4, 0xffffffff, 0x000000c2,
576 0x9698, 0x18000000, 0x18000000
577};
578
579static const u32 rv740_mgcg_init[] =
580{
581 0x8bcc, 0xffffffff, 0x13030100,
582 0x5448, 0xffffffff, 0x100,
583 0x55e4, 0xffffffff, 0x100,
584 0x160c, 0xffffffff, 0x100,
585 0x5644, 0xffffffff, 0x100,
586 0xc164, 0xffffffff, 0x100,
587 0x8a18, 0xffffffff, 0x100,
588 0x897c, 0xffffffff, 0x100,
589 0x8b28, 0xffffffff, 0x100,
590 0x9144, 0xffffffff, 0x100,
591 0x9a1c, 0xffffffff, 0x10000,
592 0x9a50, 0xffffffff, 0x100,
593 0x9a1c, 0xffffffff, 0x10001,
594 0x9a50, 0xffffffff, 0x100,
595 0x9a1c, 0xffffffff, 0x10002,
596 0x9a50, 0xffffffff, 0x100,
597 0x9a1c, 0xffffffff, 0x10003,
598 0x9a50, 0xffffffff, 0x100,
599 0x9a1c, 0xffffffff, 0x0,
600 0x9870, 0xffffffff, 0x100,
601 0x8d58, 0xffffffff, 0x100,
602 0x9500, 0xffffffff, 0x0,
603 0x9510, 0xffffffff, 0x100,
604 0x9500, 0xffffffff, 0x1,
605 0x9510, 0xffffffff, 0x100,
606 0x9500, 0xffffffff, 0x2,
607 0x9510, 0xffffffff, 0x100,
608 0x9500, 0xffffffff, 0x3,
609 0x9510, 0xffffffff, 0x100,
610 0x9500, 0xffffffff, 0x4,
611 0x9510, 0xffffffff, 0x100,
612 0x9500, 0xffffffff, 0x5,
613 0x9510, 0xffffffff, 0x100,
614 0x9500, 0xffffffff, 0x6,
615 0x9510, 0xffffffff, 0x100,
616 0x9500, 0xffffffff, 0x7,
617 0x9510, 0xffffffff, 0x100,
618 0x9500, 0xffffffff, 0x8000,
619 0x9490, 0xffffffff, 0x0,
620 0x949c, 0xffffffff, 0x100,
621 0x9490, 0xffffffff, 0x1,
622 0x949c, 0xffffffff, 0x100,
623 0x9490, 0xffffffff, 0x2,
624 0x949c, 0xffffffff, 0x100,
625 0x9490, 0xffffffff, 0x3,
626 0x949c, 0xffffffff, 0x100,
627 0x9490, 0xffffffff, 0x4,
628 0x949c, 0xffffffff, 0x100,
629 0x9490, 0xffffffff, 0x5,
630 0x949c, 0xffffffff, 0x100,
631 0x9490, 0xffffffff, 0x6,
632 0x949c, 0xffffffff, 0x100,
633 0x9490, 0xffffffff, 0x7,
634 0x949c, 0xffffffff, 0x100,
635 0x9490, 0xffffffff, 0x8000,
636 0x9604, 0xffffffff, 0x0,
637 0x9654, 0xffffffff, 0x100,
638 0x9604, 0xffffffff, 0x1,
639 0x9654, 0xffffffff, 0x100,
640 0x9604, 0xffffffff, 0x2,
641 0x9654, 0xffffffff, 0x100,
642 0x9604, 0xffffffff, 0x3,
643 0x9654, 0xffffffff, 0x100,
644 0x9604, 0xffffffff, 0x4,
645 0x9654, 0xffffffff, 0x100,
646 0x9604, 0xffffffff, 0x5,
647 0x9654, 0xffffffff, 0x100,
648 0x9604, 0xffffffff, 0x6,
649 0x9654, 0xffffffff, 0x100,
650 0x9604, 0xffffffff, 0x7,
651 0x9654, 0xffffffff, 0x100,
652 0x9604, 0xffffffff, 0x80000000,
653 0x9030, 0xffffffff, 0x100,
654 0x9034, 0xffffffff, 0x100,
655 0x9038, 0xffffffff, 0x100,
656 0x903c, 0xffffffff, 0x100,
657 0x9040, 0xffffffff, 0x100,
658 0xa200, 0xffffffff, 0x100,
659 0xa204, 0xffffffff, 0x100,
660 0xa208, 0xffffffff, 0x100,
661 0xa20c, 0xffffffff, 0x100,
662 0x971c, 0xffffffff, 0x100,
663 0x915c, 0xffffffff, 0x00020001,
664 0x9160, 0xffffffff, 0x00040003,
665 0x916c, 0xffffffff, 0x00060005,
666 0x9170, 0xffffffff, 0x00080007,
667 0x9174, 0xffffffff, 0x000a0009,
668 0x9178, 0xffffffff, 0x000c000b,
669 0x917c, 0xffffffff, 0x000e000d,
670 0x9180, 0xffffffff, 0x0010000f,
671 0x918c, 0xffffffff, 0x00120011,
672 0x9190, 0xffffffff, 0x00140013,
673 0x9194, 0xffffffff, 0x00020001,
674 0x9198, 0xffffffff, 0x00040003,
675 0x919c, 0xffffffff, 0x00060005,
676 0x91a8, 0xffffffff, 0x00080007,
677 0x91ac, 0xffffffff, 0x000a0009,
678 0x91b0, 0xffffffff, 0x000c000b,
679 0x91b4, 0xffffffff, 0x000e000d,
680 0x91b8, 0xffffffff, 0x0010000f,
681 0x91c4, 0xffffffff, 0x00120011,
682 0x91c8, 0xffffffff, 0x00140013,
683 0x91cc, 0xffffffff, 0x00020001,
684 0x91d0, 0xffffffff, 0x00040003,
685 0x91d4, 0xffffffff, 0x00060005,
686 0x91e0, 0xffffffff, 0x00080007,
687 0x91e4, 0xffffffff, 0x000a0009,
688 0x91e8, 0xffffffff, 0x000c000b,
689 0x91ec, 0xffffffff, 0x00020001,
690 0x91f0, 0xffffffff, 0x00040003,
691 0x91f4, 0xffffffff, 0x00060005,
692 0x9200, 0xffffffff, 0x00080007,
693 0x9204, 0xffffffff, 0x000a0009,
694 0x9208, 0xffffffff, 0x000c000b,
695 0x920c, 0xffffffff, 0x000e000d,
696 0x9210, 0xffffffff, 0x0010000f,
697 0x921c, 0xffffffff, 0x00120011,
698 0x9220, 0xffffffff, 0x00140013,
699 0x9224, 0xffffffff, 0x00020001,
700 0x9228, 0xffffffff, 0x00040003,
701 0x922c, 0xffffffff, 0x00060005,
702 0x9238, 0xffffffff, 0x00080007,
703 0x923c, 0xffffffff, 0x000a0009,
704 0x9240, 0xffffffff, 0x000c000b,
705 0x9244, 0xffffffff, 0x000e000d,
706 0x9248, 0xffffffff, 0x0010000f,
707 0x9254, 0xffffffff, 0x00120011,
708 0x9258, 0xffffffff, 0x00140013,
709 0x9294, 0xffffffff, 0x00020001,
710 0x929c, 0xffffffff, 0x00040003,
711 0x92a0, 0xffffffff, 0x00060005,
712 0x92a4, 0xffffffff, 0x00080007
713};
714
715static void rv770_init_golden_registers(struct radeon_device *rdev)
716{
717 switch (rdev->family) {
718 case CHIP_RV770:
719 radeon_program_register_sequence(rdev,
720 r7xx_golden_registers,
721 (const u32)ARRAY_SIZE(r7xx_golden_registers));
722 radeon_program_register_sequence(rdev,
723 r7xx_golden_dyn_gpr_registers,
724 (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
725 if (rdev->pdev->device == 0x994e)
726 radeon_program_register_sequence(rdev,
727 rv770ce_golden_registers,
728 (const u32)ARRAY_SIZE(rv770ce_golden_registers));
729 else
730 radeon_program_register_sequence(rdev,
731 rv770_golden_registers,
732 (const u32)ARRAY_SIZE(rv770_golden_registers));
733 radeon_program_register_sequence(rdev,
734 rv770_mgcg_init,
735 (const u32)ARRAY_SIZE(rv770_mgcg_init));
736 break;
737 case CHIP_RV730:
738 radeon_program_register_sequence(rdev,
739 r7xx_golden_registers,
740 (const u32)ARRAY_SIZE(r7xx_golden_registers));
741 radeon_program_register_sequence(rdev,
742 r7xx_golden_dyn_gpr_registers,
743 (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
744 radeon_program_register_sequence(rdev,
745 rv730_golden_registers,
Alex Deucher022374c02013-08-13 15:57:32 -0400746 (const u32)ARRAY_SIZE(rv730_golden_registers));
Alex Deucherfbb55662013-02-26 15:59:47 -0500747 radeon_program_register_sequence(rdev,
748 rv730_mgcg_init,
Alex Deucher022374c02013-08-13 15:57:32 -0400749 (const u32)ARRAY_SIZE(rv730_mgcg_init));
Alex Deucherfbb55662013-02-26 15:59:47 -0500750 break;
751 case CHIP_RV710:
752 radeon_program_register_sequence(rdev,
753 r7xx_golden_registers,
754 (const u32)ARRAY_SIZE(r7xx_golden_registers));
755 radeon_program_register_sequence(rdev,
756 r7xx_golden_dyn_gpr_registers,
757 (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
758 radeon_program_register_sequence(rdev,
759 rv710_golden_registers,
Alex Deucher022374c02013-08-13 15:57:32 -0400760 (const u32)ARRAY_SIZE(rv710_golden_registers));
Alex Deucherfbb55662013-02-26 15:59:47 -0500761 radeon_program_register_sequence(rdev,
762 rv710_mgcg_init,
Alex Deucher022374c02013-08-13 15:57:32 -0400763 (const u32)ARRAY_SIZE(rv710_mgcg_init));
Alex Deucherfbb55662013-02-26 15:59:47 -0500764 break;
765 case CHIP_RV740:
766 radeon_program_register_sequence(rdev,
767 rv740_golden_registers,
Alex Deucher022374c02013-08-13 15:57:32 -0400768 (const u32)ARRAY_SIZE(rv740_golden_registers));
Alex Deucherfbb55662013-02-26 15:59:47 -0500769 radeon_program_register_sequence(rdev,
770 rv740_mgcg_init,
Alex Deucher022374c02013-08-13 15:57:32 -0400771 (const u32)ARRAY_SIZE(rv740_mgcg_init));
Alex Deucherfbb55662013-02-26 15:59:47 -0500772 break;
773 default:
774 break;
775 }
776}
777
Alex Deucher454d2e22013-02-14 10:04:02 -0500778#define PCIE_BUS_CLK 10000
779#define TCLK (PCIE_BUS_CLK / 10)
780
781/**
782 * rv770_get_xclk - get the xclk
783 *
784 * @rdev: radeon_device pointer
785 *
786 * Returns the reference clock used by the gfx engine
787 * (r7xx-cayman).
788 */
789u32 rv770_get_xclk(struct radeon_device *rdev)
790{
791 u32 reference_clock = rdev->clock.spll.reference_freq;
792 u32 tmp = RREG32(CG_CLKPIN_CNTL);
793
794 if (tmp & MUX_TCLK_TO_XCLK)
795 return TCLK;
796
797 if (tmp & XTALIN_DIVIDE)
798 return reference_clock / 4;
799
800 return reference_clock;
801}
802
Christian König157fa142014-05-27 16:49:20 +0200803void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
Alex Deucher6f34be52010-11-21 10:59:01 -0500804{
805 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
806 u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
Alex Deucherf6496472011-11-28 14:49:26 -0500807 int i;
Alex Deucher6f34be52010-11-21 10:59:01 -0500808
809 /* Lock the graphics update lock */
810 tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
811 WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
812
813 /* update the scanout addresses */
814 if (radeon_crtc->crtc_id) {
815 WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
816 WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
817 } else {
818 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
819 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
820 }
821 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
822 (u32)crtc_base);
823 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
824 (u32)crtc_base);
825
826 /* Wait for update_pending to go high. */
Alex Deucherf6496472011-11-28 14:49:26 -0500827 for (i = 0; i < rdev->usec_timeout; i++) {
828 if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
829 break;
830 udelay(1);
831 }
Alex Deucher6f34be52010-11-21 10:59:01 -0500832 DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
833
834 /* Unlock the lock, so double-buffering can take place inside vblank */
835 tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
836 WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
Christian König157fa142014-05-27 16:49:20 +0200837}
838
839bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc_id)
840{
841 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
Alex Deucher6f34be52010-11-21 10:59:01 -0500842
843 /* Return current update_pending status: */
Christian König157fa142014-05-27 16:49:20 +0200844 return !!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
845 AVIVO_D1GRPH_SURFACE_UPDATE_PENDING);
Alex Deucher6f34be52010-11-21 10:59:01 -0500846}
847
Alex Deucher21a81222010-07-02 12:58:16 -0400848/* get temperature in millidegrees */
Alex Deucher20d391d2011-02-01 16:12:34 -0500849int rv770_get_temp(struct radeon_device *rdev)
Alex Deucher21a81222010-07-02 12:58:16 -0400850{
851 u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
852 ASIC_T_SHIFT;
Alex Deucher20d391d2011-02-01 16:12:34 -0500853 int actual_temp;
Alex Deucher21a81222010-07-02 12:58:16 -0400854
Alex Deucher20d391d2011-02-01 16:12:34 -0500855 if (temp & 0x400)
856 actual_temp = -256;
857 else if (temp & 0x200)
858 actual_temp = 255;
859 else if (temp & 0x100) {
860 actual_temp = temp & 0x1ff;
861 actual_temp |= ~0x1ff;
862 } else
863 actual_temp = temp & 0xff;
Alex Deucher21a81222010-07-02 12:58:16 -0400864
Alex Deucher20d391d2011-02-01 16:12:34 -0500865 return (actual_temp * 1000) / 2;
Alex Deucher21a81222010-07-02 12:58:16 -0400866}
867
Alex Deucher49e02b72010-04-23 17:57:27 -0400868void rv770_pm_misc(struct radeon_device *rdev)
869{
Rafał Miłeckia081a9d2010-06-07 18:20:25 -0400870 int req_ps_idx = rdev->pm.requested_power_state_index;
871 int req_cm_idx = rdev->pm.requested_clock_mode_index;
872 struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
873 struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
Alex Deucher4d601732010-06-07 18:15:18 -0400874
875 if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
Alex Deuchera377e182011-06-20 13:00:31 -0400876 /* 0xff01 is a flag rather then an actual voltage */
877 if (voltage->voltage == 0xff01)
878 return;
Alex Deucher4d601732010-06-07 18:15:18 -0400879 if (voltage->voltage != rdev->pm.current_vddc) {
Alex Deucher8a83ec52011-04-12 14:49:23 -0400880 radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
Alex Deucher4d601732010-06-07 18:15:18 -0400881 rdev->pm.current_vddc = voltage->voltage;
Rafał Miłecki0fcbe942010-06-07 18:25:21 -0400882 DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
Alex Deucher4d601732010-06-07 18:15:18 -0400883 }
884 }
Alex Deucher49e02b72010-04-23 17:57:27 -0400885}
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000886
887/*
888 * GART
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200889 */
Lauri Kasanen1109ca02012-08-31 13:43:50 -0400890static int rv770_pcie_gart_enable(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000891{
892 u32 tmp;
893 int r, i;
894
Jerome Glissec9a1be92011-11-03 11:16:49 -0400895 if (rdev->gart.robj == NULL) {
Jerome Glisse4aac0472009-09-14 18:29:49 +0200896 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
897 return -EINVAL;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000898 }
Jerome Glisse4aac0472009-09-14 18:29:49 +0200899 r = radeon_gart_table_vram_pin(rdev);
900 if (r)
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000901 return r;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000902 /* Setup L2 cache */
903 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
904 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
905 EFFECTIVE_L2_QUEUE_SIZE(7));
906 WREG32(VM_L2_CNTL2, 0);
907 WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
908 /* Setup TLB control */
909 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
910 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
911 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
912 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
913 WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
914 WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
915 WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
Alex Deucher0b8c30b2012-05-31 18:54:43 -0400916 if (rdev->family == CHIP_RV740)
917 WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000918 WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
919 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
920 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
921 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
922 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
Jerome Glisse1a029b72009-10-06 19:04:30 +0200923 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000924 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
925 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
926 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
927 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
928 (u32)(rdev->dummy_page.addr >> 12));
929 for (i = 1; i < 7; i++)
930 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
931
932 r600_pcie_gart_tlb_flush(rdev);
Tormod Voldenfcf4de52011-08-31 21:54:07 +0000933 DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
934 (unsigned)(rdev->mc.gtt_size >> 20),
935 (unsigned long long)rdev->gart.table_addr);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000936 rdev->gart.ready = true;
937 return 0;
938}
939
Lauri Kasanen1109ca02012-08-31 13:43:50 -0400940static void rv770_pcie_gart_disable(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000941{
942 u32 tmp;
Jerome Glissec9a1be92011-11-03 11:16:49 -0400943 int i;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000944
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000945 /* Disable all tables */
946 for (i = 0; i < 7; i++)
947 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
948
949 /* Setup L2 cache */
950 WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
951 EFFECTIVE_L2_QUEUE_SIZE(7));
952 WREG32(VM_L2_CNTL2, 0);
953 WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
954 /* Setup TLB control */
955 tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
956 WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
957 WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
958 WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
959 WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
960 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
961 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
962 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
Jerome Glissec9a1be92011-11-03 11:16:49 -0400963 radeon_gart_table_vram_unpin(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +0200964}
965
Lauri Kasanen1109ca02012-08-31 13:43:50 -0400966static void rv770_pcie_gart_fini(struct radeon_device *rdev)
Jerome Glisse4aac0472009-09-14 18:29:49 +0200967{
Jerome Glissef9274562010-03-17 14:44:29 +0000968 radeon_gart_fini(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +0200969 rv770_pcie_gart_disable(rdev);
970 radeon_gart_table_vram_free(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000971}
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200972
973
Lauri Kasanen1109ca02012-08-31 13:43:50 -0400974static void rv770_agp_enable(struct radeon_device *rdev)
Jerome Glisse1a029b72009-10-06 19:04:30 +0200975{
976 u32 tmp;
977 int i;
978
979 /* Setup L2 cache */
980 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
981 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
982 EFFECTIVE_L2_QUEUE_SIZE(7));
983 WREG32(VM_L2_CNTL2, 0);
984 WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
985 /* Setup TLB control */
986 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
987 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
988 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
989 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
990 WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
991 WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
992 WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
993 WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
994 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
995 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
996 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
997 for (i = 0; i < 7; i++)
998 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
999}
1000
Jerome Glissea3c19452009-10-01 18:02:13 +02001001static void rv770_mc_program(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001002{
Jerome Glissea3c19452009-10-01 18:02:13 +02001003 struct rv515_mc_save save;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001004 u32 tmp;
1005 int i, j;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001006
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001007 /* Initialize HDP */
1008 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
1009 WREG32((0x2c14 + j), 0x00000000);
1010 WREG32((0x2c18 + j), 0x00000000);
1011 WREG32((0x2c1c + j), 0x00000000);
1012 WREG32((0x2c20 + j), 0x00000000);
1013 WREG32((0x2c24 + j), 0x00000000);
1014 }
Alex Deucher812d0462010-07-26 18:51:53 -04001015 /* r7xx hw bug. Read from HDP_DEBUG1 rather
1016 * than writing to HDP_REG_COHERENCY_FLUSH_CNTL
1017 */
1018 tmp = RREG32(HDP_DEBUG1);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001019
Jerome Glissea3c19452009-10-01 18:02:13 +02001020 rv515_mc_stop(rdev, &save);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001021 if (r600_mc_wait_for_idle(rdev)) {
Jerome Glissea3c19452009-10-01 18:02:13 +02001022 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001023 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001024 /* Lockout access through VGA aperture*/
1025 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001026 /* Update configuration */
Jerome Glisse1a029b72009-10-06 19:04:30 +02001027 if (rdev->flags & RADEON_IS_AGP) {
1028 if (rdev->mc.vram_start < rdev->mc.gtt_start) {
1029 /* VRAM before AGP */
1030 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
1031 rdev->mc.vram_start >> 12);
1032 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1033 rdev->mc.gtt_end >> 12);
1034 } else {
1035 /* VRAM after AGP */
1036 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
1037 rdev->mc.gtt_start >> 12);
1038 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1039 rdev->mc.vram_end >> 12);
1040 }
1041 } else {
1042 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
1043 rdev->mc.vram_start >> 12);
1044 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1045 rdev->mc.vram_end >> 12);
1046 }
Alex Deucher16cdf042011-10-28 10:30:02 -04001047 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
Jerome Glisse1a029b72009-10-06 19:04:30 +02001048 tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001049 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
1050 WREG32(MC_VM_FB_LOCATION, tmp);
1051 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
1052 WREG32(HDP_NONSURFACE_INFO, (2 << 7));
Jerome Glisse46fcd2b2010-06-03 19:34:48 +02001053 WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001054 if (rdev->flags & RADEON_IS_AGP) {
Jerome Glisse1a029b72009-10-06 19:04:30 +02001055 WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001056 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
1057 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
1058 } else {
1059 WREG32(MC_VM_AGP_BASE, 0);
1060 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
1061 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
1062 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001063 if (r600_mc_wait_for_idle(rdev)) {
Jerome Glissea3c19452009-10-01 18:02:13 +02001064 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001065 }
Jerome Glissea3c19452009-10-01 18:02:13 +02001066 rv515_mc_resume(rdev, &save);
Dave Airlie698443d2009-09-18 14:16:38 +10001067 /* we need to own VRAM, so turn off the VGA renderer here
1068 * to stop it overwriting our objects */
Jerome Glissed39c3b82009-09-28 18:34:43 +02001069 rv515_vga_render_disable(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001070}
1071
1072
1073/*
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001074 * CP.
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001075 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001076void r700_cp_stop(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001077{
Alex Deucher50efa512014-01-27 11:26:33 -05001078 if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
1079 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001080 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
Alex Deucher724c80e2010-08-27 18:25:25 -04001081 WREG32(SCRATCH_UMSK, 0);
Alex Deucher4d756582012-09-27 15:08:35 -04001082 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001083}
1084
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001085static int rv770_cp_load_microcode(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001086{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001087 const __be32 *fw_data;
1088 int i;
1089
1090 if (!rdev->me_fw || !rdev->pfp_fw)
1091 return -EINVAL;
1092
1093 r700_cp_stop(rdev);
Cédric Cano4eace7f2011-02-11 19:45:38 -05001094 WREG32(CP_RB_CNTL,
1095#ifdef __BIG_ENDIAN
1096 BUF_SWAP_32BIT |
1097#endif
1098 RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001099
1100 /* Reset cp */
1101 WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
1102 RREG32(GRBM_SOFT_RESET);
1103 mdelay(15);
1104 WREG32(GRBM_SOFT_RESET, 0);
1105
1106 fw_data = (const __be32 *)rdev->pfp_fw->data;
1107 WREG32(CP_PFP_UCODE_ADDR, 0);
1108 for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
1109 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1110 WREG32(CP_PFP_UCODE_ADDR, 0);
1111
1112 fw_data = (const __be32 *)rdev->me_fw->data;
1113 WREG32(CP_ME_RAM_WADDR, 0);
1114 for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
1115 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1116
1117 WREG32(CP_PFP_UCODE_ADDR, 0);
1118 WREG32(CP_ME_RAM_WADDR, 0);
1119 WREG32(CP_ME_RAM_RADDR, 0);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001120 return 0;
1121}
1122
Alex Deucherfe251e22010-03-24 13:36:43 -04001123void r700_cp_fini(struct radeon_device *rdev)
1124{
Christian König45df6802012-07-06 16:22:55 +02001125 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucherfe251e22010-03-24 13:36:43 -04001126 r700_cp_stop(rdev);
Christian König45df6802012-07-06 16:22:55 +02001127 radeon_ring_fini(rdev, ring);
1128 radeon_scratch_free(rdev, ring->rptr_save_reg);
Alex Deucherfe251e22010-03-24 13:36:43 -04001129}
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001130
Alex Deucherde9ae742013-11-01 19:01:36 -04001131void rv770_set_clk_bypass_mode(struct radeon_device *rdev)
1132{
1133 u32 tmp, i;
1134
1135 if (rdev->flags & RADEON_IS_IGP)
1136 return;
1137
1138 tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
1139 tmp &= SCLK_MUX_SEL_MASK;
1140 tmp |= SCLK_MUX_SEL(1) | SCLK_MUX_UPDATE;
1141 WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
1142
1143 for (i = 0; i < rdev->usec_timeout; i++) {
1144 if (RREG32(CG_SPLL_STATUS) & SPLL_CHG_STATUS)
1145 break;
1146 udelay(1);
1147 }
1148
1149 tmp &= ~SCLK_MUX_UPDATE;
1150 WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
1151
1152 tmp = RREG32(MPLL_CNTL_MODE);
1153 if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
1154 tmp &= ~RV730_MPLL_MCLK_SEL;
1155 else
1156 tmp &= ~MPLL_MCLK_SEL;
1157 WREG32(MPLL_CNTL_MODE, tmp);
1158}
1159
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001160/*
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001161 * Core functions
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001162 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001163static void rv770_gpu_init(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001164{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001165 int i, j, num_qd_pipes;
Alex Deucherd03f5d52010-02-19 16:22:31 -05001166 u32 ta_aux_cntl;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001167 u32 sx_debug_1;
1168 u32 smx_dc_ctl0;
Alex Deucherd03f5d52010-02-19 16:22:31 -05001169 u32 db_debug3;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001170 u32 num_gs_verts_per_thread;
1171 u32 vgt_gs_per_es;
1172 u32 gs_prim_buffer_depth = 0;
1173 u32 sq_ms_fifo_sizes;
1174 u32 sq_config;
1175 u32 sq_thread_resource_mgmt;
1176 u32 hdp_host_path_cntl;
1177 u32 sq_dyn_gpr_size_simd_ab_0;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001178 u32 gb_tiling_config = 0;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001179 u32 cc_gc_shader_pipe_config = 0;
1180 u32 mc_arb_ramcfg;
Alex Deucher416a2bd2012-05-31 19:00:25 -04001181 u32 db_debug4, tmp;
1182 u32 inactive_pipes, shader_pipe_config;
1183 u32 disabled_rb_mask;
1184 unsigned active_number;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001185
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001186 /* setup chip specs */
Alex Deucher416a2bd2012-05-31 19:00:25 -04001187 rdev->config.rv770.tiling_group_size = 256;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001188 switch (rdev->family) {
1189 case CHIP_RV770:
1190 rdev->config.rv770.max_pipes = 4;
1191 rdev->config.rv770.max_tile_pipes = 8;
1192 rdev->config.rv770.max_simds = 10;
1193 rdev->config.rv770.max_backends = 4;
1194 rdev->config.rv770.max_gprs = 256;
1195 rdev->config.rv770.max_threads = 248;
1196 rdev->config.rv770.max_stack_entries = 512;
1197 rdev->config.rv770.max_hw_contexts = 8;
1198 rdev->config.rv770.max_gs_threads = 16 * 2;
1199 rdev->config.rv770.sx_max_export_size = 128;
1200 rdev->config.rv770.sx_max_export_pos_size = 16;
1201 rdev->config.rv770.sx_max_export_smx_size = 112;
1202 rdev->config.rv770.sq_num_cf_insts = 2;
1203
1204 rdev->config.rv770.sx_num_of_sets = 7;
1205 rdev->config.rv770.sc_prim_fifo_size = 0xF9;
1206 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1207 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1208 break;
1209 case CHIP_RV730:
1210 rdev->config.rv770.max_pipes = 2;
1211 rdev->config.rv770.max_tile_pipes = 4;
1212 rdev->config.rv770.max_simds = 8;
1213 rdev->config.rv770.max_backends = 2;
1214 rdev->config.rv770.max_gprs = 128;
1215 rdev->config.rv770.max_threads = 248;
1216 rdev->config.rv770.max_stack_entries = 256;
1217 rdev->config.rv770.max_hw_contexts = 8;
1218 rdev->config.rv770.max_gs_threads = 16 * 2;
1219 rdev->config.rv770.sx_max_export_size = 256;
1220 rdev->config.rv770.sx_max_export_pos_size = 32;
1221 rdev->config.rv770.sx_max_export_smx_size = 224;
1222 rdev->config.rv770.sq_num_cf_insts = 2;
1223
1224 rdev->config.rv770.sx_num_of_sets = 7;
1225 rdev->config.rv770.sc_prim_fifo_size = 0xf9;
1226 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1227 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1228 if (rdev->config.rv770.sx_max_export_pos_size > 16) {
1229 rdev->config.rv770.sx_max_export_pos_size -= 16;
1230 rdev->config.rv770.sx_max_export_smx_size += 16;
1231 }
1232 break;
1233 case CHIP_RV710:
1234 rdev->config.rv770.max_pipes = 2;
1235 rdev->config.rv770.max_tile_pipes = 2;
1236 rdev->config.rv770.max_simds = 2;
1237 rdev->config.rv770.max_backends = 1;
1238 rdev->config.rv770.max_gprs = 256;
1239 rdev->config.rv770.max_threads = 192;
1240 rdev->config.rv770.max_stack_entries = 256;
1241 rdev->config.rv770.max_hw_contexts = 4;
1242 rdev->config.rv770.max_gs_threads = 8 * 2;
1243 rdev->config.rv770.sx_max_export_size = 128;
1244 rdev->config.rv770.sx_max_export_pos_size = 16;
1245 rdev->config.rv770.sx_max_export_smx_size = 112;
1246 rdev->config.rv770.sq_num_cf_insts = 1;
1247
1248 rdev->config.rv770.sx_num_of_sets = 7;
1249 rdev->config.rv770.sc_prim_fifo_size = 0x40;
1250 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1251 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1252 break;
1253 case CHIP_RV740:
1254 rdev->config.rv770.max_pipes = 4;
1255 rdev->config.rv770.max_tile_pipes = 4;
1256 rdev->config.rv770.max_simds = 8;
1257 rdev->config.rv770.max_backends = 4;
1258 rdev->config.rv770.max_gprs = 256;
1259 rdev->config.rv770.max_threads = 248;
1260 rdev->config.rv770.max_stack_entries = 512;
1261 rdev->config.rv770.max_hw_contexts = 8;
1262 rdev->config.rv770.max_gs_threads = 16 * 2;
1263 rdev->config.rv770.sx_max_export_size = 256;
1264 rdev->config.rv770.sx_max_export_pos_size = 32;
1265 rdev->config.rv770.sx_max_export_smx_size = 224;
1266 rdev->config.rv770.sq_num_cf_insts = 2;
1267
1268 rdev->config.rv770.sx_num_of_sets = 7;
1269 rdev->config.rv770.sc_prim_fifo_size = 0x100;
1270 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
1271 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
1272
1273 if (rdev->config.rv770.sx_max_export_pos_size > 16) {
1274 rdev->config.rv770.sx_max_export_pos_size -= 16;
1275 rdev->config.rv770.sx_max_export_smx_size += 16;
1276 }
1277 break;
1278 default:
1279 break;
1280 }
1281
1282 /* Initialize HDP */
1283 j = 0;
1284 for (i = 0; i < 32; i++) {
1285 WREG32((0x2c14 + j), 0x00000000);
1286 WREG32((0x2c18 + j), 0x00000000);
1287 WREG32((0x2c1c + j), 0x00000000);
1288 WREG32((0x2c20 + j), 0x00000000);
1289 WREG32((0x2c24 + j), 0x00000000);
1290 j += 0x18;
1291 }
1292
1293 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
1294
1295 /* setup tiling, simd, pipe config */
1296 mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
1297
Alex Deucher416a2bd2012-05-31 19:00:25 -04001298 shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG);
1299 inactive_pipes = (shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT;
1300 for (i = 0, tmp = 1, active_number = 0; i < R7XX_MAX_PIPES; i++) {
1301 if (!(inactive_pipes & tmp)) {
1302 active_number++;
1303 }
1304 tmp <<= 1;
1305 }
1306 if (active_number == 1) {
1307 WREG32(SPI_CONFIG_CNTL, DISABLE_INTERP_1);
1308 } else {
1309 WREG32(SPI_CONFIG_CNTL, 0);
1310 }
1311
Alex Deucher416a2bd2012-05-31 19:00:25 -04001312 cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
Alex Deucher65fcf662014-06-02 16:13:21 -04001313 tmp = rdev->config.rv770.max_simds -
1314 r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK);
1315 rdev->config.rv770.active_simds = tmp;
Alex Deucher416a2bd2012-05-31 19:00:25 -04001316
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001317 switch (rdev->config.rv770.max_tile_pipes) {
1318 case 1:
Alex Deucherd03f5d52010-02-19 16:22:31 -05001319 default:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001320 gb_tiling_config = PIPE_TILING(0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001321 break;
1322 case 2:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001323 gb_tiling_config = PIPE_TILING(1);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001324 break;
1325 case 4:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001326 gb_tiling_config = PIPE_TILING(2);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001327 break;
1328 case 8:
Alex Deucher416a2bd2012-05-31 19:00:25 -04001329 gb_tiling_config = PIPE_TILING(3);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001330 break;
1331 }
Alex Deucherd03f5d52010-02-19 16:22:31 -05001332 rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001333
Alex Deucher416a2bd2012-05-31 19:00:25 -04001334 disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R7XX_MAX_BACKENDS_MASK;
Alex Deucher0a5f6e92014-08-25 14:52:15 -04001335 tmp = 0;
1336 for (i = 0; i < rdev->config.rv770.max_backends; i++)
1337 tmp |= (1 << i);
1338 /* if all the backends are disabled, fix it up here */
1339 if ((disabled_rb_mask & tmp) == tmp) {
1340 for (i = 0; i < rdev->config.rv770.max_backends; i++)
1341 disabled_rb_mask &= ~(1 << i);
1342 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001343 tmp = (gb_tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT;
1344 tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.rv770.max_backends,
1345 R7XX_MAX_BACKENDS, disabled_rb_mask);
1346 gb_tiling_config |= tmp << 16;
1347 rdev->config.rv770.backend_map = tmp;
1348
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001349 if (rdev->family == CHIP_RV770)
1350 gb_tiling_config |= BANK_TILING(1);
Alex Deucher29d65402012-05-31 18:53:36 -04001351 else {
1352 if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT)
1353 gb_tiling_config |= BANK_TILING(1);
1354 else
1355 gb_tiling_config |= BANK_TILING(0);
1356 }
Jerome Glisse961fb592010-02-10 22:30:05 +00001357 rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3);
Alex Deucher881fe6c2010-10-18 23:54:56 -04001358 gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT);
Alex Deuchere29649d2009-11-03 10:04:01 -05001359 if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001360 gb_tiling_config |= ROW_TILING(3);
1361 gb_tiling_config |= SAMPLE_SPLIT(3);
1362 } else {
1363 gb_tiling_config |=
1364 ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
1365 gb_tiling_config |=
1366 SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
1367 }
1368
1369 gb_tiling_config |= BANK_SWAPS(1);
Alex Deuchere7aeeba2010-06-04 13:10:12 -04001370 rdev->config.rv770.tile_config = gb_tiling_config;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001371
1372 WREG32(GB_TILING_CONFIG, gb_tiling_config);
1373 WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
1374 WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
Alex Deucher4d756582012-09-27 15:08:35 -04001375 WREG32(DMA_TILING_CONFIG, (gb_tiling_config & 0xffff));
1376 WREG32(DMA_TILING_CONFIG2, (gb_tiling_config & 0xffff));
Christian König9a210592013-04-08 12:41:37 +02001377 if (rdev->family == CHIP_RV730) {
1378 WREG32(UVD_UDEC_DB_TILING_CONFIG, (gb_tiling_config & 0xffff));
1379 WREG32(UVD_UDEC_DBW_TILING_CONFIG, (gb_tiling_config & 0xffff));
1380 WREG32(UVD_UDEC_TILING_CONFIG, (gb_tiling_config & 0xffff));
1381 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001382
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001383 WREG32(CGTS_SYS_TCC_DISABLE, 0);
1384 WREG32(CGTS_TCC_DISABLE, 0);
Alex Deucherf867c60d2010-03-05 14:50:37 -05001385 WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
1386 WREG32(CGTS_USER_TCC_DISABLE, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001387
Alex Deucher416a2bd2012-05-31 19:00:25 -04001388
1389 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 +10001390 WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK);
1391 WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK);
1392
1393 /* set HW defaults for 3D engine */
1394 WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
Alex Deuchere29649d2009-11-03 10:04:01 -05001395 ROQ_IB2_START(0x2b)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001396
1397 WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
1398
Alex Deucherd03f5d52010-02-19 16:22:31 -05001399 ta_aux_cntl = RREG32(TA_CNTL_AUX);
1400 WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001401
1402 sx_debug_1 = RREG32(SX_DEBUG_1);
1403 sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1404 WREG32(SX_DEBUG_1, sx_debug_1);
1405
1406 smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1407 smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff);
1408 smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1);
1409 WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1410
Alex Deucherd03f5d52010-02-19 16:22:31 -05001411 if (rdev->family != CHIP_RV740)
1412 WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
1413 GS_FLUSH_CTL(4) |
1414 ACK_FLUSH_CTL(3) |
1415 SYNC_FLUSH_CTL));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001416
Alex Deucherb866d132012-06-14 22:06:36 +02001417 if (rdev->family != CHIP_RV770)
1418 WREG32(SMX_SAR_CTL0, 0x00003f3f);
1419
Alex Deucherd03f5d52010-02-19 16:22:31 -05001420 db_debug3 = RREG32(DB_DEBUG3);
1421 db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f);
1422 switch (rdev->family) {
1423 case CHIP_RV770:
1424 case CHIP_RV740:
1425 db_debug3 |= DB_CLK_OFF_DELAY(0x1f);
1426 break;
1427 case CHIP_RV710:
1428 case CHIP_RV730:
1429 default:
1430 db_debug3 |= DB_CLK_OFF_DELAY(2);
1431 break;
1432 }
1433 WREG32(DB_DEBUG3, db_debug3);
1434
1435 if (rdev->family != CHIP_RV770) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001436 db_debug4 = RREG32(DB_DEBUG4);
1437 db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER;
1438 WREG32(DB_DEBUG4, db_debug4);
1439 }
1440
1441 WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) |
Alex Deuchere29649d2009-11-03 10:04:01 -05001442 POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
1443 SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001444
1445 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
Alex Deuchere29649d2009-11-03 10:04:01 -05001446 SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
1447 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001448
1449 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1450
1451 WREG32(VGT_NUM_INSTANCES, 1);
1452
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001453 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
1454
1455 WREG32(CP_PERFMON_CNTL, 0);
1456
1457 sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) |
1458 DONE_FIFO_HIWATER(0xe0) |
1459 ALU_UPDATE_FIFO_HIWATER(0x8));
1460 switch (rdev->family) {
1461 case CHIP_RV770:
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001462 case CHIP_RV730:
1463 case CHIP_RV710:
Alex Deucherd03f5d52010-02-19 16:22:31 -05001464 sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
1465 break;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001466 case CHIP_RV740:
1467 default:
1468 sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4);
1469 break;
1470 }
1471 WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
1472
1473 /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
1474 * should be adjusted as needed by the 2D/3D drivers. This just sets default values
1475 */
1476 sq_config = RREG32(SQ_CONFIG);
1477 sq_config &= ~(PS_PRIO(3) |
1478 VS_PRIO(3) |
1479 GS_PRIO(3) |
1480 ES_PRIO(3));
1481 sq_config |= (DX9_CONSTS |
1482 VC_ENABLE |
1483 EXPORT_SRC_C |
1484 PS_PRIO(0) |
1485 VS_PRIO(1) |
1486 GS_PRIO(2) |
1487 ES_PRIO(3));
1488 if (rdev->family == CHIP_RV710)
1489 /* no vertex cache */
1490 sq_config &= ~VC_ENABLE;
1491
1492 WREG32(SQ_CONFIG, sq_config);
1493
1494 WREG32(SQ_GPR_RESOURCE_MGMT_1, (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001495 NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
1496 NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001497
1498 WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001499 NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001500
1501 sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) |
1502 NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) |
1503 NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8));
1504 if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads)
1505 sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads);
1506 else
1507 sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8);
1508 WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
1509
1510 WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
1511 NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
1512
1513 WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
1514 NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
1515
1516 sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) |
1517 SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) |
1518 SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) |
1519 SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64));
1520
1521 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
1522 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
1523 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
1524 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
1525 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
1526 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
1527 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
1528 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
1529
1530 WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001531 FORCE_EOV_MAX_REZ_CNT(255)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001532
1533 if (rdev->family == CHIP_RV710)
1534 WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001535 AUTO_INVLD_EN(ES_AND_GS_AUTO)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001536 else
1537 WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) |
Dave Airliefe62e1a2009-09-21 14:06:30 +10001538 AUTO_INVLD_EN(ES_AND_GS_AUTO)));
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001539
1540 switch (rdev->family) {
1541 case CHIP_RV770:
1542 case CHIP_RV730:
1543 case CHIP_RV740:
1544 gs_prim_buffer_depth = 384;
1545 break;
1546 case CHIP_RV710:
1547 gs_prim_buffer_depth = 128;
1548 break;
1549 default:
1550 break;
1551 }
1552
1553 num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16;
1554 vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
1555 /* Max value for this is 256 */
1556 if (vgt_gs_per_es > 256)
1557 vgt_gs_per_es = 256;
1558
1559 WREG32(VGT_ES_PER_GS, 128);
1560 WREG32(VGT_GS_PER_ES, vgt_gs_per_es);
1561 WREG32(VGT_GS_PER_VS, 2);
1562
1563 /* more default values. 2D/3D driver should adjust as needed */
1564 WREG32(VGT_GS_VERTEX_REUSE, 16);
1565 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1566 WREG32(VGT_STRMOUT_EN, 0);
1567 WREG32(SX_MISC, 0);
1568 WREG32(PA_SC_MODE_CNTL, 0);
1569 WREG32(PA_SC_EDGERULE, 0xaaaaaaaa);
1570 WREG32(PA_SC_AA_CONFIG, 0);
1571 WREG32(PA_SC_CLIPRECT_RULE, 0xffff);
1572 WREG32(PA_SC_LINE_STIPPLE, 0);
1573 WREG32(SPI_INPUT_Z, 0);
1574 WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
1575 WREG32(CB_COLOR7_FRAG, 0);
1576
1577 /* clear render buffer base addresses */
1578 WREG32(CB_COLOR0_BASE, 0);
1579 WREG32(CB_COLOR1_BASE, 0);
1580 WREG32(CB_COLOR2_BASE, 0);
1581 WREG32(CB_COLOR3_BASE, 0);
1582 WREG32(CB_COLOR4_BASE, 0);
1583 WREG32(CB_COLOR5_BASE, 0);
1584 WREG32(CB_COLOR6_BASE, 0);
1585 WREG32(CB_COLOR7_BASE, 0);
1586
1587 WREG32(TCP_CNTL, 0);
1588
1589 hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1590 WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1591
1592 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1593
1594 WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
1595 NUM_CLIP_SEQ(3)));
Alex Deucherb866d132012-06-14 22:06:36 +02001596 WREG32(VC_ENHANCE, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001597}
1598
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001599void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
1600{
1601 u64 size_bf, size_af;
1602
1603 if (mc->mc_vram_size > 0xE0000000) {
1604 /* leave room for at least 512M GTT */
1605 dev_warn(rdev->dev, "limiting VRAM\n");
1606 mc->real_vram_size = 0xE0000000;
1607 mc->mc_vram_size = 0xE0000000;
1608 }
1609 if (rdev->flags & RADEON_IS_AGP) {
1610 size_bf = mc->gtt_start;
Alex Deucher9ed8b1f2013-04-08 11:13:01 -04001611 size_af = mc->mc_mask - mc->gtt_end;
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001612 if (size_bf > size_af) {
1613 if (mc->mc_vram_size > size_bf) {
1614 dev_warn(rdev->dev, "limiting VRAM\n");
1615 mc->real_vram_size = size_bf;
1616 mc->mc_vram_size = size_bf;
1617 }
1618 mc->vram_start = mc->gtt_start - mc->mc_vram_size;
1619 } else {
1620 if (mc->mc_vram_size > size_af) {
1621 dev_warn(rdev->dev, "limiting VRAM\n");
1622 mc->real_vram_size = size_af;
1623 mc->mc_vram_size = size_af;
1624 }
Jerome Glissedfc6ae52012-04-17 16:51:38 -04001625 mc->vram_start = mc->gtt_end + 1;
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001626 }
1627 mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
1628 dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
1629 mc->mc_vram_size >> 20, mc->vram_start,
1630 mc->vram_end, mc->real_vram_size >> 20);
1631 } else {
Alex Deucherb4183e32010-12-15 11:04:10 -05001632 radeon_vram_location(rdev, &rdev->mc, 0);
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001633 rdev->mc.gtt_base_align = 0;
1634 radeon_gtt_location(rdev, mc);
1635 }
1636}
1637
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001638static int rv770_mc_init(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001639{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001640 u32 tmp;
Alex Deucher5885b7a2009-10-19 17:23:33 -04001641 int chansize, numchan;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001642
1643 /* Get VRAM informations */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001644 rdev->mc.vram_is_ddr = true;
Alex Deucher5885b7a2009-10-19 17:23:33 -04001645 tmp = RREG32(MC_ARB_RAMCFG);
1646 if (tmp & CHANSIZE_OVERRIDE) {
1647 chansize = 16;
1648 } else if (tmp & CHANSIZE_MASK) {
1649 chansize = 64;
1650 } else {
1651 chansize = 32;
1652 }
1653 tmp = RREG32(MC_SHARED_CHMAP);
1654 switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
1655 case 0:
1656 default:
1657 numchan = 1;
1658 break;
1659 case 1:
1660 numchan = 2;
1661 break;
1662 case 2:
1663 numchan = 4;
1664 break;
1665 case 3:
1666 numchan = 8;
1667 break;
1668 }
1669 rdev->mc.vram_width = numchan * chansize;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001670 /* Could aper size report 0 ? */
Jordan Crouse01d73a62010-05-27 13:40:24 -06001671 rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
1672 rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001673 /* Setup GPU memory space */
1674 rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
1675 rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
Jerome Glisse51e5fcd2010-02-19 14:33:54 +00001676 rdev->mc.visible_vram_size = rdev->mc.aper_size;
Alex Deucher0ef0c1f2010-11-22 17:56:26 -05001677 r700_vram_gtt_location(rdev, &rdev->mc);
Alex Deucherf47299c2010-03-16 20:54:38 -04001678 radeon_update_bandwidth_info(rdev);
1679
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001680 return 0;
1681}
Jerome Glissed594e462010-02-17 21:54:29 +00001682
Dave Airliefc30b8e2009-09-18 15:19:37 +10001683static int rv770_startup(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001684{
Alex Deucher4d756582012-09-27 15:08:35 -04001685 struct radeon_ring *ring;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001686 int r;
1687
Alex Deucher9e46a482011-01-06 18:49:35 -05001688 /* enable pcie gen2 link */
1689 rv770_pcie_gen2_enable(rdev);
1690
Alex Deuchere5903d32013-08-30 08:58:20 -04001691 /* scratch needs to be initialized before MC */
1692 r = r600_vram_scratch_init(rdev);
1693 if (r)
1694 return r;
1695
Alex Deucher6fab3feb2013-08-04 12:13:17 -04001696 rv770_mc_program(rdev);
1697
Jerome Glisse1a029b72009-10-06 19:04:30 +02001698 if (rdev->flags & RADEON_IS_AGP) {
1699 rv770_agp_enable(rdev);
1700 } else {
1701 r = rv770_pcie_gart_enable(rdev);
1702 if (r)
1703 return r;
1704 }
Alex Deucher16cdf042011-10-28 10:30:02 -04001705
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001706 rv770_gpu_init(rdev);
Alex Deucherb70d6bb2010-08-06 21:36:58 -04001707
Alex Deucher724c80e2010-08-27 18:25:25 -04001708 /* allocate wb buffer */
1709 r = radeon_wb_init(rdev);
1710 if (r)
1711 return r;
1712
Jerome Glisse30eb77f2011-11-20 20:45:34 +00001713 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
1714 if (r) {
1715 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
1716 return r;
1717 }
1718
Alex Deucher4d756582012-09-27 15:08:35 -04001719 r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
1720 if (r) {
1721 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
1722 return r;
1723 }
1724
Christian Könige409b122013-08-13 11:56:53 +02001725 r = uvd_v2_2_resume(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02001726 if (!r) {
1727 r = radeon_fence_driver_start_ring(rdev,
1728 R600_RING_TYPE_UVD_INDEX);
1729 if (r)
1730 dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
1731 }
1732
1733 if (r)
1734 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
1735
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001736 /* Enable IRQ */
Adis Hamziće49f3952013-06-02 16:47:54 +02001737 if (!rdev->irq.installed) {
1738 r = radeon_irq_kms_init(rdev);
1739 if (r)
1740 return r;
1741 }
1742
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001743 r = r600_irq_init(rdev);
1744 if (r) {
1745 DRM_ERROR("radeon: IH init failed (%d).\n", r);
1746 radeon_irq_kms_fini(rdev);
1747 return r;
1748 }
1749 r600_irq_set(rdev);
1750
Alex Deucher4d756582012-09-27 15:08:35 -04001751 ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Christian Könige32eb502011-10-23 12:56:27 +02001752 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
Christian König2e1e6da2013-08-13 11:56:52 +02001753 RADEON_CP_PACKET2);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001754 if (r)
1755 return r;
Alex Deucher4d756582012-09-27 15:08:35 -04001756
1757 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
1758 r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
Christian König2e1e6da2013-08-13 11:56:52 +02001759 DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
Alex Deucher4d756582012-09-27 15:08:35 -04001760 if (r)
1761 return r;
1762
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001763 r = rv770_cp_load_microcode(rdev);
1764 if (r)
1765 return r;
1766 r = r600_cp_resume(rdev);
1767 if (r)
1768 return r;
Alex Deucher724c80e2010-08-27 18:25:25 -04001769
Alex Deucher4d756582012-09-27 15:08:35 -04001770 r = r600_dma_resume(rdev);
1771 if (r)
1772 return r;
1773
Christian Königf2ba57b2013-04-08 12:41:29 +02001774 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
1775 if (ring->ring_size) {
Christian König02c9f7f2013-08-13 11:56:51 +02001776 r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
Christian König2e1e6da2013-08-13 11:56:52 +02001777 RADEON_CP_PACKET2);
Christian Königf2ba57b2013-04-08 12:41:29 +02001778 if (!r)
Christian Könige409b122013-08-13 11:56:53 +02001779 r = uvd_v1_0_init(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02001780
1781 if (r)
1782 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
1783 }
1784
Christian König2898c342012-07-05 11:55:34 +02001785 r = radeon_ib_pool_init(rdev);
1786 if (r) {
1787 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisseb15ba512011-11-15 11:48:34 -05001788 return r;
Christian König2898c342012-07-05 11:55:34 +02001789 }
Jerome Glisseb15ba512011-11-15 11:48:34 -05001790
Alex Deucherd4e30ef2012-06-04 17:18:51 -04001791 r = r600_audio_init(rdev);
1792 if (r) {
1793 DRM_ERROR("radeon: audio init failed\n");
1794 return r;
1795 }
1796
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001797 return 0;
1798}
1799
Dave Airliefc30b8e2009-09-18 15:19:37 +10001800int rv770_resume(struct radeon_device *rdev)
1801{
1802 int r;
1803
Jerome Glisse1a029b72009-10-06 19:04:30 +02001804 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
1805 * posting will perform necessary task to bring back GPU into good
1806 * shape.
1807 */
Dave Airliefc30b8e2009-09-18 15:19:37 +10001808 /* post card */
Jerome Glissee7d40b92009-10-01 18:02:15 +02001809 atom_asic_init(rdev->mode_info.atom_context);
Dave Airliefc30b8e2009-09-18 15:19:37 +10001810
Alex Deucherfbb55662013-02-26 15:59:47 -05001811 /* init golden registers */
1812 rv770_init_golden_registers(rdev);
1813
Alex Deucherbc6a6292014-02-25 12:01:28 -05001814 if (rdev->pm.pm_method == PM_METHOD_DPM)
1815 radeon_pm_resume(rdev);
Alex Deucher6c7bcce2013-12-18 14:07:14 -05001816
Jerome Glisseb15ba512011-11-15 11:48:34 -05001817 rdev->accel_working = true;
Dave Airliefc30b8e2009-09-18 15:19:37 +10001818 r = rv770_startup(rdev);
1819 if (r) {
1820 DRM_ERROR("r600 startup failed on resume\n");
Jerome Glisse6b7746e2012-02-20 17:57:20 -05001821 rdev->accel_working = false;
Dave Airliefc30b8e2009-09-18 15:19:37 +10001822 return r;
1823 }
1824
Dave Airliefc30b8e2009-09-18 15:19:37 +10001825 return r;
1826
1827}
1828
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001829int rv770_suspend(struct radeon_device *rdev)
1830{
Alex Deucher6c7bcce2013-12-18 14:07:14 -05001831 radeon_pm_suspend(rdev);
Rafał Miłecki8a8c6e72010-03-06 13:03:36 +00001832 r600_audio_fini(rdev);
Christian Könige409b122013-08-13 11:56:53 +02001833 uvd_v1_0_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02001834 radeon_uvd_suspend(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001835 r700_cp_stop(rdev);
Alex Deucher4d756582012-09-27 15:08:35 -04001836 r600_dma_stop(rdev);
Jerome Glisse0c452492010-01-15 14:44:37 +01001837 r600_irq_suspend(rdev);
Alex Deucher724c80e2010-08-27 18:25:25 -04001838 radeon_wb_disable(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02001839 rv770_pcie_gart_disable(rdev);
Alex Deucher6ddddfe2011-10-14 10:51:22 -04001840
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001841 return 0;
1842}
1843
1844/* Plan is to move initialization in that function and use
1845 * helper function so that radeon_device_init pretty much
1846 * do nothing more than calling asic specific function. This
1847 * should also allow to remove a bunch of callback function
1848 * like vram_info.
1849 */
1850int rv770_init(struct radeon_device *rdev)
1851{
1852 int r;
1853
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001854 /* Read BIOS */
1855 if (!radeon_get_bios(rdev)) {
1856 if (ASIC_IS_AVIVO(rdev))
1857 return -EINVAL;
1858 }
1859 /* Must be an ATOMBIOS */
Jerome Glissee7d40b92009-10-01 18:02:15 +02001860 if (!rdev->is_atom_bios) {
1861 dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001862 return -EINVAL;
Jerome Glissee7d40b92009-10-01 18:02:15 +02001863 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001864 r = radeon_atombios_init(rdev);
1865 if (r)
1866 return r;
1867 /* Post card if necessary */
Alex Deucherfd909c32011-01-11 18:08:59 -05001868 if (!radeon_card_posted(rdev)) {
Dave Airlie72542d72009-12-01 14:06:31 +10001869 if (!rdev->bios) {
1870 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
1871 return -EINVAL;
1872 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001873 DRM_INFO("GPU not posted. posting now...\n");
1874 atom_asic_init(rdev->mode_info.atom_context);
1875 }
Alex Deucherfbb55662013-02-26 15:59:47 -05001876 /* init golden registers */
1877 rv770_init_golden_registers(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001878 /* Initialize scratch registers */
1879 r600_scratch_init(rdev);
1880 /* Initialize surface registers */
1881 radeon_surface_init(rdev);
Rafał Miłecki74338742009-11-03 00:53:02 +01001882 /* Initialize clocks */
Michel Dänzer5e6dde72009-09-17 09:42:28 +02001883 radeon_get_clock_info(rdev->ddev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001884 /* Fence driver */
Jerome Glisse30eb77f2011-11-20 20:45:34 +00001885 r = radeon_fence_driver_init(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001886 if (r)
1887 return r;
Jerome Glissed594e462010-02-17 21:54:29 +00001888 /* initialize AGP */
Jerome Glisse700a0cc2010-01-13 15:16:38 +01001889 if (rdev->flags & RADEON_IS_AGP) {
1890 r = radeon_agp_init(rdev);
1891 if (r)
1892 radeon_agp_disable(rdev);
1893 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001894 r = rv770_mc_init(rdev);
Jerome Glisseb574f252009-10-06 19:04:29 +02001895 if (r)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001896 return r;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001897 /* Memory manager */
Jerome Glisse4c788672009-11-20 14:29:23 +01001898 r = radeon_bo_init(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001899 if (r)
1900 return r;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001901
Alex Deucher01ac8792013-12-18 19:11:27 -05001902 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1903 r = r600_init_microcode(rdev);
1904 if (r) {
1905 DRM_ERROR("Failed to load firmware!\n");
1906 return r;
1907 }
1908 }
1909
Alex Deucher6c7bcce2013-12-18 14:07:14 -05001910 /* Initialize power management */
1911 radeon_pm_init(rdev);
1912
Christian Könige32eb502011-10-23 12:56:27 +02001913 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
1914 r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001915
Alex Deucher4d756582012-09-27 15:08:35 -04001916 rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
1917 r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
1918
Christian Königf2ba57b2013-04-08 12:41:29 +02001919 r = radeon_uvd_init(rdev);
1920 if (!r) {
1921 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
1922 r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
1923 4096);
1924 }
1925
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001926 rdev->ih.ring_obj = NULL;
1927 r600_ih_ring_init(rdev, 64 * 1024);
1928
Jerome Glisse4aac0472009-09-14 18:29:49 +02001929 r = r600_pcie_gart_init(rdev);
1930 if (r)
1931 return r;
1932
Alex Deucher779720a2009-12-09 19:31:44 -05001933 rdev->accel_working = true;
Dave Airliefc30b8e2009-09-18 15:19:37 +10001934 r = rv770_startup(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001935 if (r) {
Jerome Glisse655efd32010-02-02 11:51:45 +01001936 dev_err(rdev->dev, "disabling GPU acceleration\n");
Alex Deucherfe251e22010-03-24 13:36:43 -04001937 r700_cp_fini(rdev);
Alex Deucher4d756582012-09-27 15:08:35 -04001938 r600_dma_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01001939 r600_irq_fini(rdev);
Alex Deucher724c80e2010-08-27 18:25:25 -04001940 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02001941 radeon_ib_pool_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01001942 radeon_irq_kms_fini(rdev);
Jerome Glisse75c81292009-10-01 18:02:14 +02001943 rv770_pcie_gart_fini(rdev);
Jerome Glisse733289c2009-09-16 15:24:21 +02001944 rdev->accel_working = false;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001945 }
Rafał Miłecki8a8c6e72010-03-06 13:03:36 +00001946
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001947 return 0;
1948}
1949
1950void rv770_fini(struct radeon_device *rdev)
1951{
Alex Deucher6c7bcce2013-12-18 14:07:14 -05001952 radeon_pm_fini(rdev);
Alex Deucherfe251e22010-03-24 13:36:43 -04001953 r700_cp_fini(rdev);
Alex Deucher4d756582012-09-27 15:08:35 -04001954 r600_dma_fini(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001955 r600_irq_fini(rdev);
Alex Deucher724c80e2010-08-27 18:25:25 -04001956 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02001957 radeon_ib_pool_fini(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001958 radeon_irq_kms_fini(rdev);
Christian Könige409b122013-08-13 11:56:53 +02001959 uvd_v1_0_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02001960 radeon_uvd_fini(rdev);
Jerome Glissed9654412014-02-26 19:22:47 -05001961 rv770_pcie_gart_fini(rdev);
Alex Deucher16cdf042011-10-28 10:30:02 -04001962 r600_vram_scratch_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001963 radeon_gem_fini(rdev);
1964 radeon_fence_driver_fini(rdev);
Jerome Glissed0269ed2010-01-07 16:08:32 +01001965 radeon_agp_fini(rdev);
Jerome Glisse4c788672009-11-20 14:29:23 +01001966 radeon_bo_fini(rdev);
Jerome Glissee7d40b92009-10-01 18:02:15 +02001967 radeon_atombios_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001968 kfree(rdev->bios);
1969 rdev->bios = NULL;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001970}
Alex Deucher9e46a482011-01-06 18:49:35 -05001971
1972static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
1973{
1974 u32 link_width_cntl, lanes, speed_cntl, tmp;
1975 u16 link_cntl2;
1976
Alex Deucherd42dd572011-01-12 20:05:11 -05001977 if (radeon_pcie_gen2 == 0)
1978 return;
1979
Alex Deucher9e46a482011-01-06 18:49:35 -05001980 if (rdev->flags & RADEON_IS_IGP)
1981 return;
1982
1983 if (!(rdev->flags & RADEON_IS_PCIE))
1984 return;
1985
1986 /* x2 cards have a special sequence */
1987 if (ASIC_IS_X2(rdev))
1988 return;
1989
Kleber Sacilotto de Souza7e0e4192013-05-03 19:43:13 -03001990 if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
1991 (rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
Dave Airlie197bbb32012-06-27 08:35:54 +01001992 return;
1993
1994 DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
1995
Alex Deucher9e46a482011-01-06 18:49:35 -05001996 /* advertise upconfig capability */
Alex Deucher492d2b62012-10-25 16:06:59 -04001997 link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05001998 link_width_cntl &= ~LC_UPCONFIGURE_DIS;
Alex Deucher492d2b62012-10-25 16:06:59 -04001999 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
2000 link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002001 if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) {
2002 lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT;
2003 link_width_cntl &= ~(LC_LINK_WIDTH_MASK |
2004 LC_RECONFIG_ARC_MISSING_ESCAPE);
2005 link_width_cntl |= lanes | LC_RECONFIG_NOW |
2006 LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT;
Alex Deucher492d2b62012-10-25 16:06:59 -04002007 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002008 } else {
2009 link_width_cntl |= LC_UPCONFIGURE_DIS;
Alex Deucher492d2b62012-10-25 16:06:59 -04002010 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002011 }
2012
Alex Deucher492d2b62012-10-25 16:06:59 -04002013 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002014 if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
2015 (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
2016
2017 tmp = RREG32(0x541c);
2018 WREG32(0x541c, tmp | 0x8);
2019 WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN);
2020 link_cntl2 = RREG16(0x4088);
2021 link_cntl2 &= ~TARGET_LINK_SPEED_MASK;
2022 link_cntl2 |= 0x2;
2023 WREG16(0x4088, link_cntl2);
2024 WREG32(MM_CFGREGS_CNTL, 0);
2025
Alex Deucher492d2b62012-10-25 16:06:59 -04002026 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002027 speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
Alex Deucher492d2b62012-10-25 16:06:59 -04002028 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002029
Alex Deucher492d2b62012-10-25 16:06:59 -04002030 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002031 speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
Alex Deucher492d2b62012-10-25 16:06:59 -04002032 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002033
Alex Deucher492d2b62012-10-25 16:06:59 -04002034 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002035 speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
Alex Deucher492d2b62012-10-25 16:06:59 -04002036 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002037
Alex Deucher492d2b62012-10-25 16:06:59 -04002038 speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002039 speed_cntl |= LC_GEN2_EN_STRAP;
Alex Deucher492d2b62012-10-25 16:06:59 -04002040 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002041
2042 } else {
Alex Deucher492d2b62012-10-25 16:06:59 -04002043 link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
Alex Deucher9e46a482011-01-06 18:49:35 -05002044 /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
2045 if (1)
2046 link_width_cntl |= LC_UPCONFIGURE_DIS;
2047 else
2048 link_width_cntl &= ~LC_UPCONFIGURE_DIS;
Alex Deucher492d2b62012-10-25 16:06:59 -04002049 WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
Alex Deucher9e46a482011-01-06 18:49:35 -05002050 }
2051}