* 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
|
engine.cpp
|
||||||
hooks.cpp
|
hooks.cpp
|
||||||
pll.cpp
|
pll.cpp
|
||||||
|
mc.cpp
|
||||||
dac.cpp
|
dac.cpp
|
||||||
|
tmds.cpp
|
||||||
mode.cpp
|
mode.cpp
|
||||||
bios.cpp
|
bios.cpp
|
||||||
create_display_modes.cpp
|
create_display_modes.cpp
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "pll.h"
|
#include "pll.h"
|
||||||
|
#include "mc.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "radeon_hd.h"
|
#include "radeon_hd.h"
|
||||||
#include "pll.h"
|
#include "pll.h"
|
||||||
#include "dac.h"
|
#include "dac.h"
|
||||||
|
#include "tmds.h"
|
||||||
|
|
||||||
|
|
||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
@@ -85,6 +86,8 @@ struct register_info {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint16 location;
|
||||||
|
uint16 locationIndex;
|
||||||
uint32 vfreq_max;
|
uint32 vfreq_max;
|
||||||
uint32 vfreq_min;
|
uint32 vfreq_min;
|
||||||
uint32 hfreq_max;
|
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
|
inline uint32
|
||||||
_read32PLL(uint16 offset)
|
_read32PLL(uint16 offset)
|
||||||
{
|
{
|
||||||
@@ -200,14 +155,13 @@ Read32(uint32 subsystem, uint32 offset)
|
|||||||
default:
|
default:
|
||||||
case OUT:
|
case OUT:
|
||||||
case VGA:
|
case VGA:
|
||||||
|
case MC:
|
||||||
return _read32(offset);
|
return _read32(offset);
|
||||||
case CRT:
|
case CRT:
|
||||||
return _read32(offset);
|
return _read32(offset);
|
||||||
case PLL:
|
case PLL:
|
||||||
return _read32(offset);
|
return _read32(offset);
|
||||||
//return _read32PLL(offset);
|
//return _read32PLL(offset);
|
||||||
case MC:
|
|
||||||
return _read32MC(offset);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +173,7 @@ Write32(uint32 subsystem, uint32 offset, uint32 value)
|
|||||||
default:
|
default:
|
||||||
case OUT:
|
case OUT:
|
||||||
case VGA:
|
case VGA:
|
||||||
|
case MC:
|
||||||
_write32(offset, value);
|
_write32(offset, value);
|
||||||
return;
|
return;
|
||||||
case CRT:
|
case CRT:
|
||||||
@@ -228,9 +183,6 @@ Write32(uint32 subsystem, uint32 offset, uint32 value)
|
|||||||
_write32(offset, value);
|
_write32(offset, value);
|
||||||
//_write32PLL(offset, value);
|
//_write32PLL(offset, value);
|
||||||
return;
|
return;
|
||||||
case MC:
|
|
||||||
_write32MC(offset, value);
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,6 +195,7 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
|||||||
default:
|
default:
|
||||||
case OUT:
|
case OUT:
|
||||||
case VGA:
|
case VGA:
|
||||||
|
case MC:
|
||||||
temp = _read32(offset);
|
temp = _read32(offset);
|
||||||
break;
|
break;
|
||||||
case CRT:
|
case CRT:
|
||||||
@@ -252,9 +205,6 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
|||||||
temp = _read32(offset);
|
temp = _read32(offset);
|
||||||
//temp = _read32PLL(offset);
|
//temp = _read32PLL(offset);
|
||||||
break;
|
break;
|
||||||
case MC:
|
|
||||||
temp = _read32MC(offset);
|
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// only effect mask
|
// only effect mask
|
||||||
@@ -265,6 +215,7 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
|||||||
default:
|
default:
|
||||||
case OUT:
|
case OUT:
|
||||||
case VGA:
|
case VGA:
|
||||||
|
case MC:
|
||||||
_write32(offset, temp);
|
_write32(offset, temp);
|
||||||
return;
|
return;
|
||||||
case CRT:
|
case CRT:
|
||||||
@@ -274,9 +225,6 @@ Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
|
|||||||
_write32(offset, temp);
|
_write32(offset, temp);
|
||||||
//_write32PLL(offset, temp);
|
//_write32PLL(offset, temp);
|
||||||
return;
|
return;
|
||||||
case MC:
|
|
||||||
_write32MC(offset, temp);
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -375,3 +375,16 @@ DACPower(uint8 dacIndex, int mode)
|
|||||||
DACPowerModern(dacIndex, 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 DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine);
|
||||||
void DACSet(uint8 dacIndex, uint32 crtid);
|
void DACSet(uint8 dacIndex, uint32 crtid);
|
||||||
void DACPower(uint8 dacIndex, int mode);
|
void DACPower(uint8 dacIndex, int mode);
|
||||||
|
void DACAllIdle();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#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, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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, [email protected]
|
||||||
|
*/
|
||||||
|
#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);
|
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));
|
Write32(CRT, gRegister->grphUpdate, (1<<16));
|
||||||
// Lock for update (isn't this normally the other way around on VGA?
|
// 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);
|
init_registers(crtNumber);
|
||||||
|
|
||||||
// TODO : this obviously breaks horribly on attached multiple outputs
|
// TODO Populate gCRT with interface connection
|
||||||
if (DACSense(0))
|
if (DACSense(0))
|
||||||
dacNumber = 0;
|
dacNumber = 0;
|
||||||
else if (DACSense(1))
|
else if (DACSense(1))
|
||||||
dacNumber = 1;
|
dacNumber = 1;
|
||||||
|
|
||||||
|
TMDSSense(0); // DVI / HDMI
|
||||||
|
|
||||||
CardFBSet(mode);
|
CardFBSet(mode);
|
||||||
CardModeSet(mode);
|
CardModeSet(mode);
|
||||||
CardModeScale(mode);
|
CardModeScale(mode);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <ddc.h>
|
#include <ddc.h>
|
||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
|
|
||||||
|
#include "mc.h"
|
||||||
|
|
||||||
#define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)
|
#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