OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [drm/] [radeon_cp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* radeon_cp.c -- CP support for Radeon -*- linux-c -*-
2
 *
3
 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4
 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5
 * All Rights Reserved.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 * copy of this software and associated documentation files (the "Software"),
9
 * to deal in the Software without restriction, including without limitation
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 * and/or sell copies of the Software, and to permit persons to whom the
12
 * Software is furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the next
15
 * paragraph) shall be included in all copies or substantial portions of the
16
 * Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
 * DEALINGS IN THE SOFTWARE.
25
 *
26
 * Authors:
27
 *    Kevin E. Martin <martin@valinux.com>
28
 *    Gareth Hughes <gareth@valinux.com>
29
 */
30
 
31
#include "radeon.h"
32
#include "drmP.h"
33
#include "drm.h"
34
#include "radeon_drm.h"
35
#include "radeon_drv.h"
36
#include "drm_os_linux.h"
37
 
38
#include <linux/interrupt.h>    /* For task queue support */
39
#include <linux/delay.h>
40
#define RADEON_FIFO_DEBUG       0
41
 
42
 
43
 
44
/* CP microcode (from ATI) */
45
static u32 R200_cp_microcode[][2] = {
46
        { 0x21007000, 0000000000 },
47
        { 0x20007000, 0000000000 },
48
        { 0x000000ab, 0x00000004 },
49
        { 0x000000af, 0x00000004 },
50
        { 0x66544a49, 0000000000 },
51
        { 0x49494174, 0000000000 },
52
        { 0x54517d83, 0000000000 },
53
        { 0x498d8b64, 0000000000 },
54
        { 0x49494949, 0000000000 },
55
        { 0x49da493c, 0000000000 },
56
        { 0x49989898, 0000000000 },
57
        { 0xd34949d5, 0000000000 },
58
        { 0x9dc90e11, 0000000000 },
59
        { 0xce9b9b9b, 0000000000 },
60
        { 0x000f0000, 0x00000016 },
61
        { 0x352e232c, 0000000000 },
62
        { 0x00000013, 0x00000004 },
63
        { 0x000f0000, 0x00000016 },
64
        { 0x352e272c, 0000000000 },
65
        { 0x000f0001, 0x00000016 },
66
        { 0x3239362f, 0000000000 },
67
        { 0x000077ef, 0x00000002 },
68
        { 0x00061000, 0x00000002 },
69
        { 0x00000020, 0x0000001a },
70
        { 0x00004000, 0x0000001e },
71
        { 0x00061000, 0x00000002 },
72
        { 0x00000020, 0x0000001a },
73
        { 0x00004000, 0x0000001e },
74
        { 0x00061000, 0x00000002 },
75
        { 0x00000020, 0x0000001a },
76
        { 0x00004000, 0x0000001e },
77
        { 0x00000016, 0x00000004 },
78
        { 0x0003802a, 0x00000002 },
79
        { 0x040067e0, 0x00000002 },
80
        { 0x00000016, 0x00000004 },
81
        { 0x000077e0, 0x00000002 },
82
        { 0x00065000, 0x00000002 },
83
        { 0x000037e1, 0x00000002 },
84
        { 0x040067e1, 0x00000006 },
85
        { 0x000077e0, 0x00000002 },
86
        { 0x000077e1, 0x00000002 },
87
        { 0x000077e1, 0x00000006 },
88
        { 0xffffffff, 0000000000 },
89
        { 0x10000000, 0000000000 },
90
        { 0x0003802a, 0x00000002 },
91
        { 0x040067e0, 0x00000006 },
92
        { 0x00007675, 0x00000002 },
93
        { 0x00007676, 0x00000002 },
94
        { 0x00007677, 0x00000002 },
95
        { 0x00007678, 0x00000006 },
96
        { 0x0003802b, 0x00000002 },
97
        { 0x04002676, 0x00000002 },
98
        { 0x00007677, 0x00000002 },
99
        { 0x00007678, 0x00000006 },
100
        { 0x0000002e, 0x00000018 },
101
        { 0x0000002e, 0x00000018 },
102
        { 0000000000, 0x00000006 },
103
        { 0x0000002f, 0x00000018 },
104
        { 0x0000002f, 0x00000018 },
105
        { 0000000000, 0x00000006 },
106
        { 0x01605000, 0x00000002 },
107
        { 0x00065000, 0x00000002 },
108
        { 0x00098000, 0x00000002 },
109
        { 0x00061000, 0x00000002 },
110
        { 0x64c0603d, 0x00000004 },
111
        { 0x00080000, 0x00000016 },
112
        { 0000000000, 0000000000 },
113
        { 0x0400251d, 0x00000002 },
114
        { 0x00007580, 0x00000002 },
115
        { 0x00067581, 0x00000002 },
116
        { 0x04002580, 0x00000002 },
117
        { 0x00067581, 0x00000002 },
118
        { 0x00000046, 0x00000004 },
119
        { 0x00005000, 0000000000 },
120
        { 0x00061000, 0x00000002 },
121
        { 0x0000750e, 0x00000002 },
122
        { 0x00019000, 0x00000002 },
123
        { 0x00011055, 0x00000014 },
124
        { 0x00000055, 0x00000012 },
125
        { 0x0400250f, 0x00000002 },
126
        { 0x0000504a, 0x00000004 },
127
        { 0x00007565, 0x00000002 },
128
        { 0x00007566, 0x00000002 },
129
        { 0x00000051, 0x00000004 },
130
        { 0x01e655b4, 0x00000002 },
131
        { 0x4401b0dc, 0x00000002 },
132
        { 0x01c110dc, 0x00000002 },
133
        { 0x2666705d, 0x00000018 },
134
        { 0x040c2565, 0x00000002 },
135
        { 0x0000005d, 0x00000018 },
136
        { 0x04002564, 0x00000002 },
137
        { 0x00007566, 0x00000002 },
138
        { 0x00000054, 0x00000004 },
139
        { 0x00401060, 0x00000008 },
140
        { 0x00101000, 0x00000002 },
141
        { 0x000d80ff, 0x00000002 },
142
        { 0x00800063, 0x00000008 },
143
        { 0x000f9000, 0x00000002 },
144
        { 0x000e00ff, 0x00000002 },
145
        { 0000000000, 0x00000006 },
146
        { 0x00000080, 0x00000018 },
147
        { 0x00000054, 0x00000004 },
148
        { 0x00007576, 0x00000002 },
149
        { 0x00065000, 0x00000002 },
150
        { 0x00009000, 0x00000002 },
151
        { 0x00041000, 0x00000002 },
152
        { 0x0c00350e, 0x00000002 },
153
        { 0x00049000, 0x00000002 },
154
        { 0x00051000, 0x00000002 },
155
        { 0x01e785f8, 0x00000002 },
156
        { 0x00200000, 0x00000002 },
157
        { 0x00600073, 0x0000000c },
158
        { 0x00007563, 0x00000002 },
159
        { 0x006075f0, 0x00000021 },
160
        { 0x20007068, 0x00000004 },
161
        { 0x00005068, 0x00000004 },
162
        { 0x00007576, 0x00000002 },
163
        { 0x00007577, 0x00000002 },
164
        { 0x0000750e, 0x00000002 },
165
        { 0x0000750f, 0x00000002 },
166
        { 0x00a05000, 0x00000002 },
167
        { 0x00600076, 0x0000000c },
168
        { 0x006075f0, 0x00000021 },
169
        { 0x000075f8, 0x00000002 },
170
        { 0x00000076, 0x00000004 },
171
        { 0x000a750e, 0x00000002 },
172
        { 0x0020750f, 0x00000002 },
173
        { 0x00600079, 0x00000004 },
174
        { 0x00007570, 0x00000002 },
175
        { 0x00007571, 0x00000002 },
176
        { 0x00007572, 0x00000006 },
177
        { 0x00005000, 0x00000002 },
178
        { 0x00a05000, 0x00000002 },
179
        { 0x00007568, 0x00000002 },
180
        { 0x00061000, 0x00000002 },
181
        { 0x00000084, 0x0000000c },
182
        { 0x00058000, 0x00000002 },
183
        { 0x0c607562, 0x00000002 },
184
        { 0x00000086, 0x00000004 },
185
        { 0x00600085, 0x00000004 },
186
        { 0x400070dd, 0000000000 },
187
        { 0x000380dd, 0x00000002 },
188
        { 0x00000093, 0x0000001c },
189
        { 0x00065095, 0x00000018 },
190
        { 0x040025bb, 0x00000002 },
191
        { 0x00061096, 0x00000018 },
192
        { 0x040075bc, 0000000000 },
193
        { 0x000075bb, 0x00000002 },
194
        { 0x000075bc, 0000000000 },
195
        { 0x00090000, 0x00000006 },
196
        { 0x00090000, 0x00000002 },
197
        { 0x000d8002, 0x00000006 },
198
        { 0x00005000, 0x00000002 },
199
        { 0x00007821, 0x00000002 },
200
        { 0x00007800, 0000000000 },
201
        { 0x00007821, 0x00000002 },
202
        { 0x00007800, 0000000000 },
203
        { 0x01665000, 0x00000002 },
204
        { 0x000a0000, 0x00000002 },
205
        { 0x000671cc, 0x00000002 },
206
        { 0x0286f1cd, 0x00000002 },
207
        { 0x000000a3, 0x00000010 },
208
        { 0x21007000, 0000000000 },
209
        { 0x000000aa, 0x0000001c },
210
        { 0x00065000, 0x00000002 },
211
        { 0x000a0000, 0x00000002 },
212
        { 0x00061000, 0x00000002 },
213
        { 0x000b0000, 0x00000002 },
214
        { 0x38067000, 0x00000002 },
215
        { 0x000a00a6, 0x00000004 },
216
        { 0x20007000, 0000000000 },
217
        { 0x01200000, 0x00000002 },
218
        { 0x20077000, 0x00000002 },
219
        { 0x01200000, 0x00000002 },
220
        { 0x20007000, 0000000000 },
221
        { 0x00061000, 0x00000002 },
222
        { 0x0120751b, 0x00000002 },
223
        { 0x8040750a, 0x00000002 },
224
        { 0x8040750b, 0x00000002 },
225
        { 0x00110000, 0x00000002 },
226
        { 0x000380dd, 0x00000002 },
227
        { 0x000000bd, 0x0000001c },
228
        { 0x00061096, 0x00000018 },
229
        { 0x844075bd, 0x00000002 },
230
        { 0x00061095, 0x00000018 },
231
        { 0x840075bb, 0x00000002 },
232
        { 0x00061096, 0x00000018 },
233
        { 0x844075bc, 0x00000002 },
234
        { 0x000000c0, 0x00000004 },
235
        { 0x804075bd, 0x00000002 },
236
        { 0x800075bb, 0x00000002 },
237
        { 0x804075bc, 0x00000002 },
238
        { 0x00108000, 0x00000002 },
239
        { 0x01400000, 0x00000002 },
240
        { 0x006000c4, 0x0000000c },
241
        { 0x20c07000, 0x00000020 },
242
        { 0x000000c6, 0x00000012 },
243
        { 0x00800000, 0x00000006 },
244
        { 0x0080751d, 0x00000006 },
245
        { 0x000025bb, 0x00000002 },
246
        { 0x000040c0, 0x00000004 },
247
        { 0x0000775c, 0x00000002 },
248
        { 0x00a05000, 0x00000002 },
249
        { 0x00661000, 0x00000002 },
250
        { 0x0460275d, 0x00000020 },
251
        { 0x00004000, 0000000000 },
252
        { 0x00007999, 0x00000002 },
253
        { 0x00a05000, 0x00000002 },
254
        { 0x00661000, 0x00000002 },
255
        { 0x0460299b, 0x00000020 },
256
        { 0x00004000, 0000000000 },
257
        { 0x01e00830, 0x00000002 },
258
        { 0x21007000, 0000000000 },
259
        { 0x00005000, 0x00000002 },
260
        { 0x00038042, 0x00000002 },
261
        { 0x040025e0, 0x00000002 },
262
        { 0x000075e1, 0000000000 },
263
        { 0x00000001, 0000000000 },
264
        { 0x000380d9, 0x00000002 },
265
        { 0x04007394, 0000000000 },
266
        { 0000000000, 0000000000 },
267
        { 0000000000, 0000000000 },
268
        { 0000000000, 0000000000 },
269
        { 0000000000, 0000000000 },
270
        { 0000000000, 0000000000 },
271
        { 0000000000, 0000000000 },
272
        { 0000000000, 0000000000 },
273
        { 0000000000, 0000000000 },
274
        { 0000000000, 0000000000 },
275
        { 0000000000, 0000000000 },
276
        { 0000000000, 0000000000 },
277
        { 0000000000, 0000000000 },
278
        { 0000000000, 0000000000 },
279
        { 0000000000, 0000000000 },
280
        { 0000000000, 0000000000 },
281
        { 0000000000, 0000000000 },
282
        { 0000000000, 0000000000 },
283
        { 0000000000, 0000000000 },
284
        { 0000000000, 0000000000 },
285
        { 0000000000, 0000000000 },
286
        { 0000000000, 0000000000 },
287
        { 0000000000, 0000000000 },
288
        { 0000000000, 0000000000 },
289
        { 0000000000, 0000000000 },
290
        { 0000000000, 0000000000 },
291
        { 0000000000, 0000000000 },
292
        { 0000000000, 0000000000 },
293
        { 0000000000, 0000000000 },
294
        { 0000000000, 0000000000 },
295
        { 0000000000, 0000000000 },
296
        { 0000000000, 0000000000 },
297
        { 0000000000, 0000000000 },
298
        { 0000000000, 0000000000 },
299
        { 0000000000, 0000000000 },
300
        { 0000000000, 0000000000 },
301
        { 0000000000, 0000000000 },
302
};
303
 
304
 
305
static u32 radeon_cp_microcode[][2] = {
306
        { 0x21007000, 0000000000 },
307
        { 0x20007000, 0000000000 },
308
        { 0x000000b4, 0x00000004 },
309
        { 0x000000b8, 0x00000004 },
310
        { 0x6f5b4d4c, 0000000000 },
311
        { 0x4c4c427f, 0000000000 },
312
        { 0x5b568a92, 0000000000 },
313
        { 0x4ca09c6d, 0000000000 },
314
        { 0xad4c4c4c, 0000000000 },
315
        { 0x4ce1af3d, 0000000000 },
316
        { 0xd8afafaf, 0000000000 },
317
        { 0xd64c4cdc, 0000000000 },
318
        { 0x4cd10d10, 0000000000 },
319
        { 0x000f0000, 0x00000016 },
320
        { 0x362f242d, 0000000000 },
321
        { 0x00000012, 0x00000004 },
322
        { 0x000f0000, 0x00000016 },
323
        { 0x362f282d, 0000000000 },
324
        { 0x000380e7, 0x00000002 },
325
        { 0x04002c97, 0x00000002 },
326
        { 0x000f0001, 0x00000016 },
327
        { 0x333a3730, 0000000000 },
328
        { 0x000077ef, 0x00000002 },
329
        { 0x00061000, 0x00000002 },
330
        { 0x00000021, 0x0000001a },
331
        { 0x00004000, 0x0000001e },
332
        { 0x00061000, 0x00000002 },
333
        { 0x00000021, 0x0000001a },
334
        { 0x00004000, 0x0000001e },
335
        { 0x00061000, 0x00000002 },
336
        { 0x00000021, 0x0000001a },
337
        { 0x00004000, 0x0000001e },
338
        { 0x00000017, 0x00000004 },
339
        { 0x0003802b, 0x00000002 },
340
        { 0x040067e0, 0x00000002 },
341
        { 0x00000017, 0x00000004 },
342
        { 0x000077e0, 0x00000002 },
343
        { 0x00065000, 0x00000002 },
344
        { 0x000037e1, 0x00000002 },
345
        { 0x040067e1, 0x00000006 },
346
        { 0x000077e0, 0x00000002 },
347
        { 0x000077e1, 0x00000002 },
348
        { 0x000077e1, 0x00000006 },
349
        { 0xffffffff, 0000000000 },
350
        { 0x10000000, 0000000000 },
351
        { 0x0003802b, 0x00000002 },
352
        { 0x040067e0, 0x00000006 },
353
        { 0x00007675, 0x00000002 },
354
        { 0x00007676, 0x00000002 },
355
        { 0x00007677, 0x00000002 },
356
        { 0x00007678, 0x00000006 },
357
        { 0x0003802c, 0x00000002 },
358
        { 0x04002676, 0x00000002 },
359
        { 0x00007677, 0x00000002 },
360
        { 0x00007678, 0x00000006 },
361
        { 0x0000002f, 0x00000018 },
362
        { 0x0000002f, 0x00000018 },
363
        { 0000000000, 0x00000006 },
364
        { 0x00000030, 0x00000018 },
365
        { 0x00000030, 0x00000018 },
366
        { 0000000000, 0x00000006 },
367
        { 0x01605000, 0x00000002 },
368
        { 0x00065000, 0x00000002 },
369
        { 0x00098000, 0x00000002 },
370
        { 0x00061000, 0x00000002 },
371
        { 0x64c0603e, 0x00000004 },
372
        { 0x000380e6, 0x00000002 },
373
        { 0x040025c5, 0x00000002 },
374
        { 0x00080000, 0x00000016 },
375
        { 0000000000, 0000000000 },
376
        { 0x0400251d, 0x00000002 },
377
        { 0x00007580, 0x00000002 },
378
        { 0x00067581, 0x00000002 },
379
        { 0x04002580, 0x00000002 },
380
        { 0x00067581, 0x00000002 },
381
        { 0x00000049, 0x00000004 },
382
        { 0x00005000, 0000000000 },
383
        { 0x000380e6, 0x00000002 },
384
        { 0x040025c5, 0x00000002 },
385
        { 0x00061000, 0x00000002 },
386
        { 0x0000750e, 0x00000002 },
387
        { 0x00019000, 0x00000002 },
388
        { 0x00011055, 0x00000014 },
389
        { 0x00000055, 0x00000012 },
390
        { 0x0400250f, 0x00000002 },
391
        { 0x0000504f, 0x00000004 },
392
        { 0x000380e6, 0x00000002 },
393
        { 0x040025c5, 0x00000002 },
394
        { 0x00007565, 0x00000002 },
395
        { 0x00007566, 0x00000002 },
396
        { 0x00000058, 0x00000004 },
397
        { 0x000380e6, 0x00000002 },
398
        { 0x040025c5, 0x00000002 },
399
        { 0x01e655b4, 0x00000002 },
400
        { 0x4401b0e4, 0x00000002 },
401
        { 0x01c110e4, 0x00000002 },
402
        { 0x26667066, 0x00000018 },
403
        { 0x040c2565, 0x00000002 },
404
        { 0x00000066, 0x00000018 },
405
        { 0x04002564, 0x00000002 },
406
        { 0x00007566, 0x00000002 },
407
        { 0x0000005d, 0x00000004 },
408
        { 0x00401069, 0x00000008 },
409
        { 0x00101000, 0x00000002 },
410
        { 0x000d80ff, 0x00000002 },
411
        { 0x0080006c, 0x00000008 },
412
        { 0x000f9000, 0x00000002 },
413
        { 0x000e00ff, 0x00000002 },
414
        { 0000000000, 0x00000006 },
415
        { 0x0000008f, 0x00000018 },
416
        { 0x0000005b, 0x00000004 },
417
        { 0x000380e6, 0x00000002 },
418
        { 0x040025c5, 0x00000002 },
419
        { 0x00007576, 0x00000002 },
420
        { 0x00065000, 0x00000002 },
421
        { 0x00009000, 0x00000002 },
422
        { 0x00041000, 0x00000002 },
423
        { 0x0c00350e, 0x00000002 },
424
        { 0x00049000, 0x00000002 },
425
        { 0x00051000, 0x00000002 },
426
        { 0x01e785f8, 0x00000002 },
427
        { 0x00200000, 0x00000002 },
428
        { 0x0060007e, 0x0000000c },
429
        { 0x00007563, 0x00000002 },
430
        { 0x006075f0, 0x00000021 },
431
        { 0x20007073, 0x00000004 },
432
        { 0x00005073, 0x00000004 },
433
        { 0x000380e6, 0x00000002 },
434
        { 0x040025c5, 0x00000002 },
435
        { 0x00007576, 0x00000002 },
436
        { 0x00007577, 0x00000002 },
437
        { 0x0000750e, 0x00000002 },
438
        { 0x0000750f, 0x00000002 },
439
        { 0x00a05000, 0x00000002 },
440
        { 0x00600083, 0x0000000c },
441
        { 0x006075f0, 0x00000021 },
442
        { 0x000075f8, 0x00000002 },
443
        { 0x00000083, 0x00000004 },
444
        { 0x000a750e, 0x00000002 },
445
        { 0x000380e6, 0x00000002 },
446
        { 0x040025c5, 0x00000002 },
447
        { 0x0020750f, 0x00000002 },
448
        { 0x00600086, 0x00000004 },
449
        { 0x00007570, 0x00000002 },
450
        { 0x00007571, 0x00000002 },
451
        { 0x00007572, 0x00000006 },
452
        { 0x000380e6, 0x00000002 },
453
        { 0x040025c5, 0x00000002 },
454
        { 0x00005000, 0x00000002 },
455
        { 0x00a05000, 0x00000002 },
456
        { 0x00007568, 0x00000002 },
457
        { 0x00061000, 0x00000002 },
458
        { 0x00000095, 0x0000000c },
459
        { 0x00058000, 0x00000002 },
460
        { 0x0c607562, 0x00000002 },
461
        { 0x00000097, 0x00000004 },
462
        { 0x000380e6, 0x00000002 },
463
        { 0x040025c5, 0x00000002 },
464
        { 0x00600096, 0x00000004 },
465
        { 0x400070e5, 0000000000 },
466
        { 0x000380e6, 0x00000002 },
467
        { 0x040025c5, 0x00000002 },
468
        { 0x000380e5, 0x00000002 },
469
        { 0x000000a8, 0x0000001c },
470
        { 0x000650aa, 0x00000018 },
471
        { 0x040025bb, 0x00000002 },
472
        { 0x000610ab, 0x00000018 },
473
        { 0x040075bc, 0000000000 },
474
        { 0x000075bb, 0x00000002 },
475
        { 0x000075bc, 0000000000 },
476
        { 0x00090000, 0x00000006 },
477
        { 0x00090000, 0x00000002 },
478
        { 0x000d8002, 0x00000006 },
479
        { 0x00007832, 0x00000002 },
480
        { 0x00005000, 0x00000002 },
481
        { 0x000380e7, 0x00000002 },
482
        { 0x04002c97, 0x00000002 },
483
        { 0x00007820, 0x00000002 },
484
        { 0x00007821, 0x00000002 },
485
        { 0x00007800, 0000000000 },
486
        { 0x01200000, 0x00000002 },
487
        { 0x20077000, 0x00000002 },
488
        { 0x01200000, 0x00000002 },
489
        { 0x20007000, 0x00000002 },
490
        { 0x00061000, 0x00000002 },
491
        { 0x0120751b, 0x00000002 },
492
        { 0x8040750a, 0x00000002 },
493
        { 0x8040750b, 0x00000002 },
494
        { 0x00110000, 0x00000002 },
495
        { 0x000380e5, 0x00000002 },
496
        { 0x000000c6, 0x0000001c },
497
        { 0x000610ab, 0x00000018 },
498
        { 0x844075bd, 0x00000002 },
499
        { 0x000610aa, 0x00000018 },
500
        { 0x840075bb, 0x00000002 },
501
        { 0x000610ab, 0x00000018 },
502
        { 0x844075bc, 0x00000002 },
503
        { 0x000000c9, 0x00000004 },
504
        { 0x804075bd, 0x00000002 },
505
        { 0x800075bb, 0x00000002 },
506
        { 0x804075bc, 0x00000002 },
507
        { 0x00108000, 0x00000002 },
508
        { 0x01400000, 0x00000002 },
509
        { 0x006000cd, 0x0000000c },
510
        { 0x20c07000, 0x00000020 },
511
        { 0x000000cf, 0x00000012 },
512
        { 0x00800000, 0x00000006 },
513
        { 0x0080751d, 0x00000006 },
514
        { 0000000000, 0000000000 },
515
        { 0x0000775c, 0x00000002 },
516
        { 0x00a05000, 0x00000002 },
517
        { 0x00661000, 0x00000002 },
518
        { 0x0460275d, 0x00000020 },
519
        { 0x00004000, 0000000000 },
520
        { 0x01e00830, 0x00000002 },
521
        { 0x21007000, 0000000000 },
522
        { 0x6464614d, 0000000000 },
523
        { 0x69687420, 0000000000 },
524
        { 0x00000073, 0000000000 },
525
        { 0000000000, 0000000000 },
526
        { 0x00005000, 0x00000002 },
527
        { 0x000380d0, 0x00000002 },
528
        { 0x040025e0, 0x00000002 },
529
        { 0x000075e1, 0000000000 },
530
        { 0x00000001, 0000000000 },
531
        { 0x000380e0, 0x00000002 },
532
        { 0x04002394, 0x00000002 },
533
        { 0x00005000, 0000000000 },
534
        { 0000000000, 0000000000 },
535
        { 0000000000, 0000000000 },
536
        { 0x00000008, 0000000000 },
537
        { 0x00000004, 0000000000 },
538
        { 0000000000, 0000000000 },
539
        { 0000000000, 0000000000 },
540
        { 0000000000, 0000000000 },
541
        { 0000000000, 0000000000 },
542
        { 0000000000, 0000000000 },
543
        { 0000000000, 0000000000 },
544
        { 0000000000, 0000000000 },
545
        { 0000000000, 0000000000 },
546
        { 0000000000, 0000000000 },
547
        { 0000000000, 0000000000 },
548
        { 0000000000, 0000000000 },
549
        { 0000000000, 0000000000 },
550
        { 0000000000, 0000000000 },
551
        { 0000000000, 0000000000 },
552
        { 0000000000, 0000000000 },
553
        { 0000000000, 0000000000 },
554
        { 0000000000, 0000000000 },
555
        { 0000000000, 0000000000 },
556
        { 0000000000, 0000000000 },
557
        { 0000000000, 0000000000 },
558
        { 0000000000, 0000000000 },
559
        { 0000000000, 0000000000 },
560
        { 0000000000, 0000000000 },
561
        { 0000000000, 0000000000 },
562
};
563
 
564
 
565
int RADEON_READ_PLL(drm_device_t *dev, int addr)
566
{
567
        drm_radeon_private_t *dev_priv = dev->dev_private;
568
 
569
        RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
570
        return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
571
}
572
 
573
#if RADEON_FIFO_DEBUG
574
static void radeon_status( drm_radeon_private_t *dev_priv )
575
{
576
        printk( "%s:\n", __FUNCTION__ );
577
        printk( "RBBM_STATUS = 0x%08x\n",
578
                (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
579
        printk( "CP_RB_RTPR = 0x%08x\n",
580
                (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
581
        printk( "CP_RB_WTPR = 0x%08x\n",
582
                (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
583
        printk( "AIC_CNTL = 0x%08x\n",
584
                (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
585
        printk( "AIC_STAT = 0x%08x\n",
586
                (unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
587
        printk( "AIC_PT_BASE = 0x%08x\n",
588
                (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
589
        printk( "TLB_ADDR = 0x%08x\n",
590
                (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
591
        printk( "TLB_DATA = 0x%08x\n",
592
                (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
593
}
594
#endif
595
 
596
 
597
/* ================================================================
598
 * Engine, FIFO control
599
 */
600
 
601
static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
602
{
603
        u32 tmp;
604
        int i;
605
 
606
        dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
607
 
608
        tmp  = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT );
609
        tmp |= RADEON_RB2D_DC_FLUSH_ALL;
610
        RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp );
611
 
612
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
613
                if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT )
614
                       & RADEON_RB2D_DC_BUSY) ) {
615
                        return 0;
616
                }
617
                udelay( 1 );
618
        }
619
 
620
#if RADEON_FIFO_DEBUG
621
        DRM_ERROR( "failed!\n" );
622
        radeon_status( dev_priv );
623
#endif
624
        return -EBUSY;
625
}
626
 
627
static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
628
                                    int entries )
629
{
630
        int i;
631
 
632
        dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
633
 
634
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
635
                int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
636
                              & RADEON_RBBM_FIFOCNT_MASK );
637
                if ( slots >= entries ) return 0;
638
                udelay( 1 );
639
        }
640
 
641
#if RADEON_FIFO_DEBUG
642
        DRM_ERROR( "failed!\n" );
643
        radeon_status( dev_priv );
644
#endif
645
        return -EBUSY;
646
}
647
 
648
static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
649
{
650
        int i, ret;
651
 
652
        dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
653
 
654
        ret = radeon_do_wait_for_fifo( dev_priv, 64 );
655
        if ( ret ) return ret;
656
 
657
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
658
                if ( !(RADEON_READ( RADEON_RBBM_STATUS )
659
                       & RADEON_RBBM_ACTIVE) ) {
660
                        radeon_do_pixcache_flush( dev_priv );
661
                        return 0;
662
                }
663
                udelay( 1 );
664
        }
665
 
666
#if RADEON_FIFO_DEBUG
667
        DRM_ERROR( "failed!\n" );
668
        radeon_status( dev_priv );
669
#endif
670
        return -EBUSY;
671
}
672
 
673
 
674
/* ================================================================
675
 * CP control, initialization
676
 */
677
 
678
/* Load the microcode for the CP */
679
static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
680
{
681
        int i;
682
        DRM_DEBUG( "\n" );
683
 
684
        radeon_do_wait_for_idle( dev_priv );
685
 
686
        RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
687
 
688
        if (dev_priv->is_r200)
689
        {
690
                DRM_INFO("Loading R200 Microcode\n");
691
                for ( i = 0 ; i < 256 ; i++ )
692
                {
693
                        RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
694
                                      R200_cp_microcode[i][1] );
695
                        RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
696
                                      R200_cp_microcode[i][0] );
697
                }
698
        }
699
        else
700
        {
701
                for ( i = 0 ; i < 256 ; i++ ) {
702
                        RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
703
                                      radeon_cp_microcode[i][1] );
704
                        RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
705
                                      radeon_cp_microcode[i][0] );
706
                }
707
        }
708
}
709
 
710
/* Flush any pending commands to the CP.  This should only be used just
711
 * prior to a wait for idle, as it informs the engine that the command
712
 * stream is ending.
713
 */
714
static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
715
{
716
        DRM_DEBUG( "\n" );
717
#if 0
718
        u32 tmp;
719
 
720
        tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31);
721
        RADEON_WRITE( RADEON_CP_RB_WPTR, tmp );
722
#endif
723
}
724
 
725
/* Wait for the CP to go idle.
726
 */
727
int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
728
{
729
        RING_LOCALS;
730
        DRM_DEBUG( "\n" );
731
 
732
        BEGIN_RING( 6 );
733
 
734
        RADEON_PURGE_CACHE();
735
        RADEON_PURGE_ZCACHE();
736
        RADEON_WAIT_UNTIL_IDLE();
737
 
738
        ADVANCE_RING();
739
        COMMIT_RING();
740
 
741
        return radeon_do_wait_for_idle( dev_priv );
742
}
743
 
744
/* Start the Command Processor.
745
 */
746
static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
747
{
748
        RING_LOCALS;
749
        DRM_DEBUG( "\n" );
750
 
751
        radeon_do_wait_for_idle( dev_priv );
752
 
753
        RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode );
754
 
755
        dev_priv->cp_running = 1;
756
 
757
        BEGIN_RING( 6 );
758
 
759
        RADEON_PURGE_CACHE();
760
        RADEON_PURGE_ZCACHE();
761
        RADEON_WAIT_UNTIL_IDLE();
762
 
763
        ADVANCE_RING();
764
        COMMIT_RING();
765
}
766
 
767
/* Reset the Command Processor.  This will not flush any pending
768
 * commands, so you must wait for the CP command stream to complete
769
 * before calling this routine.
770
 */
771
static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
772
{
773
        u32 cur_read_ptr;
774
        DRM_DEBUG( "\n" );
775
 
776
        cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
777
        RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
778
        *dev_priv->ring.head = cur_read_ptr;
779
        dev_priv->ring.tail = cur_read_ptr;
780
}
781
 
782
/* Stop the Command Processor.  This will not flush any pending
783
 * commands, so you must flush the command stream and wait for the CP
784
 * to go idle before calling this routine.
785
 */
786
static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
787
{
788
        DRM_DEBUG( "\n" );
789
 
790
        RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
791
 
792
        dev_priv->cp_running = 0;
793
}
794
 
795
/* Reset the engine.  This will stop the CP if it is running.
796
 */
797
static int radeon_do_engine_reset( drm_device_t *dev )
798
{
799
        drm_radeon_private_t *dev_priv = dev->dev_private;
800
        u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
801
        DRM_DEBUG( "\n" );
802
 
803
        radeon_do_pixcache_flush( dev_priv );
804
 
805
        clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
806
        mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
807
 
808
        RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
809
                                              RADEON_FORCEON_MCLKA |
810
                                              RADEON_FORCEON_MCLKB |
811
                                              RADEON_FORCEON_YCLKA |
812
                                              RADEON_FORCEON_YCLKB |
813
                                              RADEON_FORCEON_MC |
814
                                              RADEON_FORCEON_AIC ) );
815
 
816
        rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
817
 
818
        RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset |
819
                                                RADEON_SOFT_RESET_CP |
820
                                                RADEON_SOFT_RESET_HI |
821
                                                RADEON_SOFT_RESET_SE |
822
                                                RADEON_SOFT_RESET_RE |
823
                                                RADEON_SOFT_RESET_PP |
824
                                                RADEON_SOFT_RESET_E2 |
825
                                                RADEON_SOFT_RESET_RB ) );
826
        RADEON_READ( RADEON_RBBM_SOFT_RESET );
827
        RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset &
828
                                                ~( RADEON_SOFT_RESET_CP |
829
                                                   RADEON_SOFT_RESET_HI |
830
                                                   RADEON_SOFT_RESET_SE |
831
                                                   RADEON_SOFT_RESET_RE |
832
                                                   RADEON_SOFT_RESET_PP |
833
                                                   RADEON_SOFT_RESET_E2 |
834
                                                   RADEON_SOFT_RESET_RB ) ) );
835
        RADEON_READ( RADEON_RBBM_SOFT_RESET );
836
 
837
 
838
        RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl );
839
        RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
840
        RADEON_WRITE( RADEON_RBBM_SOFT_RESET,  rbbm_soft_reset );
841
 
842
        /* Reset the CP ring */
843
        radeon_do_cp_reset( dev_priv );
844
 
845
        /* The CP is no longer running after an engine reset */
846
        dev_priv->cp_running = 0;
847
 
848
        /* Reset any pending vertex, indirect buffers */
849
        radeon_freelist_reset( dev );
850
 
851
        return 0;
852
}
853
 
854
static void radeon_cp_init_ring_buffer( drm_device_t *dev,
855
                                        drm_radeon_private_t *dev_priv )
856
{
857
        u32 ring_start, cur_read_ptr;
858
        u32 tmp;
859
 
860
        /* Initialize the memory controller */
861
        RADEON_WRITE( RADEON_MC_FB_LOCATION,
862
                      (dev_priv->agp_vm_start - 1) & 0xffff0000 );
863
 
864
        if ( !dev_priv->is_pci ) {
865
                RADEON_WRITE( RADEON_MC_AGP_LOCATION,
866
                              (((dev_priv->agp_vm_start - 1 +
867
                                 dev_priv->agp_size) & 0xffff0000) |
868
                               (dev_priv->agp_vm_start >> 16)) );
869
        }
870
 
871
#if __REALLY_HAVE_AGP
872
        if ( !dev_priv->is_pci )
873
                ring_start = (dev_priv->cp_ring->offset
874
                              - dev->agp->base
875
                              + dev_priv->agp_vm_start);
876
       else
877
#endif
878
                ring_start = (dev_priv->cp_ring->offset
879
                              - dev->sg->handle
880
                              + dev_priv->agp_vm_start);
881
 
882
        RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
883
 
884
        /* Set the write pointer delay */
885
        RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
886
        RADEON_READ( RADEON_CP_RB_WPTR_DELAY ); /* read back to propagate */
887
 
888
        /* Initialize the ring buffer's read and write pointers */
889
        cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
890
        RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
891
        *dev_priv->ring.head = cur_read_ptr;
892
        dev_priv->ring.tail = cur_read_ptr;
893
 
894
        if ( !dev_priv->is_pci ) {
895
                RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
896
                              dev_priv->ring_rptr->offset );
897
        } else {
898
                drm_sg_mem_t *entry = dev->sg;
899
                unsigned long tmp_ofs, page_ofs;
900
 
901
                tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
902
                page_ofs = tmp_ofs >> PAGE_SHIFT;
903
 
904
                RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
905
                             entry->busaddr[page_ofs]);
906
                DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
907
                           entry->busaddr[page_ofs],
908
                           entry->handle + tmp_ofs );
909
        }
910
 
911
        /* Initialize the scratch register pointer.  This will cause
912
         * the scratch register values to be written out to memory
913
         * whenever they are updated.
914
         *
915
         * We simply put this behind the ring read pointer, this works
916
         * with PCI GART as well as (whatever kind of) AGP GART
917
         */
918
        RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR )
919
                                         + RADEON_SCRATCH_REG_OFFSET );
920
 
921
        dev_priv->scratch = ((__volatile__ u32 *)
922
                             dev_priv->ring.head +
923
                             (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
924
 
925
        RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
926
 
927
        /* Writeback doesn't seem to work everywhere, test it first */
928
        writel(0, &dev_priv->scratch[1]);
929
        RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
930
 
931
        for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
932
                if ( readl( &dev_priv->scratch[1] ) == 0xdeadbeef )
933
                        break;
934
                udelay(1);
935
        }
936
 
937
        if ( tmp < dev_priv->usec_timeout ) {
938
                dev_priv->writeback_works = 1;
939
                DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp );
940
        } else {
941
                dev_priv->writeback_works = 0;
942
                DRM_DEBUG( "writeback test failed\n" );
943
        }
944
 
945
        dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
946
        RADEON_WRITE( RADEON_LAST_FRAME_REG,
947
                      dev_priv->sarea_priv->last_frame );
948
 
949
        dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
950
        RADEON_WRITE( RADEON_LAST_DISPATCH_REG,
951
                      dev_priv->sarea_priv->last_dispatch );
952
 
953
        dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
954
        RADEON_WRITE( RADEON_LAST_CLEAR_REG,
955
                      dev_priv->sarea_priv->last_clear );
956
 
957
        /* Set ring buffer size */
958
#ifdef __BIG_ENDIAN
959
        RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT );
960
#else
961
        RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
962
#endif
963
 
964
        radeon_do_wait_for_idle( dev_priv );
965
 
966
        /* Turn on bus mastering */
967
        tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
968
        RADEON_WRITE( RADEON_BUS_CNTL, tmp );
969
 
970
        /* Sync everything up */
971
        RADEON_WRITE( RADEON_ISYNC_CNTL,
972
                      (RADEON_ISYNC_ANY2D_IDLE3D |
973
                       RADEON_ISYNC_ANY3D_IDLE2D |
974
                       RADEON_ISYNC_WAIT_IDLEGUI |
975
                       RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
976
}
977
 
978
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
979
{
980
        drm_radeon_private_t *dev_priv;
981
        u32 tmp;
982
        DRM_DEBUG( "\n" );
983
 
984
        dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
985
        if ( dev_priv == NULL )
986
                return -ENOMEM;
987
 
988
        memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
989
 
990
        dev_priv->is_pci = init->is_pci;
991
 
992
        if ( dev_priv->is_pci && !dev->sg ) {
993
                DRM_ERROR( "PCI GART memory not allocated!\n" );
994
                dev->dev_private = (void *)dev_priv;
995
                radeon_do_cleanup_cp(dev);
996
                return -EINVAL;
997
        }
998
 
999
        dev_priv->usec_timeout = init->usec_timeout;
1000
        if ( dev_priv->usec_timeout < 1 ||
1001
             dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
1002
                DRM_DEBUG( "TIMEOUT problem!\n" );
1003
                dev->dev_private = (void *)dev_priv;
1004
                radeon_do_cleanup_cp(dev);
1005
                return -EINVAL;
1006
        }
1007
 
1008
        dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP);
1009
        dev_priv->do_boxes = 0;
1010
        dev_priv->cp_mode = init->cp_mode;
1011
 
1012
        /* We don't support anything other than bus-mastering ring mode,
1013
         * but the ring can be in either AGP or PCI space for the ring
1014
         * read pointer.
1015
         */
1016
        if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
1017
             ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
1018
                DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
1019
                dev->dev_private = (void *)dev_priv;
1020
                radeon_do_cleanup_cp(dev);
1021
                return -EINVAL;
1022
        }
1023
 
1024
        switch ( init->fb_bpp ) {
1025
        case 16:
1026
                dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
1027
                break;
1028
        case 32:
1029
        default:
1030
                dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
1031
                break;
1032
        }
1033
        dev_priv->front_offset  = init->front_offset;
1034
        dev_priv->front_pitch   = init->front_pitch;
1035
        dev_priv->back_offset   = init->back_offset;
1036
        dev_priv->back_pitch    = init->back_pitch;
1037
 
1038
        switch ( init->depth_bpp ) {
1039
        case 16:
1040
                dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
1041
                break;
1042
        case 32:
1043
        default:
1044
                dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
1045
                break;
1046
        }
1047
        dev_priv->depth_offset  = init->depth_offset;
1048
        dev_priv->depth_pitch   = init->depth_pitch;
1049
 
1050
        dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) |
1051
                                        (dev_priv->front_offset >> 10));
1052
        dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) |
1053
                                       (dev_priv->back_offset >> 10));
1054
        dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) |
1055
                                        (dev_priv->depth_offset >> 10));
1056
 
1057
        /* Hardware state for depth clears.  Remove this if/when we no
1058
         * longer clear the depth buffer with a 3D rectangle.  Hard-code
1059
         * all values to prevent unwanted 3D state from slipping through
1060
         * and screwing with the clear operation.
1061
         */
1062
        dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
1063
                                           (dev_priv->color_fmt << 10) |
1064
                                           (1<<15));
1065
 
1066
        dev_priv->depth_clear.rb3d_zstencilcntl =
1067
                (dev_priv->depth_fmt |
1068
                 RADEON_Z_TEST_ALWAYS |
1069
                 RADEON_STENCIL_TEST_ALWAYS |
1070
                 RADEON_STENCIL_S_FAIL_REPLACE |
1071
                 RADEON_STENCIL_ZPASS_REPLACE |
1072
                 RADEON_STENCIL_ZFAIL_REPLACE |
1073
                 RADEON_Z_WRITE_ENABLE);
1074
 
1075
        dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
1076
                                         RADEON_BFACE_SOLID |
1077
                                         RADEON_FFACE_SOLID |
1078
                                         RADEON_FLAT_SHADE_VTX_LAST |
1079
                                         RADEON_DIFFUSE_SHADE_FLAT |
1080
                                         RADEON_ALPHA_SHADE_FLAT |
1081
                                         RADEON_SPECULAR_SHADE_FLAT |
1082
                                         RADEON_FOG_SHADE_FLAT |
1083
                                         RADEON_VTX_PIX_CENTER_OGL |
1084
                                         RADEON_ROUND_MODE_TRUNC |
1085
                                         RADEON_ROUND_PREC_8TH_PIX);
1086
 
1087
        DRM_GETSAREA();
1088
 
1089
        if(!dev_priv->sarea) {
1090
                DRM_ERROR("could not find sarea!\n");
1091
                dev->dev_private = (void *)dev_priv;
1092
                radeon_do_cleanup_cp(dev);
1093
                return -EINVAL;
1094
        }
1095
 
1096
        DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
1097
        if(!dev_priv->fb) {
1098
                DRM_ERROR("could not find framebuffer!\n");
1099
                dev->dev_private = (void *)dev_priv;
1100
                radeon_do_cleanup_cp(dev);
1101
                return -EINVAL;
1102
        }
1103
        DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
1104
        if(!dev_priv->mmio) {
1105
                DRM_ERROR("could not find mmio region!\n");
1106
                dev->dev_private = (void *)dev_priv;
1107
                radeon_do_cleanup_cp(dev);
1108
                return -EINVAL;
1109
        }
1110
        DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
1111
        if(!dev_priv->cp_ring) {
1112
                DRM_ERROR("could not find cp ring region!\n");
1113
                dev->dev_private = (void *)dev_priv;
1114
                radeon_do_cleanup_cp(dev);
1115
                return -EINVAL;
1116
        }
1117
        DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
1118
        if(!dev_priv->ring_rptr) {
1119
                DRM_ERROR("could not find ring read pointer!\n");
1120
                dev->dev_private = (void *)dev_priv;
1121
                radeon_do_cleanup_cp(dev);
1122
                return -EINVAL;
1123
        }
1124
        DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
1125
        if(!dev_priv->buffers) {
1126
                DRM_ERROR("could not find dma buffer region!\n");
1127
                dev->dev_private = (void *)dev_priv;
1128
                radeon_do_cleanup_cp(dev);
1129
                return -EINVAL;
1130
        }
1131
 
1132
        if ( !dev_priv->is_pci ) {
1133
                DRM_FIND_MAP( dev_priv->agp_textures,
1134
                              init->agp_textures_offset );
1135
                if(!dev_priv->agp_textures) {
1136
                        DRM_ERROR("could not find agp texture region!\n");
1137
                        dev->dev_private = (void *)dev_priv;
1138
                        radeon_do_cleanup_cp(dev);
1139
                        return -EINVAL;
1140
                }
1141
        }
1142
 
1143
        dev_priv->sarea_priv =
1144
                (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
1145
                                       init->sarea_priv_offset);
1146
 
1147
        if ( !dev_priv->is_pci ) {
1148
                DRM_IOREMAP( dev_priv->cp_ring, dev );
1149
                DRM_IOREMAP( dev_priv->ring_rptr, dev );
1150
                DRM_IOREMAP( dev_priv->buffers, dev );
1151
                if(!dev_priv->cp_ring->handle ||
1152
                   !dev_priv->ring_rptr->handle ||
1153
                   !dev_priv->buffers->handle) {
1154
                        DRM_ERROR("could not find ioremap agp regions!\n");
1155
                        dev->dev_private = (void *)dev_priv;
1156
                        radeon_do_cleanup_cp(dev);
1157
                        return -EINVAL;
1158
                }
1159
        } else {
1160
                dev_priv->cp_ring->handle =
1161
                        (void *)dev_priv->cp_ring->offset;
1162
                dev_priv->ring_rptr->handle =
1163
                        (void *)dev_priv->ring_rptr->offset;
1164
                dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
1165
 
1166
                DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
1167
                           dev_priv->cp_ring->handle );
1168
                DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
1169
                           dev_priv->ring_rptr->handle );
1170
                DRM_DEBUG( "dev_priv->buffers->handle %p\n",
1171
                           dev_priv->buffers->handle );
1172
        }
1173
 
1174
 
1175
        dev_priv->agp_size = init->agp_size;
1176
        dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
1177
#if __REALLY_HAVE_AGP
1178
        if ( !dev_priv->is_pci )
1179
                dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
1180
                                                - dev->agp->base
1181
                                                + dev_priv->agp_vm_start);
1182
        else
1183
#endif
1184
                dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
1185
                                                - dev->sg->handle
1186
                                                + dev_priv->agp_vm_start);
1187
 
1188
        DRM_DEBUG( "dev_priv->agp_size %d\n",
1189
                   dev_priv->agp_size );
1190
        DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n",
1191
                   dev_priv->agp_vm_start );
1192
        DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n",
1193
                   dev_priv->agp_buffers_offset );
1194
 
1195
        dev_priv->ring.head = ((__volatile__ u32 *)
1196
                               dev_priv->ring_rptr->handle);
1197
 
1198
        dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle;
1199
        dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
1200
                              + init->ring_size / sizeof(u32));
1201
        dev_priv->ring.size = init->ring_size;
1202
        dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
1203
 
1204
        dev_priv->ring.tail_mask =
1205
                (dev_priv->ring.size / sizeof(u32)) - 1;
1206
 
1207
        dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
1208
 
1209
#if __REALLY_HAVE_SG
1210
        if ( dev_priv->is_pci ) {
1211
                if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
1212
                                            &dev_priv->bus_pci_gart)) {
1213
                        DRM_ERROR( "failed to init PCI GART!\n" );
1214
                        dev->dev_private = (void *)dev_priv;
1215
                        radeon_do_cleanup_cp(dev);
1216
                        return -ENOMEM;
1217
                }
1218
                /* Turn on PCI GART
1219
                 */
1220
                tmp = RADEON_READ( RADEON_AIC_CNTL )
1221
                      | RADEON_PCIGART_TRANSLATE_EN;
1222
                RADEON_WRITE( RADEON_AIC_CNTL, tmp );
1223
 
1224
                /* set PCI GART page-table base address
1225
                 */
1226
                RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
1227
 
1228
                /* set address range for PCI address translate
1229
                 */
1230
                RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
1231
                RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
1232
                                                  + dev_priv->agp_size - 1);
1233
 
1234
                /* Turn off AGP aperture -- is this required for PCIGART?
1235
                 */
1236
                RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
1237
                RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
1238
        } else {
1239
#endif /* __REALLY_HAVE_SG */
1240
                /* Turn off PCI GART
1241
                 */
1242
                tmp = RADEON_READ( RADEON_AIC_CNTL )
1243
                      & ~RADEON_PCIGART_TRANSLATE_EN;
1244
                RADEON_WRITE( RADEON_AIC_CNTL, tmp );
1245
#if __REALLY_HAVE_SG
1246
        }
1247
#endif /* __REALLY_HAVE_SG */
1248
 
1249
        radeon_cp_load_microcode( dev_priv );
1250
        radeon_cp_init_ring_buffer( dev, dev_priv );
1251
 
1252
        dev_priv->last_buf = 0;
1253
 
1254
        dev->dev_private = (void *)dev_priv;
1255
 
1256
        radeon_do_engine_reset( dev );
1257
 
1258
        return 0;
1259
}
1260
 
1261
int radeon_do_cleanup_cp( drm_device_t *dev )
1262
{
1263
        DRM_DEBUG( "\n" );
1264
 
1265
        if ( dev->dev_private ) {
1266
                drm_radeon_private_t *dev_priv = dev->dev_private;
1267
 
1268
                if ( !dev_priv->is_pci ) {
1269
                        DRM_IOREMAPFREE( dev_priv->cp_ring, dev );
1270
                        DRM_IOREMAPFREE( dev_priv->ring_rptr, dev );
1271
                        DRM_IOREMAPFREE( dev_priv->buffers, dev );
1272
                } else {
1273
#if __REALLY_HAVE_SG
1274
                        if (!DRM(ati_pcigart_cleanup)( dev,
1275
                                                dev_priv->phys_pci_gart,
1276
                                                dev_priv->bus_pci_gart ))
1277
                                DRM_ERROR( "failed to cleanup PCI GART!\n" );
1278
#endif /* __REALLY_HAVE_SG */
1279
                }
1280
 
1281
                DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
1282
                           DRM_MEM_DRIVER );
1283
                dev->dev_private = NULL;
1284
        }
1285
 
1286
        return 0;
1287
}
1288
 
1289
int radeon_cp_init( struct inode *inode, struct file *filp,
1290
                    unsigned int cmd, unsigned long arg )
1291
{
1292
        drm_file_t *priv = filp->private_data;
1293
        drm_device_t *dev = priv->dev;
1294
        drm_radeon_init_t init;
1295
 
1296
        if ( copy_from_user( &init, (drm_radeon_init_t *)arg, sizeof(init) ) )
1297
                return -EFAULT;
1298
 
1299
        switch ( init.func ) {
1300
        case RADEON_INIT_CP:
1301
        case RADEON_INIT_R200_CP:
1302
                return radeon_do_init_cp( dev, &init );
1303
        case RADEON_CLEANUP_CP:
1304
                return radeon_do_cleanup_cp( dev );
1305
        }
1306
 
1307
        return -EINVAL;
1308
}
1309
 
1310
int radeon_cp_start( struct inode *inode, struct file *filp,
1311
                     unsigned int cmd, unsigned long arg )
1312
{
1313
        drm_file_t *priv = filp->private_data;
1314
        drm_device_t *dev = priv->dev;
1315
        drm_radeon_private_t *dev_priv = dev->dev_private;
1316
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1317
 
1318
        LOCK_TEST_WITH_RETURN( dev );
1319
 
1320
        if ( dev_priv->cp_running ) {
1321
                DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
1322
                return 0;
1323
        }
1324
        if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) {
1325
                DRM_DEBUG( "%s called with bogus CP mode (%d)\n",
1326
                           __FUNCTION__, dev_priv->cp_mode );
1327
                return 0;
1328
        }
1329
 
1330
        radeon_do_cp_start( dev_priv );
1331
 
1332
        return 0;
1333
}
1334
 
1335
/* Stop the CP.  The engine must have been idled before calling this
1336
 * routine.
1337
 */
1338
int radeon_cp_stop( struct inode *inode, struct file *filp,
1339
                    unsigned int cmd, unsigned long arg )
1340
{
1341
        drm_file_t *priv = filp->private_data;
1342
        drm_device_t *dev = priv->dev;
1343
        drm_radeon_private_t *dev_priv = dev->dev_private;
1344
        drm_radeon_cp_stop_t stop;
1345
        int ret;
1346
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1347
 
1348
        LOCK_TEST_WITH_RETURN( dev );
1349
 
1350
        if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
1351
                return -EFAULT;
1352
 
1353
        /* Flush any pending CP commands.  This ensures any outstanding
1354
         * commands are exectuted by the engine before we turn it off.
1355
         */
1356
        if ( stop.flush ) {
1357
                radeon_do_cp_flush( dev_priv );
1358
        }
1359
 
1360
        /* If we fail to make the engine go idle, we return an error
1361
         * code so that the DRM ioctl wrapper can try again.
1362
         */
1363
        if ( stop.idle ) {
1364
                ret = radeon_do_cp_idle( dev_priv );
1365
                if ( ret ) return ret;
1366
        }
1367
 
1368
        /* Finally, we can turn off the CP.  If the engine isn't idle,
1369
         * we will get some dropped triangles as they won't be fully
1370
         * rendered before the CP is shut down.
1371
         */
1372
        radeon_do_cp_stop( dev_priv );
1373
 
1374
        /* Reset the engine */
1375
        radeon_do_engine_reset( dev );
1376
 
1377
        return 0;
1378
}
1379
 
1380
/* Just reset the CP ring.  Called as part of an X Server engine reset.
1381
 */
1382
int radeon_cp_reset( struct inode *inode, struct file *filp,
1383
                     unsigned int cmd, unsigned long arg )
1384
{
1385
        drm_file_t *priv = filp->private_data;
1386
        drm_device_t *dev = priv->dev;
1387
        drm_radeon_private_t *dev_priv = dev->dev_private;
1388
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1389
 
1390
        LOCK_TEST_WITH_RETURN( dev );
1391
 
1392
        if ( !dev_priv ) {
1393
                DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
1394
                return -EINVAL;
1395
        }
1396
 
1397
        radeon_do_cp_reset( dev_priv );
1398
 
1399
        /* The CP is no longer running after an engine reset */
1400
        dev_priv->cp_running = 0;
1401
 
1402
        return 0;
1403
}
1404
 
1405
int radeon_cp_idle( struct inode *inode, struct file *filp,
1406
                    unsigned int cmd, unsigned long arg )
1407
{
1408
        drm_file_t *priv = filp->private_data;
1409
        drm_device_t *dev = priv->dev;
1410
        drm_radeon_private_t *dev_priv = dev->dev_private;
1411
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1412
 
1413
        LOCK_TEST_WITH_RETURN( dev );
1414
 
1415
        return radeon_do_cp_idle( dev_priv );
1416
}
1417
 
1418
int radeon_engine_reset( struct inode *inode, struct file *filp,
1419
                         unsigned int cmd, unsigned long arg )
1420
{
1421
        drm_file_t *priv = filp->private_data;
1422
        drm_device_t *dev = priv->dev;
1423
        DRM_DEBUG( "%s\n", __FUNCTION__ );
1424
 
1425
        LOCK_TEST_WITH_RETURN( dev );
1426
 
1427
        return radeon_do_engine_reset( dev );
1428
}
1429
 
1430
 
1431
/* ================================================================
1432
 * Fullscreen mode
1433
 */
1434
 
1435
/* KW: Deprecated to say the least:
1436
 */
1437
int radeon_fullscreen(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)
1438
{
1439
        return 0;
1440
}
1441
 
1442
 
1443
/* ================================================================
1444
 * Freelist management
1445
 */
1446
 
1447
/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through
1448
 *   bufs until freelist code is used.  Note this hides a problem with
1449
 *   the scratch register * (used to keep track of last buffer
1450
 *   completed) being written to before * the last buffer has actually
1451
 *   completed rendering.
1452
 *
1453
 * KW:  It's also a good way to find free buffers quickly.
1454
 *
1455
 * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
1456
 * sleep.  However, bugs in older versions of radeon_accel.c mean that
1457
 * we essentially have to do this, else old clients will break.
1458
 *
1459
 * However, it does leave open a potential deadlock where all the
1460
 * buffers are held by other clients, which can't release them because
1461
 * they can't get the lock.
1462
 */
1463
 
1464
drm_buf_t *radeon_freelist_get( drm_device_t *dev )
1465
{
1466
        drm_device_dma_t *dma = dev->dma;
1467
        drm_radeon_private_t *dev_priv = dev->dev_private;
1468
        drm_radeon_buf_priv_t *buf_priv;
1469
        drm_buf_t *buf;
1470
        int i, t;
1471
        int start;
1472
 
1473
        if ( ++dev_priv->last_buf >= dma->buf_count )
1474
                dev_priv->last_buf = 0;
1475
 
1476
        start = dev_priv->last_buf;
1477
 
1478
        for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
1479
                u32 done_age = GET_SCRATCH( 1 );
1480
                DRM_DEBUG("done_age = %d\n",done_age);
1481
                for ( i = start ; i < dma->buf_count ; i++ ) {
1482
                        buf = dma->buflist[i];
1483
                        buf_priv = buf->dev_private;
1484
                        if ( buf->pid == 0 || (buf->pending &&
1485
                                               buf_priv->age <= done_age) ) {
1486
                                dev_priv->stats.requested_bufs++;
1487
                                buf->pending = 0;
1488
                                return buf;
1489
                        }
1490
                        start = 0;
1491
                }
1492
 
1493
                if (t) {
1494
                        udelay(1);
1495
                        dev_priv->stats.freelist_loops++;
1496
                }
1497
        }
1498
 
1499
        DRM_DEBUG( "returning NULL!\n" );
1500
        return NULL;
1501
}
1502
#if 0
1503
drm_buf_t *radeon_freelist_get( drm_device_t *dev )
1504
{
1505
        drm_device_dma_t *dma = dev->dma;
1506
        drm_radeon_private_t *dev_priv = dev->dev_private;
1507
        drm_radeon_buf_priv_t *buf_priv;
1508
        drm_buf_t *buf;
1509
        int i, t;
1510
        int start;
1511
        u32 done_age = readl(&dev_priv->scratch[1]);
1512
 
1513
        if ( ++dev_priv->last_buf >= dma->buf_count )
1514
                dev_priv->last_buf = 0;
1515
 
1516
        start = dev_priv->last_buf;
1517
        dev_priv->stats.freelist_loops++;
1518
 
1519
        for ( t = 0 ; t < 2 ; t++ ) {
1520
                for ( i = start ; i < dma->buf_count ; i++ ) {
1521
                        buf = dma->buflist[i];
1522
                        buf_priv = buf->dev_private;
1523
                        if ( buf->pid == 0 || (buf->pending &&
1524
                                               buf_priv->age <= done_age) ) {
1525
                                dev_priv->stats.requested_bufs++;
1526
                                buf->pending = 0;
1527
                                return buf;
1528
                        }
1529
                }
1530
                start = 0;
1531
        }
1532
 
1533
        return NULL;
1534
}
1535
#endif
1536
 
1537
void radeon_freelist_reset( drm_device_t *dev )
1538
{
1539
        drm_device_dma_t *dma = dev->dma;
1540
        drm_radeon_private_t *dev_priv = dev->dev_private;
1541
        int i;
1542
 
1543
        dev_priv->last_buf = 0;
1544
        for ( i = 0 ; i < dma->buf_count ; i++ ) {
1545
                drm_buf_t *buf = dma->buflist[i];
1546
                drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1547
                buf_priv->age = 0;
1548
        }
1549
}
1550
 
1551
 
1552
/* ================================================================
1553
 * CP command submission
1554
 */
1555
 
1556
int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
1557
{
1558
        drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
1559
        int i;
1560
        u32 last_head = GET_RING_HEAD(ring);
1561
 
1562
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
1563
                u32 head = GET_RING_HEAD(ring);
1564
 
1565
                ring->space = (head - ring->tail) * sizeof(u32);
1566
                if ( ring->space <= 0 )
1567
                        ring->space += ring->size;
1568
                if ( ring->space > n )
1569
                        return 0;
1570
 
1571
                dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
1572
 
1573
                if (head != last_head)
1574
                        i = 0;
1575
                last_head = head;
1576
 
1577
                udelay( 1 );
1578
        }
1579
 
1580
        /* FIXME: This return value is ignored in the BEGIN_RING macro! */
1581
#if RADEON_FIFO_DEBUG
1582
        radeon_status( dev_priv );
1583
        DRM_ERROR( "failed!\n" );
1584
#endif
1585
        return -EBUSY;
1586
}
1587
 
1588
static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
1589
{
1590
        int i;
1591
        drm_buf_t *buf;
1592
 
1593
        for ( i = d->granted_count ; i < d->request_count ; i++ ) {
1594
                buf = radeon_freelist_get( dev );
1595
                if ( !buf ) return -EAGAIN;
1596
 
1597
                buf->pid = current->pid;
1598
 
1599
                if ( copy_to_user( &d->request_indices[i], &buf->idx,
1600
                                   sizeof(buf->idx) ) )
1601
                        return -EFAULT;
1602
                if ( copy_to_user( &d->request_sizes[i], &buf->total,
1603
                                   sizeof(buf->total) ) )
1604
                        return -EFAULT;
1605
 
1606
                d->granted_count++;
1607
        }
1608
        return 0;
1609
}
1610
 
1611
int radeon_cp_buffers( struct inode *inode, struct file *filp,
1612
                       unsigned int cmd, unsigned long arg )
1613
{
1614
        drm_file_t *priv = filp->private_data;
1615
        drm_device_t *dev = priv->dev;
1616
        drm_device_dma_t *dma = dev->dma;
1617
        int ret = 0;
1618
        drm_dma_t d;
1619
 
1620
        LOCK_TEST_WITH_RETURN( dev );
1621
 
1622
        if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
1623
                return -EFAULT;
1624
 
1625
        /* Please don't send us buffers.
1626
         */
1627
        if ( d.send_count != 0 ) {
1628
                DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
1629
                           current->pid, d.send_count );
1630
                return -EINVAL;
1631
        }
1632
 
1633
        /* We'll send you buffers.
1634
         */
1635
        if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
1636
                DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
1637
                           current->pid, d.request_count, dma->buf_count );
1638
                return -EINVAL;
1639
        }
1640
 
1641
        d.granted_count = 0;
1642
 
1643
        if ( d.request_count ) {
1644
                ret = radeon_cp_get_buffers( dev, &d );
1645
        }
1646
 
1647
        if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
1648
                return -EFAULT;
1649
 
1650
        return ret;
1651
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.