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
22 void
Rage128_EngineFlush()23 Rage128_EngineFlush()
24 {
25 // Flush all dirty data in the Pixel Cache to memory.
26
27 OUTREGM(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, R128_PC_FLUSH_ALL);
28
29 for (int i = 0; i < R128_TIMEOUT; i++) {
30 if ( ! (INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
31 break;
32 }
33 }
34
35
36 void
Rage128_EngineReset()37 Rage128_EngineReset()
38 {
39 // Reset graphics card to known state.
40
41 Rage128_EngineFlush();
42
43 uint32 clockCntlIndex = INREG(R128_CLOCK_CNTL_INDEX);
44 uint32 mclkCntl = GetPLLReg(R128_MCLK_CNTL);
45
46 SetPLLReg(R128_MCLK_CNTL, mclkCntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
47
48 uint32 genResetCntl = INREG(R128_GEN_RESET_CNTL);
49
50 OUTREG(R128_GEN_RESET_CNTL, genResetCntl | R128_SOFT_RESET_GUI);
51 INREG(R128_GEN_RESET_CNTL);
52 OUTREG(R128_GEN_RESET_CNTL, genResetCntl & ~R128_SOFT_RESET_GUI);
53 INREG(R128_GEN_RESET_CNTL);
54
55 SetPLLReg(R128_MCLK_CNTL, mclkCntl);
56 OUTREG(R128_CLOCK_CNTL_INDEX, clockCntlIndex);
57 OUTREG(R128_GEN_RESET_CNTL, genResetCntl);
58 }
59
60
61 void
Rage128_EngineInit(const DisplayModeEx & mode)62 Rage128_EngineInit(const DisplayModeEx& mode)
63 {
64 // Initialize the acceleration hardware.
65
66 SharedInfo& si = *gInfo.sharedInfo;
67
68 TRACE("Rage128_EngineInit() bits/pixel: %d\n", mode.bitsPerPixel);
69
70 OUTREG(R128_SCALE_3D_CNTL, 0);
71 Rage128_EngineReset();
72
73 uint32 dataType = 0;
74
75 switch (mode.bitsPerPixel) {
76 case 8:
77 dataType = 2;
78 break;
79 case 15:
80 dataType = 3;
81 break;
82 case 16:
83 dataType = 4;
84 break;
85 case 32:
86 dataType = 6;
87 break;
88 default:
89 TRACE("Unsupported color depth: %d bits/pixel\n", mode.bitsPerPixel);
90 }
91
92 gInfo.WaitForFifo(2);
93 OUTREG(R128_DEFAULT_OFFSET, gInfo.sharedInfo->frameBufferOffset);
94 OUTREG(R128_DEFAULT_PITCH, mode.timing.h_display / 8);
95
96 gInfo.WaitForFifo(4);
97 OUTREG(R128_AUX_SC_CNTL, 0);
98 OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
99 | R128_DEFAULT_SC_BOTTOM_MAX));
100 OUTREG(R128_SC_TOP_LEFT, 0);
101 OUTREG(R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
102 | R128_DEFAULT_SC_BOTTOM_MAX));
103
104 si.r128_dpGuiMasterCntl = ((dataType << R128_GMC_DST_DATATYPE_SHIFT)
105 | R128_GMC_CLR_CMP_CNTL_DIS
106 | R128_GMC_AUX_CLIP_DIS);
107 gInfo.WaitForFifo(1);
108 OUTREG(R128_DP_GUI_MASTER_CNTL, (si.r128_dpGuiMasterCntl
109 | R128_GMC_BRUSH_SOLID_COLOR
110 | R128_GMC_SRC_DATATYPE_COLOR));
111
112 gInfo.WaitForFifo(8);
113 OUTREG(R128_DST_BRES_ERR, 0);
114 OUTREG(R128_DST_BRES_INC, 0);
115 OUTREG(R128_DST_BRES_DEC, 0);
116 OUTREG(R128_DP_BRUSH_FRGD_CLR, 0xffffffff);
117 OUTREG(R128_DP_BRUSH_BKGD_CLR, 0x00000000);
118 OUTREG(R128_DP_SRC_FRGD_CLR, 0xffffffff);
119 OUTREG(R128_DP_SRC_BKGD_CLR, 0x00000000);
120 OUTREG(R128_DP_WRITE_MASK, 0xffffffff);
121
122 gInfo.WaitForFifo(1);
123 OUTREGM(R128_DP_DATATYPE, 0, R128_HOST_BIG_ENDIAN_EN);
124
125 gInfo.WaitForIdle();
126 }
127
128
129 void
Rage128_FillRectangle(engine_token * et,uint32 color,fill_rect_params * pList,uint32 count)130 Rage128_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count)
131 {
132 (void)et; // avoid compiler warning for unused arg
133
134 gInfo.WaitForFifo(3);
135 OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
136 | R128_GMC_BRUSH_SOLID_COLOR
137 | R128_GMC_SRC_DATATYPE_COLOR
138 | R128_ROP3_P)); // use GXcopy for rop
139
140 OUTREG(R128_DP_BRUSH_FRGD_CLR, color);
141 OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
142
143 while (count--) {
144 int x = pList->left;
145 int y = pList->top;
146 int w = pList->right - x + 1;
147 int h = pList->bottom - y + 1;
148
149 gInfo.WaitForFifo(2);
150 OUTREG(R128_DST_Y_X, (y << 16) | x);
151 OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);
152
153 pList++;
154 }
155 }
156
157
158 void
Rage128_FillSpan(engine_token * et,uint32 color,uint16 * pList,uint32 count)159 Rage128_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
160 {
161 (void)et; // avoid compiler warning for unused arg
162
163 gInfo.WaitForFifo(2);
164 OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
165 | R128_GMC_BRUSH_SOLID_COLOR
166 | R128_GMC_SRC_DATATYPE_COLOR
167 | R128_ROP3_P)); // use GXcopy for rop
168
169 OUTREG(R128_DP_BRUSH_FRGD_CLR, color);
170
171 while (count--) {
172 int y = *pList++;
173 int x = *pList++;
174 int w = *pList++ - x + 1;
175
176 if (w <= 0)
177 continue; // discard span with zero or negative width
178
179 gInfo.WaitForFifo(2);
180 OUTREG(R128_DST_Y_X, (y << 16) | x);
181 OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | 1);
182 }
183 }
184
185
186 void
Rage128_InvertRectangle(engine_token * et,fill_rect_params * pList,uint32 count)187 Rage128_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count)
188 {
189 (void)et; // avoid compiler warning for unused arg
190
191 gInfo.WaitForFifo(2);
192 OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
193 | R128_GMC_BRUSH_NONE
194 | R128_GMC_SRC_DATATYPE_COLOR
195 | R128_DP_SRC_SOURCE_MEMORY
196 | R128_ROP3_Dn)); // use GXinvert for rop
197
198 OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
199
200 while (count--) {
201 int x = pList->left;
202 int y = pList->top;
203 int w = pList->right - x + 1;
204 int h = pList->bottom - y + 1;
205
206 gInfo.WaitForFifo(2);
207 OUTREG(R128_DST_Y_X, (y << 16) | x);
208 OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);
209
210 pList++;
211 }
212 }
213
214
215 void
Rage128_ScreenToScreenBlit(engine_token * et,blit_params * pList,uint32 count)216 Rage128_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count)
217 {
218 (void)et; // avoid compiler warning for unused arg
219
220 gInfo.WaitForFifo(1);
221 OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl
222 | R128_GMC_BRUSH_NONE
223 | R128_GMC_SRC_DATATYPE_COLOR
224 | R128_DP_SRC_SOURCE_MEMORY
225 | R128_ROP3_S)); // use GXcopy for rop
226
227 while (count--) {
228 int cmd = 0;
229 int src_x = pList->src_left;
230 int src_y = pList->src_top;
231 int dest_x = pList->dest_left;
232 int dest_y = pList->dest_top;
233 int width = pList->width;
234 int height = pList->height;
235
236 if (dest_x <= src_x) {
237 cmd |= R128_DST_X_LEFT_TO_RIGHT;
238 } else {
239 src_x += width;
240 dest_x += width;
241 }
242
243 if (dest_y <= src_y) {
244 cmd |= R128_DST_Y_TOP_TO_BOTTOM;
245 } else {
246 src_y += height;
247 dest_y += height;
248 }
249
250 gInfo.WaitForFifo(4);
251 OUTREG(R128_DP_CNTL, cmd);
252 OUTREG(R128_SRC_Y_X, (src_y << 16) | src_x);
253 OUTREG(R128_DST_Y_X, (dest_y << 16) | dest_x);
254 OUTREG(R128_DST_HEIGHT_WIDTH, ((height + 1) << 16) | (width + 1));
255
256 pList ++;
257 }
258 }
259