xref: /haiku/src/add-ons/accelerants/s3/trio64_init.cpp (revision c1379d357b3737534088b8e62fe68df6db9f2468)
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