Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5078 serge 1
/*
2
 * Copyright 2013 Advanced Micro Devices, Inc.
3
 * All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the
7
 * "Software"), to deal in the Software without restriction, including
8
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * distribute, sub license, and/or sell copies of the Software, and to
10
 * permit persons to whom the Software is furnished to do so, subject to
11
 * the following conditions:
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20
 *
21
 * The above copyright notice and this permission notice (including the
22
 * next paragraph) shall be included in all copies or substantial portions
23
 * of the Software.
24
 *
25
 * Authors: Christian König 
26
 */
27
 
28
#include 
29
#include 
30
#include "radeon.h"
31
#include "radeon_asic.h"
32
#include "sid.h"
33
 
34
/**
35
 * vce_v1_0_get_rptr - get read pointer
36
 *
37
 * @rdev: radeon_device pointer
38
 * @ring: radeon_ring pointer
39
 *
40
 * Returns the current hardware read pointer
41
 */
42
uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev,
43
			   struct radeon_ring *ring)
44
{
45
	if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
46
		return RREG32(VCE_RB_RPTR);
47
	else
48
		return RREG32(VCE_RB_RPTR2);
49
}
50
 
51
/**
52
 * vce_v1_0_get_wptr - get write pointer
53
 *
54
 * @rdev: radeon_device pointer
55
 * @ring: radeon_ring pointer
56
 *
57
 * Returns the current hardware write pointer
58
 */
59
uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
60
			   struct radeon_ring *ring)
61
{
62
	if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
63
		return RREG32(VCE_RB_WPTR);
64
	else
65
		return RREG32(VCE_RB_WPTR2);
66
}
67
 
68
/**
69
 * vce_v1_0_set_wptr - set write pointer
70
 *
71
 * @rdev: radeon_device pointer
72
 * @ring: radeon_ring pointer
73
 *
74
 * Commits the write pointer to the hardware
75
 */
76
void vce_v1_0_set_wptr(struct radeon_device *rdev,
77
		       struct radeon_ring *ring)
78
{
79
	if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
80
		WREG32(VCE_RB_WPTR, ring->wptr);
81
	else
82
		WREG32(VCE_RB_WPTR2, ring->wptr);
83
}
84
 
85
/**
86
 * vce_v1_0_start - start VCE block
87
 *
88
 * @rdev: radeon_device pointer
89
 *
90
 * Setup and start the VCE block
91
 */
92
int vce_v1_0_start(struct radeon_device *rdev)
93
{
94
	struct radeon_ring *ring;
95
	int i, j, r;
96
 
97
	/* set BUSY flag */
98
	WREG32_P(VCE_STATUS, 1, ~1);
99
 
100
	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
101
	WREG32(VCE_RB_RPTR, ring->wptr);
102
	WREG32(VCE_RB_WPTR, ring->wptr);
103
	WREG32(VCE_RB_BASE_LO, ring->gpu_addr);
104
	WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
105
	WREG32(VCE_RB_SIZE, ring->ring_size / 4);
106
 
107
	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
108
	WREG32(VCE_RB_RPTR2, ring->wptr);
109
	WREG32(VCE_RB_WPTR2, ring->wptr);
110
	WREG32(VCE_RB_BASE_LO2, ring->gpu_addr);
111
	WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
112
	WREG32(VCE_RB_SIZE2, ring->ring_size / 4);
113
 
114
	WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN);
115
 
116
	WREG32_P(VCE_SOFT_RESET,
117
		 VCE_ECPU_SOFT_RESET |
118
		 VCE_FME_SOFT_RESET, ~(
119
		 VCE_ECPU_SOFT_RESET |
120
		 VCE_FME_SOFT_RESET));
121
 
122
	mdelay(100);
123
 
124
	WREG32_P(VCE_SOFT_RESET, 0, ~(
125
		 VCE_ECPU_SOFT_RESET |
126
		 VCE_FME_SOFT_RESET));
127
 
128
	for (i = 0; i < 10; ++i) {
129
		uint32_t status;
130
		for (j = 0; j < 100; ++j) {
131
			status = RREG32(VCE_STATUS);
132
			if (status & 2)
133
				break;
134
			mdelay(10);
135
		}
136
		r = 0;
137
		if (status & 2)
138
			break;
139
 
140
		DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
141
		WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET);
142
		mdelay(10);
143
		WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET);
144
		mdelay(10);
145
		r = -1;
146
	}
147
 
148
	/* clear BUSY flag */
149
	WREG32_P(VCE_STATUS, 0, ~1);
150
 
151
	if (r) {
152
		DRM_ERROR("VCE not responding, giving up!!!\n");
153
		return r;
154
	}
155
 
156
	return 0;
157
}
158
 
159
int vce_v1_0_init(struct radeon_device *rdev)
160
{
161
	struct radeon_ring *ring;
162
	int r;
163
 
164
	r = vce_v1_0_start(rdev);
165
	if (r)
166
		return r;
167
 
168
	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
169
	ring->ready = true;
170
	r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring);
171
	if (r) {
172
		ring->ready = false;
173
		return r;
174
	}
175
 
176
	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
177
	ring->ready = true;
178
	r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring);
179
	if (r) {
180
		ring->ready = false;
181
		return r;
182
	}
183
 
184
	DRM_INFO("VCE initialized successfully.\n");
185
 
186
	return 0;
187
}