BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / accelerants / radeon_hd / bios.cpp
blob4d29bb0e520ce02c3e89a96d362c333645d8b418
1 /*
2 * Copyright 2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Alexander von Gluck IV, kallisti5@unixzen.com
7 */
10 #include "bios.h"
12 #include <Debug.h>
14 #include "accelerant.h"
15 #include "accelerant_protos.h"
18 #undef TRACE
20 #define TRACE_ATOM
21 #ifdef TRACE_ATOM
22 # define TRACE(x...) _sPrintf("radeon_hd: " x)
23 #else
24 # define TRACE(x...) ;
25 #endif
28 atom_context* gAtomContext;
31 void
32 radeon_bios_init_scratch()
34 radeon_shared_info &info = *gInfo->shared_info;
36 uint32 biosScratch2;
37 uint32 biosScratch6;
39 if (info.chipsetID >= RADEON_R600) {
40 biosScratch2 = Read32(OUT, R600_SCRATCH_REG2);
41 biosScratch6 = Read32(OUT, R600_SCRATCH_REG6);
42 } else {
43 biosScratch2 = Read32(OUT, RADEON_BIOS_2_SCRATCH);
44 biosScratch6 = Read32(OUT, RADEON_BIOS_6_SCRATCH);
47 biosScratch2 &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
48 // bios should control backlight
49 biosScratch6 |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
50 // bios shouldn't handle mode switching
52 if (info.chipsetID >= RADEON_R600) {
53 Write32(OUT, R600_SCRATCH_REG2, biosScratch2);
54 Write32(OUT, R600_SCRATCH_REG6, biosScratch6);
55 } else {
56 Write32(OUT, RADEON_BIOS_2_SCRATCH, biosScratch2);
57 Write32(OUT, RADEON_BIOS_6_SCRATCH, biosScratch6);
62 bool
63 radeon_bios_isposted()
65 // aka, is primary graphics card that POST loaded
67 radeon_shared_info &info = *gInfo->shared_info;
68 uint32 reg;
70 if (info.chipsetID == RADEON_PALM) {
71 // palms
72 reg = Read32(OUT, EVERGREEN_CRTC_CONTROL
73 + EVERGREEN_CRTC0_REGISTER_OFFSET)
74 | Read32(OUT, EVERGREEN_CRTC_CONTROL
75 + EVERGREEN_CRTC1_REGISTER_OFFSET);
76 if ((reg & EVERGREEN_CRTC_MASTER_EN) != 0)
77 return true;
78 } else if (info.chipsetID >= RADEON_CEDAR) {
79 // evergreen or higher
80 reg = Read32(OUT, EVERGREEN_CRTC_CONTROL
81 + EVERGREEN_CRTC0_REGISTER_OFFSET)
82 | Read32(OUT, EVERGREEN_CRTC_CONTROL
83 + EVERGREEN_CRTC1_REGISTER_OFFSET)
84 | Read32(OUT, EVERGREEN_CRTC_CONTROL
85 + EVERGREEN_CRTC2_REGISTER_OFFSET)
86 | Read32(OUT, EVERGREEN_CRTC_CONTROL
87 + EVERGREEN_CRTC3_REGISTER_OFFSET)
88 | Read32(OUT, EVERGREEN_CRTC_CONTROL
89 + EVERGREEN_CRTC4_REGISTER_OFFSET)
90 | Read32(OUT, EVERGREEN_CRTC_CONTROL
91 + EVERGREEN_CRTC5_REGISTER_OFFSET);
92 if ((reg & EVERGREEN_CRTC_MASTER_EN) != 0)
93 return true;
94 } else if (info.chipsetID >= RADEON_RS600) {
95 // avivio through r700
96 reg = Read32(OUT, AVIVO_D1CRTC_CONTROL)
97 | Read32(OUT, AVIVO_D2CRTC_CONTROL);
98 if ((reg & AVIVO_CRTC_EN) != 0) {
99 return true;
101 } else {
102 // early cards
103 reg = Read32(OUT, RADEON_CRTC_GEN_CNTL)
104 | Read32(OUT, RADEON_CRTC2_GEN_CNTL);
105 if ((reg & RADEON_CRTC_EN) != 0)
106 return true;
109 // also check memory size incase crt controlers are disabled
110 if (info.chipsetID >= RADEON_R600)
111 reg = Read32(OUT, R600_CONFIG_MEMSIZE);
112 else
113 reg = Read32(OUT, RADEON_CONFIG_MEMSIZE);
115 if (reg)
116 return true;
118 return false;
122 status_t
123 radeon_init_bios(uint8* bios)
125 radeon_shared_info &info = *gInfo->shared_info;
127 if (info.has_rom == false) {
128 TRACE("%s: called even though has_rom == false\n", __func__);
129 return B_ERROR;
132 #ifdef TRACE_ATOM
133 radeon_dump_bios();
134 #endif
136 struct card_info* atom_card_info
137 = (card_info*)malloc(sizeof(card_info));
139 if (!atom_card_info)
140 return B_NO_MEMORY;
142 atom_card_info->reg_read = Read32Cail;
143 atom_card_info->reg_write = Write32Cail;
145 // use MMIO instead of PCI I/O BAR
146 atom_card_info->ioreg_read = Read32Cail;
147 atom_card_info->ioreg_write = Write32Cail;
149 atom_card_info->mc_read = _read32;
150 atom_card_info->mc_write = _write32;
151 atom_card_info->pll_read = _read32;
152 atom_card_info->pll_write = _write32;
154 // Point AtomBIOS parser to card bios and malloc gAtomContext
155 gAtomContext = atom_parse(atom_card_info, bios);
157 if (gAtomContext == NULL) {
158 TRACE("%s: couldn't parse system AtomBIOS\n", __func__);
159 return B_ERROR;
162 if ((gAtomContext->exec_sem = create_sem(1, "AtomBIOS_exec"))
163 < B_NO_ERROR) {
164 TRACE("%s: couldn't create semaphore for AtomBIOS exec thread!\n",
165 __func__);
166 return B_ERROR;
169 radeon_bios_init_scratch();
170 atom_allocate_fb_scratch(gAtomContext);
172 // post card atombios if needed
173 if (radeon_bios_isposted() == false) {
174 TRACE("%s: init AtomBIOS for this card as it is not not posted\n",
175 __func__);
176 // radeon_gpu_reset(); // <= r500 only?
177 atom_asic_init(gAtomContext);
178 } else {
179 TRACE("%s: AtomBIOS is already posted\n",
180 __func__);
183 return B_OK;
187 status_t
188 radeon_dump_bios()
190 // For debugging use, dump card AtomBIOS
191 radeon_shared_info &info = *gInfo->shared_info;
193 TRACE("%s: Dumping AtomBIOS as ATOM_DEBUG is set...\n",
194 __func__);
196 FILE* fp;
197 char filename[255];
198 sprintf(filename, "/boot/system/cache/tmp/radeon_hd_bios_1002_%" B_PRIx32
199 "_%" B_PRIu32 ".bin", info.pciID, info.deviceIndex);
201 fp = fopen(filename, "wb");
202 if (fp == NULL) {
203 TRACE("%s: Cannot create AtomBIOS blob at %s\n", __func__, filename);
204 return B_ERROR;
207 fwrite(gInfo->rom, info.rom_size, 1, fp);
209 fclose(fp);
211 TRACE("%s: AtomBIOS dumped to %s\n", __func__, filename);
213 return B_OK;