Haiku ATI video driver adapted from the X.org ATI driver.
Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
Precision Insight, Inc., Cedar Park, Texas, and
VA Linux Systems Inc., Fremont, California.
Copyright 2009 Haiku, Inc. All rights reserved.
Distributed under the terms of the MIT license.
Authors:
Gerald Zajac 2009
*/
#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;
}