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