Gentoo Archives: gentoo-commits

From: "Mike Pagano (mpagano)" <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r2421 - genpatches-2.6/trunk/3.10
Date: Mon, 01 Jul 2013 01:13:03
Message-Id: 20130701011257.9EBA72171C@flycatcher.gentoo.org
1 Author: mpagano
2 Date: 2013-07-01 01:12:57 +0000 (Mon, 01 Jul 2013)
3 New Revision: 2421
4
5 Removed:
6 genpatches-2.6/trunk/3.10/2710_radeon-uvd-patchset.patch
7 Log:
8 Patch removal
9
10 Deleted: genpatches-2.6/trunk/3.10/2710_radeon-uvd-patchset.patch
11 ===================================================================
12 --- genpatches-2.6/trunk/3.10/2710_radeon-uvd-patchset.patch 2013-07-01 00:56:39 UTC (rev 2420)
13 +++ genpatches-2.6/trunk/3.10/2710_radeon-uvd-patchset.patch 2013-07-01 01:12:57 UTC (rev 2421)
14 @@ -1,3497 +0,0 @@
15 -diff -urN a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
16 ---- a/drivers/gpu/drm/radeon/Makefile 2013-05-09 22:13:14.640517917 +0200
17 -+++ b/drivers/gpu/drm/radeon/Makefile 2013-05-09 22:14:57.167175503 +0200
18 -@@ -76,7 +76,7 @@
19 - evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
20 - evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
21 - atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
22 -- si_blit_shaders.o radeon_prime.o
23 -+ si_blit_shaders.o radeon_prime.o radeon_uvd.o
24 -
25 - radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
26 - radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
27 -diff -urN a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
28 ---- a/drivers/gpu/drm/radeon/atombios.h 2013-05-09 22:13:14.640517917 +0200
29 -+++ b/drivers/gpu/drm/radeon/atombios.h 2013-05-09 22:14:57.227175498 +0200
30 -@@ -458,6 +458,7 @@
31 - union
32 - {
33 - ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter
34 -+ ULONG ulClockParams; //ULONG access for BE
35 - ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter
36 - };
37 - UCHAR ucRefDiv; //Output Parameter
38 -@@ -490,6 +491,7 @@
39 - union
40 - {
41 - ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter
42 -+ ULONG ulClockParams; //ULONG access for BE
43 - ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter
44 - };
45 - UCHAR ucRefDiv; //Output Parameter
46 -diff -urN a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
47 ---- a/drivers/gpu/drm/radeon/evergreen.c 2013-05-09 22:13:14.640517917 +0200
48 -+++ b/drivers/gpu/drm/radeon/evergreen.c 2013-05-09 22:14:57.217175499 +0200
49 -@@ -84,6 +84,223 @@
50 - }
51 - }
52 -
53 -+static int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock,
54 -+ u32 cntl_reg, u32 status_reg)
55 -+{
56 -+ int r, i;
57 -+ struct atom_clock_dividers dividers;
58 -+
59 -+ r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
60 -+ clock, false, &dividers);
61 -+ if (r)
62 -+ return r;
63 -+
64 -+ WREG32_P(cntl_reg, dividers.post_div, ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK));
65 -+
66 -+ for (i = 0; i < 100; i++) {
67 -+ if (RREG32(status_reg) & DCLK_STATUS)
68 -+ break;
69 -+ mdelay(10);
70 -+ }
71 -+ if (i == 100)
72 -+ return -ETIMEDOUT;
73 -+
74 -+ return 0;
75 -+}
76 -+
77 -+int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
78 -+{
79 -+ int r = 0;
80 -+ u32 cg_scratch = RREG32(CG_SCRATCH1);
81 -+
82 -+ r = sumo_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS);
83 -+ if (r)
84 -+ goto done;
85 -+ cg_scratch &= 0xffff0000;
86 -+ cg_scratch |= vclk / 100; /* Mhz */
87 -+
88 -+ r = sumo_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS);
89 -+ if (r)
90 -+ goto done;
91 -+ cg_scratch &= 0x0000ffff;
92 -+ cg_scratch |= (dclk / 100) << 16; /* Mhz */
93 -+
94 -+done:
95 -+ WREG32(CG_SCRATCH1, cg_scratch);
96 -+
97 -+ return r;
98 -+}
99 -+
100 -+static int evergreen_uvd_calc_post_div(unsigned target_freq,
101 -+ unsigned vco_freq,
102 -+ unsigned *div)
103 -+{
104 -+ /* target larger than vco frequency ? */
105 -+ if (vco_freq < target_freq)
106 -+ return -1; /* forget it */
107 -+
108 -+ /* Fclk = Fvco / PDIV */
109 -+ *div = vco_freq / target_freq;
110 -+
111 -+ /* we alway need a frequency less than or equal the target */
112 -+ if ((vco_freq / *div) > target_freq)
113 -+ *div += 1;
114 -+
115 -+ /* dividers above 5 must be even */
116 -+ if (*div > 5 && *div % 2)
117 -+ *div += 1;
118 -+
119 -+ /* out of range ? */
120 -+ if (*div >= 128)
121 -+ return -1; /* forget it */
122 -+
123 -+ return vco_freq / *div;
124 -+}
125 -+
126 -+static int evergreen_uvd_send_upll_ctlreq(struct radeon_device *rdev)
127 -+{
128 -+ unsigned i;
129 -+
130 -+ /* assert UPLL_CTLREQ */
131 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
132 -+
133 -+ /* wait for CTLACK and CTLACK2 to get asserted */
134 -+ for (i = 0; i < 100; ++i) {
135 -+ uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
136 -+ if ((RREG32(CG_UPLL_FUNC_CNTL) & mask) == mask)
137 -+ break;
138 -+ mdelay(10);
139 -+ }
140 -+ if (i == 100)
141 -+ return -ETIMEDOUT;
142 -+
143 -+ /* deassert UPLL_CTLREQ */
144 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
145 -+
146 -+ return 0;
147 -+}
148 -+
149 -+int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
150 -+{
151 -+ /* start off with something large */
152 -+ int optimal_diff_score = 0x7FFFFFF;
153 -+ unsigned optimal_fb_div = 0, optimal_vclk_div = 0;
154 -+ unsigned optimal_dclk_div = 0, optimal_vco_freq = 0;
155 -+ unsigned vco_freq;
156 -+ int r;
157 -+
158 -+ /* bypass vclk and dclk with bclk */
159 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
160 -+ VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
161 -+ ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
162 -+
163 -+ /* put PLL in bypass mode */
164 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
165 -+
166 -+ if (!vclk || !dclk) {
167 -+ /* keep the Bypass mode, put PLL to sleep */
168 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
169 -+ return 0;
170 -+ }
171 -+
172 -+ /* loop through vco from low to high */
173 -+ for (vco_freq = 125000; vco_freq <= 250000; vco_freq += 100) {
174 -+ unsigned fb_div = vco_freq / rdev->clock.spll.reference_freq * 16384;
175 -+ int calc_clk, diff_score, diff_vclk, diff_dclk;
176 -+ unsigned vclk_div, dclk_div;
177 -+
178 -+ /* fb div out of range ? */
179 -+ if (fb_div > 0x03FFFFFF)
180 -+ break; /* it can oly get worse */
181 -+
182 -+ /* calc vclk with current vco freq. */
183 -+ calc_clk = evergreen_uvd_calc_post_div(vclk, vco_freq, &vclk_div);
184 -+ if (calc_clk == -1)
185 -+ break; /* vco is too big, it has to stop. */
186 -+ diff_vclk = vclk - calc_clk;
187 -+
188 -+ /* calc dclk with current vco freq. */
189 -+ calc_clk = evergreen_uvd_calc_post_div(dclk, vco_freq, &dclk_div);
190 -+ if (calc_clk == -1)
191 -+ break; /* vco is too big, it has to stop. */
192 -+ diff_dclk = dclk - calc_clk;
193 -+
194 -+ /* determine if this vco setting is better than current optimal settings */
195 -+ diff_score = abs(diff_vclk) + abs(diff_dclk);
196 -+ if (diff_score < optimal_diff_score) {
197 -+ optimal_fb_div = fb_div;
198 -+ optimal_vclk_div = vclk_div;
199 -+ optimal_dclk_div = dclk_div;
200 -+ optimal_vco_freq = vco_freq;
201 -+ optimal_diff_score = diff_score;
202 -+ if (optimal_diff_score == 0)
203 -+ break; /* it can't get better than this */
204 -+ }
205 -+ }
206 -+
207 -+ /* set VCO_MODE to 1 */
208 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
209 -+
210 -+ /* toggle UPLL_SLEEP to 1 then back to 0 */
211 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
212 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
213 -+
214 -+ /* deassert UPLL_RESET */
215 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
216 -+
217 -+ mdelay(1);
218 -+
219 -+ r = evergreen_uvd_send_upll_ctlreq(rdev);
220 -+ if (r)
221 -+ return r;
222 -+
223 -+ /* assert UPLL_RESET again */
224 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
225 -+
226 -+ /* disable spread spectrum. */
227 -+ WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
228 -+
229 -+ /* set feedback divider */
230 -+ WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(optimal_fb_div), ~UPLL_FB_DIV_MASK);
231 -+
232 -+ /* set ref divider to 0 */
233 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
234 -+
235 -+ if (optimal_vco_freq < 187500)
236 -+ WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
237 -+ else
238 -+ WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
239 -+
240 -+ /* set PDIV_A and PDIV_B */
241 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
242 -+ UPLL_PDIV_A(optimal_vclk_div) | UPLL_PDIV_B(optimal_dclk_div),
243 -+ ~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
244 -+
245 -+ /* give the PLL some time to settle */
246 -+ mdelay(15);
247 -+
248 -+ /* deassert PLL_RESET */
249 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
250 -+
251 -+ mdelay(15);
252 -+
253 -+ /* switch from bypass mode to normal mode */
254 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
255 -+
256 -+ r = evergreen_uvd_send_upll_ctlreq(rdev);
257 -+ if (r)
258 -+ return r;
259 -+
260 -+ /* switch VCLK and DCLK selection */
261 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
262 -+ VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
263 -+ ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
264 -+
265 -+ mdelay(100);
266 -+
267 -+ return 0;
268 -+}
269 -+
270 - void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
271 - {
272 - u16 ctl, v;
273 -@@ -2058,6 +2275,9 @@
274 - WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
275 - WREG32(HDP_ADDR_CONFIG, gb_addr_config);
276 - WREG32(DMA_TILING_CONFIG, gb_addr_config);
277 -+ WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
278 -+ WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
279 -+ WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
280 -
281 - if ((rdev->config.evergreen.max_backends == 1) &&
282 - (rdev->flags & RADEON_IS_IGP)) {
283 -@@ -3360,6 +3580,9 @@
284 - DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
285 - break;
286 - }
287 -+ case 124: /* UVD */
288 -+ DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
289 -+ radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
290 - break;
291 - case 146:
292 - case 147:
293 -@@ -3571,7 +3794,7 @@
294 -
295 - static int evergreen_startup(struct radeon_device *rdev)
296 - {
297 -- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
298 -+ struct radeon_ring *ring;
299 - int r;
300 -
301 - /* enable pcie gen2 link */
302 -@@ -3638,6 +3861,17 @@
303 - return r;
304 - }
305 -
306 -+ r = rv770_uvd_resume(rdev);
307 -+ if (!r) {
308 -+ r = radeon_fence_driver_start_ring(rdev,
309 -+ R600_RING_TYPE_UVD_INDEX);
310 -+ if (r)
311 -+ dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
312 -+ }
313 -+
314 -+ if (r)
315 -+ rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
316 -+
317 - /* Enable IRQ */
318 - r = r600_irq_init(rdev);
319 - if (r) {
320 -@@ -3647,6 +3881,7 @@
321 - }
322 - evergreen_irq_set(rdev);
323 -
324 -+ ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
325 - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
326 - R600_CP_RB_RPTR, R600_CP_RB_WPTR,
327 - 0, 0xfffff, RADEON_CP_PACKET2);
328 -@@ -3670,6 +3905,19 @@
329 - if (r)
330 - return r;
331 -
332 -+ ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
333 -+ if (ring->ring_size) {
334 -+ r = radeon_ring_init(rdev, ring, ring->ring_size,
335 -+ R600_WB_UVD_RPTR_OFFSET,
336 -+ UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
337 -+ 0, 0xfffff, RADEON_CP_PACKET2);
338 -+ if (!r)
339 -+ r = r600_uvd_init(rdev);
340 -+
341 -+ if (r)
342 -+ DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
343 -+ }
344 -+
345 - r = radeon_ib_pool_init(rdev);
346 - if (r) {
347 - dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
348 -@@ -3716,8 +3964,10 @@
349 - int evergreen_suspend(struct radeon_device *rdev)
350 - {
351 - r600_audio_fini(rdev);
352 -+ radeon_uvd_suspend(rdev);
353 - r700_cp_stop(rdev);
354 - r600_dma_stop(rdev);
355 -+ r600_uvd_rbc_stop(rdev);
356 - evergreen_irq_suspend(rdev);
357 - radeon_wb_disable(rdev);
358 - evergreen_pcie_gart_disable(rdev);
359 -@@ -3797,6 +4047,13 @@
360 - rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
361 - r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
362 -
363 -+ r = radeon_uvd_init(rdev);
364 -+ if (!r) {
365 -+ rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
366 -+ r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
367 -+ 4096);
368 -+ }
369 -+
370 - rdev->ih.ring_obj = NULL;
371 - r600_ih_ring_init(rdev, 64 * 1024);
372 -
373 -@@ -3843,6 +4100,7 @@
374 - radeon_ib_pool_fini(rdev);
375 - radeon_irq_kms_fini(rdev);
376 - evergreen_pcie_gart_fini(rdev);
377 -+ radeon_uvd_fini(rdev);
378 - r600_vram_scratch_fini(rdev);
379 - radeon_gem_fini(rdev);
380 - radeon_fence_driver_fini(rdev);
381 -diff -urN a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
382 ---- a/drivers/gpu/drm/radeon/evergreend.h 2013-05-09 22:13:14.643851250 +0200
383 -+++ b/drivers/gpu/drm/radeon/evergreend.h 2013-05-09 22:14:57.210508833 +0200
384 -@@ -53,6 +53,43 @@
385 - #define RCU_IND_INDEX 0x100
386 - #define RCU_IND_DATA 0x104
387 -
388 -+/* discrete uvd clocks */
389 -+#define CG_UPLL_FUNC_CNTL 0x718
390 -+# define UPLL_RESET_MASK 0x00000001
391 -+# define UPLL_SLEEP_MASK 0x00000002
392 -+# define UPLL_BYPASS_EN_MASK 0x00000004
393 -+# define UPLL_CTLREQ_MASK 0x00000008
394 -+# define UPLL_REF_DIV_MASK 0x001F0000
395 -+# define UPLL_VCO_MODE_MASK 0x00000200
396 -+# define UPLL_CTLACK_MASK 0x40000000
397 -+# define UPLL_CTLACK2_MASK 0x80000000
398 -+#define CG_UPLL_FUNC_CNTL_2 0x71c
399 -+# define UPLL_PDIV_A(x) ((x) << 0)
400 -+# define UPLL_PDIV_A_MASK 0x0000007F
401 -+# define UPLL_PDIV_B(x) ((x) << 8)
402 -+# define UPLL_PDIV_B_MASK 0x00007F00
403 -+# define VCLK_SRC_SEL(x) ((x) << 20)
404 -+# define VCLK_SRC_SEL_MASK 0x01F00000
405 -+# define DCLK_SRC_SEL(x) ((x) << 25)
406 -+# define DCLK_SRC_SEL_MASK 0x3E000000
407 -+#define CG_UPLL_FUNC_CNTL_3 0x720
408 -+# define UPLL_FB_DIV(x) ((x) << 0)
409 -+# define UPLL_FB_DIV_MASK 0x01FFFFFF
410 -+#define CG_UPLL_FUNC_CNTL_4 0x854
411 -+# define UPLL_SPARE_ISPARE9 0x00020000
412 -+#define CG_UPLL_SPREAD_SPECTRUM 0x79c
413 -+# define SSEN_MASK 0x00000001
414 -+
415 -+/* fusion uvd clocks */
416 -+#define CG_DCLK_CNTL 0x610
417 -+# define DCLK_DIVIDER_MASK 0x7f
418 -+# define DCLK_DIR_CNTL_EN (1 << 8)
419 -+#define CG_DCLK_STATUS 0x614
420 -+# define DCLK_STATUS (1 << 0)
421 -+#define CG_VCLK_CNTL 0x618
422 -+#define CG_VCLK_STATUS 0x61c
423 -+#define CG_SCRATCH1 0x820
424 -+
425 - #define GRBM_GFX_INDEX 0x802C
426 - #define INSTANCE_INDEX(x) ((x) << 0)
427 - #define SE_INDEX(x) ((x) << 16)
428 -@@ -992,6 +1029,16 @@
429 - # define TARGET_LINK_SPEED_MASK (0xf << 0)
430 - # define SELECTABLE_DEEMPHASIS (1 << 6)
431 -
432 -+
433 -+/*
434 -+ * UVD
435 -+ */
436 -+#define UVD_UDEC_ADDR_CONFIG 0xef4c
437 -+#define UVD_UDEC_DB_ADDR_CONFIG 0xef50
438 -+#define UVD_UDEC_DBW_ADDR_CONFIG 0xef54
439 -+#define UVD_RBC_RB_RPTR 0xf690
440 -+#define UVD_RBC_RB_WPTR 0xf694
441 -+
442 - /*
443 - * PM4
444 - */
445 -diff -urN a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
446 ---- a/drivers/gpu/drm/radeon/ni.c 2013-05-09 22:13:14.643851250 +0200
447 -+++ b/drivers/gpu/drm/radeon/ni.c 2013-05-09 22:14:57.210508833 +0200
448 -@@ -624,6 +624,9 @@
449 - WREG32(HDP_ADDR_CONFIG, gb_addr_config);
450 - WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
451 - WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
452 -+ WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
453 -+ WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
454 -+ WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
455 -
456 - if ((rdev->config.cayman.max_backends_per_se == 1) &&
457 - (rdev->flags & RADEON_IS_IGP)) {
458 -@@ -931,6 +934,23 @@
459 - radeon_ring_write(ring, 10); /* poll interval */
460 - }
461 -
462 -+void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
463 -+ struct radeon_ring *ring,
464 -+ struct radeon_semaphore *semaphore,
465 -+ bool emit_wait)
466 -+{
467 -+ uint64_t addr = semaphore->gpu_addr;
468 -+
469 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
470 -+ radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
471 -+
472 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
473 -+ radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
474 -+
475 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
476 -+ radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
477 -+}
478 -+
479 - static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
480 - {
481 - if (enable)
482 -@@ -1682,6 +1702,16 @@
483 - return r;
484 - }
485 -
486 -+ r = rv770_uvd_resume(rdev);
487 -+ if (!r) {
488 -+ r = radeon_fence_driver_start_ring(rdev,
489 -+ R600_RING_TYPE_UVD_INDEX);
490 -+ if (r)
491 -+ dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
492 -+ }
493 -+ if (r)
494 -+ rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
495 -+
496 - r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
497 - if (r) {
498 - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
499 -@@ -1748,6 +1778,18 @@
500 - if (r)
501 - return r;
502 -
503 -+ ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
504 -+ if (ring->ring_size) {
505 -+ r = radeon_ring_init(rdev, ring, ring->ring_size,
506 -+ R600_WB_UVD_RPTR_OFFSET,
507 -+ UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
508 -+ 0, 0xfffff, RADEON_CP_PACKET2);
509 -+ if (!r)
510 -+ r = r600_uvd_init(rdev);
511 -+ if (r)
512 -+ DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
513 -+ }
514 -+
515 - r = radeon_ib_pool_init(rdev);
516 - if (r) {
517 - dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
518 -@@ -1794,6 +1836,8 @@
519 - radeon_vm_manager_fini(rdev);
520 - cayman_cp_enable(rdev, false);
521 - cayman_dma_stop(rdev);
522 -+ r600_uvd_rbc_stop(rdev);
523 -+ radeon_uvd_suspend(rdev);
524 - evergreen_irq_suspend(rdev);
525 - radeon_wb_disable(rdev);
526 - cayman_pcie_gart_disable(rdev);
527 -@@ -1868,6 +1912,13 @@
528 - ring->ring_obj = NULL;
529 - r600_ring_init(rdev, ring, 64 * 1024);
530 -
531 -+ r = radeon_uvd_init(rdev);
532 -+ if (!r) {
533 -+ ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
534 -+ ring->ring_obj = NULL;
535 -+ r600_ring_init(rdev, ring, 4096);
536 -+ }
537 -+
538 - rdev->ih.ring_obj = NULL;
539 - r600_ih_ring_init(rdev, 64 * 1024);
540 -
541 -@@ -1919,6 +1970,7 @@
542 - radeon_vm_manager_fini(rdev);
543 - radeon_ib_pool_fini(rdev);
544 - radeon_irq_kms_fini(rdev);
545 -+ radeon_uvd_fini(rdev);
546 - cayman_pcie_gart_fini(rdev);
547 - r600_vram_scratch_fini(rdev);
548 - radeon_gem_fini(rdev);
549 -diff -urN a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
550 ---- a/drivers/gpu/drm/radeon/nid.h 2013-05-09 22:13:14.643851250 +0200
551 -+++ b/drivers/gpu/drm/radeon/nid.h 2013-05-09 22:14:57.210508833 +0200
552 -@@ -486,6 +486,18 @@
553 - # define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0)
554 -
555 - /*
556 -+ * UVD
557 -+ */
558 -+#define UVD_SEMA_ADDR_LOW 0xEF00
559 -+#define UVD_SEMA_ADDR_HIGH 0xEF04
560 -+#define UVD_SEMA_CMD 0xEF08
561 -+#define UVD_UDEC_ADDR_CONFIG 0xEF4C
562 -+#define UVD_UDEC_DB_ADDR_CONFIG 0xEF50
563 -+#define UVD_UDEC_DBW_ADDR_CONFIG 0xEF54
564 -+#define UVD_RBC_RB_RPTR 0xF690
565 -+#define UVD_RBC_RB_WPTR 0xF694
566 -+
567 -+/*
568 - * PM4
569 - */
570 - #define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \
571 -diff -urN a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
572 ---- a/drivers/gpu/drm/radeon/r600.c 2013-05-09 22:13:14.643851250 +0200
573 -+++ b/drivers/gpu/drm/radeon/r600.c 2013-05-09 22:14:57.230508831 +0200
574 -@@ -2552,6 +2552,193 @@
575 - }
576 -
577 - /*
578 -+ * UVD
579 -+ */
580 -+int r600_uvd_rbc_start(struct radeon_device *rdev)
581 -+{
582 -+ struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
583 -+ uint64_t rptr_addr;
584 -+ uint32_t rb_bufsz, tmp;
585 -+ int r;
586 -+
587 -+ rptr_addr = rdev->wb.gpu_addr + R600_WB_UVD_RPTR_OFFSET;
588 -+
589 -+ if (upper_32_bits(rptr_addr) != upper_32_bits(ring->gpu_addr)) {
590 -+ DRM_ERROR("UVD ring and rptr not in the same 4GB segment!\n");
591 -+ return -EINVAL;
592 -+ }
593 -+
594 -+ /* force RBC into idle state */
595 -+ WREG32(UVD_RBC_RB_CNTL, 0x11010101);
596 -+
597 -+ /* Set the write pointer delay */
598 -+ WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
599 -+
600 -+ /* set the wb address */
601 -+ WREG32(UVD_RBC_RB_RPTR_ADDR, rptr_addr >> 2);
602 -+
603 -+ /* programm the 4GB memory segment for rptr and ring buffer */
604 -+ WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(rptr_addr) |
605 -+ (0x7 << 16) | (0x1 << 31));
606 -+
607 -+ /* Initialize the ring buffer's read and write pointers */
608 -+ WREG32(UVD_RBC_RB_RPTR, 0x0);
609 -+
610 -+ ring->wptr = ring->rptr = RREG32(UVD_RBC_RB_RPTR);
611 -+ WREG32(UVD_RBC_RB_WPTR, ring->wptr);
612 -+
613 -+ /* set the ring address */
614 -+ WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
615 -+
616 -+ /* Set ring buffer size */
617 -+ rb_bufsz = drm_order(ring->ring_size);
618 -+ rb_bufsz = (0x1 << 8) | rb_bufsz;
619 -+ WREG32(UVD_RBC_RB_CNTL, rb_bufsz);
620 -+
621 -+ ring->ready = true;
622 -+ r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
623 -+ if (r) {
624 -+ ring->ready = false;
625 -+ return r;
626 -+ }
627 -+
628 -+ r = radeon_ring_lock(rdev, ring, 10);
629 -+ if (r) {
630 -+ DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
631 -+ return r;
632 -+ }
633 -+
634 -+ tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
635 -+ radeon_ring_write(ring, tmp);
636 -+ radeon_ring_write(ring, 0xFFFFF);
637 -+
638 -+ tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
639 -+ radeon_ring_write(ring, tmp);
640 -+ radeon_ring_write(ring, 0xFFFFF);
641 -+
642 -+ tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
643 -+ radeon_ring_write(ring, tmp);
644 -+ radeon_ring_write(ring, 0xFFFFF);
645 -+
646 -+ /* Clear timeout status bits */
647 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
648 -+ radeon_ring_write(ring, 0x8);
649 -+
650 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
651 -+ radeon_ring_write(ring, 3);
652 -+
653 -+ radeon_ring_unlock_commit(rdev, ring);
654 -+
655 -+ return 0;
656 -+}
657 -+
658 -+void r600_uvd_rbc_stop(struct radeon_device *rdev)
659 -+{
660 -+ struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
661 -+
662 -+ /* force RBC into idle state */
663 -+ WREG32(UVD_RBC_RB_CNTL, 0x11010101);
664 -+ ring->ready = false;
665 -+}
666 -+
667 -+int r600_uvd_init(struct radeon_device *rdev)
668 -+{
669 -+ int i, j, r;
670 -+
671 -+ /* raise clocks while booting up the VCPU */
672 -+ radeon_set_uvd_clocks(rdev, 53300, 40000);
673 -+
674 -+ /* disable clock gating */
675 -+ WREG32(UVD_CGC_GATE, 0);
676 -+
677 -+ /* disable interupt */
678 -+ WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
679 -+
680 -+ /* put LMI, VCPU, RBC etc... into reset */
681 -+ WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
682 -+ LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
683 -+ CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
684 -+ mdelay(5);
685 -+
686 -+ /* take UVD block out of reset */
687 -+ WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
688 -+ mdelay(5);
689 -+
690 -+ /* initialize UVD memory controller */
691 -+ WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
692 -+ (1 << 21) | (1 << 9) | (1 << 20));
693 -+
694 -+ /* disable byte swapping */
695 -+ WREG32(UVD_LMI_SWAP_CNTL, 0);
696 -+ WREG32(UVD_MP_SWAP_CNTL, 0);
697 -+
698 -+ WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
699 -+ WREG32(UVD_MPC_SET_MUXA1, 0x0);
700 -+ WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
701 -+ WREG32(UVD_MPC_SET_MUXB1, 0x0);
702 -+ WREG32(UVD_MPC_SET_ALU, 0);
703 -+ WREG32(UVD_MPC_SET_MUX, 0x88);
704 -+
705 -+ /* Stall UMC */
706 -+ WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
707 -+ WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
708 -+
709 -+ /* take all subblocks out of reset, except VCPU */
710 -+ WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
711 -+ mdelay(5);
712 -+
713 -+ /* enable VCPU clock */
714 -+ WREG32(UVD_VCPU_CNTL, 1 << 9);
715 -+
716 -+ /* enable UMC */
717 -+ WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
718 -+
719 -+ /* boot up the VCPU */
720 -+ WREG32(UVD_SOFT_RESET, 0);
721 -+ mdelay(10);
722 -+
723 -+ WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
724 -+
725 -+ for (i = 0; i < 10; ++i) {
726 -+ uint32_t status;
727 -+ for (j = 0; j < 100; ++j) {
728 -+ status = RREG32(UVD_STATUS);
729 -+ if (status & 2)
730 -+ break;
731 -+ mdelay(10);
732 -+ }
733 -+ r = 0;
734 -+ if (status & 2)
735 -+ break;
736 -+
737 -+ DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
738 -+ WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
739 -+ mdelay(10);
740 -+ WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
741 -+ mdelay(10);
742 -+ r = -1;
743 -+ }
744 -+
745 -+ if (r) {
746 -+ DRM_ERROR("UVD not responding, giving up!!!\n");
747 -+ radeon_set_uvd_clocks(rdev, 0, 0);
748 -+ return r;
749 -+ }
750 -+
751 -+ /* enable interupt */
752 -+ WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
753 -+
754 -+ r = r600_uvd_rbc_start(rdev);
755 -+ if (!r)
756 -+ DRM_INFO("UVD initialized successfully.\n");
757 -+
758 -+ /* lower clocks again */
759 -+ radeon_set_uvd_clocks(rdev, 0, 0);
760 -+
761 -+ return r;
762 -+}
763 -+
764 -+/*
765 - * GPU scratch registers helpers function.
766 - */
767 - void r600_scratch_init(struct radeon_device *rdev)
768 -@@ -2660,6 +2847,40 @@
769 - return r;
770 - }
771 -
772 -+int r600_uvd_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
773 -+{
774 -+ uint32_t tmp = 0;
775 -+ unsigned i;
776 -+ int r;
777 -+
778 -+ WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
779 -+ r = radeon_ring_lock(rdev, ring, 3);
780 -+ if (r) {
781 -+ DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
782 -+ ring->idx, r);
783 -+ return r;
784 -+ }
785 -+ radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
786 -+ radeon_ring_write(ring, 0xDEADBEEF);
787 -+ radeon_ring_unlock_commit(rdev, ring);
788 -+ for (i = 0; i < rdev->usec_timeout; i++) {
789 -+ tmp = RREG32(UVD_CONTEXT_ID);
790 -+ if (tmp == 0xDEADBEEF)
791 -+ break;
792 -+ DRM_UDELAY(1);
793 -+ }
794 -+
795 -+ if (i < rdev->usec_timeout) {
796 -+ DRM_INFO("ring test on %d succeeded in %d usecs\n",
797 -+ ring->idx, i);
798 -+ } else {
799 -+ DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
800 -+ ring->idx, tmp);
801 -+ r = -EINVAL;
802 -+ }
803 -+ return r;
804 -+}
805 -+
806 - /*
807 - * CP fences/semaphores
808 - */
809 -@@ -2711,6 +2932,30 @@
810 - }
811 - }
812 -
813 -+void r600_uvd_fence_emit(struct radeon_device *rdev,
814 -+ struct radeon_fence *fence)
815 -+{
816 -+ struct radeon_ring *ring = &rdev->ring[fence->ring];
817 -+ uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
818 -+
819 -+ radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
820 -+ radeon_ring_write(ring, fence->seq);
821 -+ radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
822 -+ radeon_ring_write(ring, addr & 0xffffffff);
823 -+ radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
824 -+ radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
825 -+ radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
826 -+ radeon_ring_write(ring, 0);
827 -+
828 -+ radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
829 -+ radeon_ring_write(ring, 0);
830 -+ radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
831 -+ radeon_ring_write(ring, 0);
832 -+ radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
833 -+ radeon_ring_write(ring, 2);
834 -+ return;
835 -+}
836 -+
837 - void r600_semaphore_ring_emit(struct radeon_device *rdev,
838 - struct radeon_ring *ring,
839 - struct radeon_semaphore *semaphore,
840 -@@ -2780,6 +3025,23 @@
841 - radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
842 - }
843 -
844 -+void r600_uvd_semaphore_emit(struct radeon_device *rdev,
845 -+ struct radeon_ring *ring,
846 -+ struct radeon_semaphore *semaphore,
847 -+ bool emit_wait)
848 -+{
849 -+ uint64_t addr = semaphore->gpu_addr;
850 -+
851 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
852 -+ radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
853 -+
854 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
855 -+ radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
856 -+
857 -+ radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
858 -+ radeon_ring_write(ring, emit_wait ? 1 : 0);
859 -+}
860 -+
861 - int r600_copy_blit(struct radeon_device *rdev,
862 - uint64_t src_offset,
863 - uint64_t dst_offset,
864 -@@ -3183,6 +3445,16 @@
865 - radeon_ring_write(ring, ib->length_dw);
866 - }
867 -
868 -+void r600_uvd_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
869 -+{
870 -+ struct radeon_ring *ring = &rdev->ring[ib->ring];
871 -+
872 -+ radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
873 -+ radeon_ring_write(ring, ib->gpu_addr);
874 -+ radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
875 -+ radeon_ring_write(ring, ib->length_dw);
876 -+}
877 -+
878 - int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
879 - {
880 - struct radeon_ib ib;
881 -@@ -3300,6 +3572,41 @@
882 - return r;
883 - }
884 -
885 -+int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
886 -+{
887 -+ struct radeon_fence *fence = NULL;
888 -+ int r;
889 -+
890 -+ r = radeon_set_uvd_clocks(rdev, 53300, 40000);
891 -+ if (r) {
892 -+ DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
893 -+ return r;
894 -+ }
895 -+
896 -+ r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
897 -+ if (r) {
898 -+ DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
899 -+ goto error;
900 -+ }
901 -+
902 -+ r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
903 -+ if (r) {
904 -+ DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
905 -+ goto error;
906 -+ }
907 -+
908 -+ r = radeon_fence_wait(fence, false);
909 -+ if (r) {
910 -+ DRM_ERROR("radeon: fence wait failed (%d).\n", r);
911 -+ goto error;
912 -+ }
913 -+ DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
914 -+error:
915 -+ radeon_fence_unref(&fence);
916 -+ radeon_set_uvd_clocks(rdev, 0, 0);
917 -+ return r;
918 -+}
919 -+
920 - /**
921 - * r600_dma_ring_ib_execute - Schedule an IB on the DMA engine
922 - *
923 -diff -urN a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
924 ---- a/drivers/gpu/drm/radeon/r600d.h 2013-05-09 22:13:14.643851250 +0200
925 -+++ b/drivers/gpu/drm/radeon/r600d.h 2013-05-09 22:14:57.173842169 +0200
926 -@@ -691,6 +691,7 @@
927 - #define SRBM_SOFT_RESET 0xe60
928 - # define SOFT_RESET_DMA (1 << 12)
929 - # define SOFT_RESET_RLC (1 << 13)
930 -+# define SOFT_RESET_UVD (1 << 18)
931 - # define RV770_SOFT_RESET_DMA (1 << 20)
932 -
933 - #define CP_INT_CNTL 0xc124
934 -@@ -1143,6 +1144,66 @@
935 - # define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30)
936 -
937 - /*
938 -+ * UVD
939 -+ */
940 -+#define UVD_SEMA_ADDR_LOW 0xef00
941 -+#define UVD_SEMA_ADDR_HIGH 0xef04
942 -+#define UVD_SEMA_CMD 0xef08
943 -+
944 -+#define UVD_GPCOM_VCPU_CMD 0xef0c
945 -+#define UVD_GPCOM_VCPU_DATA0 0xef10
946 -+#define UVD_GPCOM_VCPU_DATA1 0xef14
947 -+#define UVD_ENGINE_CNTL 0xef18
948 -+
949 -+#define UVD_SEMA_CNTL 0xf400
950 -+#define UVD_RB_ARB_CTRL 0xf480
951 -+
952 -+#define UVD_LMI_EXT40_ADDR 0xf498
953 -+#define UVD_CGC_GATE 0xf4a8
954 -+#define UVD_LMI_CTRL2 0xf4f4
955 -+#define UVD_MASTINT_EN 0xf500
956 -+#define UVD_LMI_ADDR_EXT 0xf594
957 -+#define UVD_LMI_CTRL 0xf598
958 -+#define UVD_LMI_SWAP_CNTL 0xf5b4
959 -+#define UVD_MP_SWAP_CNTL 0xf5bC
960 -+#define UVD_MPC_CNTL 0xf5dC
961 -+#define UVD_MPC_SET_MUXA0 0xf5e4
962 -+#define UVD_MPC_SET_MUXA1 0xf5e8
963 -+#define UVD_MPC_SET_MUXB0 0xf5eC
964 -+#define UVD_MPC_SET_MUXB1 0xf5f0
965 -+#define UVD_MPC_SET_MUX 0xf5f4
966 -+#define UVD_MPC_SET_ALU 0xf5f8
967 -+
968 -+#define UVD_VCPU_CNTL 0xf660
969 -+#define UVD_SOFT_RESET 0xf680
970 -+#define RBC_SOFT_RESET (1<<0)
971 -+#define LBSI_SOFT_RESET (1<<1)
972 -+#define LMI_SOFT_RESET (1<<2)
973 -+#define VCPU_SOFT_RESET (1<<3)
974 -+#define CSM_SOFT_RESET (1<<5)
975 -+#define CXW_SOFT_RESET (1<<6)
976 -+#define TAP_SOFT_RESET (1<<7)
977 -+#define LMI_UMC_SOFT_RESET (1<<13)
978 -+#define UVD_RBC_IB_BASE 0xf684
979 -+#define UVD_RBC_IB_SIZE 0xf688
980 -+#define UVD_RBC_RB_BASE 0xf68c
981 -+#define UVD_RBC_RB_RPTR 0xf690
982 -+#define UVD_RBC_RB_WPTR 0xf694
983 -+#define UVD_RBC_RB_WPTR_CNTL 0xf698
984 -+
985 -+#define UVD_STATUS 0xf6bc
986 -+
987 -+#define UVD_SEMA_TIMEOUT_STATUS 0xf6c0
988 -+#define UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL 0xf6c4
989 -+#define UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL 0xf6c8
990 -+#define UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL 0xf6cc
991 -+
992 -+#define UVD_RBC_RB_CNTL 0xf6a4
993 -+#define UVD_RBC_RB_RPTR_ADDR 0xf6a8
994 -+
995 -+#define UVD_CONTEXT_ID 0xf6f4
996 -+
997 -+/*
998 - * PM4
999 - */
1000 - #define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \
1001 -diff -urN a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
1002 ---- a/drivers/gpu/drm/radeon/radeon.h 2013-05-09 22:13:14.643851250 +0200
1003 -+++ b/drivers/gpu/drm/radeon/radeon.h 2013-05-09 22:14:57.220508832 +0200
1004 -@@ -95,6 +95,7 @@
1005 - extern int radeon_pcie_gen2;
1006 - extern int radeon_msi;
1007 - extern int radeon_lockup_timeout;
1008 -+extern int radeon_fastfb;
1009 -
1010 - /*
1011 - * Copy from radeon_drv.h so we don't have to include both and have conflicting
1012 -@@ -109,24 +110,27 @@
1013 - #define RADEON_BIOS_NUM_SCRATCH 8
1014 -
1015 - /* max number of rings */
1016 --#define RADEON_NUM_RINGS 5
1017 -+#define RADEON_NUM_RINGS 6
1018 -
1019 - /* fence seq are set to this number when signaled */
1020 - #define RADEON_FENCE_SIGNALED_SEQ 0LL
1021 -
1022 - /* internal ring indices */
1023 - /* r1xx+ has gfx CP ring */
1024 --#define RADEON_RING_TYPE_GFX_INDEX 0
1025 -+#define RADEON_RING_TYPE_GFX_INDEX 0
1026 -
1027 - /* cayman has 2 compute CP rings */
1028 --#define CAYMAN_RING_TYPE_CP1_INDEX 1
1029 --#define CAYMAN_RING_TYPE_CP2_INDEX 2
1030 -+#define CAYMAN_RING_TYPE_CP1_INDEX 1
1031 -+#define CAYMAN_RING_TYPE_CP2_INDEX 2
1032 -
1033 - /* R600+ has an async dma ring */
1034 - #define R600_RING_TYPE_DMA_INDEX 3
1035 - /* cayman add a second async dma ring */
1036 - #define CAYMAN_RING_TYPE_DMA1_INDEX 4
1037 -
1038 -+/* R600+ */
1039 -+#define R600_RING_TYPE_UVD_INDEX 5
1040 -+
1041 - /* hardcode those limit for now */
1042 - #define RADEON_VA_IB_OFFSET (1 << 20)
1043 - #define RADEON_VA_RESERVED_SIZE (8 << 20)
1044 -@@ -202,6 +206,11 @@
1045 - void radeon_pm_resume(struct radeon_device *rdev);
1046 - void radeon_combios_get_power_modes(struct radeon_device *rdev);
1047 - void radeon_atombios_get_power_modes(struct radeon_device *rdev);
1048 -+int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
1049 -+ u8 clock_type,
1050 -+ u32 clock,
1051 -+ bool strobe_mode,
1052 -+ struct atom_clock_dividers *dividers);
1053 - void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
1054 - void rs690_pm_info(struct radeon_device *rdev);
1055 - extern int rv6xx_get_temp(struct radeon_device *rdev);
1056 -@@ -357,8 +366,9 @@
1057 - struct ttm_validate_buffer tv;
1058 - struct radeon_bo *bo;
1059 - uint64_t gpu_offset;
1060 -- unsigned rdomain;
1061 -- unsigned wdomain;
1062 -+ bool written;
1063 -+ unsigned domain;
1064 -+ unsigned alt_domain;
1065 - u32 tiling_flags;
1066 - };
1067 -
1068 -@@ -918,6 +928,7 @@
1069 - #define R600_WB_DMA_RPTR_OFFSET 1792
1070 - #define R600_WB_IH_WPTR_OFFSET 2048
1071 - #define CAYMAN_WB_DMA1_RPTR_OFFSET 2304
1072 -+#define R600_WB_UVD_RPTR_OFFSET 2560
1073 - #define R600_WB_EVENT_OFFSET 3072
1074 -
1075 - /**
1076 -@@ -1118,6 +1129,35 @@
1077 - int radeon_pm_get_type_index(struct radeon_device *rdev,
1078 - enum radeon_pm_state_type ps_type,
1079 - int instance);
1080 -+/*
1081 -+ * UVD
1082 -+ */
1083 -+#define RADEON_MAX_UVD_HANDLES 10
1084 -+#define RADEON_UVD_STACK_SIZE (1024*1024)
1085 -+#define RADEON_UVD_HEAP_SIZE (1024*1024)
1086 -+
1087 -+struct radeon_uvd {
1088 -+ struct radeon_bo *vcpu_bo;
1089 -+ void *cpu_addr;
1090 -+ uint64_t gpu_addr;
1091 -+ atomic_t handles[RADEON_MAX_UVD_HANDLES];
1092 -+ struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
1093 -+ struct delayed_work idle_work;
1094 -+};
1095 -+
1096 -+int radeon_uvd_init(struct radeon_device *rdev);
1097 -+void radeon_uvd_fini(struct radeon_device *rdev);
1098 -+int radeon_uvd_suspend(struct radeon_device *rdev);
1099 -+int radeon_uvd_resume(struct radeon_device *rdev);
1100 -+int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring,
1101 -+ uint32_t handle, struct radeon_fence **fence);
1102 -+int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring,
1103 -+ uint32_t handle, struct radeon_fence **fence);
1104 -+void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo);
1105 -+void radeon_uvd_free_handles(struct radeon_device *rdev,
1106 -+ struct drm_file *filp);
1107 -+int radeon_uvd_cs_parse(struct radeon_cs_parser *parser);
1108 -+void radeon_uvd_note_usage(struct radeon_device *rdev);
1109 -
1110 - struct r600_audio {
1111 - int channels;
1112 -@@ -1281,6 +1321,7 @@
1113 - int (*get_pcie_lanes)(struct radeon_device *rdev);
1114 - void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
1115 - void (*set_clock_gating)(struct radeon_device *rdev, int enable);
1116 -+ int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 dclk);
1117 - } pm;
1118 - /* pageflipping */
1119 - struct {
1120 -@@ -1608,6 +1649,7 @@
1121 - struct radeon_asic *asic;
1122 - struct radeon_gem gem;
1123 - struct radeon_pm pm;
1124 -+ struct radeon_uvd uvd;
1125 - uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
1126 - struct radeon_wb wb;
1127 - struct radeon_dummy_page dummy_page;
1128 -@@ -1615,12 +1657,14 @@
1129 - bool suspend;
1130 - bool need_dma32;
1131 - bool accel_working;
1132 -+ bool fastfb_working; /* IGP feature*/
1133 - struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
1134 - const struct firmware *me_fw; /* all family ME firmware */
1135 - const struct firmware *pfp_fw; /* r6/700 PFP firmware */
1136 - const struct firmware *rlc_fw; /* r6/700 RLC firmware */
1137 - const struct firmware *mc_fw; /* NI MC firmware */
1138 - const struct firmware *ce_fw; /* SI CE firmware */
1139 -+ const struct firmware *uvd_fw; /* UVD firmware */
1140 - struct r600_blit r600_blit;
1141 - struct r600_vram_scratch vram_scratch;
1142 - int msi_enabled; /* msi enabled */
1143 -@@ -1845,6 +1889,7 @@
1144 - #define radeon_get_pcie_lanes(rdev) (rdev)->asic->pm.get_pcie_lanes((rdev))
1145 - #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), (l))
1146 - #define radeon_set_clock_gating(rdev, e) (rdev)->asic->pm.set_clock_gating((rdev), (e))
1147 -+#define radeon_set_uvd_clocks(rdev, v, d) (rdev)->asic->pm.set_uvd_clocks((rdev), (v), (d))
1148 - #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s)))
1149 - #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->surface.clear_reg((rdev), (r)))
1150 - #define radeon_bandwidth_update(rdev) (rdev)->asic->display.bandwidth_update((rdev))
1151 -diff -urN a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
1152 ---- a/drivers/gpu/drm/radeon/radeon_asic.c 2013-05-09 22:13:14.643851250 +0200
1153 -+++ b/drivers/gpu/drm/radeon/radeon_asic.c 2013-05-09 22:14:57.203842167 +0200
1154 -@@ -1130,6 +1130,15 @@
1155 - .ring_test = &r600_dma_ring_test,
1156 - .ib_test = &r600_dma_ib_test,
1157 - .is_lockup = &r600_dma_is_lockup,
1158 -+ },
1159 -+ [R600_RING_TYPE_UVD_INDEX] = {
1160 -+ .ib_execute = &r600_uvd_ib_execute,
1161 -+ .emit_fence = &r600_uvd_fence_emit,
1162 -+ .emit_semaphore = &r600_uvd_semaphore_emit,
1163 -+ .cs_parse = &radeon_uvd_cs_parse,
1164 -+ .ring_test = &r600_uvd_ring_test,
1165 -+ .ib_test = &r600_uvd_ib_test,
1166 -+ .is_lockup = &radeon_ring_test_lockup,
1167 - }
1168 - },
1169 - .irq = {
1170 -@@ -1174,6 +1183,7 @@
1171 - .get_pcie_lanes = &r600_get_pcie_lanes,
1172 - .set_pcie_lanes = &r600_set_pcie_lanes,
1173 - .set_clock_gating = &radeon_atom_set_clock_gating,
1174 -+ .set_uvd_clocks = &rv770_set_uvd_clocks,
1175 - },
1176 - .pflip = {
1177 - .pre_page_flip = &rs600_pre_page_flip,
1178 -@@ -1216,6 +1226,15 @@
1179 - .ring_test = &r600_dma_ring_test,
1180 - .ib_test = &r600_dma_ib_test,
1181 - .is_lockup = &evergreen_dma_is_lockup,
1182 -+ },
1183 -+ [R600_RING_TYPE_UVD_INDEX] = {
1184 -+ .ib_execute = &r600_uvd_ib_execute,
1185 -+ .emit_fence = &r600_uvd_fence_emit,
1186 -+ .emit_semaphore = &r600_uvd_semaphore_emit,
1187 -+ .cs_parse = &radeon_uvd_cs_parse,
1188 -+ .ring_test = &r600_uvd_ring_test,
1189 -+ .ib_test = &r600_uvd_ib_test,
1190 -+ .is_lockup = &radeon_ring_test_lockup,
1191 - }
1192 - },
1193 - .irq = {
1194 -@@ -1260,6 +1279,7 @@
1195 - .get_pcie_lanes = &r600_get_pcie_lanes,
1196 - .set_pcie_lanes = &r600_set_pcie_lanes,
1197 - .set_clock_gating = NULL,
1198 -+ .set_uvd_clocks = &evergreen_set_uvd_clocks,
1199 - },
1200 - .pflip = {
1201 - .pre_page_flip = &evergreen_pre_page_flip,
1202 -@@ -1302,6 +1322,15 @@
1203 - .ring_test = &r600_dma_ring_test,
1204 - .ib_test = &r600_dma_ib_test,
1205 - .is_lockup = &evergreen_dma_is_lockup,
1206 -+ },
1207 -+ [R600_RING_TYPE_UVD_INDEX] = {
1208 -+ .ib_execute = &r600_uvd_ib_execute,
1209 -+ .emit_fence = &r600_uvd_fence_emit,
1210 -+ .emit_semaphore = &r600_uvd_semaphore_emit,
1211 -+ .cs_parse = &radeon_uvd_cs_parse,
1212 -+ .ring_test = &r600_uvd_ring_test,
1213 -+ .ib_test = &r600_uvd_ib_test,
1214 -+ .is_lockup = &radeon_ring_test_lockup,
1215 - }
1216 - },
1217 - .irq = {
1218 -@@ -1346,6 +1375,7 @@
1219 - .get_pcie_lanes = NULL,
1220 - .set_pcie_lanes = NULL,
1221 - .set_clock_gating = NULL,
1222 -+ .set_uvd_clocks = &sumo_set_uvd_clocks,
1223 - },
1224 - .pflip = {
1225 - .pre_page_flip = &evergreen_pre_page_flip,
1226 -@@ -1388,6 +1418,15 @@
1227 - .ring_test = &r600_dma_ring_test,
1228 - .ib_test = &r600_dma_ib_test,
1229 - .is_lockup = &evergreen_dma_is_lockup,
1230 -+ },
1231 -+ [R600_RING_TYPE_UVD_INDEX] = {
1232 -+ .ib_execute = &r600_uvd_ib_execute,
1233 -+ .emit_fence = &r600_uvd_fence_emit,
1234 -+ .emit_semaphore = &r600_uvd_semaphore_emit,
1235 -+ .cs_parse = &radeon_uvd_cs_parse,
1236 -+ .ring_test = &r600_uvd_ring_test,
1237 -+ .ib_test = &r600_uvd_ib_test,
1238 -+ .is_lockup = &radeon_ring_test_lockup,
1239 - }
1240 - },
1241 - .irq = {
1242 -@@ -1432,6 +1471,7 @@
1243 - .get_pcie_lanes = NULL,
1244 - .set_pcie_lanes = NULL,
1245 - .set_clock_gating = NULL,
1246 -+ .set_uvd_clocks = &evergreen_set_uvd_clocks,
1247 - },
1248 - .pflip = {
1249 - .pre_page_flip = &evergreen_pre_page_flip,
1250 -@@ -1517,6 +1557,15 @@
1251 - .ib_test = &r600_dma_ib_test,
1252 - .is_lockup = &cayman_dma_is_lockup,
1253 - .vm_flush = &cayman_dma_vm_flush,
1254 -+ },
1255 -+ [R600_RING_TYPE_UVD_INDEX] = {
1256 -+ .ib_execute = &r600_uvd_ib_execute,
1257 -+ .emit_fence = &r600_uvd_fence_emit,
1258 -+ .emit_semaphore = &cayman_uvd_semaphore_emit,
1259 -+ .cs_parse = &radeon_uvd_cs_parse,
1260 -+ .ring_test = &r600_uvd_ring_test,
1261 -+ .ib_test = &r600_uvd_ib_test,
1262 -+ .is_lockup = &radeon_ring_test_lockup,
1263 - }
1264 - },
1265 - .irq = {
1266 -@@ -1561,6 +1610,7 @@
1267 - .get_pcie_lanes = NULL,
1268 - .set_pcie_lanes = NULL,
1269 - .set_clock_gating = NULL,
1270 -+ .set_uvd_clocks = &evergreen_set_uvd_clocks,
1271 - },
1272 - .pflip = {
1273 - .pre_page_flip = &evergreen_pre_page_flip,
1274 -@@ -1646,6 +1696,15 @@
1275 - .ib_test = &r600_dma_ib_test,
1276 - .is_lockup = &cayman_dma_is_lockup,
1277 - .vm_flush = &cayman_dma_vm_flush,
1278 -+ },
1279 -+ [R600_RING_TYPE_UVD_INDEX] = {
1280 -+ .ib_execute = &r600_uvd_ib_execute,
1281 -+ .emit_fence = &r600_uvd_fence_emit,
1282 -+ .emit_semaphore = &cayman_uvd_semaphore_emit,
1283 -+ .cs_parse = &radeon_uvd_cs_parse,
1284 -+ .ring_test = &r600_uvd_ring_test,
1285 -+ .ib_test = &r600_uvd_ib_test,
1286 -+ .is_lockup = &radeon_ring_test_lockup,
1287 - }
1288 - },
1289 - .irq = {
1290 -@@ -1690,6 +1749,7 @@
1291 - .get_pcie_lanes = NULL,
1292 - .set_pcie_lanes = NULL,
1293 - .set_clock_gating = NULL,
1294 -+ .set_uvd_clocks = &sumo_set_uvd_clocks,
1295 - },
1296 - .pflip = {
1297 - .pre_page_flip = &evergreen_pre_page_flip,
1298 -@@ -1775,6 +1835,15 @@
1299 - .ib_test = &r600_dma_ib_test,
1300 - .is_lockup = &si_dma_is_lockup,
1301 - .vm_flush = &si_dma_vm_flush,
1302 -+ },
1303 -+ [R600_RING_TYPE_UVD_INDEX] = {
1304 -+ .ib_execute = &r600_uvd_ib_execute,
1305 -+ .emit_fence = &r600_uvd_fence_emit,
1306 -+ .emit_semaphore = &cayman_uvd_semaphore_emit,
1307 -+ .cs_parse = &radeon_uvd_cs_parse,
1308 -+ .ring_test = &r600_uvd_ring_test,
1309 -+ .ib_test = &r600_uvd_ib_test,
1310 -+ .is_lockup = &radeon_ring_test_lockup,
1311 - }
1312 - },
1313 - .irq = {
1314 -@@ -1819,6 +1888,7 @@
1315 - .get_pcie_lanes = NULL,
1316 - .set_pcie_lanes = NULL,
1317 - .set_clock_gating = NULL,
1318 -+ .set_uvd_clocks = &si_set_uvd_clocks,
1319 - },
1320 - .pflip = {
1321 - .pre_page_flip = &evergreen_pre_page_flip,
1322 -diff -urN a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
1323 ---- a/drivers/gpu/drm/radeon/radeon_asic.h 2013-05-09 22:13:14.643851250 +0200
1324 -+++ b/drivers/gpu/drm/radeon/radeon_asic.h 2013-05-09 22:14:57.203842167 +0200
1325 -@@ -330,6 +330,7 @@
1326 - void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
1327 - int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
1328 - int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
1329 -+int r600_uvd_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
1330 - int r600_copy_blit(struct radeon_device *rdev,
1331 - uint64_t src_offset, uint64_t dst_offset,
1332 - unsigned num_gpu_pages, struct radeon_fence **fence);
1333 -@@ -392,6 +393,19 @@
1334 - u32 r600_get_xclk(struct radeon_device *rdev);
1335 - uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
1336 -
1337 -+/* uvd */
1338 -+int r600_uvd_init(struct radeon_device *rdev);
1339 -+int r600_uvd_rbc_start(struct radeon_device *rdev);
1340 -+void r600_uvd_rbc_stop(struct radeon_device *rdev);
1341 -+int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
1342 -+void r600_uvd_fence_emit(struct radeon_device *rdev,
1343 -+ struct radeon_fence *fence);
1344 -+void r600_uvd_semaphore_emit(struct radeon_device *rdev,
1345 -+ struct radeon_ring *ring,
1346 -+ struct radeon_semaphore *semaphore,
1347 -+ bool emit_wait);
1348 -+void r600_uvd_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
1349 -+
1350 - /*
1351 - * rv770,rv730,rv710,rv740
1352 - */
1353 -@@ -409,6 +423,8 @@
1354 - unsigned num_gpu_pages,
1355 - struct radeon_fence **fence);
1356 - u32 rv770_get_xclk(struct radeon_device *rdev);
1357 -+int rv770_uvd_resume(struct radeon_device *rdev);
1358 -+int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
1359 -
1360 - /*
1361 - * evergreen
1362 -@@ -444,6 +460,8 @@
1363 - extern void evergreen_pm_finish(struct radeon_device *rdev);
1364 - extern void sumo_pm_init_profile(struct radeon_device *rdev);
1365 - extern void btc_pm_init_profile(struct radeon_device *rdev);
1366 -+int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
1367 -+int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
1368 - extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
1369 - extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
1370 - extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
1371 -@@ -465,6 +483,10 @@
1372 - */
1373 - void cayman_fence_ring_emit(struct radeon_device *rdev,
1374 - struct radeon_fence *fence);
1375 -+void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
1376 -+ struct radeon_ring *ring,
1377 -+ struct radeon_semaphore *semaphore,
1378 -+ bool emit_wait);
1379 - void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev);
1380 - int cayman_init(struct radeon_device *rdev);
1381 - void cayman_fini(struct radeon_device *rdev);
1382 -@@ -524,5 +546,6 @@
1383 - void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
1384 - u32 si_get_xclk(struct radeon_device *rdev);
1385 - uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev);
1386 -+int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
1387 -
1388 - #endif
1389 -diff -urN a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
1390 ---- a/drivers/gpu/drm/radeon/radeon_atombios.c 2013-05-09 22:13:14.647184583 +0200
1391 -+++ b/drivers/gpu/drm/radeon/radeon_atombios.c 2013-05-09 22:14:57.230508831 +0200
1392 -@@ -2654,6 +2654,111 @@
1393 - rdev->pm.current_vddc = 0;
1394 - }
1395 -
1396 -+union get_clock_dividers {
1397 -+ struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1;
1398 -+ struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2;
1399 -+ struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
1400 -+ struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
1401 -+ struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
1402 -+};
1403 -+
1404 -+int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
1405 -+ u8 clock_type,
1406 -+ u32 clock,
1407 -+ bool strobe_mode,
1408 -+ struct atom_clock_dividers *dividers)
1409 -+{
1410 -+ union get_clock_dividers args;
1411 -+ int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL);
1412 -+ u8 frev, crev;
1413 -+
1414 -+ memset(&args, 0, sizeof(args));
1415 -+ memset(dividers, 0, sizeof(struct atom_clock_dividers));
1416 -+
1417 -+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
1418 -+ return -EINVAL;
1419 -+
1420 -+ switch (crev) {
1421 -+ case 1:
1422 -+ /* r4xx, r5xx */
1423 -+ args.v1.ucAction = clock_type;
1424 -+ args.v1.ulClock = cpu_to_le32(clock); /* 10 khz */
1425 -+
1426 -+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1427 -+
1428 -+ dividers->post_div = args.v1.ucPostDiv;
1429 -+ dividers->fb_div = args.v1.ucFbDiv;
1430 -+ dividers->enable_post_div = true;
1431 -+ break;
1432 -+ case 2:
1433 -+ case 3:
1434 -+ /* r6xx, r7xx, evergreen, ni */
1435 -+ if (rdev->family <= CHIP_RV770) {
1436 -+ args.v2.ucAction = clock_type;
1437 -+ args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */
1438 -+
1439 -+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1440 -+
1441 -+ dividers->post_div = args.v2.ucPostDiv;
1442 -+ dividers->fb_div = le16_to_cpu(args.v2.usFbDiv);
1443 -+ dividers->ref_div = args.v2.ucAction;
1444 -+ if (rdev->family == CHIP_RV770) {
1445 -+ dividers->enable_post_div = (le32_to_cpu(args.v2.ulClock) & (1 << 24)) ?
1446 -+ true : false;
1447 -+ dividers->vco_mode = (le32_to_cpu(args.v2.ulClock) & (1 << 25)) ? 1 : 0;
1448 -+ } else
1449 -+ dividers->enable_post_div = (dividers->fb_div & 1) ? true : false;
1450 -+ } else {
1451 -+ if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
1452 -+ args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
1453 -+
1454 -+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1455 -+
1456 -+ dividers->post_div = args.v3.ucPostDiv;
1457 -+ dividers->enable_post_div = (args.v3.ucCntlFlag &
1458 -+ ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
1459 -+ dividers->enable_dithen = (args.v3.ucCntlFlag &
1460 -+ ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
1461 -+ dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
1462 -+ dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
1463 -+ dividers->ref_div = args.v3.ucRefDiv;
1464 -+ dividers->vco_mode = (args.v3.ucCntlFlag &
1465 -+ ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
1466 -+ } else {
1467 -+ args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
1468 -+ if (strobe_mode)
1469 -+ args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
1470 -+
1471 -+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1472 -+
1473 -+ dividers->post_div = args.v5.ucPostDiv;
1474 -+ dividers->enable_post_div = (args.v5.ucCntlFlag &
1475 -+ ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
1476 -+ dividers->enable_dithen = (args.v5.ucCntlFlag &
1477 -+ ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
1478 -+ dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
1479 -+ dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
1480 -+ dividers->ref_div = args.v5.ucRefDiv;
1481 -+ dividers->vco_mode = (args.v5.ucCntlFlag &
1482 -+ ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
1483 -+ }
1484 -+ }
1485 -+ break;
1486 -+ case 4:
1487 -+ /* fusion */
1488 -+ args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
1489 -+
1490 -+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1491 -+
1492 -+ dividers->post_div = args.v4.ucPostDiv;
1493 -+ dividers->real_clock = le32_to_cpu(args.v4.ulClock);
1494 -+ break;
1495 -+ default:
1496 -+ return -EINVAL;
1497 -+ }
1498 -+ return 0;
1499 -+}
1500 -+
1501 - void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
1502 - {
1503 - DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
1504 -diff -urN a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
1505 ---- a/drivers/gpu/drm/radeon/radeon_cs.c 2013-05-09 22:13:14.647184583 +0200
1506 -+++ b/drivers/gpu/drm/radeon/radeon_cs.c 2013-05-09 22:14:57.223842165 +0200
1507 -@@ -63,30 +63,50 @@
1508 - break;
1509 - }
1510 - }
1511 -- if (!duplicate) {
1512 -- p->relocs[i].gobj = drm_gem_object_lookup(ddev,
1513 -- p->filp,
1514 -- r->handle);
1515 -- if (p->relocs[i].gobj == NULL) {
1516 -- DRM_ERROR("gem object lookup failed 0x%x\n",
1517 -- r->handle);
1518 -- return -ENOENT;
1519 -- }
1520 -- p->relocs_ptr[i] = &p->relocs[i];
1521 -- p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj);
1522 -- p->relocs[i].lobj.bo = p->relocs[i].robj;
1523 -- p->relocs[i].lobj.wdomain = r->write_domain;
1524 -- p->relocs[i].lobj.rdomain = r->read_domains;
1525 -- p->relocs[i].lobj.tv.bo = &p->relocs[i].robj->tbo;
1526 -- p->relocs[i].handle = r->handle;
1527 -- p->relocs[i].flags = r->flags;
1528 -- radeon_bo_list_add_object(&p->relocs[i].lobj,
1529 -- &p->validated);
1530 --
1531 -- } else
1532 -+ if (duplicate) {
1533 - p->relocs[i].handle = 0;
1534 -+ continue;
1535 -+ }
1536 -+
1537 -+ p->relocs[i].gobj = drm_gem_object_lookup(ddev, p->filp,
1538 -+ r->handle);
1539 -+ if (p->relocs[i].gobj == NULL) {
1540 -+ DRM_ERROR("gem object lookup failed 0x%x\n",
1541 -+ r->handle);
1542 -+ return -ENOENT;
1543 -+ }
1544 -+ p->relocs_ptr[i] = &p->relocs[i];
1545 -+ p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj);
1546 -+ p->relocs[i].lobj.bo = p->relocs[i].robj;
1547 -+ p->relocs[i].lobj.written = !!r->write_domain;
1548 -+
1549 -+ /* the first reloc of an UVD job is the
1550 -+ msg and that must be in VRAM */
1551 -+ if (p->ring == R600_RING_TYPE_UVD_INDEX && i == 0) {
1552 -+ /* TODO: is this still needed for NI+ ? */
1553 -+ p->relocs[i].lobj.domain =
1554 -+ RADEON_GEM_DOMAIN_VRAM;
1555 -+
1556 -+ p->relocs[i].lobj.alt_domain =
1557 -+ RADEON_GEM_DOMAIN_VRAM;
1558 -+
1559 -+ } else {
1560 -+ uint32_t domain = r->write_domain ?
1561 -+ r->write_domain : r->read_domains;
1562 -+
1563 -+ p->relocs[i].lobj.domain = domain;
1564 -+ if (domain == RADEON_GEM_DOMAIN_VRAM)
1565 -+ domain |= RADEON_GEM_DOMAIN_GTT;
1566 -+ p->relocs[i].lobj.alt_domain = domain;
1567 -+ }
1568 -+
1569 -+ p->relocs[i].lobj.tv.bo = &p->relocs[i].robj->tbo;
1570 -+ p->relocs[i].handle = r->handle;
1571 -+
1572 -+ radeon_bo_list_add_object(&p->relocs[i].lobj,
1573 -+ &p->validated);
1574 - }
1575 -- return radeon_bo_list_validate(&p->validated);
1576 -+ return radeon_bo_list_validate(&p->validated, p->ring);
1577 - }
1578 -
1579 - static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority)
1580 -@@ -121,6 +141,9 @@
1581 - return -EINVAL;
1582 - }
1583 - break;
1584 -+ case RADEON_CS_RING_UVD:
1585 -+ p->ring = R600_RING_TYPE_UVD_INDEX;
1586 -+ break;
1587 - }
1588 - return 0;
1589 - }
1590 -@@ -241,15 +264,15 @@
1591 - return -EINVAL;
1592 - }
1593 -
1594 -- /* we only support VM on SI+ */
1595 -- if ((p->rdev->family >= CHIP_TAHITI) &&
1596 -- ((p->cs_flags & RADEON_CS_USE_VM) == 0)) {
1597 -- DRM_ERROR("VM required on SI+!\n");
1598 -+ if (radeon_cs_get_ring(p, ring, priority))
1599 - return -EINVAL;
1600 -- }
1601 -
1602 -- if (radeon_cs_get_ring(p, ring, priority))
1603 -+ /* we only support VM on some SI+ rings */
1604 -+ if ((p->rdev->asic->ring[p->ring].cs_parse == NULL) &&
1605 -+ ((p->cs_flags & RADEON_CS_USE_VM) == 0)) {
1606 -+ DRM_ERROR("Ring %d requires VM!\n", p->ring);
1607 - return -EINVAL;
1608 -+ }
1609 - }
1610 -
1611 - /* deal with non-vm */
1612 -@@ -526,6 +549,10 @@
1613 - r = radeon_cs_handle_lockup(rdev, r);
1614 - return r;
1615 - }
1616 -+
1617 -+ if (parser.ring == R600_RING_TYPE_UVD_INDEX)
1618 -+ radeon_uvd_note_usage(rdev);
1619 -+
1620 - r = radeon_cs_ib_chunk(rdev, &parser);
1621 - if (r) {
1622 - goto out;
1623 -diff -urN a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
1624 ---- a/drivers/gpu/drm/radeon/radeon_drv.c 2013-05-09 22:13:14.647184583 +0200
1625 -+++ b/drivers/gpu/drm/radeon/radeon_drv.c 2013-05-09 22:14:57.210508833 +0200
1626 -@@ -71,9 +71,11 @@
1627 - * 2.28.0 - r600-eg: Add MEM_WRITE packet support
1628 - * 2.29.0 - R500 FP16 color clear registers
1629 - * 2.30.0 - fix for FMASK texturing
1630 -+ * 2.31.0 - Add fastfb support for rs690
1631 -+ * 2.32.0 - new info request for rings working
1632 - */
1633 - #define KMS_DRIVER_MAJOR 2
1634 --#define KMS_DRIVER_MINOR 30
1635 -+#define KMS_DRIVER_MINOR 32
1636 - #define KMS_DRIVER_PATCHLEVEL 0
1637 - int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
1638 - int radeon_driver_unload_kms(struct drm_device *dev);
1639 -@@ -160,6 +162,7 @@
1640 - int radeon_pcie_gen2 = -1;
1641 - int radeon_msi = -1;
1642 - int radeon_lockup_timeout = 10000;
1643 -+int radeon_fastfb = 0;
1644 -
1645 - MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
1646 - module_param_named(no_wb, radeon_no_wb, int, 0444);
1647 -@@ -212,6 +215,9 @@
1648 - MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 10000 = 10 seconds, 0 = disable)");
1649 - module_param_named(lockup_timeout, radeon_lockup_timeout, int, 0444);
1650 -
1651 -+MODULE_PARM_DESC(fastfb, "Direct FB access for IGP chips (0 = disable, 1 = enable)");
1652 -+module_param_named(fastfb, radeon_fastfb, int, 0444);
1653 -+
1654 - static struct pci_device_id pciidlist[] = {
1655 - radeon_PCI_IDS
1656 - };
1657 -diff -urN a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
1658 ---- a/drivers/gpu/drm/radeon/radeon_fence.c 2013-05-09 22:13:14.647184583 +0200
1659 -+++ b/drivers/gpu/drm/radeon/radeon_fence.c 2013-05-09 22:14:57.213842166 +0200
1660 -@@ -31,9 +31,9 @@
1661 - #include <linux/seq_file.h>
1662 - #include <linux/atomic.h>
1663 - #include <linux/wait.h>
1664 --#include <linux/list.h>
1665 - #include <linux/kref.h>
1666 - #include <linux/slab.h>
1667 -+#include <linux/firmware.h>
1668 - #include <drm/drmP.h>
1669 - #include "radeon_reg.h"
1670 - #include "radeon.h"
1671 -@@ -767,8 +767,20 @@
1672 -
1673 - radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
1674 - if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) {
1675 -- rdev->fence_drv[ring].scratch_reg = 0;
1676 -- index = R600_WB_EVENT_OFFSET + ring * 4;
1677 -+ if (ring != R600_RING_TYPE_UVD_INDEX) {
1678 -+ rdev->fence_drv[ring].scratch_reg = 0;
1679 -+ index = R600_WB_EVENT_OFFSET + ring * 4;
1680 -+ rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
1681 -+ rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr +
1682 -+ index;
1683 -+
1684 -+ } else {
1685 -+ /* put fence directly behind firmware */
1686 -+ index = ALIGN(rdev->uvd_fw->size, 8);
1687 -+ rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
1688 -+ rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
1689 -+ }
1690 -+
1691 - } else {
1692 - r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg);
1693 - if (r) {
1694 -@@ -778,9 +790,9 @@
1695 - index = RADEON_WB_SCRATCH_OFFSET +
1696 - rdev->fence_drv[ring].scratch_reg -
1697 - rdev->scratch.reg_base;
1698 -+ rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
1699 -+ rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
1700 - }
1701 -- rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4];
1702 -- rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index;
1703 - radeon_fence_write(rdev, atomic64_read(&rdev->fence_drv[ring].last_seq), ring);
1704 - rdev->fence_drv[ring].initialized = true;
1705 - dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n",
1706 -diff -urN a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
1707 ---- a/drivers/gpu/drm/radeon/radeon_kms.c 2013-05-09 22:13:14.647184583 +0200
1708 -+++ b/drivers/gpu/drm/radeon/radeon_kms.c 2013-05-09 22:14:57.210508833 +0200
1709 -@@ -376,6 +376,26 @@
1710 - else
1711 - return -EINVAL;
1712 - break;
1713 -+ case RADEON_INFO_FASTFB_WORKING:
1714 -+ value = rdev->fastfb_working;
1715 -+ break;
1716 -+ case RADEON_INFO_RING_WORKING:
1717 -+ switch (value) {
1718 -+ case RADEON_CS_RING_GFX:
1719 -+ case RADEON_CS_RING_COMPUTE:
1720 -+ value = rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready;
1721 -+ break;
1722 -+ case RADEON_CS_RING_DMA:
1723 -+ value = rdev->ring[R600_RING_TYPE_DMA_INDEX].ready;
1724 -+ value |= rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready;
1725 -+ break;
1726 -+ case RADEON_CS_RING_UVD:
1727 -+ value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready;
1728 -+ break;
1729 -+ default:
1730 -+ return -EINVAL;
1731 -+ }
1732 -+ break;
1733 - default:
1734 - DRM_DEBUG_KMS("Invalid request %d\n", info->request);
1735 - return -EINVAL;
1736 -@@ -513,6 +533,7 @@
1737 - rdev->hyperz_filp = NULL;
1738 - if (rdev->cmask_filp == file_priv)
1739 - rdev->cmask_filp = NULL;
1740 -+ radeon_uvd_free_handles(rdev, file_priv);
1741 - }
1742 -
1743 - /*
1744 -diff -urN a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
1745 ---- a/drivers/gpu/drm/radeon/radeon_mode.h 2013-05-09 22:13:14.647184583 +0200
1746 -+++ b/drivers/gpu/drm/radeon/radeon_mode.h 2013-05-09 22:14:57.183842168 +0200
1747 -@@ -492,6 +492,29 @@
1748 - #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \
1749 - ((em) == ATOM_ENCODER_MODE_DP_MST))
1750 -
1751 -+struct atom_clock_dividers {
1752 -+ u32 post_div;
1753 -+ union {
1754 -+ struct {
1755 -+#ifdef __BIG_ENDIAN
1756 -+ u32 reserved : 6;
1757 -+ u32 whole_fb_div : 12;
1758 -+ u32 frac_fb_div : 14;
1759 -+#else
1760 -+ u32 frac_fb_div : 14;
1761 -+ u32 whole_fb_div : 12;
1762 -+ u32 reserved : 6;
1763 -+#endif
1764 -+ };
1765 -+ u32 fb_div;
1766 -+ };
1767 -+ u32 ref_div;
1768 -+ bool enable_post_div;
1769 -+ bool enable_dithen;
1770 -+ u32 vco_mode;
1771 -+ u32 real_clock;
1772 -+};
1773 -+
1774 - extern enum radeon_tv_std
1775 - radeon_combios_get_tv_info(struct radeon_device *rdev);
1776 - extern enum radeon_tv_std
1777 -diff -urN a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
1778 ---- a/drivers/gpu/drm/radeon/radeon_object.c 2013-05-09 22:13:14.647184583 +0200
1779 -+++ b/drivers/gpu/drm/radeon/radeon_object.c 2013-05-09 22:14:57.180508835 +0200
1780 -@@ -321,8 +321,10 @@
1781 - int radeon_bo_init(struct radeon_device *rdev)
1782 - {
1783 - /* Add an MTRR for the VRAM */
1784 -- rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
1785 -+ if (!rdev->fastfb_working) {
1786 -+ rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
1787 - MTRR_TYPE_WRCOMB, 1);
1788 -+ }
1789 - DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
1790 - rdev->mc.mc_vram_size >> 20,
1791 - (unsigned long long)rdev->mc.aper_size >> 20);
1792 -@@ -339,14 +341,14 @@
1793 - void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
1794 - struct list_head *head)
1795 - {
1796 -- if (lobj->wdomain) {
1797 -+ if (lobj->written) {
1798 - list_add(&lobj->tv.head, head);
1799 - } else {
1800 - list_add_tail(&lobj->tv.head, head);
1801 - }
1802 - }
1803 -
1804 --int radeon_bo_list_validate(struct list_head *head)
1805 -+int radeon_bo_list_validate(struct list_head *head, int ring)
1806 - {
1807 - struct radeon_bo_list *lobj;
1808 - struct radeon_bo *bo;
1809 -@@ -360,15 +362,17 @@
1810 - list_for_each_entry(lobj, head, tv.head) {
1811 - bo = lobj->bo;
1812 - if (!bo->pin_count) {
1813 -- domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
1814 -+ domain = lobj->domain;
1815 -
1816 - retry:
1817 - radeon_ttm_placement_from_domain(bo, domain);
1818 -+ if (ring == R600_RING_TYPE_UVD_INDEX)
1819 -+ radeon_uvd_force_into_uvd_segment(bo);
1820 - r = ttm_bo_validate(&bo->tbo, &bo->placement,
1821 - true, false);
1822 - if (unlikely(r)) {
1823 -- if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) {
1824 -- domain |= RADEON_GEM_DOMAIN_GTT;
1825 -+ if (r != -ERESTARTSYS && domain != lobj->alt_domain) {
1826 -+ domain = lobj->alt_domain;
1827 - goto retry;
1828 - }
1829 - return r;
1830 -diff -urN a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
1831 ---- a/drivers/gpu/drm/radeon/radeon_object.h 2013-05-09 22:13:14.647184583 +0200
1832 -+++ b/drivers/gpu/drm/radeon/radeon_object.h 2013-05-09 22:14:57.180508835 +0200
1833 -@@ -128,7 +128,7 @@
1834 - extern void radeon_bo_fini(struct radeon_device *rdev);
1835 - extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
1836 - struct list_head *head);
1837 --extern int radeon_bo_list_validate(struct list_head *head);
1838 -+extern int radeon_bo_list_validate(struct list_head *head, int ring);
1839 - extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
1840 - struct vm_area_struct *vma);
1841 - extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
1842 -diff -urN a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
1843 ---- a/drivers/gpu/drm/radeon/radeon_ring.c 2013-05-09 22:13:14.647184583 +0200
1844 -+++ b/drivers/gpu/drm/radeon/radeon_ring.c 2013-05-09 22:14:57.180508835 +0200
1845 -@@ -368,7 +368,7 @@
1846 - {
1847 - u32 rptr;
1848 -
1849 -- if (rdev->wb.enabled)
1850 -+ if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
1851 - rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
1852 - else
1853 - rptr = RREG32(ring->rptr_reg);
1854 -@@ -821,18 +821,20 @@
1855 - return 0;
1856 - }
1857 -
1858 --static int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX;
1859 --static int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX;
1860 --static int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
1861 --static int radeon_ring_type_dma1_index = R600_RING_TYPE_DMA_INDEX;
1862 --static int radeon_ring_type_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX;
1863 -+static int radeon_gfx_index = RADEON_RING_TYPE_GFX_INDEX;
1864 -+static int cayman_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX;
1865 -+static int cayman_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
1866 -+static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX;
1867 -+static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX;
1868 -+static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX;
1869 -
1870 - static struct drm_info_list radeon_debugfs_ring_info_list[] = {
1871 -- {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index},
1872 -- {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index},
1873 -- {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index},
1874 -- {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_ring_type_dma1_index},
1875 -- {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_ring_type_dma2_index},
1876 -+ {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index},
1877 -+ {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_cp1_index},
1878 -+ {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_cp2_index},
1879 -+ {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index},
1880 -+ {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index},
1881 -+ {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index},
1882 - };
1883 -
1884 - static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
1885 -diff -urN a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
1886 ---- a/drivers/gpu/drm/radeon/radeon_test.c 2013-05-09 22:13:14.647184583 +0200
1887 -+++ b/drivers/gpu/drm/radeon/radeon_test.c 2013-05-09 22:14:57.180508835 +0200
1888 -@@ -252,6 +252,36 @@
1889 - radeon_do_test_moves(rdev, RADEON_TEST_COPY_BLIT);
1890 - }
1891 -
1892 -+static int radeon_test_create_and_emit_fence(struct radeon_device *rdev,
1893 -+ struct radeon_ring *ring,
1894 -+ struct radeon_fence **fence)
1895 -+{
1896 -+ int r;
1897 -+
1898 -+ if (ring->idx == R600_RING_TYPE_UVD_INDEX) {
1899 -+ r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
1900 -+ if (r) {
1901 -+ DRM_ERROR("Failed to get dummy create msg\n");
1902 -+ return r;
1903 -+ }
1904 -+
1905 -+ r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, fence);
1906 -+ if (r) {
1907 -+ DRM_ERROR("Failed to get dummy destroy msg\n");
1908 -+ return r;
1909 -+ }
1910 -+ } else {
1911 -+ r = radeon_ring_lock(rdev, ring, 64);
1912 -+ if (r) {
1913 -+ DRM_ERROR("Failed to lock ring A %d\n", ring->idx);
1914 -+ return r;
1915 -+ }
1916 -+ radeon_fence_emit(rdev, fence, ring->idx);
1917 -+ radeon_ring_unlock_commit(rdev, ring);
1918 -+ }
1919 -+ return 0;
1920 -+}
1921 -+
1922 - void radeon_test_ring_sync(struct radeon_device *rdev,
1923 - struct radeon_ring *ringA,
1924 - struct radeon_ring *ringB)
1925 -@@ -272,21 +302,24 @@
1926 - goto out_cleanup;
1927 - }
1928 - radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
1929 -- r = radeon_fence_emit(rdev, &fence1, ringA->idx);
1930 -- if (r) {
1931 -- DRM_ERROR("Failed to emit fence 1\n");
1932 -- radeon_ring_unlock_undo(rdev, ringA);
1933 -+ radeon_ring_unlock_commit(rdev, ringA);
1934 -+
1935 -+ r = radeon_test_create_and_emit_fence(rdev, ringA, &fence1);
1936 -+ if (r)
1937 - goto out_cleanup;
1938 -- }
1939 -- radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
1940 -- r = radeon_fence_emit(rdev, &fence2, ringA->idx);
1941 -+
1942 -+ r = radeon_ring_lock(rdev, ringA, 64);
1943 - if (r) {
1944 -- DRM_ERROR("Failed to emit fence 2\n");
1945 -- radeon_ring_unlock_undo(rdev, ringA);
1946 -+ DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
1947 - goto out_cleanup;
1948 - }
1949 -+ radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
1950 - radeon_ring_unlock_commit(rdev, ringA);
1951 -
1952 -+ r = radeon_test_create_and_emit_fence(rdev, ringA, &fence2);
1953 -+ if (r)
1954 -+ goto out_cleanup;
1955 -+
1956 - mdelay(1000);
1957 -
1958 - if (radeon_fence_signaled(fence1)) {
1959 -@@ -364,27 +397,22 @@
1960 - goto out_cleanup;
1961 - }
1962 - radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
1963 -- r = radeon_fence_emit(rdev, &fenceA, ringA->idx);
1964 -- if (r) {
1965 -- DRM_ERROR("Failed to emit sync fence 1\n");
1966 -- radeon_ring_unlock_undo(rdev, ringA);
1967 -- goto out_cleanup;
1968 -- }
1969 - radeon_ring_unlock_commit(rdev, ringA);
1970 -
1971 -+ r = radeon_test_create_and_emit_fence(rdev, ringA, &fenceA);
1972 -+ if (r)
1973 -+ goto out_cleanup;
1974 -+
1975 - r = radeon_ring_lock(rdev, ringB, 64);
1976 - if (r) {
1977 - DRM_ERROR("Failed to lock ring B %d\n", ringB->idx);
1978 - goto out_cleanup;
1979 - }
1980 - radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore);
1981 -- r = radeon_fence_emit(rdev, &fenceB, ringB->idx);
1982 -- if (r) {
1983 -- DRM_ERROR("Failed to create sync fence 2\n");
1984 -- radeon_ring_unlock_undo(rdev, ringB);
1985 -- goto out_cleanup;
1986 -- }
1987 - radeon_ring_unlock_commit(rdev, ringB);
1988 -+ r = radeon_test_create_and_emit_fence(rdev, ringB, &fenceB);
1989 -+ if (r)
1990 -+ goto out_cleanup;
1991 -
1992 - mdelay(1000);
1993 -
1994 -@@ -393,7 +421,7 @@
1995 - goto out_cleanup;
1996 - }
1997 - if (radeon_fence_signaled(fenceB)) {
1998 -- DRM_ERROR("Fence A signaled without waiting for semaphore.\n");
1999 -+ DRM_ERROR("Fence B signaled without waiting for semaphore.\n");
2000 - goto out_cleanup;
2001 - }
2002 -
2003 -diff -urN a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
2004 ---- a/drivers/gpu/drm/radeon/rs690.c 2013-05-09 22:13:14.647184583 +0200
2005 -+++ b/drivers/gpu/drm/radeon/rs690.c 2013-05-09 22:14:57.163842170 +0200
2006 -@@ -148,6 +148,8 @@
2007 - static void rs690_mc_init(struct radeon_device *rdev)
2008 - {
2009 - u64 base;
2010 -+ uint32_t h_addr, l_addr;
2011 -+ unsigned long long k8_addr;
2012 -
2013 - rs400_gart_adjust_size(rdev);
2014 - rdev->mc.vram_is_ddr = true;
2015 -@@ -160,6 +162,27 @@
2016 - base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
2017 - base = G_000100_MC_FB_START(base) << 16;
2018 - rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
2019 -+
2020 -+ /* Use K8 direct mapping for fast fb access. */
2021 -+ rdev->fastfb_working = false;
2022 -+ h_addr = G_00005F_K8_ADDR_EXT(RREG32_MC(R_00005F_MC_MISC_UMA_CNTL));
2023 -+ l_addr = RREG32_MC(R_00001E_K8_FB_LOCATION);
2024 -+ k8_addr = ((unsigned long long)h_addr) << 32 | l_addr;
2025 -+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
2026 -+ if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL)
2027 -+#endif
2028 -+ {
2029 -+ /* FastFB shall be used with UMA memory. Here it is simply disabled when sideport
2030 -+ * memory is present.
2031 -+ */
2032 -+ if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) {
2033 -+ DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n",
2034 -+ (unsigned long long)rdev->mc.aper_base, k8_addr);
2035 -+ rdev->mc.aper_base = (resource_size_t)k8_addr;
2036 -+ rdev->fastfb_working = true;
2037 -+ }
2038 -+ }
2039 -+
2040 - rs690_pm_info(rdev);
2041 - radeon_vram_location(rdev, &rdev->mc, base);
2042 - rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
2043 -diff -urN a/drivers/gpu/drm/radeon/rs690d.h b/drivers/gpu/drm/radeon/rs690d.h
2044 ---- a/drivers/gpu/drm/radeon/rs690d.h 2013-05-09 22:13:14.647184583 +0200
2045 -+++ b/drivers/gpu/drm/radeon/rs690d.h 2013-05-09 22:14:57.163842170 +0200
2046 -@@ -29,6 +29,9 @@
2047 - #define __RS690D_H__
2048 -
2049 - /* Registers */
2050 -+#define R_00001E_K8_FB_LOCATION 0x00001E
2051 -+#define R_00005F_MC_MISC_UMA_CNTL 0x00005F
2052 -+#define G_00005F_K8_ADDR_EXT(x) (((x) >> 0) & 0xFF)
2053 - #define R_000078_MC_INDEX 0x000078
2054 - #define S_000078_MC_IND_ADDR(x) (((x) & 0x1FF) << 0)
2055 - #define G_000078_MC_IND_ADDR(x) (((x) >> 0) & 0x1FF)
2056 -diff -urN a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
2057 ---- a/drivers/gpu/drm/radeon/rv770.c 2013-05-09 22:13:14.647184583 +0200
2058 -+++ b/drivers/gpu/drm/radeon/rv770.c 2013-05-09 22:14:57.217175499 +0200
2059 -@@ -42,6 +42,168 @@
2060 - static void rv770_gpu_init(struct radeon_device *rdev);
2061 - void rv770_fini(struct radeon_device *rdev);
2062 - static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
2063 -+int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
2064 -+
2065 -+static int rv770_uvd_calc_post_div(unsigned target_freq,
2066 -+ unsigned vco_freq,
2067 -+ unsigned *div)
2068 -+{
2069 -+ /* Fclk = Fvco / PDIV */
2070 -+ *div = vco_freq / target_freq;
2071 -+
2072 -+ /* we alway need a frequency less than or equal the target */
2073 -+ if ((vco_freq / *div) > target_freq)
2074 -+ *div += 1;
2075 -+
2076 -+ /* out of range ? */
2077 -+ if (*div > 30)
2078 -+ return -1; /* forget it */
2079 -+
2080 -+ *div -= 1;
2081 -+ return vco_freq / (*div + 1);
2082 -+}
2083 -+
2084 -+static int rv770_uvd_send_upll_ctlreq(struct radeon_device *rdev)
2085 -+{
2086 -+ unsigned i;
2087 -+
2088 -+ /* assert UPLL_CTLREQ */
2089 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
2090 -+
2091 -+ /* wait for CTLACK and CTLACK2 to get asserted */
2092 -+ for (i = 0; i < 100; ++i) {
2093 -+ uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
2094 -+ if ((RREG32(CG_UPLL_FUNC_CNTL) & mask) == mask)
2095 -+ break;
2096 -+ mdelay(10);
2097 -+ }
2098 -+ if (i == 100)
2099 -+ return -ETIMEDOUT;
2100 -+
2101 -+ /* deassert UPLL_CTLREQ */
2102 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
2103 -+
2104 -+ return 0;
2105 -+}
2106 -+
2107 -+int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
2108 -+{
2109 -+ /* start off with something large */
2110 -+ int optimal_diff_score = 0x7FFFFFF;
2111 -+ unsigned optimal_fb_div = 0, optimal_vclk_div = 0;
2112 -+ unsigned optimal_dclk_div = 0, optimal_vco_freq = 0;
2113 -+ unsigned vco_freq, vco_min = 50000, vco_max = 160000;
2114 -+ unsigned ref_freq = rdev->clock.spll.reference_freq;
2115 -+ int r;
2116 -+
2117 -+ /* RV740 uses evergreen uvd clk programming */
2118 -+ if (rdev->family == CHIP_RV740)
2119 -+ return evergreen_set_uvd_clocks(rdev, vclk, dclk);
2120 -+
2121 -+ /* bypass vclk and dclk with bclk */
2122 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
2123 -+ VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
2124 -+ ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
2125 -+
2126 -+ if (!vclk || !dclk) {
2127 -+ /* keep the Bypass mode, put PLL to sleep */
2128 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
2129 -+ return 0;
2130 -+ }
2131 -+
2132 -+ /* loop through vco from low to high */
2133 -+ vco_min = max(max(vco_min, vclk), dclk);
2134 -+ for (vco_freq = vco_min; vco_freq <= vco_max; vco_freq += 500) {
2135 -+ uint64_t fb_div = (uint64_t)vco_freq * 43663;
2136 -+ int calc_clk, diff_score, diff_vclk, diff_dclk;
2137 -+ unsigned vclk_div, dclk_div;
2138 -+
2139 -+ do_div(fb_div, ref_freq);
2140 -+ fb_div |= 1;
2141 -+
2142 -+ /* fb div out of range ? */
2143 -+ if (fb_div > 0x03FFFFFF)
2144 -+ break; /* it can oly get worse */
2145 -+
2146 -+ /* calc vclk with current vco freq. */
2147 -+ calc_clk = rv770_uvd_calc_post_div(vclk, vco_freq, &vclk_div);
2148 -+ if (calc_clk == -1)
2149 -+ break; /* vco is too big, it has to stop. */
2150 -+ diff_vclk = vclk - calc_clk;
2151 -+
2152 -+ /* calc dclk with current vco freq. */
2153 -+ calc_clk = rv770_uvd_calc_post_div(dclk, vco_freq, &dclk_div);
2154 -+ if (calc_clk == -1)
2155 -+ break; /* vco is too big, it has to stop. */
2156 -+ diff_dclk = dclk - calc_clk;
2157 -+
2158 -+ /* determine if this vco setting is better than current optimal settings */
2159 -+ diff_score = abs(diff_vclk) + abs(diff_dclk);
2160 -+ if (diff_score < optimal_diff_score) {
2161 -+ optimal_fb_div = fb_div;
2162 -+ optimal_vclk_div = vclk_div;
2163 -+ optimal_dclk_div = dclk_div;
2164 -+ optimal_vco_freq = vco_freq;
2165 -+ optimal_diff_score = diff_score;
2166 -+ if (optimal_diff_score == 0)
2167 -+ break; /* it can't get better than this */
2168 -+ }
2169 -+ }
2170 -+
2171 -+ /* set UPLL_FB_DIV to 0x50000 */
2172 -+ WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(0x50000), ~UPLL_FB_DIV_MASK);
2173 -+
2174 -+ /* deassert UPLL_RESET and UPLL_SLEEP */
2175 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~(UPLL_RESET_MASK | UPLL_SLEEP_MASK));
2176 -+
2177 -+ /* assert BYPASS EN and FB_DIV[0] <- ??? why? */
2178 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
2179 -+ WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(1), ~UPLL_FB_DIV(1));
2180 -+
2181 -+ r = rv770_uvd_send_upll_ctlreq(rdev);
2182 -+ if (r)
2183 -+ return r;
2184 -+
2185 -+ /* assert PLL_RESET */
2186 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
2187 -+
2188 -+ /* set the required FB_DIV, REF_DIV, Post divder values */
2189 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_REF_DIV(1), ~UPLL_REF_DIV_MASK);
2190 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
2191 -+ UPLL_SW_HILEN(optimal_vclk_div >> 1) |
2192 -+ UPLL_SW_LOLEN((optimal_vclk_div >> 1) + (optimal_vclk_div & 1)) |
2193 -+ UPLL_SW_HILEN2(optimal_dclk_div >> 1) |
2194 -+ UPLL_SW_LOLEN2((optimal_dclk_div >> 1) + (optimal_dclk_div & 1)),
2195 -+ ~UPLL_SW_MASK);
2196 -+
2197 -+ WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(optimal_fb_div),
2198 -+ ~UPLL_FB_DIV_MASK);
2199 -+
2200 -+ /* give the PLL some time to settle */
2201 -+ mdelay(15);
2202 -+
2203 -+ /* deassert PLL_RESET */
2204 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
2205 -+
2206 -+ mdelay(15);
2207 -+
2208 -+ /* deassert BYPASS EN and FB_DIV[0] <- ??? why? */
2209 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
2210 -+ WREG32_P(CG_UPLL_FUNC_CNTL_3, 0, ~UPLL_FB_DIV(1));
2211 -+
2212 -+ r = rv770_uvd_send_upll_ctlreq(rdev);
2213 -+ if (r)
2214 -+ return r;
2215 -+
2216 -+ /* switch VCLK and DCLK selection */
2217 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
2218 -+ VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
2219 -+ ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
2220 -+
2221 -+ mdelay(100);
2222 -+
2223 -+ return 0;
2224 -+}
2225 -
2226 - #define PCIE_BUS_CLK 10000
2227 - #define TCLK (PCIE_BUS_CLK / 10)
2228 -@@ -68,6 +230,105 @@
2229 - return reference_clock;
2230 - }
2231 -
2232 -+int rv770_uvd_resume(struct radeon_device *rdev)
2233 -+{
2234 -+ uint64_t addr;
2235 -+ uint32_t chip_id, size;
2236 -+ int r;
2237 -+
2238 -+ r = radeon_uvd_resume(rdev);
2239 -+ if (r)
2240 -+ return r;
2241 -+
2242 -+ /* programm the VCPU memory controller bits 0-27 */
2243 -+ addr = rdev->uvd.gpu_addr >> 3;
2244 -+ size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
2245 -+ WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
2246 -+ WREG32(UVD_VCPU_CACHE_SIZE0, size);
2247 -+
2248 -+ addr += size;
2249 -+ size = RADEON_UVD_STACK_SIZE >> 3;
2250 -+ WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
2251 -+ WREG32(UVD_VCPU_CACHE_SIZE1, size);
2252 -+
2253 -+ addr += size;
2254 -+ size = RADEON_UVD_HEAP_SIZE >> 3;
2255 -+ WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
2256 -+ WREG32(UVD_VCPU_CACHE_SIZE2, size);
2257 -+
2258 -+ /* bits 28-31 */
2259 -+ addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
2260 -+ WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
2261 -+
2262 -+ /* bits 32-39 */
2263 -+ addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
2264 -+ WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
2265 -+
2266 -+ /* tell firmware which hardware it is running on */
2267 -+ switch (rdev->family) {
2268 -+ default:
2269 -+ return -EINVAL;
2270 -+ case CHIP_RV710:
2271 -+ chip_id = 0x01000005;
2272 -+ break;
2273 -+ case CHIP_RV730:
2274 -+ chip_id = 0x01000006;
2275 -+ break;
2276 -+ case CHIP_RV740:
2277 -+ chip_id = 0x01000007;
2278 -+ break;
2279 -+ case CHIP_CYPRESS:
2280 -+ case CHIP_HEMLOCK:
2281 -+ chip_id = 0x01000008;
2282 -+ break;
2283 -+ case CHIP_JUNIPER:
2284 -+ chip_id = 0x01000009;
2285 -+ break;
2286 -+ case CHIP_REDWOOD:
2287 -+ chip_id = 0x0100000a;
2288 -+ break;
2289 -+ case CHIP_CEDAR:
2290 -+ chip_id = 0x0100000b;
2291 -+ break;
2292 -+ case CHIP_SUMO:
2293 -+ chip_id = 0x0100000c;
2294 -+ break;
2295 -+ case CHIP_SUMO2:
2296 -+ chip_id = 0x0100000d;
2297 -+ break;
2298 -+ case CHIP_PALM:
2299 -+ chip_id = 0x0100000e;
2300 -+ break;
2301 -+ case CHIP_CAYMAN:
2302 -+ chip_id = 0x0100000f;
2303 -+ break;
2304 -+ case CHIP_BARTS:
2305 -+ chip_id = 0x01000010;
2306 -+ break;
2307 -+ case CHIP_TURKS:
2308 -+ chip_id = 0x01000011;
2309 -+ break;
2310 -+ case CHIP_CAICOS:
2311 -+ chip_id = 0x01000012;
2312 -+ break;
2313 -+ case CHIP_TAHITI:
2314 -+ chip_id = 0x01000014;
2315 -+ break;
2316 -+ case CHIP_VERDE:
2317 -+ chip_id = 0x01000015;
2318 -+ break;
2319 -+ case CHIP_PITCAIRN:
2320 -+ chip_id = 0x01000016;
2321 -+ break;
2322 -+ case CHIP_ARUBA:
2323 -+ chip_id = 0x01000017;
2324 -+ break;
2325 -+ }
2326 -+ WREG32(UVD_VCPU_CHIP_ID, chip_id);
2327 -+
2328 -+ return 0;
2329 -+}
2330 -+
2331 - u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
2332 - {
2333 - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
2334 -@@ -611,6 +872,11 @@
2335 - WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
2336 - WREG32(DMA_TILING_CONFIG, (gb_tiling_config & 0xffff));
2337 - WREG32(DMA_TILING_CONFIG2, (gb_tiling_config & 0xffff));
2338 -+ if (rdev->family == CHIP_RV730) {
2339 -+ WREG32(UVD_UDEC_DB_TILING_CONFIG, (gb_tiling_config & 0xffff));
2340 -+ WREG32(UVD_UDEC_DBW_TILING_CONFIG, (gb_tiling_config & 0xffff));
2341 -+ WREG32(UVD_UDEC_TILING_CONFIG, (gb_tiling_config & 0xffff));
2342 -+ }
2343 -
2344 - WREG32(CGTS_SYS_TCC_DISABLE, 0);
2345 - WREG32(CGTS_TCC_DISABLE, 0);
2346 -@@ -1040,6 +1306,17 @@
2347 - return r;
2348 - }
2349 -
2350 -+ r = rv770_uvd_resume(rdev);
2351 -+ if (!r) {
2352 -+ r = radeon_fence_driver_start_ring(rdev,
2353 -+ R600_RING_TYPE_UVD_INDEX);
2354 -+ if (r)
2355 -+ dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2356 -+ }
2357 -+
2358 -+ if (r)
2359 -+ rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2360 -+
2361 - /* Enable IRQ */
2362 - r = r600_irq_init(rdev);
2363 - if (r) {
2364 -@@ -1074,6 +1351,19 @@
2365 - if (r)
2366 - return r;
2367 -
2368 -+ ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2369 -+ if (ring->ring_size) {
2370 -+ r = radeon_ring_init(rdev, ring, ring->ring_size,
2371 -+ R600_WB_UVD_RPTR_OFFSET,
2372 -+ UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2373 -+ 0, 0xfffff, RADEON_CP_PACKET2);
2374 -+ if (!r)
2375 -+ r = r600_uvd_init(rdev);
2376 -+
2377 -+ if (r)
2378 -+ DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2379 -+ }
2380 -+
2381 - r = radeon_ib_pool_init(rdev);
2382 - if (r) {
2383 - dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
2384 -@@ -1115,6 +1405,7 @@
2385 - int rv770_suspend(struct radeon_device *rdev)
2386 - {
2387 - r600_audio_fini(rdev);
2388 -+ radeon_uvd_suspend(rdev);
2389 - r700_cp_stop(rdev);
2390 - r600_dma_stop(rdev);
2391 - r600_irq_suspend(rdev);
2392 -@@ -1190,6 +1481,13 @@
2393 - rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
2394 - r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
2395 -
2396 -+ r = radeon_uvd_init(rdev);
2397 -+ if (!r) {
2398 -+ rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
2399 -+ r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
2400 -+ 4096);
2401 -+ }
2402 -+
2403 - rdev->ih.ring_obj = NULL;
2404 - r600_ih_ring_init(rdev, 64 * 1024);
2405 -
2406 -@@ -1224,6 +1522,7 @@
2407 - radeon_ib_pool_fini(rdev);
2408 - radeon_irq_kms_fini(rdev);
2409 - rv770_pcie_gart_fini(rdev);
2410 -+ radeon_uvd_fini(rdev);
2411 - r600_vram_scratch_fini(rdev);
2412 - radeon_gem_fini(rdev);
2413 - radeon_fence_driver_fini(rdev);
2414 -diff -urN a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
2415 ---- a/drivers/gpu/drm/radeon/rv770d.h 2013-05-09 22:13:14.647184583 +0200
2416 -+++ b/drivers/gpu/drm/radeon/rv770d.h 2013-05-09 22:14:57.210508833 +0200
2417 -@@ -38,6 +38,30 @@
2418 - #define R7XX_MAX_PIPES 8
2419 - #define R7XX_MAX_PIPES_MASK 0xff
2420 -
2421 -+/* discrete uvd clocks */
2422 -+#define CG_UPLL_FUNC_CNTL 0x718
2423 -+# define UPLL_RESET_MASK 0x00000001
2424 -+# define UPLL_SLEEP_MASK 0x00000002
2425 -+# define UPLL_BYPASS_EN_MASK 0x00000004
2426 -+# define UPLL_CTLREQ_MASK 0x00000008
2427 -+# define UPLL_REF_DIV(x) ((x) << 16)
2428 -+# define UPLL_REF_DIV_MASK 0x001F0000
2429 -+# define UPLL_CTLACK_MASK 0x40000000
2430 -+# define UPLL_CTLACK2_MASK 0x80000000
2431 -+#define CG_UPLL_FUNC_CNTL_2 0x71c
2432 -+# define UPLL_SW_HILEN(x) ((x) << 0)
2433 -+# define UPLL_SW_LOLEN(x) ((x) << 4)
2434 -+# define UPLL_SW_HILEN2(x) ((x) << 8)
2435 -+# define UPLL_SW_LOLEN2(x) ((x) << 12)
2436 -+# define UPLL_SW_MASK 0x0000FFFF
2437 -+# define VCLK_SRC_SEL(x) ((x) << 20)
2438 -+# define VCLK_SRC_SEL_MASK 0x01F00000
2439 -+# define DCLK_SRC_SEL(x) ((x) << 25)
2440 -+# define DCLK_SRC_SEL_MASK 0x3E000000
2441 -+#define CG_UPLL_FUNC_CNTL_3 0x720
2442 -+# define UPLL_FB_DIV(x) ((x) << 0)
2443 -+# define UPLL_FB_DIV_MASK 0x01FFFFFF
2444 -+
2445 - /* Registers */
2446 - #define CB_COLOR0_BASE 0x28040
2447 - #define CB_COLOR1_BASE 0x28044
2448 -@@ -112,6 +136,11 @@
2449 - #define DMA_TILING_CONFIG 0x3ec8
2450 - #define DMA_TILING_CONFIG2 0xd0b8
2451 -
2452 -+/* RV730 only */
2453 -+#define UVD_UDEC_TILING_CONFIG 0xef40
2454 -+#define UVD_UDEC_DB_TILING_CONFIG 0xef44
2455 -+#define UVD_UDEC_DBW_TILING_CONFIG 0xef48
2456 -+
2457 - #define GC_USER_SHADER_PIPE_CONFIG 0x8954
2458 - #define INACTIVE_QD_PIPES(x) ((x) << 8)
2459 - #define INACTIVE_QD_PIPES_MASK 0x0000FF00
2460 -@@ -671,4 +700,18 @@
2461 - # define TARGET_LINK_SPEED_MASK (0xf << 0)
2462 - # define SELECTABLE_DEEMPHASIS (1 << 6)
2463 -
2464 -+/* UVD */
2465 -+#define UVD_LMI_EXT40_ADDR 0xf498
2466 -+#define UVD_VCPU_CHIP_ID 0xf4d4
2467 -+#define UVD_VCPU_CACHE_OFFSET0 0xf4d8
2468 -+#define UVD_VCPU_CACHE_SIZE0 0xf4dc
2469 -+#define UVD_VCPU_CACHE_OFFSET1 0xf4e0
2470 -+#define UVD_VCPU_CACHE_SIZE1 0xf4e4
2471 -+#define UVD_VCPU_CACHE_OFFSET2 0xf4e8
2472 -+#define UVD_VCPU_CACHE_SIZE2 0xf4ec
2473 -+#define UVD_LMI_ADDR_EXT 0xf594
2474 -+
2475 -+#define UVD_RBC_RB_RPTR 0xf690
2476 -+#define UVD_RBC_RB_WPTR 0xf694
2477 -+
2478 - #endif
2479 -diff -urN a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
2480 ---- a/drivers/gpu/drm/radeon/si.c 2013-05-09 22:13:14.650517916 +0200
2481 -+++ b/drivers/gpu/drm/radeon/si.c 2013-05-09 22:14:57.220508832 +0200
2482 -@@ -1768,6 +1768,9 @@
2483 - WREG32(HDP_ADDR_CONFIG, gb_addr_config);
2484 - WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
2485 - WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
2486 -+ WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
2487 -+ WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
2488 -+ WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
2489 -
2490 - si_tiling_mode_table_init(rdev);
2491 -
2492 -@@ -4372,6 +4375,16 @@
2493 - return r;
2494 - }
2495 -
2496 -+ r = rv770_uvd_resume(rdev);
2497 -+ if (!r) {
2498 -+ r = radeon_fence_driver_start_ring(rdev,
2499 -+ R600_RING_TYPE_UVD_INDEX);
2500 -+ if (r)
2501 -+ dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2502 -+ }
2503 -+ if (r)
2504 -+ rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2505 -+
2506 - /* Enable IRQ */
2507 - r = si_irq_init(rdev);
2508 - if (r) {
2509 -@@ -4429,6 +4442,18 @@
2510 - if (r)
2511 - return r;
2512 -
2513 -+ ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2514 -+ if (ring->ring_size) {
2515 -+ r = radeon_ring_init(rdev, ring, ring->ring_size,
2516 -+ R600_WB_UVD_RPTR_OFFSET,
2517 -+ UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2518 -+ 0, 0xfffff, RADEON_CP_PACKET2);
2519 -+ if (!r)
2520 -+ r = r600_uvd_init(rdev);
2521 -+ if (r)
2522 -+ DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2523 -+ }
2524 -+
2525 - r = radeon_ib_pool_init(rdev);
2526 - if (r) {
2527 - dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
2528 -@@ -4472,6 +4497,8 @@
2529 - radeon_vm_manager_fini(rdev);
2530 - si_cp_enable(rdev, false);
2531 - cayman_dma_stop(rdev);
2532 -+ r600_uvd_rbc_stop(rdev);
2533 -+ radeon_uvd_suspend(rdev);
2534 - si_irq_suspend(rdev);
2535 - radeon_wb_disable(rdev);
2536 - si_pcie_gart_disable(rdev);
2537 -@@ -4557,6 +4584,13 @@
2538 - ring->ring_obj = NULL;
2539 - r600_ring_init(rdev, ring, 64 * 1024);
2540 -
2541 -+ r = radeon_uvd_init(rdev);
2542 -+ if (!r) {
2543 -+ ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2544 -+ ring->ring_obj = NULL;
2545 -+ r600_ring_init(rdev, ring, 4096);
2546 -+ }
2547 -+
2548 - rdev->ih.ring_obj = NULL;
2549 - r600_ih_ring_init(rdev, 64 * 1024);
2550 -
2551 -@@ -4605,6 +4639,7 @@
2552 - radeon_vm_manager_fini(rdev);
2553 - radeon_ib_pool_fini(rdev);
2554 - radeon_irq_kms_fini(rdev);
2555 -+ radeon_uvd_fini(rdev);
2556 - si_pcie_gart_fini(rdev);
2557 - r600_vram_scratch_fini(rdev);
2558 - radeon_gem_fini(rdev);
2559 -@@ -4634,3 +4669,176 @@
2560 - mutex_unlock(&rdev->gpu_clock_mutex);
2561 - return clock;
2562 - }
2563 -+
2564 -+static int si_uvd_calc_post_div(unsigned target_freq,
2565 -+ unsigned vco_freq,
2566 -+ unsigned *div)
2567 -+{
2568 -+ /* target larger than vco frequency ? */
2569 -+ if (vco_freq < target_freq)
2570 -+ return -1; /* forget it */
2571 -+
2572 -+ /* Fclk = Fvco / PDIV */
2573 -+ *div = vco_freq / target_freq;
2574 -+
2575 -+ /* we alway need a frequency less than or equal the target */
2576 -+ if ((vco_freq / *div) > target_freq)
2577 -+ *div += 1;
2578 -+
2579 -+ /* dividers above 5 must be even */
2580 -+ if (*div > 5 && *div % 2)
2581 -+ *div += 1;
2582 -+
2583 -+ /* out of range ? */
2584 -+ if (*div >= 128)
2585 -+ return -1; /* forget it */
2586 -+
2587 -+ return vco_freq / *div;
2588 -+}
2589 -+
2590 -+static int si_uvd_send_upll_ctlreq(struct radeon_device *rdev)
2591 -+{
2592 -+ unsigned i;
2593 -+
2594 -+ /* assert UPLL_CTLREQ */
2595 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
2596 -+
2597 -+ /* wait for CTLACK and CTLACK2 to get asserted */
2598 -+ for (i = 0; i < 100; ++i) {
2599 -+ uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
2600 -+ if ((RREG32(CG_UPLL_FUNC_CNTL) & mask) == mask)
2601 -+ break;
2602 -+ mdelay(10);
2603 -+ }
2604 -+ if (i == 100)
2605 -+ return -ETIMEDOUT;
2606 -+
2607 -+ /* deassert UPLL_CTLREQ */
2608 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
2609 -+
2610 -+ return 0;
2611 -+}
2612 -+
2613 -+int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
2614 -+{
2615 -+ /* start off with something large */
2616 -+ int optimal_diff_score = 0x7FFFFFF;
2617 -+ unsigned optimal_fb_div = 0, optimal_vclk_div = 0;
2618 -+ unsigned optimal_dclk_div = 0, optimal_vco_freq = 0;
2619 -+ unsigned vco_freq;
2620 -+ int r;
2621 -+
2622 -+ /* bypass vclk and dclk with bclk */
2623 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
2624 -+ VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
2625 -+ ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
2626 -+
2627 -+ /* put PLL in bypass mode */
2628 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
2629 -+
2630 -+ if (!vclk || !dclk) {
2631 -+ /* keep the Bypass mode, put PLL to sleep */
2632 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
2633 -+ return 0;
2634 -+ }
2635 -+
2636 -+ /* loop through vco from low to high */
2637 -+ for (vco_freq = 125000; vco_freq <= 250000; vco_freq += 100) {
2638 -+ unsigned fb_div = vco_freq / rdev->clock.spll.reference_freq * 16384;
2639 -+ int calc_clk, diff_score, diff_vclk, diff_dclk;
2640 -+ unsigned vclk_div, dclk_div;
2641 -+
2642 -+ /* fb div out of range ? */
2643 -+ if (fb_div > 0x03FFFFFF)
2644 -+ break; /* it can oly get worse */
2645 -+
2646 -+ /* calc vclk with current vco freq. */
2647 -+ calc_clk = si_uvd_calc_post_div(vclk, vco_freq, &vclk_div);
2648 -+ if (calc_clk == -1)
2649 -+ break; /* vco is too big, it has to stop. */
2650 -+ diff_vclk = vclk - calc_clk;
2651 -+
2652 -+ /* calc dclk with current vco freq. */
2653 -+ calc_clk = si_uvd_calc_post_div(dclk, vco_freq, &dclk_div);
2654 -+ if (calc_clk == -1)
2655 -+ break; /* vco is too big, it has to stop. */
2656 -+ diff_dclk = dclk - calc_clk;
2657 -+
2658 -+ /* determine if this vco setting is better than current optimal settings */
2659 -+ diff_score = abs(diff_vclk) + abs(diff_dclk);
2660 -+ if (diff_score < optimal_diff_score) {
2661 -+ optimal_fb_div = fb_div;
2662 -+ optimal_vclk_div = vclk_div;
2663 -+ optimal_dclk_div = dclk_div;
2664 -+ optimal_vco_freq = vco_freq;
2665 -+ optimal_diff_score = diff_score;
2666 -+ if (optimal_diff_score == 0)
2667 -+ break; /* it can't get better than this */
2668 -+ }
2669 -+ }
2670 -+
2671 -+ /* set RESET_ANTI_MUX to 0 */
2672 -+ WREG32_P(CG_UPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
2673 -+
2674 -+ /* set VCO_MODE to 1 */
2675 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
2676 -+
2677 -+ /* toggle UPLL_SLEEP to 1 then back to 0 */
2678 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
2679 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
2680 -+
2681 -+ /* deassert UPLL_RESET */
2682 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
2683 -+
2684 -+ mdelay(1);
2685 -+
2686 -+ r = si_uvd_send_upll_ctlreq(rdev);
2687 -+ if (r)
2688 -+ return r;
2689 -+
2690 -+ /* assert UPLL_RESET again */
2691 -+ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
2692 -+
2693 -+ /* disable spread spectrum. */
2694 -+ WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
2695 -+
2696 -+ /* set feedback divider */
2697 -+ WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(optimal_fb_div), ~UPLL_FB_DIV_MASK);
2698 -+
2699 -+ /* set ref divider to 0 */
2700 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
2701 -+
2702 -+ if (optimal_vco_freq < 187500)
2703 -+ WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
2704 -+ else
2705 -+ WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
2706 -+
2707 -+ /* set PDIV_A and PDIV_B */
2708 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
2709 -+ UPLL_PDIV_A(optimal_vclk_div) | UPLL_PDIV_B(optimal_dclk_div),
2710 -+ ~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
2711 -+
2712 -+ /* give the PLL some time to settle */
2713 -+ mdelay(15);
2714 -+
2715 -+ /* deassert PLL_RESET */
2716 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
2717 -+
2718 -+ mdelay(15);
2719 -+
2720 -+ /* switch from bypass mode to normal mode */
2721 -+ WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
2722 -+
2723 -+ r = si_uvd_send_upll_ctlreq(rdev);
2724 -+ if (r)
2725 -+ return r;
2726 -+
2727 -+ /* switch VCLK and DCLK selection */
2728 -+ WREG32_P(CG_UPLL_FUNC_CNTL_2,
2729 -+ VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
2730 -+ ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
2731 -+
2732 -+ mdelay(100);
2733 -+
2734 -+ return 0;
2735 -+}
2736 -diff -urN a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
2737 ---- a/drivers/gpu/drm/radeon/sid.h 2013-05-09 22:13:14.650517916 +0200
2738 -+++ b/drivers/gpu/drm/radeon/sid.h 2013-05-09 22:14:57.210508833 +0200
2739 -@@ -29,6 +29,35 @@
2740 - #define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003
2741 - #define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002
2742 -
2743 -+/* discrete uvd clocks */
2744 -+#define CG_UPLL_FUNC_CNTL 0x634
2745 -+# define UPLL_RESET_MASK 0x00000001
2746 -+# define UPLL_SLEEP_MASK 0x00000002
2747 -+# define UPLL_BYPASS_EN_MASK 0x00000004
2748 -+# define UPLL_CTLREQ_MASK 0x00000008
2749 -+# define UPLL_VCO_MODE_MASK 0x00000600
2750 -+# define UPLL_REF_DIV_MASK 0x001F0000
2751 -+# define UPLL_CTLACK_MASK 0x40000000
2752 -+# define UPLL_CTLACK2_MASK 0x80000000
2753 -+#define CG_UPLL_FUNC_CNTL_2 0x638
2754 -+# define UPLL_PDIV_A(x) ((x) << 0)
2755 -+# define UPLL_PDIV_A_MASK 0x0000007F
2756 -+# define UPLL_PDIV_B(x) ((x) << 8)
2757 -+# define UPLL_PDIV_B_MASK 0x00007F00
2758 -+# define VCLK_SRC_SEL(x) ((x) << 20)
2759 -+# define VCLK_SRC_SEL_MASK 0x01F00000
2760 -+# define DCLK_SRC_SEL(x) ((x) << 25)
2761 -+# define DCLK_SRC_SEL_MASK 0x3E000000
2762 -+#define CG_UPLL_FUNC_CNTL_3 0x63C
2763 -+# define UPLL_FB_DIV(x) ((x) << 0)
2764 -+# define UPLL_FB_DIV_MASK 0x01FFFFFF
2765 -+#define CG_UPLL_FUNC_CNTL_4 0x644
2766 -+# define UPLL_SPARE_ISPARE9 0x00020000
2767 -+#define CG_UPLL_FUNC_CNTL_5 0x648
2768 -+# define RESET_ANTI_MUX_MASK 0x00000200
2769 -+#define CG_UPLL_SPREAD_SPECTRUM 0x650
2770 -+# define SSEN_MASK 0x00000001
2771 -+
2772 - #define CG_MULT_THERMAL_STATUS 0x714
2773 - #define ASIC_MAX_TEMP(x) ((x) << 0)
2774 - #define ASIC_MAX_TEMP_MASK 0x000001ff
2775 -@@ -798,6 +827,15 @@
2776 - # define THREAD_TRACE_FINISH (55 << 0)
2777 -
2778 - /*
2779 -+ * UVD
2780 -+ */
2781 -+#define UVD_UDEC_ADDR_CONFIG 0xEF4C
2782 -+#define UVD_UDEC_DB_ADDR_CONFIG 0xEF50
2783 -+#define UVD_UDEC_DBW_ADDR_CONFIG 0xEF54
2784 -+#define UVD_RBC_RB_RPTR 0xF690
2785 -+#define UVD_RBC_RB_WPTR 0xF694
2786 -+
2787 -+/*
2788 - * PM4
2789 - */
2790 - #define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \
2791 -diff -urN a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
2792 ---- a/include/uapi/drm/radeon_drm.h 2013-05-09 22:13:14.680517913 +0200
2793 -+++ b/include/uapi/drm/radeon_drm.h 2013-05-09 22:14:57.210508833 +0200
2794 -@@ -918,6 +918,7 @@
2795 - #define RADEON_CS_RING_GFX 0
2796 - #define RADEON_CS_RING_COMPUTE 1
2797 - #define RADEON_CS_RING_DMA 2
2798 -+#define RADEON_CS_RING_UVD 3
2799 - /* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */
2800 - /* 0 = normal, + = higher priority, - = lower priority */
2801 -
2802 -@@ -972,6 +973,11 @@
2803 - #define RADEON_INFO_MAX_SE 0x12
2804 - /* max SH per SE */
2805 - #define RADEON_INFO_MAX_SH_PER_SE 0x13
2806 -+/* fast fb access is enabled */
2807 -+#define RADEON_INFO_FASTFB_WORKING 0x14
2808 -+/* query if a RADEON_CS_RING_* submission is supported */
2809 -+#define RADEON_INFO_RING_WORKING 0x15
2810 -+
2811 -
2812 - struct drm_radeon_info {
2813 - uint32_t request;
2814 -diff -urN /dev/null b/include/uapi/drm/radeon_uvd.c
2815 ---- /dev/null 2013-05-09 19:51:08.911273005 +0200
2816 -+++ b/drivers/gpu/drm/radeon/radeon_uvd.c 2013-05-10 01:45:56.542720982 +0200
2817 -@@ -0,0 +1,694 @@
2818 -+/*
2819 -+ * Copyright 2011 Advanced Micro Devices, Inc.
2820 -+ * All Rights Reserved.
2821 -+ *
2822 -+ * Permission is hereby granted, free of charge, to any person obtaining a
2823 -+ * copy of this software and associated documentation files (the
2824 -+ * "Software"), to deal in the Software without restriction, including
2825 -+ * without limitation the rights to use, copy, modify, merge, publish,
2826 -+ * distribute, sub license, and/or sell copies of the Software, and to
2827 -+ * permit persons to whom the Software is furnished to do so, subject to
2828 -+ * the following conditions:
2829 -+ *
2830 -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2831 -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2832 -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
2833 -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2834 -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2835 -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2836 -+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
2837 -+ *
2838 -+ * The above copyright notice and this permission notice (including the
2839 -+ * next paragraph) shall be included in all copies or substantial portions
2840 -+ * of the Software.
2841 -+ *
2842 -+ */
2843 -+/*
2844 -+ * Authors:
2845 -+ * Christian König <deathsimple@××××××××.de>
2846 -+ */
2847 -+
2848 -+#include <linux/firmware.h>
2849 -+#include <linux/module.h>
2850 -+#include <drm/drmP.h>
2851 -+#include <drm/drm.h>
2852 -+
2853 -+#include "radeon.h"
2854 -+#include "r600d.h"
2855 -+
2856 -+/* 1 second timeout */
2857 -+#define UVD_IDLE_TIMEOUT_MS 1000
2858 -+
2859 -+/* Firmware Names */
2860 -+#define FIRMWARE_RV710 "radeon/RV710_uvd.bin"
2861 -+#define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin"
2862 -+#define FIRMWARE_SUMO "radeon/SUMO_uvd.bin"
2863 -+#define FIRMWARE_TAHITI "radeon/TAHITI_uvd.bin"
2864 -+
2865 -+MODULE_FIRMWARE(FIRMWARE_RV710);
2866 -+MODULE_FIRMWARE(FIRMWARE_CYPRESS);
2867 -+MODULE_FIRMWARE(FIRMWARE_SUMO);
2868 -+MODULE_FIRMWARE(FIRMWARE_TAHITI);
2869 -+
2870 -+static void radeon_uvd_idle_work_handler(struct work_struct *work);
2871 -+
2872 -+int radeon_uvd_init(struct radeon_device *rdev)
2873 -+{
2874 -+ struct platform_device *pdev;
2875 -+ unsigned long bo_size;
2876 -+ const char *fw_name;
2877 -+ int i, r;
2878 -+
2879 -+ INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
2880 -+
2881 -+ pdev = platform_device_register_simple("radeon_uvd", 0, NULL, 0);
2882 -+ r = IS_ERR(pdev);
2883 -+ if (r) {
2884 -+ dev_err(rdev->dev, "radeon_uvd: Failed to register firmware\n");
2885 -+ return -EINVAL;
2886 -+ }
2887 -+
2888 -+ switch (rdev->family) {
2889 -+ case CHIP_RV710:
2890 -+ case CHIP_RV730:
2891 -+ case CHIP_RV740:
2892 -+ fw_name = FIRMWARE_RV710;
2893 -+ break;
2894 -+
2895 -+ case CHIP_CYPRESS:
2896 -+ case CHIP_HEMLOCK:
2897 -+ case CHIP_JUNIPER:
2898 -+ case CHIP_REDWOOD:
2899 -+ case CHIP_CEDAR:
2900 -+ fw_name = FIRMWARE_CYPRESS;
2901 -+ break;
2902 -+
2903 -+ case CHIP_SUMO:
2904 -+ case CHIP_SUMO2:
2905 -+ case CHIP_PALM:
2906 -+ case CHIP_CAYMAN:
2907 -+ case CHIP_BARTS:
2908 -+ case CHIP_TURKS:
2909 -+ case CHIP_CAICOS:
2910 -+ fw_name = FIRMWARE_SUMO;
2911 -+ break;
2912 -+
2913 -+ case CHIP_TAHITI:
2914 -+ case CHIP_VERDE:
2915 -+ case CHIP_PITCAIRN:
2916 -+ case CHIP_ARUBA:
2917 -+ fw_name = FIRMWARE_TAHITI;
2918 -+ break;
2919 -+
2920 -+ default:
2921 -+ return -EINVAL;
2922 -+ }
2923 -+
2924 -+ r = request_firmware(&rdev->uvd_fw, fw_name, &pdev->dev);
2925 -+ if (r) {
2926 -+ dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
2927 -+ fw_name);
2928 -+ platform_device_unregister(pdev);
2929 -+ return r;
2930 -+ }
2931 -+
2932 -+ platform_device_unregister(pdev);
2933 -+
2934 -+ bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
2935 -+ RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
2936 -+ r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
2937 -+ RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
2938 -+ if (r) {
2939 -+ dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r);
2940 -+ return r;
2941 -+ }
2942 -+
2943 -+ r = radeon_uvd_resume(rdev);
2944 -+ if (r)
2945 -+ return r;
2946 -+
2947 -+ memset(rdev->uvd.cpu_addr, 0, bo_size);
2948 -+ memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
2949 -+
2950 -+ r = radeon_uvd_suspend(rdev);
2951 -+ if (r)
2952 -+ return r;
2953 -+
2954 -+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
2955 -+ atomic_set(&rdev->uvd.handles[i], 0);
2956 -+ rdev->uvd.filp[i] = NULL;
2957 -+ }
2958 -+
2959 -+ return 0;
2960 -+}
2961 -+
2962 -+void radeon_uvd_fini(struct radeon_device *rdev)
2963 -+{
2964 -+ radeon_uvd_suspend(rdev);
2965 -+ radeon_bo_unref(&rdev->uvd.vcpu_bo);
2966 -+}
2967 -+
2968 -+int radeon_uvd_suspend(struct radeon_device *rdev)
2969 -+{
2970 -+ int r;
2971 -+
2972 -+ if (rdev->uvd.vcpu_bo == NULL)
2973 -+ return 0;
2974 -+
2975 -+ r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
2976 -+ if (!r) {
2977 -+ radeon_bo_kunmap(rdev->uvd.vcpu_bo);
2978 -+ radeon_bo_unpin(rdev->uvd.vcpu_bo);
2979 -+ radeon_bo_unreserve(rdev->uvd.vcpu_bo);
2980 -+ }
2981 -+ return r;
2982 -+}
2983 -+
2984 -+int radeon_uvd_resume(struct radeon_device *rdev)
2985 -+{
2986 -+ int r;
2987 -+
2988 -+ if (rdev->uvd.vcpu_bo == NULL)
2989 -+ return -EINVAL;
2990 -+
2991 -+ r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
2992 -+ if (r) {
2993 -+ radeon_bo_unref(&rdev->uvd.vcpu_bo);
2994 -+ dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r);
2995 -+ return r;
2996 -+ }
2997 -+
2998 -+ r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
2999 -+ &rdev->uvd.gpu_addr);
3000 -+ if (r) {
3001 -+ radeon_bo_unreserve(rdev->uvd.vcpu_bo);
3002 -+ radeon_bo_unref(&rdev->uvd.vcpu_bo);
3003 -+ dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r);
3004 -+ return r;
3005 -+ }
3006 -+
3007 -+ r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
3008 -+ if (r) {
3009 -+ dev_err(rdev->dev, "(%d) UVD map failed\n", r);
3010 -+ return r;
3011 -+ }
3012 -+
3013 -+ radeon_bo_unreserve(rdev->uvd.vcpu_bo);
3014 -+
3015 -+ return 0;
3016 -+}
3017 -+
3018 -+void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo)
3019 -+{
3020 -+ rbo->placement.fpfn = 0 >> PAGE_SHIFT;
3021 -+ rbo->placement.lpfn = (256 * 1024 * 1024) >> PAGE_SHIFT;
3022 -+}
3023 -+
3024 -+void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp)
3025 -+{
3026 -+ int i, r;
3027 -+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
3028 -+ if (rdev->uvd.filp[i] == filp) {
3029 -+ uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
3030 -+ struct radeon_fence *fence;
3031 -+
3032 -+ r = radeon_uvd_get_destroy_msg(rdev,
3033 -+ R600_RING_TYPE_UVD_INDEX, handle, &fence);
3034 -+ if (r) {
3035 -+ DRM_ERROR("Error destroying UVD (%d)!\n", r);
3036 -+ continue;
3037 -+ }
3038 -+
3039 -+ radeon_fence_wait(fence, false);
3040 -+ radeon_fence_unref(&fence);
3041 -+
3042 -+ rdev->uvd.filp[i] = NULL;
3043 -+ atomic_set(&rdev->uvd.handles[i], 0);
3044 -+ }
3045 -+ }
3046 -+}
3047 -+
3048 -+static int radeon_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[])
3049 -+{
3050 -+ unsigned stream_type = msg[4];
3051 -+ unsigned width = msg[6];
3052 -+ unsigned height = msg[7];
3053 -+ unsigned dpb_size = msg[9];
3054 -+ unsigned pitch = msg[28];
3055 -+
3056 -+ unsigned width_in_mb = width / 16;
3057 -+ unsigned height_in_mb = ALIGN(height / 16, 2);
3058 -+
3059 -+ unsigned image_size, tmp, min_dpb_size;
3060 -+
3061 -+ image_size = width * height;
3062 -+ image_size += image_size / 2;
3063 -+ image_size = ALIGN(image_size, 1024);
3064 -+
3065 -+ switch (stream_type) {
3066 -+ case 0: /* H264 */
3067 -+
3068 -+ /* reference picture buffer */
3069 -+ min_dpb_size = image_size * 17;
3070 -+
3071 -+ /* macroblock context buffer */
3072 -+ min_dpb_size += width_in_mb * height_in_mb * 17 * 192;
3073 -+
3074 -+ /* IT surface buffer */
3075 -+ min_dpb_size += width_in_mb * height_in_mb * 32;
3076 -+ break;
3077 -+
3078 -+ case 1: /* VC1 */
3079 -+
3080 -+ /* reference picture buffer */
3081 -+ min_dpb_size = image_size * 3;
3082 -+
3083 -+ /* CONTEXT_BUFFER */
3084 -+ min_dpb_size += width_in_mb * height_in_mb * 128;
3085 -+
3086 -+ /* IT surface buffer */
3087 -+ min_dpb_size += width_in_mb * 64;
3088 -+
3089 -+ /* DB surface buffer */
3090 -+ min_dpb_size += width_in_mb * 128;
3091 -+
3092 -+ /* BP */
3093 -+ tmp = max(width_in_mb, height_in_mb);
3094 -+ min_dpb_size += ALIGN(tmp * 7 * 16, 64);
3095 -+ break;
3096 -+
3097 -+ case 3: /* MPEG2 */
3098 -+
3099 -+ /* reference picture buffer */
3100 -+ min_dpb_size = image_size * 3;
3101 -+ break;
3102 -+
3103 -+ case 4: /* MPEG4 */
3104 -+
3105 -+ /* reference picture buffer */
3106 -+ min_dpb_size = image_size * 3;
3107 -+
3108 -+ /* CM */
3109 -+ min_dpb_size += width_in_mb * height_in_mb * 64;
3110 -+
3111 -+ /* IT surface buffer */
3112 -+ min_dpb_size += ALIGN(width_in_mb * height_in_mb * 32, 64);
3113 -+ break;
3114 -+
3115 -+ default:
3116 -+ DRM_ERROR("UVD codec not handled %d!\n", stream_type);
3117 -+ return -EINVAL;
3118 -+ }
3119 -+
3120 -+ if (width > pitch) {
3121 -+ DRM_ERROR("Invalid UVD decoding target pitch!\n");
3122 -+ return -EINVAL;
3123 -+ }
3124 -+
3125 -+ if (dpb_size < min_dpb_size) {
3126 -+ DRM_ERROR("Invalid dpb_size in UVD message (%d / %d)!\n",
3127 -+ dpb_size, min_dpb_size);
3128 -+ return -EINVAL;
3129 -+ }
3130 -+
3131 -+ buf_sizes[0x1] = dpb_size;
3132 -+ buf_sizes[0x2] = image_size;
3133 -+ return 0;
3134 -+}
3135 -+
3136 -+static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
3137 -+ unsigned offset, unsigned buf_sizes[])
3138 -+{
3139 -+ int32_t *msg, msg_type, handle;
3140 -+ void *ptr;
3141 -+
3142 -+ int i, r;
3143 -+
3144 -+ if (offset & 0x3F) {
3145 -+ DRM_ERROR("UVD messages must be 64 byte aligned!\n");
3146 -+ return -EINVAL;
3147 -+ }
3148 -+
3149 -+ r = radeon_bo_kmap(bo, &ptr);
3150 -+ if (r)
3151 -+ return r;
3152 -+
3153 -+ msg = ptr + offset;
3154 -+
3155 -+ msg_type = msg[1];
3156 -+ handle = msg[2];
3157 -+
3158 -+ if (handle == 0) {
3159 -+ DRM_ERROR("Invalid UVD handle!\n");
3160 -+ return -EINVAL;
3161 -+ }
3162 -+
3163 -+ if (msg_type == 1) {
3164 -+ /* it's a decode msg, calc buffer sizes */
3165 -+ r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
3166 -+ radeon_bo_kunmap(bo);
3167 -+ if (r)
3168 -+ return r;
3169 -+
3170 -+ } else if (msg_type == 2) {
3171 -+ /* it's a destroy msg, free the handle */
3172 -+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
3173 -+ atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
3174 -+ radeon_bo_kunmap(bo);
3175 -+ return 0;
3176 -+ } else {
3177 -+ /* it's a create msg, no special handling needed */
3178 -+ radeon_bo_kunmap(bo);
3179 -+ }
3180 -+
3181 -+ /* create or decode, validate the handle */
3182 -+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
3183 -+ if (atomic_read(&p->rdev->uvd.handles[i]) == handle)
3184 -+ return 0;
3185 -+ }
3186 -+
3187 -+ /* handle not found try to alloc a new one */
3188 -+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
3189 -+ if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
3190 -+ p->rdev->uvd.filp[i] = p->filp;
3191 -+ return 0;
3192 -+ }
3193 -+ }
3194 -+
3195 -+ DRM_ERROR("No more free UVD handles!\n");
3196 -+ return -EINVAL;
3197 -+}
3198 -+
3199 -+static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
3200 -+ int data0, int data1,
3201 -+ unsigned buf_sizes[])
3202 -+{
3203 -+ struct radeon_cs_chunk *relocs_chunk;
3204 -+ struct radeon_cs_reloc *reloc;
3205 -+ unsigned idx, cmd, offset;
3206 -+ uint64_t start, end;
3207 -+ int r;
3208 -+
3209 -+ relocs_chunk = &p->chunks[p->chunk_relocs_idx];
3210 -+ offset = radeon_get_ib_value(p, data0);
3211 -+ idx = radeon_get_ib_value(p, data1);
3212 -+ if (idx >= relocs_chunk->length_dw) {
3213 -+ DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
3214 -+ idx, relocs_chunk->length_dw);
3215 -+ return -EINVAL;
3216 -+ }
3217 -+
3218 -+ reloc = p->relocs_ptr[(idx / 4)];
3219 -+ start = reloc->lobj.gpu_offset;
3220 -+ end = start + radeon_bo_size(reloc->robj);
3221 -+ start += offset;
3222 -+
3223 -+ p->ib.ptr[data0] = start & 0xFFFFFFFF;
3224 -+ p->ib.ptr[data1] = start >> 32;
3225 -+
3226 -+ cmd = radeon_get_ib_value(p, p->idx) >> 1;
3227 -+
3228 -+ if (cmd < 0x4) {
3229 -+ if ((end - start) < buf_sizes[cmd]) {
3230 -+ DRM_ERROR("buffer to small (%d / %d)!\n",
3231 -+ (unsigned)(end - start), buf_sizes[cmd]);
3232 -+ return -EINVAL;
3233 -+ }
3234 -+
3235 -+ } else if (cmd != 0x100) {
3236 -+ DRM_ERROR("invalid UVD command %X!\n", cmd);
3237 -+ return -EINVAL;
3238 -+ }
3239 -+
3240 -+ if ((start >> 28) != (end >> 28)) {
3241 -+ DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n",
3242 -+ start, end);
3243 -+ return -EINVAL;
3244 -+ }
3245 -+
3246 -+ /* TODO: is this still necessary on NI+ ? */
3247 -+ if ((cmd == 0 || cmd == 0x3) &&
3248 -+ (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) {
3249 -+ DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n",
3250 -+ start, end);
3251 -+ return -EINVAL;
3252 -+ }
3253 -+
3254 -+ if (cmd == 0) {
3255 -+ r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes);
3256 -+ if (r)
3257 -+ return r;
3258 -+ }
3259 -+
3260 -+ return 0;
3261 -+}
3262 -+
3263 -+static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
3264 -+ struct radeon_cs_packet *pkt,
3265 -+ int *data0, int *data1,
3266 -+ unsigned buf_sizes[])
3267 -+{
3268 -+ int i, r;
3269 -+
3270 -+ p->idx++;
3271 -+ for (i = 0; i <= pkt->count; ++i) {
3272 -+ switch (pkt->reg + i*4) {
3273 -+ case UVD_GPCOM_VCPU_DATA0:
3274 -+ *data0 = p->idx;
3275 -+ break;
3276 -+ case UVD_GPCOM_VCPU_DATA1:
3277 -+ *data1 = p->idx;
3278 -+ break;
3279 -+ case UVD_GPCOM_VCPU_CMD:
3280 -+ r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes);
3281 -+ if (r)
3282 -+ return r;
3283 -+ break;
3284 -+ case UVD_ENGINE_CNTL:
3285 -+ break;
3286 -+ default:
3287 -+ DRM_ERROR("Invalid reg 0x%X!\n",
3288 -+ pkt->reg + i*4);
3289 -+ return -EINVAL;
3290 -+ }
3291 -+ p->idx++;
3292 -+ }
3293 -+ return 0;
3294 -+}
3295 -+
3296 -+int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
3297 -+{
3298 -+ struct radeon_cs_packet pkt;
3299 -+ int r, data0 = 0, data1 = 0;
3300 -+
3301 -+ /* minimum buffer sizes */
3302 -+ unsigned buf_sizes[] = {
3303 -+ [0x00000000] = 2048,
3304 -+ [0x00000001] = 32 * 1024 * 1024,
3305 -+ [0x00000002] = 2048 * 1152 * 3,
3306 -+ [0x00000003] = 2048,
3307 -+ };
3308 -+
3309 -+ if (p->chunks[p->chunk_ib_idx].length_dw % 16) {
3310 -+ DRM_ERROR("UVD IB length (%d) not 16 dwords aligned!\n",
3311 -+ p->chunks[p->chunk_ib_idx].length_dw);
3312 -+ return -EINVAL;
3313 -+ }
3314 -+
3315 -+ if (p->chunk_relocs_idx == -1) {
3316 -+ DRM_ERROR("No relocation chunk !\n");
3317 -+ return -EINVAL;
3318 -+ }
3319 -+
3320 -+
3321 -+ do {
3322 -+ r = radeon_cs_packet_parse(p, &pkt, p->idx);
3323 -+ if (r)
3324 -+ return r;
3325 -+ switch (pkt.type) {
3326 -+ case RADEON_PACKET_TYPE0:
3327 -+ r = radeon_uvd_cs_reg(p, &pkt, &data0,
3328 -+ &data1, buf_sizes);
3329 -+ if (r)
3330 -+ return r;
3331 -+ break;
3332 -+ case RADEON_PACKET_TYPE2:
3333 -+ p->idx += pkt.count + 2;
3334 -+ break;
3335 -+ default:
3336 -+ DRM_ERROR("Unknown packet type %d !\n", pkt.type);
3337 -+ return -EINVAL;
3338 -+ }
3339 -+ } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
3340 -+ return 0;
3341 -+}
3342 -+
3343 -+static int radeon_uvd_send_msg(struct radeon_device *rdev,
3344 -+ int ring, struct radeon_bo *bo,
3345 -+ struct radeon_fence **fence)
3346 -+{
3347 -+ struct ttm_validate_buffer tv;
3348 -+ struct list_head head;
3349 -+ struct radeon_ib ib;
3350 -+ uint64_t addr;
3351 -+ int i, r;
3352 -+
3353 -+ memset(&tv, 0, sizeof(tv));
3354 -+ tv.bo = &bo->tbo;
3355 -+
3356 -+ INIT_LIST_HEAD(&head);
3357 -+ list_add(&tv.head, &head);
3358 -+
3359 -+ r = ttm_eu_reserve_buffers(&head);
3360 -+ if (r)
3361 -+ return r;
3362 -+
3363 -+ radeon_ttm_placement_from_domain(bo, RADEON_GEM_DOMAIN_VRAM);
3364 -+ radeon_uvd_force_into_uvd_segment(bo);
3365 -+
3366 -+ r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
3367 -+ if (r) {
3368 -+ ttm_eu_backoff_reservation(&head);
3369 -+ return r;
3370 -+ }
3371 -+
3372 -+ r = radeon_ib_get(rdev, ring, &ib, NULL, 16);
3373 -+ if (r) {
3374 -+ ttm_eu_backoff_reservation(&head);
3375 -+ return r;
3376 -+ }
3377 -+
3378 -+ addr = radeon_bo_gpu_offset(bo);
3379 -+ ib.ptr[0] = PACKET0(UVD_GPCOM_VCPU_DATA0, 0);
3380 -+ ib.ptr[1] = addr;
3381 -+ ib.ptr[2] = PACKET0(UVD_GPCOM_VCPU_DATA1, 0);
3382 -+ ib.ptr[3] = addr >> 32;
3383 -+ ib.ptr[4] = PACKET0(UVD_GPCOM_VCPU_CMD, 0);
3384 -+ ib.ptr[5] = 0;
3385 -+ for (i = 6; i < 16; ++i)
3386 -+ ib.ptr[i] = PACKET2(0);
3387 -+ ib.length_dw = 16;
3388 -+
3389 -+ r = radeon_ib_schedule(rdev, &ib, NULL);
3390 -+ if (r) {
3391 -+ ttm_eu_backoff_reservation(&head);
3392 -+ return r;
3393 -+ }
3394 -+ ttm_eu_fence_buffer_objects(&head, ib.fence);
3395 -+
3396 -+ if (fence)
3397 -+ *fence = radeon_fence_ref(ib.fence);
3398 -+
3399 -+ radeon_ib_free(rdev, &ib);
3400 -+ radeon_bo_unref(&bo);
3401 -+ return 0;
3402 -+}
3403 -+
3404 -+/* multiple fence commands without any stream commands in between can
3405 -+ crash the vcpu so just try to emmit a dummy create/destroy msg to
3406 -+ avoid this */
3407 -+int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring,
3408 -+ uint32_t handle, struct radeon_fence **fence)
3409 -+{
3410 -+ struct radeon_bo *bo;
3411 -+ uint32_t *msg;
3412 -+ int r, i;
3413 -+
3414 -+ r = radeon_bo_create(rdev, 1024, PAGE_SIZE, true,
3415 -+ RADEON_GEM_DOMAIN_VRAM, NULL, &bo);
3416 -+ if (r)
3417 -+ return r;
3418 -+
3419 -+ r = radeon_bo_reserve(bo, false);
3420 -+ if (r) {
3421 -+ radeon_bo_unref(&bo);
3422 -+ return r;
3423 -+ }
3424 -+
3425 -+ r = radeon_bo_kmap(bo, (void **)&msg);
3426 -+ if (r) {
3427 -+ radeon_bo_unreserve(bo);
3428 -+ radeon_bo_unref(&bo);
3429 -+ return r;
3430 -+ }
3431 -+
3432 -+ /* stitch together an UVD create msg */
3433 -+ msg[0] = 0x00000de4;
3434 -+ msg[1] = 0x00000000;
3435 -+ msg[2] = handle;
3436 -+ msg[3] = 0x00000000;
3437 -+ msg[4] = 0x00000000;
3438 -+ msg[5] = 0x00000000;
3439 -+ msg[6] = 0x00000000;
3440 -+ msg[7] = 0x00000780;
3441 -+ msg[8] = 0x00000440;
3442 -+ msg[9] = 0x00000000;
3443 -+ msg[10] = 0x01b37000;
3444 -+ for (i = 11; i < 1024; ++i)
3445 -+ msg[i] = 0x0;
3446 -+
3447 -+ radeon_bo_kunmap(bo);
3448 -+ radeon_bo_unreserve(bo);
3449 -+
3450 -+ return radeon_uvd_send_msg(rdev, ring, bo, fence);
3451 -+}
3452 -+
3453 -+int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring,
3454 -+ uint32_t handle, struct radeon_fence **fence)
3455 -+{
3456 -+ struct radeon_bo *bo;
3457 -+ uint32_t *msg;
3458 -+ int r, i;
3459 -+
3460 -+ r = radeon_bo_create(rdev, 1024, PAGE_SIZE, true,
3461 -+ RADEON_GEM_DOMAIN_VRAM, NULL, &bo);
3462 -+ if (r)
3463 -+ return r;
3464 -+
3465 -+ r = radeon_bo_reserve(bo, false);
3466 -+ if (r) {
3467 -+ radeon_bo_unref(&bo);
3468 -+ return r;
3469 -+ }
3470 -+
3471 -+ r = radeon_bo_kmap(bo, (void **)&msg);
3472 -+ if (r) {
3473 -+ radeon_bo_unreserve(bo);
3474 -+ radeon_bo_unref(&bo);
3475 -+ return r;
3476 -+ }
3477 -+
3478 -+ /* stitch together an UVD destroy msg */
3479 -+ msg[0] = 0x00000de4;
3480 -+ msg[1] = 0x00000002;
3481 -+ msg[2] = handle;
3482 -+ msg[3] = 0x00000000;
3483 -+ for (i = 4; i < 1024; ++i)
3484 -+ msg[i] = 0x0;
3485 -+
3486 -+ radeon_bo_kunmap(bo);
3487 -+ radeon_bo_unreserve(bo);
3488 -+
3489 -+ return radeon_uvd_send_msg(rdev, ring, bo, fence);
3490 -+}
3491 -+
3492 -+static void radeon_uvd_idle_work_handler(struct work_struct *work)
3493 -+{
3494 -+ struct radeon_device *rdev =
3495 -+ container_of(work, struct radeon_device, uvd.idle_work.work);
3496 -+
3497 -+ if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0)
3498 -+ radeon_set_uvd_clocks(rdev, 0, 0);
3499 -+ else
3500 -+ schedule_delayed_work(&rdev->uvd.idle_work,
3501 -+ msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
3502 -+}
3503 -+
3504 -+void radeon_uvd_note_usage(struct radeon_device *rdev)
3505 -+{
3506 -+ bool set_clocks = !cancel_delayed_work_sync(&rdev->uvd.idle_work);
3507 -+ set_clocks &= schedule_delayed_work(&rdev->uvd.idle_work,
3508 -+ msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
3509 -+ if (set_clocks)
3510 -+ radeon_set_uvd_clocks(rdev, 53300, 40000);
3511 -+}