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