Subversion Repositories Kolibri OS

Rev

Rev 2005 | Rev 2997 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1990 serge 1
/*
2
 * Copyright 2010 Advanced Micro Devices, Inc.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
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
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
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,
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
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
20
 * OTHER DEALINGS IN THE SOFTWARE.
21
 *
22
 * Authors: Alex Deucher
23
 */
24
#include 
25
//#include 
26
#include 
27
#include "drmP.h"
28
#include "radeon.h"
29
#include "radeon_asic.h"
30
#include "radeon_drm.h"
31
#include "nid.h"
32
#include "atom.h"
33
#include "ni_reg.h"
2004 serge 34
#include "cayman_blit_shaders.h"
1990 serge 35
 
36
extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
37
extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
38
extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
39
extern void evergreen_mc_program(struct radeon_device *rdev);
40
extern void evergreen_irq_suspend(struct radeon_device *rdev);
41
extern int evergreen_mc_init(struct radeon_device *rdev);
42
 
43
#define EVERGREEN_PFP_UCODE_SIZE 1120
44
#define EVERGREEN_PM4_UCODE_SIZE 1376
45
#define EVERGREEN_RLC_UCODE_SIZE 768
46
#define BTC_MC_UCODE_SIZE 6024
47
 
48
#define CAYMAN_PFP_UCODE_SIZE 2176
49
#define CAYMAN_PM4_UCODE_SIZE 2176
50
#define CAYMAN_RLC_UCODE_SIZE 1024
51
#define CAYMAN_MC_UCODE_SIZE 6037
52
 
53
/* Firmware Names */
54
MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
55
MODULE_FIRMWARE("radeon/BARTS_me.bin");
56
MODULE_FIRMWARE("radeon/BARTS_mc.bin");
57
MODULE_FIRMWARE("radeon/BTC_rlc.bin");
58
MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
59
MODULE_FIRMWARE("radeon/TURKS_me.bin");
60
MODULE_FIRMWARE("radeon/TURKS_mc.bin");
61
MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
62
MODULE_FIRMWARE("radeon/CAICOS_me.bin");
63
MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
64
MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
65
MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
66
MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
67
MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
68
 
69
#define BTC_IO_MC_REGS_SIZE 29
70
 
71
static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
72
	{0x00000077, 0xff010100},
73
	{0x00000078, 0x00000000},
74
	{0x00000079, 0x00001434},
75
	{0x0000007a, 0xcc08ec08},
76
	{0x0000007b, 0x00040000},
77
	{0x0000007c, 0x000080c0},
78
	{0x0000007d, 0x09000000},
79
	{0x0000007e, 0x00210404},
80
	{0x00000081, 0x08a8e800},
81
	{0x00000082, 0x00030444},
82
	{0x00000083, 0x00000000},
83
	{0x00000085, 0x00000001},
84
	{0x00000086, 0x00000002},
85
	{0x00000087, 0x48490000},
86
	{0x00000088, 0x20244647},
87
	{0x00000089, 0x00000005},
88
	{0x0000008b, 0x66030000},
89
	{0x0000008c, 0x00006603},
90
	{0x0000008d, 0x00000100},
91
	{0x0000008f, 0x00001c0a},
92
	{0x00000090, 0xff000001},
93
	{0x00000094, 0x00101101},
94
	{0x00000095, 0x00000fff},
95
	{0x00000096, 0x00116fff},
96
	{0x00000097, 0x60010000},
97
	{0x00000098, 0x10010000},
98
	{0x00000099, 0x00006000},
99
	{0x0000009a, 0x00001000},
100
	{0x0000009f, 0x00946a00}
101
};
102
 
103
static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
104
	{0x00000077, 0xff010100},
105
	{0x00000078, 0x00000000},
106
	{0x00000079, 0x00001434},
107
	{0x0000007a, 0xcc08ec08},
108
	{0x0000007b, 0x00040000},
109
	{0x0000007c, 0x000080c0},
110
	{0x0000007d, 0x09000000},
111
	{0x0000007e, 0x00210404},
112
	{0x00000081, 0x08a8e800},
113
	{0x00000082, 0x00030444},
114
	{0x00000083, 0x00000000},
115
	{0x00000085, 0x00000001},
116
	{0x00000086, 0x00000002},
117
	{0x00000087, 0x48490000},
118
	{0x00000088, 0x20244647},
119
	{0x00000089, 0x00000005},
120
	{0x0000008b, 0x66030000},
121
	{0x0000008c, 0x00006603},
122
	{0x0000008d, 0x00000100},
123
	{0x0000008f, 0x00001c0a},
124
	{0x00000090, 0xff000001},
125
	{0x00000094, 0x00101101},
126
	{0x00000095, 0x00000fff},
127
	{0x00000096, 0x00116fff},
128
	{0x00000097, 0x60010000},
129
	{0x00000098, 0x10010000},
130
	{0x00000099, 0x00006000},
131
	{0x0000009a, 0x00001000},
132
	{0x0000009f, 0x00936a00}
133
};
134
 
135
static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
136
	{0x00000077, 0xff010100},
137
	{0x00000078, 0x00000000},
138
	{0x00000079, 0x00001434},
139
	{0x0000007a, 0xcc08ec08},
140
	{0x0000007b, 0x00040000},
141
	{0x0000007c, 0x000080c0},
142
	{0x0000007d, 0x09000000},
143
	{0x0000007e, 0x00210404},
144
	{0x00000081, 0x08a8e800},
145
	{0x00000082, 0x00030444},
146
	{0x00000083, 0x00000000},
147
	{0x00000085, 0x00000001},
148
	{0x00000086, 0x00000002},
149
	{0x00000087, 0x48490000},
150
	{0x00000088, 0x20244647},
151
	{0x00000089, 0x00000005},
152
	{0x0000008b, 0x66030000},
153
	{0x0000008c, 0x00006603},
154
	{0x0000008d, 0x00000100},
155
	{0x0000008f, 0x00001c0a},
156
	{0x00000090, 0xff000001},
157
	{0x00000094, 0x00101101},
158
	{0x00000095, 0x00000fff},
159
	{0x00000096, 0x00116fff},
160
	{0x00000097, 0x60010000},
161
	{0x00000098, 0x10010000},
162
	{0x00000099, 0x00006000},
163
	{0x0000009a, 0x00001000},
164
	{0x0000009f, 0x00916a00}
165
};
166
 
167
static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
168
	{0x00000077, 0xff010100},
169
	{0x00000078, 0x00000000},
170
	{0x00000079, 0x00001434},
171
	{0x0000007a, 0xcc08ec08},
172
	{0x0000007b, 0x00040000},
173
	{0x0000007c, 0x000080c0},
174
	{0x0000007d, 0x09000000},
175
	{0x0000007e, 0x00210404},
176
	{0x00000081, 0x08a8e800},
177
	{0x00000082, 0x00030444},
178
	{0x00000083, 0x00000000},
179
	{0x00000085, 0x00000001},
180
	{0x00000086, 0x00000002},
181
	{0x00000087, 0x48490000},
182
	{0x00000088, 0x20244647},
183
	{0x00000089, 0x00000005},
184
	{0x0000008b, 0x66030000},
185
	{0x0000008c, 0x00006603},
186
	{0x0000008d, 0x00000100},
187
	{0x0000008f, 0x00001c0a},
188
	{0x00000090, 0xff000001},
189
	{0x00000094, 0x00101101},
190
	{0x00000095, 0x00000fff},
191
	{0x00000096, 0x00116fff},
192
	{0x00000097, 0x60010000},
193
	{0x00000098, 0x10010000},
194
	{0x00000099, 0x00006000},
195
	{0x0000009a, 0x00001000},
196
	{0x0000009f, 0x00976b00}
197
};
198
 
199
int ni_mc_load_microcode(struct radeon_device *rdev)
200
{
201
	const __be32 *fw_data;
202
	u32 mem_type, running, blackout = 0;
203
	u32 *io_mc_regs;
204
	int i, ucode_size, regs_size;
205
 
206
	if (!rdev->mc_fw)
207
		return -EINVAL;
208
 
209
	switch (rdev->family) {
210
	case CHIP_BARTS:
211
		io_mc_regs = (u32 *)&barts_io_mc_regs;
212
		ucode_size = BTC_MC_UCODE_SIZE;
213
		regs_size = BTC_IO_MC_REGS_SIZE;
214
		break;
215
	case CHIP_TURKS:
216
		io_mc_regs = (u32 *)&turks_io_mc_regs;
217
		ucode_size = BTC_MC_UCODE_SIZE;
218
		regs_size = BTC_IO_MC_REGS_SIZE;
219
		break;
220
	case CHIP_CAICOS:
221
	default:
222
		io_mc_regs = (u32 *)&caicos_io_mc_regs;
223
		ucode_size = BTC_MC_UCODE_SIZE;
224
		regs_size = BTC_IO_MC_REGS_SIZE;
225
		break;
226
	case CHIP_CAYMAN:
227
		io_mc_regs = (u32 *)&cayman_io_mc_regs;
228
		ucode_size = CAYMAN_MC_UCODE_SIZE;
229
		regs_size = BTC_IO_MC_REGS_SIZE;
230
		break;
231
	}
232
 
233
	mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
234
	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
235
 
236
	if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
237
		if (running) {
238
			blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
239
			WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
240
		}
241
 
242
		/* reset the engine and set to writable */
243
		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
244
		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
245
 
246
		/* load mc io regs */
247
		for (i = 0; i < regs_size; i++) {
248
			WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
249
			WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
250
		}
251
		/* load the MC ucode */
252
		fw_data = (const __be32 *)rdev->mc_fw->data;
253
		for (i = 0; i < ucode_size; i++)
254
			WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
255
 
256
		/* put the engine back into the active state */
257
		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
258
		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
259
		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
260
 
261
		/* wait for training to complete */
262
		while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD))
263
			udelay(10);
264
 
265
		if (running)
266
			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);