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