xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon_hd/radeon_hd.cpp (revision 6c4a44e36ba846c54467103f884d65dfa13e7fcb)
1 /*
2  * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  *		Clemens Zeidler, haiku@clemens-zeidler.de
8  *		Fredrik Holmqvis, fredrik.holmqvist@gmail.com
9  *		Alexander von Gluck, kallisti5@unixzen.com
10  */
11 
12 
13 #include "radeon_hd.h"
14 #include "sensors.h"
15 
16 #include "AreaKeeper.h"
17 #include "driver.h"
18 #include "utility.h"
19 
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 
25 #include <boot_item.h>
26 #include <driver_settings.h>
27 #include <util/kernel_cpp.h>
28 #include <vm/vm.h>
29 
30 
31 #define TRACE_DEVICE
32 #ifdef TRACE_DEVICE
33 #	define TRACE(x...) dprintf("radeon_hd: " x)
34 #else
35 #	define TRACE(x) ;
36 #endif
37 
38 #define ERROR(x...) dprintf("radeon_hd: " x)
39 
40 
41 // Must match chipset families in radeon_hd.h
42 static const char radeon_chip_name[][16] = {
43 	"R420",
44 	"R423",
45 	"RV410",
46 	"RS400",
47 	"RS480",
48 	"RS600",
49 	"RS690",
50 	"RS740",
51 	"RV515",
52 	"R520",
53 	"RV530",
54 	"RV560",
55 	"RV570",
56 	"R580",
57 	"R600",
58 	"RV610",
59 	"RV630",
60 	"RV670",
61 	"RV620",
62 	"RV635",
63 	"RS780",
64 	"RS880",
65 	"RV770",
66 	"RV730",
67 	"RV710",
68 	"RV740",
69 	"Cedar",
70 	"Redwood",
71 	"Juniper",
72 	"Cypress",
73 	"Hemlock",
74 	"Palm",
75 	"Sumo",
76 	"Sumo2",
77 	"Caicos",
78 	"Turks",
79 	"Barts",
80 	"Cayman",
81 	"Antilles",
82 	"Lombok",
83 	"Cape Verde",
84 	"Pitcairn",
85 	"Tahiti",
86 	"New Zealand"
87 };
88 
89 
90 //	#pragma mark -
91 
92 
93 status_t
94 mapAtomBIOS(radeon_info &info, uint32 romBase, uint32 romSize)
95 {
96 	TRACE("%s: seeking AtomBIOS @ 0x%" B_PRIX32 " [size: 0x%" B_PRIX32 "]\n",
97 		__func__, romBase, romSize);
98 
99 	uint8* rom;
100 
101 	// attempt to access area specified
102 	area_id testArea = map_physical_memory("radeon hd rom probe",
103 		romBase, romSize, B_ANY_KERNEL_ADDRESS, B_READ_AREA,
104 		(void**)&rom);
105 
106 	if (testArea < 0) {
107 		ERROR("%s: couldn't map potential rom @ 0x%" B_PRIX32
108 			"\n", __func__, romBase);
109 		return B_NO_MEMORY;
110 	}
111 
112 	// check for valid BIOS signature
113 	if (rom[0] != 0x55 || rom[1] != 0xAA) {
114 		uint16 id = rom[0] + (rom[1] << 8);
115 		TRACE("%s: BIOS signature incorrect @ 0x%" B_PRIX32 " (%X)\n",
116 			__func__, romBase, id);
117 		delete_area(testArea);
118 		return B_ERROR;
119 	}
120 
121 	// see if valid AtomBIOS rom
122 	uint16 romHeader = RADEON_BIOS16(rom, 0x48);
123 	bool romValid = !memcmp(&rom[romHeader + 4], "ATOM", 4)
124 		|| !memcmp(&rom[romHeader + 4], "MOTA", 4);
125 
126 	if (romValid == false) {
127 		// FAIL : a PCI VGA bios but not AtomBIOS
128 		uint16 id = rom[0] + (rom[1] << 8);
129 		TRACE("%s: not AtomBIOS rom at 0x%" B_PRIX32 "(%X)\n",
130 			__func__, romBase, id);
131 		delete_area(testArea);
132 		return B_ERROR;
133 	}
134 
135 	info.rom_area = create_area("radeon hd AtomBIOS",
136 		(void**)&info.atom_buffer, B_ANY_KERNEL_ADDRESS,
137 		romSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
138 
139 	if (info.rom_area < 0) {
140 		ERROR("%s: unable to map kernel AtomBIOS space!\n",
141 			__func__);
142 		delete_area(testArea);
143 		return B_NO_MEMORY;
144 	}
145 
146 	memset((void*)info.atom_buffer, 0, romSize);
147 		// Prevent unknown code execution by AtomBIOS parser
148 	memcpy(info.atom_buffer, (void*)rom, romSize);
149 		// Copy AtomBIOS to kernel area
150 
151 	// validate copied rom is valid
152 	romHeader = RADEON_BIOS16(info.atom_buffer, 0x48);
153 	romValid = !memcmp(&info.atom_buffer[romHeader + 4], "ATOM", 4)
154 		|| !memcmp(&info.atom_buffer[romHeader + 4], "MOTA", 4);
155 
156 	if (romValid == true) {
157 		set_area_protection(info.rom_area, B_READ_AREA);
158 		ERROR("%s: AtomBIOS verified and locked\n", __func__);
159 	} else
160 		ERROR("%s: AtomBIOS memcpy failed!\n", __func__);
161 
162 	delete_area(testArea);
163 	return romValid ? B_OK : B_ERROR;
164 }
165 
166 
167 static status_t
168 radeon_hd_getbios(radeon_info &info)
169 {
170 	TRACE("card(%ld): %s: called\n", info.id, __func__);
171 
172 	uint32 romBase = 0;
173 	uint32 romSize = 0;
174 	uint32 romMethod = 0;
175 
176 	status_t mapResult = B_ERROR;
177 
178 	// first we try to find the AtomBIOS rom via various methods
179 	for (romMethod = 0; romMethod < 3; romMethod++) {
180 		switch(romMethod) {
181 			case 0:
182 				// TODO: *** New ACPI method
183 				ERROR("%s: ACPI ATRM AtomBIOS TODO\n", __func__);
184 				break;
185 			case 1:
186 				// *** Discreet card on IGP, check PCI BAR 0
187 				// On post, the bios puts a copy of the IGP
188 				// AtomBIOS at the start of the video ram
189 				romBase = info.pci->u.h0.base_registers[PCI_BAR_FB];
190 				romSize = 256 * 1024;
191 
192 				if (romBase == 0 || romSize == 0) {
193 					ERROR("%s: No base found at PCI FB BAR\n", __func__);
194 				} else {
195 					mapResult = mapAtomBIOS(info, romBase, romSize);
196 				}
197 				break;
198 			case 2:
199 			{
200 				// *** PCI ROM BAR
201 				// Enable ROM decoding for PCI BAR rom
202 				uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
203 				pciConfig |= PCI_rom_enable;
204 				set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
205 
206 				uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
207 				if ((flags & PCI_rom_enable) != 0)
208 					TRACE("%s: PCI ROM decode enabled\n", __func__);
209 
210 				romBase = info.pci->u.h0.rom_base;
211 				romSize = info.pci->u.h0.rom_size;
212 
213 				if (romBase == 0 || romSize == 0) {
214 					ERROR("%s: No base found at PCI ROM BAR\n", __func__);
215 				} else {
216 					mapResult = mapAtomBIOS(info, romBase, romSize);
217 				}
218 
219 				// Disable ROM decoding
220 				pciConfig &= ~PCI_rom_enable;
221 				set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
222 				break;
223 			}
224 		}
225 
226 		if (mapResult == B_OK) {
227 			ERROR("%s: AtomBIOS found using active method %" B_PRIu32
228 				" at 0x%" B_PRIX32 "\n", __func__, romMethod, romBase);
229 			break;
230 		} else {
231 			ERROR("%s: AtomBIOS not found using active method %" B_PRIu32
232 				" at 0x%" B_PRIX32 "\n", __func__, romMethod, romBase);
233 		}
234 	}
235 
236 	if (mapResult == B_OK) {
237 		info.shared_info->rom_phys = romBase;
238 		info.shared_info->rom_size = romSize;
239 	} else
240 		ERROR("%s: Active AtomBIOS search failed.\n", __func__);
241 
242 	return mapResult;
243 }
244 
245 
246 static status_t
247 radeon_hd_getbios_ni(radeon_info &info)
248 {
249 	TRACE("card(%ld): %s: called\n", info.id, __func__);
250 	uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
251 	uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
252 	uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
253 	uint32 vga_render_control
254 		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
255 	uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
256 
257 	// enable the rom
258 	write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
259 	// disable VGA mode
260 	write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
261 		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
262 			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
263 	write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
264 		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
265 			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
266 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
267 		(vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
268 
269 	write32(info.registers + R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
270 
271 	// try to grab the bios via PCI ROM bar
272 	// Enable ROM decoding for PCI BAR rom
273 	uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
274 	pciConfig |= PCI_rom_enable;
275 	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
276 
277 	uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
278 	if (flags & PCI_rom_enable)
279 		TRACE("%s: PCI ROM decode enabled\n", __func__);
280 
281 	uint32 romBase = info.pci->u.h0.rom_base;
282 	uint32 romSize = info.pci->u.h0.rom_size;
283 
284 	status_t result = B_OK;
285 	if (romBase == 0 || romSize == 0) {
286 		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
287 		result = B_ERROR;
288 	} else {
289 		result = mapAtomBIOS(info, romBase, romSize);
290 	}
291 
292 	if (result == B_OK) {
293 		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
294 			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
295 		info.shared_info->rom_phys = romBase;
296 		info.shared_info->rom_size = romSize;
297 	}
298 
299 	// Disable ROM decoding
300 	pciConfig &= ~PCI_rom_enable;
301 	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
302 
303 	// restore regs
304 	write32(info.registers + R600_BUS_CNTL, bus_cntl);
305 	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
306 	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
307 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
308 	write32(info.registers + R600_ROM_CNTL, rom_cntl);
309 
310 	return result;
311 }
312 
313 
314 static status_t
315 radeon_hd_getbios_r700(radeon_info &info)
316 {
317 	TRACE("card(%ld): %s: called\n", info.id, __func__);
318 	uint32 viph_control = read32(info.registers + RADEON_VIPH_CONTROL);
319 	uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
320 	uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
321 	uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
322 	uint32 vga_render_control
323 		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
324 	uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
325 
326 	// disable VIP
327 	write32(info.registers + RADEON_VIPH_CONTROL,
328 		(viph_control & ~RADEON_VIPH_EN));
329 	// enable the rom
330 	write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
331 	// disable VGA mode
332 	write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
333 		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
334 			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
335 	write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
336 		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
337 			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
338 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
339 		(vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
340 
341 	write32(info.registers + R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
342 
343 	// try to grab the bios via PCI ROM bar
344 	// Enable ROM decoding for PCI BAR rom
345 	uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
346 	pciConfig |= PCI_rom_enable;
347 	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
348 
349 	uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
350 	if (flags & PCI_rom_enable)
351 		TRACE("%s: PCI ROM decode enabled\n", __func__);
352 
353 	uint32 romBase = info.pci->u.h0.rom_base;
354 	uint32 romSize = info.pci->u.h0.rom_size;
355 
356 	status_t result = B_OK;
357 	if (romBase == 0 || romSize == 0) {
358 		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
359 		result = B_ERROR;
360 	} else {
361 		result = mapAtomBIOS(info, romBase, romSize);
362 	}
363 
364 	if (result == B_OK) {
365 		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
366 			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
367 		info.shared_info->rom_phys = romBase;
368 		info.shared_info->rom_size = romSize;
369 	}
370 
371 	// Disable ROM decoding
372 	pciConfig &= ~PCI_rom_enable;
373 	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
374 
375 	// restore regs
376 	write32(info.registers + RADEON_VIPH_CONTROL, viph_control);
377 	write32(info.registers + R600_BUS_CNTL, bus_cntl);
378 	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
379 	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
380 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
381 	write32(info.registers + R600_ROM_CNTL, rom_cntl);
382 
383 	return result;
384 }
385 
386 
387 static status_t
388 radeon_hd_getbios_r600(radeon_info &info)
389 {
390 	TRACE("card(%ld): %s: called\n", info.id, __func__);
391 	uint32 viph_control = read32(info.registers + RADEON_VIPH_CONTROL);
392 	uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
393 	uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
394 	uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
395 	uint32 vga_render_control
396 		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
397 	uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
398 	uint32 general_pwrmgt = read32(info.registers + R600_GENERAL_PWRMGT);
399 	uint32 low_vid_lower_gpio_cntl
400 		= read32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL);
401 	uint32 medium_vid_lower_gpio_cntl
402 		= read32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL);
403 	uint32 high_vid_lower_gpio_cntl
404 		= read32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL);
405 	uint32 ctxsw_vid_lower_gpio_cntl
406 		= read32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL);
407 	uint32 lower_gpio_enable
408 		= read32(info.registers + R600_LOWER_GPIO_ENABLE);
409 
410 	// disable VIP
411 	write32(info.registers + RADEON_VIPH_CONTROL,
412 		(viph_control & ~RADEON_VIPH_EN));
413 	// enable the rom
414 	write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
415 	// disable VGA mode
416 	write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
417 		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
418 			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
419 	write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
420 		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
421 			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
422 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
423 		(vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
424 
425 	write32(info.registers + R600_ROM_CNTL,
426 		((rom_cntl & ~R600_SCK_PRESCALE_CRYSTAL_CLK_MASK)
427 		| (1 << R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT) | R600_SCK_OVERWRITE));
428 
429 	write32(info.registers + R600_GENERAL_PWRMGT,
430 		(general_pwrmgt & ~R600_OPEN_DRAIN_PADS));
431 	write32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL,
432 		(low_vid_lower_gpio_cntl & ~0x400));
433 	write32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL,
434 		(medium_vid_lower_gpio_cntl & ~0x400));
435 	write32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL,
436 		(high_vid_lower_gpio_cntl & ~0x400));
437 	write32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL,
438 		(ctxsw_vid_lower_gpio_cntl & ~0x400));
439 	write32(info.registers + R600_LOWER_GPIO_ENABLE,
440 		(lower_gpio_enable | 0x400));
441 
442 	// try to grab the bios via PCI ROM bar
443 	// Enable ROM decoding for PCI BAR rom
444 	uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
445 	pciConfig |= PCI_rom_enable;
446 	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
447 
448 	uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
449 	if (flags & PCI_rom_enable)
450 		TRACE("%s: PCI ROM decode enabled\n", __func__);
451 
452 	uint32 romBase = info.pci->u.h0.rom_base;
453 	uint32 romSize = info.pci->u.h0.rom_size;
454 
455 	status_t result = B_OK;
456 	if (romBase == 0 || romSize == 0) {
457 		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
458 		result = B_ERROR;
459 	} else {
460 		result = mapAtomBIOS(info, romBase, romSize);
461 	}
462 
463 	if (result == B_OK) {
464 		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
465 			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
466 		info.shared_info->rom_phys = romBase;
467 		info.shared_info->rom_size = romSize;
468 	}
469 
470 	// Disable ROM decoding
471 	pciConfig &= ~PCI_rom_enable;
472 	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
473 
474 	// restore regs
475 	write32(info.registers + RADEON_VIPH_CONTROL, viph_control);
476 	write32(info.registers + R600_BUS_CNTL, bus_cntl);
477 	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
478 	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
479 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
480 	write32(info.registers + R600_ROM_CNTL, rom_cntl);
481 	write32(info.registers + R600_GENERAL_PWRMGT, general_pwrmgt);
482 	write32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL,
483 		low_vid_lower_gpio_cntl);
484 	write32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL,
485 		medium_vid_lower_gpio_cntl);
486 	write32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL,
487 		high_vid_lower_gpio_cntl);
488 	write32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL,
489 		ctxsw_vid_lower_gpio_cntl);
490 	write32(info.registers + R600_LOWER_GPIO_ENABLE, lower_gpio_enable);
491 
492 	return result;
493 }
494 
495 
496 static status_t
497 radeon_hd_getbios_avivo(radeon_info &info)
498 {
499 	TRACE("card(%ld): %s: called\n", info.id, __func__);
500 	uint32 sepromControl = read32(info.registers + RADEON_SEPROM_CNTL1);
501 	uint32 viphControl = read32(info.registers + RADEON_VIPH_CONTROL);
502 	uint32 busControl = read32(info.registers + RV370_BUS_CNTL);
503 	uint32 d1vgaControl = read32(info.registers + AVIVO_D1VGA_CONTROL);
504 	uint32 d2vgaControl = read32(info.registers + AVIVO_D2VGA_CONTROL);
505 	uint32 vgaRenderControl
506 		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
507 	uint32 gpioPadA = read32(info.registers + RADEON_GPIOPAD_A);
508 	uint32 gpioPadEN = read32(info.registers + RADEON_GPIOPAD_EN);
509 	uint32 gpioPadMask = read32(info.registers + RADEON_GPIOPAD_MASK);
510 
511 	write32(info.registers + RADEON_SEPROM_CNTL1,
512 		((sepromControl & ~RADEON_SCK_PRESCALE_MASK)
513 		| (0xc << RADEON_SCK_PRESCALE_SHIFT)));
514 	write32(info.registers + RADEON_GPIOPAD_A, 0);
515 	write32(info.registers + RADEON_GPIOPAD_EN, 0);
516 	write32(info.registers + RADEON_GPIOPAD_MASK, 0);
517 
518 	// disable VIP
519 	write32(info.registers + RADEON_VIPH_CONTROL,
520 		(viphControl & ~RADEON_VIPH_EN));
521 
522 	// enable the ROM
523 	write32(info.registers + RV370_BUS_CNTL,
524 		(busControl & ~RV370_BUS_BIOS_DIS_ROM));
525 
526 	// disable VGA
527 	write32(info.registers + AVIVO_D1VGA_CONTROL,
528 		(d1vgaControl & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
529 		| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
530 	write32(info.registers + AVIVO_D2VGA_CONTROL,
531 		(d2vgaControl & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
532 		| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
533 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
534 		(vgaRenderControl & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
535 
536 	uint32 romBase = info.pci->u.h0.rom_base;
537 	uint32 romSize = info.pci->u.h0.rom_size;
538 
539 	status_t result = B_OK;
540 	if (romBase == 0 || romSize == 0) {
541 		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
542 		result = B_ERROR;
543 	} else {
544 		result = mapAtomBIOS(info, romBase, romSize);
545 	}
546 
547 	if (result == B_OK) {
548 		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
549 			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
550 		info.shared_info->rom_phys = romBase;
551 		info.shared_info->rom_size = romSize;
552 	}
553 
554 	// restore registers
555 	write32(info.registers + RADEON_SEPROM_CNTL1, sepromControl);
556 	write32(info.registers + RADEON_VIPH_CONTROL, viphControl);
557 	write32(info.registers + RV370_BUS_CNTL, busControl);
558 	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vgaControl);
559 	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vgaControl);
560 	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vgaRenderControl);
561 	write32(info.registers + RADEON_GPIOPAD_A, gpioPadA);
562 	write32(info.registers + RADEON_GPIOPAD_EN, gpioPadEN);
563 	write32(info.registers + RADEON_GPIOPAD_MASK, gpioPadMask);
564 
565 	return result;
566 }
567 
568 
569 status_t
570 radeon_hd_init(radeon_info &info)
571 {
572 	TRACE("card(%ld): %s: called\n", info.id, __func__);
573 
574 	ERROR("%s: card(%ld): "
575 		"Radeon %s 1002:%" B_PRIX32 "\n", __func__, info.id,
576 		radeon_chip_name[info.chipsetID], info.pciID);
577 
578 	// *** Map shared info
579 	AreaKeeper sharedCreator;
580 	info.shared_area = sharedCreator.Create("radeon hd shared info",
581 		(void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
582 		ROUND_TO_PAGE_SIZE(sizeof(radeon_shared_info)), B_FULL_LOCK, 0);
583 	if (info.shared_area < B_OK) {
584 		ERROR("%s: card (%ld): couldn't map shared area!\n",
585 			__func__, info.id);
586 		return info.shared_area;
587 	}
588 
589 	memset((void*)info.shared_info, 0, sizeof(radeon_shared_info));
590 	sharedCreator.Detach();
591 
592 	// *** Map Memory mapped IO
593 	AreaKeeper mmioMapper;
594 	info.registers_area = mmioMapper.Map("radeon hd mmio",
595 		(void*)info.pci->u.h0.base_registers[PCI_BAR_MMIO],
596 		info.pci->u.h0.base_register_sizes[PCI_BAR_MMIO],
597 		B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
598 		(void**)&info.registers);
599 	if (mmioMapper.InitCheck() < B_OK) {
600 		ERROR("%s: card (%ld): couldn't map memory I/O!\n",
601 			__func__, info.id);
602 		return info.registers_area;
603 	}
604 	mmioMapper.Detach();
605 
606 	// *** Populate frame buffer information
607 	if (info.chipsetID >= RADEON_CEDAR) {
608 		if ((info.chipsetFlags & CHIP_APU) != 0
609 			|| (info.chipsetFlags & CHIP_IGP) != 0) {
610 			// Evergreen+ fusion in bytes
611 			info.shared_info->graphics_memory_size
612 				= read32(info.registers + CONFIG_MEMSIZE) / 1024;
613 		} else {
614 			// Evergreen+ has memory stored in MB
615 			info.shared_info->graphics_memory_size
616 				= read32(info.registers + CONFIG_MEMSIZE) * 1024;
617 		}
618 	} else if (info.chipsetID >= RADEON_R600) {
619 		// R600-R700 has memory stored in bytes
620 		info.shared_info->graphics_memory_size
621 			= read32(info.registers + CONFIG_MEMSIZE) / 1024;
622 	} else {
623 		// R420 - R600 cards
624 		// older cards use RADEON_CONFIG_MEMSIZE vs CONFIG_MEMSIZE
625 		if ((info.chipsetFlags & CHIP_IGP) != 0) {
626 			// NB_TOM holds amount of ram stolen for GPU
627 			uint32 tom = read32(info.registers + RADEON_NB_TOM);
628 			info.shared_info->graphics_memory_size
629 				= (((tom >> 16) - (tom & 0xffff) + 1) << 16);
630 			write32(info.registers + RADEON_CONFIG_MEMSIZE,
631 				info.shared_info->graphics_memory_size);
632 		} else {
633 			info.shared_info->graphics_memory_size
634 				= read32(info.registers + RADEON_CONFIG_MEMSIZE);
635 			if (info.shared_info->graphics_memory_size == 0) {
636 				// known bug if video memory == 8MB
637 				info.shared_info->graphics_memory_size = 8192;
638 				write32(info.registers + RADEON_CONFIG_MEMSIZE,
639 					info.shared_info->graphics_memory_size * 1024);
640 			}
641 		}
642 	}
643 
644 	uint32 barSize = info.pci->u.h0.base_register_sizes[PCI_BAR_FB] / 1024;
645 
646 	// if graphics memory is larger then PCI bar, just map bar
647 	if (info.shared_info->graphics_memory_size == 0) {
648 		// we can recover as we have PCI FB bar, but this should be fixed
649 		ERROR("%s: Error: found 0MB video ram, using PCI bar size...\n",
650 			__func__);
651 		info.shared_info->frame_buffer_size = barSize;
652 	} else if (info.shared_info->graphics_memory_size > barSize) {
653 		TRACE("%s: shrinking frame buffer to PCI bar...\n",
654 			__func__);
655 		info.shared_info->frame_buffer_size = barSize;
656 	} else {
657 		info.shared_info->frame_buffer_size
658 			= info.shared_info->graphics_memory_size;
659 	}
660 
661 	TRACE("%s: mapping a frame buffer of %" B_PRIu32 "MB out of %" B_PRIu32
662 		"MB video ram\n", __func__, info.shared_info->frame_buffer_size / 1024,
663 		info.shared_info->graphics_memory_size / 1024);
664 
665 	// *** Framebuffer mapping
666 	AreaKeeper frambufferMapper;
667 	info.framebuffer_area = frambufferMapper.Map("radeon hd frame buffer",
668 		(void*)info.pci->u.h0.base_registers[PCI_BAR_FB],
669 		info.shared_info->frame_buffer_size * 1024,
670 		B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
671 		(void**)&info.shared_info->frame_buffer);
672 	if (frambufferMapper.InitCheck() < B_OK) {
673 		ERROR("%s: card(%ld): couldn't map frame buffer!\n",
674 			__func__, info.id);
675 		return info.framebuffer_area;
676 	}
677 
678 	// Turn on write combining for the frame buffer area
679 	vm_set_area_memory_type(info.framebuffer_area,
680 		info.pci->u.h0.base_registers[PCI_BAR_FB], B_MTR_WC);
681 
682 	frambufferMapper.Detach();
683 
684 	info.shared_info->frame_buffer_area = info.framebuffer_area;
685 	info.shared_info->frame_buffer_phys
686 		= info.pci->u.h0.base_registers[PCI_BAR_FB];
687 
688 	// Pass common information to accelerant
689 	info.shared_info->deviceIndex = info.id;
690 	info.shared_info->pciID = info.pciID;
691 	info.shared_info->chipsetID = info.chipsetID;
692 	info.shared_info->chipsetFlags = info.chipsetFlags;
693 	info.shared_info->dceMajor = info.dceMajor;
694 	info.shared_info->dceMinor = info.dceMinor;
695 	info.shared_info->registers_area = info.registers_area;
696 	strcpy(info.shared_info->deviceName, info.deviceName);
697 	strcpy(info.shared_info->chipsetName,
698 		radeon_chip_name[info.chipsetID]);
699 
700 	// *** AtomBIOS mapping
701 	// First we try an active bios read
702 	status_t biosStatus = radeon_hd_getbios(info);
703 
704 	if (biosStatus != B_OK) {
705 		// If the active read fails, we try a disabled read
706 		if (info.chipsetID >= RADEON_CAICOS)
707 			biosStatus = radeon_hd_getbios_ni(info);
708 		else if (info.chipsetID >= RADEON_RV770)
709 			biosStatus = radeon_hd_getbios_r700(info);
710 		else if (info.chipsetID >= RADEON_R600)
711 			biosStatus = radeon_hd_getbios_r600(info);
712 		else if (info.chipsetID >= RADEON_RS600)
713 			biosStatus = radeon_hd_getbios_avivo(info);
714 		// else legacy_read_disabled_bios
715 	}
716 
717 	if (biosStatus != B_OK) {
718 		// *** very last resort, shadow bios VGA rom
719 		ERROR("%s: Can't find an AtomBIOS rom! Trying shadow rom...\n",
720 			__func__);
721 
722 		// This works as long as the primary card is what this driver
723 		// is loaded for. Multiple cards may pose the risk of loading
724 		// the wrong AtomBIOS for the wrong card.
725 
726 		uint32 romBase = 0xC0000;
727 		uint32 romSize = 128 * 1024;
728 			// what happens when AtomBIOS goes over 128Kb?
729 			// A Radeon HD 6990 has a 128Kb AtomBIOS
730 
731 		if (mapAtomBIOS(info, romBase, romSize) == B_OK) {
732 			ERROR("%s: Found AtomBIOS at VGA shadow rom\n", __func__);
733 			// Whew!
734 			info.shared_info->rom_phys = romBase;
735 			info.shared_info->rom_size = romSize;
736 			biosStatus = B_OK;
737 		}
738 	}
739 
740 	// Check if a valid AtomBIOS image was found.
741 	if (biosStatus != B_OK) {
742 		ERROR("%s: card (%ld): couldn't find AtomBIOS rom!\n",
743 			__func__, info.id);
744 		ERROR("%s: card (%ld): exiting. Please open a bug ticket"
745 			" at haiku-os.org with your /var/log/syslog\n",
746 			__func__, info.id);
747 		// Fallback to VESA (more likely crash app_server)
748 		return B_ERROR;
749 	}
750 
751 	info.shared_info->has_rom = (biosStatus == B_OK) ? true : false;
752 	info.shared_info->rom_area = (biosStatus == B_OK) ? info.rom_area : -1;
753 
754 	// *** Pull active monitor VESA EDID from boot loader
755 	edid1_info* edidInfo
756 		= (edid1_info*)get_boot_item(EDID_BOOT_INFO, NULL);
757 
758 	if (edidInfo != NULL) {
759 		TRACE("card(%ld): %s found VESA EDID information.\n", info.id,
760 			__func__);
761 		info.shared_info->has_edid = true;
762 		memcpy(&info.shared_info->edid_info, edidInfo, sizeof(edid1_info));
763 	} else {
764 		TRACE("card(%ld): %s didn't find VESA EDID modes.\n", info.id,
765 			__func__);
766 		info.shared_info->has_edid = false;
767 	}
768 
769 	TRACE("card(%ld): %s completed successfully!\n", info.id, __func__);
770 
771 	TRACE("card(%ld): GPU thermal status: %" B_PRId32 "C\n", info.id,
772 		radeon_thermal_query(info) / 1000);
773 
774 	return B_OK;
775 }
776 
777 
778 void
779 radeon_hd_uninit(radeon_info &info)
780 {
781 	TRACE("card(%ld): %s called\n", info.id, __func__);
782 
783 	delete_area(info.shared_area);
784 	delete_area(info.registers_area);
785 	delete_area(info.framebuffer_area);
786 	delete_area(info.rom_area);
787 }
788 
789