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.
10 Gerald Zajac 2007-2008
20 VirgeWaitFifoGX2(uint32 slots
)
22 while (((ReadReg32(SUBSYS_STAT_REG
) >> 9) & 0x60) < slots
) {}
28 VirgeWaitFifoMain(uint32 slots
)
30 while (((ReadReg32(SUBSYS_STAT_REG
) >> 8) & 0x1f) < slots
) {}
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);
42 while ((IN_SUBSYS_STAT() & 0x3f00) != 0x3000);
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.
60 maxPixelClock
= 270000;
64 maxPixelClock
= 270000;
67 TRACE("Unsupported color space: 0x%X\n", colorSpace
);
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);
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) {
124 switch ((config1
& 0x60) >> 5) {
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
146 case 1: // 32 bit interface -- yuck
147 TRACE("Undefined video memory size on S3 Trio 3D/2X\n");
155 } else if (si
.chipType
== S3_TRIO_3D
) {
156 switch ((config1
& 0xE0) >> 5) {
165 } else if (si
.chipType
== S3_VIRGE_GX2
|| S3_VIRGE_MX_SERIES(si
.chipType
)) {
166 switch ((config1
& 0xC0) >> 6) {
175 switch ((config1
& 0xE0) >> 5) {
188 TRACE("usable memory: %d MB, off-screen memory: %d MB\n", ramSizeMB
, ramOffScreenMB
);
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);
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");
218 si
.displayType
= MT_CRT
;
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
);
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
;
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
;