Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1029 | serge | 1 | #define RADEON_SCRATCH_REG0 0x15e0 |
2 | #define RADEON_SCRATCH_REG1 0x15e4 |
||
3 | #define RADEON_SCRATCH_REG2 0x15e8 |
||
4 | #define RADEON_SCRATCH_REG3 0x15ec |
||
5 | #define RADEON_SCRATCH_REG4 0x15f0 |
||
6 | #define RADEON_SCRATCH_REG5 0x15f4 |
||
7 | #define RADEON_SCRATCH_UMSK 0x0770 |
||
8 | #define RADEON_SCRATCH_ADDR 0x0774 |
||
9 | |||
10 | # define RS400_BUS_MASTER_DIS (1 << 14) |
||
11 | //# define RADEON_BUS_MASTER_DIS (1 << 6) |
||
12 | |||
13 | #define RADEON_ISYNC_CNTL 0x1724 |
||
14 | # define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) |
||
15 | # define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) |
||
16 | # define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) |
||
17 | # define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) |
||
18 | # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) |
||
19 | # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) |
||
20 | |||
21 | |||
22 | void RADEONEngineFlush(RHDPtr info) |
||
23 | { |
||
24 | int i; |
||
25 | |||
26 | if (info->ChipFamily <= CHIP_FAMILY_RV280) |
||
27 | { |
||
28 | MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL, |
||
29 | ~RADEON_RB3D_DC_FLUSH_ALL); |
||
30 | for (i = 0; i < RADEON_TIMEOUT; i++) { |
||
31 | if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY)) |
||
32 | break; |
||
33 | } |
||
34 | if (i == RADEON_TIMEOUT) { |
||
35 | dbgprintf("DC flush timeout: %x\n", |
||
36 | (u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT)); |
||
37 | } |
||
38 | } |
||
39 | else |
||
40 | { |
||
41 | // MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL, |
||
42 | // ~R300_RB2D_DC_FLUSH_ALL); |
||
43 | // for (i = 0; i < RADEON_TIMEOUT; i++) { |
||
44 | // if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY)) |
||
45 | // break; |
||
46 | // } |
||
47 | // if (i == RADEON_TIMEOUT) { |
||
48 | // dbgprintf("DC flush timeout: %x\n", |
||
49 | // (u32_t)INREG(R300_DSTCACHE_CTLSTAT)); |
||
50 | // } |
||
51 | } |
||
52 | } |
||
53 | |||
54 | |||
55 | static int radeon_do_wait_for_idle() |
||
56 | { |
||
57 | int i, ret; |
||
58 | |||
59 | ret = R5xxFIFOWaitLocal(64); |
||
60 | if (ret) |
||
61 | return ret; |
||
62 | |||
63 | for (i = 0; i < RADEON_TIMEOUT; i++) |
||
64 | { |
||
65 | if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { |
||
66 | RADEONEngineFlush(&rhd); |
||
67 | return 0; |
||
68 | } |
||
69 | usleep(1); |
||
70 | } |
||
71 | dbgprintf("wait idle failed status : 0x%08X 0x%08X\n", |
||
72 | INREG(RADEON_RBBM_STATUS), |
||
73 | INREG(R300_VAP_CNTL_STATUS)); |
||
74 | |||
75 | return 1; |
||
76 | } |
||
77 | |||
78 | |||
79 | |||
80 | /* ================================================================ |
||
81 | * CP control, initialization |
||
82 | */ |
||
83 | |||
84 | /* Load the microcode for the CP */ |
||
85 | |||
86 | #include "radeon_microcode.h" |
||
87 | |||
88 | static void load_microcode(RHDPtr info) |
||
89 | { |
||
90 | int i; |
||
91 | const u32_t (*microcode)[2]; |
||
92 | |||
93 | OUTREG(RADEON_CP_ME_RAM_ADDR, 0); |
||
94 | |||
95 | if ( (info->ChipFamily == CHIP_FAMILY_LEGACY ) || |
||
96 | (info->ChipFamily == CHIP_FAMILY_RADEON ) || |
||
97 | (info->ChipFamily == CHIP_FAMILY_RV100 ) || |
||
98 | (info->ChipFamily == CHIP_FAMILY_RV200 ) || |
||
99 | (info->ChipFamily == CHIP_FAMILY_RS100 ) || |
||
100 | (info->ChipFamily == CHIP_FAMILY_RS200 )) |
||
101 | { |
||
102 | microcode = R100_cp_microcode; |
||
103 | dbgprintf("Loading R100 Microcode\n"); |
||
104 | } |
||
105 | else if ((info->ChipFamily == CHIP_FAMILY_R200 ) || |
||
106 | (info->ChipFamily == CHIP_FAMILY_RV250) || |
||
107 | (info->ChipFamily == CHIP_FAMILY_RV280) || |
||
108 | (info->ChipFamily == CHIP_FAMILY_RS300)) |
||
109 | { |
||
110 | microcode = R200_cp_microcode; |
||
111 | dbgprintf("Loading R200 Microcode\n"); |
||
112 | } |
||
113 | else if ((info->ChipFamily == CHIP_FAMILY_R300) || |
||
114 | (info->ChipFamily == CHIP_FAMILY_R350) || |
||
115 | (info->ChipFamily == CHIP_FAMILY_RV350) || |
||
116 | (info->ChipFamily == CHIP_FAMILY_RV380) || |
||
117 | (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
118 | (info->ChipFamily == CHIP_FAMILY_RS480)) |
||
119 | { |
||
120 | dbgprintf("Loading R300 Microcode\n"); |
||
121 | microcode = R300_cp_microcode; |
||
122 | } |
||
123 | else if ((info->ChipFamily == CHIP_FAMILY_R420) || |
||
124 | (info->ChipFamily == CHIP_FAMILY_RV410)) |
||
125 | { |
||
126 | dbgprintf("Loading R400 Microcode\n"); |
||
127 | microcode = R420_cp_microcode; |
||
128 | |||
129 | } |
||
130 | else if ((info->ChipFamily == CHIP_FAMILY_RS600) || |
||
131 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
132 | (info->ChipFamily == CHIP_FAMILY_RS740)) |
||
133 | { |
||
134 | dbgprintf("Loading RS690/RS740 Microcode\n"); |
||
135 | microcode = RS690_cp_microcode; |
||
136 | } |
||
137 | else if ((info->ChipFamily == CHIP_FAMILY_RV515) || |
||
138 | (info->ChipFamily == CHIP_FAMILY_R520) || |
||
139 | (info->ChipFamily == CHIP_FAMILY_RV530) || |
||
140 | (info->ChipFamily == CHIP_FAMILY_R580) || |
||
141 | (info->ChipFamily == CHIP_FAMILY_RV560) || |
||
142 | (info->ChipFamily == CHIP_FAMILY_RV570)) |
||
143 | { |
||
144 | dbgprintf("Loading R500 Microcode\n"); |
||
145 | microcode = R520_cp_microcode; |
||
146 | } |
||
147 | |||
148 | for (i = 0; i < 256; i++) { |
||
149 | OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]); |
||
150 | OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]); |
||
151 | } |
||
152 | } |
||
153 | |||
154 | |||
155 | void init_ring_buffer(RHDPtr info) |
||
156 | { |
||
157 | u32_t ring_base; |
||
158 | u32_t tmp; |
||
159 | |||
160 | info->ringBase = CreateRingBuffer( 64*1024, PG_SW); |
||
161 | |||
162 | dbgprintf("create cp ring buffer %x\n", rhd.ringBase); |
||
163 | ring_base = GetPgAddr(rhd.ringBase); |
||
164 | dbgprintf("ring base %x\n", ring_base); |
||
165 | |||
166 | OUTREG(RADEON_CP_RB_BASE, ring_base); |
||
167 | |||
168 | info->ring_avail = 64*1024/4 ; |
||
169 | |||
170 | /* Set the write pointer delay */ |
||
171 | OUTREG(RADEON_CP_RB_WPTR_DELAY, 0); |
||
172 | |||
173 | /* Initialize the ring buffer's read and write pointers */ |
||
174 | rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR); |
||
175 | rhd.host_rp = rhd.ring_rp; |
||
176 | |||
177 | OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp); |
||
178 | |||
179 | tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr((void*)&rhd.host_rp); |
||
180 | |||
181 | OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer |
||
182 | |||
183 | /* Set ring buffer size */ |
||
184 | OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13); |
||
185 | |||
186 | /* Initialize the scratch register pointer. This will cause |
||
187 | * the scratch register values to be written out to memory |
||
188 | * whenever they are updated. |
||
189 | * |
||
190 | * We simply put this behind the ring read pointer, this works |
||
191 | * with PCI GART as well as (whatever kind of) AGP GART |
||
192 | */ |
||
193 | |||
194 | tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr((void*)&rhd.scratch0); |
||
195 | OUTREG(RADEON_SCRATCH_ADDR, tmp); |
||
196 | |||
197 | OUTREG(RADEON_SCRATCH_UMSK, 0x0); |
||
198 | //OUTREG(0x778, 1); |
||
199 | |||
200 | /* Turn on bus mastering */ |
||
201 | if ( (info->ChipFamily == CHIP_FAMILY_RS400) || |
||
202 | (info->ChipFamily == CHIP_FAMILY_RS690) || |
||
203 | (info->ChipFamily == CHIP_FAMILY_RS740) ) |
||
204 | { |
||
205 | /* rs400, rs690/rs740 */ |
||
206 | tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; |
||
207 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
208 | } |
||
209 | else if (!((info->ChipFamily == CHIP_FAMILY_RV380) || |
||
210 | (info->ChipFamily >= CHIP_FAMILY_R420))) |
||
211 | { |
||
212 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ |
||
213 | tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
||
214 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
215 | } /* PCIE cards appears to not need this */ |
||
216 | |||
217 | tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
||
218 | OUTREG(RADEON_BUS_CNTL, tmp); |
||
219 | |||
220 | radeon_do_wait_for_idle(); |
||
221 | |||
222 | /* Sync everything up */ |
||
223 | OUTREG(RADEON_ISYNC_CNTL, |
||
224 | (RADEON_ISYNC_ANY2D_IDLE3D | |
||
225 | RADEON_ISYNC_ANY3D_IDLE2D | |
||
226 | RADEON_ISYNC_WAIT_IDLEGUI | |
||
227 | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); |
||
228 | } |
||
229 | |||
230 | |||
231 | |||
232 | #define RADEON_WAIT_UNTIL_IDLE() do { \ |
||
233 | OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) ); \ |
||
234 | OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ |
||
235 | RADEON_WAIT_3D_IDLECLEAN | \ |
||
236 | RADEON_WAIT_HOST_IDLECLEAN) ); \ |
||
237 | } while (0) |
||
238 | |||
239 | #define R300_ZB_ZCACHE_CTLSTAT 0x4f18 |
||
240 | # define RADEON_RB3D_ZC_FLUSH (1 << 0) |
||
241 | # define RADEON_RB3D_ZC_FREE (1 << 2) |
||
242 | # define RADEON_RB3D_ZC_FLUSH_ALL 0x5 |
||
243 | # define RADEON_RB3D_ZC_BUSY (1 << 31) |
||
244 | # define R300_ZC_FLUSH (1 << 0) |
||
245 | # define R300_ZC_FREE (1 << 1) |
||
246 | # define R300_ZC_BUSY (1 << 31) |
||
247 | # define RADEON_RB3D_DC_FLUSH (3 << 0) |
||
248 | # define RADEON_RB3D_DC_FREE (3 << 2) |
||
249 | # define RADEON_RB3D_DC_FLUSH_ALL 0xf |
||
250 | # define RADEON_RB3D_DC_BUSY (1 << 31) |
||
251 | # define R300_RB3D_DC_FLUSH (2 << 0) |
||
252 | # define R300_RB3D_DC_FREE (2 << 2) |
||
253 | # |
||
254 | #define RADEON_PURGE_CACHE() do { \ |
||
255 | if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
256 | OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1)); \ |
||
257 | OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ |
||
258 | } else { \ |
||
259 | OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1)); \ |
||
260 | OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \ |
||
261 | } \ |
||
262 | } while (0) |
||
263 | |||
264 | #define RADEON_FLUSH_ZCACHE() do { \ |
||
265 | if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
266 | OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \ |
||
267 | OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ |
||
268 | } else { \ |
||
269 | OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) ); \ |
||
270 | OUT_RING( R300_ZC_FLUSH ); \ |
||
271 | } \ |
||
272 | } while (0) |
||
273 | #define RADEON_PURGE_ZCACHE() do { \ |
||
274 | if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \ |
||
275 | OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1)); \ |
||
276 | OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ |
||
277 | } else { \ |
||
278 | OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1)); \ |
||
279 | OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ |
||
280 | } \ |
||
281 | } while (0) |
||
282 | |||
283 | static int radeon_cp_start(RHDPtr info) |
||
284 | { |
||
285 | u32_t *ring, write; |
||
286 | u32_t ifl; |
||
287 | radeon_do_wait_for_idle(64); |
||
288 | |||
289 | OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
||
290 | |||
291 | ifl = safe_cli(); |
||
292 | |||
293 | BEGIN_RING(8); |
||
294 | /* isync can only be written through cp on r5xx write it here */ |
||
295 | OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1)); |
||
296 | OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | |
||
297 | RADEON_ISYNC_ANY3D_IDLE2D | |
||
298 | RADEON_ISYNC_WAIT_IDLEGUI | |
||
299 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
||
300 | RADEON_PURGE_CACHE(); |
||
301 | RADEON_PURGE_ZCACHE(); |
||
302 | RADEON_WAIT_UNTIL_IDLE(); |
||
303 | ADVANCE_RING(); |
||
304 | COMMIT_RING(); |
||
305 | |||
306 | safe_sti(ifl); |
||
307 | |||
308 | radeon_do_wait_for_idle(); |
||
309 | }; |
||
310 | |||
311 | |||
312 | Bool init_cp(RHDPtr info) |
||
313 | { |
||
314 | load_microcode(&rhd); |
||
315 | |||
316 | init_ring_buffer(&rhd); |
||
317 | |||
318 | radeon_engine_reset(&rhd); |
||
319 | |||
320 | rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR); |
||
321 | OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp); |
||
322 | |||
323 | radeon_cp_start(&rhd); |
||
324 | |||
325 | return TRUE; |
||
326 | };=>=>=>><>><>><>><>><>><>><>><>><>><>><>8)|13); |
||
327 | |||
328 |