Author: kallisti5 Date: 2011-07-12 22:14:31 +0200 (Tue, 12 Jul 2011) New Revision: 42416 Changeset: https://dev.haiku-os.org/changeset/42416 Added: haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.h haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.h Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h Log: * Add mc.cpp for memory controller functions * Remove read32MC as it doesn't apply to radeon cards >= r600 * Add tmds.cpp for tmds connected monitor management (current radeons only have TMDSA for the moment) still needs TDMSPower, etc. * Add some MC calls to mode.cpp, causes KDL so commented out atm. * Add command to idle all DACs (although POWER_RESET doesn't do anything on DACs, we should be consistent) Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile 2011-07-12 20:14:31 UTC (rev 42416) @@ -13,7 +13,9 @@ engine.cpp hooks.cpp pll.cpp + mc.cpp dac.cpp + tmds.cpp mode.cpp bios.cpp create_display_modes.cpp Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp 2011-07-12 20:14:31 UTC (rev 42416) @@ -13,6 +13,7 @@ #include "utility.h" #include "pll.h" +#include "mc.h" #include <errno.h> #include <stdlib.h> Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h 2011-07-12 20:14:31 UTC (rev 42416) @@ -14,6 +14,7 @@ #include "radeon_hd.h" #include "pll.h" #include "dac.h" +#include "tmds.h" #include <edid.h> @@ -85,6 +86,8 @@ typedef struct { + uint16 location; + uint16 locationIndex; uint32 vfreq_max; uint32 vfreq_min; uint32 hfreq_max; @@ -130,54 +133,6 @@ inline uint32 -_read32MC(uint32 offset) -{ - radeon_shared_info &info = *gInfo->shared_info; - - if (info.device_chipset == RADEON_R600) { - _write32(RS600_MC_INDEX, ((offset & RS600_MC_INDEX_ADDR_MASK) - | RS600_MC_INDEX_CITF_ARB0)); - return _read32(RS600_MC_DATA); - } else if (info.device_chipset == (RADEON_R600 | 0x90) - || info.device_chipset == (RADEON_R700 | 0x40)) { - _write32(RS690_MC_INDEX, (offset & RS690_MC_INDEX_ADDR_MASK)); - return _read32(RS690_MC_DATA); - } else if (info.device_chipset == (RADEON_R700 | 0x80) - || info.device_chipset == (RADEON_R800 | 0x80)) { - _write32(RS780_MC_INDEX, offset & RS780_MC_INDEX_ADDR_MASK); - return _read32(RS780_MC_DATA); - } - - // eh. - return _read32(offset); -} - - -inline void -_write32MC(uint32 offset, uint32 data) -{ - radeon_shared_info &info = *gInfo->shared_info; - - if (info.device_chipset == RADEON_R600) { - _write32(RS600_MC_INDEX, ((offset & RS600_MC_INDEX_ADDR_MASK) - | RS600_MC_INDEX_CITF_ARB0 | RS600_MC_INDEX_WR_EN)); - _write32(RS600_MC_DATA, data); - } else if (info.device_chipset == (RADEON_R600 | 0x90) - || info.device_chipset == (RADEON_R700 | 0x40)) { - _write32(RS690_MC_INDEX, ((offset & RS690_MC_INDEX_ADDR_MASK) - | RS690_MC_INDEX_WR_EN)); - _write32(RS690_MC_DATA, data); - _write32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); - } else if (info.device_chipset == (RADEON_R700 | 0x80) - || info.device_chipset == (RADEON_R800 | 0x80)) { - _write32(RS780_MC_INDEX, ((offset & RS780_MC_INDEX_ADDR_MASK) - | RS780_MC_INDEX_WR_EN)); - _write32(RS780_MC_DATA, data); - } -} - - -inline uint32 _read32PLL(uint16 offset) { _write32(CLOCK_CNTL_INDEX, offset & PLL_ADDR); @@ -200,14 +155,13 @@ default: case OUT: case VGA: + case MC: return _read32(offset); case CRT: return _read32(offset); case PLL: return _read32(offset); //return _read32PLL(offset); - case MC: - return _read32MC(offset); }; } @@ -219,6 +173,7 @@ default: case OUT: case VGA: + case MC: _write32(offset, value); return; case CRT: @@ -228,9 +183,6 @@ _write32(offset, value); //_write32PLL(offset, value); return; - case MC: - _write32MC(offset, value); - return; }; } @@ -243,6 +195,7 @@ default: case OUT: case VGA: + case MC: temp = _read32(offset); break; case CRT: @@ -252,9 +205,6 @@ temp = _read32(offset); //temp = _read32PLL(offset); break; - case MC: - temp = _read32MC(offset); - break; }; // only effect mask @@ -265,6 +215,7 @@ default: case OUT: case VGA: + case MC: _write32(offset, temp); return; case CRT: @@ -274,9 +225,6 @@ _write32(offset, temp); //_write32PLL(offset, temp); return; - case MC: - _write32MC(offset, temp); - return; }; } Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.cpp 2011-07-12 20:14:31 UTC (rev 42416) @@ -375,3 +375,16 @@ DACPowerModern(dacIndex, mode); } + +void +DACAllIdle() +{ + // This really doesn't do anything on DAC monitors + // Implimented for completeness + uint8 i; + + for (i = 0; i < 2; i++) { + DACPower(i, RHD_POWER_RESET); + } +} + Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/dac.h 2011-07-12 20:14:31 UTC (rev 42416) @@ -26,6 +26,7 @@ void DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine); void DACSet(uint8 dacIndex, uint32 crtid); void DACPower(uint8 dacIndex, int mode); +void DACAllIdle(); #endif Added: haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.cpp (rev 0) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.cpp 2011-07-12 20:14:31 UTC (rev 42416) @@ -0,0 +1,88 @@ +/* + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@xxxxxxxxxxx + */ + + +#include "accelerant_protos.h" +#include "accelerant.h" +#include "utility.h" +#include "mc.h" + + +/* Read32/Write32 for MC can hande the fact that some cards need to write + to a special MC interface, while others just write to the card directly. + As of R600 - R800 though the special MC interface doesn't seem to exist +*/ + + +#define TRACE_MC +#ifdef TRACE_MC +extern "C" void _sPrintf(const char *format, ...); +# define TRACE(x...) _sPrintf("radeon_hd: " x) +#else +# define TRACE(x...) ; +#endif + + +uint64 +MCFBLocation(uint16 chipset, uint32* size) +{ + // TODO : R800 : This is only valid for all R6xx and R7xx? + uint32 fbLocationReg = Read32(MC, R7XX_MC_VM_FB_LOCATION); + *size = (((fbLocationReg & 0xFFFF0000) + - ((fbLocationReg & 0xFFFF) << 16))) << 8; + return (fbLocationReg & 0xFFFF) << 24; +} + + +uint32 +MCIdle() +{ + uint32 turboencabulator; + if (!((turboencabulator = Read32(MC, SRBM_STATUS)) & + (VMC_BUSY_bit | MCB_BUSY_bit | + MCDZ_BUSY_bit | MCDY_BUSY_bit | MCDX_BUSY_bit | MCDW_BUSY_bit))) + return 0; + + return turboencabulator; +} + + +status_t +MCFBSetup(uint32 newFbLocation, uint32 newFbSize) +{ + uint32 oldFbSize; + uint64 oldFbLocation = MCFBLocation(0, &oldFbSize); + + if (oldFbLocation == newFbLocation + && oldFbSize == newFbSize) { + TRACE("%s: not adjusting frame buffer as it is already correct\n", + __func__); + return B_OK; + } + + if (oldFbLocation >> 32) + TRACE("%s: board claims to use a frame buffer address > 32-bits\n", + __func__); + + uint32 idleState = MCIdle(); + if (idleState > 0) { + TRACE("%s: Cannot modify non-idle MC! idleState: %X\n", + __func__, idleState); + return B_ERROR; + } + + TRACE("%s: Setting MC/FB from 0x%08X to 0x%08X [size 0x%08X]\n", + __func__, oldFbLocation, newFbLocation, newFbSize); + + // The MC Write32 will handle cards needing a special MC read/write register + Write32(MC, R6XX_MC_VM_FB_LOCATION, + R6XX_FB_LOCATION(newFbLocation, newFbSize)); + Write32(MC, R6XX_HDP_NONSURFACE_BASE, R6XX_HDP_LOCATION(newFbLocation)); + + return B_OK; +} Added: haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.h (rev 0) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mc.h 2011-07-12 20:14:31 UTC (rev 42416) @@ -0,0 +1,22 @@ +/* + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@xxxxxxxxxxx + */ +#ifndef RADEON_HD_MC_H +#define RADEON_HD_MC_H + + +#define R6XX_FB_LOCATION(address, size) \ + (((((address) + (size)) >> 8) & 0xFFFF0000) | (((address) >> 24) & 0xFFFF)) +#define R6XX_HDP_LOCATION(address) \ + ((((address) >> 8) & 0x00FF0000)) + + +uint64 MCFBLocation(uint16 chipset, uint32* size); +status_t MCFBSetup(uint32 newFbLocation, uint32 newFbSize); + + +#endif Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.cpp 2011-07-12 20:14:31 UTC (rev 42416) @@ -149,6 +149,17 @@ get_color_space_format(*mode, colorMode, bytesPerRow, bitsPerPixel); + #if 0 + // TMDSAllIdle // DVI / HDMI + // LVTMAAllIdle // DVI + DACAllIdle(); + + // Set the inital frame buffer location in the memory controler + uint32 mcFbSize; + MCFBLocation(0, &mcFbSize); + MCFBSetup(Read32(OUT, R6XX_CONFIG_FB_BASE), mcFbSize); + #endif + Write32(CRT, gRegister->grphUpdate, (1<<16)); // Lock for update (isn't this normally the other way around on VGA? @@ -316,12 +327,14 @@ init_registers(crtNumber); - // TODO : this obviously breaks horribly on attached multiple outputs + // TODO Populate gCRT with interface connection if (DACSense(0)) dacNumber = 0; else if (DACSense(1)) dacNumber = 1; + TMDSSense(0); // DVI / HDMI + CardFBSet(mode); CardModeSet(mode); CardModeScale(mode); Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h 2011-07-11 21:43:04 UTC (rev 42415) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/mode.h 2011-07-12 20:14:31 UTC (rev 42416) @@ -13,6 +13,7 @@ #include <ddc.h> #include <edid.h> +#include "mc.h" #define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC) Added: haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.cpp =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.cpp (rev 0) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.cpp 2011-07-12 20:14:31 UTC (rev 42416) @@ -0,0 +1,52 @@ +/* + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@xxxxxxxxxxx + */ + + +#include "accelerant_protos.h" +#include "accelerant.h" +#include "utility.h" +#include "tmds.h" + + +#define TRACE_TMDS +#ifdef TRACE_TMDS +extern "C" void _sPrintf(const char *format, ...); +# define TRACE(x...) _sPrintf("radeon_hd: " x) +#else +# define TRACE(x...) ; +#endif + + +bool +TMDSSense(uint8 tmdsIndex) +{ + // For now radeon cards only have TMDSA and no TMDSB + + // Backup current TMDS values + uint32 loadDetect = Read32(OUT, TMDSA_LOAD_DETECT); + + // Call TMDS load detect on TMDSA + Write32Mask(OUT, TMDSA_LOAD_DETECT, 0x00000001, 0x00000001); + snooze(1); + + // Check result of TMDS load detect + bool result = Read32(OUT, TMDSA_LOAD_DETECT) & 0x00000010; + + // Restore saved value + Write32Mask(OUT, TMDSA_LOAD_DETECT, loadDetect, 0x00000001); + + if (result) { + TRACE("%s: TMDS%d: Display device attached\n", __func__, tmdsIndex); + } else { + TRACE("%s: TMDS%d: No display device attached\n", __func__, tmdsIndex); + } + + return result; +} + + Added: haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.h =================================================================== --- haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.h (rev 0) +++ haiku/trunk/src/add-ons/accelerants/radeon_hd/tmds.h 2011-07-12 20:14:31 UTC (rev 42416) @@ -0,0 +1,15 @@ +/* + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck, kallisti5@xxxxxxxxxxx + */ +#ifndef RADEON_HD_TMDS_H +#define RADEON_HD_TMDS_H + + +bool TMDSSense(uint8 tmdsIndex); + + +#endif