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