* 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:
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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__);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user