xref: /haiku/src/add-ons/accelerants/radeon_hd/gpu.cpp (revision aed35104852941f0f6f3d1dcc5338b5f337d0a3c)
1 /*
2  * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Alexander von Gluck, kallisti5@unixzen.com
7  *		Axel Dörfler, axeld@pinc-software.de
8  */
9 
10 
11 #include "gpu.h"
12 
13 #include <Debug.h>
14 
15 #include "accelerant_protos.h"
16 #include "accelerant.h"
17 #include "bios.h"
18 #include "utility.h"
19 
20 
21 #undef TRACE
22 
23 #define TRACE_GPU
24 #ifdef TRACE_GPU
25 #   define TRACE(x...) _sPrintf("radeon_hd: " x)
26 #else
27 #   define TRACE(x...) ;
28 #endif
29 
30 #define ERROR(x...) _sPrintf("radeon_hd: " x)
31 
32 
33 status_t
34 radeon_gpu_reset()
35 {
36 	radeon_shared_info &info = *gInfo->shared_info;
37 
38 	// Read GRBM Command Processor status
39 	if ((Read32(OUT, GRBM_STATUS) & GUI_ACTIVE) == 0)
40 		return B_ERROR;
41 
42 	TRACE("%s: GPU software reset in progress...\n", __func__);
43 
44 	// Halt memory controller
45 	struct gpu_state gpuState;
46 	radeon_gpu_mc_halt(&gpuState);
47 
48 	if (radeon_gpu_mc_idlewait() != B_OK)
49 		ERROR("%s: Couldn't idle memory controller!\n", __func__);
50 
51 	if (info.chipsetID < RADEON_CEDAR) {
52 		Write32(OUT, CP_ME_CNTL, CP_ME_HALT);
53 			// Disable Command Processor parsing / prefetching
54 
55 		// Register busy masks for early Radeon HD cards
56 
57 		// GRBM Command Processor Status
58 		uint32 grbmBusyMask = VC_BUSY;
59 			// Vertex Cache Busy
60 		grbmBusyMask |= VGT_BUSY_NO_DMA | VGT_BUSY;
61 			// Vertex Grouper Tessellator Busy
62 		grbmBusyMask |= TA03_BUSY;
63 			// unknown
64 		grbmBusyMask |= TC_BUSY;
65 			// Texture Cache Busy
66 		grbmBusyMask |= SX_BUSY;
67 			// Shader Export Busy
68 		grbmBusyMask |= SH_BUSY;
69 			// Sequencer Instruction Cache Busy
70 		grbmBusyMask |= SPI_BUSY;
71 			// Shader Processor Interpolator Busy
72 		grbmBusyMask |= SMX_BUSY;
73 			// Shader Memory Exchange
74 		grbmBusyMask |= SC_BUSY;
75 			// Scan Converter Busy
76 		grbmBusyMask |= PA_BUSY;
77 			// Primitive Assembler Busy
78 		grbmBusyMask |= DB_BUSY;
79 			// Depth Block Busy
80 		grbmBusyMask |= CR_BUSY;
81 			// unknown
82 		grbmBusyMask |= CB_BUSY;
83 			// Color Block Busy
84 		grbmBusyMask |= GUI_ACTIVE;
85 			// unknown (graphics pipeline active?)
86 
87 		// GRBM Command Processor Detailed Status
88 		uint32 grbm2BusyMask = SPI0_BUSY | SPI1_BUSY | SPI2_BUSY | SPI3_BUSY;
89 			// Shader Processor Interpolator 0 - 3 Busy
90 		grbm2BusyMask |= TA0_BUSY | TA1_BUSY | TA2_BUSY | TA3_BUSY;
91 			// unknown 0 - 3 Busy
92 		grbm2BusyMask |= DB0_BUSY | DB1_BUSY | DB2_BUSY | DB3_BUSY;
93 			// Depth Block 0 - 3 Busy
94 		grbm2BusyMask |= CB0_BUSY | CB1_BUSY | CB2_BUSY | CB3_BUSY;
95 			// Color Block 0 - 3 Busy
96 
97 		uint32 tmp;
98 		/* Check if any of the rendering block is busy and reset it */
99 		if ((Read32(OUT, GRBM_STATUS) & grbmBusyMask) != 0
100 			|| (Read32(OUT, GRBM_STATUS2) & grbm2BusyMask) != 0) {
101 			tmp = SOFT_RESET_CR
102 				| SOFT_RESET_DB
103 				| SOFT_RESET_CB
104 				| SOFT_RESET_PA
105 				| SOFT_RESET_SC
106 				| SOFT_RESET_SMX
107 				| SOFT_RESET_SPI
108 				| SOFT_RESET_SX
109 				| SOFT_RESET_SH
110 				| SOFT_RESET_TC
111 				| SOFT_RESET_TA
112 				| SOFT_RESET_VC
113 				| SOFT_RESET_VGT;
114 			Write32(OUT, GRBM_SOFT_RESET, tmp);
115 			Read32(OUT, GRBM_SOFT_RESET);
116 			snooze(15000);
117 			Write32(OUT, GRBM_SOFT_RESET, 0);
118 		}
119 
120 		// Reset CP
121 		tmp = SOFT_RESET_CP;
122 		Write32(OUT, GRBM_SOFT_RESET, tmp);
123 		Read32(OUT, GRBM_SOFT_RESET);
124 		snooze(15000);
125 		Write32(OUT, GRBM_SOFT_RESET, 0);
126 
127 		// Let things settle
128 		snooze(1000);
129 	} else {
130 		// Evergreen and higher
131 
132 		Write32(OUT, CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
133 			// Disable Command Processor parsing / prefetching
134 
135 		// reset the graphics pipeline components
136 		uint32 grbmReset = (SOFT_RESET_CP
137 			| SOFT_RESET_CB
138 			| SOFT_RESET_DB
139 			| SOFT_RESET_GDS
140 			| SOFT_RESET_PA
141 			| SOFT_RESET_SC
142 			| SOFT_RESET_SPI
143 			| SOFT_RESET_SH
144 			| SOFT_RESET_SX
145 			| SOFT_RESET_TC
146 			| SOFT_RESET_TA
147 			| SOFT_RESET_VGT
148 			| SOFT_RESET_IA);
149 
150 		Write32(OUT, GRBM_SOFT_RESET, grbmReset);
151 		Read32(OUT, GRBM_SOFT_RESET);
152 
153 		snooze(50);
154 		Write32(OUT, GRBM_SOFT_RESET, 0);
155 		Read32(OUT, GRBM_SOFT_RESET);
156 		snooze(50);
157 	}
158 
159 	// Resume memory controller
160 	radeon_gpu_mc_resume(&gpuState);
161 	return B_OK;
162 }
163 
164 
165 void
166 radeon_gpu_mc_halt(gpu_state* gpuState)
167 {
168 	// Backup current memory controller state
169 	gpuState->d1vgaControl = Read32(OUT, AVIVO_D1VGA_CONTROL);
170 	gpuState->d2vgaControl = Read32(OUT, AVIVO_D2VGA_CONTROL);
171 	gpuState->vgaRenderControl = Read32(OUT, AVIVO_VGA_RENDER_CONTROL);
172 	gpuState->vgaHdpControl = Read32(OUT, AVIVO_VGA_HDP_CONTROL);
173 	gpuState->d1crtcControl = Read32(OUT, AVIVO_D1CRTC_CONTROL);
174 	gpuState->d2crtcControl = Read32(OUT, AVIVO_D2CRTC_CONTROL);
175 
176 	// halt all memory controller actions
177 	Write32(OUT, AVIVO_VGA_RENDER_CONTROL, 0);
178 	Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 1);
179 	Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 1);
180 	Write32(OUT, AVIVO_D1CRTC_CONTROL, 0);
181 	Write32(OUT, AVIVO_D2CRTC_CONTROL, 0);
182 	Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 0);
183 	Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 0);
184 	Write32(OUT, AVIVO_D1VGA_CONTROL, 0);
185 	Write32(OUT, AVIVO_D2VGA_CONTROL, 0);
186 }
187 
188 
189 void
190 radeon_gpu_mc_resume(gpu_state* gpuState)
191 {
192 	Write32(OUT, AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, gInfo->fb.vramStart);
193 	Write32(OUT, AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS, gInfo->fb.vramStart);
194 	Write32(OUT, AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, gInfo->fb.vramStart);
195 	Write32(OUT, AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS, gInfo->fb.vramStart);
196 	// TODO: Evergreen high surface addresses?
197 	Write32(OUT, AVIVO_VGA_MEMORY_BASE_ADDRESS, gInfo->fb.vramStart);
198 
199 	// Unlock host access
200 	Write32(OUT, AVIVO_VGA_HDP_CONTROL, gpuState->vgaHdpControl);
201 	snooze(1);
202 
203 	// Restore memory controller state
204 	Write32(OUT, AVIVO_D1VGA_CONTROL, gpuState->d1vgaControl);
205 	Write32(OUT, AVIVO_D2VGA_CONTROL, gpuState->d2vgaControl);
206 	Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 1);
207 	Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 1);
208 	Write32(OUT, AVIVO_D1CRTC_CONTROL, gpuState->d1crtcControl);
209 	Write32(OUT, AVIVO_D2CRTC_CONTROL, gpuState->d2crtcControl);
210 	Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 0);
211 	Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 0);
212 	Write32(OUT, AVIVO_VGA_RENDER_CONTROL, gpuState->vgaRenderControl);
213 }
214 
215 
216 status_t
217 radeon_gpu_mc_idlewait()
218 {
219 	uint32 idleStatus;
220 
221 	uint32 busyBits
222 		= (VMC_BUSY | MCB_BUSY | MCDZ_BUSY | MCDY_BUSY | MCDX_BUSY | MCDW_BUSY);
223 
224 	uint32 tryCount;
225 	// We give the gpu 0.5 seconds to become idle checking once every 500usec
226 	for (tryCount = 0; tryCount < 1000; tryCount++) {
227 		if (((idleStatus = Read32(MC, SRBM_STATUS)) & busyBits) == 0)
228 			return B_OK;
229 		snooze(500);
230 	}
231 
232 	ERROR("%s: Couldn't idle SRBM!\n", __func__);
233 
234 	bool state;
235 	state = (idleStatus & VMC_BUSY) != 0;
236 	TRACE("%s: VMC is %s\n", __func__, state ? "busy" : "idle");
237 	state = (idleStatus & MCB_BUSY) != 0;
238 	TRACE("%s: MCB is %s\n", __func__, state ? "busy" : "idle");
239 	state = (idleStatus & MCDZ_BUSY) != 0;
240 	TRACE("%s: MCDZ is %s\n", __func__, state ? "busy" : "idle");
241 	state = (idleStatus & MCDY_BUSY) != 0;
242 	TRACE("%s: MCDY is %s\n", __func__, state ? "busy" : "idle");
243 	state = (idleStatus & MCDX_BUSY) != 0;
244 	TRACE("%s: MCDX is %s\n", __func__, state ? "busy" : "idle");
245 	state = (idleStatus & MCDW_BUSY) != 0;
246 	TRACE("%s: MCDW is %s\n", __func__, state ? "busy" : "idle");
247 
248 	return B_TIMED_OUT;
249 }
250 
251 
252 static status_t
253 radeon_gpu_mc_setup_r600()
254 {
255 	// HDP initialization
256 	uint32 i;
257 	uint32 j;
258 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
259 		Write32(OUT, (0x2c14 + j), 0x00000000);
260 		Write32(OUT, (0x2c18 + j), 0x00000000);
261 		Write32(OUT, (0x2c1c + j), 0x00000000);
262 		Write32(OUT, (0x2c20 + j), 0x00000000);
263 		Write32(OUT, (0x2c24 + j), 0x00000000);
264 	}
265 	Write32(OUT, R600_HDP_REG_COHERENCY_FLUSH_CNTL, 0);
266 
267 	// idle the memory controller
268 	struct gpu_state gpuState;
269 	radeon_gpu_mc_halt(&gpuState);
270 
271 	if (radeon_gpu_mc_idlewait() != B_OK)
272 		ERROR("%s: Modifying non-idle memory controller!\n", __func__);
273 
274 	// TODO: Memory Controller AGP
275 	Write32(OUT, R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR,
276 		gInfo->fb.vramStart >> 12);
277 	Write32(OUT, R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
278 		gInfo->fb.vramEnd >> 12);
279 
280 	Write32(OUT, R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
281 	uint32 tmp = ((gInfo->fb.vramEnd >> 24) & 0xFFFF) << 16;
282 	tmp |= ((gInfo->fb.vramStart >> 24) & 0xFFFF);
283 
284 	Write32(OUT, R600_MC_VM_FB_LOCATION, tmp);
285 	Write32(OUT, R600_HDP_NONSURFACE_BASE, (gInfo->fb.vramStart >> 8));
286 	Write32(OUT, R600_HDP_NONSURFACE_INFO, (2 << 7));
287 	Write32(OUT, R600_HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
288 
289 	// is AGP?
290 	//	Write32(OUT, R600_MC_VM_AGP_TOP, gInfo->fb.gartEnd >> 22);
291 	//	Write32(OUT, R600_MC_VM_AGP_BOT, gInfo->fb.gartStart >> 22);
292 	//	Write32(OUT, R600_MC_VM_AGP_BASE, gInfo->fb.agpBase >> 22);
293 	// else?
294 	Write32(OUT, R600_MC_VM_AGP_BASE, 0);
295 	Write32(OUT, R600_MC_VM_AGP_TOP, 0x0FFFFFFF);
296 	Write32(OUT, R600_MC_VM_AGP_BOT, 0x0FFFFFFF);
297 
298 	if (radeon_gpu_mc_idlewait() != B_OK)
299 		ERROR("%s: Modifying non-idle memory controller!\n", __func__);
300 
301 	radeon_gpu_mc_resume(&gpuState);
302 
303 	// disable render control
304 	Write32(OUT, 0x000300, Read32(OUT, 0x000300) & 0xFFFCFFFF);
305 
306 	return B_OK;
307 }
308 
309 
310 static status_t
311 radeon_gpu_mc_setup_r700()
312 {
313 	// HDP initialization
314 	uint32 i;
315 	uint32 j;
316 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
317 		Write32(OUT, (0x2c14 + j), 0x00000000);
318 		Write32(OUT, (0x2c18 + j), 0x00000000);
319 		Write32(OUT, (0x2c1c + j), 0x00000000);
320 		Write32(OUT, (0x2c20 + j), 0x00000000);
321 		Write32(OUT, (0x2c24 + j), 0x00000000);
322 	}
323 
324 	// On r7xx read from HDP_DEBUG1 vs write HDP_REG_COHERENCY_FLUSH_CNTL
325 	Read32(OUT, R700_HDP_DEBUG1);
326 
327 	// idle the memory controller
328 	struct gpu_state gpuState;
329 	radeon_gpu_mc_halt(&gpuState);
330 
331 	if (radeon_gpu_mc_idlewait() != B_OK)
332 		ERROR("%s: Modifying non-idle memory controller!\n", __func__);
333 
334 	Write32(OUT, AVIVO_VGA_HDP_CONTROL, AVIVO_VGA_MEMORY_DISABLE);
335 
336 	// TODO: Memory Controller AGP
337 	Write32(OUT, R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR,
338 		gInfo->fb.vramStart >> 12);
339 	Write32(OUT, R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
340 		gInfo->fb.vramEnd >> 12);
341 
342 	Write32(OUT, R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
343 	uint32 tmp = ((gInfo->fb.vramEnd >> 24) & 0xFFFF) << 16;
344 	tmp |= ((gInfo->fb.vramStart >> 24) & 0xFFFF);
345 
346 	Write32(OUT, R700_MC_VM_FB_LOCATION, tmp);
347 	Write32(OUT, R700_HDP_NONSURFACE_BASE, (gInfo->fb.vramStart >> 8));
348 	Write32(OUT, R700_HDP_NONSURFACE_INFO, (2 << 7));
349 	Write32(OUT, R700_HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
350 
351 	// is AGP?
352 	//	Write32(OUT, R700_MC_VM_AGP_TOP, gInfo->fb.gartEnd >> 22);
353 	//	Write32(OUT, R700_MC_VM_AGP_BOT, gInfo->fb.gartStart >> 22);
354 	//	Write32(OUT, R700_MC_VM_AGP_BASE, gInfo->fb.agpBase >> 22);
355 	// else?
356 	Write32(OUT, R700_MC_VM_AGP_BASE, 0);
357 	Write32(OUT, R700_MC_VM_AGP_TOP, 0x0FFFFFFF);
358 	Write32(OUT, R700_MC_VM_AGP_BOT, 0x0FFFFFFF);
359 
360 	if (radeon_gpu_mc_idlewait() != B_OK)
361 		ERROR("%s: Modifying non-idle memory controller!\n", __func__);
362 
363 	radeon_gpu_mc_resume(&gpuState);
364 
365 	// disable render control
366 	Write32(OUT, 0x000300, Read32(OUT, 0x000300) & 0xFFFCFFFF);
367 
368 	return B_OK;
369 }
370 
371 
372 static status_t
373 radeon_gpu_mc_setup_evergreen()
374 {
375 	// HDP initialization
376 	uint32 i;
377 	uint32 j;
378 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
379 		Write32(OUT, (0x2c14 + j), 0x00000000);
380 		Write32(OUT, (0x2c18 + j), 0x00000000);
381 		Write32(OUT, (0x2c1c + j), 0x00000000);
382 		Write32(OUT, (0x2c20 + j), 0x00000000);
383 		Write32(OUT, (0x2c24 + j), 0x00000000);
384 	}
385 	Write32(OUT, EVERGREEN_HDP_REG_COHERENCY_FLUSH_CNTL, 0);
386 
387 	// idle the memory controller
388 	struct gpu_state gpuState;
389 	radeon_gpu_mc_halt(&gpuState);
390 
391 	if (radeon_gpu_mc_idlewait() != B_OK)
392 		ERROR("%s: Modifying non-idle memory controller!\n", __func__);
393 
394 	Write32(OUT, AVIVO_VGA_HDP_CONTROL, AVIVO_VGA_MEMORY_DISABLE);
395 
396 	// TODO: Memory Controller AGP
397 	Write32(OUT, EVERGREEN_MC_VM_SYSTEM_APERTURE_LOW_ADDR,
398 		gInfo->fb.vramStart >> 12);
399 	Write32(OUT, EVERGREEN_MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
400 		gInfo->fb.vramEnd >> 12);
401 
402 	Write32(OUT, EVERGREEN_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
403 
404 	radeon_shared_info &info = *gInfo->shared_info;
405 	if ((info.chipsetFlags & CHIP_IGP) != 0) {
406 		// Evergreen IGP Fusion
407 		uint32 tmp = Read32(OUT, EVERGREEN_MC_FUS_VM_FB_OFFSET)
408 			& 0x000FFFFF;
409 		tmp |= ((gInfo->fb.vramEnd >> 20) & 0xF) << 24;
410 		tmp |= ((gInfo->fb.vramStart >> 20) & 0xF) << 20;
411 		Write32(OUT, EVERGREEN_MC_FUS_VM_FB_OFFSET, tmp);
412 	}
413 
414 	uint32 tmp = ((gInfo->fb.vramEnd >> 24) & 0xFFFF) << 16;
415 	tmp |= ((gInfo->fb.vramStart >> 24) & 0xFFFF);
416 
417 	Write32(OUT, EVERGREEN_MC_VM_FB_LOCATION, tmp);
418 	Write32(OUT, EVERGREEN_HDP_NONSURFACE_BASE, (gInfo->fb.vramStart >> 8));
419 	Write32(OUT, EVERGREEN_HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
420 	Write32(OUT, EVERGREEN_HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
421 
422 	// is AGP?
423 	//	Write32(OUT, EVERGREEN_MC_VM_AGP_TOP, gInfo->fb.gartEnd >> 16);
424 	//	Write32(OUT, EVERGREEN_MC_VM_AGP_BOT, gInfo->fb.gartStart >> 16);
425 	//	Write32(OUT, EVERGREEN_MC_VM_AGP_BASE, gInfo->fb.agpBase >> 22);
426 	// else?
427 	Write32(OUT, EVERGREEN_MC_VM_AGP_BASE, 0);
428 	Write32(OUT, EVERGREEN_MC_VM_AGP_TOP, 0x0FFFFFFF);
429 	Write32(OUT, EVERGREEN_MC_VM_AGP_BOT, 0x0FFFFFFF);
430 
431 	if (radeon_gpu_mc_idlewait() != B_OK)
432 		ERROR("%s: Modifying non-idle memory controller!\n", __func__);
433 
434 	radeon_gpu_mc_resume(&gpuState);
435 
436 	// disable render control
437 	Write32(OUT, 0x000300, Read32(OUT, 0x000300) & 0xFFFCFFFF);
438 
439 	return B_OK;
440 }
441 
442 
443 void
444 radeon_gpu_mc_init()
445 {
446 	radeon_shared_info &info = *gInfo->shared_info;
447 
448 	uint32 fbVMLocationReg;
449 	if (info.chipsetID >= RADEON_CEDAR) {
450 		fbVMLocationReg = EVERGREEN_MC_VM_FB_LOCATION;
451 	} else if (info.chipsetID >= RADEON_RV770) {
452 		fbVMLocationReg = R700_MC_VM_FB_LOCATION;
453 	} else {
454 		fbVMLocationReg = R600_MC_VM_FB_LOCATION;
455 	}
456 
457 	if (gInfo->shared_info->frame_buffer_size > 0)
458 		gInfo->fb.valid = true;
459 
460 	// This is the card internal location.
461 	uint64 vramBase = 0;
462 
463 	if ((info.chipsetFlags & CHIP_IGP) != 0) {
464 		vramBase = Read32(OUT, fbVMLocationReg) & 0xFFFF;
465 		vramBase <<= 24;
466 	}
467 
468 	gInfo->fb.vramStart = vramBase;
469 	gInfo->fb.vramSize = gInfo->shared_info->frame_buffer_size * 1024;
470 	gInfo->fb.vramEnd = (vramBase + gInfo->fb.vramSize) - 1;
471 }
472 
473 
474 status_t
475 radeon_gpu_mc_setup()
476 {
477 	radeon_shared_info &info = *gInfo->shared_info;
478 
479 	radeon_gpu_mc_init();
480 		// init video ram ranges for memory controler
481 
482 	if (gInfo->fb.valid != true) {
483 		ERROR("%s: Memory Controller init failed.\n", __func__);
484 		return B_ERROR;
485 	}
486 
487 	TRACE("%s: vramStart: 0x%" B_PRIX64 ", vramEnd: 0x%" B_PRIX64 "\n",
488 		__func__, gInfo->fb.vramStart, gInfo->fb.vramEnd);
489 
490 	if (info.chipsetID >= RADEON_CAYMAN)
491 		return radeon_gpu_mc_setup_evergreen();	// also for ni
492 	else if (info.chipsetID >= RADEON_CEDAR)
493 		return radeon_gpu_mc_setup_evergreen();
494 	else if (info.chipsetID >= RADEON_RV770)
495 		return radeon_gpu_mc_setup_r700();
496 	else if (info.chipsetID >= RADEON_R600)
497 		return radeon_gpu_mc_setup_r600();
498 
499 	return B_ERROR;
500 }
501 
502 
503 status_t
504 radeon_gpu_ring_setup()
505 {
506 	TRACE("%s called\n", __func__);
507 
508 	// init GFX ring queue
509 	gInfo->ringQueue[RADEON_QUEUE_TYPE_GFX_INDEX]
510 		= new RingQueue(1024 * 1024, RADEON_QUEUE_TYPE_GFX_INDEX);
511 
512 	#if 0
513 	// init IRQ ring queue (reverse of rendering/cp ring queue)
514 	gInfo->irqRingQueue
515 		= new IRQRingQueue(64 * 1024)
516 	#endif
517 
518 
519 	return B_OK;
520 }
521 
522 
523 status_t
524 radeon_gpu_ring_boot(uint32 ringType)
525 {
526 	TRACE("%s called\n", __func__);
527 
528 	RingQueue* ring = gInfo->ringQueue[ringType];
529 	if (ring == NULL) {
530 		ERROR("%s: Specified ring doesn't exist!\n", __func__);
531 		return B_ERROR;
532 	}
533 
534 	// We don't execute this code until it's more complete.
535 	ERROR("%s: TODO\n", __func__);
536 	return B_OK;
537 
538 
539 	// TODO: Write initial ring PACKET3 STATE
540 
541 	// *** r600_cp_init_ring_buffer
542 	// Reset command processor
543 	Write32(OUT, GRBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
544 	Read32(OUT, GRBM_SOFT_RESET);
545 	snooze(15000);
546 	Write32(OUT, GRBM_SOFT_RESET, 0);
547 
548 	// Set ring buffer size
549 	uint32 controlScratch = RB_NO_UPDATE
550 		| (compute_order(4096 / 8) << 8) // rptr_update_l2qw
551 		| compute_order(ring->GetSize() / 8); // size_l2qw
552 	#ifdef __BIG_ENDIAN
553 	controlScratch |= BUF_SWAP_32BIT;
554 	#endif
555 	Write32(OUT, CP_RB_CNTL, controlScratch);
556 
557 	// Set delays and timeouts
558 	Write32(OUT, CP_SEM_WAIT_TIMER, 0);
559 	Write32(OUT, CP_RB_WPTR_DELAY, 0);
560 
561 	// Enable RenderBuffer Reads
562 	controlScratch |= RB_RPTR_WR_ENA;
563 	Write32(OUT, CP_RB_CNTL, controlScratch);
564 
565 	// Zero out command processor read and write pointers
566 	Write32(OUT, CP_RB_RPTR_WR, 0);
567 	Write32(OUT, CP_RB_WPTR, 0);
568 
569 	#if 0
570 	int ringPointer = 0;
571 	// TODO: AGP cards
572 	/*
573 	if (RADEON_IS_AGP) {
574 		ringPointer = dev_priv->ring_rptr->offset
575 			- dev->agp->base
576 			+ dev_priv->gart_vm_start;
577 	} else {
578 	*/
579 	ringPointer = dev_priv->ring_rptr->offset
580 		- ((unsigned long) dev->sg->virtual)
581 		+ dev_priv->gart_vm_start;
582 
583 	Write32(OUT, CP_RB_RPTR_ADDR, (ringPointer & 0xfffffffc));
584 	Write32(OUT, CP_RB_RPTR_ADDR_HI, upper_32_bits(ringPointer));
585 
586 	// Drop RPTR_WR_ENA and update CP RB Control
587 	controlScratch &= ~R600_RB_RPTR_WR_ENA;
588 	Write32(OUT, CP_RB_CNTL, controlScratch);
589 	#endif
590 
591 	#if 0
592 	// Update command processor pointer
593 	int commandPointer = 0;
594 
595 	// TODO: AGP cards
596 	/*
597 	if (RADEON_IS_AGP) {
598 		commandPointer = (dev_priv->cp_ring->offset
599 			- dev->agp->base
600 			+ dev_priv->gart_vm_start);
601 	}
602 	*/
603 	commandPointer = (dev_priv->cp_ring->offset
604 		- (unsigned long)dev->sg->virtual
605 		+ dev_priv->gart_vm_start);
606 	#endif
607 
608 	#if 0
609 	Write32(OUT, CP_RB_BASE, commandPointer >> 8);
610 	Write32(OUT, CP_ME_CNTL, 0xff);
611 	Write32(OUT, CP_DEBUG, (1 << 27) | (1 << 28));
612 	#endif
613 
614 	#if 0
615 	// Initialize scratch register pointer.
616 	// This wil lcause the scratch register values to be wtitten
617 	// to memory whenever they are updated.
618 
619 	uint64 scratchAddr = Read32(OUT, CP_RB_RPTR_ADDR) & 0xFFFFFFFC;
620 	scratchAddr |= ((uint64)Read32(OUT, CP_RB_RPTR_ADDR_HI)) << 32;
621 	scratchAddr += R600_SCRATCH_REG_OFFSET;
622 	scratchAddr >>= 8;
623 	scratchAddr &= 0xffffffff;
624 
625 	Write32(OUT, R600_SCRATCH_ADDR, (uint32)scratchAddr);
626 
627 	Write32(OUT, R600_SCRATCH_UMSK, 0x7);
628 	#endif
629 
630 	#if 0
631 	// Enable bus mastering
632 	radeon_enable_bm(dev_priv);
633 
634 	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0);
635 	Write32(OUT, R600_LAST_FRAME_REG, 0);
636 
637 	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
638 	Write32(OUT, R600_LAST_DISPATCH_REG, 0);
639 
640 	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0);
641 	Write32(OUT, R600_LAST_CLEAR_REG, 0);
642 	#endif
643 
644 	// Reset sarea?
645 	#if 0
646 	master_priv = file_priv->master->driver_priv;
647 	if (master_priv->sarea_priv) {
648 		master_priv->sarea_priv->last_frame = 0;
649 		master_priv->sarea_priv->last_dispatch = 0;
650 		master_priv->sarea_priv->last_clear = 0;
651 	}
652 
653 	r600_do_wait_for_idle(dev_priv);
654 	#endif
655 
656 	return B_OK;
657 }
658 
659 
660 status_t
661 radeon_gpu_ss_disable()
662 {
663 	TRACE("%s called\n", __func__);
664 
665 	radeon_shared_info &info = *gInfo->shared_info;
666 	uint32 ssControl;
667 
668 	if (info.chipsetID >= RADEON_CEDAR) {
669 		// PLL1
670 		ssControl = Read32(OUT, EVERGREEN_P1PLL_SS_CNTL);
671 		ssControl &= ~EVERGREEN_PxPLL_SS_EN;
672 		Write32(OUT, EVERGREEN_P1PLL_SS_CNTL, ssControl);
673 		// PLL2
674 		ssControl = Read32(OUT, EVERGREEN_P2PLL_SS_CNTL);
675 		ssControl &= ~EVERGREEN_PxPLL_SS_EN;
676 		Write32(OUT, EVERGREEN_P2PLL_SS_CNTL, ssControl);
677 	} else if (info.chipsetID >= RADEON_RS600) {
678 		// PLL1
679 		ssControl = Read32(OUT, AVIVO_P1PLL_INT_SS_CNTL);
680 		ssControl &= ~1;
681 		Write32(OUT, AVIVO_P1PLL_INT_SS_CNTL, ssControl);
682 		// PLL2
683 		ssControl = Read32(OUT, AVIVO_P2PLL_INT_SS_CNTL);
684 		ssControl &= ~1;
685 		Write32(OUT, AVIVO_P2PLL_INT_SS_CNTL, ssControl);
686 	} else
687 		return B_ERROR;
688 
689 	return B_OK;
690 }
691