vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / ati / mach64_init.cpp
blob509855ff3353a64d3bbe97ab887ffc6c02f2f6f8
1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
4 Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina.
5 Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
7 Copyright 2009 Haiku, Inc. All rights reserved.
8 Distributed under the terms of the MIT license.
10 Authors:
11 Gerald Zajac 2009
15 #include "accelerant.h"
16 #include "mach64.h"
20 static bool
21 Mach64_InitDSPParams()
23 // Initialize global variables used to set DSP registers on a VT-B or later.
25 SharedInfo& si = *gInfo.sharedInfo;
26 M64_Params& params = si.m64Params;
28 // Retrieve XCLK settings.
30 uint8 ioValue = Mach64_GetPLLReg(PLL_XCLK_CNTL);
31 params.xClkPostDivider = ioValue & 0x7;
33 switch (params.xClkPostDivider) {
34 case 0:
35 case 1:
36 case 2:
37 case 3:
38 params.xClkRefDivider = 1;
39 break;
41 case 4:
42 params.xClkRefDivider = 3;
43 params.xClkPostDivider = 0;
44 break;
46 default:
47 TRACE("Unsupported XCLK source: %d.\n", params.xClkPostDivider);
48 return false;
51 if (ioValue & PLL_MFB_TIMES_4_2B)
52 params.xClkPostDivider--;
54 // Compute maximum RAS delay and related params.
56 uint32 memCntl = INREG(MEM_CNTL);
57 int trp = GetBits(memCntl, CTL_MEM_TRP);
58 params.xClkPageFaultDelay = GetBits(memCntl, CTL_MEM_TRCD) +
59 GetBits(memCntl, CTL_MEM_TCRD) + trp + 2;
60 params.xClkMaxRASDelay = GetBits(memCntl, CTL_MEM_TRAS) + trp + 2;
62 params.displayFIFODepth = 32;
64 if (si.chipType < MACH64_264VT4) {
65 params.xClkPageFaultDelay += 2;
66 params.xClkMaxRASDelay += 3;
67 params.displayFIFODepth = 24;
70 // Determine type of memory used with the chip.
72 int memType = INREG(CONFIG_STAT0) & 0x7;
73 TRACE("Memory type: %d\n", memType);
75 switch (memType) {
76 case MEM_DRAM:
77 if (si.videoMemSize <= 1024 * 1024) {
78 params.displayLoopLatency = 10;
79 } else {
80 params.displayLoopLatency = 8;
81 params.xClkPageFaultDelay += 2;
83 break;
85 case MEM_EDO:
86 case MEM_PSEUDO_EDO:
87 if (si.videoMemSize <= 1024 * 1024) {
88 params.displayLoopLatency = 9;
89 } else {
90 params.displayLoopLatency = 8;
91 params.xClkPageFaultDelay++;
93 break;
95 case MEM_SDRAM:
96 if (si.videoMemSize <= 1024 * 1024) {
97 params.displayLoopLatency = 11;
98 } else {
99 params.displayLoopLatency = 10;
100 params.xClkPageFaultDelay++;
102 break;
104 case MEM_SGRAM:
105 params.displayLoopLatency = 8;
106 params.xClkPageFaultDelay += 3;
107 break;
109 default: /* Set maximums */
110 params.displayLoopLatency = 11;
111 params.xClkPageFaultDelay += 3;
112 break;
115 if (params.xClkMaxRASDelay <= params.xClkPageFaultDelay)
116 params.xClkMaxRASDelay = params.xClkPageFaultDelay + 1;
118 uint32 dspConfig = INREG(DSP_CONFIG);
119 if (dspConfig)
120 params.displayLoopLatency = GetBits(dspConfig, DSP_LOOP_LATENCY);
122 return true;
126 static bool
127 Mach64_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, uint32& maxPixelClock)
129 // Get parameters for a color space which is supported by the Mach64 chips.
130 // Argument maxPixelClock is in KHz.
131 // Return true if the color space is supported; else return false.
133 SharedInfo& si = *gInfo.sharedInfo;
135 switch (colorSpace) {
136 case B_RGB32:
137 bitsPerPixel = 32;
138 break;
139 case B_RGB16:
140 bitsPerPixel = 16;
141 break;
142 case B_RGB15:
143 bitsPerPixel = 15;
144 break;
145 case B_CMAP8:
146 bitsPerPixel = 8;
147 break;
148 default:
149 TRACE("Unsupported color space: 0x%X\n", colorSpace);
150 return false;
153 if (si.chipType >= MACH64_264VTB) {
154 if ((si.chipType >= MACH64_264VT4) && (si.chipType != MACH64_264LTPRO))
155 maxPixelClock = 230000;
156 else if (si.chipType >= MACH64_264VT3)
157 maxPixelClock = 200000;
158 else
159 maxPixelClock = 170000;
160 } else {
161 if (bitsPerPixel == 8)
162 maxPixelClock = 135000;
163 else
164 maxPixelClock = 80000;
167 return true;
172 status_t
173 Mach64_Init(void)
175 TRACE("Mach64_Init()\n");
177 SharedInfo& si = *gInfo.sharedInfo;
179 static const int videoRamSizes[] =
180 { 512, 1024, 2*1024, 4*1024, 6*1024, 8*1024, 12*1024, 16*1024 };
182 uint32 memCntl = INREG(MEM_CNTL);
183 if (si.chipType < MACH64_264VTB) {
184 si.videoMemSize = videoRamSizes[memCntl & 0x7] * 1024;
185 } else {
186 uint32 ioValue = (memCntl & 0xf);
187 if (ioValue < 8)
188 si.videoMemSize = (ioValue + 1) * 512 * 1024;
189 else if (ioValue < 12)
190 si.videoMemSize = (ioValue - 3) * 1024 * 1024;
191 else
192 si.videoMemSize = (ioValue - 7) * 2048 * 1024;
195 si.cursorOffset = (si.videoMemSize - CURSOR_BYTES) & ~0xfff; // align to 4k boundary
196 si.frameBufferOffset = 0;
197 si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset;
199 TRACE("Video Memory size: %d MB frameBufferOffset: 0x%x cursorOffset: 0x%x\n",
200 si.videoMemSize / 1024 / 1024, si.frameBufferOffset, si.cursorOffset);
202 // 264VT-B's and later have DSP registers.
204 if ((si.chipType >= MACH64_264VTB) && !Mach64_InitDSPParams())
205 return B_ERROR;
207 // Determine if the LCD display of a laptop computer is active.
209 si.displayType = MT_VGA;
211 if (si.chipType == MACH64_MOBILITY && si.panelX > 0 && si.panelY > 0) {
212 if (Mach64_GetLCDReg(LCD_GEN_CNTL) & LCD_ON)
213 si.displayType = MT_LAPTOP;
216 // Set up the array of color spaces supported by the Mach64 chips.
218 si.colorSpaces[0] = B_CMAP8;
219 si.colorSpaces[1] = B_RGB15;
220 si.colorSpaces[2] = B_RGB16;
221 si.colorSpaces[3] = B_RGB32;
222 si.colorSpaceCount = 4;
224 // Setup the mode list.
226 return CreateModeList(IsModeUsable);
230 static void
231 Mach64_WaitForFifo(uint32 entries)
233 // The FIFO has 16 slots. This routines waits until at least `entries'
234 // of these slots are empty.
236 while ((INREG(FIFO_STAT) & 0xffff) > (0x8000ul >> entries)) ;
240 static void
241 Mach64_WaitForIdle()
243 // Wait for the graphics engine to be completely idle. That is, the FIFO
244 // has drained, the Pixel Cache is flushed, and the engine is idle. This
245 // is a standard "sync" function that will make the hardware "quiescent".
247 Mach64_WaitForFifo(16);
249 while (INREG(GUI_STAT) & ENGINE_BUSY) ;
253 void
254 Mach64_SetFunctionPointers(void)
256 // Setting the function pointers must be done prior to first ModeInit call
257 // or any accel activity.
259 gInfo.WaitForFifo = Mach64_WaitForFifo;
260 gInfo.WaitForIdle = Mach64_WaitForIdle;
262 gInfo.DPMSCapabilities = Mach64_DPMSCapabilities;
263 gInfo.GetDPMSMode = Mach64_GetDPMSMode;
264 gInfo.SetDPMSMode = Mach64_SetDPMSMode;
266 gInfo.LoadCursorImage = Mach64_LoadCursorImage;
267 gInfo.SetCursorPosition = Mach64_SetCursorPosition;
268 gInfo.ShowCursor = Mach64_ShowCursor;
270 gInfo.FillRectangle = Mach64_FillRectangle;
271 gInfo.FillSpan = Mach64_FillSpan;
272 gInfo.InvertRectangle = Mach64_InvertRectangle;
273 gInfo.ScreenToScreenBlit = Mach64_ScreenToScreenBlit;
275 gInfo.AdjustFrame = Mach64_AdjustFrame;
276 gInfo.ChipInit = Mach64_Init;
277 gInfo.GetColorSpaceParams = Mach64_GetColorSpaceParams;
278 gInfo.SetDisplayMode = Mach64_SetDisplayMode;
279 gInfo.SetIndexedColors = Mach64_SetIndexedColors;