xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon_hd/radeon_hd.cpp (revision db6fcb750a1afb5fdc752322972adf6044d3b4c4)
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 //	#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 	// *** Map shared info
542 	AreaKeeper sharedCreator;
543 	info.shared_area = sharedCreator.Create("radeon hd shared info",
544 		(void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
545 		ROUND_TO_PAGE_SIZE(sizeof(radeon_shared_info)), B_FULL_LOCK,
546 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA);
547 	if (info.shared_area < B_OK) {
548 		ERROR("%s: card (%" B_PRId32 "): couldn't map shared area!\n",
549 			__func__, info.id);
550 		return info.shared_area;
551 	}
552 
553 	memset((void*)info.shared_info, 0, sizeof(radeon_shared_info));
554 	sharedCreator.Detach();
555 
556 	// *** Map Memory mapped IO
557 	AreaKeeper mmioMapper;
558 	const uint32 pciBarMmio = radeon_hd_pci_bar_mmio(info.chipsetID);
559 	info.registers_area = mmioMapper.Map("radeon hd mmio",
560 		info.pci->u.h0.base_registers[pciBarMmio],
561 		info.pci->u.h0.base_register_sizes[pciBarMmio],
562 		B_ANY_KERNEL_ADDRESS,
563 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA,
564 		(void**)&info.registers);
565 	if (mmioMapper.InitCheck() < B_OK) {
566 		ERROR("%s: card (%" B_PRId32 "): couldn't map memory I/O!\n",
567 			__func__, info.id);
568 		return info.registers_area;
569 	}
570 	mmioMapper.Detach();
571 
572 	// *** Populate frame buffer information
573 	if (info.chipsetID >= RADEON_CEDAR) {
574 		if ((info.chipsetFlags & CHIP_APU) != 0
575 			|| (info.chipsetFlags & CHIP_IGP) != 0) {
576 			// Evergreen+ fusion in bytes
577 			info.shared_info->graphics_memory_size
578 				= read32(info.registers + CONFIG_MEMSIZE) / 1024;
579 		} else {
580 			// Evergreen+ has memory stored in MB
581 			info.shared_info->graphics_memory_size
582 				= read32(info.registers + CONFIG_MEMSIZE) * 1024;
583 		}
584 	} else if (info.chipsetID >= RADEON_R600) {
585 		// R600-R700 has memory stored in bytes
586 		info.shared_info->graphics_memory_size
587 			= read32(info.registers + CONFIG_MEMSIZE) / 1024;
588 	} else {
589 		// R420 - R600 cards
590 		// older cards use RADEON_CONFIG_MEMSIZE vs CONFIG_MEMSIZE
591 		if ((info.chipsetFlags & CHIP_IGP) != 0) {
592 			// NB_TOM holds amount of ram stolen for GPU
593 			uint32 tom = read32(info.registers + RADEON_NB_TOM);
594 			info.shared_info->graphics_memory_size
595 				= (((tom >> 16) - (tom & 0xffff) + 1) << 16);
596 			write32(info.registers + RADEON_CONFIG_MEMSIZE,
597 				info.shared_info->graphics_memory_size);
598 		} else {
599 			info.shared_info->graphics_memory_size
600 				= read32(info.registers + RADEON_CONFIG_MEMSIZE);
601 			if (info.shared_info->graphics_memory_size == 0) {
602 				// known bug if video memory == 8MB
603 				info.shared_info->graphics_memory_size = 8192;
604 				write32(info.registers + RADEON_CONFIG_MEMSIZE,
605 					info.shared_info->graphics_memory_size * 1024);
606 			}
607 		}
608 	}
609 
610 	uint32 barSize = info.pci->u.h0.base_register_sizes[PCI_BAR_FB] / 1024;
611 
612 	// if graphics memory is larger then PCI bar, just map bar
613 	if (info.shared_info->graphics_memory_size == 0) {
614 		// we can recover as we have PCI FB bar, but this should be fixed
615 		ERROR("%s: Error: found 0MB video ram, using PCI bar size...\n",
616 			__func__);
617 		info.shared_info->frame_buffer_size = barSize;
618 	} else if (info.shared_info->graphics_memory_size > barSize) {
619 		TRACE("%s: shrinking frame buffer to PCI bar...\n",
620 			__func__);
621 		info.shared_info->frame_buffer_size = barSize;
622 	} else {
623 		info.shared_info->frame_buffer_size
624 			= info.shared_info->graphics_memory_size;
625 	}
626 
627 	TRACE("%s: mapping a frame buffer of %" B_PRIu32 "MB out of %" B_PRIu32
628 		"MB video ram\n", __func__, info.shared_info->frame_buffer_size / 1024,
629 		info.shared_info->graphics_memory_size / 1024);
630 
631 	// *** Framebuffer mapping
632 	AreaKeeper frambufferMapper;
633 	info.framebuffer_area = frambufferMapper.Map("radeon hd frame buffer",
634 		info.pci->u.h0.base_registers[PCI_BAR_FB],
635 		info.shared_info->frame_buffer_size * 1024,
636 		B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
637 		(void**)&info.shared_info->frame_buffer);
638 	if (frambufferMapper.InitCheck() < B_OK) {
639 		ERROR("%s: card(%" B_PRId32 "): couldn't map frame buffer!\n",
640 			__func__, info.id);
641 		return info.framebuffer_area;
642 	}
643 
644 	// Turn on write combining for the frame buffer area
645 	vm_set_area_memory_type(info.framebuffer_area,
646 		info.pci->u.h0.base_registers[PCI_BAR_FB], B_MTR_WC);
647 
648 	frambufferMapper.Detach();
649 
650 	info.shared_info->frame_buffer_area = info.framebuffer_area;
651 	info.shared_info->frame_buffer_phys
652 		= info.pci->u.h0.base_registers[PCI_BAR_FB];
653 
654 	// Pass common information to accelerant
655 	info.shared_info->deviceIndex = info.id;
656 	info.shared_info->pciID = info.pciID;
657 	info.shared_info->pciRev = info.pci->revision;
658 	info.shared_info->chipsetID = info.chipsetID;
659 	info.shared_info->chipsetFlags = info.chipsetFlags;
660 	info.shared_info->dceMajor = info.dceMajor;
661 	info.shared_info->dceMinor = info.dceMinor;
662 	info.shared_info->registers_area = info.registers_area;
663 	strlcpy(info.shared_info->deviceName,
664 		info.deviceName, MAX_NAME_LENGTH);
665 	strlcpy(info.shared_info->chipsetName,
666 		radeon_chip_name[info.chipsetID], MAX_NAME_LENGTH);
667 
668 	// *** AtomBIOS mapping
669 	// First we try an active bios read
670 	status_t biosStatus = radeon_hd_getbios(info);
671 
672 	if (biosStatus != B_OK) {
673 		// If the active read fails, we try a disabled read
674 		if (info.chipsetID >= RADEON_CAICOS)
675 			biosStatus = radeon_hd_getbios_ni(info);
676 		else if (info.chipsetID >= RADEON_RV770)
677 			biosStatus = radeon_hd_getbios_r700(info);
678 		else if (info.chipsetID >= RADEON_R600)
679 			biosStatus = radeon_hd_getbios_r600(info);
680 		else if (info.chipsetID >= RADEON_RS600)
681 			biosStatus = radeon_hd_getbios_avivo(info);
682 		// else legacy_read_disabled_bios
683 	}
684 
685 	if (biosStatus != B_OK) {
686 		// *** very last resort, shadow bios VGA rom
687 		ERROR("%s: Can't find an AtomBIOS rom! Trying shadow rom...\n",
688 			__func__);
689 
690 		// This works as long as the primary card is what this driver
691 		// is loaded for. Multiple cards may pose the risk of loading
692 		// the wrong AtomBIOS for the wrong card.
693 
694 		uint32 romBase = 0xC0000;
695 		uint32 romSize = 128 * 1024;
696 			// what happens when AtomBIOS goes over 128Kb?
697 			// A Radeon HD 6990 has a 128Kb AtomBIOS
698 
699 		if (mapAtomBIOS(info, romBase, romSize) == B_OK) {
700 			ERROR("%s: Found AtomBIOS at VGA shadow rom\n", __func__);
701 			// Whew!
702 			info.shared_info->rom_phys = romBase;
703 			info.shared_info->rom_size = romSize;
704 			biosStatus = B_OK;
705 		}
706 	}
707 
708 	// Check if a valid AtomBIOS image was found.
709 	if (biosStatus != B_OK) {
710 		ERROR("%s: card (%" B_PRId32 "): couldn't find AtomBIOS rom!\n",
711 			__func__, info.id);
712 		ERROR("%s: card (%" B_PRId32 "): exiting. Please open a bug ticket"
713 			" at haiku-os.org with your /var/log/syslog\n",
714 			__func__, info.id);
715 		// Fallback to VESA (more likely crash app_server)
716 		return B_ERROR;
717 	}
718 
719 	info.shared_info->has_rom = (biosStatus == B_OK) ? true : false;
720 	info.shared_info->rom_area = (biosStatus == B_OK) ? info.rom_area : -1;
721 
722 	// *** Pull active monitor VESA EDID from boot loader
723 	edid1_info* edidInfo
724 		= (edid1_info*)get_boot_item(EDID_BOOT_INFO, NULL);
725 
726 	if (edidInfo != NULL) {
727 		TRACE("card(%" B_PRId32 "): %s found VESA EDID information.\n",
728 			info.id, __func__);
729 		info.shared_info->has_edid = true;
730 		memcpy(&info.shared_info->edid_info, edidInfo, sizeof(edid1_info));
731 	} else {
732 		TRACE("card(%" B_PRId32 "): %s didn't find VESA EDID modes.\n",
733 			info.id, __func__);
734 		info.shared_info->has_edid = false;
735 	}
736 
737 	TRACE("card(%" B_PRId32 "): %s completed successfully!\n",
738 		info.id, __func__);
739 
740 	TRACE("card(%" B_PRId32 "): GPU thermal status: %" B_PRId32 "C\n",
741 		info.id, radeon_thermal_query(info) / 1000);
742 
743 	return B_OK;
744 }
745 
746 
747 void
748 radeon_hd_uninit(radeon_info &info)
749 {
750 	TRACE("card(%" B_PRId32 "): %s called\n", info.id, __func__);
751 
752 	delete_area(info.shared_area);
753 	delete_area(info.registers_area);
754 	delete_area(info.framebuffer_area);
755 	delete_area(info.rom_area);
756 }
757 
758