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