radeon_cp.c revision 145132
1139749Simp/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */
2139749Simp/*-
395584Sanholt * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
495584Sanholt * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
595584Sanholt * All Rights Reserved.
695584Sanholt *
795584Sanholt * Permission is hereby granted, free of charge, to any person obtaining a
895584Sanholt * copy of this software and associated documentation files (the "Software"),
995584Sanholt * to deal in the Software without restriction, including without limitation
1095584Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1195584Sanholt * and/or sell copies of the Software, and to permit persons to whom the
1295584Sanholt * Software is furnished to do so, subject to the following conditions:
1395584Sanholt *
1495584Sanholt * The above copyright notice and this permission notice (including the next
1595584Sanholt * paragraph) shall be included in all copies or substantial portions of the
1695584Sanholt * Software.
1795584Sanholt *
1895584Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1995584Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2095584Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2195584Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2295584Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2395584Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2495584Sanholt * DEALINGS IN THE SOFTWARE.
2595584Sanholt *
2695584Sanholt * Authors:
2795584Sanholt *    Kevin E. Martin <martin@valinux.com>
2895584Sanholt *    Gareth Hughes <gareth@valinux.com>
2995584Sanholt *
3095584Sanholt * $FreeBSD: head/sys/dev/drm/radeon_cp.c 145132 2005-04-16 03:44:47Z anholt $
3195584Sanholt */
3295584Sanholt
3395584Sanholt#include "dev/drm/drmP.h"
34112015Sanholt#include "dev/drm/drm.h"
3595746Sanholt#include "dev/drm/radeon_drm.h"
3695584Sanholt#include "dev/drm/radeon_drv.h"
3795584Sanholt
3895584Sanholt#define RADEON_FIFO_DEBUG	0
3995584Sanholt
40145132Sanholtstatic int radeon_do_cleanup_cp(drm_device_t * dev);
4195584Sanholt
4295584Sanholt/* CP microcode (from ATI) */
43112015Sanholtstatic u32 R200_cp_microcode[][2] = {
44145132Sanholt	{0x21007000, 0000000000},
45145132Sanholt	{0x20007000, 0000000000},
46145132Sanholt	{0x000000ab, 0x00000004},
47145132Sanholt	{0x000000af, 0x00000004},
48145132Sanholt	{0x66544a49, 0000000000},
49145132Sanholt	{0x49494174, 0000000000},
50145132Sanholt	{0x54517d83, 0000000000},
51145132Sanholt	{0x498d8b64, 0000000000},
52145132Sanholt	{0x49494949, 0000000000},
53145132Sanholt	{0x49da493c, 0000000000},
54145132Sanholt	{0x49989898, 0000000000},
55145132Sanholt	{0xd34949d5, 0000000000},
56145132Sanholt	{0x9dc90e11, 0000000000},
57145132Sanholt	{0xce9b9b9b, 0000000000},
58145132Sanholt	{0x000f0000, 0x00000016},
59145132Sanholt	{0x352e232c, 0000000000},
60145132Sanholt	{0x00000013, 0x00000004},
61145132Sanholt	{0x000f0000, 0x00000016},
62145132Sanholt	{0x352e272c, 0000000000},
63145132Sanholt	{0x000f0001, 0x00000016},
64145132Sanholt	{0x3239362f, 0000000000},
65145132Sanholt	{0x000077ef, 0x00000002},
66145132Sanholt	{0x00061000, 0x00000002},
67145132Sanholt	{0x00000020, 0x0000001a},
68145132Sanholt	{0x00004000, 0x0000001e},
69145132Sanholt	{0x00061000, 0x00000002},
70145132Sanholt	{0x00000020, 0x0000001a},
71145132Sanholt	{0x00004000, 0x0000001e},
72145132Sanholt	{0x00061000, 0x00000002},
73145132Sanholt	{0x00000020, 0x0000001a},
74145132Sanholt	{0x00004000, 0x0000001e},
75145132Sanholt	{0x00000016, 0x00000004},
76145132Sanholt	{0x0003802a, 0x00000002},
77145132Sanholt	{0x040067e0, 0x00000002},
78145132Sanholt	{0x00000016, 0x00000004},
79145132Sanholt	{0x000077e0, 0x00000002},
80145132Sanholt	{0x00065000, 0x00000002},
81145132Sanholt	{0x000037e1, 0x00000002},
82145132Sanholt	{0x040067e1, 0x00000006},
83145132Sanholt	{0x000077e0, 0x00000002},
84145132Sanholt	{0x000077e1, 0x00000002},
85145132Sanholt	{0x000077e1, 0x00000006},
86145132Sanholt	{0xffffffff, 0000000000},
87145132Sanholt	{0x10000000, 0000000000},
88145132Sanholt	{0x0003802a, 0x00000002},
89145132Sanholt	{0x040067e0, 0x00000006},
90145132Sanholt	{0x00007675, 0x00000002},
91145132Sanholt	{0x00007676, 0x00000002},
92145132Sanholt	{0x00007677, 0x00000002},
93145132Sanholt	{0x00007678, 0x00000006},
94145132Sanholt	{0x0003802b, 0x00000002},
95145132Sanholt	{0x04002676, 0x00000002},
96145132Sanholt	{0x00007677, 0x00000002},
97145132Sanholt	{0x00007678, 0x00000006},
98145132Sanholt	{0x0000002e, 0x00000018},
99145132Sanholt	{0x0000002e, 0x00000018},
100145132Sanholt	{0000000000, 0x00000006},
101145132Sanholt	{0x0000002f, 0x00000018},
102145132Sanholt	{0x0000002f, 0x00000018},
103145132Sanholt	{0000000000, 0x00000006},
104145132Sanholt	{0x01605000, 0x00000002},
105145132Sanholt	{0x00065000, 0x00000002},
106145132Sanholt	{0x00098000, 0x00000002},
107145132Sanholt	{0x00061000, 0x00000002},
108145132Sanholt	{0x64c0603d, 0x00000004},
109145132Sanholt	{0x00080000, 0x00000016},
110145132Sanholt	{0000000000, 0000000000},
111145132Sanholt	{0x0400251d, 0x00000002},
112145132Sanholt	{0x00007580, 0x00000002},
113145132Sanholt	{0x00067581, 0x00000002},
114145132Sanholt	{0x04002580, 0x00000002},
115145132Sanholt	{0x00067581, 0x00000002},
116145132Sanholt	{0x00000046, 0x00000004},
117145132Sanholt	{0x00005000, 0000000000},
118145132Sanholt	{0x00061000, 0x00000002},
119145132Sanholt	{0x0000750e, 0x00000002},
120145132Sanholt	{0x00019000, 0x00000002},
121145132Sanholt	{0x00011055, 0x00000014},
122145132Sanholt	{0x00000055, 0x00000012},
123145132Sanholt	{0x0400250f, 0x00000002},
124145132Sanholt	{0x0000504a, 0x00000004},
125145132Sanholt	{0x00007565, 0x00000002},
126145132Sanholt	{0x00007566, 0x00000002},
127145132Sanholt	{0x00000051, 0x00000004},
128145132Sanholt	{0x01e655b4, 0x00000002},
129145132Sanholt	{0x4401b0dc, 0x00000002},
130145132Sanholt	{0x01c110dc, 0x00000002},
131145132Sanholt	{0x2666705d, 0x00000018},
132145132Sanholt	{0x040c2565, 0x00000002},
133145132Sanholt	{0x0000005d, 0x00000018},
134145132Sanholt	{0x04002564, 0x00000002},
135145132Sanholt	{0x00007566, 0x00000002},
136145132Sanholt	{0x00000054, 0x00000004},
137145132Sanholt	{0x00401060, 0x00000008},
138145132Sanholt	{0x00101000, 0x00000002},
139145132Sanholt	{0x000d80ff, 0x00000002},
140145132Sanholt	{0x00800063, 0x00000008},
141145132Sanholt	{0x000f9000, 0x00000002},
142145132Sanholt	{0x000e00ff, 0x00000002},
143145132Sanholt	{0000000000, 0x00000006},
144145132Sanholt	{0x00000080, 0x00000018},
145145132Sanholt	{0x00000054, 0x00000004},
146145132Sanholt	{0x00007576, 0x00000002},
147145132Sanholt	{0x00065000, 0x00000002},
148145132Sanholt	{0x00009000, 0x00000002},
149145132Sanholt	{0x00041000, 0x00000002},
150145132Sanholt	{0x0c00350e, 0x00000002},
151145132Sanholt	{0x00049000, 0x00000002},
152145132Sanholt	{0x00051000, 0x00000002},
153145132Sanholt	{0x01e785f8, 0x00000002},
154145132Sanholt	{0x00200000, 0x00000002},
155145132Sanholt	{0x00600073, 0x0000000c},
156145132Sanholt	{0x00007563, 0x00000002},
157145132Sanholt	{0x006075f0, 0x00000021},
158145132Sanholt	{0x20007068, 0x00000004},
159145132Sanholt	{0x00005068, 0x00000004},
160145132Sanholt	{0x00007576, 0x00000002},
161145132Sanholt	{0x00007577, 0x00000002},
162145132Sanholt	{0x0000750e, 0x00000002},
163145132Sanholt	{0x0000750f, 0x00000002},
164145132Sanholt	{0x00a05000, 0x00000002},
165145132Sanholt	{0x00600076, 0x0000000c},
166145132Sanholt	{0x006075f0, 0x00000021},
167145132Sanholt	{0x000075f8, 0x00000002},
168145132Sanholt	{0x00000076, 0x00000004},
169145132Sanholt	{0x000a750e, 0x00000002},
170145132Sanholt	{0x0020750f, 0x00000002},
171145132Sanholt	{0x00600079, 0x00000004},
172145132Sanholt	{0x00007570, 0x00000002},
173145132Sanholt	{0x00007571, 0x00000002},
174145132Sanholt	{0x00007572, 0x00000006},
175145132Sanholt	{0x00005000, 0x00000002},
176145132Sanholt	{0x00a05000, 0x00000002},
177145132Sanholt	{0x00007568, 0x00000002},
178145132Sanholt	{0x00061000, 0x00000002},
179145132Sanholt	{0x00000084, 0x0000000c},
180145132Sanholt	{0x00058000, 0x00000002},
181145132Sanholt	{0x0c607562, 0x00000002},
182145132Sanholt	{0x00000086, 0x00000004},
183145132Sanholt	{0x00600085, 0x00000004},
184145132Sanholt	{0x400070dd, 0000000000},
185145132Sanholt	{0x000380dd, 0x00000002},
186145132Sanholt	{0x00000093, 0x0000001c},
187145132Sanholt	{0x00065095, 0x00000018},
188145132Sanholt	{0x040025bb, 0x00000002},
189145132Sanholt	{0x00061096, 0x00000018},
190145132Sanholt	{0x040075bc, 0000000000},
191145132Sanholt	{0x000075bb, 0x00000002},
192145132Sanholt	{0x000075bc, 0000000000},
193145132Sanholt	{0x00090000, 0x00000006},
194145132Sanholt	{0x00090000, 0x00000002},
195145132Sanholt	{0x000d8002, 0x00000006},
196145132Sanholt	{0x00005000, 0x00000002},
197145132Sanholt	{0x00007821, 0x00000002},
198145132Sanholt	{0x00007800, 0000000000},
199145132Sanholt	{0x00007821, 0x00000002},
200145132Sanholt	{0x00007800, 0000000000},
201145132Sanholt	{0x01665000, 0x00000002},
202145132Sanholt	{0x000a0000, 0x00000002},
203145132Sanholt	{0x000671cc, 0x00000002},
204145132Sanholt	{0x0286f1cd, 0x00000002},
205145132Sanholt	{0x000000a3, 0x00000010},
206145132Sanholt	{0x21007000, 0000000000},
207145132Sanholt	{0x000000aa, 0x0000001c},
208145132Sanholt	{0x00065000, 0x00000002},
209145132Sanholt	{0x000a0000, 0x00000002},
210145132Sanholt	{0x00061000, 0x00000002},
211145132Sanholt	{0x000b0000, 0x00000002},
212145132Sanholt	{0x38067000, 0x00000002},
213145132Sanholt	{0x000a00a6, 0x00000004},
214145132Sanholt	{0x20007000, 0000000000},
215145132Sanholt	{0x01200000, 0x00000002},
216145132Sanholt	{0x20077000, 0x00000002},
217145132Sanholt	{0x01200000, 0x00000002},
218145132Sanholt	{0x20007000, 0000000000},
219145132Sanholt	{0x00061000, 0x00000002},
220145132Sanholt	{0x0120751b, 0x00000002},
221145132Sanholt	{0x8040750a, 0x00000002},
222145132Sanholt	{0x8040750b, 0x00000002},
223145132Sanholt	{0x00110000, 0x00000002},
224145132Sanholt	{0x000380dd, 0x00000002},
225145132Sanholt	{0x000000bd, 0x0000001c},
226145132Sanholt	{0x00061096, 0x00000018},
227145132Sanholt	{0x844075bd, 0x00000002},
228145132Sanholt	{0x00061095, 0x00000018},
229145132Sanholt	{0x840075bb, 0x00000002},
230145132Sanholt	{0x00061096, 0x00000018},
231145132Sanholt	{0x844075bc, 0x00000002},
232145132Sanholt	{0x000000c0, 0x00000004},
233145132Sanholt	{0x804075bd, 0x00000002},
234145132Sanholt	{0x800075bb, 0x00000002},
235145132Sanholt	{0x804075bc, 0x00000002},
236145132Sanholt	{0x00108000, 0x00000002},
237145132Sanholt	{0x01400000, 0x00000002},
238145132Sanholt	{0x006000c4, 0x0000000c},
239145132Sanholt	{0x20c07000, 0x00000020},
240145132Sanholt	{0x000000c6, 0x00000012},
241145132Sanholt	{0x00800000, 0x00000006},
242145132Sanholt	{0x0080751d, 0x00000006},
243145132Sanholt	{0x000025bb, 0x00000002},
244145132Sanholt	{0x000040c0, 0x00000004},
245145132Sanholt	{0x0000775c, 0x00000002},
246145132Sanholt	{0x00a05000, 0x00000002},
247145132Sanholt	{0x00661000, 0x00000002},
248145132Sanholt	{0x0460275d, 0x00000020},
249145132Sanholt	{0x00004000, 0000000000},
250145132Sanholt	{0x00007999, 0x00000002},
251145132Sanholt	{0x00a05000, 0x00000002},
252145132Sanholt	{0x00661000, 0x00000002},
253145132Sanholt	{0x0460299b, 0x00000020},
254145132Sanholt	{0x00004000, 0000000000},
255145132Sanholt	{0x01e00830, 0x00000002},
256145132Sanholt	{0x21007000, 0000000000},
257145132Sanholt	{0x00005000, 0x00000002},
258145132Sanholt	{0x00038042, 0x00000002},
259145132Sanholt	{0x040025e0, 0x00000002},
260145132Sanholt	{0x000075e1, 0000000000},
261145132Sanholt	{0x00000001, 0000000000},
262145132Sanholt	{0x000380d9, 0x00000002},
263145132Sanholt	{0x04007394, 0000000000},
264145132Sanholt	{0000000000, 0000000000},
265145132Sanholt	{0000000000, 0000000000},
266145132Sanholt	{0000000000, 0000000000},
267145132Sanholt	{0000000000, 0000000000},
268145132Sanholt	{0000000000, 0000000000},
269145132Sanholt	{0000000000, 0000000000},
270145132Sanholt	{0000000000, 0000000000},
271145132Sanholt	{0000000000, 0000000000},
272145132Sanholt	{0000000000, 0000000000},
273145132Sanholt	{0000000000, 0000000000},
274145132Sanholt	{0000000000, 0000000000},
275145132Sanholt	{0000000000, 0000000000},
276145132Sanholt	{0000000000, 0000000000},
277145132Sanholt	{0000000000, 0000000000},
278145132Sanholt	{0000000000, 0000000000},
279145132Sanholt	{0000000000, 0000000000},
280145132Sanholt	{0000000000, 0000000000},
281145132Sanholt	{0000000000, 0000000000},
282145132Sanholt	{0000000000, 0000000000},
283145132Sanholt	{0000000000, 0000000000},
284145132Sanholt	{0000000000, 0000000000},
285145132Sanholt	{0000000000, 0000000000},
286145132Sanholt	{0000000000, 0000000000},
287145132Sanholt	{0000000000, 0000000000},
288145132Sanholt	{0000000000, 0000000000},
289145132Sanholt	{0000000000, 0000000000},
290145132Sanholt	{0000000000, 0000000000},
291145132Sanholt	{0000000000, 0000000000},
292145132Sanholt	{0000000000, 0000000000},
293145132Sanholt	{0000000000, 0000000000},
294145132Sanholt	{0000000000, 0000000000},
295145132Sanholt	{0000000000, 0000000000},
296145132Sanholt	{0000000000, 0000000000},
297145132Sanholt	{0000000000, 0000000000},
298145132Sanholt	{0000000000, 0000000000},
299145132Sanholt	{0000000000, 0000000000},
300112015Sanholt};
301112015Sanholt
302145132Sanholtstatic u32 radeon_cp_microcode[][2] = {
303145132Sanholt	{0x21007000, 0000000000},
304145132Sanholt	{0x20007000, 0000000000},
305145132Sanholt	{0x000000b4, 0x00000004},
306145132Sanholt	{0x000000b8, 0x00000004},
307145132Sanholt	{0x6f5b4d4c, 0000000000},
308145132Sanholt	{0x4c4c427f, 0000000000},
309145132Sanholt	{0x5b568a92, 0000000000},
310145132Sanholt	{0x4ca09c6d, 0000000000},
311145132Sanholt	{0xad4c4c4c, 0000000000},
312145132Sanholt	{0x4ce1af3d, 0000000000},
313145132Sanholt	{0xd8afafaf, 0000000000},
314145132Sanholt	{0xd64c4cdc, 0000000000},
315145132Sanholt	{0x4cd10d10, 0000000000},
316145132Sanholt	{0x000f0000, 0x00000016},
317145132Sanholt	{0x362f242d, 0000000000},
318145132Sanholt	{0x00000012, 0x00000004},
319145132Sanholt	{0x000f0000, 0x00000016},
320145132Sanholt	{0x362f282d, 0000000000},
321145132Sanholt	{0x000380e7, 0x00000002},
322145132Sanholt	{0x04002c97, 0x00000002},
323145132Sanholt	{0x000f0001, 0x00000016},
324145132Sanholt	{0x333a3730, 0000000000},
325145132Sanholt	{0x000077ef, 0x00000002},
326145132Sanholt	{0x00061000, 0x00000002},
327145132Sanholt	{0x00000021, 0x0000001a},
328145132Sanholt	{0x00004000, 0x0000001e},
329145132Sanholt	{0x00061000, 0x00000002},
330145132Sanholt	{0x00000021, 0x0000001a},
331145132Sanholt	{0x00004000, 0x0000001e},
332145132Sanholt	{0x00061000, 0x00000002},
333145132Sanholt	{0x00000021, 0x0000001a},
334145132Sanholt	{0x00004000, 0x0000001e},
335145132Sanholt	{0x00000017, 0x00000004},
336145132Sanholt	{0x0003802b, 0x00000002},
337145132Sanholt	{0x040067e0, 0x00000002},
338145132Sanholt	{0x00000017, 0x00000004},
339145132Sanholt	{0x000077e0, 0x00000002},
340145132Sanholt	{0x00065000, 0x00000002},
341145132Sanholt	{0x000037e1, 0x00000002},
342145132Sanholt	{0x040067e1, 0x00000006},
343145132Sanholt	{0x000077e0, 0x00000002},
344145132Sanholt	{0x000077e1, 0x00000002},
345145132Sanholt	{0x000077e1, 0x00000006},
346145132Sanholt	{0xffffffff, 0000000000},
347145132Sanholt	{0x10000000, 0000000000},
348145132Sanholt	{0x0003802b, 0x00000002},
349145132Sanholt	{0x040067e0, 0x00000006},
350145132Sanholt	{0x00007675, 0x00000002},
351145132Sanholt	{0x00007676, 0x00000002},
352145132Sanholt	{0x00007677, 0x00000002},
353145132Sanholt	{0x00007678, 0x00000006},
354145132Sanholt	{0x0003802c, 0x00000002},
355145132Sanholt	{0x04002676, 0x00000002},
356145132Sanholt	{0x00007677, 0x00000002},
357145132Sanholt	{0x00007678, 0x00000006},
358145132Sanholt	{0x0000002f, 0x00000018},
359145132Sanholt	{0x0000002f, 0x00000018},
360145132Sanholt	{0000000000, 0x00000006},
361145132Sanholt	{0x00000030, 0x00000018},
362145132Sanholt	{0x00000030, 0x00000018},
363145132Sanholt	{0000000000, 0x00000006},
364145132Sanholt	{0x01605000, 0x00000002},
365145132Sanholt	{0x00065000, 0x00000002},
366145132Sanholt	{0x00098000, 0x00000002},
367145132Sanholt	{0x00061000, 0x00000002},
368145132Sanholt	{0x64c0603e, 0x00000004},
369145132Sanholt	{0x000380e6, 0x00000002},
370145132Sanholt	{0x040025c5, 0x00000002},
371145132Sanholt	{0x00080000, 0x00000016},
372145132Sanholt	{0000000000, 0000000000},
373145132Sanholt	{0x0400251d, 0x00000002},
374145132Sanholt	{0x00007580, 0x00000002},
375145132Sanholt	{0x00067581, 0x00000002},
376145132Sanholt	{0x04002580, 0x00000002},
377145132Sanholt	{0x00067581, 0x00000002},
378145132Sanholt	{0x00000049, 0x00000004},
379145132Sanholt	{0x00005000, 0000000000},
380145132Sanholt	{0x000380e6, 0x00000002},
381145132Sanholt	{0x040025c5, 0x00000002},
382145132Sanholt	{0x00061000, 0x00000002},
383145132Sanholt	{0x0000750e, 0x00000002},
384145132Sanholt	{0x00019000, 0x00000002},
385145132Sanholt	{0x00011055, 0x00000014},
386145132Sanholt	{0x00000055, 0x00000012},
387145132Sanholt	{0x0400250f, 0x00000002},
388145132Sanholt	{0x0000504f, 0x00000004},
389145132Sanholt	{0x000380e6, 0x00000002},
390145132Sanholt	{0x040025c5, 0x00000002},
391145132Sanholt	{0x00007565, 0x00000002},
392145132Sanholt	{0x00007566, 0x00000002},
393145132Sanholt	{0x00000058, 0x00000004},
394145132Sanholt	{0x000380e6, 0x00000002},
395145132Sanholt	{0x040025c5, 0x00000002},
396145132Sanholt	{0x01e655b4, 0x00000002},
397145132Sanholt	{0x4401b0e4, 0x00000002},
398145132Sanholt	{0x01c110e4, 0x00000002},
399145132Sanholt	{0x26667066, 0x00000018},
400145132Sanholt	{0x040c2565, 0x00000002},
401145132Sanholt	{0x00000066, 0x00000018},
402145132Sanholt	{0x04002564, 0x00000002},
403145132Sanholt	{0x00007566, 0x00000002},
404145132Sanholt	{0x0000005d, 0x00000004},
405145132Sanholt	{0x00401069, 0x00000008},
406145132Sanholt	{0x00101000, 0x00000002},
407145132Sanholt	{0x000d80ff, 0x00000002},
408145132Sanholt	{0x0080006c, 0x00000008},
409145132Sanholt	{0x000f9000, 0x00000002},
410145132Sanholt	{0x000e00ff, 0x00000002},
411145132Sanholt	{0000000000, 0x00000006},
412145132Sanholt	{0x0000008f, 0x00000018},
413145132Sanholt	{0x0000005b, 0x00000004},
414145132Sanholt	{0x000380e6, 0x00000002},
415145132Sanholt	{0x040025c5, 0x00000002},
416145132Sanholt	{0x00007576, 0x00000002},
417145132Sanholt	{0x00065000, 0x00000002},
418145132Sanholt	{0x00009000, 0x00000002},
419145132Sanholt	{0x00041000, 0x00000002},
420145132Sanholt	{0x0c00350e, 0x00000002},
421145132Sanholt	{0x00049000, 0x00000002},
422145132Sanholt	{0x00051000, 0x00000002},
423145132Sanholt	{0x01e785f8, 0x00000002},
424145132Sanholt	{0x00200000, 0x00000002},
425145132Sanholt	{0x0060007e, 0x0000000c},
426145132Sanholt	{0x00007563, 0x00000002},
427145132Sanholt	{0x006075f0, 0x00000021},
428145132Sanholt	{0x20007073, 0x00000004},
429145132Sanholt	{0x00005073, 0x00000004},
430145132Sanholt	{0x000380e6, 0x00000002},
431145132Sanholt	{0x040025c5, 0x00000002},
432145132Sanholt	{0x00007576, 0x00000002},
433145132Sanholt	{0x00007577, 0x00000002},
434145132Sanholt	{0x0000750e, 0x00000002},
435145132Sanholt	{0x0000750f, 0x00000002},
436145132Sanholt	{0x00a05000, 0x00000002},
437145132Sanholt	{0x00600083, 0x0000000c},
438145132Sanholt	{0x006075f0, 0x00000021},
439145132Sanholt	{0x000075f8, 0x00000002},
440145132Sanholt	{0x00000083, 0x00000004},
441145132Sanholt	{0x000a750e, 0x00000002},
442145132Sanholt	{0x000380e6, 0x00000002},
443145132Sanholt	{0x040025c5, 0x00000002},
444145132Sanholt	{0x0020750f, 0x00000002},
445145132Sanholt	{0x00600086, 0x00000004},
446145132Sanholt	{0x00007570, 0x00000002},
447145132Sanholt	{0x00007571, 0x00000002},
448145132Sanholt	{0x00007572, 0x00000006},
449145132Sanholt	{0x000380e6, 0x00000002},
450145132Sanholt	{0x040025c5, 0x00000002},
451145132Sanholt	{0x00005000, 0x00000002},
452145132Sanholt	{0x00a05000, 0x00000002},
453145132Sanholt	{0x00007568, 0x00000002},
454145132Sanholt	{0x00061000, 0x00000002},
455145132Sanholt	{0x00000095, 0x0000000c},
456145132Sanholt	{0x00058000, 0x00000002},
457145132Sanholt	{0x0c607562, 0x00000002},
458145132Sanholt	{0x00000097, 0x00000004},
459145132Sanholt	{0x000380e6, 0x00000002},
460145132Sanholt	{0x040025c5, 0x00000002},
461145132Sanholt	{0x00600096, 0x00000004},
462145132Sanholt	{0x400070e5, 0000000000},
463145132Sanholt	{0x000380e6, 0x00000002},
464145132Sanholt	{0x040025c5, 0x00000002},
465145132Sanholt	{0x000380e5, 0x00000002},
466145132Sanholt	{0x000000a8, 0x0000001c},
467145132Sanholt	{0x000650aa, 0x00000018},
468145132Sanholt	{0x040025bb, 0x00000002},
469145132Sanholt	{0x000610ab, 0x00000018},
470145132Sanholt	{0x040075bc, 0000000000},
471145132Sanholt	{0x000075bb, 0x00000002},
472145132Sanholt	{0x000075bc, 0000000000},
473145132Sanholt	{0x00090000, 0x00000006},
474145132Sanholt	{0x00090000, 0x00000002},
475145132Sanholt	{0x000d8002, 0x00000006},
476145132Sanholt	{0x00007832, 0x00000002},
477145132Sanholt	{0x00005000, 0x00000002},
478145132Sanholt	{0x000380e7, 0x00000002},
479145132Sanholt	{0x04002c97, 0x00000002},
480145132Sanholt	{0x00007820, 0x00000002},
481145132Sanholt	{0x00007821, 0x00000002},
482145132Sanholt	{0x00007800, 0000000000},
483145132Sanholt	{0x01200000, 0x00000002},
484145132Sanholt	{0x20077000, 0x00000002},
485145132Sanholt	{0x01200000, 0x00000002},
486145132Sanholt	{0x20007000, 0x00000002},
487145132Sanholt	{0x00061000, 0x00000002},
488145132Sanholt	{0x0120751b, 0x00000002},
489145132Sanholt	{0x8040750a, 0x00000002},
490145132Sanholt	{0x8040750b, 0x00000002},
491145132Sanholt	{0x00110000, 0x00000002},
492145132Sanholt	{0x000380e5, 0x00000002},
493145132Sanholt	{0x000000c6, 0x0000001c},
494145132Sanholt	{0x000610ab, 0x00000018},
495145132Sanholt	{0x844075bd, 0x00000002},
496145132Sanholt	{0x000610aa, 0x00000018},
497145132Sanholt	{0x840075bb, 0x00000002},
498145132Sanholt	{0x000610ab, 0x00000018},
499145132Sanholt	{0x844075bc, 0x00000002},
500145132Sanholt	{0x000000c9, 0x00000004},
501145132Sanholt	{0x804075bd, 0x00000002},
502145132Sanholt	{0x800075bb, 0x00000002},
503145132Sanholt	{0x804075bc, 0x00000002},
504145132Sanholt	{0x00108000, 0x00000002},
505145132Sanholt	{0x01400000, 0x00000002},
506145132Sanholt	{0x006000cd, 0x0000000c},
507145132Sanholt	{0x20c07000, 0x00000020},
508145132Sanholt	{0x000000cf, 0x00000012},
509145132Sanholt	{0x00800000, 0x00000006},
510145132Sanholt	{0x0080751d, 0x00000006},
511145132Sanholt	{0000000000, 0000000000},
512145132Sanholt	{0x0000775c, 0x00000002},
513145132Sanholt	{0x00a05000, 0x00000002},
514145132Sanholt	{0x00661000, 0x00000002},
515145132Sanholt	{0x0460275d, 0x00000020},
516145132Sanholt	{0x00004000, 0000000000},
517145132Sanholt	{0x01e00830, 0x00000002},
518145132Sanholt	{0x21007000, 0000000000},
519145132Sanholt	{0x6464614d, 0000000000},
520145132Sanholt	{0x69687420, 0000000000},
521145132Sanholt	{0x00000073, 0000000000},
522145132Sanholt	{0000000000, 0000000000},
523145132Sanholt	{0x00005000, 0x00000002},
524145132Sanholt	{0x000380d0, 0x00000002},
525145132Sanholt	{0x040025e0, 0x00000002},
526145132Sanholt	{0x000075e1, 0000000000},
527145132Sanholt	{0x00000001, 0000000000},
528145132Sanholt	{0x000380e0, 0x00000002},
529145132Sanholt	{0x04002394, 0x00000002},
530145132Sanholt	{0x00005000, 0000000000},
531145132Sanholt	{0000000000, 0000000000},
532145132Sanholt	{0000000000, 0000000000},
533145132Sanholt	{0x00000008, 0000000000},
534145132Sanholt	{0x00000004, 0000000000},
535145132Sanholt	{0000000000, 0000000000},
536145132Sanholt	{0000000000, 0000000000},
537145132Sanholt	{0000000000, 0000000000},
538145132Sanholt	{0000000000, 0000000000},
539145132Sanholt	{0000000000, 0000000000},
540145132Sanholt	{0000000000, 0000000000},
541145132Sanholt	{0000000000, 0000000000},
542145132Sanholt	{0000000000, 0000000000},
543145132Sanholt	{0000000000, 0000000000},
544145132Sanholt	{0000000000, 0000000000},
545145132Sanholt	{0000000000, 0000000000},
546145132Sanholt	{0000000000, 0000000000},
547145132Sanholt	{0000000000, 0000000000},
548145132Sanholt	{0000000000, 0000000000},
549145132Sanholt	{0000000000, 0000000000},
550145132Sanholt	{0000000000, 0000000000},
551145132Sanholt	{0000000000, 0000000000},
552145132Sanholt	{0000000000, 0000000000},
553145132Sanholt	{0000000000, 0000000000},
554145132Sanholt	{0000000000, 0000000000},
555145132Sanholt	{0000000000, 0000000000},
556145132Sanholt	{0000000000, 0000000000},
557145132Sanholt	{0000000000, 0000000000},
558145132Sanholt	{0000000000, 0000000000},
559145132Sanholt};
560112015Sanholt
561145132Sanholtstatic u32 R300_cp_microcode[][2] = {
562145132Sanholt	{ 0x4200e000, 0000000000 },
563145132Sanholt	{ 0x4000e000, 0000000000 },
564145132Sanholt	{ 0x000000af, 0x00000008 },
565145132Sanholt	{ 0x000000b3, 0x00000008 },
566145132Sanholt	{ 0x6c5a504f, 0000000000 },
567145132Sanholt	{ 0x4f4f497a, 0000000000 },
568145132Sanholt	{ 0x5a578288, 0000000000 },
569145132Sanholt	{ 0x4f91906a, 0000000000 },
570145132Sanholt	{ 0x4f4f4f4f, 0000000000 },
571145132Sanholt	{ 0x4fe24f44, 0000000000 },
572145132Sanholt	{ 0x4f9c9c9c, 0000000000 },
573145132Sanholt	{ 0xdc4f4fde, 0000000000 },
574145132Sanholt	{ 0xa1cd4f4f, 0000000000 },
575145132Sanholt	{ 0xd29d9d9d, 0000000000 },
576145132Sanholt	{ 0x4f0f9fd7, 0000000000 },
577145132Sanholt	{ 0x000ca000, 0x00000004 },
578145132Sanholt	{ 0x000d0012, 0x00000038 },
579145132Sanholt	{ 0x0000e8b4, 0x00000004 },
580145132Sanholt	{ 0x000d0014, 0x00000038 },
581145132Sanholt	{ 0x0000e8b6, 0x00000004 },
582145132Sanholt	{ 0x000d0016, 0x00000038 },
583145132Sanholt	{ 0x0000e854, 0x00000004 },
584145132Sanholt	{ 0x000d0018, 0x00000038 },
585145132Sanholt	{ 0x0000e855, 0x00000004 },
586145132Sanholt	{ 0x000d001a, 0x00000038 },
587145132Sanholt	{ 0x0000e856, 0x00000004 },
588145132Sanholt	{ 0x000d001c, 0x00000038 },
589145132Sanholt	{ 0x0000e857, 0x00000004 },
590145132Sanholt	{ 0x000d001e, 0x00000038 },
591145132Sanholt	{ 0x0000e824, 0x00000004 },
592145132Sanholt	{ 0x000d0020, 0x00000038 },
593145132Sanholt	{ 0x0000e825, 0x00000004 },
594145132Sanholt	{ 0x000d0022, 0x00000038 },
595145132Sanholt	{ 0x0000e830, 0x00000004 },
596145132Sanholt	{ 0x000d0024, 0x00000038 },
597145132Sanholt	{ 0x0000f0c0, 0x00000004 },
598145132Sanholt	{ 0x000d0026, 0x00000038 },
599145132Sanholt	{ 0x0000f0c1, 0x00000004 },
600145132Sanholt	{ 0x000d0028, 0x00000038 },
601145132Sanholt	{ 0x0000f041, 0x00000004 },
602145132Sanholt	{ 0x000d002a, 0x00000038 },
603145132Sanholt	{ 0x0000f184, 0x00000004 },
604145132Sanholt	{ 0x000d002c, 0x00000038 },
605145132Sanholt	{ 0x0000f185, 0x00000004 },
606145132Sanholt	{ 0x000d002e, 0x00000038 },
607145132Sanholt	{ 0x0000f186, 0x00000004 },
608145132Sanholt	{ 0x000d0030, 0x00000038 },
609145132Sanholt	{ 0x0000f187, 0x00000004 },
610145132Sanholt	{ 0x000d0032, 0x00000038 },
611145132Sanholt	{ 0x0000f180, 0x00000004 },
612145132Sanholt	{ 0x000d0034, 0x00000038 },
613145132Sanholt	{ 0x0000f393, 0x00000004 },
614145132Sanholt	{ 0x000d0036, 0x00000038 },
615145132Sanholt	{ 0x0000f38a, 0x00000004 },
616145132Sanholt	{ 0x000d0038, 0x00000038 },
617145132Sanholt	{ 0x0000f38e, 0x00000004 },
618145132Sanholt	{ 0x0000e821, 0x00000004 },
619145132Sanholt	{ 0x0140a000, 0x00000004 },
620145132Sanholt	{ 0x00000043, 0x00000018 },
621145132Sanholt	{ 0x00cce800, 0x00000004 },
622145132Sanholt	{ 0x001b0001, 0x00000004 },
623145132Sanholt	{ 0x08004800, 0x00000004 },
624145132Sanholt	{ 0x001b0001, 0x00000004 },
625145132Sanholt	{ 0x08004800, 0x00000004 },
626145132Sanholt	{ 0x001b0001, 0x00000004 },
627145132Sanholt	{ 0x08004800, 0x00000004 },
628145132Sanholt	{ 0x0000003a, 0x00000008 },
629145132Sanholt	{ 0x0000a000, 0000000000 },
630145132Sanholt	{ 0x02c0a000, 0x00000004 },
631145132Sanholt	{ 0x000ca000, 0x00000004 },
632145132Sanholt	{ 0x00130000, 0x00000004 },
633145132Sanholt	{ 0x000c2000, 0x00000004 },
634145132Sanholt	{ 0xc980c045, 0x00000008 },
635145132Sanholt	{ 0x2000451d, 0x00000004 },
636145132Sanholt	{ 0x0000e580, 0x00000004 },
637145132Sanholt	{ 0x000ce581, 0x00000004 },
638145132Sanholt	{ 0x08004580, 0x00000004 },
639145132Sanholt	{ 0x000ce581, 0x00000004 },
640145132Sanholt	{ 0x0000004c, 0x00000008 },
641145132Sanholt	{ 0x0000a000, 0000000000 },
642145132Sanholt	{ 0x000c2000, 0x00000004 },
643145132Sanholt	{ 0x0000e50e, 0x00000004 },
644145132Sanholt	{ 0x00032000, 0x00000004 },
645145132Sanholt	{ 0x00022056, 0x00000028 },
646145132Sanholt	{ 0x00000056, 0x00000024 },
647145132Sanholt	{ 0x0800450f, 0x00000004 },
648145132Sanholt	{ 0x0000a050, 0x00000008 },
649145132Sanholt	{ 0x0000e565, 0x00000004 },
650145132Sanholt	{ 0x0000e566, 0x00000004 },
651145132Sanholt	{ 0x00000057, 0x00000008 },
652145132Sanholt	{ 0x03cca5b4, 0x00000004 },
653145132Sanholt	{ 0x05432000, 0x00000004 },
654145132Sanholt	{ 0x00022000, 0x00000004 },
655145132Sanholt	{ 0x4ccce063, 0x00000030 },
656145132Sanholt	{ 0x08274565, 0x00000004 },
657145132Sanholt	{ 0x00000063, 0x00000030 },
658145132Sanholt	{ 0x08004564, 0x00000004 },
659145132Sanholt	{ 0x0000e566, 0x00000004 },
660145132Sanholt	{ 0x0000005a, 0x00000008 },
661145132Sanholt	{ 0x00802066, 0x00000010 },
662145132Sanholt	{ 0x00202000, 0x00000004 },
663145132Sanholt	{ 0x001b00ff, 0x00000004 },
664145132Sanholt	{ 0x01000069, 0x00000010 },
665145132Sanholt	{ 0x001f2000, 0x00000004 },
666145132Sanholt	{ 0x001c00ff, 0x00000004 },
667145132Sanholt	{ 0000000000, 0x0000000c },
668145132Sanholt	{ 0x00000085, 0x00000030 },
669145132Sanholt	{ 0x0000005a, 0x00000008 },
670145132Sanholt	{ 0x0000e576, 0x00000004 },
671145132Sanholt	{ 0x000ca000, 0x00000004 },
672145132Sanholt	{ 0x00012000, 0x00000004 },
673145132Sanholt	{ 0x00082000, 0x00000004 },
674145132Sanholt	{ 0x1800650e, 0x00000004 },
675145132Sanholt	{ 0x00092000, 0x00000004 },
676145132Sanholt	{ 0x000a2000, 0x00000004 },
677145132Sanholt	{ 0x000f0000, 0x00000004 },
678145132Sanholt	{ 0x00400000, 0x00000004 },
679145132Sanholt	{ 0x00000079, 0x00000018 },
680145132Sanholt	{ 0x0000e563, 0x00000004 },
681145132Sanholt	{ 0x00c0e5f9, 0x000000c2 },
682145132Sanholt	{ 0x0000006e, 0x00000008 },
683145132Sanholt	{ 0x0000a06e, 0x00000008 },
684145132Sanholt	{ 0x0000e576, 0x00000004 },
685145132Sanholt	{ 0x0000e577, 0x00000004 },
686145132Sanholt	{ 0x0000e50e, 0x00000004 },
687145132Sanholt	{ 0x0000e50f, 0x00000004 },
688145132Sanholt	{ 0x0140a000, 0x00000004 },
689145132Sanholt	{ 0x0000007c, 0x00000018 },
690145132Sanholt	{ 0x00c0e5f9, 0x000000c2 },
691145132Sanholt	{ 0x0000007c, 0x00000008 },
692145132Sanholt	{ 0x0014e50e, 0x00000004 },
693145132Sanholt	{ 0x0040e50f, 0x00000004 },
694145132Sanholt	{ 0x00c0007f, 0x00000008 },
695145132Sanholt	{ 0x0000e570, 0x00000004 },
696145132Sanholt	{ 0x0000e571, 0x00000004 },
697145132Sanholt	{ 0x0000e572, 0x0000000c },
698145132Sanholt	{ 0x0000a000, 0x00000004 },
699145132Sanholt	{ 0x0140a000, 0x00000004 },
700145132Sanholt	{ 0x0000e568, 0x00000004 },
701145132Sanholt	{ 0x000c2000, 0x00000004 },
702145132Sanholt	{ 0x00000089, 0x00000018 },
703145132Sanholt	{ 0x000b0000, 0x00000004 },
704145132Sanholt	{ 0x18c0e562, 0x00000004 },
705145132Sanholt	{ 0x0000008b, 0x00000008 },
706145132Sanholt	{ 0x00c0008a, 0x00000008 },
707145132Sanholt	{ 0x000700e4, 0x00000004 },
708145132Sanholt	{ 0x00000097, 0x00000038 },
709145132Sanholt	{ 0x000ca099, 0x00000030 },
710145132Sanholt	{ 0x080045bb, 0x00000004 },
711145132Sanholt	{ 0x000c209a, 0x00000030 },
712145132Sanholt	{ 0x0800e5bc, 0000000000 },
713145132Sanholt	{ 0x0000e5bb, 0x00000004 },
714145132Sanholt	{ 0x0000e5bc, 0000000000 },
715145132Sanholt	{ 0x00120000, 0x0000000c },
716145132Sanholt	{ 0x00120000, 0x00000004 },
717145132Sanholt	{ 0x001b0002, 0x0000000c },
718145132Sanholt	{ 0x0000a000, 0x00000004 },
719145132Sanholt	{ 0x0000e821, 0x00000004 },
720145132Sanholt	{ 0x0000e800, 0000000000 },
721145132Sanholt	{ 0x0000e821, 0x00000004 },
722145132Sanholt	{ 0x0000e82e, 0000000000 },
723145132Sanholt	{ 0x02cca000, 0x00000004 },
724145132Sanholt	{ 0x00140000, 0x00000004 },
725145132Sanholt	{ 0x000ce1cc, 0x00000004 },
726145132Sanholt	{ 0x050de1cd, 0x00000004 },
727145132Sanholt	{ 0x000000a7, 0x00000020 },
728145132Sanholt	{ 0x4200e000, 0000000000 },
729145132Sanholt	{ 0x000000ae, 0x00000038 },
730145132Sanholt	{ 0x000ca000, 0x00000004 },
731145132Sanholt	{ 0x00140000, 0x00000004 },
732145132Sanholt	{ 0x000c2000, 0x00000004 },
733145132Sanholt	{ 0x00160000, 0x00000004 },
734145132Sanholt	{ 0x700ce000, 0x00000004 },
735145132Sanholt	{ 0x001400aa, 0x00000008 },
736145132Sanholt	{ 0x4000e000, 0000000000 },
737145132Sanholt	{ 0x02400000, 0x00000004 },
738145132Sanholt	{ 0x400ee000, 0x00000004 },
739145132Sanholt	{ 0x02400000, 0x00000004 },
740145132Sanholt	{ 0x4000e000, 0000000000 },
741145132Sanholt	{ 0x000c2000, 0x00000004 },
742145132Sanholt	{ 0x0240e51b, 0x00000004 },
743145132Sanholt	{ 0x0080e50a, 0x00000005 },
744145132Sanholt	{ 0x0080e50b, 0x00000005 },
745145132Sanholt	{ 0x00220000, 0x00000004 },
746145132Sanholt	{ 0x000700e4, 0x00000004 },
747145132Sanholt	{ 0x000000c1, 0x00000038 },
748145132Sanholt	{ 0x000c209a, 0x00000030 },
749145132Sanholt	{ 0x0880e5bd, 0x00000005 },
750145132Sanholt	{ 0x000c2099, 0x00000030 },
751145132Sanholt	{ 0x0800e5bb, 0x00000005 },
752145132Sanholt	{ 0x000c209a, 0x00000030 },
753145132Sanholt	{ 0x0880e5bc, 0x00000005 },
754145132Sanholt	{ 0x000000c4, 0x00000008 },
755145132Sanholt	{ 0x0080e5bd, 0x00000005 },
756145132Sanholt	{ 0x0000e5bb, 0x00000005 },
757145132Sanholt	{ 0x0080e5bc, 0x00000005 },
758145132Sanholt	{ 0x00210000, 0x00000004 },
759145132Sanholt	{ 0x02800000, 0x00000004 },
760145132Sanholt	{ 0x00c000c8, 0x00000018 },
761145132Sanholt	{ 0x4180e000, 0x00000040 },
762145132Sanholt	{ 0x000000ca, 0x00000024 },
763145132Sanholt	{ 0x01000000, 0x0000000c },
764145132Sanholt	{ 0x0100e51d, 0x0000000c },
765145132Sanholt	{ 0x000045bb, 0x00000004 },
766145132Sanholt	{ 0x000080c4, 0x00000008 },
767145132Sanholt	{ 0x0000f3ce, 0x00000004 },
768145132Sanholt	{ 0x0140a000, 0x00000004 },
769145132Sanholt	{ 0x00cc2000, 0x00000004 },
770145132Sanholt	{ 0x08c053cf, 0x00000040 },
771145132Sanholt	{ 0x00008000, 0000000000 },
772145132Sanholt	{ 0x0000f3d2, 0x00000004 },
773145132Sanholt	{ 0x0140a000, 0x00000004 },
774145132Sanholt	{ 0x00cc2000, 0x00000004 },
775145132Sanholt	{ 0x08c053d3, 0x00000040 },
776145132Sanholt	{ 0x00008000, 0000000000 },
777145132Sanholt	{ 0x0000f39d, 0x00000004 },
778145132Sanholt	{ 0x0140a000, 0x00000004 },
779145132Sanholt	{ 0x00cc2000, 0x00000004 },
780145132Sanholt	{ 0x08c0539e, 0x00000040 },
781145132Sanholt	{ 0x00008000, 0000000000 },
782145132Sanholt	{ 0x03c00830, 0x00000004 },
783145132Sanholt	{ 0x4200e000, 0000000000 },
784145132Sanholt	{ 0x0000a000, 0x00000004 },
785145132Sanholt	{ 0x200045e0, 0x00000004 },
786145132Sanholt	{ 0x0000e5e1, 0000000000 },
787145132Sanholt	{ 0x00000001, 0000000000 },
788145132Sanholt	{ 0x000700e1, 0x00000004 },
789145132Sanholt	{ 0x0800e394, 0000000000 },
79095584Sanholt	{ 0000000000, 0000000000 },
79195584Sanholt	{ 0000000000, 0000000000 },
79295584Sanholt	{ 0000000000, 0000000000 },
79395584Sanholt	{ 0000000000, 0000000000 },
79495584Sanholt	{ 0000000000, 0000000000 },
79595584Sanholt	{ 0000000000, 0000000000 },
79695584Sanholt	{ 0000000000, 0000000000 },
79795584Sanholt	{ 0000000000, 0000000000 },
79895584Sanholt	{ 0000000000, 0000000000 },
79995584Sanholt	{ 0000000000, 0000000000 },
80095584Sanholt	{ 0000000000, 0000000000 },
80195584Sanholt	{ 0000000000, 0000000000 },
80295584Sanholt	{ 0000000000, 0000000000 },
80395584Sanholt	{ 0000000000, 0000000000 },
80495584Sanholt	{ 0000000000, 0000000000 },
80595584Sanholt	{ 0000000000, 0000000000 },
80695584Sanholt	{ 0000000000, 0000000000 },
80795584Sanholt	{ 0000000000, 0000000000 },
80895584Sanholt	{ 0000000000, 0000000000 },
80995584Sanholt	{ 0000000000, 0000000000 },
81095584Sanholt	{ 0000000000, 0000000000 },
81195584Sanholt	{ 0000000000, 0000000000 },
81295584Sanholt	{ 0000000000, 0000000000 },
81395584Sanholt	{ 0000000000, 0000000000 },
81495584Sanholt	{ 0000000000, 0000000000 },
81595584Sanholt	{ 0000000000, 0000000000 },
81695584Sanholt	{ 0000000000, 0000000000 },
81795584Sanholt	{ 0000000000, 0000000000 },
81895584Sanholt};
81995584Sanholt
820145132Sanholtstatic int RADEON_READ_PLL(drm_device_t * dev, int addr)
82195584Sanholt{
82295584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
82395584Sanholt
82495584Sanholt	RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
82595584Sanholt	return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
82695584Sanholt}
82795584Sanholt
82895584Sanholt#if RADEON_FIFO_DEBUG
829145132Sanholtstatic void radeon_status(drm_radeon_private_t * dev_priv)
83095584Sanholt{
831145132Sanholt	printk("%s:\n", __FUNCTION__);
832145132Sanholt	printk("RBBM_STATUS = 0x%08x\n",
833145132Sanholt	       (unsigned int)RADEON_READ(RADEON_RBBM_STATUS));
834145132Sanholt	printk("CP_RB_RTPR = 0x%08x\n",
835145132Sanholt	       (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR));
836145132Sanholt	printk("CP_RB_WTPR = 0x%08x\n",
837145132Sanholt	       (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR));
838145132Sanholt	printk("AIC_CNTL = 0x%08x\n",
839145132Sanholt	       (unsigned int)RADEON_READ(RADEON_AIC_CNTL));
840145132Sanholt	printk("AIC_STAT = 0x%08x\n",
841145132Sanholt	       (unsigned int)RADEON_READ(RADEON_AIC_STAT));
842145132Sanholt	printk("AIC_PT_BASE = 0x%08x\n",
843145132Sanholt	       (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE));
844145132Sanholt	printk("TLB_ADDR = 0x%08x\n",
845145132Sanholt	       (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR));
846145132Sanholt	printk("TLB_DATA = 0x%08x\n",
847145132Sanholt	       (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA));
84895584Sanholt}
84995584Sanholt#endif
85095584Sanholt
85195584Sanholt/* ================================================================
85295584Sanholt * Engine, FIFO control
85395584Sanholt */
85495584Sanholt
855145132Sanholtstatic int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
85695584Sanholt{
85795584Sanholt	u32 tmp;
85895584Sanholt	int i;
85995584Sanholt
860112015Sanholt	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
861112015Sanholt
862145132Sanholt	tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT);
86395584Sanholt	tmp |= RADEON_RB2D_DC_FLUSH_ALL;
864145132Sanholt	RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp);
86595584Sanholt
866145132Sanholt	for (i = 0; i < dev_priv->usec_timeout; i++) {
867145132Sanholt		if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT)
868145132Sanholt		      & RADEON_RB2D_DC_BUSY)) {
86995584Sanholt			return 0;
87095584Sanholt		}
871145132Sanholt		DRM_UDELAY(1);
87295584Sanholt	}
87395584Sanholt
87495584Sanholt#if RADEON_FIFO_DEBUG
875145132Sanholt	DRM_ERROR("failed!\n");
876145132Sanholt	radeon_status(dev_priv);
87795584Sanholt#endif
878112015Sanholt	return DRM_ERR(EBUSY);
87995584Sanholt}
88095584Sanholt
881145132Sanholtstatic int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
88295584Sanholt{
88395584Sanholt	int i;
88495584Sanholt
885112015Sanholt	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
886112015Sanholt
887145132Sanholt	for (i = 0; i < dev_priv->usec_timeout; i++) {
888145132Sanholt		int slots = (RADEON_READ(RADEON_RBBM_STATUS)
889145132Sanholt			     & RADEON_RBBM_FIFOCNT_MASK);
890145132Sanholt		if (slots >= entries)
891145132Sanholt			return 0;
892145132Sanholt		DRM_UDELAY(1);
89395584Sanholt	}
89495584Sanholt
89595584Sanholt#if RADEON_FIFO_DEBUG
896145132Sanholt	DRM_ERROR("failed!\n");
897145132Sanholt	radeon_status(dev_priv);
89895584Sanholt#endif
899112015Sanholt	return DRM_ERR(EBUSY);
90095584Sanholt}
90195584Sanholt
902145132Sanholtstatic int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
90395584Sanholt{
90495584Sanholt	int i, ret;
90595584Sanholt
906112015Sanholt	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
907112015Sanholt
908145132Sanholt	ret = radeon_do_wait_for_fifo(dev_priv, 64);
909145132Sanholt	if (ret)
910145132Sanholt		return ret;
911112015Sanholt
912145132Sanholt	for (i = 0; i < dev_priv->usec_timeout; i++) {
913145132Sanholt		if (!(RADEON_READ(RADEON_RBBM_STATUS)
914145132Sanholt		      & RADEON_RBBM_ACTIVE)) {
915145132Sanholt			radeon_do_pixcache_flush(dev_priv);
91695584Sanholt			return 0;
91795584Sanholt		}
918145132Sanholt		DRM_UDELAY(1);
91995584Sanholt	}
92095584Sanholt
92195584Sanholt#if RADEON_FIFO_DEBUG
922145132Sanholt	DRM_ERROR("failed!\n");
923145132Sanholt	radeon_status(dev_priv);
92495584Sanholt#endif
925112015Sanholt	return DRM_ERR(EBUSY);
92695584Sanholt}
92795584Sanholt
92895584Sanholt/* ================================================================
92995584Sanholt * CP control, initialization
93095584Sanholt */
93195584Sanholt
93295584Sanholt/* Load the microcode for the CP */
933145132Sanholtstatic void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
93495584Sanholt{
93595584Sanholt	int i;
936145132Sanholt	DRM_DEBUG("\n");
93795584Sanholt
938145132Sanholt	radeon_do_wait_for_idle(dev_priv);
93995584Sanholt
940145132Sanholt	RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
941112015Sanholt
942145132Sanholt	if (dev_priv->microcode_version==UCODE_R200) {
943112015Sanholt		DRM_INFO("Loading R200 Microcode\n");
944145132Sanholt		for (i = 0; i < 256; i++) {
945145132Sanholt			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
946145132Sanholt				     R200_cp_microcode[i][1]);
947145132Sanholt			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
948145132Sanholt				     R200_cp_microcode[i][0]);
949112015Sanholt		}
950145132Sanholt	} else if (dev_priv->microcode_version==UCODE_R300) {
951145132Sanholt		DRM_INFO("Loading R300 Microcode\n");
952112015Sanholt		for ( i = 0 ; i < 256 ; i++ ) {
953112015Sanholt			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
954145132Sanholt				      R300_cp_microcode[i][1] );
955112015Sanholt			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
956145132Sanholt				      R300_cp_microcode[i][0] );
957112015Sanholt		}
958145132Sanholt	} else {
959145132Sanholt		for (i = 0; i < 256; i++) {
960145132Sanholt			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
961145132Sanholt				     radeon_cp_microcode[i][1]);
962145132Sanholt			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
963145132Sanholt				     radeon_cp_microcode[i][0]);
964145132Sanholt		}
965112015Sanholt	}
96695584Sanholt}
96795584Sanholt
96895584Sanholt/* Flush any pending commands to the CP.  This should only be used just
96995584Sanholt * prior to a wait for idle, as it informs the engine that the command
97095584Sanholt * stream is ending.
97195584Sanholt */
972145132Sanholtstatic void radeon_do_cp_flush(drm_radeon_private_t * dev_priv)
97395584Sanholt{
974145132Sanholt	DRM_DEBUG("\n");
97595584Sanholt#if 0
97695584Sanholt	u32 tmp;
97795584Sanholt
978145132Sanholt	tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31);
979145132Sanholt	RADEON_WRITE(RADEON_CP_RB_WPTR, tmp);
98095584Sanholt#endif
98195584Sanholt}
98295584Sanholt
98395584Sanholt/* Wait for the CP to go idle.
98495584Sanholt */
985145132Sanholtint radeon_do_cp_idle(drm_radeon_private_t * dev_priv)
98695584Sanholt{
98795584Sanholt	RING_LOCALS;
988145132Sanholt	DRM_DEBUG("\n");
98995584Sanholt
990145132Sanholt	BEGIN_RING(6);
99195584Sanholt
99295584Sanholt	RADEON_PURGE_CACHE();
99395584Sanholt	RADEON_PURGE_ZCACHE();
99495584Sanholt	RADEON_WAIT_UNTIL_IDLE();
99595584Sanholt
99695584Sanholt	ADVANCE_RING();
997112015Sanholt	COMMIT_RING();
99895584Sanholt
999145132Sanholt	return radeon_do_wait_for_idle(dev_priv);
100095584Sanholt}
100195584Sanholt
100295584Sanholt/* Start the Command Processor.
100395584Sanholt */
1004145132Sanholtstatic void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
100595584Sanholt{
100695584Sanholt	RING_LOCALS;
1007145132Sanholt	DRM_DEBUG("\n");
100895584Sanholt
1009145132Sanholt	radeon_do_wait_for_idle(dev_priv);
101095584Sanholt
1011145132Sanholt	RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode);
101295584Sanholt
101395584Sanholt	dev_priv->cp_running = 1;
101495584Sanholt
1015145132Sanholt	BEGIN_RING(6);
101695584Sanholt
101795584Sanholt	RADEON_PURGE_CACHE();
101895584Sanholt	RADEON_PURGE_ZCACHE();
101995584Sanholt	RADEON_WAIT_UNTIL_IDLE();
102095584Sanholt
102195584Sanholt	ADVANCE_RING();
1022112015Sanholt	COMMIT_RING();
102395584Sanholt}
102495584Sanholt
102595584Sanholt/* Reset the Command Processor.  This will not flush any pending
102695584Sanholt * commands, so you must wait for the CP command stream to complete
102795584Sanholt * before calling this routine.
102895584Sanholt */
1029145132Sanholtstatic void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
103095584Sanholt{
103195584Sanholt	u32 cur_read_ptr;
1032145132Sanholt	DRM_DEBUG("\n");
103395584Sanholt
1034145132Sanholt	cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
1035145132Sanholt	RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
1036145132Sanholt	SET_RING_HEAD(dev_priv, cur_read_ptr);
103795584Sanholt	dev_priv->ring.tail = cur_read_ptr;
103895584Sanholt}
103995584Sanholt
104095584Sanholt/* Stop the Command Processor.  This will not flush any pending
104195584Sanholt * commands, so you must flush the command stream and wait for the CP
104295584Sanholt * to go idle before calling this routine.
104395584Sanholt */
1044145132Sanholtstatic void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
104595584Sanholt{
1046145132Sanholt	DRM_DEBUG("\n");
104795584Sanholt
1048145132Sanholt	RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
104995584Sanholt
105095584Sanholt	dev_priv->cp_running = 0;
105195584Sanholt}
105295584Sanholt
105395584Sanholt/* Reset the engine.  This will stop the CP if it is running.
105495584Sanholt */
1055145132Sanholtstatic int radeon_do_engine_reset(drm_device_t * dev)
105695584Sanholt{
105795584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
105895584Sanholt	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
1059145132Sanholt	DRM_DEBUG("\n");
106095584Sanholt
1061145132Sanholt	radeon_do_pixcache_flush(dev_priv);
106295584Sanholt
1063145132Sanholt	clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
1064145132Sanholt	mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
106595584Sanholt
1066145132Sanholt	RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
1067145132Sanholt					    RADEON_FORCEON_MCLKA |
1068145132Sanholt					    RADEON_FORCEON_MCLKB |
1069145132Sanholt					    RADEON_FORCEON_YCLKA |
1070145132Sanholt					    RADEON_FORCEON_YCLKB |
1071145132Sanholt					    RADEON_FORCEON_MC |
1072145132Sanholt					    RADEON_FORCEON_AIC));
107395584Sanholt
1074145132Sanholt	rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
107595584Sanholt
1076145132Sanholt	RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
1077145132Sanholt					      RADEON_SOFT_RESET_CP |
1078145132Sanholt					      RADEON_SOFT_RESET_HI |
1079145132Sanholt					      RADEON_SOFT_RESET_SE |
1080145132Sanholt					      RADEON_SOFT_RESET_RE |
1081145132Sanholt					      RADEON_SOFT_RESET_PP |
1082145132Sanholt					      RADEON_SOFT_RESET_E2 |
1083145132Sanholt					      RADEON_SOFT_RESET_RB));
1084145132Sanholt	RADEON_READ(RADEON_RBBM_SOFT_RESET);
1085145132Sanholt	RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
1086145132Sanholt					      ~(RADEON_SOFT_RESET_CP |
108795584Sanholt						RADEON_SOFT_RESET_HI |
108895584Sanholt						RADEON_SOFT_RESET_SE |
108995584Sanholt						RADEON_SOFT_RESET_RE |
109095584Sanholt						RADEON_SOFT_RESET_PP |
109195584Sanholt						RADEON_SOFT_RESET_E2 |
1092145132Sanholt						RADEON_SOFT_RESET_RB)));
1093145132Sanholt	RADEON_READ(RADEON_RBBM_SOFT_RESET);
109495584Sanholt
1095145132Sanholt	RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
1096145132Sanholt	RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
1097145132Sanholt	RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
109895584Sanholt
109995584Sanholt	/* Reset the CP ring */
1100145132Sanholt	radeon_do_cp_reset(dev_priv);
110195584Sanholt
110295584Sanholt	/* The CP is no longer running after an engine reset */
110395584Sanholt	dev_priv->cp_running = 0;
110495584Sanholt
110595584Sanholt	/* Reset any pending vertex, indirect buffers */
1106145132Sanholt	radeon_freelist_reset(dev);
110795584Sanholt
110895584Sanholt	return 0;
110995584Sanholt}
111095584Sanholt
1111145132Sanholtstatic void radeon_cp_init_ring_buffer(drm_device_t * dev,
1112145132Sanholt				       drm_radeon_private_t * dev_priv)
111395584Sanholt{
111495584Sanholt	u32 ring_start, cur_read_ptr;
111595584Sanholt	u32 tmp;
111695584Sanholt
111795584Sanholt	/* Initialize the memory controller */
1118145132Sanholt	RADEON_WRITE(RADEON_MC_FB_LOCATION,
1119145132Sanholt		     ((dev_priv->gart_vm_start - 1) & 0xffff0000)
1120145132Sanholt		     | (dev_priv->fb_location >> 16));
112195584Sanholt
1122145132Sanholt#if __OS_HAS_AGP
1123145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP) {
1124145132Sanholt		RADEON_WRITE(RADEON_MC_AGP_LOCATION,
1125145132Sanholt			     (((dev_priv->gart_vm_start - 1 +
1126145132Sanholt				dev_priv->gart_size) & 0xffff0000) |
1127145132Sanholt			      (dev_priv->gart_vm_start >> 16)));
112895584Sanholt
112995584Sanholt		ring_start = (dev_priv->cp_ring->offset
1130145132Sanholt			      - dev->agp->base + dev_priv->gart_vm_start);
1131145132Sanholt	} else
113295584Sanholt#endif
113395584Sanholt		ring_start = (dev_priv->cp_ring->offset
1134145132Sanholt			      - dev->sg->handle + dev_priv->gart_vm_start);
113595584Sanholt
1136145132Sanholt	RADEON_WRITE(RADEON_CP_RB_BASE, ring_start);
113795584Sanholt
113895584Sanholt	/* Set the write pointer delay */
1139145132Sanholt	RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0);
114095584Sanholt
114195584Sanholt	/* Initialize the ring buffer's read and write pointers */
1142145132Sanholt	cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
1143145132Sanholt	RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
1144145132Sanholt	SET_RING_HEAD(dev_priv, cur_read_ptr);
114595584Sanholt	dev_priv->ring.tail = cur_read_ptr;
114695584Sanholt
1147145132Sanholt#if __OS_HAS_AGP
1148145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP) {
1149145132Sanholt		/* set RADEON_AGP_BASE here instead of relying on X from user space */
1150145132Sanholt		RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1151145132Sanholt		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
1152145132Sanholt			     dev_priv->ring_rptr->offset
1153145132Sanholt			     - dev->agp->base + dev_priv->gart_vm_start);
1154113995Sanholt	} else
1155113995Sanholt#endif
1156113995Sanholt	{
115795584Sanholt		drm_sg_mem_t *entry = dev->sg;
115895584Sanholt		unsigned long tmp_ofs, page_ofs;
115995584Sanholt
116095584Sanholt		tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
116195584Sanholt		page_ofs = tmp_ofs >> PAGE_SHIFT;
116295584Sanholt
1163145132Sanholt		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
1164145132Sanholt		DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
1165145132Sanholt			  (unsigned long)entry->busaddr[page_ofs],
1166145132Sanholt			  entry->handle + tmp_ofs);
116795584Sanholt	}
116895584Sanholt
1169112015Sanholt	/* Initialize the scratch register pointer.  This will cause
1170112015Sanholt	 * the scratch register values to be written out to memory
1171112015Sanholt	 * whenever they are updated.
1172112015Sanholt	 *
1173112015Sanholt	 * We simply put this behind the ring read pointer, this works
1174112015Sanholt	 * with PCI GART as well as (whatever kind of) AGP GART
1175112015Sanholt	 */
1176145132Sanholt	RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
1177145132Sanholt		     + RADEON_SCRATCH_REG_OFFSET);
1178112015Sanholt
1179112015Sanholt	dev_priv->scratch = ((__volatile__ u32 *)
1180113995Sanholt			     dev_priv->ring_rptr->handle +
1181112015Sanholt			     (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
1182112015Sanholt
1183145132Sanholt	RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
1184112015Sanholt
1185112015Sanholt	/* Writeback doesn't seem to work everywhere, test it first */
1186145132Sanholt	DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
1187145132Sanholt	RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
1188112015Sanholt
1189145132Sanholt	for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
1190145132Sanholt		if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
1191145132Sanholt		    0xdeadbeef)
1192112015Sanholt			break;
1193145132Sanholt		DRM_UDELAY(1);
1194112015Sanholt	}
1195112015Sanholt
1196145132Sanholt	if (tmp < dev_priv->usec_timeout) {
1197112015Sanholt		dev_priv->writeback_works = 1;
1198145132Sanholt		DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp);
1199112015Sanholt	} else {
1200112015Sanholt		dev_priv->writeback_works = 0;
1201145132Sanholt		DRM_DEBUG("writeback test failed\n");
1202112015Sanholt	}
1203112015Sanholt
1204112015Sanholt	dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
1205145132Sanholt	RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
1206112015Sanholt
1207112015Sanholt	dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
1208145132Sanholt	RADEON_WRITE(RADEON_LAST_DISPATCH_REG,
1209145132Sanholt		     dev_priv->sarea_priv->last_dispatch);
1210112015Sanholt
1211112015Sanholt	dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
1212145132Sanholt	RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
1213112015Sanholt
121495584Sanholt	/* Set ring buffer size */
1215112015Sanholt#ifdef __BIG_ENDIAN
1216145132Sanholt	RADEON_WRITE(RADEON_CP_RB_CNTL,
1217145132Sanholt		     dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
1218112015Sanholt#else
1219145132Sanholt	RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
1220112015Sanholt#endif
122195584Sanholt
1222145132Sanholt	radeon_do_wait_for_idle(dev_priv);
122395584Sanholt
122495584Sanholt	/* Turn on bus mastering */
1225145132Sanholt	tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
1226145132Sanholt	RADEON_WRITE(RADEON_BUS_CNTL, tmp);
122795584Sanholt
122895584Sanholt	/* Sync everything up */
1229145132Sanholt	RADEON_WRITE(RADEON_ISYNC_CNTL,
1230145132Sanholt		     (RADEON_ISYNC_ANY2D_IDLE3D |
1231145132Sanholt		      RADEON_ISYNC_ANY3D_IDLE2D |
1232145132Sanholt		      RADEON_ISYNC_WAIT_IDLEGUI |
1233145132Sanholt		      RADEON_ISYNC_CPSCRATCH_IDLEGUI));
123495584Sanholt}
123595584Sanholt
1236119098Sanholt/* Enable or disable PCI GART on the chip */
1237145132Sanholtstatic void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
1238119098Sanholt{
1239145132Sanholt	u32 tmp = RADEON_READ(RADEON_AIC_CNTL);
1240119098Sanholt
1241145132Sanholt	if (on) {
1242145132Sanholt		RADEON_WRITE(RADEON_AIC_CNTL,
1243145132Sanholt			     tmp | RADEON_PCIGART_TRANSLATE_EN);
1244119098Sanholt
1245119098Sanholt		/* set PCI GART page-table base address
1246119098Sanholt		 */
1247145132Sanholt		RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart);
1248119098Sanholt
1249119098Sanholt		/* set address range for PCI address translate
1250119098Sanholt		 */
1251145132Sanholt		RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start);
1252145132Sanholt		RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
1253145132Sanholt			     + dev_priv->gart_size - 1);
1254119098Sanholt
1255119895Sanholt		/* Turn off AGP aperture -- is this required for PCI GART?
1256119098Sanholt		 */
1257145132Sanholt		RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0);	/* ?? */
1258145132Sanholt		RADEON_WRITE(RADEON_AGP_COMMAND, 0);	/* clear AGP_COMMAND */
1259119098Sanholt	} else {
1260145132Sanholt		RADEON_WRITE(RADEON_AIC_CNTL,
1261145132Sanholt			     tmp & ~RADEON_PCIGART_TRANSLATE_EN);
1262119098Sanholt	}
1263119098Sanholt}
1264119098Sanholt
1265145132Sanholtstatic int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
126695584Sanholt{
1267145132Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1268145132Sanholt	DRM_DEBUG("\n");
126995584Sanholt
1270145132Sanholt	if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
1271145132Sanholt		DRM_ERROR("PCI GART memory not allocated!\n");
127295584Sanholt		radeon_do_cleanup_cp(dev);
1273112015Sanholt		return DRM_ERR(EINVAL);
127495584Sanholt	}
127595584Sanholt
127695584Sanholt	dev_priv->usec_timeout = init->usec_timeout;
1277145132Sanholt	if (dev_priv->usec_timeout < 1 ||
1278145132Sanholt	    dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
1279145132Sanholt		DRM_DEBUG("TIMEOUT problem!\n");
128095584Sanholt		radeon_do_cleanup_cp(dev);
1281112015Sanholt		return DRM_ERR(EINVAL);
128295584Sanholt	}
128395584Sanholt
1284145132Sanholt	switch(init->func) {
1285145132Sanholt	case RADEON_INIT_R200_CP:
1286145132Sanholt		dev_priv->microcode_version=UCODE_R200;
1287145132Sanholt		break;
1288145132Sanholt	case RADEON_INIT_R300_CP:
1289145132Sanholt		dev_priv->microcode_version=UCODE_R300;
1290145132Sanholt		break;
1291145132Sanholt	default:
1292145132Sanholt		dev_priv->microcode_version=UCODE_R100;
1293145132Sanholt		break;
1294145132Sanholt	}
1295145132Sanholt
1296112015Sanholt	dev_priv->do_boxes = 0;
129795584Sanholt	dev_priv->cp_mode = init->cp_mode;
129895584Sanholt
129995584Sanholt	/* We don't support anything other than bus-mastering ring mode,
130095584Sanholt	 * but the ring can be in either AGP or PCI space for the ring
130195584Sanholt	 * read pointer.
130295584Sanholt	 */
1303145132Sanholt	if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
1304145132Sanholt	    (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
1305145132Sanholt		DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
130695584Sanholt		radeon_do_cleanup_cp(dev);
1307112015Sanholt		return DRM_ERR(EINVAL);
130895584Sanholt	}
130995584Sanholt
1310145132Sanholt	switch (init->fb_bpp) {
131195584Sanholt	case 16:
131295584Sanholt		dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
131395584Sanholt		break;
131495584Sanholt	case 32:
131595584Sanholt	default:
131695584Sanholt		dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
131795584Sanholt		break;
131895584Sanholt	}
1319145132Sanholt	dev_priv->front_offset = init->front_offset;
1320145132Sanholt	dev_priv->front_pitch = init->front_pitch;
1321145132Sanholt	dev_priv->back_offset = init->back_offset;
1322145132Sanholt	dev_priv->back_pitch = init->back_pitch;
132395584Sanholt
1324145132Sanholt	switch (init->depth_bpp) {
132595584Sanholt	case 16:
132695584Sanholt		dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
132795584Sanholt		break;
132895584Sanholt	case 32:
132995584Sanholt	default:
133095584Sanholt		dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
133195584Sanholt		break;
133295584Sanholt	}
1333145132Sanholt	dev_priv->depth_offset = init->depth_offset;
1334145132Sanholt	dev_priv->depth_pitch = init->depth_pitch;
133595584Sanholt
133695584Sanholt	/* Hardware state for depth clears.  Remove this if/when we no
133795584Sanholt	 * longer clear the depth buffer with a 3D rectangle.  Hard-code
133895584Sanholt	 * all values to prevent unwanted 3D state from slipping through
133995584Sanholt	 * and screwing with the clear operation.
134095584Sanholt	 */
134195584Sanholt	dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
134295584Sanholt					   (dev_priv->color_fmt << 10) |
1343145132Sanholt					   (dev_priv->microcode_version == UCODE_R100 ?
1344145132Sanholt						RADEON_ZBLOCK16 : 0));
134595584Sanholt
1346145132Sanholt	dev_priv->depth_clear.rb3d_zstencilcntl =
1347145132Sanholt	    (dev_priv->depth_fmt |
1348145132Sanholt	     RADEON_Z_TEST_ALWAYS |
1349145132Sanholt	     RADEON_STENCIL_TEST_ALWAYS |
1350145132Sanholt	     RADEON_STENCIL_S_FAIL_REPLACE |
1351145132Sanholt	     RADEON_STENCIL_ZPASS_REPLACE |
1352145132Sanholt	     RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE);
135395584Sanholt
135495584Sanholt	dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
135595584Sanholt					 RADEON_BFACE_SOLID |
135695584Sanholt					 RADEON_FFACE_SOLID |
135795584Sanholt					 RADEON_FLAT_SHADE_VTX_LAST |
135895584Sanholt					 RADEON_DIFFUSE_SHADE_FLAT |
135995584Sanholt					 RADEON_ALPHA_SHADE_FLAT |
136095584Sanholt					 RADEON_SPECULAR_SHADE_FLAT |
136195584Sanholt					 RADEON_FOG_SHADE_FLAT |
136295584Sanholt					 RADEON_VTX_PIX_CENTER_OGL |
136395584Sanholt					 RADEON_ROUND_MODE_TRUNC |
136495584Sanholt					 RADEON_ROUND_PREC_8TH_PIX);
136595584Sanholt
1366112015Sanholt	DRM_GETSAREA();
1367113995Sanholt
1368113995Sanholt	dev_priv->fb_offset = init->fb_offset;
1369113995Sanholt	dev_priv->mmio_offset = init->mmio_offset;
1370113995Sanholt	dev_priv->ring_offset = init->ring_offset;
1371113995Sanholt	dev_priv->ring_rptr_offset = init->ring_rptr_offset;
1372113995Sanholt	dev_priv->buffers_offset = init->buffers_offset;
1373119895Sanholt	dev_priv->gart_textures_offset = init->gart_textures_offset;
1374145132Sanholt
1375145132Sanholt	if (!dev_priv->sarea) {
137695584Sanholt		DRM_ERROR("could not find sarea!\n");
137795584Sanholt		radeon_do_cleanup_cp(dev);
1378112015Sanholt		return DRM_ERR(EINVAL);
137995584Sanholt	}
138095584Sanholt
1381145132Sanholt	dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
1382145132Sanholt	if (!dev_priv->mmio) {
138395584Sanholt		DRM_ERROR("could not find mmio region!\n");
138495584Sanholt		radeon_do_cleanup_cp(dev);
1385112015Sanholt		return DRM_ERR(EINVAL);
138695584Sanholt	}
1387145132Sanholt	dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
1388145132Sanholt	if (!dev_priv->cp_ring) {
138995584Sanholt		DRM_ERROR("could not find cp ring region!\n");
139095584Sanholt		radeon_do_cleanup_cp(dev);
1391112015Sanholt		return DRM_ERR(EINVAL);
139295584Sanholt	}
1393145132Sanholt	dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
1394145132Sanholt	if (!dev_priv->ring_rptr) {
139595584Sanholt		DRM_ERROR("could not find ring read pointer!\n");
139695584Sanholt		radeon_do_cleanup_cp(dev);
1397112015Sanholt		return DRM_ERR(EINVAL);
139895584Sanholt	}
1399145132Sanholt	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
1400145132Sanholt	if (!dev->agp_buffer_map) {
140195584Sanholt		DRM_ERROR("could not find dma buffer region!\n");
140295584Sanholt		radeon_do_cleanup_cp(dev);
1403112015Sanholt		return DRM_ERR(EINVAL);
140495584Sanholt	}
140595584Sanholt
1406145132Sanholt	if (init->gart_textures_offset) {
1407145132Sanholt		dev_priv->gart_textures =
1408145132Sanholt		    drm_core_findmap(dev, init->gart_textures_offset);
1409145132Sanholt		if (!dev_priv->gart_textures) {
1410119895Sanholt			DRM_ERROR("could not find GART texture region!\n");
141195584Sanholt			radeon_do_cleanup_cp(dev);
1412112015Sanholt			return DRM_ERR(EINVAL);
141395584Sanholt		}
141495584Sanholt	}
141595584Sanholt
141695584Sanholt	dev_priv->sarea_priv =
1417145132Sanholt	    (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
1418145132Sanholt				    init->sarea_priv_offset);
141995584Sanholt
1420145132Sanholt#if __OS_HAS_AGP
1421145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP) {
1422145132Sanholt		drm_core_ioremap(dev_priv->cp_ring, dev);
1423145132Sanholt		drm_core_ioremap(dev_priv->ring_rptr, dev);
1424145132Sanholt		drm_core_ioremap(dev->agp_buffer_map, dev);
1425145132Sanholt		if (!dev_priv->cp_ring->handle ||
1426145132Sanholt		    !dev_priv->ring_rptr->handle ||
1427145132Sanholt		    !dev->agp_buffer_map->handle) {
142895584Sanholt			DRM_ERROR("could not find ioremap agp regions!\n");
142995584Sanholt			radeon_do_cleanup_cp(dev);
1430112015Sanholt			return DRM_ERR(EINVAL);
143195584Sanholt		}
1432119098Sanholt	} else
1433119098Sanholt#endif
1434119098Sanholt	{
1435145132Sanholt		dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
143695584Sanholt		dev_priv->ring_rptr->handle =
1437145132Sanholt		    (void *)dev_priv->ring_rptr->offset;
1438145132Sanholt		dev->agp_buffer_map->handle =
1439145132Sanholt		    (void *)dev->agp_buffer_map->offset;
144095584Sanholt
1441145132Sanholt		DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
1442145132Sanholt			  dev_priv->cp_ring->handle);
1443145132Sanholt		DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
1444145132Sanholt			  dev_priv->ring_rptr->handle);
1445145132Sanholt		DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
1446145132Sanholt			  dev->agp_buffer_map->handle);
144795584Sanholt	}
144895584Sanholt
1449145132Sanholt	dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
1450145132Sanholt				 & 0xffff) << 16;
145195584Sanholt
1452145132Sanholt	dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
1453145132Sanholt					((dev_priv->front_offset
1454145132Sanholt					  + dev_priv->fb_location) >> 10));
1455122580Sanholt
1456145132Sanholt	dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
1457145132Sanholt				       ((dev_priv->back_offset
1458145132Sanholt					 + dev_priv->fb_location) >> 10));
1459122580Sanholt
1460145132Sanholt	dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
1461145132Sanholt					((dev_priv->depth_offset
1462145132Sanholt					  + dev_priv->fb_location) >> 10));
1463122580Sanholt
1464119895Sanholt	dev_priv->gart_size = init->gart_size;
1465122580Sanholt	dev_priv->gart_vm_start = dev_priv->fb_location
1466145132Sanholt	    + RADEON_READ(RADEON_CONFIG_APER_SIZE);
1467122580Sanholt
1468145132Sanholt#if __OS_HAS_AGP
1469145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP)
1470145132Sanholt		dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1471145132Sanholt						 - dev->agp->base
1472145132Sanholt						 + dev_priv->gart_vm_start);
147395584Sanholt	else
147495584Sanholt#endif
1475145132Sanholt		dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1476145132Sanholt						 - dev->sg->handle
1477145132Sanholt						 + dev_priv->gart_vm_start);
147895584Sanholt
1479145132Sanholt	DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
1480145132Sanholt	DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start);
1481145132Sanholt	DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n",
1482145132Sanholt		  dev_priv->gart_buffers_offset);
148395584Sanholt
1484145132Sanholt	dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
1485145132Sanholt	dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
148695584Sanholt			      + init->ring_size / sizeof(u32));
148795584Sanholt	dev_priv->ring.size = init->ring_size;
1488145132Sanholt	dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
148995584Sanholt
1490145132Sanholt	dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
149195584Sanholt
149295584Sanholt	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
149395584Sanholt
1494145132Sanholt#if __OS_HAS_AGP
1495145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP) {
1496119098Sanholt		/* Turn off PCI GART */
1497145132Sanholt		radeon_set_pcigart(dev_priv, 0);
1498119098Sanholt	} else
1499119098Sanholt#endif
1500119098Sanholt	{
1501145132Sanholt		if (!drm_ati_pcigart_init(dev, &dev_priv->phys_pci_gart,
1502145132Sanholt					  &dev_priv->bus_pci_gart)) {
1503145132Sanholt			DRM_ERROR("failed to init PCI GART!\n");
150495584Sanholt			radeon_do_cleanup_cp(dev);
1505112015Sanholt			return DRM_ERR(ENOMEM);
150695584Sanholt		}
150795584Sanholt
1508119098Sanholt		/* Turn on PCI GART */
1509145132Sanholt		radeon_set_pcigart(dev_priv, 1);
151095584Sanholt	}
151195584Sanholt
1512145132Sanholt	radeon_cp_load_microcode(dev_priv);
1513145132Sanholt	radeon_cp_init_ring_buffer(dev, dev_priv);
151495584Sanholt
151595584Sanholt	dev_priv->last_buf = 0;
151695584Sanholt
1517145132Sanholt	radeon_do_engine_reset(dev);
151895584Sanholt
151995584Sanholt	return 0;
152095584Sanholt}
152195584Sanholt
1522145132Sanholtstatic int radeon_do_cleanup_cp(drm_device_t * dev)
152395584Sanholt{
1524145132Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1525145132Sanholt	DRM_DEBUG("\n");
152695584Sanholt
1527119098Sanholt	/* Make sure interrupts are disabled here because the uninstall ioctl
1528119098Sanholt	 * may not have been called from userspace and after dev_private
1529119098Sanholt	 * is freed, it's too late.
1530119098Sanholt	 */
1531145132Sanholt	if (dev->irq_enabled)
1532145132Sanholt		drm_irq_uninstall(dev);
1533119098Sanholt
1534145132Sanholt#if __OS_HAS_AGP
1535145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP) {
1536145132Sanholt		if (dev_priv->cp_ring != NULL) {
1537145132Sanholt			drm_core_ioremapfree(dev_priv->cp_ring, dev);
1538145132Sanholt			dev_priv->cp_ring = NULL;
1539145132Sanholt		}
1540145132Sanholt		if (dev_priv->ring_rptr != NULL) {
1541145132Sanholt			drm_core_ioremapfree(dev_priv->ring_rptr, dev);
1542145132Sanholt			dev_priv->ring_rptr = NULL;
1543145132Sanholt		}
1544145132Sanholt		if (dev->agp_buffer_map != NULL) {
1545145132Sanholt			drm_core_ioremapfree(dev->agp_buffer_map, dev);
1546145132Sanholt			dev->agp_buffer_map = NULL;
1547145132Sanholt		}
1548145132Sanholt	} else
1549119098Sanholt#endif
1550145132Sanholt	{
1551145132Sanholt		if (!drm_ati_pcigart_cleanup(dev,
1552145132Sanholt					     dev_priv->phys_pci_gart,
1553145132Sanholt					     dev_priv->bus_pci_gart))
1554145132Sanholt			DRM_ERROR("failed to cleanup PCI GART!\n");
155595584Sanholt	}
1556145132Sanholt	/* only clear to the start of flags */
1557145132Sanholt	memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
155895584Sanholt
155995584Sanholt	return 0;
156095584Sanholt}
156195584Sanholt
1562145132Sanholt/* This code will reinit the Radeon CP hardware after a resume from disc.
1563145132Sanholt * AFAIK, it would be very difficult to pickle the state at suspend time, so
1564119098Sanholt * here we make sure that all Radeon hardware initialisation is re-done without
1565119098Sanholt * affecting running applications.
1566119098Sanholt *
1567119098Sanholt * Charl P. Botha <http://cpbotha.net>
1568119098Sanholt */
1569145132Sanholtstatic int radeon_do_resume_cp(drm_device_t * dev)
1570119098Sanholt{
1571119098Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1572119098Sanholt
1573145132Sanholt	if (!dev_priv) {
1574145132Sanholt		DRM_ERROR("Called with no initialization\n");
1575145132Sanholt		return DRM_ERR(EINVAL);
1576119098Sanholt	}
1577119098Sanholt
1578119098Sanholt	DRM_DEBUG("Starting radeon_do_resume_cp()\n");
1579119098Sanholt
1580145132Sanholt#if __OS_HAS_AGP
1581145132Sanholt	if (dev_priv->flags & CHIP_IS_AGP) {
1582119098Sanholt		/* Turn off PCI GART */
1583145132Sanholt		radeon_set_pcigart(dev_priv, 0);
1584119098Sanholt	} else
1585119098Sanholt#endif
1586119098Sanholt	{
1587119098Sanholt		/* Turn on PCI GART */
1588145132Sanholt		radeon_set_pcigart(dev_priv, 1);
1589119098Sanholt	}
1590119098Sanholt
1591145132Sanholt	radeon_cp_load_microcode(dev_priv);
1592145132Sanholt	radeon_cp_init_ring_buffer(dev, dev_priv);
1593119098Sanholt
1594145132Sanholt	radeon_do_engine_reset(dev);
1595119098Sanholt
1596119098Sanholt	DRM_DEBUG("radeon_do_resume_cp() complete\n");
1597119098Sanholt
1598119098Sanholt	return 0;
1599119098Sanholt}
1600119098Sanholt
1601145132Sanholtint radeon_cp_init(DRM_IOCTL_ARGS)
160295584Sanholt{
1603112015Sanholt	DRM_DEVICE;
160495584Sanholt	drm_radeon_init_t init;
160595584Sanholt
1606145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
1607119098Sanholt
1608145132Sanholt	DRM_COPY_FROM_USER_IOCTL(init, (drm_radeon_init_t __user *) data,
1609145132Sanholt				 sizeof(init));
161095584Sanholt
1611145132Sanholt	switch (init.func) {
161295584Sanholt	case RADEON_INIT_CP:
1613112015Sanholt	case RADEON_INIT_R200_CP:
1614145132Sanholt	case RADEON_INIT_R300_CP:
1615145132Sanholt		return radeon_do_init_cp(dev, &init);
161695584Sanholt	case RADEON_CLEANUP_CP:
1617145132Sanholt		return radeon_do_cleanup_cp(dev);
161895584Sanholt	}
161995584Sanholt
1620112015Sanholt	return DRM_ERR(EINVAL);
162195584Sanholt}
162295584Sanholt
1623145132Sanholtint radeon_cp_start(DRM_IOCTL_ARGS)
162495584Sanholt{
1625112015Sanholt	DRM_DEVICE;
162695584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1627145132Sanholt	DRM_DEBUG("\n");
162895584Sanholt
1629145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
163095584Sanholt
1631145132Sanholt	if (dev_priv->cp_running) {
1632145132Sanholt		DRM_DEBUG("%s while CP running\n", __FUNCTION__);
163395584Sanholt		return 0;
163495584Sanholt	}
1635145132Sanholt	if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
1636145132Sanholt		DRM_DEBUG("%s called with bogus CP mode (%d)\n",
1637145132Sanholt			  __FUNCTION__, dev_priv->cp_mode);
163895584Sanholt		return 0;
163995584Sanholt	}
164095584Sanholt
1641145132Sanholt	radeon_do_cp_start(dev_priv);
164295584Sanholt
164395584Sanholt	return 0;
164495584Sanholt}
164595584Sanholt
164695584Sanholt/* Stop the CP.  The engine must have been idled before calling this
164795584Sanholt * routine.
164895584Sanholt */
1649145132Sanholtint radeon_cp_stop(DRM_IOCTL_ARGS)
165095584Sanholt{
1651112015Sanholt	DRM_DEVICE;
165295584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
165395584Sanholt	drm_radeon_cp_stop_t stop;
165495584Sanholt	int ret;
1655145132Sanholt	DRM_DEBUG("\n");
165695584Sanholt
1657145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
165895584Sanholt
1659145132Sanholt	DRM_COPY_FROM_USER_IOCTL(stop, (drm_radeon_cp_stop_t __user *) data,
1660145132Sanholt				 sizeof(stop));
166195584Sanholt
1662112015Sanholt	if (!dev_priv->cp_running)
1663112015Sanholt		return 0;
1664112015Sanholt
166595584Sanholt	/* Flush any pending CP commands.  This ensures any outstanding
166695584Sanholt	 * commands are exectuted by the engine before we turn it off.
166795584Sanholt	 */
1668145132Sanholt	if (stop.flush) {
1669145132Sanholt		radeon_do_cp_flush(dev_priv);
167095584Sanholt	}
167195584Sanholt
167295584Sanholt	/* If we fail to make the engine go idle, we return an error
167395584Sanholt	 * code so that the DRM ioctl wrapper can try again.
167495584Sanholt	 */
1675145132Sanholt	if (stop.idle) {
1676145132Sanholt		ret = radeon_do_cp_idle(dev_priv);
1677145132Sanholt		if (ret)
1678145132Sanholt			return ret;
167995584Sanholt	}
168095584Sanholt
168195584Sanholt	/* Finally, we can turn off the CP.  If the engine isn't idle,
168295584Sanholt	 * we will get some dropped triangles as they won't be fully
168395584Sanholt	 * rendered before the CP is shut down.
168495584Sanholt	 */
1685145132Sanholt	radeon_do_cp_stop(dev_priv);
168695584Sanholt
168795584Sanholt	/* Reset the engine */
1688145132Sanholt	radeon_do_engine_reset(dev);
168995584Sanholt
169095584Sanholt	return 0;
169195584Sanholt}
169295584Sanholt
1693145132Sanholtvoid radeon_do_release(drm_device_t * dev)
1694112015Sanholt{
1695112015Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1696145132Sanholt	int i, ret;
1697112015Sanholt
1698112015Sanholt	if (dev_priv) {
1699145132Sanholt
1700112015Sanholt		if (dev_priv->cp_running) {
1701112015Sanholt			/* Stop the cp */
1702145132Sanholt			while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
1703112015Sanholt				DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
1704112015Sanholt#ifdef __linux__
1705112015Sanholt				schedule();
1706112015Sanholt#else
1707112015Sanholt				tsleep(&ret, PZERO, "rdnrel", 1);
1708112015Sanholt#endif
1709112015Sanholt			}
1710145132Sanholt			radeon_do_cp_stop(dev_priv);
1711145132Sanholt			radeon_do_engine_reset(dev);
1712112015Sanholt		}
1713112015Sanholt
1714112015Sanholt		/* Disable *all* interrupts */
1715145132Sanholt		if (dev_priv->mmio)	/* remove this after permanent addmaps */
1716145132Sanholt			RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
1717112015Sanholt
1718145132Sanholt		if (dev_priv->mmio) {/* remove all surfaces */
1719145132Sanholt			for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1720145132Sanholt				RADEON_WRITE(RADEON_SURFACE0_INFO + 16*i, 0);
1721145132Sanholt				RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*i, 0);
1722145132Sanholt				RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*i, 0);
1723145132Sanholt			}
1724145132Sanholt		}
1725145132Sanholt
1726112015Sanholt		/* Free memory heap structures */
1727145132Sanholt		radeon_mem_takedown(&(dev_priv->gart_heap));
1728145132Sanholt		radeon_mem_takedown(&(dev_priv->fb_heap));
1729112015Sanholt
1730112015Sanholt		/* deallocate kernel resources */
1731145132Sanholt		radeon_do_cleanup_cp(dev);
1732112015Sanholt	}
1733112015Sanholt}
1734112015Sanholt
173595584Sanholt/* Just reset the CP ring.  Called as part of an X Server engine reset.
173695584Sanholt */
1737145132Sanholtint radeon_cp_reset(DRM_IOCTL_ARGS)
173895584Sanholt{
1739112015Sanholt	DRM_DEVICE;
174095584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1741145132Sanholt	DRM_DEBUG("\n");
174295584Sanholt
1743145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
174495584Sanholt
1745145132Sanholt	if (!dev_priv) {
1746145132Sanholt		DRM_DEBUG("%s called before init done\n", __FUNCTION__);
1747112015Sanholt		return DRM_ERR(EINVAL);
174895584Sanholt	}
174995584Sanholt
1750145132Sanholt	radeon_do_cp_reset(dev_priv);
175195584Sanholt
175295584Sanholt	/* The CP is no longer running after an engine reset */
175395584Sanholt	dev_priv->cp_running = 0;
175495584Sanholt
175595584Sanholt	return 0;
175695584Sanholt}
175795584Sanholt
1758145132Sanholtint radeon_cp_idle(DRM_IOCTL_ARGS)
175995584Sanholt{
1760112015Sanholt	DRM_DEVICE;
176195584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1762145132Sanholt	DRM_DEBUG("\n");
176395584Sanholt
1764145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
176595584Sanholt
1766145132Sanholt	return radeon_do_cp_idle(dev_priv);
176795584Sanholt}
176895584Sanholt
1769119098Sanholt/* Added by Charl P. Botha to call radeon_do_resume_cp().
1770119098Sanholt */
1771145132Sanholtint radeon_cp_resume(DRM_IOCTL_ARGS)
1772119098Sanholt{
1773119098Sanholt	DRM_DEVICE;
1774119098Sanholt
1775119098Sanholt	return radeon_do_resume_cp(dev);
1776119098Sanholt}
1777119098Sanholt
1778145132Sanholtint radeon_engine_reset(DRM_IOCTL_ARGS)
177995584Sanholt{
1780112015Sanholt	DRM_DEVICE;
1781145132Sanholt	DRM_DEBUG("\n");
178295584Sanholt
1783145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
178495584Sanholt
1785145132Sanholt	return radeon_do_engine_reset(dev);
178695584Sanholt}
178795584Sanholt
178895584Sanholt/* ================================================================
178995584Sanholt * Fullscreen mode
179095584Sanholt */
179195584Sanholt
1792112015Sanholt/* KW: Deprecated to say the least:
1793112015Sanholt */
1794145132Sanholtint radeon_fullscreen(DRM_IOCTL_ARGS)
179595584Sanholt{
179695584Sanholt	return 0;
179795584Sanholt}
179895584Sanholt
179995584Sanholt/* ================================================================
180095584Sanholt * Freelist management
180195584Sanholt */
180295584Sanholt
1803112015Sanholt/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through
1804112015Sanholt *   bufs until freelist code is used.  Note this hides a problem with
1805112015Sanholt *   the scratch register * (used to keep track of last buffer
1806112015Sanholt *   completed) being written to before * the last buffer has actually
1807145132Sanholt *   completed rendering.
1808112015Sanholt *
1809112015Sanholt * KW:  It's also a good way to find free buffers quickly.
1810112015Sanholt *
1811112015Sanholt * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
1812112015Sanholt * sleep.  However, bugs in older versions of radeon_accel.c mean that
1813112015Sanholt * we essentially have to do this, else old clients will break.
1814145132Sanholt *
1815112015Sanholt * However, it does leave open a potential deadlock where all the
1816112015Sanholt * buffers are held by other clients, which can't release them because
1817145132Sanholt * they can't get the lock.
1818112015Sanholt */
1819112015Sanholt
1820145132Sanholtdrm_buf_t *radeon_freelist_get(drm_device_t * dev)
182195584Sanholt{
182295584Sanholt	drm_device_dma_t *dma = dev->dma;
182395584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
1824112015Sanholt	drm_radeon_buf_priv_t *buf_priv;
182595584Sanholt	drm_buf_t *buf;
1826112015Sanholt	int i, t;
1827112015Sanholt	int start;
182895584Sanholt
1829145132Sanholt	if (++dev_priv->last_buf >= dma->buf_count)
1830112015Sanholt		dev_priv->last_buf = 0;
183195584Sanholt
1832112015Sanholt	start = dev_priv->last_buf;
183395584Sanholt
1834145132Sanholt	for (t = 0; t < dev_priv->usec_timeout; t++) {
1835145132Sanholt		u32 done_age = GET_SCRATCH(1);
1836145132Sanholt		DRM_DEBUG("done_age = %d\n", done_age);
1837145132Sanholt		for (i = start; i < dma->buf_count; i++) {
1838112015Sanholt			buf = dma->buflist[i];
1839112015Sanholt			buf_priv = buf->dev_private;
1840145132Sanholt			if (buf->filp == 0 || (buf->pending &&
1841145132Sanholt					       buf_priv->age <= done_age)) {
1842112015Sanholt				dev_priv->stats.requested_bufs++;
1843112015Sanholt				buf->pending = 0;
1844112015Sanholt				return buf;
1845112015Sanholt			}
1846112015Sanholt			start = 0;
1847112015Sanholt		}
184895584Sanholt
1849112015Sanholt		if (t) {
1850145132Sanholt			DRM_UDELAY(1);
1851112015Sanholt			dev_priv->stats.freelist_loops++;
1852112015Sanholt		}
185395584Sanholt	}
185495584Sanholt
1855145132Sanholt	DRM_DEBUG("returning NULL!\n");
1856112015Sanholt	return NULL;
185795584Sanholt}
1858145132Sanholt
1859112015Sanholt#if 0
1860145132Sanholtdrm_buf_t *radeon_freelist_get(drm_device_t * dev)
186195584Sanholt{
186295584Sanholt	drm_device_dma_t *dma = dev->dma;
186395584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
186495584Sanholt	drm_radeon_buf_priv_t *buf_priv;
186595584Sanholt	drm_buf_t *buf;
186695584Sanholt	int i, t;
186795584Sanholt	int start;
1868112015Sanholt	u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
186995584Sanholt
1870145132Sanholt	if (++dev_priv->last_buf >= dma->buf_count)
187195584Sanholt		dev_priv->last_buf = 0;
1872112015Sanholt
187395584Sanholt	start = dev_priv->last_buf;
1874112015Sanholt	dev_priv->stats.freelist_loops++;
1875145132Sanholt
1876145132Sanholt	for (t = 0; t < 2; t++) {
1877145132Sanholt		for (i = start; i < dma->buf_count; i++) {
187895584Sanholt			buf = dma->buflist[i];
187995584Sanholt			buf_priv = buf->dev_private;
1880145132Sanholt			if (buf->filp == 0 || (buf->pending &&
1881145132Sanholt					       buf_priv->age <= done_age)) {
1882112015Sanholt				dev_priv->stats.requested_bufs++;
188395584Sanholt				buf->pending = 0;
188495584Sanholt				return buf;
188595584Sanholt			}
188695584Sanholt		}
1887112015Sanholt		start = 0;
188895584Sanholt	}
188995584Sanholt
189095584Sanholt	return NULL;
189195584Sanholt}
1892112015Sanholt#endif
189395584Sanholt
1894145132Sanholtvoid radeon_freelist_reset(drm_device_t * dev)
189595584Sanholt{
189695584Sanholt	drm_device_dma_t *dma = dev->dma;
189795584Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
189895584Sanholt	int i;
189995584Sanholt
190095584Sanholt	dev_priv->last_buf = 0;
1901145132Sanholt	for (i = 0; i < dma->buf_count; i++) {
190295584Sanholt		drm_buf_t *buf = dma->buflist[i];
190395584Sanholt		drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
190495584Sanholt		buf_priv->age = 0;
190595584Sanholt	}
190695584Sanholt}
190795584Sanholt
190895584Sanholt/* ================================================================
190995584Sanholt * CP command submission
191095584Sanholt */
191195584Sanholt
1912145132Sanholtint radeon_wait_ring(drm_radeon_private_t * dev_priv, int n)
191395584Sanholt{
191495584Sanholt	drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
191595584Sanholt	int i;
1916145132Sanholt	u32 last_head = GET_RING_HEAD(dev_priv);
191795584Sanholt
1918145132Sanholt	for (i = 0; i < dev_priv->usec_timeout; i++) {
1919145132Sanholt		u32 head = GET_RING_HEAD(dev_priv);
1920112015Sanholt
1921112015Sanholt		ring->space = (head - ring->tail) * sizeof(u32);
1922145132Sanholt		if (ring->space <= 0)
1923112015Sanholt			ring->space += ring->size;
1924145132Sanholt		if (ring->space > n)
192595584Sanholt			return 0;
1926145132Sanholt
1927112015Sanholt		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
1928112015Sanholt
1929112015Sanholt		if (head != last_head)
1930112015Sanholt			i = 0;
1931112015Sanholt		last_head = head;
1932112015Sanholt
1933145132Sanholt		DRM_UDELAY(1);
193495584Sanholt	}
193595584Sanholt
193695584Sanholt	/* FIXME: This return value is ignored in the BEGIN_RING macro! */
193795584Sanholt#if RADEON_FIFO_DEBUG
1938145132Sanholt	radeon_status(dev_priv);
1939145132Sanholt	DRM_ERROR("failed!\n");
194095584Sanholt#endif
1941112015Sanholt	return DRM_ERR(EBUSY);
194295584Sanholt}
194395584Sanholt
1944145132Sanholtstatic int radeon_cp_get_buffers(DRMFILE filp, drm_device_t * dev,
1945145132Sanholt				 drm_dma_t * d)
194695584Sanholt{
194795584Sanholt	int i;
194895584Sanholt	drm_buf_t *buf;
194995584Sanholt
1950145132Sanholt	for (i = d->granted_count; i < d->request_count; i++) {
1951145132Sanholt		buf = radeon_freelist_get(dev);
1952145132Sanholt		if (!buf)
1953145132Sanholt			return DRM_ERR(EBUSY);	/* NOTE: broken client */
195495584Sanholt
1955113995Sanholt		buf->filp = filp;
195695584Sanholt
1957145132Sanholt		if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
1958145132Sanholt				     sizeof(buf->idx)))
1959112015Sanholt			return DRM_ERR(EFAULT);
1960145132Sanholt		if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
1961145132Sanholt				     sizeof(buf->total)))
1962112015Sanholt			return DRM_ERR(EFAULT);
196395584Sanholt
196495584Sanholt		d->granted_count++;
196595584Sanholt	}
196695584Sanholt	return 0;
196795584Sanholt}
196895584Sanholt
1969145132Sanholtint radeon_cp_buffers(DRM_IOCTL_ARGS)
197095584Sanholt{
1971112015Sanholt	DRM_DEVICE;
197295584Sanholt	drm_device_dma_t *dma = dev->dma;
197395584Sanholt	int ret = 0;
1974145132Sanholt	drm_dma_t __user *argp = (void __user *)data;
197595584Sanholt	drm_dma_t d;
197695584Sanholt
1977145132Sanholt	LOCK_TEST_WITH_RETURN(dev, filp);
197895584Sanholt
1979145132Sanholt	DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));
198095584Sanholt
198195584Sanholt	/* Please don't send us buffers.
198295584Sanholt	 */
1983145132Sanholt	if (d.send_count != 0) {
1984145132Sanholt		DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1985145132Sanholt			  DRM_CURRENTPID, d.send_count);
1986112015Sanholt		return DRM_ERR(EINVAL);
198795584Sanholt	}
198895584Sanholt
198995584Sanholt	/* We'll send you buffers.
199095584Sanholt	 */
1991145132Sanholt	if (d.request_count < 0 || d.request_count > dma->buf_count) {
1992145132Sanholt		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1993145132Sanholt			  DRM_CURRENTPID, d.request_count, dma->buf_count);
1994112015Sanholt		return DRM_ERR(EINVAL);
199595584Sanholt	}
199695584Sanholt
199795584Sanholt	d.granted_count = 0;
199895584Sanholt
1999145132Sanholt	if (d.request_count) {
2000145132Sanholt		ret = radeon_cp_get_buffers(filp, dev, &d);
200195584Sanholt	}
200295584Sanholt
2003145132Sanholt	DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d));
200495584Sanholt
200595584Sanholt	return ret;
200695584Sanholt}
2007145132Sanholt
2008145132Sanholt/* Always create a map record for MMIO and FB memory, done from DRIVER_POSTINIT */
2009145132Sanholtint radeon_preinit(struct drm_device *dev, unsigned long flags)
2010145132Sanholt{
2011145132Sanholt	drm_radeon_private_t *dev_priv;
2012145132Sanholt	int ret = 0;
2013145132Sanholt
2014145132Sanholt	dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
2015145132Sanholt	if (dev_priv == NULL)
2016145132Sanholt		return DRM_ERR(ENOMEM);
2017145132Sanholt
2018145132Sanholt	memset(dev_priv, 0, sizeof(drm_radeon_private_t));
2019145132Sanholt	dev->dev_private = (void *)dev_priv;
2020145132Sanholt	dev_priv->flags = flags;
2021145132Sanholt
2022145132Sanholt	switch (flags & CHIP_FAMILY_MASK) {
2023145132Sanholt	case CHIP_R100:
2024145132Sanholt	case CHIP_RV200:
2025145132Sanholt	case CHIP_R200:
2026145132Sanholt	case CHIP_R300:
2027145132Sanholt		dev_priv->flags |= CHIP_HAS_HIERZ;
2028145132Sanholt		break;
2029145132Sanholt	default:
2030145132Sanholt	/* all other chips have no hierarchical z buffer */
2031145132Sanholt		break;
2032145132Sanholt	}
2033145132Sanholt
2034145132Sanholt	ret = drm_initmap(dev, drm_get_resource_start(dev, 2),
2035145132Sanholt			  drm_get_resource_len(dev, 2), 2, _DRM_REGISTERS, 0);
2036145132Sanholt	if (ret != 0)
2037145132Sanholt		return ret;
2038145132Sanholt
2039145132Sanholt	ret = drm_initmap(dev, drm_get_resource_start(dev, 0),
2040145132Sanholt			  drm_get_resource_len(dev, 0), 0, _DRM_FRAME_BUFFER,
2041145132Sanholt			  _DRM_WRITE_COMBINING);
2042145132Sanholt	if (ret != 0)
2043145132Sanholt		return ret;
2044145132Sanholt
2045145132Sanholt	/* The original method of detecting AGP is known to not work correctly,
2046145132Sanholt	 * according to Mike Harris.  The solution is to walk the capabilities
2047145132Sanholt	 * list, which should be done in drm_device_is_agp().
2048145132Sanholt	 */
2049145132Sanholt	if (drm_device_is_agp(dev))
2050145132Sanholt		dev_priv->flags |= CHIP_IS_AGP;
2051145132Sanholt
2052145132Sanholt	DRM_DEBUG("%s card detected\n",
2053145132Sanholt		  ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
2054145132Sanholt
2055145132Sanholt#if defined(__linux__)
2056145132Sanholt	/* Check if we need a reset */
2057145132Sanholt	if (!
2058145132Sanholt	    (dev_priv->mmio =
2059145132Sanholt	     drm_core_findmap(dev, pci_resource_start(dev->pdev, 2))))
2060145132Sanholt		return DRM_ERR(ENOMEM);
2061145132Sanholt
2062145132Sanholt	ret = radeon_create_i2c_busses(dev);
2063145132Sanholt#endif
2064145132Sanholt	return ret;
2065145132Sanholt}
2066145132Sanholt
2067145132Sanholtint radeon_postcleanup(struct drm_device *dev)
2068145132Sanholt{
2069145132Sanholt	drm_radeon_private_t *dev_priv = dev->dev_private;
2070145132Sanholt
2071145132Sanholt	DRM_DEBUG("\n");
2072145132Sanholt#if defined(__linux__)
2073145132Sanholt	radeon_delete_i2c_busses(dev);
2074145132Sanholt#endif
2075145132Sanholt	drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
2076145132Sanholt
2077145132Sanholt	dev->dev_private = NULL;
2078145132Sanholt	return 0;
2079145132Sanholt}
2080