Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5271 Rev 6104
1
/*
1
/*
2
 * Copyright 2013 Advanced Micro Devices, Inc.
2
 * Copyright 2013 Advanced Micro Devices, Inc.
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice shall be included in
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
12
 * all copies or substantial portions of the Software.
13
 *
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 * OTHER DEALINGS IN THE SOFTWARE.
20
 * OTHER DEALINGS IN THE SOFTWARE.
21
 *
21
 *
22
 * Authors: Christian König 
22
 * Authors: Christian König 
23
 */
23
 */
-
 
24
 
24
 
25
#include 
25
#include 
26
#include 
26
#include "radeon.h"
27
#include "radeon.h"
27
#include "radeon_asic.h"
28
#include "radeon_asic.h"
28
#include "r600d.h"
29
#include "r600d.h"
29
 
30
 
30
/**
31
/**
31
 * uvd_v1_0_get_rptr - get read pointer
32
 * uvd_v1_0_get_rptr - get read pointer
32
 *
33
 *
33
 * @rdev: radeon_device pointer
34
 * @rdev: radeon_device pointer
34
 * @ring: radeon_ring pointer
35
 * @ring: radeon_ring pointer
35
 *
36
 *
36
 * Returns the current hardware read pointer
37
 * Returns the current hardware read pointer
37
 */
38
 */
38
uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
39
uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
39
			   struct radeon_ring *ring)
40
			   struct radeon_ring *ring)
40
{
41
{
41
	return RREG32(UVD_RBC_RB_RPTR);
42
	return RREG32(UVD_RBC_RB_RPTR);
42
}
43
}
43
 
44
 
44
/**
45
/**
45
 * uvd_v1_0_get_wptr - get write pointer
46
 * uvd_v1_0_get_wptr - get write pointer
46
 *
47
 *
47
 * @rdev: radeon_device pointer
48
 * @rdev: radeon_device pointer
48
 * @ring: radeon_ring pointer
49
 * @ring: radeon_ring pointer
49
 *
50
 *
50
 * Returns the current hardware write pointer
51
 * Returns the current hardware write pointer
51
 */
52
 */
52
uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
53
uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
53
			   struct radeon_ring *ring)
54
			   struct radeon_ring *ring)
54
{
55
{
55
	return RREG32(UVD_RBC_RB_WPTR);
56
	return RREG32(UVD_RBC_RB_WPTR);
56
}
57
}
57
 
58
 
58
/**
59
/**
59
 * uvd_v1_0_set_wptr - set write pointer
60
 * uvd_v1_0_set_wptr - set write pointer
60
 *
61
 *
61
 * @rdev: radeon_device pointer
62
 * @rdev: radeon_device pointer
62
 * @ring: radeon_ring pointer
63
 * @ring: radeon_ring pointer
63
 *
64
 *
64
 * Commits the write pointer to the hardware
65
 * Commits the write pointer to the hardware
65
 */
66
 */
66
void uvd_v1_0_set_wptr(struct radeon_device *rdev,
67
void uvd_v1_0_set_wptr(struct radeon_device *rdev,
67
		       struct radeon_ring *ring)
68
		       struct radeon_ring *ring)
68
{
69
{
69
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);
70
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);
70
}
71
}
71
 
72
 
72
/**
73
/**
73
 * uvd_v1_0_fence_emit - emit an fence & trap command
74
 * uvd_v1_0_fence_emit - emit an fence & trap command
74
 *
75
 *
75
 * @rdev: radeon_device pointer
76
 * @rdev: radeon_device pointer
76
 * @fence: fence to emit
77
 * @fence: fence to emit
77
 *
78
 *
78
 * Write a fence and a trap command to the ring.
79
 * Write a fence and a trap command to the ring.
79
 */
80
 */
80
void uvd_v1_0_fence_emit(struct radeon_device *rdev,
81
void uvd_v1_0_fence_emit(struct radeon_device *rdev,
81
			 struct radeon_fence *fence)
82
			 struct radeon_fence *fence)
82
{
83
{
83
	struct radeon_ring *ring = &rdev->ring[fence->ring];
84
	struct radeon_ring *ring = &rdev->ring[fence->ring];
84
	uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
85
	uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
85
 
86
 
86
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
87
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
87
	radeon_ring_write(ring, addr & 0xffffffff);
88
	radeon_ring_write(ring, addr & 0xffffffff);
88
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
89
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
89
	radeon_ring_write(ring, fence->seq);
90
	radeon_ring_write(ring, fence->seq);
90
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
91
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
91
	radeon_ring_write(ring, 0);
92
	radeon_ring_write(ring, 0);
92
 
93
 
93
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
94
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
94
	radeon_ring_write(ring, 0);
95
	radeon_ring_write(ring, 0);
95
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
96
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
96
	radeon_ring_write(ring, 0);
97
	radeon_ring_write(ring, 0);
97
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
98
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
98
	radeon_ring_write(ring, 2);
99
	radeon_ring_write(ring, 2);
99
	return;
100
	return;
100
}
101
}
101
 
102
 
102
/**
103
/**
103
 * uvd_v1_0_resume - memory controller programming
104
 * uvd_v1_0_resume - memory controller programming
104
 *
105
 *
105
 * @rdev: radeon_device pointer
106
 * @rdev: radeon_device pointer
106
 *
107
 *
107
 * Let the UVD memory controller know it's offsets
108
 * Let the UVD memory controller know it's offsets
108
 */
109
 */
109
int uvd_v1_0_resume(struct radeon_device *rdev)
110
int uvd_v1_0_resume(struct radeon_device *rdev)
110
{
111
{
111
	uint64_t addr;
112
	uint64_t addr;
112
	uint32_t size;
113
	uint32_t size;
113
	int r;
114
	int r;
114
 
115
 
115
	r = radeon_uvd_resume(rdev);
116
	r = radeon_uvd_resume(rdev);
116
	if (r)
117
	if (r)
117
		return r;
118
		return r;
118
 
119
 
119
	/* programm the VCPU memory controller bits 0-27 */
120
	/* programm the VCPU memory controller bits 0-27 */
120
	addr = (rdev->uvd.gpu_addr >> 3) + 16;
121
	addr = (rdev->uvd.gpu_addr >> 3) + 16;
121
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
122
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
122
	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
123
	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
123
	WREG32(UVD_VCPU_CACHE_SIZE0, size);
124
	WREG32(UVD_VCPU_CACHE_SIZE0, size);
124
 
125
 
125
	addr += size;
126
	addr += size;
126
	size = RADEON_UVD_STACK_SIZE >> 3;
127
	size = RADEON_UVD_STACK_SIZE >> 3;
127
	WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
128
	WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
128
	WREG32(UVD_VCPU_CACHE_SIZE1, size);
129
	WREG32(UVD_VCPU_CACHE_SIZE1, size);
129
 
130
 
130
	addr += size;
131
	addr += size;
131
	size = RADEON_UVD_HEAP_SIZE >> 3;
132
	size = RADEON_UVD_HEAP_SIZE >> 3;
132
	WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
133
	WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
133
	WREG32(UVD_VCPU_CACHE_SIZE2, size);
134
	WREG32(UVD_VCPU_CACHE_SIZE2, size);
134
 
135
 
135
	/* bits 28-31 */
136
	/* bits 28-31 */
136
	addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
137
	addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
137
	WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
138
	WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
138
 
139
 
139
	/* bits 32-39 */
140
	/* bits 32-39 */
140
	addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
141
	addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
141
	WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
142
	WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
142
 
143
 
143
	WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr));
144
	WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr));
144
 
145
 
145
	return 0;
146
	return 0;
146
}
147
}
147
 
148
 
148
/**
149
/**
149
 * uvd_v1_0_init - start and test UVD block
150
 * uvd_v1_0_init - start and test UVD block
150
 *
151
 *
151
 * @rdev: radeon_device pointer
152
 * @rdev: radeon_device pointer
152
 *
153
 *
153
 * Initialize the hardware, boot up the VCPU and do some testing
154
 * Initialize the hardware, boot up the VCPU and do some testing
154
 */
155
 */
155
int uvd_v1_0_init(struct radeon_device *rdev)
156
int uvd_v1_0_init(struct radeon_device *rdev)
156
{
157
{
157
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
158
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
158
	uint32_t tmp;
159
	uint32_t tmp;
159
	int r;
160
	int r;
160
 
161
 
161
	/* raise clocks while booting up the VCPU */
162
	/* raise clocks while booting up the VCPU */
162
	if (rdev->family < CHIP_RV740)
163
	if (rdev->family < CHIP_RV740)
163
		radeon_set_uvd_clocks(rdev, 10000, 10000);
164
		radeon_set_uvd_clocks(rdev, 10000, 10000);
164
	else
165
	else
165
		radeon_set_uvd_clocks(rdev, 53300, 40000);
166
		radeon_set_uvd_clocks(rdev, 53300, 40000);
166
 
167
 
167
	r = uvd_v1_0_start(rdev);
168
	r = uvd_v1_0_start(rdev);
168
	if (r)
169
	if (r)
169
		goto done;
170
		goto done;
170
 
171
 
171
	ring->ready = true;
172
	ring->ready = true;
172
	r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
173
	r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
173
	if (r) {
174
	if (r) {
174
		ring->ready = false;
175
		ring->ready = false;
175
		goto done;
176
		goto done;
176
	}
177
	}
177
 
178
 
178
	r = radeon_ring_lock(rdev, ring, 10);
179
	r = radeon_ring_lock(rdev, ring, 10);
179
	if (r) {
180
	if (r) {
180
		DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
181
		DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
181
		goto done;
182
		goto done;
182
	}
183
	}
183
 
184
 
184
	tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
185
	tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
185
	radeon_ring_write(ring, tmp);
186
	radeon_ring_write(ring, tmp);
186
	radeon_ring_write(ring, 0xFFFFF);
187
	radeon_ring_write(ring, 0xFFFFF);
187
 
188
 
188
	tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
189
	tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
189
	radeon_ring_write(ring, tmp);
190
	radeon_ring_write(ring, tmp);
190
	radeon_ring_write(ring, 0xFFFFF);
191
	radeon_ring_write(ring, 0xFFFFF);
191
 
192
 
192
	tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
193
	tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
193
	radeon_ring_write(ring, tmp);
194
	radeon_ring_write(ring, tmp);
194
	radeon_ring_write(ring, 0xFFFFF);
195
	radeon_ring_write(ring, 0xFFFFF);
195
 
196
 
196
	/* Clear timeout status bits */
197
	/* Clear timeout status bits */
197
	radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
198
	radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
198
	radeon_ring_write(ring, 0x8);
199
	radeon_ring_write(ring, 0x8);
199
 
200
 
200
	radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
201
	radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
201
	radeon_ring_write(ring, 3);
202
	radeon_ring_write(ring, 3);
202
 
203
 
203
	radeon_ring_unlock_commit(rdev, ring, false);
204
	radeon_ring_unlock_commit(rdev, ring, false);
204
 
205
 
205
done:
206
done:
206
	/* lower clocks again */
207
	/* lower clocks again */
207
	radeon_set_uvd_clocks(rdev, 0, 0);
208
	radeon_set_uvd_clocks(rdev, 0, 0);
208
 
209
 
209
	if (!r) {
210
	if (!r) {
210
		switch (rdev->family) {
211
		switch (rdev->family) {
211
		case CHIP_RV610:
212
		case CHIP_RV610:
212
		case CHIP_RV630:
213
		case CHIP_RV630:
213
		case CHIP_RV620:
214
		case CHIP_RV620:
214
			/* 64byte granularity workaround */
215
			/* 64byte granularity workaround */
215
			WREG32(MC_CONFIG, 0);
216
			WREG32(MC_CONFIG, 0);
216
			WREG32(MC_CONFIG, 1 << 4);
217
			WREG32(MC_CONFIG, 1 << 4);
217
			WREG32(RS_DQ_RD_RET_CONF, 0x3f);
218
			WREG32(RS_DQ_RD_RET_CONF, 0x3f);
218
			WREG32(MC_CONFIG, 0x1f);
219
			WREG32(MC_CONFIG, 0x1f);
219
 
220
 
220
			/* fall through */
221
			/* fall through */
221
		case CHIP_RV670:
222
		case CHIP_RV670:
222
		case CHIP_RV635:
223
		case CHIP_RV635:
223
 
224
 
224
			/* write clean workaround */
225
			/* write clean workaround */
225
			WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
226
			WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
226
			break;
227
			break;
227
 
228
 
228
		default:
229
		default:
229
			/* TODO: Do we need more? */
230
			/* TODO: Do we need more? */
230
			break;
231
			break;
231
		}
232
		}
232
 
233
 
233
		DRM_INFO("UVD initialized successfully.\n");
234
		DRM_INFO("UVD initialized successfully.\n");
234
	}
235
	}
235
 
236
 
236
	return r;
237
	return r;
237
}
238
}
238
 
239
 
239
/**
240
/**
240
 * uvd_v1_0_fini - stop the hardware block
241
 * uvd_v1_0_fini - stop the hardware block
241
 *
242
 *
242
 * @rdev: radeon_device pointer
243
 * @rdev: radeon_device pointer
243
 *
244
 *
244
 * Stop the UVD block, mark ring as not ready any more
245
 * Stop the UVD block, mark ring as not ready any more
245
 */
246
 */
246
void uvd_v1_0_fini(struct radeon_device *rdev)
247
void uvd_v1_0_fini(struct radeon_device *rdev)
247
{
248
{
248
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
249
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
249
 
250
 
250
	uvd_v1_0_stop(rdev);
251
	uvd_v1_0_stop(rdev);
251
	ring->ready = false;
252
	ring->ready = false;
252
}
253
}
253
 
254
 
254
/**
255
/**
255
 * uvd_v1_0_start - start UVD block
256
 * uvd_v1_0_start - start UVD block
256
 *
257
 *
257
 * @rdev: radeon_device pointer
258
 * @rdev: radeon_device pointer
258
 *
259
 *
259
 * Setup and start the UVD block
260
 * Setup and start the UVD block
260
 */
261
 */
261
int uvd_v1_0_start(struct radeon_device *rdev)
262
int uvd_v1_0_start(struct radeon_device *rdev)
262
{
263
{
263
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
264
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
264
	uint32_t rb_bufsz;
265
	uint32_t rb_bufsz;
265
	int i, j, r;
266
	int i, j, r;
266
 
267
 
267
	/* disable byte swapping */
268
	/* disable byte swapping */
268
	u32 lmi_swap_cntl = 0;
269
	u32 lmi_swap_cntl = 0;
269
	u32 mp_swap_cntl = 0;
270
	u32 mp_swap_cntl = 0;
270
 
271
 
271
	/* disable clock gating */
272
	/* disable clock gating */
272
	WREG32(UVD_CGC_GATE, 0);
273
	WREG32(UVD_CGC_GATE, 0);
273
 
274
 
274
	/* disable interupt */
275
	/* disable interupt */
275
	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
276
	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
276
 
277
 
277
	/* Stall UMC and register bus before resetting VCPU */
278
	/* Stall UMC and register bus before resetting VCPU */
278
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
279
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
279
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
280
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
280
	mdelay(1);
281
	mdelay(1);
281
 
282
 
282
	/* put LMI, VCPU, RBC etc... into reset */
283
	/* put LMI, VCPU, RBC etc... into reset */
283
	WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
284
	WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
284
	       LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
285
	       LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
285
	       CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
286
	       CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
286
	mdelay(5);
287
	mdelay(5);
287
 
288
 
288
	/* take UVD block out of reset */
289
	/* take UVD block out of reset */
289
	WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
290
	WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
290
	mdelay(5);
291
	mdelay(5);
291
 
292
 
292
	/* initialize UVD memory controller */
293
	/* initialize UVD memory controller */
293
	WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
294
	WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
294
			     (1 << 21) | (1 << 9) | (1 << 20));
295
			     (1 << 21) | (1 << 9) | (1 << 20));
295
 
296
 
296
#ifdef __BIG_ENDIAN
297
#ifdef __BIG_ENDIAN
297
	/* swap (8 in 32) RB and IB */
298
	/* swap (8 in 32) RB and IB */
298
	lmi_swap_cntl = 0xa;
299
	lmi_swap_cntl = 0xa;
299
	mp_swap_cntl = 0;
300
	mp_swap_cntl = 0;
300
#endif
301
#endif
301
	WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
302
	WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
302
	WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
303
	WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
303
 
304
 
304
	WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
305
	WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
305
	WREG32(UVD_MPC_SET_MUXA1, 0x0);
306
	WREG32(UVD_MPC_SET_MUXA1, 0x0);
306
	WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
307
	WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
307
	WREG32(UVD_MPC_SET_MUXB1, 0x0);
308
	WREG32(UVD_MPC_SET_MUXB1, 0x0);
308
	WREG32(UVD_MPC_SET_ALU, 0);
309
	WREG32(UVD_MPC_SET_ALU, 0);
309
	WREG32(UVD_MPC_SET_MUX, 0x88);
310
	WREG32(UVD_MPC_SET_MUX, 0x88);
310
 
311
 
311
	/* take all subblocks out of reset, except VCPU */
312
	/* take all subblocks out of reset, except VCPU */
312
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
313
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
313
	mdelay(5);
314
	mdelay(5);
314
 
315
 
315
	/* enable VCPU clock */
316
	/* enable VCPU clock */
316
	WREG32(UVD_VCPU_CNTL,  1 << 9);
317
	WREG32(UVD_VCPU_CNTL,  1 << 9);
317
 
318
 
318
	/* enable UMC */
319
	/* enable UMC */
319
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
320
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
320
 
321
 
321
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
322
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
322
 
323
 
323
	/* boot up the VCPU */
324
	/* boot up the VCPU */
324
	WREG32(UVD_SOFT_RESET, 0);
325
	WREG32(UVD_SOFT_RESET, 0);
325
	mdelay(10);
326
	mdelay(10);
326
 
327
 
327
	for (i = 0; i < 10; ++i) {
328
	for (i = 0; i < 10; ++i) {
328
		uint32_t status;
329
		uint32_t status;
329
		for (j = 0; j < 100; ++j) {
330
		for (j = 0; j < 100; ++j) {
330
			status = RREG32(UVD_STATUS);
331
			status = RREG32(UVD_STATUS);
331
			if (status & 2)
332
			if (status & 2)
332
				break;
333
				break;
333
			mdelay(10);
334
			mdelay(10);
334
		}
335
		}
335
		r = 0;
336
		r = 0;
336
		if (status & 2)
337
		if (status & 2)
337
			break;
338
			break;
338
 
339
 
339
		DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
340
		DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
340
		WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
341
		WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
341
		mdelay(10);
342
		mdelay(10);
342
		WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
343
		WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
343
		mdelay(10);
344
		mdelay(10);
344
		r = -1;
345
		r = -1;
345
	}
346
	}
346
 
347
 
347
	if (r) {
348
	if (r) {
348
		DRM_ERROR("UVD not responding, giving up!!!\n");
349
		DRM_ERROR("UVD not responding, giving up!!!\n");
349
		return r;
350
		return r;
350
	}
351
	}
351
 
352
 
352
	/* enable interupt */
353
	/* enable interupt */
353
	WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
354
	WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
354
 
355
 
355
	/* force RBC into idle state */
356
	/* force RBC into idle state */
356
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
357
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
357
 
358
 
358
	/* Set the write pointer delay */
359
	/* Set the write pointer delay */
359
	WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
360
	WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
360
 
361
 
361
	/* programm the 4GB memory segment for rptr and ring buffer */
362
	/* programm the 4GB memory segment for rptr and ring buffer */
362
	WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
363
	WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
363
				   (0x7 << 16) | (0x1 << 31));
364
				   (0x7 << 16) | (0x1 << 31));
364
 
365
 
365
	/* Initialize the ring buffer's read and write pointers */
366
	/* Initialize the ring buffer's read and write pointers */
366
	WREG32(UVD_RBC_RB_RPTR, 0x0);
367
	WREG32(UVD_RBC_RB_RPTR, 0x0);
367
 
368
 
368
	ring->wptr = RREG32(UVD_RBC_RB_RPTR);
369
	ring->wptr = RREG32(UVD_RBC_RB_RPTR);
369
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);
370
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);
370
 
371
 
371
	/* set the ring address */
372
	/* set the ring address */
372
	WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
373
	WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
373
 
374
 
374
	/* Set ring buffer size */
375
	/* Set ring buffer size */
375
	rb_bufsz = order_base_2(ring->ring_size);
376
	rb_bufsz = order_base_2(ring->ring_size);
376
	rb_bufsz = (0x1 << 8) | rb_bufsz;
377
	rb_bufsz = (0x1 << 8) | rb_bufsz;
377
	WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
378
	WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
378
 
379
 
379
	return 0;
380
	return 0;
380
}
381
}
381
 
382
 
382
/**
383
/**
383
 * uvd_v1_0_stop - stop UVD block
384
 * uvd_v1_0_stop - stop UVD block
384
 *
385
 *
385
 * @rdev: radeon_device pointer
386
 * @rdev: radeon_device pointer
386
 *
387
 *
387
 * stop the UVD block
388
 * stop the UVD block
388
 */
389
 */
389
void uvd_v1_0_stop(struct radeon_device *rdev)
390
void uvd_v1_0_stop(struct radeon_device *rdev)
390
{
391
{
391
	/* force RBC into idle state */
392
	/* force RBC into idle state */
392
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
393
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
393
 
394
 
394
	/* Stall UMC and register bus before resetting VCPU */
395
	/* Stall UMC and register bus before resetting VCPU */
395
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
396
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
396
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
397
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
397
	mdelay(1);
398
	mdelay(1);
398
 
399
 
399
	/* put VCPU into reset */
400
	/* put VCPU into reset */
400
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
401
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
401
	mdelay(5);
402
	mdelay(5);
402
 
403
 
403
	/* disable VCPU clock */
404
	/* disable VCPU clock */
404
	WREG32(UVD_VCPU_CNTL, 0x0);
405
	WREG32(UVD_VCPU_CNTL, 0x0);
405
 
406
 
406
	/* Unstall UMC and register bus */
407
	/* Unstall UMC and register bus */
407
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
408
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
408
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
409
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
409
}
410
}
410
 
411
 
411
/**
412
/**
412
 * uvd_v1_0_ring_test - register write test
413
 * uvd_v1_0_ring_test - register write test
413
 *
414
 *
414
 * @rdev: radeon_device pointer
415
 * @rdev: radeon_device pointer
415
 * @ring: radeon_ring pointer
416
 * @ring: radeon_ring pointer
416
 *
417
 *
417
 * Test if we can successfully write to the context register
418
 * Test if we can successfully write to the context register
418
 */
419
 */
419
int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
420
int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
420
{
421
{
421
	uint32_t tmp = 0;
422
	uint32_t tmp = 0;
422
	unsigned i;
423
	unsigned i;
423
	int r;
424
	int r;
424
 
425
 
425
	WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
426
	WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
426
	r = radeon_ring_lock(rdev, ring, 3);
427
	r = radeon_ring_lock(rdev, ring, 3);
427
	if (r) {
428
	if (r) {
428
		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
429
		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
429
			  ring->idx, r);
430
			  ring->idx, r);
430
		return r;
431
		return r;
431
	}
432
	}
432
	radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
433
	radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
433
	radeon_ring_write(ring, 0xDEADBEEF);
434
	radeon_ring_write(ring, 0xDEADBEEF);
434
	radeon_ring_unlock_commit(rdev, ring, false);
435
	radeon_ring_unlock_commit(rdev, ring, false);
435
	for (i = 0; i < rdev->usec_timeout; i++) {
436
	for (i = 0; i < rdev->usec_timeout; i++) {
436
		tmp = RREG32(UVD_CONTEXT_ID);
437
		tmp = RREG32(UVD_CONTEXT_ID);
437
		if (tmp == 0xDEADBEEF)
438
		if (tmp == 0xDEADBEEF)
438
			break;
439
			break;
439
		DRM_UDELAY(1);
440
		DRM_UDELAY(1);
440
	}
441
	}
441
 
442
 
442
	if (i < rdev->usec_timeout) {
443
	if (i < rdev->usec_timeout) {
443
		DRM_INFO("ring test on %d succeeded in %d usecs\n",
444
		DRM_INFO("ring test on %d succeeded in %d usecs\n",
444
			 ring->idx, i);
445
			 ring->idx, i);
445
	} else {
446
	} else {
446
		DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
447
		DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
447
			  ring->idx, tmp);
448
			  ring->idx, tmp);
448
		r = -EINVAL;
449
		r = -EINVAL;
449
	}
450
	}
450
	return r;
451
	return r;
451
}
452
}
452
 
453
 
453
/**
454
/**
454
 * uvd_v1_0_semaphore_emit - emit semaphore command
455
 * uvd_v1_0_semaphore_emit - emit semaphore command
455
 *
456
 *
456
 * @rdev: radeon_device pointer
457
 * @rdev: radeon_device pointer
457
 * @ring: radeon_ring pointer
458
 * @ring: radeon_ring pointer
458
 * @semaphore: semaphore to emit commands for
459
 * @semaphore: semaphore to emit commands for
459
 * @emit_wait: true if we should emit a wait command
460
 * @emit_wait: true if we should emit a wait command
460
 *
461
 *
461
 * Emit a semaphore command (either wait or signal) to the UVD ring.
462
 * Emit a semaphore command (either wait or signal) to the UVD ring.
462
 */
463
 */
463
bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
464
bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
464
			     struct radeon_ring *ring,
465
			     struct radeon_ring *ring,
465
			     struct radeon_semaphore *semaphore,
466
			     struct radeon_semaphore *semaphore,
466
			     bool emit_wait)
467
			     bool emit_wait)
467
{
468
{
468
	uint64_t addr = semaphore->gpu_addr;
469
	/* disable semaphores for UVD V1 hardware */
469
 
-
 
470
	radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
-
 
471
	radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
-
 
472
 
-
 
473
	radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
-
 
474
	radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
-
 
475
 
-
 
476
	radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
-
 
477
	radeon_ring_write(ring, emit_wait ? 1 : 0);
-
 
478
 
-
 
479
	return true;
470
	return false;
480
}
471
}
481
 
472
 
482
/**
473
/**
483
 * uvd_v1_0_ib_execute - execute indirect buffer
474
 * uvd_v1_0_ib_execute - execute indirect buffer
484
 *
475
 *
485
 * @rdev: radeon_device pointer
476
 * @rdev: radeon_device pointer
486
 * @ib: indirect buffer to execute
477
 * @ib: indirect buffer to execute
487
 *
478
 *
488
 * Write ring commands to execute the indirect buffer
479
 * Write ring commands to execute the indirect buffer
489
 */
480
 */
490
void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
481
void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
491
{
482
{
492
	struct radeon_ring *ring = &rdev->ring[ib->ring];
483
	struct radeon_ring *ring = &rdev->ring[ib->ring];
493
 
484
 
494
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
485
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
495
	radeon_ring_write(ring, ib->gpu_addr);
486
	radeon_ring_write(ring, ib->gpu_addr);
496
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
487
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
497
	radeon_ring_write(ring, ib->length_dw);
488
	radeon_ring_write(ring, ib->length_dw);
498
}
489
}
499
 
490
 
500
/**
491
/**
501
 * uvd_v1_0_ib_test - test ib execution
492
 * uvd_v1_0_ib_test - test ib execution
502
 *
493
 *
503
 * @rdev: radeon_device pointer
494
 * @rdev: radeon_device pointer
504
 * @ring: radeon_ring pointer
495
 * @ring: radeon_ring pointer
505
 *
496
 *
506
 * Test if we can successfully execute an IB
497
 * Test if we can successfully execute an IB
507
 */
498
 */
508
int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
499
int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
509
{
500
{
510
	struct radeon_fence *fence = NULL;
501
	struct radeon_fence *fence = NULL;
511
	int r;
502
	int r;
512
 
503
 
513
	if (rdev->family < CHIP_RV740)
504
	if (rdev->family < CHIP_RV740)
514
		r = radeon_set_uvd_clocks(rdev, 10000, 10000);
505
		r = radeon_set_uvd_clocks(rdev, 10000, 10000);
515
	else
506
	else
516
		r = radeon_set_uvd_clocks(rdev, 53300, 40000);
507
		r = radeon_set_uvd_clocks(rdev, 53300, 40000);
517
	if (r) {
508
	if (r) {
518
		DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
509
		DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
519
		return r;
510
		return r;
520
	}
511
	}
521
 
512
 
522
	r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
513
	r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
523
	if (r) {
514
	if (r) {
524
		DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
515
		DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
525
		goto error;
516
		goto error;
526
	}
517
	}
527
 
518
 
528
	r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
519
	r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
529
	if (r) {
520
	if (r) {
530
		DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
521
		DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
531
		goto error;
522
		goto error;
532
	}
523
	}
533
 
524
 
534
	r = radeon_fence_wait(fence, false);
525
	r = radeon_fence_wait(fence, false);
535
	if (r) {
526
	if (r) {
536
		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
527
		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
537
		goto error;
528
		goto error;
538
	}
529
	}
539
	DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
530
	DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
540
error:
531
error:
541
	radeon_fence_unref(&fence);
532
	radeon_fence_unref(&fence);
542
	radeon_set_uvd_clocks(rdev, 0, 0);
533
	radeon_set_uvd_clocks(rdev, 0, 0);
543
	return r;
534
	return r;
544
}
535
}