135db13eaSAxel Dörfler /*
235db13eaSAxel Dörfler Haiku S3 Trio64 driver adapted from the X.org S3 driver.
335db13eaSAxel Dörfler
435db13eaSAxel Dörfler Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
535db13eaSAxel Dörfler
635db13eaSAxel Dörfler Copyright 2008 Haiku, Inc. All rights reserved.
735db13eaSAxel Dörfler Distributed under the terms of the MIT license.
835db13eaSAxel Dörfler
935db13eaSAxel Dörfler Authors:
1035db13eaSAxel Dörfler Gerald Zajac 2008
1135db13eaSAxel Dörfler */
1235db13eaSAxel Dörfler
1335db13eaSAxel Dörfler
1435db13eaSAxel Dörfler #include "accel.h"
1535db13eaSAxel Dörfler #include "trio64.h"
1635db13eaSAxel Dörfler
1735db13eaSAxel Dörfler
1835db13eaSAxel Dörfler
1935db13eaSAxel Dörfler static void
WaitQueue(uint32 slots)2035db13eaSAxel Dörfler WaitQueue(uint32 slots )
2135db13eaSAxel Dörfler {
2235db13eaSAxel Dörfler // Wait until the requested number of queue slots are available.
2335db13eaSAxel Dörfler
2435db13eaSAxel Dörfler while (ReadReg16(GP_STAT) & (0x0100 >> slots)) {}
2535db13eaSAxel Dörfler }
2635db13eaSAxel Dörfler
2735db13eaSAxel Dörfler
2835db13eaSAxel Dörfler static void
WaitIdle()2935db13eaSAxel Dörfler WaitIdle()
3035db13eaSAxel Dörfler {
3135db13eaSAxel Dörfler // Wait until Graphics Processor is idle.
3235db13eaSAxel Dörfler
3335db13eaSAxel Dörfler while (ReadReg16(GP_STAT) & GP_BUSY);
3435db13eaSAxel Dörfler }
3535db13eaSAxel Dörfler
3635db13eaSAxel Dörfler
3735db13eaSAxel Dörfler
3835db13eaSAxel Dörfler static bool
Trio64_GetColorSpaceParams(int colorSpace,uint32 & bitsPerPixel,uint32 & maxPixelClock)3935db13eaSAxel Dörfler Trio64_GetColorSpaceParams(int colorSpace, uint32& bitsPerPixel, uint32& maxPixelClock)
4035db13eaSAxel Dörfler {
4135db13eaSAxel Dörfler // Get parameters for a color space which is supported by the Trio64 chips.
4235db13eaSAxel Dörfler // Argument maxPixelClock is in KHz.
4335db13eaSAxel Dörfler // Return true if the color space is supported; else return false.
4435db13eaSAxel Dörfler
4535db13eaSAxel Dörfler switch (colorSpace) {
4635db13eaSAxel Dörfler case B_RGB16:
4735db13eaSAxel Dörfler bitsPerPixel = 16;
4835db13eaSAxel Dörfler maxPixelClock = 110000;
4935db13eaSAxel Dörfler break;
5035db13eaSAxel Dörfler case B_CMAP8:
5135db13eaSAxel Dörfler bitsPerPixel = 8;
5235db13eaSAxel Dörfler maxPixelClock = 180000;
5335db13eaSAxel Dörfler break;
5435db13eaSAxel Dörfler default:
5535db13eaSAxel Dörfler TRACE("Unsupported color space: 0x%X\n", colorSpace);
5635db13eaSAxel Dörfler return false;
5735db13eaSAxel Dörfler }
5835db13eaSAxel Dörfler
5935db13eaSAxel Dörfler return true;
6035db13eaSAxel Dörfler }
6135db13eaSAxel Dörfler
6235db13eaSAxel Dörfler
6335db13eaSAxel Dörfler static bool
Trio64_IsModeUsable(const display_mode * mode)6435db13eaSAxel Dörfler Trio64_IsModeUsable(const display_mode* mode)
6535db13eaSAxel Dörfler {
6635db13eaSAxel Dörfler // Test if the display mode is usable by the current video chip.
6735db13eaSAxel Dörfler // Return true if the mode is usable.
6835db13eaSAxel Dörfler
6935db13eaSAxel Dörfler SharedInfo& si = *gInfo.sharedInfo;
7035db13eaSAxel Dörfler
7135db13eaSAxel Dörfler if (si.chipType == S3_TRIO64 && mode->timing.h_display >= 1600)
7235db13eaSAxel Dörfler return false;
7335db13eaSAxel Dörfler
7435db13eaSAxel Dörfler return IsModeUsable(mode);
7535db13eaSAxel Dörfler }
7635db13eaSAxel Dörfler
7735db13eaSAxel Dörfler
7835db13eaSAxel Dörfler static status_t
Trio64_Init(void)7935db13eaSAxel Dörfler Trio64_Init(void)
8035db13eaSAxel Dörfler {
8135db13eaSAxel Dörfler TRACE("Trio64_Init()\n");
8235db13eaSAxel Dörfler
8335db13eaSAxel Dörfler SharedInfo& si = *gInfo.sharedInfo;
8435db13eaSAxel Dörfler
8535db13eaSAxel Dörfler // Use PIO to enable VGA, enable color instead of monochrome, and
8635db13eaSAxel Dörfler // enable MMIO.
8735db13eaSAxel Dörfler
8835db13eaSAxel Dörfler WritePIO_8(VGA_ENABLE, ReadPIO_8(VGA_ENABLE) | 0x01);
8935db13eaSAxel Dörfler WritePIO_8(MISC_OUT_W, ReadPIO_8(MISC_OUT_R) | 0x01); // enable color
9035db13eaSAxel Dörfler
9135db13eaSAxel Dörfler WritePIO_8(CRTC_INDEX, 0x53);
9235db13eaSAxel Dörfler WritePIO_8(CRTC_DATA, ReadPIO_8(CRTC_DATA) | 0x8); // enable MMIO
9335db13eaSAxel Dörfler
9435db13eaSAxel Dörfler WriteCrtcReg(0x38, 0x48); // unlock sys regs
9535db13eaSAxel Dörfler WriteCrtcReg(0x39, 0xa5); // unlock sys regs
9635db13eaSAxel Dörfler
9735db13eaSAxel Dörfler WriteCrtcReg(0x40, 0x01, 0x01);
9835db13eaSAxel Dörfler WriteCrtcReg(0x35, 0x00, 0x30);
9935db13eaSAxel Dörfler WriteCrtcReg(0x33, 0x20, 0x72);
10035db13eaSAxel Dörfler
10135db13eaSAxel Dörfler if (si.chipType == S3_TRIO64_V2) {
10235db13eaSAxel Dörfler WriteCrtcReg(0x86, 0x80);
10335db13eaSAxel Dörfler WriteCrtcReg(0x90, 0x00);
10435db13eaSAxel Dörfler }
10535db13eaSAxel Dörfler
10635db13eaSAxel Dörfler // Detect number of megabytes of installed ram.
10735db13eaSAxel Dörfler
10835db13eaSAxel Dörfler static const uint8 ramSizes[] = { 4, 0, 3, 8, 2, 6, 1, 0 };
10935db13eaSAxel Dörfler int ramSizeMB = ramSizes[(ReadCrtcReg(0x36) >> 5) & 0x7];
11035db13eaSAxel Dörfler
11135db13eaSAxel Dörfler TRACE("memory size: %d MB\n", ramSizeMB);
11235db13eaSAxel Dörfler
11335db13eaSAxel Dörfler if (ramSizeMB <= 0)
11435db13eaSAxel Dörfler return B_ERROR;
11535db13eaSAxel Dörfler
11635db13eaSAxel Dörfler si.videoMemSize = ramSizeMB * 1024 * 1024;
11735db13eaSAxel Dörfler si.cursorOffset = si.videoMemSize - CURSOR_BYTES; // put cursor at end of video memory
11835db13eaSAxel Dörfler si.frameBufferOffset = 0;
11935db13eaSAxel Dörfler si.maxFrameBufferSize = si.videoMemSize - CURSOR_BYTES;
12035db13eaSAxel Dörfler
12135db13eaSAxel Dörfler // Detect current mclk.
12235db13eaSAxel Dörfler
12335db13eaSAxel Dörfler WriteSeqReg(0x08, 0x06); // unlock extended sequencer regs
12435db13eaSAxel Dörfler
12535db13eaSAxel Dörfler uint8 m = ReadSeqReg(0x11) & 0x7f;
12635db13eaSAxel Dörfler uint8 n = ReadSeqReg(0x10);
12735db13eaSAxel Dörfler uint8 n1 = n & 0x1f;
12835db13eaSAxel Dörfler uint8 n2 = (n >> 5) & 0x03;
12935db13eaSAxel Dörfler si.mclk = ((1431818 * (m + 2)) / (n1 + 2) / (1 << n2) + 50) / 100;
13035db13eaSAxel Dörfler
13135db13eaSAxel Dörfler TRACE("MCLK value: %1.3f MHz\n", si.mclk / 1000.0);
13235db13eaSAxel Dörfler
13335db13eaSAxel Dörfler // Set up the array of color spaces supported by the Trio64 chips.
13435db13eaSAxel Dörfler
13535db13eaSAxel Dörfler si.colorSpaces[0] = B_CMAP8;
13635db13eaSAxel Dörfler si.colorSpaces[1] = B_RGB16;
13735db13eaSAxel Dörfler si.colorSpaceCount = 2;
13835db13eaSAxel Dörfler
139*c1379d35SAxel Dörfler si.bDisableHdwCursor = false; // allow use of hardware cursor
140*c1379d35SAxel Dörfler si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
141*c1379d35SAxel Dörfler
14235db13eaSAxel Dörfler // Setup the mode list.
14335db13eaSAxel Dörfler
144*c1379d35SAxel Dörfler return CreateModeList(Trio64_IsModeUsable, NULL);
14535db13eaSAxel Dörfler }
14635db13eaSAxel Dörfler
14735db13eaSAxel Dörfler
14835db13eaSAxel Dörfler void
Trio64_SetFunctionPointers(void)14935db13eaSAxel Dörfler Trio64_SetFunctionPointers(void)
15035db13eaSAxel Dörfler {
15135db13eaSAxel Dörfler // Setting the function pointers must be done prior to first ModeInit call
15235db13eaSAxel Dörfler // or any accel activity.
15335db13eaSAxel Dörfler
15435db13eaSAxel Dörfler gInfo.WaitQueue = WaitQueue;
15535db13eaSAxel Dörfler gInfo.WaitIdleEmpty = WaitIdle;
15635db13eaSAxel Dörfler
15735db13eaSAxel Dörfler gInfo.DPMSCapabilities = Trio64_DPMSCapabilities;
158*c1379d35SAxel Dörfler gInfo.GetDPMSMode = Trio64_GetDPMSMode;
15935db13eaSAxel Dörfler gInfo.SetDPMSMode = Trio64_SetDPMSMode;
16035db13eaSAxel Dörfler
16135db13eaSAxel Dörfler gInfo.LoadCursorImage = Trio64_LoadCursorImage;
16235db13eaSAxel Dörfler gInfo.SetCursorPosition = Trio64_SetCursorPosition;
16335db13eaSAxel Dörfler gInfo.ShowCursor = Trio64_ShowCursor;
16435db13eaSAxel Dörfler
16535db13eaSAxel Dörfler // Note that the 2D accel functions set below do not work with all display
16635db13eaSAxel Dörfler // modes; thus, when a mode is set, the function setting the mode will
16735db13eaSAxel Dörfler // adjust the pointers according to the mode that is set.
16835db13eaSAxel Dörfler
16935db13eaSAxel Dörfler gInfo.FillRectangle = Trio64_FillRectangle;
17035db13eaSAxel Dörfler gInfo.FillSpan = Trio64_FillSpan;
17135db13eaSAxel Dörfler gInfo.InvertRectangle = Trio64_InvertRectangle;
17235db13eaSAxel Dörfler gInfo.ScreenToScreenBlit = Trio64_ScreenToScreenBlit;
17335db13eaSAxel Dörfler
17435db13eaSAxel Dörfler gInfo.AdjustFrame = Trio64_AdjustFrame;
17535db13eaSAxel Dörfler gInfo.ChipInit = Trio64_Init;
17635db13eaSAxel Dörfler gInfo.GetColorSpaceParams = Trio64_GetColorSpaceParams;
17735db13eaSAxel Dörfler gInfo.SetDisplayMode = Trio64_SetDisplayMode;
17835db13eaSAxel Dörfler gInfo.SetIndexedColors = Trio64_SetIndexedColors;
17935db13eaSAxel Dörfler }
180