BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / graphics / radeon_hd / radeon_hd.cpp
blob5769b112ccaaa20ed269d8a93e7f6aaca05e7290
1 /*
2 * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
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
13 #include "radeon_hd.h"
14 #include "sensors.h"
16 #include "AreaKeeper.h"
17 #include "driver.h"
18 #include "utility.h"
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
25 #include <boot_item.h>
26 #include <driver_settings.h>
27 #include <util/kernel_cpp.h>
28 #include <vm/vm.h>
31 #define TRACE_DEVICE
32 #ifdef TRACE_DEVICE
33 # define TRACE(x...) dprintf("radeon_hd: " x)
34 #else
35 # define TRACE(x) ;
36 #endif
38 #define ERROR(x...) dprintf("radeon_hd: " x)
41 // #pragma mark -
44 status_t
45 mapAtomBIOS(radeon_info &info, uint32 romBase, uint32 romSize)
47 TRACE("%s: seeking AtomBIOS @ 0x%" B_PRIX32 " [size: 0x%" B_PRIX32 "]\n",
48 __func__, romBase, romSize);
50 uint8* rom;
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_READ_AREA,
55 (void**)&rom);
57 if (testArea < 0) {
58 ERROR("%s: couldn't map potential rom @ 0x%" B_PRIX32
59 "\n", __func__, romBase);
60 return B_NO_MEMORY;
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;
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);
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;
86 info.rom_area = create_area("radeon hd AtomBIOS",
87 (void**)&info.atom_buffer, B_ANY_KERNEL_ADDRESS,
88 romSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
90 if (info.rom_area < 0) {
91 ERROR("%s: unable to map kernel AtomBIOS space!\n",
92 __func__);
93 delete_area(testArea);
94 return B_NO_MEMORY;
97 memset((void*)info.atom_buffer, 0, romSize);
98 // Prevent unknown code execution by AtomBIOS parser
99 memcpy(info.atom_buffer, (void*)rom, romSize);
100 // Copy AtomBIOS to kernel area
102 // validate copied rom is valid
103 romHeader = RADEON_BIOS16(info.atom_buffer, 0x48);
104 romValid = !memcmp(&info.atom_buffer[romHeader + 4], "ATOM", 4)
105 || !memcmp(&info.atom_buffer[romHeader + 4], "MOTA", 4);
107 if (romValid == true) {
108 set_area_protection(info.rom_area, B_READ_AREA);
109 ERROR("%s: AtomBIOS verified and locked\n", __func__);
110 } else
111 ERROR("%s: AtomBIOS memcpy failed!\n", __func__);
113 delete_area(testArea);
114 return romValid ? B_OK : B_ERROR;
118 static status_t
119 radeon_hd_getbios(radeon_info &info)
121 TRACE("card(%ld): %s: called\n", info.id, __func__);
123 uint32 romBase = 0;
124 uint32 romSize = 0;
125 uint32 romMethod = 0;
127 status_t mapResult = B_ERROR;
129 // first we try to find the AtomBIOS rom via various methods
130 for (romMethod = 0; romMethod < 3; romMethod++) {
131 switch(romMethod) {
132 case 0:
133 // TODO: *** New ACPI method
134 ERROR("%s: ACPI ATRM AtomBIOS TODO\n", __func__);
135 break;
136 case 1:
137 // *** Discreet card on IGP, check PCI BAR 0
138 // On post, the bios puts a copy of the IGP
139 // AtomBIOS at the start of the video ram
140 romBase = info.pci->u.h0.base_registers[PCI_BAR_FB];
141 romSize = 256 * 1024;
143 if (romBase == 0 || romSize == 0) {
144 ERROR("%s: No base found at PCI FB BAR\n", __func__);
145 } else {
146 mapResult = mapAtomBIOS(info, romBase, romSize);
148 break;
149 case 2:
151 // *** PCI ROM BAR
152 // Enable ROM decoding for PCI BAR rom
153 uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
154 pciConfig |= PCI_rom_enable;
155 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
157 uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
158 if ((flags & PCI_rom_enable) != 0)
159 TRACE("%s: PCI ROM decode enabled\n", __func__);
161 romBase = info.pci->u.h0.rom_base;
162 romSize = info.pci->u.h0.rom_size;
164 if (romBase == 0 || romSize == 0) {
165 ERROR("%s: No base found at PCI ROM BAR\n", __func__);
166 } else {
167 mapResult = mapAtomBIOS(info, romBase, romSize);
170 // Disable ROM decoding
171 pciConfig &= ~PCI_rom_enable;
172 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
173 break;
177 if (mapResult == B_OK) {
178 ERROR("%s: AtomBIOS found using active method %" B_PRIu32
179 " at 0x%" B_PRIX32 "\n", __func__, romMethod, romBase);
180 break;
181 } else {
182 ERROR("%s: AtomBIOS not found using active method %" B_PRIu32
183 " at 0x%" B_PRIX32 "\n", __func__, romMethod, romBase);
187 if (mapResult == B_OK) {
188 info.shared_info->rom_phys = romBase;
189 info.shared_info->rom_size = romSize;
190 } else
191 ERROR("%s: Active AtomBIOS search failed.\n", __func__);
193 return mapResult;
197 static status_t
198 radeon_hd_getbios_ni(radeon_info &info)
200 TRACE("card(%ld): %s: called\n", info.id, __func__);
201 uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
202 uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
203 uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
204 uint32 vga_render_control
205 = read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
206 uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
208 // enable the rom
209 write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
210 // disable VGA mode
211 write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
212 & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
213 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
214 write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
215 & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
216 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
217 write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
218 (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
220 write32(info.registers + R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
222 // try to grab the bios via PCI ROM bar
223 // Enable ROM decoding for PCI BAR rom
224 uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
225 pciConfig |= PCI_rom_enable;
226 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
228 uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
229 if (flags & PCI_rom_enable)
230 TRACE("%s: PCI ROM decode enabled\n", __func__);
232 uint32 romBase = info.pci->u.h0.rom_base;
233 uint32 romSize = info.pci->u.h0.rom_size;
235 status_t result = B_OK;
236 if (romBase == 0 || romSize == 0) {
237 ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
238 result = B_ERROR;
239 } else {
240 result = mapAtomBIOS(info, romBase, romSize);
243 if (result == B_OK) {
244 ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
245 " [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
246 info.shared_info->rom_phys = romBase;
247 info.shared_info->rom_size = romSize;
250 // Disable ROM decoding
251 pciConfig &= ~PCI_rom_enable;
252 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
254 // restore regs
255 write32(info.registers + R600_BUS_CNTL, bus_cntl);
256 write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
257 write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
258 write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
259 write32(info.registers + R600_ROM_CNTL, rom_cntl);
261 return result;
265 static status_t
266 radeon_hd_getbios_r700(radeon_info &info)
268 TRACE("card(%ld): %s: called\n", info.id, __func__);
269 uint32 viph_control = read32(info.registers + RADEON_VIPH_CONTROL);
270 uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
271 uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
272 uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
273 uint32 vga_render_control
274 = read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
275 uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
277 // disable VIP
278 write32(info.registers + RADEON_VIPH_CONTROL,
279 (viph_control & ~RADEON_VIPH_EN));
280 // enable the rom
281 write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
282 // disable VGA mode
283 write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
284 & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
285 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
286 write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
287 & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
288 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
289 write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
290 (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
292 write32(info.registers + R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE));
294 // try to grab the bios via PCI ROM bar
295 // Enable ROM decoding for PCI BAR rom
296 uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
297 pciConfig |= PCI_rom_enable;
298 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
300 uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
301 if (flags & PCI_rom_enable)
302 TRACE("%s: PCI ROM decode enabled\n", __func__);
304 uint32 romBase = info.pci->u.h0.rom_base;
305 uint32 romSize = info.pci->u.h0.rom_size;
307 status_t result = B_OK;
308 if (romBase == 0 || romSize == 0) {
309 ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
310 result = B_ERROR;
311 } else {
312 result = mapAtomBIOS(info, romBase, romSize);
315 if (result == B_OK) {
316 ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
317 " [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
318 info.shared_info->rom_phys = romBase;
319 info.shared_info->rom_size = romSize;
322 // Disable ROM decoding
323 pciConfig &= ~PCI_rom_enable;
324 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
326 // restore regs
327 write32(info.registers + RADEON_VIPH_CONTROL, viph_control);
328 write32(info.registers + R600_BUS_CNTL, bus_cntl);
329 write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
330 write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
331 write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
332 write32(info.registers + R600_ROM_CNTL, rom_cntl);
334 return result;
338 static status_t
339 radeon_hd_getbios_r600(radeon_info &info)
341 TRACE("card(%ld): %s: called\n", info.id, __func__);
342 uint32 viph_control = read32(info.registers + RADEON_VIPH_CONTROL);
343 uint32 bus_cntl = read32(info.registers + R600_BUS_CNTL);
344 uint32 d1vga_control = read32(info.registers + AVIVO_D1VGA_CONTROL);
345 uint32 d2vga_control = read32(info.registers + AVIVO_D2VGA_CONTROL);
346 uint32 vga_render_control
347 = read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
348 uint32 rom_cntl = read32(info.registers + R600_ROM_CNTL);
349 uint32 general_pwrmgt = read32(info.registers + R600_GENERAL_PWRMGT);
350 uint32 low_vid_lower_gpio_cntl
351 = read32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL);
352 uint32 medium_vid_lower_gpio_cntl
353 = read32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL);
354 uint32 high_vid_lower_gpio_cntl
355 = read32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL);
356 uint32 ctxsw_vid_lower_gpio_cntl
357 = read32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL);
358 uint32 lower_gpio_enable
359 = read32(info.registers + R600_LOWER_GPIO_ENABLE);
361 // disable VIP
362 write32(info.registers + RADEON_VIPH_CONTROL,
363 (viph_control & ~RADEON_VIPH_EN));
364 // enable the rom
365 write32(info.registers + R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
366 // disable VGA mode
367 write32(info.registers + AVIVO_D1VGA_CONTROL, (d1vga_control
368 & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
369 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
370 write32(info.registers + AVIVO_D2VGA_CONTROL, (d2vga_control
371 & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
372 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
373 write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
374 (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
376 write32(info.registers + R600_ROM_CNTL,
377 ((rom_cntl & ~R600_SCK_PRESCALE_CRYSTAL_CLK_MASK)
378 | (1 << R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT) | R600_SCK_OVERWRITE));
380 write32(info.registers + R600_GENERAL_PWRMGT,
381 (general_pwrmgt & ~R600_OPEN_DRAIN_PADS));
382 write32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL,
383 (low_vid_lower_gpio_cntl & ~0x400));
384 write32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL,
385 (medium_vid_lower_gpio_cntl & ~0x400));
386 write32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL,
387 (high_vid_lower_gpio_cntl & ~0x400));
388 write32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL,
389 (ctxsw_vid_lower_gpio_cntl & ~0x400));
390 write32(info.registers + R600_LOWER_GPIO_ENABLE,
391 (lower_gpio_enable | 0x400));
393 // try to grab the bios via PCI ROM bar
394 // Enable ROM decoding for PCI BAR rom
395 uint32 pciConfig = get_pci_config(info.pci, PCI_rom_base, 4);
396 pciConfig |= PCI_rom_enable;
397 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
399 uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
400 if (flags & PCI_rom_enable)
401 TRACE("%s: PCI ROM decode enabled\n", __func__);
403 uint32 romBase = info.pci->u.h0.rom_base;
404 uint32 romSize = info.pci->u.h0.rom_size;
406 status_t result = B_OK;
407 if (romBase == 0 || romSize == 0) {
408 ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
409 result = B_ERROR;
410 } else {
411 result = mapAtomBIOS(info, romBase, romSize);
414 if (result == B_OK) {
415 ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
416 " [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
417 info.shared_info->rom_phys = romBase;
418 info.shared_info->rom_size = romSize;
421 // Disable ROM decoding
422 pciConfig &= ~PCI_rom_enable;
423 set_pci_config(info.pci, PCI_rom_base, 4, pciConfig);
425 // restore regs
426 write32(info.registers + RADEON_VIPH_CONTROL, viph_control);
427 write32(info.registers + R600_BUS_CNTL, bus_cntl);
428 write32(info.registers + AVIVO_D1VGA_CONTROL, d1vga_control);
429 write32(info.registers + AVIVO_D2VGA_CONTROL, d2vga_control);
430 write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vga_render_control);
431 write32(info.registers + R600_ROM_CNTL, rom_cntl);
432 write32(info.registers + R600_GENERAL_PWRMGT, general_pwrmgt);
433 write32(info.registers + R600_LOW_VID_LOWER_GPIO_CNTL,
434 low_vid_lower_gpio_cntl);
435 write32(info.registers + R600_MEDIUM_VID_LOWER_GPIO_CNTL,
436 medium_vid_lower_gpio_cntl);
437 write32(info.registers + R600_HIGH_VID_LOWER_GPIO_CNTL,
438 high_vid_lower_gpio_cntl);
439 write32(info.registers + R600_CTXSW_VID_LOWER_GPIO_CNTL,
440 ctxsw_vid_lower_gpio_cntl);
441 write32(info.registers + R600_LOWER_GPIO_ENABLE, lower_gpio_enable);
443 return result;
447 static status_t
448 radeon_hd_getbios_avivo(radeon_info &info)
450 TRACE("card(%ld): %s: called\n", info.id, __func__);
451 uint32 sepromControl = read32(info.registers + RADEON_SEPROM_CNTL1);
452 uint32 viphControl = read32(info.registers + RADEON_VIPH_CONTROL);
453 uint32 busControl = read32(info.registers + RV370_BUS_CNTL);
454 uint32 d1vgaControl = read32(info.registers + AVIVO_D1VGA_CONTROL);
455 uint32 d2vgaControl = read32(info.registers + AVIVO_D2VGA_CONTROL);
456 uint32 vgaRenderControl
457 = read32(info.registers + AVIVO_VGA_RENDER_CONTROL);
458 uint32 gpioPadA = read32(info.registers + RADEON_GPIOPAD_A);
459 uint32 gpioPadEN = read32(info.registers + RADEON_GPIOPAD_EN);
460 uint32 gpioPadMask = read32(info.registers + RADEON_GPIOPAD_MASK);
462 write32(info.registers + RADEON_SEPROM_CNTL1,
463 ((sepromControl & ~RADEON_SCK_PRESCALE_MASK)
464 | (0xc << RADEON_SCK_PRESCALE_SHIFT)));
465 write32(info.registers + RADEON_GPIOPAD_A, 0);
466 write32(info.registers + RADEON_GPIOPAD_EN, 0);
467 write32(info.registers + RADEON_GPIOPAD_MASK, 0);
469 // disable VIP
470 write32(info.registers + RADEON_VIPH_CONTROL,
471 (viphControl & ~RADEON_VIPH_EN));
473 // enable the ROM
474 write32(info.registers + RV370_BUS_CNTL,
475 (busControl & ~RV370_BUS_BIOS_DIS_ROM));
477 // disable VGA
478 write32(info.registers + AVIVO_D1VGA_CONTROL,
479 (d1vgaControl & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
480 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
481 write32(info.registers + AVIVO_D2VGA_CONTROL,
482 (d2vgaControl & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE
483 | AVIVO_DVGA_CONTROL_TIMING_SELECT)));
484 write32(info.registers + AVIVO_VGA_RENDER_CONTROL,
485 (vgaRenderControl & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
487 uint32 romBase = info.pci->u.h0.rom_base;
488 uint32 romSize = info.pci->u.h0.rom_size;
490 status_t result = B_OK;
491 if (romBase == 0 || romSize == 0) {
492 ERROR("%s: No AtomBIOS location found at PCI ROM BAR\n", __func__);
493 result = B_ERROR;
494 } else {
495 result = mapAtomBIOS(info, romBase, romSize);
498 if (result == B_OK) {
499 ERROR("%s: AtomBIOS found using disabled method at 0x%" B_PRIX32
500 " [size: 0x%" B_PRIX32 "]\n", __func__, romBase, romSize);
501 info.shared_info->rom_phys = romBase;
502 info.shared_info->rom_size = romSize;
505 // restore registers
506 write32(info.registers + RADEON_SEPROM_CNTL1, sepromControl);
507 write32(info.registers + RADEON_VIPH_CONTROL, viphControl);
508 write32(info.registers + RV370_BUS_CNTL, busControl);
509 write32(info.registers + AVIVO_D1VGA_CONTROL, d1vgaControl);
510 write32(info.registers + AVIVO_D2VGA_CONTROL, d2vgaControl);
511 write32(info.registers + AVIVO_VGA_RENDER_CONTROL, vgaRenderControl);
512 write32(info.registers + RADEON_GPIOPAD_A, gpioPadA);
513 write32(info.registers + RADEON_GPIOPAD_EN, gpioPadEN);
514 write32(info.registers + RADEON_GPIOPAD_MASK, gpioPadMask);
516 return result;
520 static uint32
521 radeon_hd_pci_bar_mmio(uint16 chipsetID)
523 if (chipsetID < RADEON_BONAIRE)
524 return 2;
525 else
526 return 5;
530 status_t
531 radeon_hd_init(radeon_info &info)
533 TRACE("card(%ld): %s: called\n", info.id, __func__);
535 ERROR("%s: card(%ld): "
536 "Radeon %s 1002:%" B_PRIX32 "\n", __func__, info.id,
537 radeon_chip_name[info.chipsetID], info.pciID);
539 // *** Map shared info
540 AreaKeeper sharedCreator;
541 info.shared_area = sharedCreator.Create("radeon hd shared info",
542 (void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
543 ROUND_TO_PAGE_SIZE(sizeof(radeon_shared_info)), B_FULL_LOCK, 0);
544 if (info.shared_area < B_OK) {
545 ERROR("%s: card (%ld): couldn't map shared area!\n",
546 __func__, info.id);
547 return info.shared_area;
550 memset((void*)info.shared_info, 0, sizeof(radeon_shared_info));
551 sharedCreator.Detach();
553 // *** Map Memory mapped IO
554 AreaKeeper mmioMapper;
555 const uint32 pciBarMmio = radeon_hd_pci_bar_mmio(info.chipsetID);
556 info.registers_area = mmioMapper.Map("radeon hd mmio",
557 info.pci->u.h0.base_registers[pciBarMmio],
558 info.pci->u.h0.base_register_sizes[pciBarMmio],
559 B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
560 (void**)&info.registers);
561 if (mmioMapper.InitCheck() < B_OK) {
562 ERROR("%s: card (%ld): couldn't map memory I/O!\n",
563 __func__, info.id);
564 return info.registers_area;
566 mmioMapper.Detach();
568 // *** Populate frame buffer information
569 if (info.chipsetID >= RADEON_CEDAR) {
570 if ((info.chipsetFlags & CHIP_APU) != 0
571 || (info.chipsetFlags & CHIP_IGP) != 0) {
572 // Evergreen+ fusion in bytes
573 info.shared_info->graphics_memory_size
574 = read32(info.registers + CONFIG_MEMSIZE) / 1024;
575 } else {
576 // Evergreen+ has memory stored in MB
577 info.shared_info->graphics_memory_size
578 = read32(info.registers + CONFIG_MEMSIZE) * 1024;
580 } else if (info.chipsetID >= RADEON_R600) {
581 // R600-R700 has memory stored in bytes
582 info.shared_info->graphics_memory_size
583 = read32(info.registers + CONFIG_MEMSIZE) / 1024;
584 } else {
585 // R420 - R600 cards
586 // older cards use RADEON_CONFIG_MEMSIZE vs CONFIG_MEMSIZE
587 if ((info.chipsetFlags & CHIP_IGP) != 0) {
588 // NB_TOM holds amount of ram stolen for GPU
589 uint32 tom = read32(info.registers + RADEON_NB_TOM);
590 info.shared_info->graphics_memory_size
591 = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
592 write32(info.registers + RADEON_CONFIG_MEMSIZE,
593 info.shared_info->graphics_memory_size);
594 } else {
595 info.shared_info->graphics_memory_size
596 = read32(info.registers + RADEON_CONFIG_MEMSIZE);
597 if (info.shared_info->graphics_memory_size == 0) {
598 // known bug if video memory == 8MB
599 info.shared_info->graphics_memory_size = 8192;
600 write32(info.registers + RADEON_CONFIG_MEMSIZE,
601 info.shared_info->graphics_memory_size * 1024);
606 uint32 barSize = info.pci->u.h0.base_register_sizes[PCI_BAR_FB] / 1024;
608 // if graphics memory is larger then PCI bar, just map bar
609 if (info.shared_info->graphics_memory_size == 0) {
610 // we can recover as we have PCI FB bar, but this should be fixed
611 ERROR("%s: Error: found 0MB video ram, using PCI bar size...\n",
612 __func__);
613 info.shared_info->frame_buffer_size = barSize;
614 } else if (info.shared_info->graphics_memory_size > barSize) {
615 TRACE("%s: shrinking frame buffer to PCI bar...\n",
616 __func__);
617 info.shared_info->frame_buffer_size = barSize;
618 } else {
619 info.shared_info->frame_buffer_size
620 = info.shared_info->graphics_memory_size;
623 TRACE("%s: mapping a frame buffer of %" B_PRIu32 "MB out of %" B_PRIu32
624 "MB video ram\n", __func__, info.shared_info->frame_buffer_size / 1024,
625 info.shared_info->graphics_memory_size / 1024);
627 // *** Framebuffer mapping
628 AreaKeeper frambufferMapper;
629 info.framebuffer_area = frambufferMapper.Map("radeon hd frame buffer",
630 info.pci->u.h0.base_registers[PCI_BAR_FB],
631 info.shared_info->frame_buffer_size * 1024,
632 B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
633 (void**)&info.shared_info->frame_buffer);
634 if (frambufferMapper.InitCheck() < B_OK) {
635 ERROR("%s: card(%ld): couldn't map frame buffer!\n",
636 __func__, info.id);
637 return info.framebuffer_area;
640 // Turn on write combining for the frame buffer area
641 vm_set_area_memory_type(info.framebuffer_area,
642 info.pci->u.h0.base_registers[PCI_BAR_FB], B_MTR_WC);
644 frambufferMapper.Detach();
646 info.shared_info->frame_buffer_area = info.framebuffer_area;
647 info.shared_info->frame_buffer_phys
648 = info.pci->u.h0.base_registers[PCI_BAR_FB];
650 // Pass common information to accelerant
651 info.shared_info->deviceIndex = info.id;
652 info.shared_info->pciID = info.pciID;
653 info.shared_info->chipsetID = info.chipsetID;
654 info.shared_info->chipsetFlags = info.chipsetFlags;
655 info.shared_info->dceMajor = info.dceMajor;
656 info.shared_info->dceMinor = info.dceMinor;
657 info.shared_info->registers_area = info.registers_area;
658 strlcpy(info.shared_info->deviceName,
659 info.deviceName, MAX_NAME_LENGTH);
660 strlcpy(info.shared_info->chipsetName,
661 radeon_chip_name[info.chipsetID], MAX_NAME_LENGTH);
663 // *** AtomBIOS mapping
664 // First we try an active bios read
665 status_t biosStatus = radeon_hd_getbios(info);
667 if (biosStatus != B_OK) {
668 // If the active read fails, we try a disabled read
669 if (info.chipsetID >= RADEON_CAICOS)
670 biosStatus = radeon_hd_getbios_ni(info);
671 else if (info.chipsetID >= RADEON_RV770)
672 biosStatus = radeon_hd_getbios_r700(info);
673 else if (info.chipsetID >= RADEON_R600)
674 biosStatus = radeon_hd_getbios_r600(info);
675 else if (info.chipsetID >= RADEON_RS600)
676 biosStatus = radeon_hd_getbios_avivo(info);
677 // else legacy_read_disabled_bios
680 if (biosStatus != B_OK) {
681 // *** very last resort, shadow bios VGA rom
682 ERROR("%s: Can't find an AtomBIOS rom! Trying shadow rom...\n",
683 __func__);
685 // This works as long as the primary card is what this driver
686 // is loaded for. Multiple cards may pose the risk of loading
687 // the wrong AtomBIOS for the wrong card.
689 uint32 romBase = 0xC0000;
690 uint32 romSize = 128 * 1024;
691 // what happens when AtomBIOS goes over 128Kb?
692 // A Radeon HD 6990 has a 128Kb AtomBIOS
694 if (mapAtomBIOS(info, romBase, romSize) == B_OK) {
695 ERROR("%s: Found AtomBIOS at VGA shadow rom\n", __func__);
696 // Whew!
697 info.shared_info->rom_phys = romBase;
698 info.shared_info->rom_size = romSize;
699 biosStatus = B_OK;
703 // Check if a valid AtomBIOS image was found.
704 if (biosStatus != B_OK) {
705 ERROR("%s: card (%ld): couldn't find AtomBIOS rom!\n",
706 __func__, info.id);
707 ERROR("%s: card (%ld): exiting. Please open a bug ticket"
708 " at haiku-os.org with your /var/log/syslog\n",
709 __func__, info.id);
710 // Fallback to VESA (more likely crash app_server)
711 return B_ERROR;
714 info.shared_info->has_rom = (biosStatus == B_OK) ? true : false;
715 info.shared_info->rom_area = (biosStatus == B_OK) ? info.rom_area : -1;
717 // *** Pull active monitor VESA EDID from boot loader
718 edid1_info* edidInfo
719 = (edid1_info*)get_boot_item(EDID_BOOT_INFO, NULL);
721 if (edidInfo != NULL) {
722 TRACE("card(%ld): %s found VESA EDID information.\n", info.id,
723 __func__);
724 info.shared_info->has_edid = true;
725 memcpy(&info.shared_info->edid_info, edidInfo, sizeof(edid1_info));
726 } else {
727 TRACE("card(%ld): %s didn't find VESA EDID modes.\n", info.id,
728 __func__);
729 info.shared_info->has_edid = false;
732 TRACE("card(%ld): %s completed successfully!\n", info.id, __func__);
734 TRACE("card(%ld): GPU thermal status: %" B_PRId32 "C\n", info.id,
735 radeon_thermal_query(info) / 1000);
737 return B_OK;
741 void
742 radeon_hd_uninit(radeon_info &info)
744 TRACE("card(%ld): %s called\n", info.id, __func__);
746 delete_area(info.shared_area);
747 delete_area(info.registers_area);
748 delete_area(info.framebuffer_area);
749 delete_area(info.rom_area);