10ceb8395SAlexander von Gluck IV /* 20ceb8395SAlexander von Gluck IV * Copyright 2011, Haiku, Inc. All Rights Reserved. 30ceb8395SAlexander von Gluck IV * Distributed under the terms of the MIT License. 40ceb8395SAlexander von Gluck IV * 50ceb8395SAlexander von Gluck IV * Authors: 60ceb8395SAlexander von Gluck IV * Alexander von Gluck IV, kallisti5@unixzen.com 70ceb8395SAlexander von Gluck IV */ 80ceb8395SAlexander von Gluck IV 90ceb8395SAlexander von Gluck IV 100ceb8395SAlexander von Gluck IV #include "bios.h" 110ceb8395SAlexander von Gluck IV 1261cf7133SAlexander von Gluck IV #include <Debug.h> 1361cf7133SAlexander von Gluck IV 140ceb8395SAlexander von Gluck IV #include "accelerant.h" 150ceb8395SAlexander von Gluck IV #include "accelerant_protos.h" 160ceb8395SAlexander von Gluck IV 170ceb8395SAlexander von Gluck IV 180ceb8395SAlexander von Gluck IV #undef TRACE 190ceb8395SAlexander von Gluck IV 200ceb8395SAlexander von Gluck IV #define TRACE_ATOM 210ceb8395SAlexander von Gluck IV #ifdef TRACE_ATOM 2212c25669SAlexander von Gluck IV # define TRACE(x...) _sPrintf("radeon_hd: " x) 230ceb8395SAlexander von Gluck IV #else 2412c25669SAlexander von Gluck IV # define TRACE(x...) ; 250ceb8395SAlexander von Gluck IV #endif 260ceb8395SAlexander von Gluck IV 2751360674SAlexander von Gluck IV 281d5cfc64SAlexander von Gluck IV atom_context* gAtomContext; 2951360674SAlexander von Gluck IV 3051360674SAlexander von Gluck IV 31d77ff85eSAlexander von Gluck IV void 32d77ff85eSAlexander von Gluck IV radeon_bios_init_scratch() 33d77ff85eSAlexander von Gluck IV { 34d77ff85eSAlexander von Gluck IV radeon_shared_info &info = *gInfo->shared_info; 35d77ff85eSAlexander von Gluck IV 3653aac744SAlexander von Gluck IV uint32 biosScratch2; 3753aac744SAlexander von Gluck IV uint32 biosScratch6; 38d77ff85eSAlexander von Gluck IV 39359b926fSAlexander von Gluck IV if (info.chipsetID >= RADEON_R600) { 40*93aac98dSAlexander von Gluck IV biosScratch2 = Read32(OUT, R600_SCRATCH_REG2); 41*93aac98dSAlexander von Gluck IV biosScratch6 = Read32(OUT, R600_SCRATCH_REG6); 42d77ff85eSAlexander von Gluck IV } else { 4353aac744SAlexander von Gluck IV biosScratch2 = Read32(OUT, RADEON_BIOS_2_SCRATCH); 4453aac744SAlexander von Gluck IV biosScratch6 = Read32(OUT, RADEON_BIOS_6_SCRATCH); 45d77ff85eSAlexander von Gluck IV } 46d77ff85eSAlexander von Gluck IV 4753aac744SAlexander von Gluck IV biosScratch2 &= ~ATOM_S2_VRI_BRIGHT_ENABLE; 48d77ff85eSAlexander von Gluck IV // bios should control backlight 4953aac744SAlexander von Gluck IV biosScratch6 |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH; 50d77ff85eSAlexander von Gluck IV // bios shouldn't handle mode switching 51d77ff85eSAlexander von Gluck IV 52359b926fSAlexander von Gluck IV if (info.chipsetID >= RADEON_R600) { 53*93aac98dSAlexander von Gluck IV Write32(OUT, R600_SCRATCH_REG2, biosScratch2); 54*93aac98dSAlexander von Gluck IV Write32(OUT, R600_SCRATCH_REG6, biosScratch6); 55d77ff85eSAlexander von Gluck IV } else { 5653aac744SAlexander von Gluck IV Write32(OUT, RADEON_BIOS_2_SCRATCH, biosScratch2); 5753aac744SAlexander von Gluck IV Write32(OUT, RADEON_BIOS_6_SCRATCH, biosScratch6); 58d77ff85eSAlexander von Gluck IV } 59d77ff85eSAlexander von Gluck IV } 60d77ff85eSAlexander von Gluck IV 61d77ff85eSAlexander von Gluck IV 62d3e8b642SAlexander von Gluck IV bool 63d3e8b642SAlexander von Gluck IV radeon_bios_isposted() 64d3e8b642SAlexander von Gluck IV { 65d3e8b642SAlexander von Gluck IV // aka, is primary graphics card that POST loaded 66d3e8b642SAlexander von Gluck IV 67d3e8b642SAlexander von Gluck IV radeon_shared_info &info = *gInfo->shared_info; 68d3e8b642SAlexander von Gluck IV uint32 reg; 69d3e8b642SAlexander von Gluck IV 70359b926fSAlexander von Gluck IV if (info.chipsetID == RADEON_PALM) { 71d3e8b642SAlexander von Gluck IV // palms 72d3e8b642SAlexander von Gluck IV reg = Read32(OUT, EVERGREEN_CRTC_CONTROL 73d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC0_REGISTER_OFFSET) 74d3e8b642SAlexander von Gluck IV | Read32(OUT, EVERGREEN_CRTC_CONTROL 75d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC1_REGISTER_OFFSET); 76dc223cc5SAlexander von Gluck IV if ((reg & EVERGREEN_CRTC_MASTER_EN) != 0) 77d3e8b642SAlexander von Gluck IV return true; 78359b926fSAlexander von Gluck IV } else if (info.chipsetID >= RADEON_CEDAR) { 79d3e8b642SAlexander von Gluck IV // evergreen or higher 80d3e8b642SAlexander von Gluck IV reg = Read32(OUT, EVERGREEN_CRTC_CONTROL 81d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC0_REGISTER_OFFSET) 82d3e8b642SAlexander von Gluck IV | Read32(OUT, EVERGREEN_CRTC_CONTROL 83d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC1_REGISTER_OFFSET) 84d3e8b642SAlexander von Gluck IV | Read32(OUT, EVERGREEN_CRTC_CONTROL 85d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC2_REGISTER_OFFSET) 86d3e8b642SAlexander von Gluck IV | Read32(OUT, EVERGREEN_CRTC_CONTROL 87d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC3_REGISTER_OFFSET) 88d3e8b642SAlexander von Gluck IV | Read32(OUT, EVERGREEN_CRTC_CONTROL 89d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC4_REGISTER_OFFSET) 90d3e8b642SAlexander von Gluck IV | Read32(OUT, EVERGREEN_CRTC_CONTROL 91d3e8b642SAlexander von Gluck IV + EVERGREEN_CRTC5_REGISTER_OFFSET); 92dc223cc5SAlexander von Gluck IV if ((reg & EVERGREEN_CRTC_MASTER_EN) != 0) 93d3e8b642SAlexander von Gluck IV return true; 94e35c1f2dSAlexander von Gluck IV } else if (info.chipsetID >= RADEON_RS600) { 95d3e8b642SAlexander von Gluck IV // avivio through r700 96bbd90770SAlexander von Gluck IV reg = Read32(OUT, AVIVO_D1CRTC_CONTROL) 97bbd90770SAlexander von Gluck IV | Read32(OUT, AVIVO_D2CRTC_CONTROL); 98dc223cc5SAlexander von Gluck IV if ((reg & AVIVO_CRTC_EN) != 0) { 99d3e8b642SAlexander von Gluck IV return true; 100d3e8b642SAlexander von Gluck IV } 101e35c1f2dSAlexander von Gluck IV } else { 102e35c1f2dSAlexander von Gluck IV // early cards 103e35c1f2dSAlexander von Gluck IV reg = Read32(OUT, RADEON_CRTC_GEN_CNTL) 104e35c1f2dSAlexander von Gluck IV | Read32(OUT, RADEON_CRTC2_GEN_CNTL); 105e35c1f2dSAlexander von Gluck IV if ((reg & RADEON_CRTC_EN) != 0) 106e35c1f2dSAlexander von Gluck IV return true; 107d3e8b642SAlexander von Gluck IV } 108d3e8b642SAlexander von Gluck IV 109e35c1f2dSAlexander von Gluck IV // also check memory size incase crt controlers are disabled 110e35c1f2dSAlexander von Gluck IV if (info.chipsetID >= RADEON_R600) 111e35c1f2dSAlexander von Gluck IV reg = Read32(OUT, R600_CONFIG_MEMSIZE); 112e35c1f2dSAlexander von Gluck IV else 113e35c1f2dSAlexander von Gluck IV reg = Read32(OUT, RADEON_CONFIG_MEMSIZE); 114e35c1f2dSAlexander von Gluck IV 115e35c1f2dSAlexander von Gluck IV if (reg) 116e35c1f2dSAlexander von Gluck IV return true; 117e35c1f2dSAlexander von Gluck IV 118d3e8b642SAlexander von Gluck IV return false; 119d3e8b642SAlexander von Gluck IV } 120d3e8b642SAlexander von Gluck IV 121d3e8b642SAlexander von Gluck IV 12251360674SAlexander von Gluck IV status_t 1235cf44ddaSAlexander von Gluck IV radeon_init_bios(uint8* bios) 1241d5cfc64SAlexander von Gluck IV { 1251d5cfc64SAlexander von Gluck IV radeon_shared_info &info = *gInfo->shared_info; 1261d5cfc64SAlexander von Gluck IV 1275cf44ddaSAlexander von Gluck IV if (info.has_rom == false) { 1285cf44ddaSAlexander von Gluck IV TRACE("%s: called even though has_rom == false\n", __func__); 1295cf44ddaSAlexander von Gluck IV return B_ERROR; 1301d5cfc64SAlexander von Gluck IV } 1311d5cfc64SAlexander von Gluck IV 132a8232073SAlexander von Gluck IV #ifdef TRACE_ATOM 133a8232073SAlexander von Gluck IV radeon_dump_bios(); 134a8232073SAlexander von Gluck IV #endif 135a8232073SAlexander von Gluck IV 13651360674SAlexander von Gluck IV struct card_info* atom_card_info 13751360674SAlexander von Gluck IV = (card_info*)malloc(sizeof(card_info)); 13851360674SAlexander von Gluck IV 13951360674SAlexander von Gluck IV if (!atom_card_info) 14051360674SAlexander von Gluck IV return B_NO_MEMORY; 14151360674SAlexander von Gluck IV 14211390ce0SAlexander von Gluck IV atom_card_info->reg_read = Read32Cail; 14311390ce0SAlexander von Gluck IV atom_card_info->reg_write = Write32Cail; 14451360674SAlexander von Gluck IV 145f66a1a8dSAlexander von Gluck IV // use MMIO instead of PCI I/O BAR 14611390ce0SAlexander von Gluck IV atom_card_info->ioreg_read = Read32Cail; 14711390ce0SAlexander von Gluck IV atom_card_info->ioreg_write = Write32Cail; 148f66a1a8dSAlexander von Gluck IV 14951360674SAlexander von Gluck IV atom_card_info->mc_read = _read32; 15051360674SAlexander von Gluck IV atom_card_info->mc_write = _write32; 15151360674SAlexander von Gluck IV atom_card_info->pll_read = _read32; 15251360674SAlexander von Gluck IV atom_card_info->pll_write = _write32; 15351360674SAlexander von Gluck IV 1541d5cfc64SAlexander von Gluck IV // Point AtomBIOS parser to card bios and malloc gAtomContext 155f0b0d6cbSAlexander von Gluck IV gAtomContext = atom_parse(atom_card_info, bios); 15651360674SAlexander von Gluck IV 1571d5cfc64SAlexander von Gluck IV if (gAtomContext == NULL) { 158ef2909a1SAlexander von Gluck IV TRACE("%s: couldn't parse system AtomBIOS\n", __func__); 159ef2909a1SAlexander von Gluck IV return B_ERROR; 160ef2909a1SAlexander von Gluck IV } 161ef2909a1SAlexander von Gluck IV 16281e071b7SAlexander von Gluck IV if ((gAtomContext->exec_sem = create_sem(1, "AtomBIOS_exec")) 16381e071b7SAlexander von Gluck IV < B_NO_ERROR) { 16481e071b7SAlexander von Gluck IV TRACE("%s: couldn't create semaphore for AtomBIOS exec thread!\n", 16581e071b7SAlexander von Gluck IV __func__); 16681e071b7SAlexander von Gluck IV return B_ERROR; 16781e071b7SAlexander von Gluck IV } 16881e071b7SAlexander von Gluck IV 169d77ff85eSAlexander von Gluck IV radeon_bios_init_scratch(); 17077e8ac07SAlexander von Gluck IV atom_allocate_fb_scratch(gAtomContext); 17151360674SAlexander von Gluck IV 172d3e8b642SAlexander von Gluck IV // post card atombios if needed 173936aec74SAlexander von Gluck IV if (radeon_bios_isposted() == false) { 174d3e8b642SAlexander von Gluck IV TRACE("%s: init AtomBIOS for this card as it is not not posted\n", 175d3e8b642SAlexander von Gluck IV __func__); 176d3e8b642SAlexander von Gluck IV // radeon_gpu_reset(); // <= r500 only? 1770cd93754SAlexander von Gluck IV atom_asic_init(gAtomContext); 178d3e8b642SAlexander von Gluck IV } else { 179d3e8b642SAlexander von Gluck IV TRACE("%s: AtomBIOS is already posted\n", 180d3e8b642SAlexander von Gluck IV __func__); 181d3e8b642SAlexander von Gluck IV } 1820cd93754SAlexander von Gluck IV 18351360674SAlexander von Gluck IV return B_OK; 18451360674SAlexander von Gluck IV } 185a8232073SAlexander von Gluck IV 186a8232073SAlexander von Gluck IV 187a8232073SAlexander von Gluck IV status_t 188a8232073SAlexander von Gluck IV radeon_dump_bios() 189a8232073SAlexander von Gluck IV { 190a8232073SAlexander von Gluck IV // For debugging use, dump card AtomBIOS 191a8232073SAlexander von Gluck IV radeon_shared_info &info = *gInfo->shared_info; 192a8232073SAlexander von Gluck IV 193a8232073SAlexander von Gluck IV TRACE("%s: Dumping AtomBIOS as ATOM_DEBUG is set...\n", 194a8232073SAlexander von Gluck IV __func__); 195a8232073SAlexander von Gluck IV 196a8232073SAlexander von Gluck IV FILE* fp; 197a8232073SAlexander von Gluck IV char filename[255]; 198a8232073SAlexander von Gluck IV sprintf(filename, "/boot/common/cache/tmp/radeon_hd_bios_1002_%" B_PRIx32 199359b926fSAlexander von Gluck IV "_%" B_PRIu32 ".bin", info.pciID, info.deviceIndex); 200a8232073SAlexander von Gluck IV 201a8232073SAlexander von Gluck IV fp = fopen(filename, "wb"); 202a8232073SAlexander von Gluck IV if (fp == NULL) { 203a8232073SAlexander von Gluck IV TRACE("%s: Cannot create AtomBIOS blob at %s\n", __func__, filename); 204a8232073SAlexander von Gluck IV return B_ERROR; 205a8232073SAlexander von Gluck IV } 206a8232073SAlexander von Gluck IV 207a8232073SAlexander von Gluck IV fwrite(gInfo->rom, info.rom_size, 1, fp); 208a8232073SAlexander von Gluck IV 209a8232073SAlexander von Gluck IV fclose(fp); 210a8232073SAlexander von Gluck IV 211a8232073SAlexander von Gluck IV TRACE("%s: AtomBIOS dumped to %s\n", __func__, filename); 212a8232073SAlexander von Gluck IV 213a8232073SAlexander von Gluck IV return B_OK; 214a8232073SAlexander von Gluck IV } 215