1 /* 2 * Copyright 2011, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Alexander von Gluck IV, kallisti5@unixzen.com 7 */ 8 9 10 #include <Debug.h> 11 12 #include "bios.h" 13 14 #include "accelerant.h" 15 #include "accelerant_protos.h" 16 17 18 #undef TRACE 19 20 #define TRACE_ATOM 21 #ifdef TRACE_ATOM 22 # define TRACE(x...) _sPrintf("radeon_hd: " x) 23 #else 24 # define TRACE(x...) ; 25 #endif 26 27 28 atom_context *gAtomContext; 29 30 31 void 32 radeon_bios_init_scratch() 33 { 34 radeon_shared_info &info = *gInfo->shared_info; 35 36 uint32 biosScratch2; 37 uint32 biosScratch6; 38 39 if (info.device_chipset >= RADEON_R600) { 40 biosScratch2 = Read32(OUT, R600_BIOS_2_SCRATCH); 41 biosScratch6 = Read32(OUT, R600_BIOS_6_SCRATCH); 42 } else { 43 biosScratch2 = Read32(OUT, RADEON_BIOS_2_SCRATCH); 44 biosScratch6 = Read32(OUT, RADEON_BIOS_6_SCRATCH); 45 } 46 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 51 52 if (info.device_chipset >= RADEON_R600) { 53 Write32(OUT, R600_BIOS_2_SCRATCH, biosScratch2); 54 Write32(OUT, R600_BIOS_6_SCRATCH, biosScratch6); 55 } else { 56 Write32(OUT, RADEON_BIOS_2_SCRATCH, biosScratch2); 57 Write32(OUT, RADEON_BIOS_6_SCRATCH, biosScratch6); 58 } 59 } 60 61 62 bool 63 radeon_bios_isposted() 64 { 65 // aka, is primary graphics card that POST loaded 66 67 radeon_shared_info &info = *gInfo->shared_info; 68 uint32 reg; 69 70 if (info.device_chipset == (RADEON_R1000 | 0x50)) { 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.device_chipset >= RADEON_R1000) { 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.device_chipset > RADEON_R580) { 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; 100 } 101 } 102 103 return false; 104 } 105 106 107 status_t 108 radeon_init_bios(uint8* bios) 109 { 110 radeon_shared_info &info = *gInfo->shared_info; 111 112 if (info.has_rom == false) { 113 TRACE("%s: called even though has_rom == false\n", __func__); 114 return B_ERROR; 115 } 116 117 #ifdef TRACE_ATOM 118 radeon_dump_bios(); 119 #endif 120 121 struct card_info *atom_card_info 122 = (card_info*)malloc(sizeof(card_info)); 123 124 if (!atom_card_info) 125 return B_NO_MEMORY; 126 127 atom_card_info->reg_read = Read32Cail; 128 atom_card_info->reg_write = Write32Cail; 129 130 // use MMIO instead of PCI I/O BAR 131 atom_card_info->ioreg_read = Read32Cail; 132 atom_card_info->ioreg_write = Write32Cail; 133 134 atom_card_info->mc_read = _read32; 135 atom_card_info->mc_write = _write32; 136 atom_card_info->pll_read = _read32; 137 atom_card_info->pll_write = _write32; 138 139 // Point AtomBIOS parser to card bios and malloc gAtomContext 140 gAtomContext = atom_parse(atom_card_info, bios); 141 142 if (gAtomContext == NULL) { 143 TRACE("%s: couldn't parse system AtomBIOS\n", __func__); 144 return B_ERROR; 145 } 146 147 if ((gAtomContext->exec_sem = create_sem(1, "AtomBIOS_exec")) 148 < B_NO_ERROR) { 149 TRACE("%s: couldn't create semaphore for AtomBIOS exec thread!\n", 150 __func__); 151 return B_ERROR; 152 } 153 154 radeon_bios_init_scratch(); 155 atom_allocate_fb_scratch(gAtomContext); 156 157 // post card atombios if needed 158 if (radeon_bios_isposted() == false) { 159 TRACE("%s: init AtomBIOS for this card as it is not not posted\n", 160 __func__); 161 // radeon_gpu_reset(); // <= r500 only? 162 atom_asic_init(gAtomContext); 163 } else { 164 TRACE("%s: AtomBIOS is already posted\n", 165 __func__); 166 } 167 168 return B_OK; 169 } 170 171 172 status_t 173 radeon_dump_bios() 174 { 175 // For debugging use, dump card AtomBIOS 176 radeon_shared_info &info = *gInfo->shared_info; 177 178 TRACE("%s: Dumping AtomBIOS as ATOM_DEBUG is set...\n", 179 __func__); 180 181 FILE* fp; 182 char filename[255]; 183 sprintf(filename, "/boot/common/cache/tmp/radeon_hd_bios_1002_%" B_PRIx32 184 "_%" B_PRIu32 ".bin", info.device_id, info.device_index); 185 186 fp = fopen(filename, "wb"); 187 if (fp == NULL) { 188 TRACE("%s: Cannot create AtomBIOS blob at %s\n", __func__, filename); 189 return B_ERROR; 190 } 191 192 fwrite(gInfo->rom, info.rom_size, 1, fp); 193 194 fclose(fp); 195 196 TRACE("%s: AtomBIOS dumped to %s\n", __func__, filename); 197 198 return B_OK; 199 } 200