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
46static status_t
47mapAtomBIOSACPI(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
130static size_t
131radeon_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
156static status_t
157mapAtomBIOS(radeon_info &info, phys_addr_t romBase, uint32 romSize,
158	bool findROMlength = false)
159{
160	TRACE("%s: seeking AtomBIOS @ 0x%" B_PRIXPHYSADDR " [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_PRIXPHYSADDR
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_PRIXPHYSADDR " (%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_PRIXPHYSADDR "(%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
241static status_t
242radeon_hd_getbios(radeon_info &info)
243{
244	TRACE("card(%" B_PRId32 "): %s: called\n", info.id, __func__);
245
246	phys_addr_t 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				if ((info.pci->u.h0.base_register_flags[PCI_BAR_FB] & PCI_address_type)
265					== PCI_address_type_64) {
266					romBase |= (uint64)info.pci->u.h0.base_registers[PCI_BAR_FB + 1] << 32;
267				}
268				romSize = 256 * 1024;
269
270				if (romBase == 0 || romSize == 0) {
271					ERROR("%s: No base found at PCI FB BAR\n", __func__);
272				} else {
273					mapResult = mapAtomBIOS(info, romBase, romSize);
274				}
275				break;
276			case 2:
277			{
278				// *** PCI ROM BAR
279				// Enable ROM decoding for PCI BAR rom
280				uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
281				pciConfig |= PCI_rom_enable;
282				set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
283
284				uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
285				if ((flags & PCI_rom_enable) != 0)
286					TRACE("%s: PCI ROM decode enabled\n", __func__);
287
288				romBase = info.pci->u.h0.rom_base;
289				romSize = info.pci->u.h0.rom_size;
290
291				if (romBase == 0 || romSize == 0) {
292					ERROR("%s: No base found at PCI ROM BAR\n", __func__);
293				} else {
294					mapResult = mapAtomBIOS(info, romBase, romSize, true);
295				}
296
297				// Disable ROM decoding
298				pciConfig &= ~PCI_rom_enable;
299				set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
300				break;
301			}
302		}
303
304		if (mapResult == B_OK) {
305			ERROR("%s: AtomBIOS found using active method %" B_PRIu32
306				" at 0x%" B_PRIXPHYSADDR "\n", __func__, romMethod, romBase);
307			break;
308		} else {
309			ERROR("%s: AtomBIOS not found using active method %" B_PRIu32
310				" at 0x%" B_PRIXPHYSADDR "\n", __func__, romMethod, romBase);
311		}
312	}
313
314	if (mapResult == B_OK) {
315		info.shared_info->rom_phys = romBase;
316		info.shared_info->rom_size = romSize;
317	} else
318		ERROR("%s: Active AtomBIOS search failed.\n", __func__);
319
320	return mapResult;
321}
322
323
324static status_t
325radeon_hd_getbios_ni(radeon_info &info)
326{
327	TRACE("card(%" B_PRId32 "): %s: called\n", info.id, __func__);
328	uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
329	uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
330	uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
331	uint32 vga_render_control
332		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
333	uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
334
335	// enable the rom
336	write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
337	// disable VGA mode
338	write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
339		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
340			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
341	write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
342		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
343			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
344	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
345		(vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
346
347	write32(info.registers + R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
348
349	// try to grab the bios via PCI ROM bar
350	// Enable ROM decoding for PCI BAR rom
351	uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
352	pciConfig |= PCI_rom_enable;
353	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
354
355	uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
356	if (flags & PCI_rom_enable)
357		TRACE("%s: PCI ROM decode enabled\n", __func__);
358
359	uint32 romBase = info.pci->u.h0.rom_base;
360	uint32 romSize = info.pci->u.h0.rom_size;
361
362	status_t result = B_OK;
363	if (romBase == 0 || romSize == 0) {
364		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
365		result = B_ERROR;
366	} else {
367		result = mapAtomBIOS(info, romBase, romSize, true);
368	}
369
370	if (result == B_OK) {
371		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
372			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
373		info.shared_info->rom_phys = romBase;
374		info.shared_info->rom_size = romSize;
375	}
376
377	// Disable ROM decoding
378	pciConfig &= ~PCI_rom_enable;
379	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
380
381	// restore regs
382	write32(info.registers + R600_BUS_CNTL, bus_cntl);
383	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
384	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
385	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
386	write32(info.registers + R600_ROM_CNTL, rom_cntl);
387
388	return result;
389}
390
391
392static status_t
393radeon_hd_getbios_r700(radeon_info &info)
394{
395	TRACE("card(%" B_PRId32 "): %s: called\n", info.id, __func__);
396	uint32 viph_control = read32(info.registers + RADEON_VIPH_CONTROL);
397	uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
398	uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
399	uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
400	uint32 vga_render_control
401		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
402	uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
403
404	// disable VIP
405	write32(info.registers + RADEON_VIPH_CONTROL,
406		(viph_control & ~RADEON_VIPH_EN));
407	// enable the rom
408	write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
409	// disable VGA mode
410	write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
411		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
412			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
413	write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
414		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
415			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
416	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
417		(vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
418
419	write32(info.registers + R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
420
421	// try to grab the bios via PCI ROM bar
422	// Enable ROM decoding for PCI BAR rom
423	uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
424	pciConfig |= PCI_rom_enable;
425	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
426
427	uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
428	if (flags & PCI_rom_enable)
429		TRACE("%s: PCI ROM decode enabled\n", __func__);
430
431	uint32 romBase = info.pci->u.h0.rom_base;
432	uint32 romSize = info.pci->u.h0.rom_size;
433
434	status_t result = B_OK;
435	if (romBase == 0 || romSize == 0) {
436		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
437		result = B_ERROR;
438	} else {
439		result = mapAtomBIOS(info, romBase, romSize);
440	}
441
442	if (result == B_OK) {
443		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
444			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
445		info.shared_info->rom_phys = romBase;
446		info.shared_info->rom_size = romSize;
447	}
448
449	// Disable ROM decoding
450	pciConfig &= ~PCI_rom_enable;
451	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
452
453	// restore regs
454	write32(info.registers + RADEON_VIPH_CONTROL, viph_control);
455	write32(info.registers + R600_BUS_CNTL, bus_cntl);
456	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
457	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
458	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
459	write32(info.registers + R600_ROM_CNTL, rom_cntl);
460
461	return result;
462}
463
464
465static status_t
466radeon_hd_getbios_r600(radeon_info &info)
467{
468	TRACE("card(%" B_PRId32 "): %s: called\n", info.id, __func__);
469	uint32 viph_control = read32(info.registers + RADEON_VIPH_CONTROL);
470	uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
471	uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
472	uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
473	uint32 vga_render_control
474		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
475	uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
476	uint32 general_pwrmgt = read32(info.registers + R600_GENERAL_PWRMGT);
477	uint32 low_vid_lower_gpio_cntl
478		= read32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL);
479	uint32 medium_vid_lower_gpio_cntl
480		= read32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL);
481	uint32 high_vid_lower_gpio_cntl
482		= read32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL);
483	uint32 ctxsw_vid_lower_gpio_cntl
484		= read32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL);
485	uint32 lower_gpio_enable
486		= read32(info.registers + R600_LOWER_GPIO_ENABLE);
487
488	// disable VIP
489	write32(info.registers + RADEON_VIPH_CONTROL,
490		(viph_control & ~RADEON_VIPH_EN));
491	// enable the rom
492	write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
493	// disable VGA mode
494	write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
495		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
496			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
497	write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
498		& ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
499			| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
500	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
501		(vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
502
503	write32(info.registers + R600_ROM_CNTL,
504		((rom_cntl & ~R600_SCK_PRESCALE_CRYSTAL_CLK_MASK)
505		| (1 << R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT) | R600_SCK_OVERWRITE));
506
507	write32(info.registers + R600_GENERAL_PWRMGT,
508		(general_pwrmgt & ~R600_OPEN_DRAIN_PADS));
509	write32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL,
510		(low_vid_lower_gpio_cntl & ~0x400));
511	write32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL,
512		(medium_vid_lower_gpio_cntl & ~0x400));
513	write32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL,
514		(high_vid_lower_gpio_cntl & ~0x400));
515	write32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL,
516		(ctxsw_vid_lower_gpio_cntl & ~0x400));
517	write32(info.registers + R600_LOWER_GPIO_ENABLE,
518		(lower_gpio_enable | 0x400));
519
520	// try to grab the bios via PCI ROM bar
521	// Enable ROM decoding for PCI BAR rom
522	uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
523	pciConfig |= PCI_rom_enable;
524	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
525
526	uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
527	if (flags & PCI_rom_enable)
528		TRACE("%s: PCI ROM decode enabled\n", __func__);
529
530	uint32 romBase = info.pci->u.h0.rom_base;
531	uint32 romSize = info.pci->u.h0.rom_size;
532
533	status_t result = B_OK;
534	if (romBase == 0 || romSize == 0) {
535		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
536		result = B_ERROR;
537	} else {
538		result = mapAtomBIOS(info, romBase, romSize);
539	}
540
541	if (result == B_OK) {
542		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
543			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
544		info.shared_info->rom_phys = romBase;
545		info.shared_info->rom_size = romSize;
546	}
547
548	// Disable ROM decoding
549	pciConfig &= ~PCI_rom_enable;
550	set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
551
552	// restore regs
553	write32(info.registers + RADEON_VIPH_CONTROL, viph_control);
554	write32(info.registers + R600_BUS_CNTL, bus_cntl);
555	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
556	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
557	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
558	write32(info.registers + R600_ROM_CNTL, rom_cntl);
559	write32(info.registers + R600_GENERAL_PWRMGT, general_pwrmgt);
560	write32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL,
561		low_vid_lower_gpio_cntl);
562	write32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL,
563		medium_vid_lower_gpio_cntl);
564	write32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL,
565		high_vid_lower_gpio_cntl);
566	write32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL,
567		ctxsw_vid_lower_gpio_cntl);
568	write32(info.registers + R600_LOWER_GPIO_ENABLE, lower_gpio_enable);
569
570	return result;
571}
572
573
574static status_t
575radeon_hd_getbios_avivo(radeon_info &info)
576{
577	TRACE("card(%" B_PRId32 "): %s: called\n", info.id, __func__);
578	uint32 sepromControl = read32(info.registers + RADEON_SEPROM_CNTL1);
579	uint32 viphControl = read32(info.registers + RADEON_VIPH_CONTROL);
580	uint32 busControl = read32(info.registers + RV370_BUS_CNTL);
581	uint32 d1vgaControl = read32(info.registers + AVIVO_D1VGA_CONTROL);
582	uint32 d2vgaControl = read32(info.registers + AVIVO_D2VGA_CONTROL);
583	uint32 vgaRenderControl
584		= read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
585	uint32 gpioPadA = read32(info.registers + RADEON_GPIOPAD_A);
586	uint32 gpioPadEN = read32(info.registers + RADEON_GPIOPAD_EN);
587	uint32 gpioPadMask = read32(info.registers + RADEON_GPIOPAD_MASK);
588
589	write32(info.registers + RADEON_SEPROM_CNTL1,
590		((sepromControl & ~RADEON_SCK_PRESCALE_MASK)
591		| (0xc << RADEON_SCK_PRESCALE_SHIFT)));
592	write32(info.registers + RADEON_GPIOPAD_A, 0);
593	write32(info.registers + RADEON_GPIOPAD_EN, 0);
594	write32(info.registers + RADEON_GPIOPAD_MASK, 0);
595
596	// disable VIP
597	write32(info.registers + RADEON_VIPH_CONTROL,
598		(viphControl & ~RADEON_VIPH_EN));
599
600	// enable the ROM
601	write32(info.registers + RV370_BUS_CNTL,
602		(busControl & ~RV370_BUS_BIOS_DIS_ROM));
603
604	// disable VGA
605	write32(info.registers + AVIVO_D1VGA_CONTROL,
606		(d1vgaControl & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
607		| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
608	write32(info.registers + AVIVO_D2VGA_CONTROL,
609		(d2vgaControl & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
610		| AVIVO_DVGA_CONTROL_TIMING_SELECT)));
611	write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
612		(vgaRenderControl & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
613
614	uint32 romBase = info.pci->u.h0.rom_base;
615	uint32 romSize = info.pci->u.h0.rom_size;
616
617	status_t result = B_OK;
618	if (romBase == 0 || romSize == 0) {
619		ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
620		result = B_ERROR;
621	} else {
622		result = mapAtomBIOS(info, romBase, romSize);
623	}
624
625	if (result == B_OK) {
626		ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
627			" [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
628		info.shared_info->rom_phys = romBase;
629		info.shared_info->rom_size = romSize;
630	}
631
632	// restore registers
633	write32(info.registers + RADEON_SEPROM_CNTL1, sepromControl);
634	write32(info.registers + RADEON_VIPH_CONTROL, viphControl);
635	write32(info.registers + RV370_BUS_CNTL, busControl);
636	write32(info.registers + AVIVO_D1VGA_CONTROL, d1vgaControl);
637	write32(info.registers + AVIVO_D2VGA_CONTROL, d2vgaControl);
638	write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vgaRenderControl);
639	write32(info.registers + RADEON_GPIOPAD_A, gpioPadA);
640	write32(info.registers + RADEON_GPIOPAD_EN, gpioPadEN);
641	write32(info.registers + RADEON_GPIOPAD_MASK, gpioPadMask);
642
643	return result;
644}
645
646
647static uint32
648radeon_hd_pci_bar_mmio(uint16 chipsetID)
649{
650	if (chipsetID < RADEON_BONAIRE)
651		return 2;
652	else
653		return 5;
654}
655
656
657status_t
658radeon_hd_init(radeon_info &info)
659{
660	TRACE("card(%" B_PRId32 "): %s: called\n", info.id, __func__);
661
662	ERROR("%s: card(%" B_PRId32 "): "
663		"Radeon %s 1002:%" B_PRIX32 "\n", __func__, info.id,
664		radeon_chip_name[info.chipsetID], info.pciID);
665
666	// Enable response in I/O, memory space. Enable bus mastering
667	uint32 pciConfig = get_pci_config(info.pci, PCI_command, 2);
668	pciConfig |= PCI_command_io | PCI_command_memory | PCI_command_master;
669	set_pci_config(info.pci, PCI_command, 2, pciConfig);
670
671	// *** Map shared info
672	AreaKeeper sharedCreator;
673	info.shared_area = sharedCreator.Create("radeon hd shared info",
674		(void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
675		ROUND_TO_PAGE_SIZE(sizeof(radeon_shared_info)), B_FULL_LOCK,
676		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA);
677	if (info.shared_area < B_OK) {
678		ERROR("%s: card (%" B_PRId32 "): couldn't map shared area!\n",
679			__func__, info.id);
680		return info.shared_area;
681	}
682
683	memset((void*)info.shared_info, 0, sizeof(radeon_shared_info));
684	sharedCreator.Detach();
685
686	// *** Map Memory mapped IO
687	const uint32 pciBarMmio = radeon_hd_pci_bar_mmio(info.chipsetID);
688	phys_addr_t addr = info.pci->u.h0.base_registers[pciBarMmio];
689	uint64 mmioSize = info.pci->u.h0.base_register_sizes[pciBarMmio];
690	if (pciBarMmio < 5
691		&& (info.pci->u.h0.base_register_flags[pciBarMmio] & PCI_address_type) == PCI_address_type_64) {
692		addr |= (uint64)info.pci->u.h0.base_registers[pciBarMmio + 1] << 32;
693		mmioSize |= (uint64)info.pci->u.h0.base_register_sizes[pciBarMmio + 1] << 32;
694	}
695
696	AreaKeeper mmioMapper;
697	info.registers_area = mmioMapper.Map("radeon hd mmio", addr, mmioSize,
698		B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA,
699		(void**)&info.registers);
700	if (mmioMapper.InitCheck() < B_OK) {
701		ERROR("%s: card (%" B_PRId32 "): couldn't map memory I/O!\n",
702			__func__, info.id);
703		return info.registers_area;
704	}
705	mmioMapper.Detach();
706
707	// *** Populate frame buffer information
708	if (info.chipsetID >= RADEON_TAHITI) {
709		// Tahiti+ has memory stored in MB
710		info.shared_info->graphics_memory_size
711			= read32(info.registers + CONFIG_MEMSIZE_TAHITI) * 1024;
712	} else if (info.chipsetID >= RADEON_CEDAR) {
713		switch (info.chipsetID) {
714			default:
715				// Evergreen+ has memory stored in MB
716				info.shared_info->graphics_memory_size
717					= read32(info.registers + CONFIG_MEMSIZE) * 1024;
718				break;
719			case RADEON_PALM:
720			case RADEON_SUMO:
721			case RADEON_SUMO2:
722				// Fusion in bytes
723				info.shared_info->graphics_memory_size
724					= read32(info.registers + CONFIG_MEMSIZE) / 1024;
725				break;
726		}
727	} else if (info.chipsetID >= RADEON_R600) {
728		// R600-R700 has memory stored in bytes
729		info.shared_info->graphics_memory_size
730			= read32(info.registers + CONFIG_MEMSIZE) / 1024;
731	} else {
732		// R420 - R600 cards
733		// older cards use RADEON_CONFIG_MEMSIZE vs CONFIG_MEMSIZE
734		if ((info.chipsetFlags & CHIP_IGP) != 0) {
735			// NB_TOM holds amount of ram stolen for GPU
736			uint32 tom = read32(info.registers + RADEON_NB_TOM);
737			info.shared_info->graphics_memory_size
738				= (((tom >> 16) - (tom & 0xffff) + 1) << 16);
739			write32(info.registers + RADEON_CONFIG_MEMSIZE,
740				info.shared_info->graphics_memory_size);
741		} else {
742			info.shared_info->graphics_memory_size
743				= read32(info.registers + RADEON_CONFIG_MEMSIZE);
744			if (info.shared_info->graphics_memory_size == 0) {
745				// known bug if video memory == 8MB
746				info.shared_info->graphics_memory_size = 8192;
747				write32(info.registers + RADEON_CONFIG_MEMSIZE,
748					info.shared_info->graphics_memory_size * 1024);
749			}
750		}
751	}
752
753	phys_addr_t fbAddr = info.pci->u.h0.base_registers[PCI_BAR_FB];
754	uint64 fbBarSize = info.pci->u.h0.base_register_sizes[PCI_BAR_FB];
755	if ((info.pci->u.h0.base_register_flags[PCI_BAR_FB] & PCI_address_type)
756			== PCI_address_type_64) {
757		fbAddr |= (uint64)info.pci->u.h0.base_registers[PCI_BAR_FB + 1] << 32;
758		fbBarSize |= (uint64)info.pci->u.h0.base_register_sizes[PCI_BAR_FB + 1] << 32;
759	}
760
761	// Make KiB
762	fbBarSize /= 1024;
763
764	// if graphics memory is larger then PCI bar, just map bar
765	if (info.shared_info->graphics_memory_size == 0) {
766		// we can recover as we have PCI FB bar, but this should be fixed
767		ERROR("%s: Error: found 0MB video ram, using PCI bar size...\n",
768			__func__);
769		info.shared_info->frame_buffer_size = fbBarSize;
770	} else if (info.shared_info->graphics_memory_size > fbBarSize) {
771		TRACE("%s: shrinking frame buffer to PCI bar...\n",
772			__func__);
773		info.shared_info->frame_buffer_size = fbBarSize;
774	} else {
775		info.shared_info->frame_buffer_size
776			= info.shared_info->graphics_memory_size;
777	}
778
779	if (info.shared_info->frame_buffer_size < 8192) {
780		ERROR("%s: Error: frame buffer is less than 8 MiB. I give up.\n",
781			__func__);
782		return B_ERROR;
783	}
784
785	TRACE("%s: mapping a frame buffer of %" B_PRIu32 "MB out of %" B_PRIu32
786		"MB video ram\n", __func__, info.shared_info->frame_buffer_size / 1024,
787		info.shared_info->graphics_memory_size / 1024);
788
789	// *** Framebuffer mapping
790
791	TRACE("framebuffer paddr: %#" B_PRIxPHYSADDR "\n", fbAddr);
792	AreaKeeper frambufferMapper;
793	info.framebuffer_area = frambufferMapper.Map("radeon hd frame buffer",
794		fbAddr, info.shared_info->frame_buffer_size * 1024,
795		B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
796		(void**)&info.shared_info->frame_buffer);
797
798	if (frambufferMapper.InitCheck() < B_OK) {
799		ERROR("%s: card(%" B_PRId32 "): couldn't map frame buffer!\n",
800			__func__, info.id);
801		return info.framebuffer_area;
802	}
803	TRACE("frambuffer vaddr: %#" B_PRIxADDR "\n",
804		(addr_t)info.shared_info->frame_buffer);
805	TRACE("frambuffer size: %#" B_PRIxSIZE "\n",
806		(size_t)info.shared_info->frame_buffer_size * 1024);
807
808	// Turn on write combining for the frame buffer area
809	vm_set_area_memory_type(info.framebuffer_area, fbAddr, B_MTR_WC);
810
811	frambufferMapper.Detach();
812
813	info.shared_info->frame_buffer_area = info.framebuffer_area;
814	info.shared_info->frame_buffer_phys = fbAddr;
815
816	// Pass common information to accelerant
817	info.shared_info->deviceIndex = info.id;
818	info.shared_info->pciID = info.pciID;
819	info.shared_info->pciRev = info.pci->revision;
820	info.shared_info->chipsetID = info.chipsetID;
821	info.shared_info->chipsetFlags = info.chipsetFlags;
822	info.shared_info->dceMajor = info.dceMajor;
823	info.shared_info->dceMinor = info.dceMinor;
824	info.shared_info->registers_area = info.registers_area;
825	strlcpy(info.shared_info->deviceName,
826		info.deviceName, MAX_NAME_LENGTH);
827	strlcpy(info.shared_info->chipsetName,
828		radeon_chip_name[info.chipsetID], MAX_NAME_LENGTH);
829
830	// *** AtomBIOS mapping
831	// First we try an active bios read
832	status_t biosStatus = radeon_hd_getbios(info);
833
834	if (biosStatus != B_OK) {
835		// If the active read fails, we try a disabled read
836		if (info.chipsetID >= RADEON_CAICOS)
837			biosStatus = radeon_hd_getbios_ni(info);
838		else if (info.chipsetID >= RADEON_RV770)
839			biosStatus = radeon_hd_getbios_r700(info);
840		else if (info.chipsetID >= RADEON_R600)
841			biosStatus = radeon_hd_getbios_r600(info);
842		else if (info.chipsetID >= RADEON_RS600)
843			biosStatus = radeon_hd_getbios_avivo(info);
844		// else legacy_read_disabled_bios
845	}
846
847	if (biosStatus != B_OK) {
848		// *** very last resort, shadow bios VGA rom
849		ERROR("%s: Can't find an AtomBIOS rom! Trying shadow rom...\n",
850			__func__);
851
852		// This works as long as the primary card is what this driver
853		// is loaded for. Multiple cards may pose the risk of loading
854		// the wrong AtomBIOS for the wrong card.
855
856		uint32 romBase = 0xC0000;
857		uint32 romSize = 128 * 1024;
858			// what happens when AtomBIOS goes over 128Kb?
859			// A Radeon HD 6990 has a 128Kb AtomBIOS
860
861		if (mapAtomBIOS(info, romBase, romSize) == B_OK) {
862			ERROR("%s: Found AtomBIOS at VGA shadow rom\n", __func__);
863			// Whew!
864			info.shared_info->rom_phys = romBase;
865			info.shared_info->rom_size = romSize;
866			biosStatus = B_OK;
867		}
868	}
869
870	// Check if a valid AtomBIOS image was found.
871	if (biosStatus != B_OK) {
872		ERROR("%s: card (%" B_PRId32 "): couldn't find AtomBIOS rom!\n",
873			__func__, info.id);
874		ERROR("%s: card (%" B_PRId32 "): exiting. Please open a bug ticket"
875			" at haiku-os.org with your /var/log/syslog\n",
876			__func__, info.id);
877		// Fallback to VESA (more likely crash app_server)
878		return B_ERROR;
879	}
880
881	info.shared_info->has_rom = (biosStatus == B_OK) ? true : false;
882	info.shared_info->rom_area = (biosStatus == B_OK) ? info.rom_area : -1;
883
884	// *** Pull active monitor VESA EDID from boot loader
885	edid1_info* edidInfo
886		= (edid1_info*)get_boot_item(EDID_BOOT_INFO, NULL);
887
888	if (edidInfo != NULL) {
889		TRACE("card(%" B_PRId32 "): %s found VESA EDID information.\n",
890			info.id, __func__);
891		info.shared_info->has_edid = true;
892		memcpy(&info.shared_info->edid_info, edidInfo, sizeof(edid1_info));
893	} else {
894		TRACE("card(%" B_PRId32 "): %s didn't find VESA EDID modes.\n",
895			info.id, __func__);
896		info.shared_info->has_edid = false;
897	}
898
899	TRACE("card(%" B_PRId32 "): %s completed successfully!\n",
900		info.id, __func__);
901
902	TRACE("card(%" B_PRId32 "): GPU thermal status: %" B_PRId32 "C\n",
903		info.id, radeon_thermal_query(info) / 1000);
904
905	return B_OK;
906}
907
908
909void
910radeon_hd_uninit(radeon_info &info)
911{
912	TRACE("card(%" B_PRId32 "): %s called\n", info.id, __func__);
913
914	delete_area(info.shared_area);
915	delete_area(info.registers_area);
916	delete_area(info.framebuffer_area);
917	delete_area(info.rom_area);
918}
919
920