1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
3
4 Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 Precision Insight, Inc., Cedar Park, Texas, and
6 VA Linux Systems Inc., Fremont, California.
7
8 Copyright 2009 Haiku, Inc. All rights reserved.
9 Distributed under the terms of the MIT license.
10
11 Authors:
12 Gerald Zajac 2009
13 */
14
15
16 #include "accelerant.h"
17 #include "rage128.h"
18
19
20
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" },
28 };
29
30
31
32 static bool
Rage128_GetColorSpaceParams(int colorSpace,uint8 & bitsPerPixel,uint32 & maxPixelClock)33 Rage128_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, uint32& maxPixelClock)
34 {
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.
38
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;
55 }
56
57 maxPixelClock = gInfo.sharedInfo->r128PLLParams.max_pll_freq * 10;
58 return true;
59 }
60
61
62 static void
WaitForFifo(uint32 entries)63 WaitForFifo(uint32 entries)
64 {
65 // The FIFO has 64 slots. This routines waits until at least `entries'
66 // of these slots are empty.
67
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;
73 }
74
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");
80
81 Rage128_EngineReset();
82 }
83 }
84
85
86 static void
WaitForIdle()87 WaitForIdle()
88 {
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".
92
93 WaitForFifo(64);
94
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 ;
100 }
101 }
102
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");
108
109 Rage128_EngineReset();
110 }
111 }
112
113
114 status_t
Rage128_Init(void)115 Rage128_Init(void)
116 {
117 TRACE("Rage128_Init()\n");
118
119 SharedInfo& si = *gInfo.sharedInfo;
120
121 si.videoMemSize = INREG(R128_CONFIG_MEMSIZE);
122
123 si.cursorOffset = (si.videoMemSize - CURSOR_BYTES) & ~0xfff; // align to 4k boundary
124 si.frameBufferOffset = 0;
125 si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset;
126
127 TRACE("Video Memory size: %d MB frameBufferOffset: 0x%x cursorOffset: 0x%x\n",
128 si.videoMemSize / 1024 / 1024, si.frameBufferOffset, si.cursorOffset);
129
130 // Get the specifications of the memory used by the chip.
131
132 uint32 offset;
133
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;
152 }
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;
163 }
164 si.r128MemSpec = sRAMSpecs[offset];
165 TRACE("RAM type: %s\n", si.r128MemSpec.name);
166
167 // Determine the type of display.
168
169 si.displayType = MT_VGA;
170
171 if (INREG(R128_FP_PANEL_CNTL) & R128_FP_DIGON) // don't know if this is correct
172 si.displayType = MT_DVI;
173
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
177 }
178
179 // Set up the array of color spaces supported by the Rage128 chips.
180
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;
186
187 // Setup the mode list.
188
189 return CreateModeList(IsModeUsable);
190 }
191
192
193 void
Rage128_SetFunctionPointers(void)194 Rage128_SetFunctionPointers(void)
195 {
196 // Setting the function pointers must be done prior to first ModeInit call
197 // or any accel activity.
198
199 gInfo.WaitForFifo = WaitForFifo;
200 gInfo.WaitForIdle = WaitForIdle;
201
202 gInfo.DPMSCapabilities = Rage128_DPMSCapabilities;
203 gInfo.GetDPMSMode = Rage128_GetDPMSMode;
204 gInfo.SetDPMSMode = Rage128_SetDPMSMode;
205
206 gInfo.LoadCursorImage = Rage128_LoadCursorImage;
207 gInfo.SetCursorPosition = Rage128_SetCursorPosition;
208 gInfo.ShowCursor = Rage128_ShowCursor;
209
210 gInfo.FillRectangle = Rage128_FillRectangle;
211 gInfo.FillSpan = Rage128_FillSpan;
212 gInfo.InvertRectangle = Rage128_InvertRectangle;
213 gInfo.ScreenToScreenBlit = Rage128_ScreenToScreenBlit;
214
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;
220 }
221
222