* Final (hopefully?) calculation for blank start/end
* Lets actually call PLLPower after PLLSet * Improve screen blanking function * Detect DAC/PLL to use separately from CRT id * Add DACSense that senses displays on DACA/DACB * Grab CRT in PLL code via gRegister crtid * Set overscan to 0 for now * Setting extended video modes now kinda works sometimes :-/ git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42397 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8f3fe015dc
commit
f2fe29a0db
@ -22,6 +22,79 @@ extern "C" void _sPrintf(const char *format, ...);
|
||||
#endif
|
||||
|
||||
|
||||
bool
|
||||
DACSense(uint8 dacIndex)
|
||||
{
|
||||
uint32 dacOffset = (dacIndex == 1) ? REG_DACB_OFFSET : REG_DACA_OFFSET;
|
||||
|
||||
// Backup current DAC values
|
||||
uint32 compEnable = Read32(OUT, dacOffset + DACA_COMPARATOR_ENABLE);
|
||||
uint32 control1 = Read32(OUT, dacOffset + DACA_CONTROL1);
|
||||
uint32 control2 = Read32(OUT, dacOffset + DACA_CONTROL2);
|
||||
uint32 detectControl = Read32(OUT, dacOffset + DACA_AUTODETECT_CONTROL);
|
||||
uint32 enable = Read32(OUT, dacOffset + DACA_ENABLE);
|
||||
|
||||
Write32(OUT, dacOffset + DACA_ENABLE, 1);
|
||||
// Acknowledge autodetect
|
||||
Write32Mask(OUT, dacOffset + DACA_AUTODETECT_INT_CONTROL, 0x01, 0x01);
|
||||
Write32Mask(OUT, dacOffset + DACA_AUTODETECT_CONTROL, 0, 0x00000003);
|
||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x00000001);
|
||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x00ff0000);
|
||||
|
||||
Write32(OUT, dacOffset + DACA_FORCE_DATA, 0);
|
||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0x00000001, 0x0000001);
|
||||
|
||||
Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
|
||||
0x00070000, 0x00070101);
|
||||
Write32(OUT, dacOffset + DACA_CONTROL1, 0x00050802);
|
||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x00000001);
|
||||
// Shutdown Bandgap voltage reference
|
||||
|
||||
snooze(5);
|
||||
|
||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x01010100);
|
||||
// Shutdown RGB
|
||||
|
||||
Write32(OUT, dacOffset + DACA_FORCE_DATA, 0x1e6);
|
||||
// 486 out of 1024
|
||||
snooze(200);
|
||||
|
||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0x01010100, 0x01010100);
|
||||
// Enable RGB
|
||||
snooze(88);
|
||||
|
||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x01010100);
|
||||
// Shutdown RGB
|
||||
|
||||
Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
|
||||
0x00000100, 0x00000100);
|
||||
|
||||
snooze(100);
|
||||
|
||||
// Get detected RGB channels
|
||||
// If only G is found, it could be a monochrome monitor, but we
|
||||
// don't bother checking.
|
||||
uint8 out = (Read32(OUT, dacOffset + DACA_COMPARATOR_OUTPUT) & 0x0E) >> 1;
|
||||
|
||||
// Restore stored DAC values
|
||||
Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
|
||||
compEnable, 0x00FFFFFF);
|
||||
Write32(OUT, dacOffset + DACA_CONTROL1, control1);
|
||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, control2, 0x000001FF);
|
||||
Write32Mask(OUT, dacOffset + DACA_AUTODETECT_CONTROL,
|
||||
detectControl, 0x000000FF);
|
||||
Write32Mask(OUT, dacOffset + DACA_ENABLE, enable, 0x000000FF);
|
||||
|
||||
if (out == 0x7) {
|
||||
TRACE("%s: DAC%d : Display device attached\n", __func__, dacIndex);
|
||||
return true;
|
||||
} else {
|
||||
TRACE("%s: DAC%d : No display device attached\n", __func__, dacIndex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DACGetElectrical(uint8 type, uint8 dac,
|
||||
uint8 *bandgap, uint8 *whitefine)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define FORMAT_TvCV 0x3
|
||||
|
||||
|
||||
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);
|
||||
|
@ -128,10 +128,12 @@ get_color_space_format(const display_mode &mode, uint32 &colorMode,
|
||||
|
||||
// Blacks the screen out, useful for mode setting
|
||||
static void
|
||||
CardBlankSet(bool blank)
|
||||
CardBlankSet(uint8 crtid, bool blank)
|
||||
{
|
||||
int blackColorReg = D1CRTC_BLACK_COLOR;
|
||||
int blankControlReg = D1CRTC_BLANK_CONTROL;
|
||||
int blackColorReg
|
||||
= (crtid == 1) ? D2CRTC_BLACK_COLOR : D1CRTC_BLACK_COLOR;
|
||||
int blankControlReg
|
||||
= (crtid == 1) ? D2CRTC_BLANK_CONTROL : D1CRTC_BLANK_CONTROL;
|
||||
|
||||
Write32(CRT, blackColorReg, 0);
|
||||
Write32Mask(CRT, blankControlReg, blank ? 1 << 8 : 0, 1 << 8);
|
||||
@ -233,12 +235,10 @@ CardModeSet(display_mode *mode)
|
||||
Write32(CRT, gRegister->crtHTotal,
|
||||
displayTiming.h_total - 1);
|
||||
|
||||
// Calculate blanking
|
||||
uint16 frontPorch = displayTiming.h_sync_start - displayTiming.h_display;
|
||||
uint16 backPorch = displayTiming.h_total - displayTiming.h_sync_end;
|
||||
|
||||
uint16 blankStart = frontPorch - OVERSCAN;
|
||||
uint16 blankEnd = backPorch;
|
||||
// Blanking
|
||||
uint16 blankStart = displayTiming.h_total
|
||||
+ displayTiming.h_display - displayTiming.h_sync_start;
|
||||
uint16 blankEnd = displayTiming.h_total - displayTiming.h_sync_start;
|
||||
|
||||
Write32(CRT, gRegister->crtHBlank,
|
||||
blankStart | (blankEnd << 16));
|
||||
@ -254,11 +254,9 @@ CardModeSet(display_mode *mode)
|
||||
Write32(CRT, gRegister->crtVTotal,
|
||||
displayTiming.v_total - 1);
|
||||
|
||||
frontPorch = displayTiming.v_sync_start - displayTiming.v_display;
|
||||
backPorch = displayTiming.v_total - displayTiming.v_sync_end;
|
||||
|
||||
blankStart = frontPorch - OVERSCAN;
|
||||
blankEnd = backPorch;
|
||||
blankStart = displayTiming.v_total
|
||||
+ displayTiming.v_display - displayTiming.v_sync_start;
|
||||
blankEnd = displayTiming.v_total - displayTiming.v_sync_start;
|
||||
|
||||
Write32(CRT, gRegister->crtVBlank,
|
||||
blankStart | (blankEnd << 16));
|
||||
@ -290,13 +288,14 @@ static void
|
||||
CardModeScale(display_mode *mode)
|
||||
{
|
||||
// No scaling
|
||||
//Write32(CRT, gRegister->sclUpdate, (1<<16));// Lock
|
||||
Write32(CRT, gRegister->sclUpdate, (1<<16));// Lock
|
||||
|
||||
// For now, default overscan
|
||||
#if 0
|
||||
Write32(CRT, D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
|
||||
(OVERSCAN << 16) | OVERSCAN); // LEFT | RIGHT
|
||||
Write32(CRT, D1MODE_EXT_OVERSCAN_TOP_BOTTOM,
|
||||
(OVERSCAN << 16) | OVERSCAN); // TOP | BOTTOM
|
||||
#endif
|
||||
|
||||
Write32(CRT, gRegister->viewportStart, 0);
|
||||
Write32(CRT, gRegister->viewportSize,
|
||||
@ -305,7 +304,7 @@ CardModeScale(display_mode *mode)
|
||||
Write32(CRT, gRegister->sclTapControl, 0);
|
||||
Write32(CRT, gRegister->modeCenter, 2);
|
||||
// D1MODE_DATA_FORMAT?
|
||||
//Write32(CRT, gRegister->sclUpdate, 0); // Unlock
|
||||
Write32(CRT, gRegister->sclUpdate, 0); // Unlock
|
||||
}
|
||||
|
||||
|
||||
@ -313,24 +312,40 @@ status_t
|
||||
radeon_set_display_mode(display_mode *mode)
|
||||
{
|
||||
uint8 crtNumber = 0;
|
||||
uint8 dacNumber = 0;
|
||||
|
||||
init_registers(crtNumber);
|
||||
|
||||
// TODO : this obviously breaks horribly on attached multiple outputs
|
||||
if (DACSense(0))
|
||||
dacNumber = 0;
|
||||
else if (DACSense(1))
|
||||
dacNumber = 1;
|
||||
|
||||
CardFBSet(mode);
|
||||
CardModeSet(mode);
|
||||
CardModeScale(mode);
|
||||
PLLSet(0, mode->timing.pixel_clock);
|
||||
|
||||
PLLSet(dacNumber, mode->timing.pixel_clock);
|
||||
// Set pixel clock
|
||||
|
||||
Write32(CRT, D1GRPH_LUT_SEL, 0);
|
||||
|
||||
DACSet(crtNumber, 0);
|
||||
// Set DAC A to crt 0
|
||||
DACPower(crtNumber, RHD_POWER_ON);
|
||||
CardBlankSet(false);
|
||||
DACSet(dacNumber, crtNumber);
|
||||
|
||||
// TODO : Shutdown unused PLL/DAC
|
||||
|
||||
// Power up the output
|
||||
PLLPower(dacNumber, RHD_POWER_ON);
|
||||
DACPower(dacNumber, RHD_POWER_ON);
|
||||
|
||||
// Ensure screen isn't blanked
|
||||
CardBlankSet(crtNumber, false);
|
||||
|
||||
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
|
||||
TRACE("CRT0 Status: 0x%X\n", crtstatus);
|
||||
crtstatus = Read32(CRT, D2CRTC_STATUS);
|
||||
TRACE("CRT1 Status: 0x%X\n", crtstatus);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -21,8 +21,8 @@
|
||||
#define FMT1_REG_OFFSET 0x0000
|
||||
#define FMT2_REG_OFFSET 0x800
|
||||
|
||||
#define OVERSCAN 8
|
||||
// default overscan? Applied to all sides
|
||||
#define OVERSCAN 0
|
||||
// TODO : Overscan and scaling support
|
||||
|
||||
status_t detect_crt_ranges();
|
||||
status_t create_mode_list(void);
|
||||
|
@ -187,9 +187,15 @@ PLLPower(uint8 pllIndex, int command)
|
||||
snooze(2);
|
||||
|
||||
if (info.device_chipset >= (RADEON_R600 | 0x20)) {
|
||||
uint16 pllDiffPostReg
|
||||
= (pllIndex == 1) ? RV620_EXT2_DIFF_POST_DIV_CNTL
|
||||
: RV620_EXT1_DIFF_POST_DIV_CNTL;
|
||||
uint16 pllDiffDriverEnable
|
||||
= (pllIndex == 1) ? RV62_EXT2_DIFF_DRIVER_ENABLE
|
||||
: RV62_EXT1_DIFF_DRIVER_ENABLE;
|
||||
// Sometimes we have to keep an unused PLL running. X Bug #18016
|
||||
if ((Read32(PLL, RV620_EXT1_DIFF_POST_DIV_CNTL)
|
||||
& RV62_EXT1_DIFF_DRIVER_ENABLE) == 0) {
|
||||
if ((Read32(PLL, pllDiffPostReg)
|
||||
& pllDiffDriverEnable) == 0) {
|
||||
Write32Mask(PLL, pllControlReg, 0x02, 0x02);
|
||||
// Power Down
|
||||
} else {
|
||||
@ -201,6 +207,11 @@ PLLPower(uint8 pllIndex, int command)
|
||||
|
||||
Write32Mask(PLL, pllControlReg, 0x2000, 0x2000);
|
||||
// Reset anti-glitch?
|
||||
|
||||
} else {
|
||||
Write32Mask(PLL, pllControlReg, 0x02, 0x02);
|
||||
// Power Down
|
||||
snooze(200);
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +344,8 @@ PLLSetLowLegacy(uint8 pllIndex, uint32 pixelClock, uint16 reference,
|
||||
Write32(PLL, pllExtPostDivSrc, 0x01);
|
||||
// Set source as PLL
|
||||
|
||||
PLLCRTCGrab(pllIndex, false);
|
||||
// TODO : better way to grab crt to work on?
|
||||
PLLCRTCGrab(pllIndex, gRegister->crtid);
|
||||
}
|
||||
|
||||
|
||||
@ -448,7 +460,8 @@ PLLSetLowR620(uint8 pllIndex, uint32 pixelClock, uint16 reference,
|
||||
Write32Mask(PLL, pllCntl, 0, 0x80000000);
|
||||
// needed and undocumented
|
||||
|
||||
PLLCRTCGrab(pllIndex, false);
|
||||
// TODO : better way to grab crt to work on?
|
||||
PLLCRTCGrab(pllIndex, gRegister->crtid);
|
||||
|
||||
if (hasDccg)
|
||||
DCCGCLKSet(pllIndex, RV620_DCCGCLK_GRAB);
|
||||
@ -492,11 +505,11 @@ PLLCalibrate(uint8 pllIndex)
|
||||
|
||||
|
||||
void
|
||||
PLLCRTCGrab(uint8 pllIndex, bool crt2)
|
||||
PLLCRTCGrab(uint8 pllIndex, uint8 crtid)
|
||||
{
|
||||
bool pll2IsCurrent;
|
||||
|
||||
if (!crt2) {
|
||||
if (crtid == 0) {
|
||||
pll2IsCurrent = Read32(PLL, PCLK_CRTC1_CNTL) & 0x00010000;
|
||||
|
||||
Write32Mask(PLL, PCLK_CRTC1_CNTL, (pllIndex == 0) ? 0x00010000 : 0,
|
||||
|
@ -42,7 +42,7 @@ void PLLSetLowR620(uint8 pllIndex, uint32 pixelClock, uint16 reference,
|
||||
uint16 feedback, uint16 post);
|
||||
status_t PLLPower(uint8 pllIndex, int command);
|
||||
status_t PLLCalibrate(uint8 pllIndex);
|
||||
void PLLCRTCGrab(uint8 pllIndex, bool crt2);
|
||||
void PLLCRTCGrab(uint8 pllIndex, uint8 crtid);
|
||||
bool DCCGCLKAvailable(uint8 pllIndex);
|
||||
void DCCGCLKSet(uint8 pllIndex, int set);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user