vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / ati / rage128_init.cpp
blobbdb74e28ac95beb75f5903edef77577533b4b919
1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
4 Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 Precision Insight, Inc., Cedar Park, Texas, and
6 VA Linux Systems Inc., Fremont, California.
8 Copyright 2009 Haiku, Inc. All rights reserved.
9 Distributed under the terms of the MIT license.
11 Authors:
12 Gerald Zajac 2009
16 #include "accelerant.h"
17 #include "rage128.h"
21 // Memory Specifications from RAGE 128 Software Development Manual
22 // (Technical Reference Manual P/N SDK-G04000 Rev 0.01), page 3-21.
23 static R128_RAMSpec sRAMSpecs[] = {
24 { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" },
25 { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" },
26 { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" },
27 { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },
32 static bool
33 Rage128_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, uint32& maxPixelClock)
35 // Get parameters for a color space which is supported by the Rage128 chips.
36 // Argument maxPixelClock is in KHz.
37 // Return true if the color space is supported; else return false.
39 switch (colorSpace) {
40 case B_RGB32:
41 bitsPerPixel = 32;
42 break;
43 case B_RGB16:
44 bitsPerPixel = 16;
45 break;
46 case B_RGB15:
47 bitsPerPixel = 15;
48 break;
49 case B_CMAP8:
50 bitsPerPixel = 8;
51 break;
52 default:
53 TRACE("Unsupported color space: 0x%X\n", colorSpace);
54 return false;
57 maxPixelClock = gInfo.sharedInfo->r128PLLParams.max_pll_freq * 10;
58 return true;
62 static void
63 WaitForFifo(uint32 entries)
65 // The FIFO has 64 slots. This routines waits until at least `entries'
66 // of these slots are empty.
68 while (true) {
69 for (int i = 0; i < R128_TIMEOUT; i++) {
70 uint32 slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
71 if (slots >= entries)
72 return;
75 TRACE("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n",
76 INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,
77 INREG(R128_GUI_STAT),
78 INREG(R128_GUI_PROBE));
79 TRACE("FIFO timed out, resetting engine...\n");
81 Rage128_EngineReset();
86 static void
87 WaitForIdle()
89 // Wait for the graphics engine to be completely idle. That is, the FIFO
90 // has drained, the Pixel Cache is flushed, and the engine is idle. This
91 // is a standard "sync" function that will make the hardware "quiescent".
93 WaitForFifo(64);
95 while (true) {
96 for (uint32 i = 0; i < R128_TIMEOUT; i++) {
97 if ( ! (INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
98 Rage128_EngineFlush();
99 return ;
103 TRACE("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n",
104 INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,
105 INREG(R128_GUI_STAT),
106 INREG(R128_GUI_PROBE));
107 TRACE("Idle timed out, resetting engine...\n");
109 Rage128_EngineReset();
114 status_t
115 Rage128_Init(void)
117 TRACE("Rage128_Init()\n");
119 SharedInfo& si = *gInfo.sharedInfo;
121 si.videoMemSize = INREG(R128_CONFIG_MEMSIZE);
123 si.cursorOffset = (si.videoMemSize - CURSOR_BYTES) & ~0xfff; // align to 4k boundary
124 si.frameBufferOffset = 0;
125 si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset;
127 TRACE("Video Memory size: %d MB frameBufferOffset: 0x%x cursorOffset: 0x%x\n",
128 si.videoMemSize / 1024 / 1024, si.frameBufferOffset, si.cursorOffset);
130 // Get the specifications of the memory used by the chip.
132 uint32 offset;
134 switch (INREG(R128_MEM_CNTL) & 0x3) {
135 case 0: // SDR SGRAM 1:1
136 switch (si.deviceID) {
137 case 0x4C45: // RAGE128 LE:
138 case 0x4C46: // RAGE128 LF:
139 case 0x4D46: // RAGE128 MF:
140 case 0x4D4C: // RAGE128 ML:
141 case 0x5245: // RAGE128 RE:
142 case 0x5246: // RAGE128 RF:
143 case 0x5247: // RAGE128 RG:
144 case 0x5446: // RAGE128 TF:
145 case 0x544C: // RAGE128 TL:
146 case 0x5452: // RAGE128 TR:
147 offset = 0; // 128-bit SDR SGRAM 1:1
148 break;
149 default:
150 offset = 1; // 64-bit SDR SGRAM 1:1
151 break;
153 break;
154 case 1:
155 offset = 2; // 64-bit SDR SGRAM 2:1
156 break;
157 case 2:
158 offset = 3; // 64-bit DDR SGRAM
159 break;
160 default:
161 offset = 1; // 64-bit SDR SGRAM 1:1
162 break;
164 si.r128MemSpec = sRAMSpecs[offset];
165 TRACE("RAM type: %s\n", si.r128MemSpec.name);
167 // Determine the type of display.
169 si.displayType = MT_VGA;
171 if (INREG(R128_FP_PANEL_CNTL) & R128_FP_DIGON) // don't know if this is correct
172 si.displayType = MT_DVI;
174 if (si.chipType == RAGE128_MOBILITY && si.panelX > 0 && si.panelY > 0) {
175 if (INREG(R128_LVDS_GEN_CNTL) & R128_LVDS_ON)
176 si.displayType = MT_LAPTOP; // laptop LCD display is on
179 // Set up the array of color spaces supported by the Rage128 chips.
181 si.colorSpaces[0] = B_CMAP8;
182 si.colorSpaces[1] = B_RGB15;
183 si.colorSpaces[2] = B_RGB16;
184 si.colorSpaces[3] = B_RGB32;
185 si.colorSpaceCount = 4;
187 // Setup the mode list.
189 return CreateModeList(IsModeUsable);
193 void
194 Rage128_SetFunctionPointers(void)
196 // Setting the function pointers must be done prior to first ModeInit call
197 // or any accel activity.
199 gInfo.WaitForFifo = WaitForFifo;
200 gInfo.WaitForIdle = WaitForIdle;
202 gInfo.DPMSCapabilities = Rage128_DPMSCapabilities;
203 gInfo.GetDPMSMode = Rage128_GetDPMSMode;
204 gInfo.SetDPMSMode = Rage128_SetDPMSMode;
206 gInfo.LoadCursorImage = Rage128_LoadCursorImage;
207 gInfo.SetCursorPosition = Rage128_SetCursorPosition;
208 gInfo.ShowCursor = Rage128_ShowCursor;
210 gInfo.FillRectangle = Rage128_FillRectangle;
211 gInfo.FillSpan = Rage128_FillSpan;
212 gInfo.InvertRectangle = Rage128_InvertRectangle;
213 gInfo.ScreenToScreenBlit = Rage128_ScreenToScreenBlit;
215 gInfo.AdjustFrame = Rage128_AdjustFrame;
216 gInfo.ChipInit = Rage128_Init;
217 gInfo.GetColorSpaceParams = Rage128_GetColorSpaceParams;
218 gInfo.SetDisplayMode = Rage128_SetDisplayMode;
219 gInfo.SetIndexedColors = Rage128_SetIndexedColors;