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