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 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 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 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 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 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 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