* Move to common MMIO function set to make card subsystem access easier

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42159 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV
2011-06-13 22:28:13 +00:00
parent d9e412b339
commit aa2a6e33cb
4 changed files with 237 additions and 166 deletions
+108 -37
View File
@@ -82,6 +82,13 @@ struct register_info {
#define HEAD_MODE_CLONE 0x03
#define HEAD_MODE_LVDS_PANEL 0x08
// register MMIO modes
#define OUT 0x1 // direct MMIO calls
#define CRT 0x2 // crt controler calls
#define VGA 0x3 // vga calls
#define PLL 0x4 // PLL calls
#define MC 0x5 // Memory Controler calls
extern accelerant_info *gInfo;
extern register_info *gRegister;
@@ -92,100 +99,164 @@ status_t init_registers(uint8 crtid);
// register access
inline uint32
read32(uint32 offset)
_read32(uint32 offset)
{
return *(volatile uint32 *)(gInfo->regs + offset);
}
inline void
write32(uint32 offset, uint32 value)
_write32(uint32 offset, uint32 value)
{
*(volatile uint32 *)(gInfo->regs + offset) = value;
}
inline void
write32AtMask(uint32 offset, uint32 value, uint32 mask)
{
uint32 temp = read32(offset);
temp &= ~mask;
temp |= value & mask;
write32(offset, temp);
}
inline uint32
read32MC(uint32 offset)
_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)
_write32(RS600_MC_INDEX, ((offset & RS600_MC_INDEX_ADDR_MASK)
| RS600_MC_INDEX_CITF_ARB0));
return read32(RS600_MC_DATA);
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);
_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);
_write32(RS780_MC_INDEX, offset & RS780_MC_INDEX_ADDR_MASK);
return _read32(RS780_MC_DATA);
}
// eh.
return read32(offset);
return _read32(offset);
}
inline void
write32MC(uint32 offset, uint32 data)
_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)
_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);
_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)
_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);
_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)
_write32(RS780_MC_INDEX, ((offset & RS780_MC_INDEX_ADDR_MASK)
| RS780_MC_INDEX_WR_EN));
write32(RS780_MC_DATA, data);
_write32(RS780_MC_DATA, data);
}
}
inline uint32
read32PLL(uint16 offset)
_read32PLL(uint16 offset)
{
write32(CLOCK_CNTL_INDEX, offset & PLL_ADDR);
return read32(CLOCK_CNTL_DATA);
_write32(CLOCK_CNTL_INDEX, offset & PLL_ADDR);
return _read32(CLOCK_CNTL_DATA);
}
inline void
write32PLL(uint16 offset, uint32 data)
_write32PLL(uint16 offset, uint32 data)
{
write32(CLOCK_CNTL_INDEX, (offset & PLL_ADDR) | PLL_WR_EN);
write32(CLOCK_CNTL_DATA, data);
_write32(CLOCK_CNTL_INDEX, (offset & PLL_ADDR) | PLL_WR_EN);
_write32(CLOCK_CNTL_DATA, data);
}
inline uint32
Read32(uint32 subsystem, uint32 offset)
{
switch (subsystem) {
default:
case OUT:
case VGA:
return _read32(offset);
case CRT:
return _read32(offset);
case PLL:
return _read32PLL(offset);
case MC:
return _read32MC(offset);
};
}
inline void
write32PLLAtMask(uint16 offset, uint32 value, uint32 mask)
Write32(uint32 subsystem, uint32 offset, uint32 value)
{
uint32 temp = read32PLL(offset);
switch (subsystem) {
default:
case OUT:
case VGA:
_write32(offset, value);
return;
case CRT:
_write32(offset, value);
return;
case PLL:
_write32PLL(offset, value);
return;
case MC:
_write32MC(offset, value);
return;
};
}
inline void
Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
{
uint32 temp;
switch (subsystem) {
default:
case OUT:
case VGA:
temp = _read32(offset);
break;
case CRT:
temp = _read32(offset);
break;
case PLL:
temp = _read32PLL(offset);
break;
case MC:
temp = _read32MC(offset);
break;
};
// only effect mask
temp &= ~mask;
temp |= value & mask;
write32PLL(offset, temp);
switch (subsystem) {
default:
case OUT:
case VGA:
_write32(offset, temp);
return;
case CRT:
_write32(offset, temp);
return;
case PLL:
_write32PLL(offset, temp);
return;
case MC:
_write32MC(offset, temp);
return;
};
}
+6 -6
View File
@@ -89,7 +89,7 @@ UINT32
CailReadATIRegister(VOID* CAIL, UINT32 idx)
{
TRACE("AtomBios callback %s, idx (0x%X)\n", __func__, idx << 2);
return read32(idx << 2);
return Read32(OUT, idx << 2);
}
@@ -100,7 +100,7 @@ CailWriteATIRegister(VOID *CAIL, UINT32 idx, UINT32 data)
// TODO : save MMIO via atomSaveRegisters in CailWriteATIRegister
// atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterMMIO, idx << 2);
write32(idx << 2, data);
Write32(OUT, idx << 2, data);
}
@@ -131,7 +131,7 @@ ULONG
CailReadPLL(VOID *CAIL, ULONG address)
{
TRACE("AtomBios callback %s, addr (0x%X)\n", __func__, address);
return read32PLL(address);
return Read32(PLL, address);
}
@@ -143,7 +143,7 @@ CailWritePLL(VOID *CAIL, ULONG address, ULONG data)
// TODO : save PLL registers
// atomSaveRegisters((atomBiosHandlePtr)CAIL, atomRegisterPLL, address);
// TODO : Assumed screen index 0
write32PLL(address, data);
Write32(PLL, address, data);
}
@@ -186,7 +186,7 @@ CailReadFBData(VOID* CAIL, UINT32 idx)
// If we have a physical offset for our frame buffer, use it
if (fbLocation > 0)
ret = read32(fbLocation + idx);
ret = Read32(PLL, fbLocation + idx);
else {
TRACE("%s: ERROR: Frame Buffer offset not defined\n",
__func__);
@@ -209,7 +209,7 @@ CailWriteFBData(VOID *CAIL, UINT32 idx, UINT32 data)
// If we have a physical offset for our frame buffer, use it
if (fbLocation > 0)
write32(fbLocation + idx, data);
Write32(OUT, fbLocation + idx, data);
else
TRACE("%s: ERROR: Frame Buffer offset not defined\n",
__func__);
+58 -58
View File
@@ -134,8 +134,8 @@ CardBlankSet(bool blank)
blackColorReg = D1CRTC_BLACK_COLOR;
blankControlReg = D1CRTC_BLANK_CONTROL;
write32(blackColorReg, 0);
write32AtMask(blankControlReg, blank ? 1 << 8 : 0, 1 << 8);
Write32(CRT, blackColorReg, 0);
Write32Mask(CRT, blankControlReg, blank ? 1 << 8 : 0, 1 << 8);
}
@@ -149,39 +149,39 @@ CardFBSet(display_mode *mode)
get_color_space_format(*mode, colorMode, bytesPerRow, bitsPerPixel);
// Disable VGA mode to enable Radeon extended registers
write32AtMask(VGA_RENDER_CONTROL, 0, 0x00030000);
write32AtMask(VGA_MODE_CONTROL, 0, 0x00000030);
write32AtMask(VGA_HDP_CONTROL, 0x00010010, 0x00010010);
write32AtMask(gRegister->vgaControl, 0, D1VGA_MODE_ENABLE
Write32Mask(VGA, VGA_RENDER_CONTROL, 0, 0x00030000);
Write32Mask(VGA, VGA_MODE_CONTROL, 0, 0x00000030);
Write32Mask(VGA, VGA_HDP_CONTROL, 0x00010010, 0x00010010);
Write32Mask(VGA, gRegister->vgaControl, 0, D1VGA_MODE_ENABLE
| D1VGA_TIMING_SELECT | D1VGA_SYNC_POLARITY_SELECT);
// disable R/B swap, disable tiling, disable 16bit alpha, etc.
write32AtMask(gRegister->grphEnable, 1, 0x00000001);
write32(gRegister->grphControl, 0);
Write32Mask(CRT, gRegister->grphEnable, 1, 0x00000001);
Write32(CRT, gRegister->grphControl, 0);
// set color mode on video card
switch (mode->space) {
case B_CMAP8:
write32AtMask(gRegister->grphControl,
Write32Mask(CRT, gRegister->grphControl,
0, 0x00000703);
break;
case B_RGB15_LITTLE:
write32AtMask(gRegister->grphControl,
Write32Mask(CRT, gRegister->grphControl,
0x000001, 0x00000703);
break;
case B_RGB16_LITTLE:
write32AtMask(gRegister->grphControl,
Write32Mask(CRT, gRegister->grphControl,
0x000101, 0x00000703);
break;
case B_RGB24_LITTLE:
case B_RGB32_LITTLE:
default:
write32AtMask(gRegister->grphControl,
Write32Mask(CRT, gRegister->grphControl,
0x000002, 0x00000703);
break;
}
write32(gRegister->grphSwapControl, 0);
Write32(CRT, gRegister->grphSwapControl, 0);
// only for chipsets > r600
// R5xx - RS690 case is GRPH_CONTROL bit 16
@@ -191,27 +191,27 @@ CardFBSet(display_mode *mode)
// Tell GPU which frame buffer address to draw from
if (gInfo->shared_info->device_chipset >= (uint16)(RADEON_R700 & 0x70)) {
write32(gRegister->grphPrimarySurfaceAddrHigh,
Write32(CRT, gRegister->grphPrimarySurfaceAddrHigh,
(fbAddress >> 32) & 0xf);
write32(gRegister->grphSecondarySurfaceAddrHigh,
Write32(CRT, gRegister->grphSecondarySurfaceAddrHigh,
(fbAddress >> 32) & 0xf);
}
write32(gRegister->grphPrimarySurfaceAddr,
Write32(CRT, gRegister->grphPrimarySurfaceAddr,
fbAddress & 0xffffffff);
write32(gRegister->grphSecondarySurfaceAddr,
Write32(CRT, gRegister->grphSecondarySurfaceAddr,
fbAddress & 0xffffffff);
write32(gRegister->grphPitch, bytesPerRow / 4);
write32(gRegister->grphSurfaceOffsetX, 0);
write32(gRegister->grphSurfaceOffsetY, 0);
write32(gRegister->grphXStart, 0);
write32(gRegister->grphYStart, 0);
write32(gRegister->grphXEnd, mode->virtual_width);
write32(gRegister->grphYEnd, mode->virtual_height);
Write32(CRT, gRegister->grphPitch, bytesPerRow / 4);
Write32(CRT, gRegister->grphSurfaceOffsetX, 0);
Write32(CRT, gRegister->grphSurfaceOffsetY, 0);
Write32(CRT, gRegister->grphXStart, 0);
Write32(CRT, gRegister->grphYStart, 0);
Write32(CRT, gRegister->grphXEnd, mode->virtual_width);
Write32(CRT, gRegister->grphYEnd, mode->virtual_height);
/* D1Mode registers */
write32(gRegister->modeDesktopHeight, mode->virtual_height);
Write32(CRT, gRegister->modeDesktopHeight, mode->virtual_height);
// update shared info
gInfo->shared_info->bytes_per_row = bytesPerRow;
@@ -229,10 +229,10 @@ CardModeSet(display_mode *mode)
__func__, displayTiming.h_display, displayTiming.v_display);
// enable read requests
write32AtMask(gRegister->grphControl, 0, 0x01000000);
Write32Mask(CRT, gRegister->grphControl, 0, 0x01000000);
// *** Horizontal
write32(gRegister->crtHTotal,
Write32(CRT, gRegister->crtHTotal,
displayTiming.h_total - 1);
#if 0
@@ -240,89 +240,89 @@ CardModeSet(display_mode *mode)
uint16 blankStart = displayTiming.h_display;
uint16 blankEnd = displayTiming.h_total;
write32(gRegister->crtHBlank,
Write32(CRT, gRegister->crtHBlank,
blankStart | (blankEnd << 16));
#endif
write32(gRegister->crtHSync,
Write32(CRT, gRegister->crtHSync,
(displayTiming.h_sync_end - displayTiming.h_sync_start) << 16);
// set flag for neg. H sync. M76 Register Reference Guide 2-256
write32AtMask(gRegister->crtHPolarity,
Write32Mask(CRT, gRegister->crtHPolarity,
displayTiming.flags & B_POSITIVE_HSYNC ? 0 : 1, 0x1);
// *** Vertical
write32(gRegister->crtVTotal,
Write32(CRT, gRegister->crtVTotal,
displayTiming.v_total - 1);
#if 0
blankStart = displayTiming.v_display;
blankEnd = displayTiming.v_total;
write32(gRegister->crtVBlank,
Write32(CRT, gRegister->crtVBlank,
blankStart | (blankEnd << 16));
#endif
// Set Interlace if specified within mode line
if (displayTiming.flags & B_TIMING_INTERLACED) {
write32(gRegister->crtInterlace, 0x1);
write32(gRegister->modeDataFormat, 0x1);
Write32(CRT, gRegister->crtInterlace, 0x1);
Write32(CRT, gRegister->modeDataFormat, 0x1);
} else {
write32(gRegister->crtInterlace, 0x0);
write32(gRegister->modeDataFormat, 0x0);
Write32(CRT, gRegister->crtInterlace, 0x0);
Write32(CRT, gRegister->modeDataFormat, 0x0);
}
write32(gRegister->crtVSync,
Write32(CRT, gRegister->crtVSync,
(displayTiming.v_sync_end - displayTiming.v_sync_start) << 16);
// set flag for neg. V sync. M76 Register Reference Guide 2-258
// we don't need a mask here as this is the only param for Vertical
write32(gRegister->crtVPolarity,
Write32(CRT, gRegister->crtVPolarity,
displayTiming.flags & B_POSITIVE_VSYNC ? 0 : 1);
/* set D1CRTC_HORZ_COUNT_BY2_EN to 0;
should only be set to 1 on 30bpp DVI modes
*/
write32AtMask(gRegister->crtCountControl, 0x0, 0x1);
Write32Mask(CRT, gRegister->crtCountControl, 0x0, 0x1);
}
static void
CardModeScale(display_mode *mode)
{
write32(gRegister->viewportSize,
Write32(CRT, gRegister->viewportSize,
mode->timing.v_display | (mode->timing.h_display << 16));
write32(gRegister->viewportStart, 0);
Write32(CRT, gRegister->viewportStart, 0);
// For now, no overscan support
write32(D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
Write32(CRT, D1MODE_EXT_OVERSCAN_LEFT_RIGHT,
(0 << 16) | 0); // LEFT | RIGHT
write32(D1MODE_EXT_OVERSCAN_TOP_BOTTOM,
Write32(CRT, D1MODE_EXT_OVERSCAN_TOP_BOTTOM,
(0 << 16) | 0); // TOP | BOTTOM
// No scaling
write32(gRegister->sclUpdate, (1<<16)); // Lock
write32(gRegister->sclEnable, 0);
write32(gRegister->sclTapControl, 0);
write32(gRegister->modeCenter, 0);
write32(gRegister->sclUpdate, 0); // Unlock
Write32(CRT, gRegister->sclUpdate, (1<<16));// Lock
Write32(CRT, gRegister->sclEnable, 0);
Write32(CRT, gRegister->sclTapControl, 0);
Write32(CRT, gRegister->modeCenter, 0);
Write32(CRT, gRegister->sclUpdate, 0); // Unlock
#if 0
// Auto scale keeping aspect ratio
write32(regOffset + D1MODE_CENTER, 1);
Write32(CRT, regOffset + D1MODE_CENTER, 1);
write32(regOffset + D1SCL_UPDATE, 0);
write32(regOffset + D1SCL_FLIP_CONTROL, 0);
Write32(CRT, regOffset + D1SCL_UPDATE, 0);
Write32(CRT, regOffset + D1SCL_FLIP_CONTROL, 0);
write32(regOffset + D1SCL_ENABLE, 1);
write32(regOffset + D1SCL_HVSCALE, 0x00010001);
Write32(CRT, regOffset + D1SCL_ENABLE, 1);
Write32(CRT, regOffset + D1SCL_HVSCALE, 0x00010001);
write32(regOffset + D1SCL_TAP_CONTROL, 0x00000101);
Write32(CRT, regOffset + D1SCL_TAP_CONTROL, 0x00000101);
write32(regOffset + D1SCL_HFILTER, 0x00030100);
write32(regOffset + D1SCL_VFILTER, 0x00030100);
Write32(CRT, regOffset + D1SCL_HFILTER, 0x00030100);
Write32(CRT, regOffset + D1SCL_VFILTER, 0x00030100);
write32(regOffset + D1SCL_DITHER, 0x00001010);
Write32(CRT, regOffset + D1SCL_DITHER, 0x00001010);
#endif
}
@@ -343,7 +343,7 @@ radeon_set_display_mode(display_mode *mode)
DACPower(0, RHD_POWER_ON);
CardBlankSet(false);
int32 crtstatus = read32(D1CRTC_STATUS);
int32 crtstatus = Read32(CRT, D1CRTC_STATUS);
TRACE("CRT0 Status: 0x%X\n", crtstatus);
return B_OK;
+65 -65
View File
@@ -149,7 +149,7 @@ PLLPower(uint8 pllIndex, int command)
if (hasDccg)
DCCGCLKSet(pllIndex, RV620_DCCGCLK_RESET);
write32PLLAtMask(pllControlReg, 0, 0x02);
Write32Mask(PLL, pllControlReg, 0, 0x02);
// Power On
snooze(2);
PLLCalibrate(pllIndex);
@@ -166,10 +166,10 @@ PLLPower(uint8 pllIndex, int command)
if (hasDccg)
DCCGCLKSet(pllIndex, RV620_DCCGCLK_RELEASE);
write32PLLAtMask(pllControlReg, 0x01, 0x01);
Write32Mask(PLL, pllControlReg, 0x01, 0x01);
// Reset
snooze(2);
write32PLLAtMask(pllControlReg, 0, 0x02);
Write32Mask(PLL, pllControlReg, 0, 0x02);
// Power On
snooze(2);
return B_OK;
@@ -182,14 +182,14 @@ PLLPower(uint8 pllIndex, int command)
if (hasDccg)
DCCGCLKSet(pllIndex, RV620_DCCGCLK_RELEASE);
write32PLLAtMask(pllControlReg, 0x01, 0x01);
Write32Mask(PLL, pllControlReg, 0x01, 0x01);
// Reset
snooze(2);
// Sometimes we have to keep an unused PLL running. Xorg Bug #18016
if ((read32PLL(RV620_EXT1_DIFF_POST_DIV_CNTL)
if ((Read32(PLL, RV620_EXT1_DIFF_POST_DIV_CNTL)
& RV62_EXT1_DIFF_DRIVER_ENABLE) == 0) {
write32PLLAtMask(pllControlReg, 0x02, 0x02);
Write32Mask(PLL, pllControlReg, 0x02, 0x02);
// Power Down
} else {
TRACE("%s: PHYA differential clock driver not disabled\n",
@@ -198,7 +198,7 @@ PLLPower(uint8 pllIndex, int command)
snooze(200);
write32PLLAtMask(pllControlReg, 0x2000, 0x2000);
Write32Mask(PLL, pllControlReg, 0x2000, 0x2000);
// Reset anti-glitch?
}
@@ -247,15 +247,15 @@ PLLSet(uint8 pllIndex, uint32 pixelClock)
uint16 pllPostDividerSrcReg
= (pllIndex == 1) ? EXT2_PPLL_POST_DIV_SRC : EXT1_PPLL_POST_DIV_SRC;
write32PLLAtMask(pllIntSSControlReg, 0, 0x00000001);
Write32Mask(PLL, pllIntSSControlReg, 0, 0x00000001);
// Disable Spread Spectrum
uint32 referenceDivider = reference;
uint32 feedbackDivider = read32PLL(pllFeedbackDividerReg) & ~0x07FF003F;
uint32 feedbackDivider = Read32(PLL, pllFeedbackDividerReg) & ~0x07FF003F;
feedbackDivider |= ((feedback << 16) | 0x0030) & 0x07FF003F;
uint32 postDivider = read32PLL(pllPostDividerReg) & ~0x0000007F;
uint32 postDivider = Read32(PLL, pllPostDividerReg) & ~0x0000007F;
postDivider |= post & 0x0000007F;
uint32 control;
@@ -267,54 +267,54 @@ PLLSet(uint8 pllIndex, uint32 pixelClock)
uint8 symPostDiv = post & 0x0000007F;
/* switch to external */
write32PLL(pllPostDividerSrcReg, 0);
write32PLLAtMask(pllDisplayClockControlReg, 0x00000200, 0x00000300);
write32PLLAtMask(pllPostDividerReg, 0, 0x00000100);
Write32(PLL, pllPostDividerSrcReg, 0);
Write32Mask(PLL, pllDisplayClockControlReg, 0x00000200, 0x00000300);
Write32Mask(PLL, pllPostDividerReg, 0, 0x00000100);
write32PLLAtMask(pllControlReg, 0x00000001, 0x00000001);
Write32Mask(PLL, pllControlReg, 0x00000001, 0x00000001);
// reset
snooze(2);
write32PLLAtMask(pllControlReg, 0x00000002, 0x00000002);
Write32Mask(PLL, pllControlReg, 0x00000002, 0x00000002);
// power down
snooze(10);
write32PLLAtMask(pllControlReg, 0x00002000, 0x00002000);
Write32Mask(PLL, pllControlReg, 0x00002000, 0x00002000);
// reset antiglitch
write32PLL(pllExtControlReg, control);
Write32(PLL, pllExtControlReg, control);
write32PLLAtMask(pllDisplayClockControlReg, 2, 0x0000003F);
Write32Mask(PLL, pllDisplayClockControlReg, 2, 0x0000003F);
// Scalar Divider 2
write32PLL(pllLockReg, 1);
Write32(PLL, pllLockReg, 1);
// Lock PLL
/* Write PLL clocks */
write32PLL(pllPostDividerSrcReg, 0x00000001);
write32PLL(pllReferenceDividerReg, referenceDivider);
write32PLL(pllFeedbackDividerReg, feedbackDivider);
write32PLLAtMask(pllPostDividerReg, postDivider, 0x0000007F);
write32PLLAtMask(pplPostDividerSymReg, symPostDiv, 0x0000007F);
Write32(PLL, pllPostDividerSrcReg, 0x00000001);
Write32(PLL, pllReferenceDividerReg, referenceDivider);
Write32(PLL, pllFeedbackDividerReg, feedbackDivider);
Write32Mask(PLL, pllPostDividerReg, postDivider, 0x0000007F);
Write32Mask(PLL, pplPostDividerSymReg, symPostDiv, 0x0000007F);
snooze(10);
write32PLL(pllLockReg, 0);
Write32(PLL, pllLockReg, 0);
// Unlock PLL
write32PLLAtMask(pllControlReg, 0, 0x00000002);
Write32Mask(PLL, pllControlReg, 0, 0x00000002);
// power up
snooze(10);
write32PLLAtMask(pllControlReg, 0, 0x00002000);
Write32Mask(PLL, pllControlReg, 0, 0x00002000);
// undo reset antiglitch
PLLCalibrate(pllIndex);
/* Switch back to PLL */
write32PLLAtMask(pllDisplayClockControlReg, 0, 0x00000300);
write32PLLAtMask(pplPostDividerSymReg, 0x00000100, 0x00000100);
write32PLL(pllPostDividerSrcReg, 0x00000001);
Write32Mask(PLL, pllDisplayClockControlReg, 0, 0x00000300);
Write32Mask(PLL, pplPostDividerSymReg, 0x00000100, 0x00000100);
Write32(PLL, pllPostDividerSrcReg, 0x00000001);
write32PLLAtMask(pllControlReg, 0, 0x80000000);
Write32Mask(PLL, pllControlReg, 0, 0x80000000);
// needed and undocumented
// TODO : If CRT2 ah-la R500PLLCRTCGrab
@@ -334,24 +334,24 @@ PLLCalibrate(uint8 pllIndex)
uint16 pllControlReg = (pllIndex == 1) ? P2PLL_CNTL : P1PLL_CNTL;
write32PLLAtMask(pllControlReg, 1, 0x01);
Write32Mask(PLL, pllControlReg, 1, 0x01);
// PLL Reset
snooze(2);
write32PLLAtMask(pllControlReg, 0, 0x01);
Write32Mask(PLL, pllControlReg, 0, 0x01);
// PLL Set
int i;
for (i = 0; i < PLL_CALIBRATE_WAIT; i++)
if (((read32PLL(pllControlReg) >> 20) & 0x03) == 0x03)
if (((Read32(PLL, pllControlReg) >> 20) & 0x03) == 0x03)
break;
if (i >= PLL_CALIBRATE_WAIT) {
if (read32PLL(pllControlReg) & 0x00100000) /* Calibration done? */
if (Read32(PLL, pllControlReg) & 0x00100000) /* Calibration done? */
TRACE("%s: Calibration Failed\n", __func__);
if (read32PLL(pllControlReg) & 0x00200000) /* PLL locked? */
if (Read32(PLL, pllControlReg) & 0x00200000) /* PLL locked? */
TRACE("%s: Locking Failed\n", __func__);
TRACE("%s: We encountered a problem calibrating the PLL.\n", __func__);
return B_ERROR;
@@ -368,35 +368,35 @@ PLLCRTCGrab(uint8 pllIndex, bool crt2)
bool pll2IsCurrent;
if (!crt2) {
pll2IsCurrent = read32PLL(PCLK_CRTC1_CNTL) & 0x00010000;
pll2IsCurrent = Read32(PLL, PCLK_CRTC1_CNTL) & 0x00010000;
write32PLLAtMask(PCLK_CRTC1_CNTL, (pllIndex == 1) ? 0x00010000 : 0,
Write32Mask(PLL, PCLK_CRTC1_CNTL, (pllIndex == 1) ? 0x00010000 : 0,
0x00010000);
} else {
pll2IsCurrent = read32PLL(PCLK_CRTC2_CNTL) & 0x00010000;
pll2IsCurrent = Read32(PLL, PCLK_CRTC2_CNTL) & 0x00010000;
write32PLLAtMask(PCLK_CRTC2_CNTL, (pllIndex == 1) ? 0x00010000 : 0,
Write32Mask(PLL, PCLK_CRTC2_CNTL, (pllIndex == 1) ? 0x00010000 : 0,
0x00010000);
}
/* if the current pll is not active, then poke it just enough to flip
* owners */
if (!pll2IsCurrent) {
uint32 stored = read32PLL(P1PLL_CNTL);
uint32 stored = Read32(PLL, P1PLL_CNTL);
if (stored & 0x03) {
write32PLLAtMask(P1PLL_CNTL, 0, 0x03);
Write32Mask(PLL, P1PLL_CNTL, 0, 0x03);
snooze(10);
write32PLLAtMask(P1PLL_CNTL, stored, 0x03);
Write32Mask(PLL, P1PLL_CNTL, stored, 0x03);
}
} else {
uint32 stored = read32PLL(P2PLL_CNTL);
uint32 stored = Read32(PLL, P2PLL_CNTL);
if (stored & 0x03) {
write32PLLAtMask(P2PLL_CNTL, 0, 0x03);
Write32Mask(PLL, P2PLL_CNTL, 0, 0x03);
snooze(10);
write32PLLAtMask(P2PLL_CNTL, stored, 0x03);
Write32Mask(PLL, P2PLL_CNTL, stored, 0x03);
}
}
}
@@ -407,7 +407,7 @@ PLLCRTCGrab(uint8 pllIndex, bool crt2)
bool
DCCGCLKAvailable(uint8 pllIndex)
{
uint32 dccg = read32PLL(DCCG_DISP_CLK_SRCSEL) & 0x03;
uint32 dccg = Read32(PLL, DCCG_DISP_CLK_SRCSEL) & 0x03;
if (dccg & 0x02)
return true;
@@ -429,41 +429,41 @@ DCCGCLKSet(uint8 pllIndex, int set)
switch(set) {
case RV620_DCCGCLK_GRAB:
if (pllIndex == 0)
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 0, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 0, 0x00000003);
else if (pllIndex == 1)
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 1, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 1, 0x00000003);
else
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
break;
case RV620_DCCGCLK_RELEASE:
buffer = read32PLL(DCCG_DISP_CLK_SRCSEL) & 0x03;
buffer = Read32(PLL, DCCG_DISP_CLK_SRCSEL) & 0x03;
if ((pllIndex == 0) && (buffer == 0)) {
/* set to other PLL or external */
buffer = read32PLL(P2PLL_CNTL);
buffer = Read32(PLL, P2PLL_CNTL);
// if powered and not in reset, and calibrated and locked
if (!(buffer & 0x03) && ((buffer & 0x00300000) == 0x00300000))
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 1, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 1, 0x00000003);
else
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
} else if ((pllIndex == 1) && (buffer == 1)) {
/* set to other PLL or external */
buffer = read32PLL(P1PLL_CNTL);
buffer = Read32(PLL, P1PLL_CNTL);
// if powered and not in reset, and calibrated and locked
if (!(buffer & 0x03) && ((buffer & 0x00300000) == 0x00300000))
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 0, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 0, 0x00000003);
else
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
} // no other action needed
break;
case RV620_DCCGCLK_RESET:
buffer = read32PLL(DCCG_DISP_CLK_SRCSEL) & 0x03;
buffer = Read32(PLL, DCCG_DISP_CLK_SRCSEL) & 0x03;
if (((pllIndex == 0) && (buffer == 0))
|| ((pllIndex == 1) && (buffer == 1)))
write32PLLAtMask(DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
Write32Mask(PLL, DCCG_DISP_CLK_SRCSEL, 3, 0x00000003);
break;
default:
break;
@@ -481,14 +481,14 @@ DACPower(uint8 dacIndex, int mode)
case RHD_POWER_ON:
// TODO : SensedType Detection?
powerdown = 0;
write32(dacOffset + DACA_ENABLE, 1);
write32(dacOffset + DACA_POWERDOWN, 0);
Write32(OUT, dacOffset + DACA_ENABLE, 1);
Write32(OUT, dacOffset + DACA_POWERDOWN, 0);
snooze(14);
write32AtMask(dacOffset + DACA_POWERDOWN, powerdown, 0xFFFFFF00);
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, powerdown, 0xFFFFFF00);
snooze(2);
write32(dacOffset + DACA_FORCE_OUTPUT_CNTL, 0);
write32AtMask(dacOffset + DACA_SYNC_SELECT, 0, 0x00000101);
write32(dacOffset + DACA_SYNC_TRISTATE_CONTROL, 0);
Write32(OUT, dacOffset + DACA_FORCE_OUTPUT_CNTL, 0);
Write32Mask(OUT, dacOffset + DACA_SYNC_SELECT, 0, 0x00000101);
Write32(OUT, dacOffset + DACA_SYNC_TRISTATE_CONTROL, 0);
return;
}
}