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
35status_t
36radeon_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
91status_t
92radeon_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
223void
224radeon_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
247void
248radeon_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
274status_t
275radeon_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
310static status_t
311radeon_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
368static status_t
369radeon_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
430static status_t
431radeon_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
501void
502radeon_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
532status_t
533radeon_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
561status_t
562radeon_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
581status_t
582radeon_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
718status_t
719radeon_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