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