2 * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
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"
16 #include "AreaKeeper.h"
25 #include <boot_item.h>
26 #include <driver_settings.h>
27 #include <util/kernel_cpp.h>
33 # define TRACE(x...) dprintf("radeon_hd: " x)
38 #define ERROR(x...) dprintf("radeon_hd: " x)
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
);
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
,
58 ERROR("%s: couldn't map potential rom @ 0x%" B_PRIX32
59 "\n", __func__
, romBase
);
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
);
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
);
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",
93 delete_area(testArea
);
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__
);
111 ERROR("%s: AtomBIOS memcpy failed!\n", __func__
);
113 delete_area(testArea
);
114 return romValid
? B_OK
: B_ERROR
;
119 radeon_hd_getbios(radeon_info
&info
)
121 TRACE("card(%ld): %s: called\n", info
.id
, __func__
);
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
++) {
133 // TODO: *** New ACPI method
134 ERROR("%s: ACPI ATRM AtomBIOS TODO\n", __func__
);
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__
);
146 mapResult
= mapAtomBIOS(info
, romBase
, romSize
);
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__
);
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
);
177 if (mapResult
== B_OK
) {
178 ERROR("%s: AtomBIOS found using active method %" B_PRIu32
179 " at 0x%" B_PRIX32
"\n", __func__
, romMethod
, romBase
);
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
;
191 ERROR("%s: Active AtomBIOS search failed.\n", __func__
);
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
);
209 write32(info
.registers
+ R600_BUS_CNTL
, (bus_cntl
& ~R600_BIOS_ROM_DIS
));
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__
);
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
);
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
);
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
);
278 write32(info
.registers
+ RADEON_VIPH_CONTROL
,
279 (viph_control
& ~RADEON_VIPH_EN
));
281 write32(info
.registers
+ R600_BUS_CNTL
, (bus_cntl
& ~R600_BIOS_ROM_DIS
));
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__
);
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
);
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
);
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
);
362 write32(info
.registers
+ RADEON_VIPH_CONTROL
,
363 (viph_control
& ~RADEON_VIPH_EN
));
365 write32(info
.registers
+ R600_BUS_CNTL
, (bus_cntl
& ~R600_BIOS_ROM_DIS
));
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__
);
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
);
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
);
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);
470 write32(info
.registers
+ RADEON_VIPH_CONTROL
,
471 (viphControl
& ~RADEON_VIPH_EN
));
474 write32(info
.registers
+ RV370_BUS_CNTL
,
475 (busControl
& ~RV370_BUS_BIOS_DIS_ROM
));
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__
);
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
;
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
);
521 radeon_hd_pci_bar_mmio(uint16 chipsetID
)
523 if (chipsetID
< RADEON_BONAIRE
)
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",
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",
564 return info
.registers_area
;
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;
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;
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
);
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",
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",
617 info
.shared_info
->frame_buffer_size
= barSize
;
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",
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",
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__
);
697 info
.shared_info
->rom_phys
= romBase
;
698 info
.shared_info
->rom_size
= romSize
;
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",
707 ERROR("%s: card (%ld): exiting. Please open a bug ticket"
708 " at haiku-os.org with your /var/log/syslog\n",
710 // Fallback to VESA (more likely crash app_server)
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
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
,
724 info
.shared_info
->has_edid
= true;
725 memcpy(&info
.shared_info
->edid_info
, edidInfo
, sizeof(edid1_info
));
727 TRACE("card(%ld): %s didn't find VESA EDID modes.\n", info
.id
,
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);
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
);