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