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