ast_2dtool.c revision 58e54220
1/* 2 * Copyright (c) 2005 ASPEED Technology Inc. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of the authors not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. The authors makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include <config.h> 25#endif 26#include "xf86.h" 27#include "xf86_OSproc.h" 28#include "xf86cmap.h" 29#include "compiler.h" 30#include "vgaHW.h" 31#include "mipointer.h" 32#include "micmap.h" 33 34#include "fb.h" 35#include "regionstr.h" 36#include "xf86xv.h" 37#include <X11/extensions/Xv.h> 38 39#include "xf86Pci.h" 40 41/* framebuffer offscreen manager */ 42#include "xf86fbman.h" 43 44#include "xaarop.h" 45 46/* H/W cursor support */ 47#include "xf86Cursor.h" 48 49/* Driver specific headers */ 50#include "ast.h" 51#include "ast_vgatool.h" 52#include "ast_2dtool.h" 53 54#ifdef Accel_2D 55typedef Bool (*PFN_bENABLE_CMDQ)(ScrnInfoPtr , ASTRecPtr); 56 57/* Prototype type declaration */ 58 59static Bool 60bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST) 61{ 62 63 ScreenPtr pScreen; 64 65 /* CMDQ mode Init */ 66 if (!pAST->MMIO2D) { 67 pAST->CMDQInfo.ulCMDQType = VM_CMD_QUEUE; 68 69 pScreen = xf86ScrnToScreen(pScrn); 70 71 do { 72 pAST->pCMDQPtr = xf86AllocateOffscreenLinear (pScreen, pAST->CMDQInfo.ulCMDQSize, 8, NULL, NULL, NULL); 73 74 if (pAST->pCMDQPtr) break; 75 76 pAST->CMDQInfo.ulCMDQSize >>= 1; 77 78 } while (pAST->CMDQInfo.ulCMDQSize >= MIN_CMDQ_SIZE); 79 80 if (pAST->pCMDQPtr) 81 { 82 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"Allocate CMDQ size is %ld kbyte \n", (unsigned long) (pAST->CMDQInfo.ulCMDQSize/1024)); 83 84 pAST->CMDQInfo.ulCMDQOffsetAddr = pAST->pCMDQPtr->offset*((pScrn->bitsPerPixel + 1) / 8); 85 pAST->CMDQInfo.pjCMDQVirtualAddr = pAST->FBVirtualAddr + pAST->CMDQInfo.ulCMDQOffsetAddr; 86 87 pAST->CMDQInfo.ulCurCMDQueueLen = pAST->CMDQInfo.ulCMDQSize - CMD_QUEUE_GUARD_BAND; 88 pAST->CMDQInfo.ulCMDQMask = pAST->CMDQInfo.ulCMDQSize - 1 ; 89 90 } 91 else 92 { 93 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate CMDQ failed \n"); 94 pAST->MMIO2D = TRUE; /* set to MMIO mode if CMDQ allocate failed */ 95 } 96 97 } 98 99 /* MMIO mode init */ 100 if (pAST->MMIO2D) { 101 pAST->CMDQInfo.ulCMDQType = VM_CMD_MMIO; 102 } 103 104 return (TRUE); 105} 106 107static Bool 108bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST) 109{ 110 ULONG ulVMCmdQBasePort = 0; 111 112 vASTWaitEngIdle(pScrn, pAST); 113 114 /* set DBG Select Info */ 115 if (pAST->DBGSelect) 116 { 117 *(ULONG *) (pAST->MMIOVirtualAddr + 0x804C) = (ULONG) (pAST->DBGSelect); 118 } 119 120 /* set CMDQ base */ 121 switch (pAST->CMDQInfo.ulCMDQType) 122 { 123 case VM_CMD_QUEUE: 124 ulVMCmdQBasePort = (pAST->CMDQInfo.ulCMDQOffsetAddr - 0) >> 3; 125 126 /* set CMDQ Threshold */ 127 ulVMCmdQBasePort |= 0xF0000000; 128 129 /* set CMDQ Size */ 130 switch (pAST->CMDQInfo.ulCMDQSize) 131 { 132 case CMD_QUEUE_SIZE_256K: 133 ulVMCmdQBasePort |= 0x00000000; 134 break; 135 136 case CMD_QUEUE_SIZE_512K: 137 ulVMCmdQBasePort |= 0x04000000; 138 break; 139 140 case CMD_QUEUE_SIZE_1M: 141 ulVMCmdQBasePort |= 0x08000000; 142 break; 143 144 case CMD_QUEUE_SIZE_2M: 145 ulVMCmdQBasePort |= 0x0C000000; 146 break; 147 148 default: 149 return(FALSE); 150 break; 151 } 152 153 *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort; 154 pAST->CMDQInfo.ulWritePointer = *(ULONG *) (pAST->CMDQInfo.pjWritePort) << 3; 155 break; 156 157 case VM_CMD_MMIO: 158 /* set CMDQ Threshold */ 159 ulVMCmdQBasePort |= 0xF0000000; 160 161 ulVMCmdQBasePort |= 0x02000000; /* MMIO mode */ 162 *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort; 163 break; 164 165 default: 166 return (FALSE); 167 break; 168 } 169 170 return (TRUE); 171} 172 173static Bool 174bEnableCMDQ2300(ScrnInfoPtr pScrn, ASTRecPtr pAST) 175{ 176 ULONG ulVMCmdQBasePort = 0, ulNewModeData; 177 178 vASTWaitEngIdle(pScrn, pAST); 179 180 /* set DBG Select Info */ 181 if (pAST->DBGSelect) 182 { 183 *(ULONG *) (pAST->MMIOVirtualAddr + 0x804C) = (ULONG) (pAST->DBGSelect); 184 } 185 186 /* set CMDQ base */ 187 switch (pAST->CMDQInfo.ulCMDQType) 188 { 189 case VM_CMD_QUEUE: 190 /* enable new CMDQ mode */ 191 ulNewModeData = 0xc00000f0; 192 /* set CMDQ Size */ 193 switch (pAST->CMDQInfo.ulCMDQSize) 194 { 195 case CMD_QUEUE_SIZE_256K: 196 ulNewModeData |= 0x00000000; 197 break; 198 199 case CMD_QUEUE_SIZE_512K: 200 ulNewModeData |= 0x00000004; 201 break; 202 203 case CMD_QUEUE_SIZE_1M: 204 ulNewModeData |= 0x00000008; 205 break; 206 207 case CMD_QUEUE_SIZE_2M: 208 ulNewModeData |= 0x0000000C; 209 break; 210 211 default: 212 return(FALSE); 213 break; 214 } 215 *(ULONG *) (pAST->MMIOVirtualAddr + 0x8060) = ulNewModeData; 216 217 /* Set CMDQ Base */ 218 ulVMCmdQBasePort = (pAST->CMDQInfo.ulCMDQOffsetAddr - 0) >> 3; 219 *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort; 220 pAST->CMDQInfo.ulWritePointer = *(ULONG *) (pAST->CMDQInfo.pjWritePort) << 3; 221 break; 222 223 case VM_CMD_MMIO: 224 /* enable new CMDQ mode */ 225 ulNewModeData = 0xc00000f2; 226 *(ULONG *) (pAST->MMIOVirtualAddr + 0x8060) = ulNewModeData; 227 break; 228 229 default: 230 return (FALSE); 231 break; 232 } 233 234 return (TRUE); 235 236} /* bEnableCMDQ2300 */ 237 238Bool 239bASTEnable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST) 240{ 241 ULONG ulData; 242 PFN_bENABLE_CMDQ pfnEnableCMDQ = bEnableCMDQ; 243 244 if ( (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500) ) 245 pfnEnableCMDQ = bEnableCMDQ2300; 246 247 switch (pAST->jChipType) 248 { 249 case AST2100: 250 case AST1100: 251 case AST2200: 252 case AST2150: 253 case AST2300: 254 case AST2400: 255 case AST2500: 256 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; 257 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; 258 259 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c); 260 *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c) = (ulData & 0xFFFFFFFD); 261 262 case AST2000: 263 SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01); /* enable 2D */ 264 265 break; 266 } 267 268 if (!bInitCMDQInfo(pScrn, pAST)) 269 { 270 vASTDisable2D(pScrn, pAST); 271 return (FALSE); 272 } 273 274 if (!pfnEnableCMDQ(pScrn, pAST)) 275 { 276 vASTDisable2D(pScrn, pAST); 277 return (FALSE); 278 } 279 280 return (TRUE); 281} 282 283void 284vASTDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST) 285{ 286 287 vASTWaitEngIdle(pScrn, pAST); 288 vASTWaitEngIdle(pScrn, pAST); 289 290 /* restore 2D settings */ 291 if (pAST->jChipType != AST1180) 292 { 293 if (pAST->SavedReg.REGA4 & 0x01) /* 2D enabled */ 294 { 295 SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01); 296 *(ULONG *) (pAST->MMIOVirtualAddr + 0x8044) = pAST->SavedReg.ENG8044; 297 } 298 else /* 2D disabled */ 299 { 300 SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00); 301 } 302 } 303} 304 305 306void 307vASTWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST) 308{ 309 ULONG ulEngState, ulEngState2; 310 UCHAR jReg; 311 ULONG ulEngCheckSetting = 0x80000000; 312 313 if (pAST->jChipType != AST1180) 314 { 315 316 /* 2D disable if 0xA4 D[0] = 1 */ 317 GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg); 318 if (!jReg) goto Exit_vASTWaitEngIdle; 319 320 /* 2D not work if in std. mode */ 321 GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg); 322 if (!jReg) goto Exit_vASTWaitEngIdle; 323 } 324 325 if (*(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) & 0x02000000) /* MMIO Mode */ 326 ulEngCheckSetting = 0x10000000; 327 328 do 329 { 330 ulEngState = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000; 331 ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000; 332 ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000; 333 ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000; 334 ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000; 335 ulEngState2 = (*(volatile ULONG *)(pAST->CMDQInfo.pjEngStatePort)) & 0xFFFC0000; 336 337 } while ((ulEngState & ulEngCheckSetting) || (ulEngState != ulEngState2)); 338 339Exit_vASTWaitEngIdle: 340 ; 341} 342 343/* ULONG ulGetCMDQLength() */ 344static __inline ULONG ulGetCMDQLength(ASTRecPtr pAST, ULONG ulWritePointer, ULONG ulCMDQMask) 345{ 346 ULONG ulReadPointer, ulReadPointer2; 347 348 do { 349 ulReadPointer = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)); 350 ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)); 351 ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)); 352 ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)); 353 ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)); 354 ulReadPointer2 = *((volatile ULONG *)(pAST->CMDQInfo.pjReadPort)); 355 } while ( ((ulReadPointer & 0x0003FFFF) != (ulReadPointer2 & 0x0003FFFF)) || (ulReadPointer == 0xFFFFEEEE) ); 356 357 return ((ulReadPointer << 3) - ulWritePointer - CMD_QUEUE_GUARD_BAND) & ulCMDQMask; 358} 359 360UCHAR *pASTjRequestCMDQ( 361ASTRecPtr pAST, ULONG ulDataLen) 362{ 363 UCHAR *pjBuffer; 364 ULONG i, ulWritePointer, ulCMDQMask, ulCurCMDQLen, ulContinueCMDQLen; 365 366 ulWritePointer = pAST->CMDQInfo.ulWritePointer; 367 ulContinueCMDQLen = pAST->CMDQInfo.ulCMDQSize - ulWritePointer; 368 ulCMDQMask = pAST->CMDQInfo.ulCMDQMask; 369 370 if (ulContinueCMDQLen >= ulDataLen) 371 { 372 /* Get CMDQ Buffer */ 373 if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen) 374 { 375 ; 376 } 377 else 378 { 379 380 do 381 { 382 ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask); 383 } while (ulCurCMDQLen < ulDataLen); 384 385 pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen; 386 387 } 388 389 pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer; 390 pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen; 391 pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask; 392 return pjBuffer; 393 } 394 else 395 { 396 397 /* Fill NULL CMD to the last of the CMDQ */ 398 if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulContinueCMDQLen) 399 { 400 ; 401 } 402 else 403 { 404 405 do 406 { 407 ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask); 408 } while (ulCurCMDQLen < ulContinueCMDQLen); 409 410 pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen; 411 412 } 413 414 pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer; 415 for (i = 0; i<ulContinueCMDQLen/8; i++, pjBuffer+=8) 416 { 417 *(ULONG *)pjBuffer = (ULONG) PKT_NULL_CMD; 418 *(ULONG *) (pjBuffer+4) = 0; 419 420 } 421 pAST->CMDQInfo.ulCurCMDQueueLen -= ulContinueCMDQLen; 422 pAST->CMDQInfo.ulWritePointer = ulWritePointer = 0; 423 424 /* Get CMDQ Buffer */ 425 if (pAST->CMDQInfo.ulCurCMDQueueLen >= ulDataLen) 426 { 427 ; 428 } 429 else 430 { 431 432 do 433 { 434 ulCurCMDQLen = ulGetCMDQLength(pAST, ulWritePointer, ulCMDQMask); 435 } while (ulCurCMDQLen < ulDataLen); 436 437 pAST->CMDQInfo.ulCurCMDQueueLen = ulCurCMDQLen; 438 439 } 440 441 pAST->CMDQInfo.ulCurCMDQueueLen -= ulDataLen; 442 pjBuffer = pAST->CMDQInfo.pjCMDQVirtualAddr + ulWritePointer; 443 pAST->CMDQInfo.ulWritePointer = (ulWritePointer + ulDataLen) & ulCMDQMask; 444 return pjBuffer; 445 446 } 447 448} /* end of pjRequestCmdQ() */ 449 450Bool bASTGetLineTerm(_LINEInfo *LineInfo, LINEPARAM *dsLineParam) 451{ 452 LONG GAbsX, GAbsY, GXInc, GYInc, GXMajor; 453 LONG MM, mm, Error0, K1, K2; 454 455 /* Init */ 456#ifdef LONG64 457 GAbsX = abs (LineInfo->X1 - LineInfo->X2); 458 GAbsY = abs (LineInfo->Y1 - LineInfo->Y2); 459#else 460 GAbsX = labs (LineInfo->X1 - LineInfo->X2); 461 GAbsY = labs (LineInfo->Y1 - LineInfo->Y2); 462#endif 463 464 GXInc = (LineInfo->X1 < LineInfo->X2) ? 1:0; 465 GYInc = (LineInfo->Y1 < LineInfo->Y2) ? 1:0; 466 GXMajor = (GAbsX >= GAbsY) ? 1:0; 467 468 /* Calculate */ 469 if (GXMajor) 470 { 471 MM = GAbsX; 472 mm = GAbsY; 473 } 474 else 475 { 476 MM = GAbsY; 477 mm = GAbsX; 478 } 479 480 Error0 = (signed) (2*mm - MM); 481 482 K1 = 2* mm; 483 K2 = (signed) (2*mm - 2*MM); 484 485 /*save the Param to dsLineParam */ 486 dsLineParam->dsLineX = (USHORT) LineInfo->X1; 487 dsLineParam->dsLineY = (USHORT) LineInfo->Y1; 488 dsLineParam->dsLineWidth = (USHORT) MM; 489 dsLineParam->dwErrorTerm = (ULONG) Error0; 490 dsLineParam->dwK1Term = K1; 491 dsLineParam->dwK2Term = K2; 492 493 dsLineParam->dwLineAttributes = 0; 494 if (GXMajor) dsLineParam->dwLineAttributes |= LINEPARAM_XM; 495 if (!GXInc) dsLineParam->dwLineAttributes |= LINEPARAM_X_DEC; 496 if (!GYInc) dsLineParam->dwLineAttributes |= LINEPARAM_Y_DEC; 497 498 return(TRUE); 499 500} 501#endif /* end of Accel_2D */ 502 503 504