* 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) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42416 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -13,7 +13,9 @@ Addon radeon_hd.accelerant :
|
||||
engine.cpp
|
||||
hooks.cpp
|
||||
pll.cpp
|
||||
mc.cpp
|
||||
dac.cpp
|
||||
tmds.cpp
|
||||
mode.cpp
|
||||
bios.cpp
|
||||
create_display_modes.cpp
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "utility.h"
|
||||
#include "pll.h"
|
||||
#include "mc.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "radeon_hd.h"
|
||||
#include "pll.h"
|
||||
#include "dac.h"
|
||||
#include "tmds.h"
|
||||
|
||||
|
||||
#include <edid.h>
|
||||
@@ -85,6 +86,8 @@ struct register_info {
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16 location;
|
||||
uint16 locationIndex;
|
||||
uint32 vfreq_max;
|
||||
uint32 vfreq_min;
|
||||
uint32 hfreq_max;
|
||||
@@ -129,54 +132,6 @@ _write32(uint32 offset, uint32 value)
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -200,14 +155,13 @@ Read32(uint32 subsystem, uint32 offset)
|
||||
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 @@ Write32(uint32 subsystem, uint32 offset, uint32 value)
|
||||
default:
|
||||
case OUT:
|
||||
case VGA:
|
||||
case MC:
|
||||
_write32(offset, value);
|
||||
return;
|
||||
case CRT:
|
||||
@@ -228,9 +183,6 @@ Write32(uint32 subsystem, uint32 offset, uint32 value)
|
||||
_write32(offset, value);
|
||||
//_write32PLL(offset, value);
|
||||
return;
|
||||
case MC:
|
||||
_write32MC(offset, value);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -243,6 +195,7 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
||||
default:
|
||||
case OUT:
|
||||
case VGA:
|
||||
case MC:
|
||||
temp = _read32(offset);
|
||||
break;
|
||||
case CRT:
|
||||
@@ -252,9 +205,6 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
||||
temp = _read32(offset);
|
||||
//temp = _read32PLL(offset);
|
||||
break;
|
||||
case MC:
|
||||
temp = _read32MC(offset);
|
||||
break;
|
||||
};
|
||||
|
||||
// only effect mask
|
||||
@@ -265,6 +215,7 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
||||
default:
|
||||
case OUT:
|
||||
case VGA:
|
||||
case MC:
|
||||
_write32(offset, temp);
|
||||
return;
|
||||
case CRT:
|
||||
@@ -274,9 +225,6 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
||||
_write32(offset, temp);
|
||||
//_write32PLL(offset, temp);
|
||||
return;
|
||||
case MC:
|
||||
_write32MC(offset, temp);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -375,3 +375,16 @@ DACPower(uint8 dacIndex, int mode)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ bool DACSense(uint8 dacIndex);
|
||||
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
|
||||
|
||||
@@ -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@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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@unixzen.com
|
||||
*/
|
||||
#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
|
||||
@@ -149,6 +149,17 @@ CardFBSet(display_mode *mode)
|
||||
|
||||
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 @@ radeon_set_display_mode(display_mode *mode)
|
||||
|
||||
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);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <ddc.h>
|
||||
#include <edid.h>
|
||||
|
||||
#include "mc.h"
|
||||
|
||||
#define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)
|
||||
|
||||
|
||||
@@ -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@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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@unixzen.com
|
||||
*/
|
||||
#ifndef RADEON_HD_TMDS_H
|
||||
#define RADEON_HD_TMDS_H
|
||||
|
||||
|
||||
bool TMDSSense(uint8 tmdsIndex);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user