tcp: Add APICall trace entry and move TRACEs into locked parts.
[haiku.git] / src / add-ons / accelerants / s3 / virge_init.cpp
blobb726cc49db162aca8fa734ea480b87374659bae4
1 /*
2 Haiku S3 Virge driver adapted from the X.org Virge driver.
4 Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
6 Copyright 2007-2008 Haiku, Inc. All rights reserved.
7 Distributed under the terms of the MIT license.
9 Authors:
10 Gerald Zajac 2007-2008
14 #include "accel.h"
15 #include "virge.h"
19 static void
20 VirgeWaitFifoGX2(uint32 slots )
22 while (((ReadReg32(SUBSYS_STAT_REG) >> 9) & 0x60) < slots) {}
27 static void
28 VirgeWaitFifoMain(uint32 slots )
30 while (((ReadReg32(SUBSYS_STAT_REG) >> 8) & 0x1f) < slots) {}
34 static void
35 VirgeWaitIdleEmpty()
37 // Wait until GP is idle and queue is empty.
39 if(gInfo.sharedInfo->chipType == S3_TRIO_3D)
40 while ((IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) != 0x20002000);
41 else
42 while ((IN_SUBSYS_STAT() & 0x3f00) != 0x3000);
46 static bool
47 Virge_GetColorSpaceParams(int colorSpace, uint32& bitsPerPixel, uint32& maxPixelClock)
49 // Get parameters for a color space which is supported by the Virge chips.
50 // Argument maxPixelClock is in KHz.
51 // Return true if the color space is supported; else return false.
53 // Note that the X.org code set the max clock to 440000 for a Virge VX chip
54 // and 270000 for all other chips. 440000 seems rather high for a chip that
55 // old; thus, 270000 is used for all chips.
57 switch (colorSpace) {
58 case B_RGB16:
59 bitsPerPixel = 16;
60 maxPixelClock = 270000;
61 break;
62 case B_CMAP8:
63 bitsPerPixel = 8;
64 maxPixelClock = 270000;
65 break;
66 default:
67 TRACE("Unsupported color space: 0x%X\n", colorSpace);
68 return false;
71 return true;
76 status_t
77 Virge_Init(void)
79 TRACE("Virge_Init()\n");
81 SharedInfo& si = *gInfo.sharedInfo;
83 // Use PIO for following operations since MMIO may not be currently enabled.
85 WritePIO_8(VGA_ENABLE, ReadPIO_8(VGA_ENABLE) | 0x01); // enable VGA
86 WritePIO_8(MISC_OUT_W, ReadPIO_8(MISC_OUT_R) | 0x01); // enable color
88 // Set linear base register to the PCI register value;
89 // some DX chipsets don't seem to do it automatically.
91 WritePIO_8(CRTC_INDEX, 0x59);
92 WritePIO_8(CRTC_DATA, (uint32)(si.videoMemPCI) >> 24);
93 WritePIO_8(CRTC_INDEX, 0x5A);
94 WritePIO_8(CRTC_DATA, (uint32)(si.videoMemPCI) >> 16);
96 // Enable MMIO.
98 WritePIO_8(CRTC_INDEX, 0x53);
99 WritePIO_8(CRTC_DATA, ReadPIO_8(CRTC_DATA) | 0x8);
101 if (si.chipType == S3_TRIO_3D)
102 WriteCrtcReg(0x40, 0x01, 0x01);
104 // Detect amount of installed ram.
106 uint8 config1 = ReadCrtcReg(0x36); // get amount of vram installed
107 uint8 config2 = ReadCrtcReg(0x37); // get amount of off-screen ram
109 // Compute the amount of video memory and offscreen memory.
111 int ramOffScreenMB = 0; // off screen memory size in megabytes
112 int ramSizeMB = 0; // memory size in megabytes
114 if (si.chipType == S3_VIRGE_VX) {
115 switch ((config2 & 0x60) >> 5) {
116 case 1:
117 ramOffScreenMB = 4;
118 break;
119 case 2:
120 ramOffScreenMB = 2;
121 break;
124 switch ((config1 & 0x60) >> 5) {
125 case 0:
126 ramSizeMB = 2;
127 break;
128 case 1:
129 ramSizeMB = 4;
130 break;
131 case 2:
132 ramSizeMB = 6;
133 break;
134 case 3:
135 ramSizeMB = 8;
136 break;
138 ramSizeMB -= ramOffScreenMB;
140 } else if (si.chipType == S3_TRIO_3D_2X) {
141 switch ((config1 & 0xE0) >> 5) {
142 case 0: // 8MB -- only 4MB usable for display/cursor
143 ramSizeMB = 4;
144 ramOffScreenMB = 4;
145 break;
146 case 1: // 32 bit interface -- yuck
147 TRACE("Undefined video memory size on S3 Trio 3D/2X\n");
148 case 2:
149 ramSizeMB = 4;
150 break;
151 case 6:
152 ramSizeMB = 2;
153 break;
155 } else if (si.chipType == S3_TRIO_3D) {
156 switch ((config1 & 0xE0) >> 5) {
157 case 0:
158 case 2:
159 ramSizeMB = 4;
160 break;
161 case 4:
162 ramSizeMB = 2;
163 break;
165 } else if (si.chipType == S3_VIRGE_GX2 || S3_VIRGE_MX_SERIES(si.chipType)) {
166 switch ((config1 & 0xC0) >> 6) {
167 case 1:
168 ramSizeMB = 4;
169 break;
170 case 3:
171 ramSizeMB = 2;
172 break;
174 } else {
175 switch ((config1 & 0xE0) >> 5) {
176 case 0:
177 ramSizeMB = 4;
178 break;
179 case 4:
180 ramSizeMB = 2;
181 break;
182 case 6:
183 ramSizeMB = 1;
184 break;
188 TRACE("usable memory: %d MB, off-screen memory: %d MB\n", ramSizeMB, ramOffScreenMB);
190 if (ramSizeMB <= 0)
191 return B_ERROR;
193 si.videoMemSize = ramSizeMB * 1024 * 1024;
194 si.cursorOffset = si.videoMemSize - CURSOR_BYTES; // put cursor at end of video memory
195 si.frameBufferOffset = 0;
196 si.maxFrameBufferSize = si.videoMemSize - CURSOR_BYTES;
198 // Detect current mclk.
200 WriteSeqReg(0x08, 0x06); // unlock extended sequencer regs
202 uint8 m = ReadSeqReg(0x11) & 0x7f;
203 uint8 n = ReadSeqReg(0x10);
204 uint8 n1 = n & 0x1f;
205 uint8 n2 = (n >> 5) & 0x03;
206 si.mclk = ((1431818 * (m + 2)) / (n1 + 2) / (1 << n2) + 50) / 100;
208 TRACE("Detected current MCLK value of %1.3f MHz\n", si.mclk / 1000.0);
210 if (S3_VIRGE_MX_SERIES(si.chipType)) {
211 si.displayType = ((ReadSeqReg(0x31) & 0x10) ? MT_LCD : MT_CRT);
212 si.panelX = (ReadSeqReg(0x61) + ((ReadSeqReg(0x66) & 0x02) << 7) + 1) * 8;
213 si.panelY = ReadSeqReg(0x69) + ((ReadSeqReg(0x6e) & 0x70) << 4) + 1;
215 TRACE("%dx%d LCD panel detected %s\n", si.panelX, si.panelY,
216 si.displayType == MT_LCD ? "and active" : "but not active");
217 } else {
218 si.displayType = MT_CRT;
219 si.panelX = 0;
220 si.panelY = 0;
223 // Set up the array of color spaces supported by the Virge/Trio3D chips.
225 si.colorSpaces[0] = B_CMAP8;
226 si.colorSpaces[1] = B_RGB16;
227 si.colorSpaceCount = 2;
229 si.bDisableHdwCursor = false; // allow use of hardware cursor
230 si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
232 // Setup the mode list.
234 return CreateModeList(IsModeUsable, Virge_GetEdidInfo);
238 void
239 Virge_SetFunctionPointers(void)
241 // Setting the function pointers must be done prior to first ModeInit call
242 // or any accel activity.
244 if (S3_VIRGE_GX2_SERIES(gInfo.sharedInfo->chipType)) {
245 gInfo.WaitQueue = VirgeWaitFifoGX2;
246 } else {
247 gInfo.WaitQueue = VirgeWaitFifoMain;
250 gInfo.WaitIdleEmpty = VirgeWaitIdleEmpty;
252 gInfo.DPMSCapabilities = Virge_DPMSCapabilities;
253 gInfo.GetDPMSMode = Virge_GetDPMSMode;
254 gInfo.SetDPMSMode = Virge_SetDPMSMode;
256 gInfo.LoadCursorImage = Virge_LoadCursorImage;
257 gInfo.SetCursorPosition = Virge_SetCursorPosition;
258 gInfo.ShowCursor = Virge_ShowCursor;
260 gInfo.FillRectangle = Virge_FillRectangle;
261 gInfo.FillSpan = Virge_FillSpan;
262 gInfo.InvertRectangle = Virge_InvertRectangle;
263 gInfo.ScreenToScreenBlit = Virge_ScreenToScreenBlit;
265 gInfo.AdjustFrame = Virge_AdjustFrame;
266 gInfo.ChipInit = Virge_Init;
267 gInfo.GetColorSpaceParams = Virge_GetColorSpaceParams;
268 gInfo.SetDisplayMode = Virge_SetDisplayMode;
269 gInfo.SetIndexedColors = Virge_SetIndexedColors;