1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver.
3
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
6
7 Copyright 2009 Haiku, Inc. All rights reserved.
8 Distributed under the terms of the MIT license.
9
10 Authors:
11 Gerald Zajac 2009
12 */
13
14
15 #include "accelerant.h"
16 #include "mach64.h"
17
18
19
20 void
Mach64_EngineReset()21 Mach64_EngineReset()
22 {
23 // Reset engine and then enable it.
24
25 uint32 genTestCntl = INREG(GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE;
26 OUTREG(GEN_TEST_CNTL, genTestCntl);
27 OUTREG(GEN_TEST_CNTL, genTestCntl | GUI_ENGINE_ENABLE);
28
29 // Ensure engine is not locked up by clearing any FIFO errors.
30
31 OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK);
32 }
33
34
35 void
Mach64_EngineInit(const DisplayModeEx & mode)36 Mach64_EngineInit(const DisplayModeEx& mode)
37 {
38 // Initialize the drawing environment and clear the display.
39
40 Mach64_EngineReset();
41
42 gInfo.WaitForIdle();
43
44 OUTREG(MEM_VGA_WP_SEL, 0x00010000);
45 OUTREG(MEM_VGA_RP_SEL, 0x00010000);
46
47 uint32 dpPixWidth = 0;
48 uint32 dpChainMask = 0;
49
50 switch (mode.bitsPerPixel) {
51 case 8:
52 dpPixWidth = HOST_8BPP | SRC_8BPP | DST_8BPP;
53 dpChainMask = DP_CHAIN_8BPP;
54 break;
55 case 15:
56 dpPixWidth = HOST_15BPP | SRC_15BPP | DST_15BPP;
57 dpChainMask = DP_CHAIN_15BPP;
58 break;
59 case 16:
60 dpPixWidth = HOST_16BPP | SRC_16BPP | DST_16BPP;
61 dpChainMask = DP_CHAIN_16BPP;
62 break;
63 case 32:
64 dpPixWidth = HOST_32BPP | SRC_32BPP | DST_32BPP;
65 dpChainMask = DP_CHAIN_32BPP;
66 break;
67 }
68
69 dpPixWidth |= BYTE_ORDER_LSB_TO_MSB; // set for little-endian byte order
70
71 gInfo.WaitForFifo(3);
72 OUTREG(DP_PIX_WIDTH, dpPixWidth);
73 OUTREG(DP_CHAIN_MASK, dpChainMask);
74
75 OUTREG(CONTEXT_MASK, 0xffffffff);
76
77 gInfo.WaitForFifo(7);
78 OUTREG(DST_OFF_PITCH, (mode.timing.h_display / 8) << 22);
79 OUTREG(DST_Y_X, 0);
80 OUTREG(DST_HEIGHT, 0);
81 OUTREG(DST_BRES_ERR, 0);
82 OUTREG(DST_BRES_INC, 0);
83 OUTREG(DST_BRES_DEC, 0);
84 OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
85
86 gInfo.WaitForFifo(6);
87 OUTREG(SRC_OFF_PITCH, (mode.timing.h_display / 8) << 22);
88 OUTREG(SRC_Y_X, 0);
89 OUTREG(SRC_HEIGHT1_WIDTH1, 0x10001);
90 OUTREG(SRC_Y_X_START, 0);
91 OUTREG(SRC_HEIGHT2_WIDTH2, 0x10001);
92 OUTREG(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
93
94 gInfo.WaitForFifo(7);
95 OUTREGM(HOST_CNTL, 0, HOST_BYTE_ALIGN);
96 OUTREG(PAT_REG0, 0);
97 OUTREG(PAT_REG1, 0);
98 OUTREG(PAT_CNTL, 0);
99
100 OUTREG(SC_LEFT_RIGHT, ((mode.timing.h_display << 16) | 0 ));
101 OUTREG(SC_TOP_BOTTOM, ((mode.timing.v_display << 16) | 0 ));
102
103 gInfo.WaitForFifo(9);
104 OUTREG(DP_BKGD_CLR, 0);
105 OUTREG(DP_FRGD_CLR, 0xffffffff);
106 OUTREG(DP_WRITE_MASK, 0xffffffff);
107 OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST);
108 OUTREG(DP_SRC, FRGD_SRC_FRGD_CLR);
109
110 OUTREG(CLR_CMP_CLR, 0);
111 OUTREG(CLR_CMP_MASK, 0xffffffff);
112 OUTREG(CLR_CMP_CNTL, 0);
113
114 gInfo.WaitForIdle();
115 }
116
117
118 void
Mach64_FillRectangle(engine_token * et,uint32 color,fill_rect_params * pList,uint32 count)119 Mach64_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count)
120 {
121 (void)et; // avoid compiler warning for unused arg
122
123 gInfo.WaitForFifo(4);
124 OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE);
125 OUTREG(DP_FRGD_CLR, color);
126 OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST);
127 OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
128
129 while (count--) {
130 int x = pList->left;
131 int y = pList->top;
132 int w = pList->right - x + 1;
133 int h = pList->bottom - y + 1;
134
135 gInfo.WaitForFifo(2);
136 OUTREG(DST_Y_X, (x << 16) | y);
137 OUTREG(DST_HEIGHT_WIDTH, (w << 16) | h);
138
139 pList++;
140 }
141 }
142
143
144 void
Mach64_FillSpan(engine_token * et,uint32 color,uint16 * pList,uint32 count)145 Mach64_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
146 {
147 (void)et; // avoid compiler warning for unused arg
148
149 gInfo.WaitForFifo(4);
150 OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE);
151 OUTREG(DP_FRGD_CLR, color);
152 OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST);
153 OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
154
155 while (count--) {
156 int y = *pList++;
157 int x = *pList++;
158 int w = *pList++ - x + 1;
159
160 if (w <= 0)
161 continue; // discard span with zero or negative width
162
163 gInfo.WaitForFifo(2);
164 OUTREG(DST_Y_X, (x << 16) | y);
165 OUTREG(DST_HEIGHT_WIDTH, (w << 16) | 1);
166 }
167 }
168
169
170 void
Mach64_InvertRectangle(engine_token * et,fill_rect_params * pList,uint32 count)171 Mach64_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count)
172 {
173 (void)et; // avoid compiler warning for unused arg
174
175 gInfo.WaitForFifo(3);
176 OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE);
177 OUTREG(DP_MIX, MIX_NOT_DST << 16);
178 OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL);
179
180 while (count--) {
181 int x = pList->left;
182 int y = pList->top;
183 int w = pList->right - x + 1;
184 int h = pList->bottom - y + 1;
185
186 gInfo.WaitForFifo(2);
187 OUTREG(DST_Y_X, (x << 16) | y);
188 OUTREG(DST_HEIGHT_WIDTH, (w << 16) | h);
189
190 pList++;
191 }
192 }
193
194
195 void
Mach64_ScreenToScreenBlit(engine_token * et,blit_params * pList,uint32 count)196 Mach64_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count)
197 {
198 (void)et; // avoid compiler warning for unused arg
199
200 gInfo.WaitForFifo(2);
201 OUTREG(DP_SRC, FRGD_SRC_BLIT);
202 OUTREG(DP_MIX, MIX_SRC << 16);
203
204 while (count--) {
205 int cmd = DST_LAST_PEL;
206 int src_x = pList->src_left;
207 int src_y = pList->src_top;
208 int dest_x = pList->dest_left;
209 int dest_y = pList->dest_top;
210 int width = pList->width;
211 int height = pList->height;
212
213 if (dest_x <= src_x) {
214 cmd |= DST_X_LEFT_TO_RIGHT;
215 } else {
216 src_x += width;
217 dest_x += width;
218 }
219
220 if (dest_y <= src_y) {
221 cmd |= DST_Y_TOP_TO_BOTTOM;
222 } else {
223 src_y += height;
224 dest_y += height;
225 }
226
227 gInfo.WaitForFifo(5);
228 OUTREG(DST_CNTL, cmd);
229 OUTREG(SRC_Y_X, (src_x << 16) | src_y);
230 OUTREG(SRC_HEIGHT1_WIDTH1, ((width + 1) << 16) | (height + 1));
231 OUTREG(DST_Y_X, (dest_x << 16) | dest_y);
232 OUTREG(DST_HEIGHT_WIDTH, ((width + 1) << 16) | (height + 1));
233
234 pList ++;
235 }
236 }
237