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 si.bDisableHdwCursor = false; // allow use of hardware cursor 140 si.bDisableAccelDraw = false; // allow use of accelerated drawing functions 141 142 // Setup the mode list. 143 144 return CreateModeList(Trio64_IsModeUsable, NULL); 145 } 146 147 148 void 149 Trio64_SetFunctionPointers(void) 150 { 151 // Setting the function pointers must be done prior to first ModeInit call 152 // or any accel activity. 153 154 gInfo.WaitQueue = WaitQueue; 155 gInfo.WaitIdleEmpty = WaitIdle; 156 157 gInfo.DPMSCapabilities = Trio64_DPMSCapabilities; 158 gInfo.GetDPMSMode = Trio64_GetDPMSMode; 159 gInfo.SetDPMSMode = Trio64_SetDPMSMode; 160 161 gInfo.LoadCursorImage = Trio64_LoadCursorImage; 162 gInfo.SetCursorPosition = Trio64_SetCursorPosition; 163 gInfo.ShowCursor = Trio64_ShowCursor; 164 165 // Note that the 2D accel functions set below do not work with all display 166 // modes; thus, when a mode is set, the function setting the mode will 167 // adjust the pointers according to the mode that is set. 168 169 gInfo.FillRectangle = Trio64_FillRectangle; 170 gInfo.FillSpan = Trio64_FillSpan; 171 gInfo.InvertRectangle = Trio64_InvertRectangle; 172 gInfo.ScreenToScreenBlit = Trio64_ScreenToScreenBlit; 173 174 gInfo.AdjustFrame = Trio64_AdjustFrame; 175 gInfo.ChipInit = Trio64_Init; 176 gInfo.GetColorSpaceParams = Trio64_GetColorSpaceParams; 177 gInfo.SetDisplayMode = Trio64_SetDisplayMode; 178 gInfo.SetIndexedColors = Trio64_SetIndexedColors; 179 } 180