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