xref: /haiku/src/add-ons/accelerants/s3/trio64_init.cpp (revision b30304acc8c37e678a1bf66976d15bdab103f931)
1 /*
2 	Haiku S3 Trio64 driver adapted from the X.org S3 driver.
3 
4 	Copyright 2001	Ani Joshi <ajoshi@unixbox.com>
5 
6 	Copyright 2008 Haiku, Inc.  All rights reserved.
7 	Distributed under the terms of the MIT license.
8 
9 	Authors:
10 	Gerald Zajac 2008
11 */
12 
13 
14 #include "accel.h"
15 #include "trio64.h"
16 
17 
18 
19 static void
20 WaitQueue(uint32 slots )
21 {
22 	// Wait until the requested number of queue slots are available.
23 
24 	while (ReadReg16(GP_STAT) & (0x0100 >> slots)) {}
25 }
26 
27 
28 static void
29 WaitIdle()
30 {
31 	// Wait until Graphics Processor is idle.
32 
33 	while (ReadReg16(GP_STAT) & GP_BUSY);
34 }
35 
36 
37 
38 static bool
39 Trio64_GetColorSpaceParams(int colorSpace, uint32& bitsPerPixel, uint32& maxPixelClock)
40 {
41 	// Get parameters for a color space which is supported by the Trio64 chips.
42 	// Argument maxPixelClock is in KHz.
43 	// Return true if the color space is supported;  else return false.
44 
45 	switch (colorSpace) {
46 		case B_RGB16:
47 			bitsPerPixel = 16;
48 			maxPixelClock = 110000;
49 			break;
50 		case B_CMAP8:
51 			bitsPerPixel = 8;
52 			maxPixelClock = 180000;
53 			break;
54 		default:
55 			TRACE("Unsupported color space: 0x%X\n", colorSpace);
56 			return false;
57 	}
58 
59 	return true;
60 }
61 
62 
63 static bool
64 Trio64_IsModeUsable(const display_mode* mode)
65 {
66 	// Test if the display mode is usable by the current video chip.
67 	// Return true if the mode is usable.
68 
69 	SharedInfo& si = *gInfo.sharedInfo;
70 
71 	if (si.chipType == S3_TRIO64 && mode->timing.h_display >= 1600)
72 		return false;
73 
74 	return IsModeUsable(mode);
75 }
76 
77 
78 static status_t
79 Trio64_Init(void)
80 {
81 	TRACE("Trio64_Init()\n");
82 
83 	SharedInfo& si = *gInfo.sharedInfo;
84 
85 	// Use PIO to enable VGA, enable color instead of monochrome, and
86 	// enable MMIO.
87 
88 	WritePIO_8(VGA_ENABLE, ReadPIO_8(VGA_ENABLE) | 0x01);
89 	WritePIO_8(MISC_OUT_W, ReadPIO_8(MISC_OUT_R) | 0x01);	// enable color
90 
91 	WritePIO_8(CRTC_INDEX, 0x53);
92 	WritePIO_8(CRTC_DATA, ReadPIO_8(CRTC_DATA) | 0x8);		// enable MMIO
93 
94 	WriteCrtcReg(0x38, 0x48);		// unlock sys regs
95 	WriteCrtcReg(0x39, 0xa5);		// unlock sys regs
96 
97 	WriteCrtcReg(0x40, 0x01, 0x01);
98 	WriteCrtcReg(0x35, 0x00, 0x30);
99 	WriteCrtcReg(0x33, 0x20, 0x72);
100 
101 	if (si.chipType == S3_TRIO64_V2) {
102 		WriteCrtcReg(0x86, 0x80);
103 		WriteCrtcReg(0x90, 0x00);
104 	}
105 
106 	// Detect number of megabytes of installed ram.
107 
108 	static const uint8 ramSizes[] = { 4, 0, 3, 8, 2, 6, 1, 0 };
109 	int ramSizeMB = ramSizes[(ReadCrtcReg(0x36) >> 5) & 0x7];
110 
111 	TRACE("memory size: %d MB\n", ramSizeMB);
112 
113 	if (ramSizeMB <= 0)
114 		return B_ERROR;
115 
116 	si.videoMemSize = ramSizeMB * 1024 * 1024;
117 	si.cursorOffset = si.videoMemSize - CURSOR_BYTES;	// put cursor at end of video memory
118 	si.frameBufferOffset = 0;
119 	si.maxFrameBufferSize = si.videoMemSize - CURSOR_BYTES;
120 
121 	// Detect current mclk.
122 
123 	WriteSeqReg(0x08, 0x06);		// unlock extended sequencer regs
124 
125 	uint8 m = ReadSeqReg(0x11) & 0x7f;
126 	uint8 n = ReadSeqReg(0x10);
127 	uint8 n1 = n & 0x1f;
128 	uint8 n2 = (n >> 5) & 0x03;
129 	si.mclk = ((1431818 * (m + 2)) / (n1 + 2) / (1 << n2) + 50) / 100;
130 
131 	TRACE("MCLK value: %1.3f MHz\n", si.mclk / 1000.0);
132 
133 	// Set up the array of color spaces supported by the Trio64 chips.
134 
135 	si.colorSpaces[0] = B_CMAP8;
136 	si.colorSpaces[1] = B_RGB16;
137 	si.colorSpaceCount = 2;
138 
139 	// Setup the mode list.
140 
141 	return CreateModeList(Trio64_IsModeUsable);
142 }
143 
144 
145 void
146 Trio64_SetFunctionPointers(void)
147 {
148 	// Setting the function pointers must be done prior to first ModeInit call
149 	// or any accel activity.
150 
151 	gInfo.WaitQueue = WaitQueue;
152 	gInfo.WaitIdleEmpty = WaitIdle;
153 
154 	gInfo.DPMSCapabilities = Trio64_DPMSCapabilities;
155 	gInfo.DPMSMode = Trio64_DPMSMode;
156 	gInfo.SetDPMSMode = Trio64_SetDPMSMode;
157 
158 	gInfo.LoadCursorImage = Trio64_LoadCursorImage;
159 	gInfo.SetCursorPosition = Trio64_SetCursorPosition;
160 	gInfo.ShowCursor = Trio64_ShowCursor;
161 
162 	// Note that the 2D accel functions set below do not work with all display
163 	// modes;  thus, when a mode is set, the function setting the mode will
164 	// adjust the pointers according to the mode that is set.
165 
166 	gInfo.FillRectangle = Trio64_FillRectangle;
167 	gInfo.FillSpan = Trio64_FillSpan;
168 	gInfo.InvertRectangle = Trio64_InvertRectangle;
169 	gInfo.ScreenToScreenBlit = Trio64_ScreenToScreenBlit;
170 
171 	gInfo.AdjustFrame = Trio64_AdjustFrame;
172 	gInfo.ChipInit = Trio64_Init;
173 	gInfo.GetColorSpaceParams = Trio64_GetColorSpaceParams;
174 	gInfo.SetDisplayMode = Trio64_SetDisplayMode;
175 	gInfo.SetIndexedColors = Trio64_SetIndexedColors;
176 }
177