#include "accelerant.h"
#include "rage128.h"
static R128_RAMSpec sRAMSpecs[] = {
{ 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" },
{ 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" },
{ 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" },
{ 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },
};
static bool
Rage128_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, uint32& maxPixelClock)
{
switch (colorSpace) {
case B_RGB32:
bitsPerPixel = 32;
break;
case B_RGB16:
bitsPerPixel = 16;
break;
case B_RGB15:
bitsPerPixel = 15;
break;
case B_CMAP8:
bitsPerPixel = 8;
break;
default:
TRACE("Unsupported color space: 0x%X\n", colorSpace);
return false;
}
maxPixelClock = gInfo.sharedInfo->r128PLLParams.max_pll_freq * 10;
return true;
}
static void
WaitForFifo(uint32 entries)
{
while (true) {
for (int i = 0; i < R128_TIMEOUT; i++) {
uint32 slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
if (slots >= entries)
return;
}
TRACE("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n",
INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,
INREG(R128_GUI_STAT),
INREG(R128_GUI_PROBE));
TRACE("FIFO timed out, resetting engine...\n");
Rage128_EngineReset();
}
}
static void
WaitForIdle()
{
WaitForFifo(64);
while (true) {
for (uint32 i = 0; i < R128_TIMEOUT; i++) {
if ( ! (INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
Rage128_EngineFlush();
return ;
}
}
TRACE("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n",
INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,
INREG(R128_GUI_STAT),
INREG(R128_GUI_PROBE));
TRACE("Idle timed out, resetting engine...\n");
Rage128_EngineReset();
}
}
status_t
Rage128_Init(void)
{
TRACE("Rage128_Init()\n");
SharedInfo& si = *gInfo.sharedInfo;
si.videoMemSize = INREG(R128_CONFIG_MEMSIZE);
si.cursorOffset = (si.videoMemSize - CURSOR_BYTES) & ~0xfff;
si.frameBufferOffset = 0;
si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset;
TRACE("Video Memory size: %d MB frameBufferOffset: 0x%x cursorOffset: 0x%x\n",
si.videoMemSize / 1024 / 1024, si.frameBufferOffset, si.cursorOffset);
uint32 offset;
switch (INREG(R128_MEM_CNTL) & 0x3) {
case 0:
switch (si.deviceID) {
case 0x4C45:
case 0x4C46:
case 0x4D46:
case 0x4D4C:
case 0x5245:
case 0x5246:
case 0x5247:
case 0x5446:
case 0x544C:
case 0x5452:
offset = 0;
break;
default:
offset = 1;
break;
}
break;
case 1:
offset = 2;
break;
case 2:
offset = 3;
break;
default:
offset = 1;
break;
}
si.r128MemSpec = sRAMSpecs[offset];
TRACE("RAM type: %s\n", si.r128MemSpec.name);
si.displayType = MT_VGA;
if (INREG(R128_FP_PANEL_CNTL) & R128_FP_DIGON)
si.displayType = MT_DVI;
if (si.chipType == RAGE128_MOBILITY && si.panelX > 0 && si.panelY > 0) {
if (INREG(R128_LVDS_GEN_CNTL) & R128_LVDS_ON)
si.displayType = MT_LAPTOP;
}
si.colorSpaces[0] = B_CMAP8;
si.colorSpaces[1] = B_RGB15;
si.colorSpaces[2] = B_RGB16;
si.colorSpaces[3] = B_RGB32;
si.colorSpaceCount = 4;
return CreateModeList(IsModeUsable);
}
void
Rage128_SetFunctionPointers(void)
{
gInfo.WaitForFifo = WaitForFifo;
gInfo.WaitForIdle = WaitForIdle;
gInfo.DPMSCapabilities = Rage128_DPMSCapabilities;
gInfo.GetDPMSMode = Rage128_GetDPMSMode;
gInfo.SetDPMSMode = Rage128_SetDPMSMode;
gInfo.LoadCursorImage = Rage128_LoadCursorImage;
gInfo.SetCursorPosition = Rage128_SetCursorPosition;
gInfo.ShowCursor = Rage128_ShowCursor;
gInfo.FillRectangle = Rage128_FillRectangle;
gInfo.FillSpan = Rage128_FillSpan;
gInfo.InvertRectangle = Rage128_InvertRectangle;
gInfo.ScreenToScreenBlit = Rage128_ScreenToScreenBlit;
gInfo.AdjustFrame = Rage128_AdjustFrame;
gInfo.ChipInit = Rage128_Init;
gInfo.GetColorSpaceParams = Rage128_GetColorSpaceParams;
gInfo.SetDisplayMode = Rage128_SetDisplayMode;
gInfo.SetIndexedColors = Rage128_SetIndexedColors;
}